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