1 //===- IRObjectFile.cpp - IR object file implementation ---------*- 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 // Part of the IRObjectFile class implementation. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "llvm/Object/IRObjectFile.h" 15 #include "RecordStreamer.h" 16 #include "llvm/ADT/STLExtras.h" 17 #include "llvm/Bitcode/ReaderWriter.h" 18 #include "llvm/IR/GVMaterializer.h" 19 #include "llvm/IR/LLVMContext.h" 20 #include "llvm/IR/Mangler.h" 21 #include "llvm/IR/Module.h" 22 #include "llvm/MC/MCAsmInfo.h" 23 #include "llvm/MC/MCContext.h" 24 #include "llvm/MC/MCInstrInfo.h" 25 #include "llvm/MC/MCObjectFileInfo.h" 26 #include "llvm/MC/MCParser/MCAsmParser.h" 27 #include "llvm/MC/MCParser/MCTargetAsmParser.h" 28 #include "llvm/MC/MCRegisterInfo.h" 29 #include "llvm/MC/MCSubtargetInfo.h" 30 #include "llvm/Object/ObjectFile.h" 31 #include "llvm/Support/MemoryBuffer.h" 32 #include "llvm/Support/SourceMgr.h" 33 #include "llvm/Support/TargetRegistry.h" 34 #include "llvm/Support/raw_ostream.h" 35 using namespace llvm; 36 using namespace object; 37 38 IRObjectFile::IRObjectFile(MemoryBufferRef Object, std::unique_ptr<Module> Mod) 39 : SymbolicFile(Binary::ID_IR, Object), M(std::move(Mod)) { 40 Mang.reset(new Mangler()); 41 CollectAsmUndefinedRefs(Triple(M->getTargetTriple()), M->getModuleInlineAsm(), 42 [this](StringRef Name, BasicSymbolRef::Flags Flags) { 43 AsmSymbols.emplace_back(Name, std::move(Flags)); 44 }); 45 } 46 47 // Parse inline ASM and collect the list of symbols that are not defined in 48 // the current module. This is inspired from IRObjectFile. 49 void IRObjectFile::CollectAsmUndefinedRefs( 50 const Triple &TT, StringRef InlineAsm, 51 function_ref<void(StringRef, BasicSymbolRef::Flags)> AsmUndefinedRefs) { 52 if (InlineAsm.empty()) 53 return; 54 55 std::string Err; 56 const Target *T = TargetRegistry::lookupTarget(TT.str(), Err); 57 if (!T) 58 return; 59 60 std::unique_ptr<MCRegisterInfo> MRI(T->createMCRegInfo(TT.str())); 61 if (!MRI) 62 return; 63 64 std::unique_ptr<MCAsmInfo> MAI(T->createMCAsmInfo(*MRI, TT.str())); 65 if (!MAI) 66 return; 67 68 std::unique_ptr<MCSubtargetInfo> STI( 69 T->createMCSubtargetInfo(TT.str(), "", "")); 70 if (!STI) 71 return; 72 73 std::unique_ptr<MCInstrInfo> MCII(T->createMCInstrInfo()); 74 if (!MCII) 75 return; 76 77 MCObjectFileInfo MOFI; 78 MCContext MCCtx(MAI.get(), MRI.get(), &MOFI); 79 MOFI.InitMCObjectFileInfo(TT, /*PIC*/ false, CodeModel::Default, MCCtx); 80 std::unique_ptr<RecordStreamer> Streamer(new RecordStreamer(MCCtx)); 81 T->createNullTargetStreamer(*Streamer); 82 83 std::unique_ptr<MemoryBuffer> Buffer(MemoryBuffer::getMemBuffer(InlineAsm)); 84 SourceMgr SrcMgr; 85 SrcMgr.AddNewSourceBuffer(std::move(Buffer), SMLoc()); 86 std::unique_ptr<MCAsmParser> Parser( 87 createMCAsmParser(SrcMgr, MCCtx, *Streamer, *MAI)); 88 89 MCTargetOptions MCOptions; 90 std::unique_ptr<MCTargetAsmParser> TAP( 91 T->createMCAsmParser(*STI, *Parser, *MCII, MCOptions)); 92 if (!TAP) 93 return; 94 95 Parser->setTargetParser(*TAP); 96 if (Parser->Run(false)) 97 return; 98 99 for (auto &KV : *Streamer) { 100 StringRef Key = KV.first(); 101 RecordStreamer::State Value = KV.second; 102 uint32_t Res = BasicSymbolRef::SF_None; 103 switch (Value) { 104 case RecordStreamer::NeverSeen: 105 llvm_unreachable("foo"); 106 case RecordStreamer::DefinedGlobal: 107 Res |= BasicSymbolRef::SF_Global; 108 break; 109 case RecordStreamer::Defined: 110 break; 111 case RecordStreamer::Global: 112 case RecordStreamer::Used: 113 Res |= BasicSymbolRef::SF_Undefined; 114 Res |= BasicSymbolRef::SF_Global; 115 break; 116 case RecordStreamer::GlobalWeak: 117 Res |= BasicSymbolRef::SF_Weak; 118 Res |= BasicSymbolRef::SF_Global; 119 break; 120 } 121 AsmUndefinedRefs(Key, BasicSymbolRef::Flags(Res)); 122 } 123 } 124 125 IRObjectFile::~IRObjectFile() { 126 } 127 128 static GlobalValue *getGV(DataRefImpl &Symb) { 129 if ((Symb.p & 3) == 3) 130 return nullptr; 131 132 return reinterpret_cast<GlobalValue*>(Symb.p & ~uintptr_t(3)); 133 } 134 135 static uintptr_t skipEmpty(Module::const_alias_iterator I, const Module &M) { 136 if (I == M.alias_end()) 137 return 3; 138 const GlobalValue *GV = &*I; 139 return reinterpret_cast<uintptr_t>(GV) | 2; 140 } 141 142 static uintptr_t skipEmpty(Module::const_global_iterator I, const Module &M) { 143 if (I == M.global_end()) 144 return skipEmpty(M.alias_begin(), M); 145 const GlobalValue *GV = &*I; 146 return reinterpret_cast<uintptr_t>(GV) | 1; 147 } 148 149 static uintptr_t skipEmpty(Module::const_iterator I, const Module &M) { 150 if (I == M.end()) 151 return skipEmpty(M.global_begin(), M); 152 const GlobalValue *GV = &*I; 153 return reinterpret_cast<uintptr_t>(GV) | 0; 154 } 155 156 static unsigned getAsmSymIndex(DataRefImpl Symb) { 157 assert((Symb.p & uintptr_t(3)) == 3); 158 uintptr_t Index = Symb.p & ~uintptr_t(3); 159 Index >>= 2; 160 return Index; 161 } 162 163 void IRObjectFile::moveSymbolNext(DataRefImpl &Symb) const { 164 const GlobalValue *GV = getGV(Symb); 165 uintptr_t Res; 166 167 switch (Symb.p & 3) { 168 case 0: { 169 Module::const_iterator Iter(static_cast<const Function*>(GV)); 170 ++Iter; 171 Res = skipEmpty(Iter, *M); 172 break; 173 } 174 case 1: { 175 Module::const_global_iterator Iter(static_cast<const GlobalVariable*>(GV)); 176 ++Iter; 177 Res = skipEmpty(Iter, *M); 178 break; 179 } 180 case 2: { 181 Module::const_alias_iterator Iter(static_cast<const GlobalAlias*>(GV)); 182 ++Iter; 183 Res = skipEmpty(Iter, *M); 184 break; 185 } 186 case 3: { 187 unsigned Index = getAsmSymIndex(Symb); 188 assert(Index < AsmSymbols.size()); 189 ++Index; 190 Res = (Index << 2) | 3; 191 break; 192 } 193 default: 194 llvm_unreachable("unreachable case"); 195 } 196 197 Symb.p = Res; 198 } 199 200 std::error_code IRObjectFile::printSymbolName(raw_ostream &OS, 201 DataRefImpl Symb) const { 202 const GlobalValue *GV = getGV(Symb); 203 if (!GV) { 204 unsigned Index = getAsmSymIndex(Symb); 205 assert(Index <= AsmSymbols.size()); 206 OS << AsmSymbols[Index].first; 207 return std::error_code(); 208 } 209 210 if (GV->hasDLLImportStorageClass()) 211 OS << "__imp_"; 212 213 if (Mang) 214 Mang->getNameWithPrefix(OS, GV, false); 215 else 216 OS << GV->getName(); 217 218 return std::error_code(); 219 } 220 221 uint32_t IRObjectFile::getSymbolFlags(DataRefImpl Symb) const { 222 const GlobalValue *GV = getGV(Symb); 223 224 if (!GV) { 225 unsigned Index = getAsmSymIndex(Symb); 226 assert(Index <= AsmSymbols.size()); 227 return AsmSymbols[Index].second; 228 } 229 230 uint32_t Res = BasicSymbolRef::SF_None; 231 if (GV->isDeclarationForLinker()) 232 Res |= BasicSymbolRef::SF_Undefined; 233 else if (GV->hasHiddenVisibility() && !GV->hasLocalLinkage()) 234 Res |= BasicSymbolRef::SF_Hidden; 235 if (const GlobalVariable *GVar = dyn_cast<GlobalVariable>(GV)) { 236 if (GVar->isConstant()) 237 Res |= BasicSymbolRef::SF_Const; 238 } 239 if (GV->hasPrivateLinkage()) 240 Res |= BasicSymbolRef::SF_FormatSpecific; 241 if (!GV->hasLocalLinkage()) 242 Res |= BasicSymbolRef::SF_Global; 243 if (GV->hasCommonLinkage()) 244 Res |= BasicSymbolRef::SF_Common; 245 if (GV->hasLinkOnceLinkage() || GV->hasWeakLinkage() || 246 GV->hasExternalWeakLinkage()) 247 Res |= BasicSymbolRef::SF_Weak; 248 249 if (GV->getName().startswith("llvm.")) 250 Res |= BasicSymbolRef::SF_FormatSpecific; 251 else if (auto *Var = dyn_cast<GlobalVariable>(GV)) { 252 if (Var->getSection() == "llvm.metadata") 253 Res |= BasicSymbolRef::SF_FormatSpecific; 254 } 255 256 return Res; 257 } 258 259 GlobalValue *IRObjectFile::getSymbolGV(DataRefImpl Symb) { return getGV(Symb); } 260 261 std::unique_ptr<Module> IRObjectFile::takeModule() { return std::move(M); } 262 263 basic_symbol_iterator IRObjectFile::symbol_begin_impl() const { 264 Module::const_iterator I = M->begin(); 265 DataRefImpl Ret; 266 Ret.p = skipEmpty(I, *M); 267 return basic_symbol_iterator(BasicSymbolRef(Ret, this)); 268 } 269 270 basic_symbol_iterator IRObjectFile::symbol_end_impl() const { 271 DataRefImpl Ret; 272 uint64_t NumAsm = AsmSymbols.size(); 273 NumAsm <<= 2; 274 Ret.p = 3 | NumAsm; 275 return basic_symbol_iterator(BasicSymbolRef(Ret, this)); 276 } 277 278 ErrorOr<MemoryBufferRef> IRObjectFile::findBitcodeInObject(const ObjectFile &Obj) { 279 for (const SectionRef &Sec : Obj.sections()) { 280 if (Sec.isBitcode()) { 281 StringRef SecContents; 282 if (std::error_code EC = Sec.getContents(SecContents)) 283 return EC; 284 return MemoryBufferRef(SecContents, Obj.getFileName()); 285 } 286 } 287 288 return object_error::bitcode_section_not_found; 289 } 290 291 ErrorOr<MemoryBufferRef> IRObjectFile::findBitcodeInMemBuffer(MemoryBufferRef Object) { 292 sys::fs::file_magic Type = sys::fs::identify_magic(Object.getBuffer()); 293 switch (Type) { 294 case sys::fs::file_magic::bitcode: 295 return Object; 296 case sys::fs::file_magic::elf_relocatable: 297 case sys::fs::file_magic::macho_object: 298 case sys::fs::file_magic::coff_object: { 299 Expected<std::unique_ptr<ObjectFile>> ObjFile = 300 ObjectFile::createObjectFile(Object, Type); 301 if (!ObjFile) 302 return errorToErrorCode(ObjFile.takeError()); 303 return findBitcodeInObject(*ObjFile->get()); 304 } 305 default: 306 return object_error::invalid_file_type; 307 } 308 } 309 310 ErrorOr<std::unique_ptr<IRObjectFile>> 311 llvm::object::IRObjectFile::create(MemoryBufferRef Object, 312 LLVMContext &Context) { 313 ErrorOr<MemoryBufferRef> BCOrErr = findBitcodeInMemBuffer(Object); 314 if (!BCOrErr) 315 return BCOrErr.getError(); 316 317 std::unique_ptr<MemoryBuffer> Buff = 318 MemoryBuffer::getMemBuffer(BCOrErr.get(), false); 319 320 ErrorOr<std::unique_ptr<Module>> MOrErr = 321 getLazyBitcodeModule(std::move(Buff), Context, 322 /*ShouldLazyLoadMetadata*/ true); 323 if (std::error_code EC = MOrErr.getError()) 324 return EC; 325 326 std::unique_ptr<Module> &M = MOrErr.get(); 327 return llvm::make_unique<IRObjectFile>(Object, std::move(M)); 328 } 329