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(Triple(M->getTargetTriple()), M->getModuleInlineAsm(), 54 [this](StringRef Name, BasicSymbolRef::Flags Flags) { 55 SymTab.push_back(new (AsmSymbols.Allocate()) 56 AsmSymbol(Name, Flags)); 57 }); 58 } 59 60 void ModuleSymbolTable::CollectAsmSymbols( 61 const Triple &TT, StringRef InlineAsm, 62 function_ref<void(StringRef, BasicSymbolRef::Flags)> AsmSymbol) { 63 if (InlineAsm.empty()) 64 return; 65 66 std::string Err; 67 const Target *T = TargetRegistry::lookupTarget(TT.str(), Err); 68 assert(T && T->hasMCAsmParser()); 69 70 std::unique_ptr<MCRegisterInfo> MRI(T->createMCRegInfo(TT.str())); 71 if (!MRI) 72 return; 73 74 std::unique_ptr<MCAsmInfo> MAI(T->createMCAsmInfo(*MRI, TT.str())); 75 if (!MAI) 76 return; 77 78 std::unique_ptr<MCSubtargetInfo> STI( 79 T->createMCSubtargetInfo(TT.str(), "", "")); 80 if (!STI) 81 return; 82 83 std::unique_ptr<MCInstrInfo> MCII(T->createMCInstrInfo()); 84 if (!MCII) 85 return; 86 87 MCObjectFileInfo MOFI; 88 MCContext MCCtx(MAI.get(), MRI.get(), &MOFI); 89 MOFI.InitMCObjectFileInfo(TT, /*PIC*/ false, CodeModel::Default, MCCtx); 90 RecordStreamer Streamer(MCCtx); 91 T->createNullTargetStreamer(Streamer); 92 93 std::unique_ptr<MemoryBuffer> Buffer(MemoryBuffer::getMemBuffer(InlineAsm)); 94 SourceMgr SrcMgr; 95 SrcMgr.AddNewSourceBuffer(std::move(Buffer), SMLoc()); 96 std::unique_ptr<MCAsmParser> Parser( 97 createMCAsmParser(SrcMgr, MCCtx, Streamer, *MAI)); 98 99 MCTargetOptions MCOptions; 100 std::unique_ptr<MCTargetAsmParser> TAP( 101 T->createMCAsmParser(*STI, *Parser, *MCII, MCOptions)); 102 if (!TAP) 103 return; 104 105 Parser->setTargetParser(*TAP); 106 if (Parser->Run(false)) 107 return; 108 109 for (auto &KV : Streamer) { 110 StringRef Key = KV.first(); 111 RecordStreamer::State Value = KV.second; 112 // FIXME: For now we just assume that all asm symbols are executable. 113 uint32_t Res = BasicSymbolRef::SF_Executable; 114 switch (Value) { 115 case RecordStreamer::NeverSeen: 116 llvm_unreachable("NeverSeen should have been replaced earlier"); 117 case RecordStreamer::DefinedGlobal: 118 Res |= BasicSymbolRef::SF_Global; 119 break; 120 case RecordStreamer::Defined: 121 break; 122 case RecordStreamer::Global: 123 case RecordStreamer::Used: 124 Res |= BasicSymbolRef::SF_Undefined; 125 Res |= BasicSymbolRef::SF_Global; 126 break; 127 case RecordStreamer::DefinedWeak: 128 Res |= BasicSymbolRef::SF_Weak; 129 Res |= BasicSymbolRef::SF_Global; 130 break; 131 case RecordStreamer::UndefinedWeak: 132 Res |= BasicSymbolRef::SF_Weak; 133 Res |= BasicSymbolRef::SF_Undefined; 134 } 135 AsmSymbol(Key, BasicSymbolRef::Flags(Res)); 136 } 137 } 138 139 void ModuleSymbolTable::printSymbolName(raw_ostream &OS, Symbol S) const { 140 if (S.is<AsmSymbol *>()) { 141 OS << S.get<AsmSymbol *>()->first; 142 return; 143 } 144 145 auto *GV = S.get<GlobalValue *>(); 146 if (GV->hasDLLImportStorageClass()) 147 OS << "__imp_"; 148 149 Mang.getNameWithPrefix(OS, GV, false); 150 } 151 152 uint32_t ModuleSymbolTable::getSymbolFlags(Symbol S) const { 153 if (S.is<AsmSymbol *>()) 154 return S.get<AsmSymbol *>()->second; 155 156 auto *GV = S.get<GlobalValue *>(); 157 158 uint32_t Res = BasicSymbolRef::SF_None; 159 if (GV->isDeclarationForLinker()) 160 Res |= BasicSymbolRef::SF_Undefined; 161 else if (GV->hasHiddenVisibility() && !GV->hasLocalLinkage()) 162 Res |= BasicSymbolRef::SF_Hidden; 163 if (const GlobalVariable *GVar = dyn_cast<GlobalVariable>(GV)) { 164 if (GVar->isConstant()) 165 Res |= BasicSymbolRef::SF_Const; 166 } 167 if (dyn_cast_or_null<Function>(GV->getBaseObject())) 168 Res |= BasicSymbolRef::SF_Executable; 169 if (isa<GlobalAlias>(GV)) 170 Res |= BasicSymbolRef::SF_Indirect; 171 if (GV->hasPrivateLinkage()) 172 Res |= BasicSymbolRef::SF_FormatSpecific; 173 if (!GV->hasLocalLinkage()) 174 Res |= BasicSymbolRef::SF_Global; 175 if (GV->hasCommonLinkage()) 176 Res |= BasicSymbolRef::SF_Common; 177 if (GV->hasLinkOnceLinkage() || GV->hasWeakLinkage() || 178 GV->hasExternalWeakLinkage()) 179 Res |= BasicSymbolRef::SF_Weak; 180 181 if (GV->getName().startswith("llvm.")) 182 Res |= BasicSymbolRef::SF_FormatSpecific; 183 else if (auto *Var = dyn_cast<GlobalVariable>(GV)) { 184 if (Var->getSection() == "llvm.metadata") 185 Res |= BasicSymbolRef::SF_FormatSpecific; 186 } 187 188 return Res; 189 } 190