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