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/StringRef.h"
19 #include "llvm/IR/Function.h"
20 #include "llvm/IR/GlobalAlias.h"
21 #include "llvm/IR/GlobalValue.h"
22 #include "llvm/IR/GlobalVariable.h"
23 #include "llvm/IR/InlineAsm.h"
24 #include "llvm/IR/Module.h"
25 #include "llvm/MC/MCAsmInfo.h"
26 #include "llvm/MC/MCContext.h"
27 #include "llvm/MC/MCInstrInfo.h"
28 #include "llvm/MC/MCObjectFileInfo.h"
29 #include "llvm/MC/MCParser/MCAsmParser.h"
30 #include "llvm/MC/MCParser/MCTargetAsmParser.h"
31 #include "llvm/MC/MCRegisterInfo.h"
32 #include "llvm/MC/MCSubtargetInfo.h"
33 #include "llvm/MC/MCSymbol.h"
34 #include "llvm/MC/MCTargetOptions.h"
35 #include "llvm/MC/TargetRegistry.h"
36 #include "llvm/Object/SymbolicFile.h"
37 #include "llvm/Support/Casting.h"
38 #include "llvm/Support/ErrorHandling.h"
39 #include "llvm/Support/MemoryBuffer.h"
40 #include "llvm/Support/SMLoc.h"
41 #include "llvm/Support/SourceMgr.h"
42 #include "llvm/Support/raw_ostream.h"
43 #include "llvm/TargetParser/Triple.h"
51 using namespace object
;
53 void ModuleSymbolTable::addModule(Module
*M
) {
55 assert(FirstMod
->getTargetTriple() == M
->getTargetTriple());
59 for (GlobalValue
&GV
: M
->global_values())
60 SymTab
.push_back(&GV
);
62 CollectAsmSymbols(*M
, [this](StringRef Name
, BasicSymbolRef::Flags Flags
) {
63 SymTab
.push_back(new (AsmSymbols
.Allocate())
64 AsmSymbol(std::string(Name
), Flags
));
69 initializeRecordStreamer(const Module
&M
,
70 function_ref
<void(RecordStreamer
&)> Init
) {
71 StringRef InlineAsm
= M
.getModuleInlineAsm();
72 if (InlineAsm
.empty())
76 const Triple
TT(M
.getTargetTriple());
77 const Target
*T
= TargetRegistry::lookupTarget(TT
.str(), Err
);
78 assert(T
&& T
->hasMCAsmParser());
80 std::unique_ptr
<MCRegisterInfo
> MRI(T
->createMCRegInfo(TT
.str()));
84 MCTargetOptions MCOptions
;
85 std::unique_ptr
<MCAsmInfo
> MAI(T
->createMCAsmInfo(*MRI
, TT
.str(), MCOptions
));
89 std::unique_ptr
<MCSubtargetInfo
> STI(
90 T
->createMCSubtargetInfo(TT
.str(), "", ""));
94 std::unique_ptr
<MCInstrInfo
> MCII(T
->createMCInstrInfo());
98 std::unique_ptr
<MemoryBuffer
> Buffer(MemoryBuffer::getMemBuffer(InlineAsm
));
100 SrcMgr
.AddNewSourceBuffer(std::move(Buffer
), SMLoc());
102 MCContext
MCCtx(TT
, MAI
.get(), MRI
.get(), STI
.get(), &SrcMgr
);
103 std::unique_ptr
<MCObjectFileInfo
> MOFI(
104 T
->createMCObjectFileInfo(MCCtx
, /*PIC=*/false));
105 MOFI
->setSDKVersion(M
.getSDKVersion());
106 MCCtx
.setObjectFileInfo(MOFI
.get());
107 RecordStreamer
Streamer(MCCtx
, M
);
108 T
->createNullTargetStreamer(Streamer
);
110 std::unique_ptr
<MCAsmParser
> Parser(
111 createMCAsmParser(SrcMgr
, MCCtx
, Streamer
, *MAI
));
113 std::unique_ptr
<MCTargetAsmParser
> TAP(
114 T
->createMCAsmParser(*STI
, *Parser
, *MCII
, MCOptions
));
118 // Module-level inline asm is assumed to use At&t syntax (see
119 // AsmPrinter::doInitialization()).
120 Parser
->setAssemblerDialect(InlineAsm::AD_ATT
);
122 Parser
->setTargetParser(*TAP
);
123 if (Parser
->Run(false))
129 void ModuleSymbolTable::CollectAsmSymbols(
131 function_ref
<void(StringRef
, BasicSymbolRef::Flags
)> AsmSymbol
) {
132 initializeRecordStreamer(M
, [&](RecordStreamer
&Streamer
) {
133 Streamer
.flushSymverDirectives();
135 for (auto &KV
: Streamer
) {
136 StringRef Key
= KV
.first();
137 RecordStreamer::State Value
= KV
.second
;
138 // FIXME: For now we just assume that all asm symbols are executable.
139 uint32_t Res
= BasicSymbolRef::SF_Executable
;
141 case RecordStreamer::NeverSeen
:
142 llvm_unreachable("NeverSeen should have been replaced earlier");
143 case RecordStreamer::DefinedGlobal
:
144 Res
|= BasicSymbolRef::SF_Global
;
146 case RecordStreamer::Defined
:
148 case RecordStreamer::Global
:
149 case RecordStreamer::Used
:
150 Res
|= BasicSymbolRef::SF_Undefined
;
151 Res
|= BasicSymbolRef::SF_Global
;
153 case RecordStreamer::DefinedWeak
:
154 Res
|= BasicSymbolRef::SF_Weak
;
155 Res
|= BasicSymbolRef::SF_Global
;
157 case RecordStreamer::UndefinedWeak
:
158 Res
|= BasicSymbolRef::SF_Weak
;
159 Res
|= BasicSymbolRef::SF_Undefined
;
161 AsmSymbol(Key
, BasicSymbolRef::Flags(Res
));
166 void ModuleSymbolTable::CollectAsmSymvers(
167 const Module
&M
, function_ref
<void(StringRef
, StringRef
)> AsmSymver
) {
168 initializeRecordStreamer(M
, [&](RecordStreamer
&Streamer
) {
169 for (auto &KV
: Streamer
.symverAliases())
170 for (auto &Alias
: KV
.second
)
171 AsmSymver(KV
.first
->getName(), Alias
);
175 void ModuleSymbolTable::printSymbolName(raw_ostream
&OS
, Symbol S
) const {
176 if (isa
<AsmSymbol
*>(S
)) {
177 OS
<< cast
<AsmSymbol
*>(S
)->first
;
181 auto *GV
= cast
<GlobalValue
*>(S
);
182 if (GV
->hasDLLImportStorageClass())
185 Mang
.getNameWithPrefix(OS
, GV
, false);
188 uint32_t ModuleSymbolTable::getSymbolFlags(Symbol S
) const {
189 if (isa
<AsmSymbol
*>(S
))
190 return cast
<AsmSymbol
*>(S
)->second
;
192 auto *GV
= cast
<GlobalValue
*>(S
);
194 uint32_t Res
= BasicSymbolRef::SF_None
;
195 if (GV
->isDeclarationForLinker())
196 Res
|= BasicSymbolRef::SF_Undefined
;
197 else if (GV
->hasHiddenVisibility() && !GV
->hasLocalLinkage())
198 Res
|= BasicSymbolRef::SF_Hidden
;
199 if (const GlobalVariable
*GVar
= dyn_cast
<GlobalVariable
>(GV
)) {
200 if (GVar
->isConstant())
201 Res
|= BasicSymbolRef::SF_Const
;
203 if (const GlobalObject
*GO
= GV
->getAliaseeObject())
204 if (isa
<Function
>(GO
) || isa
<GlobalIFunc
>(GO
))
205 Res
|= BasicSymbolRef::SF_Executable
;
206 if (isa
<GlobalAlias
>(GV
))
207 Res
|= BasicSymbolRef::SF_Indirect
;
208 if (GV
->hasPrivateLinkage())
209 Res
|= BasicSymbolRef::SF_FormatSpecific
;
210 if (!GV
->hasLocalLinkage())
211 Res
|= BasicSymbolRef::SF_Global
;
212 if (GV
->hasCommonLinkage())
213 Res
|= BasicSymbolRef::SF_Common
;
214 if (GV
->hasLinkOnceLinkage() || GV
->hasWeakLinkage() ||
215 GV
->hasExternalWeakLinkage())
216 Res
|= BasicSymbolRef::SF_Weak
;
218 if (GV
->getName().startswith("llvm."))
219 Res
|= BasicSymbolRef::SF_FormatSpecific
;
220 else if (auto *Var
= dyn_cast
<GlobalVariable
>(GV
)) {
221 if (Var
->getSection() == "llvm.metadata")
222 Res
|= BasicSymbolRef::SF_FormatSpecific
;