* infptrace.c: Include "gdb_assert.h".

(PTRACE_XFER_TYPE): Remove define.
(offsetof): Only define if U_REGS_OFFSET isn't defined.
(fetch_register, store_register): Rewrite to use PTRACE_TYPE_RET.
Tweak comment.
(fetch_inferior_registers, store_inferior_registers): Remove
redundant culry braces.  Tweak comment.  s/regno/regnum.
* Makefile.in (infptrace.o): Update dependencies.
This commit is contained in:
Mark Kettenis 2004-08-22 15:35:02 +00:00
parent 5885ab493f
commit 652fc1376f
3 changed files with 87 additions and 98 deletions

View File

@ -1,5 +1,14 @@
2004-08-22 Mark Kettenis <kettenis@gnu.org> 2004-08-22 Mark Kettenis <kettenis@gnu.org>
* infptrace.c: Include "gdb_assert.h".
(PTRACE_XFER_TYPE): Remove define.
(offsetof): Only define if U_REGS_OFFSET isn't defined.
(fetch_register, store_register): Rewrite to use PTRACE_TYPE_RET.
Tweak comment.
(fetch_inferior_registers, store_inferior_registers): Remove
redundant culry braces. Tweak comment. s/regno/regnum.
* Makefile.in (infptrace.o): Update dependencies.
* configure.in: Change test for return type of ptrace to default * configure.in: Change test for return type of ptrace to default
to `long' instead of `int'. to `long' instead of `int'.
* configure: Regenerate. * configure: Regenerate.

View File

@ -2051,7 +2051,8 @@ inflow.o: inflow.c $(defs_h) $(frame_h) $(inferior_h) $(command_h) \
$(inflow_h) $(inflow_h)
infptrace.o: infptrace.c $(defs_h) $(frame_h) $(inferior_h) $(target_h) \ infptrace.o: infptrace.c $(defs_h) $(frame_h) $(inferior_h) $(target_h) \
$(gdb_string_h) $(regcache_h) $(gdb_wait_h) $(command_h) \ $(gdb_string_h) $(regcache_h) $(gdb_wait_h) $(command_h) \
$(gdb_dirent_h) $(gdb_ptrace_h) $(gdbcore_h) $(gdb_stat_h) $(gdb_dirent_h) $(gdb_ptrace_h) $(gdbcore_h) $(gdb_stat_h) \
$(gdb_assert_h)
infrun.o: infrun.c $(defs_h) $(gdb_string_h) $(symtab_h) $(frame_h) \ infrun.o: infrun.c $(defs_h) $(gdb_string_h) $(symtab_h) $(frame_h) \
$(inferior_h) $(breakpoint_h) $(gdb_wait_h) $(gdbcore_h) $(gdbcmd_h) \ $(inferior_h) $(breakpoint_h) $(gdb_wait_h) $(gdbcore_h) $(gdbcmd_h) \
$(cli_script_h) $(target_h) $(gdbthread_h) $(annotate_h) \ $(cli_script_h) $(target_h) $(gdbthread_h) $(annotate_h) \

View File

@ -53,6 +53,8 @@
#include "gdb_stat.h" #include "gdb_stat.h"
#endif #endif
#include "gdb_assert.h"
#if !defined (FETCH_INFERIOR_REGISTERS) #if !defined (FETCH_INFERIOR_REGISTERS)
#include <sys/user.h> /* Probably need to poke the user structure */ #include <sys/user.h> /* Probably need to poke the user structure */
#endif /* !FETCH_INFERIOR_REGISTERS */ #endif /* !FETCH_INFERIOR_REGISTERS */
@ -269,153 +271,130 @@ detach (int signal)
#endif #endif
} }
/* Default the type of the ptrace transfer to int. */
#ifndef PTRACE_XFER_TYPE
#define PTRACE_XFER_TYPE int
#endif
#if !defined (FETCH_INFERIOR_REGISTERS) #ifndef FETCH_INFERIOR_REGISTERS
#if !defined (offsetof) /* U_REGS_OFFSET is the offset of the registers within the u area. */
#ifndef U_REGS_OFFSET
#ifndef offsetof
#define offsetof(TYPE, MEMBER) ((unsigned long) &((TYPE *)0)->MEMBER) #define offsetof(TYPE, MEMBER) ((unsigned long) &((TYPE *)0)->MEMBER)
#endif #endif
/* U_REGS_OFFSET is the offset of the registers within the u area. */
#if !defined (U_REGS_OFFSET)
#define U_REGS_OFFSET \ #define U_REGS_OFFSET \
ptrace (PT_READ_U, PIDGET (inferior_ptid), \ ptrace (PT_READ_U, PIDGET (inferior_ptid), \
(PTRACE_TYPE_ARG3) (offsetof (struct user, u_ar0)), 0) \ (PTRACE_TYPE_ARG3) (offsetof (struct user, u_ar0)), 0) \
- KERNEL_U_ADDR - KERNEL_U_ADDR
#endif #endif
/* Fetch one register. */ /* Fetch register REGNUM from the inferior. */
static void static void
fetch_register (int regno) fetch_register (int regnum)
{ {
/* This isn't really an address. But ptrace thinks of it as one. */ CORE_ADDR addr;
CORE_ADDR regaddr; size_t size;
char mess[128]; /* For messages */ PTRACE_TYPE_RET *buf;
int i; int tid, i;
unsigned int offset; /* Offset of registers within the u area. */
char buf[MAX_REGISTER_SIZE];
int tid;
if (CANNOT_FETCH_REGISTER (regno)) if (CANNOT_FETCH_REGISTER (regnum))
{ {
regcache_raw_supply (current_regcache, regno, NULL); regcache_raw_supply (current_regcache, regnum, NULL);
return; return;
} }
/* Overload thread id onto process id */ /* GNU/Linux LWP ID's are process ID's. */
if ((tid = TIDGET (inferior_ptid)) == 0) tid = TIDGET (inferior_ptid);
tid = PIDGET (inferior_ptid); /* no thread id, just use process id */ if (tid == 0)
tid = PIDGET (inferior_ptid); /* Not a threaded program. */
offset = U_REGS_OFFSET; /* This isn't really an address. But ptrace thinks of it as one. */
addr = register_addr (regnum, U_REGS_OFFSET);
size = register_size (current_gdbarch, regnum);
regaddr = register_addr (regno, offset); gdb_assert ((size % sizeof (PTRACE_TYPE_RET)) == 0);
for (i = 0; i < register_size (current_gdbarch, regno); i += sizeof (PTRACE_XFER_TYPE)) 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; errno = 0;
*(PTRACE_XFER_TYPE *) & buf[i] = ptrace (PT_READ_U, tid, buf[i] = ptrace (PT_READ_U, tid, (PTRACE_TYPE_ARG3) addr, 0);
(PTRACE_TYPE_ARG3) regaddr, 0);
regaddr += sizeof (PTRACE_XFER_TYPE);
if (errno != 0) if (errno != 0)
{ error ("Couldn't read register %s (#%d): %s.", REGISTER_NAME (regnum),
sprintf (mess, "reading register %s (#%d)", regnum, safe_strerror (errno));
REGISTER_NAME (regno), regno);
perror_with_name (mess); addr += sizeof (PTRACE_TYPE_RET);
}
} }
regcache_raw_supply (current_regcache, regno, buf); regcache_raw_supply (current_regcache, regnum, buf);
} }
/* Fetch register REGNUM from the inferior. If REGNUM is -1, do this
/* Fetch register values from the inferior. for all registers. */
If REGNO is negative, do this for all registers.
Otherwise, REGNO specifies which register (so we can save time). */
void void
fetch_inferior_registers (int regno) fetch_inferior_registers (int regnum)
{ {
if (regno >= 0) if (regnum == -1)
{ for (regnum = 0; regnum < NUM_REGS; regnum++)
fetch_register (regno); fetch_register (regnum);
}
else else
{ fetch_register (regnum);
for (regno = 0; regno < NUM_REGS; regno++)
{
fetch_register (regno);
}
}
} }
/* Store one register. */ /* Store register REGNUM into the inferior. */
static void static void
store_register (int regno) store_register (int regnum)
{ {
CORE_ADDR addr;
size_t size;
PTRACE_TYPE_RET *buf;
int tid, i;
if (CANNOT_STORE_REGISTER (regnum))
return;
/* GNU/Linux LWP ID's are process ID's. */
tid = TIDGET (inferior_ptid);
if (tid == 0)
tid = PIDGET (inferior_ptid); /* Not a threaded program. */
/* This isn't really an address. But ptrace thinks of it as one. */ /* This isn't really an address. But ptrace thinks of it as one. */
CORE_ADDR regaddr; addr = register_addr (regnum, U_REGS_OFFSET);
char mess[128]; /* For messages */ size = register_size (current_gdbarch, regnum);
int i;
unsigned int offset; /* Offset of registers within the u area. */
int tid;
char buf[MAX_REGISTER_SIZE];
if (CANNOT_STORE_REGISTER (regno)) gdb_assert ((size % sizeof (PTRACE_TYPE_RET)) == 0);
{ buf = alloca (size);
return;
}
/* Overload thread id onto process id */ /* Write the register contents into the inferior a chunk at the time. */
if ((tid = TIDGET (inferior_ptid)) == 0) regcache_raw_collect (current_regcache, regnum, buf);
tid = PIDGET (inferior_ptid); /* no thread id, just use process id */ for (i = 0; i < size / sizeof (PTRACE_TYPE_RET); i++)
offset = U_REGS_OFFSET;
regaddr = register_addr (regno, offset);
/* Put the contents of regno into a local buffer */
regcache_raw_collect (current_regcache, regno, buf);
/* Store the local buffer into the inferior a chunk at the time. */
for (i = 0; i < register_size (current_gdbarch, regno); i += sizeof (PTRACE_XFER_TYPE))
{ {
errno = 0; errno = 0;
ptrace (PT_WRITE_U, tid, (PTRACE_TYPE_ARG3) regaddr, ptrace (PT_WRITE_U, tid, (PTRACE_TYPE_ARG3) addr, buf[i]);
*(PTRACE_XFER_TYPE *) (buf + i));
regaddr += sizeof (PTRACE_XFER_TYPE);
if (errno != 0) if (errno != 0)
{ error ("Couldn't write register %s (#%d): %s.", REGISTER_NAME (regnum),
sprintf (mess, "writing register %s (#%d)", regnum, safe_strerror (errno));
REGISTER_NAME (regno), regno);
perror_with_name (mess); addr += sizeof (PTRACE_TYPE_RET);
}
} }
} }
/* Store our register values back into the inferior. /* Store register REGNUM back into the inferior. If REGNUM is -1, do
If REGNO is negative, do this for all registers. this for all registers (including the floating point registers). */
Otherwise, REGNO specifies which register (so we can save time). */
void void
store_inferior_registers (int regno) store_inferior_registers (int regnum)
{ {
if (regno >= 0) if (regnum == -1)
{ for (regnum = 0; regnum < NUM_REGS; regnum++)
store_register (regno); store_register (regnum);
}
else else
{ store_register (regnum);
for (regno = 0; regno < NUM_REGS; regno++)
{
store_register (regno);
}
}
} }
#endif /* !defined (FETCH_INFERIOR_REGISTERS). */
#endif /* not FETCH_INFERIOR_REGISTERS. */
/* Set an upper limit on alloca. */ /* Set an upper limit on alloca. */