Reference.h revision 292934
1//===- Core/References.h - A Reference to Another Atom --------------------===// 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_REFERENCES_H 11#define LLD_CORE_REFERENCES_H 12 13#include "lld/Core/LLVM.h" 14#include "llvm/ADT/StringSwitch.h" 15 16namespace lld { 17class Atom; 18 19/// 20/// The linker has a Graph Theory model of linking. An object file is seen 21/// as a set of Atoms with References to other Atoms. Each Atom is a node 22/// and each Reference is an edge. 23/// 24/// For example if a function contains a call site to "malloc" 40 bytes into 25/// the Atom, then the function Atom will have a Reference of: offsetInAtom=40, 26/// kind=callsite, target=malloc, addend=0. 27/// 28/// Besides supporting traditional "relocations", References are also used 29/// grouping atoms (group comdat), forcing layout (one atom must follow 30/// another), marking data-in-code (jump tables or ARM constants), etc. 31/// 32/// The "kind" of a reference is a tuple of <namespace, arch, value>. This 33/// enable us to re-use existing relocation types definded for various 34/// file formats and architectures. For instance, in ELF the relocation type 10 35/// means R_X86_64_32 for x86_64, and R_386_GOTPC for i386. For PE/COFF 36/// relocation 10 means IMAGE_REL_AMD64_SECTION. 37/// 38/// References and atoms form a directed graph. The dead-stripping pass 39/// traverses them starting from dead-strip root atoms to garbage collect 40/// unreachable ones. 41/// 42/// References of any kind are considered as directed edges. In addition to 43/// that, references of some kind is considered as bidirected edges. 44class Reference { 45public: 46 /// Which universe defines the kindValue(). 47 enum class KindNamespace { 48 all = 0, 49 testing = 1, 50 ELF = 2, 51 COFF = 3, 52 mach_o = 4, 53 }; 54 55 KindNamespace kindNamespace() const { return (KindNamespace)_kindNamespace; } 56 void setKindNamespace(KindNamespace ns) { _kindNamespace = (uint8_t)ns; } 57 58 // Which architecture the kind value is for. 59 enum class KindArch { all, AArch64, AMDGPU, ARM, Hexagon, Mips, x86, x86_64 }; 60 61 KindArch kindArch() const { return (KindArch)_kindArch; } 62 void setKindArch(KindArch a) { _kindArch = (uint8_t)a; } 63 64 typedef uint16_t KindValue; 65 66 KindValue kindValue() const { return _kindValue; } 67 68 /// setKindValue() is needed because during linking, some optimizations may 69 /// change the codegen and hence the reference kind. 70 void setKindValue(KindValue value) { 71 _kindValue = value; 72 } 73 74 /// KindValues used with KindNamespace::all and KindArch::all. 75 enum { 76 // kindLayoutAfter is treated as a bidirected edge by the dead-stripping 77 // pass. 78 kindLayoutAfter = 1, 79 // kindGroupChild is treated as a bidirected edge too. 80 kindGroupChild, 81 kindAssociate, 82 }; 83 84 // A value to be added to the value of a target 85 typedef int64_t Addend; 86 87 /// If the reference is a fixup in the Atom, then this returns the 88 /// byte offset into the Atom's content to do the fix up. 89 virtual uint64_t offsetInAtom() const = 0; 90 91 /// Returns the atom this reference refers to. 92 virtual const Atom *target() const = 0; 93 94 /// During linking, the linker may merge graphs which coalesces some nodes 95 /// (i.e. Atoms). To switch the target of a reference, this method is called. 96 virtual void setTarget(const Atom *) = 0; 97 98 /// Some relocations require a symbol and a value (e.g. foo + 4). 99 virtual Addend addend() const = 0; 100 101 /// During linking, some optimzations may change addend value. 102 virtual void setAddend(Addend) = 0; 103 104 /// Returns target specific attributes of the reference. 105 virtual uint32_t tag() const { return 0; } 106 107protected: 108 /// Reference is an abstract base class. Only subclasses can use constructor. 109 Reference(KindNamespace ns, KindArch a, KindValue value) 110 : _kindValue(value), _kindNamespace((uint8_t)ns), _kindArch((uint8_t)a) {} 111 112 /// The memory for Reference objects is always managed by the owning File 113 /// object. Therefore, no one but the owning File object should call 114 /// delete on an Reference. In fact, some File objects may bulk allocate 115 /// an array of References, so they cannot be individually deleted by anyone. 116 virtual ~Reference() {} 117 118 KindValue _kindValue; 119 uint8_t _kindNamespace; 120 uint8_t _kindArch; 121}; 122 123} // namespace lld 124 125#endif // LLD_CORE_REFERENCES_H 126