]> git.saurik.com Git - apple/ld64.git/blame - src/ObjectFile.h
ld64-59.2.tar.gz
[apple/ld64.git] / src / ObjectFile.h
CommitLineData
d696c285 1/* -*- mode: C++; c-basic-offset: 4; tab-width: 4 -*-
6e880c60 2 *
d696c285 3 * Copyright (c) 2005-2006 Apple Computer, Inc. All rights reserved.
c2646906
A
4 *
5 * @APPLE_LICENSE_HEADER_START@
d696c285 6 *
c2646906
A
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
12 * file.
d696c285 13 *
c2646906
A
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.
d696c285 21 *
c2646906
A
22 * @APPLE_LICENSE_HEADER_END@
23 */
24
25
26#ifndef __OBJECTFILE__
27#define __OBJECTFILE__
28
29#include <stdint.h>
30#include <vector>
31#include <map>
32
33
34
d696c285
A
35//
36// These classes represent the abstract Atoms and References that are the basis of the linker.
37// An Atom and a Reference correspond to a Node and Edge in graph theory.
38//
39// A Reader is a class which parses an object file and presents it as Atoms and References.
40// All linking operations are done on Atoms and References. This makes the linker file
41// format independent.
42//
43// A Writer takes a vector of Atoms with all References resolved and produces an executable file.
44//
45//
46
47
c2646906
A
48namespace ObjectFile {
49
d696c285
A
50
51struct LineInfo
c2646906 52{
d696c285
A
53 uint32_t atomOffset;
54 const char* fileName;
55 uint32_t lineNumber;
c2646906
A
56};
57
d696c285 58
c2646906
A
59class ReaderOptions
60{
61public:
69a49097
A
62 ReaderOptions() : fFullyLoadArchives(false), fLoadObjcClassesInArchives(false), fFlatNamespace(false),
63 fForFinalLinkedImage(false), fWhyLoad(false), fDebugInfoStripping(kDebugInfoFull),
64 fTraceDylibs(false), fTraceIndirectDylibs(false), fTraceArchives(false), fTraceOutputFile(NULL) {}
d696c285 65 enum DebugInfoStripping { kDebugInfoNone, kDebugInfoMinimal, kDebugInfoFull };
c2646906
A
66
67 bool fFullyLoadArchives;
68 bool fLoadObjcClassesInArchives;
69 bool fFlatNamespace;
69a49097
A
70 bool fForFinalLinkedImage;
71 bool fWhyLoad;
d696c285 72 DebugInfoStripping fDebugInfoStripping;
c2646906
A
73 bool fTraceDylibs;
74 bool fTraceIndirectDylibs;
75 bool fTraceArchives;
d696c285 76 const char* fTraceOutputFile;
c2646906
A
77};
78
79
80class Reader
81{
82public:
d696c285
A
83 enum DebugInfoKind { kDebugInfoNone=0, kDebugInfoStabs=1, kDebugInfoDwarf=2, kDebugInfoStabsUUID=3 };
84 struct Stab
85 {
86 class Atom* atom;
87 uint8_t type;
88 uint8_t other;
89 uint16_t desc;
90 uint32_t value;
91 const char* string;
92 };
93
c2646906 94 static Reader* createReader(const char* path, const ReaderOptions& options);
d696c285 95
c2646906 96 virtual const char* getPath() = 0;
d696c285
A
97 virtual time_t getModificationTime() = 0;
98 virtual DebugInfoKind getDebugInfoKind() = 0;
c2646906
A
99 virtual std::vector<class Atom*>& getAtoms() = 0;
100 virtual std::vector<class Atom*>* getJustInTimeAtomsFor(const char* name) = 0;
d696c285
A
101 virtual std::vector<Stab>* getStabs() = 0;
102 unsigned int getSortOrder() const { return fSortOrder; }
103 void setSortOrder(unsigned int order) { fSortOrder=order; }
104
c2646906
A
105 // For Dynamic Libraries only
106 virtual const char* getInstallPath() { return NULL; }
107 virtual uint32_t getTimestamp() { return 0; }
108 virtual uint32_t getCurrentVersion() { return 0; }
109 virtual uint32_t getCompatibilityVersion() { return 0; }
110 virtual std::vector<const char*>* getDependentLibraryPaths() { return NULL; }
111 virtual bool reExports(Reader*) { return false; }
d696c285
A
112 virtual const char* parentUmbrella() { return NULL; }
113 virtual std::vector<const char*>* getAllowableClients() { return NULL; }
114
c2646906 115protected:
d696c285 116 Reader() : fSortOrder(0) {}
6e880c60 117 virtual ~Reader() {}
d696c285
A
118
119 unsigned int fSortOrder;
c2646906
A
120};
121
122class Segment
123{
124public:
125 virtual const char* getName() const = 0;
126 virtual bool isContentReadable() const = 0;
127 virtual bool isContentWritable() const = 0;
128 virtual bool isContentExecutable() const = 0;
d696c285 129
c2646906
A
130 uint64_t getBaseAddress() const { return fBaseAddress; }
131 void setBaseAddress(uint64_t addr) { fBaseAddress = addr; }
6e880c60 132 virtual bool hasFixedAddress() const { return false; }
c2646906
A
133
134protected:
6e880c60
A
135 Segment() : fBaseAddress(0) {}
136 virtual ~Segment() {}
c2646906
A
137 uint64_t fBaseAddress;
138};
139
140class Reference;
141
d696c285 142class Section
c2646906
A
143{
144public:
145 unsigned int getIndex() { return fIndex; }
146 uint64_t getBaseAddress() { return fBaseAddress; }
147 void setBaseAddress(uint64_t addr) { fBaseAddress = addr; }
148 void* fOther;
d696c285 149
c2646906
A
150protected:
151 Section() : fOther(NULL), fBaseAddress(0), fIndex(0) {}
152 uint64_t fBaseAddress;
153 unsigned int fIndex;
154};
155
156
c2646906 157
d696c285
A
158//
159// An atom is the fundamental unit of linking. A C function or global variable is an atom.
160// An atom has content and some attributes. The content of a function atom is the instructions
161// that implement the function. The content of a global variable atom is its initial bits.
162//
163// Name:
164// The name of an atom is the label name generated by the compiler. A C compiler names foo()
165// as _foo. A C++ compiler names foo() as __Z3foov.
166// The name refers to the first byte of the content. An atom cannot have multiple entry points.
167// Such code is modeled as multiple atoms, each having a "follow on" reference to the next.
168// A "follow on" reference is a contraint to the linker to the atoms must be laid out contiguously.
169//
170// Scope:
171// An atom is in one of three scopes: translation-unit, linkage-unit, or global. These correspond
172// to the C visibility of static, hidden, default.
173//
174// DefinitionKind:
175// An atom is one of five defintion kinds:
176// regular Most atoms.
177// weak C++ compiler makes some functions weak if there might be multiple copies
178// that the linker needs to coalesce.
179// tentative A straggler from ancient C when the extern did not exist. "int foo;" is ambiguous.
180// It could be a prototype or it could be a definition.
181// external This is a "proxy" atom produced by a dylib reader. It has no content. It exists
182// so that all References can be resolved.
183// external-weak Same as external, but the definition in the dylib is weak.
184//
185// SymbolTableInclusion:
186// An atom may or may not be in the symbol table in an object file.
187// in Most atoms for functions or global data
188// not-in Anonymous atoms such literal c-strings, or other compiler generated data
189// in-never-strip Atom whose name the strip tool should never remove (e.g. REFERENCED_DYNAMICALLY in mach-o)
190//
191class Atom
c2646906
A
192{
193public:
194 enum Scope { scopeTranslationUnit, scopeLinkageUnit, scopeGlobal };
d696c285 195 enum DefinitionKind { kRegularDefinition, kWeakDefinition, kTentativeDefinition, kExternalDefinition, kExternalWeakDefinition };
69a49097 196 enum SymbolTableInclusion { kSymbolTableNotIn, kSymbolTableIn, kSymbolTableInAndNeverStrip, kSymbolTableInAsAbsolute };
d696c285 197
c2646906 198 virtual Reader* getFile() const = 0;
d696c285 199 virtual bool getTranslationUnitSource(const char** dir, const char** name) const = 0;
c2646906
A
200 virtual const char* getName() const = 0;
201 virtual const char* getDisplayName() const = 0;
202 virtual Scope getScope() const = 0;
d696c285
A
203 virtual DefinitionKind getDefinitionKind() const = 0;
204 virtual SymbolTableInclusion getSymbolTableInclusion() const = 0;
69a49097 205 virtual bool dontDeadStrip() const = 0;
c2646906 206 virtual bool isZeroFill() const = 0;
c2646906
A
207 virtual uint64_t getSize() const = 0;
208 virtual std::vector<ObjectFile::Reference*>& getReferences() const = 0;
209 virtual bool mustRemainInSection() const = 0;
210 virtual const char* getSectionName() const = 0;
211 virtual Segment& getSegment() const = 0;
212 virtual bool requiresFollowOnAtom() const = 0;
213 virtual Atom& getFollowOnAtom() const = 0;
d696c285 214 virtual std::vector<LineInfo>* getLineInfo() const = 0;
c2646906 215 virtual uint8_t getAlignment() const = 0;
c2646906 216 virtual void copyRawContent(uint8_t buffer[]) const = 0;
c2646906 217 virtual void setScope(Scope) = 0;
c2646906 218
d696c285 219
c2646906
A
220 uint64_t getSectionOffset() const { return fSectionOffset; }
221 uint64_t getSegmentOffset() const { return fSegmentOffset; }
222 uint64_t getAddress() const { return fSection->getBaseAddress() + fSectionOffset; }
223 unsigned int getSortOrder() const { return fSortOrder; }
224 class Section* getSection() const { return fSection; }
225
226 void setSegmentOffset(uint64_t offset) { fSegmentOffset = offset; }
227 void setSectionOffset(uint64_t offset) { fSectionOffset = offset; }
d696c285 228 void setSection(class Section* sect) { fSection = sect; }
c2646906
A
229 unsigned int setSortOrder(unsigned int order); // recursively sets follow-on atoms
230
231protected:
69a49097 232 Atom() : fSegmentOffset(0), fSectionOffset(0), fSortOrder(0), fSection(NULL) {}
6e880c60 233 virtual ~Atom() {}
d696c285 234
c2646906
A
235 uint64_t fSegmentOffset;
236 uint64_t fSectionOffset;
237 unsigned int fSortOrder;
238 class Section* fSection;
239};
240
241
242
243// recursively sets follow-on atoms
244inline unsigned int Atom::setSortOrder(unsigned int order)
245{
246 if ( this->requiresFollowOnAtom() ) {
247 fSortOrder = order;
248 return this->getFollowOnAtom().setSortOrder(order+1);
249 }
250 else {
251 fSortOrder = order;
252 return (order + 1);
253 }
254}
255
256
257
d696c285
A
258//
259// A Reference is a directed edge to another Atom. When an instruction in
260// the content of an Atom refers to another Atom, that is represented by a
261// Reference.
262//
263// There are two kinds of references: direct and by-name. With a direct Reference,
264// the target is bound by the Reader that created it. For instance a reference to a
265// static would produce a direct reference. A by-name reference requires the linker
266// to find the target Atom with the required name in order to be bound.
267//
268// For a link to succeed all References must be bound.
269//
270// A Reference has an optional "from" target. This is used when the content to fix-up
271// is the difference of two Atom address. For instance, if a pointer sized data Atom
272// is to contain A - B, then the Atom would have on Reference with a target of "A" and
273// a from-target of "B".
274//
275// A Reference also has a fix-up-offset. This is the offset into the content of the
276// Atom holding the reference where the fix-up (relocation) will be applied.
277//
278//
279//
c2646906
A
280class Reference
281{
282public:
c2646906 283
6e880c60
A
284 virtual bool isTargetUnbound() const = 0;
285 virtual bool isFromTargetUnbound() const = 0;
d696c285 286 virtual uint8_t getKind() const = 0;
c2646906
A
287 virtual uint64_t getFixUpOffset() const = 0;
288 virtual const char* getTargetName() const = 0;
289 virtual Atom& getTarget() const = 0;
290 virtual uint64_t getTargetOffset() const = 0;
6e880c60 291 virtual bool hasFromTarget() const = 0;
c2646906
A
292 virtual Atom& getFromTarget() const = 0;
293 virtual const char* getFromTargetName() const = 0;
294 virtual uint64_t getFromTargetOffset() const = 0;
295
6e880c60 296 virtual void setTarget(Atom&, uint64_t offset) = 0;
c2646906
A
297 virtual void setFromTarget(Atom&) = 0;
298 virtual const char* getDescription() const = 0;
d696c285 299
6e880c60
A
300protected:
301 Reference() {}
302 virtual ~Reference() {}
c2646906
A
303};
304
305
306}; // namespace ObjectFile
307
308
309#endif // __OBJECTFILE__