blob: 08aa71743188c2c990a082748cd17deb3b90b532 [file] [log] [blame]
Shankar Easwarand7de1082014-01-27 00:45:57 +00001//===- lib/ReaderWriter/ELF/ELFReader.h -----------------------------------===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef LLD_READER_WRITER_ELF_READER_H
11#define LLD_READER_WRITER_ELF_READER_H
12
13#include "CreateELF.h"
14#include "DynamicFile.h"
15#include "ELFFile.h"
Shankar Easwarand7de1082014-01-27 00:45:57 +000016#include "lld/ReaderWriter/Reader.h"
17
18namespace lld {
19namespace elf {
20
Shankar Easwaran322d0df2014-10-21 03:12:57 +000021template <typename ELFT, typename ELFTraitsT>
Shankar Easwarand7de1082014-01-27 00:45:57 +000022class ELFObjectReader : public Reader {
23public:
Shankar Easwaran322d0df2014-10-21 03:12:57 +000024 typedef llvm::object::Elf_Ehdr_Impl<ELFT> Elf_Ehdr;
25
26 ELFObjectReader(bool atomizeStrings, uint64_t machine)
27 : _atomizeStrings(atomizeStrings), _machine(machine) {}
Shankar Easwarand7de1082014-01-27 00:45:57 +000028
Rui Ueyama9d0698e2014-03-28 21:26:13 +000029 bool canParse(file_magic magic, StringRef,
Shankar Easwaran322d0df2014-10-21 03:12:57 +000030 const MemoryBuffer &buf) const override {
31 return (magic == llvm::sys::fs::file_magic::elf_relocatable &&
32 elfHeader(buf)->e_machine == _machine);
Shankar Easwarand7de1082014-01-27 00:45:57 +000033 }
34
Rafael Espindolab1a4d3a2014-06-12 14:53:47 +000035 std::error_code
Rui Ueyamadf230b22015-01-15 04:34:31 +000036 loadFile(std::unique_ptr<MemoryBuffer> mb, const class Registry &,
37 std::vector<std::unique_ptr<File>> &result) const override {
Shankar Easwarand7de1082014-01-27 00:45:57 +000038 std::size_t maxAlignment =
39 1ULL << llvm::countTrailingZeros(uintptr_t(mb->getBufferStart()));
Shankar Easwaran322d0df2014-10-21 03:12:57 +000040 auto f =
41 createELF<ELFTraitsT>(llvm::object::getElfArchType(mb->getBuffer()),
42 maxAlignment, std::move(mb), _atomizeStrings);
Rafael Espindolab1a4d3a2014-06-12 14:53:47 +000043 if (std::error_code ec = f.getError())
Shankar Easwarand7de1082014-01-27 00:45:57 +000044 return ec;
45 result.push_back(std::move(*f));
Rafael Espindolab1a4d3a2014-06-12 14:53:47 +000046 return std::error_code();
Shankar Easwarand7de1082014-01-27 00:45:57 +000047 }
48
Shankar Easwaran322d0df2014-10-21 03:12:57 +000049 const Elf_Ehdr *elfHeader(const MemoryBuffer &buf) const {
50 const uint8_t *data =
51 reinterpret_cast<const uint8_t *>(buf.getBuffer().data());
52 return (reinterpret_cast<const Elf_Ehdr *>(data));
53 }
54
Shankar Easwarane7b831a2014-01-27 01:02:03 +000055protected:
Shankar Easwarand7de1082014-01-27 00:45:57 +000056 bool _atomizeStrings;
Shankar Easwaran322d0df2014-10-21 03:12:57 +000057 uint64_t _machine;
Shankar Easwarand7de1082014-01-27 00:45:57 +000058};
59
Shankar Easwaran322d0df2014-10-21 03:12:57 +000060template <typename ELFT, typename ELFTraitsT>
Shankar Easwarand7de1082014-01-27 00:45:57 +000061class ELFDSOReader : public Reader {
62public:
Shankar Easwaran322d0df2014-10-21 03:12:57 +000063 typedef llvm::object::Elf_Ehdr_Impl<ELFT> Elf_Ehdr;
64
65 ELFDSOReader(bool useUndefines, uint64_t machine)
66 : _useUndefines(useUndefines), _machine(machine) {}
Shankar Easwarand7de1082014-01-27 00:45:57 +000067
Rui Ueyama9d0698e2014-03-28 21:26:13 +000068 bool canParse(file_magic magic, StringRef,
Shankar Easwaran322d0df2014-10-21 03:12:57 +000069 const MemoryBuffer &buf) const override {
70 return (magic == llvm::sys::fs::file_magic::elf_shared_object &&
71 elfHeader(buf)->e_machine == _machine);
Shankar Easwarand7de1082014-01-27 00:45:57 +000072 }
73
Rafael Espindolab1a4d3a2014-06-12 14:53:47 +000074 std::error_code
Rui Ueyamadf230b22015-01-15 04:34:31 +000075 loadFile(std::unique_ptr<MemoryBuffer> mb, const class Registry &,
76 std::vector<std::unique_ptr<File>> &result) const override {
Shankar Easwarand7de1082014-01-27 00:45:57 +000077 std::size_t maxAlignment =
78 1ULL << llvm::countTrailingZeros(uintptr_t(mb->getBufferStart()));
Shankar Easwaran322d0df2014-10-21 03:12:57 +000079 auto f =
80 createELF<ELFTraitsT>(llvm::object::getElfArchType(mb->getBuffer()),
81 maxAlignment, std::move(mb), _useUndefines);
Rafael Espindolab1a4d3a2014-06-12 14:53:47 +000082 if (std::error_code ec = f.getError())
Shankar Easwarand7de1082014-01-27 00:45:57 +000083 return ec;
84 result.push_back(std::move(*f));
Rafael Espindolab1a4d3a2014-06-12 14:53:47 +000085 return std::error_code();
Shankar Easwarand7de1082014-01-27 00:45:57 +000086 }
87
Shankar Easwaran322d0df2014-10-21 03:12:57 +000088 const Elf_Ehdr *elfHeader(const MemoryBuffer &buf) const {
89 const uint8_t *data =
90 reinterpret_cast<const uint8_t *>(buf.getBuffer().data());
91 return (reinterpret_cast<const Elf_Ehdr *>(data));
92 }
93
Shankar Easwarane7b831a2014-01-27 01:02:03 +000094protected:
Shankar Easwarand7de1082014-01-27 00:45:57 +000095 bool _useUndefines;
Shankar Easwaran322d0df2014-10-21 03:12:57 +000096 uint64_t _machine;
Shankar Easwarand7de1082014-01-27 00:45:57 +000097};
98
99} // namespace elf
100} // namespace lld
101
102#endif // LLD_READER_WRITER_ELF_READER_H