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 53*d8204472STeresa Johnson CollectAsmSymbols(*M, [this](StringRef Name, BasicSymbolRef::Flags Flags) { 54*d8204472STeresa Johnson SymTab.push_back(new (AsmSymbols.Allocate()) AsmSymbol(Name, Flags)); 55863cbfbeSPeter Collingbourne }); 56863cbfbeSPeter Collingbourne } 57863cbfbeSPeter Collingbourne 58*d8204472STeresa Johnson // Ensure ELF .symver aliases get the same binding as the defined symbol 59*d8204472STeresa Johnson // they alias with. 60*d8204472STeresa Johnson static void handleSymverAliases(const Module &M, RecordStreamer &Streamer) { 61*d8204472STeresa Johnson if (Streamer.symverAliases().empty()) 62*d8204472STeresa Johnson return; 63*d8204472STeresa Johnson 64*d8204472STeresa Johnson // The name in the assembler will be mangled, but the name in the IR 65*d8204472STeresa Johnson // might not, so we first compute a mapping from mangled name to GV. 66*d8204472STeresa Johnson Mangler Mang; 67*d8204472STeresa Johnson SmallString<64> MangledName; 68*d8204472STeresa Johnson StringMap<const GlobalValue *> MangledNameMap; 69*d8204472STeresa Johnson auto GetMangledName = [&](const GlobalValue &GV) { 70*d8204472STeresa Johnson if (!GV.hasName()) 71*d8204472STeresa Johnson return; 72*d8204472STeresa Johnson 73*d8204472STeresa Johnson MangledName.clear(); 74*d8204472STeresa Johnson MangledName.reserve(GV.getName().size() + 1); 75*d8204472STeresa Johnson Mang.getNameWithPrefix(MangledName, &GV, /*CannotUsePrivateLabel=*/false); 76*d8204472STeresa Johnson MangledNameMap[MangledName] = &GV; 77*d8204472STeresa Johnson }; 78*d8204472STeresa Johnson for (const Function &F : M) 79*d8204472STeresa Johnson GetMangledName(F); 80*d8204472STeresa Johnson for (const GlobalVariable &GV : M.globals()) 81*d8204472STeresa Johnson GetMangledName(GV); 82*d8204472STeresa Johnson for (const GlobalAlias &GA : M.aliases()) 83*d8204472STeresa Johnson GetMangledName(GA); 84*d8204472STeresa Johnson 85*d8204472STeresa Johnson // Walk all the recorded .symver aliases, and set up the binding 86*d8204472STeresa Johnson // for each alias. 87*d8204472STeresa Johnson for (auto &Symver : Streamer.symverAliases()) { 88*d8204472STeresa Johnson const MCSymbol *Aliasee = Symver.first; 89*d8204472STeresa Johnson MCSymbolAttr Attr = MCSA_Invalid; 90*d8204472STeresa Johnson 91*d8204472STeresa Johnson // First check if the aliasee binding was recorded in the asm. 92*d8204472STeresa Johnson RecordStreamer::State state = Streamer.getSymbolState(Aliasee); 93*d8204472STeresa Johnson switch (state) { 94*d8204472STeresa Johnson case RecordStreamer::Global: 95*d8204472STeresa Johnson case RecordStreamer::DefinedGlobal: 96*d8204472STeresa Johnson Attr = MCSA_Global; 97*d8204472STeresa Johnson break; 98*d8204472STeresa Johnson case RecordStreamer::UndefinedWeak: 99*d8204472STeresa Johnson case RecordStreamer::DefinedWeak: 100*d8204472STeresa Johnson Attr = MCSA_Weak; 101*d8204472STeresa Johnson break; 102*d8204472STeresa Johnson default: 103*d8204472STeresa Johnson break; 104*d8204472STeresa Johnson } 105*d8204472STeresa Johnson 106*d8204472STeresa Johnson // If we don't have a symbol attribute from assembly, then check if 107*d8204472STeresa Johnson // the aliasee was defined in the IR. 108*d8204472STeresa Johnson if (Attr == MCSA_Invalid) { 109*d8204472STeresa Johnson const auto *GV = M.getNamedValue(Aliasee->getName()); 110*d8204472STeresa Johnson if (!GV) { 111*d8204472STeresa Johnson auto MI = MangledNameMap.find(Aliasee->getName()); 112*d8204472STeresa Johnson if (MI != MangledNameMap.end()) 113*d8204472STeresa Johnson GV = MI->second; 114*d8204472STeresa Johnson else 115*d8204472STeresa Johnson continue; 116*d8204472STeresa Johnson } 117*d8204472STeresa Johnson if (GV->hasExternalLinkage()) 118*d8204472STeresa Johnson Attr = MCSA_Global; 119*d8204472STeresa Johnson else if (GV->hasLocalLinkage()) 120*d8204472STeresa Johnson Attr = MCSA_Local; 121*d8204472STeresa Johnson else if (GV->isWeakForLinker()) 122*d8204472STeresa Johnson Attr = MCSA_Weak; 123*d8204472STeresa Johnson } 124*d8204472STeresa Johnson if (Attr == MCSA_Invalid) 125*d8204472STeresa Johnson continue; 126*d8204472STeresa Johnson 127*d8204472STeresa Johnson // Set the detected binding on each alias with this aliasee. 128*d8204472STeresa Johnson for (auto &Alias : Symver.second) 129*d8204472STeresa Johnson Streamer.EmitSymbolAttribute(Alias, Attr); 130*d8204472STeresa Johnson } 131*d8204472STeresa Johnson } 132*d8204472STeresa Johnson 133863cbfbeSPeter Collingbourne void ModuleSymbolTable::CollectAsmSymbols( 134*d8204472STeresa Johnson const Module &M, 135863cbfbeSPeter Collingbourne function_ref<void(StringRef, BasicSymbolRef::Flags)> AsmSymbol) { 136*d8204472STeresa Johnson StringRef InlineAsm = M.getModuleInlineAsm(); 137863cbfbeSPeter Collingbourne if (InlineAsm.empty()) 138863cbfbeSPeter Collingbourne return; 139863cbfbeSPeter Collingbourne 140863cbfbeSPeter Collingbourne std::string Err; 141*d8204472STeresa Johnson const Triple TT(M.getTargetTriple()); 142863cbfbeSPeter Collingbourne const Target *T = TargetRegistry::lookupTarget(TT.str(), Err); 143863cbfbeSPeter Collingbourne assert(T && T->hasMCAsmParser()); 144863cbfbeSPeter Collingbourne 145863cbfbeSPeter Collingbourne std::unique_ptr<MCRegisterInfo> MRI(T->createMCRegInfo(TT.str())); 146863cbfbeSPeter Collingbourne if (!MRI) 147863cbfbeSPeter Collingbourne return; 148863cbfbeSPeter Collingbourne 149863cbfbeSPeter Collingbourne std::unique_ptr<MCAsmInfo> MAI(T->createMCAsmInfo(*MRI, TT.str())); 150863cbfbeSPeter Collingbourne if (!MAI) 151863cbfbeSPeter Collingbourne return; 152863cbfbeSPeter Collingbourne 153863cbfbeSPeter Collingbourne std::unique_ptr<MCSubtargetInfo> STI( 154863cbfbeSPeter Collingbourne T->createMCSubtargetInfo(TT.str(), "", "")); 155863cbfbeSPeter Collingbourne if (!STI) 156863cbfbeSPeter Collingbourne return; 157863cbfbeSPeter Collingbourne 158863cbfbeSPeter Collingbourne std::unique_ptr<MCInstrInfo> MCII(T->createMCInstrInfo()); 159863cbfbeSPeter Collingbourne if (!MCII) 160863cbfbeSPeter Collingbourne return; 161863cbfbeSPeter Collingbourne 162863cbfbeSPeter Collingbourne MCObjectFileInfo MOFI; 163863cbfbeSPeter Collingbourne MCContext MCCtx(MAI.get(), MRI.get(), &MOFI); 164863cbfbeSPeter Collingbourne MOFI.InitMCObjectFileInfo(TT, /*PIC*/ false, CodeModel::Default, MCCtx); 165863cbfbeSPeter Collingbourne RecordStreamer Streamer(MCCtx); 166863cbfbeSPeter Collingbourne T->createNullTargetStreamer(Streamer); 167863cbfbeSPeter Collingbourne 168863cbfbeSPeter Collingbourne std::unique_ptr<MemoryBuffer> Buffer(MemoryBuffer::getMemBuffer(InlineAsm)); 169863cbfbeSPeter Collingbourne SourceMgr SrcMgr; 170863cbfbeSPeter Collingbourne SrcMgr.AddNewSourceBuffer(std::move(Buffer), SMLoc()); 171863cbfbeSPeter Collingbourne std::unique_ptr<MCAsmParser> Parser( 172863cbfbeSPeter Collingbourne createMCAsmParser(SrcMgr, MCCtx, Streamer, *MAI)); 173863cbfbeSPeter Collingbourne 174863cbfbeSPeter Collingbourne MCTargetOptions MCOptions; 175863cbfbeSPeter Collingbourne std::unique_ptr<MCTargetAsmParser> TAP( 176863cbfbeSPeter Collingbourne T->createMCAsmParser(*STI, *Parser, *MCII, MCOptions)); 177863cbfbeSPeter Collingbourne if (!TAP) 178863cbfbeSPeter Collingbourne return; 179863cbfbeSPeter Collingbourne 180863cbfbeSPeter Collingbourne Parser->setTargetParser(*TAP); 181863cbfbeSPeter Collingbourne if (Parser->Run(false)) 182863cbfbeSPeter Collingbourne return; 183863cbfbeSPeter Collingbourne 184*d8204472STeresa Johnson handleSymverAliases(M, Streamer); 185*d8204472STeresa Johnson 186863cbfbeSPeter Collingbourne for (auto &KV : Streamer) { 187863cbfbeSPeter Collingbourne StringRef Key = KV.first(); 188863cbfbeSPeter Collingbourne RecordStreamer::State Value = KV.second; 189e2f1b4a6SPeter Collingbourne // FIXME: For now we just assume that all asm symbols are executable. 190e2f1b4a6SPeter Collingbourne uint32_t Res = BasicSymbolRef::SF_Executable; 191863cbfbeSPeter Collingbourne switch (Value) { 192863cbfbeSPeter Collingbourne case RecordStreamer::NeverSeen: 193863cbfbeSPeter Collingbourne llvm_unreachable("NeverSeen should have been replaced earlier"); 194863cbfbeSPeter Collingbourne case RecordStreamer::DefinedGlobal: 195863cbfbeSPeter Collingbourne Res |= BasicSymbolRef::SF_Global; 196863cbfbeSPeter Collingbourne break; 197863cbfbeSPeter Collingbourne case RecordStreamer::Defined: 198863cbfbeSPeter Collingbourne break; 199863cbfbeSPeter Collingbourne case RecordStreamer::Global: 200863cbfbeSPeter Collingbourne case RecordStreamer::Used: 201863cbfbeSPeter Collingbourne Res |= BasicSymbolRef::SF_Undefined; 202863cbfbeSPeter Collingbourne Res |= BasicSymbolRef::SF_Global; 203863cbfbeSPeter Collingbourne break; 204863cbfbeSPeter Collingbourne case RecordStreamer::DefinedWeak: 205863cbfbeSPeter Collingbourne Res |= BasicSymbolRef::SF_Weak; 206863cbfbeSPeter Collingbourne Res |= BasicSymbolRef::SF_Global; 207863cbfbeSPeter Collingbourne break; 208863cbfbeSPeter Collingbourne case RecordStreamer::UndefinedWeak: 209863cbfbeSPeter Collingbourne Res |= BasicSymbolRef::SF_Weak; 210863cbfbeSPeter Collingbourne Res |= BasicSymbolRef::SF_Undefined; 211863cbfbeSPeter Collingbourne } 212863cbfbeSPeter Collingbourne AsmSymbol(Key, BasicSymbolRef::Flags(Res)); 213863cbfbeSPeter Collingbourne } 214863cbfbeSPeter Collingbourne } 215863cbfbeSPeter Collingbourne 216863cbfbeSPeter Collingbourne void ModuleSymbolTable::printSymbolName(raw_ostream &OS, Symbol S) const { 217863cbfbeSPeter Collingbourne if (S.is<AsmSymbol *>()) { 218863cbfbeSPeter Collingbourne OS << S.get<AsmSymbol *>()->first; 219863cbfbeSPeter Collingbourne return; 220863cbfbeSPeter Collingbourne } 221863cbfbeSPeter Collingbourne 222863cbfbeSPeter Collingbourne auto *GV = S.get<GlobalValue *>(); 223863cbfbeSPeter Collingbourne if (GV->hasDLLImportStorageClass()) 224863cbfbeSPeter Collingbourne OS << "__imp_"; 225863cbfbeSPeter Collingbourne 226863cbfbeSPeter Collingbourne Mang.getNameWithPrefix(OS, GV, false); 227863cbfbeSPeter Collingbourne } 228863cbfbeSPeter Collingbourne 229863cbfbeSPeter Collingbourne uint32_t ModuleSymbolTable::getSymbolFlags(Symbol S) const { 230863cbfbeSPeter Collingbourne if (S.is<AsmSymbol *>()) 231863cbfbeSPeter Collingbourne return S.get<AsmSymbol *>()->second; 232863cbfbeSPeter Collingbourne 233863cbfbeSPeter Collingbourne auto *GV = S.get<GlobalValue *>(); 234863cbfbeSPeter Collingbourne 235863cbfbeSPeter Collingbourne uint32_t Res = BasicSymbolRef::SF_None; 236863cbfbeSPeter Collingbourne if (GV->isDeclarationForLinker()) 237863cbfbeSPeter Collingbourne Res |= BasicSymbolRef::SF_Undefined; 238863cbfbeSPeter Collingbourne else if (GV->hasHiddenVisibility() && !GV->hasLocalLinkage()) 239863cbfbeSPeter Collingbourne Res |= BasicSymbolRef::SF_Hidden; 240863cbfbeSPeter Collingbourne if (const GlobalVariable *GVar = dyn_cast<GlobalVariable>(GV)) { 241863cbfbeSPeter Collingbourne if (GVar->isConstant()) 242863cbfbeSPeter Collingbourne Res |= BasicSymbolRef::SF_Const; 243863cbfbeSPeter Collingbourne } 244e2f1b4a6SPeter Collingbourne if (dyn_cast_or_null<Function>(GV->getBaseObject())) 245e2f1b4a6SPeter Collingbourne Res |= BasicSymbolRef::SF_Executable; 246d64ecf26SPeter Collingbourne if (isa<GlobalAlias>(GV)) 247d64ecf26SPeter Collingbourne Res |= BasicSymbolRef::SF_Indirect; 248863cbfbeSPeter Collingbourne if (GV->hasPrivateLinkage()) 249863cbfbeSPeter Collingbourne Res |= BasicSymbolRef::SF_FormatSpecific; 250863cbfbeSPeter Collingbourne if (!GV->hasLocalLinkage()) 251863cbfbeSPeter Collingbourne Res |= BasicSymbolRef::SF_Global; 252863cbfbeSPeter Collingbourne if (GV->hasCommonLinkage()) 253863cbfbeSPeter Collingbourne Res |= BasicSymbolRef::SF_Common; 254863cbfbeSPeter Collingbourne if (GV->hasLinkOnceLinkage() || GV->hasWeakLinkage() || 255863cbfbeSPeter Collingbourne GV->hasExternalWeakLinkage()) 256863cbfbeSPeter Collingbourne Res |= BasicSymbolRef::SF_Weak; 257863cbfbeSPeter Collingbourne 258863cbfbeSPeter Collingbourne if (GV->getName().startswith("llvm.")) 259863cbfbeSPeter Collingbourne Res |= BasicSymbolRef::SF_FormatSpecific; 260863cbfbeSPeter Collingbourne else if (auto *Var = dyn_cast<GlobalVariable>(GV)) { 261863cbfbeSPeter Collingbourne if (Var->getSection() == "llvm.metadata") 262863cbfbeSPeter Collingbourne Res |= BasicSymbolRef::SF_FormatSpecific; 263863cbfbeSPeter Collingbourne } 264863cbfbeSPeter Collingbourne 265863cbfbeSPeter Collingbourne return Res; 266863cbfbeSPeter Collingbourne } 267