1 //===- Core/References.h - A Reference to Another Atom ----------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
9 #ifndef LLD_CORE_REFERENCES_H
10 #define LLD_CORE_REFERENCES_H
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.
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.
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.
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.
35 /// References and atoms form a directed graph. The dead-stripping pass
36 /// traverses them starting from dead-strip root atoms to garbage collect
39 /// References of any kind are considered as directed edges. In addition to
40 /// that, references of some kind is considered as bidirected edges.
43 /// Which universe defines the kindValue().
44 enum class KindNamespace {
50 KindNamespace kindNamespace() const { return (KindNamespace)_kindNamespace; }
51 void setKindNamespace(KindNamespace ns) { _kindNamespace = (uint8_t)ns; }
53 // Which architecture the kind value is for.
54 enum class KindArch { all, AArch64, ARM, x86, x86_64};
56 KindArch kindArch() const { return (KindArch)_kindArch; }
57 void setKindArch(KindArch a) { _kindArch = (uint8_t)a; }
59 typedef uint16_t KindValue;
61 KindValue kindValue() const { return _kindValue; }
63 /// setKindValue() is needed because during linking, some optimizations may
64 /// change the codegen and hence the reference kind.
65 void setKindValue(KindValue value) {
69 /// KindValues used with KindNamespace::all and KindArch::all.
71 // kindLayoutAfter is treated as a bidirected edge by the dead-stripping
77 // A value to be added to the value of a target
78 typedef int64_t Addend;
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;
84 /// Returns the atom this reference refers to.
85 virtual const Atom *target() const = 0;
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;
91 /// Some relocations require a symbol and a value (e.g. foo + 4).
92 virtual Addend addend() const = 0;
94 /// During linking, some optimzations may change addend value.
95 virtual void setAddend(Addend) = 0;
97 /// Returns target specific attributes of the reference.
98 virtual uint32_t tag() const { return 0; }
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) {}
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 an 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;
111 KindValue _kindValue;
112 uint8_t _kindNamespace;
116 } // end namespace lld
118 #endif // LLD_CORE_REFERENCES_H