1 //===- IRObjectFile.cpp - IR object file implementation ---------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // Part of the IRObjectFile class implementation.
12 //===----------------------------------------------------------------------===//
14 #include "llvm/Object/IRObjectFile.h"
15 #include "RecordStreamer.h"
16 #include "llvm/ADT/STLExtras.h"
17 #include "llvm/BinaryFormat/Magic.h"
18 #include "llvm/Bitcode/BitcodeReader.h"
19 #include "llvm/IR/GVMaterializer.h"
20 #include "llvm/IR/LLVMContext.h"
21 #include "llvm/IR/Mangler.h"
22 #include "llvm/IR/Module.h"
23 #include "llvm/MC/MCAsmInfo.h"
24 #include "llvm/MC/MCContext.h"
25 #include "llvm/MC/MCInstrInfo.h"
26 #include "llvm/MC/MCObjectFileInfo.h"
27 #include "llvm/MC/MCParser/MCAsmParser.h"
28 #include "llvm/MC/MCParser/MCTargetAsmParser.h"
29 #include "llvm/MC/MCRegisterInfo.h"
30 #include "llvm/MC/MCSubtargetInfo.h"
31 #include "llvm/Object/ObjectFile.h"
32 #include "llvm/Support/MemoryBuffer.h"
33 #include "llvm/Support/SourceMgr.h"
34 #include "llvm/Support/TargetRegistry.h"
35 #include "llvm/Support/raw_ostream.h"
37 using namespace object
;
39 IRObjectFile::IRObjectFile(MemoryBufferRef Object
,
40 std::vector
<std::unique_ptr
<Module
>> Mods
)
41 : SymbolicFile(Binary::ID_IR
, Object
), Mods(std::move(Mods
)) {
42 for (auto &M
: this->Mods
)
43 SymTab
.addModule(M
.get());
46 IRObjectFile::~IRObjectFile() {}
48 static ModuleSymbolTable::Symbol
getSym(DataRefImpl
&Symb
) {
49 return *reinterpret_cast<ModuleSymbolTable::Symbol
*>(Symb
.p
);
52 void IRObjectFile::moveSymbolNext(DataRefImpl
&Symb
) const {
53 Symb
.p
+= sizeof(ModuleSymbolTable::Symbol
);
56 std::error_code
IRObjectFile::printSymbolName(raw_ostream
&OS
,
57 DataRefImpl Symb
) const {
58 SymTab
.printSymbolName(OS
, getSym(Symb
));
59 return std::error_code();
62 uint32_t IRObjectFile::getSymbolFlags(DataRefImpl Symb
) const {
63 return SymTab
.getSymbolFlags(getSym(Symb
));
66 basic_symbol_iterator
IRObjectFile::symbol_begin() const {
68 Ret
.p
= reinterpret_cast<uintptr_t>(SymTab
.symbols().data());
69 return basic_symbol_iterator(BasicSymbolRef(Ret
, this));
72 basic_symbol_iterator
IRObjectFile::symbol_end() const {
74 Ret
.p
= reinterpret_cast<uintptr_t>(SymTab
.symbols().data() +
75 SymTab
.symbols().size());
76 return basic_symbol_iterator(BasicSymbolRef(Ret
, this));
79 StringRef
IRObjectFile::getTargetTriple() const {
80 // Each module must have the same target triple, so we arbitrarily access the
82 return Mods
[0]->getTargetTriple();
85 ErrorOr
<MemoryBufferRef
> IRObjectFile::findBitcodeInObject(const ObjectFile
&Obj
) {
86 for (const SectionRef
&Sec
: Obj
.sections()) {
87 if (Sec
.isBitcode()) {
88 StringRef SecContents
;
89 if (std::error_code EC
= Sec
.getContents(SecContents
))
91 return MemoryBufferRef(SecContents
, Obj
.getFileName());
95 return object_error::bitcode_section_not_found
;
98 ErrorOr
<MemoryBufferRef
> IRObjectFile::findBitcodeInMemBuffer(MemoryBufferRef Object
) {
99 file_magic Type
= identify_magic(Object
.getBuffer());
101 case file_magic::bitcode
:
103 case file_magic::elf_relocatable
:
104 case file_magic::macho_object
:
105 case file_magic::coff_object
: {
106 Expected
<std::unique_ptr
<ObjectFile
>> ObjFile
=
107 ObjectFile::createObjectFile(Object
, Type
);
109 return errorToErrorCode(ObjFile
.takeError());
110 return findBitcodeInObject(*ObjFile
->get());
113 return object_error::invalid_file_type
;
117 Expected
<std::unique_ptr
<IRObjectFile
>>
118 IRObjectFile::create(MemoryBufferRef Object
, LLVMContext
&Context
) {
119 ErrorOr
<MemoryBufferRef
> BCOrErr
= findBitcodeInMemBuffer(Object
);
121 return errorCodeToError(BCOrErr
.getError());
123 Expected
<std::vector
<BitcodeModule
>> BMsOrErr
=
124 getBitcodeModuleList(*BCOrErr
);
126 return BMsOrErr
.takeError();
128 std::vector
<std::unique_ptr
<Module
>> Mods
;
129 for (auto BM
: *BMsOrErr
) {
130 Expected
<std::unique_ptr
<Module
>> MOrErr
=
131 BM
.getLazyModule(Context
, /*ShouldLazyLoadMetadata*/ true,
132 /*IsImporting*/ false);
134 return MOrErr
.takeError();
136 Mods
.push_back(std::move(*MOrErr
));
139 return std::unique_ptr
<IRObjectFile
>(
140 new IRObjectFile(*BCOrErr
, std::move(Mods
)));
143 Expected
<IRSymtabFile
> object::readIRSymtab(MemoryBufferRef MBRef
) {
145 ErrorOr
<MemoryBufferRef
> BCOrErr
=
146 IRObjectFile::findBitcodeInMemBuffer(MBRef
);
148 return errorCodeToError(BCOrErr
.getError());
150 Expected
<BitcodeFileContents
> BFCOrErr
= getBitcodeFileContents(*BCOrErr
);
152 return BFCOrErr
.takeError();
154 Expected
<irsymtab::FileContents
> FCOrErr
= irsymtab::readBitcode(*BFCOrErr
);
156 return FCOrErr
.takeError();
158 F
.Mods
= std::move(BFCOrErr
->Mods
);
159 F
.Symtab
= std::move(FCOrErr
->Symtab
);
160 F
.Strtab
= std::move(FCOrErr
->Strtab
);
161 F
.TheReader
= std::move(FCOrErr
->TheReader
);