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