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@
35 #include <unordered_set>
37 #include "configure.h"
44 // Abstract base class for all object or library files the linker processes.
46 // forEachAtom() iterates over the Atoms in the order they occur in the file.
48 // justInTimeforEachAtom(name) iterates over lazily created Atoms. For instance if
49 // File is a static library, justInTimeforEachAtom() will iterate over the base set
50 // of Atoms from the archive member implementing 'name'.
55 enum ObjcConstraint { objcConstraintNone, objcConstraintRetainRelease,
56 objcConstraintRetainReleaseOrGC, objcConstraintGC,
57 objcConstraintRetainReleaseForSimulator };
61 virtual ~AtomHandler() {}
62 virtual void doAtom(const class Atom&) = 0;
63 virtual void doFile(const class File&) = 0;
69 // Codifies the rules of ordering input files for symbol precedence. These are:
70 // - Input files listed on the command line are ordered according to their index in the argument list.
71 // - Input files listed in a file list are ordered first at the index of the file list argument, then
72 // by index in the file list
73 // - Input files extracted from archives are ordered using the ordinal of the archive itself plus the
74 // index of the object file within the archive
75 // - Indirect dylibs are ordered after all input files derived from the command line, in the order that
76 // they are discovered.
77 // - The LTO object file is last.
82 // The actual numeric ordinal. Lower values have higher precedence and a zero value is invalid.
83 // The 64 bit ordinal is broken into 4 16 bit chunks. The high 16 bits are a "partition" that
84 // is used to distinguish major ordinal groups: command line, indirect dylib, LTO.
85 // The remaining chunks are used according to the partition (see below).
88 Ordinal (uint64_t ordinal) : _ordinal(ordinal) {}
90 enum { kArgListPartition=0, kIndirectDylibPartition=1, kLTOPartition = 2, kLinkerOptionPartition = 2, InvalidParition=0xffff };
91 Ordinal(uint16_t partition, uint16_t majorIndex, uint16_t minorIndex, uint16_t counter) {
92 _ordinal = ((uint64_t)partition<<48) | ((uint64_t)majorIndex<<32) | ((uint64_t)minorIndex<<16) | ((uint64_t)counter<<0);
95 const uint16_t partition() const { return (_ordinal>>48)&0xffff; }
96 const uint16_t majorIndex() const { return (_ordinal>>32)&0xffff; }
97 const uint16_t minorIndex() const { return (_ordinal>>16)&0xffff; }
98 const uint16_t counter() const { return (_ordinal>>00)&0xffff; }
100 const Ordinal nextMajorIndex() const { assert(majorIndex() < 0xffff); return Ordinal(_ordinal+((uint64_t)1<<32)); }
101 const Ordinal nextMinorIndex() const { assert(minorIndex() < 0xffff); return Ordinal(_ordinal+((uint64_t)1<<16)); }
102 const Ordinal nextCounter() const { assert(counter() < 0xffff); return Ordinal(_ordinal+((uint64_t)1<<0)); }
105 Ordinal() : _ordinal(0) {};
107 static const Ordinal NullOrdinal() { return Ordinal((uint64_t)0); }
109 const bool validOrdinal() const { return _ordinal != 0; }
111 bool operator ==(const Ordinal& rhs) const { return _ordinal == rhs._ordinal; }
112 bool operator !=(const Ordinal& rhs) const { return _ordinal != rhs._ordinal; }
113 bool operator < (const Ordinal& rhs) const { return _ordinal < rhs._ordinal; }
114 bool operator > (const Ordinal& rhs) const { return _ordinal > rhs._ordinal; }
116 // For ordinals derived from the command line args the partition is ArgListPartition
117 // The majorIndex is the arg index that pulls in the file, file list, or archive.
118 // 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.
119 // The counter is used for .a files and the value is the index of the object in the archive.
120 // Thus, an object pulled in from a .a that was listed in a file list could use all three fields.
121 static const Ordinal makeArgOrdinal(uint16_t argIndex) { return Ordinal(kArgListPartition, argIndex, 0, 0); };
122 const Ordinal nextFileListOrdinal() const { return nextMinorIndex(); }
123 const Ordinal archiveOrdinalWithMemberIndex(uint16_t index) const { return Ordinal(kArgListPartition, majorIndex(), minorIndex(), index); }
125 // For indirect libraries the partition is IndirectDylibPartition and the counter is used or order the libraries.
126 static const ld::File::Ordinal indirectDylibBase() { return Ordinal(kIndirectDylibPartition, 0, 0, 0); }
127 const Ordinal nextIndirectDylibOrdinal() const { return nextCounter(); }
129 // For the LTO mach-o the partition is LTOPartition. As there is only one LTO file no other fields are needed.
130 static const ld::File::Ordinal LTOOrdinal() { return Ordinal(kLTOPartition, 0, 0, 0); }
132 // For linker options embedded in object files
133 static const ld::File::Ordinal linkeOptionBase() { return Ordinal(kIndirectDylibPartition, 1, 0, 0); }
134 const Ordinal nextLinkerOptionOrdinal() { nextCounter(); return *this; };
138 typedef enum { Reloc, Dylib, Archive, Other } Type;
140 File(const char* pth, time_t modTime, Ordinal ord, Type type)
141 : _path(pth), _modTime(modTime), _ordinal(ord), _type(type) { }
143 const char* path() const { return _path; }
144 time_t modificationTime() const{ return _modTime; }
145 Ordinal ordinal() const { return _ordinal; }
146 virtual bool forEachAtom(AtomHandler&) const = 0;
147 virtual bool justInTimeforEachAtom(const char* name, AtomHandler&) const = 0;
148 virtual ObjcConstraint objCConstraint() const { return objcConstraintNone; }
149 virtual uint32_t cpuSubType() const { return 0; }
150 virtual uint32_t subFileCount() const { return 1; }
151 bool fileExists() const { return _modTime != 0; }
152 Type type() const { return _type; }
156 const Ordinal _ordinal;
162 // minumum OS versions
164 enum MacVersionMin { macVersionUnset=0, mac10_4=0x000A0400, mac10_5=0x000A0500,
165 mac10_6=0x000A0600, mac10_7=0x000A0700, mac10_8=0x000A0800,
166 mac10_9=0x000A0900, mac10_Future=0x10000000 };
167 enum IOSVersionMin { iOSVersionUnset=0, iOS_2_0=0x00020000, iOS_3_1=0x00030100,
168 iOS_4_2=0x00040200, iOS_4_3=0x00040300, iOS_5_0=0x00050000,
169 iOS_6_0=0x00060000, iOS_7_0=0x00070000, iOS_Future=0x10000000};
171 namespace relocatable {
173 // ld::relocatable::File
175 // Abstract base class for object files the linker processes.
177 // debugInfo() returns if the object file contains debugger information (stabs or dwarf).
179 // stabs() lazily creates a vector of Stab objects for each atom
181 // canScatterAtoms() true for all compiler generated code. Hand written assembly can opt-in
182 // via .subsections_via_symbols directive. When true it means the linker can break up section
183 // content at symbol boundaries and do optimizations like coalescing, dead code stripping, or
184 // apply order files.
186 // optimize() used by libLTO to lazily generate code from llvm bit-code files
188 class File : public ld::File
191 enum DebugInfoKind { kDebugInfoNone=0, kDebugInfoStabs=1, kDebugInfoDwarf=2, kDebugInfoStabsUUID=3 };
193 const class Atom* atom;
200 typedef const std::vector< std::vector<const char*> > LinkerOptionsList;
202 File(const char* pth, time_t modTime, Ordinal ord)
203 : ld::File(pth, modTime, ord, Reloc) { }
205 virtual DebugInfoKind debugInfo() const = 0;
206 virtual const char* debugInfoPath() const { return path(); }
207 virtual time_t debugInfoModificationTime() const { return modificationTime(); }
208 virtual const std::vector<Stab>* stabs() const = 0;
209 virtual bool canScatterAtoms() const = 0;
210 virtual bool hasLongBranchStubs() { return false; }
211 virtual LinkerOptionsList* linkerOptions() const = 0;
213 } // namespace relocatable
221 // Abstract base class for dynamic shared libraries read by the linker processes.
223 class File : public ld::File
229 virtual ~DylibHandler() {}
230 virtual File* findDylib(const char* installPath, const char* fromPath) = 0;
233 File(const char* pth, time_t modTime, Ordinal ord)
234 : ld::File(pth, modTime, ord, Dylib), _dylibInstallPath(NULL),
235 _dylibTimeStamp(0), _dylibCurrentVersion(0), _dylibCompatibilityVersion(0),
236 _explicitlyLinked(false), _implicitlyLinked(false),
237 _lazyLoadedDylib(false), _forcedWeakLinked(false), _reExported(false),
238 _upward(false), _dead(false) { }
239 const char* installPath() const { return _dylibInstallPath; }
240 uint32_t timestamp() const { return _dylibTimeStamp; }
241 uint32_t currentVersion() const { return _dylibCurrentVersion; }
242 uint32_t compatibilityVersion() const{ return _dylibCompatibilityVersion; }
243 void setExplicitlyLinked() { _explicitlyLinked = true; }
244 bool explicitlyLinked() const { return _explicitlyLinked; }
245 void setImplicitlyLinked() { _implicitlyLinked = true; }
246 bool implicitlyLinked() const { return _implicitlyLinked; }
248 // attributes of how dylib will be used when linked
249 void setWillBeLazyLoadedDylb() { _lazyLoadedDylib = true; }
250 bool willBeLazyLoadedDylib() const { return _lazyLoadedDylib; }
251 void setForcedWeakLinked() { _forcedWeakLinked = true; }
252 bool forcedWeakLinked() const { return _forcedWeakLinked; }
254 void setWillBeReExported() { _reExported = true; }
255 bool willBeReExported() const { return _reExported; }
256 void setWillBeUpwardDylib() { _upward = true; }
257 bool willBeUpwardDylib() const { return _upward; }
258 void setWillBeRemoved(bool value) { _dead = value; }
259 bool willRemoved() const { return _dead; }
261 virtual void processIndirectLibraries(DylibHandler* handler, bool addImplicitDylibs) = 0;
262 virtual bool providedExportAtom() const = 0;
263 virtual const char* parentUmbrella() const = 0;
264 virtual const std::vector<const char*>* allowableClients() const = 0;
265 virtual bool hasWeakExternals() const = 0;
266 virtual bool deadStrippable() const = 0;
267 virtual bool hasWeakDefinition(const char* name) const = 0;
268 virtual bool hasPublicInstallName() const = 0;
269 virtual bool allSymbolsAreWeakImported() const = 0;
270 virtual const void* codeSignatureDR() const = 0;
271 virtual bool installPathVersionSpecific() const { return false; }
273 const char* _dylibInstallPath;
274 uint32_t _dylibTimeStamp;
275 uint32_t _dylibCurrentVersion;
276 uint32_t _dylibCompatibilityVersion;
277 bool _explicitlyLinked;
278 bool _implicitlyLinked;
279 bool _lazyLoadedDylib;
280 bool _forcedWeakLinked;
292 // Abstract base class for static libraries read by the linker processes.
294 class File : public ld::File
297 File(const char* pth, time_t modTime, Ordinal ord)
298 : ld::File(pth, modTime, ord, Archive) { }
300 virtual bool justInTimeDataOnlyforEachAtom(const char* name, AtomHandler&) const = 0;
302 } // namespace archive
311 enum Type { typeUnclassified, typeCode, typePageZero, typeImportProxies, typeLinkEdit, typeMachHeader, typeStack,
312 typeLiteral4, typeLiteral8, typeLiteral16, typeConstants, typeTempLTO,
313 typeCString, typeNonStdCString, typeCStringPointer, typeUTF16Strings, typeCFString, typeObjC1Classes,
314 typeCFI, typeLSDA, typeDtraceDOF, typeUnwindInfo, typeObjCClassRefs, typeObjC2CategoryList,
315 typeZeroFill, typeTentativeDefs, typeLazyPointer, typeStub, typeNonLazyPointer, typeDyldInfo,
316 typeLazyDylibPointer, typeStubHelper, typeInitializerPointers, typeTerminatorPointers,
317 typeStubClose, typeLazyPointerClose, typeAbsoluteSymbols,
318 typeTLVDefs, typeTLVZeroFill, typeTLVInitialValues, typeTLVInitializerPointers, typeTLVPointers,
319 typeFirstSection, typeLastSection, typeDebug };
322 Section(const char* sgName, const char* sctName,
323 Type t, bool hidden=false)
324 : _segmentName(sgName), _sectionName(sctName),
325 _type(t), _hidden(hidden) {}
326 Section(const Section& sect)
327 : _segmentName(sect.segmentName()), _sectionName(sect.sectionName()),
328 _type(sect.type()), _hidden(sect.isSectionHidden()) {}
330 bool operator==(const Section& rhs) const { return ( (_hidden==rhs._hidden) &&
331 (strcmp(_segmentName, rhs._segmentName)==0) &&
332 (strcmp(_sectionName, rhs._sectionName)==0) ); }
333 bool operator!=(const Section& rhs) const { return ! (*this == rhs); }
334 const char* segmentName() const { return _segmentName; }
335 const char* sectionName() const { return _sectionName; }
336 Type type() const { return _type; }
337 bool isSectionHidden() const { return _hidden; }
340 const char* _segmentName;
341 const char* _sectionName;
351 // A Fixup describes how part of an Atom's content must be fixed up. For instance,
352 // an instruction may contain a displacement to another Atom that must be
353 // fixed up by the linker.
355 // A Fixup my reference another Atom. There are two kinds of references: direct and by-name.
356 // With a direct reference, the target is bound by the File that created it.
357 // For instance a reference to a static would produce a direct reference.
358 // A by-name reference requires the linker to find the target Atom with the
359 // required name in order to be bound.
361 // For a link to succeed all Fixup must be bound.
363 // A Reference also has a fix-up-offset. This is the offset into the content of the
364 // Atom holding the reference where the fix-up (relocation) will be applied.
369 enum TargetBinding { bindingNone, bindingByNameUnbound, bindingDirectlyBound, bindingByContentBound, bindingsIndirectlyBound };
370 enum Cluster { k1of1, k1of2, k2of2, k1of3, k2of3, k3of3, k1of4, k2of4, k3of4, k4of4, k1of5, k2of5, k3of5, k4of5, k5of5 };
371 enum Kind { kindNone, kindNoneFollowOn,
373 kindNoneGroupSubordinate,
374 kindNoneGroupSubordinateFDE, kindNoneGroupSubordinateLSDA, kindNoneGroupSubordinatePersonality,
375 // value calculations
376 kindSetTargetAddress,
377 kindSubtractTargetAddress,
380 kindSetTargetImageOffset,
381 kindSetTargetSectionOffset,
382 kindSetTargetTLVTemplateOffset,
383 // pointer store kinds (of current calculated value)
385 kindStoreLittleEndian16,
386 kindStoreLittleEndianLow24of32,
387 kindStoreLittleEndian32,
388 kindStoreLittleEndian64,
389 kindStoreBigEndian16,
390 kindStoreBigEndianLow24of32,
391 kindStoreBigEndian32,
392 kindStoreBigEndian64,
393 // Intel specific store kinds
394 kindStoreX86BranchPCRel8, kindStoreX86BranchPCRel32,
395 kindStoreX86PCRel8, kindStoreX86PCRel16,
396 kindStoreX86PCRel32, kindStoreX86PCRel32_1, kindStoreX86PCRel32_2, kindStoreX86PCRel32_4,
397 kindStoreX86PCRel32GOTLoad, kindStoreX86PCRel32GOTLoadNowLEA, kindStoreX86PCRel32GOT,
398 kindStoreX86PCRel32TLVLoad, kindStoreX86PCRel32TLVLoadNowLEA,
399 kindStoreX86Abs32TLVLoad, kindStoreX86Abs32TLVLoadNowLEA,
400 // ARM specific store kinds
401 kindStoreARMBranch24, kindStoreThumbBranch22,
403 kindStoreARMLow16, kindStoreARMHigh16,
404 kindStoreThumbLow16, kindStoreThumbHigh16,
405 #if SUPPORT_ARCH_arm64
406 // ARM64 specific store kinds
407 kindStoreARM64Branch26,
408 kindStoreARM64Page21, kindStoreARM64PageOff12,
409 kindStoreARM64GOTLoadPage21, kindStoreARM64GOTLoadPageOff12,
410 kindStoreARM64GOTLeaPage21, kindStoreARM64GOTLeaPageOff12,
411 kindStoreARM64TLVPLoadPage21, kindStoreARM64TLVPLoadPageOff12,
412 kindStoreARM64PointerToGOT, kindStoreARM64PCRelToGOT,
416 kindStoreX86DtraceCallSiteNop, kindStoreX86DtraceIsEnableSiteClear,
417 kindStoreARMDtraceCallSiteNop, kindStoreARMDtraceIsEnableSiteClear,
418 kindStoreARM64DtraceCallSiteNop, kindStoreARM64DtraceIsEnableSiteClear,
419 kindStoreThumbDtraceCallSiteNop, kindStoreThumbDtraceIsEnableSiteClear,
421 kindLazyTarget, kindSetLazyOffset,
422 // data-in-code markers
423 kindDataInCodeStartData, kindDataInCodeStartJT8, kindDataInCodeStartJT16,
424 kindDataInCodeStartJT32, kindDataInCodeStartJTA32, kindDataInCodeEnd,
425 // pointer store combinations
426 kindStoreTargetAddressLittleEndian32, // kindSetTargetAddress + kindStoreLittleEndian32
427 kindStoreTargetAddressLittleEndian64, // kindSetTargetAddress + kindStoreLittleEndian64
428 kindStoreTargetAddressBigEndian32, // kindSetTargetAddress + kindStoreBigEndian32
429 kindStoreTargetAddressBigEndian64, // kindSetTargetAddress + kindStoreBigEndian364
430 kindSetTargetTLVTemplateOffsetLittleEndian32, // kindSetTargetTLVTemplateOffset + kindStoreLittleEndian32
431 kindSetTargetTLVTemplateOffsetLittleEndian64, // kindSetTargetTLVTemplateOffset + kindStoreLittleEndian64
432 // Intel value calculation and store combinations
433 kindStoreTargetAddressX86PCRel32, // kindSetTargetAddress + kindStoreX86PCRel32
434 kindStoreTargetAddressX86BranchPCRel32, // kindSetTargetAddress + kindStoreX86BranchPCRel32
435 kindStoreTargetAddressX86PCRel32GOTLoad,// kindSetTargetAddress + kindStoreX86PCRel32GOTLoad
436 kindStoreTargetAddressX86PCRel32GOTLoadNowLEA,// kindSetTargetAddress + kindStoreX86PCRel32GOTLoadNowLEA
437 kindStoreTargetAddressX86PCRel32TLVLoad, // kindSetTargetAddress + kindStoreX86PCRel32TLVLoad
438 kindStoreTargetAddressX86PCRel32TLVLoadNowLEA, // kindSetTargetAddress + kindStoreX86PCRel32TLVLoadNowLEA
439 kindStoreTargetAddressX86Abs32TLVLoad, // kindSetTargetAddress + kindStoreX86Abs32TLVLoad
440 kindStoreTargetAddressX86Abs32TLVLoadNowLEA, // kindSetTargetAddress + kindStoreX86Abs32TLVLoadNowLEA
441 // ARM value calculation and store combinations
442 kindStoreTargetAddressARMBranch24, // kindSetTargetAddress + kindStoreARMBranch24
443 kindStoreTargetAddressThumbBranch22, // kindSetTargetAddress + kindStoreThumbBranch22
444 kindStoreTargetAddressARMLoad12, // kindSetTargetAddress + kindStoreARMLoad12
445 #if SUPPORT_ARCH_arm64
446 // ARM64 value calculation and store combinations
447 kindStoreTargetAddressARM64Branch26, // kindSetTargetAddress + kindStoreARM64Branch26
448 kindStoreTargetAddressARM64Page21, // kindSetTargetAddress + kindStoreARM64Page21
449 kindStoreTargetAddressARM64PageOff12, // kindSetTargetAddress + kindStoreARM64PageOff12
450 kindStoreTargetAddressARM64GOTLoadPage21, // kindSetTargetAddress + kindStoreARM64GOTLoadPage21
451 kindStoreTargetAddressARM64GOTLoadPageOff12,// kindSetTargetAddress + kindStoreARM64GOTLoadPageOff12
452 kindStoreTargetAddressARM64GOTLeaPage21, // kindSetTargetAddress + kindStoreARM64GOTLeaPage21
453 kindStoreTargetAddressARM64GOTLeaPageOff12, // kindSetTargetAddress + kindStoreARM64GOTLeaPageOff12
461 uint32_t bindingIndex;
463 uint32_t offsetInAtom;
465 Cluster clusterSize : 4;
467 TargetBinding binding : 3;
468 bool contentAddendOnly : 1;
469 bool contentDetlaToAddendOnly : 1;
470 bool contentIgnoresAddend : 1;
472 typedef Fixup* iterator;
475 offsetInAtom(0), kind(kindNone), clusterSize(k1of1), weakImport(false),
476 binding(bindingNone),
477 contentAddendOnly(false), contentDetlaToAddendOnly(false), contentIgnoresAddend(false) { u.target = NULL; }
479 Fixup(Kind k, Atom* targetAtom) :
480 offsetInAtom(0), kind(k), clusterSize(k1of1), weakImport(false),
481 binding(Fixup::bindingDirectlyBound),
482 contentAddendOnly(false), contentDetlaToAddendOnly(false), contentIgnoresAddend(false)
483 { assert(targetAtom != NULL); u.target = targetAtom; }
485 Fixup(uint32_t off, Cluster c, Kind k) :
486 offsetInAtom(off), kind(k), clusterSize(c), weakImport(false),
487 binding(Fixup::bindingNone),
488 contentAddendOnly(false), contentDetlaToAddendOnly(false), contentIgnoresAddend(false)
491 Fixup(uint32_t off, Cluster c, Kind k, bool weakIm, const char* name) :
492 offsetInAtom(off), kind(k), clusterSize(c), weakImport(weakIm),
493 binding(Fixup::bindingByNameUnbound),
494 contentAddendOnly(false), contentDetlaToAddendOnly(false), contentIgnoresAddend(false)
495 { assert(name != NULL); u.name = name; }
497 Fixup(uint32_t off, Cluster c, Kind k, TargetBinding b, const char* name) :
498 offsetInAtom(off), kind(k), clusterSize(c), weakImport(false), binding(b),
499 contentAddendOnly(false), contentDetlaToAddendOnly(false), contentIgnoresAddend(false)
500 { assert(name != NULL); u.name = name; }
502 Fixup(uint32_t off, Cluster c, Kind k, const Atom* targetAtom) :
503 offsetInAtom(off), kind(k), clusterSize(c), weakImport(false),
504 binding(Fixup::bindingDirectlyBound),
505 contentAddendOnly(false), contentDetlaToAddendOnly(false), contentIgnoresAddend(false)
506 { assert(targetAtom != NULL); u.target = targetAtom; }
508 Fixup(uint32_t off, Cluster c, Kind k, TargetBinding b, const Atom* targetAtom) :
509 offsetInAtom(off), kind(k), clusterSize(c), weakImport(false), binding(b),
510 contentAddendOnly(false), contentDetlaToAddendOnly(false), contentIgnoresAddend(false)
511 { assert(targetAtom != NULL); u.target = targetAtom; }
513 Fixup(uint32_t off, Cluster c, Kind k, uint64_t addend) :
514 offsetInAtom(off), kind(k), clusterSize(c), weakImport(false),
515 binding(Fixup::bindingNone),
516 contentAddendOnly(false), contentDetlaToAddendOnly(false), contentIgnoresAddend(false)
517 { u.addend = addend; }
519 bool firstInCluster() const {
520 switch (clusterSize) {
533 bool lastInCluster() const {
534 switch (clusterSize) {
552 // An atom is the fundamental unit of linking. A C function or global variable is an atom.
553 // An atom has content and attributes. The content of a function atom is the instructions
554 // that implement the function. The content of a global variable atom is its initial bits.
557 // The name of an atom is the label name generated by the compiler. A C compiler names foo()
558 // as _foo. A C++ compiler names foo() as __Z3foov.
559 // The name refers to the first byte of the content. An atom cannot have multiple entry points.
560 // Such code is modeled as multiple atoms, each having a "follow on" reference to the next.
561 // A "follow on" reference is a contraint to the linker to the atoms must be laid out contiguously.
564 // An atom is in one of three scopes: translation-unit, linkage-unit, or global. These correspond
565 // to the C visibility of static, hidden, default.
568 // An atom is one of five defintion kinds:
569 // regular Most atoms.
570 // weak C++ compiler makes some functions weak if there might be multiple copies
571 // that the linker needs to coalesce.
572 // tentative A straggler from ancient C when the extern did not exist. "int foo;" is ambiguous.
573 // It could be a prototype or it could be a definition.
574 // external This is a "proxy" atom produced by a dylib reader. It has no content. It exists
575 // so that the graph of Atoms can be complete.
576 // external-weak Same as external, but the definition in the dylib is weak.
578 // SymbolTableInclusion:
579 // An atom may or may not be in the symbol table in an object file.
580 // in Most atoms for functions or global data
581 // not-in Anonymous atoms such literal c-strings, or other compiler generated data
582 // not-in-final Atom whose name should not be in the symbol table of final linkd image (e.g. 'l' labels .eh labels)
583 // in-never-strip Atom whose name the strip tool should never remove (e.g. REFERENCED_DYNAMICALLY in mach-o)
586 // Some atoms require specially processing by the linker based on their content. For instance, zero-fill data
587 // atom are group together at the end of the DATA segment to reduce disk size.
590 // For reproducability, the linker lays out atoms in the order they occurred in the source (object) files.
591 // The objectAddress() method returns the address of an atom in the object file so that the linker
592 // can arrange the atoms.
598 enum Scope { scopeTranslationUnit, scopeLinkageUnit, scopeGlobal };
599 enum Definition { definitionRegular, definitionTentative, definitionAbsolute, definitionProxy };
600 enum Combine { combineNever, combineByName, combineByNameAndContent, combineByNameAndReferences };
601 enum ContentType { typeUnclassified, typeZeroFill, typeCString, typeCFI, typeLSDA, typeSectionStart,
602 typeSectionEnd, typeBranchIsland, typeLazyPointer, typeStub, typeNonLazyPointer,
603 typeLazyDylibPointer, typeStubHelper, typeInitializerPointers, typeTerminatorPointers,
604 typeLTOtemporary, typeResolver,
605 typeTLV, typeTLVZeroFill, typeTLVInitialValue, typeTLVInitializerPointers };
607 enum SymbolTableInclusion { symbolTableNotIn, symbolTableNotInFinalLinkedImages, symbolTableIn,
608 symbolTableInAndNeverStrip, symbolTableInAsAbsolute,
609 symbolTableInWithRandomAutoStripLabel };
610 enum WeakImportState { weakImportUnset, weakImportTrue, weakImportFalse };
613 Alignment(int p2, int m=0) : powerOf2(p2), modulus(m) {}
614 uint8_t trailingZeros() const { return (modulus==0) ? powerOf2 : __builtin_ctz(modulus); }
619 const char* fileName;
623 typedef LineInfo* iterator;
626 uint32_t startOffset;
629 typedef UnwindInfo* iterator;
632 Atom(const Section& sect, Definition d, Combine c, Scope s, ContentType ct,
633 SymbolTableInclusion i, bool dds, bool thumb, bool al, Alignment a) :
634 _section(§), _address(0), _alignmentModulus(a.modulus),
635 _alignmentPowerOf2(a.powerOf2), _definition(d), _combine(c),
636 _dontDeadStrip(dds), _thumb(thumb), _alias(al), _autoHide(false),
637 _contentType(ct), _symbolTableInclusion(i),
638 _scope(s), _mode(modeSectionOffset),
639 _overridesADylibsWeakDef(false), _coalescedAway(false),
640 _live(false), _machoSection(0), _weakImportState(weakImportUnset)
643 switch ( _combine ) {
644 case combineByNameAndContent:
645 case combineByNameAndReferences:
646 assert(_symbolTableInclusion != symbolTableIn);
647 assert(_scope != scopeGlobal);
657 const Section& section() const { return *_section; }
658 Definition definition() const { return _definition; }
659 Combine combine() const { return _combine; }
660 Scope scope() const { return _scope; }
661 ContentType contentType() const { return _contentType; }
662 SymbolTableInclusion symbolTableInclusion() const{ return _symbolTableInclusion; }
663 bool dontDeadStrip() const { return _dontDeadStrip; }
664 bool isThumb() const { return _thumb; }
665 bool isAlias() const { return _alias; }
666 Alignment alignment() const { return Alignment(_alignmentPowerOf2, _alignmentModulus); }
667 bool overridesDylibsWeakDef() const { return _overridesADylibsWeakDef; }
668 bool coalescedAway() const { return _coalescedAway; }
669 bool weakImported() const { return _weakImportState == weakImportTrue; }
670 WeakImportState weakImportState() const { return _weakImportState; }
671 bool autoHide() const { return _autoHide; }
672 bool live() const { return _live; }
673 uint8_t machoSection() const { assert(_machoSection != 0); return _machoSection; }
675 void setScope(Scope s) { _scope = s; }
676 void setSymbolTableInclusion(SymbolTableInclusion i)
677 { _symbolTableInclusion = i; }
678 void setCombine(Combine c) { _combine = c; }
679 void setOverridesDylibsWeakDef() { _overridesADylibsWeakDef = true; }
680 void setCoalescedAway() { _coalescedAway = true; }
681 void setWeakImportState(bool w) { assert(_definition == definitionProxy); _weakImportState = ( w ? weakImportTrue : weakImportFalse); }
682 void setAutoHide() { _autoHide = true; }
683 void setLive() { _live = true; }
684 void setLive(bool value) { _live = value; }
685 void setMachoSection(unsigned x) { assert(x != 0); assert(x < 256); _machoSection = x; }
686 void setSectionOffset(uint64_t o){ assert(_mode == modeSectionOffset); _address = o; _mode = modeSectionOffset; }
687 void setSectionStartAddress(uint64_t a) { assert(_mode == modeSectionOffset); _address += a; _mode = modeFinalAddress; }
688 uint64_t sectionOffset() const { assert(_mode == modeSectionOffset); return _address; }
689 uint64_t finalAddress() const { assert(_mode == modeFinalAddress); return _address; }
691 bool finalAddressMode() const { return (_mode == modeFinalAddress); }
693 virtual const File* file() const = 0;
694 virtual const char* translationUnitSource() const { return NULL; }
695 virtual const char* name() const = 0;
696 virtual uint64_t objectAddress() const = 0;
697 virtual uint64_t size() const = 0;
698 virtual void copyRawContent(uint8_t buffer[]) const = 0;
699 virtual const uint8_t* rawContentPointer() const { return NULL; }
700 virtual unsigned long contentHash(const class IndirectBindingTable&) const { return 0; }
701 virtual bool canCoalesceWith(const Atom& rhs, const class IndirectBindingTable&) const { return false; }
702 virtual Fixup::iterator fixupsBegin() const { return NULL; }
703 virtual Fixup::iterator fixupsEnd() const { return NULL; }
704 bool hasFixupsOfKind(Fixup::Kind kind) const {
705 for (ld::Fixup::iterator fit = fixupsBegin(), end=fixupsEnd(); fit != end; ++fit) {
706 if ( fit->kind == kind ) return true;
711 virtual UnwindInfo::iterator beginUnwind() const { return NULL; }
712 virtual UnwindInfo::iterator endUnwind() const { return NULL; }
713 virtual LineInfo::iterator beginLineInfo() const { return NULL; }
714 virtual LineInfo::iterator endLineInfo() const { return NULL; }
717 enum AddressMode { modeSectionOffset, modeFinalAddress };
719 void setAttributesFromAtom(const Atom& a) {
720 _section = a._section;
721 _alignmentModulus = a._alignmentModulus;
722 _alignmentPowerOf2 = a._alignmentPowerOf2;
723 _definition = a._definition;
724 _combine = a._combine;
725 _dontDeadStrip = a._dontDeadStrip;
727 _autoHide = a._autoHide;
728 _contentType = a._contentType;
729 _symbolTableInclusion = a._symbolTableInclusion;
732 _overridesADylibsWeakDef = a._overridesADylibsWeakDef;
733 _coalescedAway = a._coalescedAway;
734 _weakImportState = a._weakImportState;
737 const Section * _section;
739 uint16_t _alignmentModulus;
740 uint8_t _alignmentPowerOf2;
741 Definition _definition : 2;
742 Combine _combine : 2;
743 bool _dontDeadStrip : 1;
747 ContentType _contentType : 5;
748 SymbolTableInclusion _symbolTableInclusion : 3;
750 AddressMode _mode: 2;
751 bool _overridesADylibsWeakDef : 1;
752 bool _coalescedAway : 1;
754 unsigned _machoSection : 8;
755 WeakImportState _weakImportState : 2;
759 class IndirectBindingTable
762 virtual const char* indirectName(uint32_t bindingIndex) const = 0;
763 virtual const ld::Atom* indirectAtom(uint32_t bindingIndex) const = 0;
768 // utility classes for using std::unordered_map with c-strings
770 size_t operator()(const char* __s) const {
773 __h = 5 * __h + *__s;
779 bool operator()(const char* left, const char* right) const { return (strcmp(left, right) == 0); }
782 typedef std::unordered_set<const char*, ld::CStringHash, ld::CStringEquals> CStringSet;
787 class FinalSection : public ld::Section {
789 FinalSection(const Section& sect) : Section(sect), address(0),
790 fileOffset(0), size(0), alignment(0),
791 indirectSymTabStartIndex(0), indirectSymTabElementSize(0),
792 relocStart(0), relocCount(0),
793 hasLocalRelocs(false), hasExternalRelocs(false) {}
794 std::vector<const Atom*> atoms;
798 uint32_t alignmentPaddingBytes;
800 uint32_t indirectSymTabStartIndex;
801 uint32_t indirectSymTabElementSize;
805 bool hasExternalRelocs;
809 virtual ld::Internal::FinalSection* addAtom(const Atom&) = 0;
810 virtual ld::Internal::FinalSection* getFinalSection(const ld::Section& inputSection) = 0;
811 virtual ~Internal() {}
812 Internal() : bundleLoader(NULL),
813 entryPoint(NULL), classicBindingHelper(NULL),
814 lazyBindingHelper(NULL), compressedFastBinderProxy(NULL),
815 objcObjectConstraint(ld::File::objcConstraintNone),
816 objcDylibConstraint(ld::File::objcConstraintNone),
818 allObjectFilesScatterable(true),
819 someObjectFileHasDwarf(false), usingHugeSections(false) { }
821 std::vector<FinalSection*> sections;
822 std::vector<ld::dylib::File*> dylibs;
823 std::vector<ld::relocatable::File::Stab> stabs;
824 CStringSet linkerOptionLibraries;
825 CStringSet linkerOptionFrameworks;
826 std::vector<const ld::Atom*> indirectBindingTable;
827 const ld::dylib::File* bundleLoader;
828 const Atom* entryPoint;
829 const Atom* classicBindingHelper;
830 const Atom* lazyBindingHelper;
831 const Atom* compressedFastBinderProxy;
832 ld::File::ObjcConstraint objcObjectConstraint;
833 ld::File::ObjcConstraint objcDylibConstraint;
835 bool allObjectFilesScatterable;
836 bool someObjectFileHasDwarf;
837 bool usingHugeSections;