Coverage Report

Created: 2019-05-19 14:56

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/tools/lld/include/lld/Core/Reference.h
Line
Count
Source
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
14
namespace lld {
15
16
class 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.
41
class Reference {
42
public:
43
  /// Which universe defines the kindValue().
44
  enum class KindNamespace {
45
    all     = 0,
46
    testing = 1,
47
    mach_o  = 2,
48
  };
49
50
5.46k
  KindNamespace kindNamespace() const { return (KindNamespace)_kindNamespace; }
51
18
  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
1.33k
  KindArch kindArch() const { return (KindArch)_kindArch; }
57
18
  void setKindArch(KindArch a) { _kindArch = (uint8_t)a; }
58
59
  typedef uint16_t KindValue;
60
61
4.75k
  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
39
  void setKindValue(KindValue value) {
66
39
    _kindValue = value;
67
39
  }
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
442
  virtual uint32_t tag() const { return 0; }
99
100
protected:
101
  /// Reference is an abstract base class.  Only subclasses can use constructor.
102
  Reference(KindNamespace ns, KindArch a, KindValue value)
103
1.33k
      : _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 an Reference.  In fact, some File objects may bulk allocate
108
  /// an array of References, so they cannot be individually deleted by anyone.
109
442
  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