1321369Sdim//===- ModuleSymbolTable.cpp - symbol table for in-memory IR --------------===// 2311116Sdim// 3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353358Sdim// See https://llvm.org/LICENSE.txt for license information. 5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6311116Sdim// 7311116Sdim//===----------------------------------------------------------------------===// 8311116Sdim// 9311116Sdim// This class represents a symbol table built from in-memory IR. It provides 10311116Sdim// access to GlobalValues and should only be used if such access is required 11311116Sdim// (e.g. in the LTO implementation). 12311116Sdim// 13311116Sdim//===----------------------------------------------------------------------===// 14311116Sdim 15321369Sdim#include "llvm/Object/ModuleSymbolTable.h" 16311116Sdim#include "RecordStreamer.h" 17311116Sdim#include "llvm/ADT/STLExtras.h" 18321369Sdim#include "llvm/ADT/SmallString.h" 19321369Sdim#include "llvm/ADT/StringMap.h" 20321369Sdim#include "llvm/ADT/StringRef.h" 21321369Sdim#include "llvm/ADT/Triple.h" 22321369Sdim#include "llvm/IR/Function.h" 23321369Sdim#include "llvm/IR/GlobalAlias.h" 24321369Sdim#include "llvm/IR/GlobalValue.h" 25321369Sdim#include "llvm/IR/GlobalVariable.h" 26311116Sdim#include "llvm/IR/Module.h" 27311116Sdim#include "llvm/MC/MCAsmInfo.h" 28311116Sdim#include "llvm/MC/MCContext.h" 29321369Sdim#include "llvm/MC/MCDirectives.h" 30311116Sdim#include "llvm/MC/MCInstrInfo.h" 31311116Sdim#include "llvm/MC/MCObjectFileInfo.h" 32311116Sdim#include "llvm/MC/MCParser/MCAsmParser.h" 33311116Sdim#include "llvm/MC/MCParser/MCTargetAsmParser.h" 34311116Sdim#include "llvm/MC/MCRegisterInfo.h" 35311116Sdim#include "llvm/MC/MCSubtargetInfo.h" 36321369Sdim#include "llvm/MC/MCSymbol.h" 37321369Sdim#include "llvm/MC/MCTargetOptions.h" 38321369Sdim#include "llvm/Object/SymbolicFile.h" 39321369Sdim#include "llvm/Support/Casting.h" 40321369Sdim#include "llvm/Support/CodeGen.h" 41321369Sdim#include "llvm/Support/ErrorHandling.h" 42311116Sdim#include "llvm/Support/MemoryBuffer.h" 43321369Sdim#include "llvm/Support/SMLoc.h" 44311116Sdim#include "llvm/Support/SourceMgr.h" 45311116Sdim#include "llvm/Support/TargetRegistry.h" 46311116Sdim#include "llvm/Support/raw_ostream.h" 47321369Sdim#include <algorithm> 48321369Sdim#include <cassert> 49321369Sdim#include <cstdint> 50321369Sdim#include <memory> 51321369Sdim#include <string> 52321369Sdim 53311116Sdimusing namespace llvm; 54311116Sdimusing namespace object; 55311116Sdim 56311116Sdimvoid ModuleSymbolTable::addModule(Module *M) { 57311116Sdim if (FirstMod) 58311116Sdim assert(FirstMod->getTargetTriple() == M->getTargetTriple()); 59311116Sdim else 60311116Sdim FirstMod = M; 61311116Sdim 62321369Sdim for (GlobalValue &GV : M->global_values()) 63311116Sdim SymTab.push_back(&GV); 64311116Sdim 65321369Sdim CollectAsmSymbols(*M, [this](StringRef Name, BasicSymbolRef::Flags Flags) { 66321369Sdim SymTab.push_back(new (AsmSymbols.Allocate()) AsmSymbol(Name, Flags)); 67321369Sdim }); 68311116Sdim} 69311116Sdim 70341825Sdimstatic void 71341825SdiminitializeRecordStreamer(const Module &M, 72341825Sdim function_ref<void(RecordStreamer &)> Init) { 73321369Sdim StringRef InlineAsm = M.getModuleInlineAsm(); 74311116Sdim if (InlineAsm.empty()) 75311116Sdim return; 76311116Sdim 77311116Sdim std::string Err; 78321369Sdim const Triple TT(M.getTargetTriple()); 79311116Sdim const Target *T = TargetRegistry::lookupTarget(TT.str(), Err); 80311116Sdim assert(T && T->hasMCAsmParser()); 81311116Sdim 82311116Sdim std::unique_ptr<MCRegisterInfo> MRI(T->createMCRegInfo(TT.str())); 83311116Sdim if (!MRI) 84311116Sdim return; 85311116Sdim 86360784Sdim MCTargetOptions MCOptions; 87360784Sdim std::unique_ptr<MCAsmInfo> MAI(T->createMCAsmInfo(*MRI, TT.str(), MCOptions)); 88311116Sdim if (!MAI) 89311116Sdim return; 90311116Sdim 91311116Sdim std::unique_ptr<MCSubtargetInfo> STI( 92311116Sdim T->createMCSubtargetInfo(TT.str(), "", "")); 93311116Sdim if (!STI) 94311116Sdim return; 95311116Sdim 96311116Sdim std::unique_ptr<MCInstrInfo> MCII(T->createMCInstrInfo()); 97311116Sdim if (!MCII) 98311116Sdim return; 99311116Sdim 100311116Sdim MCObjectFileInfo MOFI; 101311116Sdim MCContext MCCtx(MAI.get(), MRI.get(), &MOFI); 102327952Sdim MOFI.InitMCObjectFileInfo(TT, /*PIC*/ false, MCCtx); 103344779Sdim MOFI.setSDKVersion(M.getSDKVersion()); 104331366Sdim RecordStreamer Streamer(MCCtx, M); 105311116Sdim T->createNullTargetStreamer(Streamer); 106311116Sdim 107311116Sdim std::unique_ptr<MemoryBuffer> Buffer(MemoryBuffer::getMemBuffer(InlineAsm)); 108311116Sdim SourceMgr SrcMgr; 109311116Sdim SrcMgr.AddNewSourceBuffer(std::move(Buffer), SMLoc()); 110311116Sdim std::unique_ptr<MCAsmParser> Parser( 111311116Sdim createMCAsmParser(SrcMgr, MCCtx, Streamer, *MAI)); 112311116Sdim 113311116Sdim std::unique_ptr<MCTargetAsmParser> TAP( 114311116Sdim T->createMCAsmParser(*STI, *Parser, *MCII, MCOptions)); 115311116Sdim if (!TAP) 116311116Sdim return; 117311116Sdim 118311116Sdim Parser->setTargetParser(*TAP); 119311116Sdim if (Parser->Run(false)) 120311116Sdim return; 121311116Sdim 122341825Sdim Init(Streamer); 123341825Sdim} 124321369Sdim 125341825Sdimvoid ModuleSymbolTable::CollectAsmSymbols( 126341825Sdim const Module &M, 127341825Sdim function_ref<void(StringRef, BasicSymbolRef::Flags)> AsmSymbol) { 128341825Sdim initializeRecordStreamer(M, [&](RecordStreamer &Streamer) { 129341825Sdim Streamer.flushSymverDirectives(); 130341825Sdim 131341825Sdim for (auto &KV : Streamer) { 132341825Sdim StringRef Key = KV.first(); 133341825Sdim RecordStreamer::State Value = KV.second; 134341825Sdim // FIXME: For now we just assume that all asm symbols are executable. 135341825Sdim uint32_t Res = BasicSymbolRef::SF_Executable; 136341825Sdim switch (Value) { 137341825Sdim case RecordStreamer::NeverSeen: 138341825Sdim llvm_unreachable("NeverSeen should have been replaced earlier"); 139341825Sdim case RecordStreamer::DefinedGlobal: 140341825Sdim Res |= BasicSymbolRef::SF_Global; 141341825Sdim break; 142341825Sdim case RecordStreamer::Defined: 143341825Sdim break; 144341825Sdim case RecordStreamer::Global: 145341825Sdim case RecordStreamer::Used: 146341825Sdim Res |= BasicSymbolRef::SF_Undefined; 147341825Sdim Res |= BasicSymbolRef::SF_Global; 148341825Sdim break; 149341825Sdim case RecordStreamer::DefinedWeak: 150341825Sdim Res |= BasicSymbolRef::SF_Weak; 151341825Sdim Res |= BasicSymbolRef::SF_Global; 152341825Sdim break; 153341825Sdim case RecordStreamer::UndefinedWeak: 154341825Sdim Res |= BasicSymbolRef::SF_Weak; 155341825Sdim Res |= BasicSymbolRef::SF_Undefined; 156341825Sdim } 157341825Sdim AsmSymbol(Key, BasicSymbolRef::Flags(Res)); 158311116Sdim } 159341825Sdim }); 160311116Sdim} 161311116Sdim 162341825Sdimvoid ModuleSymbolTable::CollectAsmSymvers( 163341825Sdim const Module &M, function_ref<void(StringRef, StringRef)> AsmSymver) { 164341825Sdim initializeRecordStreamer(M, [&](RecordStreamer &Streamer) { 165341825Sdim for (auto &KV : Streamer.symverAliases()) 166341825Sdim for (auto &Alias : KV.second) 167341825Sdim AsmSymver(KV.first->getName(), Alias); 168341825Sdim }); 169341825Sdim} 170341825Sdim 171311116Sdimvoid ModuleSymbolTable::printSymbolName(raw_ostream &OS, Symbol S) const { 172311116Sdim if (S.is<AsmSymbol *>()) { 173311116Sdim OS << S.get<AsmSymbol *>()->first; 174311116Sdim return; 175311116Sdim } 176311116Sdim 177311116Sdim auto *GV = S.get<GlobalValue *>(); 178311116Sdim if (GV->hasDLLImportStorageClass()) 179311116Sdim OS << "__imp_"; 180311116Sdim 181311116Sdim Mang.getNameWithPrefix(OS, GV, false); 182311116Sdim} 183311116Sdim 184311116Sdimuint32_t ModuleSymbolTable::getSymbolFlags(Symbol S) const { 185311116Sdim if (S.is<AsmSymbol *>()) 186311116Sdim return S.get<AsmSymbol *>()->second; 187311116Sdim 188311116Sdim auto *GV = S.get<GlobalValue *>(); 189311116Sdim 190311116Sdim uint32_t Res = BasicSymbolRef::SF_None; 191311116Sdim if (GV->isDeclarationForLinker()) 192311116Sdim Res |= BasicSymbolRef::SF_Undefined; 193311116Sdim else if (GV->hasHiddenVisibility() && !GV->hasLocalLinkage()) 194311116Sdim Res |= BasicSymbolRef::SF_Hidden; 195311116Sdim if (const GlobalVariable *GVar = dyn_cast<GlobalVariable>(GV)) { 196311116Sdim if (GVar->isConstant()) 197311116Sdim Res |= BasicSymbolRef::SF_Const; 198311116Sdim } 199311116Sdim if (dyn_cast_or_null<Function>(GV->getBaseObject())) 200311116Sdim Res |= BasicSymbolRef::SF_Executable; 201311116Sdim if (isa<GlobalAlias>(GV)) 202311116Sdim Res |= BasicSymbolRef::SF_Indirect; 203311116Sdim if (GV->hasPrivateLinkage()) 204311116Sdim Res |= BasicSymbolRef::SF_FormatSpecific; 205311116Sdim if (!GV->hasLocalLinkage()) 206311116Sdim Res |= BasicSymbolRef::SF_Global; 207311116Sdim if (GV->hasCommonLinkage()) 208311116Sdim Res |= BasicSymbolRef::SF_Common; 209311116Sdim if (GV->hasLinkOnceLinkage() || GV->hasWeakLinkage() || 210311116Sdim GV->hasExternalWeakLinkage()) 211311116Sdim Res |= BasicSymbolRef::SF_Weak; 212311116Sdim 213311116Sdim if (GV->getName().startswith("llvm.")) 214311116Sdim Res |= BasicSymbolRef::SF_FormatSpecific; 215311116Sdim else if (auto *Var = dyn_cast<GlobalVariable>(GV)) { 216311116Sdim if (Var->getSection() == "llvm.metadata") 217311116Sdim Res |= BasicSymbolRef::SF_FormatSpecific; 218311116Sdim } 219311116Sdim 220311116Sdim return Res; 221311116Sdim} 222