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 uint8_t swiftVersion() const { return 0; }
150 virtual uint32_t cpuSubType() const { return 0; }
151 virtual uint32_t subFileCount() const { return 1; }
152 bool fileExists() const { return _modTime != 0; }
153 Type type() const { return _type; }
157 const Ordinal _ordinal;
163 // minumum OS versions
165 enum MacVersionMin { macVersionUnset=0, mac10_4=0x000A0400, mac10_5=0x000A0500,
166 mac10_6=0x000A0600, mac10_7=0x000A0700, mac10_8=0x000A0800,
167 mac10_9=0x000A0900, mac10_Future=0x10000000 };
168 enum IOSVersionMin { iOSVersionUnset=0, iOS_2_0=0x00020000, iOS_3_1=0x00030100,
169 iOS_4_2=0x00040200, iOS_4_3=0x00040300, iOS_5_0=0x00050000,
170 iOS_6_0=0x00060000, iOS_7_0=0x00070000, iOS_8_0=0x00080000,
171 iOS_9_0=0x00090000, iOS_Future=0x10000000};
173 namespace relocatable {
175 // ld::relocatable::File
177 // Abstract base class for object files the linker processes.
179 // debugInfo() returns if the object file contains debugger information (stabs or dwarf).
181 // stabs() lazily creates a vector of Stab objects for each atom
183 // canScatterAtoms() true for all compiler generated code. Hand written assembly can opt-in
184 // via .subsections_via_symbols directive. When true it means the linker can break up section
185 // content at symbol boundaries and do optimizations like coalescing, dead code stripping, or
186 // apply order files.
188 // optimize() used by libLTO to lazily generate code from llvm bit-code files
190 class File : public ld::File
193 enum DebugInfoKind { kDebugInfoNone=0, kDebugInfoStabs=1, kDebugInfoDwarf=2, kDebugInfoStabsUUID=3 };
195 const class Atom* atom;
202 typedef const std::vector< std::vector<const char*> > LinkerOptionsList;
204 File(const char* pth, time_t modTime, Ordinal ord)
205 : ld::File(pth, modTime, ord, Reloc) { }
207 virtual DebugInfoKind debugInfo() const = 0;
208 virtual const char* debugInfoPath() const { return path(); }
209 virtual time_t debugInfoModificationTime() const { return modificationTime(); }
210 virtual const std::vector<Stab>* stabs() const = 0;
211 virtual bool canScatterAtoms() const = 0;
212 virtual bool hasLongBranchStubs() { return false; }
213 virtual LinkerOptionsList* linkerOptions() const = 0;
215 } // namespace relocatable
223 // Abstract base class for dynamic shared libraries read by the linker processes.
225 class File : public ld::File
231 virtual ~DylibHandler() {}
232 virtual File* findDylib(const char* installPath, const char* fromPath) = 0;
235 File(const char* pth, time_t modTime, Ordinal ord)
236 : ld::File(pth, modTime, ord, Dylib), _dylibInstallPath(NULL),
237 _dylibTimeStamp(0), _dylibCurrentVersion(0), _dylibCompatibilityVersion(0),
238 _explicitlyLinked(false), _implicitlyLinked(false),
239 _lazyLoadedDylib(false), _forcedWeakLinked(false), _reExported(false),
240 _upward(false), _dead(false) { }
241 const char* installPath() const { return _dylibInstallPath; }
242 uint32_t timestamp() const { return _dylibTimeStamp; }
243 uint32_t currentVersion() const { return _dylibCurrentVersion; }
244 uint32_t compatibilityVersion() const{ return _dylibCompatibilityVersion; }
245 void setExplicitlyLinked() { _explicitlyLinked = true; }
246 bool explicitlyLinked() const { return _explicitlyLinked; }
247 void setImplicitlyLinked() { _implicitlyLinked = true; }
248 bool implicitlyLinked() const { return _implicitlyLinked; }
250 // attributes of how dylib will be used when linked
251 void setWillBeLazyLoadedDylb() { _lazyLoadedDylib = true; }
252 bool willBeLazyLoadedDylib() const { return _lazyLoadedDylib; }
253 void setForcedWeakLinked() { _forcedWeakLinked = true; }
254 bool forcedWeakLinked() const { return _forcedWeakLinked; }
256 void setWillBeReExported() { _reExported = true; }
257 bool willBeReExported() const { return _reExported; }
258 void setWillBeUpwardDylib() { _upward = true; }
259 bool willBeUpwardDylib() const { return _upward; }
260 void setWillBeRemoved(bool value) { _dead = value; }
261 bool willRemoved() const { return _dead; }
263 virtual void processIndirectLibraries(DylibHandler* handler, bool addImplicitDylibs) = 0;
264 virtual bool providedExportAtom() const = 0;
265 virtual const char* parentUmbrella() const = 0;
266 virtual const std::vector<const char*>* allowableClients() const = 0;
267 virtual bool hasWeakExternals() const = 0;
268 virtual bool deadStrippable() const = 0;
269 virtual bool hasWeakDefinition(const char* name) const = 0;
270 virtual bool hasPublicInstallName() const = 0;
271 virtual bool allSymbolsAreWeakImported() const = 0;
272 virtual const void* codeSignatureDR() const = 0;
273 virtual bool installPathVersionSpecific() const { return false; }
274 virtual bool appExtensionSafe() const = 0;
275 virtual MacVersionMin macMinVersion() const { return macVersionUnset; }
276 virtual IOSVersionMin iOSMinVersion() const { return iOSVersionUnset; }
279 const char* _dylibInstallPath;
280 uint32_t _dylibTimeStamp;
281 uint32_t _dylibCurrentVersion;
282 uint32_t _dylibCompatibilityVersion;
283 bool _explicitlyLinked;
284 bool _implicitlyLinked;
285 bool _lazyLoadedDylib;
286 bool _forcedWeakLinked;
298 // Abstract base class for static libraries read by the linker processes.
300 class File : public ld::File
303 File(const char* pth, time_t modTime, Ordinal ord)
304 : ld::File(pth, modTime, ord, Archive) { }
306 virtual bool justInTimeDataOnlyforEachAtom(const char* name, AtomHandler&) const = 0;
308 } // namespace archive
317 enum Type { typeUnclassified, typeCode, typePageZero, typeImportProxies, typeLinkEdit, typeMachHeader, typeStack,
318 typeLiteral4, typeLiteral8, typeLiteral16, typeConstants, typeTempLTO, typeTempAlias,
319 typeCString, typeNonStdCString, typeCStringPointer, typeUTF16Strings, typeCFString, typeObjC1Classes,
320 typeCFI, typeLSDA, typeDtraceDOF, typeUnwindInfo, typeObjCClassRefs, typeObjC2CategoryList,
321 typeZeroFill, typeTentativeDefs, typeLazyPointer, typeStub, typeNonLazyPointer, typeDyldInfo,
322 typeLazyDylibPointer, typeStubHelper, typeInitializerPointers, typeTerminatorPointers,
323 typeStubClose, typeLazyPointerClose, typeAbsoluteSymbols,
324 typeTLVDefs, typeTLVZeroFill, typeTLVInitialValues, typeTLVInitializerPointers, typeTLVPointers,
325 typeFirstSection, typeLastSection, typeDebug };
328 Section(const char* sgName, const char* sctName,
329 Type t, bool hidden=false)
330 : _segmentName(sgName), _sectionName(sctName),
331 _type(t), _hidden(hidden) {}
332 Section(const Section& sect)
333 : _segmentName(sect.segmentName()), _sectionName(sect.sectionName()),
334 _type(sect.type()), _hidden(sect.isSectionHidden()) {}
336 bool operator==(const Section& rhs) const { return ( (_hidden==rhs._hidden) &&
337 (strcmp(_segmentName, rhs._segmentName)==0) &&
338 (strcmp(_sectionName, rhs._sectionName)==0) ); }
339 bool operator!=(const Section& rhs) const { return ! (*this == rhs); }
340 const char* segmentName() const { return _segmentName; }
341 const char* sectionName() const { return _sectionName; }
342 Type type() const { return _type; }
343 bool isSectionHidden() const { return _hidden; }
346 const char* _segmentName;
347 const char* _sectionName;
357 // A Fixup describes how part of an Atom's content must be fixed up. For instance,
358 // an instruction may contain a displacement to another Atom that must be
359 // fixed up by the linker.
361 // A Fixup my reference another Atom. There are two kinds of references: direct and by-name.
362 // With a direct reference, the target is bound by the File that created it.
363 // For instance a reference to a static would produce a direct reference.
364 // A by-name reference requires the linker to find the target Atom with the
365 // required name in order to be bound.
367 // For a link to succeed all Fixup must be bound.
369 // A Reference also has a fix-up-offset. This is the offset into the content of the
370 // Atom holding the reference where the fix-up (relocation) will be applied.
375 enum TargetBinding { bindingNone, bindingByNameUnbound, bindingDirectlyBound, bindingByContentBound, bindingsIndirectlyBound };
376 enum Cluster { k1of1, k1of2, k2of2, k1of3, k2of3, k3of3, k1of4, k2of4, k3of4, k4of4, k1of5, k2of5, k3of5, k4of5, k5of5 };
377 enum Kind { kindNone, kindNoneFollowOn,
379 kindNoneGroupSubordinate,
380 kindNoneGroupSubordinateFDE, kindNoneGroupSubordinateLSDA, kindNoneGroupSubordinatePersonality,
381 // value calculations
382 kindSetTargetAddress,
383 kindSubtractTargetAddress,
386 kindSetTargetImageOffset,
387 kindSetTargetSectionOffset,
388 kindSetTargetTLVTemplateOffset,
389 // pointer store kinds (of current calculated value)
391 kindStoreLittleEndian16,
392 kindStoreLittleEndianLow24of32,
393 kindStoreLittleEndian32,
394 kindStoreLittleEndian64,
395 kindStoreBigEndian16,
396 kindStoreBigEndianLow24of32,
397 kindStoreBigEndian32,
398 kindStoreBigEndian64,
399 // Intel specific store kinds
400 kindStoreX86BranchPCRel8, kindStoreX86BranchPCRel32,
401 kindStoreX86PCRel8, kindStoreX86PCRel16,
402 kindStoreX86PCRel32, kindStoreX86PCRel32_1, kindStoreX86PCRel32_2, kindStoreX86PCRel32_4,
403 kindStoreX86PCRel32GOTLoad, kindStoreX86PCRel32GOTLoadNowLEA, kindStoreX86PCRel32GOT,
404 kindStoreX86PCRel32TLVLoad, kindStoreX86PCRel32TLVLoadNowLEA,
405 kindStoreX86Abs32TLVLoad, kindStoreX86Abs32TLVLoadNowLEA,
406 // ARM specific store kinds
407 kindStoreARMBranch24, kindStoreThumbBranch22,
409 kindStoreARMLow16, kindStoreARMHigh16,
410 kindStoreThumbLow16, kindStoreThumbHigh16,
411 #if SUPPORT_ARCH_arm64
412 // ARM64 specific store kinds
413 kindStoreARM64Branch26,
414 kindStoreARM64Page21, kindStoreARM64PageOff12,
415 kindStoreARM64GOTLoadPage21, kindStoreARM64GOTLoadPageOff12,
416 kindStoreARM64GOTLeaPage21, kindStoreARM64GOTLeaPageOff12,
417 kindStoreARM64TLVPLoadPage21, kindStoreARM64TLVPLoadPageOff12,
418 kindStoreARM64TLVPLoadNowLeaPage21, kindStoreARM64TLVPLoadNowLeaPageOff12,
419 kindStoreARM64PointerToGOT, kindStoreARM64PCRelToGOT,
423 kindStoreX86DtraceCallSiteNop, kindStoreX86DtraceIsEnableSiteClear,
424 kindStoreARMDtraceCallSiteNop, kindStoreARMDtraceIsEnableSiteClear,
425 kindStoreARM64DtraceCallSiteNop, kindStoreARM64DtraceIsEnableSiteClear,
426 kindStoreThumbDtraceCallSiteNop, kindStoreThumbDtraceIsEnableSiteClear,
428 kindLazyTarget, kindSetLazyOffset,
431 // data-in-code markers
432 kindDataInCodeStartData, kindDataInCodeStartJT8, kindDataInCodeStartJT16,
433 kindDataInCodeStartJT32, kindDataInCodeStartJTA32, kindDataInCodeEnd,
434 // linker optimzation hints
435 kindLinkerOptimizationHint,
436 // pointer store combinations
437 kindStoreTargetAddressLittleEndian32, // kindSetTargetAddress + kindStoreLittleEndian32
438 kindStoreTargetAddressLittleEndian64, // kindSetTargetAddress + kindStoreLittleEndian64
439 kindStoreTargetAddressBigEndian32, // kindSetTargetAddress + kindStoreBigEndian32
440 kindStoreTargetAddressBigEndian64, // kindSetTargetAddress + kindStoreBigEndian364
441 kindSetTargetTLVTemplateOffsetLittleEndian32, // kindSetTargetTLVTemplateOffset + kindStoreLittleEndian32
442 kindSetTargetTLVTemplateOffsetLittleEndian64, // kindSetTargetTLVTemplateOffset + kindStoreLittleEndian64
443 // Intel value calculation and store combinations
444 kindStoreTargetAddressX86PCRel32, // kindSetTargetAddress + kindStoreX86PCRel32
445 kindStoreTargetAddressX86BranchPCRel32, // kindSetTargetAddress + kindStoreX86BranchPCRel32
446 kindStoreTargetAddressX86PCRel32GOTLoad,// kindSetTargetAddress + kindStoreX86PCRel32GOTLoad
447 kindStoreTargetAddressX86PCRel32GOTLoadNowLEA,// kindSetTargetAddress + kindStoreX86PCRel32GOTLoadNowLEA
448 kindStoreTargetAddressX86PCRel32TLVLoad, // kindSetTargetAddress + kindStoreX86PCRel32TLVLoad
449 kindStoreTargetAddressX86PCRel32TLVLoadNowLEA, // kindSetTargetAddress + kindStoreX86PCRel32TLVLoadNowLEA
450 kindStoreTargetAddressX86Abs32TLVLoad, // kindSetTargetAddress + kindStoreX86Abs32TLVLoad
451 kindStoreTargetAddressX86Abs32TLVLoadNowLEA, // kindSetTargetAddress + kindStoreX86Abs32TLVLoadNowLEA
452 // ARM value calculation and store combinations
453 kindStoreTargetAddressARMBranch24, // kindSetTargetAddress + kindStoreARMBranch24
454 kindStoreTargetAddressThumbBranch22, // kindSetTargetAddress + kindStoreThumbBranch22
455 kindStoreTargetAddressARMLoad12, // kindSetTargetAddress + kindStoreARMLoad12
456 #if SUPPORT_ARCH_arm64
457 // ARM64 value calculation and store combinations
458 kindStoreTargetAddressARM64Branch26, // kindSetTargetAddress + kindStoreARM64Branch26
459 kindStoreTargetAddressARM64Page21, // kindSetTargetAddress + kindStoreARM64Page21
460 kindStoreTargetAddressARM64PageOff12, // kindSetTargetAddress + kindStoreARM64PageOff12
461 kindStoreTargetAddressARM64GOTLoadPage21, // kindSetTargetAddress + kindStoreARM64GOTLoadPage21
462 kindStoreTargetAddressARM64GOTLoadPageOff12,// kindSetTargetAddress + kindStoreARM64GOTLoadPageOff12
463 kindStoreTargetAddressARM64GOTLeaPage21, // kindSetTargetAddress + kindStoreARM64GOTLeaPage21
464 kindStoreTargetAddressARM64GOTLeaPageOff12, // kindSetTargetAddress + kindStoreARM64GOTLeaPageOff12
465 kindStoreTargetAddressARM64TLVPLoadPage21, // kindSetTargetAddress + kindStoreARM64TLVPLoadPage21
466 kindStoreTargetAddressARM64TLVPLoadPageOff12,// kindSetTargetAddress + kindStoreARM64TLVPLoadPageOff12
467 kindStoreTargetAddressARM64TLVPLoadNowLeaPage21, // kindSetTargetAddress + kindStoreARM64TLVPLoadNowLeaPage21
468 kindStoreTargetAddressARM64TLVPLoadNowLeaPageOff12, // kindSetTargetAddress + kindStoreARM64TLVPLoadNowLeaPageOff12
476 uint32_t bindingIndex;
478 uint32_t offsetInAtom;
480 Cluster clusterSize : 4;
482 TargetBinding binding : 3;
483 bool contentAddendOnly : 1;
484 bool contentDetlaToAddendOnly : 1;
485 bool contentIgnoresAddend : 1;
487 typedef Fixup* iterator;
490 offsetInAtom(0), kind(kindNone), clusterSize(k1of1), weakImport(false),
491 binding(bindingNone),
492 contentAddendOnly(false), contentDetlaToAddendOnly(false), contentIgnoresAddend(false) { u.target = NULL; }
494 Fixup(Kind k, Atom* targetAtom) :
495 offsetInAtom(0), kind(k), clusterSize(k1of1), weakImport(false),
496 binding(Fixup::bindingDirectlyBound),
497 contentAddendOnly(false), contentDetlaToAddendOnly(false), contentIgnoresAddend(false)
498 { assert(targetAtom != NULL); u.target = targetAtom; }
500 Fixup(uint32_t off, Cluster c, Kind k) :
501 offsetInAtom(off), kind(k), clusterSize(c), weakImport(false),
502 binding(Fixup::bindingNone),
503 contentAddendOnly(false), contentDetlaToAddendOnly(false), contentIgnoresAddend(false)
506 Fixup(uint32_t off, Cluster c, Kind k, bool weakIm, const char* name) :
507 offsetInAtom(off), kind(k), clusterSize(c), weakImport(weakIm),
508 binding(Fixup::bindingByNameUnbound),
509 contentAddendOnly(false), contentDetlaToAddendOnly(false), contentIgnoresAddend(false)
510 { assert(name != NULL); u.name = name; }
512 Fixup(uint32_t off, Cluster c, Kind k, TargetBinding b, const char* name) :
513 offsetInAtom(off), kind(k), clusterSize(c), weakImport(false), binding(b),
514 contentAddendOnly(false), contentDetlaToAddendOnly(false), contentIgnoresAddend(false)
515 { assert(name != NULL); u.name = name; }
517 Fixup(uint32_t off, Cluster c, Kind k, const Atom* targetAtom) :
518 offsetInAtom(off), kind(k), clusterSize(c), weakImport(false),
519 binding(Fixup::bindingDirectlyBound),
520 contentAddendOnly(false), contentDetlaToAddendOnly(false), contentIgnoresAddend(false)
521 { assert(targetAtom != NULL); u.target = targetAtom; }
523 Fixup(uint32_t off, Cluster c, Kind k, TargetBinding b, const Atom* targetAtom) :
524 offsetInAtom(off), kind(k), clusterSize(c), weakImport(false), binding(b),
525 contentAddendOnly(false), contentDetlaToAddendOnly(false), contentIgnoresAddend(false)
526 { assert(targetAtom != NULL); u.target = targetAtom; }
528 Fixup(uint32_t off, Cluster c, Kind k, uint64_t addend) :
529 offsetInAtom(off), kind(k), clusterSize(c), weakImport(false),
530 binding(Fixup::bindingNone),
531 contentAddendOnly(false), contentDetlaToAddendOnly(false), contentIgnoresAddend(false)
532 { u.addend = addend; }
534 Fixup(Kind k, uint32_t lohKind, uint32_t off1, uint32_t off2) :
535 offsetInAtom(off1), kind(k), clusterSize(k1of1),
536 weakImport(false), binding(Fixup::bindingNone), contentAddendOnly(false),
537 contentDetlaToAddendOnly(false), contentIgnoresAddend(false) {
538 assert(k == kindLinkerOptimizationHint);
541 extra.info.kind = lohKind;
542 extra.info.count = 1;
543 extra.info.delta1 = 0;
544 extra.info.delta2 = (off2 - off1) >> 2;
545 u.addend = extra.addend;
549 bool firstInCluster() const {
550 switch (clusterSize) {
563 bool lastInCluster() const {
564 switch (clusterSize) {
581 count : 2, // 00 => 1 addr, 11 => 4 addrs
582 delta1 : 14, // 16-bit delta, low 2 bits assumed zero
594 // An atom is the fundamental unit of linking. A C function or global variable is an atom.
595 // An atom has content and attributes. The content of a function atom is the instructions
596 // that implement the function. The content of a global variable atom is its initial bits.
599 // The name of an atom is the label name generated by the compiler. A C compiler names foo()
600 // as _foo. A C++ compiler names foo() as __Z3foov.
601 // The name refers to the first byte of the content. An atom cannot have multiple entry points.
602 // Such code is modeled as multiple atoms, each having a "follow on" reference to the next.
603 // A "follow on" reference is a contraint to the linker to the atoms must be laid out contiguously.
606 // An atom is in one of three scopes: translation-unit, linkage-unit, or global. These correspond
607 // to the C visibility of static, hidden, default.
610 // An atom is one of five defintion kinds:
611 // regular Most atoms.
612 // weak C++ compiler makes some functions weak if there might be multiple copies
613 // that the linker needs to coalesce.
614 // tentative A straggler from ancient C when the extern did not exist. "int foo;" is ambiguous.
615 // It could be a prototype or it could be a definition.
616 // external This is a "proxy" atom produced by a dylib reader. It has no content. It exists
617 // so that the graph of Atoms can be complete.
618 // external-weak Same as external, but the definition in the dylib is weak.
620 // SymbolTableInclusion:
621 // An atom may or may not be in the symbol table in an object file.
622 // in Most atoms for functions or global data
623 // not-in Anonymous atoms such literal c-strings, or other compiler generated data
624 // not-in-final Atom whose name should not be in the symbol table of final linkd image (e.g. 'l' labels .eh labels)
625 // in-never-strip Atom whose name the strip tool should never remove (e.g. REFERENCED_DYNAMICALLY in mach-o)
628 // Some atoms require specially processing by the linker based on their content. For instance, zero-fill data
629 // atom are group together at the end of the DATA segment to reduce disk size.
632 // For reproducability, the linker lays out atoms in the order they occurred in the source (object) files.
633 // The objectAddress() method returns the address of an atom in the object file so that the linker
634 // can arrange the atoms.
640 enum Scope { scopeTranslationUnit, scopeLinkageUnit, scopeGlobal };
641 enum Definition { definitionRegular, definitionTentative, definitionAbsolute, definitionProxy };
642 enum Combine { combineNever, combineByName, combineByNameAndContent, combineByNameAndReferences };
643 enum ContentType { typeUnclassified, typeZeroFill, typeCString, typeCFI, typeLSDA, typeSectionStart,
644 typeSectionEnd, typeBranchIsland, typeLazyPointer, typeStub, typeNonLazyPointer,
645 typeLazyDylibPointer, typeStubHelper, typeInitializerPointers, typeTerminatorPointers,
646 typeLTOtemporary, typeResolver,
647 typeTLV, typeTLVZeroFill, typeTLVInitialValue, typeTLVInitializerPointers };
649 enum SymbolTableInclusion { symbolTableNotIn, symbolTableNotInFinalLinkedImages, symbolTableIn,
650 symbolTableInAndNeverStrip, symbolTableInAsAbsolute,
651 symbolTableInWithRandomAutoStripLabel };
652 enum WeakImportState { weakImportUnset, weakImportTrue, weakImportFalse };
655 Alignment(int p2, int m=0) : powerOf2(p2), modulus(m) {}
656 uint8_t trailingZeros() const { return (modulus==0) ? powerOf2 : __builtin_ctz(modulus); }
661 const char* fileName;
665 typedef LineInfo* iterator;
668 uint32_t startOffset;
671 typedef UnwindInfo* iterator;
674 Atom(const Section& sect, Definition d, Combine c, Scope s, ContentType ct,
675 SymbolTableInclusion i, bool dds, bool thumb, bool al, Alignment a) :
676 _section(§), _address(0), _alignmentModulus(a.modulus),
677 _alignmentPowerOf2(a.powerOf2), _definition(d), _combine(c),
678 _dontDeadStrip(dds), _thumb(thumb), _alias(al), _autoHide(false),
679 _contentType(ct), _symbolTableInclusion(i),
680 _scope(s), _mode(modeSectionOffset),
681 _overridesADylibsWeakDef(false), _coalescedAway(false),
682 _live(false), _machoSection(0), _weakImportState(weakImportUnset)
685 switch ( _combine ) {
686 case combineByNameAndContent:
687 case combineByNameAndReferences:
688 assert(_symbolTableInclusion != symbolTableIn);
689 assert(_scope != scopeGlobal);
699 const Section& section() const { return *_section; }
700 Definition definition() const { return _definition; }
701 Combine combine() const { return _combine; }
702 Scope scope() const { return _scope; }
703 ContentType contentType() const { return _contentType; }
704 SymbolTableInclusion symbolTableInclusion() const{ return _symbolTableInclusion; }
705 bool dontDeadStrip() const { return _dontDeadStrip; }
706 bool isThumb() const { return _thumb; }
707 bool isAlias() const { return _alias; }
708 Alignment alignment() const { return Alignment(_alignmentPowerOf2, _alignmentModulus); }
709 bool overridesDylibsWeakDef() const { return _overridesADylibsWeakDef; }
710 bool coalescedAway() const { return _coalescedAway; }
711 bool weakImported() const { return _weakImportState == weakImportTrue; }
712 WeakImportState weakImportState() const { return _weakImportState; }
713 bool autoHide() const { return _autoHide; }
714 bool live() const { return _live; }
715 uint8_t machoSection() const { assert(_machoSection != 0); return _machoSection; }
717 void setScope(Scope s) { _scope = s; }
718 void setSymbolTableInclusion(SymbolTableInclusion i)
719 { _symbolTableInclusion = i; }
720 void setCombine(Combine c) { _combine = c; }
721 void setOverridesDylibsWeakDef() { _overridesADylibsWeakDef = true; }
722 void setCoalescedAway() { _coalescedAway = true; }
723 void setWeakImportState(bool w) { assert(_definition == definitionProxy); _weakImportState = ( w ? weakImportTrue : weakImportFalse); }
724 void setAutoHide() { _autoHide = true; }
725 void setLive() { _live = true; }
726 void setLive(bool value) { _live = value; }
727 void setMachoSection(unsigned x) { assert(x != 0); assert(x < 256); _machoSection = x; }
728 void setSectionOffset(uint64_t o){ assert(_mode == modeSectionOffset); _address = o; _mode = modeSectionOffset; }
729 void setSectionStartAddress(uint64_t a) { assert(_mode == modeSectionOffset); _address += a; _mode = modeFinalAddress; }
730 uint64_t sectionOffset() const { assert(_mode == modeSectionOffset); return _address; }
731 uint64_t finalAddress() const { assert(_mode == modeFinalAddress); return _address; }
733 bool finalAddressMode() const { return (_mode == modeFinalAddress); }
735 virtual const File* file() const = 0;
736 virtual const char* translationUnitSource() const { return NULL; }
737 virtual const char* name() const = 0;
738 virtual uint64_t objectAddress() const = 0;
739 virtual uint64_t size() const = 0;
740 virtual void copyRawContent(uint8_t buffer[]) const = 0;
741 virtual const uint8_t* rawContentPointer() const { return NULL; }
742 virtual unsigned long contentHash(const class IndirectBindingTable&) const { return 0; }
743 virtual bool canCoalesceWith(const Atom& rhs, const class IndirectBindingTable&) const { return false; }
744 virtual Fixup::iterator fixupsBegin() const { return NULL; }
745 virtual Fixup::iterator fixupsEnd() const { return NULL; }
746 bool hasFixupsOfKind(Fixup::Kind kind) const {
747 for (ld::Fixup::iterator fit = fixupsBegin(), end=fixupsEnd(); fit != end; ++fit) {
748 if ( fit->kind == kind ) return true;
752 virtual void setFile(const File* f) { }
754 virtual UnwindInfo::iterator beginUnwind() const { return NULL; }
755 virtual UnwindInfo::iterator endUnwind() const { return NULL; }
756 virtual LineInfo::iterator beginLineInfo() const { return NULL; }
757 virtual LineInfo::iterator endLineInfo() const { return NULL; }
759 void setAttributesFromAtom(const Atom& a) {
760 _section = a._section;
761 _alignmentModulus = a._alignmentModulus;
762 _alignmentPowerOf2 = a._alignmentPowerOf2;
763 _definition = a._definition;
764 _combine = a._combine;
765 _dontDeadStrip = a._dontDeadStrip;
767 _autoHide = a._autoHide;
768 _contentType = a._contentType;
769 _symbolTableInclusion = a._symbolTableInclusion;
772 _overridesADylibsWeakDef = a._overridesADylibsWeakDef;
773 _coalescedAway = a._coalescedAway;
774 _weakImportState = a._weakImportState;
778 enum AddressMode { modeSectionOffset, modeFinalAddress };
780 const Section * _section;
782 uint16_t _alignmentModulus;
783 uint8_t _alignmentPowerOf2;
784 Definition _definition : 2;
785 Combine _combine : 2;
786 bool _dontDeadStrip : 1;
790 ContentType _contentType : 5;
791 SymbolTableInclusion _symbolTableInclusion : 3;
793 AddressMode _mode: 2;
794 bool _overridesADylibsWeakDef : 1;
795 bool _coalescedAway : 1;
797 unsigned _machoSection : 8;
798 WeakImportState _weakImportState : 2;
802 class IndirectBindingTable
805 virtual const char* indirectName(uint32_t bindingIndex) const = 0;
806 virtual const ld::Atom* indirectAtom(uint32_t bindingIndex) const = 0;
811 // utility classes for using std::unordered_map with c-strings
813 size_t operator()(const char* __s) const {
816 __h = 5 * __h + *__s;
822 bool operator()(const char* left, const char* right) const { return (strcmp(left, right) == 0); }
825 typedef std::unordered_set<const char*, ld::CStringHash, ld::CStringEquals> CStringSet;
830 class FinalSection : public ld::Section {
832 FinalSection(const Section& sect) : Section(sect), address(0),
833 fileOffset(0), size(0), alignment(0),
834 indirectSymTabStartIndex(0), indirectSymTabElementSize(0),
835 relocStart(0), relocCount(0),
836 hasLocalRelocs(false), hasExternalRelocs(false) {}
837 std::vector<const Atom*> atoms;
841 uint32_t alignmentPaddingBytes;
843 uint32_t indirectSymTabStartIndex;
844 uint32_t indirectSymTabElementSize;
848 bool hasExternalRelocs;
851 virtual uint64_t assignFileOffsets() = 0;
852 virtual void setSectionSizesAndAlignments() = 0;
853 virtual ld::Internal::FinalSection* addAtom(const Atom&) = 0;
854 virtual ld::Internal::FinalSection* getFinalSection(const ld::Section& inputSection) = 0;
855 virtual ~Internal() {}
856 Internal() : bundleLoader(NULL),
857 entryPoint(NULL), classicBindingHelper(NULL),
858 lazyBindingHelper(NULL), compressedFastBinderProxy(NULL),
859 objcObjectConstraint(ld::File::objcConstraintNone),
860 objcDylibConstraint(ld::File::objcConstraintNone),
861 swiftVersion(0), cpuSubType(0),
862 allObjectFilesScatterable(true),
863 someObjectFileHasDwarf(false), usingHugeSections(false),
864 hasThreadLocalVariableDefinitions(false),
865 hasWeakExternalSymbols(false),
866 someObjectHasOptimizationHints(false) { }
868 std::vector<FinalSection*> sections;
869 std::vector<ld::dylib::File*> dylibs;
870 std::vector<ld::relocatable::File::Stab> stabs;
871 CStringSet linkerOptionLibraries;
872 CStringSet linkerOptionFrameworks;
873 std::vector<const ld::Atom*> indirectBindingTable;
874 const ld::dylib::File* bundleLoader;
875 const Atom* entryPoint;
876 const Atom* classicBindingHelper;
877 const Atom* lazyBindingHelper;
878 const Atom* compressedFastBinderProxy;
879 ld::File::ObjcConstraint objcObjectConstraint;
880 ld::File::ObjcConstraint objcDylibConstraint;
881 uint8_t swiftVersion;
883 bool allObjectFilesScatterable;
884 bool someObjectFileHasDwarf;
885 bool usingHugeSections;
886 bool hasThreadLocalVariableDefinitions;
887 bool hasWeakExternalSymbols;
888 bool someObjectHasOptimizationHints;