]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lld/include/lld/Core/Reference.h
Bring lld (release_39 branch, r279477) to contrib
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lld / include / lld / Core / Reference.h
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
16 namespace lld {
17 class 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 /// forcing layout (one atom must follow another), marking data-in-code
30 /// (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.
35 ///
36 /// References and atoms form a directed graph. The dead-stripping pass
37 /// traverses them starting from dead-strip root atoms to garbage collect
38 /// unreachable ones.
39 ///
40 /// References of any kind are considered as directed edges. In addition to
41 /// that, references of some kind is considered as bidirected edges.
42 class Reference {
43 public:
44   /// Which universe defines the kindValue().
45   enum class KindNamespace {
46     all     = 0,
47     testing = 1,
48     mach_o  = 2,
49   };
50
51   KindNamespace kindNamespace() const { return (KindNamespace)_kindNamespace; }
52   void setKindNamespace(KindNamespace ns) { _kindNamespace = (uint8_t)ns; }
53
54   // Which architecture the kind value is for.
55   enum class KindArch { all, AArch64, ARM, x86, x86_64};
56
57   KindArch kindArch() const { return (KindArch)_kindArch; }
58   void setKindArch(KindArch a) { _kindArch = (uint8_t)a; }
59
60   typedef uint16_t KindValue;
61
62   KindValue kindValue() const { return _kindValue; }
63
64   /// setKindValue() is needed because during linking, some optimizations may
65   /// change the codegen and hence the reference kind.
66   void setKindValue(KindValue value) {
67     _kindValue = value;
68   }
69
70   /// KindValues used with KindNamespace::all and KindArch::all.
71   enum {
72     // kindLayoutAfter is treated as a bidirected edge by the dead-stripping
73     // pass.
74     kindLayoutAfter = 1,
75     kindAssociate,
76   };
77
78   // A value to be added to the value of a target
79   typedef int64_t Addend;
80
81   /// If the reference is a fixup in the Atom, then this returns the
82   /// byte offset into the Atom's content to do the fix up.
83   virtual uint64_t offsetInAtom() const = 0;
84
85   /// Returns the atom this reference refers to.
86   virtual const Atom *target() const = 0;
87
88   /// During linking, the linker may merge graphs which coalesces some nodes
89   /// (i.e. Atoms).  To switch the target of a reference, this method is called.
90   virtual void setTarget(const Atom *) = 0;
91
92   /// Some relocations require a symbol and a value (e.g. foo + 4).
93   virtual Addend addend() const = 0;
94
95   /// During linking, some optimzations may change addend value.
96   virtual void setAddend(Addend) = 0;
97
98   /// Returns target specific attributes of the reference.
99   virtual uint32_t tag() const { return 0; }
100
101 protected:
102   /// Reference is an abstract base class.  Only subclasses can use constructor.
103   Reference(KindNamespace ns, KindArch a, KindValue value)
104       : _kindValue(value), _kindNamespace((uint8_t)ns), _kindArch((uint8_t)a) {}
105
106   /// The memory for Reference objects is always managed by the owning File
107   /// object.  Therefore, no one but the owning File object should call
108   /// delete on an Reference.  In fact, some File objects may bulk allocate
109   /// an array of References, so they cannot be individually deleted by anyone.
110   virtual ~Reference() {}
111
112   KindValue  _kindValue;
113   uint8_t    _kindNamespace;
114   uint8_t    _kindArch;
115 };
116
117 } // namespace lld
118
119 #endif // LLD_CORE_REFERENCES_H