1 /* -*- mode: C++; c-basic-offset: 4; tab-width: 4 -*-
3 * Copyright (c) 2005-2007 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@
26 #ifndef __OBJECTFILE__
27 #define __OBJECTFILE__
37 // These classes represent the abstract Atoms and References that are the basis of the linker.
38 // An Atom and a Reference correspond to a Node and Edge in graph theory.
40 // A Reader is a class which parses an object file and presents it as Atoms and References.
41 // All linking operations are done on Atoms and References. This makes the linker file
42 // format independent.
44 // A Writer takes a vector of Atoms with all References resolved and produces an executable file.
50 namespace ObjectFile
{
64 ReaderOptions() : fFullyLoadArchives(false), fLoadAllObjcObjectsFromArchives(false), fFlatNamespace(false),
65 fLinkingMainExecutable(false),
66 fForFinalLinkedImage(false), fNoEHLabels(false), fForStatic(false), fForDyld(false), fMakeTentativeDefinitionsReal(false),
67 fWhyLoad(false), fRootSafe(false), fSetuidSafe(false),fDebugInfoStripping(kDebugInfoFull
),
68 fImplicitlyLinkPublicDylibs(true),
69 fAddCompactUnwindEncoding(true),
70 fWarnCompactUnwind(false),
71 fRemoveDwarfUnwindIfCompactExists(false),
72 fMakeCompressedDyldInfo(false),
73 fAutoOrderInitializers(true),
74 fOptimizeZeroFill(true),
75 fLogObjectFiles(false), fLogAllFiles(false),
76 fTraceDylibs(false), fTraceIndirectDylibs(false), fTraceArchives(false),
77 fTraceOutputFile(NULL
), fMacVersionMin(kMinMacVersionUnset
), fIPhoneVersionMin(kMinIPhoneVersionUnset
) {}
78 enum DebugInfoStripping
{ kDebugInfoNone
, kDebugInfoMinimal
, kDebugInfoFull
};
79 enum MacVersionMin
{ kMinMacVersionUnset
, k10_1
, k10_2
, k10_3
, k10_4
, k10_5
, k10_6
, k10_7
};
80 enum IPhoneVersionMin
{ kMinIPhoneVersionUnset
, k2_0
, k2_1
, k2_2
, k3_0
, k3_1
, k3_2
, k4_0
};
87 bool fFullyLoadArchives
;
88 bool fLoadAllObjcObjectsFromArchives
;
90 bool fLinkingMainExecutable
;
91 bool fForFinalLinkedImage
;
95 bool fMakeTentativeDefinitionsReal
;
99 DebugInfoStripping fDebugInfoStripping
;
100 bool fImplicitlyLinkPublicDylibs
;
101 bool fAddCompactUnwindEncoding
;
102 bool fWarnCompactUnwind
;
103 bool fRemoveDwarfUnwindIfCompactExists
;
104 bool fMakeCompressedDyldInfo
;
105 bool fAutoOrderInitializers
;
106 bool fOptimizeZeroFill
;
107 bool fLogObjectFiles
;
110 bool fTraceIndirectDylibs
;
112 const char* fTraceOutputFile
;
113 MacVersionMin fMacVersionMin
;
114 IPhoneVersionMin fIPhoneVersionMin
;
115 std::vector
<AliasPair
> fAliases
;
122 enum DebugInfoKind
{ kDebugInfoNone
=0, kDebugInfoStabs
=1, kDebugInfoDwarf
=2, kDebugInfoStabsUUID
=3 };
132 enum ObjcConstraint
{ kObjcNone
, kObjcRetainRelease
, kObjcRetainReleaseOrGC
, kObjcGC
};
133 enum CpuConstraint
{ kCpuAny
= 0 };
138 virtual ~DylibHander() {}
139 virtual Reader
* findDylib(const char* installPath
, const char* fromPath
) = 0;
143 static Reader
* createReader(const char* path
, const ReaderOptions
& options
);
145 virtual const char* getPath() = 0;
146 virtual time_t getModificationTime() = 0;
147 virtual DebugInfoKind
getDebugInfoKind() = 0;
148 virtual std::vector
<class Atom
*>& getAtoms() = 0;
149 virtual std::vector
<class Atom
*>* getJustInTimeAtomsFor(const char* name
) = 0;
150 virtual std::vector
<Stab
>* getStabs() = 0;
151 virtual ObjcConstraint
getObjCConstraint() { return kObjcNone
; }
152 virtual uint32_t updateCpuConstraint(uint32_t current
) { return current
; }
153 virtual bool objcReplacementClasses() { return false; }
155 // For relocatable object files only
156 virtual bool canScatterAtoms() { return true; }
157 virtual bool optimize(const std::vector
<ObjectFile::Atom
*>&, std::vector
<ObjectFile::Atom
*>&,
158 std::vector
<const char*>&, const std::set
<ObjectFile::Atom
*>&,
159 std::vector
<ObjectFile::Atom
*>&,
160 uint32_t, ObjectFile::Reader
* writer
,
161 ObjectFile::Atom
* entryPointAtom
,
162 const std::vector
<const char*>& llvmOptions
,
163 bool allGlobalsAReDeadStripRoots
, int okind
,
164 bool verbose
, bool saveTemps
, const char* outputFilePath
,
165 bool pie
, bool allowTextRelocs
) { return false; }
166 virtual bool hasLongBranchStubs() { return false; }
168 // For Dynamic Libraries only
169 virtual const char* getInstallPath() { return NULL
; }
170 virtual uint32_t getTimestamp() { return 0; }
171 virtual uint32_t getCurrentVersion() { return 0; }
172 virtual uint32_t getCompatibilityVersion() { return 0; }
173 virtual void processIndirectLibraries(DylibHander
* handler
) { }
174 virtual void setExplicitlyLinked() { }
175 virtual bool explicitlyLinked() { return false; }
176 virtual bool implicitlyLinked() { return false; }
177 virtual bool providedExportAtom() { return false; }
178 virtual const char* parentUmbrella() { return NULL
; }
179 virtual std::vector
<const char*>* getAllowableClients() { return NULL
; }
180 virtual bool hasWeakExternals() { return false; }
181 virtual bool deadStrippable() { return false; }
182 virtual bool isLazyLoadedDylib() { return false; }
192 virtual const char* getName() const = 0;
193 virtual bool isContentReadable() const = 0;
194 virtual bool isContentWritable() const = 0;
195 virtual bool isContentExecutable() const = 0;
197 uint64_t getBaseAddress() const { return fBaseAddress
; }
198 void setBaseAddress(uint64_t addr
) { fBaseAddress
= addr
; }
199 virtual bool hasFixedAddress() const { return false; }
202 Segment() : fBaseAddress(0) {}
203 virtual ~Segment() {}
204 uint64_t fBaseAddress
;
212 unsigned int getIndex() { return fIndex
; }
213 uint64_t getBaseAddress() { return fBaseAddress
; }
214 void setBaseAddress(uint64_t addr
) { fBaseAddress
= addr
; }
218 Section() : fOther(NULL
), fBaseAddress(0), fIndex(0) {}
219 uint64_t fBaseAddress
;
226 Alignment(int p2
, int m
=0) : powerOf2(p2
), modulus(m
) {}
227 uint8_t trailingZeros() const { return (modulus
==0) ? powerOf2
: __builtin_ctz(modulus
); }
234 uint32_t startOffset
;
237 typedef UnwindInfo
* iterator
;
243 // An atom is the fundamental unit of linking. A C function or global variable is an atom.
244 // An atom has content and some attributes. The content of a function atom is the instructions
245 // that implement the function. The content of a global variable atom is its initial bits.
248 // The name of an atom is the label name generated by the compiler. A C compiler names foo()
249 // as _foo. A C++ compiler names foo() as __Z3foov.
250 // The name refers to the first byte of the content. An atom cannot have multiple entry points.
251 // Such code is modeled as multiple atoms, each having a "follow on" reference to the next.
252 // A "follow on" reference is a contraint to the linker to the atoms must be laid out contiguously.
255 // An atom is in one of three scopes: translation-unit, linkage-unit, or global. These correspond
256 // to the C visibility of static, hidden, default.
259 // An atom is one of five defintion kinds:
260 // regular Most atoms.
261 // weak C++ compiler makes some functions weak if there might be multiple copies
262 // that the linker needs to coalesce.
263 // tentative A straggler from ancient C when the extern did not exist. "int foo;" is ambiguous.
264 // It could be a prototype or it could be a definition.
265 // external This is a "proxy" atom produced by a dylib reader. It has no content. It exists
266 // so that all References can be resolved.
267 // external-weak Same as external, but the definition in the dylib is weak.
269 // SymbolTableInclusion:
270 // An atom may or may not be in the symbol table in an object file.
271 // in Most atoms for functions or global data
272 // not-in Anonymous atoms such literal c-strings, or other compiler generated data
273 // in-never-strip Atom whose name the strip tool should never remove (e.g. REFERENCED_DYNAMICALLY in mach-o)
276 // When a reader is created it is given a base ordinal number. All atoms created by the reader
277 // should return a contiguous range of ordinal values that start at the base ordinal. The ordinal
278 // values are used by the linker to sort the atom graph when producing the output file.
283 enum Scope
{ scopeTranslationUnit
, scopeLinkageUnit
, scopeGlobal
};
284 enum DefinitionKind
{ kRegularDefinition
, kWeakDefinition
, kTentativeDefinition
, kExternalDefinition
, kExternalWeakDefinition
, kAbsoluteSymbol
};
285 enum ContentType
{ kUnclassifiedType
, kCStringType
, kCFIType
, kLSDAType
, kSectionStart
, kSectionEnd
, kBranchIsland
,
286 kLazyPointer
, kStub
, kNonLazyPointer
, kLazyDylibPointer
, kStubHelper
};
287 enum SymbolTableInclusion
{ kSymbolTableNotIn
, kSymbolTableIn
, kSymbolTableInAndNeverStrip
, kSymbolTableInAsAbsolute
};
289 virtual Reader
* getFile() const = 0;
290 virtual bool getTranslationUnitSource(const char** dir
, const char** name
) const = 0;
291 virtual const char* getName() const = 0;
292 virtual const char* getDisplayName() const = 0;
293 virtual Scope
getScope() const = 0;
294 virtual DefinitionKind
getDefinitionKind() const = 0;
295 virtual ContentType
getContentType() const { return kUnclassifiedType
; }
296 virtual SymbolTableInclusion
getSymbolTableInclusion() const = 0;
297 virtual bool dontDeadStrip() const = 0;
298 virtual bool isZeroFill() const = 0;
299 virtual bool isThumb() const = 0;
300 virtual uint64_t getSize() const = 0;
301 virtual std::vector
<ObjectFile::Reference
*>& getReferences() const = 0;
302 virtual bool mustRemainInSection() const = 0;
303 virtual const char* getSectionName() const = 0;
304 virtual Segment
& getSegment() const = 0;
305 virtual Atom
& getFollowOnAtom() const = 0;
306 virtual uint32_t getOrdinal() const = 0;
307 virtual std::vector
<LineInfo
>* getLineInfo() const = 0;
308 virtual Alignment
getAlignment() const = 0;
309 virtual void copyRawContent(uint8_t buffer
[]) const = 0;
310 virtual void setScope(Scope
) = 0;
311 virtual UnwindInfo::iterator
beginUnwind() { return NULL
; }
312 virtual UnwindInfo::iterator
endUnwind() { return NULL
; }
313 virtual Reference
* getLSDA() { return NULL
; }
314 virtual Reference
* getFDE() { return NULL
; }
315 virtual Atom
* getPersonalityPointer() { return NULL
; }
317 uint64_t getSectionOffset() const { return fSectionOffset
; }
318 uint64_t getAddress() const { return fSection
->getBaseAddress() + fSectionOffset
; }
319 class Section
* getSection() const { return fSection
; }
321 virtual void setSectionOffset(uint64_t offset
) { fSectionOffset
= offset
; }
322 virtual void setSection(class Section
* sect
) { fSection
= sect
; }
325 Atom() : fSectionOffset(0), fSection(NULL
) {}
328 uint64_t fSectionOffset
;
329 class Section
* fSection
;
334 // A Reference is a directed edge to another Atom. When an instruction in
335 // the content of an Atom refers to another Atom, that is represented by a
338 // There are two kinds of references: direct and by-name. With a direct Reference,
339 // the target is bound by the Reader that created it. For instance a reference to a
340 // static would produce a direct reference. A by-name reference requires the linker
341 // to find the target Atom with the required name in order to be bound.
343 // For a link to succeed all References must be bound.
345 // A Reference has an optional "from" target. This is used when the content to fix-up
346 // is the difference of two Atom address. For instance, if a pointer sized data Atom
347 // is to contain A - B, then the Atom would have on Reference with a target of "A" and
348 // a from-target of "B".
350 // A Reference also has a fix-up-offset. This is the offset into the content of the
351 // Atom holding the reference where the fix-up (relocation) will be applied.
358 enum TargetBinding
{ kUnboundByName
, kBoundDirectly
, kBoundByName
, kDontBind
};
360 virtual TargetBinding
getTargetBinding() const = 0;
361 virtual TargetBinding
getFromTargetBinding() const = 0;
362 virtual uint8_t getKind() const = 0;
363 virtual uint64_t getFixUpOffset() const = 0;
364 virtual const char* getTargetName() const = 0;
365 virtual Atom
& getTarget() const = 0;
366 virtual uint64_t getTargetOffset() const = 0;
367 virtual Atom
& getFromTarget() const = 0;
368 virtual const char* getFromTargetName() const = 0;
369 virtual uint64_t getFromTargetOffset() const = 0;
371 virtual void setTarget(Atom
&, uint64_t offset
) = 0;
372 virtual void setFromTarget(Atom
&) = 0;
373 virtual const char* getDescription() const = 0;
374 virtual bool isBranch() const { return false; }
378 virtual ~Reference() {}
382 }; // namespace ObjectFile
385 #endif // __OBJECTFILE__