* 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:
parent
f7dd0ed7de
commit
037a727e3d
|
@ -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".
|
||||
|
|
|
@ -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) \
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
203
gdb/rs6000-nat.c
203
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)
|
||||
/* 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;
|
||||
|
|
Loading…
Reference in New Issue