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/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/InlineAsm.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"
55 using namespace object
;
57 void ModuleSymbolTable::addModule(Module
*M
) {
59 assert(FirstMod
->getTargetTriple() == M
->getTargetTriple());
63 for (GlobalValue
&GV
: M
->global_values())
64 SymTab
.push_back(&GV
);
66 CollectAsmSymbols(*M
, [this](StringRef Name
, BasicSymbolRef::Flags Flags
) {
67 SymTab
.push_back(new (AsmSymbols
.Allocate())
68 AsmSymbol(std::string(Name
), Flags
));
73 initializeRecordStreamer(const Module
&M
,
74 function_ref
<void(RecordStreamer
&)> Init
) {
75 StringRef InlineAsm
= M
.getModuleInlineAsm();
76 if (InlineAsm
.empty())
80 const Triple
TT(M
.getTargetTriple());
81 const Target
*T
= TargetRegistry::lookupTarget(TT
.str(), Err
);
82 assert(T
&& T
->hasMCAsmParser());
84 std::unique_ptr
<MCRegisterInfo
> MRI(T
->createMCRegInfo(TT
.str()));
88 MCTargetOptions MCOptions
;
89 std::unique_ptr
<MCAsmInfo
> MAI(T
->createMCAsmInfo(*MRI
, TT
.str(), MCOptions
));
93 std::unique_ptr
<MCSubtargetInfo
> STI(
94 T
->createMCSubtargetInfo(TT
.str(), "", ""));
98 std::unique_ptr
<MCInstrInfo
> MCII(T
->createMCInstrInfo());
102 std::unique_ptr
<MemoryBuffer
> Buffer(MemoryBuffer::getMemBuffer(InlineAsm
));
104 SrcMgr
.AddNewSourceBuffer(std::move(Buffer
), SMLoc());
106 MCContext
MCCtx(TT
, MAI
.get(), MRI
.get(), STI
.get(), &SrcMgr
);
107 std::unique_ptr
<MCObjectFileInfo
> MOFI(
108 T
->createMCObjectFileInfo(MCCtx
, /*PIC=*/false));
109 MOFI
->setSDKVersion(M
.getSDKVersion());
110 MCCtx
.setObjectFileInfo(MOFI
.get());
111 RecordStreamer
Streamer(MCCtx
, M
);
112 T
->createNullTargetStreamer(Streamer
);
114 std::unique_ptr
<MCAsmParser
> Parser(
115 createMCAsmParser(SrcMgr
, MCCtx
, Streamer
, *MAI
));
117 std::unique_ptr
<MCTargetAsmParser
> TAP(
118 T
->createMCAsmParser(*STI
, *Parser
, *MCII
, MCOptions
));
122 // Module-level inline asm is assumed to use At&t syntax (see
123 // AsmPrinter::doInitialization()).
124 Parser
->setAssemblerDialect(InlineAsm::AD_ATT
);
126 Parser
->setTargetParser(*TAP
);
127 if (Parser
->Run(false))
133 void ModuleSymbolTable::CollectAsmSymbols(
135 function_ref
<void(StringRef
, BasicSymbolRef::Flags
)> AsmSymbol
) {
136 initializeRecordStreamer(M
, [&](RecordStreamer
&Streamer
) {
137 Streamer
.flushSymverDirectives();
139 for (auto &KV
: Streamer
) {
140 StringRef Key
= KV
.first();
141 RecordStreamer::State Value
= KV
.second
;
142 // FIXME: For now we just assume that all asm symbols are executable.
143 uint32_t Res
= BasicSymbolRef::SF_Executable
;
145 case RecordStreamer::NeverSeen
:
146 llvm_unreachable("NeverSeen should have been replaced earlier");
147 case RecordStreamer::DefinedGlobal
:
148 Res
|= BasicSymbolRef::SF_Global
;
150 case RecordStreamer::Defined
:
152 case RecordStreamer::Global
:
153 case RecordStreamer::Used
:
154 Res
|= BasicSymbolRef::SF_Undefined
;
155 Res
|= BasicSymbolRef::SF_Global
;
157 case RecordStreamer::DefinedWeak
:
158 Res
|= BasicSymbolRef::SF_Weak
;
159 Res
|= BasicSymbolRef::SF_Global
;
161 case RecordStreamer::UndefinedWeak
:
162 Res
|= BasicSymbolRef::SF_Weak
;
163 Res
|= BasicSymbolRef::SF_Undefined
;
165 AsmSymbol(Key
, BasicSymbolRef::Flags(Res
));
170 void ModuleSymbolTable::CollectAsmSymvers(
171 const Module
&M
, function_ref
<void(StringRef
, StringRef
)> AsmSymver
) {
172 initializeRecordStreamer(M
, [&](RecordStreamer
&Streamer
) {
173 for (auto &KV
: Streamer
.symverAliases())
174 for (auto &Alias
: KV
.second
)
175 AsmSymver(KV
.first
->getName(), Alias
);
179 void ModuleSymbolTable::printSymbolName(raw_ostream
&OS
, Symbol S
) const {
180 if (S
.is
<AsmSymbol
*>()) {
181 OS
<< S
.get
<AsmSymbol
*>()->first
;
185 auto *GV
= S
.get
<GlobalValue
*>();
186 if (GV
->hasDLLImportStorageClass())
189 Mang
.getNameWithPrefix(OS
, GV
, false);
192 uint32_t ModuleSymbolTable::getSymbolFlags(Symbol S
) const {
193 if (S
.is
<AsmSymbol
*>())
194 return S
.get
<AsmSymbol
*>()->second
;
196 auto *GV
= S
.get
<GlobalValue
*>();
198 uint32_t Res
= BasicSymbolRef::SF_None
;
199 if (GV
->isDeclarationForLinker())
200 Res
|= BasicSymbolRef::SF_Undefined
;
201 else if (GV
->hasHiddenVisibility() && !GV
->hasLocalLinkage())
202 Res
|= BasicSymbolRef::SF_Hidden
;
203 if (const GlobalVariable
*GVar
= dyn_cast
<GlobalVariable
>(GV
)) {
204 if (GVar
->isConstant())
205 Res
|= BasicSymbolRef::SF_Const
;
207 if (dyn_cast_or_null
<Function
>(GV
->getBaseObject()))
208 Res
|= BasicSymbolRef::SF_Executable
;
209 if (isa
<GlobalAlias
>(GV
))
210 Res
|= BasicSymbolRef::SF_Indirect
;
211 if (GV
->hasPrivateLinkage())
212 Res
|= BasicSymbolRef::SF_FormatSpecific
;
213 if (!GV
->hasLocalLinkage())
214 Res
|= BasicSymbolRef::SF_Global
;
215 if (GV
->hasCommonLinkage())
216 Res
|= BasicSymbolRef::SF_Common
;
217 if (GV
->hasLinkOnceLinkage() || GV
->hasWeakLinkage() ||
218 GV
->hasExternalWeakLinkage())
219 Res
|= BasicSymbolRef::SF_Weak
;
221 if (GV
->getName().startswith("llvm."))
222 Res
|= BasicSymbolRef::SF_FormatSpecific
;
223 else if (auto *Var
= dyn_cast
<GlobalVariable
>(GV
)) {
224 if (Var
->getSection() == "llvm.metadata")
225 Res
|= BasicSymbolRef::SF_FormatSpecific
;