#include <unistd.h>
#include <assert.h>
+#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
//
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;
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
{
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;
virtual bool canScatterAtoms() const = 0;
virtual bool hasLongBranchStubs() { return false; }
virtual LinkerOptionsList* linkerOptions() const = 0;
+ virtual SourceKind sourceKind() const { return kSourceUnknown; }
};
} // namespace relocatable
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;
{
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,
kindStoreARM64GOTLoadPage21, kindStoreARM64GOTLoadPageOff12,
kindStoreARM64GOTLeaPage21, kindStoreARM64GOTLeaPageOff12,
kindStoreARM64TLVPLoadPage21, kindStoreARM64TLVPLoadPageOff12,
+ kindStoreARM64TLVPLoadNowLeaPage21, kindStoreARM64TLVPLoadNowLeaPageOff12,
kindStoreARM64PointerToGOT, kindStoreARM64PCRelToGOT,
#endif
// dtrace probes
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
kindStoreTargetAddressARM64GOTLoadPageOff12,// kindSetTargetAddress + kindStoreARM64GOTLoadPageOff12
kindStoreTargetAddressARM64GOTLeaPage21, // kindSetTargetAddress + kindStoreARM64GOTLeaPage21
kindStoreTargetAddressARM64GOTLeaPageOff12, // kindSetTargetAddress + kindStoreARM64GOTLeaPageOff12
+ kindStoreTargetAddressARM64TLVPLoadPage21, // kindSetTargetAddress + kindStoreARM64TLVPLoadPage21
+ kindStoreTargetAddressARM64TLVPLoadPageOff12,// kindSetTargetAddress + kindStoreARM64TLVPLoadPageOff12
+ kindStoreTargetAddressARM64TLVPLoadNowLeaPage21, // kindSetTargetAddress + kindStoreARM64TLVPLoadNowLeaPage21
+ kindStoreTargetAddressARM64TLVPLoadNowLeaPageOff12, // kindSetTargetAddress + kindStoreARM64TLVPLoadNowLeaPageOff12
#endif
};
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:
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;
+ };
+
};
//
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,
_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 ) {
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); }
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; }
}
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;
_weakImportState = a._weakImportState;
}
+protected:
+ enum AddressMode { modeSectionOffset, modeFinalAddress };
+
const Section * _section;
uint64_t _address;
uint16_t _alignmentModulus;
bool _overridesADylibsWeakDef : 1;
bool _coalescedAway : 1;
bool _live : 1;
+ bool _dontDeadStripIfRefLive : 1;
unsigned _machoSection : 8;
WeakImportState _weakImportState : 2;
};
typedef std::unordered_set<const char*, ld::CStringHash, ld::CStringEquals> CStringSet;
+
class Internal
{
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() {}
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;
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;
};
-
-
-
-
} // namespace ld
#endif // __LD_HPP__