1// Copyright 2013 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef COURGETTE_DISASSEMBLER_ELF_32_ARM_H_
6#define COURGETTE_DISASSEMBLER_ELF_32_ARM_H_
7
8#include "base/basictypes.h"
9#include "courgette/disassembler_elf_32.h"
10#include "courgette/memory_allocator.h"
11#include "courgette/types_elf.h"
12
13namespace courgette {
14
15class AssemblyProgram;
16
17enum ARM_RVA {
18  ARM_OFF8,
19  ARM_OFF11,
20  ARM_OFF24,
21  ARM_OFF25,
22  ARM_OFF21,
23};
24
25class DisassemblerElf32ARM : public DisassemblerElf32 {
26 public:
27  class TypedRVAARM : public TypedRVA {
28   public:
29    TypedRVAARM(ARM_RVA type, RVA rva) : TypedRVA(rva), type_(type) { }
30
31    uint16 c_op() const {
32      return c_op_;
33    }
34
35    virtual CheckBool ComputeRelativeTarget(const uint8* op_pointer);
36
37    virtual CheckBool EmitInstruction(AssemblyProgram* program,
38                                      RVA target_rva);
39
40    virtual uint16 op_size() const;
41
42   private:
43    ARM_RVA type_;
44
45    uint16 c_op_;  // set by ComputeRelativeTarget()
46    const uint8* arm_op_;
47  };
48
49  explicit DisassemblerElf32ARM(const void* start, size_t length);
50
51  virtual ExecutableType kind() { return EXE_ELF_32_ARM; }
52
53  virtual e_machine_values ElfEM() { return EM_ARM; }
54
55  static CheckBool Compress(ARM_RVA type, uint32 arm_op, RVA rva,
56                            uint16* c_op /* out */, uint32* addr /* out */);
57
58  static CheckBool Decompress(ARM_RVA type, uint16 c_op, uint32 addr,
59                              uint32* arm_op /* out */);
60
61 protected:
62
63  virtual CheckBool RelToRVA(Elf32_Rel rel, RVA* result)
64    const WARN_UNUSED_RESULT;
65
66  virtual CheckBool ParseRelocationSection(
67      const Elf32_Shdr *section_header,
68        AssemblyProgram* program) WARN_UNUSED_RESULT;
69
70  virtual CheckBool ParseRel32RelocsFromSection(
71      const Elf32_Shdr* section) WARN_UNUSED_RESULT;
72
73#if COURGETTE_HISTOGRAM_TARGETS
74  std::map<RVA, int> rel32_target_rvas_;
75#endif
76
77  DISALLOW_COPY_AND_ASSIGN(DisassemblerElf32ARM);
78};
79
80}  // namespace courgette
81
82#endif  // COURGETTE_DISASSEMBLER_ELF_32_ARM_H_
83