1 //===- ModuleSymbolTable.cpp - symbol table for in-memory IR --------------===//
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
7 //===----------------------------------------------------------------------===//
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).
13 //===----------------------------------------------------------------------===//
15 #include "llvm/Object/ModuleSymbolTable.h"
16 #include "RecordStreamer.h"
17 #include "llvm/ADT/STLExtras.h"
18 #include "llvm/ADT/StringMap.h"
19 #include "llvm/ADT/StringRef.h"
20 #include "llvm/IR/Function.h"
21 #include "llvm/IR/GlobalAlias.h"
22 #include "llvm/IR/GlobalValue.h"
23 #include "llvm/IR/GlobalVariable.h"
24 #include "llvm/IR/InlineAsm.h"
25 #include "llvm/IR/Module.h"
26 #include "llvm/MC/MCAsmInfo.h"
27 #include "llvm/MC/MCContext.h"
28 #include "llvm/MC/MCInstrInfo.h"
29 #include "llvm/MC/MCObjectFileInfo.h"
30 #include "llvm/MC/MCParser/MCAsmParser.h"
31 #include "llvm/MC/MCParser/MCTargetAsmParser.h"
32 #include "llvm/MC/MCRegisterInfo.h"
33 #include "llvm/MC/MCSubtargetInfo.h"
34 #include "llvm/MC/MCSymbol.h"
35 #include "llvm/MC/MCTargetOptions.h"
36 #include "llvm/MC/TargetRegistry.h"
37 #include "llvm/Object/SymbolicFile.h"
38 #include "llvm/Support/Casting.h"
39 #include "llvm/Support/ErrorHandling.h"
40 #include "llvm/Support/MemoryBuffer.h"
41 #include "llvm/Support/SMLoc.h"
42 #include "llvm/Support/SourceMgr.h"
43 #include "llvm/Support/raw_ostream.h"
44 #include "llvm/TargetParser/Triple.h"
52 using namespace object
;
54 void ModuleSymbolTable::addModule(Module
*M
) {
56 assert(FirstMod
->getTargetTriple() == M
->getTargetTriple());
60 for (GlobalValue
&GV
: M
->global_values())
61 SymTab
.push_back(&GV
);
63 CollectAsmSymbols(*M
, [this](StringRef Name
, BasicSymbolRef::Flags Flags
) {
64 SymTab
.push_back(new (AsmSymbols
.Allocate())
65 AsmSymbol(std::string(Name
), Flags
));
70 initializeRecordStreamer(const Module
&M
,
71 function_ref
<void(RecordStreamer
&)> Init
) {
72 StringRef InlineAsm
= M
.getModuleInlineAsm();
73 if (InlineAsm
.empty())
77 const Triple
TT(M
.getTargetTriple());
78 const Target
*T
= TargetRegistry::lookupTarget(TT
.str(), Err
);
79 assert(T
&& T
->hasMCAsmParser());
81 std::unique_ptr
<MCRegisterInfo
> MRI(T
->createMCRegInfo(TT
.str()));
85 MCTargetOptions MCOptions
;
86 std::unique_ptr
<MCAsmInfo
> MAI(T
->createMCAsmInfo(*MRI
, TT
.str(), MCOptions
));
90 std::unique_ptr
<MCSubtargetInfo
> STI(
91 T
->createMCSubtargetInfo(TT
.str(), "", ""));
95 std::unique_ptr
<MCInstrInfo
> MCII(T
->createMCInstrInfo());
99 std::unique_ptr
<MemoryBuffer
> Buffer(MemoryBuffer::getMemBuffer(InlineAsm
));
101 SrcMgr
.AddNewSourceBuffer(std::move(Buffer
), SMLoc());
103 MCContext
MCCtx(TT
, MAI
.get(), MRI
.get(), STI
.get(), &SrcMgr
);
104 std::unique_ptr
<MCObjectFileInfo
> MOFI(
105 T
->createMCObjectFileInfo(MCCtx
, /*PIC=*/false));
106 MOFI
->setSDKVersion(M
.getSDKVersion());
107 MCCtx
.setObjectFileInfo(MOFI
.get());
108 RecordStreamer
Streamer(MCCtx
, M
);
109 T
->createNullTargetStreamer(Streamer
);
111 std::unique_ptr
<MCAsmParser
> Parser(
112 createMCAsmParser(SrcMgr
, MCCtx
, Streamer
, *MAI
));
114 std::unique_ptr
<MCTargetAsmParser
> TAP(
115 T
->createMCAsmParser(*STI
, *Parser
, *MCII
, MCOptions
));
119 // Module-level inline asm is assumed to use At&t syntax (see
120 // AsmPrinter::doInitialization()).
121 Parser
->setAssemblerDialect(InlineAsm::AD_ATT
);
123 Parser
->setTargetParser(*TAP
);
124 if (Parser
->Run(false))
130 void ModuleSymbolTable::CollectAsmSymbols(
132 function_ref
<void(StringRef
, BasicSymbolRef::Flags
)> AsmSymbol
) {
133 initializeRecordStreamer(M
, [&](RecordStreamer
&Streamer
) {
134 Streamer
.flushSymverDirectives();
136 for (auto &KV
: Streamer
) {
137 StringRef Key
= KV
.first();
138 RecordStreamer::State Value
= KV
.second
;
139 // FIXME: For now we just assume that all asm symbols are executable.
140 uint32_t Res
= BasicSymbolRef::SF_Executable
;
142 case RecordStreamer::NeverSeen
:
143 llvm_unreachable("NeverSeen should have been replaced earlier");
144 case RecordStreamer::DefinedGlobal
:
145 Res
|= BasicSymbolRef::SF_Global
;
147 case RecordStreamer::Defined
:
149 case RecordStreamer::Global
:
150 case RecordStreamer::Used
:
151 Res
|= BasicSymbolRef::SF_Undefined
;
152 Res
|= BasicSymbolRef::SF_Global
;
154 case RecordStreamer::DefinedWeak
:
155 Res
|= BasicSymbolRef::SF_Weak
;
156 Res
|= BasicSymbolRef::SF_Global
;
158 case RecordStreamer::UndefinedWeak
:
159 Res
|= BasicSymbolRef::SF_Weak
;
160 Res
|= BasicSymbolRef::SF_Undefined
;
162 AsmSymbol(Key
, BasicSymbolRef::Flags(Res
));
167 void ModuleSymbolTable::CollectAsmSymvers(
168 const Module
&M
, function_ref
<void(StringRef
, StringRef
)> AsmSymver
) {
169 initializeRecordStreamer(M
, [&](RecordStreamer
&Streamer
) {
170 for (auto &KV
: Streamer
.symverAliases())
171 for (auto &Alias
: KV
.second
)
172 AsmSymver(KV
.first
->getName(), Alias
);
176 void ModuleSymbolTable::printSymbolName(raw_ostream
&OS
, Symbol S
) const {
177 if (isa
<AsmSymbol
*>(S
)) {
178 OS
<< cast
<AsmSymbol
*>(S
)->first
;
182 auto *GV
= cast
<GlobalValue
*>(S
);
183 if (GV
->hasDLLImportStorageClass())
186 Mang
.getNameWithPrefix(OS
, GV
, false);
189 uint32_t ModuleSymbolTable::getSymbolFlags(Symbol S
) const {
190 if (isa
<AsmSymbol
*>(S
))
191 return cast
<AsmSymbol
*>(S
)->second
;
193 auto *GV
= cast
<GlobalValue
*>(S
);
195 uint32_t Res
= BasicSymbolRef::SF_None
;
196 if (GV
->isDeclarationForLinker())
197 Res
|= BasicSymbolRef::SF_Undefined
;
198 else if (GV
->hasHiddenVisibility() && !GV
->hasLocalLinkage())
199 Res
|= BasicSymbolRef::SF_Hidden
;
200 if (const GlobalVariable
*GVar
= dyn_cast
<GlobalVariable
>(GV
)) {
201 if (GVar
->isConstant())
202 Res
|= BasicSymbolRef::SF_Const
;
204 if (const GlobalObject
*GO
= GV
->getAliaseeObject())
205 if (isa
<Function
>(GO
) || isa
<GlobalIFunc
>(GO
))
206 Res
|= BasicSymbolRef::SF_Executable
;
207 if (isa
<GlobalAlias
>(GV
))
208 Res
|= BasicSymbolRef::SF_Indirect
;
209 if (GV
->hasPrivateLinkage())
210 Res
|= BasicSymbolRef::SF_FormatSpecific
;
211 if (!GV
->hasLocalLinkage())
212 Res
|= BasicSymbolRef::SF_Global
;
213 if (GV
->hasCommonLinkage())
214 Res
|= BasicSymbolRef::SF_Common
;
215 if (GV
->hasLinkOnceLinkage() || GV
->hasWeakLinkage() ||
216 GV
->hasExternalWeakLinkage())
217 Res
|= BasicSymbolRef::SF_Weak
;
219 if (GV
->getName().startswith("llvm."))
220 Res
|= BasicSymbolRef::SF_FormatSpecific
;
221 else if (auto *Var
= dyn_cast
<GlobalVariable
>(GV
)) {
222 if (Var
->getSection() == "llvm.metadata")
223 Res
|= BasicSymbolRef::SF_FormatSpecific
;