Coverage Report

Created: 2019-07-24 05:18

/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 "Symbols.h"
14
#include "lld/Common/Strings.h"
15
#include "llvm/ADT/CachedHashString.h"
16
#include "llvm/ADT/DenseMap.h"
17
#include "llvm/ADT/STLExtras.h"
18
19
namespace lld {
20
namespace elf {
21
22
// SymbolTable is a bucket of all known symbols, including defined,
23
// undefined, or lazy symbols (the last one is symbols in archive
24
// files whose archive members are not yet loaded).
25
//
26
// We put all symbols of all files to a SymbolTable, and the
27
// SymbolTable selects the "best" symbols if there are name
28
// conflicts. For example, obviously, a defined symbol is better than
29
// an undefined symbol. Or, if there's a conflict between a lazy and a
30
// undefined, it'll read an archive member to read a real definition
31
// to replace the lazy symbol. The logic is implemented in the
32
// add*() functions, which are called by input files as they are parsed. There
33
// is one add* function per symbol type.
34
class SymbolTable {
35
public:
36
  void wrap(Symbol *sym, Symbol *real, Symbol *wrap);
37
38
18.4k
  void forEachSymbol(llvm::function_ref<void(Symbol *)> fn) {
39
18.4k
    for (Symbol *sym : symVector)
40
120k
      if (!sym->isPlaceholder())
41
120k
        fn(sym);
42
18.4k
  }
43
44
  Symbol *insert(StringRef name);
45
46
  Symbol *addSymbol(const Symbol &New);
47
48
  void scanVersionScript();
49
50
  Symbol *find(StringRef name);
51
52
  void handleDynamicList();
53
54
  // Set of .so files to not link the same shared object file more than once.
55
  llvm::DenseMap<StringRef, SharedFile *> soNames;
56
57
  // Comdat groups define "link once" sections. If two comdat groups have the
58
  // same name, only one of them is linked, and the other is ignored. This map
59
  // is used to uniquify them.
60
  llvm::DenseMap<llvm::CachedHashStringRef, const InputFile *> comdatGroups;
61
62
private:
63
  std::vector<Symbol *> findByVersion(SymbolVersion ver);
64
  std::vector<Symbol *> findAllByVersion(SymbolVersion ver);
65
66
  llvm::StringMap<std::vector<Symbol *>> &getDemangledSyms();
67
  void assignExactVersion(SymbolVersion ver, uint16_t versionId,
68
                          StringRef versionName);
69
  void assignWildcardVersion(SymbolVersion ver, uint16_t versionId);
70
71
  // The order the global symbols are in is not defined. We can use an arbitrary
72
  // order, but it has to be reproducible. That is true even when cross linking.
73
  // The default hashing of StringRef produces different results on 32 and 64
74
  // bit systems so we use a map to a vector. That is arbitrary, deterministic
75
  // but a bit inefficient.
76
  // FIXME: Experiment with passing in a custom hashing or sorting the symbols
77
  // once symbol resolution is finished.
78
  llvm::DenseMap<llvm::CachedHashStringRef, int> symMap;
79
  std::vector<Symbol *> symVector;
80
81
  // A map from demangled symbol names to their symbol objects.
82
  // This mapping is 1:N because two symbols with different versions
83
  // can have the same name. We use this map to handle "extern C++ {}"
84
  // directive in version scripts.
85
  llvm::Optional<llvm::StringMap<std::vector<Symbol *>>> demangledSyms;
86
};
87
88
extern SymbolTable *symtab;
89
90
} // namespace elf
91
} // namespace lld
92
93
#endif