aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdb/ChangeLog22
-rw-r--r--gdb/Makefile.in3
-rw-r--r--gdb/aix-thread.c29
-rw-r--r--gdb/config/powerpc/aix.mh2
-rw-r--r--gdb/config/rs6000/nm-rs6000.h13
-rw-r--r--gdb/rs6000-nat.c203
6 files changed, 145 insertions, 127 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 9d8b79f..b8e256c 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,27 @@
2007-04-27 Ulrich Weigand <uweigand@de.ibm.com>
+ * aix-thread.c (aix_thread_xfer_memory): Replace by ...
+ (aix_thread_xfer_partial): ... this.
+ (init_aix_thread_ops): Install to_xfer_partial instead
+ of deprecated_xfer_memory target method.
+
+ * config/powerpc/aix.mh (NATDEPFILES): Remove infptrace.o
+ and inftarg.o, add inf-ptrace.o.
+ * config/rs6000/nm-rs6000.h (FETCH_INFERIOR_REGISTERS,
+ CHILD_XFER_MEMORY, KERNEL_U_SIZE, kernel_u_size): Remove.
+ * rs6000-nat.c: Include "inf-ptrace.h" and "gdb_stdint.h".
+ (fetch_inferior_registers): Rename to ...
+ (rs6000_fetch_inferior_registers): ... this. Make static.
+ (store_inferior_registers): Rename to ...
+ (rs6000_store_inferior_registers): ... this. Make static.
+ (read_word, child_xfer_memory): Remove.
+ (rs6000_xfer_partial): New function.
+ (kernel_u_size): Remove.
+ (_initialize_core_rs6000): Add inf_ptrace-based target.
+ * Makefile.in (rs6000-nat.o): Update dependencies.
+
+2007-04-27 Ulrich Weigand <uweigand@de.ibm.com>
+
* inf-ptrace.c: Include "gdb_stdint.h".
(inf_ptrace_xfer_partial): Use "uintptr_t" instead of "long" as
intermediate type when casting CORE_ADDR to PTRACE_TYPE_ARG3.
diff --git a/gdb/Makefile.in b/gdb/Makefile.in
index 2551ea1..fab430b 100644
--- a/gdb/Makefile.in
+++ b/gdb/Makefile.in
@@ -2509,7 +2509,8 @@ remote-sim.o: remote-sim.c $(defs_h) $(inferior_h) $(value_h) \
rs6000-nat.o: rs6000-nat.c $(defs_h) $(inferior_h) $(target_h) $(gdbcore_h) \
$(xcoffsolib_h) $(symfile_h) $(objfiles_h) $(libbfd_h) $(bfd_h) \
$(exceptions_h) $(gdb_stabs_h) $(regcache_h) $(arch_utils_h) \
- $(ppc_tdep_h) $(rs6000_tdep_h) $(exec_h) $(gdb_stat_h)
+ $(inf_ptrace_h) $(ppc_tdep_h) $(rs6000_tdep_h) $(exec_h) \
+ $(gdb_stdint_h) $(gdb_stat_h)
rs6000-tdep.o: rs6000-tdep.c $(defs_h) $(frame_h) $(inferior_h) $(symtab_h) \
$(target_h) $(gdbcore_h) $(gdbcmd_h) $(objfiles_h) $(arch_utils_h) \
$(regcache_h) $(regset_h) $(doublest_h) $(value_h) $(parser_defs_h) \
diff --git a/gdb/aix-thread.c b/gdb/aix-thread.c
index 481c1fe..f69e8df 100644
--- a/gdb/aix-thread.c
+++ b/gdb/aix-thread.c
@@ -1615,23 +1615,24 @@ aix_thread_store_registers (int regno)
}
}
-/* Transfer LEN bytes of memory from GDB address MYADDR to target
- address MEMADDR if WRITE and vice versa otherwise. */
-
-static int
-aix_thread_xfer_memory (CORE_ADDR memaddr, gdb_byte *myaddr, int len, int write,
- struct mem_attrib *attrib,
- struct target_ops *target)
+/* Attempt a transfer all LEN bytes starting at OFFSET between the
+ inferior's OBJECT:ANNEX space and GDB's READBUF/WRITEBUF buffer.
+ Return the number of bytes actually transferred. */
+
+static LONGEST
+aix_thread_xfer_partial (struct target_ops *ops, enum target_object object,
+ const char *annex, gdb_byte *readbuf,
+ const gdb_byte *writebuf, ULONGEST offset, LONGEST len)
{
- int n;
- struct cleanup *cleanup = save_inferior_ptid ();
+ struct cleanup *old_chain = save_inferior_ptid ();
+ LONGEST xfer;
inferior_ptid = pid_to_ptid (PIDGET (inferior_ptid));
- n = base_target.deprecated_xfer_memory (memaddr, myaddr, len,
- write, attrib, &base_target);
- do_cleanups (cleanup);
+ xfer = base_target.to_xfer_partial (ops, object, annex,
+ readbuf, writebuf, offset, len);
- return n;
+ do_cleanups (old_chain);
+ return xfer;
}
/* Kill and forget about the inferior process. */
@@ -1763,7 +1764,7 @@ init_aix_thread_ops (void)
aix_thread_ops.to_wait = aix_thread_wait;
aix_thread_ops.to_fetch_registers = aix_thread_fetch_registers;
aix_thread_ops.to_store_registers = aix_thread_store_registers;
- aix_thread_ops.deprecated_xfer_memory = aix_thread_xfer_memory;
+ aix_thread_ops.to_xfer_partial = aix_thread_xfer_partial;
/* No need for aix_thread_ops.to_create_inferior, because we activate thread
debugging when the inferior reaches pd_brk_addr. */
aix_thread_ops.to_kill = aix_thread_kill;
diff --git a/gdb/config/powerpc/aix.mh b/gdb/config/powerpc/aix.mh
index ac5276f..1a76524 100644
--- a/gdb/config/powerpc/aix.mh
+++ b/gdb/config/powerpc/aix.mh
@@ -3,7 +3,7 @@
NAT_FILE= config/rs6000/nm-rs6000.h
# aix-thread.o is not listed in NATDEPFILES as it is pulled in by configure.
-NATDEPFILES= fork-child.o infptrace.o inftarg.o corelow.o rs6000-nat.o \
+NATDEPFILES= fork-child.o inf-ptrace.o corelow.o rs6000-nat.o \
xcoffread.o xcoffsolib.o
# When compiled with cc, for debugging, this argument should be passed.
diff --git a/gdb/config/rs6000/nm-rs6000.h b/gdb/config/rs6000/nm-rs6000.h
index 15d589e..9690491 100644
--- a/gdb/config/rs6000/nm-rs6000.h
+++ b/gdb/config/rs6000/nm-rs6000.h
@@ -19,14 +19,6 @@
Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
-/* Override copies of {fetch,store}_inferior_registers in infptrace.c. */
-
-#define FETCH_INFERIOR_REGISTERS
-
-/* Override child_xfer_memory in infptrace.c. */
-
-#define CHILD_XFER_MEMORY
-
/* When a child process is just starting, we sneak in and relocate
the symbol table (and other stuff) after the dynamic linker has
figured out where they go. */
@@ -56,11 +48,6 @@ extern void xcoff_relocate_core (struct target_ops *);
#define PC_SOLIB(PC) xcoff_solib_address(PC)
extern char *xcoff_solib_address (CORE_ADDR);
-/* Return sizeof user struct to callers in less machine dependent routines */
-
-#define KERNEL_U_SIZE kernel_u_size()
-extern int kernel_u_size (void);
-
/* Flag for machine-specific stuff in shared files. FIXME */
#define DEPRECATED_IBM6000_TARGET
diff --git a/gdb/rs6000-nat.c b/gdb/rs6000-nat.c
index 46907ae..986f9a0 100644
--- a/gdb/rs6000-nat.c
+++ b/gdb/rs6000-nat.c
@@ -34,9 +34,11 @@
#include "gdb-stabs.h"
#include "regcache.h"
#include "arch-utils.h"
+#include "inf-ptrace.h"
#include "ppc-tdep.h"
#include "rs6000-tdep.h"
#include "exec.h"
+#include "gdb_stdint.h"
#include <sys/ptrace.h>
#include <sys/reg.h>
@@ -343,8 +345,8 @@ store_register (int regno)
/* Read from the inferior all registers if REGNO == -1 and just register
REGNO otherwise. */
-void
-fetch_inferior_registers (int regno)
+static void
+rs6000_fetch_inferior_registers (int regno)
{
if (regno != -1)
fetch_register (regno);
@@ -384,8 +386,8 @@ fetch_inferior_registers (int regno)
If REGNO is -1, do this for all registers.
Otherwise, REGNO specifies which register (so we can save time). */
-void
-store_inferior_registers (int regno)
+static void
+rs6000_store_inferior_registers (int regno)
{
if (regno != -1)
store_register (regno);
@@ -421,104 +423,107 @@ store_inferior_registers (int regno)
}
}
-/* Store in *TO the 32-bit word at 32-bit-aligned ADDR in the child
- process, which is 64-bit if ARCH64 and 32-bit otherwise. Return
- success. */
-static int
-read_word (CORE_ADDR from, int *to, int arch64)
-{
- /* Retrieved values may be -1, so infer errors from errno. */
- errno = 0;
+/* Attempt a transfer all LEN bytes starting at OFFSET between the
+ inferior's OBJECT:ANNEX space and GDB's READBUF/WRITEBUF buffer.
+ Return the number of bytes actually transferred. */
- if (arch64)
- *to = rs6000_ptrace64 (PT_READ_I, PIDGET (inferior_ptid), from, 0, NULL);
- else
- *to = rs6000_ptrace32 (PT_READ_I, PIDGET (inferior_ptid), (int *)(long) from,
- 0, NULL);
-
- return !errno;
-}
-
-/* Copy LEN bytes to or from inferior's memory starting at MEMADDR
- to debugger memory starting at MYADDR. Copy to inferior if
- WRITE is nonzero.
-
- Returns the length copied, which is either the LEN argument or
- zero. This xfer function does not do partial moves, since
- deprecated_child_ops doesn't allow memory operations to cross below
- us in the target stack anyway. */
-
-int
-child_xfer_memory (CORE_ADDR memaddr, gdb_byte *myaddr, int len,
- int write, struct mem_attrib *attrib,
- struct target_ops *target)
+static LONGEST
+rs6000_xfer_partial (struct target_ops *ops, enum target_object object,
+ const char *annex, gdb_byte *readbuf,
+ const gdb_byte *writebuf,
+ ULONGEST offset, LONGEST len)
{
- /* Round starting address down to 32-bit word boundary. */
- int mask = sizeof (int) - 1;
- CORE_ADDR addr = memaddr & ~(CORE_ADDR)mask;
-
- /* Round ending address up to 32-bit word boundary. */
- int count = ((memaddr + len - addr + mask) & ~(CORE_ADDR)mask)
- / sizeof (int);
-
- /* Allocate word transfer buffer. */
- /* FIXME (alloca): This code, cloned from infptrace.c, is unsafe
- because it uses alloca to allocate a buffer of arbitrary size.
- For very large xfers, this could crash GDB's stack. */
- int *buf = (int *) alloca (count * sizeof (int));
-
+ pid_t pid = ptid_get_pid (inferior_ptid);
int arch64 = ARCH64 ();
- int i;
- if (!write)
+ switch (object)
{
- /* Retrieve memory a word at a time. */
- for (i = 0; i < count; i++, addr += sizeof (int))
+ case TARGET_OBJECT_MEMORY:
+ {
+ union
{
- if (!read_word (addr, buf + i, arch64))
- return 0;
- QUIT;
- }
-
- /* Copy memory to supplied buffer. */
- addr -= count * sizeof (int);
- memcpy (myaddr, (char *)buf + (memaddr - addr), len);
- }
- else
- {
- /* Fetch leading memory needed for alignment. */
- if (addr < memaddr)
- if (!read_word (addr, buf, arch64))
- return 0;
-
- /* Fetch trailing memory needed for alignment. */
- if (addr + count * sizeof (int) > memaddr + len)
- if (!read_word (addr + (count - 1) * sizeof (int),
- buf + count - 1, arch64))
- return 0;
-
- /* Copy supplied data into memory buffer. */
- memcpy ((char *)buf + (memaddr - addr), myaddr, len);
-
- /* Store memory one word at a time. */
- for (i = 0, errno = 0; i < count; i++, addr += sizeof (int))
- {
- if (arch64)
- rs6000_ptrace64 (PT_WRITE_D, PIDGET (inferior_ptid), addr, buf[i], NULL);
- else
- rs6000_ptrace32 (PT_WRITE_D, PIDGET (inferior_ptid), (int *)(long) addr,
- buf[i], NULL);
-
- if (errno)
- return 0;
- QUIT;
- }
+ PTRACE_TYPE_RET word;
+ gdb_byte byte[sizeof (PTRACE_TYPE_RET)];
+ } buffer;
+ ULONGEST rounded_offset;
+ LONGEST partial_len;
+
+ /* Round the start offset down to the next long word
+ boundary. */
+ rounded_offset = offset & -(ULONGEST) sizeof (PTRACE_TYPE_RET);
+
+ /* Since ptrace will transfer a single word starting at that
+ rounded_offset the partial_len needs to be adjusted down to
+ that (remember this function only does a single transfer).
+ Should the required length be even less, adjust it down
+ again. */
+ partial_len = (rounded_offset + sizeof (PTRACE_TYPE_RET)) - offset;
+ if (partial_len > len)
+ partial_len = len;
+
+ if (writebuf)
+ {
+ /* If OFFSET:PARTIAL_LEN is smaller than
+ ROUNDED_OFFSET:WORDSIZE then a read/modify write will
+ be needed. Read in the entire word. */
+ if (rounded_offset < offset
+ || (offset + partial_len
+ < rounded_offset + sizeof (PTRACE_TYPE_RET)))
+ {
+ /* Need part of initial word -- fetch it. */
+ if (arch64)
+ buffer.word = rs6000_ptrace64 (PT_READ_I, pid,
+ rounded_offset, 0, NULL);
+ else
+ buffer.word = rs6000_ptrace32 (PT_READ_I, pid,
+ (int *)(uintptr_t)rounded_offset,
+ 0, NULL);
+ }
+
+ /* Copy data to be written over corresponding part of
+ buffer. */
+ memcpy (buffer.byte + (offset - rounded_offset),
+ writebuf, partial_len);
+
+ errno = 0;
+ if (arch64)
+ rs6000_ptrace64 (PT_WRITE_D, pid,
+ rounded_offset, buffer.word, NULL);
+ else
+ rs6000_ptrace32 (PT_WRITE_D, pid,
+ (int *)(uintptr_t)rounded_offset, buffer.word, NULL);
+ if (errno)
+ return 0;
+ }
+
+ if (readbuf)
+ {
+ errno = 0;
+ if (arch64)
+ buffer.word = rs6000_ptrace64 (PT_READ_I, pid,
+ rounded_offset, 0, NULL);
+ else
+ buffer.word = rs6000_ptrace32 (PT_READ_I, pid,
+ (int *)(uintptr_t)rounded_offset,
+ 0, NULL);
+ if (errno)
+ return 0;
+
+ /* Copy appropriate bytes out of the buffer. */
+ memcpy (readbuf, buffer.byte + (offset - rounded_offset),
+ partial_len);
+ }
+
+ return partial_len;
+ }
+
+ default:
+ return -1;
}
-
- return len;
}
+
/* Execute one dummy breakpoint instruction. This way we give the kernel
a chance to do some housekeeping and update inferior's internal data,
including u_area. */
@@ -1200,12 +1205,6 @@ xcoff_relocate_core (struct target_ops *target)
breakpoint_re_set ();
do_cleanups (old);
}
-
-int
-kernel_u_size (void)
-{
- return (sizeof (struct user));
-}
/* Under AIX, we have to pass the correct TOC pointer to a function
when calling functions in the inferior.
@@ -1245,6 +1244,14 @@ static struct core_fns rs6000_core_fns =
void
_initialize_core_rs6000 (void)
{
+ struct target_ops *t;
+
+ t = inf_ptrace_target ();
+ t->to_fetch_registers = rs6000_fetch_inferior_registers;
+ t->to_store_registers = rs6000_store_inferior_registers;
+ t->to_xfer_partial = rs6000_xfer_partial;
+ add_target (t);
+
/* Initialize hook in rs6000-tdep.c for determining the TOC address
when calling functions in the inferior. */
rs6000_find_toc_address_hook = find_toc_address;