/* Intel 386 target-dependent stuff.
Copyright 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996,
- 1997, 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+ 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software
+ Foundation, Inc.
This file is part of GDB.
#include "i386-tdep.h"
#include "i387-tdep.h"
-/* Names of the registers. The first 10 registers match the register
- numbering scheme used by GCC for stabs and DWARF. */
+/* Register names. */
static char *i386_register_names[] =
{
static const int i386_num_register_names = ARRAY_SIZE (i386_register_names);
-/* MMX registers. */
+/* Register names for MMX pseudo-registers. */
static char *i386_mmx_names[] =
{
return NULL;
}
-/* Convert stabs register number REG to the appropriate register
+/* Convert a dbx register number REG to the appropriate register
number used by GDB. */
static int
-i386_stab_reg_to_regnum (int reg)
+i386_dbx_reg_to_regnum (int reg)
{
- /* This implements what GCC calls the "default" register map. */
+ /* This implements what GCC calls the "default" register map
+ (dbx_register_map[]). */
+
if (reg >= 0 && reg <= 7)
{
- /* General-purpose registers. */
- return reg;
+ /* General-purpose registers. The debug info calls %ebp
+ register 4, and %esp register 5. */
+ if (reg == 4)
+ return 5;
+ else if (reg == 5)
+ return 4;
+ else return reg;
}
else if (reg >= 12 && reg <= 19)
{
return NUM_REGS + NUM_PSEUDO_REGS;
}
-/* Convert DWARF register number REG to the appropriate register
- number used by GDB. */
+/* Convert SVR4 register number REG to the appropriate register number
+ used by GDB. */
static int
-i386_dwarf_reg_to_regnum (int reg)
+i386_svr4_reg_to_regnum (int reg)
{
- /* The DWARF register numbering includes %eip and %eflags, and
+ /* This implements the GCC register map that tries to be compatible
+ with the SVR4 C compiler for DWARF (svr4_dbx_register_map[]). */
+
+ /* The SVR4 register numbering includes %eip and %eflags, and
numbers the floating point registers differently. */
if (reg >= 0 && reg <= 9)
{
}
else if (reg >= 21)
{
- /* The SSE and MMX registers have identical numbers as in stabs. */
- return i386_stab_reg_to_regnum (reg);
+ /* The SSE and MMX registers have the same numbers as with dbx. */
+ return i386_dbx_reg_to_regnum (reg);
}
/* This will hopefully provoke a warning. */
xorl %ebx, %ebx
xorl %ecx, %ecx
xorl %edx, %edx
+ xorl %eax, %eax
and the equivalent
subl %ebx, %ebx
subl %ecx, %ecx
subl %edx, %edx
+ subl %eax, %eax
+
+ Because of the symmetry, there are actually two ways to
+ encode these instructions; with opcode bytes 0x29 and 0x2b
+ for `subl' and opcode bytes 0x31 and 0x33 for `xorl'.
Make sure we only skip these instructions if we later see the
`movl %esp, %ebp' that actually sets up the frame. */
- while (op == 0x29 || op == 0x31)
+ while (op == 0x29 || op == 0x2b || op == 0x31 || op == 0x33)
{
op = read_memory_unsigned_integer (pc + skip + 2, 1);
switch (op)
case 0xdb: /* %ebx */
case 0xc9: /* %ecx */
case 0xd2: /* %edx */
+ case 0xc0: /* %eax */
skip += 2;
break;
default:
subl $XXX, %esp
- NOTE: You can't subtract a 16 bit immediate from a 32 bit
+ NOTE: You can't subtract a 16-bit immediate from a 32-bit
reg, so we don't have to worry about a data16 prefix. */
op = read_memory_unsigned_integer (pc + 3, 1);
if (op == 0x83)
{
- /* `subl' with 8 bit immediate. */
+ /* `subl' with 8-bit immediate. */
if (read_memory_unsigned_integer (pc + 4, 1) != 0xec)
/* Some instruction starting with 0x83 other than `subl'. */
return pc + 3;
}
else if (op == 0x81)
{
- /* Maybe it is `subl' with a 32 bit immedediate. */
+ /* Maybe it is `subl' with a 32-bit immediate. */
if (read_memory_unsigned_integer (pc + 4, 1) != 0xec)
/* Some instruction starting with 0x81 other than `subl'. */
return pc + 3;
- /* It is `subl' with a 32 bit immediate. */
+ /* It is `subl' with a 32-bit immediate. */
cache->locals = read_memory_integer (pc + 5, 4);
return pc + 9;
}
once used in the System V compiler).
Local space is allocated just below the saved %ebp by either the
- 'enter' instruction, or by "subl $<size>, %esp". 'enter' has a 16
- bit unsigned argument for space to allocate, and the 'addl'
- instruction could have either a signed byte, or 32 bit immediate.
+ 'enter' instruction, or by "subl $<size>, %esp". 'enter' has a
+ 16-bit unsigned argument for space to allocate, and the 'addl'
+ instruction could have either a signed byte, or 32-bit immediate.
Next, the registers used by this function are pushed. With the
System V compiler they will always be in the order: %edi, %esi,
}
}
- return i386_follow_jump (pc);
+ /* If the function starts with a branch (to startup code at the end)
+ the last instruction should bring us back to the first
+ instruction of the real code. */
+ if (i386_follow_jump (start_pc) != start_pc)
+ pc = i386_follow_jump (pc);
+
+ return pc;
}
/* This function is 64-bit safe. */
static const struct frame_unwind *
i386_sigtramp_frame_sniffer (struct frame_info *next_frame)
{
- CORE_ADDR pc = frame_pc_unwind (next_frame);
- char *name;
+ struct gdbarch_tdep *tdep = gdbarch_tdep (get_frame_arch (next_frame));
- /* We shouldn't even bother to try if the OSABI didn't register
- a sigcontext_addr handler. */
- if (!gdbarch_tdep (current_gdbarch)->sigcontext_addr)
+ /* We shouldn't even bother if we don't have a sigcontext_addr
+ handler. */
+ if (tdep->sigcontext_addr == NULL)
return NULL;
- find_pc_partial_function (pc, &name, NULL, NULL);
- if (PC_IN_SIGTRAMP (pc, name))
- return &i386_sigtramp_frame_unwind;
+ if (tdep->sigtramp_p != NULL)
+ {
+ if (tdep->sigtramp_p (next_frame))
+ return &i386_sigtramp_frame_unwind;
+ }
+
+ if (tdep->sigtramp_start != 0)
+ {
+ CORE_ADDR pc = frame_pc_unwind (next_frame);
+
+ gdb_assert (tdep->sigtramp_end != 0);
+ if (pc >= tdep->sigtramp_start && pc < tdep->sigtramp_end)
+ return &i386_sigtramp_frame_unwind;
+ }
return NULL;
}
\f
static CORE_ADDR
-i386_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_addr,
+i386_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
struct regcache *regcache, CORE_ADDR bp_addr, int nargs,
struct value **args, CORE_ADDR sp, int struct_return,
CORE_ADDR struct_addr)
(i386_frame_this_id, i386_sigtramp_frame_this_id,
i386_unwind_dummy_id). It's there, since all frame unwinders for
a given target have to agree (within a certain margin) on the
- defenition of the stack address of a frame. Otherwise
+ definition of the stack address of a frame. Otherwise
frame_id_inner() won't work correctly. Since DWARF2/GCC uses the
stack address *before* the function call as a frame's CFA. On
the i386, when %ebp is used as a frame pointer, the offset
#define LOW_RETURN_REGNUM I386_EAX_REGNUM /* %eax */
#define HIGH_RETURN_REGNUM I386_EDX_REGNUM /* %edx */
-/* Extract from an array REGBUF containing the (raw) register state, a
- function return value of TYPE, and copy that, in virtual format,
- into VALBUF. */
+/* Read, for architecture GDBARCH, a function return value of TYPE
+ from REGCACHE, and copy that into VALBUF. */
static void
-i386_extract_return_value (struct type *type, struct regcache *regcache,
- void *dst)
+i386_extract_return_value (struct gdbarch *gdbarch, struct type *type,
+ struct regcache *regcache, void *valbuf)
{
- struct gdbarch_tdep *tdep = gdbarch_tdep (get_regcache_arch (regcache));
- bfd_byte *valbuf = dst;
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
int len = TYPE_LENGTH (type);
char buf[I386_MAX_REGISTER_SIZE];
- if (TYPE_CODE (type) == TYPE_CODE_STRUCT
- && TYPE_NFIELDS (type) == 1)
- {
- i386_extract_return_value (TYPE_FIELD_TYPE (type, 0), regcache, valbuf);
- return;
- }
-
if (TYPE_CODE (type) == TYPE_CODE_FLT)
{
if (tdep->st0_regnum < 0)
regcache_raw_read (regcache, LOW_RETURN_REGNUM, buf);
memcpy (valbuf, buf, low_size);
regcache_raw_read (regcache, HIGH_RETURN_REGNUM, buf);
- memcpy (valbuf + low_size, buf, len - low_size);
+ memcpy ((char *) valbuf + low_size, buf, len - low_size);
}
else
internal_error (__FILE__, __LINE__,
}
}
-/* Write into the appropriate registers a function return value stored
- in VALBUF of type TYPE, given in virtual format. */
+/* Write, for architecture GDBARCH, a function return value of TYPE
+ from VALBUF into REGCACHE. */
static void
-i386_store_return_value (struct type *type, struct regcache *regcache,
- const void *valbuf)
+i386_store_return_value (struct gdbarch *gdbarch, struct type *type,
+ struct regcache *regcache, const void *valbuf)
{
- struct gdbarch_tdep *tdep = gdbarch_tdep (get_regcache_arch (regcache));
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
int len = TYPE_LENGTH (type);
/* Define I387_ST0_REGNUM such that we use the proper definitions
for the architecture. */
#define I387_ST0_REGNUM I386_ST0_REGNUM
- if (TYPE_CODE (type) == TYPE_CODE_STRUCT
- && TYPE_NFIELDS (type) == 1)
- {
- i386_store_return_value (TYPE_FIELD_TYPE (type, 0), regcache, valbuf);
- return;
- }
-
if (TYPE_CODE (type) == TYPE_CODE_FLT)
{
ULONGEST fstat;
#undef I387_ST0_REGNUM
}
-
-/* Extract from REGCACHE, which contains the (raw) register state, the
- address in which a function should return its structure value, as a
- CORE_ADDR. */
-
-static CORE_ADDR
-i386_extract_struct_value_address (struct regcache *regcache)
-{
- char buf[4];
-
- regcache_cooked_read (regcache, I386_EAX_REGNUM, buf);
- return extract_unsigned_integer (buf, 4);
-}
\f
/* This is the variable that is set with "set struct-convention", and
};
static const char *struct_convention = default_struct_convention;
+/* Return non-zero if TYPE, which is assumed to be a structure or
+ union type, should be returned in registers for architecture
+ GDBARCH. */
+
static int
-i386_use_struct_convention (int gcc_p, struct type *type)
+i386_reg_struct_return_p (struct gdbarch *gdbarch, struct type *type)
{
- enum struct_return struct_return;
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ enum type_code code = TYPE_CODE (type);
+ int len = TYPE_LENGTH (type);
- if (struct_convention == default_struct_convention)
- struct_return = gdbarch_tdep (current_gdbarch)->struct_return;
- else if (struct_convention == pcc_struct_convention)
- struct_return = pcc_struct_return;
- else
- struct_return = reg_struct_return;
+ gdb_assert (code == TYPE_CODE_STRUCT || code == TYPE_CODE_UNION);
+
+ if (struct_convention == pcc_struct_convention
+ || (struct_convention == default_struct_convention
+ && tdep->struct_return == pcc_struct_return))
+ return 0;
+
+ return (len == 1 || len == 2 || len == 4 || len == 8);
+}
+
+/* Determine, for architecture GDBARCH, how a return value of TYPE
+ should be returned. If it is supposed to be returned in registers,
+ and READBUF is non-zero, read the appropriate value from REGCACHE,
+ and copy it into READBUF. If WRITEBUF is non-zero, write the value
+ from WRITEBUF into REGCACHE. */
+
+static enum return_value_convention
+i386_return_value (struct gdbarch *gdbarch, struct type *type,
+ struct regcache *regcache, void *readbuf,
+ const void *writebuf)
+{
+ enum type_code code = TYPE_CODE (type);
+
+ if ((code == TYPE_CODE_STRUCT || code == TYPE_CODE_UNION)
+ && !i386_reg_struct_return_p (gdbarch, type))
+ {
+ /* The System V ABI says that:
+
+ "A function that returns a structure or union also sets %eax
+ to the value of the original address of the caller's area
+ before it returns. Thus when the caller receives control
+ again, the address of the returned object resides in register
+ %eax and can be used to access the object."
+
+ So the ABI guarantees that we can always find the return
+ value just after the function has returned. */
+
+ if (readbuf)
+ {
+ ULONGEST addr;
+
+ regcache_raw_read_unsigned (regcache, I386_EAX_REGNUM, &addr);
+ read_memory (addr, readbuf, TYPE_LENGTH (type));
+ }
- return generic_use_struct_convention (struct_return == reg_struct_return,
- type);
+ return RETURN_VALUE_ABI_RETURNS_ADDRESS;
+ }
+
+ /* This special case is for structures consisting of a single
+ `float' or `double' member. These structures are returned in
+ %st(0). For these structures, we call ourselves recursively,
+ changing TYPE into the type of the first member of the structure.
+ Since that should work for all structures that have only one
+ member, we don't bother to check the member's type here. */
+ if (code == TYPE_CODE_STRUCT && TYPE_NFIELDS (type) == 1)
+ {
+ type = check_typedef (TYPE_FIELD_TYPE (type, 0));
+ return i386_return_value (gdbarch, type, regcache, readbuf, writebuf);
+ }
+
+ if (readbuf)
+ i386_extract_return_value (gdbarch, type, regcache, readbuf);
+ if (writebuf)
+ i386_store_return_value (gdbarch, type, regcache, writebuf);
+
+ return RETURN_VALUE_REGISTER_CONVENTION;
}
\f
}
\f
-/* These registers don't have pervasive standard uses. Move them to
- i386-tdep.h if necessary. */
-
-#define I386_EBX_REGNUM 3 /* %ebx */
-#define I386_ECX_REGNUM 1 /* %ecx */
-#define I386_ESI_REGNUM 6 /* %esi */
-#define I386_EDI_REGNUM 7 /* %edi */
-
/* Return the register number of the register allocated by GCC after
REGNUM, or -1 if there is no such register. */
return;
}
- /* Read a value spread accross multiple registers. */
+ /* Read a value spread across multiple registers. */
gdb_assert (len > 4 && len % 4 == 0);
return;
}
- /* Write a value spread accross multiple registers. */
+ /* Write a value spread across multiple registers. */
gdb_assert (len > 4 && len % 4 == 0);
}
}
\f
-/* Supply register REGNUM from the general-purpose register set REGSET
- to register cache REGCACHE. If REGNUM is -1, do this for all
- registers in REGSET. */
+/* Supply register REGNUM from the buffer specified by GREGS and LEN
+ in the general-purpose register set REGSET to register cache
+ REGCACHE. If REGNUM is -1, do this for all registers in REGSET. */
-static void
+void
i386_supply_gregset (const struct regset *regset, struct regcache *regcache,
int regnum, const void *gregs, size_t len)
{
- const struct gdbarch_tdep *tdep = regset->descr;
+ const struct gdbarch_tdep *tdep = gdbarch_tdep (regset->arch);
const char *regs = gregs;
int i;
}
}
-/* Supply register REGNUM from the floating-point register set REGSET
- to register cache REGCACHE. If REGNUM is -1, do this for all
- registers in REGSET. */
+/* Collect register REGNUM from the register cache REGCACHE and store
+ it in the buffer specified by GREGS and LEN as described by the
+ general-purpose register set REGSET. If REGNUM is -1, do this for
+ all registers in REGSET. */
+
+void
+i386_collect_gregset (const struct regset *regset,
+ const struct regcache *regcache,
+ int regnum, void *gregs, size_t len)
+{
+ const struct gdbarch_tdep *tdep = gdbarch_tdep (regset->arch);
+ char *regs = gregs;
+ int i;
+
+ gdb_assert (len == tdep->sizeof_gregset);
+
+ for (i = 0; i < tdep->gregset_num_regs; i++)
+ {
+ if ((regnum == i || regnum == -1)
+ && tdep->gregset_reg_offset[i] != -1)
+ regcache_raw_collect (regcache, i, regs + tdep->gregset_reg_offset[i]);
+ }
+}
+
+/* Supply register REGNUM from the buffer specified by FPREGS and LEN
+ in the floating-point register set REGSET to register cache
+ REGCACHE. If REGNUM is -1, do this for all registers in REGSET. */
static void
i386_supply_fpregset (const struct regset *regset, struct regcache *regcache,
int regnum, const void *fpregs, size_t len)
{
- const struct gdbarch_tdep *tdep = regset->descr;
+ const struct gdbarch_tdep *tdep = gdbarch_tdep (regset->arch);
+
+ if (len == I387_SIZEOF_FXSAVE)
+ {
+ i387_supply_fxsave (regcache, regnum, fpregs);
+ return;
+ }
gdb_assert (len == tdep->sizeof_fpregset);
i387_supply_fsave (regcache, regnum, fpregs);
}
+
+/* Collect register REGNUM from the register cache REGCACHE and store
+ it in the buffer specified by FPREGS and LEN as described by the
+ floating-point register set REGSET. If REGNUM is -1, do this for
+ all registers in REGSET. */
+
+static void
+i386_collect_fpregset (const struct regset *regset,
+ const struct regcache *regcache,
+ int regnum, void *fpregs, size_t len)
+{
+ const struct gdbarch_tdep *tdep = gdbarch_tdep (regset->arch);
+
+ if (len == I387_SIZEOF_FXSAVE)
+ {
+ i387_collect_fxsave (regcache, regnum, fpregs);
+ return;
+ }
+
+ gdb_assert (len == tdep->sizeof_fpregset);
+ i387_collect_fsave (regcache, regnum, fpregs);
+}
+
+/* Return the appropriate register set for the core section identified
+ by SECT_NAME and SECT_SIZE. */
+
+const struct regset *
+i386_regset_from_core_section (struct gdbarch *gdbarch,
+ const char *sect_name, size_t sect_size)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+ if (strcmp (sect_name, ".reg") == 0 && sect_size == tdep->sizeof_gregset)
+ {
+ if (tdep->gregset == NULL)
+ tdep->gregset = regset_alloc (gdbarch, i386_supply_gregset,
+ i386_collect_gregset);
+ return tdep->gregset;
+ }
+
+ if ((strcmp (sect_name, ".reg2") == 0 && sect_size == tdep->sizeof_fpregset)
+ || (strcmp (sect_name, ".reg-xfp") == 0
+ && sect_size == I387_SIZEOF_FXSAVE))
+ {
+ if (tdep->fpregset == NULL)
+ tdep->fpregset = regset_alloc (gdbarch, i386_supply_fpregset,
+ i386_collect_fpregset);
+ return tdep->fpregset;
+ }
+
+ return NULL;
+}
\f
#ifdef STATIC_TRANSFORM_NAME
}
\f
-/* Return non-zero if PC and NAME show that we are in a signal
- trampoline. */
+/* Return whether the frame preceding NEXT_FRAME corresponds to a
+ sigtramp routine. */
static int
-i386_pc_in_sigtramp (CORE_ADDR pc, char *name)
+i386_sigtramp_p (struct frame_info *next_frame)
{
+ CORE_ADDR pc = frame_pc_unwind (next_frame);
+ char *name;
+
+ find_pc_partial_function (pc, &name, NULL, NULL);
return (name && strcmp ("_sigtramp", name) == 0);
}
\f
/* System V Release 4 (SVR4). */
+/* Return whether the frame preceding NEXT_FRAME corresponds to a SVR4
+ sigtramp routine. */
+
static int
-i386_svr4_pc_in_sigtramp (CORE_ADDR pc, char *name)
+i386_svr4_sigtramp_p (struct frame_info *next_frame)
{
+ CORE_ADDR pc = frame_pc_unwind (next_frame);
+ char *name;
+
/* UnixWare uses _sigacthandler. The origin of the other symbols is
currently unknown. */
+ find_pc_partial_function (pc, &name, NULL, NULL);
return (name && (strcmp ("_sigreturn", name) == 0
|| strcmp ("_sigacthandler", name) == 0
|| strcmp ("sigvechandler", name) == 0));
}
\f
-/* DJGPP. */
-
-static int
-i386_go32_pc_in_sigtramp (CORE_ADDR pc, char *name)
-{
- /* DJGPP doesn't have any special frames for signal handlers. */
- return 0;
-}
-\f
-
/* Generic ELF. */
void
i386_elf_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
{
- /* We typically use stabs-in-ELF with the DWARF register numbering. */
- set_gdbarch_stab_reg_to_regnum (gdbarch, i386_dwarf_reg_to_regnum);
+ /* We typically use stabs-in-ELF with the SVR4 register numbering. */
+ set_gdbarch_stab_reg_to_regnum (gdbarch, i386_svr4_reg_to_regnum);
}
/* System V Release 4 (SVR4). */
set_gdbarch_in_solib_call_trampoline (gdbarch, in_plt_section);
set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
- set_gdbarch_pc_in_sigtramp (gdbarch, i386_svr4_pc_in_sigtramp);
+ tdep->sigtramp_p = i386_svr4_sigtramp_p;
tdep->sigcontext_addr = i386_svr4_sigcontext_addr;
tdep->sc_pc_offset = 36 + 14 * 4;
tdep->sc_sp_offset = 36 + 17 * 4;
{
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
- set_gdbarch_pc_in_sigtramp (gdbarch, i386_go32_pc_in_sigtramp);
+ /* DJGPP doesn't have any special frames for signal handlers. */
+ tdep->sigtramp_p = NULL;
tdep->jb_pc_offset = 36;
}
tdep->sizeof_fpregset = I387_SIZEOF_FSAVE;
/* The default settings include the FPU registers, the MMX registers
- and the SSE registers. This can be overidden for a specific ABI
+ and the SSE registers. This can be overridden for a specific ABI
by adjusting the members `st0_regnum', `mm0_regnum' and
`num_xmm_regs' of `struct gdbarch_tdep', otherwise the registers
will show up in the output of "info all-registers". Ideally we
tdep->st0_regnum = I386_ST0_REGNUM;
/* The MMX registers are implemented as pseudo-registers. Put off
- caclulating the register number for %mm0 until we know the number
+ calculating the register number for %mm0 until we know the number
of raw registers. */
tdep->mm0_regnum = 0;
tdep->struct_return = pcc_struct_return;
tdep->sigtramp_start = 0;
tdep->sigtramp_end = 0;
+ tdep->sigtramp_p = i386_sigtramp_p;
tdep->sigcontext_addr = NULL;
tdep->sc_reg_offset = NULL;
tdep->sc_pc_offset = -1;
set_gdbarch_ps_regnum (gdbarch, I386_EFLAGS_REGNUM); /* %eflags */
set_gdbarch_fp0_regnum (gdbarch, I386_ST0_REGNUM); /* %st(0) */
- /* Use the "default" register numbering scheme for stabs and COFF. */
- set_gdbarch_stab_reg_to_regnum (gdbarch, i386_stab_reg_to_regnum);
- set_gdbarch_sdb_reg_to_regnum (gdbarch, i386_stab_reg_to_regnum);
-
- /* Use the DWARF register numbering scheme for DWARF and DWARF 2. */
- set_gdbarch_dwarf_reg_to_regnum (gdbarch, i386_dwarf_reg_to_regnum);
- set_gdbarch_dwarf2_reg_to_regnum (gdbarch, i386_dwarf_reg_to_regnum);
+ /* NOTE: kettenis/20040418: GCC does have two possible register
+ numbering schemes on the i386: dbx and SVR4. These schemes
+ differ in how they number %ebp, %esp, %eflags, and the
+ floating-point registers, and are implemented by the arrays
+ dbx_register_map[] and svr4_dbx_register_map in
+ gcc/config/i386.c. GCC also defines a third numbering scheme in
+ gcc/config/i386.c, which it designates as the "default" register
+ map used in 64bit mode. This last register numbering scheme is
+ implemented in dbx64_register_map, and is used for AMD64; see
+ amd64-tdep.c.
+
+ Currently, each GCC i386 target always uses the same register
+ numbering scheme across all its supported debugging formats
+ i.e. SDB (COFF), stabs and DWARF 2. This is because
+ gcc/sdbout.c, gcc/dbxout.c and gcc/dwarf2out.c all use the
+ DBX_REGISTER_NUMBER macro which is defined by each target's
+ respective config header in a manner independent of the requested
+ output debugging format.
+
+ This does not match the arrangement below, which presumes that
+ the SDB and stabs numbering schemes differ from the DWARF and
+ DWARF 2 ones. The reason for this arrangement is that it is
+ likely to get the numbering scheme for the target's
+ default/native debug format right. For targets where GCC is the
+ native compiler (FreeBSD, NetBSD, OpenBSD, GNU/Linux) or for
+ targets where the native toolchain uses a different numbering
+ scheme for a particular debug format (stabs-in-ELF on Solaris)
+ the defaults below will have to be overridden, like
+ i386_elf_init_abi() does. */
+
+ /* Use the dbx register numbering scheme for stabs and COFF. */
+ set_gdbarch_stab_reg_to_regnum (gdbarch, i386_dbx_reg_to_regnum);
+ set_gdbarch_sdb_reg_to_regnum (gdbarch, i386_dbx_reg_to_regnum);
+
+ /* Use the SVR4 register numbering scheme for DWARF and DWARF 2. */
+ set_gdbarch_dwarf_reg_to_regnum (gdbarch, i386_svr4_reg_to_regnum);
+ set_gdbarch_dwarf2_reg_to_regnum (gdbarch, i386_svr4_reg_to_regnum);
/* We don't define ECOFF_REG_TO_REGNUM, since ECOFF doesn't seem to
be in use on any of the supported i386 targets. */
set_gdbarch_register_to_value (gdbarch, i386_register_to_value);
set_gdbarch_value_to_register (gdbarch, i386_value_to_register);
- set_gdbarch_extract_return_value (gdbarch, i386_extract_return_value);
- set_gdbarch_store_return_value (gdbarch, i386_store_return_value);
- set_gdbarch_extract_struct_value_address (gdbarch,
- i386_extract_struct_value_address);
- set_gdbarch_use_struct_convention (gdbarch, i386_use_struct_convention);
+ set_gdbarch_return_value (gdbarch, i386_return_value);
set_gdbarch_skip_prologue (gdbarch, i386_skip_prologue);
set_gdbarch_breakpoint_from_pc (gdbarch, i386_breakpoint_from_pc);
set_gdbarch_decr_pc_after_break (gdbarch, 1);
- set_gdbarch_function_start_offset (gdbarch, 0);
set_gdbarch_frame_args_skip (gdbarch, 8);
- set_gdbarch_pc_in_sigtramp (gdbarch, i386_pc_in_sigtramp);
/* Wire in the MMX registers. */
set_gdbarch_num_pseudo_regs (gdbarch, i386_num_mmx_regs);
frame_unwind_append_sniffer (gdbarch, i386_sigtramp_frame_sniffer);
frame_unwind_append_sniffer (gdbarch, i386_frame_sniffer);
+ /* If we have a register mapping, enable the generic core file
+ support, unless it has already been enabled. */
+ if (tdep->gregset_reg_offset
+ && !gdbarch_regset_from_core_section_p (gdbarch))
+ set_gdbarch_regset_from_core_section (gdbarch,
+ i386_regset_from_core_section);
+
/* Unless support for MMX has been disabled, make %mm0 the first
pseudo-register. */
if (tdep->mm0_regnum == 0)