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