Support all registers

This commit is contained in:
momo5502
2025-01-19 11:30:32 +01:00
parent 77b4ee5e1e
commit ce291728bd

View File

@@ -5,17 +5,102 @@
#include <gdb-stub/gdb_stub.hpp>
#include "x64_target_descriptions.hpp"
#include <optional>
inline std::vector gdb_registers{
x64_register::rax, x64_register::rbx, x64_register::rcx, x64_register::rdx, x64_register::rsi, x64_register::rdi,
x64_register::rbp, x64_register::rsp, x64_register::r8, x64_register::r9, x64_register::r10, x64_register::r11,
x64_register::r12, x64_register::r13, x64_register::r14, x64_register::r15, x64_register::rip, x64_register::rflags,
/*x64_register::cs,
x64_register::ss,
x64_register::ds,
x64_register::es,
x64_register::fs,
x64_register::gs,*/
struct register_entry
{
x64_register reg;
std::optional<size_t> expected_size;
std::optional<size_t> offset;
register_entry(const x64_register reg = x64_register::invalid,
const std::optional<size_t> expected_size = std::nullopt,
const std::optional<size_t> offset = std::nullopt)
: reg(reg),
expected_size(expected_size),
offset(offset)
{
}
};
inline std::vector<register_entry> gdb_registers{
x64_register::rax,
x64_register::rbx,
x64_register::rcx,
x64_register::rdx,
x64_register::rsi,
x64_register::rdi,
x64_register::rbp,
x64_register::rsp,
x64_register::r8,
x64_register::r9,
x64_register::r10,
x64_register::r11,
x64_register::r12,
x64_register::r13,
x64_register::r14,
x64_register::r15,
x64_register::rip,
x64_register::eflags,
{x64_register::cs, 4},
{x64_register::ss, 4},
{x64_register::ds, 4},
{x64_register::es, 4},
{x64_register::fs, 4},
{x64_register::gs, 4},
x64_register::st0,
x64_register::st1,
x64_register::st2,
x64_register::st3,
x64_register::st4,
x64_register::st5,
x64_register::st6,
x64_register::st7,
{x64_register::fpcw, 4}, // fctrl
{x64_register::fpsw, 4}, // fstat
{x64_register::fptag, 4}, // ftag
{x64_register::fcs, 4}, // fiseg
{x64_register::fip, 4}, // fioff
{x64_register::fds, 4}, // foseg
{x64_register::fdp, 4}, // fooff
{x64_register::fop, 4}, // fop
x64_register::xmm0,
x64_register::xmm1,
x64_register::xmm2,
x64_register::xmm3,
x64_register::xmm4,
x64_register::xmm5,
x64_register::xmm6,
x64_register::xmm7,
x64_register::xmm8,
x64_register::xmm9,
x64_register::xmm10,
x64_register::xmm11,
x64_register::xmm12,
x64_register::xmm13,
x64_register::xmm14,
x64_register::xmm15,
x64_register::mxcsr,
x64_register::fs_base,
x64_register::gs_base,
{x64_register::ymm0, std::nullopt, 16},
{x64_register::ymm1, std::nullopt, 16},
{x64_register::ymm2, std::nullopt, 16},
{x64_register::ymm3, std::nullopt, 16},
{x64_register::ymm4, std::nullopt, 16},
{x64_register::ymm5, std::nullopt, 16},
{x64_register::ymm6, std::nullopt, 16},
{x64_register::ymm7, std::nullopt, 16},
{x64_register::ymm8, std::nullopt, 16},
{x64_register::ymm9, std::nullopt, 16},
{x64_register::ymm10, std::nullopt, 16},
{x64_register::ymm11, std::nullopt, 16},
{x64_register::ymm12, std::nullopt, 16},
{x64_register::ymm13, std::nullopt, 16},
{x64_register::ymm14, std::nullopt, 16},
{x64_register::ymm15, std::nullopt, 16},
};
inline memory_operation map_breakpoint_type(const gdb_stub::breakpoint_type type)
@@ -117,7 +202,24 @@ class x64_gdb_stub_handler : public gdb_stub::debugging_handler
return 0;
}
return this->emu_->read_register(gdb_registers[reg], data, max_length);
const auto real_reg = gdb_registers[reg];
auto size = this->emu_->read_register(real_reg.reg, data, max_length);
if (real_reg.offset)
{
size -= *real_reg.offset;
memcpy(data, static_cast<uint8_t*>(data) + *real_reg.offset, size);
}
const auto result_size = real_reg.expected_size.value_or(size);
if (result_size > size)
{
memset(static_cast<uint8_t*>(data) + size, 0, result_size - size);
}
return result_size;
}
catch (...)
{
@@ -134,7 +236,31 @@ class x64_gdb_stub_handler : public gdb_stub::debugging_handler
return 0;
}
return this->emu_->write_register(gdb_registers[reg], data, size);
const auto real_reg = gdb_registers[reg];
size_t written_size = 0;
if (real_reg.offset)
{
std::vector<std::byte> full_data{};
full_data.resize(this->get_max_register_size());
written_size = this->emu_->read_register(real_reg.reg, full_data.data(), full_data.size());
if (written_size < *real_reg.offset)
{
return 0;
}
memcpy(full_data.data() + *real_reg.offset, data, written_size - *real_reg.offset);
this->emu_->write_register(real_reg.reg, full_data.data(), written_size);
written_size -= *real_reg.offset;
}
else
{
written_size = this->emu_->write_register(real_reg.reg, data, size);
}
return real_reg.expected_size.value_or(written_size);
}
catch (...)
{