================
@@ -13,15 +13,124 @@
 #include "lldb/Core/Disassembler.h"
 #include "lldb/Target/ExecutionContext.h"
 #include "lldb/Utility/ArchSpec.h"
+#include "lldb/Utility/RegisterValue.h"
 
 #include "Plugins/Instruction/ARM64/EmulateInstructionARM64.h"
+#include "Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h"
+#include "Plugins/Process/Utility/lldb-arm64-register-enums.h"
 
 using namespace lldb;
 using namespace lldb_private;
 
 struct Arch64EmulatorTester : public EmulateInstructionARM64 {
+  RegisterInfoPOSIX_arm64::GPR gpr;
+  uint8_t memory[64] = {0};
+  uint64_t memory_offset = 0;
+
   Arch64EmulatorTester()
-      : EmulateInstructionARM64(ArchSpec("arm64-apple-ios")) {}
+      : EmulateInstructionARM64(ArchSpec("arm64-apple-ios")) {
+    memset(&gpr, 0, sizeof(gpr));
+    EmulateInstruction::SetCallbacks(ReadMemoryCallback, WriteMemoryCallback,
+                                     ReadRegisterCallback,
+                                     WriteRegisterCallback);
+  }
+
+  static bool ReadRegisterCallback(EmulateInstruction *instruction, void 
*baton,
+                                   const RegisterInfo *reg_info,
+                                   RegisterValue &reg_value) {
+    auto *tester = static_cast<Arch64EmulatorTester *>(instruction);
+    uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
+    if (reg >= gpr_x1_arm64 && reg <= gpr_x28_arm64) {
+      reg_value.SetUInt64(tester->gpr.x[reg - gpr_x0_arm64]);
+      return true;
+    }
+    if (reg >= gpr_w1_arm64 && reg <= gpr_w28_arm64) {
+      reg_value.SetUInt32(tester->gpr.x[reg - gpr_w0_arm64]);
+      return true;
+    }
+    switch (reg) {
+    case gpr_x0_arm64:
+      reg_value.SetUInt64(0);
+      return true;
+    case gpr_w0_arm64:
+      reg_value.SetUInt32(0);
+      return true;
+    case gpr_fp_arm64:
+      reg_value.SetUInt64(tester->gpr.fp);
+      return true;
+    case gpr_lr_arm64:
+      reg_value.SetUInt64(tester->gpr.lr);
+      return true;
+    case gpr_sp_arm64:
+      reg_value.SetUInt64(tester->gpr.sp);
+      return true;
+    case gpr_pc_arm64:
+      reg_value.SetUInt64(tester->gpr.pc);
+      return true;
+    case gpr_cpsr_arm64:
+      reg_value.SetUInt64(tester->gpr.cpsr);
+      return true;
+    default:
+      return false;
+    }
+  }
+
+  static bool WriteRegisterCallback(EmulateInstruction *instruction,
+                                    void *baton, const Context &context,
+                                    const RegisterInfo *reg_info,
+                                    const RegisterValue &reg_value) {
+    auto *tester = static_cast<Arch64EmulatorTester *>(instruction);
+    uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
+    if (reg >= gpr_x1_arm64 && reg <= gpr_x28_arm64) {
+      tester->gpr.x[reg - gpr_x0_arm64] = reg_value.GetAsUInt64();
+      return true;
+    }
+    if (reg >= gpr_w1_arm64 && reg <= gpr_w28_arm64) {
+      tester->gpr.x[reg - gpr_w0_arm64] = reg_value.GetAsUInt32();
+      return true;
+    }
+    switch (reg) {
+    case gpr_fp_arm64:
+      tester->gpr.fp = reg_value.GetAsUInt64();
+      return true;
+    case gpr_lr_arm64:
+      tester->gpr.lr = reg_value.GetAsUInt64();
+      return true;
+    case gpr_sp_arm64:
+      tester->gpr.sp = reg_value.GetAsUInt64();
+      return true;
+    case gpr_pc_arm64:
+      tester->gpr.pc = reg_value.GetAsUInt64();
+      return true;
+    case gpr_cpsr_arm64:
+      tester->gpr.cpsr = reg_value.GetAsUInt64();
+      return true;
+    default:
+      return false;
+    }
+  }
+
+  static size_t ReadMemoryCallback(EmulateInstruction *instruction, void 
*baton,
+                                   const Context &context, addr_t addr,
+                                   void *dst, size_t length) {
+    auto *tester = static_cast<Arch64EmulatorTester *>(instruction);
+    assert(addr >= tester->memory_offset);
+    assert(addr - tester->memory_offset + length <= sizeof(tester->memory));
+    if (addr >= tester->memory_offset &&
+        addr - tester->memory_offset + length <= sizeof(tester->memory)) {
+      memcpy(dst, tester->memory + addr - tester->memory_offset, length);
+      return length;
+    }
+    return 0;
+  };
+
+  static size_t WriteMemoryCallback(EmulateInstruction *instruction,
+                                    void *baton, const Context &context,
+                                    addr_t addr, const void *dst,
+                                    size_t length) {
+    // TODO: implement when required
----------------
DavidSpickett wrote:

Does this ever get called? If not you could add an assert here too.

https://github.com/llvm/llvm-project/pull/151460
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to