Reference.h revision 280461
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, 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