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/BitcodeReader.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 42 for (Function &F : *M) 43 SymTab.push_back(&F); 44 for (GlobalVariable &GV : M->globals()) 45 SymTab.push_back(&GV); 46 for (GlobalAlias &GA : M->aliases()) 47 SymTab.push_back(&GA); 48 49 CollectAsmUndefinedRefs(Triple(M->getTargetTriple()), M->getModuleInlineAsm(), 50 [this](StringRef Name, BasicSymbolRef::Flags Flags) { 51 SymTab.push_back(new (AsmSymbols.Allocate()) 52 AsmSymbol(Name, Flags)); 53 }); 54 } 55 56 // Parse inline ASM and collect the list of symbols that are not defined in 57 // the current module. This is inspired from IRObjectFile. 58 void IRObjectFile::CollectAsmUndefinedRefs( 59 const Triple &TT, StringRef InlineAsm, 60 function_ref<void(StringRef, BasicSymbolRef::Flags)> AsmUndefinedRefs) { 61 if (InlineAsm.empty()) 62 return; 63 64 std::string Err; 65 const Target *T = TargetRegistry::lookupTarget(TT.str(), Err); 66 assert(T && T->hasMCAsmParser()); 67 68 std::unique_ptr<MCRegisterInfo> MRI(T->createMCRegInfo(TT.str())); 69 if (!MRI) 70 return; 71 72 std::unique_ptr<MCAsmInfo> MAI(T->createMCAsmInfo(*MRI, TT.str())); 73 if (!MAI) 74 return; 75 76 std::unique_ptr<MCSubtargetInfo> STI( 77 T->createMCSubtargetInfo(TT.str(), "", "")); 78 if (!STI) 79 return; 80 81 std::unique_ptr<MCInstrInfo> MCII(T->createMCInstrInfo()); 82 if (!MCII) 83 return; 84 85 MCObjectFileInfo MOFI; 86 MCContext MCCtx(MAI.get(), MRI.get(), &MOFI); 87 MOFI.InitMCObjectFileInfo(TT, /*PIC*/ false, CodeModel::Default, MCCtx); 88 RecordStreamer Streamer(MCCtx); 89 T->createNullTargetStreamer(Streamer); 90 91 std::unique_ptr<MemoryBuffer> Buffer(MemoryBuffer::getMemBuffer(InlineAsm)); 92 SourceMgr SrcMgr; 93 SrcMgr.AddNewSourceBuffer(std::move(Buffer), SMLoc()); 94 std::unique_ptr<MCAsmParser> Parser( 95 createMCAsmParser(SrcMgr, MCCtx, Streamer, *MAI)); 96 97 MCTargetOptions MCOptions; 98 std::unique_ptr<MCTargetAsmParser> TAP( 99 T->createMCAsmParser(*STI, *Parser, *MCII, MCOptions)); 100 if (!TAP) 101 return; 102 103 Parser->setTargetParser(*TAP); 104 if (Parser->Run(false)) 105 return; 106 107 for (auto &KV : Streamer) { 108 StringRef Key = KV.first(); 109 RecordStreamer::State Value = KV.second; 110 uint32_t Res = BasicSymbolRef::SF_None; 111 switch (Value) { 112 case RecordStreamer::NeverSeen: 113 llvm_unreachable("NeverSeen should have been replaced earlier"); 114 case RecordStreamer::DefinedGlobal: 115 Res |= BasicSymbolRef::SF_Global; 116 break; 117 case RecordStreamer::Defined: 118 break; 119 case RecordStreamer::Global: 120 case RecordStreamer::Used: 121 Res |= BasicSymbolRef::SF_Undefined; 122 Res |= BasicSymbolRef::SF_Global; 123 break; 124 case RecordStreamer::DefinedWeak: 125 Res |= BasicSymbolRef::SF_Weak; 126 Res |= BasicSymbolRef::SF_Global; 127 break; 128 case RecordStreamer::UndefinedWeak: 129 Res |= BasicSymbolRef::SF_Weak; 130 Res |= BasicSymbolRef::SF_Undefined; 131 } 132 AsmUndefinedRefs(Key, BasicSymbolRef::Flags(Res)); 133 } 134 } 135 136 IRObjectFile::~IRObjectFile() {} 137 138 void IRObjectFile::moveSymbolNext(DataRefImpl &Symb) const { 139 Symb.p += sizeof(Sym); 140 } 141 142 std::error_code IRObjectFile::printSymbolName(raw_ostream &OS, 143 DataRefImpl Symb) const { 144 Sym S = getSym(Symb); 145 if (S.is<AsmSymbol *>()) { 146 OS << S.get<AsmSymbol *>()->first; 147 return std::error_code(); 148 } 149 150 auto *GV = S.get<GlobalValue *>(); 151 if (GV->hasDLLImportStorageClass()) 152 OS << "__imp_"; 153 154 if (Mang) 155 Mang->getNameWithPrefix(OS, GV, false); 156 else 157 OS << GV->getName(); 158 159 return std::error_code(); 160 } 161 162 uint32_t IRObjectFile::getSymbolFlags(DataRefImpl Symb) const { 163 Sym S = getSym(Symb); 164 if (S.is<AsmSymbol *>()) 165 return S.get<AsmSymbol *>()->second; 166 167 auto *GV = S.get<GlobalValue *>(); 168 169 uint32_t Res = BasicSymbolRef::SF_None; 170 if (GV->isDeclarationForLinker()) 171 Res |= BasicSymbolRef::SF_Undefined; 172 else if (GV->hasHiddenVisibility() && !GV->hasLocalLinkage()) 173 Res |= BasicSymbolRef::SF_Hidden; 174 if (const GlobalVariable *GVar = dyn_cast<GlobalVariable>(GV)) { 175 if (GVar->isConstant()) 176 Res |= BasicSymbolRef::SF_Const; 177 } 178 if (GV->hasPrivateLinkage()) 179 Res |= BasicSymbolRef::SF_FormatSpecific; 180 if (!GV->hasLocalLinkage()) 181 Res |= BasicSymbolRef::SF_Global; 182 if (GV->hasCommonLinkage()) 183 Res |= BasicSymbolRef::SF_Common; 184 if (GV->hasLinkOnceLinkage() || GV->hasWeakLinkage() || 185 GV->hasExternalWeakLinkage()) 186 Res |= BasicSymbolRef::SF_Weak; 187 188 if (GV->getName().startswith("llvm.")) 189 Res |= BasicSymbolRef::SF_FormatSpecific; 190 else if (auto *Var = dyn_cast<GlobalVariable>(GV)) { 191 if (Var->getSection() == "llvm.metadata") 192 Res |= BasicSymbolRef::SF_FormatSpecific; 193 } 194 195 return Res; 196 } 197 198 GlobalValue *IRObjectFile::getSymbolGV(DataRefImpl Symb) { 199 return getSym(Symb).dyn_cast<GlobalValue *>(); 200 } 201 202 std::unique_ptr<Module> IRObjectFile::takeModule() { return std::move(M); } 203 204 basic_symbol_iterator IRObjectFile::symbol_begin() const { 205 DataRefImpl Ret; 206 Ret.p = reinterpret_cast<uintptr_t>(SymTab.data()); 207 return basic_symbol_iterator(BasicSymbolRef(Ret, this)); 208 } 209 210 basic_symbol_iterator IRObjectFile::symbol_end() const { 211 DataRefImpl Ret; 212 Ret.p = reinterpret_cast<uintptr_t>(SymTab.data() + SymTab.size()); 213 return basic_symbol_iterator(BasicSymbolRef(Ret, this)); 214 } 215 216 ErrorOr<MemoryBufferRef> IRObjectFile::findBitcodeInObject(const ObjectFile &Obj) { 217 for (const SectionRef &Sec : Obj.sections()) { 218 if (Sec.isBitcode()) { 219 StringRef SecContents; 220 if (std::error_code EC = Sec.getContents(SecContents)) 221 return EC; 222 return MemoryBufferRef(SecContents, Obj.getFileName()); 223 } 224 } 225 226 return object_error::bitcode_section_not_found; 227 } 228 229 ErrorOr<MemoryBufferRef> IRObjectFile::findBitcodeInMemBuffer(MemoryBufferRef Object) { 230 sys::fs::file_magic Type = sys::fs::identify_magic(Object.getBuffer()); 231 switch (Type) { 232 case sys::fs::file_magic::bitcode: 233 return Object; 234 case sys::fs::file_magic::elf_relocatable: 235 case sys::fs::file_magic::macho_object: 236 case sys::fs::file_magic::coff_object: { 237 Expected<std::unique_ptr<ObjectFile>> ObjFile = 238 ObjectFile::createObjectFile(Object, Type); 239 if (!ObjFile) 240 return errorToErrorCode(ObjFile.takeError()); 241 return findBitcodeInObject(*ObjFile->get()); 242 } 243 default: 244 return object_error::invalid_file_type; 245 } 246 } 247 248 Expected<std::unique_ptr<IRObjectFile>> 249 llvm::object::IRObjectFile::create(MemoryBufferRef Object, 250 LLVMContext &Context) { 251 ErrorOr<MemoryBufferRef> BCOrErr = findBitcodeInMemBuffer(Object); 252 if (!BCOrErr) 253 return errorCodeToError(BCOrErr.getError()); 254 255 Expected<std::unique_ptr<Module>> MOrErr = 256 getLazyBitcodeModule(*BCOrErr, Context, 257 /*ShouldLazyLoadMetadata*/ true); 258 if (!MOrErr) 259 return MOrErr.takeError(); 260 261 std::unique_ptr<Module> &M = MOrErr.get(); 262 return llvm::make_unique<IRObjectFile>(BCOrErr.get(), std::move(M)); 263 } 264