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,
_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
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);
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");
}
}
- // 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(<oBitcode, _state.ltoBitcodePath.c_str(), ltoTempFile);
+ obfuscator->bitcodeHideSymbols(<oBitcode, 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
// 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) )
}
}
+ // 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)