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/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"
54 using namespace object
;
56 void ModuleSymbolTable::addModule(Module
*M
) {
58 assert(FirstMod
->getTargetTriple() == M
->getTargetTriple());
62 for (GlobalValue
&GV
: M
->global_values())
63 SymTab
.push_back(&GV
);
65 CollectAsmSymbols(*M
, [this](StringRef Name
, BasicSymbolRef::Flags Flags
) {
66 SymTab
.push_back(new (AsmSymbols
.Allocate()) AsmSymbol(Name
, Flags
));
71 initializeRecordStreamer(const Module
&M
,
72 function_ref
<void(RecordStreamer
&)> Init
) {
73 StringRef InlineAsm
= M
.getModuleInlineAsm();
74 if (InlineAsm
.empty())
78 const Triple
TT(M
.getTargetTriple());
79 const Target
*T
= TargetRegistry::lookupTarget(TT
.str(), Err
);
80 assert(T
&& T
->hasMCAsmParser());
82 std::unique_ptr
<MCRegisterInfo
> MRI(T
->createMCRegInfo(TT
.str()));
86 std::unique_ptr
<MCAsmInfo
> MAI(T
->createMCAsmInfo(*MRI
, TT
.str()));
90 std::unique_ptr
<MCSubtargetInfo
> STI(
91 T
->createMCSubtargetInfo(TT
.str(), "", ""));
95 std::unique_ptr
<MCInstrInfo
> MCII(T
->createMCInstrInfo());
99 MCObjectFileInfo MOFI
;
100 MCContext
MCCtx(MAI
.get(), MRI
.get(), &MOFI
);
101 MOFI
.InitMCObjectFileInfo(TT
, /*PIC*/ false, MCCtx
);
102 MOFI
.setSDKVersion(M
.getSDKVersion());
103 RecordStreamer
Streamer(MCCtx
, M
);
104 T
->createNullTargetStreamer(Streamer
);
106 std::unique_ptr
<MemoryBuffer
> Buffer(MemoryBuffer::getMemBuffer(InlineAsm
));
108 SrcMgr
.AddNewSourceBuffer(std::move(Buffer
), SMLoc());
109 std::unique_ptr
<MCAsmParser
> Parser(
110 createMCAsmParser(SrcMgr
, MCCtx
, Streamer
, *MAI
));
112 MCTargetOptions MCOptions
;
113 std::unique_ptr
<MCTargetAsmParser
> TAP(
114 T
->createMCAsmParser(*STI
, *Parser
, *MCII
, MCOptions
));
118 Parser
->setTargetParser(*TAP
);
119 if (Parser
->Run(false))
125 void ModuleSymbolTable::CollectAsmSymbols(
127 function_ref
<void(StringRef
, BasicSymbolRef::Flags
)> AsmSymbol
) {
128 initializeRecordStreamer(M
, [&](RecordStreamer
&Streamer
) {
129 Streamer
.flushSymverDirectives();
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
;
137 case RecordStreamer::NeverSeen
:
138 llvm_unreachable("NeverSeen should have been replaced earlier");
139 case RecordStreamer::DefinedGlobal
:
140 Res
|= BasicSymbolRef::SF_Global
;
142 case RecordStreamer::Defined
:
144 case RecordStreamer::Global
:
145 case RecordStreamer::Used
:
146 Res
|= BasicSymbolRef::SF_Undefined
;
147 Res
|= BasicSymbolRef::SF_Global
;
149 case RecordStreamer::DefinedWeak
:
150 Res
|= BasicSymbolRef::SF_Weak
;
151 Res
|= BasicSymbolRef::SF_Global
;
153 case RecordStreamer::UndefinedWeak
:
154 Res
|= BasicSymbolRef::SF_Weak
;
155 Res
|= BasicSymbolRef::SF_Undefined
;
157 AsmSymbol(Key
, BasicSymbolRef::Flags(Res
));
162 void ModuleSymbolTable::CollectAsmSymvers(
163 const Module
&M
, function_ref
<void(StringRef
, StringRef
)> AsmSymver
) {
164 initializeRecordStreamer(M
, [&](RecordStreamer
&Streamer
) {
165 for (auto &KV
: Streamer
.symverAliases())
166 for (auto &Alias
: KV
.second
)
167 AsmSymver(KV
.first
->getName(), Alias
);
171 void ModuleSymbolTable::printSymbolName(raw_ostream
&OS
, Symbol S
) const {
172 if (S
.is
<AsmSymbol
*>()) {
173 OS
<< S
.get
<AsmSymbol
*>()->first
;
177 auto *GV
= S
.get
<GlobalValue
*>();
178 if (GV
->hasDLLImportStorageClass())
181 Mang
.getNameWithPrefix(OS
, GV
, false);
184 uint32_t ModuleSymbolTable::getSymbolFlags(Symbol S
) const {
185 if (S
.is
<AsmSymbol
*>())
186 return S
.get
<AsmSymbol
*>()->second
;
188 auto *GV
= S
.get
<GlobalValue
*>();
190 uint32_t Res
= BasicSymbolRef::SF_None
;
191 if (GV
->isDeclarationForLinker())
192 Res
|= BasicSymbolRef::SF_Undefined
;
193 else if (GV
->hasHiddenVisibility() && !GV
->hasLocalLinkage())
194 Res
|= BasicSymbolRef::SF_Hidden
;
195 if (const GlobalVariable
*GVar
= dyn_cast
<GlobalVariable
>(GV
)) {
196 if (GVar
->isConstant())
197 Res
|= BasicSymbolRef::SF_Const
;
199 if (dyn_cast_or_null
<Function
>(GV
->getBaseObject()))
200 Res
|= BasicSymbolRef::SF_Executable
;
201 if (isa
<GlobalAlias
>(GV
))
202 Res
|= BasicSymbolRef::SF_Indirect
;
203 if (GV
->hasPrivateLinkage())
204 Res
|= BasicSymbolRef::SF_FormatSpecific
;
205 if (!GV
->hasLocalLinkage())
206 Res
|= BasicSymbolRef::SF_Global
;
207 if (GV
->hasCommonLinkage())
208 Res
|= BasicSymbolRef::SF_Common
;
209 if (GV
->hasLinkOnceLinkage() || GV
->hasWeakLinkage() ||
210 GV
->hasExternalWeakLinkage())
211 Res
|= BasicSymbolRef::SF_Weak
;
213 if (GV
->getName().startswith("llvm."))
214 Res
|= BasicSymbolRef::SF_FormatSpecific
;
215 else if (auto *Var
= dyn_cast
<GlobalVariable
>(GV
)) {
216 if (Var
->getSection() == "llvm.metadata")
217 Res
|= BasicSymbolRef::SF_FormatSpecific
;