diff --git a/repos/ports/lib/mk/spec/nova_x86_64/gdbserver_platform.mk b/repos/ports/lib/mk/spec/nova_x86_64/gdbserver_platform.mk new file mode 100644 index 0000000000..6ad2c50f47 --- /dev/null +++ b/repos/ports/lib/mk/spec/nova_x86_64/gdbserver_platform.mk @@ -0,0 +1,4 @@ +SRC_CC = spec/nova_x86_64/low.cc \ + spec/nova/native_cpu.cc + +include $(REP_DIR)/lib/mk/spec/x86_64/gdbserver_platform.inc diff --git a/repos/ports/run/gdb_monitor.run b/repos/ports/run/gdb_monitor.run index 089527eb7b..4d810ed852 100644 --- a/repos/ports/run/gdb_monitor.run +++ b/repos/ports/run/gdb_monitor.run @@ -6,16 +6,15 @@ # # -# Only the 32-bit NOVA and Fiasco.OC base platforms support most of the tested features +# Only the NOVA and 32-bit Fiasco.OC base platforms support most of the tested features # at this time. # -if {![have_include "power_on/qemu"] || (![have_spec foc] && ![have_spec nova])} { - puts "Run script is only supported for foc or nova in Qemu"; exit 0 +if {![have_include "power_on/qemu"] || + !([have_spec nova] || ([have_spec foc] && [have_spec 32bit]))} { + puts "Run script is only supported for NOVA or 32-bit Fiasco.OC in Qemu"; exit 0 } -assert_spec 32bit - # # Build # @@ -55,7 +54,10 @@ set config { - + + + + diff --git a/repos/ports/src/lib/gdbserver_platform/spec/nova_x86_32/low.cc b/repos/ports/src/lib/gdbserver_platform/spec/nova_x86_32/low.cc index e8573e4c3a..9177137e09 100644 --- a/repos/ports/src/lib/gdbserver_platform/spec/nova_x86_32/low.cc +++ b/repos/ports/src/lib/gdbserver_platform/spec/nova_x86_32/low.cc @@ -1,5 +1,5 @@ /* - * \brief NOVA specific helper functions for GDB server + * \brief NOVA (x86_32) specific helper functions for GDB server * \author Alexander Boettcher * \date 2012-08-09 */ diff --git a/repos/ports/src/lib/gdbserver_platform/spec/nova_x86_64/low.cc b/repos/ports/src/lib/gdbserver_platform/spec/nova_x86_64/low.cc new file mode 100644 index 0000000000..b04814d8a1 --- /dev/null +++ b/repos/ports/src/lib/gdbserver_platform/spec/nova_x86_64/low.cc @@ -0,0 +1,171 @@ +/* + * \brief NOVA (x86_64) specific helper functions for GDB server + * \author Alexander Boettcher + * \author Christian Prochaska + * \date 2014-01-30 + */ + +/* + * Copyright (C) 2014-2016 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU General Public License version 2. + */ + +#include "amd64.h" +#include "cpu_session_component.h" +#include "gdbserver_platform_helper.h" +#include "genode_child_resources.h" + +using namespace Genode; + +extern "C" int genode_fetch_register(int regno, unsigned long *value) +{ + Thread_state ts; + + try { ts = get_current_thread_state(); } + catch (...) { + PERR("%s: could not get current thread state", __PRETTY_FUNCTION__); + return -1; + } + + switch((enum reg_index)regno) + { + case RAX: fetch_register("RAX", ts.rax, *value); return 0; + case RBX: fetch_register("RBX", ts.rbx, *value); return 0; + case RCX: fetch_register("RCX", ts.rcx, *value); return 0; + case RDX: fetch_register("RDX", ts.rdx, *value); return 0; + case RSI: fetch_register("RSI", ts.rsi, *value); return 0; + case RDI: fetch_register("RDI", ts.rdi, *value); return 0; + case RBP: fetch_register("RBP", ts.rbp, *value); return 0; + case RSP: fetch_register("RSP", ts.sp, *value); return 0; + case R8: fetch_register("R8 ", ts.r8, *value); return 0; + case R9: fetch_register("R9 ", ts.r9, *value); return 0; + case R10: fetch_register("R10", ts.r10, *value); return 0; + case R11: fetch_register("R11", ts.r11, *value); return 0; + case R12: fetch_register("R12", ts.r12, *value); return 0; + case R13: fetch_register("R13", ts.r13, *value); return 0; + case R14: fetch_register("R14", ts.r14, *value); return 0; + case R15: fetch_register("R15", ts.r15, *value); return 0; + case RIP: fetch_register("RIP", ts.ip, *value); return 0; + case EFLAGS: fetch_register("RFL", ts.eflags, *value); return 0; + case CS: cannot_fetch_register("CS"); return -1; + case SS: cannot_fetch_register("SS"); return -1; + case DS: cannot_fetch_register("DS"); return -1; + case ES: cannot_fetch_register("ES"); return -1; + case FS: cannot_fetch_register("FS"); return -1; + case GS: cannot_fetch_register("GS"); return -1; + case ST0: cannot_fetch_register("ST0"); return -1; + case ST1: cannot_fetch_register("ST1"); return -1; + case ST2: cannot_fetch_register("ST2"); return -1; + case ST3: cannot_fetch_register("ST3"); return -1; + case ST4: cannot_fetch_register("ST4"); return -1; + case ST5: cannot_fetch_register("ST5"); return -1; + case ST6: cannot_fetch_register("ST6"); return -1; + case ST7: cannot_fetch_register("ST7"); return -1; + case FCTRL: cannot_fetch_register("FCTRL"); return -1; + case FSTAT: cannot_fetch_register("FSTAT"); return -1; + case FTAG: cannot_fetch_register("FTAG"); return -1; + case FISEG: cannot_fetch_register("FISEG"); return -1; + case FIOFF: cannot_fetch_register("FIOFF"); return -1; + case FOSEG: cannot_fetch_register("FOSEG"); return -1; + case FOOFF: cannot_fetch_register("FOOFF"); return -1; + case FOP: cannot_fetch_register("FOP"); return -1; + case XMM0: cannot_fetch_register("XMM0"); return -1; + case XMM1: cannot_fetch_register("XMM1"); return -1; + case XMM2: cannot_fetch_register("XMM2"); return -1; + case XMM3: cannot_fetch_register("XMM3"); return -1; + case XMM4: cannot_fetch_register("XMM4"); return -1; + case XMM5: cannot_fetch_register("XMM5"); return -1; + case XMM6: cannot_fetch_register("XMM6"); return -1; + case XMM7: cannot_fetch_register("XMM7"); return -1; + case XMM8: cannot_fetch_register("XMM8"); return -1; + case XMM9: cannot_fetch_register("XMM9"); return -1; + case XMM10: cannot_fetch_register("XMM10"); return -1; + case XMM11: cannot_fetch_register("XMM11"); return -1; + case XMM12: cannot_fetch_register("XMM12"); return -1; + case XMM13: cannot_fetch_register("XMM13"); return -1; + case XMM14: cannot_fetch_register("XMM14"); return -1; + case XMM15: cannot_fetch_register("XMM15"); return -1; + case MXCSR: cannot_fetch_register("MXCSR"); return -1; + default: PERR("unhandled register %d", regno); return -1; + } + + return -1; +} + + +extern "C" void genode_store_register(int regno, unsigned long value) +{ + Thread_state ts; + + try { ts = get_current_thread_state(); } + catch (...) { + PERR("%s: could not get current thread state", __PRETTY_FUNCTION__); + return; + } + + switch ((enum reg_index)regno) + { + case RAX: if (!store_register("RAX", ts.rax, value)) return; break; + case RBX: if (!store_register("RBX", ts.rbx, value)) return; break; + case RCX: if (!store_register("RCX", ts.rcx, value)) return; break; + case RDX: if (!store_register("RDX", ts.rdx, value)) return; break; + case RSI: if (!store_register("RSI", ts.rsi, value)) return; break; + case RDI: if (!store_register("RDI", ts.rdi, value)) return; break; + case RBP: if (!store_register("RBP", ts.rbp, value)) return; break; + case RSP: if (!store_register("RSP", ts.sp, value)) return; break; + case R8: if (!store_register("R8 ", ts.r8, value)) return; break; + case R9: if (!store_register("R9 ", ts.r9, value)) return; break; + case R10: if (!store_register("R10", ts.r10, value)) return; break; + case R11: if (!store_register("R11", ts.r11, value)) return; break; + case R12: if (!store_register("R12", ts.r12, value)) return; break; + case R13: if (!store_register("R13", ts.r13, value)) return; break; + case R14: if (!store_register("R14", ts.r14, value)) return; break; + case R15: if (!store_register("R15", ts.r15, value)) return; break; + case RIP: if (!store_register("RIP", ts.ip, value)) return; break; + case EFLAGS: if (!store_register("RFL", ts.eflags, value)) return; break; + case CS: cannot_store_register("CS", value); return; + case SS: cannot_store_register("SS", value); return; + case DS: cannot_store_register("DS", value); return; + case ES: cannot_store_register("ES", value); return; + case FS: cannot_store_register("FS", value); return; + case GS: cannot_store_register("GS", value); return; + case ST0: cannot_store_register("ST0", value); return; + case ST1: cannot_store_register("ST1", value); return; + case ST2: cannot_store_register("ST2", value); return; + case ST3: cannot_store_register("ST3", value); return; + case ST4: cannot_store_register("ST4", value); return; + case ST5: cannot_store_register("ST5", value); return; + case ST6: cannot_store_register("ST6", value); return; + case ST7: cannot_store_register("ST7", value); return; + case FCTRL: cannot_store_register("FCTRL", value); return; + case FSTAT: cannot_store_register("FSTAT", value); return; + case FTAG: cannot_store_register("FTAG", value); return; + case FISEG: cannot_store_register("FISEG", value); return; + case FIOFF: cannot_store_register("FIOFF", value); return; + case FOSEG: cannot_store_register("FOSEG", value); return; + case FOOFF: cannot_store_register("FOOFF", value); return; + case FOP: cannot_store_register("FOP", value); return; + case XMM0: cannot_store_register("XMM0", value); return; + case XMM1: cannot_store_register("XMM1", value); return; + case XMM2: cannot_store_register("XMM2", value); return; + case XMM3: cannot_store_register("XMM3", value); return; + case XMM4: cannot_store_register("XMM4", value); return; + case XMM5: cannot_store_register("XMM5", value); return; + case XMM6: cannot_store_register("XMM6", value); return; + case XMM7: cannot_store_register("XMM7", value); return; + case XMM8: cannot_store_register("XMM8", value); return; + case XMM9: cannot_store_register("XMM9", value); return; + case XMM10: cannot_store_register("XMM10", value); return; + case XMM11: cannot_store_register("XMM11", value); return; + case XMM12: cannot_store_register("XMM12", value); return; + case XMM13: cannot_store_register("XMM13", value); return; + case XMM14: cannot_store_register("XMM14", value); return; + case XMM15: cannot_store_register("XMM15", value); return; + case MXCSR: cannot_store_register("MXCSR", value); return; + default: PERR("unhandled register %d", regno); return; + } + + set_current_thread_state(ts); +}