blob: 28c64b4194000e1975176196cc754db5e89fdc40 [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
Rafael Espindola48af1c22014-08-19 18:44:46 +000038IRObjectFile::IRObjectFile(MemoryBufferRef Object, std::unique_ptr<Module> Mod)
39 : SymbolicFile(Binary::ID_IR, Object), M(std::move(Mod)) {
Peter Collingbourne863cbfb2016-12-01 06:51:47 +000040 SymTab.addModule(M.get());
Rafael Espindolaf12b8282014-02-21 20:10:59 +000041}
42
Peter Collingbournee32baa02016-11-24 00:41:05 +000043IRObjectFile::~IRObjectFile() {}
Rafael Espindola13b69d62014-07-03 18:59:23 +000044
Peter Collingbourne863cbfb2016-12-01 06:51:47 +000045static ModuleSymbolTable::Symbol getSym(DataRefImpl &Symb) {
46 return *reinterpret_cast<ModuleSymbolTable::Symbol *>(Symb.p);
47}
48
Rafael Espindolaf12b8282014-02-21 20:10:59 +000049void IRObjectFile::moveSymbolNext(DataRefImpl &Symb) const {
Peter Collingbourne863cbfb2016-12-01 06:51:47 +000050 Symb.p += sizeof(ModuleSymbolTable::Symbol);
Rafael Espindolaf12b8282014-02-21 20:10:59 +000051}
52
Rafael Espindoladb4ed0b2014-06-13 02:24:39 +000053std::error_code IRObjectFile::printSymbolName(raw_ostream &OS,
54 DataRefImpl Symb) const {
Peter Collingbourne863cbfb2016-12-01 06:51:47 +000055 SymTab.printSymbolName(OS, getSym(Symb));
Rui Ueyama7d099192015-06-09 15:20:42 +000056 return std::error_code();
Rafael Espindolaf12b8282014-02-21 20:10:59 +000057}
58
59uint32_t IRObjectFile::getSymbolFlags(DataRefImpl Symb) const {
Peter Collingbourne863cbfb2016-12-01 06:51:47 +000060 return SymTab.getSymbolFlags(getSym(Symb));
Rafael Espindolaf12b8282014-02-21 20:10:59 +000061}
62
Peter Collingbournee32baa02016-11-24 00:41:05 +000063GlobalValue *IRObjectFile::getSymbolGV(DataRefImpl Symb) {
64 return getSym(Symb).dyn_cast<GlobalValue *>();
65}
Rafael Espindolaf12b8282014-02-21 20:10:59 +000066
Rafael Espindola25a7e0a2014-12-09 16:18:11 +000067std::unique_ptr<Module> IRObjectFile::takeModule() { return std::move(M); }
68
Peter Collingbourne435890a2016-11-22 03:38:40 +000069basic_symbol_iterator IRObjectFile::symbol_begin() const {
Rafael Espindolaf12b8282014-02-21 20:10:59 +000070 DataRefImpl Ret;
Peter Collingbourne863cbfb2016-12-01 06:51:47 +000071 Ret.p = reinterpret_cast<uintptr_t>(SymTab.symbols().data());
Rafael Espindolaf12b8282014-02-21 20:10:59 +000072 return basic_symbol_iterator(BasicSymbolRef(Ret, this));
73}
74
Peter Collingbourne435890a2016-11-22 03:38:40 +000075basic_symbol_iterator IRObjectFile::symbol_end() const {
Rafael Espindolaf12b8282014-02-21 20:10:59 +000076 DataRefImpl Ret;
Peter Collingbourne863cbfb2016-12-01 06:51:47 +000077 Ret.p = reinterpret_cast<uintptr_t>(SymTab.symbols().data() +
78 SymTab.symbols().size());
Rafael Espindolaf12b8282014-02-21 20:10:59 +000079 return basic_symbol_iterator(BasicSymbolRef(Ret, this));
80}
81
Peter Collingbournedebb6f62016-11-24 01:13:09 +000082StringRef IRObjectFile::getTargetTriple() const { return M->getTargetTriple(); }
83
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>>
Rafael Espindola5dec7ea2014-12-09 20:36:13 +0000117llvm::object::IRObjectFile::create(MemoryBufferRef Object,
118 LLVMContext &Context) {
Peter Collingbourne10039c02014-09-18 21:28:49 +0000119 ErrorOr<MemoryBufferRef> BCOrErr = findBitcodeInMemBuffer(Object);
120 if (!BCOrErr)
Peter Collingbourned9445c42016-11-13 07:00:17 +0000121 return errorCodeToError(BCOrErr.getError());
Rafael Espindola48af1c22014-08-19 18:44:46 +0000122
Peter Collingbourned9445c42016-11-13 07:00:17 +0000123 Expected<std::unique_ptr<Module>> MOrErr =
Peter Collingbournee2dcf7c2016-11-08 06:03:43 +0000124 getLazyBitcodeModule(*BCOrErr, Context,
Rafael Espindolacba833a2015-03-13 21:54:20 +0000125 /*ShouldLazyLoadMetadata*/ true);
Peter Collingbourned9445c42016-11-13 07:00:17 +0000126 if (!MOrErr)
127 return MOrErr.takeError();
Rafael Espindoladddd1fd2014-07-04 18:40:36 +0000128
Rafael Espindoladcd1dca2015-06-16 22:27:55 +0000129 std::unique_ptr<Module> &M = MOrErr.get();
Teresa Johnson9ba95f92016-08-11 14:58:12 +0000130 return llvm::make_unique<IRObjectFile>(BCOrErr.get(), std::move(M));
Rafael Espindolaf12b8282014-02-21 20:10:59 +0000131}