From 192d5687ff4dcf9d13aead64ef307fe69a0f76f8 Mon Sep 17 00:00:00 2001 From: momo5502 Date: Sun, 19 Jan 2025 09:37:59 +0100 Subject: [PATCH 1/4] Provide x86_64 target descriptions --- src/gdb-stub/gdb_stub.cpp | 36 ++- src/gdb-stub/gdb_stub.hpp | 2 +- .../debugging/win_x64_gdb_stub_handler.hpp | 5 - .../debugging/x64_gdb_stub_handler.hpp | 13 ++ .../debugging/x64_target_descriptions.hpp | 215 ++++++++++++++++++ 5 files changed, 262 insertions(+), 9 deletions(-) create mode 100644 src/windows-emulator/debugging/x64_target_descriptions.hpp diff --git a/src/gdb-stub/gdb_stub.cpp b/src/gdb-stub/gdb_stub.cpp index 6f67cd0d..308cded5 100644 --- a/src/gdb-stub/gdb_stub.cpp +++ b/src/gdb-stub/gdb_stub.cpp @@ -49,15 +49,45 @@ namespace gdb_stub return {name, args}; } + void handle_features(connection_handler& connection, debugging_handler& handler, const std::string_view payload) + { + const auto [command, args] = split_string(payload, ':'); + + if (command != "read") + { + connection.send_reply({}); + return; + } + + const auto [file, data] = split_string(args, ':'); + + size_t offset{}, length{}; + rt_assert(sscanf_s(std::string(data).c_str(), "%zx,%zx", &offset, &length) == 2); + + const auto target_description = handler.get_target_description(file); + + if (offset >= target_description.size()) + { + connection.send_reply("l"); + return; + } + + const auto remaining = target_description.size() - offset; + const auto real_length = std::min(remaining, length); + const auto is_end = real_length == remaining; + + const auto sub_region = target_description.substr(offset, real_length); + + connection.send_reply((is_end ? "l" : "m") + sub_region); + } + void process_xfer(connection_handler& connection, debugging_handler& handler, const std::string_view payload) { auto [name, args] = split_string(payload, ':'); if (name == "features") { - connection.send_reply("l" // - + handler.get_target_description() // - + ""); + handle_features(connection, handler, args); } else { diff --git a/src/gdb-stub/gdb_stub.hpp b/src/gdb-stub/gdb_stub.hpp index 9a71b7b2..493a960e 100644 --- a/src/gdb-stub/gdb_stub.hpp +++ b/src/gdb-stub/gdb_stub.hpp @@ -42,7 +42,7 @@ namespace gdb_stub virtual void on_interrupt() = 0; - virtual std::string get_target_description() = 0; + virtual std::string get_target_description(std::string_view file) = 0; }; bool run_gdb_stub(const network::address& bind_address, debugging_handler& handler); diff --git a/src/windows-emulator/debugging/win_x64_gdb_stub_handler.hpp b/src/windows-emulator/debugging/win_x64_gdb_stub_handler.hpp index 96b87212..451078a8 100644 --- a/src/windows-emulator/debugging/win_x64_gdb_stub_handler.hpp +++ b/src/windows-emulator/debugging/win_x64_gdb_stub_handler.hpp @@ -40,11 +40,6 @@ class win_x64_gdb_stub_handler : public x64_gdb_stub_handler return gdb_stub::action::resume; } - std::string get_target_description() override - { - return "i386:x86-64"; - } - private: windows_emulator* win_emu_{}; }; diff --git a/src/windows-emulator/debugging/x64_gdb_stub_handler.hpp b/src/windows-emulator/debugging/x64_gdb_stub_handler.hpp index f80996cd..7dde76a4 100644 --- a/src/windows-emulator/debugging/x64_gdb_stub_handler.hpp +++ b/src/windows-emulator/debugging/x64_gdb_stub_handler.hpp @@ -4,6 +4,8 @@ #include #include +#include "x64_target_descriptions.hpp" + 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, @@ -211,6 +213,17 @@ class x64_gdb_stub_handler : public gdb_stub::debugging_handler this->emu_->stop(); } + std::string get_target_description(const std::string_view file) override + { + const auto entry = x64_target_descriptions.find(file); + if (entry == x64_target_descriptions.end()) + { + return {}; + } + + return entry->second; + } + private: x64_emulator* emu_{}; diff --git a/src/windows-emulator/debugging/x64_target_descriptions.hpp b/src/windows-emulator/debugging/x64_target_descriptions.hpp new file mode 100644 index 00000000..a775f6ad --- /dev/null +++ b/src/windows-emulator/debugging/x64_target_descriptions.hpp @@ -0,0 +1,215 @@ +#pragma once + +#include +#include + +inline std::map> x64_target_descriptions{ + { + "target.xml", + R"__xml__( + + + + + + + i386:x86-64 + + + + + +)__xml__", + }, + { + "64bit-core.xml", + R"__xml__( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +)__xml__", + }, + { + "64bit-sse.xml", + R"__xml__( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +)__xml__", + }, + { + "64bit-segments.xml", + R"__xml__( + + + + + + + +)__xml__", + }, + { + "64bit-avx.xml", + R"__xml__( + + + + + + + + + + + + + + + + + + + + + +)__xml__", + }, +}; From 77b4ee5e1edb80c29515e1c6f13ba7734ae6ec64 Mon Sep 17 00:00:00 2001 From: momo5502 Date: Sun, 19 Jan 2025 10:18:45 +0100 Subject: [PATCH 2/4] Properly read and write registers --- src/common/utils/string.hpp | 2 +- src/emulator/cpu_interface.hpp | 4 +-- src/emulator/typed_emulator.hpp | 12 +++---- src/gdb-stub/gdb_stub.cpp | 34 +++++++++---------- src/gdb-stub/gdb_stub.hpp | 4 +-- src/unicorn-emulator/unicorn_x64_emulator.cpp | 10 ++++-- .../debugging/x64_gdb_stub_handler.hpp | 24 +++++-------- 7 files changed, 43 insertions(+), 47 deletions(-) diff --git a/src/common/utils/string.hpp b/src/common/utils/string.hpp index 2b5100b8..0c1bb0c5 100644 --- a/src/common/utils/string.hpp +++ b/src/common/utils/string.hpp @@ -109,7 +109,7 @@ namespace utils::string return to_hex_string(&i, sizeof(Integer), uppercase); } - inline std::string to_hex_string(const std::span data, const bool uppercase = false) + inline std::string to_hex_string(const std::span data, const bool uppercase = false) { return to_hex_string(data.data(), data.size(), uppercase); } diff --git a/src/emulator/cpu_interface.hpp b/src/emulator/cpu_interface.hpp index 4d30eef0..06e35593 100644 --- a/src/emulator/cpu_interface.hpp +++ b/src/emulator/cpu_interface.hpp @@ -12,8 +12,8 @@ struct cpu_interface virtual void start(uint64_t start, uint64_t end = 0, std::chrono::nanoseconds timeout = {}, size_t count = 0) = 0; virtual void stop() = 0; - virtual void read_raw_register(int reg, void* value, size_t size) = 0; - virtual void write_raw_register(int reg, const void* value, size_t size) = 0; + virtual size_t read_raw_register(int reg, void* value, size_t size) = 0; + virtual size_t write_raw_register(int reg, const void* value, size_t size) = 0; virtual std::vector save_registers() = 0; virtual void restore_registers(const std::vector& register_data) = 0; diff --git a/src/emulator/typed_emulator.hpp b/src/emulator/typed_emulator.hpp index d7224940..63516cba 100644 --- a/src/emulator/typed_emulator.hpp +++ b/src/emulator/typed_emulator.hpp @@ -20,14 +20,14 @@ class typed_emulator : public emulator this->start(this->read_instruction_pointer(), 0, timeout, count); } - void write_register(registers reg, const void* value, const size_t size) + size_t write_register(registers reg, const void* value, const size_t size) { - this->write_raw_register(static_cast(reg), value, size); + return this->write_raw_register(static_cast(reg), value, size); } - void read_register(registers reg, void* value, const size_t size) + size_t read_register(registers reg, void* value, const size_t size) { - this->read_raw_register(static_cast(reg), value, size); + return this->read_raw_register(static_cast(reg), value, size); } template @@ -90,6 +90,6 @@ class typed_emulator : public emulator private: emulator_hook* hook_instruction(int instruction_type, instruction_hook_callback callback) override = 0; - void read_raw_register(int reg, void* value, size_t size) override = 0; - void write_raw_register(int reg, const void* value, size_t size) override = 0; + size_t read_raw_register(int reg, void* value, size_t size) override = 0; + size_t write_raw_register(int reg, const void* value, size_t size) override = 0; }; diff --git a/src/gdb-stub/gdb_stub.cpp b/src/gdb-stub/gdb_stub.cpp index 308cded5..764fbf14 100644 --- a/src/gdb-stub/gdb_stub.cpp +++ b/src/gdb-stub/gdb_stub.cpp @@ -209,16 +209,16 @@ namespace gdb_stub for (size_t i = 0; i < registers; ++i) { - memset(data.data(), 0, data.size()); - const auto res = handler.read_register(i, data.data(), data.size()); + const auto size = handler.read_register(i, data.data(), data.size()); - if (!res) + if (!size) { connection.send_reply("E01"); return; } - response.append(utils::string::to_hex_string(data)); + const std::span register_data(data.data(), size); + response.append(utils::string::to_hex_string(register_data)); } connection.send_reply(response); @@ -231,20 +231,21 @@ namespace gdb_stub const auto registers = handler.get_register_count(); const auto register_size = handler.get_max_register_size(); + size_t offset = 0; for (size_t i = 0; i < registers; ++i) { - const auto offset = i * register_size; - const auto end_offset = offset + register_size; - - if (data.size() < end_offset) + if (offset >= data.size()) { connection.send_reply("E01"); return; } - const auto res = handler.write_register(i, data.data() + offset, register_size); + const auto max_size = std::min(register_size, data.size() - offset); + const auto size = handler.write_register(i, data.data() + offset, max_size); - if (!res) + offset += size; + + if (!size) { connection.send_reply("E01"); return; @@ -263,11 +264,12 @@ namespace gdb_stub std::vector data{}; data.resize(handler.get_max_register_size()); - const auto res = handler.read_register(reg, data.data(), data.size()); + const auto size = handler.read_register(reg, data.data(), data.size()); - if (res) + if (size) { - connection.send_reply(utils::string::to_hex_string(data)); + const std::span register_data(data.data(), size); + connection.send_reply(utils::string::to_hex_string(register_data)); } else { @@ -283,12 +285,8 @@ namespace gdb_stub size_t register_index{}; rt_assert(sscanf_s(std::string(reg).c_str(), "%zx", ®ister_index) == 1); - const auto register_size = handler.get_max_register_size(); const auto data = utils::string::from_hex_string(hex_data); - - const auto res = register_size <= data.size() && // - handler.write_register(register_index, data.data(), register_size); - + const auto res = handler.write_register(register_index, data.data(), data.size()) > 0; connection.send_reply(res ? "OK" : "E01"); } diff --git a/src/gdb-stub/gdb_stub.hpp b/src/gdb-stub/gdb_stub.hpp index 493a960e..c779aaaa 100644 --- a/src/gdb-stub/gdb_stub.hpp +++ b/src/gdb-stub/gdb_stub.hpp @@ -31,8 +31,8 @@ namespace gdb_stub virtual size_t get_register_count() = 0; virtual size_t get_max_register_size() = 0; - virtual bool read_register(size_t reg, void* data, size_t max_length) = 0; - virtual bool write_register(size_t reg, const void* data, size_t size) = 0; + virtual size_t read_register(size_t reg, void* data, size_t max_length) = 0; + virtual size_t write_register(size_t reg, const void* data, size_t size) = 0; virtual bool read_memory(uint64_t address, void* data, size_t length) = 0; virtual bool write_memory(uint64_t address, const void* data, size_t length) = 0; diff --git a/src/unicorn-emulator/unicorn_x64_emulator.cpp b/src/unicorn-emulator/unicorn_x64_emulator.cpp index 2fe9f4ef..369cf7fb 100644 --- a/src/unicorn-emulator/unicorn_x64_emulator.cpp +++ b/src/unicorn-emulator/unicorn_x64_emulator.cpp @@ -301,9 +301,9 @@ namespace unicorn uce(uc_emu_stop(*this)); } - void write_raw_register(const int reg, const void* value, const size_t size) override + size_t write_raw_register(const int reg, const void* value, const size_t size) override { - size_t result_size = size; + auto result_size = size; uce(uc_reg_write2(*this, reg, value, &result_size)); if (size < result_size) @@ -311,9 +311,11 @@ namespace unicorn throw std::runtime_error("Register size mismatch: " + std::to_string(size) + " != " + std::to_string(result_size)); } + + return result_size; } - void read_raw_register(const int reg, void* value, const size_t size) override + size_t read_raw_register(const int reg, void* value, const size_t size) override { size_t result_size = size; memset(value, 0, size); @@ -324,6 +326,8 @@ namespace unicorn throw std::runtime_error("Register size mismatch: " + std::to_string(size) + " != " + std::to_string(result_size)); } + + return result_size; } void map_mmio(const uint64_t address, const size_t size, mmio_read_callback read_cb, diff --git a/src/windows-emulator/debugging/x64_gdb_stub_handler.hpp b/src/windows-emulator/debugging/x64_gdb_stub_handler.hpp index 7dde76a4..4489a03f 100644 --- a/src/windows-emulator/debugging/x64_gdb_stub_handler.hpp +++ b/src/windows-emulator/debugging/x64_gdb_stub_handler.hpp @@ -105,46 +105,40 @@ class x64_gdb_stub_handler : public gdb_stub::debugging_handler size_t get_max_register_size() override { - // return 256 / 8; - return 64 / 8; + return 512 / 8; } - bool read_register(const size_t reg, void* data, const size_t max_length) override + size_t read_register(const size_t reg, void* data, const size_t max_length) override { try { if (reg >= gdb_registers.size()) { - // TODO: Fix - return true; + return 0; } - this->emu_->read_register(gdb_registers[reg], data, max_length); - return true; + return this->emu_->read_register(gdb_registers[reg], data, max_length); } catch (...) { - // TODO: Fix - return true; + return 0; } } - bool write_register(const size_t reg, const void* data, const size_t size) override + size_t write_register(const size_t reg, const void* data, const size_t size) override { try { if (reg >= gdb_registers.size()) { - // TODO: Fix - return true; + return 0; } - this->emu_->write_register(gdb_registers[reg], data, size); - return true; + return this->emu_->write_register(gdb_registers[reg], data, size); } catch (...) { - return false; + return 0; } } From ce291728bd80912cc42818d8ddddd57369684757 Mon Sep 17 00:00:00 2001 From: momo5502 Date: Sun, 19 Jan 2025 11:30:32 +0100 Subject: [PATCH 3/4] Support all registers --- .../debugging/x64_gdb_stub_handler.hpp | 150 ++++++++++++++++-- 1 file changed, 138 insertions(+), 12 deletions(-) diff --git a/src/windows-emulator/debugging/x64_gdb_stub_handler.hpp b/src/windows-emulator/debugging/x64_gdb_stub_handler.hpp index 4489a03f..c1cf111c 100644 --- a/src/windows-emulator/debugging/x64_gdb_stub_handler.hpp +++ b/src/windows-emulator/debugging/x64_gdb_stub_handler.hpp @@ -5,17 +5,102 @@ #include #include "x64_target_descriptions.hpp" +#include -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 expected_size; + std::optional offset; + + register_entry(const x64_register reg = x64_register::invalid, + const std::optional expected_size = std::nullopt, + const std::optional offset = std::nullopt) + : reg(reg), + expected_size(expected_size), + offset(offset) + { + } +}; + +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::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(data) + *real_reg.offset, size); + } + + const auto result_size = real_reg.expected_size.value_or(size); + + if (result_size > size) + { + memset(static_cast(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 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 (...) { From 8afceeca6e3e55751f60fbf800dbe7e4393f5f16 Mon Sep 17 00:00:00 2001 From: momo5502 Date: Sun, 19 Jan 2025 11:36:03 +0100 Subject: [PATCH 4/4] Extract register mapping --- .../debugging/x64_gdb_stub_handler.hpp | 102 +----------------- .../debugging/x64_register_mapping.hpp | 102 ++++++++++++++++++ 2 files changed, 106 insertions(+), 98 deletions(-) create mode 100644 src/windows-emulator/debugging/x64_register_mapping.hpp diff --git a/src/windows-emulator/debugging/x64_gdb_stub_handler.hpp b/src/windows-emulator/debugging/x64_gdb_stub_handler.hpp index c1cf111c..70a6e039 100644 --- a/src/windows-emulator/debugging/x64_gdb_stub_handler.hpp +++ b/src/windows-emulator/debugging/x64_gdb_stub_handler.hpp @@ -1,107 +1,13 @@ #pragma once #include -#include "scoped_hook.hpp" + #include #include +#include "scoped_hook.hpp" + +#include "x64_register_mapping.hpp" #include "x64_target_descriptions.hpp" -#include - -struct register_entry -{ - x64_register reg; - std::optional expected_size; - std::optional offset; - - register_entry(const x64_register reg = x64_register::invalid, - const std::optional expected_size = std::nullopt, - const std::optional offset = std::nullopt) - : reg(reg), - expected_size(expected_size), - offset(offset) - { - } -}; - -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::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) { diff --git a/src/windows-emulator/debugging/x64_register_mapping.hpp b/src/windows-emulator/debugging/x64_register_mapping.hpp new file mode 100644 index 00000000..cedbc1ad --- /dev/null +++ b/src/windows-emulator/debugging/x64_register_mapping.hpp @@ -0,0 +1,102 @@ +#pragma once +#include +#include +#include + +struct register_entry +{ + x64_register reg; + std::optional expected_size; + std::optional offset; + + register_entry(const x64_register reg = x64_register::invalid, + const std::optional expected_size = std::nullopt, + const std::optional offset = std::nullopt) + : reg(reg), + expected_size(expected_size), + offset(offset) + { + } +}; + +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::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, 16, 16}, + {x64_register::ymm1, 16, 16}, + {x64_register::ymm2, 16, 16}, + {x64_register::ymm3, 16, 16}, + {x64_register::ymm4, 16, 16}, + {x64_register::ymm5, 16, 16}, + {x64_register::ymm6, 16, 16}, + {x64_register::ymm7, 16, 16}, + {x64_register::ymm8, 16, 16}, + {x64_register::ymm9, 16, 16}, + {x64_register::ymm10, 16, 16}, + {x64_register::ymm11, 16, 16}, + {x64_register::ymm12, 16, 16}, + {x64_register::ymm13, 16, 16}, + {x64_register::ymm14, 16, 16}, + {x64_register::ymm15, 16, 16}, +};