Coverage Report

Created: 2019-05-19 14:56

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/tools/lld/ELF/SymbolTable.h
Line
Count
Source
1
//===- SymbolTable.h --------------------------------------------*- 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_ELF_SYMBOL_TABLE_H
10
#define LLD_ELF_SYMBOL_TABLE_H
11
12
#include "InputFiles.h"
13
#include "LTO.h"
14
#include "lld/Common/Strings.h"
15
#include "llvm/ADT/CachedHashString.h"
16
#include "llvm/ADT/DenseMap.h"
17
18
namespace lld {
19
namespace elf {
20
21
class CommonSymbol;
22
class Defined;
23
class LazyArchive;
24
class LazyObject;
25
class SectionBase;
26
class SharedSymbol;
27
class Undefined;
28
29
// SymbolTable is a bucket of all known symbols, including defined,
30
// undefined, or lazy symbols (the last one is symbols in archive
31
// files whose archive members are not yet loaded).
32
//
33
// We put all symbols of all files to a SymbolTable, and the
34
// SymbolTable selects the "best" symbols if there are name
35
// conflicts. For example, obviously, a defined symbol is better than
36
// an undefined symbol. Or, if there's a conflict between a lazy and a
37
// undefined, it'll read an archive member to read a real definition
38
// to replace the lazy symbol. The logic is implemented in the
39
// add*() functions, which are called by input files as they are parsed. There
40
// is one add* function per symbol type.
41
class SymbolTable {
42
public:
43
  template <class ELFT> void addCombinedLTOObject();
44
  void wrap(Symbol *Sym, Symbol *Real, Symbol *Wrap);
45
46
16.9k
  ArrayRef<Symbol *> getSymbols() const { return SymVector; }
47
48
  Symbol *insert(StringRef Name);
49
50
  Symbol *addSymbol(const Symbol &New);
51
52
  void fetchLazy(Symbol *Sym);
53
54
  void scanVersionScript();
55
56
  Symbol *find(StringRef Name);
57
58
  void trace(StringRef Name);
59
60
  void handleDynamicList();
61
62
  // Set of .so files to not link the same shared object file more than once.
63
  llvm::DenseMap<StringRef, SharedFile *> SoNames;
64
65
private:
66
  std::vector<Symbol *> findByVersion(SymbolVersion Ver);
67
  std::vector<Symbol *> findAllByVersion(SymbolVersion Ver);
68
69
  llvm::StringMap<std::vector<Symbol *>> &getDemangledSyms();
70
  void handleAnonymousVersion();
71
  void assignExactVersion(SymbolVersion Ver, uint16_t VersionId,
72
                          StringRef VersionName);
73
  void assignWildcardVersion(SymbolVersion Ver, uint16_t VersionId);
74
75
  // The order the global symbols are in is not defined. We can use an arbitrary
76
  // order, but it has to be reproducible. That is true even when cross linking.
77
  // The default hashing of StringRef produces different results on 32 and 64
78
  // bit systems so we use a map to a vector. That is arbitrary, deterministic
79
  // but a bit inefficient.
80
  // FIXME: Experiment with passing in a custom hashing or sorting the symbols
81
  // once symbol resolution is finished.
82
  llvm::DenseMap<llvm::CachedHashStringRef, int> SymMap;
83
  std::vector<Symbol *> SymVector;
84
85
  // Comdat groups define "link once" sections. If two comdat groups have the
86
  // same name, only one of them is linked, and the other is ignored. This set
87
  // is used to uniquify them.
88
  llvm::DenseSet<llvm::CachedHashStringRef> ComdatGroups;
89
90
  // A map from demangled symbol names to their symbol objects.
91
  // This mapping is 1:N because two symbols with different versions
92
  // can have the same name. We use this map to handle "extern C++ {}"
93
  // directive in version scripts.
94
  llvm::Optional<llvm::StringMap<std::vector<Symbol *>>> DemangledSyms;
95
96
  // For LTO.
97
  std::unique_ptr<BitcodeCompiler> LTO;
98
};
99
100
extern SymbolTable *Symtab;
101
102
void mergeSymbolProperties(Symbol *Old, const Symbol &New);
103
void resolveSymbol(Symbol *Old, const Symbol &New);
104
105
} // namespace elf
106
} // namespace lld
107
108
#endif