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/LLVMContext.h" 18 #include "llvm/IR/GVMaterializer.h" 19 #include "llvm/IR/Mangler.h" 20 #include "llvm/IR/Module.h" 21 #include "llvm/MC/MCRegisterInfo.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/MCTargetAsmParser.h" 27 #include "llvm/MC/MCParser/MCAsmParser.h" 28 #include "llvm/Support/MemoryBuffer.h" 29 #include "llvm/Support/SourceMgr.h" 30 #include "llvm/Support/TargetRegistry.h" 31 #include "llvm/Support/raw_ostream.h" 32 using namespace llvm; 33 using namespace object; 34 35 IRObjectFile::IRObjectFile(MemoryBufferRef Object, std::unique_ptr<Module> Mod) 36 : SymbolicFile(Binary::ID_IR, Object), M(std::move(Mod)) { 37 // If we have a DataLayout, setup a mangler. 38 const DataLayout *DL = M->getDataLayout(); 39 if (!DL) 40 return; 41 42 Mang.reset(new Mangler(DL)); 43 44 const std::string &InlineAsm = M->getModuleInlineAsm(); 45 if (InlineAsm.empty()) 46 return; 47 48 StringRef Triple = M->getTargetTriple(); 49 std::string Err; 50 const Target *T = TargetRegistry::lookupTarget(Triple, Err); 51 if (!T) 52 return; 53 54 std::unique_ptr<MCRegisterInfo> MRI(T->createMCRegInfo(Triple)); 55 if (!MRI) 56 return; 57 58 std::unique_ptr<MCAsmInfo> MAI(T->createMCAsmInfo(*MRI, Triple)); 59 if (!MAI) 60 return; 61 62 std::unique_ptr<MCSubtargetInfo> STI( 63 T->createMCSubtargetInfo(Triple, "", "")); 64 if (!STI) 65 return; 66 67 std::unique_ptr<MCInstrInfo> MCII(T->createMCInstrInfo()); 68 if (!MCII) 69 return; 70 71 MCObjectFileInfo MOFI; 72 MCContext MCCtx(MAI.get(), MRI.get(), &MOFI); 73 MOFI.InitMCObjectFileInfo(Triple, Reloc::Default, CodeModel::Default, MCCtx); 74 std::unique_ptr<RecordStreamer> Streamer(new RecordStreamer(MCCtx)); 75 76 std::unique_ptr<MemoryBuffer> Buffer(MemoryBuffer::getMemBuffer(InlineAsm)); 77 SourceMgr SrcMgr; 78 SrcMgr.AddNewSourceBuffer(std::move(Buffer), SMLoc()); 79 std::unique_ptr<MCAsmParser> Parser( 80 createMCAsmParser(SrcMgr, MCCtx, *Streamer, *MAI)); 81 82 MCTargetOptions MCOptions; 83 std::unique_ptr<MCTargetAsmParser> TAP( 84 T->createMCAsmParser(*STI, *Parser, *MCII, MCOptions)); 85 if (!TAP) 86 return; 87 88 Parser->setTargetParser(*TAP); 89 if (Parser->Run(false)) 90 return; 91 92 for (auto &KV : *Streamer) { 93 StringRef Key = KV.first(); 94 RecordStreamer::State Value = KV.second; 95 uint32_t Res = BasicSymbolRef::SF_None; 96 switch (Value) { 97 case RecordStreamer::NeverSeen: 98 llvm_unreachable("foo"); 99 case RecordStreamer::DefinedGlobal: 100 Res |= BasicSymbolRef::SF_Global; 101 break; 102 case RecordStreamer::Defined: 103 break; 104 case RecordStreamer::Global: 105 case RecordStreamer::Used: 106 Res |= BasicSymbolRef::SF_Undefined; 107 Res |= BasicSymbolRef::SF_Global; 108 break; 109 } 110 AsmSymbols.push_back( 111 std::make_pair<std::string, uint32_t>(Key, std::move(Res))); 112 } 113 } 114 115 IRObjectFile::~IRObjectFile() { 116 } 117 118 static const GlobalValue *getGV(DataRefImpl &Symb) { 119 if ((Symb.p & 3) == 3) 120 return nullptr; 121 122 return reinterpret_cast<GlobalValue*>(Symb.p & ~uintptr_t(3)); 123 } 124 125 static uintptr_t skipEmpty(Module::const_alias_iterator I, const Module &M) { 126 if (I == M.alias_end()) 127 return 3; 128 const GlobalValue *GV = &*I; 129 return reinterpret_cast<uintptr_t>(GV) | 2; 130 } 131 132 static uintptr_t skipEmpty(Module::const_global_iterator I, const Module &M) { 133 if (I == M.global_end()) 134 return skipEmpty(M.alias_begin(), M); 135 const GlobalValue *GV = &*I; 136 return reinterpret_cast<uintptr_t>(GV) | 1; 137 } 138 139 static uintptr_t skipEmpty(Module::const_iterator I, const Module &M) { 140 if (I == M.end()) 141 return skipEmpty(M.global_begin(), M); 142 const GlobalValue *GV = &*I; 143 return reinterpret_cast<uintptr_t>(GV) | 0; 144 } 145 146 static unsigned getAsmSymIndex(DataRefImpl Symb) { 147 assert((Symb.p & uintptr_t(3)) == 3); 148 uintptr_t Index = Symb.p & ~uintptr_t(3); 149 Index >>= 2; 150 return Index; 151 } 152 153 void IRObjectFile::moveSymbolNext(DataRefImpl &Symb) const { 154 const GlobalValue *GV = getGV(Symb); 155 uintptr_t Res; 156 157 switch (Symb.p & 3) { 158 case 0: { 159 Module::const_iterator Iter(static_cast<const Function*>(GV)); 160 ++Iter; 161 Res = skipEmpty(Iter, *M); 162 break; 163 } 164 case 1: { 165 Module::const_global_iterator Iter(static_cast<const GlobalVariable*>(GV)); 166 ++Iter; 167 Res = skipEmpty(Iter, *M); 168 break; 169 } 170 case 2: { 171 Module::const_alias_iterator Iter(static_cast<const GlobalAlias*>(GV)); 172 ++Iter; 173 Res = skipEmpty(Iter, *M); 174 break; 175 } 176 case 3: { 177 unsigned Index = getAsmSymIndex(Symb); 178 assert(Index < AsmSymbols.size()); 179 ++Index; 180 Res = (Index << 2) | 3; 181 break; 182 } 183 } 184 185 Symb.p = Res; 186 } 187 188 std::error_code IRObjectFile::printSymbolName(raw_ostream &OS, 189 DataRefImpl Symb) const { 190 const GlobalValue *GV = getGV(Symb); 191 if (!GV) { 192 unsigned Index = getAsmSymIndex(Symb); 193 assert(Index <= AsmSymbols.size()); 194 OS << AsmSymbols[Index].first; 195 return object_error::success;; 196 } 197 198 if (Mang) 199 Mang->getNameWithPrefix(OS, GV, false); 200 else 201 OS << GV->getName(); 202 203 return object_error::success; 204 } 205 206 static bool isDeclaration(const GlobalValue &V) { 207 if (V.hasAvailableExternallyLinkage()) 208 return true; 209 210 if (V.isMaterializable()) 211 return false; 212 213 return V.isDeclaration(); 214 } 215 216 uint32_t IRObjectFile::getSymbolFlags(DataRefImpl Symb) const { 217 const GlobalValue *GV = getGV(Symb); 218 219 if (!GV) { 220 unsigned Index = getAsmSymIndex(Symb); 221 assert(Index <= AsmSymbols.size()); 222 return AsmSymbols[Index].second; 223 } 224 225 uint32_t Res = BasicSymbolRef::SF_None; 226 if (isDeclaration(*GV)) 227 Res |= BasicSymbolRef::SF_Undefined; 228 if (GV->hasPrivateLinkage()) 229 Res |= BasicSymbolRef::SF_FormatSpecific; 230 if (!GV->hasLocalLinkage()) 231 Res |= BasicSymbolRef::SF_Global; 232 if (GV->hasCommonLinkage()) 233 Res |= BasicSymbolRef::SF_Common; 234 if (GV->hasLinkOnceLinkage() || GV->hasWeakLinkage()) 235 Res |= BasicSymbolRef::SF_Weak; 236 237 if (GV->getName().startswith("llvm.")) 238 Res |= BasicSymbolRef::SF_FormatSpecific; 239 else if (auto *Var = dyn_cast<GlobalVariable>(GV)) { 240 if (Var->getSection() == StringRef("llvm.metadata")) 241 Res |= BasicSymbolRef::SF_FormatSpecific; 242 } 243 244 return Res; 245 } 246 247 const GlobalValue *IRObjectFile::getSymbolGV(DataRefImpl Symb) const { 248 const GlobalValue *GV = getGV(Symb); 249 return GV; 250 } 251 252 basic_symbol_iterator IRObjectFile::symbol_begin_impl() const { 253 Module::const_iterator I = M->begin(); 254 DataRefImpl Ret; 255 Ret.p = skipEmpty(I, *M); 256 return basic_symbol_iterator(BasicSymbolRef(Ret, this)); 257 } 258 259 basic_symbol_iterator IRObjectFile::symbol_end_impl() const { 260 DataRefImpl Ret; 261 uint64_t NumAsm = AsmSymbols.size(); 262 NumAsm <<= 2; 263 Ret.p = 3 | NumAsm; 264 return basic_symbol_iterator(BasicSymbolRef(Ret, this)); 265 } 266 267 ErrorOr<IRObjectFile *> 268 llvm::object::IRObjectFile::createIRObjectFile(MemoryBufferRef Object, 269 LLVMContext &Context) { 270 271 StringRef Data = Object.getBuffer(); 272 StringRef FileName = Object.getBufferIdentifier(); 273 std::unique_ptr<MemoryBuffer> Buff( 274 MemoryBuffer::getMemBuffer(Data, FileName, false)); 275 276 ErrorOr<Module *> MOrErr = getLazyBitcodeModule(Buff.get(), Context); 277 if (std::error_code EC = MOrErr.getError()) 278 return EC; 279 Buff.release(); 280 281 std::unique_ptr<Module> M(MOrErr.get()); 282 return new IRObjectFile(Object, std::move(M)); 283 } 284