/Users/buildslave/jenkins/sharedspace/clang-stage2-coverage-R@2/llvm/tools/lld/include/lld/Core/Reference.h
Line | Count | Source |
1 | | //===- Core/References.h - A Reference to Another Atom ----------*- C++ -*-===// |
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 <cstdint> |
14 | | |
15 | | namespace lld { |
16 | | |
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 | 5.46k | KindNamespace kindNamespace() const { return (KindNamespace)_kindNamespace; } |
52 | 18 | 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 | 1.33k | KindArch kindArch() const { return (KindArch)_kindArch; } |
58 | 18 | void setKindArch(KindArch a) { _kindArch = (uint8_t)a; } |
59 | | |
60 | | typedef uint16_t KindValue; |
61 | | |
62 | 4.75k | 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 | 39 | void setKindValue(KindValue value) { |
67 | 39 | _kindValue = value; |
68 | 39 | } |
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 | 442 | 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 | 1.33k | : _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 | 442 | virtual ~Reference() = default; |
111 | | |
112 | | KindValue _kindValue; |
113 | | uint8_t _kindNamespace; |
114 | | uint8_t _kindArch; |
115 | | }; |
116 | | |
117 | | } // end namespace lld |
118 | | |
119 | | #endif // LLD_CORE_REFERENCES_H |