1 //===- Core/DefinedAtom.h - An Atom with content --------------------------===//
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #ifndef LLD_CORE_DEFINED_ATOM_H
11 #define LLD_CORE_DEFINED_ATOM_H
13 #include "lld/Core/Atom.h"
14 #include "lld/Core/Reference.h"
15 #include "lld/Core/LLVM.h"
16 #include "llvm/Support/ErrorHandling.h"
21 /// \brief The fundamental unit of linking.
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
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
33 /// C function: void foo() {} <br>
34 /// name=foo, type=code, perm=r_x, scope=global
36 /// C static function: staic void func() {} <br>
37 /// name=func, type=code, perm=r_x
39 /// C global variable: int count = 1; <br>
40 /// name=count, type=data, perm=rw_, scope=global
42 /// C tentative definition: int bar; <br>
43 /// name=bar, type=zerofill, perm=rw_, scope=global,
44 /// merge=asTentative, interposable=yesAndRuntimeWeak
46 /// Uninitialized C static variable: static int stuff; <br>
47 /// name=stuff, type=zerofill, perm=rw_
49 /// Weak C function: __attribute__((weak)) void foo() {} <br>
50 /// name=foo, type=code, perm=r_x, scope=global, merge=asWeak
52 /// Hidden C function: __attribute__((visibility("hidden"))) void foo() {}<br>
53 /// name=foo, type=code, perm=r_x, scope=linkageUnit
55 /// No-dead-strip function: __attribute__((used)) void foo() {} <br>
56 /// name=foo, type=code, perm=r_x, scope=global, deadStrip=never
58 /// Non-inlined C++ inline method: inline void Foo::doit() {} <br>
59 /// name=_ZN3Foo4doitEv, type=code, perm=r_x, scope=global,
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
67 /// literal c-string: "hello" <br>
68 /// name="" type=cstring, perm=r__, scope=linkageUnit
70 /// literal double: 1.234 <br>
71 /// name="" type=literal8, perm=r__, scope=linkageUnit
73 /// constant: { 1,2,3 } <br>
74 /// name="" type=constant, perm=r__, scope=linkageUnit
76 /// Pointer to initializer function: <br>
77 /// name="" type=initializer, perm=rw_l,
78 /// sectionChoice=customRequired
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
85 class DefinedAtom : public Atom {
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
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
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.
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]
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
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
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
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
182 /// \brief The linker may or may not export this atom dynamically depending
183 /// on the output type and other context of the link.
185 /// \brief The linker will always export this atom dynamically.
189 // Attributes describe a code model used by the atom.
191 codeNA, // no specific code model
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
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)
205 Alignment(int v, int m = 0) : value(v), modulus(m) {}
210 bool operator==(const Alignment &rhs) const {
211 return (value == rhs.value) && (modulus == rhs.modulus);
215 /// \brief returns a value for the order of this Atom within its file.
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;
221 /// \brief the number of bytes of space this atom's content will occupy in the
222 /// final linked image.
224 /// For a function atom, it is the number of bytes of code in the function.
225 virtual uint64_t size() const = 0;
227 /// \brief The size of the section from which the atom is instantiated.
229 /// Merge::mergeByLargestSection is defined in terms of section size
230 /// and not in terms of atom size, so we need this function separate
232 virtual uint64_t sectionSize() const { return 0; }
234 /// \brief The visibility of this atom to other atoms.
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;
242 /// \brief Whether the linker should use direct or indirect access to this
244 virtual Interposable interposable() const = 0;
246 /// \brief how the linker should handle if multiple atoms have the same name.
247 virtual Merge merge() const = 0;
249 /// \brief The type of this atom, such as code or data.
250 virtual ContentType contentType() const = 0;
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;
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
259 virtual SectionChoice sectionChoice() const = 0;
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;
265 /// \brief constraints on whether the linker may dead strip away this atom.
266 virtual DeadStripKind deadStrip() const = 0;
268 /// \brief Under which conditions should this atom be dynamically exported.
269 virtual DynamicExport dynamicExport() const {
270 return dynamicExportNormal;
273 /// \brief Code model used by the atom.
274 virtual CodeModel codeModel() const { return codeNA; }
276 /// \brief Returns the OS memory protections required for this atom's content
279 /// A function atom is R_X, a global variable is RW_, and a read-only constant
281 virtual ContentPermissions permissions() const;
283 /// \brief returns a reference to the raw (unrelocated) bytes of this Atom's
285 virtual ArrayRef<uint8_t> rawContent() const = 0;
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 {
292 reference_iterator(const DefinedAtom &a, const void *it)
293 : _atom(a), _it(it) { }
295 const Reference *operator*() const {
296 return _atom.derefIterator(_it);
299 const Reference *operator->() const {
300 return _atom.derefIterator(_it);
303 bool operator==(const reference_iterator &other) const {
304 return _it == other._it;
307 bool operator!=(const reference_iterator &other) const {
308 return !(*this == other);
311 reference_iterator &operator++() {
312 _atom.incrementIterator(_it);
316 const DefinedAtom &_atom;
320 /// \brief Returns an iterator to the beginning of this Atom's References.
321 virtual reference_iterator begin() const = 0;
323 /// \brief Returns an iterator to the end of this Atom's References.
324 virtual reference_iterator end() const = 0;
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 const Atom *target, Reference::Addend a) {
331 llvm_unreachable("Subclass does not permit adding references");
334 static bool classof(const Atom *a) {
335 return a->definition() == definitionRegular;
338 /// Utility for deriving permissions from content type
339 static ContentPermissions permissions(ContentType type);
341 /// Utility function to check if the atom occupies file space
342 bool occupiesDiskSpace() const {
343 ContentType atomContentType = contentType();
344 return !(atomContentType == DefinedAtom::typeZeroFill ||
345 atomContentType == DefinedAtom::typeZeroFillFast ||
346 atomContentType == DefinedAtom::typeTLVInitialZeroFill);
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 bool relocsToDefinedCanBeImplicit() const {
353 ContentType atomContentType = contentType();
354 return atomContentType == typeCFI;
358 // DefinedAtom is an abstract base class. Only subclasses can access
360 DefinedAtom() : Atom(definitionRegular) { }
362 ~DefinedAtom() override = default;
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;
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;
372 } // end namespace lld