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/Common/LLVM.h" 14 #include "lld/Core/Atom.h" 15 #include "lld/Core/Reference.h" 16 #include "llvm/Support/ErrorHandling.h" 17 18 namespace lld { 19 class File; 20 21 /// 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 /// 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 /// 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 { valueAlignment205 Alignment(int v, int m = 0) : value(v), modulus(m) {} 206 207 uint16_t value; 208 uint16_t modulus; 209 210 bool operator==(const Alignment &rhs) const { 211 return (value == rhs.value) && (modulus == rhs.modulus); 212 } 213 }; 214 215 /// 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 /// 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 /// 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(). sectionSize()232 virtual uint64_t sectionSize() const { return 0; } 233 234 /// 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 /// Whether the linker should use direct or indirect access to this 243 /// atom. 244 virtual Interposable interposable() const = 0; 245 246 /// how the linker should handle if multiple atoms have the same name. 247 virtual Merge merge() const = 0; 248 249 /// The type of this atom, such as code or data. 250 virtual ContentType contentType() const = 0; 251 252 /// 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 /// 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 /// 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 /// constraints on whether the linker may dead strip away this atom. 266 virtual DeadStripKind deadStrip() const = 0; 267 268 /// Under which conditions should this atom be dynamically exported. dynamicExport()269 virtual DynamicExport dynamicExport() const { 270 return dynamicExportNormal; 271 } 272 273 /// Code model used by the atom. codeModel()274 virtual CodeModel codeModel() const { return codeNA; } 275 276 /// 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 /// 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: reference_iterator(const DefinedAtom & a,const void * it)292 reference_iterator(const DefinedAtom &a, const void *it) 293 : _atom(a), _it(it) { } 294 295 const Reference *operator*() const { 296 return _atom.derefIterator(_it); 297 } 298 299 const Reference *operator->() const { 300 return _atom.derefIterator(_it); 301 } 302 303 bool operator==(const reference_iterator &other) const { 304 return _it == other._it; 305 } 306 307 bool operator!=(const reference_iterator &other) const { 308 return !(*this == other); 309 } 310 311 reference_iterator &operator++() { 312 _atom.incrementIterator(_it); 313 return *this; 314 } 315 private: 316 const DefinedAtom &_atom; 317 const void *_it; 318 }; 319 320 /// Returns an iterator to the beginning of this Atom's References. 321 virtual reference_iterator begin() const = 0; 322 323 /// 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. addReference(Reference::KindNamespace ns,Reference::KindArch arch,Reference::KindValue kindValue,uint64_t off,const Atom * target,Reference::Addend a)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"); 332 } 333 classof(const Atom * a)334 static bool classof(const Atom *a) { 335 return a->definition() == definitionRegular; 336 } 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 occupiesDiskSpace()342 bool occupiesDiskSpace() const { 343 ContentType atomContentType = contentType(); 344 return !(atomContentType == DefinedAtom::typeZeroFill || 345 atomContentType == DefinedAtom::typeZeroFillFast || 346 atomContentType == DefinedAtom::typeTLVInitialZeroFill); 347 } 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. relocsToDefinedCanBeImplicit()352 bool relocsToDefinedCanBeImplicit() const { 353 ContentType atomContentType = contentType(); 354 return atomContentType == typeCFI; 355 } 356 357 protected: 358 // DefinedAtom is an abstract base class. Only subclasses can access 359 // constructor. DefinedAtom()360 DefinedAtom() : Atom(definitionRegular) { } 361 362 ~DefinedAtom() override = default; 363 364 /// 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 /// 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 375