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;
63 File(const char* pth, time_t modTime, uint32_t ord)
64 : _path(pth), _modTime(modTime), _ordinal(ord) { }
66 const char* path() const { return _path; }
67 time_t modificationTime() const{ return _modTime; }
68 uint32_t ordinal() const { return _ordinal; }
69 virtual bool forEachAtom(AtomHandler&) const = 0;
70 virtual bool justInTimeforEachAtom(const char* name, AtomHandler&) const = 0;
71 virtual ObjcConstraint objCConstraint() const { return objcConstraintNone; }
72 virtual uint32_t cpuSubType() const { return 0; }
73 virtual uint32_t subFileCount() const { return 1; }
82 // minumum OS versions
84 enum MacVersionMin { macVersionUnset=0, mac10_4=0x000A0400, mac10_5=0x000A0500,
85 mac10_6=0x000A0600, mac10_7=0x000A0700 };
86 enum IOSVersionMin { iOSVersionUnset=0, iOS_2_0=0x00020000, iOS_3_1=0x00030100,
87 iOS_4_2=0x00040200, iOS_4_3=0x00040300, iOS_5_0=0x00050000 };
89 namespace relocatable {
91 // ld::relocatable::File
93 // Abstract base class for object files the linker processes.
95 // objcReplacementClasses() is reflects if the file was compiled for fix-and-continue
97 // debugInfo() returns if the object file contains debugger information (stabs or dwarf).
99 // stabs() lazily creates a vector of Stab objects for each atom
101 // canScatterAtoms() true for all compiler generated code. Hand written assembly can opt-in
102 // via .subsections_via_symbols directive. When true it means the linker can break up section
103 // content at symbol boundaries and do optimizations like coalescing, dead code stripping, or
104 // apply order files.
106 // optimize() used by libLTO to lazily generate code from llvm bit-code files
108 class File : public ld::File
111 enum DebugInfoKind { kDebugInfoNone=0, kDebugInfoStabs=1, kDebugInfoDwarf=2, kDebugInfoStabsUUID=3 };
113 const class Atom* atom;
121 File(const char* pth, time_t modTime, uint32_t ord)
122 : ld::File(pth, modTime, ord) { }
124 virtual bool objcReplacementClasses() const = 0;
125 virtual DebugInfoKind debugInfo() const = 0;
126 virtual const char* debugInfoPath() const { return path(); }
127 virtual time_t debugInfoModificationTime() const { return modificationTime(); }
128 virtual const std::vector<Stab>* stabs() const = 0;
129 virtual bool canScatterAtoms() const = 0;
130 virtual bool hasLongBranchStubs() { return false; }
132 } // namespace relocatable
140 // Abstract base class for dynamic shared libraries read by the linker processes.
142 class File : public ld::File
148 virtual ~DylibHandler() {}
149 virtual File* findDylib(const char* installPath, const char* fromPath) = 0;
152 File(const char* pth, time_t modTime, uint32_t ord)
153 : ld::File(pth, modTime, ord), _dylibInstallPath(NULL),
154 _dylibTimeStamp(0), _dylibCurrentVersion(0), _dylibCompatibilityVersion(0),
155 _explicitlyLinked(false), _implicitlyLinked(false),
156 _lazyLoadedDylib(false), _forcedWeakLinked(false), _reExported(false),
157 _upward(false), _dead(false) { }
158 const char* installPath() const { return _dylibInstallPath; }
159 uint32_t timestamp() const { return _dylibTimeStamp; }
160 uint32_t currentVersion() const { return _dylibCurrentVersion; }
161 uint32_t compatibilityVersion() const{ return _dylibCompatibilityVersion; }
162 void setExplicitlyLinked() { _explicitlyLinked = true; }
163 bool explicitlyLinked() const { return _explicitlyLinked; }
164 void setImplicitlyLinked() { _implicitlyLinked = true; }
165 bool implicitlyLinked() const { return _implicitlyLinked; }
166 // attributes of how dylib will be used when linked
167 void setWillBeLazyLoadedDylb() { _lazyLoadedDylib = true; }
168 bool willBeLazyLoadedDylib() const { return _lazyLoadedDylib; }
169 void setForcedWeakLinked() { _forcedWeakLinked = true; }
170 bool forcedWeakLinked() const { return _forcedWeakLinked; }
172 void setWillBeReExported() { _reExported = true; }
173 bool willBeReExported() const { return _reExported; }
174 void setWillBeUpwardDylib() { _upward = true; }
175 bool willBeUpwardDylib() const { return _upward; }
176 void setWillBeRemoved(bool value) { _dead = value; }
177 bool willRemoved() const { return _dead; }
179 virtual void processIndirectLibraries(DylibHandler* handler, bool addImplicitDylibs) = 0;
180 virtual bool providedExportAtom() const = 0;
181 virtual const char* parentUmbrella() const = 0;
182 virtual const std::vector<const char*>* allowableClients() const = 0;
183 virtual bool hasWeakExternals() const = 0;
184 virtual bool deadStrippable() const = 0;
185 virtual bool hasWeakDefinition(const char* name) const = 0;
186 virtual bool hasPublicInstallName() const = 0;
187 virtual bool allSymbolsAreWeakImported() const = 0;
189 const char* _dylibInstallPath;
190 uint32_t _dylibTimeStamp;
191 uint32_t _dylibCurrentVersion;
192 uint32_t _dylibCompatibilityVersion;
193 bool _explicitlyLinked;
194 bool _implicitlyLinked;
195 bool _lazyLoadedDylib;
196 bool _forcedWeakLinked;
208 // Abstract base class for static libraries read by the linker processes.
210 class File : public ld::File
213 File(const char* pth, time_t modTime, uint32_t ord)
214 : ld::File(pth, modTime, ord) { }
216 virtual bool justInTimeDataOnlyforEachAtom(const char* name, AtomHandler&) const = 0;
218 } // namespace archive
227 enum Type { typeUnclassified, typeCode, typePageZero, typeImportProxies, typeLinkEdit, typeMachHeader, typeStack,
228 typeLiteral4, typeLiteral8, typeLiteral16, typeConstants, typeTempLTO,
229 typeCString, typeNonStdCString, typeCStringPointer, typeUTF16Strings, typeCFString, typeObjC1Classes,
230 typeCFI, typeLSDA, typeDtraceDOF, typeUnwindInfo, typeObjCClassRefs, typeObjC2CategoryList,
231 typeZeroFill, typeTentativeDefs, typeLazyPointer, typeStub, typeNonLazyPointer, typeDyldInfo,
232 typeLazyDylibPointer, typeStubHelper, typeInitializerPointers, typeTerminatorPointers,
233 typeStubClose, typeLazyPointerClose, typeAbsoluteSymbols,
234 typeTLVDefs, typeTLVZeroFill, typeTLVInitialValues, typeTLVInitializerPointers, typeTLVPointers,
235 typeFirstSection, typeLastSection, typeDebug };
238 Section(const char* sgName, const char* sctName,
239 Type t, bool hidden=false)
240 : _segmentName(sgName), _sectionName(sctName),
241 _type(t), _hidden(hidden) {}
242 Section(const Section& sect)
243 : _segmentName(sect.segmentName()), _sectionName(sect.sectionName()),
244 _type(sect.type()), _hidden(sect.isSectionHidden()) {}
246 bool operator==(const Section& rhs) const { return ( (_hidden==rhs._hidden) &&
247 (strcmp(_segmentName, rhs._segmentName)==0) &&
248 (strcmp(_sectionName, rhs._sectionName)==0) ); }
249 bool operator!=(const Section& rhs) const { return ! (*this == rhs); }
250 const char* segmentName() const { return _segmentName; }
251 const char* sectionName() const { return _sectionName; }
252 Type type() const { return _type; }
253 bool isSectionHidden() const { return _hidden; }
256 const char* _segmentName;
257 const char* _sectionName;
267 // A Fixup describes how part of an Atom's content must be fixed up. For instance,
268 // an instruction may contain a displacement to another Atom that must be
269 // fixed up by the linker.
271 // A Fixup my reference another Atom. There are two kinds of references: direct and by-name.
272 // With a direct reference, the target is bound by the File that created it.
273 // For instance a reference to a static would produce a direct reference.
274 // A by-name reference requires the linker to find the target Atom with the
275 // required name in order to be bound.
277 // For a link to succeed all Fixup must be bound.
279 // A Reference also has a fix-up-offset. This is the offset into the content of the
280 // Atom holding the reference where the fix-up (relocation) will be applied.
285 enum TargetBinding { bindingNone, bindingByNameUnbound, bindingDirectlyBound, bindingByContentBound, bindingsIndirectlyBound };
286 enum Cluster { k1of1, k1of2, k2of2, k1of3, k2of3, k3of3, k1of4, k2of4, k3of4, k4of4, k1of5, k2of5, k3of5, k4of5, k5of5 };
287 enum Kind { kindNone, kindNoneFollowOn,
289 kindNoneGroupSubordinate,
290 kindNoneGroupSubordinateFDE, kindNoneGroupSubordinateLSDA, kindNoneGroupSubordinatePersonality,
291 // value calculations
292 kindSetTargetAddress,
293 kindSubtractTargetAddress,
296 kindSetTargetImageOffset,
297 kindSetTargetSectionOffset,
298 kindSetTargetTLVTemplateOffset,
299 // pointer store kinds (of current calculated value)
301 kindStoreLittleEndian16,
302 kindStoreLittleEndianLow24of32,
303 kindStoreLittleEndian32,
304 kindStoreLittleEndian64,
305 kindStoreBigEndian16,
306 kindStoreBigEndianLow24of32,
307 kindStoreBigEndian32,
308 kindStoreBigEndian64,
309 // Intel specific store kinds
310 kindStoreX86BranchPCRel8, kindStoreX86BranchPCRel32,
311 kindStoreX86PCRel8, kindStoreX86PCRel16,
312 kindStoreX86PCRel32, kindStoreX86PCRel32_1, kindStoreX86PCRel32_2, kindStoreX86PCRel32_4,
313 kindStoreX86PCRel32GOTLoad, kindStoreX86PCRel32GOTLoadNowLEA, kindStoreX86PCRel32GOT,
314 kindStoreX86PCRel32TLVLoad, kindStoreX86PCRel32TLVLoadNowLEA,
315 kindStoreX86Abs32TLVLoad, kindStoreX86Abs32TLVLoadNowLEA,
316 // ARM specific store kinds
317 kindStoreARMBranch24, kindStoreThumbBranch22,
319 kindStoreARMLow16, kindStoreARMHigh16,
320 kindStoreThumbLow16, kindStoreThumbHigh16,
323 kindStoreX86DtraceCallSiteNop, kindStoreX86DtraceIsEnableSiteClear,
324 kindStoreARMDtraceCallSiteNop, kindStoreARMDtraceIsEnableSiteClear,
325 kindStoreThumbDtraceCallSiteNop, kindStoreThumbDtraceIsEnableSiteClear,
327 kindLazyTarget, kindSetLazyOffset,
328 // pointer store combinations
329 kindStoreTargetAddressLittleEndian32, // kindSetTargetAddress + kindStoreLittleEndian32
330 kindStoreTargetAddressLittleEndian64, // kindSetTargetAddress + kindStoreLittleEndian64
331 kindStoreTargetAddressBigEndian32, // kindSetTargetAddress + kindStoreBigEndian32
332 kindStoreTargetAddressBigEndian64, // kindSetTargetAddress + kindStoreBigEndian364
333 kindSetTargetTLVTemplateOffsetLittleEndian32, // kindSetTargetTLVTemplateOffset + kindStoreLittleEndian32
334 kindSetTargetTLVTemplateOffsetLittleEndian64, // kindSetTargetTLVTemplateOffset + kindStoreLittleEndian64
335 // Intel value calculation and store combinations
336 kindStoreTargetAddressX86PCRel32, // kindSetTargetAddress + kindStoreX86PCRel32
337 kindStoreTargetAddressX86BranchPCRel32, // kindSetTargetAddress + kindStoreX86BranchPCRel32
338 kindStoreTargetAddressX86PCRel32GOTLoad,// kindSetTargetAddress + kindStoreX86PCRel32GOTLoad
339 kindStoreTargetAddressX86PCRel32GOTLoadNowLEA,// kindSetTargetAddress + kindStoreX86PCRel32GOTLoadNowLEA
340 kindStoreTargetAddressX86PCRel32TLVLoad, // kindSetTargetAddress + kindStoreX86PCRel32TLVLoad
341 kindStoreTargetAddressX86PCRel32TLVLoadNowLEA, // kindSetTargetAddress + kindStoreX86PCRel32TLVLoadNowLEA
342 kindStoreTargetAddressX86Abs32TLVLoad, // kindSetTargetAddress + kindStoreX86Abs32TLVLoad
343 kindStoreTargetAddressX86Abs32TLVLoadNowLEA, // kindSetTargetAddress + kindStoreX86Abs32TLVLoadNowLEA
344 // ARM value calculation and store combinations
345 kindStoreTargetAddressARMBranch24, // kindSetTargetAddress + kindStoreARMBranch24
346 kindStoreTargetAddressThumbBranch22, // kindSetTargetAddress + kindStoreThumbBranch22
347 kindStoreTargetAddressARMLoad12, // kindSetTargetAddress + kindStoreARMLoad12
354 uint32_t bindingIndex;
356 uint32_t offsetInAtom;
358 Cluster clusterSize : 4;
360 TargetBinding binding : 3;
361 bool contentAddendOnly : 1;
362 bool contentDetlaToAddendOnly : 1;
364 typedef Fixup* iterator;
367 offsetInAtom(0), kind(kindNone), clusterSize(k1of1), weakImport(false),
368 binding(bindingNone),
369 contentAddendOnly(false), contentDetlaToAddendOnly(false) { u.target = NULL; }
371 Fixup(Kind k, Atom* targetAtom) :
372 offsetInAtom(0), kind(k), clusterSize(k1of1), weakImport(false),
373 binding(Fixup::bindingDirectlyBound),
374 contentAddendOnly(false), contentDetlaToAddendOnly(false)
375 { assert(targetAtom != NULL); u.target = targetAtom; }
377 Fixup(uint32_t off, Cluster c, Kind k) :
378 offsetInAtom(off), kind(k), clusterSize(c), weakImport(false),
379 binding(Fixup::bindingNone),
380 contentAddendOnly(false), contentDetlaToAddendOnly(false)
383 Fixup(uint32_t off, Cluster c, Kind k, bool weakIm, const char* name) :
384 offsetInAtom(off), kind(k), clusterSize(c), weakImport(weakIm),
385 binding(Fixup::bindingByNameUnbound),
386 contentAddendOnly(false), contentDetlaToAddendOnly(false)
387 { assert(name != NULL); u.name = name; }
389 Fixup(uint32_t off, Cluster c, Kind k, TargetBinding b, const char* name) :
390 offsetInAtom(off), kind(k), clusterSize(c), weakImport(false), binding(b),
391 contentAddendOnly(false), contentDetlaToAddendOnly(false)
392 { assert(name != NULL); u.name = name; }
394 Fixup(uint32_t off, Cluster c, Kind k, const Atom* targetAtom) :
395 offsetInAtom(off), kind(k), clusterSize(c), weakImport(false),
396 binding(Fixup::bindingDirectlyBound),
397 contentAddendOnly(false), contentDetlaToAddendOnly(false)
398 { assert(targetAtom != NULL); u.target = targetAtom; }
400 Fixup(uint32_t off, Cluster c, Kind k, TargetBinding b, const Atom* targetAtom) :
401 offsetInAtom(off), kind(k), clusterSize(c), weakImport(false), binding(b),
402 contentAddendOnly(false), contentDetlaToAddendOnly(false)
403 { assert(targetAtom != NULL); u.target = targetAtom; }
405 Fixup(uint32_t off, Cluster c, Kind k, uint64_t addend) :
406 offsetInAtom(off), kind(k), clusterSize(c), weakImport(false),
407 binding(Fixup::bindingNone),
408 contentAddendOnly(false), contentDetlaToAddendOnly(false)
409 { u.addend = addend; }
411 bool firstInCluster() const {
412 switch (clusterSize) {
425 bool lastInCluster() const {
426 switch (clusterSize) {
444 // An atom is the fundamental unit of linking. A C function or global variable is an atom.
445 // An atom has content and attributes. The content of a function atom is the instructions
446 // that implement the function. The content of a global variable atom is its initial bits.
449 // The name of an atom is the label name generated by the compiler. A C compiler names foo()
450 // as _foo. A C++ compiler names foo() as __Z3foov.
451 // The name refers to the first byte of the content. An atom cannot have multiple entry points.
452 // Such code is modeled as multiple atoms, each having a "follow on" reference to the next.
453 // A "follow on" reference is a contraint to the linker to the atoms must be laid out contiguously.
456 // An atom is in one of three scopes: translation-unit, linkage-unit, or global. These correspond
457 // to the C visibility of static, hidden, default.
460 // An atom is one of five defintion kinds:
461 // regular Most atoms.
462 // weak C++ compiler makes some functions weak if there might be multiple copies
463 // that the linker needs to coalesce.
464 // tentative A straggler from ancient C when the extern did not exist. "int foo;" is ambiguous.
465 // It could be a prototype or it could be a definition.
466 // external This is a "proxy" atom produced by a dylib reader. It has no content. It exists
467 // so that the graph of Atoms can be complete.
468 // external-weak Same as external, but the definition in the dylib is weak.
470 // SymbolTableInclusion:
471 // An atom may or may not be in the symbol table in an object file.
472 // in Most atoms for functions or global data
473 // not-in Anonymous atoms such literal c-strings, or other compiler generated data
474 // not-in-final Atom whose name should not be in the symbol table of final linkd image (e.g. 'l' labels .eh labels)
475 // in-never-strip Atom whose name the strip tool should never remove (e.g. REFERENCED_DYNAMICALLY in mach-o)
478 // Some atoms require specially processing by the linker based on their content. For instance, zero-fill data
479 // atom are group together at the end of the DATA segment to reduce disk size.
482 // For reproducability, the linker lays out atoms in the order they occurred in the source (object) files.
483 // The objectAddress() method returns the address of an atom in the object file so that the linker
484 // can arrange the atoms.
490 enum Scope { scopeTranslationUnit, scopeLinkageUnit, scopeGlobal };
491 enum Definition { definitionRegular, definitionTentative, definitionAbsolute, definitionProxy };
492 enum Combine { combineNever, combineByName, combineByNameAndContent, combineByNameAndReferences };
493 enum ContentType { typeUnclassified, typeZeroFill, typeCString, typeCFI, typeLSDA, typeSectionStart,
494 typeSectionEnd, typeBranchIsland, typeLazyPointer, typeStub, typeNonLazyPointer,
495 typeLazyDylibPointer, typeStubHelper, typeInitializerPointers, typeTerminatorPointers,
496 typeLTOtemporary, typeResolver,
497 typeTLV, typeTLVZeroFill, typeTLVInitialValue, typeTLVInitializerPointers };
499 enum SymbolTableInclusion { symbolTableNotIn, symbolTableNotInFinalLinkedImages, symbolTableIn,
500 symbolTableInAndNeverStrip, symbolTableInAsAbsolute,
501 symbolTableInWithRandomAutoStripLabel };
502 enum WeakImportState { weakImportUnset, weakImportTrue, weakImportFalse };
505 Alignment(int p2, int m=0) : powerOf2(p2), modulus(m) {}
506 uint8_t trailingZeros() const { return (modulus==0) ? powerOf2 : __builtin_ctz(modulus); }
511 const char* fileName;
515 typedef LineInfo* iterator;
518 uint32_t startOffset;
521 typedef UnwindInfo* iterator;
524 Atom(const Section& sect, Definition d, Combine c, Scope s, ContentType ct,
525 SymbolTableInclusion i, bool dds, bool thumb, bool al, Alignment a) :
526 _section(§), _address(0), _alignmentModulus(a.modulus),
527 _alignmentPowerOf2(a.powerOf2), _definition(d), _combine(c),
528 _dontDeadStrip(dds), _thumb(thumb), _alias(al), _autoHide(false),
529 _contentType(ct), _symbolTableInclusion(i),
530 _scope(s), _mode(modeSectionOffset),
531 _overridesADylibsWeakDef(false), _coalescedAway(false),
532 _live(false), _machoSection(0), _weakImportState(weakImportUnset)
535 switch ( _combine ) {
536 case combineByNameAndContent:
537 case combineByNameAndReferences:
538 assert(_symbolTableInclusion == symbolTableNotIn);
539 assert(_scope != scopeGlobal);
549 const Section& section() const { return *_section; }
550 Definition definition() const { return _definition; }
551 Combine combine() const { return _combine; }
552 Scope scope() const { return _scope; }
553 ContentType contentType() const { return _contentType; }
554 SymbolTableInclusion symbolTableInclusion() const{ return _symbolTableInclusion; }
555 bool dontDeadStrip() const { return _dontDeadStrip; }
556 bool isThumb() const { return _thumb; }
557 bool isAlias() const { return _alias; }
558 Alignment alignment() const { return Alignment(_alignmentPowerOf2, _alignmentModulus); }
559 bool overridesDylibsWeakDef() const { return _overridesADylibsWeakDef; }
560 bool coalescedAway() const { return _coalescedAway; }
561 bool weakImported() const { return _weakImportState == weakImportTrue; }
562 WeakImportState weakImportState() const { return _weakImportState; }
563 bool autoHide() const { return _autoHide; }
564 bool live() const { return _live; }
565 uint8_t machoSection() const { assert(_machoSection != 0); return _machoSection; }
567 void setScope(Scope s) { _scope = s; }
568 void setSymbolTableInclusion(SymbolTableInclusion i)
569 { _symbolTableInclusion = i; }
570 void setCombine(Combine c) { _combine = c; }
571 void setOverridesDylibsWeakDef() { _overridesADylibsWeakDef = true; }
572 void setCoalescedAway() { _coalescedAway = true; }
573 void setWeakImportState(bool w) { assert(_definition == definitionProxy); _weakImportState = ( w ? weakImportTrue : weakImportFalse); }
574 void setAutoHide() { _autoHide = true; }
575 void setLive() { _live = true; }
576 void setLive(bool value) { _live = value; }
577 void setMachoSection(unsigned x) { assert(x != 0); assert(x < 256); _machoSection = x; }
578 void setSectionOffset(uint64_t o){ assert(_mode == modeSectionOffset); _address = o; _mode = modeSectionOffset; }
579 void setSectionStartAddress(uint64_t a) { assert(_mode == modeSectionOffset); _address += a; _mode = modeFinalAddress; }
580 uint64_t sectionOffset() const { assert(_mode == modeSectionOffset); return _address; }
581 uint64_t finalAddress() const { assert(_mode == modeFinalAddress); return _address; }
583 virtual const File* file() const = 0;
584 virtual bool translationUnitSource(const char** dir, const char** name) const = 0;
585 virtual const char* name() const = 0;
586 virtual uint64_t objectAddress() const = 0;
587 virtual uint64_t size() const = 0;
588 virtual void copyRawContent(uint8_t buffer[]) const = 0;
589 virtual const uint8_t* rawContentPointer() const { return NULL; }
590 virtual unsigned long contentHash(const class IndirectBindingTable&) const { return 0; }
591 virtual bool canCoalesceWith(const Atom& rhs, const class IndirectBindingTable&) const { return false; }
592 virtual Fixup::iterator fixupsBegin() const { return NULL; }
593 virtual Fixup::iterator fixupsEnd() const { return NULL; }
594 virtual UnwindInfo::iterator beginUnwind() const { return NULL; }
595 virtual UnwindInfo::iterator endUnwind() const { return NULL; }
596 virtual LineInfo::iterator beginLineInfo() const { return NULL; }
597 virtual LineInfo::iterator endLineInfo() const { return NULL; }
600 enum AddressMode { modeSectionOffset, modeFinalAddress };
602 void setAttributesFromAtom(const Atom& a) {
603 _section = a._section;
604 _alignmentModulus = a._alignmentModulus;
605 _alignmentPowerOf2 = a._alignmentPowerOf2;
606 _definition = a._definition;
607 _combine = a._combine;
608 _dontDeadStrip = a._dontDeadStrip;
611 _autoHide = a._autoHide;
612 _contentType = a._contentType;
613 _symbolTableInclusion = a._symbolTableInclusion;
616 _overridesADylibsWeakDef = a._overridesADylibsWeakDef;
617 _coalescedAway = a._coalescedAway;
618 _weakImportState = a._weakImportState;
621 const Section * _section;
623 uint16_t _alignmentModulus;
624 uint8_t _alignmentPowerOf2;
625 Definition _definition : 2;
626 Combine _combine : 2;
627 bool _dontDeadStrip : 1;
631 ContentType _contentType : 5;
632 SymbolTableInclusion _symbolTableInclusion : 3;
634 AddressMode _mode: 2;
635 bool _overridesADylibsWeakDef : 1;
636 bool _coalescedAway : 1;
638 unsigned _machoSection : 8;
639 WeakImportState _weakImportState : 2;
643 class IndirectBindingTable
646 virtual const char* indirectName(uint32_t bindingIndex) const = 0;
647 virtual const ld::Atom* indirectAtom(uint32_t bindingIndex) const = 0;
654 class FinalSection : public ld::Section {
656 FinalSection(const Section& sect) : Section(sect), address(0),
657 fileOffset(0), size(0), alignment(0),
658 indirectSymTabStartIndex(0), indirectSymTabElementSize(0),
659 relocStart(0), relocCount(0),
660 hasLocalRelocs(false), hasExternalRelocs(false) {}
661 std::vector<const Atom*> atoms;
665 uint32_t alignmentPaddingBytes;
667 uint32_t indirectSymTabStartIndex;
668 uint32_t indirectSymTabElementSize;
672 bool hasExternalRelocs;
675 virtual ld::Internal::FinalSection* addAtom(const Atom&) = 0;
676 virtual ld::Internal::FinalSection* getFinalSection(const ld::Section& inputSection) = 0;
677 virtual ~Internal() {}
678 Internal() : bundleLoader(NULL),
679 entryPoint(NULL), classicBindingHelper(NULL),
680 lazyBindingHelper(NULL), compressedFastBinderProxy(NULL),
681 objcObjectConstraint(ld::File::objcConstraintNone),
682 objcDylibConstraint(ld::File::objcConstraintNone),
684 allObjectFilesScatterable(true), hasObjcReplacementClasses(false),
685 someObjectFileHasDwarf(false), usingHugeSections(false) { }
687 std::vector<FinalSection*> sections;
688 std::vector<ld::dylib::File*> dylibs;
689 std::vector<ld::relocatable::File::Stab> stabs;
690 std::vector<const ld::Atom*> indirectBindingTable;
691 const ld::dylib::File* bundleLoader;
692 const Atom* entryPoint;
693 const Atom* classicBindingHelper;
694 const Atom* lazyBindingHelper;
695 const Atom* compressedFastBinderProxy;
696 ld::File::ObjcConstraint objcObjectConstraint;
697 ld::File::ObjcConstraint objcDylibConstraint;
699 bool allObjectFilesScatterable;
700 bool hasObjcReplacementClasses;
701 bool someObjectFileHasDwarf;
702 bool usingHugeSections;