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