]> git.saurik.com Git - apple/ld64.git/blobdiff - src/ld/InputFiles.cpp
ld64-409.12.tar.gz
[apple/ld64.git] / src / ld / InputFiles.cpp
index 1c69de62135e58464aca1c0174b4bfe09425485c..af66ec71994c2accc5c1a620774bc370a42ff85d 100644 (file)
@@ -214,6 +214,16 @@ const char* InputFiles::fileArch(const uint8_t* p, unsigned len)
 
 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);
@@ -238,11 +248,19 @@ ld::File* InputFiles::makeFile(const Options::FileInfo& info, bool indirectDylib
                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;
@@ -250,9 +268,10 @@ ld::File* InputFiles::makeFile(const Options::FileInfo& info, bool indirectDylib
                        }
                }
                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;
@@ -304,9 +323,11 @@ ld::File* InputFiles::makeFile(const Options::FileInfo& info, bool indirectDylib
        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();
@@ -418,7 +439,7 @@ ld::File* InputFiles::makeFile(const Options::FileInfo& info, bool indirectDylib
        }
        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);
        }
@@ -455,19 +476,19 @@ void InputFiles::logDylib(ld::File* file, bool indirect, bool speculative)
        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());
                }
        }
 }
@@ -620,13 +641,14 @@ void InputFiles::addLinkerOptionLibraries(ld::Internal& state, ld::File::AtomHan
                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);
@@ -635,14 +657,23 @@ void InputFiles::addLinkerOptionLibraries(ld::Internal& state, ld::File::AtomHan
                                                        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);
                }
 
@@ -653,11 +684,11 @@ void InputFiles::addLinkerOptionLibraries(ld::Internal& state, ld::File::AtomHan
                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);
@@ -671,8 +702,7 @@ void InputFiles::addLinkerOptionLibraries(ld::Internal& state, ld::File::AtomHan
                                        }
                                        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);
@@ -682,10 +712,11 @@ void InputFiles::addLinkerOptionLibraries(ld::Internal& state, ld::File::AtomHan
                                                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);
                }
        }
@@ -736,8 +767,7 @@ void InputFiles::createOpaqueFileSections()
        // 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);
        }
 
 }
@@ -845,9 +875,10 @@ void InputFiles::inferArchitecture(Options& opts, const char** archName)
                                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;
                                        }
@@ -859,11 +890,11 @@ void InputFiles::inferArchitecture(Options& opts, const char** archName)
        // 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
@@ -1199,8 +1230,7 @@ void InputFiles::forEachInitialAtom(ld::File::AtomHandler& handler, ld::Internal
                        {
                                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:
@@ -1220,8 +1250,7 @@ void InputFiles::forEachInitialAtom(ld::File::AtomHandler& handler, ld::Internal
                                        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:
@@ -1471,8 +1500,16 @@ void InputFiles::dylibs(ld::Internal& state)
        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)