================ @@ -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 ®_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 ®_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 ---------------- labath wrote:
or even `llvm_unreachable` 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