File(const uint8_t* fileContent, uint64_t fileLength, const char* path,
time_t mTime, ld::File::Ordinal ordinal, bool linkingFlatNamespace,
bool linkingMainExecutable, bool hoistImplicitPublicDylibs,
- Options::Platform platform, uint32_t linkMinOSVersion, bool allowSimToMacOSX,
- bool addVers, bool buildingForSimulator,
+ Options::Platform platform, uint32_t linkMinOSVersion, bool allowWeakImports,
+ bool allowSimToMacOSX, bool addVers, bool buildingForSimulator,
bool logAllFiles, const char* installPath,
bool indirectDylib, bool ignoreMismatchPlatform, bool usingBitcode);
virtual ~File() noexcept {}
private:
using P = typename A::P;
using E = typename A::P::E;
+ using pint_t = typename A::P::uint_t;
void addDyldFastStub();
void buildExportHashTableFromExportInfo(const macho_dyld_info_command<P>* dyldInfo,
void buildExportHashTableFromSymbolTable(const macho_dysymtab_command<P>* dynamicInfo,
const macho_nlist<P>* symbolTable, const char* strings,
const uint8_t* fileContent);
+ void addSymbol(const char* name, bool weakDef = false, bool tlv = false, pint_t address = 0);
static const char* objCInfoSegmentName();
static const char* objCInfoSectionName();
template <typename A>
File<A>::File(const uint8_t* fileContent, uint64_t fileLength, const char* path, time_t mTime,
ld::File::Ordinal ord, bool linkingFlatNamespace, bool linkingMainExecutable,
- bool hoistImplicitPublicDylibs, Options::Platform platform, uint32_t linkMinOSVersion,
+ bool hoistImplicitPublicDylibs, Options::Platform platform, uint32_t linkMinOSVersion, bool allowWeakImports,
bool allowSimToMacOSX, bool addVers, bool buildingForSimulator, bool logAllFiles,
const char* targetInstallPath, bool indirectDylib, bool ignoreMismatchPlatform, bool usingBitcode)
- : Base(strdup(path), mTime, ord, platform, linkMinOSVersion, linkingFlatNamespace,
- hoistImplicitPublicDylibs, allowSimToMacOSX, addVers), _fileLength(fileLength), _linkeditStartOffset(0)
+ : Base(strdup(path), mTime, ord, platform, linkMinOSVersion, allowWeakImports, linkingFlatNamespace,
+ hoistImplicitPublicDylibs, allowSimToMacOSX, addVers), _fileLength(fileLength), _linkeditStartOffset(0)
{
const macho_header<P>* header = (const macho_header<P>*)fileContent;
const uint32_t cmd_count = header->ncmds();
// <rdar://problem/20627554> Don't hoist "public" (in /usr/lib/) dylibs that should not be directly linked
this->_hasPublicInstallName = false;
break;
+ case LC_RPATH:
+ this->_rpaths.push_back(strdup(((macho_rpath_command<P>*)cmd)->path()));
+ break;
case LC_VERSION_MIN_MACOSX:
case LC_VERSION_MIN_IPHONEOS:
case LC_VERSION_MIN_WATCHOS:
}
}
+template <typename A>
+void File<A>::addSymbol(const char* name, bool weakDef, bool tlv, pint_t address)
+{
+ // symbols that start with $ld$ are meta-data to the static linker
+ // <rdar://problem/5182537> need way for ld and dyld to see different exported symbols in a dylib
+ if ( strncmp(name, "$ld$", 4) == 0 ) {
+ // $ld$ <action> $ <condition> $ <symbol-name>
+ const char* symAction = &name[4];
+ const char* symCond = strchr(symAction, '$');
+ if ( symCond != nullptr ) {
+ char curOSVers[16];
+ sprintf(curOSVers, "$os%d.%d$", (this->_linkMinOSVersion >> 16), ((this->_linkMinOSVersion >> 8) & 0xFF));
+ if ( strncmp(symCond, curOSVers, strlen(curOSVers)) == 0 ) {
+ const char* symName = strchr(&symCond[1], '$');
+ if ( symName != nullptr ) {
+ ++symName;
+ if ( strncmp(symAction, "hide$", 5) == 0 ) {
+ if ( this->_s_logHashtable )
+ fprintf(stderr, " adding %s to ignore set for %s\n", symName, this->path());
+ this->_ignoreExports.insert(strdup(symName));
+ return;
+ }
+ else if ( strncmp(symAction, "add$", 4) == 0 ) {
+ this->addSymbol(symName, weakDef);
+ return;
+ }
+ else if ( strncmp(symAction, "weak$", 5) == 0 ) {
+ if ( !this->_allowWeakImports )
+ this->_ignoreExports.insert(strdup(symName));
+ }
+ else if ( strncmp(symAction, "install_name$", 13) == 0 ) {
+ this->_dylibInstallPath = symName;
+ this->_installPathOverride = true;
+ // <rdar://problem/14448206> CoreGraphics redirects to ApplicationServices, but with wrong compat version
+ if ( strcmp(this->_dylibInstallPath, "/System/Library/Frameworks/ApplicationServices.framework/Versions/A/ApplicationServices") == 0 )
+ this->_dylibCompatibilityVersion = Options::parseVersionNumber32("1.0");
+ return;
+ }
+ else if ( strncmp(symAction, "compatibility_version$", 22) == 0 ) {
+ this->_dylibCompatibilityVersion = Options::parseVersionNumber32(symName);
+ return;
+ }
+ else {
+ warning("bad symbol action: %s in dylib %s", name, this->path());
+ }
+ }
+ }
+ }
+ else {
+ warning("bad symbol condition: %s in dylib %s", name, this->path());
+ }
+ }
+
+ // add symbol as possible export if we are not supposed to ignore it
+ if ( this->_ignoreExports.count(name) == 0 ) {
+ typename Base::AtomAndWeak bucket = { nullptr, weakDef, tlv, address };
+ if ( this->_s_logHashtable )
+ fprintf(stderr, " adding %s to hash table for %s\n", name, this->path());
+ this->_atoms[strdup(name)] = bucket;
+ }
+}
template <>
void File<x86_64>::addDyldFastStub()
{
return new File<A>(fileContent, fileLength, path, mTime, ordinal, opts.flatNamespace(),
opts.linkingMainExecutable(), opts.implicitlyLinkIndirectPublicDylibs(),
- opts.platform(), opts.minOSversion(),
+ opts.platform(), opts.minOSversion(), opts.allowWeakImports(),
opts.allowSimulatorToLinkWithMacOSX(), opts.addVersionLoadCommand(),
opts.targetIOSSimulator(), opts.logAllFiles(), opts.installPath(),
indirectDylib, opts.outputKind() == Options::kPreload, opts.bundleBitcode());
}
#endif
+
//
// used by linker is error messages to describe mismatched files
//