Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/tools/lld/COFF/Symbols.cpp
Line
Count
Source (jump to first uncovered line)
1
//===- Symbols.cpp --------------------------------------------------------===//
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
#include "Symbols.h"
10
#include "InputFiles.h"
11
#include "lld/Common/ErrorHandler.h"
12
#include "lld/Common/Memory.h"
13
#include "lld/Common/Strings.h"
14
#include "llvm/ADT/STLExtras.h"
15
#include "llvm/Support/Debug.h"
16
#include "llvm/Support/raw_ostream.h"
17
18
using namespace llvm;
19
using namespace llvm::object;
20
21
using namespace lld::coff;
22
23
namespace lld {
24
25
static_assert(sizeof(SymbolUnion) <= 48,
26
              "symbols should be optimized for memory usage");
27
28
// Returns a symbol name for an error message.
29
352
static std::string demangle(StringRef symName) {
30
352
  if (config->demangle)
31
341
    if (Optional<std::string> s = demangleMSVC(symName))
32
27
      return *s;
33
325
  return symName;
34
325
}
35
196
std::string toString(coff::Symbol &b) { return demangle(b.getName()); }
36
156
std::string toCOFFString(const Archive::Symbol &b) {
37
156
  return demangle(b.getName());
38
156
}
39
40
namespace coff {
41
42
2.58k
StringRef Symbol::getName() {
43
2.58k
  // COFF symbol names are read lazily for a performance reason.
44
2.58k
  // Non-external symbol names are never used by the linker except for logging
45
2.58k
  // or debugging. Their internal references are resolved not by name but by
46
2.58k
  // symbol index. And because they are not external, no one can refer them by
47
2.58k
  // name. Object files contain lots of non-external symbols, and creating
48
2.58k
  // StringRefs for them (which involves lots of strlen() on the string table)
49
2.58k
  // is a waste of time.
50
2.58k
  if (nameData == nullptr) {
51
264
    auto *d = cast<DefinedCOFF>(this);
52
264
    StringRef nameStr;
53
264
    cast<ObjFile>(d->file)->getCOFFObj()->getSymbolName(d->sym, nameStr);
54
264
    nameData = nameStr.data();
55
264
    nameSize = nameStr.size();
56
264
    assert(nameSize == nameStr.size() && "name length truncated");
57
264
  }
58
2.58k
  return StringRef(nameData, nameSize);
59
2.58k
}
60
61
223
InputFile *Symbol::getFile() {
62
223
  if (auto *sym = dyn_cast<DefinedCOFF>(this))
63
218
    return sym->file;
64
5
  if (auto *sym = dyn_cast<Lazy>(this))
65
0
    return sym->file;
66
5
  return nullptr;
67
5
}
68
69
1.60k
bool Symbol::isLive() const {
70
1.60k
  if (auto *r = dyn_cast<DefinedRegular>(this))
71
317
    return r->getChunk()->live;
72
1.28k
  if (auto *imp = dyn_cast<DefinedImportData>(this))
73
14
    return imp->file->live;
74
1.27k
  if (auto *imp = dyn_cast<DefinedImportThunk>(this))
75
14
    return imp->wrappedSym->file->thunkLive;
76
1.26k
  // Assume any other kind of symbol is live.
77
1.26k
  return true;
78
1.26k
}
79
80
// MinGW specific.
81
8
void Symbol::replaceKeepingName(Symbol *other, size_t size) {
82
8
  StringRef origName = getName();
83
8
  memcpy(this, other, size);
84
8
  nameData = origName.data();
85
8
  nameSize = origName.size();
86
8
}
87
88
635
COFFSymbolRef DefinedCOFF::getCOFFSymbol() {
89
635
  size_t symSize = cast<ObjFile>(file)->getCOFFObj()->getSymbolTableEntrySize();
90
635
  if (symSize == sizeof(coff_symbol16))
91
635
    return COFFSymbolRef(reinterpret_cast<const coff_symbol16 *>(sym));
92
0
  assert(symSize == sizeof(coff_symbol32));
93
0
  return COFFSymbolRef(reinterpret_cast<const coff_symbol32 *>(sym));
94
0
}
95
96
uint16_t DefinedAbsolute::numOutputSections;
97
98
98
static Chunk *makeImportThunk(DefinedImportData *s, uint16_t machine) {
99
98
  if (machine == AMD64)
100
74
    return make<ImportThunkChunkX64>(s);
101
24
  if (machine == I386)
102
18
    return make<ImportThunkChunkX86>(s);
103
6
  if (machine == ARM64)
104
4
    return make<ImportThunkChunkARM64>(s);
105
2
  assert(machine == ARMNT);
106
2
  return make<ImportThunkChunkARM>(s);
107
2
}
108
109
DefinedImportThunk::DefinedImportThunk(StringRef name, DefinedImportData *s,
110
                                       uint16_t machine)
111
    : Defined(DefinedImportThunkKind, name), wrappedSym(s),
112
98
      data(makeImportThunk(s, machine)) {}
113
114
130
Defined *Undefined::getWeakAlias() {
115
130
  // A weak alias may be a weak alias to another symbol, so check recursively.
116
130
  for (Symbol *a = weakAlias; a; 
a = cast<Undefined>(a)->weakAlias0
)
117
36
    if (auto *d = dyn_cast<Defined>(a))
118
36
      return d;
119
130
  
return nullptr94
;
120
130
}
121
} // namespace coff
122
} // namespace lld