]> git.saurik.com Git - apple/ld64.git/blobdiff - src/ld/passes/bitcode_bundle.cpp
ld64-409.12.tar.gz
[apple/ld64.git] / src / ld / passes / bitcode_bundle.cpp
index dce37836fb3187d496afe3dce909993d2ef731b5..19e8b410870b74dca053e92a50fad3b4ddc48666 100644 (file)
@@ -218,6 +218,25 @@ private:
     ld::Internal&                           _state;
 };
 
+#if LTO_API_VERSION >= 7
+static void ltoDiagnosticHandler(lto_codegen_diagnostic_severity_t severity, const char* message, void*)
+{
+    switch ( severity ) {
+#if LTO_API_VERSION >= 10
+        case LTO_DS_REMARK:
+#endif
+        case LTO_DS_NOTE:
+            break; // ignore remarks and notes
+        case LTO_DS_WARNING:
+            warning("%s", message);
+            break;
+        case LTO_DS_ERROR:
+            throwf("%s", message);
+    }
+}
+#endif
+
+
 BitcodeAtom::BitcodeAtom()
 : ld::Atom(bitcodeBundleSection,
            ld::Atom::definitionRegular, ld::Atom::combineNever,
@@ -285,6 +304,11 @@ BitcodeObfuscator::BitcodeObfuscator()
         _lto_get_asm_symbol_num == NULL || _lto_get_asm_symbol_name == NULL || ::lto_api_version() < 14 )
         throwf("loaded libLTO doesn't support -bitcode_hide_symbols: %s", ::lto_get_version());
     _obfuscator = ::lto_codegen_create_in_local_context();
+
+#if LTO_API_VERSION >= 7
+    lto_codegen_set_diagnostic_handler(_obfuscator, ltoDiagnosticHandler, NULL);
+#endif
+
   #if LTO_API_VERSION >= 14
     lto_codegen_set_should_internalize(_obfuscator, false);
   #endif
@@ -455,6 +479,7 @@ void BundleHandler::copyXARProp(xar_file_t src, xar_file_t dst)
              strcmp(key, "hide-symbols") == 0 ||
              strcmp(key, "platform") == 0 ||
              strcmp(key, "sdkversion") == 0 ||
+             strcmp(key, "swift-version") == 0 ||
              strcmp(key, "dylibs/lib") == 0 ||
              strcmp(key, "link-options/option") == 0 ) {
             xar_prop_create(dst, key, val);
@@ -657,10 +682,25 @@ void BitcodeBundle::doPass()
                 bh->populateMustPreserveSymbols(obfuscator);
                 handlerMap.emplace(std::string(f->path()), bh);
             } else if ( ld::LLVMBitcode* bitcode = dynamic_cast<ld::LLVMBitcode*>(f->getBitcode()) ) {
-                BitcodeHandler* bitcodeHandler = new BitcodeHandler((char*)bitcode->getContent(), bitcode->getSize());
-                bitcodeHandler->populateMustPreserveSymbols(obfuscator);
+                BitcodeHandler bitcodeHandler((char*)bitcode->getContent(), bitcode->getSize());
+                bitcodeHandler.populateMustPreserveSymbols(obfuscator);
             }
         }
+        // add must preserve symbols from lto input.
+        for ( auto &f : _state.ltoBitcodePath ) {
+            BitcodeTempFile ltoTemp(f.c_str(), false); // Keep the temp file because it needs to be read in later in the pass.
+            BitcodeHandler bitcodeHandler((char*)ltoTemp.getContent(), ltoTemp.getSize());
+            bitcodeHandler.populateMustPreserveSymbols(obfuscator);
+        }
+        // add must preserve symbols from compiler_rt input.
+        for ( auto &f : _state.filesFromCompilerRT ) {
+            std::vector<const char*> symbols;
+            if ( f->fileContent() && mach_o::relocatable::getNonLocalSymbols(f->fileContent(), symbols) ) {
+                for ( auto &sym : symbols)
+                    obfuscator->addMustPreserveSymbols(sym);
+            }
+        }
+
         // special symbols supplied by linker
         obfuscator->addMustPreserveSymbols("___dso_handle");
         obfuscator->addMustPreserveSymbols("__mh_execute_header");
@@ -762,26 +802,30 @@ void BitcodeBundle::doPass()
         }
     }
 
-    // Write merged LTO bitcode
+    // Write merged LTO bitcode files
     if ( !_state.ltoBitcodePath.empty() ) {
-        xar_file_t ltoFile = NULL;
-        BitcodeTempFile* ltoTemp = new BitcodeTempFile(_state.ltoBitcodePath.c_str(), !_options.saveTempFiles());
-        if ( _options.hideSymbols() ) {
+        int count = 0;
+        for (auto &path : _state.ltoBitcodePath) {
+          std::string xar_name = "lto.o." + std::to_string(count++);
+          xar_file_t ltoFile = NULL;
+          BitcodeTempFile* ltoTemp = new BitcodeTempFile(path.c_str(), !_options.saveTempFiles());
+          if ( _options.hideSymbols() ) {
             ld::Bitcode ltoBitcode(ltoTemp->getContent(), ltoTemp->getSize());
             char ltoTempFile[PATH_MAX];
             sprintf(ltoTempFile, "%s/lto.bc", tempdir);
-            obfuscator->bitcodeHideSymbols(&ltoBitcode, _state.ltoBitcodePath.c_str(), ltoTempFile);
+            obfuscator->bitcodeHideSymbols(&ltoBitcode, path.c_str(), ltoTempFile);
             BitcodeTempFile* ltoStrip = new BitcodeTempFile(ltoTempFile, !_options.saveTempFiles());
-            ltoFile = xar_add_frombuffer(x, NULL, "lto.o", (char*)ltoStrip->getContent(), ltoStrip->getSize());
+            ltoFile = xar_add_frombuffer(x, NULL, xar_name.c_str(), (char*)ltoStrip->getContent(), ltoStrip->getSize());
             delete ltoStrip;
-        } else {
-            ltoFile = xar_add_frombuffer(x, NULL, "lto.o", (char*)ltoTemp->getContent(), ltoTemp->getSize());
+          } else {
+            ltoFile = xar_add_frombuffer(x, NULL, xar_name.c_str(), (char*)ltoTemp->getContent(), ltoTemp->getSize());
+          }
+          if ( ltoFile == NULL )
+            throwf("could not add lto file %s to bitcode bundle", path.c_str());
+          if ( xar_prop_set(ltoFile, "file-type", "LTO") != 0 )
+            throwf("could not set bitcode property for %s in bitcode bundle", path.c_str());
+          delete ltoTemp;
         }
-        if ( ltoFile == NULL )
-            throwf("could not add lto file %s to bitcode bundle", _state.ltoBitcodePath.c_str());
-        if ( xar_prop_set(ltoFile, "file-type", "LTO") != 0 )
-            throwf("could not set bitcode property for %s in bitcode bundle", _state.ltoBitcodePath.c_str());
-        delete ltoTemp;
     }
 
     // Common LinkOptions
@@ -942,11 +986,19 @@ void BitcodeBundle::doPass()
     // Write SDK version
     if ( _options.sdkPaths().size() > 1 )
         throwf("only one -syslibroot is accepted for bitcode bundle");
-    if ( xar_prop_create((xar_file_t)linkXML, "platform", _options.getPlatformStr().c_str()) != 0 )
+    if ( xar_prop_create((xar_file_t)linkXML, "platform", _options.platforms().to_str().c_str()) != 0 )
         throwf("could not add platform name to bitcode bundle");
     if ( xar_prop_create((xar_file_t)linkXML, "sdkversion", _options.getSDKVersionStr().c_str()) != 0 )
         throwf("could not add SDK version to bitcode bundle");
 
+    // Write swift version into header
+    if (_state.swiftVersion != 0) {
+        char swiftVersion[64];
+        Options::userReadableSwiftVersion(_state.swiftVersion, swiftVersion);
+        if ( xar_prop_create((xar_file_t)linkXML, "swift-version", swiftVersion) )
+            throwf("could not add swift version to bitcode bundle");
+    }
+
     // Write dylibs
     char sdkRoot[PATH_MAX];
     if ( _options.sdkPaths().empty() || (realpath(_options.sdkPaths().front(), sdkRoot) == NULL) )
@@ -982,6 +1034,12 @@ void BitcodeBundle::doPass()
         }
     }
 
+    // Write if compiler_rt is force loaded
+    if (_state.forceLoadCompilerRT) {
+        if ( xar_prop_create((xar_file_t)linkXML, "rt-forceload", "1") != 0 )
+            throwf("could not add compiler_rt force_load info to bitcode bundle");
+    }
+
     // Write link-line into archive
     for ( auto &it : linkCmd ) {
         if (xar_prop_create((xar_file_t)linkXML, "link-options/option", it.c_str()) != 0)