summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Cagney <cagney@redhat.com>2003-08-21 20:16:49 +0000
committerAndrew Cagney <cagney@redhat.com>2003-08-21 20:16:49 +0000
commit5e1c865bc487deb2936aa144d2fe88445ea90558 (patch)
treeb3fab7da8b763cbe9c539247c7c3b1735c37947b
parent8c04ad1437f5c354d3d55e4e2c6b880ecd287140 (diff)
downloadbinutils-gdb-5e1c865bc487deb2936aa144d2fe88445ea90558.tar.gz
2003-08-21 Andrew Cagney <cagney@redhat.com>
* i386-tdep.h (i386_regnums): Replace I386_EAX_REGNUM, I386_EDX_REGNUM, I386_ESP_REGNUM, I386_EBP_REGNUM, I386_EIP_REGNUM, I386_EFLAGS_REGNUM, I386_ST0_REGNUM. * i386-linux-tdep.h (i386_linux_greg_offset): Declare. (i386_linux_supply_fpxregset): Declare. (i386_linux_supply_fpregset): Declare. (i386_linux_supply_gregset): Declare. * i386-linux-tdep.c: Include "gdb_assert.h", and "i387-tdep.h". Do not include "gregset.h". (enum user_regs): Define. (struct regnum_map, struct regnum_to_user): Define. (i386_linux_greg_offset): New function. (dummy_sse_values): New function, copied from "i386-linux-nat.c" make hist independant. (i386_linux_supply_fpregset): New function. (i386_linux_supply_gregset): New function. (i386_linux_supply_fpxregset): New function. (fetch_core_registers): New function. (i386_linux_core_sniffer): New function. (i386_linux_core_fns): New table. (_initialize_i386_linux_tdep): Add i386_linux_core_fns to core functions. * i386-linux-nat.c: Do not include "gregset.h". (dummy_sse_values) Delete function. (regmap): Delete array. (register_u_addr, fill_gregset, cannot_fetch_register): Use i386_linux_greg_offset. (cannot_store_register): Call cannot_fetch_register. (supply_gregset): Call i386_linux_supply_gregset. (supply_fpregset): Call i386_linux_supply_fpregset. (supply_fpxregset): Call i386_linux_supply_fpxregset. (fetch_core_registers): Delete function. (linux_elf_core_fns): Delete table. (_initialize_i386_linux_nat): Delete function.
-rw-r--r--gdb/ChangeLog37
-rw-r--r--gdb/i386-linux-nat.c193
-rw-r--r--gdb/i386-linux-tdep.c264
-rw-r--r--gdb/i386-linux-tdep.h11
-rw-r--r--gdb/i386-tdep.h56
5 files changed, 380 insertions, 181 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index eedfad0c56e..2939178459c 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,40 @@
+2003-08-21 Andrew Cagney <cagney@redhat.com>
+
+ * i386-tdep.h (i386_regnums): Replace I386_EAX_REGNUM,
+ I386_EDX_REGNUM, I386_ESP_REGNUM, I386_EBP_REGNUM,
+ I386_EIP_REGNUM, I386_EFLAGS_REGNUM, I386_ST0_REGNUM.
+ * i386-linux-tdep.h (i386_linux_greg_offset): Declare.
+ (i386_linux_supply_fpxregset): Declare.
+ (i386_linux_supply_fpregset): Declare.
+ (i386_linux_supply_gregset): Declare.
+ * i386-linux-tdep.c: Include "gdb_assert.h", and "i387-tdep.h".
+ Do not include "gregset.h".
+ (enum user_regs): Define.
+ (struct regnum_map, struct regnum_to_user): Define.
+ (i386_linux_greg_offset): New function.
+ (dummy_sse_values): New function, copied from "i386-linux-nat.c"
+ make hist independant.
+ (i386_linux_supply_fpregset): New function.
+ (i386_linux_supply_gregset): New function.
+ (i386_linux_supply_fpxregset): New function.
+ (fetch_core_registers): New function.
+ (i386_linux_core_sniffer): New function.
+ (i386_linux_core_fns): New table.
+ (_initialize_i386_linux_tdep): Add i386_linux_core_fns to core
+ functions.
+ * i386-linux-nat.c: Do not include "gregset.h".
+ (dummy_sse_values) Delete function.
+ (regmap): Delete array.
+ (register_u_addr, fill_gregset, cannot_fetch_register): Use
+ i386_linux_greg_offset.
+ (cannot_store_register): Call cannot_fetch_register.
+ (supply_gregset): Call i386_linux_supply_gregset.
+ (supply_fpregset): Call i386_linux_supply_fpregset.
+ (supply_fpxregset): Call i386_linux_supply_fpxregset.
+ (fetch_core_registers): Delete function.
+ (linux_elf_core_fns): Delete table.
+ (_initialize_i386_linux_nat): Delete function.
+
2003-08-20 Michael Snyder <msnyder@redhat.com>
* sh-tdep.h (struct gdbarch_tdep): New member FLOAT_ARGLAST_REG.
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);
-}
diff --git a/gdb/i386-linux-tdep.c b/gdb/i386-linux-tdep.c
index 6d284f1ea98..26f838e8e7f 100644
--- a/gdb/i386-linux-tdep.c
+++ b/gdb/i386-linux-tdep.c
@@ -26,6 +26,7 @@
#include "regcache.h"
#include "inferior.h"
#include "reggroups.h"
+#include "gdb_assert.h"
/* For i386_linux_skip_solib_resolver. */
#include "symtab.h"
@@ -37,8 +38,123 @@
#include "osabi.h"
#include "i386-tdep.h"
+#include "i387-tdep.h"
#include "i386-linux-tdep.h"
+
+/* 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. */
+
+enum user_regs {
+ USER_INVALID = -1,
+ USER_EBX,
+ USER_ECX,
+ USER_EDX,
+ USER_ESI,
+ USER_EDI,
+ USER_EBP,
+ USER_EAX,
+ USER_DS,
+ USER_ES,
+ USER_FS,
+ USER_GS,
+ USER_ORIG_EAX,
+ USER_EIP,
+ USER_CS,
+ USER_EFL,
+ USER_UESP,
+ USER_SS,
+ USER_MAX
+};
+
+struct regnum_map
+{
+ enum i386_regnums regnum;
+ enum user_regs user;
+};
+
+struct regnum_to_user
+{
+ long nr;
+ const struct regnum_map *map;
+};
+
+long
+i386_linux_greg_offset (int regnum)
+{
+ /* Mapping between the general-purpose registers in `struct user'
+ format and GDB's register array layout. */
+ static const struct regnum_map regnum_map[] =
+ {
+ { I386_EAX_REGNUM, USER_EAX },
+ { I386_ECX_REGNUM, USER_ECX },
+ { I386_EDX_REGNUM, USER_EDX },
+ { I386_EBX_REGNUM, USER_EBX },
+ { I386_ESP_REGNUM, USER_UESP },
+ { I386_EBP_REGNUM, USER_EBP },
+ { I386_ESI_REGNUM, USER_ESI },
+ { I386_EDI_REGNUM, USER_EDI },
+ { I386_EIP_REGNUM, USER_EIP },
+ { I386_EFLAGS_REGNUM, USER_EFL },
+ { I386_CS_REGNUM, USER_CS },
+ { I386_SS_REGNUM, USER_SS },
+ { I386_DS_REGNUM, USER_DS },
+ { I386_ES_REGNUM, USER_ES },
+ { I386_FS_REGNUM, USER_FS },
+ { I386_GS_REGNUM, USER_GS },
+ { I386_ST0_REGNUM, USER_INVALID },
+ { I386_ST1_REGNUM, USER_INVALID },
+ { I386_ST2_REGNUM, USER_INVALID },
+ { I386_ST3_REGNUM, USER_INVALID },
+ { I386_ST4_REGNUM, USER_INVALID },
+ { I386_ST5_REGNUM, USER_INVALID },
+ { I386_ST6_REGNUM, USER_INVALID },
+ { I386_ST7_REGNUM, USER_INVALID },
+ { I386_FCTRL_REGNUM, USER_INVALID },
+ { I386_FSTAT_REGNUM, USER_INVALID },
+ { I386_FTAG_REGNUM, USER_INVALID },
+ { I386_FISEG_REGNUM, USER_INVALID },
+ { I386_FIOFF_REGNUM, USER_INVALID },
+ { I386_FOSEG_REGNUM, USER_INVALID },
+ { I386_FOOFF_REGNUM, USER_INVALID },
+ { I386_FOP_REGNUM, USER_INVALID },
+ { I386_XMM0_REGNUM, USER_INVALID },
+ { I386_XMM1_REGNUM, USER_INVALID },
+ { I386_XMM2_REGNUM, USER_INVALID },
+ { I386_XMM3_REGNUM, USER_INVALID },
+ { I386_XMM4_REGNUM, USER_INVALID },
+ { I386_XMM5_REGNUM, USER_INVALID },
+ { I386_XMM6_REGNUM, USER_INVALID },
+ { I386_XMM6_REGNUM, USER_INVALID },
+ { I386_MXCSR_REGNUM, USER_INVALID },
+ { I386_LINUX_ORIG_EAX_REGNUM, USER_ORIG_EAX }
+ };
+ const static struct regnum_to_user regnum_to_user =
+ {
+ ARRAY_SIZE (regnum_map), regnum_map
+ };
+
+ gdb_assert (TARGET_ARCHITECTURE->arch == bfd_arch_i386);
+ if (regnum < 0)
+ return USER_MAX * 4;
+ if (regnum >= regnum_to_user.nr)
+ return -1;
+ gdb_assert (regnum_to_user.map[regnum].regnum == regnum);
+ if (regnum_to_user.map[regnum].user < 0)
+ return -1;
+ return regnum_to_user.map[regnum].user * 4;
+}
+
+
/* Return the name of register REG. */
static const char *
@@ -496,12 +612,160 @@ i386_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
i386_linux_svr4_fetch_link_map_offsets);
}
+
+
+/* Interpreting register set info found in core files and ptrace
+ buffers. */
+
+/* Fill GDB's register array with the floating-point register values in
+ *FPREGSETP. */
+
+/* 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);
+ int reg;
+ /* Assume i386 is always little endian. */
+ static const char mxcsr[MAX_REGISTER_SIZE] = { 0x80, 0x1f };
+ /* C doesn't have a syntax for NaN's (0xffffffffff), so generate it
+ on the fly. */
+ char nan[MAX_REGISTER_SIZE];
+ memset (nan, -1, sizeof nan);
+
+ for (reg = 0; reg < tdep->num_xmm_regs; reg++)
+ supply_register (XMM0_REGNUM + reg, (char *) nan);
+ if (tdep->num_xmm_regs > 0)
+ supply_register (MXCSR_REGNUM, (char *) &mxcsr);
+}
+
+void
+i386_linux_supply_fpregset (void *fpregset)
+{
+ i387_supply_fsave (fpregset);
+ dummy_sse_values ();
+}
+
+/* Fill GDB's register array with the general-purpose register values
+ in *GREGSETP. */
+
+void
+i386_linux_supply_gregset (void *gregset)
+{
+ bfd_byte *regp = gregset;
+ int i;
+
+ for (i = 0; i < I386_NUM_GREGS; i++)
+ {
+ long offset = i386_linux_greg_offset (i);
+ if (offset >= 0)
+ supply_register (i, regp + offset);
+ }
+
+ if (I386_LINUX_ORIG_EAX_REGNUM < NUM_REGS)
+ {
+ long offset = i386_linux_greg_offset (I386_LINUX_ORIG_EAX_REGNUM);
+ if (offset >= 0)
+ supply_register (I386_LINUX_ORIG_EAX_REGNUM, regp + offset);
+ }
+}
+
+/* Fill GDB's register array with the floating-point and SSE register
+ values in *FPXREGSETP. */
+
+void
+i386_linux_supply_fpxregset (void *fpxregsetp)
+{
+ i387_supply_fxsave (fpxregsetp);
+}
+
+
+/* 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)
+{
+ switch (which)
+ {
+ case 0:
+ if (core_reg_size < i386_linux_greg_offset (-1))
+ warning ("Wrong size register set in core file.");
+ else
+ i386_linux_supply_gregset (core_reg_sect);
+ break;
+
+ case 2:
+ if (core_reg_size < 108)
+ warning ("Wrong size fpregset in core file.");
+ else
+ i386_linux_supply_fpregset (core_reg_sect);
+ break;
+
+ case 3:
+ if (core_reg_size < 512)
+ warning ("Wrong size fpxregset in core file.");
+ else
+ i386_linux_supply_fpxregset (core_reg_sect);
+ break;
+
+ 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;
+ }
+}
+
+static int
+i386_linux_core_sniffer (struct core_fns *our_fns, bfd *abfd)
+{
+ int result;
+
+ result = ((bfd_get_flavour (abfd) == our_fns -> core_flavour)
+ && bfd_get_arch (abfd) == bfd_arch_i386
+ && (bfd_get_mach (abfd) == bfd_mach_i386_i386
+ || bfd_get_mach (abfd) == bfd_mach_i386_i386_intel_syntax));
+ return (result);
+}
+
+static struct core_fns i386_linux_core_fns =
+{
+ bfd_target_elf_flavour, /* core_flavour */
+ default_check_format, /* check_format */
+ i386_linux_core_sniffer, /* core_sniffer */
+ fetch_core_registers, /* core_read_registers */
+ NULL /* next */
+};
+
+
/* Provide a prototype to silence -Wmissing-prototypes. */
extern void _initialize_i386_linux_tdep (void);
void
_initialize_i386_linux_tdep (void)
{
+ add_core_fns (&i386_linux_core_fns);
gdbarch_register_osabi (bfd_arch_i386, 0, GDB_OSABI_LINUX,
i386_linux_init_abi);
}
diff --git a/gdb/i386-linux-tdep.h b/gdb/i386-linux-tdep.h
index 95b168ac88e..b9c8d92d98e 100644
--- a/gdb/i386-linux-tdep.h
+++ b/gdb/i386-linux-tdep.h
@@ -33,4 +33,15 @@
system call number that the kernel is supposed to restart. */
#define I386_LINUX_ORIG_EAX_REGNUM I386_SSE_NUM_REGS
+/* Given REGNUM, return the corresponding offset, into GREG/user
+ register area, or -1 if the map isn't applicable. Given a -ve
+ REGNUM, return the GREG's upper bound. */
+extern long i386_linux_greg_offset (int regnum);
+
+/* Given a system dependant PTRACE buffer, supply GDB's regcache with
+ the register values. */
+extern void i386_linux_supply_gregset (void *gregset);
+extern void i386_linux_supply_fpregset (void *gregset);
+extern void i386_linux_supply_fpxregset (void *gregset);
+
#endif /* i386-linux-tdep.h */
diff --git a/gdb/i386-tdep.h b/gdb/i386-tdep.h
index 7412b8ea867..1d93cc98271 100644
--- a/gdb/i386-tdep.h
+++ b/gdb/i386-tdep.h
@@ -142,15 +142,53 @@ extern int i386_mxcsr_regnum_p (int regnum);
#define FDS_REGNUM FOSEG_REGNUM
#define FDOFF_REGNUM FOOFF_REGNUM
-/* Register numbers of various important registers. */
-
-#define I386_EAX_REGNUM 0 /* %eax */
-#define I386_EDX_REGNUM 2 /* %edx */
-#define I386_ESP_REGNUM 4 /* %esp */
-#define I386_EBP_REGNUM 5 /* %ebp */
-#define I386_EIP_REGNUM 8 /* %eip */
-#define I386_EFLAGS_REGNUM 9 /* %eflags */
-#define I386_ST0_REGNUM 16 /* %st(0) */
+/* Register numbers for the fixed i386 registers. */
+
+enum i386_regnums
+{
+ I386_EAX_REGNUM,
+ I386_ECX_REGNUM,
+ I386_EDX_REGNUM,
+ I386_EBX_REGNUM,
+ I386_ESP_REGNUM,
+ I386_EBP_REGNUM,
+ I386_ESI_REGNUM,
+ I386_EDI_REGNUM,
+ I386_EIP_REGNUM,
+ I386_EFLAGS_REGNUM,
+ I386_CS_REGNUM,
+ I386_SS_REGNUM,
+ I386_DS_REGNUM,
+ I386_ES_REGNUM,
+ I386_FS_REGNUM,
+ I386_GS_REGNUM,
+ I386_ST0_REGNUM,
+ I386_ST1_REGNUM,
+ I386_ST2_REGNUM,
+ I386_ST3_REGNUM,
+ I386_ST4_REGNUM,
+ I386_ST5_REGNUM,
+ I386_ST6_REGNUM,
+ I386_ST7_REGNUM,
+ I386_FCTRL_REGNUM,
+ I386_FSTAT_REGNUM,
+ I386_FTAG_REGNUM,
+ I386_FISEG_REGNUM,
+ I386_FIOFF_REGNUM,
+ I386_FOSEG_REGNUM,
+ I386_FOOFF_REGNUM,
+ I386_FOP_REGNUM,
+ I386_XMM0_REGNUM,
+ I386_XMM1_REGNUM,
+ I386_XMM2_REGNUM,
+ I386_XMM3_REGNUM,
+ I386_XMM4_REGNUM,
+ I386_XMM5_REGNUM,
+ I386_XMM6_REGNUM,
+ I386_XMM7_REGNUM,
+ I386_MXCSR_REGNUM,
+ I386_ORIG_EAX_REGNUM
+};
#define I386_NUM_GREGS 16
#define I386_NUM_FREGS 16