Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/lib/Object/ModuleSymbolTable.cpp
Line
Count
Source (jump to first uncovered line)
1
//===- ModuleSymbolTable.cpp - symbol table for in-memory IR --------------===//
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
// This class represents a symbol table built from in-memory IR. It provides
10
// access to GlobalValues and should only be used if such access is required
11
// (e.g. in the LTO implementation).
12
//
13
//===----------------------------------------------------------------------===//
14
15
#include "llvm/Object/ModuleSymbolTable.h"
16
#include "RecordStreamer.h"
17
#include "llvm/ADT/STLExtras.h"
18
#include "llvm/ADT/SmallString.h"
19
#include "llvm/ADT/StringMap.h"
20
#include "llvm/ADT/StringRef.h"
21
#include "llvm/ADT/Triple.h"
22
#include "llvm/IR/Function.h"
23
#include "llvm/IR/GlobalAlias.h"
24
#include "llvm/IR/GlobalValue.h"
25
#include "llvm/IR/GlobalVariable.h"
26
#include "llvm/IR/Module.h"
27
#include "llvm/MC/MCAsmInfo.h"
28
#include "llvm/MC/MCContext.h"
29
#include "llvm/MC/MCDirectives.h"
30
#include "llvm/MC/MCInstrInfo.h"
31
#include "llvm/MC/MCObjectFileInfo.h"
32
#include "llvm/MC/MCParser/MCAsmParser.h"
33
#include "llvm/MC/MCParser/MCTargetAsmParser.h"
34
#include "llvm/MC/MCRegisterInfo.h"
35
#include "llvm/MC/MCSubtargetInfo.h"
36
#include "llvm/MC/MCSymbol.h"
37
#include "llvm/MC/MCTargetOptions.h"
38
#include "llvm/Object/SymbolicFile.h"
39
#include "llvm/Support/Casting.h"
40
#include "llvm/Support/CodeGen.h"
41
#include "llvm/Support/ErrorHandling.h"
42
#include "llvm/Support/MemoryBuffer.h"
43
#include "llvm/Support/SMLoc.h"
44
#include "llvm/Support/SourceMgr.h"
45
#include "llvm/Support/TargetRegistry.h"
46
#include "llvm/Support/raw_ostream.h"
47
#include <algorithm>
48
#include <cassert>
49
#include <cstdint>
50
#include <memory>
51
#include <string>
52
53
using namespace llvm;
54
using namespace object;
55
56
3.11k
void ModuleSymbolTable::addModule(Module *M) {
57
3.11k
  if (FirstMod)
58
3.11k
    assert(FirstMod->getTargetTriple() == M->getTargetTriple());
59
3.11k
  else
60
3.11k
    
FirstMod = M3.11k
;
61
3.11k
62
3.11k
  for (GlobalValue &GV : M->global_values())
63
23.1k
    SymTab.push_back(&GV);
64
3.11k
65
3.11k
  CollectAsmSymbols(*M, [this](StringRef Name, BasicSymbolRef::Flags Flags) {
66
240
    SymTab.push_back(new (AsmSymbols.Allocate()) AsmSymbol(Name, Flags));
67
240
  });
68
3.11k
}
69
70
static void
71
initializeRecordStreamer(const Module &M,
72
3.15k
                         function_ref<void(RecordStreamer &)> Init) {
73
3.15k
  StringRef InlineAsm = M.getModuleInlineAsm();
74
3.15k
  if (InlineAsm.empty())
75
3.07k
    return;
76
78
77
78
  std::string Err;
78
78
  const Triple TT(M.getTargetTriple());
79
78
  const Target *T = TargetRegistry::lookupTarget(TT.str(), Err);
80
78
  assert(T && T->hasMCAsmParser());
81
78
82
78
  std::unique_ptr<MCRegisterInfo> MRI(T->createMCRegInfo(TT.str()));
83
78
  if (!MRI)
84
0
    return;
85
78
86
78
  std::unique_ptr<MCAsmInfo> MAI(T->createMCAsmInfo(*MRI, TT.str()));
87
78
  if (!MAI)
88
0
    return;
89
78
90
78
  std::unique_ptr<MCSubtargetInfo> STI(
91
78
      T->createMCSubtargetInfo(TT.str(), "", ""));
92
78
  if (!STI)
93
0
    return;
94
78
95
78
  std::unique_ptr<MCInstrInfo> MCII(T->createMCInstrInfo());
96
78
  if (!MCII)
97
0
    return;
98
78
99
78
  MCObjectFileInfo MOFI;
100
78
  MCContext MCCtx(MAI.get(), MRI.get(), &MOFI);
101
78
  MOFI.InitMCObjectFileInfo(TT, /*PIC*/ false, MCCtx);
102
78
  MOFI.setSDKVersion(M.getSDKVersion());
103
78
  RecordStreamer Streamer(MCCtx, M);
104
78
  T->createNullTargetStreamer(Streamer);
105
78
106
78
  std::unique_ptr<MemoryBuffer> Buffer(MemoryBuffer::getMemBuffer(InlineAsm));
107
78
  SourceMgr SrcMgr;
108
78
  SrcMgr.AddNewSourceBuffer(std::move(Buffer), SMLoc());
109
78
  std::unique_ptr<MCAsmParser> Parser(
110
78
      createMCAsmParser(SrcMgr, MCCtx, Streamer, *MAI));
111
78
112
78
  MCTargetOptions MCOptions;
113
78
  std::unique_ptr<MCTargetAsmParser> TAP(
114
78
      T->createMCAsmParser(*STI, *Parser, *MCII, MCOptions));
115
78
  if (!TAP)
116
0
    return;
117
78
118
78
  Parser->setTargetParser(*TAP);
119
78
  if (Parser->Run(false))
120
0
    return;
121
78
122
78
  Init(Streamer);
123
78
}
124
125
void ModuleSymbolTable::CollectAsmSymbols(
126
    const Module &M,
127
3.12k
    function_ref<void(StringRef, BasicSymbolRef::Flags)> AsmSymbol) {
128
3.12k
  initializeRecordStreamer(M, [&](RecordStreamer &Streamer) {
129
74
    Streamer.flushSymverDirectives();
130
74
131
264
    for (auto &KV : Streamer) {
132
264
      StringRef Key = KV.first();
133
264
      RecordStreamer::State Value = KV.second;
134
264
      // FIXME: For now we just assume that all asm symbols are executable.
135
264
      uint32_t Res = BasicSymbolRef::SF_Executable;
136
264
      switch (Value) {
137
264
      case RecordStreamer::NeverSeen:
138
0
        llvm_unreachable("NeverSeen should have been replaced earlier");
139
264
      case RecordStreamer::DefinedGlobal:
140
60
        Res |= BasicSymbolRef::SF_Global;
141
60
        break;
142
264
      case RecordStreamer::Defined:
143
80
        break;
144
264
      case RecordStreamer::Global:
145
80
      case RecordStreamer::Used:
146
80
        Res |= BasicSymbolRef::SF_Undefined;
147
80
        Res |= BasicSymbolRef::SF_Global;
148
80
        break;
149
80
      case RecordStreamer::DefinedWeak:
150
43
        Res |= BasicSymbolRef::SF_Weak;
151
43
        Res |= BasicSymbolRef::SF_Global;
152
43
        break;
153
80
      case RecordStreamer::UndefinedWeak:
154
1
        Res |= BasicSymbolRef::SF_Weak;
155
1
        Res |= BasicSymbolRef::SF_Undefined;
156
264
      }
157
264
      AsmSymbol(Key, BasicSymbolRef::Flags(Res));
158
264
    }
159
74
  });
160
3.12k
}
161
162
void ModuleSymbolTable::CollectAsmSymvers(
163
30
    const Module &M, function_ref<void(StringRef, StringRef)> AsmSymver) {
164
30
  initializeRecordStreamer(M, [&](RecordStreamer &Streamer) {
165
2
    for (auto &KV : Streamer.symverAliases())
166
3
      for (auto &Alias : KV.second)
167
3
        AsmSymver(KV.first->getName(), Alias);
168
2
  });
169
30
}
170
171
22.5k
void ModuleSymbolTable::printSymbolName(raw_ostream &OS, Symbol S) const {
172
22.5k
  if (S.is<AsmSymbol *>()) {
173
214
    OS << S.get<AsmSymbol *>()->first;
174
214
    return;
175
214
  }
176
22.3k
177
22.3k
  auto *GV = S.get<GlobalValue *>();
178
22.3k
  if (GV->hasDLLImportStorageClass())
179
13
    OS << "__imp_";
180
22.3k
181
22.3k
  Mang.getNameWithPrefix(OS, GV, false);
182
22.3k
}
183
184
23.5k
uint32_t ModuleSymbolTable::getSymbolFlags(Symbol S) const {
185
23.5k
  if (S.is<AsmSymbol *>())
186
306
    return S.get<AsmSymbol *>()->second;
187
23.2k
188
23.2k
  auto *GV = S.get<GlobalValue *>();
189
23.2k
190
23.2k
  uint32_t Res = BasicSymbolRef::SF_None;
191
23.2k
  if (GV->isDeclarationForLinker())
192
5.48k
    Res |= BasicSymbolRef::SF_Undefined;
193
17.8k
  else if (GV->hasHiddenVisibility() && 
!GV->hasLocalLinkage()476
)
194
476
    Res |= BasicSymbolRef::SF_Hidden;
195
23.2k
  if (const GlobalVariable *GVar = dyn_cast<GlobalVariable>(GV)) {
196
9.28k
    if (GVar->isConstant())
197
6.42k
      Res |= BasicSymbolRef::SF_Const;
198
9.28k
  }
199
23.2k
  if (dyn_cast_or_null<Function>(GV->getBaseObject()))
200
13.8k
    Res |= BasicSymbolRef::SF_Executable;
201
23.2k
  if (isa<GlobalAlias>(GV))
202
456
    Res |= BasicSymbolRef::SF_Indirect;
203
23.2k
  if (GV->hasPrivateLinkage())
204
1.93k
    Res |= BasicSymbolRef::SF_FormatSpecific;
205
23.2k
  if (!GV->hasLocalLinkage())
206
15.7k
    Res |= BasicSymbolRef::SF_Global;
207
23.2k
  if (GV->hasCommonLinkage())
208
132
    Res |= BasicSymbolRef::SF_Common;
209
23.2k
  if (GV->hasLinkOnceLinkage() || 
GV->hasWeakLinkage()21.0k
||
210
23.2k
      
GV->hasExternalWeakLinkage()18.5k
)
211
5.12k
    Res |= BasicSymbolRef::SF_Weak;
212
23.2k
213
23.2k
  if (GV->getName().startswith("llvm."))
214
796
    Res |= BasicSymbolRef::SF_FormatSpecific;
215
22.4k
  else if (auto *Var = dyn_cast<GlobalVariable>(GV)) {
216
8.95k
    if (Var->getSection() == "llvm.metadata")
217
0
      Res |= BasicSymbolRef::SF_FormatSpecific;
218
8.95k
  }
219
23.2k
220
23.2k
  return Res;
221
23.2k
}