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/LLVM.h"
20 /// \brief 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 typeCode, // executable code
109 typeResolver, // function which returns address of target
110 typeBranchIsland, // linker created for large binaries
111 typeBranchShim, // linker created to switch thumb mode
112 typeStub, // linker created for calling external function
113 typeStubHelper, // linker created for initial stub binding
114 typeConstant, // a read-only constant
115 typeCString, // a zero terminated UTF8 C string
116 typeUTF16String, // a zero terminated UTF16 string
117 typeCFI, // a FDE or CIE from dwarf unwind info
118 typeLSDA, // extra unwinding info
119 typeLiteral4, // a four-btye read-only constant
120 typeLiteral8, // an eight-btye read-only constant
121 typeLiteral16, // a sixteen-btye read-only constant
122 typeData, // read-write data
123 typeDataFast, // allow data to be quickly accessed
124 typeZeroFill, // zero-fill data
125 typeZeroFillFast, // allow zero-fill data to be quicky accessed
126 typeConstData, // read-only data after dynamic linker is done
127 typeObjC1Class, // ObjC1 class [Darwin]
128 typeLazyPointer, // pointer through which a stub jumps
129 typeLazyDylibPointer, // pointer through which a stub jumps [Darwin]
130 typeCFString, // NS/CFString object [Darwin]
131 typeGOT, // pointer to external symbol
132 typeInitializerPtr, // pointer to initializer function
133 typeTerminatorPtr, // pointer to terminator function
134 typeCStringPtr, // pointer to UTF8 C string [Darwin]
135 typeObjCClassPtr, // pointer to ObjC class [Darwin]
136 typeObjC2CategoryList, // pointers to ObjC category [Darwin]
137 typeDTraceDOF, // runtime data for Dtrace [Darwin]
138 typeInterposingTuples, // tuples of interposing info for dyld [Darwin]
139 typeTempLTO, // temporary atom for bitcode reader
140 typeCompactUnwindInfo, // runtime data for unwinder [Darwin]
141 typeProcessedUnwindInfo,// compressed compact unwind info [Darwin]
142 typeThunkTLV, // thunk used to access a TLV [Darwin]
143 typeTLVInitialData, // initial data for a TLV [Darwin]
144 typeTLVInitialZeroFill, // TLV initial zero fill data [Darwin]
145 typeTLVInitializerPtr, // pointer to thread local initializer [Darwin]
146 typeMachHeader, // atom representing mach_header [Darwin]
147 typeThreadZeroFill, // Uninitialized thread local data(TBSS) [ELF]
148 typeThreadData, // Initialized thread local data(TDATA) [ELF]
149 typeRONote, // Identifies readonly note sections [ELF]
150 typeRWNote, // Identifies readwrite note sections [ELF]
151 typeNoAlloc, // Identifies non allocatable sections [ELF]
152 typeGroupComdat, // Identifies a section group [ELF, COFF]
153 typeGnuLinkOnce, // Identifies a gnu.linkonce section [ELF]
156 // Permission bits for atoms and segments. The order of these values are
157 // important, because the layout pass may sort atoms by permission if other
158 // attributes are the same.
159 enum ContentPermissions {
160 perm___ = 0, // mapped as unaccessible
161 permR__ = 8, // mapped read-only
162 permRW_ = 8 + 2, // mapped readable and writable
163 permRW_L = 8 + 2 + 1, // initially mapped r/w, then made read-only
165 permR_X = 8 + 4, // mapped readable and executable
166 permRWX = 8 + 2 + 4, // mapped readable and writable and executable
167 permUnknown = 16 // unknown or invalid permissions
171 sectionBasedOnContent, // linker infers final section based on content
172 sectionCustomPreferred, // linker may place in specific section
173 sectionCustomRequired // linker must place in specific section
177 deadStripNormal, // linker may dead strip this atom
178 deadStripNever, // linker must never dead strip this atom
179 deadStripAlways // linker must remove this atom if unused
183 /// \brief The linker may or may not export this atom dynamically depending
184 /// on the output type and other context of the link.
186 /// \brief The linker will always export this atom dynamically.
190 // Attributes describe a code model used by the atom.
192 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
197 codeARMThumb, // ARM Thumb instruction set
201 Alignment(int p2, int m = 0)
208 bool operator==(const Alignment &rhs) const {
209 return (powerOf2 == rhs.powerOf2) && (modulus == rhs.modulus);
213 /// \brief returns a value for the order of this Atom within its file.
215 /// This is used by the linker to order the layout of Atoms so that the
216 /// resulting image is stable and reproducible.
218 /// Note that this should not be confused with ordinals of exported symbols in
219 /// Windows DLLs. In Windows terminology, ordinals are symbols' export table
220 /// indices (small integers) which can be used instead of symbol names to
221 /// refer items in a DLL.
222 virtual uint64_t ordinal() const = 0;
224 /// \brief the number of bytes of space this atom's content will occupy in the
225 /// final linked image.
227 /// For a function atom, it is the number of bytes of code in the function.
228 virtual uint64_t size() const = 0;
230 /// \brief The size of the section from which the atom is instantiated.
232 /// Merge::mergeByLargestSection is defined in terms of section size
233 /// and not in terms of atom size, so we need this function separate
235 virtual uint64_t sectionSize() const { return 0; }
237 /// \brief The visibility of this atom to other atoms.
239 /// C static functions have scope scopeTranslationUnit. Regular C functions
240 /// have scope scopeGlobal. Functions compiled with visibility=hidden have
241 /// scope scopeLinkageUnit so they can be see by other atoms being linked but
242 /// not by the OS loader.
243 virtual Scope scope() const = 0;
245 /// \brief Whether the linker should use direct or indirect access to this
247 virtual Interposable interposable() const = 0;
249 /// \brief how the linker should handle if multiple atoms have the same name.
250 virtual Merge merge() const = 0;
252 /// \brief The type of this atom, such as code or data.
253 virtual ContentType contentType() const = 0;
255 /// \brief The alignment constraints on how this atom must be laid out in the
256 /// final linked image (e.g. 16-byte aligned).
257 virtual Alignment alignment() const = 0;
259 /// \brief Whether this atom must be in a specially named section in the final
260 /// linked image, or if the linker can infer the section based on the
262 virtual SectionChoice sectionChoice() const = 0;
264 /// \brief If sectionChoice() != sectionBasedOnContent, then this return the
265 /// name of the section the atom should be placed into.
266 virtual StringRef customSectionName() const = 0;
268 /// \brief constraints on whether the linker may dead strip away this atom.
269 virtual DeadStripKind deadStrip() const = 0;
271 /// \brief Under which conditions should this atom be dynamically exported.
272 virtual DynamicExport dynamicExport() const {
273 return dynamicExportNormal;
276 /// \brief Code model used by the atom.
277 virtual CodeModel codeModel() const { return codeNA; }
279 /// \brief Returns the OS memory protections required for this atom's content
282 /// A function atom is R_X, a global variable is RW_, and a read-only constant
284 virtual ContentPermissions permissions() const;
286 /// \brief returns a reference to the raw (unrelocated) bytes of this Atom's
288 virtual ArrayRef<uint8_t> rawContent() const = 0;
290 /// This class abstracts iterating over the sequence of References
291 /// in an Atom. Concrete instances of DefinedAtom must implement
292 /// the derefIterator() and incrementIterator() methods.
293 class reference_iterator {
295 reference_iterator(const DefinedAtom &a, const void *it)
296 : _atom(a), _it(it) { }
298 const Reference *operator*() const {
299 return _atom.derefIterator(_it);
302 const Reference *operator->() const {
303 return _atom.derefIterator(_it);
306 bool operator!=(const reference_iterator &other) const {
307 return _it != other._it;
310 reference_iterator &operator++() {
311 _atom.incrementIterator(_it);
315 const DefinedAtom &_atom;
319 /// \brief Returns an iterator to the beginning of this Atom's References.
320 virtual reference_iterator begin() const = 0;
322 /// \brief Returns an iterator to the end of this Atom's References.
323 virtual reference_iterator end() const = 0;
325 static bool classof(const Atom *a) {
326 return a->definition() == definitionRegular;
329 /// Utility for deriving permissions from content type
330 static ContentPermissions permissions(ContentType type);
332 /// Utility function to check if the atom occupies file space
333 bool occupiesDiskSpace() const {
334 ContentType atomContentType = contentType();
335 return !(atomContentType == DefinedAtom::typeZeroFill ||
336 atomContentType == DefinedAtom::typeZeroFillFast ||
337 atomContentType == DefinedAtom::typeTLVInitialZeroFill ||
338 atomContentType == DefinedAtom::typeThreadZeroFill);
341 /// Utility function to check if the atom belongs to a group section
342 /// that represents section groups or .gnu.linkonce sections.
343 bool isGroupParent() const {
344 ContentType atomContentType = contentType();
345 return (atomContentType == DefinedAtom::typeGroupComdat ||
346 atomContentType == DefinedAtom::typeGnuLinkOnce);
349 // Returns true if lhs should be placed before rhs in the final output.
350 static bool compareByPosition(const DefinedAtom *lhs,
351 const DefinedAtom *rhs);
354 // DefinedAtom is an abstract base class. Only subclasses can access
356 DefinedAtom() : Atom(definitionRegular) { }
358 /// \brief Returns a pointer to the Reference object that the abstract
359 /// iterator "points" to.
360 virtual const Reference *derefIterator(const void *iter) const = 0;
362 /// \brief Adjusts the abstract iterator to "point" to the next Reference
363 /// object for this Atom.
364 virtual void incrementIterator(const void *&iter) const = 0;
366 } // end namespace lld