151690af2SDimitry Andric //===- ModuleSymbolTable.cpp - symbol table for in-memory IR --------------===// 2d88c1a5aSDimitry Andric // 3d88c1a5aSDimitry Andric // The LLVM Compiler Infrastructure 4d88c1a5aSDimitry Andric // 5d88c1a5aSDimitry Andric // This file is distributed under the University of Illinois Open Source 6d88c1a5aSDimitry Andric // License. See LICENSE.TXT for details. 7d88c1a5aSDimitry Andric // 8d88c1a5aSDimitry Andric //===----------------------------------------------------------------------===// 9d88c1a5aSDimitry Andric // 10d88c1a5aSDimitry Andric // This class represents a symbol table built from in-memory IR. It provides 11d88c1a5aSDimitry Andric // access to GlobalValues and should only be used if such access is required 12d88c1a5aSDimitry Andric // (e.g. in the LTO implementation). 13d88c1a5aSDimitry Andric // 14d88c1a5aSDimitry Andric //===----------------------------------------------------------------------===// 15d88c1a5aSDimitry Andric 16db17bf38SDimitry Andric #include "llvm/Object/ModuleSymbolTable.h" 17d88c1a5aSDimitry Andric #include "RecordStreamer.h" 18d88c1a5aSDimitry Andric #include "llvm/ADT/STLExtras.h" 19db17bf38SDimitry Andric #include "llvm/ADT/SmallString.h" 2051690af2SDimitry Andric #include "llvm/ADT/StringMap.h" 2151690af2SDimitry Andric #include "llvm/ADT/StringRef.h" 2251690af2SDimitry Andric #include "llvm/ADT/Triple.h" 2351690af2SDimitry Andric #include "llvm/IR/Function.h" 2451690af2SDimitry Andric #include "llvm/IR/GlobalAlias.h" 2551690af2SDimitry Andric #include "llvm/IR/GlobalValue.h" 2651690af2SDimitry Andric #include "llvm/IR/GlobalVariable.h" 27d88c1a5aSDimitry Andric #include "llvm/IR/Mangler.h" 28d88c1a5aSDimitry Andric #include "llvm/IR/Module.h" 29d88c1a5aSDimitry Andric #include "llvm/MC/MCAsmInfo.h" 30d88c1a5aSDimitry Andric #include "llvm/MC/MCContext.h" 3151690af2SDimitry Andric #include "llvm/MC/MCDirectives.h" 32d88c1a5aSDimitry Andric #include "llvm/MC/MCInstrInfo.h" 33d88c1a5aSDimitry Andric #include "llvm/MC/MCObjectFileInfo.h" 34d88c1a5aSDimitry Andric #include "llvm/MC/MCParser/MCAsmParser.h" 35d88c1a5aSDimitry Andric #include "llvm/MC/MCParser/MCTargetAsmParser.h" 36d88c1a5aSDimitry Andric #include "llvm/MC/MCRegisterInfo.h" 37d88c1a5aSDimitry Andric #include "llvm/MC/MCSubtargetInfo.h" 3851690af2SDimitry Andric #include "llvm/MC/MCSymbol.h" 3951690af2SDimitry Andric #include "llvm/MC/MCTargetOptions.h" 4051690af2SDimitry Andric #include "llvm/Object/SymbolicFile.h" 4151690af2SDimitry Andric #include "llvm/Support/Casting.h" 4251690af2SDimitry Andric #include "llvm/Support/CodeGen.h" 4351690af2SDimitry Andric #include "llvm/Support/ErrorHandling.h" 44d88c1a5aSDimitry Andric #include "llvm/Support/MemoryBuffer.h" 4551690af2SDimitry Andric #include "llvm/Support/SMLoc.h" 46d88c1a5aSDimitry Andric #include "llvm/Support/SourceMgr.h" 47d88c1a5aSDimitry Andric #include "llvm/Support/TargetRegistry.h" 48db17bf38SDimitry Andric #include "llvm/Support/raw_ostream.h" 4951690af2SDimitry Andric #include <algorithm> 5051690af2SDimitry Andric #include <cassert> 5151690af2SDimitry Andric #include <cstdint> 5251690af2SDimitry Andric #include <memory> 5351690af2SDimitry Andric #include <string> 5451690af2SDimitry Andric 55d88c1a5aSDimitry Andric using namespace llvm; 56d88c1a5aSDimitry Andric using namespace object; 57d88c1a5aSDimitry Andric 58d88c1a5aSDimitry Andric void ModuleSymbolTable::addModule(Module *M) { 59d88c1a5aSDimitry Andric if (FirstMod) 60d88c1a5aSDimitry Andric assert(FirstMod->getTargetTriple() == M->getTargetTriple()); 61d88c1a5aSDimitry Andric else 62d88c1a5aSDimitry Andric FirstMod = M; 63d88c1a5aSDimitry Andric 647a7e6055SDimitry Andric for (GlobalValue &GV : M->global_values()) 65d88c1a5aSDimitry Andric SymTab.push_back(&GV); 66d88c1a5aSDimitry Andric 677a7e6055SDimitry Andric CollectAsmSymbols(*M, [this](StringRef Name, BasicSymbolRef::Flags Flags) { 687a7e6055SDimitry Andric SymTab.push_back(new (AsmSymbols.Allocate()) AsmSymbol(Name, Flags)); 69d88c1a5aSDimitry Andric }); 70d88c1a5aSDimitry Andric } 71d88c1a5aSDimitry Andric 727a7e6055SDimitry Andric // Ensure ELF .symver aliases get the same binding as the defined symbol 737a7e6055SDimitry Andric // they alias with. 747a7e6055SDimitry Andric static void handleSymverAliases(const Module &M, RecordStreamer &Streamer) { 757a7e6055SDimitry Andric if (Streamer.symverAliases().empty()) 767a7e6055SDimitry Andric return; 777a7e6055SDimitry Andric 787a7e6055SDimitry Andric // The name in the assembler will be mangled, but the name in the IR 797a7e6055SDimitry Andric // might not, so we first compute a mapping from mangled name to GV. 807a7e6055SDimitry Andric Mangler Mang; 817a7e6055SDimitry Andric SmallString<64> MangledName; 827a7e6055SDimitry Andric StringMap<const GlobalValue *> MangledNameMap; 837a7e6055SDimitry Andric auto GetMangledName = [&](const GlobalValue &GV) { 847a7e6055SDimitry Andric if (!GV.hasName()) 857a7e6055SDimitry Andric return; 867a7e6055SDimitry Andric 877a7e6055SDimitry Andric MangledName.clear(); 887a7e6055SDimitry Andric MangledName.reserve(GV.getName().size() + 1); 897a7e6055SDimitry Andric Mang.getNameWithPrefix(MangledName, &GV, /*CannotUsePrivateLabel=*/false); 907a7e6055SDimitry Andric MangledNameMap[MangledName] = &GV; 917a7e6055SDimitry Andric }; 927a7e6055SDimitry Andric for (const Function &F : M) 937a7e6055SDimitry Andric GetMangledName(F); 947a7e6055SDimitry Andric for (const GlobalVariable &GV : M.globals()) 957a7e6055SDimitry Andric GetMangledName(GV); 967a7e6055SDimitry Andric for (const GlobalAlias &GA : M.aliases()) 977a7e6055SDimitry Andric GetMangledName(GA); 987a7e6055SDimitry Andric 997a7e6055SDimitry Andric // Walk all the recorded .symver aliases, and set up the binding 1007a7e6055SDimitry Andric // for each alias. 1017a7e6055SDimitry Andric for (auto &Symver : Streamer.symverAliases()) { 1027a7e6055SDimitry Andric const MCSymbol *Aliasee = Symver.first; 1037a7e6055SDimitry Andric MCSymbolAttr Attr = MCSA_Invalid; 1047a7e6055SDimitry Andric 1057a7e6055SDimitry Andric // First check if the aliasee binding was recorded in the asm. 1067a7e6055SDimitry Andric RecordStreamer::State state = Streamer.getSymbolState(Aliasee); 1077a7e6055SDimitry Andric switch (state) { 1087a7e6055SDimitry Andric case RecordStreamer::Global: 1097a7e6055SDimitry Andric case RecordStreamer::DefinedGlobal: 1107a7e6055SDimitry Andric Attr = MCSA_Global; 1117a7e6055SDimitry Andric break; 1127a7e6055SDimitry Andric case RecordStreamer::UndefinedWeak: 1137a7e6055SDimitry Andric case RecordStreamer::DefinedWeak: 1147a7e6055SDimitry Andric Attr = MCSA_Weak; 1157a7e6055SDimitry Andric break; 1167a7e6055SDimitry Andric default: 1177a7e6055SDimitry Andric break; 1187a7e6055SDimitry Andric } 1197a7e6055SDimitry Andric 1207a7e6055SDimitry Andric // If we don't have a symbol attribute from assembly, then check if 1217a7e6055SDimitry Andric // the aliasee was defined in the IR. 1227a7e6055SDimitry Andric if (Attr == MCSA_Invalid) { 1237a7e6055SDimitry Andric const auto *GV = M.getNamedValue(Aliasee->getName()); 1247a7e6055SDimitry Andric if (!GV) { 1257a7e6055SDimitry Andric auto MI = MangledNameMap.find(Aliasee->getName()); 1267a7e6055SDimitry Andric if (MI != MangledNameMap.end()) 1277a7e6055SDimitry Andric GV = MI->second; 1287a7e6055SDimitry Andric else 1297a7e6055SDimitry Andric continue; 1307a7e6055SDimitry Andric } 1317a7e6055SDimitry Andric if (GV->hasExternalLinkage()) 1327a7e6055SDimitry Andric Attr = MCSA_Global; 1337a7e6055SDimitry Andric else if (GV->hasLocalLinkage()) 1347a7e6055SDimitry Andric Attr = MCSA_Local; 1357a7e6055SDimitry Andric else if (GV->isWeakForLinker()) 1367a7e6055SDimitry Andric Attr = MCSA_Weak; 1377a7e6055SDimitry Andric } 1387a7e6055SDimitry Andric if (Attr == MCSA_Invalid) 1397a7e6055SDimitry Andric continue; 1407a7e6055SDimitry Andric 1417a7e6055SDimitry Andric // Set the detected binding on each alias with this aliasee. 1427a7e6055SDimitry Andric for (auto &Alias : Symver.second) 1437a7e6055SDimitry Andric Streamer.EmitSymbolAttribute(Alias, Attr); 1447a7e6055SDimitry Andric } 1457a7e6055SDimitry Andric } 1467a7e6055SDimitry Andric 147d88c1a5aSDimitry Andric void ModuleSymbolTable::CollectAsmSymbols( 1487a7e6055SDimitry Andric const Module &M, 149d88c1a5aSDimitry Andric function_ref<void(StringRef, BasicSymbolRef::Flags)> AsmSymbol) { 1507a7e6055SDimitry Andric StringRef InlineAsm = M.getModuleInlineAsm(); 151d88c1a5aSDimitry Andric if (InlineAsm.empty()) 152d88c1a5aSDimitry Andric return; 153d88c1a5aSDimitry Andric 154d88c1a5aSDimitry Andric std::string Err; 1557a7e6055SDimitry Andric const Triple TT(M.getTargetTriple()); 156d88c1a5aSDimitry Andric const Target *T = TargetRegistry::lookupTarget(TT.str(), Err); 157d88c1a5aSDimitry Andric assert(T && T->hasMCAsmParser()); 158d88c1a5aSDimitry Andric 159d88c1a5aSDimitry Andric std::unique_ptr<MCRegisterInfo> MRI(T->createMCRegInfo(TT.str())); 160d88c1a5aSDimitry Andric if (!MRI) 161d88c1a5aSDimitry Andric return; 162d88c1a5aSDimitry Andric 163d88c1a5aSDimitry Andric std::unique_ptr<MCAsmInfo> MAI(T->createMCAsmInfo(*MRI, TT.str())); 164d88c1a5aSDimitry Andric if (!MAI) 165d88c1a5aSDimitry Andric return; 166d88c1a5aSDimitry Andric 167d88c1a5aSDimitry Andric std::unique_ptr<MCSubtargetInfo> STI( 168d88c1a5aSDimitry Andric T->createMCSubtargetInfo(TT.str(), "", "")); 169d88c1a5aSDimitry Andric if (!STI) 170d88c1a5aSDimitry Andric return; 171d88c1a5aSDimitry Andric 172d88c1a5aSDimitry Andric std::unique_ptr<MCInstrInfo> MCII(T->createMCInstrInfo()); 173d88c1a5aSDimitry Andric if (!MCII) 174d88c1a5aSDimitry Andric return; 175d88c1a5aSDimitry Andric 176d88c1a5aSDimitry Andric MCObjectFileInfo MOFI; 177d88c1a5aSDimitry Andric MCContext MCCtx(MAI.get(), MRI.get(), &MOFI); 1782cab237bSDimitry Andric MOFI.InitMCObjectFileInfo(TT, /*PIC*/ false, MCCtx); 179d88c1a5aSDimitry Andric RecordStreamer Streamer(MCCtx); 180d88c1a5aSDimitry Andric T->createNullTargetStreamer(Streamer); 181d88c1a5aSDimitry Andric 182d88c1a5aSDimitry Andric std::unique_ptr<MemoryBuffer> Buffer(MemoryBuffer::getMemBuffer(InlineAsm)); 183d88c1a5aSDimitry Andric SourceMgr SrcMgr; 184d88c1a5aSDimitry Andric SrcMgr.AddNewSourceBuffer(std::move(Buffer), SMLoc()); 185d88c1a5aSDimitry Andric std::unique_ptr<MCAsmParser> Parser( 186d88c1a5aSDimitry Andric createMCAsmParser(SrcMgr, MCCtx, Streamer, *MAI)); 187d88c1a5aSDimitry Andric 188d88c1a5aSDimitry Andric MCTargetOptions MCOptions; 189d88c1a5aSDimitry Andric std::unique_ptr<MCTargetAsmParser> TAP( 190d88c1a5aSDimitry Andric T->createMCAsmParser(*STI, *Parser, *MCII, MCOptions)); 191d88c1a5aSDimitry Andric if (!TAP) 192d88c1a5aSDimitry Andric return; 193d88c1a5aSDimitry Andric 194d88c1a5aSDimitry Andric Parser->setTargetParser(*TAP); 195d88c1a5aSDimitry Andric if (Parser->Run(false)) 196d88c1a5aSDimitry Andric return; 197d88c1a5aSDimitry Andric 1987a7e6055SDimitry Andric handleSymverAliases(M, Streamer); 1997a7e6055SDimitry Andric 200d88c1a5aSDimitry Andric for (auto &KV : Streamer) { 201d88c1a5aSDimitry Andric StringRef Key = KV.first(); 202d88c1a5aSDimitry Andric RecordStreamer::State Value = KV.second; 203d88c1a5aSDimitry Andric // FIXME: For now we just assume that all asm symbols are executable. 204d88c1a5aSDimitry Andric uint32_t Res = BasicSymbolRef::SF_Executable; 205d88c1a5aSDimitry Andric switch (Value) { 206d88c1a5aSDimitry Andric case RecordStreamer::NeverSeen: 207d88c1a5aSDimitry Andric llvm_unreachable("NeverSeen should have been replaced earlier"); 208d88c1a5aSDimitry Andric case RecordStreamer::DefinedGlobal: 209d88c1a5aSDimitry Andric Res |= BasicSymbolRef::SF_Global; 210d88c1a5aSDimitry Andric break; 211d88c1a5aSDimitry Andric case RecordStreamer::Defined: 212d88c1a5aSDimitry Andric break; 213d88c1a5aSDimitry Andric case RecordStreamer::Global: 214d88c1a5aSDimitry Andric case RecordStreamer::Used: 215d88c1a5aSDimitry Andric Res |= BasicSymbolRef::SF_Undefined; 216d88c1a5aSDimitry Andric Res |= BasicSymbolRef::SF_Global; 217d88c1a5aSDimitry Andric break; 218d88c1a5aSDimitry Andric case RecordStreamer::DefinedWeak: 219d88c1a5aSDimitry Andric Res |= BasicSymbolRef::SF_Weak; 220d88c1a5aSDimitry Andric Res |= BasicSymbolRef::SF_Global; 221d88c1a5aSDimitry Andric break; 222d88c1a5aSDimitry Andric case RecordStreamer::UndefinedWeak: 223d88c1a5aSDimitry Andric Res |= BasicSymbolRef::SF_Weak; 224d88c1a5aSDimitry Andric Res |= BasicSymbolRef::SF_Undefined; 225d88c1a5aSDimitry Andric } 226d88c1a5aSDimitry Andric AsmSymbol(Key, BasicSymbolRef::Flags(Res)); 227d88c1a5aSDimitry Andric } 228d88c1a5aSDimitry Andric } 229d88c1a5aSDimitry Andric 230d88c1a5aSDimitry Andric void ModuleSymbolTable::printSymbolName(raw_ostream &OS, Symbol S) const { 231d88c1a5aSDimitry Andric if (S.is<AsmSymbol *>()) { 232d88c1a5aSDimitry Andric OS << S.get<AsmSymbol *>()->first; 233d88c1a5aSDimitry Andric return; 234d88c1a5aSDimitry Andric } 235d88c1a5aSDimitry Andric 236d88c1a5aSDimitry Andric auto *GV = S.get<GlobalValue *>(); 237d88c1a5aSDimitry Andric if (GV->hasDLLImportStorageClass()) 238d88c1a5aSDimitry Andric OS << "__imp_"; 239d88c1a5aSDimitry Andric 240d88c1a5aSDimitry Andric Mang.getNameWithPrefix(OS, GV, false); 241d88c1a5aSDimitry Andric } 242d88c1a5aSDimitry Andric 243d88c1a5aSDimitry Andric uint32_t ModuleSymbolTable::getSymbolFlags(Symbol S) const { 244d88c1a5aSDimitry Andric if (S.is<AsmSymbol *>()) 245d88c1a5aSDimitry Andric return S.get<AsmSymbol *>()->second; 246d88c1a5aSDimitry Andric 247d88c1a5aSDimitry Andric auto *GV = S.get<GlobalValue *>(); 248d88c1a5aSDimitry Andric 249d88c1a5aSDimitry Andric uint32_t Res = BasicSymbolRef::SF_None; 250d88c1a5aSDimitry Andric if (GV->isDeclarationForLinker()) 251d88c1a5aSDimitry Andric Res |= BasicSymbolRef::SF_Undefined; 252d88c1a5aSDimitry Andric else if (GV->hasHiddenVisibility() && !GV->hasLocalLinkage()) 253d88c1a5aSDimitry Andric Res |= BasicSymbolRef::SF_Hidden; 254d88c1a5aSDimitry Andric if (const GlobalVariable *GVar = dyn_cast<GlobalVariable>(GV)) { 255d88c1a5aSDimitry Andric if (GVar->isConstant()) 256d88c1a5aSDimitry Andric Res |= BasicSymbolRef::SF_Const; 257d88c1a5aSDimitry Andric } 258d88c1a5aSDimitry Andric if (dyn_cast_or_null<Function>(GV->getBaseObject())) 259d88c1a5aSDimitry Andric Res |= BasicSymbolRef::SF_Executable; 260d88c1a5aSDimitry Andric if (isa<GlobalAlias>(GV)) 261d88c1a5aSDimitry Andric Res |= BasicSymbolRef::SF_Indirect; 262d88c1a5aSDimitry Andric if (GV->hasPrivateLinkage()) 263d88c1a5aSDimitry Andric Res |= BasicSymbolRef::SF_FormatSpecific; 264d88c1a5aSDimitry Andric if (!GV->hasLocalLinkage()) 265d88c1a5aSDimitry Andric Res |= BasicSymbolRef::SF_Global; 266d88c1a5aSDimitry Andric if (GV->hasCommonLinkage()) 267d88c1a5aSDimitry Andric Res |= BasicSymbolRef::SF_Common; 268d88c1a5aSDimitry Andric if (GV->hasLinkOnceLinkage() || GV->hasWeakLinkage() || 269d88c1a5aSDimitry Andric GV->hasExternalWeakLinkage()) 270d88c1a5aSDimitry Andric Res |= BasicSymbolRef::SF_Weak; 271d88c1a5aSDimitry Andric 272d88c1a5aSDimitry Andric if (GV->getName().startswith("llvm.")) 273d88c1a5aSDimitry Andric Res |= BasicSymbolRef::SF_FormatSpecific; 274d88c1a5aSDimitry Andric else if (auto *Var = dyn_cast<GlobalVariable>(GV)) { 275d88c1a5aSDimitry Andric if (Var->getSection() == "llvm.metadata") 276d88c1a5aSDimitry Andric Res |= BasicSymbolRef::SF_FormatSpecific; 277d88c1a5aSDimitry Andric } 278d88c1a5aSDimitry Andric 279d88c1a5aSDimitry Andric return Res; 280d88c1a5aSDimitry Andric } 281