]> git.saurik.com Git - apple/ld64.git/blobdiff - src/ld/ld.hpp
ld64-302.3.1.tar.gz
[apple/ld64.git] / src / ld / ld.hpp
index e297036efe41243d1241d73b821df7b860f64e51..5e9164f14953fcf3f6300c09b2aee7ed02957587 100644 (file)
@@ -93,7 +93,7 @@ public:
                
                Ordinal (uint64_t ordinal) : _ordinal(ordinal) {}
                
-               enum { kArgListPartition=0, kIndirectDylibPartition=1, kLTOPartition = 2, kLinkerOptionPartition = 2, InvalidParition=0xffff };
+               enum { kArgListPartition=0, kIndirectDylibPartition=1, kLTOPartition = 2, kLinkerOptionPartition = 3, InvalidParition=0xffff };
                Ordinal(uint16_t partition, uint16_t majorIndex, uint16_t minorIndex, uint16_t counter) {
                        _ordinal = ((uint64_t)partition<<48) | ((uint64_t)majorIndex<<32) | ((uint64_t)minorIndex<<16) | ((uint64_t)counter<<0);
                }
@@ -102,14 +102,14 @@ public:
                const uint16_t  majorIndex() const              { return (_ordinal>>32)&0xffff; }
                const uint16_t  minorIndex() const              { return (_ordinal>>16)&0xffff; }
                const uint16_t  counter() const                 { return (_ordinal>>00)&0xffff; }
-               
+
                const Ordinal nextMajorIndex()          const { assert(majorIndex() < 0xffff); return Ordinal(_ordinal+((uint64_t)1<<32)); }
                const Ordinal nextMinorIndex()          const { assert(minorIndex() < 0xffff); return Ordinal(_ordinal+((uint64_t)1<<16)); }
                const Ordinal nextCounter()             const { assert(counter() < 0xffff); return Ordinal(_ordinal+((uint64_t)1<<0)); }
                
        public:
                Ordinal() : _ordinal(0) {};
-               
+
                static const Ordinal NullOrdinal()              { return Ordinal((uint64_t)0); }
                
                const bool validOrdinal() const { return _ordinal != 0; }
@@ -126,7 +126,7 @@ public:
                // Thus, an object pulled in from a .a that was listed in a file list could use all three fields.
                static const Ordinal makeArgOrdinal(uint16_t argIndex) { return Ordinal(kArgListPartition, argIndex, 0, 0); };
                const Ordinal nextFileListOrdinal() const { return nextMinorIndex(); }
-               const Ordinal archiveOrdinalWithMemberIndex(uint16_t index) const { return Ordinal(kArgListPartition, majorIndex(), minorIndex(), index); }
+               const Ordinal archiveOrdinalWithMemberIndex(uint16_t memberIndex) const { return Ordinal(partition(), majorIndex(), minorIndex(), memberIndex); }
                
                // For indirect libraries the partition is IndirectDylibPartition and the counter is used or order the libraries.
                static const ld::File::Ordinal indirectDylibBase() { return Ordinal(kIndirectDylibPartition, 0, 0, 0); }
@@ -137,8 +137,8 @@ public:
 
                // For linker options embedded in object files
                static const ld::File::Ordinal linkeOptionBase() { return Ordinal(kIndirectDylibPartition, 1, 0, 0); }
-               const Ordinal nextLinkerOptionOrdinal() { nextCounter(); return *this; };
-               
+               const Ordinal nextLinkerOptionOrdinal() { return nextCounter(); };
+
        };
        
        typedef enum { Reloc, Dylib, Archive, Other } Type;
@@ -152,11 +152,12 @@ public:
        virtual bool                                            forEachAtom(AtomHandler&) const = 0;
        virtual bool                                            justInTimeforEachAtom(const char* name, AtomHandler&) const = 0;
        virtual ObjcConstraint                          objCConstraint() const                  { return objcConstraintNone; }
+    virtual bool                                               objcHasCategoryClassPropertiesField() const { return false; }
        virtual uint8_t                                         swiftVersion() const                    { return 0; }
        virtual uint32_t                                        cpuSubType() const              { return 0; }
        virtual uint32_t                                        subFileCount() const    { return 1; }
        virtual uint32_t                                        minOSVersion() const    { return 0; }
-       virtual uint32_t                                        platformLoadCommand() const             { return 0; }
+       virtual uint32_t                                        platform() const                { return 0; }
     bool                                                               fileExists() const     { return _modTime != 0; }
        Type                                                            type() const { return _type; }
        virtual Bitcode*                                        getBitcode() const              { return NULL; }
@@ -173,11 +174,11 @@ private:
 //
 enum MacVersionMin { macVersionUnset=0, mac10_4=0x000A0400, mac10_5=0x000A0500, 
                                                mac10_6=0x000A0600, mac10_7=0x000A0700, mac10_8=0x000A0800,
-                                               mac10_9=0x000A0900, mac10_Future=0x10000000 };
+                                               mac10_9=0x000A0900, mac10_12=0x000A0C00, mac10_Future=0x10000000 };
 enum IOSVersionMin { iOSVersionUnset=0, iOS_2_0=0x00020000, iOS_3_1=0x00030100, 
                                                iOS_4_2=0x00040200, iOS_4_3=0x00040300, iOS_5_0=0x00050000,
                                                iOS_6_0=0x00060000, iOS_7_0=0x00070000, iOS_8_0=0x00080000,
-                                               iOS_9_0=0x00090000, iOS_Future=0x10000000};
+                                               iOS_9_0=0x00090000, iOS_10_0=0x000A0000, iOS_Future=0x10000000};
 enum WatchOSVersionMin  { wOSVersionUnset=0, wOS_1_0=0x00010000, wOS_2_0=0x00020000 };
 
 
@@ -212,6 +213,7 @@ namespace relocatable {
                        const char*                     string;
                };
                typedef const std::vector< std::vector<const char*> > LinkerOptionsList;
+               typedef std::vector<std::pair<uint32_t,uint32_t>> ToolVersionList;
 
                                                                                        File(const char* pth, time_t modTime, Ordinal ord)
                                                                                                : ld::File(pth, modTime, ord, Reloc) { }
@@ -223,7 +225,9 @@ namespace relocatable {
                virtual bool                                            canScatterAtoms() const = 0;
                virtual bool                                            hasLongBranchStubs()            { return false; }
                virtual LinkerOptionsList*                      linkerOptions() const = 0;
+               virtual const ToolVersionList&          toolVersions() const = 0;
                virtual SourceKind                                      sourceKind() const { return kSourceUnknown; }
+               virtual const uint8_t*                          fileContent() const { return nullptr; }
        };
 } // namespace relocatable
 
@@ -242,16 +246,17 @@ namespace dylib {
                {
                public:
                        virtual                         ~DylibHandler() {}
-                       virtual File*           findDylib(const char* installPath, const char* fromPath) = 0;
+                       virtual File*           findDylib(const char* installPath, const ld::dylib::File* fromDylib, bool speculative) = 0;
                };
                        
                                                                                        File(const char* pth, time_t modTime, Ordinal ord)
-                                                                                               : ld::File(pth, modTime, ord, Dylib), _dylibInstallPath(NULL),
+                                                                                               : ld::File(pth, modTime, ord, Dylib), _dylibInstallPath(NULL), _frameworkName(NULL),
                                                                                                _dylibTimeStamp(0), _dylibCurrentVersion(0), _dylibCompatibilityVersion(0),
-                                                                                               _explicitlyLinked(false), _implicitlyLinked(false),
+                                                                                               _explicitlyLinked(false), _implicitlyLinked(false), _speculativelyLoaded(false),
                                                                                                _lazyLoadedDylib(false), _forcedWeakLinked(false), _reExported(false),
                                                                                                _upward(false), _dead(false) { }
                                const char*                                     installPath() const                     { return _dylibInstallPath; }
+                               const char*                                     frameworkName() const           { return _frameworkName; }
                                uint32_t                                        timestamp() const                       { return _dylibTimeStamp; }
                                uint32_t                                        currentVersion() const          { return _dylibCurrentVersion; }
                                uint32_t                                        compatibilityVersion() const{ return _dylibCompatibilityVersion; }
@@ -259,7 +264,9 @@ namespace dylib {
                                bool                                            explicitlyLinked() const        { return _explicitlyLinked; }
                                void                                            setImplicitlyLinked()           { _implicitlyLinked = true; }
                                bool                                            implicitlyLinked() const        { return _implicitlyLinked; }
-                               
+                               void                                            setSpeculativelyLoaded()        { _speculativelyLoaded = true; }
+                               bool                                            speculativelyLoaded() const     { return _speculativelyLoaded; }
+
                                // attributes of how dylib will be used when linked
                                void                                            setWillBeLazyLoadedDylb()               { _lazyLoadedDylib = true; }
                                bool                                            willBeLazyLoadedDylib() const   { return _lazyLoadedDylib; }
@@ -277,6 +284,7 @@ namespace dylib {
                virtual bool                                            providedExportAtom() const = 0;
                virtual const char*                                     parentUmbrella() const = 0;
                virtual const std::vector<const char*>* allowableClients() const = 0;
+               virtual const std::vector<const char*>& rpaths() const = 0;
                virtual bool                                            hasWeakExternals() const = 0;
                virtual bool                                            deadStrippable() const = 0;
                virtual bool                                            hasWeakDefinition(const char* name) const = 0;
@@ -285,18 +293,15 @@ namespace dylib {
                virtual bool                                            installPathVersionSpecific() const { return false; }
                virtual bool                                            appExtensionSafe() const = 0;
 
-       protected:
-               struct ReExportChain { ReExportChain* prev; const File* file; };
-               virtual std::pair<bool, bool>           hasWeakDefinitionImpl(const char* name) const = 0;
-               virtual bool                                            containsOrReExports(const char* name, bool& weakDef, bool& tlv, uint64_t& defAddress) const = 0;
-               virtual void                                            assertNoReExportCycles(ReExportChain*) const = 0;
-
+       public:
                const char*                                                     _dylibInstallPath;
+               const char*                                                     _frameworkName;
                uint32_t                                                        _dylibTimeStamp;
                uint32_t                                                        _dylibCurrentVersion;
                uint32_t                                                        _dylibCompatibilityVersion;
                bool                                                            _explicitlyLinked;
                bool                                                            _implicitlyLinked;
+               bool                                                            _speculativelyLoaded;
                bool                                                            _lazyLoadedDylib;
                bool                                                            _forcedWeakLinked;
                bool                                                            _reExported;
@@ -446,7 +451,7 @@ struct Fixup
                                        // data-in-code markers
                                        kindDataInCodeStartData, kindDataInCodeStartJT8, kindDataInCodeStartJT16, 
                                        kindDataInCodeStartJT32, kindDataInCodeStartJTA32, kindDataInCodeEnd,
-                                       // linker optimzation hints
+                                       // linker optimization hints
                                        kindLinkerOptimizationHint,
                                        // pointer store combinations
                                        kindStoreTargetAddressLittleEndian32,   // kindSetTargetAddress + kindStoreLittleEndian32
@@ -751,6 +756,9 @@ public:
        bool                                                                    finalAddressMode() const    { return (_mode == modeFinalAddress); }
 #endif
        virtual const File*                                             file() const = 0;
+       // Return the original file this atom belongs to, for instance for an LTO atom,
+       // file() would return the LTO MachO file instead of the original bitcode file.
+       virtual const ld::File*                             originalFile() const       { return file(); }
        virtual const char*                                             translationUnitSource() const { return NULL; }
        virtual const char*                                             name() const = 0;
        virtual uint64_t                                                objectAddress() const = 0;
@@ -781,6 +789,7 @@ public:
                                                                                                        _definition = a._definition;
                                                                                                        _combine = a._combine;
                                                                                                        _dontDeadStrip = a._dontDeadStrip;
+                                                                                                       _dontDeadStripIfRefLive = a._dontDeadStripIfRefLive;
                                                                                                        _thumb = a._thumb;
                                                                                                        _autoHide = a._autoHide;
                                                                                                        _contentType = a._contentType;
@@ -792,6 +801,14 @@ public:
                                                                                                        _weakImportState = a._weakImportState;
                                                                                                }
 
+       const char*                                                             safeFilePath() const {
+                                                                                               const File* f = this->file();
+                                                                                               if ( f != NULL )
+                                                                                                       return f->path();
+                                                                                               else
+                                                                                                       return "<internal>";
+                                                                                       }
+
 protected:
        enum AddressMode { modeSectionOffset, modeFinalAddress };
 
@@ -826,7 +843,7 @@ public:
 };
 
 
-       
+
 // utility classes for using std::unordered_map with c-strings
 struct CStringHash {
        size_t operator()(const char* __s) const {
@@ -887,16 +904,24 @@ public:
                                                                                        hasThreadLocalVariableDefinitions(false),
                                                                                        hasWeakExternalSymbols(false),
                                                                                        someObjectHasOptimizationHints(false),
-                                                                                       dropAllBitcode(false), embedMarkerOnly(false)   { }
+                                                                                       dropAllBitcode(false), embedMarkerOnly(false),
+                                                                                       forceLoadCompilerRT(false)      { }
 
        std::vector<FinalSection*>                                      sections;
        std::vector<ld::dylib::File*>                           dylibs;
+       std::vector<std::string>                                        archivePaths;
        std::vector<ld::relocatable::File::Stab>        stabs;
        AtomToSection                                                           atomToSection;          
+       CStringSet                                                                      unprocessedLinkerOptionLibraries;
+       CStringSet                                                                      unprocessedLinkerOptionFrameworks;
        CStringSet                                                                      linkerOptionLibraries;
        CStringSet                                                                      linkerOptionFrameworks;
        std::vector<const ld::Atom*>                            indirectBindingTable;
        std::vector<const ld::relocatable::File*>       filesWithBitcode;
+       std::vector<const ld::relocatable::File*>       filesFromCompilerRT;
+       std::vector<const ld::Atom*>                            deadAtoms;
+       std::unordered_set<const char*>                         allUndefProxies;
+       std::unordered_set<uint64_t>                            toolsVersions;
        const ld::dylib::File*                                          bundleLoader;
        const Atom*                                                                     entryPoint;
        const Atom*                                                                     classicBindingHelper;
@@ -907,7 +932,7 @@ public:
        uint8_t                                                                         swiftVersion;
        uint32_t                                                                        cpuSubType;
        uint32_t                                                                        minOSVersion;
-       uint32_t                                                                        derivedPlatformLoadCommand;
+       uint32_t                                                                        derivedPlatform;
        bool                                                                            objectFileFoundWithNoVersion;
        bool                                                                            allObjectFilesScatterable;
        bool                                                                            someObjectFileHasDwarf;
@@ -917,7 +942,8 @@ public:
        bool                                                                            someObjectHasOptimizationHints;
        bool                                                                            dropAllBitcode;
        bool                                                                            embedMarkerOnly;
-       std::string                                                                     ltoBitcodePath;
+       bool                                                                            forceLoadCompilerRT;
+       std::vector<std::string>                                        ltoBitcodePath;
 };