1*09467b48Spatrick //===- ModuleSymbolTable.cpp - symbol table for in-memory IR --------------===// 2*09467b48Spatrick // 3*09467b48Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*09467b48Spatrick // See https://llvm.org/LICENSE.txt for license information. 5*09467b48Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*09467b48Spatrick // 7*09467b48Spatrick //===----------------------------------------------------------------------===// 8*09467b48Spatrick // 9*09467b48Spatrick // This class represents a symbol table built from in-memory IR. It provides 10*09467b48Spatrick // access to GlobalValues and should only be used if such access is required 11*09467b48Spatrick // (e.g. in the LTO implementation). 12*09467b48Spatrick // 13*09467b48Spatrick //===----------------------------------------------------------------------===// 14*09467b48Spatrick 15*09467b48Spatrick #include "llvm/Object/ModuleSymbolTable.h" 16*09467b48Spatrick #include "RecordStreamer.h" 17*09467b48Spatrick #include "llvm/ADT/STLExtras.h" 18*09467b48Spatrick #include "llvm/ADT/SmallString.h" 19*09467b48Spatrick #include "llvm/ADT/StringMap.h" 20*09467b48Spatrick #include "llvm/ADT/StringRef.h" 21*09467b48Spatrick #include "llvm/ADT/Triple.h" 22*09467b48Spatrick #include "llvm/IR/Function.h" 23*09467b48Spatrick #include "llvm/IR/GlobalAlias.h" 24*09467b48Spatrick #include "llvm/IR/GlobalValue.h" 25*09467b48Spatrick #include "llvm/IR/GlobalVariable.h" 26*09467b48Spatrick #include "llvm/IR/Module.h" 27*09467b48Spatrick #include "llvm/MC/MCAsmInfo.h" 28*09467b48Spatrick #include "llvm/MC/MCContext.h" 29*09467b48Spatrick #include "llvm/MC/MCDirectives.h" 30*09467b48Spatrick #include "llvm/MC/MCInstrInfo.h" 31*09467b48Spatrick #include "llvm/MC/MCObjectFileInfo.h" 32*09467b48Spatrick #include "llvm/MC/MCParser/MCAsmParser.h" 33*09467b48Spatrick #include "llvm/MC/MCParser/MCTargetAsmParser.h" 34*09467b48Spatrick #include "llvm/MC/MCRegisterInfo.h" 35*09467b48Spatrick #include "llvm/MC/MCSubtargetInfo.h" 36*09467b48Spatrick #include "llvm/MC/MCSymbol.h" 37*09467b48Spatrick #include "llvm/MC/MCTargetOptions.h" 38*09467b48Spatrick #include "llvm/Object/SymbolicFile.h" 39*09467b48Spatrick #include "llvm/Support/Casting.h" 40*09467b48Spatrick #include "llvm/Support/CodeGen.h" 41*09467b48Spatrick #include "llvm/Support/ErrorHandling.h" 42*09467b48Spatrick #include "llvm/Support/MemoryBuffer.h" 43*09467b48Spatrick #include "llvm/Support/SMLoc.h" 44*09467b48Spatrick #include "llvm/Support/SourceMgr.h" 45*09467b48Spatrick #include "llvm/Support/TargetRegistry.h" 46*09467b48Spatrick #include "llvm/Support/raw_ostream.h" 47*09467b48Spatrick #include <algorithm> 48*09467b48Spatrick #include <cassert> 49*09467b48Spatrick #include <cstdint> 50*09467b48Spatrick #include <memory> 51*09467b48Spatrick #include <string> 52*09467b48Spatrick 53*09467b48Spatrick using namespace llvm; 54*09467b48Spatrick using namespace object; 55*09467b48Spatrick 56*09467b48Spatrick void ModuleSymbolTable::addModule(Module *M) { 57*09467b48Spatrick if (FirstMod) 58*09467b48Spatrick assert(FirstMod->getTargetTriple() == M->getTargetTriple()); 59*09467b48Spatrick else 60*09467b48Spatrick FirstMod = M; 61*09467b48Spatrick 62*09467b48Spatrick for (GlobalValue &GV : M->global_values()) 63*09467b48Spatrick SymTab.push_back(&GV); 64*09467b48Spatrick 65*09467b48Spatrick CollectAsmSymbols(*M, [this](StringRef Name, BasicSymbolRef::Flags Flags) { 66*09467b48Spatrick SymTab.push_back(new (AsmSymbols.Allocate()) AsmSymbol(Name, Flags)); 67*09467b48Spatrick }); 68*09467b48Spatrick } 69*09467b48Spatrick 70*09467b48Spatrick static void 71*09467b48Spatrick initializeRecordStreamer(const Module &M, 72*09467b48Spatrick function_ref<void(RecordStreamer &)> Init) { 73*09467b48Spatrick StringRef InlineAsm = M.getModuleInlineAsm(); 74*09467b48Spatrick if (InlineAsm.empty()) 75*09467b48Spatrick return; 76*09467b48Spatrick 77*09467b48Spatrick std::string Err; 78*09467b48Spatrick const Triple TT(M.getTargetTriple()); 79*09467b48Spatrick const Target *T = TargetRegistry::lookupTarget(TT.str(), Err); 80*09467b48Spatrick assert(T && T->hasMCAsmParser()); 81*09467b48Spatrick 82*09467b48Spatrick std::unique_ptr<MCRegisterInfo> MRI(T->createMCRegInfo(TT.str())); 83*09467b48Spatrick if (!MRI) 84*09467b48Spatrick return; 85*09467b48Spatrick 86*09467b48Spatrick MCTargetOptions MCOptions; 87*09467b48Spatrick std::unique_ptr<MCAsmInfo> MAI(T->createMCAsmInfo(*MRI, TT.str(), MCOptions)); 88*09467b48Spatrick if (!MAI) 89*09467b48Spatrick return; 90*09467b48Spatrick 91*09467b48Spatrick std::unique_ptr<MCSubtargetInfo> STI( 92*09467b48Spatrick T->createMCSubtargetInfo(TT.str(), "", "")); 93*09467b48Spatrick if (!STI) 94*09467b48Spatrick return; 95*09467b48Spatrick 96*09467b48Spatrick std::unique_ptr<MCInstrInfo> MCII(T->createMCInstrInfo()); 97*09467b48Spatrick if (!MCII) 98*09467b48Spatrick return; 99*09467b48Spatrick 100*09467b48Spatrick MCObjectFileInfo MOFI; 101*09467b48Spatrick MCContext MCCtx(MAI.get(), MRI.get(), &MOFI); 102*09467b48Spatrick MOFI.InitMCObjectFileInfo(TT, /*PIC*/ false, MCCtx); 103*09467b48Spatrick MOFI.setSDKVersion(M.getSDKVersion()); 104*09467b48Spatrick RecordStreamer Streamer(MCCtx, M); 105*09467b48Spatrick T->createNullTargetStreamer(Streamer); 106*09467b48Spatrick 107*09467b48Spatrick std::unique_ptr<MemoryBuffer> Buffer(MemoryBuffer::getMemBuffer(InlineAsm)); 108*09467b48Spatrick SourceMgr SrcMgr; 109*09467b48Spatrick SrcMgr.AddNewSourceBuffer(std::move(Buffer), SMLoc()); 110*09467b48Spatrick std::unique_ptr<MCAsmParser> Parser( 111*09467b48Spatrick createMCAsmParser(SrcMgr, MCCtx, Streamer, *MAI)); 112*09467b48Spatrick 113*09467b48Spatrick std::unique_ptr<MCTargetAsmParser> TAP( 114*09467b48Spatrick T->createMCAsmParser(*STI, *Parser, *MCII, MCOptions)); 115*09467b48Spatrick if (!TAP) 116*09467b48Spatrick return; 117*09467b48Spatrick 118*09467b48Spatrick Parser->setTargetParser(*TAP); 119*09467b48Spatrick if (Parser->Run(false)) 120*09467b48Spatrick return; 121*09467b48Spatrick 122*09467b48Spatrick Init(Streamer); 123*09467b48Spatrick } 124*09467b48Spatrick 125*09467b48Spatrick void ModuleSymbolTable::CollectAsmSymbols( 126*09467b48Spatrick const Module &M, 127*09467b48Spatrick function_ref<void(StringRef, BasicSymbolRef::Flags)> AsmSymbol) { 128*09467b48Spatrick initializeRecordStreamer(M, [&](RecordStreamer &Streamer) { 129*09467b48Spatrick Streamer.flushSymverDirectives(); 130*09467b48Spatrick 131*09467b48Spatrick for (auto &KV : Streamer) { 132*09467b48Spatrick StringRef Key = KV.first(); 133*09467b48Spatrick RecordStreamer::State Value = KV.second; 134*09467b48Spatrick // FIXME: For now we just assume that all asm symbols are executable. 135*09467b48Spatrick uint32_t Res = BasicSymbolRef::SF_Executable; 136*09467b48Spatrick switch (Value) { 137*09467b48Spatrick case RecordStreamer::NeverSeen: 138*09467b48Spatrick llvm_unreachable("NeverSeen should have been replaced earlier"); 139*09467b48Spatrick case RecordStreamer::DefinedGlobal: 140*09467b48Spatrick Res |= BasicSymbolRef::SF_Global; 141*09467b48Spatrick break; 142*09467b48Spatrick case RecordStreamer::Defined: 143*09467b48Spatrick break; 144*09467b48Spatrick case RecordStreamer::Global: 145*09467b48Spatrick case RecordStreamer::Used: 146*09467b48Spatrick Res |= BasicSymbolRef::SF_Undefined; 147*09467b48Spatrick Res |= BasicSymbolRef::SF_Global; 148*09467b48Spatrick break; 149*09467b48Spatrick case RecordStreamer::DefinedWeak: 150*09467b48Spatrick Res |= BasicSymbolRef::SF_Weak; 151*09467b48Spatrick Res |= BasicSymbolRef::SF_Global; 152*09467b48Spatrick break; 153*09467b48Spatrick case RecordStreamer::UndefinedWeak: 154*09467b48Spatrick Res |= BasicSymbolRef::SF_Weak; 155*09467b48Spatrick Res |= BasicSymbolRef::SF_Undefined; 156*09467b48Spatrick } 157*09467b48Spatrick AsmSymbol(Key, BasicSymbolRef::Flags(Res)); 158*09467b48Spatrick } 159*09467b48Spatrick }); 160*09467b48Spatrick } 161*09467b48Spatrick 162*09467b48Spatrick void ModuleSymbolTable::CollectAsmSymvers( 163*09467b48Spatrick const Module &M, function_ref<void(StringRef, StringRef)> AsmSymver) { 164*09467b48Spatrick initializeRecordStreamer(M, [&](RecordStreamer &Streamer) { 165*09467b48Spatrick for (auto &KV : Streamer.symverAliases()) 166*09467b48Spatrick for (auto &Alias : KV.second) 167*09467b48Spatrick AsmSymver(KV.first->getName(), Alias); 168*09467b48Spatrick }); 169*09467b48Spatrick } 170*09467b48Spatrick 171*09467b48Spatrick void ModuleSymbolTable::printSymbolName(raw_ostream &OS, Symbol S) const { 172*09467b48Spatrick if (S.is<AsmSymbol *>()) { 173*09467b48Spatrick OS << S.get<AsmSymbol *>()->first; 174*09467b48Spatrick return; 175*09467b48Spatrick } 176*09467b48Spatrick 177*09467b48Spatrick auto *GV = S.get<GlobalValue *>(); 178*09467b48Spatrick if (GV->hasDLLImportStorageClass()) 179*09467b48Spatrick OS << "__imp_"; 180*09467b48Spatrick 181*09467b48Spatrick Mang.getNameWithPrefix(OS, GV, false); 182*09467b48Spatrick } 183*09467b48Spatrick 184*09467b48Spatrick uint32_t ModuleSymbolTable::getSymbolFlags(Symbol S) const { 185*09467b48Spatrick if (S.is<AsmSymbol *>()) 186*09467b48Spatrick return S.get<AsmSymbol *>()->second; 187*09467b48Spatrick 188*09467b48Spatrick auto *GV = S.get<GlobalValue *>(); 189*09467b48Spatrick 190*09467b48Spatrick uint32_t Res = BasicSymbolRef::SF_None; 191*09467b48Spatrick if (GV->isDeclarationForLinker()) 192*09467b48Spatrick Res |= BasicSymbolRef::SF_Undefined; 193*09467b48Spatrick else if (GV->hasHiddenVisibility() && !GV->hasLocalLinkage()) 194*09467b48Spatrick Res |= BasicSymbolRef::SF_Hidden; 195*09467b48Spatrick if (const GlobalVariable *GVar = dyn_cast<GlobalVariable>(GV)) { 196*09467b48Spatrick if (GVar->isConstant()) 197*09467b48Spatrick Res |= BasicSymbolRef::SF_Const; 198*09467b48Spatrick } 199*09467b48Spatrick if (dyn_cast_or_null<Function>(GV->getBaseObject())) 200*09467b48Spatrick Res |= BasicSymbolRef::SF_Executable; 201*09467b48Spatrick if (isa<GlobalAlias>(GV)) 202*09467b48Spatrick Res |= BasicSymbolRef::SF_Indirect; 203*09467b48Spatrick if (GV->hasPrivateLinkage()) 204*09467b48Spatrick Res |= BasicSymbolRef::SF_FormatSpecific; 205*09467b48Spatrick if (!GV->hasLocalLinkage()) 206*09467b48Spatrick Res |= BasicSymbolRef::SF_Global; 207*09467b48Spatrick if (GV->hasCommonLinkage()) 208*09467b48Spatrick Res |= BasicSymbolRef::SF_Common; 209*09467b48Spatrick if (GV->hasLinkOnceLinkage() || GV->hasWeakLinkage() || 210*09467b48Spatrick GV->hasExternalWeakLinkage()) 211*09467b48Spatrick Res |= BasicSymbolRef::SF_Weak; 212*09467b48Spatrick 213*09467b48Spatrick if (GV->getName().startswith("llvm.")) 214*09467b48Spatrick Res |= BasicSymbolRef::SF_FormatSpecific; 215*09467b48Spatrick else if (auto *Var = dyn_cast<GlobalVariable>(GV)) { 216*09467b48Spatrick if (Var->getSection() == "llvm.metadata") 217*09467b48Spatrick Res |= BasicSymbolRef::SF_FormatSpecific; 218*09467b48Spatrick } 219*09467b48Spatrick 220*09467b48Spatrick return Res; 221*09467b48Spatrick } 222