1*863cbfbeSPeter Collingbourne //===- ModuleSymbolTable.cpp - symbol table for in-memory IR ----*- C++ -*-===// 2*863cbfbeSPeter Collingbourne // 3*863cbfbeSPeter Collingbourne // The LLVM Compiler Infrastructure 4*863cbfbeSPeter Collingbourne // 5*863cbfbeSPeter Collingbourne // This file is distributed under the University of Illinois Open Source 6*863cbfbeSPeter Collingbourne // License. See LICENSE.TXT for details. 7*863cbfbeSPeter Collingbourne // 8*863cbfbeSPeter Collingbourne //===----------------------------------------------------------------------===// 9*863cbfbeSPeter Collingbourne // 10*863cbfbeSPeter Collingbourne // This class represents a symbol table built from in-memory IR. It provides 11*863cbfbeSPeter Collingbourne // access to GlobalValues and should only be used if such access is required 12*863cbfbeSPeter Collingbourne // (e.g. in the LTO implementation). 13*863cbfbeSPeter Collingbourne // 14*863cbfbeSPeter Collingbourne //===----------------------------------------------------------------------===// 15*863cbfbeSPeter Collingbourne 16*863cbfbeSPeter Collingbourne #include "llvm/Object/IRObjectFile.h" 17*863cbfbeSPeter Collingbourne #include "RecordStreamer.h" 18*863cbfbeSPeter Collingbourne #include "llvm/ADT/STLExtras.h" 19*863cbfbeSPeter Collingbourne #include "llvm/Bitcode/BitcodeReader.h" 20*863cbfbeSPeter Collingbourne #include "llvm/IR/GVMaterializer.h" 21*863cbfbeSPeter Collingbourne #include "llvm/IR/LLVMContext.h" 22*863cbfbeSPeter Collingbourne #include "llvm/IR/Mangler.h" 23*863cbfbeSPeter Collingbourne #include "llvm/IR/Module.h" 24*863cbfbeSPeter Collingbourne #include "llvm/MC/MCAsmInfo.h" 25*863cbfbeSPeter Collingbourne #include "llvm/MC/MCContext.h" 26*863cbfbeSPeter Collingbourne #include "llvm/MC/MCInstrInfo.h" 27*863cbfbeSPeter Collingbourne #include "llvm/MC/MCObjectFileInfo.h" 28*863cbfbeSPeter Collingbourne #include "llvm/MC/MCParser/MCAsmParser.h" 29*863cbfbeSPeter Collingbourne #include "llvm/MC/MCParser/MCTargetAsmParser.h" 30*863cbfbeSPeter Collingbourne #include "llvm/MC/MCRegisterInfo.h" 31*863cbfbeSPeter Collingbourne #include "llvm/MC/MCSubtargetInfo.h" 32*863cbfbeSPeter Collingbourne #include "llvm/Object/ObjectFile.h" 33*863cbfbeSPeter Collingbourne #include "llvm/Support/MemoryBuffer.h" 34*863cbfbeSPeter Collingbourne #include "llvm/Support/SourceMgr.h" 35*863cbfbeSPeter Collingbourne #include "llvm/Support/TargetRegistry.h" 36*863cbfbeSPeter Collingbourne #include "llvm/Support/raw_ostream.h" 37*863cbfbeSPeter Collingbourne using namespace llvm; 38*863cbfbeSPeter Collingbourne using namespace object; 39*863cbfbeSPeter Collingbourne 40*863cbfbeSPeter Collingbourne void ModuleSymbolTable::addModule(Module *M) { 41*863cbfbeSPeter Collingbourne if (FirstMod) 42*863cbfbeSPeter Collingbourne assert(FirstMod->getTargetTriple() == M->getTargetTriple()); 43*863cbfbeSPeter Collingbourne else 44*863cbfbeSPeter Collingbourne FirstMod = M; 45*863cbfbeSPeter Collingbourne 46*863cbfbeSPeter Collingbourne for (Function &F : *M) 47*863cbfbeSPeter Collingbourne SymTab.push_back(&F); 48*863cbfbeSPeter Collingbourne for (GlobalVariable &GV : M->globals()) 49*863cbfbeSPeter Collingbourne SymTab.push_back(&GV); 50*863cbfbeSPeter Collingbourne for (GlobalAlias &GA : M->aliases()) 51*863cbfbeSPeter Collingbourne SymTab.push_back(&GA); 52*863cbfbeSPeter Collingbourne 53*863cbfbeSPeter Collingbourne CollectAsmSymbols(Triple(M->getTargetTriple()), M->getModuleInlineAsm(), 54*863cbfbeSPeter Collingbourne [this](StringRef Name, BasicSymbolRef::Flags Flags) { 55*863cbfbeSPeter Collingbourne SymTab.push_back(new (AsmSymbols.Allocate()) 56*863cbfbeSPeter Collingbourne AsmSymbol(Name, Flags)); 57*863cbfbeSPeter Collingbourne }); 58*863cbfbeSPeter Collingbourne } 59*863cbfbeSPeter Collingbourne 60*863cbfbeSPeter Collingbourne void ModuleSymbolTable::CollectAsmSymbols( 61*863cbfbeSPeter Collingbourne const Triple &TT, StringRef InlineAsm, 62*863cbfbeSPeter Collingbourne function_ref<void(StringRef, BasicSymbolRef::Flags)> AsmSymbol) { 63*863cbfbeSPeter Collingbourne if (InlineAsm.empty()) 64*863cbfbeSPeter Collingbourne return; 65*863cbfbeSPeter Collingbourne 66*863cbfbeSPeter Collingbourne std::string Err; 67*863cbfbeSPeter Collingbourne const Target *T = TargetRegistry::lookupTarget(TT.str(), Err); 68*863cbfbeSPeter Collingbourne assert(T && T->hasMCAsmParser()); 69*863cbfbeSPeter Collingbourne 70*863cbfbeSPeter Collingbourne std::unique_ptr<MCRegisterInfo> MRI(T->createMCRegInfo(TT.str())); 71*863cbfbeSPeter Collingbourne if (!MRI) 72*863cbfbeSPeter Collingbourne return; 73*863cbfbeSPeter Collingbourne 74*863cbfbeSPeter Collingbourne std::unique_ptr<MCAsmInfo> MAI(T->createMCAsmInfo(*MRI, TT.str())); 75*863cbfbeSPeter Collingbourne if (!MAI) 76*863cbfbeSPeter Collingbourne return; 77*863cbfbeSPeter Collingbourne 78*863cbfbeSPeter Collingbourne std::unique_ptr<MCSubtargetInfo> STI( 79*863cbfbeSPeter Collingbourne T->createMCSubtargetInfo(TT.str(), "", "")); 80*863cbfbeSPeter Collingbourne if (!STI) 81*863cbfbeSPeter Collingbourne return; 82*863cbfbeSPeter Collingbourne 83*863cbfbeSPeter Collingbourne std::unique_ptr<MCInstrInfo> MCII(T->createMCInstrInfo()); 84*863cbfbeSPeter Collingbourne if (!MCII) 85*863cbfbeSPeter Collingbourne return; 86*863cbfbeSPeter Collingbourne 87*863cbfbeSPeter Collingbourne MCObjectFileInfo MOFI; 88*863cbfbeSPeter Collingbourne MCContext MCCtx(MAI.get(), MRI.get(), &MOFI); 89*863cbfbeSPeter Collingbourne MOFI.InitMCObjectFileInfo(TT, /*PIC*/ false, CodeModel::Default, MCCtx); 90*863cbfbeSPeter Collingbourne RecordStreamer Streamer(MCCtx); 91*863cbfbeSPeter Collingbourne T->createNullTargetStreamer(Streamer); 92*863cbfbeSPeter Collingbourne 93*863cbfbeSPeter Collingbourne std::unique_ptr<MemoryBuffer> Buffer(MemoryBuffer::getMemBuffer(InlineAsm)); 94*863cbfbeSPeter Collingbourne SourceMgr SrcMgr; 95*863cbfbeSPeter Collingbourne SrcMgr.AddNewSourceBuffer(std::move(Buffer), SMLoc()); 96*863cbfbeSPeter Collingbourne std::unique_ptr<MCAsmParser> Parser( 97*863cbfbeSPeter Collingbourne createMCAsmParser(SrcMgr, MCCtx, Streamer, *MAI)); 98*863cbfbeSPeter Collingbourne 99*863cbfbeSPeter Collingbourne MCTargetOptions MCOptions; 100*863cbfbeSPeter Collingbourne std::unique_ptr<MCTargetAsmParser> TAP( 101*863cbfbeSPeter Collingbourne T->createMCAsmParser(*STI, *Parser, *MCII, MCOptions)); 102*863cbfbeSPeter Collingbourne if (!TAP) 103*863cbfbeSPeter Collingbourne return; 104*863cbfbeSPeter Collingbourne 105*863cbfbeSPeter Collingbourne Parser->setTargetParser(*TAP); 106*863cbfbeSPeter Collingbourne if (Parser->Run(false)) 107*863cbfbeSPeter Collingbourne return; 108*863cbfbeSPeter Collingbourne 109*863cbfbeSPeter Collingbourne for (auto &KV : Streamer) { 110*863cbfbeSPeter Collingbourne StringRef Key = KV.first(); 111*863cbfbeSPeter Collingbourne RecordStreamer::State Value = KV.second; 112*863cbfbeSPeter Collingbourne uint32_t Res = BasicSymbolRef::SF_None; 113*863cbfbeSPeter Collingbourne switch (Value) { 114*863cbfbeSPeter Collingbourne case RecordStreamer::NeverSeen: 115*863cbfbeSPeter Collingbourne llvm_unreachable("NeverSeen should have been replaced earlier"); 116*863cbfbeSPeter Collingbourne case RecordStreamer::DefinedGlobal: 117*863cbfbeSPeter Collingbourne Res |= BasicSymbolRef::SF_Global; 118*863cbfbeSPeter Collingbourne break; 119*863cbfbeSPeter Collingbourne case RecordStreamer::Defined: 120*863cbfbeSPeter Collingbourne break; 121*863cbfbeSPeter Collingbourne case RecordStreamer::Global: 122*863cbfbeSPeter Collingbourne case RecordStreamer::Used: 123*863cbfbeSPeter Collingbourne Res |= BasicSymbolRef::SF_Undefined; 124*863cbfbeSPeter Collingbourne Res |= BasicSymbolRef::SF_Global; 125*863cbfbeSPeter Collingbourne break; 126*863cbfbeSPeter Collingbourne case RecordStreamer::DefinedWeak: 127*863cbfbeSPeter Collingbourne Res |= BasicSymbolRef::SF_Weak; 128*863cbfbeSPeter Collingbourne Res |= BasicSymbolRef::SF_Global; 129*863cbfbeSPeter Collingbourne break; 130*863cbfbeSPeter Collingbourne case RecordStreamer::UndefinedWeak: 131*863cbfbeSPeter Collingbourne Res |= BasicSymbolRef::SF_Weak; 132*863cbfbeSPeter Collingbourne Res |= BasicSymbolRef::SF_Undefined; 133*863cbfbeSPeter Collingbourne } 134*863cbfbeSPeter Collingbourne AsmSymbol(Key, BasicSymbolRef::Flags(Res)); 135*863cbfbeSPeter Collingbourne } 136*863cbfbeSPeter Collingbourne } 137*863cbfbeSPeter Collingbourne 138*863cbfbeSPeter Collingbourne void ModuleSymbolTable::printSymbolName(raw_ostream &OS, Symbol S) const { 139*863cbfbeSPeter Collingbourne if (S.is<AsmSymbol *>()) { 140*863cbfbeSPeter Collingbourne OS << S.get<AsmSymbol *>()->first; 141*863cbfbeSPeter Collingbourne return; 142*863cbfbeSPeter Collingbourne } 143*863cbfbeSPeter Collingbourne 144*863cbfbeSPeter Collingbourne auto *GV = S.get<GlobalValue *>(); 145*863cbfbeSPeter Collingbourne if (GV->hasDLLImportStorageClass()) 146*863cbfbeSPeter Collingbourne OS << "__imp_"; 147*863cbfbeSPeter Collingbourne 148*863cbfbeSPeter Collingbourne Mang.getNameWithPrefix(OS, GV, false); 149*863cbfbeSPeter Collingbourne } 150*863cbfbeSPeter Collingbourne 151*863cbfbeSPeter Collingbourne uint32_t ModuleSymbolTable::getSymbolFlags(Symbol S) const { 152*863cbfbeSPeter Collingbourne if (S.is<AsmSymbol *>()) 153*863cbfbeSPeter Collingbourne return S.get<AsmSymbol *>()->second; 154*863cbfbeSPeter Collingbourne 155*863cbfbeSPeter Collingbourne auto *GV = S.get<GlobalValue *>(); 156*863cbfbeSPeter Collingbourne 157*863cbfbeSPeter Collingbourne uint32_t Res = BasicSymbolRef::SF_None; 158*863cbfbeSPeter Collingbourne if (GV->isDeclarationForLinker()) 159*863cbfbeSPeter Collingbourne Res |= BasicSymbolRef::SF_Undefined; 160*863cbfbeSPeter Collingbourne else if (GV->hasHiddenVisibility() && !GV->hasLocalLinkage()) 161*863cbfbeSPeter Collingbourne Res |= BasicSymbolRef::SF_Hidden; 162*863cbfbeSPeter Collingbourne if (const GlobalVariable *GVar = dyn_cast<GlobalVariable>(GV)) { 163*863cbfbeSPeter Collingbourne if (GVar->isConstant()) 164*863cbfbeSPeter Collingbourne Res |= BasicSymbolRef::SF_Const; 165*863cbfbeSPeter Collingbourne } 166*863cbfbeSPeter Collingbourne if (GV->hasPrivateLinkage()) 167*863cbfbeSPeter Collingbourne Res |= BasicSymbolRef::SF_FormatSpecific; 168*863cbfbeSPeter Collingbourne if (!GV->hasLocalLinkage()) 169*863cbfbeSPeter Collingbourne Res |= BasicSymbolRef::SF_Global; 170*863cbfbeSPeter Collingbourne if (GV->hasCommonLinkage()) 171*863cbfbeSPeter Collingbourne Res |= BasicSymbolRef::SF_Common; 172*863cbfbeSPeter Collingbourne if (GV->hasLinkOnceLinkage() || GV->hasWeakLinkage() || 173*863cbfbeSPeter Collingbourne GV->hasExternalWeakLinkage()) 174*863cbfbeSPeter Collingbourne Res |= BasicSymbolRef::SF_Weak; 175*863cbfbeSPeter Collingbourne 176*863cbfbeSPeter Collingbourne if (GV->getName().startswith("llvm.")) 177*863cbfbeSPeter Collingbourne Res |= BasicSymbolRef::SF_FormatSpecific; 178*863cbfbeSPeter Collingbourne else if (auto *Var = dyn_cast<GlobalVariable>(GV)) { 179*863cbfbeSPeter Collingbourne if (Var->getSection() == "llvm.metadata") 180*863cbfbeSPeter Collingbourne Res |= BasicSymbolRef::SF_FormatSpecific; 181*863cbfbeSPeter Collingbourne } 182*863cbfbeSPeter Collingbourne 183*863cbfbeSPeter Collingbourne return Res; 184*863cbfbeSPeter Collingbourne } 185