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