ld::File* InputFiles::makeFile(const Options::FileInfo& info, bool indirectDylib)
{
+ // handle inlined framework first.
+ if (info.isInlined) {
+ auto interface = _options.findTAPIFile(info.path);
+ if (!interface)
+ throwf("could not find inlined dylib file: %s", info.path);
+ auto file = textstub::dylib::parse(info.path, interface, info.modTime, info.ordinal, _options, indirectDylib);
+ if (!file)
+ throwf("could not parse inlined dylib file: %s(%s)", interface->getInstallName().c_str(), info.path);
+ return file;
+ }
// map in whole file
struct stat stat_buf;
int fd = ::open(info.path, O_RDONLY, 0);
const struct fat_arch* archs = (struct fat_arch*)(p + sizeof(struct fat_header));
bool sliceFound = false;
sliceCount = OSSwapBigToHostInt32(fh->nfat_arch);
- if ( _options.preferSubArchitecture() ) {
- // first try to find a slice that match cpu-type and cpu-sub-type
+ // first try to find a slice that match cpu-type and cpu-sub-type
+ for (uint32_t i=0; i < sliceCount; ++i) {
+ if ( (OSSwapBigToHostInt32(archs[i].cputype) == (uint32_t)_options.architecture())
+ && ((OSSwapBigToHostInt32(archs[i].cpusubtype) & ~CPU_SUBTYPE_MASK) == (uint32_t)_options.subArchitecture()) ) {
+ sliceToUse = i;
+ sliceFound = true;
+ break;
+ }
+ }
+ if ( !sliceFound && _options.allowSubArchitectureMismatches() ) {
+ // look for any slice that matches just cpu-type
for (uint32_t i=0; i < sliceCount; ++i) {
- if ( (OSSwapBigToHostInt32(archs[i].cputype) == (uint32_t)_options.architecture())
- && (OSSwapBigToHostInt32(archs[i].cpusubtype) == (uint32_t)_options.subArchitecture()) ) {
+ if ( OSSwapBigToHostInt32(archs[i].cputype) == (uint32_t)_options.architecture() ) {
sliceToUse = i;
sliceFound = true;
break;
}
}
if ( !sliceFound ) {
- // look for any slice that matches just cpu-type
- for (uint32_t i=0; i < sliceCount; ++i) {
- if ( OSSwapBigToHostInt32(archs[i].cputype) == (uint32_t)_options.architecture() ) {
+ // Look for a fallback slice.
+ for (uint32_t i = 0; i < sliceCount; ++i) {
+ if ( OSSwapBigToHostInt32(archs[i].cputype) == (uint32_t)_options.fallbackArchitecture() &&
+ OSSwapBigToHostInt32(archs[i].cpusubtype) == (uint32_t)_options.fallbackSubArchitecture() ) {
sliceToUse = i;
sliceFound = true;
break;
objOpts.armUsesZeroCostExceptions = _options.armUsesZeroCostExceptions();
objOpts.simulator = _options.targetIOSSimulator();
objOpts.ignoreMismatchPlatform = ((_options.outputKind() == Options::kPreload) || (_options.outputKind() == Options::kStaticExecutable));
+#if SUPPORT_ARCH_arm64e
+ objOpts.supportsAuthenticatedPointers = _options.supportsAuthenticatedPointers();
+#endif
objOpts.subType = _options.subArchitecture();
- objOpts.platform = _options.platform();
- objOpts.minOSVersion = _options.minOSversion();
+ objOpts.platforms = _options.platforms();
objOpts.srcKind = ld::relocatable::File::kSourceObj;
objOpts.treateBitcodeAsData = _options.bitcodeKind() == Options::kBitcodeAsData;
objOpts.usingBitcode = _options.bundleBitcode();
}
else {
if ( isFatFile )
- throwf("file is universal (%u slices) but does not contain a(n) %s slice: %s", sliceCount, _options.architectureName(), info.path);
+ throwf("file is universal (%u slices) but does not contain the %s architecture: %s", sliceCount, _options.architectureName(), info.path);
else
throwf("file was built for %s which is not the architecture being linked (%s): %s", fileArch(p, len), _options.architectureName(), info.path);
}
if ( _options.dumpDependencyInfo() ) {
const ld::dylib::File* dylib = dynamic_cast<const ld::dylib::File*>(file);
if ( file == _bundleLoader ) {
- _options.dumpDependency(Options::depBundleLoader, file->path());
+ _options.addDependency(Options::depBundleLoader, file->path());
}
else if ( (dylib != NULL ) && dylib->willBeUpwardDylib() ) {
if ( indirect )
- _options.dumpDependency(Options::depUpwardIndirectDylib, file->path());
+ _options.addDependency(Options::depUpwardIndirectDylib, file->path());
else
- _options.dumpDependency(Options::depUpwardDirectDylib, file->path());
+ _options.addDependency(Options::depUpwardDirectDylib, file->path());
}
else {
if ( indirect )
- _options.dumpDependency(Options::depIndirectDylib, file->path());
+ _options.addDependency(Options::depIndirectDylib, file->path());
else
- _options.dumpDependency(Options::depDirectDylib, file->path());
+ _options.addDependency(Options::depDirectDylib, file->path());
}
}
}
for (const char* frameworkName : newFrameworks) {
if ( state.linkerOptionFrameworks.count(frameworkName) )
continue;
- Options::FileInfo info = _options.findFramework(frameworkName);
- if ( ! this->frameworkAlreadyLoaded(info.path, frameworkName) ) {
- _linkerOptionOrdinal = _linkerOptionOrdinal.nextLinkerOptionOrdinal();
- info.ordinal = _linkerOptionOrdinal;
- try {
+ try {
+ Options::FileInfo info = _options.findFramework(frameworkName);
+ if ( ! this->frameworkAlreadyLoaded(info.path, frameworkName) ) {
+ _linkerOptionOrdinal = _linkerOptionOrdinal.nextLinkerOptionOrdinal();
+ info.ordinal = _linkerOptionOrdinal;
ld::File* reader = this->makeFile(info, true);
ld::dylib::File* dylibReader = dynamic_cast<ld::dylib::File*>(reader);
+ ld::archive::File* archiveReader = dynamic_cast<ld::archive::File*>(reader);
if ( dylibReader != NULL ) {
if ( ! dylibReader->installPathVersionSpecific() ) {
dylibReader->forEachAtom(handler);
this->addDylib(dylibReader, info);
}
}
+ else if ( archiveReader != NULL ) {
+ _searchLibraries.push_back(LibraryInfo(archiveReader));
+ _options.addDependency(Options::depArchive, archiveReader->path());
+ //<rdar://problem/17787306> -force_load_swift_libs
+ if (info.options.fForceLoad) {
+ archiveReader->forEachAtom(handler);
+ }
+ }
else {
- throwf("framework linker option at %s is not a dylib", info.path);
+ throwf("framework linker option at %s is not a dylib and not an archive", info.path);
}
}
- catch (const char* msg) {
- warning("Auto-Linking supplied '%s', %s", info.path, msg);
- }
}
+ catch (const char* msg) {
+ // <rdar://problem/40829444> only warn about missing auto-linked framework if some missing symbol error happens later
+ state.missingLinkerOptionFrameworks.insert(frameworkName);
+ }
state.linkerOptionFrameworks.insert(frameworkName);
}
for (const char* libName : newLibraries) {
if ( state.linkerOptionLibraries.count(libName) )
continue;
- Options::FileInfo info = _options.findLibrary(libName);
- if ( ! this->libraryAlreadyLoaded(info.path) ) {
- _linkerOptionOrdinal = _linkerOptionOrdinal.nextLinkerOptionOrdinal();
- info.ordinal = _linkerOptionOrdinal;
- try {
+ try {
+ Options::FileInfo info = _options.findLibrary(libName);
+ if ( ! this->libraryAlreadyLoaded(info.path) ) {
+ _linkerOptionOrdinal = _linkerOptionOrdinal.nextLinkerOptionOrdinal();
+ info.ordinal = _linkerOptionOrdinal;
//<rdar://problem/17787306> -force_load_swift_libs
info.options.fForceLoad = _options.forceLoadSwiftLibs() && (strncmp(libName, "swift", 5) == 0);
ld::File* reader = this->makeFile(info, true);
}
else if ( archiveReader != NULL ) {
_searchLibraries.push_back(LibraryInfo(archiveReader));
- if ( _options.dumpDependencyInfo() )
- _options.dumpDependency(Options::depArchive, archiveReader->path());
+ _options.addDependency(Options::depArchive, archiveReader->path());
//<rdar://problem/17787306> -force_load_swift_libs
if (info.options.fForceLoad) {
archiveReader->forEachAtom(handler);
throwf("linker option dylib at %s is not a dylib", info.path);
}
}
- catch (const char* msg) {
- warning("Auto-Linking supplied '%s', %s", info.path, msg);
- }
}
+ catch (const char* msg) {
+ // <rdar://problem/40829444> only warn about missing auto-linked library if some missing symbol error happens later
+ state.missingLinkerOptionLibraries.insert(libName);
+ }
state.linkerOptionLibraries.insert(libName);
}
}
// extra command line sections always at end
for (Options::ExtraSection::const_iterator it=_options.extraSectionsBegin(); it != _options.extraSectionsEnd(); ++it) {
_inputFiles.push_back(opaque_section::parse(it->segmentName, it->sectionName, it->path, it->data, it->dataLen));
- if ( _options.dumpDependencyInfo() )
- _options.dumpDependency(Options::depSection, it->path);
+ _options.addDependency(Options::depSection, it->path);
}
}
if ( amount >= readAmount ) {
cpu_type_t type;
cpu_subtype_t subtype;
- Options::Platform platform;
- if ( mach_o::relocatable::isObjectFile(buffer, &type, &subtype, &platform) ) {
- opts.setArchitecture(type, subtype, platform);
+ ld::Platform platform;
+ uint32_t minOsVersion;
+ if ( mach_o::relocatable::isObjectFile(buffer, &type, &subtype, &platform, &minOsVersion) ) {
+ opts.setArchitecture(type, subtype, platform, minOsVersion);
*archName = opts.architectureName();
return;
}
// no thin .o files found, so default to same architecture this tool was built as
warning("-arch not specified");
#if __i386__
- opts.setArchitecture(CPU_TYPE_I386, CPU_SUBTYPE_X86_ALL, Options::kPlatformOSX);
+ opts.setArchitecture(CPU_TYPE_I386, CPU_SUBTYPE_X86_ALL, ld::kPlatform_macOS, 0);
#elif __x86_64__
- opts.setArchitecture(CPU_TYPE_X86_64, CPU_SUBTYPE_X86_64_ALL, Options::kPlatformOSX);
+ opts.setArchitecture(CPU_TYPE_X86_64, CPU_SUBTYPE_X86_64_ALL, ld::kPlatform_macOS, 0);
#elif __arm__
- opts.setArchitecture(CPU_TYPE_ARM, CPU_SUBTYPE_ARM_V6, Options::kPlatformOSX);
+ opts.setArchitecture(CPU_TYPE_ARM, CPU_SUBTYPE_ARM_V6, ld::kPlatform_macOS, 0);
#else
#error unknown default architecture
#endif
{
ld::relocatable::File* reloc = (ld::relocatable::File*)file;
_options.snapshot().recordObjectFile(reloc->path());
- if ( _options.dumpDependencyInfo() )
- _options.dumpDependency(Options::depObjectFile, reloc->path());
+ _options.addDependency(Options::depObjectFile, reloc->path());
}
break;
case ld::File::Dylib:
state.forceLoadCompilerRT = true;
_searchLibraries.push_back(LibraryInfo(archive));
- if ( _options.dumpDependencyInfo() )
- _options.dumpDependency(Options::depArchive, archive->path());
+ _options.addDependency(Options::depArchive, archive->path());
}
break;
case ld::File::Other:
state.bundleLoader = _bundleLoader;
// <rdar://problem/10807040> give an error when -nostdlib is used and libSystem is missing
- if ( (state.dylibs.size() == 0) && _options.needsEntryPointLoadCommand() )
- throw "dynamic main executables must link with libSystem.dylib";
+ if ( (state.dylibs.size() == 0) && _options.needsEntryPointLoadCommand() ) {
+ // HACK until 39514191 is fixed
+ bool grandfather = false;
+ for (const File* inFile : _inputFiles) {
+ if ( strstr(inFile->path(), "exit-asm.o") != NULL )
+ grandfather = true;
+ }
+ if ( !grandfather )
+ throw "dynamic main executables must link with libSystem.dylib";
+ }
}
void InputFiles::archives(ld::Internal& state)