IRObjectFile.cpp revision 314564
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/BitcodeReader.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"
35using namespace llvm;
36using namespace object;
37
38IRObjectFile::IRObjectFile(MemoryBufferRef Object,
39                           std::vector<std::unique_ptr<Module>> Mods)
40    : SymbolicFile(Binary::ID_IR, Object), Mods(std::move(Mods)) {
41  for (auto &M : this->Mods)
42    SymTab.addModule(M.get());
43}
44
45IRObjectFile::~IRObjectFile() {}
46
47static ModuleSymbolTable::Symbol getSym(DataRefImpl &Symb) {
48  return *reinterpret_cast<ModuleSymbolTable::Symbol *>(Symb.p);
49}
50
51void IRObjectFile::moveSymbolNext(DataRefImpl &Symb) const {
52  Symb.p += sizeof(ModuleSymbolTable::Symbol);
53}
54
55std::error_code IRObjectFile::printSymbolName(raw_ostream &OS,
56                                              DataRefImpl Symb) const {
57  SymTab.printSymbolName(OS, getSym(Symb));
58  return std::error_code();
59}
60
61uint32_t IRObjectFile::getSymbolFlags(DataRefImpl Symb) const {
62  return SymTab.getSymbolFlags(getSym(Symb));
63}
64
65basic_symbol_iterator IRObjectFile::symbol_begin() const {
66  DataRefImpl Ret;
67  Ret.p = reinterpret_cast<uintptr_t>(SymTab.symbols().data());
68  return basic_symbol_iterator(BasicSymbolRef(Ret, this));
69}
70
71basic_symbol_iterator IRObjectFile::symbol_end() const {
72  DataRefImpl Ret;
73  Ret.p = reinterpret_cast<uintptr_t>(SymTab.symbols().data() +
74                                      SymTab.symbols().size());
75  return basic_symbol_iterator(BasicSymbolRef(Ret, this));
76}
77
78StringRef IRObjectFile::getTargetTriple() const {
79  // Each module must have the same target triple, so we arbitrarily access the
80  // first one.
81  return Mods[0]->getTargetTriple();
82}
83
84ErrorOr<MemoryBufferRef> IRObjectFile::findBitcodeInObject(const ObjectFile &Obj) {
85  for (const SectionRef &Sec : Obj.sections()) {
86    if (Sec.isBitcode()) {
87      StringRef SecContents;
88      if (std::error_code EC = Sec.getContents(SecContents))
89        return EC;
90      return MemoryBufferRef(SecContents, Obj.getFileName());
91    }
92  }
93
94  return object_error::bitcode_section_not_found;
95}
96
97ErrorOr<MemoryBufferRef> IRObjectFile::findBitcodeInMemBuffer(MemoryBufferRef Object) {
98  sys::fs::file_magic Type = sys::fs::identify_magic(Object.getBuffer());
99  switch (Type) {
100  case sys::fs::file_magic::bitcode:
101    return Object;
102  case sys::fs::file_magic::elf_relocatable:
103  case sys::fs::file_magic::macho_object:
104  case sys::fs::file_magic::coff_object: {
105    Expected<std::unique_ptr<ObjectFile>> ObjFile =
106        ObjectFile::createObjectFile(Object, Type);
107    if (!ObjFile)
108      return errorToErrorCode(ObjFile.takeError());
109    return findBitcodeInObject(*ObjFile->get());
110  }
111  default:
112    return object_error::invalid_file_type;
113  }
114}
115
116Expected<std::unique_ptr<IRObjectFile>>
117IRObjectFile::create(MemoryBufferRef Object, LLVMContext &Context) {
118  ErrorOr<MemoryBufferRef> BCOrErr = findBitcodeInMemBuffer(Object);
119  if (!BCOrErr)
120    return errorCodeToError(BCOrErr.getError());
121
122  Expected<std::vector<BitcodeModule>> BMsOrErr =
123      getBitcodeModuleList(*BCOrErr);
124  if (!BMsOrErr)
125    return BMsOrErr.takeError();
126
127  std::vector<std::unique_ptr<Module>> Mods;
128  for (auto BM : *BMsOrErr) {
129    Expected<std::unique_ptr<Module>> MOrErr =
130        BM.getLazyModule(Context, /*ShouldLazyLoadMetadata*/ true,
131                         /*IsImporting*/ false);
132    if (!MOrErr)
133      return MOrErr.takeError();
134
135    Mods.push_back(std::move(*MOrErr));
136  }
137
138  return std::unique_ptr<IRObjectFile>(
139      new IRObjectFile(*BCOrErr, std::move(Mods)));
140}
141