diff options
-rw-r--r-- | gdb/ChangeLog | 22 | ||||
-rw-r--r-- | gdb/Makefile.in | 3 | ||||
-rw-r--r-- | gdb/aix-thread.c | 29 | ||||
-rw-r--r-- | gdb/config/powerpc/aix.mh | 2 | ||||
-rw-r--r-- | gdb/config/rs6000/nm-rs6000.h | 13 | ||||
-rw-r--r-- | gdb/rs6000-nat.c | 203 |
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; |