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