blob: 2d055e14470c0b8076a0e1a5b023bcdbc9e77696 [file] [log] [blame]
Rafael Espindolaf12b8282014-02-21 20:10:59 +00001//===- 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
Rafael Espindolaba79dba2014-07-04 22:44:18 +000014#include "llvm/Object/IRObjectFile.h"
15#include "RecordStreamer.h"
Benjamin Kramer0a446fd2015-03-01 21:28:53 +000016#include "llvm/ADT/STLExtras.h"
Teresa Johnsonad176792016-11-11 05:34:58 +000017#include "llvm/Bitcode/BitcodeReader.h"
Rafael Espindolac3f9b5a2014-06-23 21:53:12 +000018#include "llvm/IR/GVMaterializer.h"
Chandler Carruthd9903882015-01-14 11:23:27 +000019#include "llvm/IR/LLVMContext.h"
Rafael Espindolaa51f0f82014-02-28 02:17:23 +000020#include "llvm/IR/Mangler.h"
Rafael Espindolaf12b8282014-02-21 20:10:59 +000021#include "llvm/IR/Module.h"
Rafael Espindola13b69d62014-07-03 18:59:23 +000022#include "llvm/MC/MCAsmInfo.h"
23#include "llvm/MC/MCContext.h"
24#include "llvm/MC/MCInstrInfo.h"
25#include "llvm/MC/MCObjectFileInfo.h"
Rafael Espindola13b69d62014-07-03 18:59:23 +000026#include "llvm/MC/MCParser/MCAsmParser.h"
Benjamin Kramerb3e8a6d2016-01-27 10:01:28 +000027#include "llvm/MC/MCParser/MCTargetAsmParser.h"
Chandler Carruthd9903882015-01-14 11:23:27 +000028#include "llvm/MC/MCRegisterInfo.h"
Pete Cooper81902a32015-05-15 22:19:42 +000029#include "llvm/MC/MCSubtargetInfo.h"
Peter Collingbourne10039c02014-09-18 21:28:49 +000030#include "llvm/Object/ObjectFile.h"
Rafael Espindola2e60ca92014-06-24 13:56:32 +000031#include "llvm/Support/MemoryBuffer.h"
Rafael Espindola13b69d62014-07-03 18:59:23 +000032#include "llvm/Support/SourceMgr.h"
33#include "llvm/Support/TargetRegistry.h"
Rafael Espindola23f04062014-02-21 20:21:55 +000034#include "llvm/Support/raw_ostream.h"
Rafael Espindolaf12b8282014-02-21 20:10:59 +000035using namespace llvm;
36using namespace object;
37
Peter Collingbourne45102a22016-12-13 20:20:17 +000038IRObjectFile::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());
Rafael Espindolaf12b8282014-02-21 20:10:59 +000043}
44
Peter Collingbournee32baa02016-11-24 00:41:05 +000045IRObjectFile::~IRObjectFile() {}
Rafael Espindola13b69d62014-07-03 18:59:23 +000046
Peter Collingbourne863cbfb2016-12-01 06:51:47 +000047static ModuleSymbolTable::Symbol getSym(DataRefImpl &Symb) {
48 return *reinterpret_cast<ModuleSymbolTable::Symbol *>(Symb.p);
49}
50
Rafael Espindolaf12b8282014-02-21 20:10:59 +000051void IRObjectFile::moveSymbolNext(DataRefImpl &Symb) const {
Peter Collingbourne863cbfb2016-12-01 06:51:47 +000052 Symb.p += sizeof(ModuleSymbolTable::Symbol);
Rafael Espindolaf12b8282014-02-21 20:10:59 +000053}
54
Rafael Espindoladb4ed0b2014-06-13 02:24:39 +000055std::error_code IRObjectFile::printSymbolName(raw_ostream &OS,
56 DataRefImpl Symb) const {
Peter Collingbourne863cbfb2016-12-01 06:51:47 +000057 SymTab.printSymbolName(OS, getSym(Symb));
Rui Ueyama7d099192015-06-09 15:20:42 +000058 return std::error_code();
Rafael Espindolaf12b8282014-02-21 20:10:59 +000059}
60
61uint32_t IRObjectFile::getSymbolFlags(DataRefImpl Symb) const {
Peter Collingbourne863cbfb2016-12-01 06:51:47 +000062 return SymTab.getSymbolFlags(getSym(Symb));
Rafael Espindolaf12b8282014-02-21 20:10:59 +000063}
64
Peter Collingbourne435890a2016-11-22 03:38:40 +000065basic_symbol_iterator IRObjectFile::symbol_begin() const {
Rafael Espindolaf12b8282014-02-21 20:10:59 +000066 DataRefImpl Ret;
Peter Collingbourne863cbfb2016-12-01 06:51:47 +000067 Ret.p = reinterpret_cast<uintptr_t>(SymTab.symbols().data());
Rafael Espindolaf12b8282014-02-21 20:10:59 +000068 return basic_symbol_iterator(BasicSymbolRef(Ret, this));
69}
70
Peter Collingbourne435890a2016-11-22 03:38:40 +000071basic_symbol_iterator IRObjectFile::symbol_end() const {
Rafael Espindolaf12b8282014-02-21 20:10:59 +000072 DataRefImpl Ret;
Peter Collingbourne863cbfb2016-12-01 06:51:47 +000073 Ret.p = reinterpret_cast<uintptr_t>(SymTab.symbols().data() +
74 SymTab.symbols().size());
Rafael Espindolaf12b8282014-02-21 20:10:59 +000075 return basic_symbol_iterator(BasicSymbolRef(Ret, this));
76}
77
Peter Collingbourne45102a22016-12-13 20:20:17 +000078StringRef 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}
Peter Collingbournedebb6f62016-11-24 01:13:09 +000083
Peter Collingbourne10039c02014-09-18 21:28:49 +000084ErrorOr<MemoryBufferRef> IRObjectFile::findBitcodeInObject(const ObjectFile &Obj) {
85 for (const SectionRef &Sec : Obj.sections()) {
Steven Wuf2fe0142016-02-29 19:40:10 +000086 if (Sec.isBitcode()) {
Peter Collingbourne10039c02014-09-18 21:28:49 +000087 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: {
Kevin Enderby3fcdf6a2016-04-06 22:14:09 +0000105 Expected<std::unique_ptr<ObjectFile>> ObjFile =
Peter Collingbourne10039c02014-09-18 21:28:49 +0000106 ObjectFile::createObjectFile(Object, Type);
107 if (!ObjFile)
Kevin Enderby3fcdf6a2016-04-06 22:14:09 +0000108 return errorToErrorCode(ObjFile.takeError());
Peter Collingbourne10039c02014-09-18 21:28:49 +0000109 return findBitcodeInObject(*ObjFile->get());
110 }
111 default:
112 return object_error::invalid_file_type;
113 }
114}
115
Peter Collingbourned9445c42016-11-13 07:00:17 +0000116Expected<std::unique_ptr<IRObjectFile>>
Peter Collingbourne45102a22016-12-13 20:20:17 +0000117IRObjectFile::create(MemoryBufferRef Object, LLVMContext &Context) {
Peter Collingbourne10039c02014-09-18 21:28:49 +0000118 ErrorOr<MemoryBufferRef> BCOrErr = findBitcodeInMemBuffer(Object);
119 if (!BCOrErr)
Peter Collingbourned9445c42016-11-13 07:00:17 +0000120 return errorCodeToError(BCOrErr.getError());
Rafael Espindola48af1c22014-08-19 18:44:46 +0000121
Peter Collingbourne45102a22016-12-13 20:20:17 +0000122 Expected<std::vector<BitcodeModule>> BMsOrErr =
123 getBitcodeModuleList(*BCOrErr);
124 if (!BMsOrErr)
125 return BMsOrErr.takeError();
Rafael Espindoladddd1fd2014-07-04 18:40:36 +0000126
Peter Collingbourne45102a22016-12-13 20:20:17 +0000127 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 if (!MOrErr)
132 return MOrErr.takeError();
133
134 Mods.push_back(std::move(*MOrErr));
135 }
136
Peter Collingbournec5fecb42016-12-13 20:10:22 +0000137 return std::unique_ptr<IRObjectFile>(
Peter Collingbourne45102a22016-12-13 20:20:17 +0000138 new IRObjectFile(*BCOrErr, std::move(Mods)));
Rafael Espindolaf12b8282014-02-21 20:10:59 +0000139}