xref: /llvm-project/llvm/lib/Object/ModuleSymbolTable.cpp (revision d820447212e616093941f45775b52bd4afc86cf0)
1 //===- ModuleSymbolTable.cpp - symbol table for in-memory IR ----*- C++ -*-===//
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/IRObjectFile.h"
17 #include "RecordStreamer.h"
18 #include "llvm/ADT/STLExtras.h"
19 #include "llvm/Bitcode/BitcodeReader.h"
20 #include "llvm/IR/GVMaterializer.h"
21 #include "llvm/IR/LLVMContext.h"
22 #include "llvm/IR/Mangler.h"
23 #include "llvm/IR/Module.h"
24 #include "llvm/MC/MCAsmInfo.h"
25 #include "llvm/MC/MCContext.h"
26 #include "llvm/MC/MCInstrInfo.h"
27 #include "llvm/MC/MCObjectFileInfo.h"
28 #include "llvm/MC/MCParser/MCAsmParser.h"
29 #include "llvm/MC/MCParser/MCTargetAsmParser.h"
30 #include "llvm/MC/MCRegisterInfo.h"
31 #include "llvm/MC/MCSubtargetInfo.h"
32 #include "llvm/Object/ObjectFile.h"
33 #include "llvm/Support/MemoryBuffer.h"
34 #include "llvm/Support/SourceMgr.h"
35 #include "llvm/Support/TargetRegistry.h"
36 #include "llvm/Support/raw_ostream.h"
37 using namespace llvm;
38 using namespace object;
39 
40 void ModuleSymbolTable::addModule(Module *M) {
41   if (FirstMod)
42     assert(FirstMod->getTargetTriple() == M->getTargetTriple());
43   else
44     FirstMod = M;
45 
46   for (Function &F : *M)
47     SymTab.push_back(&F);
48   for (GlobalVariable &GV : M->globals())
49     SymTab.push_back(&GV);
50   for (GlobalAlias &GA : M->aliases())
51     SymTab.push_back(&GA);
52 
53   CollectAsmSymbols(*M, [this](StringRef Name, BasicSymbolRef::Flags Flags) {
54     SymTab.push_back(new (AsmSymbols.Allocate()) AsmSymbol(Name, Flags));
55   });
56 }
57 
58 // Ensure ELF .symver aliases get the same binding as the defined symbol
59 // they alias with.
60 static void handleSymverAliases(const Module &M, RecordStreamer &Streamer) {
61   if (Streamer.symverAliases().empty())
62     return;
63 
64   // The name in the assembler will be mangled, but the name in the IR
65   // might not, so we first compute a mapping from mangled name to GV.
66   Mangler Mang;
67   SmallString<64> MangledName;
68   StringMap<const GlobalValue *> MangledNameMap;
69   auto GetMangledName = [&](const GlobalValue &GV) {
70     if (!GV.hasName())
71       return;
72 
73     MangledName.clear();
74     MangledName.reserve(GV.getName().size() + 1);
75     Mang.getNameWithPrefix(MangledName, &GV, /*CannotUsePrivateLabel=*/false);
76     MangledNameMap[MangledName] = &GV;
77   };
78   for (const Function &F : M)
79     GetMangledName(F);
80   for (const GlobalVariable &GV : M.globals())
81     GetMangledName(GV);
82   for (const GlobalAlias &GA : M.aliases())
83     GetMangledName(GA);
84 
85   // Walk all the recorded .symver aliases, and set up the binding
86   // for each alias.
87   for (auto &Symver : Streamer.symverAliases()) {
88     const MCSymbol *Aliasee = Symver.first;
89     MCSymbolAttr Attr = MCSA_Invalid;
90 
91     // First check if the aliasee binding was recorded in the asm.
92     RecordStreamer::State state = Streamer.getSymbolState(Aliasee);
93     switch (state) {
94     case RecordStreamer::Global:
95     case RecordStreamer::DefinedGlobal:
96       Attr = MCSA_Global;
97       break;
98     case RecordStreamer::UndefinedWeak:
99     case RecordStreamer::DefinedWeak:
100       Attr = MCSA_Weak;
101       break;
102     default:
103       break;
104     }
105 
106     // If we don't have a symbol attribute from assembly, then check if
107     // the aliasee was defined in the IR.
108     if (Attr == MCSA_Invalid) {
109       const auto *GV = M.getNamedValue(Aliasee->getName());
110       if (!GV) {
111         auto MI = MangledNameMap.find(Aliasee->getName());
112         if (MI != MangledNameMap.end())
113           GV = MI->second;
114         else
115           continue;
116       }
117       if (GV->hasExternalLinkage())
118         Attr = MCSA_Global;
119       else if (GV->hasLocalLinkage())
120         Attr = MCSA_Local;
121       else if (GV->isWeakForLinker())
122         Attr = MCSA_Weak;
123     }
124     if (Attr == MCSA_Invalid)
125       continue;
126 
127     // Set the detected binding on each alias with this aliasee.
128     for (auto &Alias : Symver.second)
129       Streamer.EmitSymbolAttribute(Alias, Attr);
130   }
131 }
132 
133 void ModuleSymbolTable::CollectAsmSymbols(
134     const Module &M,
135     function_ref<void(StringRef, BasicSymbolRef::Flags)> AsmSymbol) {
136   StringRef InlineAsm = M.getModuleInlineAsm();
137   if (InlineAsm.empty())
138     return;
139 
140   std::string Err;
141   const Triple TT(M.getTargetTriple());
142   const Target *T = TargetRegistry::lookupTarget(TT.str(), Err);
143   assert(T && T->hasMCAsmParser());
144 
145   std::unique_ptr<MCRegisterInfo> MRI(T->createMCRegInfo(TT.str()));
146   if (!MRI)
147     return;
148 
149   std::unique_ptr<MCAsmInfo> MAI(T->createMCAsmInfo(*MRI, TT.str()));
150   if (!MAI)
151     return;
152 
153   std::unique_ptr<MCSubtargetInfo> STI(
154       T->createMCSubtargetInfo(TT.str(), "", ""));
155   if (!STI)
156     return;
157 
158   std::unique_ptr<MCInstrInfo> MCII(T->createMCInstrInfo());
159   if (!MCII)
160     return;
161 
162   MCObjectFileInfo MOFI;
163   MCContext MCCtx(MAI.get(), MRI.get(), &MOFI);
164   MOFI.InitMCObjectFileInfo(TT, /*PIC*/ false, CodeModel::Default, MCCtx);
165   RecordStreamer Streamer(MCCtx);
166   T->createNullTargetStreamer(Streamer);
167 
168   std::unique_ptr<MemoryBuffer> Buffer(MemoryBuffer::getMemBuffer(InlineAsm));
169   SourceMgr SrcMgr;
170   SrcMgr.AddNewSourceBuffer(std::move(Buffer), SMLoc());
171   std::unique_ptr<MCAsmParser> Parser(
172       createMCAsmParser(SrcMgr, MCCtx, Streamer, *MAI));
173 
174   MCTargetOptions MCOptions;
175   std::unique_ptr<MCTargetAsmParser> TAP(
176       T->createMCAsmParser(*STI, *Parser, *MCII, MCOptions));
177   if (!TAP)
178     return;
179 
180   Parser->setTargetParser(*TAP);
181   if (Parser->Run(false))
182     return;
183 
184   handleSymverAliases(M, Streamer);
185 
186   for (auto &KV : Streamer) {
187     StringRef Key = KV.first();
188     RecordStreamer::State Value = KV.second;
189     // FIXME: For now we just assume that all asm symbols are executable.
190     uint32_t Res = BasicSymbolRef::SF_Executable;
191     switch (Value) {
192     case RecordStreamer::NeverSeen:
193       llvm_unreachable("NeverSeen should have been replaced earlier");
194     case RecordStreamer::DefinedGlobal:
195       Res |= BasicSymbolRef::SF_Global;
196       break;
197     case RecordStreamer::Defined:
198       break;
199     case RecordStreamer::Global:
200     case RecordStreamer::Used:
201       Res |= BasicSymbolRef::SF_Undefined;
202       Res |= BasicSymbolRef::SF_Global;
203       break;
204     case RecordStreamer::DefinedWeak:
205       Res |= BasicSymbolRef::SF_Weak;
206       Res |= BasicSymbolRef::SF_Global;
207       break;
208     case RecordStreamer::UndefinedWeak:
209       Res |= BasicSymbolRef::SF_Weak;
210       Res |= BasicSymbolRef::SF_Undefined;
211     }
212     AsmSymbol(Key, BasicSymbolRef::Flags(Res));
213   }
214 }
215 
216 void ModuleSymbolTable::printSymbolName(raw_ostream &OS, Symbol S) const {
217   if (S.is<AsmSymbol *>()) {
218     OS << S.get<AsmSymbol *>()->first;
219     return;
220   }
221 
222   auto *GV = S.get<GlobalValue *>();
223   if (GV->hasDLLImportStorageClass())
224     OS << "__imp_";
225 
226   Mang.getNameWithPrefix(OS, GV, false);
227 }
228 
229 uint32_t ModuleSymbolTable::getSymbolFlags(Symbol S) const {
230   if (S.is<AsmSymbol *>())
231     return S.get<AsmSymbol *>()->second;
232 
233   auto *GV = S.get<GlobalValue *>();
234 
235   uint32_t Res = BasicSymbolRef::SF_None;
236   if (GV->isDeclarationForLinker())
237     Res |= BasicSymbolRef::SF_Undefined;
238   else if (GV->hasHiddenVisibility() && !GV->hasLocalLinkage())
239     Res |= BasicSymbolRef::SF_Hidden;
240   if (const GlobalVariable *GVar = dyn_cast<GlobalVariable>(GV)) {
241     if (GVar->isConstant())
242       Res |= BasicSymbolRef::SF_Const;
243   }
244   if (dyn_cast_or_null<Function>(GV->getBaseObject()))
245     Res |= BasicSymbolRef::SF_Executable;
246   if (isa<GlobalAlias>(GV))
247     Res |= BasicSymbolRef::SF_Indirect;
248   if (GV->hasPrivateLinkage())
249     Res |= BasicSymbolRef::SF_FormatSpecific;
250   if (!GV->hasLocalLinkage())
251     Res |= BasicSymbolRef::SF_Global;
252   if (GV->hasCommonLinkage())
253     Res |= BasicSymbolRef::SF_Common;
254   if (GV->hasLinkOnceLinkage() || GV->hasWeakLinkage() ||
255       GV->hasExternalWeakLinkage())
256     Res |= BasicSymbolRef::SF_Weak;
257 
258   if (GV->getName().startswith("llvm."))
259     Res |= BasicSymbolRef::SF_FormatSpecific;
260   else if (auto *Var = dyn_cast<GlobalVariable>(GV)) {
261     if (Var->getSection() == "llvm.metadata")
262       Res |= BasicSymbolRef::SF_FormatSpecific;
263   }
264 
265   return Res;
266 }
267