genode/repos/ports/src/noux-pkg/gdb/patches/gdbserver_genode.patch
Christian Prochaska 8903179537 tool_chain: use port mechanism
Fixes #2340
2017-03-27 12:35:10 +02:00

667 lines
17 KiB
Diff
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

gdbserver_genode.patch
From: Christian Prochaska <christian.prochaska@genode-labs.com>
---
gdb/gdbserver/linux-arm-low.c | 13 +++++
gdb/gdbserver/linux-low.c | 114 +++++++++++++++++++++++++++++++++++++++++
gdb/gdbserver/linux-low.h | 2 +
gdb/gdbserver/linux-x86-low.c | 53 +++++++++++++++++++
gdb/gdbserver/remote-utils.c | 12 ++++
gdb/gdbserver/server.c | 30 +++++++++--
gdb/gdbserver/server.h | 4 +
7 files changed, 217 insertions(+), 11 deletions(-)
diff --git a/gdb/gdbserver/linux-arm-low.c b/gdb/gdbserver/linux-arm-low.c
index babb20c..23d9e60 100644
--- a/gdb/gdbserver/linux-arm-low.c
+++ b/gdb/gdbserver/linux-arm-low.c
@@ -25,6 +25,9 @@
#ifndef ELFMAG0
#include <elf.h>
#endif
+#ifdef __GENODE__
+#include <sys/procfs.h>
+#endif
#include <sys/ptrace.h>
/* Defined in auto-generated files. */
@@ -209,7 +212,11 @@ static const unsigned short thumb2_breakpoint[] = { 0xf7f0, 0xa000 };
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__
+static const unsigned long arm_eabi_breakpoint = 0xe7ffdefe;
+#else
static const unsigned long arm_eabi_breakpoint = 0xe7f001f0;
+#endif
static int
arm_breakpoint_at (CORE_ADDR where)
@@ -306,6 +313,11 @@ static void
arm_arch_setup (void)
{
arm_hwcap = 0;
+
+#ifndef __GENODE__
+
+ /* Genode: 'init_registers_arm_with_*()' functions not generated */
+
if (arm_get_hwcap (&arm_hwcap) == 0)
{
init_registers_arm ();
@@ -347,6 +359,7 @@ arm_arch_setup (void)
return;
}
+#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 e597e2f..62215fc 100644
--- a/gdb/gdbserver/linux-low.c
+++ b/gdb/gdbserver/linux-low.c
@@ -20,6 +20,10 @@
#include "server.h"
#include "linux-low.h"
+#ifdef __GENODE__
+#include "genode-low.h"
+#endif
+
#include <sys/wait.h>
#include <stdio.h>
#include <sys/param.h>
@@ -606,6 +610,7 @@ linux_attach_lwp_1 (unsigned long lwpid, int initial)
ptid_t ptid;
struct lwp_info *new_lwp;
+#ifndef __GENODE__
if (ptrace (PTRACE_ATTACH, lwpid, 0, 0) != 0)
{
if (!initial)
@@ -621,6 +626,7 @@ linux_attach_lwp_1 (unsigned long lwpid, int initial)
error ("Cannot attach to lwp %ld: %s (%d)\n", lwpid,
strerror (errno), errno);
}
+#endif
if (initial)
/* NOTE/FIXME: This lwp might have not been the tgid. */
@@ -637,6 +643,9 @@ linux_attach_lwp_1 (unsigned long lwpid, int initial)
new_lwp = (struct lwp_info *) add_lwp (ptid);
add_thread (ptid, new_lwp);
+#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;
@@ -675,6 +684,7 @@ linux_attach_lwp_1 (unsigned long lwpid, int initial)
end of the list, and so the new thread has not yet reached
wait_for_sigstop (but will). */
new_lwp->stop_expected = 1;
+#endif
}
void
@@ -689,6 +699,7 @@ linux_attach (unsigned long pid)
linux_attach_lwp_1 (pid, 1);
linux_add_process (pid, 1);
+#ifndef __GENODE__
if (!non_stop)
{
struct thread_info *thread;
@@ -698,6 +709,7 @@ linux_attach (unsigned long pid)
thread = find_thread_ptid (ptid_build (pid, pid, 0));
thread->last_resume_kind = resume_stop;
}
+#endif
return 0;
}
@@ -812,7 +824,11 @@ linux_kill (int pid)
return 0;
}
+#ifdef __GENODE__
+int
+#else
static int
+#endif
linux_detach_one_lwp (struct inferior_list_entry *entry, void *args)
{
struct thread_info *thread = (struct thread_info *) entry;
@@ -822,6 +838,7 @@ linux_detach_one_lwp (struct inferior_list_entry *entry, void *args)
if (ptid_get_pid (entry->id) != pid)
return 0;
+#ifndef __GENODE__
/* If this process is stopped but is expecting a SIGSTOP, then make
sure we take care of that now. This isn't absolutely guaranteed
to collect the SIGSTOP, but is fairly likely to. */
@@ -833,13 +850,16 @@ linux_detach_one_lwp (struct inferior_list_entry *entry, void *args)
linux_resume_one_lwp (lwp, 0, 0, NULL);
linux_wait_for_event (lwp->head.id, &wstat, __WALL);
}
+#endif
/* Flush any pending changes to the process's registers. */
regcache_invalidate_one ((struct inferior_list_entry *)
get_lwp_thread (lwp));
+#ifndef __GENODE__
/* Finally, let it resume. */
ptrace (PTRACE_DETACH, lwpid_of (lwp), 0, 0);
+#endif
delete_lwp (lwp);
return 0;
@@ -1071,6 +1091,10 @@ retry:
if (WIFSTOPPED (*wstatp) && WSTOPSIG (*wstatp) == SIGTRAP)
{
+#ifdef __GENODE__
+ /* no watchpoint support yet */
+ child->stopped_by_watchpoint = 0;
+#else
if (the_low_target.stopped_by_watchpoint == NULL)
{
child->stopped_by_watchpoint = 0;
@@ -1096,7 +1120,8 @@ retry:
current_inferior = saved_inferior;
}
- }
+#endif
+ }
/* Store the STOP_PC, with adjustment applied. This depends on the
architecture being defined already (so that CHILD has a valid
@@ -2469,18 +2494,22 @@ linux_wait (ptid_t ptid,
if (debug_threads)
fprintf (stderr, "linux_wait: [%s]\n", target_pid_to_str (ptid));
+#ifndef __GENODE__
/* Flush the async file first. */
if (target_is_async_p ())
async_file_flush ();
+#endif
event_ptid = linux_wait_1 (ptid, ourstatus, target_options);
+#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
&& !ptid_equal (event_ptid, null_ptid))
async_file_mark ();
+#endif
return event_ptid;
}
@@ -2958,10 +2987,25 @@ lwp %ld wants to get out of fast tracepoint jump pad single-stepping\n",
lwp->stopped = 0;
lwp->stopped_by_watchpoint = 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(lwp), step);
+
+#else
ptrace (step ? PTRACE_SINGLESTEP : PTRACE_CONT, lwpid_of (lwp), 0,
/* Coerce to a uintptr_t first to avoid potential gcc warning
of coercing an 8 byte integer to a 4 byte pointer. */
(PTRACE_ARG4_TYPE) (uintptr_t) signal);
+#endif
current_inferior = saved_inferior;
if (errno)
@@ -5009,6 +5053,13 @@ linux_core_of_thread (ptid_t ptid)
static void
linux_process_qsupported (const char *query)
{
+#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 (query);
}
@@ -5110,26 +5161,56 @@ linux_emit_ops (void)
static struct target_ops linux_target_ops = {
linux_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,
+#else
+ NULL,
+#endif
linux_insert_point,
linux_remove_point,
+#ifndef __GENODE__
linux_stopped_by_watchpoint,
linux_stopped_data_address,
+#else
+ NULL,
+ NULL,
+#endif
#if defined(__UCLIBC__) && defined(HAS_NOMMU)
linux_read_offsets,
#else
@@ -5140,6 +5221,7 @@ static struct target_ops linux_target_ops = {
#else
NULL,
#endif
+#ifndef __GENODE__
linux_qxfer_spu,
hostio_last_error_from_errno,
linux_qxfer_osdata,
@@ -5148,13 +5230,28 @@ static struct target_ops linux_target_ops = {
linux_async,
linux_start_non_stop,
linux_supports_multi_process,
+#else
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+#endif
#ifdef USE_THREAD_DB
thread_db_handle_monitor_command,
#else
NULL,
#endif
+#ifndef __GENODE__
linux_core_of_thread,
+#else
+ NULL,
+#endif
linux_process_qsupported,
+#ifndef __GENODE__
linux_supports_tracepoints,
linux_read_pc,
linux_write_pc,
@@ -5166,6 +5263,19 @@ static struct target_ops linux_target_ops = {
linux_stabilize_threads,
linux_install_fast_tracepoint_jump_pad,
linux_emit_ops
+#else
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+#endif
};
static void
@@ -5187,7 +5297,9 @@ initialize_low (void)
set_breakpoint_data (the_low_target.breakpoint,
the_low_target.breakpoint_len);
linux_init_signals ();
+#ifndef __GENODE__
linux_test_for_tracefork ();
+#endif
#ifdef HAVE_LINUX_REGSETS
for (num_regsets = 0; target_regsets[num_regsets].size >= 0; num_regsets++)
;
diff --git a/gdb/gdbserver/linux-low.h b/gdb/gdbserver/linux-low.h
index d449e1b..0bbcbfd 100644
--- a/gdb/gdbserver/linux-low.h
+++ b/gdb/gdbserver/linux-low.h
@@ -22,7 +22,9 @@
#endif
#include <signal.h>
+#ifndef __GENODE__
#include "gdb_proc_service.h"
+#endif
#ifdef HAVE_LINUX_REGSETS
typedef void (*regset_fill_func) (struct regcache *, void *);
diff --git a/gdb/gdbserver/linux-x86-low.c b/gdb/gdbserver/linux-x86-low.c
index 82dcf83..e98e3bd 100644
--- a/gdb/gdbserver/linux-x86-low.c
+++ b/gdb/gdbserver/linux-x86-low.c
@@ -28,8 +28,17 @@
#include "i386-xstate.h"
#include "elf/common.h"
+#ifndef __GENODE__
#include "gdb_proc_service.h"
+#endif
+#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(); }
+void init_registers_i386_avx (void);
+static inline void init_registers_i386_avx_linux(void) { init_registers_i386_avx(); }
+#else
/* Defined in auto-generated file i386-linux.c. */
void init_registers_i386_linux (void);
/* Defined in auto-generated file amd64-linux.c. */
@@ -40,10 +49,24 @@ void init_registers_i386_avx_linux (void);
void init_registers_amd64_avx_linux (void);
/* Defined in auto-generated file i386-mmx-linux.c. */
void init_registers_i386_mmx_linux (void);
+#endif
static unsigned char jump_insn[] = { 0xe9, 0, 0, 0, 0 };
/* Backward compatibility for gdb without XML support. */
+#ifdef __GENODE__
+
+static const char *xmltarget_i386_linux_no_xml = "@<target>\
+<architecture>i386</architecture>\
+</target>";
+
+#ifdef __x86_64__
+static const char *xmltarget_amd64_linux_no_xml = "@<target>\
+<architecture>i386:x86-64</architecture>\
+</target>";
+#endif
+
+#else
static const char *xmltarget_i386_linux_no_xml = "@<target>\
<architecture>i386</architecture>\
@@ -57,7 +80,15 @@ static const char *xmltarget_amd64_linux_no_xml = "@<target>\
</target>";
#endif
+#endif /* __GENODE__ */
+
+#ifdef __GENODE__
+#ifndef __x86_64__
+#include "i386.h"
+#endif /* __x86_64__ */
+#else
#include <sys/reg.h>
+#endif
#include <sys/procfs.h>
#include <sys/ptrace.h>
#include <sys/uio.h>
@@ -273,8 +304,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 * 4);
+#endif
}
static void
@@ -295,8 +328,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 * 4);
+#endif
}
static void
@@ -414,7 +449,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 unsigned char x86_breakpoint[] = { 0xF4 };
+#else
static const unsigned char x86_breakpoint[] = { 0xCC };
+#endif
#define x86_breakpoint_len 1
static int
@@ -423,7 +466,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;
@@ -2561,7 +2604,11 @@ struct linux_target_ops the_low_target =
x86_breakpoint,
x86_breakpoint_len,
NULL,
+#ifndef __GENODE__
1,
+#else
+ 0, /* With the HLT instruction, the PC does not get incremented */
+#endif
x86_breakpoint_at,
x86_insert_point,
x86_remove_point,
@@ -2576,7 +2623,11 @@ struct linux_target_ops the_low_target =
x86_siginfo_fixup,
x86_linux_new_process,
x86_linux_new_thread,
+#ifndef __GENODE__
x86_linux_prepare_to_resume,
+#else
+ NULL,
+#endif
x86_linux_process_qsupported,
x86_supports_tracepoints,
x86_get_thread_area,
diff --git a/gdb/gdbserver/remote-utils.c b/gdb/gdbserver/remote-utils.c
index 650ddf8..7a53e77 100644
--- a/gdb/gdbserver/remote-utils.c
+++ b/gdb/gdbserver/remote-utils.c
@@ -21,6 +21,12 @@
#include "server.h"
#include "terminal.h"
#include "target.h"
+
+#ifdef __GENODE__
+#include <sys/types.h>
+#include "genode-low.h"
+#endif
+
#include <stdio.h>
#include <string.h>
#if HAVE_SYS_IOCTL_H
@@ -106,8 +112,10 @@ struct sym_cache
int remote_debug = 0;
struct ui_file *gdb_stdlog;
-
-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 2f4484f..124c98d 100644
--- a/gdb/gdbserver/server.c
+++ b/gdb/gdbserver/server.c
@@ -20,6 +20,11 @@
#include "server.h"
+#ifdef __GENODE__
+#include "genode-low.h"
+#include "linux-low.h"
+#endif
+
#if HAVE_UNISTD_H
#include <unistd.h>
#endif
@@ -2055,11 +2060,11 @@ handle_v_requests (char *own_buf, int packet_len, int *new_packet_len)
return;
}
}
-
+#ifndef __GENODE__
if (strncmp (own_buf, "vFile:", 6) == 0
&& handle_vFile (own_buf, packet_len, new_packet_len))
return;
-
+#endif
if (strncmp (own_buf, "vAttach;", 8) == 0)
{
if (!multi_process && target_running ())
@@ -2449,7 +2454,11 @@ join_inferiors_callback (struct inferior_list_entry *entry)
}
int
+#ifdef __GENODE__
+gdbserver_main (int argc, char *argv[])
+#else
main (int argc, char *argv[])
+#endif
{
int bad_attach;
int pid;
@@ -2754,6 +2763,9 @@ process_serial_event (void)
response_needed = 1;
i = 0;
+#ifdef __GENODE
+ if (debug_threads) printf("GDB command = %s\n", own_buf);
+#endif
ch = own_buf[i++];
switch (ch)
{
@@ -2844,7 +2856,9 @@ process_serial_event (void)
gone. */
for_each_inferior (&all_processes,
join_inferiors_callback);
+#ifndef __GENODE__
exit (0);
+#endif
}
}
break;
@@ -3076,7 +3090,11 @@ process_serial_event (void)
return 0;
}
else
+#ifndef __GENODE__
exit (0);
+#else
+ return 0;
+#endif
case 'T':
{
@@ -3140,14 +3158,16 @@ process_serial_event (void)
own_buf[0] = '\0';
break;
}
-
+#ifdef __GENODE__
+ if (debug_threads) printf("GDBserver response = %s\n", own_buf);
+#endif
if (new_packet_len != -1)
putpkt_binary (own_buf, new_packet_len);
else
putpkt (own_buf);
response_needed = 0;
-
+#ifndef __GENODE__
if (!extended_protocol && have_ran && !target_running ())
{
/* In non-stop, defer exiting until GDB had a chance to query
@@ -3159,7 +3179,7 @@ process_serial_event (void)
exit (0);
}
}
-
+#endif
if (exit_requested)
return -1;
diff --git a/gdb/gdbserver/server.h b/gdb/gdbserver/server.h
index 77f5dd6..897abed 100644
--- a/gdb/gdbserver/server.h
+++ b/gdb/gdbserver/server.h
@@ -664,8 +664,8 @@ struct emit_ops
/* Returns the address of the get_raw_reg function in the IPA. */
CORE_ADDR get_raw_reg_func_addr (void);
-CORE_ADDR current_insn_ptr;
-int emit_error;
+extern CORE_ADDR current_insn_ptr;
+extern int emit_error;
/* Version information, from version.c. */
extern const char version[];