mirror of
https://github.com/momo5502/emulator.git
synced 2026-01-25 22:51:03 +00:00
Provide correct GDB target description (#92)
This commit is contained in:
@@ -109,7 +109,7 @@ namespace utils::string
|
||||
return to_hex_string(&i, sizeof(Integer), uppercase);
|
||||
}
|
||||
|
||||
inline std::string to_hex_string(const std::span<std::byte> data, const bool uppercase = false)
|
||||
inline std::string to_hex_string(const std::span<const std::byte> data, const bool uppercase = false)
|
||||
{
|
||||
return to_hex_string(data.data(), data.size(), uppercase);
|
||||
}
|
||||
|
||||
@@ -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<std::byte> save_registers() = 0;
|
||||
virtual void restore_registers(const std::vector<std::byte>& register_data) = 0;
|
||||
|
||||
@@ -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<int>(reg), value, size);
|
||||
return this->write_raw_register(static_cast<int>(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<int>(reg), value, size);
|
||||
return this->read_raw_register(static_cast<int>(reg), value, size);
|
||||
}
|
||||
|
||||
template <typename T = pointer_type>
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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<target version=\"1.0\"><architecture>" //
|
||||
+ handler.get_target_description() //
|
||||
+ "</architecture></target>");
|
||||
handle_features(connection, handler, args);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -179,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);
|
||||
@@ -201,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;
|
||||
@@ -233,11 +264,12 @@ namespace gdb_stub
|
||||
std::vector<std::byte> 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
|
||||
{
|
||||
@@ -253,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");
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
@@ -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);
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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_{};
|
||||
};
|
||||
|
||||
@@ -1,20 +1,13 @@
|
||||
#pragma once
|
||||
#include <x64_emulator.hpp>
|
||||
#include "scoped_hook.hpp"
|
||||
|
||||
#include <utils/concurrency.hpp>
|
||||
#include <gdb-stub/gdb_stub.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,
|
||||
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,*/
|
||||
};
|
||||
#include "scoped_hook.hpp"
|
||||
|
||||
#include "x64_register_mapping.hpp"
|
||||
#include "x64_target_descriptions.hpp"
|
||||
|
||||
inline memory_operation map_breakpoint_type(const gdb_stub::breakpoint_type type)
|
||||
{
|
||||
@@ -103,46 +96,81 @@ 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;
|
||||
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 (...)
|
||||
{
|
||||
// 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;
|
||||
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 (...)
|
||||
{
|
||||
return false;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -211,6 +239,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_{};
|
||||
|
||||
|
||||
102
src/windows-emulator/debugging/x64_register_mapping.hpp
Normal file
102
src/windows-emulator/debugging/x64_register_mapping.hpp
Normal file
@@ -0,0 +1,102 @@
|
||||
#pragma once
|
||||
#include <cstddef>
|
||||
#include <optional>
|
||||
#include <x64_register.hpp>
|
||||
|
||||
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, 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},
|
||||
};
|
||||
215
src/windows-emulator/debugging/x64_target_descriptions.hpp
Normal file
215
src/windows-emulator/debugging/x64_target_descriptions.hpp
Normal file
@@ -0,0 +1,215 @@
|
||||
#pragma once
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
inline std::map<std::string, std::string, std::less<>> x64_target_descriptions{
|
||||
{
|
||||
"target.xml",
|
||||
R"__xml__(<?xml version="1.0"?>
|
||||
<!-- Copyright (C) 2010-2018 Free Software Foundation, Inc.
|
||||
|
||||
Copying and distribution of this file, with or without modification,
|
||||
are permitted in any medium without royalty provided the copyright
|
||||
notice and this notice are preserved. -->
|
||||
|
||||
<!-- AMD64 with AVX -->
|
||||
|
||||
<!DOCTYPE target SYSTEM "gdb-target.dtd">
|
||||
<target>
|
||||
<architecture>i386:x86-64</architecture>
|
||||
<xi:include href="64bit-core.xml"/>
|
||||
<xi:include href="64bit-sse.xml"/>
|
||||
<xi:include href="64bit-segments.xml"/>
|
||||
<xi:include href="64bit-avx.xml"/>
|
||||
</target>
|
||||
)__xml__",
|
||||
},
|
||||
{
|
||||
"64bit-core.xml",
|
||||
R"__xml__(<?xml version="1.0"?>
|
||||
<!-- Copyright (C) 2010-2018 Free Software Foundation, Inc.
|
||||
|
||||
Copying and distribution of this file, with or without modification,
|
||||
are permitted in any medium without royalty provided the copyright
|
||||
notice and this notice are preserved. -->
|
||||
|
||||
<!DOCTYPE feature SYSTEM "gdb-target.dtd">
|
||||
<feature name="org.gnu.gdb.i386.core">
|
||||
<flags id="i386_eflags" size="4">
|
||||
<field name="CF" start="0" end="0"/>
|
||||
<field name="" start="1" end="1"/>
|
||||
<field name="PF" start="2" end="2"/>
|
||||
<field name="AF" start="4" end="4"/>
|
||||
<field name="ZF" start="6" end="6"/>
|
||||
<field name="SF" start="7" end="7"/>
|
||||
<field name="TF" start="8" end="8"/>
|
||||
<field name="IF" start="9" end="9"/>
|
||||
<field name="DF" start="10" end="10"/>
|
||||
<field name="OF" start="11" end="11"/>
|
||||
<field name="NT" start="14" end="14"/>
|
||||
<field name="RF" start="16" end="16"/>
|
||||
<field name="VM" start="17" end="17"/>
|
||||
<field name="AC" start="18" end="18"/>
|
||||
<field name="VIF" start="19" end="19"/>
|
||||
<field name="VIP" start="20" end="20"/>
|
||||
<field name="ID" start="21" end="21"/>
|
||||
</flags>
|
||||
|
||||
<reg name="rax" bitsize="64" type="int64"/>
|
||||
<reg name="rbx" bitsize="64" type="int64"/>
|
||||
<reg name="rcx" bitsize="64" type="int64"/>
|
||||
<reg name="rdx" bitsize="64" type="int64"/>
|
||||
<reg name="rsi" bitsize="64" type="int64"/>
|
||||
<reg name="rdi" bitsize="64" type="int64"/>
|
||||
<reg name="rbp" bitsize="64" type="data_ptr"/>
|
||||
<reg name="rsp" bitsize="64" type="data_ptr"/>
|
||||
<reg name="r8" bitsize="64" type="int64"/>
|
||||
<reg name="r9" bitsize="64" type="int64"/>
|
||||
<reg name="r10" bitsize="64" type="int64"/>
|
||||
<reg name="r11" bitsize="64" type="int64"/>
|
||||
<reg name="r12" bitsize="64" type="int64"/>
|
||||
<reg name="r13" bitsize="64" type="int64"/>
|
||||
<reg name="r14" bitsize="64" type="int64"/>
|
||||
<reg name="r15" bitsize="64" type="int64"/>
|
||||
|
||||
<reg name="rip" bitsize="64" type="code_ptr"/>
|
||||
<reg name="eflags" bitsize="32" type="i386_eflags"/>
|
||||
<reg name="cs" bitsize="32" type="int32"/>
|
||||
<reg name="ss" bitsize="32" type="int32"/>
|
||||
<reg name="ds" bitsize="32" type="int32"/>
|
||||
<reg name="es" bitsize="32" type="int32"/>
|
||||
<reg name="fs" bitsize="32" type="int32"/>
|
||||
<reg name="gs" bitsize="32" type="int32"/>
|
||||
|
||||
<reg name="st0" bitsize="80" type="i387_ext"/>
|
||||
<reg name="st1" bitsize="80" type="i387_ext"/>
|
||||
<reg name="st2" bitsize="80" type="i387_ext"/>
|
||||
<reg name="st3" bitsize="80" type="i387_ext"/>
|
||||
<reg name="st4" bitsize="80" type="i387_ext"/>
|
||||
<reg name="st5" bitsize="80" type="i387_ext"/>
|
||||
<reg name="st6" bitsize="80" type="i387_ext"/>
|
||||
<reg name="st7" bitsize="80" type="i387_ext"/>
|
||||
|
||||
<reg name="fctrl" bitsize="32" type="int" group="float"/>
|
||||
<reg name="fstat" bitsize="32" type="int" group="float"/>
|
||||
<reg name="ftag" bitsize="32" type="int" group="float"/>
|
||||
<reg name="fiseg" bitsize="32" type="int" group="float"/>
|
||||
<reg name="fioff" bitsize="32" type="int" group="float"/>
|
||||
<reg name="foseg" bitsize="32" type="int" group="float"/>
|
||||
<reg name="fooff" bitsize="32" type="int" group="float"/>
|
||||
<reg name="fop" bitsize="32" type="int" group="float"/>
|
||||
</feature>
|
||||
)__xml__",
|
||||
},
|
||||
{
|
||||
"64bit-sse.xml",
|
||||
R"__xml__(<?xml version="1.0"?>
|
||||
<!-- Copyright (C) 2010-2018 Free Software Foundation, Inc.
|
||||
|
||||
Copying and distribution of this file, with or without modification,
|
||||
are permitted in any medium without royalty provided the copyright
|
||||
notice and this notice are preserved. -->
|
||||
|
||||
<!DOCTYPE feature SYSTEM "gdb-target.dtd">
|
||||
<feature name="org.gnu.gdb.i386.sse">
|
||||
<vector id="v4f" type="ieee_single" count="4"/>
|
||||
<vector id="v2d" type="ieee_double" count="2"/>
|
||||
<vector id="v16i8" type="int8" count="16"/>
|
||||
<vector id="v8i16" type="int16" count="8"/>
|
||||
<vector id="v4i32" type="int32" count="4"/>
|
||||
<vector id="v2i64" type="int64" count="2"/>
|
||||
<union id="vec128">
|
||||
<field name="v4_float" type="v4f"/>
|
||||
<field name="v2_double" type="v2d"/>
|
||||
<field name="v16_int8" type="v16i8"/>
|
||||
<field name="v8_int16" type="v8i16"/>
|
||||
<field name="v4_int32" type="v4i32"/>
|
||||
<field name="v2_int64" type="v2i64"/>
|
||||
<field name="uint128" type="uint128"/>
|
||||
</union>
|
||||
<flags id="i386_mxcsr" size="4">
|
||||
<field name="IE" start="0" end="0"/>
|
||||
<field name="DE" start="1" end="1"/>
|
||||
<field name="ZE" start="2" end="2"/>
|
||||
<field name="OE" start="3" end="3"/>
|
||||
<field name="UE" start="4" end="4"/>
|
||||
<field name="PE" start="5" end="5"/>
|
||||
<field name="DAZ" start="6" end="6"/>
|
||||
<field name="IM" start="7" end="7"/>
|
||||
<field name="DM" start="8" end="8"/>
|
||||
<field name="ZM" start="9" end="9"/>
|
||||
<field name="OM" start="10" end="10"/>
|
||||
<field name="UM" start="11" end="11"/>
|
||||
<field name="PM" start="12" end="12"/>
|
||||
<field name="FZ" start="15" end="15"/>
|
||||
</flags>
|
||||
|
||||
<reg name="xmm0" bitsize="128" type="vec128" regnum="40"/>
|
||||
<reg name="xmm1" bitsize="128" type="vec128"/>
|
||||
<reg name="xmm2" bitsize="128" type="vec128"/>
|
||||
<reg name="xmm3" bitsize="128" type="vec128"/>
|
||||
<reg name="xmm4" bitsize="128" type="vec128"/>
|
||||
<reg name="xmm5" bitsize="128" type="vec128"/>
|
||||
<reg name="xmm6" bitsize="128" type="vec128"/>
|
||||
<reg name="xmm7" bitsize="128" type="vec128"/>
|
||||
<reg name="xmm8" bitsize="128" type="vec128"/>
|
||||
<reg name="xmm9" bitsize="128" type="vec128"/>
|
||||
<reg name="xmm10" bitsize="128" type="vec128"/>
|
||||
<reg name="xmm11" bitsize="128" type="vec128"/>
|
||||
<reg name="xmm12" bitsize="128" type="vec128"/>
|
||||
<reg name="xmm13" bitsize="128" type="vec128"/>
|
||||
<reg name="xmm14" bitsize="128" type="vec128"/>
|
||||
<reg name="xmm15" bitsize="128" type="vec128"/>
|
||||
|
||||
<reg name="mxcsr" bitsize="32" type="i386_mxcsr" group="vector"/>
|
||||
</feature>
|
||||
)__xml__",
|
||||
},
|
||||
{
|
||||
"64bit-segments.xml",
|
||||
R"__xml__(<?xml version="1.0"?>
|
||||
<!-- Copyright (C) 2016-2018 Free Software Foundation, Inc.
|
||||
|
||||
Copying and distribution of this file, with or without modification,
|
||||
are permitted in any medium without royalty provided the copyright
|
||||
notice and this notice are preserved. -->
|
||||
|
||||
<!DOCTYPE feature SYSTEM "gdb-target.dtd">
|
||||
<feature name="org.gnu.gdb.i386.segments">
|
||||
<reg name="fs_base" bitsize="64" type="int"/>
|
||||
<reg name="gs_base" bitsize="64" type="int"/>
|
||||
</feature>
|
||||
)__xml__",
|
||||
},
|
||||
{
|
||||
"64bit-avx.xml",
|
||||
R"__xml__(<?xml version="1.0"?>
|
||||
<!-- Copyright (C) 2010-2018 Free Software Foundation, Inc.
|
||||
|
||||
Copying and distribution of this file, with or without modification,
|
||||
are permitted in any medium without royalty provided the copyright
|
||||
notice and this notice are preserved. -->
|
||||
|
||||
<!DOCTYPE feature SYSTEM "gdb-target.dtd">
|
||||
<feature name="org.gnu.gdb.i386.avx">
|
||||
<reg name="ymm0h" bitsize="128" type="uint128"/>
|
||||
<reg name="ymm1h" bitsize="128" type="uint128"/>
|
||||
<reg name="ymm2h" bitsize="128" type="uint128"/>
|
||||
<reg name="ymm3h" bitsize="128" type="uint128"/>
|
||||
<reg name="ymm4h" bitsize="128" type="uint128"/>
|
||||
<reg name="ymm5h" bitsize="128" type="uint128"/>
|
||||
<reg name="ymm6h" bitsize="128" type="uint128"/>
|
||||
<reg name="ymm7h" bitsize="128" type="uint128"/>
|
||||
<reg name="ymm8h" bitsize="128" type="uint128"/>
|
||||
<reg name="ymm9h" bitsize="128" type="uint128"/>
|
||||
<reg name="ymm10h" bitsize="128" type="uint128"/>
|
||||
<reg name="ymm11h" bitsize="128" type="uint128"/>
|
||||
<reg name="ymm12h" bitsize="128" type="uint128"/>
|
||||
<reg name="ymm13h" bitsize="128" type="uint128"/>
|
||||
<reg name="ymm14h" bitsize="128" type="uint128"/>
|
||||
<reg name="ymm15h" bitsize="128" type="uint128"/>
|
||||
</feature>
|
||||
)__xml__",
|
||||
},
|
||||
};
|
||||
Reference in New Issue
Block a user