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,
170 iOS_Future=0x10000000};
172 namespace relocatable {
174 // ld::relocatable::File
176 // Abstract base class for object files the linker processes.
178 // debugInfo() returns if the object file contains debugger information (stabs or dwarf).
180 // stabs() lazily creates a vector of Stab objects for each atom
182 // canScatterAtoms() true for all compiler generated code. Hand written assembly can opt-in
183 // via .subsections_via_symbols directive. When true it means the linker can break up section
184 // content at symbol boundaries and do optimizations like coalescing, dead code stripping, or
185 // apply order files.
187 // optimize() used by libLTO to lazily generate code from llvm bit-code files
189 class File : public ld::File
192 enum DebugInfoKind { kDebugInfoNone=0, kDebugInfoStabs=1, kDebugInfoDwarf=2, kDebugInfoStabsUUID=3 };
194 const class Atom* atom;
201 typedef const std::vector< std::vector<const char*> > LinkerOptionsList;
203 File(const char* pth, time_t modTime, Ordinal ord)
204 : ld::File(pth, modTime, ord, Reloc) { }
206 virtual DebugInfoKind debugInfo() const = 0;
207 virtual const char* debugInfoPath() const { return path(); }
208 virtual time_t debugInfoModificationTime() const { return modificationTime(); }
209 virtual const std::vector<Stab>* stabs() const = 0;
210 virtual bool canScatterAtoms() const = 0;
211 virtual bool hasLongBranchStubs() { return false; }
212 virtual LinkerOptionsList* linkerOptions() const = 0;
214 } // namespace relocatable
222 // Abstract base class for dynamic shared libraries read by the linker processes.
224 class File : public ld::File
230 virtual ~DylibHandler() {}
231 virtual File* findDylib(const char* installPath, const char* fromPath) = 0;
234 File(const char* pth, time_t modTime, Ordinal ord)
235 : ld::File(pth, modTime, ord, Dylib), _dylibInstallPath(NULL),
236 _dylibTimeStamp(0), _dylibCurrentVersion(0), _dylibCompatibilityVersion(0),
237 _explicitlyLinked(false), _implicitlyLinked(false),
238 _lazyLoadedDylib(false), _forcedWeakLinked(false), _reExported(false),
239 _upward(false), _dead(false) { }
240 const char* installPath() const { return _dylibInstallPath; }
241 uint32_t timestamp() const { return _dylibTimeStamp; }
242 uint32_t currentVersion() const { return _dylibCurrentVersion; }
243 uint32_t compatibilityVersion() const{ return _dylibCompatibilityVersion; }
244 void setExplicitlyLinked() { _explicitlyLinked = true; }
245 bool explicitlyLinked() const { return _explicitlyLinked; }
246 void setImplicitlyLinked() { _implicitlyLinked = true; }
247 bool implicitlyLinked() const { return _implicitlyLinked; }
249 // attributes of how dylib will be used when linked
250 void setWillBeLazyLoadedDylb() { _lazyLoadedDylib = true; }
251 bool willBeLazyLoadedDylib() const { return _lazyLoadedDylib; }
252 void setForcedWeakLinked() { _forcedWeakLinked = true; }
253 bool forcedWeakLinked() const { return _forcedWeakLinked; }
255 void setWillBeReExported() { _reExported = true; }
256 bool willBeReExported() const { return _reExported; }
257 void setWillBeUpwardDylib() { _upward = true; }
258 bool willBeUpwardDylib() const { return _upward; }
259 void setWillBeRemoved(bool value) { _dead = value; }
260 bool willRemoved() const { return _dead; }
262 virtual void processIndirectLibraries(DylibHandler* handler, bool addImplicitDylibs) = 0;
263 virtual bool providedExportAtom() const = 0;
264 virtual const char* parentUmbrella() const = 0;
265 virtual const std::vector<const char*>* allowableClients() const = 0;
266 virtual bool hasWeakExternals() const = 0;
267 virtual bool deadStrippable() const = 0;
268 virtual bool hasWeakDefinition(const char* name) const = 0;
269 virtual bool hasPublicInstallName() const = 0;
270 virtual bool allSymbolsAreWeakImported() const = 0;
271 virtual const void* codeSignatureDR() const = 0;
272 virtual bool installPathVersionSpecific() const { return false; }
274 const char* _dylibInstallPath;
275 uint32_t _dylibTimeStamp;
276 uint32_t _dylibCurrentVersion;
277 uint32_t _dylibCompatibilityVersion;
278 bool _explicitlyLinked;
279 bool _implicitlyLinked;
280 bool _lazyLoadedDylib;
281 bool _forcedWeakLinked;
293 // Abstract base class for static libraries read by the linker processes.
295 class File : public ld::File
298 File(const char* pth, time_t modTime, Ordinal ord)
299 : ld::File(pth, modTime, ord, Archive) { }
301 virtual bool justInTimeDataOnlyforEachAtom(const char* name, AtomHandler&) const = 0;
303 } // namespace archive
312 enum Type { typeUnclassified, typeCode, typePageZero, typeImportProxies, typeLinkEdit, typeMachHeader, typeStack,
313 typeLiteral4, typeLiteral8, typeLiteral16, typeConstants, typeTempLTO,
314 typeCString, typeNonStdCString, typeCStringPointer, typeUTF16Strings, typeCFString, typeObjC1Classes,
315 typeCFI, typeLSDA, typeDtraceDOF, typeUnwindInfo, typeObjCClassRefs, typeObjC2CategoryList,
316 typeZeroFill, typeTentativeDefs, typeLazyPointer, typeStub, typeNonLazyPointer, typeDyldInfo,
317 typeLazyDylibPointer, typeStubHelper, typeInitializerPointers, typeTerminatorPointers,
318 typeStubClose, typeLazyPointerClose, typeAbsoluteSymbols,
319 typeTLVDefs, typeTLVZeroFill, typeTLVInitialValues, typeTLVInitializerPointers, typeTLVPointers,
320 typeFirstSection, typeLastSection, typeDebug };
323 Section(const char* sgName, const char* sctName,
324 Type t, bool hidden=false)
325 : _segmentName(sgName), _sectionName(sctName),
326 _type(t), _hidden(hidden) {}
327 Section(const Section& sect)
328 : _segmentName(sect.segmentName()), _sectionName(sect.sectionName()),
329 _type(sect.type()), _hidden(sect.isSectionHidden()) {}
331 bool operator==(const Section& rhs) const { return ( (_hidden==rhs._hidden) &&
332 (strcmp(_segmentName, rhs._segmentName)==0) &&
333 (strcmp(_sectionName, rhs._sectionName)==0) ); }
334 bool operator!=(const Section& rhs) const { return ! (*this == rhs); }
335 const char* segmentName() const { return _segmentName; }
336 const char* sectionName() const { return _sectionName; }
337 Type type() const { return _type; }
338 bool isSectionHidden() const { return _hidden; }
341 const char* _segmentName;
342 const char* _sectionName;
352 // A Fixup describes how part of an Atom's content must be fixed up. For instance,
353 // an instruction may contain a displacement to another Atom that must be
354 // fixed up by the linker.
356 // A Fixup my reference another Atom. There are two kinds of references: direct and by-name.
357 // With a direct reference, the target is bound by the File that created it.
358 // For instance a reference to a static would produce a direct reference.
359 // A by-name reference requires the linker to find the target Atom with the
360 // required name in order to be bound.
362 // For a link to succeed all Fixup must be bound.
364 // A Reference also has a fix-up-offset. This is the offset into the content of the
365 // Atom holding the reference where the fix-up (relocation) will be applied.
370 enum TargetBinding { bindingNone, bindingByNameUnbound, bindingDirectlyBound, bindingByContentBound, bindingsIndirectlyBound };
371 enum Cluster { k1of1, k1of2, k2of2, k1of3, k2of3, k3of3, k1of4, k2of4, k3of4, k4of4, k1of5, k2of5, k3of5, k4of5, k5of5 };
372 enum Kind { kindNone, kindNoneFollowOn,
374 kindNoneGroupSubordinate,
375 kindNoneGroupSubordinateFDE, kindNoneGroupSubordinateLSDA, kindNoneGroupSubordinatePersonality,
376 // value calculations
377 kindSetTargetAddress,
378 kindSubtractTargetAddress,
381 kindSetTargetImageOffset,
382 kindSetTargetSectionOffset,
383 kindSetTargetTLVTemplateOffset,
384 // pointer store kinds (of current calculated value)
386 kindStoreLittleEndian16,
387 kindStoreLittleEndianLow24of32,
388 kindStoreLittleEndian32,
389 kindStoreLittleEndian64,
390 kindStoreBigEndian16,
391 kindStoreBigEndianLow24of32,
392 kindStoreBigEndian32,
393 kindStoreBigEndian64,
394 // Intel specific store kinds
395 kindStoreX86BranchPCRel8, kindStoreX86BranchPCRel32,
396 kindStoreX86PCRel8, kindStoreX86PCRel16,
397 kindStoreX86PCRel32, kindStoreX86PCRel32_1, kindStoreX86PCRel32_2, kindStoreX86PCRel32_4,
398 kindStoreX86PCRel32GOTLoad, kindStoreX86PCRel32GOTLoadNowLEA, kindStoreX86PCRel32GOT,
399 kindStoreX86PCRel32TLVLoad, kindStoreX86PCRel32TLVLoadNowLEA,
400 kindStoreX86Abs32TLVLoad, kindStoreX86Abs32TLVLoadNowLEA,
401 // ARM specific store kinds
402 kindStoreARMBranch24, kindStoreThumbBranch22,
404 kindStoreARMLow16, kindStoreARMHigh16,
405 kindStoreThumbLow16, kindStoreThumbHigh16,
406 #if SUPPORT_ARCH_arm64
407 // ARM64 specific store kinds
408 kindStoreARM64Branch26,
409 kindStoreARM64Page21, kindStoreARM64PageOff12,
410 kindStoreARM64GOTLoadPage21, kindStoreARM64GOTLoadPageOff12,
411 kindStoreARM64GOTLeaPage21, kindStoreARM64GOTLeaPageOff12,
412 kindStoreARM64TLVPLoadPage21, kindStoreARM64TLVPLoadPageOff12,
413 kindStoreARM64TLVPLoadNowLeaPage21, kindStoreARM64TLVPLoadNowLeaPageOff12,
414 kindStoreARM64PointerToGOT, kindStoreARM64PCRelToGOT,
418 kindStoreX86DtraceCallSiteNop, kindStoreX86DtraceIsEnableSiteClear,
419 kindStoreARMDtraceCallSiteNop, kindStoreARMDtraceIsEnableSiteClear,
420 kindStoreARM64DtraceCallSiteNop, kindStoreARM64DtraceIsEnableSiteClear,
421 kindStoreThumbDtraceCallSiteNop, kindStoreThumbDtraceIsEnableSiteClear,
423 kindLazyTarget, kindSetLazyOffset,
426 // data-in-code markers
427 kindDataInCodeStartData, kindDataInCodeStartJT8, kindDataInCodeStartJT16,
428 kindDataInCodeStartJT32, kindDataInCodeStartJTA32, kindDataInCodeEnd,
429 // linker optimzation hints
430 kindLinkerOptimizationHint,
431 // pointer store combinations
432 kindStoreTargetAddressLittleEndian32, // kindSetTargetAddress + kindStoreLittleEndian32
433 kindStoreTargetAddressLittleEndian64, // kindSetTargetAddress + kindStoreLittleEndian64
434 kindStoreTargetAddressBigEndian32, // kindSetTargetAddress + kindStoreBigEndian32
435 kindStoreTargetAddressBigEndian64, // kindSetTargetAddress + kindStoreBigEndian364
436 kindSetTargetTLVTemplateOffsetLittleEndian32, // kindSetTargetTLVTemplateOffset + kindStoreLittleEndian32
437 kindSetTargetTLVTemplateOffsetLittleEndian64, // kindSetTargetTLVTemplateOffset + kindStoreLittleEndian64
438 // Intel value calculation and store combinations
439 kindStoreTargetAddressX86PCRel32, // kindSetTargetAddress + kindStoreX86PCRel32
440 kindStoreTargetAddressX86BranchPCRel32, // kindSetTargetAddress + kindStoreX86BranchPCRel32
441 kindStoreTargetAddressX86PCRel32GOTLoad,// kindSetTargetAddress + kindStoreX86PCRel32GOTLoad
442 kindStoreTargetAddressX86PCRel32GOTLoadNowLEA,// kindSetTargetAddress + kindStoreX86PCRel32GOTLoadNowLEA
443 kindStoreTargetAddressX86PCRel32TLVLoad, // kindSetTargetAddress + kindStoreX86PCRel32TLVLoad
444 kindStoreTargetAddressX86PCRel32TLVLoadNowLEA, // kindSetTargetAddress + kindStoreX86PCRel32TLVLoadNowLEA
445 kindStoreTargetAddressX86Abs32TLVLoad, // kindSetTargetAddress + kindStoreX86Abs32TLVLoad
446 kindStoreTargetAddressX86Abs32TLVLoadNowLEA, // kindSetTargetAddress + kindStoreX86Abs32TLVLoadNowLEA
447 // ARM value calculation and store combinations
448 kindStoreTargetAddressARMBranch24, // kindSetTargetAddress + kindStoreARMBranch24
449 kindStoreTargetAddressThumbBranch22, // kindSetTargetAddress + kindStoreThumbBranch22
450 kindStoreTargetAddressARMLoad12, // kindSetTargetAddress + kindStoreARMLoad12
451 #if SUPPORT_ARCH_arm64
452 // ARM64 value calculation and store combinations
453 kindStoreTargetAddressARM64Branch26, // kindSetTargetAddress + kindStoreARM64Branch26
454 kindStoreTargetAddressARM64Page21, // kindSetTargetAddress + kindStoreARM64Page21
455 kindStoreTargetAddressARM64PageOff12, // kindSetTargetAddress + kindStoreARM64PageOff12
456 kindStoreTargetAddressARM64GOTLoadPage21, // kindSetTargetAddress + kindStoreARM64GOTLoadPage21
457 kindStoreTargetAddressARM64GOTLoadPageOff12,// kindSetTargetAddress + kindStoreARM64GOTLoadPageOff12
458 kindStoreTargetAddressARM64GOTLeaPage21, // kindSetTargetAddress + kindStoreARM64GOTLeaPage21
459 kindStoreTargetAddressARM64GOTLeaPageOff12, // kindSetTargetAddress + kindStoreARM64GOTLeaPageOff12
460 kindStoreTargetAddressARM64TLVPLoadPage21, // kindSetTargetAddress + kindStoreARM64TLVPLoadPage21
461 kindStoreTargetAddressARM64TLVPLoadPageOff12,// kindSetTargetAddress + kindStoreARM64TLVPLoadPageOff12
462 kindStoreTargetAddressARM64TLVPLoadNowLeaPage21, // kindSetTargetAddress + kindStoreARM64TLVPLoadNowLeaPage21
463 kindStoreTargetAddressARM64TLVPLoadNowLeaPageOff12, // kindSetTargetAddress + kindStoreARM64TLVPLoadNowLeaPageOff12
471 uint32_t bindingIndex;
473 uint32_t offsetInAtom;
475 Cluster clusterSize : 4;
477 TargetBinding binding : 3;
478 bool contentAddendOnly : 1;
479 bool contentDetlaToAddendOnly : 1;
480 bool contentIgnoresAddend : 1;
482 typedef Fixup* iterator;
485 offsetInAtom(0), kind(kindNone), clusterSize(k1of1), weakImport(false),
486 binding(bindingNone),
487 contentAddendOnly(false), contentDetlaToAddendOnly(false), contentIgnoresAddend(false) { u.target = NULL; }
489 Fixup(Kind k, Atom* targetAtom) :
490 offsetInAtom(0), kind(k), clusterSize(k1of1), weakImport(false),
491 binding(Fixup::bindingDirectlyBound),
492 contentAddendOnly(false), contentDetlaToAddendOnly(false), contentIgnoresAddend(false)
493 { assert(targetAtom != NULL); u.target = targetAtom; }
495 Fixup(uint32_t off, Cluster c, Kind k) :
496 offsetInAtom(off), kind(k), clusterSize(c), weakImport(false),
497 binding(Fixup::bindingNone),
498 contentAddendOnly(false), contentDetlaToAddendOnly(false), contentIgnoresAddend(false)
501 Fixup(uint32_t off, Cluster c, Kind k, bool weakIm, const char* name) :
502 offsetInAtom(off), kind(k), clusterSize(c), weakImport(weakIm),
503 binding(Fixup::bindingByNameUnbound),
504 contentAddendOnly(false), contentDetlaToAddendOnly(false), contentIgnoresAddend(false)
505 { assert(name != NULL); u.name = name; }
507 Fixup(uint32_t off, Cluster c, Kind k, TargetBinding b, const char* name) :
508 offsetInAtom(off), kind(k), clusterSize(c), weakImport(false), binding(b),
509 contentAddendOnly(false), contentDetlaToAddendOnly(false), contentIgnoresAddend(false)
510 { assert(name != NULL); u.name = name; }
512 Fixup(uint32_t off, Cluster c, Kind k, const Atom* targetAtom) :
513 offsetInAtom(off), kind(k), clusterSize(c), weakImport(false),
514 binding(Fixup::bindingDirectlyBound),
515 contentAddendOnly(false), contentDetlaToAddendOnly(false), contentIgnoresAddend(false)
516 { assert(targetAtom != NULL); u.target = targetAtom; }
518 Fixup(uint32_t off, Cluster c, Kind k, TargetBinding b, const Atom* targetAtom) :
519 offsetInAtom(off), kind(k), clusterSize(c), weakImport(false), binding(b),
520 contentAddendOnly(false), contentDetlaToAddendOnly(false), contentIgnoresAddend(false)
521 { assert(targetAtom != NULL); u.target = targetAtom; }
523 Fixup(uint32_t off, Cluster c, Kind k, uint64_t addend) :
524 offsetInAtom(off), kind(k), clusterSize(c), weakImport(false),
525 binding(Fixup::bindingNone),
526 contentAddendOnly(false), contentDetlaToAddendOnly(false), contentIgnoresAddend(false)
527 { u.addend = addend; }
529 #if SUPPORT_ARCH_arm64
530 Fixup(Kind k, uint32_t lohKind, uint32_t off1, uint32_t off2) :
531 offsetInAtom(off1), kind(k), clusterSize(k1of1),
532 weakImport(false), binding(Fixup::bindingNone), contentAddendOnly(false),
533 contentDetlaToAddendOnly(false), contentIgnoresAddend(false) {
534 assert(k == kindLinkerOptimizationHint);
537 extra.info.kind = lohKind;
538 extra.info.count = 1;
539 extra.info.delta1 = 0;
540 extra.info.delta2 = (off2 - off1) >> 2;
541 u.addend = extra.addend;
546 bool firstInCluster() const {
547 switch (clusterSize) {
560 bool lastInCluster() const {
561 switch (clusterSize) {
574 #if SUPPORT_ARCH_arm64
579 count : 2, // 00 => 1 addr, 11 => 4 addrs
580 delta1 : 14, // 16-bit delta, low 2 bits assumed zero
593 // An atom is the fundamental unit of linking. A C function or global variable is an atom.
594 // An atom has content and attributes. The content of a function atom is the instructions
595 // that implement the function. The content of a global variable atom is its initial bits.
598 // The name of an atom is the label name generated by the compiler. A C compiler names foo()
599 // as _foo. A C++ compiler names foo() as __Z3foov.
600 // The name refers to the first byte of the content. An atom cannot have multiple entry points.
601 // Such code is modeled as multiple atoms, each having a "follow on" reference to the next.
602 // A "follow on" reference is a contraint to the linker to the atoms must be laid out contiguously.
605 // An atom is in one of three scopes: translation-unit, linkage-unit, or global. These correspond
606 // to the C visibility of static, hidden, default.
609 // An atom is one of five defintion kinds:
610 // regular Most atoms.
611 // weak C++ compiler makes some functions weak if there might be multiple copies
612 // that the linker needs to coalesce.
613 // tentative A straggler from ancient C when the extern did not exist. "int foo;" is ambiguous.
614 // It could be a prototype or it could be a definition.
615 // external This is a "proxy" atom produced by a dylib reader. It has no content. It exists
616 // so that the graph of Atoms can be complete.
617 // external-weak Same as external, but the definition in the dylib is weak.
619 // SymbolTableInclusion:
620 // An atom may or may not be in the symbol table in an object file.
621 // in Most atoms for functions or global data
622 // not-in Anonymous atoms such literal c-strings, or other compiler generated data
623 // not-in-final Atom whose name should not be in the symbol table of final linkd image (e.g. 'l' labels .eh labels)
624 // in-never-strip Atom whose name the strip tool should never remove (e.g. REFERENCED_DYNAMICALLY in mach-o)
627 // Some atoms require specially processing by the linker based on their content. For instance, zero-fill data
628 // atom are group together at the end of the DATA segment to reduce disk size.
631 // For reproducability, the linker lays out atoms in the order they occurred in the source (object) files.
632 // The objectAddress() method returns the address of an atom in the object file so that the linker
633 // can arrange the atoms.
639 enum Scope { scopeTranslationUnit, scopeLinkageUnit, scopeGlobal };
640 enum Definition { definitionRegular, definitionTentative, definitionAbsolute, definitionProxy };
641 enum Combine { combineNever, combineByName, combineByNameAndContent, combineByNameAndReferences };
642 enum ContentType { typeUnclassified, typeZeroFill, typeCString, typeCFI, typeLSDA, typeSectionStart,
643 typeSectionEnd, typeBranchIsland, typeLazyPointer, typeStub, typeNonLazyPointer,
644 typeLazyDylibPointer, typeStubHelper, typeInitializerPointers, typeTerminatorPointers,
645 typeLTOtemporary, typeResolver,
646 typeTLV, typeTLVZeroFill, typeTLVInitialValue, typeTLVInitializerPointers };
648 enum SymbolTableInclusion { symbolTableNotIn, symbolTableNotInFinalLinkedImages, symbolTableIn,
649 symbolTableInAndNeverStrip, symbolTableInAsAbsolute,
650 symbolTableInWithRandomAutoStripLabel };
651 enum WeakImportState { weakImportUnset, weakImportTrue, weakImportFalse };
654 Alignment(int p2, int m=0) : powerOf2(p2), modulus(m) {}
655 uint8_t trailingZeros() const { return (modulus==0) ? powerOf2 : __builtin_ctz(modulus); }
660 const char* fileName;
664 typedef LineInfo* iterator;
667 uint32_t startOffset;
670 typedef UnwindInfo* iterator;
673 Atom(const Section& sect, Definition d, Combine c, Scope s, ContentType ct,
674 SymbolTableInclusion i, bool dds, bool thumb, bool al, Alignment a) :
675 _section(§), _address(0), _alignmentModulus(a.modulus),
676 _alignmentPowerOf2(a.powerOf2), _definition(d), _combine(c),
677 _dontDeadStrip(dds), _thumb(thumb), _alias(al), _autoHide(false),
678 _contentType(ct), _symbolTableInclusion(i),
679 _scope(s), _mode(modeSectionOffset),
680 _overridesADylibsWeakDef(false), _coalescedAway(false),
681 _live(false), _machoSection(0), _weakImportState(weakImportUnset)
684 switch ( _combine ) {
685 case combineByNameAndContent:
686 case combineByNameAndReferences:
687 assert(_symbolTableInclusion != symbolTableIn);
688 assert(_scope != scopeGlobal);
698 const Section& section() const { return *_section; }
699 Definition definition() const { return _definition; }
700 Combine combine() const { return _combine; }
701 Scope scope() const { return _scope; }
702 ContentType contentType() const { return _contentType; }
703 SymbolTableInclusion symbolTableInclusion() const{ return _symbolTableInclusion; }
704 bool dontDeadStrip() const { return _dontDeadStrip; }
705 bool isThumb() const { return _thumb; }
706 bool isAlias() const { return _alias; }
707 Alignment alignment() const { return Alignment(_alignmentPowerOf2, _alignmentModulus); }
708 bool overridesDylibsWeakDef() const { return _overridesADylibsWeakDef; }
709 bool coalescedAway() const { return _coalescedAway; }
710 bool weakImported() const { return _weakImportState == weakImportTrue; }
711 WeakImportState weakImportState() const { return _weakImportState; }
712 bool autoHide() const { return _autoHide; }
713 bool live() const { return _live; }
714 uint8_t machoSection() const { assert(_machoSection != 0); return _machoSection; }
716 void setScope(Scope s) { _scope = s; }
717 void setSymbolTableInclusion(SymbolTableInclusion i)
718 { _symbolTableInclusion = i; }
719 void setCombine(Combine c) { _combine = c; }
720 void setOverridesDylibsWeakDef() { _overridesADylibsWeakDef = true; }
721 void setCoalescedAway() { _coalescedAway = true; }
722 void setWeakImportState(bool w) { assert(_definition == definitionProxy); _weakImportState = ( w ? weakImportTrue : weakImportFalse); }
723 void setAutoHide() { _autoHide = true; }
724 void setLive() { _live = true; }
725 void setLive(bool value) { _live = value; }
726 void setMachoSection(unsigned x) { assert(x != 0); assert(x < 256); _machoSection = x; }
727 void setSectionOffset(uint64_t o){ assert(_mode == modeSectionOffset); _address = o; _mode = modeSectionOffset; }
728 void setSectionStartAddress(uint64_t a) { assert(_mode == modeSectionOffset); _address += a; _mode = modeFinalAddress; }
729 uint64_t sectionOffset() const { assert(_mode == modeSectionOffset); return _address; }
730 uint64_t finalAddress() const { assert(_mode == modeFinalAddress); return _address; }
732 bool finalAddressMode() const { return (_mode == modeFinalAddress); }
734 virtual const File* file() const = 0;
735 virtual const char* translationUnitSource() const { return NULL; }
736 virtual const char* name() const = 0;
737 virtual uint64_t objectAddress() const = 0;
738 virtual uint64_t size() const = 0;
739 virtual void copyRawContent(uint8_t buffer[]) const = 0;
740 virtual const uint8_t* rawContentPointer() const { return NULL; }
741 virtual unsigned long contentHash(const class IndirectBindingTable&) const { return 0; }
742 virtual bool canCoalesceWith(const Atom& rhs, const class IndirectBindingTable&) const { return false; }
743 virtual Fixup::iterator fixupsBegin() const { return NULL; }
744 virtual Fixup::iterator fixupsEnd() const { return NULL; }
745 bool hasFixupsOfKind(Fixup::Kind kind) const {
746 for (ld::Fixup::iterator fit = fixupsBegin(), end=fixupsEnd(); fit != end; ++fit) {
747 if ( fit->kind == kind ) return true;
751 virtual void setFile(const File* f) { }
753 virtual UnwindInfo::iterator beginUnwind() const { return NULL; }
754 virtual UnwindInfo::iterator endUnwind() const { return NULL; }
755 virtual LineInfo::iterator beginLineInfo() const { return NULL; }
756 virtual LineInfo::iterator endLineInfo() const { return NULL; }
759 enum AddressMode { modeSectionOffset, modeFinalAddress };
761 void setAttributesFromAtom(const Atom& a) {
762 _section = a._section;
763 _alignmentModulus = a._alignmentModulus;
764 _alignmentPowerOf2 = a._alignmentPowerOf2;
765 _definition = a._definition;
766 _combine = a._combine;
767 _dontDeadStrip = a._dontDeadStrip;
769 _autoHide = a._autoHide;
770 _contentType = a._contentType;
771 _symbolTableInclusion = a._symbolTableInclusion;
774 _overridesADylibsWeakDef = a._overridesADylibsWeakDef;
775 _coalescedAway = a._coalescedAway;
776 _weakImportState = a._weakImportState;
779 const Section * _section;
781 uint16_t _alignmentModulus;
782 uint8_t _alignmentPowerOf2;
783 Definition _definition : 2;
784 Combine _combine : 2;
785 bool _dontDeadStrip : 1;
789 ContentType _contentType : 5;
790 SymbolTableInclusion _symbolTableInclusion : 3;
792 AddressMode _mode: 2;
793 bool _overridesADylibsWeakDef : 1;
794 bool _coalescedAway : 1;
796 unsigned _machoSection : 8;
797 WeakImportState _weakImportState : 2;
801 class IndirectBindingTable
804 virtual const char* indirectName(uint32_t bindingIndex) const = 0;
805 virtual const ld::Atom* indirectAtom(uint32_t bindingIndex) const = 0;
810 // utility classes for using std::unordered_map with c-strings
812 size_t operator()(const char* __s) const {
815 __h = 5 * __h + *__s;
821 bool operator()(const char* left, const char* right) const { return (strcmp(left, right) == 0); }
824 typedef std::unordered_set<const char*, ld::CStringHash, ld::CStringEquals> CStringSet;
829 class FinalSection : public ld::Section {
831 FinalSection(const Section& sect) : Section(sect), address(0),
832 fileOffset(0), size(0), alignment(0),
833 indirectSymTabStartIndex(0), indirectSymTabElementSize(0),
834 relocStart(0), relocCount(0),
835 hasLocalRelocs(false), hasExternalRelocs(false) {}
836 std::vector<const Atom*> atoms;
840 uint32_t alignmentPaddingBytes;
842 uint32_t indirectSymTabStartIndex;
843 uint32_t indirectSymTabElementSize;
847 bool hasExternalRelocs;
850 virtual uint64_t assignFileOffsets() = 0;
851 virtual void setSectionSizesAndAlignments() = 0;
852 virtual ld::Internal::FinalSection* addAtom(const Atom&) = 0;
853 virtual ld::Internal::FinalSection* getFinalSection(const ld::Section& inputSection) = 0;
854 virtual ~Internal() {}
855 Internal() : bundleLoader(NULL),
856 entryPoint(NULL), classicBindingHelper(NULL),
857 lazyBindingHelper(NULL), compressedFastBinderProxy(NULL),
858 objcObjectConstraint(ld::File::objcConstraintNone),
859 objcDylibConstraint(ld::File::objcConstraintNone),
861 allObjectFilesScatterable(true),
862 someObjectFileHasDwarf(false), usingHugeSections(false),
863 hasThreadLocalVariableDefinitions(false),
864 hasWeakExternalSymbols(false),
865 someObjectHasOptimizationHints(false) { }
867 std::vector<FinalSection*> sections;
868 std::vector<ld::dylib::File*> dylibs;
869 std::vector<ld::relocatable::File::Stab> stabs;
870 CStringSet linkerOptionLibraries;
871 CStringSet linkerOptionFrameworks;
872 std::vector<const ld::Atom*> indirectBindingTable;
873 const ld::dylib::File* bundleLoader;
874 const Atom* entryPoint;
875 const Atom* classicBindingHelper;
876 const Atom* lazyBindingHelper;
877 const Atom* compressedFastBinderProxy;
878 ld::File::ObjcConstraint objcObjectConstraint;
879 ld::File::ObjcConstraint objcDylibConstraint;
881 bool allObjectFilesScatterable;
882 bool someObjectFileHasDwarf;
883 bool usingHugeSections;
884 bool hasThreadLocalVariableDefinitions;
885 bool hasWeakExternalSymbols;
886 bool someObjectHasOptimizationHints;