]> git.saurik.com Git - apple/ld64.git/blobdiff - src/ld/ld.hpp
ld64-253.9.tar.gz
[apple/ld64.git] / src / ld / ld.hpp
index c33bff681bdac0af35617dd5fdd0457c8670c9fd..e297036efe41243d1241d73b821df7b860f64e51 100644 (file)
 #include <unistd.h>
 #include <assert.h>
 
-#include <vector>
 #include <set>
+#include <map>
+#include <vector>
+#include <string>
+#include <unordered_set>
 
+#include "configure.h"
 
 namespace ld {
 
+// Forward declaration for bitcode support
+class Bitcode;
+
 //
 // ld::File 
 //
@@ -51,7 +58,9 @@ namespace ld {
 class File
 {
 public:
-       enum ObjcConstraint { objcConstraintNone, objcConstraintRetainRelease, objcConstraintRetainReleaseOrGC, objcConstraintGC };
+       enum ObjcConstraint { objcConstraintNone, objcConstraintRetainRelease, 
+                                                       objcConstraintRetainReleaseOrGC, objcConstraintGC,
+                                                       objcConstraintRetainReleaseForSimulator };
        
        class AtomHandler {
        public:
@@ -84,7 +93,7 @@ public:
                
                Ordinal (uint64_t ordinal) : _ordinal(ordinal) {}
                
-               enum { ArgListPartition=0, IndirectDylibPartition=1, LTOPartition = 2, InvalidParition=0xffff };
+               enum { kArgListPartition=0, kIndirectDylibPartition=1, kLTOPartition = 2, kLinkerOptionPartition = 2, 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);
                }
@@ -115,16 +124,21 @@ public:
                // The minorIndex is used for files pulled in by a file list and the value is the index of the file in the file list.
                // The counter is used for .a files and the value is the index of the object in the archive.
                // 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(ArgListPartition, argIndex, 0, 0); };
+               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(ArgListPartition, majorIndex(), minorIndex(), index); }
+               const Ordinal archiveOrdinalWithMemberIndex(uint16_t index) const { return Ordinal(kArgListPartition, majorIndex(), minorIndex(), index); }
                
                // For indirect libraries the partition is IndirectDylibPartition and the counter is used or order the libraries.
-               static const ld::File::Ordinal indirectDylibBase() { return Ordinal(IndirectDylibPartition, 0, 0, 0); }
+               static const ld::File::Ordinal indirectDylibBase() { return Ordinal(kIndirectDylibPartition, 0, 0, 0); }
                const Ordinal nextIndirectDylibOrdinal() const { return nextCounter(); }
                
                // For the LTO mach-o the partition is LTOPartition. As there is only one LTO file no other fields are needed.
-               static const ld::File::Ordinal LTOOrdinal()                     { return Ordinal(LTOPartition, 0, 0, 0); }
+               static const ld::File::Ordinal LTOOrdinal()                     { return Ordinal(kLTOPartition, 0, 0, 0); }
+
+               // 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; };
+               
        };
        
        typedef enum { Reloc, Dylib, Archive, Other } Type;
@@ -138,10 +152,14 @@ public:
        virtual bool                                            forEachAtom(AtomHandler&) const = 0;
        virtual bool                                            justInTimeforEachAtom(const char* name, AtomHandler&) const = 0;
        virtual ObjcConstraint                          objCConstraint() const                  { return objcConstraintNone; }
+       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; }
     bool                                                               fileExists() const     { return _modTime != 0; }
        Type                                                            type() const { return _type; }
+       virtual Bitcode*                                        getBitcode() const              { return NULL; }
 private:
        const char*                                                     _path;
        time_t                                                          _modTime;
@@ -155,11 +173,14 @@ private:
 //
 enum MacVersionMin { macVersionUnset=0, mac10_4=0x000A0400, mac10_5=0x000A0500, 
                                                mac10_6=0x000A0600, mac10_7=0x000A0700, mac10_8=0x000A0800,
-                                               mac10_Future=0x10000000 };
+                                               mac10_9=0x000A0900, 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_Future=0x10000000};
+                                               iOS_6_0=0x00060000, iOS_7_0=0x00070000, iOS_8_0=0x00080000,
+                                               iOS_9_0=0x00090000, iOS_Future=0x10000000};
+enum WatchOSVersionMin  { wOSVersionUnset=0, wOS_1_0=0x00010000, wOS_2_0=0x00020000 };
+
+
 namespace relocatable {
        //
        // ld::relocatable::File 
@@ -181,6 +202,7 @@ namespace relocatable {
        {
        public:
                enum DebugInfoKind { kDebugInfoNone=0, kDebugInfoStabs=1, kDebugInfoDwarf=2, kDebugInfoStabsUUID=3 };
+               enum SourceKind { kSourceUnknown=0, kSourceObj, kSourceLTO, kSourceArchive, kSourceCompilerArchive };
                struct Stab {
                        const class Atom*       atom;
                        uint8_t                         type;
@@ -189,6 +211,7 @@ namespace relocatable {
                        uint32_t                        value;
                        const char*                     string;
                };
+               typedef const std::vector< std::vector<const char*> > LinkerOptionsList;
 
                                                                                        File(const char* pth, time_t modTime, Ordinal ord)
                                                                                                : ld::File(pth, modTime, ord, Reloc) { }
@@ -199,6 +222,8 @@ namespace relocatable {
                virtual const std::vector<Stab>*        stabs() const = 0;
                virtual bool                                            canScatterAtoms() const = 0;
                virtual bool                                            hasLongBranchStubs()            { return false; }
+               virtual LinkerOptionsList*                      linkerOptions() const = 0;
+               virtual SourceKind                                      sourceKind() const { return kSourceUnknown; }
        };
 } // namespace relocatable
 
@@ -257,8 +282,15 @@ namespace dylib {
                virtual bool                                            hasWeakDefinition(const char* name) const = 0;
                virtual bool                                            hasPublicInstallName() const = 0;
                virtual bool                                            allSymbolsAreWeakImported() const = 0;
-               virtual const void*                                     codeSignatureDR() const = 0;
+               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;
+
                const char*                                                     _dylibInstallPath;
                uint32_t                                                        _dylibTimeStamp;
                uint32_t                                                        _dylibCurrentVersion;
@@ -298,14 +330,14 @@ class Section
 {
 public:
        enum Type { typeUnclassified, typeCode, typePageZero, typeImportProxies, typeLinkEdit, typeMachHeader, typeStack,
-                               typeLiteral4, typeLiteral8, typeLiteral16, typeConstants, typeTempLTO, 
+                               typeLiteral4, typeLiteral8, typeLiteral16, typeConstants, typeTempLTO, typeTempAlias,
                                typeCString, typeNonStdCString, typeCStringPointer, typeUTF16Strings, typeCFString, typeObjC1Classes,
                                typeCFI, typeLSDA, typeDtraceDOF, typeUnwindInfo, typeObjCClassRefs, typeObjC2CategoryList,
                                typeZeroFill, typeTentativeDefs, typeLazyPointer, typeStub, typeNonLazyPointer, typeDyldInfo, 
                                typeLazyDylibPointer, typeStubHelper, typeInitializerPointers, typeTerminatorPointers,
                                typeStubClose, typeLazyPointerClose, typeAbsoluteSymbols, 
                                typeTLVDefs, typeTLVZeroFill, typeTLVInitialValues, typeTLVInitializerPointers, typeTLVPointers,
-                               typeFirstSection, typeLastSection, typeDebug };
+                               typeFirstSection, typeLastSection, typeDebug, typeSectCreate };
 
 
                                        Section(const char* sgName, const char* sctName,
@@ -391,16 +423,31 @@ struct Fixup
                                        kindStoreARMLoad12,
                                        kindStoreARMLow16, kindStoreARMHigh16, 
                                        kindStoreThumbLow16, kindStoreThumbHigh16, 
+#if SUPPORT_ARCH_arm64
+                                       // ARM64 specific store kinds
+                                       kindStoreARM64Branch26,  
+                                       kindStoreARM64Page21, kindStoreARM64PageOff12,
+                                       kindStoreARM64GOTLoadPage21, kindStoreARM64GOTLoadPageOff12,
+                                       kindStoreARM64GOTLeaPage21, kindStoreARM64GOTLeaPageOff12,
+                                       kindStoreARM64TLVPLoadPage21, kindStoreARM64TLVPLoadPageOff12,
+                                       kindStoreARM64TLVPLoadNowLeaPage21, kindStoreARM64TLVPLoadNowLeaPageOff12,
+                                       kindStoreARM64PointerToGOT, kindStoreARM64PCRelToGOT,
+#endif
                                        // dtrace probes
                                        kindDtraceExtra,
                                        kindStoreX86DtraceCallSiteNop, kindStoreX86DtraceIsEnableSiteClear,
                                        kindStoreARMDtraceCallSiteNop, kindStoreARMDtraceIsEnableSiteClear,
+                                       kindStoreARM64DtraceCallSiteNop, kindStoreARM64DtraceIsEnableSiteClear,
                                        kindStoreThumbDtraceCallSiteNop, kindStoreThumbDtraceIsEnableSiteClear,
                                        // lazy binding
                                        kindLazyTarget, kindSetLazyOffset,
+                                       // islands
+                                       kindIslandTarget,
                                        // data-in-code markers
                                        kindDataInCodeStartData, kindDataInCodeStartJT8, kindDataInCodeStartJT16, 
                                        kindDataInCodeStartJT32, kindDataInCodeStartJTA32, kindDataInCodeEnd,
+                                       // linker optimzation hints
+                                       kindLinkerOptimizationHint,
                                        // pointer store combinations
                                        kindStoreTargetAddressLittleEndian32,   // kindSetTargetAddress + kindStoreLittleEndian32
                                        kindStoreTargetAddressLittleEndian64,   // kindSetTargetAddress + kindStoreLittleEndian64
@@ -421,6 +468,20 @@ struct Fixup
                                        kindStoreTargetAddressARMBranch24,              // kindSetTargetAddress + kindStoreARMBranch24
                                        kindStoreTargetAddressThumbBranch22,    // kindSetTargetAddress + kindStoreThumbBranch22
                                        kindStoreTargetAddressARMLoad12,                // kindSetTargetAddress + kindStoreARMLoad12
+#if SUPPORT_ARCH_arm64
+                                       // ARM64 value calculation and store combinations
+                                       kindStoreTargetAddressARM64Branch26,            // kindSetTargetAddress + kindStoreARM64Branch26
+                                       kindStoreTargetAddressARM64Page21,                      // kindSetTargetAddress + kindStoreARM64Page21
+                                       kindStoreTargetAddressARM64PageOff12,           // kindSetTargetAddress + kindStoreARM64PageOff12
+                                       kindStoreTargetAddressARM64GOTLoadPage21,       // kindSetTargetAddress + kindStoreARM64GOTLoadPage21
+                                       kindStoreTargetAddressARM64GOTLoadPageOff12,// kindSetTargetAddress + kindStoreARM64GOTLoadPageOff12
+                                       kindStoreTargetAddressARM64GOTLeaPage21,        // kindSetTargetAddress + kindStoreARM64GOTLeaPage21
+                                       kindStoreTargetAddressARM64GOTLeaPageOff12,     // kindSetTargetAddress + kindStoreARM64GOTLeaPageOff12
+                                       kindStoreTargetAddressARM64TLVPLoadPage21,      // kindSetTargetAddress + kindStoreARM64TLVPLoadPage21
+                                       kindStoreTargetAddressARM64TLVPLoadPageOff12,// kindSetTargetAddress + kindStoreARM64TLVPLoadPageOff12
+                                       kindStoreTargetAddressARM64TLVPLoadNowLeaPage21,        // kindSetTargetAddress + kindStoreARM64TLVPLoadNowLeaPage21
+                                       kindStoreTargetAddressARM64TLVPLoadNowLeaPageOff12,     // kindSetTargetAddress + kindStoreARM64TLVPLoadNowLeaPageOff12
+#endif
                        };
 
        union {
@@ -436,54 +497,70 @@ struct Fixup
        TargetBinding   binding : 3;
        bool                    contentAddendOnly : 1;
        bool                    contentDetlaToAddendOnly : 1;
+       bool                    contentIgnoresAddend : 1;
        
        typedef Fixup*          iterator;
 
        Fixup() :
                offsetInAtom(0), kind(kindNone), clusterSize(k1of1), weakImport(false), 
                binding(bindingNone),  
-               contentAddendOnly(false), contentDetlaToAddendOnly(false) { u.target = NULL; }
+               contentAddendOnly(false), contentDetlaToAddendOnly(false), contentIgnoresAddend(false) { u.target = NULL; }
 
        Fixup(Kind k, Atom* targetAtom) :
                offsetInAtom(0), kind(k), clusterSize(k1of1), weakImport(false), 
                binding(Fixup::bindingDirectlyBound),  
-               contentAddendOnly(false), contentDetlaToAddendOnly(false)  
+               contentAddendOnly(false), contentDetlaToAddendOnly(false), contentIgnoresAddend(false)  
                        { assert(targetAtom != NULL); u.target = targetAtom; }
 
        Fixup(uint32_t off, Cluster c, Kind k) :
                offsetInAtom(off), kind(k), clusterSize(c), weakImport(false), 
                binding(Fixup::bindingNone),  
-               contentAddendOnly(false), contentDetlaToAddendOnly(false)  
+               contentAddendOnly(false), contentDetlaToAddendOnly(false), contentIgnoresAddend(false)  
                        { u.addend = 0; }
 
        Fixup(uint32_t off, Cluster c, Kind k, bool weakIm, const char* name) :
                offsetInAtom(off), kind(k), clusterSize(c), weakImport(weakIm), 
                binding(Fixup::bindingByNameUnbound),  
-               contentAddendOnly(false), contentDetlaToAddendOnly(false) 
+               contentAddendOnly(false), contentDetlaToAddendOnly(false), contentIgnoresAddend(false) 
                        { assert(name != NULL); u.name = name; }
                
        Fixup(uint32_t off, Cluster c, Kind k, TargetBinding b, const char* name) :
                offsetInAtom(off), kind(k), clusterSize(c), weakImport(false), binding(b),  
-               contentAddendOnly(false), contentDetlaToAddendOnly(false) 
+               contentAddendOnly(false), contentDetlaToAddendOnly(false), contentIgnoresAddend(false) 
                        { assert(name != NULL); u.name = name; }
                
        Fixup(uint32_t off, Cluster c, Kind k, const Atom* targetAtom) :
                offsetInAtom(off), kind(k), clusterSize(c), weakImport(false), 
                binding(Fixup::bindingDirectlyBound),  
-               contentAddendOnly(false), contentDetlaToAddendOnly(false) 
+               contentAddendOnly(false), contentDetlaToAddendOnly(false), contentIgnoresAddend(false) 
                        { assert(targetAtom != NULL); u.target = targetAtom; }
                
        Fixup(uint32_t off, Cluster c, Kind k, TargetBinding b, const Atom* targetAtom) :
                offsetInAtom(off), kind(k), clusterSize(c), weakImport(false), binding(b),  
-               contentAddendOnly(false), contentDetlaToAddendOnly(false) 
+               contentAddendOnly(false), contentDetlaToAddendOnly(false), contentIgnoresAddend(false) 
                        { assert(targetAtom != NULL); u.target = targetAtom; }
                
        Fixup(uint32_t off, Cluster c, Kind k, uint64_t addend) :
                offsetInAtom(off), kind(k), clusterSize(c), weakImport(false), 
                binding(Fixup::bindingNone),  
-               contentAddendOnly(false), contentDetlaToAddendOnly(false) 
+               contentAddendOnly(false), contentDetlaToAddendOnly(false), contentIgnoresAddend(false) 
                        { u.addend = addend; }
                        
+       Fixup(Kind k, uint32_t lohKind, uint32_t off1, uint32_t off2) :
+               offsetInAtom(off1), kind(k), clusterSize(k1of1),  
+               weakImport(false), binding(Fixup::bindingNone), contentAddendOnly(false), 
+               contentDetlaToAddendOnly(false), contentIgnoresAddend(false) {
+                       assert(k == kindLinkerOptimizationHint);
+                       LOH_arm64 extra;
+                       extra.addend = 0;
+                       extra.info.kind = lohKind;
+                       extra.info.count = 1;
+                       extra.info.delta1 = 0;
+                       extra.info.delta2 = (off2 - off1) >> 2;
+                       u.addend = extra.addend; 
+               }
+                       
+
        bool firstInCluster() const { 
                switch (clusterSize) {
                        case k1of1:
@@ -512,6 +589,18 @@ struct Fixup
                return false;
        }
        
+       union LOH_arm64 {
+               uint64_t        addend;
+               struct {
+                       unsigned        kind    :  6,
+                                               count   :  2,   // 00 => 1 addr, 11 => 4 addrs
+                                               delta1 : 14,    // 16-bit delta, low 2 bits assumed zero
+                                               delta2 : 14,
+                                               delta3 : 14,
+                                               delta4 : 14;    
+               } info;
+       };
+       
 };
 
 //
@@ -570,7 +659,7 @@ public:
                                        typeSectionEnd, typeBranchIsland, typeLazyPointer, typeStub, typeNonLazyPointer, 
                                        typeLazyDylibPointer, typeStubHelper, typeInitializerPointers, typeTerminatorPointers,
                                        typeLTOtemporary, typeResolver,
-                                       typeTLV, typeTLVZeroFill, typeTLVInitialValue, typeTLVInitializerPointers };
+                                       typeTLV, typeTLVZeroFill, typeTLVInitialValue, typeTLVInitializerPointers, typeTLVPointer };
 
        enum SymbolTableInclusion { symbolTableNotIn, symbolTableNotInFinalLinkedImages, symbolTableIn,
                                                                symbolTableInAndNeverStrip, symbolTableInAsAbsolute, 
@@ -605,13 +694,14 @@ public:
                                                                                                        _contentType(ct), _symbolTableInclusion(i),
                                                                                                        _scope(s), _mode(modeSectionOffset), 
                                                                                                        _overridesADylibsWeakDef(false), _coalescedAway(false),
-                                                                                                       _live(false), _machoSection(0), _weakImportState(weakImportUnset)
+                                                                                                       _live(false), _dontDeadStripIfRefLive(false),
+                                                                                                       _machoSection(0), _weakImportState(weakImportUnset)
                                                                                                         {
                                                                                                        #ifndef NDEBUG
                                                                                                                switch ( _combine ) {
                                                                                                                        case combineByNameAndContent:
                                                                                                                        case combineByNameAndReferences:
-                                                                                                                               assert(_symbolTableInclusion == symbolTableNotIn);
+                                                                                                                               assert(_symbolTableInclusion != symbolTableIn);
                                                                                                                                assert(_scope != scopeGlobal);
                                                                 break;
                                                             case combineByName:
@@ -629,6 +719,7 @@ public:
        ContentType                                                             contentType() const                     { return _contentType; }
        SymbolTableInclusion                                    symbolTableInclusion() const{ return _symbolTableInclusion; }
        bool                                                                    dontDeadStrip() const           { return _dontDeadStrip; }
+       bool                                                                    dontDeadStripIfReferencesLive() const { return _dontDeadStripIfRefLive; }
        bool                                                                    isThumb() const                         { return _thumb; }
        bool                                                                    isAlias() const                         { return _alias; }
        Alignment                                                               alignment() const                       { return Alignment(_alignmentPowerOf2, _alignmentModulus); }
@@ -648,6 +739,7 @@ public:
        void                                                                    setCoalescedAway()                      { _coalescedAway = true; }
        void                                                                    setWeakImportState(bool w)      { assert(_definition == definitionProxy); _weakImportState = ( w ? weakImportTrue : weakImportFalse); }
        void                                                                    setAutoHide()                           { _autoHide = true; }
+       void                                                                    setDontDeadStripIfReferencesLive() { _dontDeadStripIfRefLive = true; }
        void                                                                    setLive()                                       { _live = true; }
        void                                                                    setLive(bool value)                     { _live = value; }
        void                                                                    setMachoSection(unsigned x) { assert(x != 0); assert(x < 256); _machoSection = x; }
@@ -659,7 +751,7 @@ public:
        bool                                                                    finalAddressMode() const    { return (_mode == modeFinalAddress); }
 #endif
        virtual const File*                                             file() const = 0;
-       virtual bool                                                    translationUnitSource(const char** dir, const char** name) const = 0;
+       virtual const char*                                             translationUnitSource() const { return NULL; }
        virtual const char*                                             name() const = 0;
        virtual uint64_t                                                objectAddress() const = 0;
        virtual uint64_t                                                size() const = 0;
@@ -675,15 +767,13 @@ public:
                }
                return false;
        }
+       virtual void                                                    setFile(const File* f)          { }
        
        virtual UnwindInfo::iterator                    beginUnwind() const { return NULL; }
        virtual UnwindInfo::iterator                    endUnwind() const       { return NULL; }
        virtual LineInfo::iterator                              beginLineInfo() const { return NULL; }
        virtual LineInfo::iterator                              endLineInfo() const { return NULL; }
                                                                                        
-protected:
-       enum AddressMode { modeSectionOffset, modeFinalAddress };
-
                                                                                        void setAttributesFromAtom(const Atom& a) { 
                                                                                                        _section = a._section; 
                                                                                                        _alignmentModulus = a._alignmentModulus;
@@ -692,7 +782,6 @@ protected:
                                                                                                        _combine = a._combine;
                                                                                                        _dontDeadStrip = a._dontDeadStrip;
                                                                                                        _thumb = a._thumb;
-                                                                                                       _alias = a._alias;
                                                                                                        _autoHide = a._autoHide;
                                                                                                        _contentType = a._contentType;
                                                                                                        _symbolTableInclusion = a._symbolTableInclusion;
@@ -703,6 +792,9 @@ protected:
                                                                                                        _weakImportState = a._weakImportState;
                                                                                                }
 
+protected:
+       enum AddressMode { modeSectionOffset, modeFinalAddress };
+
        const Section *                                         _section;
        uint64_t                                                        _address;
        uint16_t                                                        _alignmentModulus;
@@ -720,6 +812,7 @@ protected:
        bool                                                            _overridesADylibsWeakDef : 1;
        bool                                                            _coalescedAway : 1;
        bool                                                            _live : 1;
+       bool                                                            _dontDeadStripIfRefLive : 1;
        unsigned                                                        _machoSection : 8;
        WeakImportState                                         _weakImportState : 2;
 };
@@ -733,6 +826,24 @@ public:
 };
 
 
+       
+// utility classes for using std::unordered_map with c-strings
+struct CStringHash {
+       size_t operator()(const char* __s) const {
+               size_t __h = 0;
+               for ( ; *__s; ++__s)
+                       __h = 5 * __h + *__s;
+               return __h;
+       };
+};
+struct CStringEquals
+{
+       bool operator()(const char* left, const char* right) const { return (strcmp(left, right) == 0); }
+};
+
+typedef        std::unordered_set<const char*, ld::CStringHash, ld::CStringEquals>  CStringSet;
+
+
 class Internal
 {
 public:
@@ -757,6 +868,10 @@ public:
                bool                                                    hasExternalRelocs;
        };
        
+       typedef std::map<const ld::Atom*, FinalSection*>        AtomToSection;          
+
+       virtual uint64_t                                        assignFileOffsets() = 0;
+       virtual void                                            setSectionSizesAndAlignments() = 0;
        virtual ld::Internal::FinalSection*     addAtom(const Atom&) = 0;
        virtual ld::Internal::FinalSection* getFinalSection(const ld::Section& inputSection) = 0;
        virtual                                                         ~Internal() {}
@@ -765,14 +880,23 @@ public:
                                                                                        lazyBindingHelper(NULL), compressedFastBinderProxy(NULL),
                                                                                        objcObjectConstraint(ld::File::objcConstraintNone), 
                                                                                        objcDylibConstraint(ld::File::objcConstraintNone), 
-                                                                                       cpuSubType(0), 
+                                                                                       swiftVersion(0), cpuSubType(0), minOSVersion(0),
+                                                                                       objectFileFoundWithNoVersion(false),
                                                                                        allObjectFilesScatterable(true), 
-                                                                                       someObjectFileHasDwarf(false), usingHugeSections(false) { }
-                                                                               
+                                                                                       someObjectFileHasDwarf(false), usingHugeSections(false),
+                                                                                       hasThreadLocalVariableDefinitions(false),
+                                                                                       hasWeakExternalSymbols(false),
+                                                                                       someObjectHasOptimizationHints(false),
+                                                                                       dropAllBitcode(false), embedMarkerOnly(false)   { }
+
        std::vector<FinalSection*>                                      sections;
        std::vector<ld::dylib::File*>                           dylibs;
        std::vector<ld::relocatable::File::Stab>        stabs;
+       AtomToSection                                                           atomToSection;          
+       CStringSet                                                                      linkerOptionLibraries;
+       CStringSet                                                                      linkerOptionFrameworks;
        std::vector<const ld::Atom*>                            indirectBindingTable;
+       std::vector<const ld::relocatable::File*>       filesWithBitcode;
        const ld::dylib::File*                                          bundleLoader;
        const Atom*                                                                     entryPoint;
        const Atom*                                                                     classicBindingHelper;
@@ -780,10 +904,20 @@ public:
        const Atom*                                                                     compressedFastBinderProxy;
        ld::File::ObjcConstraint                                        objcObjectConstraint;
        ld::File::ObjcConstraint                                        objcDylibConstraint;
+       uint8_t                                                                         swiftVersion;
        uint32_t                                                                        cpuSubType;
+       uint32_t                                                                        minOSVersion;
+       uint32_t                                                                        derivedPlatformLoadCommand;
+       bool                                                                            objectFileFoundWithNoVersion;
        bool                                                                            allObjectFilesScatterable;
        bool                                                                            someObjectFileHasDwarf;
        bool                                                                            usingHugeSections;
+       bool                                                                            hasThreadLocalVariableDefinitions;
+       bool                                                                            hasWeakExternalSymbols;
+       bool                                                                            someObjectHasOptimizationHints;
+       bool                                                                            dropAllBitcode;
+       bool                                                                            embedMarkerOnly;
+       std::string                                                                     ltoBitcodePath;
 };
 
 
@@ -792,11 +926,6 @@ public:
 
 
 
-
-
-
-
-
 } // namespace ld 
 
 #endif // __LD_HPP__