X-Git-Url: https://git.saurik.com/apple/ld64.git/blobdiff_plain/f80fe69f3f29962e8aa43a99f8ed9201548f3d78..fb9a160cc46cd88a41dda5ab61012c5572e56f33:/src/ld/ld.hpp?ds=sidebyside diff --git a/src/ld/ld.hpp b/src/ld/ld.hpp index 42d5aa6..e297036 100644 --- a/src/ld/ld.hpp +++ b/src/ld/ld.hpp @@ -31,13 +31,19 @@ #include #include +#include +#include #include +#include #include #include "configure.h" namespace ld { +// Forward declaration for bitcode support +class Bitcode; + // // ld::File // @@ -146,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; @@ -166,8 +176,11 @@ enum MacVersionMin { macVersionUnset=0, mac10_4=0x000A0400, mac10_5=0x000A0500, 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_6_0=0x00060000, iOS_7_0=0x00070000, 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 @@ -189,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; @@ -209,6 +223,7 @@ namespace relocatable { virtual bool canScatterAtoms() const = 0; virtual bool hasLongBranchStubs() { return false; } virtual LinkerOptionsList* linkerOptions() const = 0; + virtual SourceKind sourceKind() const { return kSourceUnknown; } }; } // namespace relocatable @@ -267,9 +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 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; @@ -309,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, @@ -409,6 +430,7 @@ struct Fixup kindStoreARM64GOTLoadPage21, kindStoreARM64GOTLoadPageOff12, kindStoreARM64GOTLeaPage21, kindStoreARM64GOTLeaPageOff12, kindStoreARM64TLVPLoadPage21, kindStoreARM64TLVPLoadPageOff12, + kindStoreARM64TLVPLoadNowLeaPage21, kindStoreARM64TLVPLoadNowLeaPageOff12, kindStoreARM64PointerToGOT, kindStoreARM64PCRelToGOT, #endif // dtrace probes @@ -419,9 +441,13 @@ struct Fixup 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 @@ -451,6 +477,10 @@ struct Fixup kindStoreTargetAddressARM64GOTLoadPageOff12,// kindSetTargetAddress + kindStoreARM64GOTLoadPageOff12 kindStoreTargetAddressARM64GOTLeaPage21, // kindSetTargetAddress + kindStoreARM64GOTLeaPage21 kindStoreTargetAddressARM64GOTLeaPageOff12, // kindSetTargetAddress + kindStoreARM64GOTLeaPageOff12 + kindStoreTargetAddressARM64TLVPLoadPage21, // kindSetTargetAddress + kindStoreARM64TLVPLoadPage21 + kindStoreTargetAddressARM64TLVPLoadPageOff12,// kindSetTargetAddress + kindStoreARM64TLVPLoadPageOff12 + kindStoreTargetAddressARM64TLVPLoadNowLeaPage21, // kindSetTargetAddress + kindStoreARM64TLVPLoadNowLeaPage21 + kindStoreTargetAddressARM64TLVPLoadNowLeaPageOff12, // kindSetTargetAddress + kindStoreARM64TLVPLoadNowLeaPageOff12 #endif }; @@ -516,6 +546,21 @@ struct Fixup 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: @@ -544,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; + }; + }; // @@ -602,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, @@ -637,7 +694,8 @@ 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 ) { @@ -661,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); } @@ -680,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; } @@ -707,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; @@ -734,6 +792,9 @@ protected: _weakImportState = a._weakImportState; } +protected: + enum AddressMode { modeSectionOffset, modeFinalAddress }; + const Section * _section; uint64_t _address; uint16_t _alignmentModulus; @@ -751,6 +812,7 @@ protected: bool _overridesADylibsWeakDef : 1; bool _coalescedAway : 1; bool _live : 1; + bool _dontDeadStripIfRefLive : 1; unsigned _machoSection : 8; WeakImportState _weakImportState : 2; }; @@ -781,6 +843,7 @@ struct CStringEquals typedef std::unordered_set CStringSet; + class Internal { public: @@ -805,7 +868,10 @@ public: bool hasExternalRelocs; }; + typedef std::map 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() {} @@ -814,16 +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 sections; std::vector dylibs; std::vector stabs; + AtomToSection atomToSection; CStringSet linkerOptionLibraries; CStringSet linkerOptionFrameworks; std::vector indirectBindingTable; + std::vector filesWithBitcode; const ld::dylib::File* bundleLoader; const Atom* entryPoint; const Atom* classicBindingHelper; @@ -831,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; }; @@ -843,10 +926,6 @@ public: - - - - } // namespace ld #endif // __LD_HPP__