summaryrefslogtreecommitdiffstatshomepage
path: root/src/osd/modules/debugger/debuggdbstub.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/osd/modules/debugger/debuggdbstub.cpp')
-rw-r--r--src/osd/modules/debugger/debuggdbstub.cpp204
1 files changed, 141 insertions, 63 deletions
diff --git a/src/osd/modules/debugger/debuggdbstub.cpp b/src/osd/modules/debugger/debuggdbstub.cpp
index eaeb1df4cca..e5092c71548 100644
--- a/src/osd/modules/debugger/debuggdbstub.cpp
+++ b/src/osd/modules/debugger/debuggdbstub.cpp
@@ -7,17 +7,26 @@
//============================================================
#include "emu.h"
+#include "debug_module.h"
+
#include "debug/debugcon.h"
#include "debug/debugcpu.h"
#include "debug/points.h"
#include "debug/textbuf.h"
-#include "debug_module.h"
#include "debugger.h"
-#include "fileio.h"
+
#include "modules/lib/osdobj_common.h"
#include "modules/osdmodule.h"
+#include "fileio.h"
+
#include <cinttypes>
+#include <string_view>
+
+
+namespace osd {
+
+namespace {
//-------------------------------------------------------------------------
#define MAX_PACKET_SIZE 16384
@@ -245,9 +254,9 @@ static const gdb_register_map gdb_register_map_m68020pmmu =
{ "A4", "a4", false, TYPE_INT },
{ "A5", "a5", false, TYPE_INT },
{ "A6", "fp", true, TYPE_INT },
- { "A7", "sp", true, TYPE_INT },
+ { "SP", "sp", true, TYPE_INT },
{ "SR", "ps", false, TYPE_INT }, // NOTE GDB named it ps, but it's actually sr
- { "PC", "pc", true, TYPE_CODE_POINTER },
+ { "CURPC","pc", true, TYPE_CODE_POINTER },
}
};
@@ -272,9 +281,9 @@ static const gdb_register_map gdb_register_map_m68000 =
{ "A4", "a4", false, TYPE_INT },
{ "A5", "a5", false, TYPE_INT },
{ "A6", "fp", true, TYPE_INT },
- { "A7", "sp", true, TYPE_INT },
+ { "SP", "sp", true, TYPE_INT },
{ "SR", "ps", false, TYPE_INT }, // NOTE GDB named it ps, but it's actually sr
- { "PC", "pc", true, TYPE_CODE_POINTER },
+ { "CURPC","pc", true, TYPE_CODE_POINTER },
//NOTE m68-elf-gdb complains about fpcontrol register not present but 68000 doesn't have floating point so...
}
};
@@ -401,6 +410,65 @@ static const gdb_register_map gdb_register_map_score7 =
}
};
+
+//-------------------------------------------------------------------------
+static const gdb_register_map gdb_register_map_nios2 =
+{
+ "nios2",
+ "org.gnu.gdb.nios2.cpu",
+ {
+ { "zero", "zero", false, TYPE_INT },
+ { "at", "at", false, TYPE_INT },
+ { "r2", "r2", false, TYPE_INT },
+ { "r3", "r3", false, TYPE_INT },
+ { "r4", "r4", false, TYPE_INT },
+ { "r5", "r5", false, TYPE_INT },
+ { "r6", "r6", false, TYPE_INT },
+ { "r7", "r7", false, TYPE_INT },
+ { "r8", "r8", false, TYPE_INT },
+ { "r9", "r9", false, TYPE_INT },
+ { "r10", "r10", false, TYPE_INT },
+ { "r11", "r11", false, TYPE_INT },
+ { "r12", "r12", false, TYPE_INT },
+ { "r13", "r13", false, TYPE_INT },
+ { "r14", "r14", false, TYPE_INT },
+ { "r15", "r15", false, TYPE_INT },
+ { "r16", "r16", false, TYPE_INT },
+ { "r17", "r17", false, TYPE_INT },
+ { "r18", "r18", false, TYPE_INT },
+ { "r19", "r19", false, TYPE_INT },
+ { "r20", "r20", false, TYPE_INT },
+ { "r21", "r21", false, TYPE_INT },
+ { "r22", "r22", false, TYPE_INT },
+ { "r23", "r23", false, TYPE_INT },
+ { "et", "et", false, TYPE_INT },
+ { "bt", "bt", false, TYPE_INT },
+ { "gp", "gp", false, TYPE_DATA_POINTER },
+ { "sp", "sp", true, TYPE_DATA_POINTER },
+ { "fp", "fp", false, TYPE_DATA_POINTER },
+ { "ea", "ea", false, TYPE_CODE_POINTER },
+ { "ba", "sstatus", false, TYPE_INT }, // this is Altera's fault
+ { "ra", "ra", false, TYPE_CODE_POINTER },
+ { "status", "status", false, TYPE_INT },
+ { "estatus", "estatus", false, TYPE_INT },
+ { "bstatus", "bstatus", false, TYPE_INT },
+ { "ienable", "ienable", false, TYPE_INT },
+ { "ipending", "ipending", false, TYPE_INT },
+ { "cpuid", "cpuid", false, TYPE_INT },
+ { "ctl6", "ctl6", false, TYPE_INT },
+ { "exception","exception",false, TYPE_INT },
+ { "pteaddr", "pteaddr", false, TYPE_INT },
+ { "tlbacc", "tlbacc", false, TYPE_INT },
+ { "tlbmisc", "tlbmisc", false, TYPE_INT },
+ { "eccinj", "eccinj", false, TYPE_INT },
+ { "badaddr", "badaddr", false, TYPE_INT },
+ { "config", "config", false, TYPE_INT },
+ { "mpubase", "mpubase", false, TYPE_INT },
+ { "mpuacc", "mpuacc", false, TYPE_INT },
+ { "PC", "pc", true, TYPE_CODE_POINTER },
+ }
+};
+
//-------------------------------------------------------------------------
static const std::map<std::string, const gdb_register_map &> gdb_register_maps = {
{ "i486", gdb_register_map_i486 },
@@ -410,10 +478,17 @@ static const std::map<std::string, const gdb_register_map &> gdb_register_maps =
{ "m68020pmmu", gdb_register_map_m68020pmmu },
{ "m68000", gdb_register_map_m68000 },
{ "z80", gdb_register_map_z80 },
+ { "z84c015", gdb_register_map_z80 },
{ "m6502", gdb_register_map_m6502 },
- { "n2a03", gdb_register_map_m6502 },
+ { "m6507", gdb_register_map_m6502 },
+ { "m6510", gdb_register_map_m6502 },
+ { "m65c02", gdb_register_map_m6502 },
+ { "m65ce02", gdb_register_map_m6502 },
+ { "rp2a03", gdb_register_map_m6502 },
+ { "w65c02s", gdb_register_map_m6502 },
{ "m6809", gdb_register_map_m6809 },
{ "score7", gdb_register_map_score7 },
+ { "nios2", gdb_register_map_nios2 },
};
//-------------------------------------------------------------------------
@@ -450,7 +525,7 @@ public:
virtual ~debug_gdbstub() { }
- virtual int init(const osd_options &options) override;
+ virtual int init(osd_interface &osd, const osd_options &options) override;
virtual void exit() override;
virtual void init_debugger(running_machine &machine) override;
@@ -495,6 +570,7 @@ public:
cmd_reply handle_P(const char *buf);
cmd_reply handle_q(const char *buf);
cmd_reply handle_s(const char *buf);
+ cmd_reply handle_T(const char *buf);
cmd_reply handle_z(const char *buf);
cmd_reply handle_Z(const char *buf);
@@ -512,7 +588,7 @@ public:
int readchar();
- void send_reply(const char *str);
+ void send_reply(std::string_view str);
void send_stop_packet();
private:
@@ -563,7 +639,7 @@ private:
};
//-------------------------------------------------------------------------
-int debug_gdbstub::init(const osd_options &options)
+int debug_gdbstub::init(osd_interface &osd, const osd_options &options)
{
m_debugger_port = options.debugger_port();
return 0;
@@ -601,11 +677,11 @@ int debug_gdbstub::readchar()
}
//-------------------------------------------------------------------------
-static std::string escape_packet(const std::string src)
+static std::string escape_packet(std::string_view src)
{
std::string result;
result.reserve(src.length());
- for ( char ch: src )
+ for ( char ch : src )
{
if ( ch == '#' || ch == '$' || ch == '}' )
{
@@ -626,10 +702,10 @@ void debug_gdbstub::generate_target_xml()
target_xml += "<?xml version=\"1.0\"?>\n";
target_xml += "<!DOCTYPE target SYSTEM \"gdb-target.dtd\">\n";
target_xml += "<target version=\"1.0\">\n";
- target_xml += string_format("<architecture>%s</architecture>\n", m_gdb_arch.c_str());
- target_xml += string_format(" <feature name=\"%s\">\n", m_gdb_feature.c_str());
+ target_xml += string_format("<architecture>%s</architecture>\n", m_gdb_arch);
+ target_xml += string_format(" <feature name=\"%s\">\n", m_gdb_feature);
for ( const auto &reg: m_gdb_registers )
- target_xml += string_format(" <reg name=\"%s\" bitsize=\"%d\" type=\"%s\"/>\n", reg.gdb_name.c_str(), reg.gdb_bitsize, gdb_register_type_str[reg.gdb_type]);
+ target_xml += string_format(" <reg name=\"%s\" bitsize=\"%d\" type=\"%s\"/>\n", reg.gdb_name, reg.gdb_bitsize, gdb_register_type_str[reg.gdb_type]);
target_xml += " </feature>\n";
target_xml += "</target>\n";
m_target_xml = escape_packet(target_xml);
@@ -644,7 +720,7 @@ void debug_gdbstub::wait_for_debugger(device_t &device, bool firststop)
if ( firststop && !m_initialized )
{
// find the "main" CPU, which is the first CPU (gdbstub doesn't have any notion of switching CPUs)
- m_maincpu = device_type_enumerator<cpu_device>(m_machine->root_device()).first();
+ m_maincpu = device_interface_enumerator<cpu_device>(m_machine->root_device()).first();
if (!m_maincpu)
fatalerror("gdbstub: cannot find any CPUs\n");
@@ -762,26 +838,24 @@ void debug_gdbstub::debugger_update()
//-------------------------------------------------------------------------
void debug_gdbstub::send_nack()
{
- m_socket.puts("-");
+ m_socket.write("-", 1);
}
//-------------------------------------------------------------------------
void debug_gdbstub::send_ack()
{
- m_socket.puts("+");
+ m_socket.write("+", 1);
}
//-------------------------------------------------------------------------
-void debug_gdbstub::send_reply(const char *str)
+void debug_gdbstub::send_reply(std::string_view str)
{
- size_t length = strlen(str);
-
uint8_t checksum = 0;
- for ( size_t i = 0; i < length; i++ )
- checksum += str[i];
+ for ( char ch : str )
+ checksum += ch;
std::string reply = string_format("$%s#%02x", str, checksum);
- m_socket.puts(reply);
+ m_socket.write(reply.c_str(), reply.length());
}
@@ -839,7 +913,7 @@ debug_gdbstub::cmd_reply debug_gdbstub::handle_g(const char *buf)
std::string reply;
for ( const auto &reg: m_gdb_registers )
reply += get_register_string(reg.gdb_regnum);
- send_reply(reply.c_str());
+ send_reply(reply);
return REPLY_NONE;
}
@@ -894,7 +968,8 @@ debug_gdbstub::cmd_reply debug_gdbstub::handle_m(const char *buf)
return REPLY_ENN;
offs_t offset = address;
- if ( !m_memory->translate(m_address_space->spacenum(), TRANSLATE_READ_DEBUG, offset) )
+ address_space *tspace;
+ if ( !m_memory->translate(m_address_space->spacenum(), device_memory_interface::TR_READ, offset, tspace) )
return REPLY_ENN;
// Disable side effects while reading memory.
@@ -904,10 +979,10 @@ debug_gdbstub::cmd_reply debug_gdbstub::handle_m(const char *buf)
reply.reserve(length * 2);
for ( int i = 0; i < length; i++ )
{
- uint8_t value = m_address_space->read_byte(offset + i);
+ uint8_t value = tspace->read_byte(offset + i);
reply += string_format("%02x", value);
}
- send_reply(reply.c_str());
+ send_reply(reply);
return REPLY_NONE;
}
@@ -939,7 +1014,8 @@ debug_gdbstub::cmd_reply debug_gdbstub::handle_M(const char *buf)
return REPLY_ENN;
offs_t offset = address;
- if ( !m_memory->translate(m_address_space->spacenum(), TRANSLATE_READ_DEBUG, offset) )
+ address_space *tspace;
+ if ( !m_memory->translate(m_address_space->spacenum(), device_memory_interface::TR_READ, offset, tspace) )
return REPLY_ENN;
std::vector<uint8_t> data;
@@ -947,7 +1023,7 @@ debug_gdbstub::cmd_reply debug_gdbstub::handle_M(const char *buf)
return REPLY_ENN;
for ( int i = 0; i < length; i++ )
- m_address_space->write_byte(offset + i, data[i]);
+ tspace->write_byte(offset + i, data[i]);
return REPLY_OK;
}
@@ -962,7 +1038,7 @@ debug_gdbstub::cmd_reply debug_gdbstub::handle_p(const char *buf)
if ( sscanf(buf, "%x", &gdb_regnum) != 1 || gdb_regnum >= m_gdb_registers.size() )
return REPLY_ENN;
std::string reply = get_register_string(gdb_regnum);
- send_reply(reply.c_str());
+ send_reply(reply);
return REPLY_NONE;
}
@@ -1029,7 +1105,7 @@ debug_gdbstub::cmd_reply debug_gdbstub::handle_q(const char *buf)
reply += string_format("%02x", *line++);
reply += "0A";
}
- send_reply(reply.c_str());
+ send_reply(reply);
return REPLY_NONE;
}
@@ -1046,7 +1122,7 @@ debug_gdbstub::cmd_reply debug_gdbstub::handle_q(const char *buf)
{
std::string reply = string_format("PacketSize=%x", MAX_PACKET_SIZE);
reply += ";qXfer:features:read+";
- send_reply(reply.c_str());
+ send_reply(reply);
return REPLY_NONE;
}
else if ( name == "Xfer" )
@@ -1067,7 +1143,7 @@ debug_gdbstub::cmd_reply debug_gdbstub::handle_q(const char *buf)
else
reply += 'l';
reply += m_target_xml.substr(offset, length);
- send_reply(reply.c_str());
+ send_reply(reply);
m_target_xml_sent = true;
return REPLY_NONE;
}
@@ -1101,6 +1177,17 @@ debug_gdbstub::cmd_reply debug_gdbstub::handle_s(const char *buf)
}
//-------------------------------------------------------------------------
+// Find out if the thread XX is alive.
+debug_gdbstub::cmd_reply debug_gdbstub::handle_T(const char *buf)
+{
+ if ( is_thread_id_ok(buf) )
+ return REPLY_OK;
+
+ // thread is dead
+ return REPLY_ENN;
+}
+
+//-------------------------------------------------------------------------
static bool remove_breakpoint(device_debug *debug, uint64_t address, int /*kind*/)
{
const debug_breakpoint *bp = debug->breakpoint_find(address);
@@ -1140,9 +1227,10 @@ debug_gdbstub::cmd_reply debug_gdbstub::handle_z(const char *buf)
// watchpoints
offs_t offset = address;
+ address_space *tspace;
if ( type == 2 || type == 3 || type == 4 )
{
- if ( !m_memory->translate(m_address_space->spacenum(), TRANSLATE_READ_DEBUG, offset) )
+ if ( !m_memory->translate(m_address_space->spacenum(), device_memory_interface::TR_READ, offset, tspace) )
return REPLY_ENN;
m_address_map.erase(offset);
}
@@ -1181,9 +1269,10 @@ debug_gdbstub::cmd_reply debug_gdbstub::handle_Z(const char *buf)
// watchpoints
offs_t offset = address;
+ address_space *tspace;
if ( type == 2 || type == 3 || type == 4 )
{
- if ( !m_memory->translate(m_address_space->spacenum(), TRANSLATE_READ_DEBUG, offset) )
+ if ( !m_memory->translate(m_address_space->spacenum(), device_memory_interface::TR_READ, offset, tspace) )
return REPLY_ENN;
m_address_map[offset] = address;
}
@@ -1199,15 +1288,15 @@ debug_gdbstub::cmd_reply debug_gdbstub::handle_Z(const char *buf)
return REPLY_OK;
case 2:
// write watchpoint
- debug->watchpoint_set(*m_address_space, read_or_write::WRITE, offset, kind, nullptr, nullptr);
+ debug->watchpoint_set(*m_address_space, read_or_write::WRITE, offset, kind);
return REPLY_OK;
case 3:
// read watchpoint
- debug->watchpoint_set(*m_address_space, read_or_write::READ, offset, kind, nullptr, nullptr);
+ debug->watchpoint_set(*m_address_space, read_or_write::READ, offset, kind);
return REPLY_OK;
case 4:
// access watchpoint
- debug->watchpoint_set(*m_address_space, read_or_write::READWRITE, offset, kind, nullptr, nullptr);
+ debug->watchpoint_set(*m_address_space, read_or_write::READWRITE, offset, kind);
return REPLY_OK;
}
@@ -1241,7 +1330,7 @@ void debug_gdbstub::send_stop_packet()
if ( m_target_xml_sent )
for ( const auto &gdb_regnum: m_stop_reply_registers )
reply += string_format("%02x:%s;", gdb_regnum, get_register_string(gdb_regnum));
- send_reply(reply.c_str());
+ send_reply(reply);
}
//-------------------------------------------------------------------------
@@ -1270,6 +1359,7 @@ void debug_gdbstub::handle_packet()
case 'P': reply = handle_P(buf); break;
case 'q': reply = handle_q(buf); break;
case 's': reply = handle_s(buf); break;
+ case 'T': reply = handle_T(buf); break;
case 'z': reply = handle_z(buf); break;
case 'Z': reply = handle_Z(buf); break;
}
@@ -1282,22 +1372,6 @@ void debug_gdbstub::handle_packet()
}
//-------------------------------------------------------------------------
-#define BYTESWAP_64(x) ((((x) << 56) & 0xFF00000000000000) \
- | (((x) << 40) & 0x00FF000000000000) \
- | (((x) << 24) & 0x0000FF0000000000) \
- | (((x) << 8) & 0x000000FF00000000) \
- | (((x) >> 8) & 0x00000000FF000000) \
- | (((x) >> 24) & 0x0000000000FF0000) \
- | (((x) >> 40) & 0x000000000000FF00) \
- | (((x) >> 56) & 0x00000000000000FF))
-#define BYTESWAP_32(x) ((((x) << 24) & 0xFF000000) \
- | (((x) << 8) & 0x00FF0000) \
- | (((x) >> 8) & 0x0000FF00) \
- | (((x) >> 24) & 0x000000FF))
-#define BYTESWAP_16(x) ((((x) << 8) & 0xFF00) \
- | (((x) >> 8) & 0x00FF))
-
-//-------------------------------------------------------------------------
std::string debug_gdbstub::get_register_string(int gdb_regnum)
{
const gdb_register &reg = m_gdb_registers[gdb_regnum];
@@ -1310,9 +1384,9 @@ std::string debug_gdbstub::get_register_string(int gdb_regnum)
value &= (1ULL << reg.gdb_bitsize) - 1;
if ( !m_is_be )
{
- value = (reg.gdb_bitsize == 64) ? BYTESWAP_64(value)
- : (reg.gdb_bitsize == 32) ? BYTESWAP_32(value)
- : (reg.gdb_bitsize == 16) ? BYTESWAP_16(value)
+ value = (reg.gdb_bitsize == 64) ? swapendian_int64(value)
+ : (reg.gdb_bitsize == 32) ? swapendian_int32(value)
+ : (reg.gdb_bitsize == 16) ? swapendian_int16(value)
: value;
}
return string_format(fmt, value);
@@ -1331,9 +1405,9 @@ bool debug_gdbstub::parse_register_string(uint64_t *pvalue, const char *buf, int
return false;
if ( !m_is_be )
{
- value = (reg.gdb_bitsize == 64) ? BYTESWAP_64(value)
- : (reg.gdb_bitsize == 32) ? BYTESWAP_32(value)
- : (reg.gdb_bitsize == 16) ? BYTESWAP_16(value)
+ value = (reg.gdb_bitsize == 64) ? swapendian_int64(value)
+ : (reg.gdb_bitsize == 32) ? swapendian_int32(value)
+ : (reg.gdb_bitsize == 16) ? swapendian_int16(value)
: value;
}
*pvalue = value;
@@ -1430,5 +1504,9 @@ void debug_gdbstub::handle_character(char ch)
}
}
+} // anonymous namespace
+
+} // namespace osd
+
//-------------------------------------------------------------------------
-MODULE_DEFINITION(DEBUG_GDBSTUB, debug_gdbstub)
+MODULE_DEFINITION(DEBUG_GDBSTUB, osd::debug_gdbstub)