OSDN Git Service

* dwarf2-frame.c (dwarf2_frame_cache, dwarf2_frame_this_id)
[pf3gnuchains/pf3gnuchains3x.git] / gdb / i386-tdep.c
index cfe426d..4d9583d 100644 (file)
@@ -1,8 +1,8 @@
 /* Intel 386 target-dependent stuff.
 
-   Copyright 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996,
-   1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software
-   Foundation, Inc.
+   Copyright (C) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
+   1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
+   Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -18,8 +18,8 @@
 
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place - Suite 330,
-   Boston, MA 02111-1307, USA.  */
+   Foundation, Inc., 51 Franklin Street, Fifth Floor,
+   Boston, MA 02110-1301, USA.  */
 
 #include "defs.h"
 #include "arch-utils.h"
 #include "dummy-frame.h"
 #include "dwarf2-frame.h"
 #include "doublest.h"
-#include "floatformat.h"
 #include "frame.h"
 #include "frame-base.h"
 #include "frame-unwind.h"
 #include "inferior.h"
 #include "gdbcmd.h"
 #include "gdbcore.h"
+#include "gdbtypes.h"
 #include "objfiles.h"
 #include "osabi.h"
 #include "regcache.h"
@@ -51,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[] =
 {
@@ -71,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[] =
 {
@@ -152,63 +151,29 @@ i386_fpc_regnum_p (int regnum)
   return (I387_FCTRL_REGNUM <= regnum && regnum < I387_XMM0_REGNUM);
 }
 
-/* Return the name of register REG.  */
+/* Return the name of register REGNUM.  */
 
 const char *
-i386_register_name (int reg)
+i386_register_name (int regnum)
 {
-  if (i386_mmx_regnum_p (current_gdbarch, reg))
-    return i386_mmx_names[reg - I387_MM0_REGNUM];
+  if (i386_mmx_regnum_p (current_gdbarch, regnum))
+    return i386_mmx_names[regnum - I387_MM0_REGNUM];
 
-  if (reg >= 0 && reg < i386_num_register_names)
-    return i386_register_names[reg];
+  if (regnum >= 0 && regnum < i386_num_register_names)
+    return i386_register_names[regnum];
 
   return NULL;
 }
 
-
-/* FIXME: jimb/2004-04-01: I don't think these functions are right.
-   For a given platform, GCC always uses the same register numbering
-   in both STABS and Dwarf2: gcc/dbxout.c and gcc/dwarf2out.c both use
-   the DBX_REGISTER_NUMBER macro, as defined by the config headers.
-   If you compile a program so that its variables are allocated to
-   floating-point registers, first with STABS and again with Dwarf 2,
-   you'll see that the variable's register numbers are the same in
-   each case.
-
-   GCC does use (at least) two different register numberings on the
-   i386; they differ in how they number %ebp, %esp, %eflags, and the
-   floating-point registers.  And it has a third numbering for "64bit
-   mode", which I assume is x86_64.  But it always uses a given
-   numbering in both STABS and Dwarf.
-
-   This does not match the arrangement we have below, which presumes
-   that STABS and Dwarf numberings are different, and does some
-   strange mixing and matching (e.g., registering the Dwarf 2 function
-   as the STABS function for "Generic i386 ELF") to get close enough
-   to the right effect on the platforms we care about.
-
-   If we wanted to match GCC, we should have two separate register
-   number translation functions (we handle x86_64 in a separate tdep
-   file altogether), one corresponding to each of GCC's i386 register
-   maps.  And for a given platform, we would register one of them as
-   both the STABS and Dwarf 2 functions.
-
-   However, we don't aspire to match GCC; we aspire to match the
-   native system's tools.  I don't have access to lots of different
-   native compilers and debuggers to verify that GCC is matching their
-   behavior in this regard.  Is it sufficient to argue that we at
-   least want to match GNU's compiler, and say we'll fix bugs relative
-   to native tools as they're reported?  */
-
-
-/* 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.  The debug info calls %ebp
@@ -239,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)
     {
@@ -257,10 +225,23 @@ i386_dwarf_reg_to_regnum (int reg)
       /* Floating-point registers.  */
       return reg - 11 + I387_ST0_REGNUM;
     }
-  else if (reg >= 21)
+  else if (reg >= 21 && reg <= 36)
+    {
+      /* The SSE and MMX registers have the same numbers as with dbx.  */
+      return i386_dbx_reg_to_regnum (reg);
+    }
+
+  switch (reg)
     {
-      /* The SSE and MMX registers have identical numbers as in stabs.  */
-      return i386_stab_reg_to_regnum (reg);
+    case 37: return I387_FCTRL_REGNUM;
+    case 38: return I387_FSTAT_REGNUM;
+    case 39: return I387_MXCSR_REGNUM;
+    case 40: return I386_ES_REGNUM;
+    case 41: return I386_CS_REGNUM;
+    case 42: return I386_SS_REGNUM;
+    case 43: return I386_DS_REGNUM;
+    case 44: return I386_FS_REGNUM;
+    case 45: return I386_GS_REGNUM;
     }
 
   /* This will hopefully provoke a warning.  */
@@ -295,12 +276,12 @@ static const char *disassembly_flavor = att_flavor;
    and can be inserted anywhere.
 
    This function is 64-bit safe.  */
-   
-static const unsigned char *
+
+static const gdb_byte *
 i386_breakpoint_from_pc (CORE_ADDR *pc, int *len)
 {
-  static unsigned char break_insn[] = { 0xcc };        /* int 3 */
-  
+  static gdb_byte break_insn[] = { 0xcc }; /* int 3 */
+
   *len = sizeof (break_insn);
   return break_insn;
 }
@@ -321,12 +302,13 @@ struct i386_frame_cache
 {
   /* Base address.  */
   CORE_ADDR base;
-  CORE_ADDR sp_offset;
+  LONGEST sp_offset;
   CORE_ADDR pc;
 
   /* Saved registers.  */
   CORE_ADDR saved_regs[I386_NUM_SAVED_REGS];
   CORE_ADDR saved_sp;
+  int stack_align;
   int pc_in_eax;
 
   /* Stack space reserved for local variables.  */
@@ -353,6 +335,7 @@ i386_alloc_frame_cache (void)
   for (i = 0; i < I386_NUM_SAVED_REGS; i++)
     cache->saved_regs[i] = -1;
   cache->saved_sp = 0;
+  cache->stack_align = 0;
   cache->pc_in_eax = 0;
 
   /* Frameless until proven otherwise.  */
@@ -367,11 +350,11 @@ i386_alloc_frame_cache (void)
 static CORE_ADDR
 i386_follow_jump (CORE_ADDR pc)
 {
-  unsigned char op;
+  gdb_byte op;
   long delta = 0;
   int data16 = 0;
 
-  op = read_memory_unsigned_integer (pc, 1);
+  read_memory_nobpt (pc, &op, 1);
   if (op == 0x66)
     {
       data16 = 1;
@@ -429,20 +412,20 @@ i386_analyze_struct_return (CORE_ADDR pc, CORE_ADDR current_pc,
      and the assembler doesn't try to optimize it, so the 'sib' form
      gets generated).  This sequence is used to get the address of the
      return buffer for a function that returns a structure.  */
-  static unsigned char proto1[3] = { 0x87, 0x04, 0x24 };
-  static unsigned char proto2[4] = { 0x87, 0x44, 0x24, 0x00 };
-  unsigned char buf[4];
-  unsigned char op;
+  static gdb_byte proto1[3] = { 0x87, 0x04, 0x24 };
+  static gdb_byte proto2[4] = { 0x87, 0x44, 0x24, 0x00 };
+  gdb_byte buf[4];
+  gdb_byte op;
 
   if (current_pc <= pc)
     return pc;
 
-  op = read_memory_unsigned_integer (pc, 1);
+  read_memory_nobpt (pc, &op, 1);
 
   if (op != 0x58)              /* popl %eax */
     return pc;
 
-  read_memory (pc + 1, buf, 4);
+  read_memory_nobpt (pc + 1, buf, 4);
   if (memcmp (buf, proto1, 3) != 0 && memcmp (buf, proto2, 4) != 0)
     return pc;
 
@@ -478,10 +461,10 @@ i386_skip_probe (CORE_ADDR pc)
         pushl %ebp
 
      etc.  */
-  unsigned char buf[8];
-  unsigned char op;
+  gdb_byte buf[8];
+  gdb_byte op;
 
-  op = read_memory_unsigned_integer (pc, 1);
+  read_memory_nobpt (pc, &op, 1);
 
   if (op == 0x68 || op == 0x6a)
     {
@@ -504,23 +487,170 @@ i386_skip_probe (CORE_ADDR pc)
   return pc;
 }
 
+/* GCC 4.1 and later, can put code in the prologue to realign the
+   stack pointer.  Check whether PC points to such code, and update
+   CACHE accordingly.  Return the first instruction after the code
+   sequence or CURRENT_PC, whichever is smaller.  If we don't
+   recognize the code, return PC.  */
+
+static CORE_ADDR
+i386_analyze_stack_align (CORE_ADDR pc, CORE_ADDR current_pc,
+                         struct i386_frame_cache *cache)
+{
+  /* The register used by the compiler to perform the stack re-alignment 
+     is, in order of preference, either %ecx, %edx, or %eax.  GCC should
+     never use %ebx as it always treats it as callee-saved, whereas
+     the compiler can only use caller-saved registers.  */
+  static const gdb_byte insns_ecx[10] = { 
+    0x8d, 0x4c, 0x24, 0x04,    /* leal  4(%esp), %ecx */
+    0x83, 0xe4, 0xf0,          /* andl  $-16, %esp */
+    0xff, 0x71, 0xfc           /* pushl -4(%ecx) */
+  };
+  static const gdb_byte insns_edx[10] = { 
+    0x8d, 0x54, 0x24, 0x04,    /* leal  4(%esp), %edx */
+    0x83, 0xe4, 0xf0,          /* andl  $-16, %esp */
+    0xff, 0x72, 0xfc           /* pushl -4(%edx) */
+  };
+  static const gdb_byte insns_eax[10] = { 
+    0x8d, 0x44, 0x24, 0x04,    /* leal  4(%esp), %eax */
+    0x83, 0xe4, 0xf0,          /* andl  $-16, %esp */
+    0xff, 0x70, 0xfc           /* pushl -4(%eax) */
+  };
+  gdb_byte buf[10];
+
+  if (target_read_memory (pc, buf, sizeof buf)
+      || (memcmp (buf, insns_ecx, sizeof buf) != 0
+          && memcmp (buf, insns_edx, sizeof buf) != 0
+          && memcmp (buf, insns_eax, sizeof buf) != 0))
+    return pc;
+
+  if (current_pc > pc + 4)
+    cache->stack_align = 1;
+
+  return min (pc + 10, current_pc);
+}
+
+/* Maximum instruction length we need to handle.  */
+#define I386_MAX_INSN_LEN      6
+
+/* Instruction description.  */
+struct i386_insn
+{
+  size_t len;
+  gdb_byte insn[I386_MAX_INSN_LEN];
+  gdb_byte mask[I386_MAX_INSN_LEN];
+};
+
+/* Search for the instruction at PC in the list SKIP_INSNS.  Return
+   the first instruction description that matches.  Otherwise, return
+   NULL.  */
+
+static struct i386_insn *
+i386_match_insn (CORE_ADDR pc, struct i386_insn *skip_insns)
+{
+  struct i386_insn *insn;
+  gdb_byte op;
+
+  read_memory_nobpt (pc, &op, 1);
+
+  for (insn = skip_insns; insn->len > 0; insn++)
+    {
+      if ((op & insn->mask[0]) == insn->insn[0])
+       {
+         gdb_byte buf[I386_MAX_INSN_LEN - 1];
+         int insn_matched = 1;
+         size_t i;
+
+         gdb_assert (insn->len > 1);
+         gdb_assert (insn->len <= I386_MAX_INSN_LEN);
+
+         read_memory_nobpt (pc + 1, buf, insn->len - 1);
+         for (i = 1; i < insn->len; i++)
+           {
+             if ((buf[i - 1] & insn->mask[i]) != insn->insn[i])
+               insn_matched = 0;
+           }
+
+         if (insn_matched)
+           return insn;
+       }
+    }
+
+  return NULL;
+}
+
+/* Some special instructions that might be migrated by GCC into the
+   part of the prologue that sets up the new stack frame.  Because the
+   stack frame hasn't been setup yet, no registers have been saved
+   yet, and only the scratch registers %eax, %ecx and %edx can be
+   touched.  */
+
+struct i386_insn i386_frame_setup_skip_insns[] =
+{
+  /* Check for `movb imm8, r' and `movl imm32, r'. 
+    
+     ??? Should we handle 16-bit operand-sizes here?  */
+
+  /* `movb imm8, %al' and `movb imm8, %ah' */
+  /* `movb imm8, %cl' and `movb imm8, %ch' */
+  { 2, { 0xb0, 0x00 }, { 0xfa, 0x00 } },
+  /* `movb imm8, %dl' and `movb imm8, %dh' */
+  { 2, { 0xb2, 0x00 }, { 0xfb, 0x00 } },
+  /* `movl imm32, %eax' and `movl imm32, %ecx' */
+  { 5, { 0xb8 }, { 0xfe } },
+  /* `movl imm32, %edx' */
+  { 5, { 0xba }, { 0xff } },
+
+  /* Check for `mov imm32, r32'.  Note that there is an alternative
+     encoding for `mov m32, %eax'.
+
+     ??? Should we handle SIB adressing here?
+     ??? Should we handle 16-bit operand-sizes here?  */
+
+  /* `movl m32, %eax' */
+  { 5, { 0xa1 }, { 0xff } },
+  /* `movl m32, %eax' and `mov; m32, %ecx' */
+  { 6, { 0x89, 0x05 }, {0xff, 0xf7 } },
+  /* `movl m32, %edx' */
+  { 6, { 0x89, 0x15 }, {0xff, 0xff } },
+
+  /* Check for `xorl r32, r32' and the equivalent `subl r32, r32'.
+     Because of the symmetry, there are actually two ways to encode
+     these instructions; opcode bytes 0x29 and 0x2b for `subl' and
+     opcode bytes 0x31 and 0x33 for `xorl'.  */
+
+  /* `subl %eax, %eax' */
+  { 2, { 0x29, 0xc0 }, { 0xfd, 0xff } },
+  /* `subl %ecx, %ecx' */
+  { 2, { 0x29, 0xc9 }, { 0xfd, 0xff } },
+  /* `subl %edx, %edx' */
+  { 2, { 0x29, 0xd2 }, { 0xfd, 0xff } },
+  /* `xorl %eax, %eax' */
+  { 2, { 0x31, 0xc0 }, { 0xfd, 0xff } },
+  /* `xorl %ecx, %ecx' */
+  { 2, { 0x31, 0xc9 }, { 0xfd, 0xff } },
+  /* `xorl %edx, %edx' */
+  { 2, { 0x31, 0xd2 }, { 0xfd, 0xff } },
+  { 0 }
+};
+
 /* Check whether PC points at a code that sets up a new stack frame.
    If so, it updates CACHE and returns the address of the first
-   instruction after the sequence that sets removes the "hidden"
-   argument from the stack or CURRENT_PC, whichever is smaller.
-   Otherwise, return PC.  */
+   instruction after the sequence that sets up the frame or LIMIT,
+   whichever is smaller.  If we don't recognize the code, return PC.  */
 
 static CORE_ADDR
-i386_analyze_frame_setup (CORE_ADDR pc, CORE_ADDR current_pc,
+i386_analyze_frame_setup (CORE_ADDR pc, CORE_ADDR limit,
                          struct i386_frame_cache *cache)
 {
-  unsigned char op;
+  struct i386_insn *insn;
+  gdb_byte op;
   int skip = 0;
 
-  if (current_pc <= pc)
-    return current_pc;
+  if (limit <= pc)
+    return limit;
 
-  op = read_memory_unsigned_integer (pc, 1);
+  read_memory_nobpt (pc, &op, 1);
 
   if (op == 0x55)              /* pushl %ebp */
     {
@@ -528,65 +658,48 @@ i386_analyze_frame_setup (CORE_ADDR pc, CORE_ADDR current_pc,
         starts this instruction sequence.  */
       cache->saved_regs[I386_EBP_REGNUM] = 0;
       cache->sp_offset += 4;
+      pc++;
 
       /* If that's all, return now.  */
-      if (current_pc <= pc + 1)
-       return current_pc;
-
-      op = read_memory_unsigned_integer (pc + 1, 1);
-
-      /* Check for some special instructions that might be migrated
-        by GCC into the prologue.  We check for
-
-           xorl %ebx, %ebx
-           xorl %ecx, %ecx
-           xorl %edx, %edx
-           xorl %eax, %eax
-
-        and the equivalent
+      if (limit <= pc)
+       return limit;
 
-           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'.
+      /* Check for some special instructions that might be migrated by
+        GCC into the prologue and skip them.  At this point in the
+        prologue, code should only touch the scratch registers %eax,
+        %ecx and %edx, so while the number of posibilities is sheer,
+        it is limited.
 
         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 == 0x2b || op == 0x31 || op == 0x33)
+      while (pc + skip < limit)
        {
-         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:
-             return pc + 1;
-           }
+         insn = i386_match_insn (pc + skip, i386_frame_setup_skip_insns);
+         if (insn == NULL)
+           break;
 
-         op = read_memory_unsigned_integer (pc + skip + 1, 1);
+         skip += insn->len;
        }
 
+      /* If that's all, return now.  */
+      if (limit <= pc + skip)
+       return limit;
+
+      read_memory_nobpt (pc + skip, &op, 1);
+
       /* Check for `movl %esp, %ebp' -- can be written in two ways.  */
       switch (op)
        {
        case 0x8b:
-         if (read_memory_unsigned_integer (pc + skip + 2, 1) != 0xec)
-           return pc + 1;
+         if (read_memory_unsigned_integer (pc + skip + 1, 1) != 0xec)
+           return pc;
          break;
        case 0x89:
-         if (read_memory_unsigned_integer (pc + skip + 2, 1) != 0xe5)
-           return pc + 1;
+         if (read_memory_unsigned_integer (pc + skip + 1, 1) != 0xe5)
+           return pc;
          break;
        default:
-         return pc + 1;
+         return pc;
        }
 
       /* OK, we actually have a frame.  We just don't know how large
@@ -594,49 +707,49 @@ i386_analyze_frame_setup (CORE_ADDR pc, CORE_ADDR current_pc,
         necessary.  We also now commit to skipping the special
         instructions mentioned before.  */
       cache->locals = 0;
-      pc += skip;
+      pc += (skip + 2);
 
       /* If that's all, return now.  */
-      if (current_pc <= pc + 3)
-       return current_pc;
+      if (limit <= pc)
+       return limit;
 
       /* Check for stack adjustment 
 
            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);
+      read_memory_nobpt (pc, &op, 1);
       if (op == 0x83)
        {
-         /* `subl' with 8 bit immediate.  */
-         if (read_memory_unsigned_integer (pc + 4, 1) != 0xec)
+         /* `subl' with 8-bit immediate.  */
+         if (read_memory_unsigned_integer (pc + 1, 1) != 0xec)
            /* Some instruction starting with 0x83 other than `subl'.  */
-           return pc + 3;
+           return pc;
 
-         /* `subl' with signed byte immediate (though it wouldn't make
-            sense to be negative).  */
-         cache->locals = read_memory_integer (pc + 5, 1);
-         return pc + 6;
+         /* `subl' with signed 8-bit immediate (though it wouldn't
+            make sense to be negative).  */
+         cache->locals = read_memory_integer (pc + 2, 1);
+         return pc + 3;
        }
       else if (op == 0x81)
        {
-         /* Maybe it is `subl' with a 32 bit immedediate.  */
-         if (read_memory_unsigned_integer (pc + 4, 1) != 0xec)
+         /* Maybe it is `subl' with a 32-bit immediate.  */
+         if (read_memory_unsigned_integer (pc + 1, 1) != 0xec)
            /* Some instruction starting with 0x81 other than `subl'.  */
-           return pc + 3;
+           return pc;
 
-         /* It is `subl' with a 32 bit immediate.  */
-         cache->locals = read_memory_integer (pc + 5, 4);
-         return pc + 9;
+         /* It is `subl' with a 32-bit immediate.  */
+         cache->locals = read_memory_integer (pc + 2, 4);
+         return pc + 6;
        }
       else
        {
          /* Some instruction other than `subl'.  */
-         return pc + 3;
+         return pc;
        }
     }
-  else if (op == 0xc8)         /* enter $XXX */
+  else if (op == 0xc8)         /* enter */
     {
       cache->locals = read_memory_unsigned_integer (pc + 1, 2);
       return pc + 4;
@@ -655,14 +768,14 @@ i386_analyze_register_saves (CORE_ADDR pc, CORE_ADDR current_pc,
                             struct i386_frame_cache *cache)
 {
   CORE_ADDR offset = 0;
-  unsigned char op;
+  gdb_byte op;
   int i;
 
   if (cache->locals > 0)
     offset -= cache->locals;
   for (i = 0; i < 8 && pc < current_pc; i++)
     {
-      op = read_memory_unsigned_integer (pc, 1);
+      read_memory_nobpt (pc, &op, 1);
       if (op < 0x50 || op > 0x57)
        break;
 
@@ -689,9 +802,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,
@@ -709,6 +822,7 @@ i386_analyze_prologue (CORE_ADDR pc, CORE_ADDR current_pc,
   pc = i386_follow_jump (pc);
   pc = i386_analyze_struct_return (pc, current_pc, cache);
   pc = i386_skip_probe (pc);
+  pc = i386_analyze_stack_align (pc, current_pc, cache);
   pc = i386_analyze_frame_setup (pc, current_pc, cache);
   return i386_analyze_register_saves (pc, current_pc, cache);
 }
@@ -718,14 +832,14 @@ i386_analyze_prologue (CORE_ADDR pc, CORE_ADDR current_pc,
 static CORE_ADDR
 i386_skip_prologue (CORE_ADDR start_pc)
 {
-  static unsigned char pic_pat[6] =
+  static gdb_byte pic_pat[6] =
   {
     0xe8, 0, 0, 0, 0,          /* call 0x0 */
     0x5b,                      /* popl %ebx */
   };
   struct i386_frame_cache cache;
   CORE_ADDR pc;
-  unsigned char op;
+  gdb_byte op;
   int i;
 
   cache.locals = -1;
@@ -750,7 +864,7 @@ i386_skip_prologue (CORE_ADDR start_pc)
 
   for (i = 0; i < 6; i++)
     {
-      op = read_memory_unsigned_integer (pc + i, 1);
+      read_memory_nobpt (pc + i, &op, 1);
       if (pic_pat[i] != op)
        break;
     }
@@ -758,7 +872,7 @@ i386_skip_prologue (CORE_ADDR start_pc)
     {
       int delta = 6;
 
-      op = read_memory_unsigned_integer (pc + delta, 1);
+      read_memory_nobpt (pc + delta, &op, 1);
 
       if (op == 0x89)          /* movl %ebx, x(%ebp) */
        {
@@ -771,18 +885,24 @@ i386_skip_prologue (CORE_ADDR start_pc)
          else                  /* Unexpected instruction.  */
            delta = 0;
 
-         op = read_memory_unsigned_integer (pc + delta, 1);
+          read_memory_nobpt (pc + delta, &op, 1);
        }
 
       /* addl y,%ebx */
       if (delta > 0 && op == 0x81
-         && read_memory_unsigned_integer (pc + delta + 1, 1) == 0xc3);
+         && read_memory_unsigned_integer (pc + delta + 1, 1) == 0xc3)
        {
          pc += delta + 6;
        }
     }
 
-  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.  */
@@ -790,7 +910,7 @@ i386_skip_prologue (CORE_ADDR start_pc)
 static CORE_ADDR
 i386_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
 {
-  char buf[8];
+  gdb_byte buf[8];
 
   frame_unwind_register (next_frame, PC_REGNUM, buf);
   return extract_typed_address (buf, builtin_type_void_func_ptr);
@@ -803,7 +923,7 @@ static struct i386_frame_cache *
 i386_frame_cache (struct frame_info *next_frame, void **this_cache)
 {
   struct i386_frame_cache *cache;
-  char buf[4];
+  gdb_byte buf[4];
   int i;
 
   if (*this_cache)
@@ -829,10 +949,17 @@ i386_frame_cache (struct frame_info *next_frame, void **this_cache)
   /* For normal frames, %eip is stored at 4(%ebp).  */
   cache->saved_regs[I386_EIP_REGNUM] = 4;
 
-  cache->pc = frame_func_unwind (next_frame);
+  cache->pc = frame_func_unwind (next_frame, NORMAL_FRAME);
   if (cache->pc != 0)
     i386_analyze_prologue (cache->pc, frame_pc_unwind (next_frame), cache);
 
+  if (cache->stack_align)
+    {
+      /* Saved stack pointer has been saved in %ecx.  */
+      frame_unwind_register (next_frame, I386_ECX_REGNUM, buf);
+      cache->saved_sp = extract_unsigned_integer(buf, 4);
+    }
+
   if (cache->locals < 0)
     {
       /* We didn't find a valid frame, which means that CACHE->base
@@ -843,13 +970,26 @@ i386_frame_cache (struct frame_info *next_frame, void **this_cache)
         frame by looking at the stack pointer.  For truly "frameless"
         functions this might work too.  */
 
-      frame_unwind_register (next_frame, I386_ESP_REGNUM, buf);
-      cache->base = extract_unsigned_integer (buf, 4) + cache->sp_offset;
+      if (cache->stack_align)
+       {
+         /* We're halfway aligning the stack.  */
+         cache->base = ((cache->saved_sp - 4) & 0xfffffff0) - 4;
+         cache->saved_regs[I386_EIP_REGNUM] = cache->saved_sp - 4;
+
+         /* This will be added back below.  */
+         cache->saved_regs[I386_EIP_REGNUM] -= cache->base;
+       }
+      else
+       {
+         frame_unwind_register (next_frame, I386_ESP_REGNUM, buf);
+         cache->base = extract_unsigned_integer (buf, 4) + cache->sp_offset;
+       }
     }
 
   /* Now that we have the base address for the stack frame we can
      calculate the value of %esp in the calling frame.  */
-  cache->saved_sp = cache->base + 8;
+  if (cache->saved_sp == 0)
+    cache->saved_sp = cache->base + 8;
 
   /* Adjust all the saved registers such that they contain addresses
      instead of offsets.  */
@@ -878,7 +1018,7 @@ static void
 i386_frame_prev_register (struct frame_info *next_frame, void **this_cache,
                          int regnum, int *optimizedp,
                          enum lval_type *lvalp, CORE_ADDR *addrp,
-                         int *realnump, void *valuep)
+                         int *realnump, gdb_byte *valuep)
 {
   struct i386_frame_cache *cache = i386_frame_cache (next_frame, this_cache);
 
@@ -925,8 +1065,12 @@ i386_frame_prev_register (struct frame_info *next_frame, void **this_cache,
 
   if (regnum == I386_EIP_REGNUM && cache->pc_in_eax)
     {
-      frame_register_unwind (next_frame, I386_EAX_REGNUM,
-                            optimizedp, lvalp, addrp, realnump, valuep);
+      *optimizedp = 0;
+      *lvalp = lval_register;
+      *addrp = 0;
+      *realnump = I386_EAX_REGNUM;
+      if (valuep)
+       frame_unwind_register (next_frame, (*realnump), valuep);
       return;
     }
 
@@ -959,8 +1103,12 @@ i386_frame_prev_register (struct frame_info *next_frame, void **this_cache,
       return;
     }
 
-  frame_register_unwind (next_frame, regnum,
-                        optimizedp, lvalp, addrp, realnump, valuep);
+  *optimizedp = 0;
+  *lvalp = lval_register;
+  *addrp = 0;
+  *realnump = regnum;
+  if (valuep)
+    frame_unwind_register (next_frame, (*realnump), valuep);
 }
 
 static const struct frame_unwind i386_frame_unwind =
@@ -985,7 +1133,7 @@ i386_sigtramp_frame_cache (struct frame_info *next_frame, void **this_cache)
   struct i386_frame_cache *cache;
   struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
   CORE_ADDR addr;
-  char buf[4];
+  gdb_byte buf[4];
 
   if (*this_cache)
     return *this_cache;
@@ -1032,7 +1180,7 @@ i386_sigtramp_frame_prev_register (struct frame_info *next_frame,
                                   void **this_cache,
                                   int regnum, int *optimizedp,
                                   enum lval_type *lvalp, CORE_ADDR *addrp,
-                                  int *realnump, void *valuep)
+                                  int *realnump, gdb_byte *valuep)
 {
   /* Make sure we've initialized the cache.  */
   i386_sigtramp_frame_cache (next_frame, this_cache);
@@ -1051,17 +1199,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 (DEPRECATED_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 +1244,7 @@ static const struct frame_base i386_frame_base =
 static struct frame_id
 i386_unwind_dummy_id (struct gdbarch *gdbarch, struct frame_info *next_frame)
 {
-  char buf[4];
+  gdb_byte buf[4];
   CORE_ADDR fp;
 
   frame_unwind_register (next_frame, I386_EBP_REGNUM, buf);
@@ -1108,7 +1266,7 @@ i386_unwind_dummy_id (struct gdbarch *gdbarch, struct frame_info *next_frame)
 static int
 i386_get_longjmp_target (CORE_ADDR *pc)
 {
-  char buf[8];
+  gdb_byte buf[8];
   CORE_ADDR sp, jb_addr;
   int jb_pc_offset = gdbarch_tdep (current_gdbarch)->jb_pc_offset;
   int len = TYPE_LENGTH (builtin_type_void_func_ptr);
@@ -1135,18 +1293,18 @@ 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)
 {
-  char buf[4];
+  gdb_byte buf[4];
   int i;
 
   /* Push arguments in reverse order.  */
   for (i = nargs - 1; i >= 0; i--)
     {
-      int len = TYPE_LENGTH (VALUE_ENCLOSING_TYPE (args[i]));
+      int len = TYPE_LENGTH (value_enclosing_type (args[i]));
 
       /* The System V ABI says that:
 
@@ -1154,9 +1312,9 @@ i386_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_addr,
         multiple of [32-bit] words.  This may require tail padding,
         depending on the size of the argument."
 
-        This makes sure the stack says word-aligned.  */
+        This makes sure the stack stays word-aligned.  */
       sp -= (len + 3) & ~3;
-      write_memory (sp, VALUE_CONTENTS_ALL (args[i]), len);
+      write_memory (sp, value_contents_all (args[i]), len);
     }
 
   /* Push value address.  */
@@ -1183,7 +1341,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
@@ -1202,17 +1360,17 @@ i386_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_addr,
 
 static void
 i386_extract_return_value (struct gdbarch *gdbarch, struct type *type,
-                          struct regcache *regcache, void *valbuf)
+                          struct regcache *regcache, gdb_byte *valbuf)
 {
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
   int len = TYPE_LENGTH (type);
-  char buf[I386_MAX_REGISTER_SIZE];
+  gdb_byte buf[I386_MAX_REGISTER_SIZE];
 
   if (TYPE_CODE (type) == TYPE_CODE_FLT)
     {
       if (tdep->st0_regnum < 0)
        {
-         warning ("Cannot find floating-point return value.");
+         warning (_("Cannot find floating-point return value."));
          memset (valbuf, 0, len);
          return;
        }
@@ -1239,11 +1397,11 @@ i386_extract_return_value (struct gdbarch *gdbarch, struct type *type,
          regcache_raw_read (regcache, LOW_RETURN_REGNUM, buf);
          memcpy (valbuf, buf, low_size);
          regcache_raw_read (regcache, HIGH_RETURN_REGNUM, buf);
-         memcpy ((char *) valbuf + low_size, buf, len - low_size);
+         memcpy (valbuf + low_size, buf, len - low_size);
        }
       else
        internal_error (__FILE__, __LINE__,
-                       "Cannot extract return value of %d bytes long.", len);
+                       _("Cannot extract return value of %d bytes long."), len);
     }
 }
 
@@ -1252,7 +1410,7 @@ i386_extract_return_value (struct gdbarch *gdbarch, struct type *type,
 
 static void
 i386_store_return_value (struct gdbarch *gdbarch, struct type *type,
-                        struct regcache *regcache, const void *valbuf)
+                        struct regcache *regcache, const gdb_byte *valbuf)
 {
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
   int len = TYPE_LENGTH (type);
@@ -1264,11 +1422,11 @@ i386_store_return_value (struct gdbarch *gdbarch, struct type *type,
   if (TYPE_CODE (type) == TYPE_CODE_FLT)
     {
       ULONGEST fstat;
-      char buf[I386_MAX_REGISTER_SIZE];
+      gdb_byte buf[I386_MAX_REGISTER_SIZE];
 
       if (tdep->st0_regnum < 0)
        {
-         warning ("Cannot set floating-point return value.");
+         warning (_("Cannot set floating-point return value."));
          return;
        }
 
@@ -1307,11 +1465,11 @@ i386_store_return_value (struct gdbarch *gdbarch, struct type *type,
        {
          regcache_raw_write (regcache, LOW_RETURN_REGNUM, valbuf);
          regcache_raw_write_part (regcache, HIGH_RETURN_REGNUM, 0,
-                                  len - low_size, (char *) valbuf + low_size);
+                                  len - low_size, valbuf + low_size);
        }
       else
        internal_error (__FILE__, __LINE__,
-                       "Cannot store return value of %d bytes long.", len);
+                       _("Cannot store return value of %d bytes long."), len);
     }
 
 #undef I387_ST0_REGNUM
@@ -1332,9 +1490,9 @@ 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.  */
+/* Return non-zero if TYPE, which is assumed to be a structure,
+   a union type, or an array type, should be returned in registers
+   for architecture GDBARCH.  */
 
 static int
 i386_reg_struct_return_p (struct gdbarch *gdbarch, struct type *type)
@@ -1343,13 +1501,24 @@ i386_reg_struct_return_p (struct gdbarch *gdbarch, struct type *type)
   enum type_code code = TYPE_CODE (type);
   int len = TYPE_LENGTH (type);
 
-  gdb_assert (code == TYPE_CODE_STRUCT || code == TYPE_CODE_UNION);
+  gdb_assert (code == TYPE_CODE_STRUCT
+              || code == TYPE_CODE_UNION
+              || code == TYPE_CODE_ARRAY);
 
   if (struct_convention == pcc_struct_convention
       || (struct_convention == default_struct_convention
          && tdep->struct_return == pcc_struct_return))
     return 0;
 
+  /* Structures consisting of a single `float', `double' or 'long
+     double' member are returned in %st(0).  */
+  if (code == TYPE_CODE_STRUCT && TYPE_NFIELDS (type) == 1)
+    {
+      type = check_typedef (TYPE_FIELD_TYPE (type, 0));
+      if (TYPE_CODE (type) == TYPE_CODE_FLT)
+       return (len == 4 || len == 8 || len == 12);
+    }
+
   return (len == 1 || len == 2 || len == 4 || len == 8);
 }
 
@@ -1361,21 +1530,51 @@ i386_reg_struct_return_p (struct gdbarch *gdbarch, struct type *type)
 
 static enum return_value_convention
 i386_return_value (struct gdbarch *gdbarch, struct type *type,
-                  struct regcache *regcache, void *readbuf,
-                  const void *writebuf)
+                  struct regcache *regcache, gdb_byte *readbuf,
+                  const gdb_byte *writebuf)
 {
   enum type_code code = TYPE_CODE (type);
 
-  if ((code == TYPE_CODE_STRUCT || code == TYPE_CODE_UNION)
+  if ((code == TYPE_CODE_STRUCT
+       || code == TYPE_CODE_UNION
+       || code == TYPE_CODE_ARRAY)
       && !i386_reg_struct_return_p (gdbarch, type))
-    return RETURN_VALUE_STRUCT_CONVENTION;
+    {
+      /* 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.  */
+
+      /* Note that the ABI doesn't mention functions returning arrays,
+         which is something possible in certain languages such as Ada.
+         In this case, the value is returned as if it was wrapped in
+         a record, so the convention applied to records also applies
+         to arrays.  */
+
+      if (readbuf)
+       {
+         ULONGEST addr;
+
+         regcache_raw_read_unsigned (regcache, I386_EAX_REGNUM, &addr);
+         read_memory (addr, readbuf, TYPE_LENGTH (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.  */
+     `float', `double' or 'long 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));
@@ -1391,6 +1590,104 @@ i386_return_value (struct gdbarch *gdbarch, struct type *type,
 }
 \f
 
+/* Type for %eflags.  */
+struct type *i386_eflags_type;
+
+/* Types for the MMX and SSE registers.  */
+struct type *i386_mmx_type;
+struct type *i386_sse_type;
+struct type *i386_mxcsr_type;
+
+/* Construct types for ISA-specific registers.  */
+static void
+i386_init_types (void)
+{
+  struct type *type;
+
+  type = init_flags_type ("builtin_type_i386_eflags", 4);
+  append_flags_type_flag (type, 0, "CF");
+  append_flags_type_flag (type, 1, NULL);
+  append_flags_type_flag (type, 2, "PF");
+  append_flags_type_flag (type, 4, "AF");
+  append_flags_type_flag (type, 6, "ZF");
+  append_flags_type_flag (type, 7, "SF");
+  append_flags_type_flag (type, 8, "TF");
+  append_flags_type_flag (type, 9, "IF");
+  append_flags_type_flag (type, 10, "DF");
+  append_flags_type_flag (type, 11, "OF");
+  append_flags_type_flag (type, 14, "NT");
+  append_flags_type_flag (type, 16, "RF");
+  append_flags_type_flag (type, 17, "VM");
+  append_flags_type_flag (type, 18, "AC");
+  append_flags_type_flag (type, 19, "VIF");
+  append_flags_type_flag (type, 20, "VIP");
+  append_flags_type_flag (type, 21, "ID");
+  i386_eflags_type = type;
+
+  /* The type we're building is this: */
+#if 0
+  union __gdb_builtin_type_vec64i
+  {
+    int64_t uint64;
+    int32_t v2_int32[2];
+    int16_t v4_int16[4];
+    int8_t v8_int8[8];
+  };
+#endif
+
+  type = init_composite_type ("__gdb_builtin_type_vec64i", TYPE_CODE_UNION);
+  append_composite_type_field (type, "uint64", builtin_type_int64);
+  append_composite_type_field (type, "v2_int32", builtin_type_v2_int32);
+  append_composite_type_field (type, "v4_int16", builtin_type_v4_int16);
+  append_composite_type_field (type, "v8_int8", builtin_type_v8_int8);
+  TYPE_FLAGS (type) |= TYPE_FLAG_VECTOR;
+  TYPE_NAME (type) = "builtin_type_vec64i";
+  i386_mmx_type = type;
+
+  /* The type we're building is this: */
+#if 0
+  union __gdb_builtin_type_vec128i
+  {
+    int128_t uint128;
+    int64_t v2_int64[2];
+    int32_t v4_int32[4];
+    int16_t v8_int16[8];
+    int8_t v16_int8[16];
+    double v2_double[2];
+    float v4_float[4];
+  };
+#endif
+
+  type = init_composite_type ("__gdb_builtin_type_vec128i", TYPE_CODE_UNION);
+  append_composite_type_field (type, "v4_float", builtin_type_v4_float);
+  append_composite_type_field (type, "v2_double", builtin_type_v2_double);
+  append_composite_type_field (type, "v16_int8", builtin_type_v16_int8);
+  append_composite_type_field (type, "v8_int16", builtin_type_v8_int16);
+  append_composite_type_field (type, "v4_int32", builtin_type_v4_int32);
+  append_composite_type_field (type, "v2_int64", builtin_type_v2_int64);
+  append_composite_type_field (type, "uint128", builtin_type_int128);
+  TYPE_FLAGS (type) |= TYPE_FLAG_VECTOR;
+  TYPE_NAME (type) = "builtin_type_vec128i";
+  i386_sse_type = type;
+
+  type = init_flags_type ("builtin_type_i386_mxcsr", 4);
+  append_flags_type_flag (type, 0, "IE");
+  append_flags_type_flag (type, 1, "DE");
+  append_flags_type_flag (type, 2, "ZE");
+  append_flags_type_flag (type, 3, "OE");
+  append_flags_type_flag (type, 4, "UE");
+  append_flags_type_flag (type, 5, "PE");
+  append_flags_type_flag (type, 6, "DAZ");
+  append_flags_type_flag (type, 7, "IM");
+  append_flags_type_flag (type, 8, "DM");
+  append_flags_type_flag (type, 9, "ZM");
+  append_flags_type_flag (type, 10, "OM");
+  append_flags_type_flag (type, 11, "UM");
+  append_flags_type_flag (type, 12, "PM");
+  append_flags_type_flag (type, 15, "FZ");
+  i386_mxcsr_type = type;
+}
+
 /* Return the GDB type object for the "standard" data type of data in
    register REGNUM.  Perhaps %esi and %edi should go here, but
    potentially they could be used for things other than address.  */
@@ -1398,18 +1695,32 @@ i386_return_value (struct gdbarch *gdbarch, struct type *type,
 static struct type *
 i386_register_type (struct gdbarch *gdbarch, int regnum)
 {
-  if (regnum == I386_EIP_REGNUM
-      || regnum == I386_EBP_REGNUM || regnum == I386_ESP_REGNUM)
-    return lookup_pointer_type (builtin_type_void);
+  if (regnum == I386_EIP_REGNUM)
+    return builtin_type_void_func_ptr;
+
+  if (regnum == I386_EFLAGS_REGNUM)
+    return i386_eflags_type;
+
+  if (regnum == I386_EBP_REGNUM || regnum == I386_ESP_REGNUM)
+    return builtin_type_void_data_ptr;
 
   if (i386_fp_regnum_p (regnum))
     return builtin_type_i387_ext;
 
+  if (i386_mmx_regnum_p (gdbarch, regnum))
+    return i386_mmx_type;
+
   if (i386_sse_regnum_p (gdbarch, regnum))
-    return builtin_type_vec128i;
+    return i386_sse_type;
 
-  if (i386_mmx_regnum_p (gdbarch, regnum))
-    return builtin_type_vec64i;
+#define I387_ST0_REGNUM I386_ST0_REGNUM
+#define I387_NUM_XMM_REGS (gdbarch_tdep (current_gdbarch)->num_xmm_regs)
+
+  if (regnum == I387_MXCSR_REGNUM)
+    return i386_mxcsr_type;
+
+#undef I387_ST0_REGNUM
+#undef I387_NUM_XMM_REGS
 
   return builtin_type_int;
 }
@@ -1441,11 +1752,11 @@ i386_mmx_regnum_to_fp_regnum (struct regcache *regcache, int regnum)
 
 static void
 i386_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
-                          int regnum, void *buf)
+                          int regnum, gdb_byte *buf)
 {
   if (i386_mmx_regnum_p (gdbarch, regnum))
     {
-      char mmx_buf[MAX_REGISTER_SIZE];
+      gdb_byte mmx_buf[MAX_REGISTER_SIZE];
       int fpnum = i386_mmx_regnum_to_fp_regnum (regcache, regnum);
 
       /* Extract (always little endian).  */
@@ -1458,11 +1769,11 @@ i386_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
 
 static void
 i386_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
-                           int regnum, const void *buf)
+                           int regnum, const gdb_byte *buf)
 {
   if (i386_mmx_regnum_p (gdbarch, regnum))
     {
-      char mmx_buf[MAX_REGISTER_SIZE];
+      gdb_byte mmx_buf[MAX_REGISTER_SIZE];
       int fpnum = i386_mmx_regnum_to_fp_regnum (regcache, regnum);
 
       /* Read ...  */
@@ -1541,10 +1852,9 @@ i386_convert_register_p (int regnum, struct type *type)
 
 static void
 i386_register_to_value (struct frame_info *frame, int regnum,
-                       struct type *type, void *to)
+                       struct type *type, gdb_byte *to)
 {
   int len = TYPE_LENGTH (type);
-  char *buf = to;
 
   /* FIXME: kettenis/20030609: What should we do if REGNUM isn't
      available in FRAME (i.e. if it wasn't saved)?  */
@@ -1555,7 +1865,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);
 
@@ -1564,10 +1874,10 @@ i386_register_to_value (struct frame_info *frame, int regnum,
       gdb_assert (regnum != -1);
       gdb_assert (register_size (current_gdbarch, regnum) == 4);
 
-      get_frame_register (frame, regnum, buf);
+      get_frame_register (frame, regnum, to);
       regnum = i386_next_regnum (regnum);
       len -= 4;
-      buf += 4;
+      to += 4;
     }
 }
 
@@ -1576,10 +1886,9 @@ i386_register_to_value (struct frame_info *frame, int regnum,
 
 static void
 i386_value_to_register (struct frame_info *frame, int regnum,
-                       struct type *type, const void *from)
+                       struct type *type, const gdb_byte *from)
 {
   int len = TYPE_LENGTH (type);
-  const char *buf = from;
 
   if (i386_fp_regnum_p (regnum))
     {
@@ -1587,7 +1896,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);
 
@@ -1596,23 +1905,23 @@ i386_value_to_register (struct frame_info *frame, int regnum,
       gdb_assert (regnum != -1);
       gdb_assert (register_size (current_gdbarch, regnum) == 4);
 
-      put_frame_register (frame, regnum, buf);
+      put_frame_register (frame, regnum, from);
       regnum = i386_next_regnum (regnum);
       len -= 4;
-      buf += 4;
+      from += 4;
     }
 }
 \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.  */
 
 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 char *regs = gregs;
+  const struct gdbarch_tdep *tdep = gdbarch_tdep (regset->arch);
+  const gdb_byte *regs = gregs;
   int i;
 
   gdb_assert (len == tdep->sizeof_gregset);
@@ -1625,15 +1934,39 @@ 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);
+  gdb_byte *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)
     {
@@ -1645,6 +1978,28 @@ i386_supply_fpregset (const struct regset *regset, struct regcache *regcache,
   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.  */
 
@@ -1657,11 +2012,8 @@ i386_regset_from_core_section (struct gdbarch *gdbarch,
   if (strcmp (sect_name, ".reg") == 0 && sect_size == tdep->sizeof_gregset)
     {
       if (tdep->gregset == NULL)
-       {
-         tdep->gregset = XMALLOC (struct regset);
-         tdep->gregset->descr = tdep;
-         tdep->gregset->supply_regset = i386_supply_gregset;
-       }
+       tdep->gregset = regset_alloc (gdbarch, i386_supply_gregset,
+                                     i386_collect_gregset);
       return tdep->gregset;
     }
 
@@ -1670,11 +2022,8 @@ i386_regset_from_core_section (struct gdbarch *gdbarch,
          && sect_size == I387_SIZEOF_FXSAVE))
     {
       if (tdep->fpregset == NULL)
-       {
-         tdep->fpregset = XMALLOC (struct regset);
-         tdep->fpregset->descr = tdep;
-         tdep->fpregset->supply_regset = i386_supply_fpregset;
-       }
+       tdep->fpregset = regset_alloc (gdbarch, i386_supply_fpregset,
+                                      i386_collect_fpregset);
       return tdep->fpregset;
     }
 
@@ -1731,12 +2080,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
@@ -1766,11 +2119,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));
@@ -1783,7 +2143,7 @@ i386_svr4_pc_in_sigtramp (CORE_ADDR pc, char *name)
 static CORE_ADDR
 i386_svr4_sigcontext_addr (struct frame_info *next_frame)
 {
-  char buf[4];
+  gdb_byte buf[4];
   CORE_ADDR sp;
 
   frame_unwind_register (next_frame, I386_ESP_REGNUM, buf);
@@ -1793,23 +2153,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).  */
@@ -1823,10 +2173,9 @@ i386_svr4_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
   i386_elf_init_abi (info, gdbarch);
 
   /* System V Release 4 has shared libraries.  */
-  set_gdbarch_in_solib_call_trampoline (gdbarch, in_plt_section);
   set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
 
-  set_gdbarch_deprecated_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;
@@ -1841,7 +2190,8 @@ i386_go32_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
 {
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
 
-  set_gdbarch_deprecated_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;
 }
@@ -1946,7 +2296,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
@@ -1962,7 +2312,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;
 
@@ -1973,6 +2323,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;
@@ -1982,7 +2333,7 @@ i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
      the i387 extended floating-point format.  In fact, of all targets
      in the GCC 2.95 tree, only OSF/1 does it different, and insists
      on having a `long double' that's not `long' at all.  */
-  set_gdbarch_long_double_format (gdbarch, &floatformat_i387_ext);
+  set_gdbarch_long_double_format (gdbarch, floatformats_i387_ext);
 
   /* Although the i387 extended floating-point has only 80 significant
      bits, a `long double' actually takes up 96, probably to enforce
@@ -2001,13 +2352,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.  */
@@ -2034,7 +2415,6 @@ i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   set_gdbarch_decr_pc_after_break (gdbarch, 1);
 
   set_gdbarch_frame_args_skip (gdbarch, 8);
-  set_gdbarch_deprecated_pc_in_sigtramp (gdbarch, i386_pc_in_sigtramp);
 
   /* Wire in the MMX registers.  */
   set_gdbarch_num_pseudo_regs (gdbarch, i386_num_mmx_regs);
@@ -2106,32 +2486,26 @@ _initialize_i386_tdep (void)
   register_gdbarch_init (bfd_arch_i386, i386_gdbarch_init);
 
   /* Add the variable that controls the disassembly flavor.  */
-  {
-    struct cmd_list_element *new_cmd;
-
-    new_cmd = add_set_enum_cmd ("disassembly-flavor", no_class,
-                               valid_flavors,
-                               &disassembly_flavor,
-                               "\
-Set the disassembly flavor, the valid values are \"att\" and \"intel\", \
-and the default value is \"att\".",
-                               &setlist);
-    add_show_from_set (new_cmd, &showlist);
-  }
+  add_setshow_enum_cmd ("disassembly-flavor", no_class, valid_flavors,
+                       &disassembly_flavor, _("\
+Set the disassembly flavor."), _("\
+Show the disassembly flavor."), _("\
+The valid values are \"att\" and \"intel\", and the default value is \"att\"."),
+                       NULL,
+                       NULL, /* FIXME: i18n: */
+                       &setlist, &showlist);
 
   /* Add the variable that controls the convention for returning
      structs.  */
-  {
-    struct cmd_list_element *new_cmd;
-
-    new_cmd = add_set_enum_cmd ("struct-convention", no_class,
-                               valid_conventions,
-                               &struct_convention, "\
-Set the convention for returning small structs, valid values \
-are \"default\", \"pcc\" and \"reg\", and the default value is \"default\".",
-                                &setlist);
-    add_show_from_set (new_cmd, &showlist);
-  }
+  add_setshow_enum_cmd ("struct-convention", no_class, valid_conventions,
+                       &struct_convention, _("\
+Set the convention for returning small structs."), _("\
+Show the convention for returning small structs."), _("\
+Valid values are \"default\", \"pcc\" and \"reg\", and the default value\n\
+is \"default\"."),
+                       NULL,
+                       NULL, /* FIXME: i18n: */
+                       &setlist, &showlist);
 
   gdbarch_register_osabi_sniffer (bfd_arch_i386, bfd_target_coff_flavour,
                                  i386_coff_osabi_sniffer);
@@ -2145,6 +2519,7 @@ are \"default\", \"pcc\" and \"reg\", and the default value is \"default\".",
   gdbarch_register_osabi (bfd_arch_i386, 0, GDB_OSABI_NETWARE,
                          i386_nw_init_abi);
 
-  /* Initialize the i386 specific register groups.  */
+  /* Initialize the i386-specific register groups & types.  */
   i386_init_reggroups ();
+  i386_init_types();
 }