summaryrefslogtreecommitdiff
path: root/gdb/i386-linux-nat.c
diff options
context:
space:
mode:
Diffstat (limited to 'gdb/i386-linux-nat.c')
-rw-r--r--gdb/i386-linux-nat.c193
1 files changed, 21 insertions, 172 deletions
diff --git a/gdb/i386-linux-nat.c b/gdb/i386-linux-nat.c
index 4549b37ad1d..8b1eebdc7e9 100644
--- a/gdb/i386-linux-nat.c
+++ b/gdb/i386-linux-nat.c
@@ -59,9 +59,6 @@
#define DR_CONTROL 7
#endif
-/* Prototypes for supply_gregset etc. */
-#include "gregset.h"
-
/* Prototypes for i387_supply_fsave etc. */
#include "i387-tdep.h"
@@ -73,41 +70,8 @@
/* Defines ps_err_e, struct ps_prochandle. */
#include "gdb_proc_service.h"
-
-/* Prototypes for local functions. */
-static void dummy_sse_values (void);
-/* The register sets used in GNU/Linux ELF core-dumps are identical to
- the register sets in `struct user' that is used for a.out
- core-dumps, and is also used by `ptrace'. The corresponding types
- are `elf_gregset_t' for the general-purpose registers (with
- `elf_greg_t' the type of a single GP register) and `elf_fpregset_t'
- for the floating-point registers.
-
- Those types used to be available under the names `gregset_t' and
- `fpregset_t' too, and this file used those names in the past. But
- those names are now used for the register sets used in the
- `mcontext_t' type, and have a different size and layout. */
-
-/* Mapping between the general-purpose registers in `struct user'
- format and GDB's register array layout. */
-static int regmap[] =
-{
- EAX, ECX, EDX, EBX,
- UESP, EBP, ESI, EDI,
- EIP, EFL, CS, SS,
- 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?
These apply to the corresponding SET requests as well. */
@@ -154,7 +118,9 @@ int have_ptrace_getfpxregs =
CORE_ADDR
register_u_addr (CORE_ADDR blockend, int regnum)
{
- return (blockend + 4 * regmap[regnum]);
+ long offset = i386_linux_greg_offset (regnum);
+ gdb_assert (offset >= 0);
+ return (blockend + offset);
}
/* Return the size of the user struct. */
@@ -232,14 +198,7 @@ store_register (int regno)
void
supply_gregset (elf_gregset_t *gregsetp)
{
- elf_greg_t *regp = (elf_greg_t *) gregsetp;
- int i;
-
- for (i = 0; i < I386_NUM_GREGS; i++)
- supply_register (i, regp + regmap[i]);
-
- if (I386_LINUX_ORIG_EAX_REGNUM < NUM_REGS)
- supply_register (I386_LINUX_ORIG_EAX_REGNUM, regp + ORIG_EAX);
+ i386_linux_supply_gregset (gregsetp);
}
/* Fill register REGNO (if it is a general-purpose register) in
@@ -249,16 +208,23 @@ supply_gregset (elf_gregset_t *gregsetp)
void
fill_gregset (elf_gregset_t *gregsetp, int regno)
{
- elf_greg_t *regp = (elf_greg_t *) gregsetp;
+ bfd_byte *regp = (bfd_byte *) gregsetp;
int i;
for (i = 0; i < I386_NUM_GREGS; i++)
if (regno == -1 || regno == i)
- regcache_collect (i, regp + regmap[i]);
+ {
+ long offset = i386_linux_greg_offset (i);
+ if (offset >= 0)
+ regcache_collect (i, regp + offset);
+ }
- if ((regno == -1 || regno == I386_LINUX_ORIG_EAX_REGNUM)
- && I386_LINUX_ORIG_EAX_REGNUM < NUM_REGS)
- regcache_collect (I386_LINUX_ORIG_EAX_REGNUM, regp + ORIG_EAX);
+ if (regno == -1 || regno == I386_LINUX_ORIG_EAX_REGNUM)
+ {
+ long offset = i386_linux_greg_offset (I386_LINUX_ORIG_EAX_REGNUM);
+ if (offset >= 0)
+ regcache_collect (I386_LINUX_ORIG_EAX_REGNUM, regp + offset);
+ }
}
#ifdef HAVE_PTRACE_GETREGS
@@ -320,8 +286,7 @@ static void store_regs (int tid, int regno) {}
void
supply_fpregset (elf_fpregset_t *fpregsetp)
{
- i387_supply_fsave ((char *) fpregsetp);
- dummy_sse_values ();
+ i386_linux_supply_fpregset (fpregsetp);
}
/* Fill register REGNO (if it is a floating-point register) in
@@ -385,7 +350,7 @@ static void store_fpregs (int tid, int regno) {}
void
supply_fpxregset (elf_fpxregset_t *fpxregsetp)
{
- i387_supply_fxsave ((char *) fpxregsetp);
+ i386_linux_supply_fpxregset (fpxregsetp);
}
/* Fill register REGNO (if it is a floating-point or SSE register) in
@@ -456,32 +421,10 @@ store_fpxregs (int tid, int regno)
return 1;
}
-/* Fill the XMM registers in the register array with dummy values. For
- cases where we don't have access to the XMM registers. I think
- this is cleaner than printing a warning. For a cleaner solution,
- we should gdbarchify the i386 family. */
-
-static void
-dummy_sse_values (void)
-{
- struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
- /* C doesn't have a syntax for NaN's, so write it out as an array of
- longs. */
- static long dummy[4] = { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff };
- static long mxcsr = 0x1f80;
- int reg;
-
- for (reg = 0; reg < tdep->num_xmm_regs; reg++)
- supply_register (XMM0_REGNUM + reg, (char *) dummy);
- if (tdep->num_xmm_regs > 0)
- supply_register (MXCSR_REGNUM, (char *) &mxcsr);
-}
-
#else
static int fetch_fpxregs (int tid) { return 0; }
static int store_fpxregs (int tid, int regno) { return 0; }
-static void dummy_sse_values (void) {}
#endif /* HAVE_PTRACE_GETFPXREGS */
@@ -497,14 +440,14 @@ int
cannot_fetch_register (int regno)
{
gdb_assert (regno >= 0 && regno < NUM_REGS);
- return (!have_ptrace_getregs && regmap[regno] == -1);
+ return (!have_ptrace_getregs
+ && i386_linux_greg_offset (regno) < 0);
}
int
cannot_store_register (int regno)
{
- gdb_assert (regno >= 0 && regno < NUM_REGS);
- return (!have_ptrace_getregs && regmap[regno] == -1);
+ return cannot_fetch_register (regno);
}
/* Fetch register REGNO from the child process. If REGNO is -1, do
@@ -729,81 +672,6 @@ i386_linux_dr_get_status (void)
{
return i386_linux_dr_get (DR_STATUS);
}
-
-
-/* Interpreting register set info found in core files. */
-
-/* Provide registers to GDB from a core file.
-
- (We can't use the generic version of this function in
- core-regset.c, because GNU/Linux has *three* different kinds of
- register set notes. core-regset.c would have to call
- supply_fpxregset, which most platforms don't have.)
-
- CORE_REG_SECT points to an array of bytes, which are the contents
- of a `note' from a core file which BFD thinks might contain
- register contents. CORE_REG_SIZE is its size.
-
- WHICH says which register set corelow suspects this is:
- 0 --- the general-purpose register set, in elf_gregset_t format
- 2 --- the floating-point register set, in elf_fpregset_t format
- 3 --- the extended floating-point register set, in elf_fpxregset_t format
-
- REG_ADDR isn't used on GNU/Linux. */
-
-static void
-fetch_core_registers (char *core_reg_sect, unsigned core_reg_size,
- int which, CORE_ADDR reg_addr)
-{
- elf_gregset_t gregset;
- elf_fpregset_t fpregset;
-
- switch (which)
- {
- case 0:
- if (core_reg_size != sizeof (gregset))
- warning ("Wrong size gregset in core file.");
- else
- {
- memcpy (&gregset, core_reg_sect, sizeof (gregset));
- supply_gregset (&gregset);
- }
- break;
-
- case 2:
- if (core_reg_size != sizeof (fpregset))
- warning ("Wrong size fpregset in core file.");
- else
- {
- memcpy (&fpregset, core_reg_sect, sizeof (fpregset));
- supply_fpregset (&fpregset);
- }
- break;
-
-#ifdef HAVE_PTRACE_GETFPXREGS
- {
- elf_fpxregset_t fpxregset;
-
- case 3:
- if (core_reg_size != sizeof (fpxregset))
- warning ("Wrong size fpxregset in core file.");
- else
- {
- memcpy (&fpxregset, core_reg_sect, sizeof (fpxregset));
- supply_fpxregset (&fpxregset);
- }
- break;
- }
-#endif
-
- default:
- /* We've covered all the kinds of registers we know about here,
- so this must be something we wouldn't know what to do with
- anyway. Just ignore it. */
- break;
- }
-}
-
/* The instruction for a GNU/Linux system call is:
int $0x80
@@ -898,22 +766,3 @@ child_post_startup_inferior (ptid_t ptid)
i386_cleanup_dregs ();
linux_child_post_startup_inferior (ptid);
}
-
-
-/* Register that we are able to handle GNU/Linux ELF core file
- formats. */
-
-static struct core_fns linux_elf_core_fns =
-{
- bfd_target_elf_flavour, /* core_flavour */
- default_check_format, /* check_format */
- default_core_sniffer, /* core_sniffer */
- fetch_core_registers, /* core_read_registers */
- NULL /* next */
-};
-
-void
-_initialize_i386_linux_nat (void)
-{
- add_core_fns (&linux_elf_core_fns);
-}