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, /*PIC*/ false, 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 case RecordStreamer::GlobalWeak: 120 Res |= BasicSymbolRef::SF_Weak; 121 Res |= BasicSymbolRef::SF_Global; 122 break; 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>(Object, std::move(M)); 331 } 332