1 /* -*- mode: C++; c-basic-offset: 4; tab-width: 4 -*-
3 * Copyright (c) 2005-2010 Apple Inc. All rights reserved.
5 * @APPLE_LICENSE_HEADER_START@
7 * This file contains Original Code and/or Modifications of Original Code
8 * as defined in and that are subject to the Apple Public Source License
9 * Version 2.0 (the 'License'). You may not use this file except in
10 * compliance with the License. Please obtain a copy of the License at
11 * http://www.opensource.apple.com/apsl/ and read it before using this
14 * The Original Code and all software distributed under the License are
15 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
19 * Please see the License for the specific language governing rights and
20 * limitations under the License.
22 * @APPLE_LICENSE_HEADER_END@
38 #include <unordered_set>
40 #include "configure.h"
44 // Forward declaration for bitcode support
50 // Abstract base class for all object or library files the linker processes.
52 // forEachAtom() iterates over the Atoms in the order they occur in the file.
54 // justInTimeforEachAtom(name) iterates over lazily created Atoms. For instance if
55 // File is a static library, justInTimeforEachAtom() will iterate over the base set
56 // of Atoms from the archive member implementing 'name'.
61 enum ObjcConstraint { objcConstraintNone, objcConstraintRetainRelease,
62 objcConstraintRetainReleaseOrGC, objcConstraintGC,
63 objcConstraintRetainReleaseForSimulator };
67 virtual ~AtomHandler() {}
68 virtual void doAtom(const class Atom&) = 0;
69 virtual void doFile(const class File&) = 0;
75 // Codifies the rules of ordering input files for symbol precedence. These are:
76 // - Input files listed on the command line are ordered according to their index in the argument list.
77 // - Input files listed in a file list are ordered first at the index of the file list argument, then
78 // by index in the file list
79 // - Input files extracted from archives are ordered using the ordinal of the archive itself plus the
80 // index of the object file within the archive
81 // - Indirect dylibs are ordered after all input files derived from the command line, in the order that
82 // they are discovered.
83 // - The LTO object file is last.
88 // The actual numeric ordinal. Lower values have higher precedence and a zero value is invalid.
89 // The 64 bit ordinal is broken into 4 16 bit chunks. The high 16 bits are a "partition" that
90 // is used to distinguish major ordinal groups: command line, indirect dylib, LTO.
91 // The remaining chunks are used according to the partition (see below).
94 Ordinal (uint64_t ordinal) : _ordinal(ordinal) {}
96 enum { kArgListPartition=0, kIndirectDylibPartition=1, kLTOPartition = 2, kLinkerOptionPartition = 2, InvalidParition=0xffff };
97 Ordinal(uint16_t partition, uint16_t majorIndex, uint16_t minorIndex, uint16_t counter) {
98 _ordinal = ((uint64_t)partition<<48) | ((uint64_t)majorIndex<<32) | ((uint64_t)minorIndex<<16) | ((uint64_t)counter<<0);
101 const uint16_t partition() const { return (_ordinal>>48)&0xffff; }
102 const uint16_t majorIndex() const { return (_ordinal>>32)&0xffff; }
103 const uint16_t minorIndex() const { return (_ordinal>>16)&0xffff; }
104 const uint16_t counter() const { return (_ordinal>>00)&0xffff; }
106 const Ordinal nextMajorIndex() const { assert(majorIndex() < 0xffff); return Ordinal(_ordinal+((uint64_t)1<<32)); }
107 const Ordinal nextMinorIndex() const { assert(minorIndex() < 0xffff); return Ordinal(_ordinal+((uint64_t)1<<16)); }
108 const Ordinal nextCounter() const { assert(counter() < 0xffff); return Ordinal(_ordinal+((uint64_t)1<<0)); }
111 Ordinal() : _ordinal(0) {};
113 static const Ordinal NullOrdinal() { return Ordinal((uint64_t)0); }
115 const bool validOrdinal() const { return _ordinal != 0; }
117 bool operator ==(const Ordinal& rhs) const { return _ordinal == rhs._ordinal; }
118 bool operator !=(const Ordinal& rhs) const { return _ordinal != rhs._ordinal; }
119 bool operator < (const Ordinal& rhs) const { return _ordinal < rhs._ordinal; }
120 bool operator > (const Ordinal& rhs) const { return _ordinal > rhs._ordinal; }
122 // For ordinals derived from the command line args the partition is ArgListPartition
123 // The majorIndex is the arg index that pulls in the file, file list, or archive.
124 // 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.
125 // The counter is used for .a files and the value is the index of the object in the archive.
126 // Thus, an object pulled in from a .a that was listed in a file list could use all three fields.
127 static const Ordinal makeArgOrdinal(uint16_t argIndex) { return Ordinal(kArgListPartition, argIndex, 0, 0); };
128 const Ordinal nextFileListOrdinal() const { return nextMinorIndex(); }
129 const Ordinal archiveOrdinalWithMemberIndex(uint16_t index) const { return Ordinal(kArgListPartition, majorIndex(), minorIndex(), index); }
131 // For indirect libraries the partition is IndirectDylibPartition and the counter is used or order the libraries.
132 static const ld::File::Ordinal indirectDylibBase() { return Ordinal(kIndirectDylibPartition, 0, 0, 0); }
133 const Ordinal nextIndirectDylibOrdinal() const { return nextCounter(); }
135 // For the LTO mach-o the partition is LTOPartition. As there is only one LTO file no other fields are needed.
136 static const ld::File::Ordinal LTOOrdinal() { return Ordinal(kLTOPartition, 0, 0, 0); }
138 // For linker options embedded in object files
139 static const ld::File::Ordinal linkeOptionBase() { return Ordinal(kIndirectDylibPartition, 1, 0, 0); }
140 const Ordinal nextLinkerOptionOrdinal() { nextCounter(); return *this; };
144 typedef enum { Reloc, Dylib, Archive, Other } Type;
146 File(const char* pth, time_t modTime, Ordinal ord, Type type)
147 : _path(pth), _modTime(modTime), _ordinal(ord), _type(type) { }
149 const char* path() const { return _path; }
150 time_t modificationTime() const{ return _modTime; }
151 Ordinal ordinal() const { return _ordinal; }
152 virtual bool forEachAtom(AtomHandler&) const = 0;
153 virtual bool justInTimeforEachAtom(const char* name, AtomHandler&) const = 0;
154 virtual ObjcConstraint objCConstraint() const { return objcConstraintNone; }
155 virtual uint8_t swiftVersion() const { return 0; }
156 virtual uint32_t cpuSubType() const { return 0; }
157 virtual uint32_t subFileCount() const { return 1; }
158 virtual uint32_t minOSVersion() const { return 0; }
159 virtual uint32_t platformLoadCommand() const { return 0; }
160 bool fileExists() const { return _modTime != 0; }
161 Type type() const { return _type; }
162 virtual Bitcode* getBitcode() const { return NULL; }
166 const Ordinal _ordinal;
172 // minumum OS versions
174 enum MacVersionMin { macVersionUnset=0, mac10_4=0x000A0400, mac10_5=0x000A0500,
175 mac10_6=0x000A0600, mac10_7=0x000A0700, mac10_8=0x000A0800,
176 mac10_9=0x000A0900, mac10_Future=0x10000000 };
177 enum IOSVersionMin { iOSVersionUnset=0, iOS_2_0=0x00020000, iOS_3_1=0x00030100,
178 iOS_4_2=0x00040200, iOS_4_3=0x00040300, iOS_5_0=0x00050000,
179 iOS_6_0=0x00060000, iOS_7_0=0x00070000, iOS_8_0=0x00080000,
180 iOS_9_0=0x00090000, iOS_Future=0x10000000};
181 enum WatchOSVersionMin { wOSVersionUnset=0, wOS_1_0=0x00010000, wOS_2_0=0x00020000 };
184 namespace relocatable {
186 // ld::relocatable::File
188 // Abstract base class for object files the linker processes.
190 // debugInfo() returns if the object file contains debugger information (stabs or dwarf).
192 // stabs() lazily creates a vector of Stab objects for each atom
194 // canScatterAtoms() true for all compiler generated code. Hand written assembly can opt-in
195 // via .subsections_via_symbols directive. When true it means the linker can break up section
196 // content at symbol boundaries and do optimizations like coalescing, dead code stripping, or
197 // apply order files.
199 // optimize() used by libLTO to lazily generate code from llvm bit-code files
201 class File : public ld::File
204 enum DebugInfoKind { kDebugInfoNone=0, kDebugInfoStabs=1, kDebugInfoDwarf=2, kDebugInfoStabsUUID=3 };
205 enum SourceKind { kSourceUnknown=0, kSourceObj, kSourceLTO, kSourceArchive, kSourceCompilerArchive };
207 const class Atom* atom;
214 typedef const std::vector< std::vector<const char*> > LinkerOptionsList;
216 File(const char* pth, time_t modTime, Ordinal ord)
217 : ld::File(pth, modTime, ord, Reloc) { }
219 virtual DebugInfoKind debugInfo() const = 0;
220 virtual const char* debugInfoPath() const { return path(); }
221 virtual time_t debugInfoModificationTime() const { return modificationTime(); }
222 virtual const std::vector<Stab>* stabs() const = 0;
223 virtual bool canScatterAtoms() const = 0;
224 virtual bool hasLongBranchStubs() { return false; }
225 virtual LinkerOptionsList* linkerOptions() const = 0;
226 virtual SourceKind sourceKind() const { return kSourceUnknown; }
228 } // namespace relocatable
236 // Abstract base class for dynamic shared libraries read by the linker processes.
238 class File : public ld::File
244 virtual ~DylibHandler() {}
245 virtual File* findDylib(const char* installPath, const char* fromPath) = 0;
248 File(const char* pth, time_t modTime, Ordinal ord)
249 : ld::File(pth, modTime, ord, Dylib), _dylibInstallPath(NULL),
250 _dylibTimeStamp(0), _dylibCurrentVersion(0), _dylibCompatibilityVersion(0),
251 _explicitlyLinked(false), _implicitlyLinked(false),
252 _lazyLoadedDylib(false), _forcedWeakLinked(false), _reExported(false),
253 _upward(false), _dead(false) { }
254 const char* installPath() const { return _dylibInstallPath; }
255 uint32_t timestamp() const { return _dylibTimeStamp; }
256 uint32_t currentVersion() const { return _dylibCurrentVersion; }
257 uint32_t compatibilityVersion() const{ return _dylibCompatibilityVersion; }
258 void setExplicitlyLinked() { _explicitlyLinked = true; }
259 bool explicitlyLinked() const { return _explicitlyLinked; }
260 void setImplicitlyLinked() { _implicitlyLinked = true; }
261 bool implicitlyLinked() const { return _implicitlyLinked; }
263 // attributes of how dylib will be used when linked
264 void setWillBeLazyLoadedDylb() { _lazyLoadedDylib = true; }
265 bool willBeLazyLoadedDylib() const { return _lazyLoadedDylib; }
266 void setForcedWeakLinked() { _forcedWeakLinked = true; }
267 bool forcedWeakLinked() const { return _forcedWeakLinked; }
269 void setWillBeReExported() { _reExported = true; }
270 bool willBeReExported() const { return _reExported; }
271 void setWillBeUpwardDylib() { _upward = true; }
272 bool willBeUpwardDylib() const { return _upward; }
273 void setWillBeRemoved(bool value) { _dead = value; }
274 bool willRemoved() const { return _dead; }
276 virtual void processIndirectLibraries(DylibHandler* handler, bool addImplicitDylibs) = 0;
277 virtual bool providedExportAtom() const = 0;
278 virtual const char* parentUmbrella() const = 0;
279 virtual const std::vector<const char*>* allowableClients() const = 0;
280 virtual bool hasWeakExternals() const = 0;
281 virtual bool deadStrippable() const = 0;
282 virtual bool hasWeakDefinition(const char* name) const = 0;
283 virtual bool hasPublicInstallName() const = 0;
284 virtual bool allSymbolsAreWeakImported() const = 0;
285 virtual bool installPathVersionSpecific() const { return false; }
286 virtual bool appExtensionSafe() const = 0;
289 struct ReExportChain { ReExportChain* prev; const File* file; };
290 virtual std::pair<bool, bool> hasWeakDefinitionImpl(const char* name) const = 0;
291 virtual bool containsOrReExports(const char* name, bool& weakDef, bool& tlv, uint64_t& defAddress) const = 0;
292 virtual void assertNoReExportCycles(ReExportChain*) const = 0;
294 const char* _dylibInstallPath;
295 uint32_t _dylibTimeStamp;
296 uint32_t _dylibCurrentVersion;
297 uint32_t _dylibCompatibilityVersion;
298 bool _explicitlyLinked;
299 bool _implicitlyLinked;
300 bool _lazyLoadedDylib;
301 bool _forcedWeakLinked;
313 // Abstract base class for static libraries read by the linker processes.
315 class File : public ld::File
318 File(const char* pth, time_t modTime, Ordinal ord)
319 : ld::File(pth, modTime, ord, Archive) { }
321 virtual bool justInTimeDataOnlyforEachAtom(const char* name, AtomHandler&) const = 0;
323 } // namespace archive
332 enum Type { typeUnclassified, typeCode, typePageZero, typeImportProxies, typeLinkEdit, typeMachHeader, typeStack,
333 typeLiteral4, typeLiteral8, typeLiteral16, typeConstants, typeTempLTO, typeTempAlias,
334 typeCString, typeNonStdCString, typeCStringPointer, typeUTF16Strings, typeCFString, typeObjC1Classes,
335 typeCFI, typeLSDA, typeDtraceDOF, typeUnwindInfo, typeObjCClassRefs, typeObjC2CategoryList,
336 typeZeroFill, typeTentativeDefs, typeLazyPointer, typeStub, typeNonLazyPointer, typeDyldInfo,
337 typeLazyDylibPointer, typeStubHelper, typeInitializerPointers, typeTerminatorPointers,
338 typeStubClose, typeLazyPointerClose, typeAbsoluteSymbols,
339 typeTLVDefs, typeTLVZeroFill, typeTLVInitialValues, typeTLVInitializerPointers, typeTLVPointers,
340 typeFirstSection, typeLastSection, typeDebug, typeSectCreate };
343 Section(const char* sgName, const char* sctName,
344 Type t, bool hidden=false)
345 : _segmentName(sgName), _sectionName(sctName),
346 _type(t), _hidden(hidden) {}
347 Section(const Section& sect)
348 : _segmentName(sect.segmentName()), _sectionName(sect.sectionName()),
349 _type(sect.type()), _hidden(sect.isSectionHidden()) {}
351 bool operator==(const Section& rhs) const { return ( (_hidden==rhs._hidden) &&
352 (strcmp(_segmentName, rhs._segmentName)==0) &&
353 (strcmp(_sectionName, rhs._sectionName)==0) ); }
354 bool operator!=(const Section& rhs) const { return ! (*this == rhs); }
355 const char* segmentName() const { return _segmentName; }
356 const char* sectionName() const { return _sectionName; }
357 Type type() const { return _type; }
358 bool isSectionHidden() const { return _hidden; }
361 const char* _segmentName;
362 const char* _sectionName;
372 // A Fixup describes how part of an Atom's content must be fixed up. For instance,
373 // an instruction may contain a displacement to another Atom that must be
374 // fixed up by the linker.
376 // A Fixup my reference another Atom. There are two kinds of references: direct and by-name.
377 // With a direct reference, the target is bound by the File that created it.
378 // For instance a reference to a static would produce a direct reference.
379 // A by-name reference requires the linker to find the target Atom with the
380 // required name in order to be bound.
382 // For a link to succeed all Fixup must be bound.
384 // A Reference also has a fix-up-offset. This is the offset into the content of the
385 // Atom holding the reference where the fix-up (relocation) will be applied.
390 enum TargetBinding { bindingNone, bindingByNameUnbound, bindingDirectlyBound, bindingByContentBound, bindingsIndirectlyBound };
391 enum Cluster { k1of1, k1of2, k2of2, k1of3, k2of3, k3of3, k1of4, k2of4, k3of4, k4of4, k1of5, k2of5, k3of5, k4of5, k5of5 };
392 enum Kind { kindNone, kindNoneFollowOn,
394 kindNoneGroupSubordinate,
395 kindNoneGroupSubordinateFDE, kindNoneGroupSubordinateLSDA, kindNoneGroupSubordinatePersonality,
396 // value calculations
397 kindSetTargetAddress,
398 kindSubtractTargetAddress,
401 kindSetTargetImageOffset,
402 kindSetTargetSectionOffset,
403 kindSetTargetTLVTemplateOffset,
404 // pointer store kinds (of current calculated value)
406 kindStoreLittleEndian16,
407 kindStoreLittleEndianLow24of32,
408 kindStoreLittleEndian32,
409 kindStoreLittleEndian64,
410 kindStoreBigEndian16,
411 kindStoreBigEndianLow24of32,
412 kindStoreBigEndian32,
413 kindStoreBigEndian64,
414 // Intel specific store kinds
415 kindStoreX86BranchPCRel8, kindStoreX86BranchPCRel32,
416 kindStoreX86PCRel8, kindStoreX86PCRel16,
417 kindStoreX86PCRel32, kindStoreX86PCRel32_1, kindStoreX86PCRel32_2, kindStoreX86PCRel32_4,
418 kindStoreX86PCRel32GOTLoad, kindStoreX86PCRel32GOTLoadNowLEA, kindStoreX86PCRel32GOT,
419 kindStoreX86PCRel32TLVLoad, kindStoreX86PCRel32TLVLoadNowLEA,
420 kindStoreX86Abs32TLVLoad, kindStoreX86Abs32TLVLoadNowLEA,
421 // ARM specific store kinds
422 kindStoreARMBranch24, kindStoreThumbBranch22,
424 kindStoreARMLow16, kindStoreARMHigh16,
425 kindStoreThumbLow16, kindStoreThumbHigh16,
426 #if SUPPORT_ARCH_arm64
427 // ARM64 specific store kinds
428 kindStoreARM64Branch26,
429 kindStoreARM64Page21, kindStoreARM64PageOff12,
430 kindStoreARM64GOTLoadPage21, kindStoreARM64GOTLoadPageOff12,
431 kindStoreARM64GOTLeaPage21, kindStoreARM64GOTLeaPageOff12,
432 kindStoreARM64TLVPLoadPage21, kindStoreARM64TLVPLoadPageOff12,
433 kindStoreARM64TLVPLoadNowLeaPage21, kindStoreARM64TLVPLoadNowLeaPageOff12,
434 kindStoreARM64PointerToGOT, kindStoreARM64PCRelToGOT,
438 kindStoreX86DtraceCallSiteNop, kindStoreX86DtraceIsEnableSiteClear,
439 kindStoreARMDtraceCallSiteNop, kindStoreARMDtraceIsEnableSiteClear,
440 kindStoreARM64DtraceCallSiteNop, kindStoreARM64DtraceIsEnableSiteClear,
441 kindStoreThumbDtraceCallSiteNop, kindStoreThumbDtraceIsEnableSiteClear,
443 kindLazyTarget, kindSetLazyOffset,
446 // data-in-code markers
447 kindDataInCodeStartData, kindDataInCodeStartJT8, kindDataInCodeStartJT16,
448 kindDataInCodeStartJT32, kindDataInCodeStartJTA32, kindDataInCodeEnd,
449 // linker optimzation hints
450 kindLinkerOptimizationHint,
451 // pointer store combinations
452 kindStoreTargetAddressLittleEndian32, // kindSetTargetAddress + kindStoreLittleEndian32
453 kindStoreTargetAddressLittleEndian64, // kindSetTargetAddress + kindStoreLittleEndian64
454 kindStoreTargetAddressBigEndian32, // kindSetTargetAddress + kindStoreBigEndian32
455 kindStoreTargetAddressBigEndian64, // kindSetTargetAddress + kindStoreBigEndian364
456 kindSetTargetTLVTemplateOffsetLittleEndian32, // kindSetTargetTLVTemplateOffset + kindStoreLittleEndian32
457 kindSetTargetTLVTemplateOffsetLittleEndian64, // kindSetTargetTLVTemplateOffset + kindStoreLittleEndian64
458 // Intel value calculation and store combinations
459 kindStoreTargetAddressX86PCRel32, // kindSetTargetAddress + kindStoreX86PCRel32
460 kindStoreTargetAddressX86BranchPCRel32, // kindSetTargetAddress + kindStoreX86BranchPCRel32
461 kindStoreTargetAddressX86PCRel32GOTLoad,// kindSetTargetAddress + kindStoreX86PCRel32GOTLoad
462 kindStoreTargetAddressX86PCRel32GOTLoadNowLEA,// kindSetTargetAddress + kindStoreX86PCRel32GOTLoadNowLEA
463 kindStoreTargetAddressX86PCRel32TLVLoad, // kindSetTargetAddress + kindStoreX86PCRel32TLVLoad
464 kindStoreTargetAddressX86PCRel32TLVLoadNowLEA, // kindSetTargetAddress + kindStoreX86PCRel32TLVLoadNowLEA
465 kindStoreTargetAddressX86Abs32TLVLoad, // kindSetTargetAddress + kindStoreX86Abs32TLVLoad
466 kindStoreTargetAddressX86Abs32TLVLoadNowLEA, // kindSetTargetAddress + kindStoreX86Abs32TLVLoadNowLEA
467 // ARM value calculation and store combinations
468 kindStoreTargetAddressARMBranch24, // kindSetTargetAddress + kindStoreARMBranch24
469 kindStoreTargetAddressThumbBranch22, // kindSetTargetAddress + kindStoreThumbBranch22
470 kindStoreTargetAddressARMLoad12, // kindSetTargetAddress + kindStoreARMLoad12
471 #if SUPPORT_ARCH_arm64
472 // ARM64 value calculation and store combinations
473 kindStoreTargetAddressARM64Branch26, // kindSetTargetAddress + kindStoreARM64Branch26
474 kindStoreTargetAddressARM64Page21, // kindSetTargetAddress + kindStoreARM64Page21
475 kindStoreTargetAddressARM64PageOff12, // kindSetTargetAddress + kindStoreARM64PageOff12
476 kindStoreTargetAddressARM64GOTLoadPage21, // kindSetTargetAddress + kindStoreARM64GOTLoadPage21
477 kindStoreTargetAddressARM64GOTLoadPageOff12,// kindSetTargetAddress + kindStoreARM64GOTLoadPageOff12
478 kindStoreTargetAddressARM64GOTLeaPage21, // kindSetTargetAddress + kindStoreARM64GOTLeaPage21
479 kindStoreTargetAddressARM64GOTLeaPageOff12, // kindSetTargetAddress + kindStoreARM64GOTLeaPageOff12
480 kindStoreTargetAddressARM64TLVPLoadPage21, // kindSetTargetAddress + kindStoreARM64TLVPLoadPage21
481 kindStoreTargetAddressARM64TLVPLoadPageOff12,// kindSetTargetAddress + kindStoreARM64TLVPLoadPageOff12
482 kindStoreTargetAddressARM64TLVPLoadNowLeaPage21, // kindSetTargetAddress + kindStoreARM64TLVPLoadNowLeaPage21
483 kindStoreTargetAddressARM64TLVPLoadNowLeaPageOff12, // kindSetTargetAddress + kindStoreARM64TLVPLoadNowLeaPageOff12
491 uint32_t bindingIndex;
493 uint32_t offsetInAtom;
495 Cluster clusterSize : 4;
497 TargetBinding binding : 3;
498 bool contentAddendOnly : 1;
499 bool contentDetlaToAddendOnly : 1;
500 bool contentIgnoresAddend : 1;
502 typedef Fixup* iterator;
505 offsetInAtom(0), kind(kindNone), clusterSize(k1of1), weakImport(false),
506 binding(bindingNone),
507 contentAddendOnly(false), contentDetlaToAddendOnly(false), contentIgnoresAddend(false) { u.target = NULL; }
509 Fixup(Kind k, Atom* targetAtom) :
510 offsetInAtom(0), kind(k), clusterSize(k1of1), weakImport(false),
511 binding(Fixup::bindingDirectlyBound),
512 contentAddendOnly(false), contentDetlaToAddendOnly(false), contentIgnoresAddend(false)
513 { assert(targetAtom != NULL); u.target = targetAtom; }
515 Fixup(uint32_t off, Cluster c, Kind k) :
516 offsetInAtom(off), kind(k), clusterSize(c), weakImport(false),
517 binding(Fixup::bindingNone),
518 contentAddendOnly(false), contentDetlaToAddendOnly(false), contentIgnoresAddend(false)
521 Fixup(uint32_t off, Cluster c, Kind k, bool weakIm, const char* name) :
522 offsetInAtom(off), kind(k), clusterSize(c), weakImport(weakIm),
523 binding(Fixup::bindingByNameUnbound),
524 contentAddendOnly(false), contentDetlaToAddendOnly(false), contentIgnoresAddend(false)
525 { assert(name != NULL); u.name = name; }
527 Fixup(uint32_t off, Cluster c, Kind k, TargetBinding b, const char* name) :
528 offsetInAtom(off), kind(k), clusterSize(c), weakImport(false), binding(b),
529 contentAddendOnly(false), contentDetlaToAddendOnly(false), contentIgnoresAddend(false)
530 { assert(name != NULL); u.name = name; }
532 Fixup(uint32_t off, Cluster c, Kind k, const Atom* targetAtom) :
533 offsetInAtom(off), kind(k), clusterSize(c), weakImport(false),
534 binding(Fixup::bindingDirectlyBound),
535 contentAddendOnly(false), contentDetlaToAddendOnly(false), contentIgnoresAddend(false)
536 { assert(targetAtom != NULL); u.target = targetAtom; }
538 Fixup(uint32_t off, Cluster c, Kind k, TargetBinding b, const Atom* targetAtom) :
539 offsetInAtom(off), kind(k), clusterSize(c), weakImport(false), binding(b),
540 contentAddendOnly(false), contentDetlaToAddendOnly(false), contentIgnoresAddend(false)
541 { assert(targetAtom != NULL); u.target = targetAtom; }
543 Fixup(uint32_t off, Cluster c, Kind k, uint64_t addend) :
544 offsetInAtom(off), kind(k), clusterSize(c), weakImport(false),
545 binding(Fixup::bindingNone),
546 contentAddendOnly(false), contentDetlaToAddendOnly(false), contentIgnoresAddend(false)
547 { u.addend = addend; }
549 Fixup(Kind k, uint32_t lohKind, uint32_t off1, uint32_t off2) :
550 offsetInAtom(off1), kind(k), clusterSize(k1of1),
551 weakImport(false), binding(Fixup::bindingNone), contentAddendOnly(false),
552 contentDetlaToAddendOnly(false), contentIgnoresAddend(false) {
553 assert(k == kindLinkerOptimizationHint);
556 extra.info.kind = lohKind;
557 extra.info.count = 1;
558 extra.info.delta1 = 0;
559 extra.info.delta2 = (off2 - off1) >> 2;
560 u.addend = extra.addend;
564 bool firstInCluster() const {
565 switch (clusterSize) {
578 bool lastInCluster() const {
579 switch (clusterSize) {
596 count : 2, // 00 => 1 addr, 11 => 4 addrs
597 delta1 : 14, // 16-bit delta, low 2 bits assumed zero
609 // An atom is the fundamental unit of linking. A C function or global variable is an atom.
610 // An atom has content and attributes. The content of a function atom is the instructions
611 // that implement the function. The content of a global variable atom is its initial bits.
614 // The name of an atom is the label name generated by the compiler. A C compiler names foo()
615 // as _foo. A C++ compiler names foo() as __Z3foov.
616 // The name refers to the first byte of the content. An atom cannot have multiple entry points.
617 // Such code is modeled as multiple atoms, each having a "follow on" reference to the next.
618 // A "follow on" reference is a contraint to the linker to the atoms must be laid out contiguously.
621 // An atom is in one of three scopes: translation-unit, linkage-unit, or global. These correspond
622 // to the C visibility of static, hidden, default.
625 // An atom is one of five defintion kinds:
626 // regular Most atoms.
627 // weak C++ compiler makes some functions weak if there might be multiple copies
628 // that the linker needs to coalesce.
629 // tentative A straggler from ancient C when the extern did not exist. "int foo;" is ambiguous.
630 // It could be a prototype or it could be a definition.
631 // external This is a "proxy" atom produced by a dylib reader. It has no content. It exists
632 // so that the graph of Atoms can be complete.
633 // external-weak Same as external, but the definition in the dylib is weak.
635 // SymbolTableInclusion:
636 // An atom may or may not be in the symbol table in an object file.
637 // in Most atoms for functions or global data
638 // not-in Anonymous atoms such literal c-strings, or other compiler generated data
639 // not-in-final Atom whose name should not be in the symbol table of final linkd image (e.g. 'l' labels .eh labels)
640 // in-never-strip Atom whose name the strip tool should never remove (e.g. REFERENCED_DYNAMICALLY in mach-o)
643 // Some atoms require specially processing by the linker based on their content. For instance, zero-fill data
644 // atom are group together at the end of the DATA segment to reduce disk size.
647 // For reproducability, the linker lays out atoms in the order they occurred in the source (object) files.
648 // The objectAddress() method returns the address of an atom in the object file so that the linker
649 // can arrange the atoms.
655 enum Scope { scopeTranslationUnit, scopeLinkageUnit, scopeGlobal };
656 enum Definition { definitionRegular, definitionTentative, definitionAbsolute, definitionProxy };
657 enum Combine { combineNever, combineByName, combineByNameAndContent, combineByNameAndReferences };
658 enum ContentType { typeUnclassified, typeZeroFill, typeCString, typeCFI, typeLSDA, typeSectionStart,
659 typeSectionEnd, typeBranchIsland, typeLazyPointer, typeStub, typeNonLazyPointer,
660 typeLazyDylibPointer, typeStubHelper, typeInitializerPointers, typeTerminatorPointers,
661 typeLTOtemporary, typeResolver,
662 typeTLV, typeTLVZeroFill, typeTLVInitialValue, typeTLVInitializerPointers, typeTLVPointer };
664 enum SymbolTableInclusion { symbolTableNotIn, symbolTableNotInFinalLinkedImages, symbolTableIn,
665 symbolTableInAndNeverStrip, symbolTableInAsAbsolute,
666 symbolTableInWithRandomAutoStripLabel };
667 enum WeakImportState { weakImportUnset, weakImportTrue, weakImportFalse };
670 Alignment(int p2, int m=0) : powerOf2(p2), modulus(m) {}
671 uint8_t trailingZeros() const { return (modulus==0) ? powerOf2 : __builtin_ctz(modulus); }
676 const char* fileName;
680 typedef LineInfo* iterator;
683 uint32_t startOffset;
686 typedef UnwindInfo* iterator;
689 Atom(const Section& sect, Definition d, Combine c, Scope s, ContentType ct,
690 SymbolTableInclusion i, bool dds, bool thumb, bool al, Alignment a) :
691 _section(§), _address(0), _alignmentModulus(a.modulus),
692 _alignmentPowerOf2(a.powerOf2), _definition(d), _combine(c),
693 _dontDeadStrip(dds), _thumb(thumb), _alias(al), _autoHide(false),
694 _contentType(ct), _symbolTableInclusion(i),
695 _scope(s), _mode(modeSectionOffset),
696 _overridesADylibsWeakDef(false), _coalescedAway(false),
697 _live(false), _dontDeadStripIfRefLive(false),
698 _machoSection(0), _weakImportState(weakImportUnset)
701 switch ( _combine ) {
702 case combineByNameAndContent:
703 case combineByNameAndReferences:
704 assert(_symbolTableInclusion != symbolTableIn);
705 assert(_scope != scopeGlobal);
715 const Section& section() const { return *_section; }
716 Definition definition() const { return _definition; }
717 Combine combine() const { return _combine; }
718 Scope scope() const { return _scope; }
719 ContentType contentType() const { return _contentType; }
720 SymbolTableInclusion symbolTableInclusion() const{ return _symbolTableInclusion; }
721 bool dontDeadStrip() const { return _dontDeadStrip; }
722 bool dontDeadStripIfReferencesLive() const { return _dontDeadStripIfRefLive; }
723 bool isThumb() const { return _thumb; }
724 bool isAlias() const { return _alias; }
725 Alignment alignment() const { return Alignment(_alignmentPowerOf2, _alignmentModulus); }
726 bool overridesDylibsWeakDef() const { return _overridesADylibsWeakDef; }
727 bool coalescedAway() const { return _coalescedAway; }
728 bool weakImported() const { return _weakImportState == weakImportTrue; }
729 WeakImportState weakImportState() const { return _weakImportState; }
730 bool autoHide() const { return _autoHide; }
731 bool live() const { return _live; }
732 uint8_t machoSection() const { assert(_machoSection != 0); return _machoSection; }
734 void setScope(Scope s) { _scope = s; }
735 void setSymbolTableInclusion(SymbolTableInclusion i)
736 { _symbolTableInclusion = i; }
737 void setCombine(Combine c) { _combine = c; }
738 void setOverridesDylibsWeakDef() { _overridesADylibsWeakDef = true; }
739 void setCoalescedAway() { _coalescedAway = true; }
740 void setWeakImportState(bool w) { assert(_definition == definitionProxy); _weakImportState = ( w ? weakImportTrue : weakImportFalse); }
741 void setAutoHide() { _autoHide = true; }
742 void setDontDeadStripIfReferencesLive() { _dontDeadStripIfRefLive = true; }
743 void setLive() { _live = true; }
744 void setLive(bool value) { _live = value; }
745 void setMachoSection(unsigned x) { assert(x != 0); assert(x < 256); _machoSection = x; }
746 void setSectionOffset(uint64_t o){ assert(_mode == modeSectionOffset); _address = o; _mode = modeSectionOffset; }
747 void setSectionStartAddress(uint64_t a) { assert(_mode == modeSectionOffset); _address += a; _mode = modeFinalAddress; }
748 uint64_t sectionOffset() const { assert(_mode == modeSectionOffset); return _address; }
749 uint64_t finalAddress() const { assert(_mode == modeFinalAddress); return _address; }
751 bool finalAddressMode() const { return (_mode == modeFinalAddress); }
753 virtual const File* file() const = 0;
754 virtual const char* translationUnitSource() const { return NULL; }
755 virtual const char* name() const = 0;
756 virtual uint64_t objectAddress() const = 0;
757 virtual uint64_t size() const = 0;
758 virtual void copyRawContent(uint8_t buffer[]) const = 0;
759 virtual const uint8_t* rawContentPointer() const { return NULL; }
760 virtual unsigned long contentHash(const class IndirectBindingTable&) const { return 0; }
761 virtual bool canCoalesceWith(const Atom& rhs, const class IndirectBindingTable&) const { return false; }
762 virtual Fixup::iterator fixupsBegin() const { return NULL; }
763 virtual Fixup::iterator fixupsEnd() const { return NULL; }
764 bool hasFixupsOfKind(Fixup::Kind kind) const {
765 for (ld::Fixup::iterator fit = fixupsBegin(), end=fixupsEnd(); fit != end; ++fit) {
766 if ( fit->kind == kind ) return true;
770 virtual void setFile(const File* f) { }
772 virtual UnwindInfo::iterator beginUnwind() const { return NULL; }
773 virtual UnwindInfo::iterator endUnwind() const { return NULL; }
774 virtual LineInfo::iterator beginLineInfo() const { return NULL; }
775 virtual LineInfo::iterator endLineInfo() const { return NULL; }
777 void setAttributesFromAtom(const Atom& a) {
778 _section = a._section;
779 _alignmentModulus = a._alignmentModulus;
780 _alignmentPowerOf2 = a._alignmentPowerOf2;
781 _definition = a._definition;
782 _combine = a._combine;
783 _dontDeadStrip = a._dontDeadStrip;
785 _autoHide = a._autoHide;
786 _contentType = a._contentType;
787 _symbolTableInclusion = a._symbolTableInclusion;
790 _overridesADylibsWeakDef = a._overridesADylibsWeakDef;
791 _coalescedAway = a._coalescedAway;
792 _weakImportState = a._weakImportState;
796 enum AddressMode { modeSectionOffset, modeFinalAddress };
798 const Section * _section;
800 uint16_t _alignmentModulus;
801 uint8_t _alignmentPowerOf2;
802 Definition _definition : 2;
803 Combine _combine : 2;
804 bool _dontDeadStrip : 1;
808 ContentType _contentType : 5;
809 SymbolTableInclusion _symbolTableInclusion : 3;
811 AddressMode _mode: 2;
812 bool _overridesADylibsWeakDef : 1;
813 bool _coalescedAway : 1;
815 bool _dontDeadStripIfRefLive : 1;
816 unsigned _machoSection : 8;
817 WeakImportState _weakImportState : 2;
821 class IndirectBindingTable
824 virtual const char* indirectName(uint32_t bindingIndex) const = 0;
825 virtual const ld::Atom* indirectAtom(uint32_t bindingIndex) const = 0;
830 // utility classes for using std::unordered_map with c-strings
832 size_t operator()(const char* __s) const {
835 __h = 5 * __h + *__s;
841 bool operator()(const char* left, const char* right) const { return (strcmp(left, right) == 0); }
844 typedef std::unordered_set<const char*, ld::CStringHash, ld::CStringEquals> CStringSet;
850 class FinalSection : public ld::Section {
852 FinalSection(const Section& sect) : Section(sect), address(0),
853 fileOffset(0), size(0), alignment(0),
854 indirectSymTabStartIndex(0), indirectSymTabElementSize(0),
855 relocStart(0), relocCount(0),
856 hasLocalRelocs(false), hasExternalRelocs(false) {}
857 std::vector<const Atom*> atoms;
861 uint32_t alignmentPaddingBytes;
863 uint32_t indirectSymTabStartIndex;
864 uint32_t indirectSymTabElementSize;
868 bool hasExternalRelocs;
871 typedef std::map<const ld::Atom*, FinalSection*> AtomToSection;
873 virtual uint64_t assignFileOffsets() = 0;
874 virtual void setSectionSizesAndAlignments() = 0;
875 virtual ld::Internal::FinalSection* addAtom(const Atom&) = 0;
876 virtual ld::Internal::FinalSection* getFinalSection(const ld::Section& inputSection) = 0;
877 virtual ~Internal() {}
878 Internal() : bundleLoader(NULL),
879 entryPoint(NULL), classicBindingHelper(NULL),
880 lazyBindingHelper(NULL), compressedFastBinderProxy(NULL),
881 objcObjectConstraint(ld::File::objcConstraintNone),
882 objcDylibConstraint(ld::File::objcConstraintNone),
883 swiftVersion(0), cpuSubType(0), minOSVersion(0),
884 objectFileFoundWithNoVersion(false),
885 allObjectFilesScatterable(true),
886 someObjectFileHasDwarf(false), usingHugeSections(false),
887 hasThreadLocalVariableDefinitions(false),
888 hasWeakExternalSymbols(false),
889 someObjectHasOptimizationHints(false),
890 dropAllBitcode(false), embedMarkerOnly(false) { }
892 std::vector<FinalSection*> sections;
893 std::vector<ld::dylib::File*> dylibs;
894 std::vector<ld::relocatable::File::Stab> stabs;
895 AtomToSection atomToSection;
896 CStringSet linkerOptionLibraries;
897 CStringSet linkerOptionFrameworks;
898 std::vector<const ld::Atom*> indirectBindingTable;
899 std::vector<const ld::relocatable::File*> filesWithBitcode;
900 const ld::dylib::File* bundleLoader;
901 const Atom* entryPoint;
902 const Atom* classicBindingHelper;
903 const Atom* lazyBindingHelper;
904 const Atom* compressedFastBinderProxy;
905 ld::File::ObjcConstraint objcObjectConstraint;
906 ld::File::ObjcConstraint objcDylibConstraint;
907 uint8_t swiftVersion;
909 uint32_t minOSVersion;
910 uint32_t derivedPlatformLoadCommand;
911 bool objectFileFoundWithNoVersion;
912 bool allObjectFilesScatterable;
913 bool someObjectFileHasDwarf;
914 bool usingHugeSections;
915 bool hasThreadLocalVariableDefinitions;
916 bool hasWeakExternalSymbols;
917 bool someObjectHasOptimizationHints;
919 bool embedMarkerOnly;
920 std::string ltoBitcodePath;