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