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