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