* 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:
parent
5885ab493f
commit
652fc1376f
|
@ -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.
|
||||||
|
|
|
@ -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) \
|
||||||
|
|
167
gdb/infptrace.c
167
gdb/infptrace.c
|
@ -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, regnum, buf);
|
||||||
regcache_raw_supply (current_regcache, regno, 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)
|
||||||
{
|
{
|
||||||
/* 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. */
|
|
||||||
int tid;
|
|
||||||
char buf[MAX_REGISTER_SIZE];
|
|
||||||
|
|
||||||
if (CANNOT_STORE_REGISTER (regno))
|
if (CANNOT_STORE_REGISTER (regnum))
|
||||||
{
|
|
||||||
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);
|
||||||
|
buf = alloca (size);
|
||||||
|
|
||||||
/* Put the contents of regno into a local buffer */
|
/* Write the register contents into the inferior a chunk at the time. */
|
||||||
regcache_raw_collect (current_regcache, regno, buf);
|
regcache_raw_collect (current_regcache, regnum, buf);
|
||||||
|
for (i = 0; i < size / sizeof (PTRACE_TYPE_RET); i++)
|
||||||
/* 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. */
|
||||||
|
|
Loading…
Reference in New Issue