]> git.saurik.com Git - apple/ld64.git/blobdiff - src/ld/Resolver.cpp
ld64-351.8.tar.gz
[apple/ld64.git] / src / ld / Resolver.cpp
index 24af5f8083186ab3e993b7c33832c17a6cbe0299..51afe8dfca9b8ac3482228c50d9c347ff28abb2a 100644 (file)
@@ -51,7 +51,6 @@
 #include <AvailabilityMacros.h>
 
 #include "Options.h"
-
 #include "ld.hpp"
 #include "Bitcode.hpp"
 #include "InputFiles.h"
 #include "Resolver.h"
 #include "parsers/lto_file.h"
 
+#include "configure.h"
+
+#define VAL(x) #x
+#define STRINGIFY(x) VAL(x)
 
 namespace ld {
 namespace tool {
@@ -284,7 +287,7 @@ void Resolver::initializeState()
        
        _internal.cpuSubType = _options.subArchitecture();
        _internal.minOSVersion = _options.minOSversion();
-       _internal.derivedPlatformLoadCommand = 0;
+       _internal.derivedPlatform = 0;
        
        // In -r mode, look for -linker_option additions
        if ( _options.outputKind() == Options::kObjectFile ) {
@@ -293,6 +296,11 @@ void Resolver::initializeState()
                        doLinkerOption(*it, "command line");
                }
        }
+#ifdef LD64_VERSION_NUM
+       uint32_t packedNum = Options::parseVersionNumber32(STRINGIFY(LD64_VERSION_NUM));
+       uint64_t combined = (uint64_t)TOOL_LD << 32 | packedNum;
+       _internal.toolsVersions.insert(combined);
+#endif
 }
 
 void Resolver::buildAtomList()
@@ -366,6 +374,7 @@ void Resolver::doFile(const ld::File& file)
                                        // No bitcode section, figure out if the object file comes from LTO/compiler static library
                                        switch ( _options.platform() ) {
                                        case Options::kPlatformOSX:
+                                       case Options::kPlatform_bridgeOS:
                                        case Options::kPlatformUnknown:
                                                warning("all bitcode will be dropped because '%s' was built without bitcode. "
                                                                "You must rebuild it with bitcode enabled (Xcode setting ENABLE_BITCODE), obtain an updated library from the vendor, or disable bitcode for this target. ", file.path());
@@ -453,12 +462,22 @@ void Resolver::doFile(const ld::File& file)
                                Options::userReadableSwiftVersion(file.swiftVersion(), fileVersion);
                                Options::userReadableSwiftVersion(_internal.swiftVersion, otherVersion);
                                if ( file.swiftVersion() > _internal.swiftVersion ) {
-                                       throwf("%s compiled with newer version of Swift language (%s) than previous files (%s)", 
-                                                  file.path(), fileVersion, otherVersion);
+                                       if ( _options.warnOnSwiftABIVersionMismatches() ) {
+                                               warning("%s compiled with newer version of Swift language (%s) than previous files (%s)",
+                                                       file.path(), fileVersion, otherVersion);
+                                       } else {
+                                               throwf("%s compiled with newer version of Swift language (%s) than previous files (%s)",
+                                                      file.path(), fileVersion, otherVersion);
+                                       }
                                }
                                else {
-                                       throwf("%s compiled with older version of Swift language (%s) than previous files (%s)", 
-                                              file.path(), fileVersion, otherVersion);
+                                       if ( _options.warnOnSwiftABIVersionMismatches() ) {
+                                               warning("%s compiled with older version of Swift language (%s) than previous files (%s)",
+                                                       file.path(), fileVersion, otherVersion);
+                                       } else {
+                                               throwf("%s compiled with older version of Swift language (%s) than previous files (%s)",
+                                                      file.path(), fileVersion, otherVersion);
+                                       }
                                }
                        }
                }
@@ -470,19 +489,28 @@ void Resolver::doFile(const ld::File& file)
                // remember if any .o file did not have MH_SUBSECTIONS_VIA_SYMBOLS bit set
                if ( ! objFile->canScatterAtoms() )
                        _internal.allObjectFilesScatterable = false;
-       
+
+               // remember if building for profiling (so we don't warn about initializers)
+               if ( objFile->hasllvmProfiling() )
+                       _havellvmProfiling = true;
+
                // update minOSVersion off all .o files
                uint32_t objMinOS = objFile->minOSVersion();
                if ( !objMinOS )
                        _internal.objectFileFoundWithNoVersion = true;
-
-               uint32_t objPlatformLC = objFile->platformLoadCommand();
-               if ( (objPlatformLC != 0) && (_internal.derivedPlatformLoadCommand == 0) && (_options.outputKind() == Options::kObjectFile) )
-                       _internal.derivedPlatformLoadCommand = objPlatformLC;
-
                if ( (_options.outputKind() == Options::kObjectFile) && (objMinOS > _internal.minOSVersion) )
                        _internal.minOSVersion = objMinOS;
 
+               uint32_t objPlatform = objFile->platform();
+               if ( (objPlatform != 0) && (_options.outputKind() == Options::kObjectFile) && (_internal.derivedPlatform == 0)  )
+                       _internal.derivedPlatform = objPlatform;
+
+               // update set of known tools used
+               for (const std::pair<uint32_t,uint32_t>& entry : objFile->toolVersions()) {
+                       uint64_t combined = (uint64_t)entry.first << 32 | entry.second;
+                       _internal.toolsVersions.insert(combined);
+               }
+
                // update cpu-sub-type
                cpu_subtype_t nextObjectSubType = file.cpuSubType();
                switch ( _options.architecture() ) {
@@ -505,6 +533,19 @@ void Resolver::doFile(const ld::File& file)
                                }
                                break;
                        
+                       case CPU_TYPE_ARM64:
+                               if ( _options.subArchitecture() != nextObjectSubType ) {
+                                       if ( _options.allowSubArchitectureMismatches() ) {
+                                               warning("object file %s was built for different arm64 sub-type (%d) than link command line (%d)",
+                                                       file.path(), nextObjectSubType, _options.subArchitecture());
+                                       }
+                                       else {
+                                               throwf("object file %s was built for different arm64 sub-type (%d) than link command line (%d)",
+                                                       file.path(), nextObjectSubType, _options.subArchitecture());
+                                       }
+                               }
+                               break;
+
                        case CPU_TYPE_I386:
                                _internal.cpuSubType = CPU_SUBTYPE_I386_ALL;
                                break;
@@ -547,6 +588,7 @@ void Resolver::doFile(const ld::File& file)
                                         strncmp(tcLibPath, tempPath, strlen(tcLibPath)) != 0 ) {
                                        switch ( _options.platform() ) {
                                        case Options::kPlatformOSX:
+                                       case Options::kPlatform_bridgeOS:
                                        case Options::kPlatformUnknown:
                                                warning("all bitcode will be dropped because '%s' was built without bitcode. "
                                                                "You must rebuild it with bitcode enabled (Xcode setting ENABLE_BITCODE), obtain an updated library from the vendor, or disable bitcode for this target.", file.path());
@@ -624,12 +666,22 @@ void Resolver::doFile(const ld::File& file)
                                Options::userReadableSwiftVersion(file.swiftVersion(), fileVersion);
                                Options::userReadableSwiftVersion(_internal.swiftVersion, otherVersion);
                                if ( file.swiftVersion() > _internal.swiftVersion ) {
-                                       throwf("%s compiled with newer version of Swift language (%s) than previous files (%s)", 
-                                                  file.path(), fileVersion, otherVersion);
+                                       if ( _options.warnOnSwiftABIVersionMismatches() ) {
+                                               warning("%s compiled with newer version of Swift language (%s) than previous files (%s)",
+                                                       file.path(), fileVersion, otherVersion);
+                                       } else {
+                                               throwf("%s compiled with newer version of Swift language (%s) than previous files (%s)",
+                                                      file.path(), fileVersion, otherVersion);
+                                       }
                                }
                                else {
-                                       throwf("%s compiled with older version of Swift language (%s) than previous files (%s)", 
-                                              file.path(), fileVersion, otherVersion);
+                                       if ( _options.warnOnSwiftABIVersionMismatches() ) {
+                                               warning("%s compiled with older version of Swift language (%s) than previous files (%s)",
+                                                       file.path(), fileVersion, otherVersion);
+                                       } else {
+                                               throwf("%s compiled with older version of Swift language (%s) than previous files (%s)",
+                                                      file.path(), fileVersion, otherVersion);
+                                       }
                                }
                        }
                }
@@ -766,6 +818,19 @@ void Resolver::doAtom(const ld::Atom& atom)
        if ( atom.section().type() == ld::Section::typeTempAlias )
                _haveAliases = true;
        
+       // error or warn about initializers
+       if ( (atom.section().type() == ld::Section::typeInitializerPointers) && !_havellvmProfiling ) {
+               switch ( _options.initializersTreatment() ) {
+                       case Options::kError:
+                               throwf("static initializer found in '%s'",atom.safeFilePath());
+                       case Options::kWarning:
+                               warning("static initializer found in '%s'. Use -no_inits to make this an error.  Use -no_warn_inits to suppress warning",atom.safeFilePath());
+                               break;
+                       default:
+                               break;
+               }
+       }
+       
        if ( _options.deadCodeStrip() ) {
                // add to set of dead-strip-roots, all symbols that the compiler marks as don't strip
                if ( atom.dontDeadStrip() )
@@ -1799,7 +1864,7 @@ void Resolver::linkTimeOptimize()
                // and re-compute dead code
                this->deadStripOptimize(true);
        }
-       
+
        // <rdar://problem/12386559> if -exported_symbols_list on command line, re-force scope
        if ( _options.hasExportMaskList() ) {
                for (std::vector<const ld::Atom*>::const_iterator it=_atoms.begin(); it != _atoms.end(); ++it) {
@@ -1823,6 +1888,23 @@ void Resolver::linkTimeOptimize()
 
                // check new code does not override some dylib
                this->checkDylibSymbolCollisions();
+
+               // <rdar://problem/33853815> remove undefs from LTO objects that gets optimized away
+               std::unordered_set<const ld::Atom*> mustPreserve;
+               if ( _internal.classicBindingHelper != NULL )
+                       mustPreserve.insert(_internal.classicBindingHelper);
+               if ( _internal.compressedFastBinderProxy != NULL )
+                       mustPreserve.insert(_internal.compressedFastBinderProxy);
+               if ( _internal.lazyBindingHelper != NULL )
+                       mustPreserve.insert(_internal.lazyBindingHelper);
+               if ( const ld::Atom* entry = this->entryPoint(true) )
+                       mustPreserve.insert(entry);
+               for (Options::UndefinesIterator uit=_options.initialUndefinesBegin(); uit != _options.initialUndefinesEnd(); ++uit) {
+                       SymbolTable::IndirectBindingSlot slot = _symbolTable.findSlotForName(*uit);
+                       if ( _internal.indirectBindingTable[slot] != NULL )
+                               mustPreserve.insert(_internal.indirectBindingTable[slot]);
+               }
+               _symbolTable.removeDeadUndefs(_atoms, mustPreserve);
        }
 }