aboutsummaryrefslogtreecommitdiff
path: root/gdb
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@gnu.org>2005-01-10 20:36:38 +0000
committerMark Kettenis <kettenis@gnu.org>2005-01-10 20:36:38 +0000
commit8785ced03ac5b8817f23f2bbfa590763a535cac2 (patch)
tree3fbeed5f36c39aa81bb8036e731375fa06e5d974 /gdb
parent0853c0928a75434195960f3ff72c2e865d68d6ac (diff)
downloadgdb-8785ced03ac5b8817f23f2bbfa590763a535cac2.zip
gdb-8785ced03ac5b8817f23f2bbfa590763a535cac2.tar.gz
gdb-8785ced03ac5b8817f23f2bbfa590763a535cac2.tar.bz2
* inf-ptrace.h: Update copyright year. Sync comment with
inf-ptrace.c. (inf_ptrace_trad_target): New prototype. * inf-ptrace.c: Update copyright year. Include "regcache.h" and "gdb_assert.h" (inf_ptrace_target): Add comment. (inf_ptrace+register_u_offset): New variable. (inf_ptrace_fetch_register, inf_ptrace_fetch_registers) (inf_ptrace_store_register, inf_ptrace_store_registers) (inf_ptrace_trad_target): New functions. * Makefile.in (inf-ptrace.o): Update dependencies.
Diffstat (limited to 'gdb')
-rw-r--r--gdb/ChangeLog14
-rw-r--r--gdb/Makefile.in4
-rw-r--r--gdb/inf-ptrace.c132
-rw-r--r--gdb/inf-ptrace.h12
4 files changed, 156 insertions, 6 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 4fc76e1..d3c3a7b 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,17 @@
+2005-01-10 Mark Kettenis <kettenis@gnu.org>
+
+ * inf-ptrace.h: Update copyright year. Sync comment with
+ inf-ptrace.c.
+ (inf_ptrace_trad_target): New prototype.
+ * inf-ptrace.c: Update copyright year. Include "regcache.h" and
+ "gdb_assert.h"
+ (inf_ptrace_target): Add comment.
+ (inf_ptrace+register_u_offset): New variable.
+ (inf_ptrace_fetch_register, inf_ptrace_fetch_registers)
+ (inf_ptrace_store_register, inf_ptrace_store_registers)
+ (inf_ptrace_trad_target): New functions.
+ * Makefile.in (inf-ptrace.o): Update dependencies.
+
2005-01-09 Mark Kettenis <kettenis@gnu.org>
* configure.ac: Provide prerequisite headers when checking
diff --git a/gdb/Makefile.in b/gdb/Makefile.in
index 77f5e62..68c2a60 100644
--- a/gdb/Makefile.in
+++ b/gdb/Makefile.in
@@ -2079,8 +2079,8 @@ inflow.o: inflow.c $(defs_h) $(frame_h) $(inferior_h) $(command_h) \
$(serial_h) $(terminal_h) $(target_h) $(gdbthread_h) $(gdb_string_h) \
$(inflow_h)
inf-ptrace.o: inf-ptrace.c $(defs_h) $(command_h) $(inferior_h) $(inflow_h) \
- $(gdbcore_h) $(observer_h) $(gdb_string_h) $(gdb_ptrace_h) \
- $(gdb_wait_h) $(inf_child_h)
+ $(gdbcore_h) $(observer_h) $(regcache_h) $(gdb_assert_h) \
+ $(gdb_string_h) $(gdb_ptrace_h) $(gdb_wait_h) $(inf_child_h)
inf-ttrace.o: inf-ttrace.c $(defs_h) $(command_h) $(gdbcore_h) \
$(gdbthread_h) $(inferior_h) $(observer_h) $(target_h) \
$(gdb_assert_h) $(gdb_string_h) $(inf_child_h) $(inf_ttrace_h)
diff --git a/gdb/inf-ptrace.c b/gdb/inf-ptrace.c
index c2f5ead..821e424 100644
--- a/gdb/inf-ptrace.c
+++ b/gdb/inf-ptrace.c
@@ -1,7 +1,8 @@
/* Low-level child interface to ptrace.
Copyright 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996,
- 1998, 1999, 2000, 2001, 2002, 2004 Free Software Foundation, Inc.
+ 1998, 1999, 2000, 2001, 2002, 2004, 2005
+ Free Software Foundation, Inc.
This file is part of GDB.
@@ -26,7 +27,9 @@
#include "inflow.h"
#include "gdbcore.h"
#include "observer.h"
+#include "regcache.h"
+#include "gdb_assert.h"
#include "gdb_string.h"
#include "gdb_ptrace.h"
#include "gdb_wait.h"
@@ -592,10 +595,14 @@ inf_ptrace_pid_to_str (ptid_t ptid)
return normal_pid_to_str (ptid);
}
+/* Create a prototype ptrace target. The client can override it with
+ local methods. */
+
struct target_ops *
inf_ptrace_target (void)
{
struct target_ops *t = inf_child_target ();
+
t->to_open = inf_ptrace_open;
t->to_attach = inf_ptrace_attach;
t->to_post_attach = inf_ptrace_post_attach;
@@ -633,5 +640,128 @@ inf_ptrace_target (void)
t->to_has_execution = 1;
t->to_magic = OPS_MAGIC;
ptrace_ops_hack = t;
+
+ return t;
+}
+
+
+/* Pointer to a function that returns the oggset within the user area
+ where a particular register is stored. */
+static CORE_ADDR (*inf_ptrace_register_u_offset)(int);
+
+/* Fetch register REGNUM from the inferior. */
+
+static void
+inf_ptrace_fetch_register (int regnum)
+{
+ CORE_ADDR addr;
+ size_t size;
+ PTRACE_TYPE_RET *buf;
+ int pid, i;
+
+ /* Cater for systems like GNU/Linux, that implement threads as
+ seperate processes. */
+ pid = ptid_get_lwp (inferior_ptid);
+ if (pid == 0)
+ pid = ptid_get_pid (inferior_ptid);
+
+ /* This isn't really an address, but ptrace thinks of it as one. */
+ addr = inf_ptrace_register_u_offset (regnum);
+ size = register_size (current_gdbarch, regnum);
+
+ gdb_assert ((size % sizeof (PTRACE_TYPE_RET)) == 0);
+ buf = alloca (size);
+
+ /* Read the register contents from the inferior a chuck at the time. */
+ for (i = 0; i < size / sizeof (PTRACE_TYPE_RET); i++)
+ {
+ errno = 0;
+ buf[i] = ptrace (PT_READ_U, pid, (PTRACE_TYPE_ARG3) addr, 0);
+ if (errno != 0)
+ error ("Couldn't read register %s (#%d): %s.", REGISTER_NAME (regnum),
+ regnum, safe_strerror (errno));
+
+ addr += sizeof (PTRACE_TYPE_RET);
+ }
+ regcache_raw_supply (current_regcache, regnum, buf);
+}
+
+/* Fetch register REGNUM from the inferior. If REGNUM is -1, do this
+ for all registers. */
+
+static void
+inf_ptrace_fetch_registers (int regnum)
+{
+ if (regnum == -1)
+ for (regnum = 0; regnum < NUM_REGS; regnum++)
+ inf_ptrace_fetch_register (regnum);
+ else
+ inf_ptrace_fetch_register (regnum);
+}
+
+/* Store register REGNUM into the inferior. */
+
+static void
+inf_ptrace_store_register (int regnum)
+{
+ CORE_ADDR addr;
+ size_t size;
+ PTRACE_TYPE_RET *buf;
+ int pid, i;
+
+ /* Cater for systems like GNU/Linux, that implement threads as
+ seperate processes. */
+ pid = ptid_get_lwp (inferior_ptid);
+ if (pid == 0)
+ pid = ptid_get_pid (inferior_ptid);
+
+ /* This isn't really an address, but ptrace thinks of it as one. */
+ addr = inf_ptrace_register_u_offset (regnum);
+ size = register_size (current_gdbarch, regnum);
+
+ gdb_assert ((size % sizeof (PTRACE_TYPE_RET)) == 0);
+ buf = alloca (size);
+
+ /* Write the register contents into the inferior a chunk at the time. */
+ regcache_raw_collect (current_regcache, regnum, buf);
+ for (i = 0; i < size / sizeof (PTRACE_TYPE_RET); i++)
+ {
+ errno = 0;
+ ptrace (PT_WRITE_U, pid, (PTRACE_TYPE_ARG3) addr, buf[i]);
+ if (errno != 0)
+ error ("Couldn't write register %s (#%d): %s.", REGISTER_NAME (regnum),
+ regnum, safe_strerror (errno));
+
+ addr += sizeof (PTRACE_TYPE_RET);
+ }
+}
+
+/* Store register REGNUM back into the inferior. If REGNUM is -1, do
+ this for all registers. */
+
+void
+inf_ptrace_store_registers (int regnum)
+{
+ if (regnum == -1)
+ for (regnum = 0; regnum < NUM_REGS; regnum++)
+ inf_ptrace_store_register (regnum);
+ else
+ inf_ptrace_store_register (regnum);
+}
+
+/* Create a "traditional" ptrace target. REGISTER_U_OFFSET should be
+ a function returning the offset within the user area where a
+ particular register is stored. */
+
+struct target_ops *
+inf_ptrace_trad_target (CORE_ADDR (*register_u_offset)(int))
+{
+ struct target_ops *t = inf_ptrace_target();
+
+ gdb_assert (register_u_offset);
+ inf_ptrace_register_u_offset = register_u_offset;
+ t->to_fetch_registers = inf_ptrace_fetch_registers;
+ t->to_store_registers = inf_ptrace_store_registers;
+
return t;
}
diff --git a/gdb/inf-ptrace.h b/gdb/inf-ptrace.h
index e9ceae3..ef86b51 100644
--- a/gdb/inf-ptrace.h
+++ b/gdb/inf-ptrace.h
@@ -1,7 +1,6 @@
-/* Low level Unix child interface to ptrace, for GDB when running
- under Unix.
+/* Low level child interface to ptrace.
- Copyright 2004 Free Software Foundation, Inc.
+ Copyright 2004, 2005 Free Software Foundation, Inc.
This file is part of GDB.
@@ -28,4 +27,11 @@
extern struct target_ops *inf_ptrace_target (void);
+/* Create a "traditional" ptrace target. REGISTER_U_OFFSET should be
+ a function returning the offset within the user area where a
+ particular register is stored. */
+
+extern struct target_ops *
+ inf_ptrace_trad_target (CORE_ADDR (*register_u_offset)(int));
+
#endif