blob: d157908a85603d9d26ad2154a1407e286eafa569 [file] [log] [blame]
Rafael Espindolaf12b8282014-02-21 20:10:59 +00001//===- IRObjectFile.cpp - IR object file implementation ---------*- C++ -*-===//
2//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
Rafael Espindolaf12b8282014-02-21 20:10:59 +00006//
7//===----------------------------------------------------------------------===//
8//
9// Part of the IRObjectFile class implementation.
10//
11//===----------------------------------------------------------------------===//
12
Rafael Espindolaba79dba2014-07-04 22:44:18 +000013#include "llvm/Object/IRObjectFile.h"
Benjamin Kramer0a446fd2015-03-01 21:28:53 +000014#include "llvm/ADT/STLExtras.h"
Zachary Turner264b5d92017-06-07 03:48:56 +000015#include "llvm/BinaryFormat/Magic.h"
Teresa Johnsonad176792016-11-11 05:34:58 +000016#include "llvm/Bitcode/BitcodeReader.h"
Rafael Espindolac3f9b5a2014-06-23 21:53:12 +000017#include "llvm/IR/GVMaterializer.h"
Chandler Carruthd9903882015-01-14 11:23:27 +000018#include "llvm/IR/LLVMContext.h"
Rafael Espindolaa51f0f82014-02-28 02:17:23 +000019#include "llvm/IR/Mangler.h"
Rafael Espindolaf12b8282014-02-21 20:10:59 +000020#include "llvm/IR/Module.h"
Peter Collingbourne10039c02014-09-18 21:28:49 +000021#include "llvm/Object/ObjectFile.h"
Rafael Espindola2e60ca92014-06-24 13:56:32 +000022#include "llvm/Support/MemoryBuffer.h"
Rafael Espindola13b69d62014-07-03 18:59:23 +000023#include "llvm/Support/TargetRegistry.h"
Rafael Espindola23f04062014-02-21 20:21:55 +000024#include "llvm/Support/raw_ostream.h"
Rafael Espindolaf12b8282014-02-21 20:10:59 +000025using namespace llvm;
26using namespace object;
27
Peter Collingbourne45102a22016-12-13 20:20:17 +000028IRObjectFile::IRObjectFile(MemoryBufferRef Object,
29 std::vector<std::unique_ptr<Module>> Mods)
30 : SymbolicFile(Binary::ID_IR, Object), Mods(std::move(Mods)) {
31 for (auto &M : this->Mods)
32 SymTab.addModule(M.get());
Rafael Espindolaf12b8282014-02-21 20:10:59 +000033}
34
Peter Collingbournee32baa02016-11-24 00:41:05 +000035IRObjectFile::~IRObjectFile() {}
Rafael Espindola13b69d62014-07-03 18:59:23 +000036
Peter Collingbourne863cbfb2016-12-01 06:51:47 +000037static ModuleSymbolTable::Symbol getSym(DataRefImpl &Symb) {
38 return *reinterpret_cast<ModuleSymbolTable::Symbol *>(Symb.p);
39}
40
Rafael Espindolaf12b8282014-02-21 20:10:59 +000041void IRObjectFile::moveSymbolNext(DataRefImpl &Symb) const {
Peter Collingbourne863cbfb2016-12-01 06:51:47 +000042 Symb.p += sizeof(ModuleSymbolTable::Symbol);
Rafael Espindolaf12b8282014-02-21 20:10:59 +000043}
44
Rafael Espindoladb4ed0b2014-06-13 02:24:39 +000045std::error_code IRObjectFile::printSymbolName(raw_ostream &OS,
46 DataRefImpl Symb) const {
Peter Collingbourne863cbfb2016-12-01 06:51:47 +000047 SymTab.printSymbolName(OS, getSym(Symb));
Rui Ueyama7d099192015-06-09 15:20:42 +000048 return std::error_code();
Rafael Espindolaf12b8282014-02-21 20:10:59 +000049}
50
51uint32_t IRObjectFile::getSymbolFlags(DataRefImpl Symb) const {
Peter Collingbourne863cbfb2016-12-01 06:51:47 +000052 return SymTab.getSymbolFlags(getSym(Symb));
Rafael Espindolaf12b8282014-02-21 20:10:59 +000053}
54
Peter Collingbourne435890a2016-11-22 03:38:40 +000055basic_symbol_iterator IRObjectFile::symbol_begin() const {
Rafael Espindolaf12b8282014-02-21 20:10:59 +000056 DataRefImpl Ret;
Peter Collingbourne863cbfb2016-12-01 06:51:47 +000057 Ret.p = reinterpret_cast<uintptr_t>(SymTab.symbols().data());
Rafael Espindolaf12b8282014-02-21 20:10:59 +000058 return basic_symbol_iterator(BasicSymbolRef(Ret, this));
59}
60
Peter Collingbourne435890a2016-11-22 03:38:40 +000061basic_symbol_iterator IRObjectFile::symbol_end() const {
Rafael Espindolaf12b8282014-02-21 20:10:59 +000062 DataRefImpl Ret;
Peter Collingbourne863cbfb2016-12-01 06:51:47 +000063 Ret.p = reinterpret_cast<uintptr_t>(SymTab.symbols().data() +
64 SymTab.symbols().size());
Rafael Espindolaf12b8282014-02-21 20:10:59 +000065 return basic_symbol_iterator(BasicSymbolRef(Ret, this));
66}
67
Peter Collingbourne45102a22016-12-13 20:20:17 +000068StringRef IRObjectFile::getTargetTriple() const {
69 // Each module must have the same target triple, so we arbitrarily access the
70 // first one.
71 return Mods[0]->getTargetTriple();
72}
Peter Collingbournedebb6f62016-11-24 01:13:09 +000073
Rafael Espindola3500f5e2017-10-11 18:07:18 +000074Expected<MemoryBufferRef>
75IRObjectFile::findBitcodeInObject(const ObjectFile &Obj) {
Peter Collingbourne10039c02014-09-18 21:28:49 +000076 for (const SectionRef &Sec : Obj.sections()) {
Steven Wuf2fe0142016-02-29 19:40:10 +000077 if (Sec.isBitcode()) {
Peter Collingbourne10039c02014-09-18 21:28:49 +000078 StringRef SecContents;
79 if (std::error_code EC = Sec.getContents(SecContents))
Rafael Espindola3500f5e2017-10-11 18:07:18 +000080 return errorCodeToError(EC);
Steven Wu5a593542019-03-21 21:01:31 +000081 if (SecContents.size() <= 1)
82 return errorCodeToError(object_error::bitcode_section_not_found);
Peter Collingbourne10039c02014-09-18 21:28:49 +000083 return MemoryBufferRef(SecContents, Obj.getFileName());
84 }
85 }
86
Rafael Espindola3500f5e2017-10-11 18:07:18 +000087 return errorCodeToError(object_error::bitcode_section_not_found);
Peter Collingbourne10039c02014-09-18 21:28:49 +000088}
89
Rafael Espindola3500f5e2017-10-11 18:07:18 +000090Expected<MemoryBufferRef>
91IRObjectFile::findBitcodeInMemBuffer(MemoryBufferRef Object) {
Zachary Turner264b5d92017-06-07 03:48:56 +000092 file_magic Type = identify_magic(Object.getBuffer());
Peter Collingbourne10039c02014-09-18 21:28:49 +000093 switch (Type) {
Zachary Turner264b5d92017-06-07 03:48:56 +000094 case file_magic::bitcode:
Peter Collingbourne10039c02014-09-18 21:28:49 +000095 return Object;
Zachary Turner264b5d92017-06-07 03:48:56 +000096 case file_magic::elf_relocatable:
97 case file_magic::macho_object:
98 case file_magic::coff_object: {
Kevin Enderby3fcdf6a2016-04-06 22:14:09 +000099 Expected<std::unique_ptr<ObjectFile>> ObjFile =
Peter Collingbourne10039c02014-09-18 21:28:49 +0000100 ObjectFile::createObjectFile(Object, Type);
101 if (!ObjFile)
Rafael Espindola3500f5e2017-10-11 18:07:18 +0000102 return ObjFile.takeError();
Peter Collingbourne10039c02014-09-18 21:28:49 +0000103 return findBitcodeInObject(*ObjFile->get());
104 }
105 default:
Rafael Espindola3500f5e2017-10-11 18:07:18 +0000106 return errorCodeToError(object_error::invalid_file_type);
Peter Collingbourne10039c02014-09-18 21:28:49 +0000107 }
108}
109
Peter Collingbourned9445c42016-11-13 07:00:17 +0000110Expected<std::unique_ptr<IRObjectFile>>
Peter Collingbourne45102a22016-12-13 20:20:17 +0000111IRObjectFile::create(MemoryBufferRef Object, LLVMContext &Context) {
Rafael Espindola3500f5e2017-10-11 18:07:18 +0000112 Expected<MemoryBufferRef> BCOrErr = findBitcodeInMemBuffer(Object);
Peter Collingbourne10039c02014-09-18 21:28:49 +0000113 if (!BCOrErr)
Rafael Espindola3500f5e2017-10-11 18:07:18 +0000114 return BCOrErr.takeError();
Rafael Espindola48af1c22014-08-19 18:44:46 +0000115
Peter Collingbourne45102a22016-12-13 20:20:17 +0000116 Expected<std::vector<BitcodeModule>> BMsOrErr =
117 getBitcodeModuleList(*BCOrErr);
118 if (!BMsOrErr)
119 return BMsOrErr.takeError();
Rafael Espindoladddd1fd2014-07-04 18:40:36 +0000120
Peter Collingbourne45102a22016-12-13 20:20:17 +0000121 std::vector<std::unique_ptr<Module>> Mods;
122 for (auto BM : *BMsOrErr) {
123 Expected<std::unique_ptr<Module>> MOrErr =
Teresa Johnsona61f5e32016-12-16 21:25:01 +0000124 BM.getLazyModule(Context, /*ShouldLazyLoadMetadata*/ true,
125 /*IsImporting*/ false);
Peter Collingbourne45102a22016-12-13 20:20:17 +0000126 if (!MOrErr)
127 return MOrErr.takeError();
128
129 Mods.push_back(std::move(*MOrErr));
130 }
131
Peter Collingbournec5fecb42016-12-13 20:10:22 +0000132 return std::unique_ptr<IRObjectFile>(
Peter Collingbourne45102a22016-12-13 20:20:17 +0000133 new IRObjectFile(*BCOrErr, std::move(Mods)));
Rafael Espindolaf12b8282014-02-21 20:10:59 +0000134}
Peter Collingbournec00c2b22017-06-08 01:26:14 +0000135
136Expected<IRSymtabFile> object::readIRSymtab(MemoryBufferRef MBRef) {
137 IRSymtabFile F;
Rafael Espindola3500f5e2017-10-11 18:07:18 +0000138 Expected<MemoryBufferRef> BCOrErr =
Peter Collingbournec00c2b22017-06-08 01:26:14 +0000139 IRObjectFile::findBitcodeInMemBuffer(MBRef);
140 if (!BCOrErr)
Rafael Espindola3500f5e2017-10-11 18:07:18 +0000141 return BCOrErr.takeError();
Peter Collingbournec00c2b22017-06-08 01:26:14 +0000142
Peter Collingbourne8dde4cb2017-06-08 22:00:24 +0000143 Expected<BitcodeFileContents> BFCOrErr = getBitcodeFileContents(*BCOrErr);
144 if (!BFCOrErr)
145 return BFCOrErr.takeError();
Peter Collingbournec00c2b22017-06-08 01:26:14 +0000146
Peter Collingbourne8dde4cb2017-06-08 22:00:24 +0000147 Expected<irsymtab::FileContents> FCOrErr = irsymtab::readBitcode(*BFCOrErr);
Peter Collingbournec00c2b22017-06-08 01:26:14 +0000148 if (!FCOrErr)
149 return FCOrErr.takeError();
150
Peter Collingbourne8dde4cb2017-06-08 22:00:24 +0000151 F.Mods = std::move(BFCOrErr->Mods);
Peter Collingbournec00c2b22017-06-08 01:26:14 +0000152 F.Symtab = std::move(FCOrErr->Symtab);
153 F.Strtab = std::move(FCOrErr->Strtab);
154 F.TheReader = std::move(FCOrErr->TheReader);
155 return std::move(F);
156}