* i386-linux-nat.c (ORIG_EAX): Define to -1 if not already

defined.
(regmap): Extend to cover all registers.
(PT_READ_U, PT_WRITE_U, PTRACE_XFER_TYPE,
OLD_CANNOT_FETCH_REGISTERS, OLD_CANNOT_STORE_REGISTERS): Remove
definitions.
(fetch_register, sore_register): Simplify.
(old_fetch_inferior_registers, old_store_inferior_registers):
Remove functions.
(cannot_fetch_register, cannot_store_register): Change
implementation to use regmap array to decide which registers
cannot be fetched/stored.  This removes $orig_eax from the
registers that cannot be fetched/stored.
(fetch_inferior_registers): Call fetch_register directly instead
of calling old_fetch_inferior_registers.
(store_inferior_registers): Call store_register directly instead
of calling old_store_inferior_registers.
(i386_linux_dr_get): Replace PT_READ_U with PTRACE_PEEKUSER.
(i386_linux_dr_set): Replace PT_WRITE_U with PTRACE_POKEUSER.
* config/i386/nm-linux.h (U_REGS_OFFSET): Remove definition.
This commit is contained in:
Mark Kettenis 2002-11-09 21:31:12 +00:00
parent 932bb5249e
commit ce556f8539
3 changed files with 84 additions and 140 deletions

View File

@ -1,3 +1,26 @@
2002-11-09 Mark Kettenis <kettenis@gnu.org>
* i386-linux-nat.c (ORIG_EAX): Define to -1 if not already
defined.
(regmap): Extend to cover all registers.
(PT_READ_U, PT_WRITE_U, PTRACE_XFER_TYPE,
OLD_CANNOT_FETCH_REGISTERS, OLD_CANNOT_STORE_REGISTERS): Remove
definitions.
(fetch_register, sore_register): Simplify.
(old_fetch_inferior_registers, old_store_inferior_registers):
Remove functions.
(cannot_fetch_register, cannot_store_register): Change
implementation to use regmap array to decide which registers
cannot be fetched/stored. This removes $orig_eax from the
registers that cannot be fetched/stored.
(fetch_inferior_registers): Call fetch_register directly instead
of calling old_fetch_inferior_registers.
(store_inferior_registers): Call store_register directly instead
of calling old_store_inferior_registers.
(i386_linux_dr_get): Replace PT_READ_U with PTRACE_PEEKUSER.
(i386_linux_dr_set): Replace PT_WRITE_U with PTRACE_POKEUSER.
* config/i386/nm-linux.h (U_REGS_OFFSET): Remove definition.
2002-11-09 Klee Dienes <kdienes@apple.com>
* i387-tdep.c (i387_supply_register): When called with NULL as a

View File

@ -39,9 +39,6 @@ extern int kernel_u_size (void);
the core file of the register values. */
#define KERNEL_U_ADDR 0
/* Offset of the registers within the user area. */
#define U_REGS_OFFSET 0
extern CORE_ADDR register_u_addr (CORE_ADDR blockend, int regnum);
#define REGISTER_U_ADDR(addr, blockend, regnum) \
(addr) = register_u_addr (blockend, regnum)

View File

@ -34,6 +34,10 @@
#include <sys/reg.h>
#endif
#ifndef ORIG_EAX
#define ORIG_EAX -1
#endif
#ifdef HAVE_SYS_DEBUGREG_H
#include <sys/debugreg.h>
#endif
@ -90,7 +94,15 @@ static int regmap[] =
EAX, ECX, EDX, EBX,
UESP, EBP, ESI, EDI,
EIP, EFL, CS, SS,
DS, ES, FS, GS
DS, ES, FS, GS,
-1, -1, -1, -1, /* st0, st1, st2, st3 */
-1, -1, -1, -1, /* st4, st5, st6, st7 */
-1, -1, -1, -1, /* fctrl, fstat, ftag, fiseg */
-1, -1, -1, -1, /* fioff, foseg, fooff, fop */
-1, -1, -1, -1, /* xmm0, xmm1, xmm2, xmm3 */
-1, -1, -1, -1, /* xmm4, xmm5, xmm6, xmm6 */
-1, /* mxcsr */
ORIG_EAX
};
/* Which ptrace request retrieves which registers?
@ -148,155 +160,58 @@ kernel_u_size (void)
}
/* Fetching registers directly from the U area, one at a time. */
/* FIXME: kettenis/2000-03-05: This duplicates code from `inptrace.c'.
The problem is that we define FETCH_INFERIOR_REGISTERS since we
want to use our own versions of {fetch,store}_inferior_registers
that use the GETREGS request. This means that the code in
`infptrace.c' is #ifdef'd out. But we need to fall back on that
code when GDB is running on top of a kernel that doesn't support
the GETREGS request. I want to avoid changing `infptrace.c' right
now. */
#ifndef PT_READ_U
#define PT_READ_U PTRACE_PEEKUSR
#endif
#ifndef PT_WRITE_U
#define PT_WRITE_U PTRACE_POKEUSR
#endif
/* Default the type of the ptrace transfer to int. */
#ifndef PTRACE_XFER_TYPE
#define PTRACE_XFER_TYPE int
#endif
/* Registers we shouldn't try to fetch. */
#define OLD_CANNOT_FETCH_REGISTER(regno) ((regno) >= I386_NUM_GREGS)
/* Accessing registers through the U area, one at a time. */
/* Fetch one register. */
static void
fetch_register (int regno)
{
/* This isn't really an address. But ptrace thinks of it as one. */
CORE_ADDR regaddr;
char mess[128]; /* For messages */
register int i;
unsigned int offset; /* Offset of registers within the u area. */
char buf[MAX_REGISTER_RAW_SIZE];
int tid;
int val;
if (OLD_CANNOT_FETCH_REGISTER (regno))
gdb_assert (!have_ptrace_getregs);
if (cannot_fetch_register (regno))
{
memset (buf, '\0', REGISTER_RAW_SIZE (regno)); /* Supply zeroes */
supply_register (regno, buf);
supply_register (regno, NULL);
return;
}
/* Overload thread id onto process id */
/* GNU/Linux LWP ID's are process ID's. */
if ((tid = TIDGET (inferior_ptid)) == 0)
tid = PIDGET (inferior_ptid); /* no thread id, just use process id */
tid = PIDGET (inferior_ptid); /* Not a threaded program. */
offset = U_REGS_OFFSET;
errno = 0;
val = ptrace (PTRACE_PEEKUSER, tid, register_addr (regno, 0), 0);
if (errno != 0)
error ("Couldn't read register %s (#%d): %s.", REGISTER_NAME (regno),
regno, safe_strerror (errno));
regaddr = register_addr (regno, offset);
for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof (PTRACE_XFER_TYPE))
{
errno = 0;
*(PTRACE_XFER_TYPE *) & buf[i] = ptrace (PT_READ_U, tid,
(PTRACE_ARG3_TYPE) regaddr, 0);
regaddr += sizeof (PTRACE_XFER_TYPE);
if (errno != 0)
{
sprintf (mess, "reading register %s (#%d)",
REGISTER_NAME (regno), regno);
perror_with_name (mess);
}
}
supply_register (regno, buf);
supply_register (regno, &val);
}
/* Fetch register values from the inferior.
If REGNO is negative, do this for all registers.
Otherwise, REGNO specifies which register (so we can save time). */
void
old_fetch_inferior_registers (int regno)
{
if (regno >= 0)
{
fetch_register (regno);
}
else
{
for (regno = 0; regno < NUM_REGS; regno++)
{
fetch_register (regno);
}
}
}
/* Registers we shouldn't try to store. */
#define OLD_CANNOT_STORE_REGISTER(regno) ((regno) >= I386_NUM_GREGS)
/* Store one register. */
static void
store_register (int regno)
{
/* This isn't really an address. But ptrace thinks of it as one. */
CORE_ADDR regaddr;
char mess[128]; /* For messages */
register int i;
unsigned int offset; /* Offset of registers within the u area. */
int tid;
int val;
if (OLD_CANNOT_STORE_REGISTER (regno))
{
return;
}
gdb_assert (!have_ptrace_getregs);
if (cannot_store_register (regno))
return;
/* Overload thread id onto process id */
/* GNU/Linux LWP ID's are process ID's. */
if ((tid = TIDGET (inferior_ptid)) == 0)
tid = PIDGET (inferior_ptid); /* no thread id, just use process id */
tid = PIDGET (inferior_ptid); /* Not a threaded program. */
offset = U_REGS_OFFSET;
regaddr = register_addr (regno, offset);
for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof (PTRACE_XFER_TYPE))
{
errno = 0;
ptrace (PT_WRITE_U, tid, (PTRACE_ARG3_TYPE) regaddr,
*(PTRACE_XFER_TYPE *) & registers[REGISTER_BYTE (regno) + i]);
regaddr += sizeof (PTRACE_XFER_TYPE);
if (errno != 0)
{
sprintf (mess, "writing register %s (#%d)",
REGISTER_NAME (regno), regno);
perror_with_name (mess);
}
}
}
/* Store our register values back into the inferior.
If REGNO is negative, do this for all registers.
Otherwise, REGNO specifies which register (so we can save time). */
void
old_store_inferior_registers (int regno)
{
if (regno >= 0)
{
store_register (regno);
}
else
{
for (regno = 0; regno < NUM_REGS; regno++)
{
store_register (regno);
}
}
errno = 0;
regcache_collect (regno, &val);
ptrace (PTRACE_POKEUSER, tid, register_addr (regno, 0), val);
if (errno != 0)
error ("Couldn't read register %s (#%d): %s.", REGISTER_NAME (regno),
regno, safe_strerror (errno));
}
@ -573,16 +488,15 @@ static void dummy_sse_values (void) {}
int
cannot_fetch_register (int regno)
{
if (! have_ptrace_getregs)
return OLD_CANNOT_FETCH_REGISTER (regno);
return 0;
gdb_assert (regno >= 0 && regno < NUM_REGS);
return (!have_ptrace_getregs && regmap[regno] == -1);
}
int
cannot_store_register (int regno)
{
if (! have_ptrace_getregs)
return OLD_CANNOT_STORE_REGISTER (regno);
return 0;
gdb_assert (regno >= 0 && regno < NUM_REGS);
return (!have_ptrace_getregs && regmap[regno] == -1);
}
/* Fetch register REGNO from the child process. If REGNO is -1, do
@ -596,9 +510,14 @@ fetch_inferior_registers (int regno)
/* Use the old method of peeking around in `struct user' if the
GETREGS request isn't available. */
if (! have_ptrace_getregs)
if (!have_ptrace_getregs)
{
old_fetch_inferior_registers (regno);
int i;
for (i = 0; i < NUM_REGS; i++)
if (regno == -1 || regno == i)
fetch_register (i);
return;
}
@ -615,9 +534,9 @@ fetch_inferior_registers (int regno)
fetch_regs (tid);
/* The call above might reset `have_ptrace_getregs'. */
if (! have_ptrace_getregs)
if (!have_ptrace_getregs)
{
old_fetch_inferior_registers (-1);
fetch_inferior_registers (regno);
return;
}
@ -662,9 +581,14 @@ store_inferior_registers (int regno)
/* Use the old method of poking around in `struct user' if the
SETREGS request isn't available. */
if (! have_ptrace_getregs)
if (!have_ptrace_getregs)
{
old_store_inferior_registers (regno);
int i;
for (i = 0; i < NUM_REGS; i++)
if (regno == -1 || regno == i)
store_register (i);
return;
}
@ -724,7 +648,7 @@ i386_linux_dr_get (int regnum)
stuff to the target vectore. For now, just return zero if the
ptrace call fails. */
errno = 0;
value = ptrace (PT_READ_U, tid,
value = ptrace (PTRACE_PEEKUSER, tid,
offsetof (struct user, u_debugreg[regnum]), 0);
if (errno != 0)
#if 0
@ -747,7 +671,7 @@ i386_linux_dr_set (int regnum, unsigned long value)
tid = PIDGET (inferior_ptid);
errno = 0;
ptrace (PT_WRITE_U, tid,
ptrace (PTRACE_POKEUSER, tid,
offsetof (struct user, u_debugreg[regnum]), value);
if (errno != 0)
perror_with_name ("Couldn't write debug register");