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