1*a03ca8b9SKrzysztof Kosiński // Copyright 2018 The Chromium Authors. All rights reserved.
2*a03ca8b9SKrzysztof Kosiński // Use of this source code is governed by a BSD-style license that can be
3*a03ca8b9SKrzysztof Kosiński // found in the LICENSE file.
4*a03ca8b9SKrzysztof Kosiński
5*a03ca8b9SKrzysztof Kosiński #ifndef COMPONENTS_ZUCCHINI_DISASSEMBLER_ELF_H_
6*a03ca8b9SKrzysztof Kosiński #define COMPONENTS_ZUCCHINI_DISASSEMBLER_ELF_H_
7*a03ca8b9SKrzysztof Kosiński
8*a03ca8b9SKrzysztof Kosiński #include <stdint.h>
9*a03ca8b9SKrzysztof Kosiński
10*a03ca8b9SKrzysztof Kosiński #include <algorithm>
11*a03ca8b9SKrzysztof Kosiński #include <deque>
12*a03ca8b9SKrzysztof Kosiński #include <memory>
13*a03ca8b9SKrzysztof Kosiński #include <string>
14*a03ca8b9SKrzysztof Kosiński #include <vector>
15*a03ca8b9SKrzysztof Kosiński
16*a03ca8b9SKrzysztof Kosiński #include "components/zucchini/address_translator.h"
17*a03ca8b9SKrzysztof Kosiński #include "components/zucchini/buffer_view.h"
18*a03ca8b9SKrzysztof Kosiński #include "components/zucchini/disassembler.h"
19*a03ca8b9SKrzysztof Kosiński #include "components/zucchini/image_utils.h"
20*a03ca8b9SKrzysztof Kosiński #include "components/zucchini/rel32_finder.h"
21*a03ca8b9SKrzysztof Kosiński #include "components/zucchini/rel32_utils.h"
22*a03ca8b9SKrzysztof Kosiński #include "components/zucchini/reloc_elf.h"
23*a03ca8b9SKrzysztof Kosiński #include "components/zucchini/type_elf.h"
24*a03ca8b9SKrzysztof Kosiński
25*a03ca8b9SKrzysztof Kosiński namespace zucchini {
26*a03ca8b9SKrzysztof Kosiński
27*a03ca8b9SKrzysztof Kosiński struct ArmReferencePool {
28*a03ca8b9SKrzysztof Kosiński enum : uint8_t {
29*a03ca8b9SKrzysztof Kosiński kPoolReloc,
30*a03ca8b9SKrzysztof Kosiński kPoolAbs32,
31*a03ca8b9SKrzysztof Kosiński kPoolRel32,
32*a03ca8b9SKrzysztof Kosiński };
33*a03ca8b9SKrzysztof Kosiński };
34*a03ca8b9SKrzysztof Kosiński
35*a03ca8b9SKrzysztof Kosiński struct AArch32ReferenceType {
36*a03ca8b9SKrzysztof Kosiński enum : uint8_t {
37*a03ca8b9SKrzysztof Kosiński kReloc, // kPoolReloc
38*a03ca8b9SKrzysztof Kosiński
39*a03ca8b9SKrzysztof Kosiński kAbs32, // kPoolAbs32
40*a03ca8b9SKrzysztof Kosiński
41*a03ca8b9SKrzysztof Kosiński kRel32_A24, // kPoolRel32
42*a03ca8b9SKrzysztof Kosiński kRel32_T8,
43*a03ca8b9SKrzysztof Kosiński kRel32_T11,
44*a03ca8b9SKrzysztof Kosiński kRel32_T20,
45*a03ca8b9SKrzysztof Kosiński kRel32_T24,
46*a03ca8b9SKrzysztof Kosiński
47*a03ca8b9SKrzysztof Kosiński kTypeCount
48*a03ca8b9SKrzysztof Kosiński };
49*a03ca8b9SKrzysztof Kosiński };
50*a03ca8b9SKrzysztof Kosiński
51*a03ca8b9SKrzysztof Kosiński struct AArch64ReferenceType {
52*a03ca8b9SKrzysztof Kosiński enum : uint8_t {
53*a03ca8b9SKrzysztof Kosiński kReloc, // kPoolReloc
54*a03ca8b9SKrzysztof Kosiński
55*a03ca8b9SKrzysztof Kosiński kAbs32, // kPoolAbs32
56*a03ca8b9SKrzysztof Kosiński
57*a03ca8b9SKrzysztof Kosiński kRel32_Immd14, // kPoolRel32
58*a03ca8b9SKrzysztof Kosiński kRel32_Immd19,
59*a03ca8b9SKrzysztof Kosiński kRel32_Immd26,
60*a03ca8b9SKrzysztof Kosiński
61*a03ca8b9SKrzysztof Kosiński kTypeCount
62*a03ca8b9SKrzysztof Kosiński };
63*a03ca8b9SKrzysztof Kosiński };
64*a03ca8b9SKrzysztof Kosiński
65*a03ca8b9SKrzysztof Kosiński struct Elf32Traits {
66*a03ca8b9SKrzysztof Kosiński static constexpr uint16_t kVersion = 1;
67*a03ca8b9SKrzysztof Kosiński static constexpr Bitness kBitness = kBit32;
68*a03ca8b9SKrzysztof Kosiński static constexpr elf::FileClass kIdentificationClass = elf::ELFCLASS32;
69*a03ca8b9SKrzysztof Kosiński using Elf_Shdr = elf::Elf32_Shdr;
70*a03ca8b9SKrzysztof Kosiński using Elf_Phdr = elf::Elf32_Phdr;
71*a03ca8b9SKrzysztof Kosiński using Elf_Ehdr = elf::Elf32_Ehdr;
72*a03ca8b9SKrzysztof Kosiński using Elf_Rel = elf::Elf32_Rel;
73*a03ca8b9SKrzysztof Kosiński using Elf_Rela = elf::Elf32_Rela;
74*a03ca8b9SKrzysztof Kosiński };
75*a03ca8b9SKrzysztof Kosiński
76*a03ca8b9SKrzysztof Kosiński // Architecture-specific definitions.
77*a03ca8b9SKrzysztof Kosiński
78*a03ca8b9SKrzysztof Kosiński struct Elf32IntelTraits : public Elf32Traits {
79*a03ca8b9SKrzysztof Kosiński static constexpr ExecutableType kExeType = kExeTypeElfX86;
80*a03ca8b9SKrzysztof Kosiński static const char kExeTypeString[];
81*a03ca8b9SKrzysztof Kosiński static constexpr elf::MachineArchitecture kMachineValue = elf::EM_386;
82*a03ca8b9SKrzysztof Kosiński static constexpr uint32_t kRelType = elf::R_386_RELATIVE;
83*a03ca8b9SKrzysztof Kosiński enum : uint32_t { kVAWidth = 4 };
84*a03ca8b9SKrzysztof Kosiński using Rel32FinderUse = Rel32FinderX86;
85*a03ca8b9SKrzysztof Kosiński };
86*a03ca8b9SKrzysztof Kosiński
87*a03ca8b9SKrzysztof Kosiński struct ElfAArch32Traits : public Elf32Traits {
88*a03ca8b9SKrzysztof Kosiński static constexpr ExecutableType kExeType = kExeTypeElfAArch32;
89*a03ca8b9SKrzysztof Kosiński static const char kExeTypeString[];
90*a03ca8b9SKrzysztof Kosiński static constexpr elf::MachineArchitecture kMachineValue = elf::EM_ARM;
91*a03ca8b9SKrzysztof Kosiński static constexpr uint32_t kRelType = elf::R_ARM_RELATIVE;
92*a03ca8b9SKrzysztof Kosiński enum : uint32_t { kVAWidth = 4 };
93*a03ca8b9SKrzysztof Kosiński using ArmReferenceType = AArch32ReferenceType;
94*a03ca8b9SKrzysztof Kosiński using Rel32FinderUse = Rel32FinderAArch32;
95*a03ca8b9SKrzysztof Kosiński };
96*a03ca8b9SKrzysztof Kosiński
97*a03ca8b9SKrzysztof Kosiński struct Elf64Traits {
98*a03ca8b9SKrzysztof Kosiński static constexpr uint16_t kVersion = 1;
99*a03ca8b9SKrzysztof Kosiński static constexpr Bitness kBitness = kBit64;
100*a03ca8b9SKrzysztof Kosiński static constexpr elf::FileClass kIdentificationClass = elf::ELFCLASS64;
101*a03ca8b9SKrzysztof Kosiński using Elf_Shdr = elf::Elf64_Shdr;
102*a03ca8b9SKrzysztof Kosiński using Elf_Phdr = elf::Elf64_Phdr;
103*a03ca8b9SKrzysztof Kosiński using Elf_Ehdr = elf::Elf64_Ehdr;
104*a03ca8b9SKrzysztof Kosiński using Elf_Rel = elf::Elf64_Rel;
105*a03ca8b9SKrzysztof Kosiński using Elf_Rela = elf::Elf64_Rela;
106*a03ca8b9SKrzysztof Kosiński };
107*a03ca8b9SKrzysztof Kosiński
108*a03ca8b9SKrzysztof Kosiński // Architecture-specific definitions.
109*a03ca8b9SKrzysztof Kosiński struct Elf64IntelTraits : public Elf64Traits {
110*a03ca8b9SKrzysztof Kosiński static constexpr ExecutableType kExeType = kExeTypeElfX64;
111*a03ca8b9SKrzysztof Kosiński static const char kExeTypeString[];
112*a03ca8b9SKrzysztof Kosiński static constexpr elf::MachineArchitecture kMachineValue = elf::EM_X86_64;
113*a03ca8b9SKrzysztof Kosiński static constexpr uint32_t kRelType = elf::R_X86_64_RELATIVE;
114*a03ca8b9SKrzysztof Kosiński enum : uint32_t { kVAWidth = 8 };
115*a03ca8b9SKrzysztof Kosiński using Rel32FinderUse = Rel32FinderX64;
116*a03ca8b9SKrzysztof Kosiński };
117*a03ca8b9SKrzysztof Kosiński
118*a03ca8b9SKrzysztof Kosiński struct ElfAArch64Traits : public Elf64Traits {
119*a03ca8b9SKrzysztof Kosiński static constexpr ExecutableType kExeType = kExeTypeElfAArch64;
120*a03ca8b9SKrzysztof Kosiński static const char kExeTypeString[];
121*a03ca8b9SKrzysztof Kosiński static constexpr elf::MachineArchitecture kMachineValue = elf::EM_AARCH64;
122*a03ca8b9SKrzysztof Kosiński // TODO(huangs): See if R_AARCH64_GLOB_DAT and R_AARCH64_JUMP_SLOT should be
123*a03ca8b9SKrzysztof Kosiński // used.
124*a03ca8b9SKrzysztof Kosiński static constexpr uint32_t kRelType = elf::R_AARCH64_RELATIVE;
125*a03ca8b9SKrzysztof Kosiński enum : uint32_t { kVAWidth = 8 };
126*a03ca8b9SKrzysztof Kosiński using ArmReferenceType = AArch64ReferenceType;
127*a03ca8b9SKrzysztof Kosiński using Rel32FinderUse = Rel32FinderAArch64;
128*a03ca8b9SKrzysztof Kosiński };
129*a03ca8b9SKrzysztof Kosiński
130*a03ca8b9SKrzysztof Kosiński // Decides whether target |offset| is covered by a section in |sorted_headers|.
131*a03ca8b9SKrzysztof Kosiński template <class ELF_SHDR>
IsTargetOffsetInElfSectionList(const std::vector<const ELF_SHDR * > & sorted_headers,offset_t offset)132*a03ca8b9SKrzysztof Kosiński bool IsTargetOffsetInElfSectionList(
133*a03ca8b9SKrzysztof Kosiński const std::vector<const ELF_SHDR*>& sorted_headers,
134*a03ca8b9SKrzysztof Kosiński offset_t offset) {
135*a03ca8b9SKrzysztof Kosiński // Use binary search to search in a list of intervals, in a fashion similar to
136*a03ca8b9SKrzysztof Kosiński // AddressTranslator::OffsetToUnit().
137*a03ca8b9SKrzysztof Kosiński auto comp = [](offset_t offset, const ELF_SHDR* header) -> bool {
138*a03ca8b9SKrzysztof Kosiński return offset < header->sh_offset;
139*a03ca8b9SKrzysztof Kosiński };
140*a03ca8b9SKrzysztof Kosiński auto it = std::upper_bound(sorted_headers.begin(), sorted_headers.end(),
141*a03ca8b9SKrzysztof Kosiński offset, comp);
142*a03ca8b9SKrzysztof Kosiński if (it == sorted_headers.begin())
143*a03ca8b9SKrzysztof Kosiński return false;
144*a03ca8b9SKrzysztof Kosiński --it;
145*a03ca8b9SKrzysztof Kosiński // Just check offset without worrying about width, since this is a target.
146*a03ca8b9SKrzysztof Kosiński // Not using RangeCovers() because |sh_offset| and |sh_size| can be 64-bit.
147*a03ca8b9SKrzysztof Kosiński return offset >= (*it)->sh_offset &&
148*a03ca8b9SKrzysztof Kosiński offset - (*it)->sh_offset < (*it)->sh_size;
149*a03ca8b9SKrzysztof Kosiński }
150*a03ca8b9SKrzysztof Kosiński
151*a03ca8b9SKrzysztof Kosiński // Disassembler for ELF.
152*a03ca8b9SKrzysztof Kosiński template <class TRAITS>
153*a03ca8b9SKrzysztof Kosiński class DisassemblerElf : public Disassembler {
154*a03ca8b9SKrzysztof Kosiński public:
155*a03ca8b9SKrzysztof Kosiński using Traits = TRAITS;
156*a03ca8b9SKrzysztof Kosiński static constexpr uint16_t kVersion = Traits::kVersion;
157*a03ca8b9SKrzysztof Kosiński // Applies quick checks to determine whether |image| *may* point to the start
158*a03ca8b9SKrzysztof Kosiński // of an executable. Returns true iff the check passes.
159*a03ca8b9SKrzysztof Kosiński static bool QuickDetect(ConstBufferView image);
160*a03ca8b9SKrzysztof Kosiński
161*a03ca8b9SKrzysztof Kosiński DisassemblerElf(const DisassemblerElf&) = delete;
162*a03ca8b9SKrzysztof Kosiński const DisassemblerElf& operator=(const DisassemblerElf&) = delete;
163*a03ca8b9SKrzysztof Kosiński ~DisassemblerElf() override;
164*a03ca8b9SKrzysztof Kosiński
165*a03ca8b9SKrzysztof Kosiński // Disassembler:
166*a03ca8b9SKrzysztof Kosiński ExecutableType GetExeType() const override;
167*a03ca8b9SKrzysztof Kosiński std::string GetExeTypeString() const override;
168*a03ca8b9SKrzysztof Kosiński std::vector<ReferenceGroup> MakeReferenceGroups() const override = 0;
169*a03ca8b9SKrzysztof Kosiński
170*a03ca8b9SKrzysztof Kosiński // Read/Write functions that are common among different architectures.
171*a03ca8b9SKrzysztof Kosiński std::unique_ptr<ReferenceReader> MakeReadRelocs(offset_t lo, offset_t hi);
172*a03ca8b9SKrzysztof Kosiński std::unique_ptr<ReferenceWriter> MakeWriteRelocs(MutableBufferView image);
173*a03ca8b9SKrzysztof Kosiński
translator()174*a03ca8b9SKrzysztof Kosiński const AddressTranslator& translator() const { return translator_; }
175*a03ca8b9SKrzysztof Kosiński
176*a03ca8b9SKrzysztof Kosiński protected:
177*a03ca8b9SKrzysztof Kosiński friend Disassembler;
178*a03ca8b9SKrzysztof Kosiński
179*a03ca8b9SKrzysztof Kosiński DisassemblerElf();
180*a03ca8b9SKrzysztof Kosiński
181*a03ca8b9SKrzysztof Kosiński bool Parse(ConstBufferView image) override;
182*a03ca8b9SKrzysztof Kosiński
183*a03ca8b9SKrzysztof Kosiński // Returns the supported Elf_Ehdr::e_machine enum.
supported_architecture()184*a03ca8b9SKrzysztof Kosiński static constexpr elf::MachineArchitecture supported_architecture() {
185*a03ca8b9SKrzysztof Kosiński return Traits::kMachineValue;
186*a03ca8b9SKrzysztof Kosiński }
187*a03ca8b9SKrzysztof Kosiński
188*a03ca8b9SKrzysztof Kosiński // Returns the type to look for in the reloc section.
supported_relocation_type()189*a03ca8b9SKrzysztof Kosiński static constexpr uint32_t supported_relocation_type() {
190*a03ca8b9SKrzysztof Kosiński return Traits::kRelType;
191*a03ca8b9SKrzysztof Kosiński }
192*a03ca8b9SKrzysztof Kosiński
193*a03ca8b9SKrzysztof Kosiński // Performs architecture-specific parsing of an executable section, to extract
194*a03ca8b9SKrzysztof Kosiński // rel32 references.
195*a03ca8b9SKrzysztof Kosiński virtual void ParseExecSection(const typename Traits::Elf_Shdr& section) = 0;
196*a03ca8b9SKrzysztof Kosiński
197*a03ca8b9SKrzysztof Kosiński // Processes rel32 data after they are extracted from executable sections.
198*a03ca8b9SKrzysztof Kosiński virtual void PostProcessRel32() = 0;
199*a03ca8b9SKrzysztof Kosiński
200*a03ca8b9SKrzysztof Kosiński // Parses ELF header and section headers, and performs basic validation.
201*a03ca8b9SKrzysztof Kosiński // Returns whether parsing was successful.
202*a03ca8b9SKrzysztof Kosiński bool ParseHeader();
203*a03ca8b9SKrzysztof Kosiński
204*a03ca8b9SKrzysztof Kosiński // Extracts and stores section headers that we need.
205*a03ca8b9SKrzysztof Kosiński void ExtractInterestingSectionHeaders();
206*a03ca8b9SKrzysztof Kosiński
207*a03ca8b9SKrzysztof Kosiński // Parsing functions that extract references from various sections.
208*a03ca8b9SKrzysztof Kosiński void GetAbs32FromRelocSections();
209*a03ca8b9SKrzysztof Kosiński void GetRel32FromCodeSections();
210*a03ca8b9SKrzysztof Kosiński void ParseSections();
211*a03ca8b9SKrzysztof Kosiński
212*a03ca8b9SKrzysztof Kosiński // Main ELF header.
213*a03ca8b9SKrzysztof Kosiński const typename Traits::Elf_Ehdr* header_ = nullptr;
214*a03ca8b9SKrzysztof Kosiński
215*a03ca8b9SKrzysztof Kosiński // Section header table, ordered by section id.
216*a03ca8b9SKrzysztof Kosiński elf::Elf32_Half sections_count_ = 0;
217*a03ca8b9SKrzysztof Kosiński const typename Traits::Elf_Shdr* sections_ = nullptr;
218*a03ca8b9SKrzysztof Kosiński
219*a03ca8b9SKrzysztof Kosiński // Program header table.
220*a03ca8b9SKrzysztof Kosiński elf::Elf32_Half segments_count_ = 0;
221*a03ca8b9SKrzysztof Kosiński const typename Traits::Elf_Phdr* segments_ = nullptr;
222*a03ca8b9SKrzysztof Kosiński
223*a03ca8b9SKrzysztof Kosiński // Bit fields to store the role each section may play.
224*a03ca8b9SKrzysztof Kosiński std::vector<int> section_judgements_;
225*a03ca8b9SKrzysztof Kosiński
226*a03ca8b9SKrzysztof Kosiński // Translator between offsets and RVAs.
227*a03ca8b9SKrzysztof Kosiński AddressTranslator translator_;
228*a03ca8b9SKrzysztof Kosiński
229*a03ca8b9SKrzysztof Kosiński // Identity translator for abs32 translation.
230*a03ca8b9SKrzysztof Kosiński AddressTranslator identity_translator_;
231*a03ca8b9SKrzysztof Kosiński
232*a03ca8b9SKrzysztof Kosiński // Extracted relocation section dimensions data, sorted by file offsets.
233*a03ca8b9SKrzysztof Kosiński std::vector<SectionDimensionsElf> reloc_section_dims_;
234*a03ca8b9SKrzysztof Kosiński
235*a03ca8b9SKrzysztof Kosiński // Headers of executable sections, sorted by file offsets of the data each
236*a03ca8b9SKrzysztof Kosiński // header points to.
237*a03ca8b9SKrzysztof Kosiński std::vector<const typename Traits::Elf_Shdr*> exec_headers_;
238*a03ca8b9SKrzysztof Kosiński
239*a03ca8b9SKrzysztof Kosiński // Sorted file offsets of abs32 locations.
240*a03ca8b9SKrzysztof Kosiński std::vector<offset_t> abs32_locations_;
241*a03ca8b9SKrzysztof Kosiński };
242*a03ca8b9SKrzysztof Kosiński
243*a03ca8b9SKrzysztof Kosiński // Disassembler for ELF with Intel architectures.
244*a03ca8b9SKrzysztof Kosiński template <class TRAITS>
245*a03ca8b9SKrzysztof Kosiński class DisassemblerElfIntel : public DisassemblerElf<TRAITS> {
246*a03ca8b9SKrzysztof Kosiński public:
247*a03ca8b9SKrzysztof Kosiński using Traits = TRAITS;
248*a03ca8b9SKrzysztof Kosiński enum ReferenceType : uint8_t { kReloc, kAbs32, kRel32, kTypeCount };
249*a03ca8b9SKrzysztof Kosiński
250*a03ca8b9SKrzysztof Kosiński DisassemblerElfIntel();
251*a03ca8b9SKrzysztof Kosiński DisassemblerElfIntel(const DisassemblerElfIntel&) = delete;
252*a03ca8b9SKrzysztof Kosiński const DisassemblerElfIntel& operator=(const DisassemblerElfIntel&) = delete;
253*a03ca8b9SKrzysztof Kosiński ~DisassemblerElfIntel() override;
254*a03ca8b9SKrzysztof Kosiński
255*a03ca8b9SKrzysztof Kosiński // Disassembler:
256*a03ca8b9SKrzysztof Kosiński std::vector<ReferenceGroup> MakeReferenceGroups() const override;
257*a03ca8b9SKrzysztof Kosiński
258*a03ca8b9SKrzysztof Kosiński // DisassemblerElf:
259*a03ca8b9SKrzysztof Kosiński void ParseExecSection(const typename Traits::Elf_Shdr& section) override;
260*a03ca8b9SKrzysztof Kosiński void PostProcessRel32() override;
261*a03ca8b9SKrzysztof Kosiński
262*a03ca8b9SKrzysztof Kosiński // Specialized Read/Write functions.
263*a03ca8b9SKrzysztof Kosiński std::unique_ptr<ReferenceReader> MakeReadAbs32(offset_t lo, offset_t hi);
264*a03ca8b9SKrzysztof Kosiński std::unique_ptr<ReferenceWriter> MakeWriteAbs32(MutableBufferView image);
265*a03ca8b9SKrzysztof Kosiński std::unique_ptr<ReferenceReader> MakeReadRel32(offset_t lo, offset_t hi);
266*a03ca8b9SKrzysztof Kosiński std::unique_ptr<ReferenceWriter> MakeWriteRel32(MutableBufferView image);
267*a03ca8b9SKrzysztof Kosiński
268*a03ca8b9SKrzysztof Kosiński private:
269*a03ca8b9SKrzysztof Kosiński // Sorted file offsets of rel32 locations.
270*a03ca8b9SKrzysztof Kosiński // Using std::deque to reduce peak memory footprint.
271*a03ca8b9SKrzysztof Kosiński std::deque<offset_t> rel32_locations_;
272*a03ca8b9SKrzysztof Kosiński };
273*a03ca8b9SKrzysztof Kosiński
274*a03ca8b9SKrzysztof Kosiński using DisassemblerElfX86 = DisassemblerElfIntel<Elf32IntelTraits>;
275*a03ca8b9SKrzysztof Kosiński using DisassemblerElfX64 = DisassemblerElfIntel<Elf64IntelTraits>;
276*a03ca8b9SKrzysztof Kosiński
277*a03ca8b9SKrzysztof Kosiński // Disassembler for ELF with ARM architectures.
278*a03ca8b9SKrzysztof Kosiński template <class TRAITS>
279*a03ca8b9SKrzysztof Kosiński class DisassemblerElfArm : public DisassemblerElf<TRAITS> {
280*a03ca8b9SKrzysztof Kosiński public:
281*a03ca8b9SKrzysztof Kosiński using Traits = TRAITS;
282*a03ca8b9SKrzysztof Kosiński DisassemblerElfArm();
283*a03ca8b9SKrzysztof Kosiński DisassemblerElfArm(const DisassemblerElfArm&) = delete;
284*a03ca8b9SKrzysztof Kosiński const DisassemblerElfArm& operator=(const DisassemblerElfArm&) = delete;
285*a03ca8b9SKrzysztof Kosiński ~DisassemblerElfArm() override;
286*a03ca8b9SKrzysztof Kosiński
287*a03ca8b9SKrzysztof Kosiński // Determines whether target |offset| is in an executable section.
288*a03ca8b9SKrzysztof Kosiński bool IsTargetOffsetInExecSection(offset_t offset) const;
289*a03ca8b9SKrzysztof Kosiński
290*a03ca8b9SKrzysztof Kosiński // Creates an architecture-specific Rel32Finder for ParseExecSection.
291*a03ca8b9SKrzysztof Kosiński virtual std::unique_ptr<typename Traits::Rel32FinderUse> MakeRel32Finder(
292*a03ca8b9SKrzysztof Kosiński const typename Traits::Elf_Shdr& section) = 0;
293*a03ca8b9SKrzysztof Kosiński
294*a03ca8b9SKrzysztof Kosiński // DisassemblerElf:
295*a03ca8b9SKrzysztof Kosiński void ParseExecSection(const typename Traits::Elf_Shdr& section) override;
296*a03ca8b9SKrzysztof Kosiński void PostProcessRel32() override;
297*a03ca8b9SKrzysztof Kosiński
298*a03ca8b9SKrzysztof Kosiński // Specialized Read/Write functions.
299*a03ca8b9SKrzysztof Kosiński std::unique_ptr<ReferenceReader> MakeReadAbs32(offset_t lo, offset_t hi);
300*a03ca8b9SKrzysztof Kosiński std::unique_ptr<ReferenceWriter> MakeWriteAbs32(MutableBufferView image);
301*a03ca8b9SKrzysztof Kosiński
302*a03ca8b9SKrzysztof Kosiński // Specialized Read/Write functions for different rel32 address types.
303*a03ca8b9SKrzysztof Kosiński template <class ADDR_TRAITS>
304*a03ca8b9SKrzysztof Kosiński std::unique_ptr<ReferenceReader> MakeReadRel32(offset_t lower,
305*a03ca8b9SKrzysztof Kosiński offset_t upper);
306*a03ca8b9SKrzysztof Kosiński template <class ADDR_TRAITS>
307*a03ca8b9SKrzysztof Kosiński std::unique_ptr<ReferenceWriter> MakeWriteRel32(MutableBufferView image);
308*a03ca8b9SKrzysztof Kosiński
309*a03ca8b9SKrzysztof Kosiński protected:
310*a03ca8b9SKrzysztof Kosiński // Sorted file offsets of rel32 locations for each rel32 address type.
311*a03ca8b9SKrzysztof Kosiński std::deque<offset_t>
312*a03ca8b9SKrzysztof Kosiński rel32_locations_table_[Traits::ArmReferenceType::kTypeCount];
313*a03ca8b9SKrzysztof Kosiński };
314*a03ca8b9SKrzysztof Kosiński
315*a03ca8b9SKrzysztof Kosiński // Disassembler for ELF with AArch32 (AKA ARM32).
316*a03ca8b9SKrzysztof Kosiński class DisassemblerElfAArch32 : public DisassemblerElfArm<ElfAArch32Traits> {
317*a03ca8b9SKrzysztof Kosiński public:
318*a03ca8b9SKrzysztof Kosiński DisassemblerElfAArch32();
319*a03ca8b9SKrzysztof Kosiński DisassemblerElfAArch32(const DisassemblerElfAArch32&) = delete;
320*a03ca8b9SKrzysztof Kosiński const DisassemblerElfAArch32& operator=(const DisassemblerElfAArch32&) =
321*a03ca8b9SKrzysztof Kosiński delete;
322*a03ca8b9SKrzysztof Kosiński ~DisassemblerElfAArch32() override;
323*a03ca8b9SKrzysztof Kosiński
324*a03ca8b9SKrzysztof Kosiński // Disassembler:
325*a03ca8b9SKrzysztof Kosiński std::vector<ReferenceGroup> MakeReferenceGroups() const override;
326*a03ca8b9SKrzysztof Kosiński
327*a03ca8b9SKrzysztof Kosiński // DisassemblerElfArm:
328*a03ca8b9SKrzysztof Kosiński std::unique_ptr<typename Traits::Rel32FinderUse> MakeRel32Finder(
329*a03ca8b9SKrzysztof Kosiński const typename Traits::Elf_Shdr& section) override;
330*a03ca8b9SKrzysztof Kosiński
331*a03ca8b9SKrzysztof Kosiński // Under the naive assumption that an executable section is entirely ARM mode
332*a03ca8b9SKrzysztof Kosiński // or THUMB2 mode, this function implements heuristics to distinguish between
333*a03ca8b9SKrzysztof Kosiński // the two. Returns true if section is THUMB2 mode; otherwise return false.
334*a03ca8b9SKrzysztof Kosiński bool IsExecSectionThumb2(const typename Traits::Elf_Shdr& section) const;
335*a03ca8b9SKrzysztof Kosiński };
336*a03ca8b9SKrzysztof Kosiński
337*a03ca8b9SKrzysztof Kosiński // Disassembler for ELF with AArch64 (AKA ARM64).
338*a03ca8b9SKrzysztof Kosiński class DisassemblerElfAArch64 : public DisassemblerElfArm<ElfAArch64Traits> {
339*a03ca8b9SKrzysztof Kosiński public:
340*a03ca8b9SKrzysztof Kosiński DisassemblerElfAArch64();
341*a03ca8b9SKrzysztof Kosiński DisassemblerElfAArch64(const DisassemblerElfAArch64&) = delete;
342*a03ca8b9SKrzysztof Kosiński const DisassemblerElfAArch64& operator=(const DisassemblerElfAArch64&) =
343*a03ca8b9SKrzysztof Kosiński delete;
344*a03ca8b9SKrzysztof Kosiński ~DisassemblerElfAArch64() override;
345*a03ca8b9SKrzysztof Kosiński
346*a03ca8b9SKrzysztof Kosiński // Disassembler:
347*a03ca8b9SKrzysztof Kosiński std::vector<ReferenceGroup> MakeReferenceGroups() const override;
348*a03ca8b9SKrzysztof Kosiński
349*a03ca8b9SKrzysztof Kosiński // DisassemblerElfArm:
350*a03ca8b9SKrzysztof Kosiński std::unique_ptr<typename Traits::Rel32FinderUse> MakeRel32Finder(
351*a03ca8b9SKrzysztof Kosiński const typename Traits::Elf_Shdr& section) override;
352*a03ca8b9SKrzysztof Kosiński };
353*a03ca8b9SKrzysztof Kosiński
354*a03ca8b9SKrzysztof Kosiński } // namespace zucchini
355*a03ca8b9SKrzysztof Kosiński
356*a03ca8b9SKrzysztof Kosiński #endif // COMPONENTS_ZUCCHINI_DISASSEMBLER_ELF_H_
357