IRObjectFile.cpp (276479) | IRObjectFile.cpp (280031) |
---|---|
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" | 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" | 17#include "llvm/IR/GVMaterializer.h" |
18#include "llvm/IR/LLVMContext.h" |
|
19#include "llvm/IR/Mangler.h" 20#include "llvm/IR/Module.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" | 21#include "llvm/MC/MCAsmInfo.h" 22#include "llvm/MC/MCContext.h" 23#include "llvm/MC/MCInstrInfo.h" 24#include "llvm/MC/MCObjectFileInfo.h" |
26#include "llvm/MC/MCTargetAsmParser.h" | |
27#include "llvm/MC/MCParser/MCAsmParser.h" | 25#include "llvm/MC/MCParser/MCAsmParser.h" |
26#include "llvm/MC/MCRegisterInfo.h" 27#include "llvm/MC/MCTargetAsmParser.h" 28#include "llvm/Object/ObjectFile.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" 32using namespace llvm; 33using namespace object; 34 | 29#include "llvm/Support/MemoryBuffer.h" 30#include "llvm/Support/SourceMgr.h" 31#include "llvm/Support/TargetRegistry.h" 32#include "llvm/Support/raw_ostream.h" 33using namespace llvm; 34using namespace object; 35 |
35IRObjectFile::IRObjectFile(std::unique_ptr<MemoryBuffer> Object, 36 std::unique_ptr<Module> Mod) 37 : SymbolicFile(Binary::ID_IR, std::move(Object)), M(std::move(Mod)) { | 36IRObjectFile::IRObjectFile(MemoryBufferRef Object, std::unique_ptr<Module> Mod) 37 : SymbolicFile(Binary::ID_IR, Object), M(std::move(Mod)) { |
38 // If we have a DataLayout, setup a mangler. 39 const DataLayout *DL = M->getDataLayout(); 40 if (!DL) 41 return; 42 43 Mang.reset(new Mangler(DL)); 44 45 const std::string &InlineAsm = M->getModuleInlineAsm(); --- 25 unchanged lines hidden (view full) --- 71 72 MCObjectFileInfo MOFI; 73 MCContext MCCtx(MAI.get(), MRI.get(), &MOFI); 74 MOFI.InitMCObjectFileInfo(Triple, Reloc::Default, CodeModel::Default, MCCtx); 75 std::unique_ptr<RecordStreamer> Streamer(new RecordStreamer(MCCtx)); 76 77 std::unique_ptr<MemoryBuffer> Buffer(MemoryBuffer::getMemBuffer(InlineAsm)); 78 SourceMgr SrcMgr; | 38 // If we have a DataLayout, setup a mangler. 39 const DataLayout *DL = M->getDataLayout(); 40 if (!DL) 41 return; 42 43 Mang.reset(new Mangler(DL)); 44 45 const std::string &InlineAsm = M->getModuleInlineAsm(); --- 25 unchanged lines hidden (view full) --- 71 72 MCObjectFileInfo MOFI; 73 MCContext MCCtx(MAI.get(), MRI.get(), &MOFI); 74 MOFI.InitMCObjectFileInfo(Triple, Reloc::Default, CodeModel::Default, MCCtx); 75 std::unique_ptr<RecordStreamer> Streamer(new RecordStreamer(MCCtx)); 76 77 std::unique_ptr<MemoryBuffer> Buffer(MemoryBuffer::getMemBuffer(InlineAsm)); 78 SourceMgr SrcMgr; |
79 SrcMgr.AddNewSourceBuffer(Buffer.release(), SMLoc()); | 79 SrcMgr.AddNewSourceBuffer(std::move(Buffer), SMLoc()); |
80 std::unique_ptr<MCAsmParser> Parser( 81 createMCAsmParser(SrcMgr, MCCtx, *Streamer, *MAI)); 82 83 MCTargetOptions MCOptions; 84 std::unique_ptr<MCTargetAsmParser> TAP( 85 T->createMCAsmParser(*STI, *Parser, *MCII, MCOptions)); 86 if (!TAP) 87 return; --- 21 unchanged lines hidden (view full) --- 109 break; 110 } 111 AsmSymbols.push_back( 112 std::make_pair<std::string, uint32_t>(Key, std::move(Res))); 113 } 114} 115 116IRObjectFile::~IRObjectFile() { | 80 std::unique_ptr<MCAsmParser> Parser( 81 createMCAsmParser(SrcMgr, MCCtx, *Streamer, *MAI)); 82 83 MCTargetOptions MCOptions; 84 std::unique_ptr<MCTargetAsmParser> TAP( 85 T->createMCAsmParser(*STI, *Parser, *MCII, MCOptions)); 86 if (!TAP) 87 return; --- 21 unchanged lines hidden (view full) --- 109 break; 110 } 111 AsmSymbols.push_back( 112 std::make_pair<std::string, uint32_t>(Key, std::move(Res))); 113 } 114} 115 116IRObjectFile::~IRObjectFile() { |
117 GVMaterializer *GVM = M->getMaterializer(); 118 if (GVM) 119 GVM->releaseBuffer(); | |
120 } 121 | 117 } 118 |
122static const GlobalValue *getGV(DataRefImpl &Symb) { | 119static GlobalValue *getGV(DataRefImpl &Symb) { |
123 if ((Symb.p & 3) == 3) 124 return nullptr; 125 126 return reinterpret_cast<GlobalValue*>(Symb.p & ~uintptr_t(3)); 127} 128 129static uintptr_t skipEmpty(Module::const_alias_iterator I, const Module &M) { 130 if (I == M.alias_end()) --- 48 unchanged lines hidden (view full) --- 179 } 180 case 3: { 181 unsigned Index = getAsmSymIndex(Symb); 182 assert(Index < AsmSymbols.size()); 183 ++Index; 184 Res = (Index << 2) | 3; 185 break; 186 } | 120 if ((Symb.p & 3) == 3) 121 return nullptr; 122 123 return reinterpret_cast<GlobalValue*>(Symb.p & ~uintptr_t(3)); 124} 125 126static uintptr_t skipEmpty(Module::const_alias_iterator I, const Module &M) { 127 if (I == M.alias_end()) --- 48 unchanged lines hidden (view full) --- 176 } 177 case 3: { 178 unsigned Index = getAsmSymIndex(Symb); 179 assert(Index < AsmSymbols.size()); 180 ++Index; 181 Res = (Index << 2) | 3; 182 break; 183 } |
184 default: 185 llvm_unreachable("unreachable case"); |
|
187 } 188 189 Symb.p = Res; 190} 191 192std::error_code IRObjectFile::printSymbolName(raw_ostream &OS, 193 DataRefImpl Symb) const { 194 const GlobalValue *GV = getGV(Symb); --- 7 unchanged lines hidden (view full) --- 202 if (Mang) 203 Mang->getNameWithPrefix(OS, GV, false); 204 else 205 OS << GV->getName(); 206 207 return object_error::success; 208} 209 | 186 } 187 188 Symb.p = Res; 189} 190 191std::error_code IRObjectFile::printSymbolName(raw_ostream &OS, 192 DataRefImpl Symb) const { 193 const GlobalValue *GV = getGV(Symb); --- 7 unchanged lines hidden (view full) --- 201 if (Mang) 202 Mang->getNameWithPrefix(OS, GV, false); 203 else 204 OS << GV->getName(); 205 206 return object_error::success; 207} 208 |
210static bool isDeclaration(const GlobalValue &V) { 211 if (V.hasAvailableExternallyLinkage()) 212 return true; 213 214 if (V.isMaterializable()) 215 return false; 216 217 return V.isDeclaration(); 218} 219 | |
220uint32_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; | 209uint32_t IRObjectFile::getSymbolFlags(DataRefImpl Symb) const { 210 const GlobalValue *GV = getGV(Symb); 211 212 if (!GV) { 213 unsigned Index = getAsmSymIndex(Symb); 214 assert(Index <= AsmSymbols.size()); 215 return AsmSymbols[Index].second; 216 } 217 218 uint32_t Res = BasicSymbolRef::SF_None; |
230 if (isDeclaration(*GV)) | 219 if (GV->isDeclarationForLinker()) |
231 Res |= BasicSymbolRef::SF_Undefined; 232 if (GV->hasPrivateLinkage()) 233 Res |= BasicSymbolRef::SF_FormatSpecific; 234 if (!GV->hasLocalLinkage()) 235 Res |= BasicSymbolRef::SF_Global; 236 if (GV->hasCommonLinkage()) 237 Res |= BasicSymbolRef::SF_Common; 238 if (GV->hasLinkOnceLinkage() || GV->hasWeakLinkage()) --- 4 unchanged lines hidden (view full) --- 243 else if (auto *Var = dyn_cast<GlobalVariable>(GV)) { 244 if (Var->getSection() == StringRef("llvm.metadata")) 245 Res |= BasicSymbolRef::SF_FormatSpecific; 246 } 247 248 return Res; 249} 250 | 220 Res |= BasicSymbolRef::SF_Undefined; 221 if (GV->hasPrivateLinkage()) 222 Res |= BasicSymbolRef::SF_FormatSpecific; 223 if (!GV->hasLocalLinkage()) 224 Res |= BasicSymbolRef::SF_Global; 225 if (GV->hasCommonLinkage()) 226 Res |= BasicSymbolRef::SF_Common; 227 if (GV->hasLinkOnceLinkage() || GV->hasWeakLinkage()) --- 4 unchanged lines hidden (view full) --- 232 else if (auto *Var = dyn_cast<GlobalVariable>(GV)) { 233 if (Var->getSection() == StringRef("llvm.metadata")) 234 Res |= BasicSymbolRef::SF_FormatSpecific; 235 } 236 237 return Res; 238} 239 |
251const GlobalValue *IRObjectFile::getSymbolGV(DataRefImpl Symb) const { 252 const GlobalValue *GV = getGV(Symb); 253 return GV; 254} | 240GlobalValue *IRObjectFile::getSymbolGV(DataRefImpl Symb) { return getGV(Symb); } |
255 | 241 |
242std::unique_ptr<Module> IRObjectFile::takeModule() { return std::move(M); } 243 |
|
256basic_symbol_iterator IRObjectFile::symbol_begin_impl() const { 257 Module::const_iterator I = M->begin(); 258 DataRefImpl Ret; 259 Ret.p = skipEmpty(I, *M); 260 return basic_symbol_iterator(BasicSymbolRef(Ret, this)); 261} 262 263basic_symbol_iterator IRObjectFile::symbol_end_impl() const { 264 DataRefImpl Ret; 265 uint64_t NumAsm = AsmSymbols.size(); 266 NumAsm <<= 2; 267 Ret.p = 3 | NumAsm; 268 return basic_symbol_iterator(BasicSymbolRef(Ret, this)); 269} 270 | 244basic_symbol_iterator IRObjectFile::symbol_begin_impl() const { 245 Module::const_iterator I = M->begin(); 246 DataRefImpl Ret; 247 Ret.p = skipEmpty(I, *M); 248 return basic_symbol_iterator(BasicSymbolRef(Ret, this)); 249} 250 251basic_symbol_iterator IRObjectFile::symbol_end_impl() const { 252 DataRefImpl Ret; 253 uint64_t NumAsm = AsmSymbols.size(); 254 NumAsm <<= 2; 255 Ret.p = 3 | NumAsm; 256 return basic_symbol_iterator(BasicSymbolRef(Ret, this)); 257} 258 |
271ErrorOr<IRObjectFile *> llvm::object::IRObjectFile::createIRObjectFile( 272 std::unique_ptr<MemoryBuffer> Object, LLVMContext &Context) { 273 ErrorOr<Module *> MOrErr = getLazyBitcodeModule(Object.get(), Context); | 259ErrorOr<MemoryBufferRef> IRObjectFile::findBitcodeInObject(const ObjectFile &Obj) { 260 for (const SectionRef &Sec : Obj.sections()) { 261 StringRef SecName; 262 if (std::error_code EC = Sec.getName(SecName)) 263 return EC; 264 if (SecName == ".llvmbc") { 265 StringRef SecContents; 266 if (std::error_code EC = Sec.getContents(SecContents)) 267 return EC; 268 return MemoryBufferRef(SecContents, Obj.getFileName()); 269 } 270 } 271 272 return object_error::bitcode_section_not_found; 273} 274 275ErrorOr<MemoryBufferRef> IRObjectFile::findBitcodeInMemBuffer(MemoryBufferRef Object) { 276 sys::fs::file_magic Type = sys::fs::identify_magic(Object.getBuffer()); 277 switch (Type) { 278 case sys::fs::file_magic::bitcode: 279 return Object; 280 case sys::fs::file_magic::elf_relocatable: 281 case sys::fs::file_magic::macho_object: 282 case sys::fs::file_magic::coff_object: { 283 ErrorOr<std::unique_ptr<ObjectFile>> ObjFile = 284 ObjectFile::createObjectFile(Object, Type); 285 if (!ObjFile) 286 return ObjFile.getError(); 287 return findBitcodeInObject(*ObjFile->get()); 288 } 289 default: 290 return object_error::invalid_file_type; 291 } 292} 293 294ErrorOr<std::unique_ptr<IRObjectFile>> 295llvm::object::IRObjectFile::create(MemoryBufferRef Object, 296 LLVMContext &Context) { 297 ErrorOr<MemoryBufferRef> BCOrErr = findBitcodeInMemBuffer(Object); 298 if (!BCOrErr) 299 return BCOrErr.getError(); 300 301 std::unique_ptr<MemoryBuffer> Buff( 302 MemoryBuffer::getMemBuffer(BCOrErr.get(), false)); 303 304 ErrorOr<Module *> MOrErr = getLazyBitcodeModule(std::move(Buff), Context); |
274 if (std::error_code EC = MOrErr.getError()) 275 return EC; 276 277 std::unique_ptr<Module> M(MOrErr.get()); | 305 if (std::error_code EC = MOrErr.getError()) 306 return EC; 307 308 std::unique_ptr<Module> M(MOrErr.get()); |
278 return new IRObjectFile(std::move(Object), std::move(M)); | 309 return llvm::make_unique<IRObjectFile>(Object, std::move(M)); |
279} | 310} |