ROSE  0.11.96.0
DisassemblerAarch32.h
1 #ifndef ROSE_BinaryAnalysis_DisassemblerAarch32_H
2 #define ROSE_BinaryAnalysis_DisassemblerAarch32_H
3 #include <Rose/BinaryAnalysis/Disassembler.h>
4 #ifdef ROSE_ENABLE_ASM_AARCH32
5 
6 #include <capstone/capstone.h>
7 
8 namespace Rose {
9 namespace BinaryAnalysis {
10 
15 class DisassemblerAarch32: public Disassembler {
16 public:
18  enum class Mode {
19  ARM32 = CS_MODE_ARM, // probably zero, not really a bit flag
20  THUMB = CS_MODE_THUMB,
21  MCLASS = CS_MODE_MCLASS,
22  V8 = CS_MODE_V8
23  };
24 
26  using Modes = BitFlags<Mode>;
27 
28 private:
29  Modes modes_; // a subset of Capstone's cs_mode constants (warning: nonorthoganal concepts)
30  csh capstone_; // the capstone handle
31  bool capstoneOpened_; // whether capstone_ is initialized
32 
33 public:
35  explicit DisassemblerAarch32(Modes modes = Modes())
36  : modes_(modes), capstoneOpened_(false) {
37  init();
38  }
39 
40  static DisassemblerAarch32* instanceA32() {
41  return new DisassemblerAarch32(Modes(Mode::ARM32));
42  }
43 
44  static DisassemblerAarch32* instanceT32() {
45  return new DisassemblerAarch32(Modes(Mode::THUMB));
46  }
47 
48  ~DisassemblerAarch32();
49 
50  // overrides
51  bool canDisassemble(SgAsmGenericHeader*) const override;
52  Disassembler* clone() const override;
53  Unparser::BasePtr unparser() const override;
54  SgAsmInstruction* disassembleOne(const MemoryMap::Ptr&, rose_addr_t startVa, AddressSet *successors=nullptr) override;
55  SgAsmInstruction* makeUnknownInstruction(const Exception&) override;
56 
57 private:
58  void init();
59 
60  // Convert the instruction bytes to a 32- or 16- bit integer.
61  uint32_t bytesToWord(size_t nBytes, const uint8_t *bytes);
62 
63  // Replace instruction-pointer expressions with constants if possible, leaving a comment in its place.
64  void commentIpRelative(SgAsmInstruction*);
65 
66  // Fix the mnemonic to be something more human readable.
67  std::string fixMnemonic(const std::string&, arm_cc);
68 
69  // Make a ROSE instruction operand from a Capstone operand
70  SgAsmExpression* makeOperand(const cs_insn&, const cs_arm_op&);
71 
72  // Add shift or rotate operations to an expression based on the Capstone operand.
73  SgAsmExpression* shiftOrRotate(SgAsmExpression*, const cs_arm_op&);
74 
75  // Change a memory reference expression's address by wrapping it in a SgAsmPreIncrementExpression or SgAsmPostIncrement
76  // expression if necessary.
77  void wrapPrePostIncrement(SgAsmAarch32Instruction*, const cs_insn&, const uint32_t insnWord);
78 
79  // Convert a Capstone register number to a ROSE register descriptor. ROSE's register descriptor are a lot more than just an
80  // ID number.
81  RegisterDescriptor makeRegister(arm_reg);
82 
83  // Convert a Capstone system register number to a ROSE expression.
84  SgAsmExpression* makeSystemRegister(arm_sysreg);
85 
86  // Create a register descriptor for a coprocessor register.
87  RegisterDescriptor makeCoprocRegister(int registerNumber);
88 
89  // Restrict a register to just part of a register
90  RegisterDescriptor subRegister(RegisterDescriptor, int idx);
91 
92  // Return a type for register.
93  SgAsmType* registerType(RegisterDescriptor);
94 
95  // Capstone doesn't return information about how much memory is read for a memory read operand. Therefore, we need to
96  // partially decode instructions ourselves to get this information.
97  SgAsmType* typeForMemoryRead(const cs_insn&);
98 
99  // Returns the opcode as a 32-bit value.
100  uint32_t opcode(const cs_insn&);
101 };
102 
103 } // namespace
104 } // namespace
105 
106 #endif
107 #endif
Base class for machine instructions.
Main namespace for the ROSE library.
Base class for container file headers.
const char * Mode(int64_t)
Convert Rose::AST::cmdline::graphviz_t::Mode enum constant to a string.
Base class for expressions.
Base class for binary types.