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@
43 // Abstract base class for all object or library files the linker processes.
45 // forEachAtom() iterates over the Atoms in the order they occur in the file.
47 // justInTimeforEachAtom(name) iterates over lazily created Atoms. For instance if
48 // File is a static library, justInTimeforEachAtom() will iterate over the base set
49 // of Atoms from the archive member implementing 'name'.
54 enum ObjcConstraint { objcConstraintNone, objcConstraintRetainRelease, objcConstraintRetainReleaseOrGC, objcConstraintGC };
58 virtual ~AtomHandler() {}
59 virtual void doAtom(const class Atom&) = 0;
60 virtual void doFile(const class File&) = 0;
66 // Codifies the rules of ordering input files for symbol precedence. These are:
67 // - Input files listed on the command line are ordered according to their index in the argument list.
68 // - Input files listed in a file list are ordered first at the index of the file list argument, then
69 // by index in the file list
70 // - Input files extracted from archives are ordered using the ordinal of the archive itself plus the
71 // index of the object file within the archive
72 // - Indirect dylibs are ordered after all input files derived from the command line, in the order that
73 // they are discovered.
74 // - The LTO object file is last.
79 // The actual numeric ordinal. Lower values have higher precedence and a zero value is invalid.
80 // The 64 bit ordinal is broken into 4 16 bit chunks. The high 16 bits are a "partition" that
81 // is used to distinguish major ordinal groups: command line, indirect dylib, LTO.
82 // The remaining chunks are used according to the partition (see below).
85 Ordinal (uint64_t ordinal) : _ordinal(ordinal) {}
87 enum { ArgListPartition=0, IndirectDylibPartition=1, LTOPartition = 2, InvalidParition=0xffff };
88 Ordinal(uint16_t partition, uint16_t majorIndex, uint16_t minorIndex, uint16_t counter) {
89 _ordinal = ((uint64_t)partition<<48) | ((uint64_t)majorIndex<<32) | ((uint64_t)minorIndex<<16) | ((uint64_t)counter<<0);
92 const uint16_t partition() const { return (_ordinal>>48)&0xffff; }
93 const uint16_t majorIndex() const { return (_ordinal>>32)&0xffff; }
94 const uint16_t minorIndex() const { return (_ordinal>>16)&0xffff; }
95 const uint16_t counter() const { return (_ordinal>>00)&0xffff; }
97 const Ordinal nextMajorIndex() const { assert(majorIndex() < 0xffff); return Ordinal(_ordinal+((uint64_t)1<<32)); }
98 const Ordinal nextMinorIndex() const { assert(minorIndex() < 0xffff); return Ordinal(_ordinal+((uint64_t)1<<16)); }
99 const Ordinal nextCounter() const { assert(counter() < 0xffff); return Ordinal(_ordinal+((uint64_t)1<<0)); }
102 Ordinal() : _ordinal(0) {};
104 static const Ordinal NullOrdinal() { return Ordinal((uint64_t)0); }
106 const bool validOrdinal() const { return _ordinal != 0; }
108 bool operator ==(const Ordinal& rhs) const { return _ordinal == rhs._ordinal; }
109 bool operator !=(const Ordinal& rhs) const { return _ordinal != rhs._ordinal; }
110 bool operator < (const Ordinal& rhs) const { return _ordinal < rhs._ordinal; }
111 bool operator > (const Ordinal& rhs) const { return _ordinal > rhs._ordinal; }
113 // For ordinals derived from the command line args the partition is ArgListPartition
114 // The majorIndex is the arg index that pulls in the file, file list, or archive.
115 // 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.
116 // The counter is used for .a files and the value is the index of the object in the archive.
117 // Thus, an object pulled in from a .a that was listed in a file list could use all three fields.
118 static const Ordinal makeArgOrdinal(uint16_t argIndex) { return Ordinal(ArgListPartition, argIndex, 0, 0); };
119 const Ordinal nextFileListOrdinal() const { return nextMinorIndex(); }
120 const Ordinal archiveOrdinalWithMemberIndex(uint16_t index) const { return Ordinal(ArgListPartition, majorIndex(), minorIndex(), index); }
122 // For indirect libraries the partition is IndirectDylibPartition and the counter is used or order the libraries.
123 static const ld::File::Ordinal indirectDylibBase() { return Ordinal(IndirectDylibPartition, 0, 0, 0); }
124 const Ordinal nextIndirectDylibOrdinal() const { return nextCounter(); }
126 // For the LTO mach-o the partition is LTOPartition. As there is only one LTO file no other fields are needed.
127 static const ld::File::Ordinal LTOOrdinal() { return Ordinal(LTOPartition, 0, 0, 0); }
130 typedef enum { Reloc, Dylib, Archive, Other } Type;
132 File(const char* pth, time_t modTime, Ordinal ord, Type type)
133 : _path(pth), _modTime(modTime), _ordinal(ord), _type(type) { }
135 const char* path() const { return _path; }
136 time_t modificationTime() const{ return _modTime; }
137 Ordinal ordinal() const { return _ordinal; }
138 virtual bool forEachAtom(AtomHandler&) const = 0;
139 virtual bool justInTimeforEachAtom(const char* name, AtomHandler&) const = 0;
140 virtual ObjcConstraint objCConstraint() const { return objcConstraintNone; }
141 virtual uint32_t cpuSubType() const { return 0; }
142 virtual uint32_t subFileCount() const { return 1; }
143 bool fileExists() const { return _modTime != 0; }
144 Type type() const { return _type; }
148 const Ordinal _ordinal;
154 // minumum OS versions
156 enum MacVersionMin { macVersionUnset=0, mac10_4=0x000A0400, mac10_5=0x000A0500,
157 mac10_6=0x000A0600, mac10_7=0x000A0700, mac10_8=0x000A0800,
158 mac10_Future=0x10000000 };
159 enum IOSVersionMin { iOSVersionUnset=0, iOS_2_0=0x00020000, iOS_3_1=0x00030100,
160 iOS_4_2=0x00040200, iOS_4_3=0x00040300, iOS_5_0=0x00050000,
161 iOS_6_0=0x00060000, iOS_Future=0x10000000};
163 namespace relocatable {
165 // ld::relocatable::File
167 // Abstract base class for object files the linker processes.
169 // debugInfo() returns if the object file contains debugger information (stabs or dwarf).
171 // stabs() lazily creates a vector of Stab objects for each atom
173 // canScatterAtoms() true for all compiler generated code. Hand written assembly can opt-in
174 // via .subsections_via_symbols directive. When true it means the linker can break up section
175 // content at symbol boundaries and do optimizations like coalescing, dead code stripping, or
176 // apply order files.
178 // optimize() used by libLTO to lazily generate code from llvm bit-code files
180 class File : public ld::File
183 enum DebugInfoKind { kDebugInfoNone=0, kDebugInfoStabs=1, kDebugInfoDwarf=2, kDebugInfoStabsUUID=3 };
185 const class Atom* atom;
193 File(const char* pth, time_t modTime, Ordinal ord)
194 : ld::File(pth, modTime, ord, Reloc) { }
196 virtual DebugInfoKind debugInfo() const = 0;
197 virtual const char* debugInfoPath() const { return path(); }
198 virtual time_t debugInfoModificationTime() const { return modificationTime(); }
199 virtual const std::vector<Stab>* stabs() const = 0;
200 virtual bool canScatterAtoms() const = 0;
201 virtual bool hasLongBranchStubs() { return false; }
203 } // namespace relocatable
211 // Abstract base class for dynamic shared libraries read by the linker processes.
213 class File : public ld::File
219 virtual ~DylibHandler() {}
220 virtual File* findDylib(const char* installPath, const char* fromPath) = 0;
223 File(const char* pth, time_t modTime, Ordinal ord)
224 : ld::File(pth, modTime, ord, Dylib), _dylibInstallPath(NULL),
225 _dylibTimeStamp(0), _dylibCurrentVersion(0), _dylibCompatibilityVersion(0),
226 _explicitlyLinked(false), _implicitlyLinked(false),
227 _lazyLoadedDylib(false), _forcedWeakLinked(false), _reExported(false),
228 _upward(false), _dead(false) { }
229 const char* installPath() const { return _dylibInstallPath; }
230 uint32_t timestamp() const { return _dylibTimeStamp; }
231 uint32_t currentVersion() const { return _dylibCurrentVersion; }
232 uint32_t compatibilityVersion() const{ return _dylibCompatibilityVersion; }
233 void setExplicitlyLinked() { _explicitlyLinked = true; }
234 bool explicitlyLinked() const { return _explicitlyLinked; }
235 void setImplicitlyLinked() { _implicitlyLinked = true; }
236 bool implicitlyLinked() const { return _implicitlyLinked; }
238 // attributes of how dylib will be used when linked
239 void setWillBeLazyLoadedDylb() { _lazyLoadedDylib = true; }
240 bool willBeLazyLoadedDylib() const { return _lazyLoadedDylib; }
241 void setForcedWeakLinked() { _forcedWeakLinked = true; }
242 bool forcedWeakLinked() const { return _forcedWeakLinked; }
244 void setWillBeReExported() { _reExported = true; }
245 bool willBeReExported() const { return _reExported; }
246 void setWillBeUpwardDylib() { _upward = true; }
247 bool willBeUpwardDylib() const { return _upward; }
248 void setWillBeRemoved(bool value) { _dead = value; }
249 bool willRemoved() const { return _dead; }
251 virtual void processIndirectLibraries(DylibHandler* handler, bool addImplicitDylibs) = 0;
252 virtual bool providedExportAtom() const = 0;
253 virtual const char* parentUmbrella() const = 0;
254 virtual const std::vector<const char*>* allowableClients() const = 0;
255 virtual bool hasWeakExternals() const = 0;
256 virtual bool deadStrippable() const = 0;
257 virtual bool hasWeakDefinition(const char* name) const = 0;
258 virtual bool hasPublicInstallName() const = 0;
259 virtual bool allSymbolsAreWeakImported() const = 0;
260 virtual const void* codeSignatureDR() const = 0;
262 const char* _dylibInstallPath;
263 uint32_t _dylibTimeStamp;
264 uint32_t _dylibCurrentVersion;
265 uint32_t _dylibCompatibilityVersion;
266 bool _explicitlyLinked;
267 bool _implicitlyLinked;
268 bool _lazyLoadedDylib;
269 bool _forcedWeakLinked;
281 // Abstract base class for static libraries read by the linker processes.
283 class File : public ld::File
286 File(const char* pth, time_t modTime, Ordinal ord)
287 : ld::File(pth, modTime, ord, Archive) { }
289 virtual bool justInTimeDataOnlyforEachAtom(const char* name, AtomHandler&) const = 0;
291 } // namespace archive
300 enum Type { typeUnclassified, typeCode, typePageZero, typeImportProxies, typeLinkEdit, typeMachHeader, typeStack,
301 typeLiteral4, typeLiteral8, typeLiteral16, typeConstants, typeTempLTO,
302 typeCString, typeNonStdCString, typeCStringPointer, typeUTF16Strings, typeCFString, typeObjC1Classes,
303 typeCFI, typeLSDA, typeDtraceDOF, typeUnwindInfo, typeObjCClassRefs, typeObjC2CategoryList,
304 typeZeroFill, typeTentativeDefs, typeLazyPointer, typeStub, typeNonLazyPointer, typeDyldInfo,
305 typeLazyDylibPointer, typeStubHelper, typeInitializerPointers, typeTerminatorPointers,
306 typeStubClose, typeLazyPointerClose, typeAbsoluteSymbols,
307 typeTLVDefs, typeTLVZeroFill, typeTLVInitialValues, typeTLVInitializerPointers, typeTLVPointers,
308 typeFirstSection, typeLastSection, typeDebug };
311 Section(const char* sgName, const char* sctName,
312 Type t, bool hidden=false)
313 : _segmentName(sgName), _sectionName(sctName),
314 _type(t), _hidden(hidden) {}
315 Section(const Section& sect)
316 : _segmentName(sect.segmentName()), _sectionName(sect.sectionName()),
317 _type(sect.type()), _hidden(sect.isSectionHidden()) {}
319 bool operator==(const Section& rhs) const { return ( (_hidden==rhs._hidden) &&
320 (strcmp(_segmentName, rhs._segmentName)==0) &&
321 (strcmp(_sectionName, rhs._sectionName)==0) ); }
322 bool operator!=(const Section& rhs) const { return ! (*this == rhs); }
323 const char* segmentName() const { return _segmentName; }
324 const char* sectionName() const { return _sectionName; }
325 Type type() const { return _type; }
326 bool isSectionHidden() const { return _hidden; }
329 const char* _segmentName;
330 const char* _sectionName;
340 // A Fixup describes how part of an Atom's content must be fixed up. For instance,
341 // an instruction may contain a displacement to another Atom that must be
342 // fixed up by the linker.
344 // A Fixup my reference another Atom. There are two kinds of references: direct and by-name.
345 // With a direct reference, the target is bound by the File that created it.
346 // For instance a reference to a static would produce a direct reference.
347 // A by-name reference requires the linker to find the target Atom with the
348 // required name in order to be bound.
350 // For a link to succeed all Fixup must be bound.
352 // A Reference also has a fix-up-offset. This is the offset into the content of the
353 // Atom holding the reference where the fix-up (relocation) will be applied.
358 enum TargetBinding { bindingNone, bindingByNameUnbound, bindingDirectlyBound, bindingByContentBound, bindingsIndirectlyBound };
359 enum Cluster { k1of1, k1of2, k2of2, k1of3, k2of3, k3of3, k1of4, k2of4, k3of4, k4of4, k1of5, k2of5, k3of5, k4of5, k5of5 };
360 enum Kind { kindNone, kindNoneFollowOn,
362 kindNoneGroupSubordinate,
363 kindNoneGroupSubordinateFDE, kindNoneGroupSubordinateLSDA, kindNoneGroupSubordinatePersonality,
364 // value calculations
365 kindSetTargetAddress,
366 kindSubtractTargetAddress,
369 kindSetTargetImageOffset,
370 kindSetTargetSectionOffset,
371 kindSetTargetTLVTemplateOffset,
372 // pointer store kinds (of current calculated value)
374 kindStoreLittleEndian16,
375 kindStoreLittleEndianLow24of32,
376 kindStoreLittleEndian32,
377 kindStoreLittleEndian64,
378 kindStoreBigEndian16,
379 kindStoreBigEndianLow24of32,
380 kindStoreBigEndian32,
381 kindStoreBigEndian64,
382 // Intel specific store kinds
383 kindStoreX86BranchPCRel8, kindStoreX86BranchPCRel32,
384 kindStoreX86PCRel8, kindStoreX86PCRel16,
385 kindStoreX86PCRel32, kindStoreX86PCRel32_1, kindStoreX86PCRel32_2, kindStoreX86PCRel32_4,
386 kindStoreX86PCRel32GOTLoad, kindStoreX86PCRel32GOTLoadNowLEA, kindStoreX86PCRel32GOT,
387 kindStoreX86PCRel32TLVLoad, kindStoreX86PCRel32TLVLoadNowLEA,
388 kindStoreX86Abs32TLVLoad, kindStoreX86Abs32TLVLoadNowLEA,
389 // ARM specific store kinds
390 kindStoreARMBranch24, kindStoreThumbBranch22,
392 kindStoreARMLow16, kindStoreARMHigh16,
393 kindStoreThumbLow16, kindStoreThumbHigh16,
396 kindStoreX86DtraceCallSiteNop, kindStoreX86DtraceIsEnableSiteClear,
397 kindStoreARMDtraceCallSiteNop, kindStoreARMDtraceIsEnableSiteClear,
398 kindStoreThumbDtraceCallSiteNop, kindStoreThumbDtraceIsEnableSiteClear,
400 kindLazyTarget, kindSetLazyOffset,
401 // data-in-code markers
402 kindDataInCodeStartData, kindDataInCodeStartJT8, kindDataInCodeStartJT16,
403 kindDataInCodeStartJT32, kindDataInCodeStartJTA32, kindDataInCodeEnd,
404 // pointer store combinations
405 kindStoreTargetAddressLittleEndian32, // kindSetTargetAddress + kindStoreLittleEndian32
406 kindStoreTargetAddressLittleEndian64, // kindSetTargetAddress + kindStoreLittleEndian64
407 kindStoreTargetAddressBigEndian32, // kindSetTargetAddress + kindStoreBigEndian32
408 kindStoreTargetAddressBigEndian64, // kindSetTargetAddress + kindStoreBigEndian364
409 kindSetTargetTLVTemplateOffsetLittleEndian32, // kindSetTargetTLVTemplateOffset + kindStoreLittleEndian32
410 kindSetTargetTLVTemplateOffsetLittleEndian64, // kindSetTargetTLVTemplateOffset + kindStoreLittleEndian64
411 // Intel value calculation and store combinations
412 kindStoreTargetAddressX86PCRel32, // kindSetTargetAddress + kindStoreX86PCRel32
413 kindStoreTargetAddressX86BranchPCRel32, // kindSetTargetAddress + kindStoreX86BranchPCRel32
414 kindStoreTargetAddressX86PCRel32GOTLoad,// kindSetTargetAddress + kindStoreX86PCRel32GOTLoad
415 kindStoreTargetAddressX86PCRel32GOTLoadNowLEA,// kindSetTargetAddress + kindStoreX86PCRel32GOTLoadNowLEA
416 kindStoreTargetAddressX86PCRel32TLVLoad, // kindSetTargetAddress + kindStoreX86PCRel32TLVLoad
417 kindStoreTargetAddressX86PCRel32TLVLoadNowLEA, // kindSetTargetAddress + kindStoreX86PCRel32TLVLoadNowLEA
418 kindStoreTargetAddressX86Abs32TLVLoad, // kindSetTargetAddress + kindStoreX86Abs32TLVLoad
419 kindStoreTargetAddressX86Abs32TLVLoadNowLEA, // kindSetTargetAddress + kindStoreX86Abs32TLVLoadNowLEA
420 // ARM value calculation and store combinations
421 kindStoreTargetAddressARMBranch24, // kindSetTargetAddress + kindStoreARMBranch24
422 kindStoreTargetAddressThumbBranch22, // kindSetTargetAddress + kindStoreThumbBranch22
423 kindStoreTargetAddressARMLoad12, // kindSetTargetAddress + kindStoreARMLoad12
430 uint32_t bindingIndex;
432 uint32_t offsetInAtom;
434 Cluster clusterSize : 4;
436 TargetBinding binding : 3;
437 bool contentAddendOnly : 1;
438 bool contentDetlaToAddendOnly : 1;
440 typedef Fixup* iterator;
443 offsetInAtom(0), kind(kindNone), clusterSize(k1of1), weakImport(false),
444 binding(bindingNone),
445 contentAddendOnly(false), contentDetlaToAddendOnly(false) { u.target = NULL; }
447 Fixup(Kind k, Atom* targetAtom) :
448 offsetInAtom(0), kind(k), clusterSize(k1of1), weakImport(false),
449 binding(Fixup::bindingDirectlyBound),
450 contentAddendOnly(false), contentDetlaToAddendOnly(false)
451 { assert(targetAtom != NULL); u.target = targetAtom; }
453 Fixup(uint32_t off, Cluster c, Kind k) :
454 offsetInAtom(off), kind(k), clusterSize(c), weakImport(false),
455 binding(Fixup::bindingNone),
456 contentAddendOnly(false), contentDetlaToAddendOnly(false)
459 Fixup(uint32_t off, Cluster c, Kind k, bool weakIm, const char* name) :
460 offsetInAtom(off), kind(k), clusterSize(c), weakImport(weakIm),
461 binding(Fixup::bindingByNameUnbound),
462 contentAddendOnly(false), contentDetlaToAddendOnly(false)
463 { assert(name != NULL); u.name = name; }
465 Fixup(uint32_t off, Cluster c, Kind k, TargetBinding b, const char* name) :
466 offsetInAtom(off), kind(k), clusterSize(c), weakImport(false), binding(b),
467 contentAddendOnly(false), contentDetlaToAddendOnly(false)
468 { assert(name != NULL); u.name = name; }
470 Fixup(uint32_t off, Cluster c, Kind k, const Atom* targetAtom) :
471 offsetInAtom(off), kind(k), clusterSize(c), weakImport(false),
472 binding(Fixup::bindingDirectlyBound),
473 contentAddendOnly(false), contentDetlaToAddendOnly(false)
474 { assert(targetAtom != NULL); u.target = targetAtom; }
476 Fixup(uint32_t off, Cluster c, Kind k, TargetBinding b, const Atom* targetAtom) :
477 offsetInAtom(off), kind(k), clusterSize(c), weakImport(false), binding(b),
478 contentAddendOnly(false), contentDetlaToAddendOnly(false)
479 { assert(targetAtom != NULL); u.target = targetAtom; }
481 Fixup(uint32_t off, Cluster c, Kind k, uint64_t addend) :
482 offsetInAtom(off), kind(k), clusterSize(c), weakImport(false),
483 binding(Fixup::bindingNone),
484 contentAddendOnly(false), contentDetlaToAddendOnly(false)
485 { u.addend = addend; }
487 bool firstInCluster() const {
488 switch (clusterSize) {
501 bool lastInCluster() const {
502 switch (clusterSize) {
520 // An atom is the fundamental unit of linking. A C function or global variable is an atom.
521 // An atom has content and attributes. The content of a function atom is the instructions
522 // that implement the function. The content of a global variable atom is its initial bits.
525 // The name of an atom is the label name generated by the compiler. A C compiler names foo()
526 // as _foo. A C++ compiler names foo() as __Z3foov.
527 // The name refers to the first byte of the content. An atom cannot have multiple entry points.
528 // Such code is modeled as multiple atoms, each having a "follow on" reference to the next.
529 // A "follow on" reference is a contraint to the linker to the atoms must be laid out contiguously.
532 // An atom is in one of three scopes: translation-unit, linkage-unit, or global. These correspond
533 // to the C visibility of static, hidden, default.
536 // An atom is one of five defintion kinds:
537 // regular Most atoms.
538 // weak C++ compiler makes some functions weak if there might be multiple copies
539 // that the linker needs to coalesce.
540 // tentative A straggler from ancient C when the extern did not exist. "int foo;" is ambiguous.
541 // It could be a prototype or it could be a definition.
542 // external This is a "proxy" atom produced by a dylib reader. It has no content. It exists
543 // so that the graph of Atoms can be complete.
544 // external-weak Same as external, but the definition in the dylib is weak.
546 // SymbolTableInclusion:
547 // An atom may or may not be in the symbol table in an object file.
548 // in Most atoms for functions or global data
549 // not-in Anonymous atoms such literal c-strings, or other compiler generated data
550 // not-in-final Atom whose name should not be in the symbol table of final linkd image (e.g. 'l' labels .eh labels)
551 // in-never-strip Atom whose name the strip tool should never remove (e.g. REFERENCED_DYNAMICALLY in mach-o)
554 // Some atoms require specially processing by the linker based on their content. For instance, zero-fill data
555 // atom are group together at the end of the DATA segment to reduce disk size.
558 // For reproducability, the linker lays out atoms in the order they occurred in the source (object) files.
559 // The objectAddress() method returns the address of an atom in the object file so that the linker
560 // can arrange the atoms.
566 enum Scope { scopeTranslationUnit, scopeLinkageUnit, scopeGlobal };
567 enum Definition { definitionRegular, definitionTentative, definitionAbsolute, definitionProxy };
568 enum Combine { combineNever, combineByName, combineByNameAndContent, combineByNameAndReferences };
569 enum ContentType { typeUnclassified, typeZeroFill, typeCString, typeCFI, typeLSDA, typeSectionStart,
570 typeSectionEnd, typeBranchIsland, typeLazyPointer, typeStub, typeNonLazyPointer,
571 typeLazyDylibPointer, typeStubHelper, typeInitializerPointers, typeTerminatorPointers,
572 typeLTOtemporary, typeResolver,
573 typeTLV, typeTLVZeroFill, typeTLVInitialValue, typeTLVInitializerPointers };
575 enum SymbolTableInclusion { symbolTableNotIn, symbolTableNotInFinalLinkedImages, symbolTableIn,
576 symbolTableInAndNeverStrip, symbolTableInAsAbsolute,
577 symbolTableInWithRandomAutoStripLabel };
578 enum WeakImportState { weakImportUnset, weakImportTrue, weakImportFalse };
581 Alignment(int p2, int m=0) : powerOf2(p2), modulus(m) {}
582 uint8_t trailingZeros() const { return (modulus==0) ? powerOf2 : __builtin_ctz(modulus); }
587 const char* fileName;
591 typedef LineInfo* iterator;
594 uint32_t startOffset;
597 typedef UnwindInfo* iterator;
600 Atom(const Section& sect, Definition d, Combine c, Scope s, ContentType ct,
601 SymbolTableInclusion i, bool dds, bool thumb, bool al, Alignment a) :
602 _section(§), _address(0), _alignmentModulus(a.modulus),
603 _alignmentPowerOf2(a.powerOf2), _definition(d), _combine(c),
604 _dontDeadStrip(dds), _thumb(thumb), _alias(al), _autoHide(false),
605 _contentType(ct), _symbolTableInclusion(i),
606 _scope(s), _mode(modeSectionOffset),
607 _overridesADylibsWeakDef(false), _coalescedAway(false),
608 _live(false), _machoSection(0), _weakImportState(weakImportUnset)
611 switch ( _combine ) {
612 case combineByNameAndContent:
613 case combineByNameAndReferences:
614 assert(_symbolTableInclusion == symbolTableNotIn);
615 assert(_scope != scopeGlobal);
625 const Section& section() const { return *_section; }
626 Definition definition() const { return _definition; }
627 Combine combine() const { return _combine; }
628 Scope scope() const { return _scope; }
629 ContentType contentType() const { return _contentType; }
630 SymbolTableInclusion symbolTableInclusion() const{ return _symbolTableInclusion; }
631 bool dontDeadStrip() const { return _dontDeadStrip; }
632 bool isThumb() const { return _thumb; }
633 bool isAlias() const { return _alias; }
634 Alignment alignment() const { return Alignment(_alignmentPowerOf2, _alignmentModulus); }
635 bool overridesDylibsWeakDef() const { return _overridesADylibsWeakDef; }
636 bool coalescedAway() const { return _coalescedAway; }
637 bool weakImported() const { return _weakImportState == weakImportTrue; }
638 WeakImportState weakImportState() const { return _weakImportState; }
639 bool autoHide() const { return _autoHide; }
640 bool live() const { return _live; }
641 uint8_t machoSection() const { assert(_machoSection != 0); return _machoSection; }
643 void setScope(Scope s) { _scope = s; }
644 void setSymbolTableInclusion(SymbolTableInclusion i)
645 { _symbolTableInclusion = i; }
646 void setCombine(Combine c) { _combine = c; }
647 void setOverridesDylibsWeakDef() { _overridesADylibsWeakDef = true; }
648 void setCoalescedAway() { _coalescedAway = true; }
649 void setWeakImportState(bool w) { assert(_definition == definitionProxy); _weakImportState = ( w ? weakImportTrue : weakImportFalse); }
650 void setAutoHide() { _autoHide = true; }
651 void setLive() { _live = true; }
652 void setLive(bool value) { _live = value; }
653 void setMachoSection(unsigned x) { assert(x != 0); assert(x < 256); _machoSection = x; }
654 void setSectionOffset(uint64_t o){ assert(_mode == modeSectionOffset); _address = o; _mode = modeSectionOffset; }
655 void setSectionStartAddress(uint64_t a) { assert(_mode == modeSectionOffset); _address += a; _mode = modeFinalAddress; }
656 uint64_t sectionOffset() const { assert(_mode == modeSectionOffset); return _address; }
657 uint64_t finalAddress() const { assert(_mode == modeFinalAddress); return _address; }
659 bool finalAddressMode() const { return (_mode == modeFinalAddress); }
661 virtual const File* file() const = 0;
662 virtual const char* translationUnitSource() const { return NULL; }
663 virtual const char* name() const = 0;
664 virtual uint64_t objectAddress() const = 0;
665 virtual uint64_t size() const = 0;
666 virtual void copyRawContent(uint8_t buffer[]) const = 0;
667 virtual const uint8_t* rawContentPointer() const { return NULL; }
668 virtual unsigned long contentHash(const class IndirectBindingTable&) const { return 0; }
669 virtual bool canCoalesceWith(const Atom& rhs, const class IndirectBindingTable&) const { return false; }
670 virtual Fixup::iterator fixupsBegin() const { return NULL; }
671 virtual Fixup::iterator fixupsEnd() const { return NULL; }
672 bool hasFixupsOfKind(Fixup::Kind kind) const {
673 for (ld::Fixup::iterator fit = fixupsBegin(), end=fixupsEnd(); fit != end; ++fit) {
674 if ( fit->kind == kind ) return true;
679 virtual UnwindInfo::iterator beginUnwind() const { return NULL; }
680 virtual UnwindInfo::iterator endUnwind() const { return NULL; }
681 virtual LineInfo::iterator beginLineInfo() const { return NULL; }
682 virtual LineInfo::iterator endLineInfo() const { return NULL; }
685 enum AddressMode { modeSectionOffset, modeFinalAddress };
687 void setAttributesFromAtom(const Atom& a) {
688 _section = a._section;
689 _alignmentModulus = a._alignmentModulus;
690 _alignmentPowerOf2 = a._alignmentPowerOf2;
691 _definition = a._definition;
692 _combine = a._combine;
693 _dontDeadStrip = a._dontDeadStrip;
696 _autoHide = a._autoHide;
697 _contentType = a._contentType;
698 _symbolTableInclusion = a._symbolTableInclusion;
701 _overridesADylibsWeakDef = a._overridesADylibsWeakDef;
702 _coalescedAway = a._coalescedAway;
703 _weakImportState = a._weakImportState;
706 const Section * _section;
708 uint16_t _alignmentModulus;
709 uint8_t _alignmentPowerOf2;
710 Definition _definition : 2;
711 Combine _combine : 2;
712 bool _dontDeadStrip : 1;
716 ContentType _contentType : 5;
717 SymbolTableInclusion _symbolTableInclusion : 3;
719 AddressMode _mode: 2;
720 bool _overridesADylibsWeakDef : 1;
721 bool _coalescedAway : 1;
723 unsigned _machoSection : 8;
724 WeakImportState _weakImportState : 2;
728 class IndirectBindingTable
731 virtual const char* indirectName(uint32_t bindingIndex) const = 0;
732 virtual const ld::Atom* indirectAtom(uint32_t bindingIndex) const = 0;
739 class FinalSection : public ld::Section {
741 FinalSection(const Section& sect) : Section(sect), address(0),
742 fileOffset(0), size(0), alignment(0),
743 indirectSymTabStartIndex(0), indirectSymTabElementSize(0),
744 relocStart(0), relocCount(0),
745 hasLocalRelocs(false), hasExternalRelocs(false) {}
746 std::vector<const Atom*> atoms;
750 uint32_t alignmentPaddingBytes;
752 uint32_t indirectSymTabStartIndex;
753 uint32_t indirectSymTabElementSize;
757 bool hasExternalRelocs;
760 virtual ld::Internal::FinalSection* addAtom(const Atom&) = 0;
761 virtual ld::Internal::FinalSection* getFinalSection(const ld::Section& inputSection) = 0;
762 virtual ~Internal() {}
763 Internal() : bundleLoader(NULL),
764 entryPoint(NULL), classicBindingHelper(NULL),
765 lazyBindingHelper(NULL), compressedFastBinderProxy(NULL),
766 objcObjectConstraint(ld::File::objcConstraintNone),
767 objcDylibConstraint(ld::File::objcConstraintNone),
769 allObjectFilesScatterable(true),
770 someObjectFileHasDwarf(false), usingHugeSections(false) { }
772 std::vector<FinalSection*> sections;
773 std::vector<ld::dylib::File*> dylibs;
774 std::vector<ld::relocatable::File::Stab> stabs;
775 std::vector<const ld::Atom*> indirectBindingTable;
776 const ld::dylib::File* bundleLoader;
777 const Atom* entryPoint;
778 const Atom* classicBindingHelper;
779 const Atom* lazyBindingHelper;
780 const Atom* compressedFastBinderProxy;
781 ld::File::ObjcConstraint objcObjectConstraint;
782 ld::File::ObjcConstraint objcDylibConstraint;
784 bool allObjectFilesScatterable;
785 bool someObjectFileHasDwarf;
786 bool usingHugeSections;
792 // utility classes for using std::unordered_map with c-strings
794 size_t operator()(const char* __s) const {
797 __h = 5 * __h + *__s;
803 bool operator()(const char* left, const char* right) const { return (strcmp(left, right) == 0); }