gdbserver_genode.patch From: Christian Prochaska --- gdb/common/common-defs.h | 8 + gdb/common/gdb_tilde_expand.c | 10 ++ gdb/common/pathstuff.c | 2 gdb/gdbserver/linux-aarch32-low.c | 4 + gdb/gdbserver/linux-arm-low.c | 8 + gdb/gdbserver/linux-low.c | 168 ++++++++++++++++++++++++++++++ gdb/gdbserver/linux-low.h | 5 + gdb/gdbserver/linux-x86-low.c | 111 +++++++++++++++++++- gdb/gdbserver/linux-x86-tdesc-selftest.c | 31 ++++++ gdb/gdbserver/linux-x86-tdesc.c | 8 + gdb/gdbserver/remote-utils.c | 11 ++ gdb/gdbserver/server.c | 36 ++++++ gdb/gdbserver/server.h | 4 + gdb/nat/fork-inferior.c | 4 - gdb/nat/gdb_ptrace.h | 2 gdb/nat/linux-ptrace.c | 17 +++ gdb/nat/linux-ptrace.h | 4 + 17 files changed, 418 insertions(+), 15 deletions(-) diff --git a/gdb/common/common-defs.h b/gdb/common/common-defs.h index eb0ec21..4dc07ce 100644 --- a/gdb/common/common-defs.h +++ b/gdb/common/common-defs.h @@ -28,7 +28,9 @@ #undef PACKAGE_TARNAME #ifdef GDBSERVER +#ifndef __GENODE__ #include "build-gnulib-gdbserver/config.h" +#endif /* __GENODE__ */ #else #include "build-gnulib/config.h" #endif @@ -69,9 +71,11 @@ #include /* for strcasecmp and strncasecmp */ #endif #include +#ifndef __GENODE__ #include - +#endif /* __GENODE__ */ #include "ansidecl.h" +#ifndef __GENODE__ /* This is defined by ansidecl.h, but we prefer gnulib's version. On MinGW, gnulib might enable __USE_MINGW_ANSI_STDIO, which may or not require use of attribute gnu_printf instead of printf. gnulib @@ -79,7 +83,7 @@ is compatible with ATTRIBUTE_PRINTF, simply use it. */ #undef ATTRIBUTE_PRINTF #define ATTRIBUTE_PRINTF _GL_ATTRIBUTE_FORMAT_PRINTF - +#endif /* __GENODE__ */ #include "libiberty.h" #include "pathmax.h" #include "gdb/signals.h" diff --git a/gdb/common/gdb_tilde_expand.c b/gdb/common/gdb_tilde_expand.c index fcb9796..bd77a83 100644 --- a/gdb/common/gdb_tilde_expand.c +++ b/gdb/common/gdb_tilde_expand.c @@ -71,7 +71,12 @@ private: std::string gdb_tilde_expand (const char *dir) { +#ifdef __GENODE__ + /* GLOB_TILDE_CHECK is not defined in Genode's libc */ + gdb_glob glob (dir, GLOB_TILDE, NULL); +#else gdb_glob glob (dir, GLOB_TILDE_CHECK, NULL); +#endif /* __GENODE__ */ gdb_assert (glob.pathc () > 0); /* "glob" may return more than one match to the path provided by the @@ -86,7 +91,12 @@ gdb_tilde_expand (const char *dir) gdb::unique_xmalloc_ptr gdb_tilde_expand_up (const char *dir) { +#ifdef __GENODE__ + /* GLOB_TILDE_CHECK is not defined in Genode's libc */ + gdb_glob glob (dir, GLOB_TILDE, NULL); +#else gdb_glob glob (dir, GLOB_TILDE_CHECK, NULL); +#endif gdb_assert (glob.pathc () > 0); /* "glob" may return more than one match to the path provided by the diff --git a/gdb/common/pathstuff.c b/gdb/common/pathstuff.c index 8c4093f..db3c23d 100644 --- a/gdb/common/pathstuff.c +++ b/gdb/common/pathstuff.c @@ -55,6 +55,7 @@ gdb_realpath (const char *filename) does not exist locally), we rely instead on GetFullPathName to perform the canonicalization. */ +#ifndef __GENODE__ #if defined (_WIN32) { char buf[MAX_PATH]; @@ -75,6 +76,7 @@ gdb_realpath (const char *filename) return gdb::unique_xmalloc_ptr (rp); } #endif +#endif /* __GENODE__ */ /* This system is a lost cause, just dup the buffer. */ return gdb::unique_xmalloc_ptr (xstrdup (filename)); diff --git a/gdb/gdbserver/linux-aarch32-low.c b/gdb/gdbserver/linux-aarch32-low.c index 12c11a4..c42b5bb 100644 --- a/gdb/gdbserver/linux-aarch32-low.c +++ b/gdb/gdbserver/linux-aarch32-low.c @@ -35,7 +35,11 @@ is used for gdbserver, so single threaded debugging should work OK, but for multi-threaded debugging we only insert the current ABI's breakpoint instruction. For now at least. */ +#ifdef __GENODE__ +#define arm_eabi_breakpoint 0xe7ffdefeUL +#else #define arm_eabi_breakpoint 0xe7f001f0UL +#endif #if (defined __ARM_EABI__ || defined __aarch64__) static const unsigned long arm_breakpoint = arm_eabi_breakpoint; diff --git a/gdb/gdbserver/linux-arm-low.c b/gdb/gdbserver/linux-arm-low.c index 6c2dcea..b682f96 100644 --- a/gdb/gdbserver/linux-arm-low.c +++ b/gdb/gdbserver/linux-arm-low.c @@ -30,6 +30,9 @@ #include #endif #include "nat/gdb_ptrace.h" +#ifdef __GENODE__ +#include +#endif #include #include @@ -878,6 +881,10 @@ arm_read_description (void) /* Query hardware watchpoint/breakpoint capabilities. */ arm_linux_init_hwbp_cap (pid); +#ifndef __GENODE__ + + /* Genode: 'init_registers_arm_with_*()' functions not generated */ + if (arm_get_hwcap (&arm_hwcap) == 0) return tdesc_arm; @@ -910,6 +917,7 @@ arm_read_description (void) return result; } +#endif /* The default configuration uses legacy FPA registers, probably simulated. */ diff --git a/gdb/gdbserver/linux-low.c b/gdb/gdbserver/linux-low.c index 7c396ae..c684d9b 100644 --- a/gdb/gdbserver/linux-low.c +++ b/gdb/gdbserver/linux-low.c @@ -27,6 +27,11 @@ #include "nat/linux-waitpid.h" #include "gdb_wait.h" #include "nat/gdb_ptrace.h" + +#ifdef __GENODE__ +#include "genode-low.h" +#endif + #include "nat/linux-ptrace.h" #include "nat/linux-procfs.h" #include "nat/linux-personality.h" @@ -719,7 +724,11 @@ handle_extended_wait (struct lwp_info **orig_event_lwp, int wstat) /* Set the event status. */ event_lwp->waitstatus.kind = TARGET_WAITKIND_EXECD; event_lwp->waitstatus.value.execd_pathname +#ifdef __GENODE__ + = xstrdup ("target"); +#else = xstrdup (linux_proc_pid_to_exec_file (lwpid_of (event_thr))); +#endif /* Mark the exec status as pending. */ event_lwp->stopped = 1; @@ -1005,8 +1014,10 @@ linux_create_inferior (const char *program, ptid_t ptid; { +#ifndef __GENODE__ maybe_disable_address_space_randomization restore_personality (cs.disable_randomization); +#endif /* __GENODE__ */ std::string str_program_args = stringify_argv (program_args); pid = fork_inferior (program, @@ -1054,12 +1065,17 @@ linux_attach_lwp (ptid_t ptid) struct lwp_info *new_lwp; int lwpid = ptid.lwp (); +#ifndef __GENODE__ if (ptrace (PTRACE_ATTACH, lwpid, (PTRACE_TYPE_ARG3) 0, (PTRACE_TYPE_ARG4) 0) != 0) return errno; +#endif new_lwp = add_lwp (ptid); +#ifdef __GENODE__ + new_lwp->stopped = 1; +#else /* We need to wait for SIGSTOP before being able to make the next ptrace call on this LWP. */ new_lwp->must_set_ptrace_flags = 1; @@ -1126,6 +1142,7 @@ linux_attach_lwp (ptid_t ptid) end of the list, and so the new thread has not yet reached wait_for_sigstop (but will). */ new_lwp->stop_expected = 1; +#endif return 0; } @@ -1200,6 +1217,7 @@ linux_attach (unsigned long pid) proc = linux_add_process (pid, 1); +#ifndef __GENODE__ /* Don't ignore the initial SIGSTOP if we just attached to this process. It will be collected by wait shortly. */ initial_thread = find_thread_ptid (ptid_t (pid, pid, 0)); @@ -1247,6 +1265,7 @@ linux_attach (unsigned long pid) gdb_assert (proc->tdesc != NULL); } +#endif return 0; } @@ -1507,14 +1526,21 @@ get_detach_signal (struct thread_info *thread) /* Detach from LWP. */ +#ifdef __GENODE__ +void +#else static void +#endif /* __GENODE__ */ linux_detach_one_lwp (struct lwp_info *lwp) { struct thread_info *thread = get_lwp_thread (lwp); +#ifndef __GENODE__ int sig; +#endif /* __GENODE__ */ int lwpid; /* If there is a pending SIGSTOP, get rid of it. */ +#ifndef __GENODE__ if (lwp->stop_expected) { if (debug_threads) @@ -1524,7 +1550,9 @@ linux_detach_one_lwp (struct lwp_info *lwp) kill_lwp (lwpid_of (thread), SIGCONT); lwp->stop_expected = 0; } +#endif +#ifndef __GENODE__ /* Pass on any pending signal for this thread. */ sig = get_detach_signal (thread); @@ -1587,6 +1615,7 @@ linux_detach_one_lwp (struct lwp_info *lwp) target_pid_to_str (ptid_of (thread)), strsignal (sig)); } +#endif delete_lwp (lwp); } @@ -1874,6 +1903,7 @@ iterate_over_lwps (ptid_t filter, static void check_zombie_leaders (void) { +#ifndef __GENODE__ for_each_process ([] (process_info *proc) { pid_t leader_pid = pid_of (proc); struct lwp_info *leader_lp; @@ -1928,6 +1958,7 @@ check_zombie_leaders (void) delete_lwp (leader_lp); } }); +#endif /* __GENODE__ */ } /* Callback for `find_thread'. Returns the first LWP that is not @@ -2730,11 +2761,13 @@ linux_wait_for_event_filtered (ptid_t wait_ptid, ptid_t filter_ptid, if (ret > 0) { +#ifndef __GENODE__ if (debug_threads) { debug_printf ("LLW: waitpid %ld received %s\n", (long) ret, status_to_str (*wstatp)); } +#endif /* __GENODE__ */ /* Filter all events. IOW, leave all events pending. We'll randomly select an event LWP out of all that have events @@ -3036,11 +3069,12 @@ linux_stabilize_threads (void) static ptid_t ignore_event (struct target_waitstatus *ourstatus) { +#ifndef __GENODE__ /* If we got an event, there may still be others, as a single SIGCHLD can indicate more than one child stopped. This forces another target_wait call. */ async_file_mark (); - +#endif /* __GENODE__ */ ourstatus->kind = TARGET_WAITKIND_IGNORE; return null_ptid; } @@ -3877,9 +3911,11 @@ linux_wait (ptid_t ptid, { ptid_t event_ptid; +#ifndef __GENODE__ /* Flush the async file first. */ if (target_is_async_p ()) async_file_flush (); +#endif do { @@ -3889,12 +3925,14 @@ linux_wait (ptid_t ptid, && event_ptid == null_ptid && ourstatus->kind == TARGET_WAITKIND_IGNORE); +#ifndef __GENODE__ /* If at least one stop was reported, there may be more. A single SIGCHLD can signal more than one child stop. */ if (target_is_async_p () && (target_options & TARGET_WNOHANG) != 0 && event_ptid != null_ptid) async_file_mark (); +#endif return event_ptid; } @@ -3904,6 +3942,9 @@ linux_wait (ptid_t ptid, static int kill_lwp (unsigned long lwpid, int signo) { +#ifdef __GENODE__ + return kill (lwpid, signo); +#else int ret; errno = 0; @@ -3915,6 +3956,7 @@ kill_lwp (unsigned long lwpid, int signo) perror_with_name (("tkill")); } return ret; +#endif } void @@ -4447,6 +4489,21 @@ linux_resume_one_lwp_throw (struct lwp_info *lwp, regcache_invalidate_thread (thread); errno = 0; lwp->stepping = step; + +#ifdef __GENODE__ + + /* + * On Linux, the thread would get stopped immediately after resuming + * if a SIGSTOP is pending. This is not the case on Genode, so we + * just keep the thread stopped. + */ + if (lwp->stop_expected) + return; + + genode_continue_thread(lwpid_of(thread), step); + +#else + if (step) ptrace_request = PTRACE_SINGLESTEP; else if (gdb_catching_syscalls_p (lwp)) @@ -4459,6 +4516,7 @@ linux_resume_one_lwp_throw (struct lwp_info *lwp, /* Coerce to a uintptr_t first to avoid potential gcc warning of coercing an 8 byte integer to a 4 byte pointer. */ (PTRACE_TYPE_ARG4) (uintptr_t) signal); +#endif current_thread = saved_thread; if (errno) @@ -4496,7 +4554,7 @@ check_ptrace_stopped_lwp_gone (struct lwp_info *lp) (observed in Linux 3.18). See also the note on ESRCH in the ptrace(2) man page. Instead, check whether the LWP has any state other than ptrace-stopped. */ - +#ifndef __GENODE__ /* Don't assume anything if /proc/PID/status can't be read. */ if (linux_proc_pid_is_trace_stopped_nowarn (lwpid_of (thread)) == 0) { @@ -4504,6 +4562,7 @@ check_ptrace_stopped_lwp_gone (struct lwp_info *lp) lp->status_pending_p = 0; return 1; } +#endif /* __GENODE__ */ return 0; } @@ -5374,6 +5433,7 @@ regsets_fetch_inferior_registers (struct regsets_info *regsets_info, this process mode. */ disable_regset (regsets_info, regset); } +#ifndef __GENODE__ else if (errno == ENODATA) { /* ENODATA may be returned if the regset is currently @@ -5386,6 +5446,7 @@ regsets_fetch_inferior_registers (struct regsets_info *regsets_info, already gone, in which case we simply ignore attempts to read its registers. */ } +#endif else { char s[256]; @@ -6566,6 +6627,13 @@ linux_read_loadmap (const char *annex, CORE_ADDR offset, static void linux_process_qsupported (char **features, int count) { +#ifdef __GENODE__ + /* + * 'qSupported' is the first command sent by GDB when attaching to the + * server, so when at this location, GDB has just (re-)attached itself. + */ + genode_stop_all_threads(); +#endif if (the_low_target.process_qsupported != NULL) the_low_target.process_qsupported (features, count); } @@ -6691,6 +6759,7 @@ linux_get_min_fast_tracepoint_insn_len (void) return (*the_low_target.get_min_fast_tracepoint_insn_len) (); } +#ifndef __GENODE__ /* Extract &phdr and num_phdr in the inferior. Return 0 on success. */ static int @@ -7176,6 +7245,7 @@ linux_qxfer_libraries_svr4 (const char *annex, unsigned char *readbuf, return len; } +#endif /* __GENODE__ */ #ifdef HAVE_LINUX_BTRACE @@ -7436,25 +7506,52 @@ static struct target_ops linux_target_ops = { linux_create_inferior, linux_post_create_inferior, linux_attach, +#ifndef __GENODE__ linux_kill, linux_detach, linux_mourn, linux_join, +#else + genode_kill, + genode_detach, + NULL, + NULL, +#endif linux_thread_alive, linux_resume, linux_wait, +#ifndef __GENODE__ linux_fetch_registers, linux_store_registers, +#else + genode_fetch_registers, + genode_store_registers, +#endif linux_prepare_to_access_memory, linux_done_accessing_memory, +#ifndef __GENODE__ linux_read_memory, linux_write_memory, +#else + genode_read_memory, + genode_write_memory, +#endif +#ifndef __GENODE__ linux_look_up_symbols, +#else + NULL, +#endif linux_request_interrupt, +#ifndef __GENODE__ linux_read_auxv, linux_supports_z_point_type, +#else + NULL, + NULL, +#endif linux_insert_point, linux_remove_point, +#ifndef __GENODE__ linux_stopped_by_sw_breakpoint, linux_supports_stopped_by_sw_breakpoint, linux_stopped_by_hw_breakpoint, @@ -7462,6 +7559,15 @@ static struct target_ops linux_target_ops = { linux_supports_hardware_single_step, linux_stopped_by_watchpoint, linux_stopped_data_address, +#else + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, +#endif #if defined(__UCLIBC__) && defined(HAS_NOMMU) \ && defined(PT_TEXT_ADDR) && defined(PT_DATA_ADDR) \ && defined(PT_TEXT_END_ADDR) @@ -7474,6 +7580,7 @@ static struct target_ops linux_target_ops = { #else NULL, #endif +#ifndef __GENODE__ linux_qxfer_spu, hostio_last_error_from_errno, linux_qxfer_osdata, @@ -7486,14 +7593,34 @@ static struct target_ops linux_target_ops = { linux_supports_vfork_events, linux_supports_exec_events, linux_handle_new_gdb_connection, +#else + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, +#endif #ifdef USE_THREAD_DB thread_db_handle_monitor_command, #else NULL, #endif +#ifndef __GENODE__ linux_common_core_of_thread, linux_read_loadmap, +#else + NULL, + NULL, +#endif linux_process_qsupported, +#ifndef __GENODE__ linux_supports_tracepoints, linux_read_pc, linux_write_pc, @@ -7525,7 +7652,34 @@ static struct target_ops linux_target_ops = { linux_mntns_unlink, linux_mntns_readlink, linux_breakpoint_kind_from_pc, +#else + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, +#endif linux_sw_breakpoint_from_kind, +#ifndef __GENODE__ linux_proc_tid_get_name, linux_breakpoint_kind_from_current_state, linux_supports_software_single_step, @@ -7536,6 +7690,14 @@ static struct target_ops linux_target_ops = { #else NULL, #endif +#else + NULL, + NULL, + NULL, + NULL, + NULL, + NULL +#endif /* __GENODE__ */ }; #ifdef HAVE_LINUX_REGSETS @@ -7557,8 +7719,10 @@ initialize_low (void) memset (&sigchld_action, 0, sizeof (sigchld_action)); set_target_ops (&linux_target_ops); +#ifndef __GENODE__ linux_ptrace_init_warnings (); linux_proc_init_warnings (); +#endif sigchld_action.sa_handler = sigchld_handler; sigemptyset (&sigchld_action.sa_mask); diff --git a/gdb/gdbserver/linux-low.h b/gdb/gdbserver/linux-low.h index 79b3311..0b7f4ed 100644 --- a/gdb/gdbserver/linux-low.h +++ b/gdb/gdbserver/linux-low.h @@ -17,11 +17,16 @@ along with this program. If not, see . */ #include "nat/linux-nat.h" +#ifndef __GENODE__ #include "nat/gdb_thread_db.h" +#endif #include #include "gdbthread.h" + +#ifndef __GENODE__ #include "gdb_proc_service.h" +#endif /* Included for ptrace type definitions. */ #include "nat/linux-ptrace.h" diff --git a/gdb/gdbserver/linux-x86-low.c b/gdb/gdbserver/linux-x86-low.c index 80b4380..b8984c9 100644 --- a/gdb/gdbserver/linux-x86-low.c +++ b/gdb/gdbserver/linux-x86-low.c @@ -31,7 +31,9 @@ #include "nat/amd64-linux-siginfo.h" #endif +#ifndef __GENODE__ #include "gdb_proc_service.h" +#endif /* Don't include elf/common.h if linux/elf.h got included by gdb_proc_service.h. */ #ifndef ELFMAG0 @@ -52,11 +54,23 @@ static struct target_desc *tdesc_amd64_linux_no_xml; #endif static struct target_desc *tdesc_i386_linux_no_xml; - static unsigned char jump_insn[] = { 0xe9, 0, 0, 0, 0 }; static unsigned char small_jump_insn[] = { 0x66, 0xe9, 0, 0 }; /* Backward compatibility for gdb without XML support. */ +#ifdef __GENODE__ + +static const char *xmltarget_i386_linux_no_xml = "@\ +i386\ +"; + +#ifdef __x86_64__ +static const char *xmltarget_amd64_linux_no_xml = "@\ +i386:x86-64\ +"; +#endif + +#else static const char *xmltarget_i386_linux_no_xml = "@\ i386\ @@ -70,7 +84,17 @@ static const char *xmltarget_amd64_linux_no_xml = "@\ "; #endif +#endif /* __GENODE__ */ + +#ifdef __GENODE__ +#ifdef __x86_64__ +#include "amd64.h" +#else +#include "i386.h" +#endif /* __x86_64__ */ +#else #include +#endif #include #include "nat/gdb_ptrace.h" #include @@ -119,7 +143,11 @@ static /*const*/ int i386_regmap[] = #define ORIG_EAX ORIG_RAX #define REGSIZE 8 -static const int x86_64_regmap[] = +static +#ifndef __GENODE__ +const +#endif +int x86_64_regmap[] = { RAX * 8, RBX * 8, RCX * 8, RDX * 8, RSI * 8, RDI * 8, RBP * 8, RSP * 8, @@ -132,6 +160,7 @@ static const int x86_64_regmap[] = -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +#ifndef __GENODE__ ORIG_RAX * 8, #ifdef HAVE_STRUCT_USER_REGS_STRUCT_FS_BASE 21 * 8, 22 * 8, @@ -150,6 +179,7 @@ static const int x86_64_regmap[] = -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 /* pkru */ +#endif }; #define X86_64_NUM_REGS (sizeof (x86_64_regmap) / sizeof (x86_64_regmap[0])) @@ -191,6 +221,7 @@ is_64bit_tdesc (void) /* Called by libthread_db. */ +#ifndef __GENODE__ ps_err_e ps_get_thread_area (struct ps_prochandle *ph, lwpid_t lwpid, int idx, void **base) @@ -229,6 +260,7 @@ ps_get_thread_area (struct ps_prochandle *ph, return PS_OK; } } +#endif /* Get the thread area address. This is used to recognize which thread is which when tracing with the in-process agent library. We @@ -284,7 +316,11 @@ x86_cannot_store_register (int regno) { #ifdef __x86_64__ if (is_64bit_tdesc ()) +#ifdef __GENODE__ + return regno >= X86_64_NUM_REGS; +#else return 0; +#endif /* GENODE */ #endif return regno >= I386_NUM_REGS; @@ -295,12 +331,30 @@ x86_cannot_fetch_register (int regno) { #ifdef __x86_64__ if (is_64bit_tdesc ()) +#ifdef __GENODE__ + return regno >= X86_64_NUM_REGS; +#else return 0; +#endif /* GENODE */ #endif return regno >= I386_NUM_REGS; } +#ifdef __x86_64__ +static int +x86_64_cannot_store_register (int regno) +{ + return regno >= X86_64_NUM_REGS; +} + +static int +x86_64_cannot_fetch_register (int regno) +{ + return regno >= X86_64_NUM_REGS; +} +#endif /* __x86_64__ */ + static void x86_fill_gregset (struct regcache *regcache, void *buf) { @@ -337,8 +391,10 @@ x86_fill_gregset (struct regcache *regcache, void *buf) for (i = 0; i < I386_NUM_REGS; i++) collect_register (regcache, i, ((char *) buf) + i386_regmap[i]); +#ifndef __GENODE__ collect_register_by_name (regcache, "orig_eax", ((char *) buf) + ORIG_EAX * REGSIZE); +#endif } static void @@ -372,8 +428,10 @@ x86_store_gregset (struct regcache *regcache, const void *buf) for (i = 0; i < I386_NUM_REGS; i++) supply_register (regcache, i, ((char *) buf) + i386_regmap[i]); +#ifndef __GENODE__ supply_register_by_name (regcache, "orig_eax", ((char *) buf) + ORIG_EAX * REGSIZE); +#endif } static void @@ -493,7 +551,15 @@ x86_set_pc (struct regcache *regcache, CORE_ADDR pc) } } +#ifdef __GENODE__ +/* The 'INT3' instruction is used by some kernel debuggers and thus cannot + * serve as breakpoint instruction for the GDB monitor. Instead, the 'HLT' + * instruction gets used. It's a privileged instruction which triggers an + * exception when executed in user mode */ +static const gdb_byte x86_breakpoint[] = { 0xF4 }; +#else static const gdb_byte x86_breakpoint[] = { 0xCC }; +#endif #define x86_breakpoint_len 1 static int @@ -502,7 +568,7 @@ x86_breakpoint_at (CORE_ADDR pc) unsigned char c; (*the_target->read_memory) (pc, &c, 1); - if (c == 0xCC) + if (c == x86_breakpoint[0]) return 1; return 0; @@ -669,6 +735,7 @@ x86_debug_reg_state (pid_t pid) as debugging it with a 32-bit GDBSERVER, we do the 32-bit <-> 64-bit conversion in-place ourselves. */ +#ifndef __GENODE__ /* Convert a ptrace/host siginfo object, into/from the siginfo in the layout of the inferiors' architecture. Returns true if any conversion was done; false otherwise. If DIRECTION is 1, then copy @@ -695,6 +762,7 @@ x86_siginfo_fixup (siginfo_t *ptrace, gdb_byte *inf, int direction) return 0; } +#endif static int use_xml; @@ -735,6 +803,13 @@ int have_ptrace_getfpxregs = static const struct target_desc * x86_linux_read_description (void) { +#ifdef __GENODE__ +#ifdef __x86_64__ + return amd64_linux_read_description(X86_XSTATE_SSE_MASK, false); +#else + return i386_linux_read_description(X86_XSTATE_SSE); +#endif +#else unsigned int machine; int is_elf64; int xcr0_features; @@ -850,7 +925,7 @@ x86_linux_read_description (void) return tdesc; } - +#endif /* __GENODE__ */ gdb_assert_not_reached ("failed to return tdesc"); } @@ -925,13 +1000,24 @@ static struct regsets_info x86_regsets_info = }; #ifdef __x86_64__ +static struct usrregs_info amd64_linux_usrregs_info = + { + X86_64_NUM_REGS, + x86_64_regmap, + }; + static struct regs_info amd64_linux_regs_info = { NULL, /* regset_bitmap */ +#ifdef __GENODE__ + &amd64_linux_usrregs_info, +#else NULL, /* usrregs_info */ +#endif &x86_regsets_info }; #endif + static struct usrregs_info i386_linux_usrregs_info = { I386_NUM_REGS, @@ -2852,12 +2938,20 @@ struct linux_target_ops the_low_target = NULL, /* breakpoint_kind_from_pc */ x86_sw_breakpoint_from_kind, NULL, +#ifndef __GENODE__ 1, +#else + 0, /* With the HLT instruction, the PC does not get incremented */ +#endif x86_breakpoint_at, x86_supports_z_point_type, x86_insert_point, x86_remove_point, +#ifndef __GENODE__ x86_stopped_by_watchpoint, +#else + NULL, +#endif x86_stopped_data_address, /* collect_ptrace_register/supply_ptrace_register are not needed in the native i386 case (no registers smaller than an xfer unit), and are not @@ -2865,13 +2959,22 @@ struct linux_target_ops the_low_target = NULL, NULL, /* need to fix up i386 siginfo if host is amd64 */ +#ifdef __GENODE__ + NULL, +#else x86_siginfo_fixup, +#endif x86_linux_new_process, x86_linux_delete_process, x86_linux_new_thread, x86_linux_delete_thread, +#ifndef __GENODE__ x86_linux_new_fork, x86_linux_prepare_to_resume, +#else + NULL, + NULL, +#endif x86_linux_process_qsupported, x86_supports_tracepoints, x86_get_thread_area, diff --git a/gdb/gdbserver/linux-x86-tdesc-selftest.c b/gdb/gdbserver/linux-x86-tdesc-selftest.c index e840b77..c7d1e34 100644 --- a/gdb/gdbserver/linux-x86-tdesc-selftest.c +++ b/gdb/gdbserver/linux-x86-tdesc-selftest.c @@ -21,6 +21,17 @@ #include "common/selftest.h" #include "x86-xstate.h" +#ifdef __GENODE__ +/* Defined in auto-generated file i386.c. */ +void init_registers_i386 (void); +static inline void init_registers_i386_linux(void) { init_registers_i386(); } +extern const struct target_desc *tdesc_i386_linux; + +void init_registers_i386_avx (void); +static inline void init_registers_i386_avx_linux(void) { init_registers_i386_avx(); } +extern const struct target_desc *tdesc_i386_avx_linux; +#else + /* Defined in auto-generated file i386-linux.c. */ void init_registers_i386_linux (void); extern const struct target_desc *tdesc_i386_linux; @@ -48,9 +59,20 @@ extern const struct target_desc *tdesc_i386_avx_mpx_avx512_pku_linux; /* Defined in auto-generated file i386-mpx-linux.c. */ void init_registers_i386_mpx_linux (void); extern const struct target_desc *tdesc_i386_mpx_linux; +#endif /* __GENODE__ */ #ifdef __x86_64__ +#ifdef __GENODE__ +void init_registers_amd64 (void); +static inline void init_registers_amd64_linux(void) { init_registers_amd64(); } +extern const struct target_desc *tdesc_amd64_linux; + +void init_registers_amd64_avx (void); +static inline void init_registers_amd64_avx_linux(void) { init_registers_amd64_avx(); } +extern const struct target_desc *tdesc_amd64_avx_linux; +#else + /* Defined in auto-generated file amd64-linux.c. */ void init_registers_amd64_linux (void); extern const struct target_desc *tdesc_amd64_linux; @@ -87,6 +109,7 @@ extern const struct target_desc *tdesc_x32_avx_linux; void init_registers_x32_avx_avx512_linux (void); extern const struct target_desc *tdesc_x32_avx_avx512_linux; +#endif /* __GENODE__ */ #endif namespace selftests { @@ -157,27 +180,35 @@ void initialize_low_tdesc () { init_registers_i386_linux (); +#ifndef __GENODE__ init_registers_i386_mmx_linux (); +#endif /* __GENODE__ */ init_registers_i386_avx_linux (); +#ifndef __GENODE init_registers_i386_mpx_linux (); init_registers_i386_avx_mpx_linux (); init_registers_i386_avx_avx512_linux (); init_registers_i386_avx_mpx_avx512_pku_linux (); selftests::register_test ("i386-tdesc", selftests::tdesc::i386_tdesc_test); +#endif /* __GENODE__ */ #ifdef __x86_64__ +#ifndef __GENODE__ init_registers_x32_linux (); init_registers_x32_avx_linux (); init_registers_x32_avx_avx512_linux (); +#endif /* __GENODE__ */ init_registers_amd64_linux (); init_registers_amd64_avx_linux (); +#ifndef __GENODE__ init_registers_amd64_mpx_linux (); init_registers_amd64_avx_mpx_linux (); init_registers_amd64_avx_avx512_linux (); init_registers_amd64_avx_mpx_avx512_pku_linux (); selftests::register_test ("amd64-tdesc", selftests::tdesc::amd64_tdesc_test); +#endif /* __GENODE__ */ #endif } diff --git a/gdb/gdbserver/linux-x86-tdesc.c b/gdb/gdbserver/linux-x86-tdesc.c index c3aa20c..e5a57c0 100644 --- a/gdb/gdbserver/linux-x86-tdesc.c +++ b/gdb/gdbserver/linux-x86-tdesc.c @@ -87,7 +87,11 @@ i386_linux_read_description (uint64_t xcr0) if (*tdesc == NULL) { +#ifdef __GENODE__ + *tdesc = i386_create_target_description (xcr0, false); +#else *tdesc = i386_create_target_description (xcr0, true); +#endif /* __GENODE__ */ init_target_desc (*tdesc, i386_expedite_regs); } @@ -118,7 +122,11 @@ amd64_linux_read_description (uint64_t xcr0, bool is_x32) if (*tdesc == NULL) { +#ifdef __GENODE__ + *tdesc = amd64_create_target_description (xcr0, is_x32, false, false); +#else *tdesc = amd64_create_target_description (xcr0, is_x32, true, true); +#endif /* __GENODE__ */ init_target_desc (*tdesc, amd64_expedite_regs); } diff --git a/gdb/gdbserver/remote-utils.c b/gdb/gdbserver/remote-utils.c index 45d5c8d..7b6b1be 100644 --- a/gdb/gdbserver/remote-utils.c +++ b/gdb/gdbserver/remote-utils.c @@ -27,6 +27,12 @@ #include "rsp-low.h" #include "gdbthread.h" #include + +#ifdef __GENODE__ +#include +#include "genode-low.h" +#endif + #if HAVE_SYS_IOCTL_H #include #endif @@ -108,7 +114,10 @@ struct ui_file *gdb_stdlog; static int remote_is_stdio = 0; -static gdb_fildes_t remote_desc = INVALID_DESCRIPTOR; +#ifndef __GENODE__ +static +#endif +gdb_fildes_t remote_desc = INVALID_DESCRIPTOR; static gdb_fildes_t listen_desc = INVALID_DESCRIPTOR; /* FIXME headerize? */ diff --git a/gdb/gdbserver/server.c b/gdb/gdbserver/server.c index bf6302b..b6a9494 100644 --- a/gdb/gdbserver/server.c +++ b/gdb/gdbserver/server.c @@ -28,6 +28,14 @@ #if HAVE_SIGNAL_H #include #endif + +#ifdef __GENODE__ +#include "genode-low.h" +#include "linux-low.h" +/* don't have the generated header with the declaration */ +extern "C" char *strchrnul(const char *s, int c_in); +#endif + #include "gdb_vecs.h" #include "gdb_wait.h" #include "btrace-common.h" @@ -70,7 +78,11 @@ static gdb_environ our_environ; /* We always try to start the inferior using a shell. */ +#ifdef __GENODE__ +int startup_with_shell = 0; +#else int startup_with_shell = 1; +#endif int server_waiting; @@ -1282,7 +1294,9 @@ handle_detach (char *own_buf) need to hang around doing nothing, until the child is gone. */ join_inferior (process->pid); +#ifndef __GENODE__ exit (0); +#endif /* __GENODE__ */ } } } @@ -3141,11 +3155,11 @@ handle_v_requests (char *own_buf, int packet_len, int *new_packet_len) return; } } - +#ifndef __GENODE__ if (startswith (own_buf, "vFile:") && handle_vFile (own_buf, packet_len, new_packet_len)) return; - +#endif if (startswith (own_buf, "vAttach;")) { if ((!extended_protocol || !cs.multi_process) && target_running ()) @@ -3737,7 +3751,9 @@ captured_main (int argc, char *argv[]) opened by remote_prepare. */ notice_open_fds (); +#ifndef __GENODE__ save_original_signals_state (false); +#endif /* __GENODE__ */ /* We need to know whether the remote connection is stdio before starting the inferior. Inferiors created in this scenario have @@ -3942,7 +3958,11 @@ captured_main (int argc, char *argv[]) /* Main function. */ int +#ifdef __GENODE__ +gdbserver_main (int argc, char *argv[]) +#else main (int argc, char *argv[]) +#endif { TRY @@ -4045,6 +4065,10 @@ process_serial_event (void) } response_needed = 1; +#ifdef __GENODE__ + if (debug_threads) printf("GDB command = %s\n", cs.own_buf); +#endif + char ch = cs.own_buf[0]; switch (ch) { @@ -4290,7 +4314,11 @@ process_serial_event (void) return 0; } else +#ifndef __GENODE__ exit (0); +#else + return 0; +#endif case 'T': { @@ -4365,7 +4393,9 @@ process_serial_event (void) cs.own_buf[0] = '\0'; break; } - +#ifdef __GENODE__ + if (debug_threads) printf("GDBserver response = %s\n", cs.own_buf); +#endif if (new_packet_len != -1) putpkt_binary (cs.own_buf, new_packet_len); else diff --git a/gdb/gdbserver/server.h b/gdb/gdbserver/server.h index 5e41e2f..fcffe77 100644 --- a/gdb/gdbserver/server.h +++ b/gdb/gdbserver/server.h @@ -60,7 +60,11 @@ int vsnprintf(char *str, size_t size, const char *format, va_list ap); #include "gdb_signals.h" #include "target.h" #include "mem-break.h" +#ifdef __GENODE__ +#include "common/environ.h" +#else #include "environ.h" +#endif /* __GENODE__ */ /* Target-specific functions */ diff --git a/gdb/nat/fork-inferior.c b/gdb/nat/fork-inferior.c index ea71aad..9b789e7 100644 --- a/gdb/nat/fork-inferior.c +++ b/gdb/nat/fork-inferior.c @@ -420,9 +420,9 @@ fork_inferior (const char *exec_file_arg, const std::string &allargs, undebuggable. Indeed, you probably got an error message saying "not parent". Sorry; you'll have to use print statements! */ - +#ifndef __GENODE__ restore_original_signals_state (); - +#endif /* __GENODE__ */ /* There is no execlpe call, so we have to set the environment for our child in the global variable. If we've vforked, this clobbers the parent, but environ is restored a few lines down diff --git a/gdb/nat/gdb_ptrace.h b/gdb/nat/gdb_ptrace.h index bdd7621..45caf22 100644 --- a/gdb/nat/gdb_ptrace.h +++ b/gdb/nat/gdb_ptrace.h @@ -129,6 +129,7 @@ extern PTRACE_TYPE_RET ptrace(); #endif +#ifndef __GENODE__ /* Some systems, at least AIX and HP-UX have a ptrace with five arguments. Since we never use the fifth argument, define a ptrace macro that calls the real ptrace with the last argument set to @@ -149,5 +150,6 @@ extern PTRACE_TYPE_RET ptrace(); # define ptrace(request, pid, addr, data) \ ptrace ((PTRACE_TYPE_ARG1) request, pid, addr, data) #endif +#endif /* __GENODE__ */ #endif /* gdb_ptrace.h */ diff --git a/gdb/nat/linux-ptrace.c b/gdb/nat/linux-ptrace.c index 1f21ef0..4538dc0 100644 --- a/gdb/nat/linux-ptrace.c +++ b/gdb/nat/linux-ptrace.c @@ -36,6 +36,7 @@ static int supported_ptrace_options = -1; std::string linux_ptrace_attach_fail_reason (pid_t pid) { +#ifndef __GENODE__ pid_t tracerpid = linux_proc_get_tracerpid_nowarn (pid); std::string result; @@ -51,6 +52,7 @@ linux_ptrace_attach_fail_reason (pid_t pid) (int) pid); return result; +#endif } /* See linux-ptrace.h. */ @@ -73,12 +75,16 @@ linux_ptrace_attach_fail_reason_string (ptid_t ptid, int err) /* Address of the 'ret' instruction in asm code block below. */ EXTERN_C void linux_ptrace_test_ret_to_nx_instr (void); +#ifndef __GENODE__ #include +#endif #include #include - +#else +#include #endif /* defined __i386__ || defined __x86_64__ */ +#ifndef __GENODE__ /* Test broken off-trunk Linux kernel patchset for NX support on i386. It was removed in Fedora kernel 88fa1f0332d188795ed73d7ac2b1564e11a0b4cd. @@ -240,6 +246,7 @@ linux_ptrace_test_ret_to_nx (void) "support detected!")); #endif /* defined __i386__ || defined __x86_64__ */ } +#endif /* __GENODE__ */ /* Helper function to fork a process and make the child process call the function FUNCTION, passing CHILD_STACK as parameter. @@ -325,6 +332,7 @@ static void linux_test_for_exitkill (int child_pid); void linux_check_ptrace_features (void) { +#ifndef __GENODE__ int child_pid, ret, status; /* Initialize the options. */ @@ -362,6 +370,7 @@ linux_check_ptrace_features (void) my_waitpid (child_pid, &status, 0); } while (WIFSTOPPED (status)); +#endif } /* Determine if PTRACE_O_TRACESYSGOOD can be used to catch @@ -479,6 +488,7 @@ linux_test_for_exitkill (int child_pid) void linux_enable_event_reporting (pid_t pid, int options) { +#ifndef __GENODE__ /* Check if we have initialized the ptrace features for this target. If not, do it now. */ if (supported_ptrace_options == -1) @@ -493,6 +503,7 @@ linux_enable_event_reporting (pid_t pid, int options) /* Set the options. */ ptrace (PTRACE_SETOPTIONS, pid, (PTRACE_TYPE_ARG3) 0, (PTRACE_TYPE_ARG4) (uintptr_t) options); +#endif /* __GENODE__ */ } /* Disable reporting of all currently supported ptrace events. */ @@ -500,8 +511,10 @@ linux_enable_event_reporting (pid_t pid, int options) void linux_disable_event_reporting (pid_t pid) { +#ifndef __GENODE__ /* Set the options. */ ptrace (PTRACE_SETOPTIONS, pid, (PTRACE_TYPE_ARG3) 0, 0); +#endif /* __GENODE__ */ } /* Returns non-zero if PTRACE_OPTIONS is contained within @@ -580,7 +593,9 @@ linux_ptrace_init_warnings (void) return; warned = 1; +#ifndef __GENODE__ linux_ptrace_test_ret_to_nx (); +#endif } /* Extract extended ptrace event from wait status. */ diff --git a/gdb/nat/linux-ptrace.h b/gdb/nat/linux-ptrace.h index 98b44a8..178310e 100644 --- a/gdb/nat/linux-ptrace.h +++ b/gdb/nat/linux-ptrace.h @@ -115,7 +115,11 @@ struct buffer; way to go. That said, some architecture may get the si_code wrong, and as such we're leaving fallback code in place. We'll remove this after a while if no problem is reported. */ +#ifdef __GENODE__ +#define USE_SIGTRAP_SIGINFO 0 +#else #define USE_SIGTRAP_SIGINFO 1 +#endif /* The x86 kernel gets some of the si_code values backwards, like this: