* gdbint.texinfo (Target Architecture Definition): Remove
[deliverable/binutils-gdb.git] / gdb / i386-tdep.c
index 27f3d272e5c11a9c311a44a15c1f83feadca240c..19e7ed9f975c4eabbc97ea36ab5e0381f2662070 100644 (file)
@@ -1,7 +1,8 @@
 /* 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.
 
@@ -50,8 +51,7 @@
 #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[] =
 {
@@ -70,7 +70,7 @@ 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[] =
 {
@@ -165,17 +165,24 @@ i386_register_name (int reg)
   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)
     {
@@ -197,13 +204,16 @@ i386_stab_reg_to_regnum (int reg)
   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)
     {
@@ -217,8 +227,8 @@ i386_dwarf_reg_to_regnum (int reg)
     }
   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.  */
@@ -499,16 +509,22 @@ i386_analyze_frame_setup (CORE_ADDR pc, CORE_ADDR current_pc,
            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)
@@ -516,6 +532,7 @@ i386_analyze_frame_setup (CORE_ADDR pc, CORE_ADDR current_pc,
            case 0xdb:  /* %ebx */
            case 0xc9:  /* %ecx */
            case 0xd2:  /* %edx */
+           case 0xc0:  /* %eax */
              skip += 2;
              break;
            default:
@@ -555,12 +572,12 @@ i386_analyze_frame_setup (CORE_ADDR pc, CORE_ADDR current_pc,
 
            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;
@@ -572,12 +589,12 @@ i386_analyze_frame_setup (CORE_ADDR pc, CORE_ADDR current_pc,
        }
       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;
        }
@@ -640,9 +657,9 @@ i386_analyze_register_saves (CORE_ADDR pc, CORE_ADDR current_pc,
    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,
@@ -733,7 +750,13 @@ i386_skip_prologue (CORE_ADDR start_pc)
        }
     }
 
-  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.  */
@@ -1002,17 +1025,27 @@ static const struct frame_unwind i386_sigtramp_frame_unwind =
 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;
 }
@@ -1086,7 +1119,7 @@ i386_get_longjmp_target (CORE_ADDR *pc)
 \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)
@@ -1134,7 +1167,7 @@ i386_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_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
@@ -1148,26 +1181,17 @@ i386_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_addr,
 #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)
@@ -1199,7 +1223,7 @@ i386_extract_return_value (struct type *type, struct regcache *regcache,
          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__,
@@ -1207,27 +1231,20 @@ i386_extract_return_value (struct type *type, struct regcache *regcache,
     }
 }
 
-/* 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;
@@ -1283,19 +1300,6 @@ i386_store_return_value (struct type *type, struct regcache *regcache,
 
 #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
@@ -1312,20 +1316,83 @@ static const char *valid_conventions[] =
 };
 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
 
@@ -1415,14 +1482,6 @@ i386_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
 }
 \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.  */
 
@@ -1501,7 +1560,7 @@ i386_register_to_value (struct frame_info *frame, int regnum,
       return;
     }
 
-  /* Read a value spread accross multiple registers.  */
+  /* Read a value spread across multiple registers.  */
 
   gdb_assert (len > 4 && len % 4 == 0);
 
@@ -1533,7 +1592,7 @@ i386_value_to_register (struct frame_info *frame, int regnum,
       return;
     }
 
-  /* Write a value spread accross multiple registers.  */
+  /* Write a value spread across multiple registers.  */
 
   gdb_assert (len > 4 && len % 4 == 0);
 
@@ -1549,15 +1608,15 @@ i386_value_to_register (struct frame_info *frame, int regnum,
     }
 }
 \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;
 
@@ -1571,19 +1630,101 @@ i386_supply_gregset (const struct regset *regset, struct regcache *regcache,
     }
 }
 
-/* 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
@@ -1635,12 +1776,16 @@ i386_pe_skip_trampoline_code (CORE_ADDR pc, char *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
@@ -1670,11 +1815,18 @@ i386_print_insn (bfd_vma pc, struct disassemble_info *info)
 
 /* 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));
@@ -1697,23 +1849,13 @@ i386_svr4_sigcontext_addr (struct frame_info *next_frame)
 }
 \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).  */
@@ -1730,7 +1872,7 @@ i386_svr4_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
   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;
@@ -1745,7 +1887,8 @@ i386_go32_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
 {
   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;
 }
@@ -1850,7 +1993,7 @@ i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   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
@@ -1866,7 +2009,7 @@ i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   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;
 
@@ -1877,6 +2020,7 @@ i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   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;
@@ -1905,13 +2049,43 @@ i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   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.  */
@@ -1927,11 +2101,7 @@ i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   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);
 
@@ -1940,10 +2110,8 @@ i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 
   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);
@@ -1974,6 +2142,13 @@ i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   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)
This page took 0.129372 seconds and 4 git commands to generate.