|
13 | 13 | #include "lldb/Core/Disassembler.h" |
14 | 14 | #include "lldb/Target/ExecutionContext.h" |
15 | 15 | #include "lldb/Utility/ArchSpec.h" |
16 | | -#include "lldb/Utility/RegisterValue.h" |
17 | 16 |
|
18 | 17 | #include "Plugins/Instruction/ARM64/EmulateInstructionARM64.h" |
19 | | -#include "Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h" |
20 | | -#include "Plugins/Process/Utility/lldb-arm64-register-enums.h" |
21 | 18 |
|
22 | 19 | using namespace lldb; |
23 | 20 | using namespace lldb_private; |
24 | 21 |
|
25 | 22 | struct Arch64EmulatorTester : public EmulateInstructionARM64 { |
26 | | - RegisterInfoPOSIX_arm64::GPR gpr; |
27 | | - uint8_t memory[64] = {0}; |
28 | | - uint64_t memory_offset = 0; |
29 | | - |
30 | 23 | Arch64EmulatorTester() |
31 | | - : EmulateInstructionARM64(ArchSpec("arm64-apple-ios")) { |
32 | | - memset(&gpr, 0, sizeof(gpr)); |
33 | | - EmulateInstruction::SetCallbacks(ReadMemoryCallback, WriteMemoryCallback, |
34 | | - ReadRegisterCallback, |
35 | | - WriteRegisterCallback); |
36 | | - } |
37 | | - |
38 | | - static bool ReadRegisterCallback(EmulateInstruction *instruction, void *baton, |
39 | | - const RegisterInfo *reg_info, |
40 | | - RegisterValue ®_value) { |
41 | | - auto *tester = static_cast<Arch64EmulatorTester *>(instruction); |
42 | | - uint32_t reg = reg_info->kinds[eRegisterKindLLDB]; |
43 | | - if (reg >= gpr_x0_arm64 && reg <= gpr_x28_arm64) { |
44 | | - reg_value.SetUInt64(tester->gpr.x[reg - gpr_x0_arm64]); |
45 | | - return true; |
46 | | - } |
47 | | - if (reg >= gpr_w0_arm64 && reg <= gpr_w28_arm64) { |
48 | | - reg_value.SetUInt32(tester->gpr.x[reg - gpr_w0_arm64]); |
49 | | - return true; |
50 | | - } |
51 | | - switch (reg) { |
52 | | - case gpr_fp_arm64: |
53 | | - reg_value.SetUInt64(tester->gpr.fp); |
54 | | - return true; |
55 | | - case gpr_lr_arm64: |
56 | | - reg_value.SetUInt64(tester->gpr.lr); |
57 | | - return true; |
58 | | - case gpr_sp_arm64: |
59 | | - reg_value.SetUInt64(tester->gpr.sp); |
60 | | - return true; |
61 | | - case gpr_pc_arm64: |
62 | | - reg_value.SetUInt64(tester->gpr.pc); |
63 | | - return true; |
64 | | - case gpr_cpsr_arm64: |
65 | | - reg_value.SetUInt64(tester->gpr.cpsr); |
66 | | - return true; |
67 | | - default: |
68 | | - return false; |
69 | | - } |
70 | | - } |
71 | | - |
72 | | - static bool WriteRegisterCallback(EmulateInstruction *instruction, |
73 | | - void *baton, const Context &context, |
74 | | - const RegisterInfo *reg_info, |
75 | | - const RegisterValue ®_value) { |
76 | | - auto *tester = static_cast<Arch64EmulatorTester *>(instruction); |
77 | | - uint32_t reg = reg_info->kinds[eRegisterKindLLDB]; |
78 | | - if (reg >= gpr_x0_arm64 && reg <= gpr_x28_arm64) { |
79 | | - tester->gpr.x[reg - gpr_x0_arm64] = reg_value.GetAsUInt64(); |
80 | | - return true; |
81 | | - } |
82 | | - if (reg >= gpr_w0_arm64 && reg <= gpr_w28_arm64) { |
83 | | - tester->gpr.x[reg - gpr_w0_arm64] = reg_value.GetAsUInt32(); |
84 | | - return true; |
85 | | - } |
86 | | - switch (reg) { |
87 | | - case gpr_fp_arm64: |
88 | | - tester->gpr.fp = reg_value.GetAsUInt64(); |
89 | | - return true; |
90 | | - case gpr_lr_arm64: |
91 | | - tester->gpr.lr = reg_value.GetAsUInt64(); |
92 | | - return true; |
93 | | - case gpr_sp_arm64: |
94 | | - tester->gpr.sp = reg_value.GetAsUInt64(); |
95 | | - return true; |
96 | | - case gpr_pc_arm64: |
97 | | - tester->gpr.pc = reg_value.GetAsUInt64(); |
98 | | - return true; |
99 | | - case gpr_cpsr_arm64: |
100 | | - tester->gpr.cpsr = reg_value.GetAsUInt64(); |
101 | | - return true; |
102 | | - default: |
103 | | - return false; |
104 | | - } |
105 | | - } |
106 | | - |
107 | | - static size_t ReadMemoryCallback(EmulateInstruction *instruction, void *baton, |
108 | | - const Context &context, addr_t addr, |
109 | | - void *dst, size_t length) { |
110 | | - auto *tester = static_cast<Arch64EmulatorTester *>(instruction); |
111 | | - assert(addr >= tester->memory_offset); |
112 | | - assert(addr - tester->memory_offset + length <= sizeof(tester->memory)); |
113 | | - if (addr >= tester->memory_offset && |
114 | | - addr - tester->memory_offset + length <= sizeof(tester->memory)) { |
115 | | - memcpy(dst, tester->memory + addr - tester->memory_offset, length); |
116 | | - return length; |
117 | | - } |
118 | | - return 0; |
119 | | - }; |
120 | | - |
121 | | - static size_t WriteMemoryCallback(EmulateInstruction *instruction, |
122 | | - void *baton, const Context &context, |
123 | | - addr_t addr, const void *dst, |
124 | | - size_t length) { |
125 | | - llvm_unreachable("implement when required"); |
126 | | - return 0; |
127 | | - }; |
| 24 | + : EmulateInstructionARM64(ArchSpec("arm64-apple-ios")) {} |
128 | 25 |
|
129 | 26 | static uint64_t AddWithCarry(uint32_t N, uint64_t x, uint64_t y, bool carry_in, |
130 | 27 | EmulateInstructionARM64::ProcState &proc_state) { |
@@ -163,18 +60,3 @@ TEST_F(TestAArch64Emulator, TestOverflow) { |
163 | 60 | ASSERT_EQ(pstate.V, 1ULL); |
164 | 61 | ASSERT_EQ(pstate.C, 0ULL); |
165 | 62 | } |
166 | | - |
167 | | -TEST_F(TestAArch64Emulator, TestAutoAdvancePC) { |
168 | | - Arch64EmulatorTester emu; |
169 | | - emu.memory_offset = 0x123456789abcde00; |
170 | | - emu.gpr.pc = 0x123456789abcde00; |
171 | | - emu.gpr.x[8] = 0x123456789abcde20; |
172 | | - memcpy(emu.memory, "\x08\x01\x40\xb9", 4); // ldr w8, [x8] |
173 | | - memcpy(emu.memory + 0x20, "\x11\x22\x33\x44", 4); // 0x44332211 |
174 | | - ASSERT_TRUE(emu.ReadInstruction()); |
175 | | - ASSERT_TRUE( |
176 | | - emu.EvaluateInstruction(eEmulateInstructionOptionAutoAdvancePC | |
177 | | - eEmulateInstructionOptionIgnoreConditions)); |
178 | | - ASSERT_EQ(emu.gpr.pc, 0x123456789abcde04); |
179 | | - ASSERT_EQ(emu.gpr.x[8], 0x44332211); |
180 | | -} |
0 commit comments