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