/Users/buildslave/jenkins/sharedspace/clang-stage2-coverage-R@2/llvm/tools/lld/include/lld/Core/DefinedAtom.h
Line | Count | Source (jump to first uncovered line) |
1 | | //===- Core/DefinedAtom.h - An Atom with content --------------------------===// |
2 | | // |
3 | | // The LLVM Linker |
4 | | // |
5 | | // This file is distributed under the University of Illinois Open Source |
6 | | // License. See LICENSE.TXT for details. |
7 | | // |
8 | | //===----------------------------------------------------------------------===// |
9 | | |
10 | | #ifndef LLD_CORE_DEFINED_ATOM_H |
11 | | #define LLD_CORE_DEFINED_ATOM_H |
12 | | |
13 | | #include "lld/Core/Atom.h" |
14 | | #include "lld/Core/Reference.h" |
15 | | #include "lld/Core/LLVM.h" |
16 | | #include "llvm/Support/ErrorHandling.h" |
17 | | |
18 | | namespace lld { |
19 | | class File; |
20 | | |
21 | | /// \brief The fundamental unit of linking. |
22 | | /// |
23 | | /// A C function or global variable is an atom. An atom has content and |
24 | | /// attributes. The content of a function atom is the instructions that |
25 | | /// implement the function. The content of a global variable atom is its |
26 | | /// initial bytes. |
27 | | /// |
28 | | /// Here are some example attribute sets for common atoms. If a particular |
29 | | /// attribute is not listed, the default values are: definition=regular, |
30 | | /// sectionChoice=basedOnContent, scope=translationUnit, merge=no, |
31 | | /// deadStrip=normal, interposable=no |
32 | | /// |
33 | | /// C function: void foo() {} <br> |
34 | | /// name=foo, type=code, perm=r_x, scope=global |
35 | | /// |
36 | | /// C static function: staic void func() {} <br> |
37 | | /// name=func, type=code, perm=r_x |
38 | | /// |
39 | | /// C global variable: int count = 1; <br> |
40 | | /// name=count, type=data, perm=rw_, scope=global |
41 | | /// |
42 | | /// C tentative definition: int bar; <br> |
43 | | /// name=bar, type=zerofill, perm=rw_, scope=global, |
44 | | /// merge=asTentative, interposable=yesAndRuntimeWeak |
45 | | /// |
46 | | /// Uninitialized C static variable: static int stuff; <br> |
47 | | /// name=stuff, type=zerofill, perm=rw_ |
48 | | /// |
49 | | /// Weak C function: __attribute__((weak)) void foo() {} <br> |
50 | | /// name=foo, type=code, perm=r_x, scope=global, merge=asWeak |
51 | | /// |
52 | | /// Hidden C function: __attribute__((visibility("hidden"))) void foo() {}<br> |
53 | | /// name=foo, type=code, perm=r_x, scope=linkageUnit |
54 | | /// |
55 | | /// No-dead-strip function: __attribute__((used)) void foo() {} <br> |
56 | | /// name=foo, type=code, perm=r_x, scope=global, deadStrip=never |
57 | | /// |
58 | | /// Non-inlined C++ inline method: inline void Foo::doit() {} <br> |
59 | | /// name=_ZN3Foo4doitEv, type=code, perm=r_x, scope=global, |
60 | | /// mergeDupes=asWeak |
61 | | /// |
62 | | /// Non-inlined C++ inline method whose address is taken: |
63 | | /// inline void Foo::doit() {} <br> |
64 | | /// name=_ZN3Foo4doitEv, type=code, perm=r_x, scope=global, |
65 | | /// mergeDupes=asAddressedWeak |
66 | | /// |
67 | | /// literal c-string: "hello" <br> |
68 | | /// name="" type=cstring, perm=r__, scope=linkageUnit |
69 | | /// |
70 | | /// literal double: 1.234 <br> |
71 | | /// name="" type=literal8, perm=r__, scope=linkageUnit |
72 | | /// |
73 | | /// constant: { 1,2,3 } <br> |
74 | | /// name="" type=constant, perm=r__, scope=linkageUnit |
75 | | /// |
76 | | /// Pointer to initializer function: <br> |
77 | | /// name="" type=initializer, perm=rw_l, |
78 | | /// sectionChoice=customRequired |
79 | | /// |
80 | | /// C function place in custom section: __attribute__((section("__foo"))) |
81 | | /// void foo() {} <br> |
82 | | /// name=foo, type=code, perm=r_x, scope=global, |
83 | | /// sectionChoice=customRequired, customSectionName=__foo |
84 | | /// |
85 | | class DefinedAtom : public Atom { |
86 | | public: |
87 | | enum Interposable { |
88 | | interposeNo, // linker can directly bind uses of this atom |
89 | | interposeYes, // linker must indirect (through GOT) uses |
90 | | interposeYesAndRuntimeWeak // must indirect and mark symbol weak in final |
91 | | // linked image |
92 | | }; |
93 | | |
94 | | enum Merge { |
95 | | mergeNo, // Another atom with same name is error |
96 | | mergeAsTentative, // Is ANSI C tentative definition, can be coalesced |
97 | | mergeAsWeak, // Is C++ inline definition that was not inlined, |
98 | | // but address was not taken, so atom can be hidden |
99 | | // by linker |
100 | | mergeAsWeakAndAddressUsed, // Is C++ definition inline definition whose |
101 | | // address was taken. |
102 | | mergeSameNameAndSize, // Another atom with different size is error |
103 | | mergeByLargestSection, // Choose an atom whose section is the largest. |
104 | | mergeByContent, // Merge with other constants with same content. |
105 | | }; |
106 | | |
107 | | enum ContentType { |
108 | | typeUnknown, // for use with definitionUndefined |
109 | | typeMachHeader, // atom representing mach_header [Darwin] |
110 | | typeCode, // executable code |
111 | | typeResolver, // function which returns address of target |
112 | | typeBranchIsland, // linker created for large binaries |
113 | | typeBranchShim, // linker created to switch thumb mode |
114 | | typeStub, // linker created for calling external function |
115 | | typeStubHelper, // linker created for initial stub binding |
116 | | typeConstant, // a read-only constant |
117 | | typeCString, // a zero terminated UTF8 C string |
118 | | typeUTF16String, // a zero terminated UTF16 string |
119 | | typeCFI, // a FDE or CIE from dwarf unwind info |
120 | | typeLSDA, // extra unwinding info |
121 | | typeLiteral4, // a four-btye read-only constant |
122 | | typeLiteral8, // an eight-btye read-only constant |
123 | | typeLiteral16, // a sixteen-btye read-only constant |
124 | | typeData, // read-write data |
125 | | typeDataFast, // allow data to be quickly accessed |
126 | | typeZeroFill, // zero-fill data |
127 | | typeZeroFillFast, // allow zero-fill data to be quicky accessed |
128 | | typeConstData, // read-only data after dynamic linker is done |
129 | | typeObjC1Class, // ObjC1 class [Darwin] |
130 | | typeLazyPointer, // pointer through which a stub jumps |
131 | | typeLazyDylibPointer, // pointer through which a stub jumps [Darwin] |
132 | | typeNonLazyPointer, // pointer to external symbol |
133 | | typeCFString, // NS/CFString object [Darwin] |
134 | | typeGOT, // pointer to external symbol |
135 | | typeInitializerPtr, // pointer to initializer function |
136 | | typeTerminatorPtr, // pointer to terminator function |
137 | | typeCStringPtr, // pointer to UTF8 C string [Darwin] |
138 | | typeObjCClassPtr, // pointer to ObjC class [Darwin] |
139 | | typeObjC2CategoryList, // pointers to ObjC category [Darwin] |
140 | | typeObjCImageInfo, // pointer to ObjC class [Darwin] |
141 | | typeObjCMethodList, // pointer to ObjC method list [Darwin] |
142 | | typeDTraceDOF, // runtime data for Dtrace [Darwin] |
143 | | typeInterposingTuples, // tuples of interposing info for dyld [Darwin] |
144 | | typeTempLTO, // temporary atom for bitcode reader |
145 | | typeCompactUnwindInfo, // runtime data for unwinder [Darwin] |
146 | | typeProcessedUnwindInfo,// compressed compact unwind info [Darwin] |
147 | | typeThunkTLV, // thunk used to access a TLV [Darwin] |
148 | | typeTLVInitialData, // initial data for a TLV [Darwin] |
149 | | typeTLVInitialZeroFill, // TLV initial zero fill data [Darwin] |
150 | | typeTLVInitializerPtr, // pointer to thread local initializer [Darwin] |
151 | | typeDSOHandle, // atom representing DSO handle [Darwin] |
152 | | typeSectCreate, // Created via the -sectcreate option [Darwin] |
153 | | }; |
154 | | |
155 | | // Permission bits for atoms and segments. The order of these values are |
156 | | // important, because the layout pass may sort atoms by permission if other |
157 | | // attributes are the same. |
158 | | enum ContentPermissions { |
159 | | perm___ = 0, // mapped as unaccessible |
160 | | permR__ = 8, // mapped read-only |
161 | | permRW_ = 8 + 2, // mapped readable and writable |
162 | | permRW_L = 8 + 2 + 1, // initially mapped r/w, then made read-only |
163 | | // loader writable |
164 | | permR_X = 8 + 4, // mapped readable and executable |
165 | | permRWX = 8 + 2 + 4, // mapped readable and writable and executable |
166 | | permUnknown = 16 // unknown or invalid permissions |
167 | | }; |
168 | | |
169 | | enum SectionChoice { |
170 | | sectionBasedOnContent, // linker infers final section based on content |
171 | | sectionCustomPreferred, // linker may place in specific section |
172 | | sectionCustomRequired // linker must place in specific section |
173 | | }; |
174 | | |
175 | | enum DeadStripKind { |
176 | | deadStripNormal, // linker may dead strip this atom |
177 | | deadStripNever, // linker must never dead strip this atom |
178 | | deadStripAlways // linker must remove this atom if unused |
179 | | }; |
180 | | |
181 | | enum DynamicExport { |
182 | | /// \brief The linker may or may not export this atom dynamically depending |
183 | | /// on the output type and other context of the link. |
184 | | dynamicExportNormal, |
185 | | /// \brief The linker will always export this atom dynamically. |
186 | | dynamicExportAlways, |
187 | | }; |
188 | | |
189 | | // Attributes describe a code model used by the atom. |
190 | | enum CodeModel { |
191 | | codeNA, // no specific code model |
192 | | // MIPS code models |
193 | | codeMipsPIC, // PIC function in a PIC / non-PIC mixed file |
194 | | codeMipsMicro, // microMIPS instruction encoding |
195 | | codeMipsMicroPIC, // microMIPS instruction encoding + PIC |
196 | | codeMips16, // MIPS-16 instruction encoding |
197 | | // ARM code models |
198 | | codeARMThumb, // ARM Thumb instruction set |
199 | | codeARM_a, // $a-like mapping symbol (for ARM code) |
200 | | codeARM_d, // $d-like mapping symbol (for data) |
201 | | codeARM_t, // $t-like mapping symbol (for Thumb code) |
202 | | }; |
203 | | |
204 | | struct Alignment { |
205 | 1.24k | Alignment(int v, int m = 0) : value(v), modulus(m) {} |
206 | | |
207 | | uint16_t value; |
208 | | uint16_t modulus; |
209 | | |
210 | 272 | bool operator==(const Alignment &rhs) const { |
211 | 102 | return (value == rhs.value) && (modulus == rhs.modulus); |
212 | 272 | } |
213 | | }; |
214 | | |
215 | | /// \brief returns a value for the order of this Atom within its file. |
216 | | /// |
217 | | /// This is used by the linker to order the layout of Atoms so that the |
218 | | /// resulting image is stable and reproducible. |
219 | | virtual uint64_t ordinal() const = 0; |
220 | | |
221 | | /// \brief the number of bytes of space this atom's content will occupy in the |
222 | | /// final linked image. |
223 | | /// |
224 | | /// For a function atom, it is the number of bytes of code in the function. |
225 | | virtual uint64_t size() const = 0; |
226 | | |
227 | | /// \brief The size of the section from which the atom is instantiated. |
228 | | /// |
229 | | /// Merge::mergeByLargestSection is defined in terms of section size |
230 | | /// and not in terms of atom size, so we need this function separate |
231 | | /// from size(). |
232 | 267 | virtual uint64_t sectionSize() const { return 0; } |
233 | | |
234 | | /// \brief The visibility of this atom to other atoms. |
235 | | /// |
236 | | /// C static functions have scope scopeTranslationUnit. Regular C functions |
237 | | /// have scope scopeGlobal. Functions compiled with visibility=hidden have |
238 | | /// scope scopeLinkageUnit so they can be see by other atoms being linked but |
239 | | /// not by the OS loader. |
240 | | virtual Scope scope() const = 0; |
241 | | |
242 | | /// \brief Whether the linker should use direct or indirect access to this |
243 | | /// atom. |
244 | | virtual Interposable interposable() const = 0; |
245 | | |
246 | | /// \brief how the linker should handle if multiple atoms have the same name. |
247 | | virtual Merge merge() const = 0; |
248 | | |
249 | | /// \brief The type of this atom, such as code or data. |
250 | | virtual ContentType contentType() const = 0; |
251 | | |
252 | | /// \brief The alignment constraints on how this atom must be laid out in the |
253 | | /// final linked image (e.g. 16-byte aligned). |
254 | | virtual Alignment alignment() const = 0; |
255 | | |
256 | | /// \brief Whether this atom must be in a specially named section in the final |
257 | | /// linked image, or if the linker can infer the section based on the |
258 | | /// contentType(). |
259 | | virtual SectionChoice sectionChoice() const = 0; |
260 | | |
261 | | /// \brief If sectionChoice() != sectionBasedOnContent, then this return the |
262 | | /// name of the section the atom should be placed into. |
263 | | virtual StringRef customSectionName() const = 0; |
264 | | |
265 | | /// \brief constraints on whether the linker may dead strip away this atom. |
266 | | virtual DeadStripKind deadStrip() const = 0; |
267 | | |
268 | | /// \brief Under which conditions should this atom be dynamically exported. |
269 | 267 | virtual DynamicExport dynamicExport() const { |
270 | 267 | return dynamicExportNormal; |
271 | 267 | } |
272 | | |
273 | | /// \brief Code model used by the atom. |
274 | 267 | virtual CodeModel codeModel() const { return codeNA; } |
275 | | |
276 | | /// \brief Returns the OS memory protections required for this atom's content |
277 | | /// at runtime. |
278 | | /// |
279 | | /// A function atom is R_X, a global variable is RW_, and a read-only constant |
280 | | /// is R__. |
281 | | virtual ContentPermissions permissions() const; |
282 | | |
283 | | /// \brief returns a reference to the raw (unrelocated) bytes of this Atom's |
284 | | /// content. |
285 | | virtual ArrayRef<uint8_t> rawContent() const = 0; |
286 | | |
287 | | /// This class abstracts iterating over the sequence of References |
288 | | /// in an Atom. Concrete instances of DefinedAtom must implement |
289 | | /// the derefIterator() and incrementIterator() methods. |
290 | | class reference_iterator { |
291 | | public: |
292 | | reference_iterator(const DefinedAtom &a, const void *it) |
293 | 12.4k | : _atom(a), _it(it) { } |
294 | | |
295 | 6.12k | const Reference *operator*() const { |
296 | 6.12k | return _atom.derefIterator(_it); |
297 | 6.12k | } |
298 | | |
299 | 3 | const Reference *operator->() const { |
300 | 3 | return _atom.derefIterator(_it); |
301 | 3 | } |
302 | | |
303 | 11.9k | bool operator==(const reference_iterator &other) const { |
304 | 11.9k | return _it == other._it; |
305 | 11.9k | } |
306 | | |
307 | 11.9k | bool operator!=(const reference_iterator &other) const { |
308 | 11.9k | return !(*this == other); |
309 | 11.9k | } |
310 | | |
311 | 5.74k | reference_iterator &operator++() { |
312 | 5.74k | _atom.incrementIterator(_it); |
313 | 5.74k | return *this; |
314 | 5.74k | } |
315 | | private: |
316 | | const DefinedAtom &_atom; |
317 | | const void *_it; |
318 | | }; |
319 | | |
320 | | /// \brief Returns an iterator to the beginning of this Atom's References. |
321 | | virtual reference_iterator begin() const = 0; |
322 | | |
323 | | /// \brief Returns an iterator to the end of this Atom's References. |
324 | | virtual reference_iterator end() const = 0; |
325 | | |
326 | | /// Adds a reference to this atom. |
327 | | virtual void addReference(Reference::KindNamespace ns, |
328 | | Reference::KindArch arch, |
329 | | Reference::KindValue kindValue, uint64_t off, |
330 | 0 | const Atom *target, Reference::Addend a) { |
331 | 0 | llvm_unreachable("Subclass does not permit adding references"); |
332 | 0 | } |
333 | | |
334 | 3.70k | static bool classof(const Atom *a) { |
335 | 3.70k | return a->definition() == definitionRegular; |
336 | 3.70k | } |
337 | | |
338 | | /// Utility for deriving permissions from content type |
339 | | static ContentPermissions permissions(ContentType type); |
340 | | |
341 | | /// Utility function to check if the atom occupies file space |
342 | 384 | bool occupiesDiskSpace() const { |
343 | 384 | ContentType atomContentType = contentType(); |
344 | 384 | return !(atomContentType == DefinedAtom::typeZeroFill || |
345 | 378 | atomContentType == DefinedAtom::typeZeroFillFast || |
346 | 378 | atomContentType == DefinedAtom::typeTLVInitialZeroFill); |
347 | 384 | } |
348 | | |
349 | | /// Utility function to check if relocations in this atom to other defined |
350 | | /// atoms can be implicitly generated, and so we don't need to explicitly |
351 | | /// emit those relocations. |
352 | 0 | bool relocsToDefinedCanBeImplicit() const { |
353 | 0 | ContentType atomContentType = contentType(); |
354 | 0 | return atomContentType == typeCFI; |
355 | 0 | } |
356 | | |
357 | | protected: |
358 | | // DefinedAtom is an abstract base class. Only subclasses can access |
359 | | // constructor. |
360 | 1.18k | DefinedAtom() : Atom(definitionRegular) { } |
361 | | |
362 | 1.18k | ~DefinedAtom() override = default; |
363 | | |
364 | | /// \brief Returns a pointer to the Reference object that the abstract |
365 | | /// iterator "points" to. |
366 | | virtual const Reference *derefIterator(const void *iter) const = 0; |
367 | | |
368 | | /// \brief Adjusts the abstract iterator to "point" to the next Reference |
369 | | /// object for this Atom. |
370 | | virtual void incrementIterator(const void *&iter) const = 0; |
371 | | }; |
372 | | } // end namespace lld |
373 | | |
374 | | #endif |