Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/tools/lld/include/lld/Core/Simple.h
Line
Count
Source (jump to first uncovered line)
1
//===- lld/Core/Simple.h - Simple implementations of Atom and File --------===//
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
/// \file
10
/// Provide simple implementations for Atoms and File.
11
///
12
//===----------------------------------------------------------------------===//
13
14
#ifndef LLD_CORE_SIMPLE_H
15
#define LLD_CORE_SIMPLE_H
16
17
#include "lld/Core/AbsoluteAtom.h"
18
#include "lld/Core/Atom.h"
19
#include "lld/Core/DefinedAtom.h"
20
#include "lld/Core/File.h"
21
#include "lld/Core/Reference.h"
22
#include "lld/Core/SharedLibraryAtom.h"
23
#include "lld/Core/UndefinedAtom.h"
24
#include "llvm/ADT/SmallVector.h"
25
#include "llvm/ADT/StringRef.h"
26
#include "llvm/ADT/ilist.h"
27
#include "llvm/ADT/ilist_node.h"
28
#include "llvm/Support/Allocator.h"
29
#include "llvm/Support/Casting.h"
30
#include "llvm/Support/ErrorHandling.h"
31
#include <algorithm>
32
#include <cassert>
33
#include <cstdint>
34
#include <functional>
35
36
namespace lld {
37
38
class SimpleFile : public File {
39
public:
40
  SimpleFile(StringRef path, File::Kind kind)
41
1.06k
    : File(path, kind) {}
42
43
1.06k
  ~SimpleFile() override {
44
1.06k
    _defined.clear();
45
1.06k
    _undefined.clear();
46
1.06k
    _shared.clear();
47
1.06k
    _absolute.clear();
48
1.06k
  }
49
50
1.38k
  void addAtom(DefinedAtom &a) {
51
1.38k
    _defined.push_back(OwningAtomPtr<DefinedAtom>(&a));
52
1.38k
  }
53
376
  void addAtom(UndefinedAtom &a) {
54
376
    _undefined.push_back(OwningAtomPtr<UndefinedAtom>(&a));
55
376
  }
56
139
  void addAtom(SharedLibraryAtom &a) {
57
139
    _shared.push_back(OwningAtomPtr<SharedLibraryAtom>(&a));
58
139
  }
59
0
  void addAtom(AbsoluteAtom &a) {
60
0
    _absolute.push_back(OwningAtomPtr<AbsoluteAtom>(&a));
61
0
  }
62
63
935
  void addAtom(const Atom &atom) {
64
935
    if (auto *p = dyn_cast<DefinedAtom>(&atom)) {
65
752
      addAtom(const_cast<DefinedAtom &>(*p));
66
752
    } else 
if (auto *183
p183
= dyn_cast<UndefinedAtom>(&atom)) {
67
44
      addAtom(const_cast<UndefinedAtom &>(*p));
68
139
    } else if (auto *p = dyn_cast<SharedLibraryAtom>(&atom)) {
69
139
      addAtom(const_cast<SharedLibraryAtom &>(*p));
70
139
    } else 
if (auto *0
p0
= dyn_cast<AbsoluteAtom>(&atom)) {
71
0
      addAtom(const_cast<AbsoluteAtom &>(*p));
72
0
    } else {
73
0
      llvm_unreachable("atom has unknown definition kind");
74
0
    }
75
935
  }
76
77
20
  void removeDefinedAtomsIf(std::function<bool(const DefinedAtom *)> pred) {
78
20
    auto &atoms = _defined;
79
20
    auto newEnd = std::remove_if(atoms.begin(), atoms.end(),
80
245
                                 [&pred](OwningAtomPtr<DefinedAtom> &p) {
81
245
                                   return pred(p.get());
82
245
                                 });
83
20
    atoms.erase(newEnd, atoms.end());
84
20
  }
85
86
1.49k
  const AtomRange<DefinedAtom> defined() const override { return _defined; }
87
88
676
  const AtomRange<UndefinedAtom> undefined() const override {
89
676
    return _undefined;
90
676
  }
91
92
692
  const AtomRange<SharedLibraryAtom> sharedLibrary() const override {
93
692
    return _shared;
94
692
  }
95
96
507
  const AtomRange<AbsoluteAtom> absolute() const override {
97
507
    return _absolute;
98
507
  }
99
100
932
  void clearAtoms() override {
101
932
    _defined.clear();
102
932
    _undefined.clear();
103
932
    _shared.clear();
104
932
    _absolute.clear();
105
932
  }
106
107
private:
108
  AtomVector<DefinedAtom> _defined;
109
  AtomVector<UndefinedAtom> _undefined;
110
  AtomVector<SharedLibraryAtom> _shared;
111
  AtomVector<AbsoluteAtom> _absolute;
112
};
113
114
class SimpleReference : public Reference,
115
                        public llvm::ilist_node<SimpleReference> {
116
public:
117
  SimpleReference(Reference::KindNamespace ns, Reference::KindArch arch,
118
                  Reference::KindValue value, uint64_t off, const Atom *t,
119
                  Reference::Addend a)
120
870
      : Reference(ns, arch, value), _target(t), _offsetInAtom(off), _addend(a) {
121
870
  }
122
  SimpleReference()
123
      : Reference(Reference::KindNamespace::all, Reference::KindArch::all, 0),
124
0
        _target(nullptr), _offsetInAtom(0), _addend(0) {}
125
126
4.89k
  uint64_t offsetInAtom() const override { return _offsetInAtom; }
127
128
5.17k
  const Atom *target() const override {
129
5.17k
    assert(_target);
130
5.17k
    return _target;
131
5.17k
  }
132
133
1.42k
  Addend addend() const override { return _addend; }
134
0
  void setAddend(Addend a) override { _addend = a; }
135
637
  void setTarget(const Atom *newAtom) override { _target = newAtom; }
136
137
private:
138
  const Atom *_target;
139
  uint64_t _offsetInAtom;
140
  Addend _addend;
141
};
142
143
class SimpleDefinedAtom : public DefinedAtom {
144
public:
145
  explicit SimpleDefinedAtom(const File &f)
146
857
      : _file(f), _ordinal(f.getNextAtomOrdinalAndIncrement()) {}
147
148
857
  ~SimpleDefinedAtom() override {
149
857
    _references.clearAndLeakNodesUnsafely();
150
857
  }
151
152
2.61k
  const File &file() const override { return _file; }
153
154
231
  StringRef name() const override { return StringRef(); }
155
156
488
  uint64_t ordinal() const override { return _ordinal; }
157
158
156
  Scope scope() const override { return DefinedAtom::scopeLinkageUnit; }
159
160
293
  Interposable interposable() const override {
161
293
    return DefinedAtom::interposeNo;
162
293
  }
163
164
8
  Merge merge() const override { return DefinedAtom::mergeNo; }
165
166
2
  Alignment alignment() const override { return 1; }
167
168
931
  SectionChoice sectionChoice() const override {
169
931
    return DefinedAtom::sectionBasedOnContent;
170
931
  }
171
172
252
  StringRef customSectionName() const override { return StringRef(); }
173
16
  DeadStripKind deadStrip() const override {
174
16
    return DefinedAtom::deadStripNormal;
175
16
  }
176
177
5.79k
  DefinedAtom::reference_iterator begin() const override {
178
5.79k
    const void *it =
179
5.79k
        reinterpret_cast<const void *>(_references.begin().getNodePtr());
180
5.79k
    return reference_iterator(*this, it);
181
5.79k
  }
182
183
5.82k
  DefinedAtom::reference_iterator end() const override {
184
5.82k
    const void *it =
185
5.82k
        reinterpret_cast<const void *>(_references.end().getNodePtr());
186
5.82k
    return reference_iterator(*this, it);
187
5.82k
  }
188
189
6.00k
  const Reference *derefIterator(const void *it) const override {
190
6.00k
    return &*RefList::const_iterator(
191
6.00k
        *reinterpret_cast<const llvm::ilist_node<SimpleReference> *>(it));
192
6.00k
  }
193
194
5.62k
  void incrementIterator(const void *&it) const override {
195
5.62k
    RefList::const_iterator ref(
196
5.62k
        *reinterpret_cast<const llvm::ilist_node<SimpleReference> *>(it));
197
5.62k
    it = reinterpret_cast<const void *>(std::next(ref).getNodePtr());
198
5.62k
  }
199
200
  void addReference(Reference::KindNamespace ns,
201
                    Reference::KindArch arch,
202
                    Reference::KindValue kindValue, uint64_t off,
203
870
                    const Atom *target, Reference::Addend a) override {
204
870
    assert(target && "trying to create reference to nothing");
205
870
    auto node = new (_file.allocator())
206
870
        SimpleReference(ns, arch, kindValue, off, target, a);
207
870
    _references.push_back(node);
208
870
  }
209
210
  /// Sort references in a canonical order (by offset, then by kind).
211
500
  void sortReferences() const {
212
500
    // Cannot sort a linked  list, so move elements into a temporary vector,
213
500
    // sort the vector, then reconstruct the list.
214
500
    llvm::SmallVector<SimpleReference *, 16> elements;
215
600
    for (SimpleReference &node : _references) {
216
600
      elements.push_back(&node);
217
600
    }
218
500
    std::sort(elements.begin(), elements.end(),
219
1.21k
        [] (const SimpleReference *lhs, const SimpleReference *rhs) -> bool {
220
1.21k
          uint64_t lhsOffset = lhs->offsetInAtom();
221
1.21k
          uint64_t rhsOffset = rhs->offsetInAtom();
222
1.21k
          if (rhsOffset != lhsOffset)
223
1.20k
            return (lhsOffset < rhsOffset);
224
6
          if (rhs->kindNamespace() != lhs->kindNamespace())
225
0
            return (lhs->kindNamespace() < rhs->kindNamespace());
226
6
          if (rhs->kindArch() != lhs->kindArch())
227
0
            return (lhs->kindArch() < rhs->kindArch());
228
6
          return (lhs->kindValue() < rhs->kindValue());
229
6
        });
230
500
    _references.clearAndLeakNodesUnsafely();
231
600
    for (SimpleReference *node : elements) {
232
600
      _references.push_back(node);
233
600
    }
234
500
  }
235
236
0
  void setOrdinal(uint64_t ord) { _ordinal = ord; }
237
238
private:
239
  typedef llvm::ilist<SimpleReference> RefList;
240
241
  const File &_file;
242
  uint64_t _ordinal;
243
  mutable RefList _references;
244
};
245
246
class SimpleUndefinedAtom : public UndefinedAtom {
247
public:
248
332
  SimpleUndefinedAtom(const File &f, StringRef name) : _file(f), _name(name) {
249
332
    assert(!name.empty() && "UndefinedAtoms must have a name");
250
332
  }
251
252
488
  ~SimpleUndefinedAtom() override = default;
253
254
  /// file - returns the File that produced/owns this Atom
255
58
  const File &file() const override { return _file; }
256
257
  /// name - The name of the atom. For a function atom, it is the (mangled)
258
  /// name of the function.
259
1.08k
  StringRef name() const override { return _name; }
260
261
200
  CanBeNull canBeNull() const override { return UndefinedAtom::canBeNullNever; }
262
263
private:
264
  const File &_file;
265
  StringRef _name;
266
};
267
268
} // end namespace lld
269
270
#endif // LLD_CORE_SIMPLE_H