1863cbfbeSPeter Collingbourne //===- ModuleSymbolTable.cpp - symbol table for in-memory IR ----*- C++ -*-===//
2863cbfbeSPeter Collingbourne //
3863cbfbeSPeter Collingbourne //                     The LLVM Compiler Infrastructure
4863cbfbeSPeter Collingbourne //
5863cbfbeSPeter Collingbourne // This file is distributed under the University of Illinois Open Source
6863cbfbeSPeter Collingbourne // License. See LICENSE.TXT for details.
7863cbfbeSPeter Collingbourne //
8863cbfbeSPeter Collingbourne //===----------------------------------------------------------------------===//
9863cbfbeSPeter Collingbourne //
10863cbfbeSPeter Collingbourne // This class represents a symbol table built from in-memory IR. It provides
11863cbfbeSPeter Collingbourne // access to GlobalValues and should only be used if such access is required
12863cbfbeSPeter Collingbourne // (e.g. in the LTO implementation).
13863cbfbeSPeter Collingbourne //
14863cbfbeSPeter Collingbourne //===----------------------------------------------------------------------===//
15863cbfbeSPeter Collingbourne 
16863cbfbeSPeter Collingbourne #include "llvm/Object/IRObjectFile.h"
17863cbfbeSPeter Collingbourne #include "RecordStreamer.h"
18863cbfbeSPeter Collingbourne #include "llvm/ADT/STLExtras.h"
19863cbfbeSPeter Collingbourne #include "llvm/Bitcode/BitcodeReader.h"
20863cbfbeSPeter Collingbourne #include "llvm/IR/GVMaterializer.h"
21863cbfbeSPeter Collingbourne #include "llvm/IR/LLVMContext.h"
22863cbfbeSPeter Collingbourne #include "llvm/IR/Mangler.h"
23863cbfbeSPeter Collingbourne #include "llvm/IR/Module.h"
24863cbfbeSPeter Collingbourne #include "llvm/MC/MCAsmInfo.h"
25863cbfbeSPeter Collingbourne #include "llvm/MC/MCContext.h"
26863cbfbeSPeter Collingbourne #include "llvm/MC/MCInstrInfo.h"
27863cbfbeSPeter Collingbourne #include "llvm/MC/MCObjectFileInfo.h"
28863cbfbeSPeter Collingbourne #include "llvm/MC/MCParser/MCAsmParser.h"
29863cbfbeSPeter Collingbourne #include "llvm/MC/MCParser/MCTargetAsmParser.h"
30863cbfbeSPeter Collingbourne #include "llvm/MC/MCRegisterInfo.h"
31863cbfbeSPeter Collingbourne #include "llvm/MC/MCSubtargetInfo.h"
32863cbfbeSPeter Collingbourne #include "llvm/Object/ObjectFile.h"
33863cbfbeSPeter Collingbourne #include "llvm/Support/MemoryBuffer.h"
34863cbfbeSPeter Collingbourne #include "llvm/Support/SourceMgr.h"
35863cbfbeSPeter Collingbourne #include "llvm/Support/TargetRegistry.h"
36863cbfbeSPeter Collingbourne #include "llvm/Support/raw_ostream.h"
37863cbfbeSPeter Collingbourne using namespace llvm;
38863cbfbeSPeter Collingbourne using namespace object;
39863cbfbeSPeter Collingbourne 
40863cbfbeSPeter Collingbourne void ModuleSymbolTable::addModule(Module *M) {
41863cbfbeSPeter Collingbourne   if (FirstMod)
42863cbfbeSPeter Collingbourne     assert(FirstMod->getTargetTriple() == M->getTargetTriple());
43863cbfbeSPeter Collingbourne   else
44863cbfbeSPeter Collingbourne     FirstMod = M;
45863cbfbeSPeter Collingbourne 
46863cbfbeSPeter Collingbourne   for (Function &F : *M)
47863cbfbeSPeter Collingbourne     SymTab.push_back(&F);
48863cbfbeSPeter Collingbourne   for (GlobalVariable &GV : M->globals())
49863cbfbeSPeter Collingbourne     SymTab.push_back(&GV);
50863cbfbeSPeter Collingbourne   for (GlobalAlias &GA : M->aliases())
51863cbfbeSPeter Collingbourne     SymTab.push_back(&GA);
52863cbfbeSPeter Collingbourne 
53863cbfbeSPeter Collingbourne   CollectAsmSymbols(Triple(M->getTargetTriple()), M->getModuleInlineAsm(),
54863cbfbeSPeter Collingbourne                     [this](StringRef Name, BasicSymbolRef::Flags Flags) {
55863cbfbeSPeter Collingbourne                       SymTab.push_back(new (AsmSymbols.Allocate())
56863cbfbeSPeter Collingbourne                                            AsmSymbol(Name, Flags));
57863cbfbeSPeter Collingbourne                     });
58863cbfbeSPeter Collingbourne }
59863cbfbeSPeter Collingbourne 
60863cbfbeSPeter Collingbourne void ModuleSymbolTable::CollectAsmSymbols(
61863cbfbeSPeter Collingbourne     const Triple &TT, StringRef InlineAsm,
62863cbfbeSPeter Collingbourne     function_ref<void(StringRef, BasicSymbolRef::Flags)> AsmSymbol) {
63863cbfbeSPeter Collingbourne   if (InlineAsm.empty())
64863cbfbeSPeter Collingbourne     return;
65863cbfbeSPeter Collingbourne 
66863cbfbeSPeter Collingbourne   std::string Err;
67863cbfbeSPeter Collingbourne   const Target *T = TargetRegistry::lookupTarget(TT.str(), Err);
68863cbfbeSPeter Collingbourne   assert(T && T->hasMCAsmParser());
69863cbfbeSPeter Collingbourne 
70863cbfbeSPeter Collingbourne   std::unique_ptr<MCRegisterInfo> MRI(T->createMCRegInfo(TT.str()));
71863cbfbeSPeter Collingbourne   if (!MRI)
72863cbfbeSPeter Collingbourne     return;
73863cbfbeSPeter Collingbourne 
74863cbfbeSPeter Collingbourne   std::unique_ptr<MCAsmInfo> MAI(T->createMCAsmInfo(*MRI, TT.str()));
75863cbfbeSPeter Collingbourne   if (!MAI)
76863cbfbeSPeter Collingbourne     return;
77863cbfbeSPeter Collingbourne 
78863cbfbeSPeter Collingbourne   std::unique_ptr<MCSubtargetInfo> STI(
79863cbfbeSPeter Collingbourne       T->createMCSubtargetInfo(TT.str(), "", ""));
80863cbfbeSPeter Collingbourne   if (!STI)
81863cbfbeSPeter Collingbourne     return;
82863cbfbeSPeter Collingbourne 
83863cbfbeSPeter Collingbourne   std::unique_ptr<MCInstrInfo> MCII(T->createMCInstrInfo());
84863cbfbeSPeter Collingbourne   if (!MCII)
85863cbfbeSPeter Collingbourne     return;
86863cbfbeSPeter Collingbourne 
87863cbfbeSPeter Collingbourne   MCObjectFileInfo MOFI;
88863cbfbeSPeter Collingbourne   MCContext MCCtx(MAI.get(), MRI.get(), &MOFI);
89863cbfbeSPeter Collingbourne   MOFI.InitMCObjectFileInfo(TT, /*PIC*/ false, CodeModel::Default, MCCtx);
90863cbfbeSPeter Collingbourne   RecordStreamer Streamer(MCCtx);
91863cbfbeSPeter Collingbourne   T->createNullTargetStreamer(Streamer);
92863cbfbeSPeter Collingbourne 
93863cbfbeSPeter Collingbourne   std::unique_ptr<MemoryBuffer> Buffer(MemoryBuffer::getMemBuffer(InlineAsm));
94863cbfbeSPeter Collingbourne   SourceMgr SrcMgr;
95863cbfbeSPeter Collingbourne   SrcMgr.AddNewSourceBuffer(std::move(Buffer), SMLoc());
96863cbfbeSPeter Collingbourne   std::unique_ptr<MCAsmParser> Parser(
97863cbfbeSPeter Collingbourne       createMCAsmParser(SrcMgr, MCCtx, Streamer, *MAI));
98863cbfbeSPeter Collingbourne 
99863cbfbeSPeter Collingbourne   MCTargetOptions MCOptions;
100863cbfbeSPeter Collingbourne   std::unique_ptr<MCTargetAsmParser> TAP(
101863cbfbeSPeter Collingbourne       T->createMCAsmParser(*STI, *Parser, *MCII, MCOptions));
102863cbfbeSPeter Collingbourne   if (!TAP)
103863cbfbeSPeter Collingbourne     return;
104863cbfbeSPeter Collingbourne 
105863cbfbeSPeter Collingbourne   Parser->setTargetParser(*TAP);
106863cbfbeSPeter Collingbourne   if (Parser->Run(false))
107863cbfbeSPeter Collingbourne     return;
108863cbfbeSPeter Collingbourne 
109863cbfbeSPeter Collingbourne   for (auto &KV : Streamer) {
110863cbfbeSPeter Collingbourne     StringRef Key = KV.first();
111863cbfbeSPeter Collingbourne     RecordStreamer::State Value = KV.second;
112e2f1b4a6SPeter Collingbourne     // FIXME: For now we just assume that all asm symbols are executable.
113e2f1b4a6SPeter Collingbourne     uint32_t Res = BasicSymbolRef::SF_Executable;
114863cbfbeSPeter Collingbourne     switch (Value) {
115863cbfbeSPeter Collingbourne     case RecordStreamer::NeverSeen:
116863cbfbeSPeter Collingbourne       llvm_unreachable("NeverSeen should have been replaced earlier");
117863cbfbeSPeter Collingbourne     case RecordStreamer::DefinedGlobal:
118863cbfbeSPeter Collingbourne       Res |= BasicSymbolRef::SF_Global;
119863cbfbeSPeter Collingbourne       break;
120863cbfbeSPeter Collingbourne     case RecordStreamer::Defined:
121863cbfbeSPeter Collingbourne       break;
122863cbfbeSPeter Collingbourne     case RecordStreamer::Global:
123863cbfbeSPeter Collingbourne     case RecordStreamer::Used:
124863cbfbeSPeter Collingbourne       Res |= BasicSymbolRef::SF_Undefined;
125863cbfbeSPeter Collingbourne       Res |= BasicSymbolRef::SF_Global;
126863cbfbeSPeter Collingbourne       break;
127863cbfbeSPeter Collingbourne     case RecordStreamer::DefinedWeak:
128863cbfbeSPeter Collingbourne       Res |= BasicSymbolRef::SF_Weak;
129863cbfbeSPeter Collingbourne       Res |= BasicSymbolRef::SF_Global;
130863cbfbeSPeter Collingbourne       break;
131863cbfbeSPeter Collingbourne     case RecordStreamer::UndefinedWeak:
132863cbfbeSPeter Collingbourne       Res |= BasicSymbolRef::SF_Weak;
133863cbfbeSPeter Collingbourne       Res |= BasicSymbolRef::SF_Undefined;
134863cbfbeSPeter Collingbourne     }
135863cbfbeSPeter Collingbourne     AsmSymbol(Key, BasicSymbolRef::Flags(Res));
136863cbfbeSPeter Collingbourne   }
137863cbfbeSPeter Collingbourne }
138863cbfbeSPeter Collingbourne 
139863cbfbeSPeter Collingbourne void ModuleSymbolTable::printSymbolName(raw_ostream &OS, Symbol S) const {
140863cbfbeSPeter Collingbourne   if (S.is<AsmSymbol *>()) {
141863cbfbeSPeter Collingbourne     OS << S.get<AsmSymbol *>()->first;
142863cbfbeSPeter Collingbourne     return;
143863cbfbeSPeter Collingbourne   }
144863cbfbeSPeter Collingbourne 
145863cbfbeSPeter Collingbourne   auto *GV = S.get<GlobalValue *>();
146863cbfbeSPeter Collingbourne   if (GV->hasDLLImportStorageClass())
147863cbfbeSPeter Collingbourne     OS << "__imp_";
148863cbfbeSPeter Collingbourne 
149863cbfbeSPeter Collingbourne   Mang.getNameWithPrefix(OS, GV, false);
150863cbfbeSPeter Collingbourne }
151863cbfbeSPeter Collingbourne 
152863cbfbeSPeter Collingbourne uint32_t ModuleSymbolTable::getSymbolFlags(Symbol S) const {
153863cbfbeSPeter Collingbourne   if (S.is<AsmSymbol *>())
154863cbfbeSPeter Collingbourne     return S.get<AsmSymbol *>()->second;
155863cbfbeSPeter Collingbourne 
156863cbfbeSPeter Collingbourne   auto *GV = S.get<GlobalValue *>();
157863cbfbeSPeter Collingbourne 
158863cbfbeSPeter Collingbourne   uint32_t Res = BasicSymbolRef::SF_None;
159863cbfbeSPeter Collingbourne   if (GV->isDeclarationForLinker())
160863cbfbeSPeter Collingbourne     Res |= BasicSymbolRef::SF_Undefined;
161863cbfbeSPeter Collingbourne   else if (GV->hasHiddenVisibility() && !GV->hasLocalLinkage())
162863cbfbeSPeter Collingbourne     Res |= BasicSymbolRef::SF_Hidden;
163863cbfbeSPeter Collingbourne   if (const GlobalVariable *GVar = dyn_cast<GlobalVariable>(GV)) {
164863cbfbeSPeter Collingbourne     if (GVar->isConstant())
165863cbfbeSPeter Collingbourne       Res |= BasicSymbolRef::SF_Const;
166863cbfbeSPeter Collingbourne   }
167e2f1b4a6SPeter Collingbourne   if (dyn_cast_or_null<Function>(GV->getBaseObject()))
168e2f1b4a6SPeter Collingbourne     Res |= BasicSymbolRef::SF_Executable;
169*d64ecf26SPeter Collingbourne   if (isa<GlobalAlias>(GV))
170*d64ecf26SPeter Collingbourne     Res |= BasicSymbolRef::SF_Indirect;
171863cbfbeSPeter Collingbourne   if (GV->hasPrivateLinkage())
172863cbfbeSPeter Collingbourne     Res |= BasicSymbolRef::SF_FormatSpecific;
173863cbfbeSPeter Collingbourne   if (!GV->hasLocalLinkage())
174863cbfbeSPeter Collingbourne     Res |= BasicSymbolRef::SF_Global;
175863cbfbeSPeter Collingbourne   if (GV->hasCommonLinkage())
176863cbfbeSPeter Collingbourne     Res |= BasicSymbolRef::SF_Common;
177863cbfbeSPeter Collingbourne   if (GV->hasLinkOnceLinkage() || GV->hasWeakLinkage() ||
178863cbfbeSPeter Collingbourne       GV->hasExternalWeakLinkage())
179863cbfbeSPeter Collingbourne     Res |= BasicSymbolRef::SF_Weak;
180863cbfbeSPeter Collingbourne 
181863cbfbeSPeter Collingbourne   if (GV->getName().startswith("llvm."))
182863cbfbeSPeter Collingbourne     Res |= BasicSymbolRef::SF_FormatSpecific;
183863cbfbeSPeter Collingbourne   else if (auto *Var = dyn_cast<GlobalVariable>(GV)) {
184863cbfbeSPeter Collingbourne     if (Var->getSection() == "llvm.metadata")
185863cbfbeSPeter Collingbourne       Res |= BasicSymbolRef::SF_FormatSpecific;
186863cbfbeSPeter Collingbourne   }
187863cbfbeSPeter Collingbourne 
188863cbfbeSPeter Collingbourne   return Res;
189863cbfbeSPeter Collingbourne }
190