* 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.
This commit is contained in:
Ulrich Weigand 2007-04-27 13:22:18 +00:00
parent f7dd0ed7de
commit 037a727e3d
6 changed files with 144 additions and 126 deletions

View File

@ -1,3 +1,25 @@
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".

View File

@ -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) \

View File

@ -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. */
/* 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 int
aix_thread_xfer_memory (CORE_ADDR memaddr, gdb_byte *myaddr, int len, int write,
struct mem_attrib *attrib,
struct target_ops *target)
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;

View File

@ -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.

View File

@ -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

View File

@ -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)
/* 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
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)
{
/* Retrieved values may be -1, so infer errors from errno. */
errno = 0;
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)
{
/* 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;
}
PTRACE_TYPE_RET word;
gdb_byte byte[sizeof (PTRACE_TYPE_RET)];
} buffer;
ULONGEST rounded_offset;
LONGEST partial_len;
/* Copy memory to supplied buffer. */
addr -= count * sizeof (int);
memcpy (myaddr, (char *)buf + (memaddr - addr), 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;
}
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;
}
}
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;