1*1df42facSEugene Zelenko //===- ModuleSymbolTable.cpp - symbol table for in-memory IR --------------===// 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 "RecordStreamer.h" 17*1df42facSEugene Zelenko #include "llvm/ADT/SmallString.h" 18863cbfbeSPeter Collingbourne #include "llvm/ADT/STLExtras.h" 19*1df42facSEugene Zelenko #include "llvm/ADT/StringMap.h" 20*1df42facSEugene Zelenko #include "llvm/ADT/StringRef.h" 21*1df42facSEugene Zelenko #include "llvm/ADT/Triple.h" 22*1df42facSEugene Zelenko #include "llvm/IR/Function.h" 23*1df42facSEugene Zelenko #include "llvm/IR/GlobalAlias.h" 24*1df42facSEugene Zelenko #include "llvm/IR/GlobalValue.h" 25*1df42facSEugene Zelenko #include "llvm/IR/GlobalVariable.h" 26863cbfbeSPeter Collingbourne #include "llvm/IR/Mangler.h" 27863cbfbeSPeter Collingbourne #include "llvm/IR/Module.h" 28863cbfbeSPeter Collingbourne #include "llvm/MC/MCAsmInfo.h" 29863cbfbeSPeter Collingbourne #include "llvm/MC/MCContext.h" 30*1df42facSEugene Zelenko #include "llvm/MC/MCDirectives.h" 31863cbfbeSPeter Collingbourne #include "llvm/MC/MCInstrInfo.h" 32863cbfbeSPeter Collingbourne #include "llvm/MC/MCObjectFileInfo.h" 33863cbfbeSPeter Collingbourne #include "llvm/MC/MCParser/MCAsmParser.h" 34863cbfbeSPeter Collingbourne #include "llvm/MC/MCParser/MCTargetAsmParser.h" 35863cbfbeSPeter Collingbourne #include "llvm/MC/MCRegisterInfo.h" 36863cbfbeSPeter Collingbourne #include "llvm/MC/MCSubtargetInfo.h" 37*1df42facSEugene Zelenko #include "llvm/MC/MCSymbol.h" 38*1df42facSEugene Zelenko #include "llvm/MC/MCTargetOptions.h" 39*1df42facSEugene Zelenko #include "llvm/Object/ModuleSymbolTable.h" 40*1df42facSEugene Zelenko #include "llvm/Object/SymbolicFile.h" 41*1df42facSEugene Zelenko #include "llvm/Support/Casting.h" 42*1df42facSEugene Zelenko #include "llvm/Support/CodeGen.h" 43*1df42facSEugene Zelenko #include "llvm/Support/ErrorHandling.h" 44863cbfbeSPeter Collingbourne #include "llvm/Support/MemoryBuffer.h" 45*1df42facSEugene Zelenko #include "llvm/Support/raw_ostream.h" 46*1df42facSEugene Zelenko #include "llvm/Support/SMLoc.h" 47863cbfbeSPeter Collingbourne #include "llvm/Support/SourceMgr.h" 48863cbfbeSPeter Collingbourne #include "llvm/Support/TargetRegistry.h" 49*1df42facSEugene Zelenko #include <algorithm> 50*1df42facSEugene Zelenko #include <cassert> 51*1df42facSEugene Zelenko #include <cstdint> 52*1df42facSEugene Zelenko #include <memory> 53*1df42facSEugene Zelenko #include <string> 54*1df42facSEugene Zelenko 55863cbfbeSPeter Collingbourne using namespace llvm; 56863cbfbeSPeter Collingbourne using namespace object; 57863cbfbeSPeter Collingbourne 58863cbfbeSPeter Collingbourne void ModuleSymbolTable::addModule(Module *M) { 59863cbfbeSPeter Collingbourne if (FirstMod) 60863cbfbeSPeter Collingbourne assert(FirstMod->getTargetTriple() == M->getTargetTriple()); 61863cbfbeSPeter Collingbourne else 62863cbfbeSPeter Collingbourne FirstMod = M; 63863cbfbeSPeter Collingbourne 64b26bc7fdSRafael Espindola for (GlobalValue &GV : M->global_values()) 65863cbfbeSPeter Collingbourne SymTab.push_back(&GV); 66863cbfbeSPeter Collingbourne 67d8204472STeresa Johnson CollectAsmSymbols(*M, [this](StringRef Name, BasicSymbolRef::Flags Flags) { 68d8204472STeresa Johnson SymTab.push_back(new (AsmSymbols.Allocate()) AsmSymbol(Name, Flags)); 69863cbfbeSPeter Collingbourne }); 70863cbfbeSPeter Collingbourne } 71863cbfbeSPeter Collingbourne 72d8204472STeresa Johnson // Ensure ELF .symver aliases get the same binding as the defined symbol 73d8204472STeresa Johnson // they alias with. 74d8204472STeresa Johnson static void handleSymverAliases(const Module &M, RecordStreamer &Streamer) { 75d8204472STeresa Johnson if (Streamer.symverAliases().empty()) 76d8204472STeresa Johnson return; 77d8204472STeresa Johnson 78d8204472STeresa Johnson // The name in the assembler will be mangled, but the name in the IR 79d8204472STeresa Johnson // might not, so we first compute a mapping from mangled name to GV. 80d8204472STeresa Johnson Mangler Mang; 81d8204472STeresa Johnson SmallString<64> MangledName; 82d8204472STeresa Johnson StringMap<const GlobalValue *> MangledNameMap; 83d8204472STeresa Johnson auto GetMangledName = [&](const GlobalValue &GV) { 84d8204472STeresa Johnson if (!GV.hasName()) 85d8204472STeresa Johnson return; 86d8204472STeresa Johnson 87d8204472STeresa Johnson MangledName.clear(); 88d8204472STeresa Johnson MangledName.reserve(GV.getName().size() + 1); 89d8204472STeresa Johnson Mang.getNameWithPrefix(MangledName, &GV, /*CannotUsePrivateLabel=*/false); 90d8204472STeresa Johnson MangledNameMap[MangledName] = &GV; 91d8204472STeresa Johnson }; 92d8204472STeresa Johnson for (const Function &F : M) 93d8204472STeresa Johnson GetMangledName(F); 94d8204472STeresa Johnson for (const GlobalVariable &GV : M.globals()) 95d8204472STeresa Johnson GetMangledName(GV); 96d8204472STeresa Johnson for (const GlobalAlias &GA : M.aliases()) 97d8204472STeresa Johnson GetMangledName(GA); 98d8204472STeresa Johnson 99d8204472STeresa Johnson // Walk all the recorded .symver aliases, and set up the binding 100d8204472STeresa Johnson // for each alias. 101d8204472STeresa Johnson for (auto &Symver : Streamer.symverAliases()) { 102d8204472STeresa Johnson const MCSymbol *Aliasee = Symver.first; 103d8204472STeresa Johnson MCSymbolAttr Attr = MCSA_Invalid; 104d8204472STeresa Johnson 105d8204472STeresa Johnson // First check if the aliasee binding was recorded in the asm. 106d8204472STeresa Johnson RecordStreamer::State state = Streamer.getSymbolState(Aliasee); 107d8204472STeresa Johnson switch (state) { 108d8204472STeresa Johnson case RecordStreamer::Global: 109d8204472STeresa Johnson case RecordStreamer::DefinedGlobal: 110d8204472STeresa Johnson Attr = MCSA_Global; 111d8204472STeresa Johnson break; 112d8204472STeresa Johnson case RecordStreamer::UndefinedWeak: 113d8204472STeresa Johnson case RecordStreamer::DefinedWeak: 114d8204472STeresa Johnson Attr = MCSA_Weak; 115d8204472STeresa Johnson break; 116d8204472STeresa Johnson default: 117d8204472STeresa Johnson break; 118d8204472STeresa Johnson } 119d8204472STeresa Johnson 120d8204472STeresa Johnson // If we don't have a symbol attribute from assembly, then check if 121d8204472STeresa Johnson // the aliasee was defined in the IR. 122d8204472STeresa Johnson if (Attr == MCSA_Invalid) { 123d8204472STeresa Johnson const auto *GV = M.getNamedValue(Aliasee->getName()); 124d8204472STeresa Johnson if (!GV) { 125d8204472STeresa Johnson auto MI = MangledNameMap.find(Aliasee->getName()); 126d8204472STeresa Johnson if (MI != MangledNameMap.end()) 127d8204472STeresa Johnson GV = MI->second; 128d8204472STeresa Johnson else 129d8204472STeresa Johnson continue; 130d8204472STeresa Johnson } 131d8204472STeresa Johnson if (GV->hasExternalLinkage()) 132d8204472STeresa Johnson Attr = MCSA_Global; 133d8204472STeresa Johnson else if (GV->hasLocalLinkage()) 134d8204472STeresa Johnson Attr = MCSA_Local; 135d8204472STeresa Johnson else if (GV->isWeakForLinker()) 136d8204472STeresa Johnson Attr = MCSA_Weak; 137d8204472STeresa Johnson } 138d8204472STeresa Johnson if (Attr == MCSA_Invalid) 139d8204472STeresa Johnson continue; 140d8204472STeresa Johnson 141d8204472STeresa Johnson // Set the detected binding on each alias with this aliasee. 142d8204472STeresa Johnson for (auto &Alias : Symver.second) 143d8204472STeresa Johnson Streamer.EmitSymbolAttribute(Alias, Attr); 144d8204472STeresa Johnson } 145d8204472STeresa Johnson } 146d8204472STeresa Johnson 147863cbfbeSPeter Collingbourne void ModuleSymbolTable::CollectAsmSymbols( 148d8204472STeresa Johnson const Module &M, 149863cbfbeSPeter Collingbourne function_ref<void(StringRef, BasicSymbolRef::Flags)> AsmSymbol) { 150d8204472STeresa Johnson StringRef InlineAsm = M.getModuleInlineAsm(); 151863cbfbeSPeter Collingbourne if (InlineAsm.empty()) 152863cbfbeSPeter Collingbourne return; 153863cbfbeSPeter Collingbourne 154863cbfbeSPeter Collingbourne std::string Err; 155d8204472STeresa Johnson const Triple TT(M.getTargetTriple()); 156863cbfbeSPeter Collingbourne const Target *T = TargetRegistry::lookupTarget(TT.str(), Err); 157863cbfbeSPeter Collingbourne assert(T && T->hasMCAsmParser()); 158863cbfbeSPeter Collingbourne 159863cbfbeSPeter Collingbourne std::unique_ptr<MCRegisterInfo> MRI(T->createMCRegInfo(TT.str())); 160863cbfbeSPeter Collingbourne if (!MRI) 161863cbfbeSPeter Collingbourne return; 162863cbfbeSPeter Collingbourne 163863cbfbeSPeter Collingbourne std::unique_ptr<MCAsmInfo> MAI(T->createMCAsmInfo(*MRI, TT.str())); 164863cbfbeSPeter Collingbourne if (!MAI) 165863cbfbeSPeter Collingbourne return; 166863cbfbeSPeter Collingbourne 167863cbfbeSPeter Collingbourne std::unique_ptr<MCSubtargetInfo> STI( 168863cbfbeSPeter Collingbourne T->createMCSubtargetInfo(TT.str(), "", "")); 169863cbfbeSPeter Collingbourne if (!STI) 170863cbfbeSPeter Collingbourne return; 171863cbfbeSPeter Collingbourne 172863cbfbeSPeter Collingbourne std::unique_ptr<MCInstrInfo> MCII(T->createMCInstrInfo()); 173863cbfbeSPeter Collingbourne if (!MCII) 174863cbfbeSPeter Collingbourne return; 175863cbfbeSPeter Collingbourne 176863cbfbeSPeter Collingbourne MCObjectFileInfo MOFI; 177863cbfbeSPeter Collingbourne MCContext MCCtx(MAI.get(), MRI.get(), &MOFI); 178863cbfbeSPeter Collingbourne MOFI.InitMCObjectFileInfo(TT, /*PIC*/ false, CodeModel::Default, MCCtx); 179863cbfbeSPeter Collingbourne RecordStreamer Streamer(MCCtx); 180863cbfbeSPeter Collingbourne T->createNullTargetStreamer(Streamer); 181863cbfbeSPeter Collingbourne 182863cbfbeSPeter Collingbourne std::unique_ptr<MemoryBuffer> Buffer(MemoryBuffer::getMemBuffer(InlineAsm)); 183863cbfbeSPeter Collingbourne SourceMgr SrcMgr; 184863cbfbeSPeter Collingbourne SrcMgr.AddNewSourceBuffer(std::move(Buffer), SMLoc()); 185863cbfbeSPeter Collingbourne std::unique_ptr<MCAsmParser> Parser( 186863cbfbeSPeter Collingbourne createMCAsmParser(SrcMgr, MCCtx, Streamer, *MAI)); 187863cbfbeSPeter Collingbourne 188863cbfbeSPeter Collingbourne MCTargetOptions MCOptions; 189863cbfbeSPeter Collingbourne std::unique_ptr<MCTargetAsmParser> TAP( 190863cbfbeSPeter Collingbourne T->createMCAsmParser(*STI, *Parser, *MCII, MCOptions)); 191863cbfbeSPeter Collingbourne if (!TAP) 192863cbfbeSPeter Collingbourne return; 193863cbfbeSPeter Collingbourne 194863cbfbeSPeter Collingbourne Parser->setTargetParser(*TAP); 195863cbfbeSPeter Collingbourne if (Parser->Run(false)) 196863cbfbeSPeter Collingbourne return; 197863cbfbeSPeter Collingbourne 198d8204472STeresa Johnson handleSymverAliases(M, Streamer); 199d8204472STeresa Johnson 200863cbfbeSPeter Collingbourne for (auto &KV : Streamer) { 201863cbfbeSPeter Collingbourne StringRef Key = KV.first(); 202863cbfbeSPeter Collingbourne RecordStreamer::State Value = KV.second; 203e2f1b4a6SPeter Collingbourne // FIXME: For now we just assume that all asm symbols are executable. 204e2f1b4a6SPeter Collingbourne uint32_t Res = BasicSymbolRef::SF_Executable; 205863cbfbeSPeter Collingbourne switch (Value) { 206863cbfbeSPeter Collingbourne case RecordStreamer::NeverSeen: 207863cbfbeSPeter Collingbourne llvm_unreachable("NeverSeen should have been replaced earlier"); 208863cbfbeSPeter Collingbourne case RecordStreamer::DefinedGlobal: 209863cbfbeSPeter Collingbourne Res |= BasicSymbolRef::SF_Global; 210863cbfbeSPeter Collingbourne break; 211863cbfbeSPeter Collingbourne case RecordStreamer::Defined: 212863cbfbeSPeter Collingbourne break; 213863cbfbeSPeter Collingbourne case RecordStreamer::Global: 214863cbfbeSPeter Collingbourne case RecordStreamer::Used: 215863cbfbeSPeter Collingbourne Res |= BasicSymbolRef::SF_Undefined; 216863cbfbeSPeter Collingbourne Res |= BasicSymbolRef::SF_Global; 217863cbfbeSPeter Collingbourne break; 218863cbfbeSPeter Collingbourne case RecordStreamer::DefinedWeak: 219863cbfbeSPeter Collingbourne Res |= BasicSymbolRef::SF_Weak; 220863cbfbeSPeter Collingbourne Res |= BasicSymbolRef::SF_Global; 221863cbfbeSPeter Collingbourne break; 222863cbfbeSPeter Collingbourne case RecordStreamer::UndefinedWeak: 223863cbfbeSPeter Collingbourne Res |= BasicSymbolRef::SF_Weak; 224863cbfbeSPeter Collingbourne Res |= BasicSymbolRef::SF_Undefined; 225863cbfbeSPeter Collingbourne } 226863cbfbeSPeter Collingbourne AsmSymbol(Key, BasicSymbolRef::Flags(Res)); 227863cbfbeSPeter Collingbourne } 228863cbfbeSPeter Collingbourne } 229863cbfbeSPeter Collingbourne 230863cbfbeSPeter Collingbourne void ModuleSymbolTable::printSymbolName(raw_ostream &OS, Symbol S) const { 231863cbfbeSPeter Collingbourne if (S.is<AsmSymbol *>()) { 232863cbfbeSPeter Collingbourne OS << S.get<AsmSymbol *>()->first; 233863cbfbeSPeter Collingbourne return; 234863cbfbeSPeter Collingbourne } 235863cbfbeSPeter Collingbourne 236863cbfbeSPeter Collingbourne auto *GV = S.get<GlobalValue *>(); 237863cbfbeSPeter Collingbourne if (GV->hasDLLImportStorageClass()) 238863cbfbeSPeter Collingbourne OS << "__imp_"; 239863cbfbeSPeter Collingbourne 240863cbfbeSPeter Collingbourne Mang.getNameWithPrefix(OS, GV, false); 241863cbfbeSPeter Collingbourne } 242863cbfbeSPeter Collingbourne 243863cbfbeSPeter Collingbourne uint32_t ModuleSymbolTable::getSymbolFlags(Symbol S) const { 244863cbfbeSPeter Collingbourne if (S.is<AsmSymbol *>()) 245863cbfbeSPeter Collingbourne return S.get<AsmSymbol *>()->second; 246863cbfbeSPeter Collingbourne 247863cbfbeSPeter Collingbourne auto *GV = S.get<GlobalValue *>(); 248863cbfbeSPeter Collingbourne 249863cbfbeSPeter Collingbourne uint32_t Res = BasicSymbolRef::SF_None; 250863cbfbeSPeter Collingbourne if (GV->isDeclarationForLinker()) 251863cbfbeSPeter Collingbourne Res |= BasicSymbolRef::SF_Undefined; 252863cbfbeSPeter Collingbourne else if (GV->hasHiddenVisibility() && !GV->hasLocalLinkage()) 253863cbfbeSPeter Collingbourne Res |= BasicSymbolRef::SF_Hidden; 254863cbfbeSPeter Collingbourne if (const GlobalVariable *GVar = dyn_cast<GlobalVariable>(GV)) { 255863cbfbeSPeter Collingbourne if (GVar->isConstant()) 256863cbfbeSPeter Collingbourne Res |= BasicSymbolRef::SF_Const; 257863cbfbeSPeter Collingbourne } 258e2f1b4a6SPeter Collingbourne if (dyn_cast_or_null<Function>(GV->getBaseObject())) 259e2f1b4a6SPeter Collingbourne Res |= BasicSymbolRef::SF_Executable; 260d64ecf26SPeter Collingbourne if (isa<GlobalAlias>(GV)) 261d64ecf26SPeter Collingbourne Res |= BasicSymbolRef::SF_Indirect; 262863cbfbeSPeter Collingbourne if (GV->hasPrivateLinkage()) 263863cbfbeSPeter Collingbourne Res |= BasicSymbolRef::SF_FormatSpecific; 264863cbfbeSPeter Collingbourne if (!GV->hasLocalLinkage()) 265863cbfbeSPeter Collingbourne Res |= BasicSymbolRef::SF_Global; 266863cbfbeSPeter Collingbourne if (GV->hasCommonLinkage()) 267863cbfbeSPeter Collingbourne Res |= BasicSymbolRef::SF_Common; 268863cbfbeSPeter Collingbourne if (GV->hasLinkOnceLinkage() || GV->hasWeakLinkage() || 269863cbfbeSPeter Collingbourne GV->hasExternalWeakLinkage()) 270863cbfbeSPeter Collingbourne Res |= BasicSymbolRef::SF_Weak; 271863cbfbeSPeter Collingbourne 272863cbfbeSPeter Collingbourne if (GV->getName().startswith("llvm.")) 273863cbfbeSPeter Collingbourne Res |= BasicSymbolRef::SF_FormatSpecific; 274863cbfbeSPeter Collingbourne else if (auto *Var = dyn_cast<GlobalVariable>(GV)) { 275863cbfbeSPeter Collingbourne if (Var->getSection() == "llvm.metadata") 276863cbfbeSPeter Collingbourne Res |= BasicSymbolRef::SF_FormatSpecific; 277863cbfbeSPeter Collingbourne } 278863cbfbeSPeter Collingbourne 279863cbfbeSPeter Collingbourne return Res; 280863cbfbeSPeter Collingbourne } 281