1 //===- ModuleSymbolTable.cpp - symbol table for in-memory IR ----*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This class represents a symbol table built from in-memory IR. It provides 11 // access to GlobalValues and should only be used if such access is required 12 // (e.g. in the LTO implementation). 13 // 14 //===----------------------------------------------------------------------===// 15 16 #include "llvm/Object/IRObjectFile.h" 17 #include "RecordStreamer.h" 18 #include "llvm/ADT/STLExtras.h" 19 #include "llvm/Bitcode/BitcodeReader.h" 20 #include "llvm/IR/GVMaterializer.h" 21 #include "llvm/IR/LLVMContext.h" 22 #include "llvm/IR/Mangler.h" 23 #include "llvm/IR/Module.h" 24 #include "llvm/MC/MCAsmInfo.h" 25 #include "llvm/MC/MCContext.h" 26 #include "llvm/MC/MCInstrInfo.h" 27 #include "llvm/MC/MCObjectFileInfo.h" 28 #include "llvm/MC/MCParser/MCAsmParser.h" 29 #include "llvm/MC/MCParser/MCTargetAsmParser.h" 30 #include "llvm/MC/MCRegisterInfo.h" 31 #include "llvm/MC/MCSubtargetInfo.h" 32 #include "llvm/Object/ObjectFile.h" 33 #include "llvm/Support/MemoryBuffer.h" 34 #include "llvm/Support/SourceMgr.h" 35 #include "llvm/Support/TargetRegistry.h" 36 #include "llvm/Support/raw_ostream.h" 37 using namespace llvm; 38 using namespace object; 39 40 void ModuleSymbolTable::addModule(Module *M) { 41 if (FirstMod) 42 assert(FirstMod->getTargetTriple() == M->getTargetTriple()); 43 else 44 FirstMod = M; 45 46 for (Function &F : *M) 47 SymTab.push_back(&F); 48 for (GlobalVariable &GV : M->globals()) 49 SymTab.push_back(&GV); 50 for (GlobalAlias &GA : M->aliases()) 51 SymTab.push_back(&GA); 52 53 CollectAsmSymbols(*M, [this](StringRef Name, BasicSymbolRef::Flags Flags) { 54 SymTab.push_back(new (AsmSymbols.Allocate()) AsmSymbol(Name, Flags)); 55 }); 56 } 57 58 // Ensure ELF .symver aliases get the same binding as the defined symbol 59 // they alias with. 60 static void handleSymverAliases(const Module &M, RecordStreamer &Streamer) { 61 if (Streamer.symverAliases().empty()) 62 return; 63 64 // The name in the assembler will be mangled, but the name in the IR 65 // might not, so we first compute a mapping from mangled name to GV. 66 Mangler Mang; 67 SmallString<64> MangledName; 68 StringMap<const GlobalValue *> MangledNameMap; 69 auto GetMangledName = [&](const GlobalValue &GV) { 70 if (!GV.hasName()) 71 return; 72 73 MangledName.clear(); 74 MangledName.reserve(GV.getName().size() + 1); 75 Mang.getNameWithPrefix(MangledName, &GV, /*CannotUsePrivateLabel=*/false); 76 MangledNameMap[MangledName] = &GV; 77 }; 78 for (const Function &F : M) 79 GetMangledName(F); 80 for (const GlobalVariable &GV : M.globals()) 81 GetMangledName(GV); 82 for (const GlobalAlias &GA : M.aliases()) 83 GetMangledName(GA); 84 85 // Walk all the recorded .symver aliases, and set up the binding 86 // for each alias. 87 for (auto &Symver : Streamer.symverAliases()) { 88 const MCSymbol *Aliasee = Symver.first; 89 MCSymbolAttr Attr = MCSA_Invalid; 90 91 // First check if the aliasee binding was recorded in the asm. 92 RecordStreamer::State state = Streamer.getSymbolState(Aliasee); 93 switch (state) { 94 case RecordStreamer::Global: 95 case RecordStreamer::DefinedGlobal: 96 Attr = MCSA_Global; 97 break; 98 case RecordStreamer::UndefinedWeak: 99 case RecordStreamer::DefinedWeak: 100 Attr = MCSA_Weak; 101 break; 102 default: 103 break; 104 } 105 106 // If we don't have a symbol attribute from assembly, then check if 107 // the aliasee was defined in the IR. 108 if (Attr == MCSA_Invalid) { 109 const auto *GV = M.getNamedValue(Aliasee->getName()); 110 if (!GV) { 111 auto MI = MangledNameMap.find(Aliasee->getName()); 112 if (MI != MangledNameMap.end()) 113 GV = MI->second; 114 else 115 continue; 116 } 117 if (GV->hasExternalLinkage()) 118 Attr = MCSA_Global; 119 else if (GV->hasLocalLinkage()) 120 Attr = MCSA_Local; 121 else if (GV->isWeakForLinker()) 122 Attr = MCSA_Weak; 123 } 124 if (Attr == MCSA_Invalid) 125 continue; 126 127 // Set the detected binding on each alias with this aliasee. 128 for (auto &Alias : Symver.second) 129 Streamer.EmitSymbolAttribute(Alias, Attr); 130 } 131 } 132 133 void ModuleSymbolTable::CollectAsmSymbols( 134 const Module &M, 135 function_ref<void(StringRef, BasicSymbolRef::Flags)> AsmSymbol) { 136 StringRef InlineAsm = M.getModuleInlineAsm(); 137 if (InlineAsm.empty()) 138 return; 139 140 std::string Err; 141 const Triple TT(M.getTargetTriple()); 142 const Target *T = TargetRegistry::lookupTarget(TT.str(), Err); 143 assert(T && T->hasMCAsmParser()); 144 145 std::unique_ptr<MCRegisterInfo> MRI(T->createMCRegInfo(TT.str())); 146 if (!MRI) 147 return; 148 149 std::unique_ptr<MCAsmInfo> MAI(T->createMCAsmInfo(*MRI, TT.str())); 150 if (!MAI) 151 return; 152 153 std::unique_ptr<MCSubtargetInfo> STI( 154 T->createMCSubtargetInfo(TT.str(), "", "")); 155 if (!STI) 156 return; 157 158 std::unique_ptr<MCInstrInfo> MCII(T->createMCInstrInfo()); 159 if (!MCII) 160 return; 161 162 MCObjectFileInfo MOFI; 163 MCContext MCCtx(MAI.get(), MRI.get(), &MOFI); 164 MOFI.InitMCObjectFileInfo(TT, /*PIC*/ false, CodeModel::Default, MCCtx); 165 RecordStreamer Streamer(MCCtx); 166 T->createNullTargetStreamer(Streamer); 167 168 std::unique_ptr<MemoryBuffer> Buffer(MemoryBuffer::getMemBuffer(InlineAsm)); 169 SourceMgr SrcMgr; 170 SrcMgr.AddNewSourceBuffer(std::move(Buffer), SMLoc()); 171 std::unique_ptr<MCAsmParser> Parser( 172 createMCAsmParser(SrcMgr, MCCtx, Streamer, *MAI)); 173 174 MCTargetOptions MCOptions; 175 std::unique_ptr<MCTargetAsmParser> TAP( 176 T->createMCAsmParser(*STI, *Parser, *MCII, MCOptions)); 177 if (!TAP) 178 return; 179 180 Parser->setTargetParser(*TAP); 181 if (Parser->Run(false)) 182 return; 183 184 handleSymverAliases(M, Streamer); 185 186 for (auto &KV : Streamer) { 187 StringRef Key = KV.first(); 188 RecordStreamer::State Value = KV.second; 189 // FIXME: For now we just assume that all asm symbols are executable. 190 uint32_t Res = BasicSymbolRef::SF_Executable; 191 switch (Value) { 192 case RecordStreamer::NeverSeen: 193 llvm_unreachable("NeverSeen should have been replaced earlier"); 194 case RecordStreamer::DefinedGlobal: 195 Res |= BasicSymbolRef::SF_Global; 196 break; 197 case RecordStreamer::Defined: 198 break; 199 case RecordStreamer::Global: 200 case RecordStreamer::Used: 201 Res |= BasicSymbolRef::SF_Undefined; 202 Res |= BasicSymbolRef::SF_Global; 203 break; 204 case RecordStreamer::DefinedWeak: 205 Res |= BasicSymbolRef::SF_Weak; 206 Res |= BasicSymbolRef::SF_Global; 207 break; 208 case RecordStreamer::UndefinedWeak: 209 Res |= BasicSymbolRef::SF_Weak; 210 Res |= BasicSymbolRef::SF_Undefined; 211 } 212 AsmSymbol(Key, BasicSymbolRef::Flags(Res)); 213 } 214 } 215 216 void ModuleSymbolTable::printSymbolName(raw_ostream &OS, Symbol S) const { 217 if (S.is<AsmSymbol *>()) { 218 OS << S.get<AsmSymbol *>()->first; 219 return; 220 } 221 222 auto *GV = S.get<GlobalValue *>(); 223 if (GV->hasDLLImportStorageClass()) 224 OS << "__imp_"; 225 226 Mang.getNameWithPrefix(OS, GV, false); 227 } 228 229 uint32_t ModuleSymbolTable::getSymbolFlags(Symbol S) const { 230 if (S.is<AsmSymbol *>()) 231 return S.get<AsmSymbol *>()->second; 232 233 auto *GV = S.get<GlobalValue *>(); 234 235 uint32_t Res = BasicSymbolRef::SF_None; 236 if (GV->isDeclarationForLinker()) 237 Res |= BasicSymbolRef::SF_Undefined; 238 else if (GV->hasHiddenVisibility() && !GV->hasLocalLinkage()) 239 Res |= BasicSymbolRef::SF_Hidden; 240 if (const GlobalVariable *GVar = dyn_cast<GlobalVariable>(GV)) { 241 if (GVar->isConstant()) 242 Res |= BasicSymbolRef::SF_Const; 243 } 244 if (dyn_cast_or_null<Function>(GV->getBaseObject())) 245 Res |= BasicSymbolRef::SF_Executable; 246 if (isa<GlobalAlias>(GV)) 247 Res |= BasicSymbolRef::SF_Indirect; 248 if (GV->hasPrivateLinkage()) 249 Res |= BasicSymbolRef::SF_FormatSpecific; 250 if (!GV->hasLocalLinkage()) 251 Res |= BasicSymbolRef::SF_Global; 252 if (GV->hasCommonLinkage()) 253 Res |= BasicSymbolRef::SF_Common; 254 if (GV->hasLinkOnceLinkage() || GV->hasWeakLinkage() || 255 GV->hasExternalWeakLinkage()) 256 Res |= BasicSymbolRef::SF_Weak; 257 258 if (GV->getName().startswith("llvm.")) 259 Res |= BasicSymbolRef::SF_FormatSpecific; 260 else if (auto *Var = dyn_cast<GlobalVariable>(GV)) { 261 if (Var->getSection() == "llvm.metadata") 262 Res |= BasicSymbolRef::SF_FormatSpecific; 263 } 264 265 return Res; 266 } 267