Implement displaced stepping.
[deliverable/binutils-gdb.git] / gdb / i386-tdep.c
index cd52bf6d0783df52672f10b9f873fbecdcbca5a8..08484bac21d03f088a8fe55470658fea636242fe 100644 (file)
@@ -1,14 +1,14 @@
 /* Intel 386 target-dependent stuff.
 
 /* Intel 386 target-dependent stuff.
 
-   Copyright (C) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996,
-   1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+   Copyright (C) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
+   1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
    Free Software Foundation, Inc.
 
    This file is part of GDB.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    Free Software Foundation, Inc.
 
    This file is part of GDB.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
+   the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
 
    This program is distributed in the hope that it will be useful,
    (at your option) any later version.
 
    This program is distributed in the hope that it will be useful,
@@ -17,9 +17,7 @@
    GNU General Public License for more details.
 
    You should have received a copy of the GNU General Public License
    GNU General Public License for more details.
 
    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., 51 Franklin Street, Fifth Floor,
-   Boston, MA 02110-1301, USA.  */
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include "defs.h"
 #include "arch-utils.h"
 
 #include "defs.h"
 #include "arch-utils.h"
 #include "dummy-frame.h"
 #include "dwarf2-frame.h"
 #include "doublest.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 "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"
 #include "objfiles.h"
 #include "osabi.h"
 #include "regcache.h"
@@ -98,16 +96,11 @@ i386_sse_regnum_p (struct gdbarch *gdbarch, int regnum)
 {
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
 
 {
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
 
-#define I387_ST0_REGNUM tdep->st0_regnum
-#define I387_NUM_XMM_REGS tdep->num_xmm_regs
-
-  if (I387_NUM_XMM_REGS == 0)
+  if (I387_NUM_XMM_REGS (tdep) == 0)
     return 0;
 
     return 0;
 
-  return (I387_XMM0_REGNUM <= regnum && regnum < I387_MXCSR_REGNUM);
-
-#undef I387_ST0_REGNUM
-#undef I387_NUM_XMM_REGS
+  return (I387_XMM0_REGNUM (tdep) <= regnum
+         && regnum < I387_MXCSR_REGNUM (tdep));
 }
 
 static int
 }
 
 static int
@@ -115,49 +108,45 @@ i386_mxcsr_regnum_p (struct gdbarch *gdbarch, int regnum)
 {
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
 
 {
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
 
-#define I387_ST0_REGNUM tdep->st0_regnum
-#define I387_NUM_XMM_REGS tdep->num_xmm_regs
-
-  if (I387_NUM_XMM_REGS == 0)
+  if (I387_NUM_XMM_REGS (tdep) == 0)
     return 0;
 
     return 0;
 
-  return (regnum == I387_MXCSR_REGNUM);
-
-#undef I387_ST0_REGNUM
-#undef I387_NUM_XMM_REGS
+  return (regnum == I387_MXCSR_REGNUM (tdep));
 }
 
 }
 
-#define I387_ST0_REGNUM (gdbarch_tdep (current_gdbarch)->st0_regnum)
-#define I387_MM0_REGNUM (gdbarch_tdep (current_gdbarch)->mm0_regnum)
-#define I387_NUM_XMM_REGS (gdbarch_tdep (current_gdbarch)->num_xmm_regs)
-
 /* FP register?  */
 
 int
 /* FP register?  */
 
 int
-i386_fp_regnum_p (int regnum)
+i386_fp_regnum_p (struct gdbarch *gdbarch, int regnum)
 {
 {
-  if (I387_ST0_REGNUM < 0)
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+  if (I387_ST0_REGNUM (tdep) < 0)
     return 0;
 
     return 0;
 
-  return (I387_ST0_REGNUM <= regnum && regnum < I387_FCTRL_REGNUM);
+  return (I387_ST0_REGNUM (tdep) <= regnum
+         && regnum < I387_FCTRL_REGNUM (tdep));
 }
 
 int
 }
 
 int
-i386_fpc_regnum_p (int regnum)
+i386_fpc_regnum_p (struct gdbarch *gdbarch, int regnum)
 {
 {
-  if (I387_ST0_REGNUM < 0)
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+  if (I387_ST0_REGNUM (tdep) < 0)
     return 0;
 
     return 0;
 
-  return (I387_FCTRL_REGNUM <= regnum && regnum < I387_XMM0_REGNUM);
+  return (I387_FCTRL_REGNUM (tdep) <= regnum 
+         && regnum < I387_XMM0_REGNUM (tdep));
 }
 
 /* Return the name of register REGNUM.  */
 
 const char *
 }
 
 /* Return the name of register REGNUM.  */
 
 const char *
-i386_register_name (int regnum)
+i386_register_name (struct gdbarch *gdbarch, int regnum)
 {
 {
-  if (i386_mmx_regnum_p (current_gdbarch, regnum))
-    return i386_mmx_names[regnum - I387_MM0_REGNUM];
+  if (i386_mmx_regnum_p (gdbarch, regnum))
+    return i386_mmx_names[regnum - I387_MM0_REGNUM (gdbarch_tdep (gdbarch))];
 
   if (regnum >= 0 && regnum < i386_num_register_names)
     return i386_register_names[regnum];
 
   if (regnum >= 0 && regnum < i386_num_register_names)
     return i386_register_names[regnum];
@@ -169,8 +158,10 @@ i386_register_name (int regnum)
    number used by GDB.  */
 
 static int
    number used by GDB.  */
 
 static int
-i386_dbx_reg_to_regnum (int reg)
+i386_dbx_reg_to_regnum (struct gdbarch *gdbarch, int reg)
 {
 {
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
   /* This implements what GCC calls the "default" register map
      (dbx_register_map[]).  */
 
   /* This implements what GCC calls the "default" register map
      (dbx_register_map[]).  */
 
@@ -187,29 +178,31 @@ i386_dbx_reg_to_regnum (int reg)
   else if (reg >= 12 && reg <= 19)
     {
       /* Floating-point registers.  */
   else if (reg >= 12 && reg <= 19)
     {
       /* Floating-point registers.  */
-      return reg - 12 + I387_ST0_REGNUM;
+      return reg - 12 + I387_ST0_REGNUM (tdep);
     }
   else if (reg >= 21 && reg <= 28)
     {
       /* SSE registers.  */
     }
   else if (reg >= 21 && reg <= 28)
     {
       /* SSE registers.  */
-      return reg - 21 + I387_XMM0_REGNUM;
+      return reg - 21 + I387_XMM0_REGNUM (tdep);
     }
   else if (reg >= 29 && reg <= 36)
     {
       /* MMX registers.  */
     }
   else if (reg >= 29 && reg <= 36)
     {
       /* MMX registers.  */
-      return reg - 29 + I387_MM0_REGNUM;
+      return reg - 29 + I387_MM0_REGNUM (tdep);
     }
 
   /* This will hopefully provoke a warning.  */
     }
 
   /* This will hopefully provoke a warning.  */
-  return NUM_REGS + NUM_PSEUDO_REGS;
+  return gdbarch_num_regs (gdbarch) + gdbarch_num_pseudo_regs (gdbarch);
 }
 
 /* Convert SVR4 register number REG to the appropriate register number
    used by GDB.  */
 
 static int
 }
 
 /* Convert SVR4 register number REG to the appropriate register number
    used by GDB.  */
 
 static int
-i386_svr4_reg_to_regnum (int reg)
+i386_svr4_reg_to_regnum (struct gdbarch *gdbarch, int reg)
 {
 {
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
   /* This implements the GCC register map that tries to be compatible
      with the SVR4 C compiler for DWARF (svr4_dbx_register_map[]).  */
 
   /* This implements the GCC register map that tries to be compatible
      with the SVR4 C compiler for DWARF (svr4_dbx_register_map[]).  */
 
@@ -223,19 +216,19 @@ i386_svr4_reg_to_regnum (int reg)
   else if (reg >= 11 && reg <= 18)
     {
       /* Floating-point registers.  */
   else if (reg >= 11 && reg <= 18)
     {
       /* Floating-point registers.  */
-      return reg - 11 + I387_ST0_REGNUM;
+      return reg - 11 + I387_ST0_REGNUM (tdep);
     }
   else if (reg >= 21 && reg <= 36)
     {
       /* The SSE and MMX registers have the same numbers as with dbx.  */
     }
   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);
+      return i386_dbx_reg_to_regnum (gdbarch, reg);
     }
 
   switch (reg)
     {
     }
 
   switch (reg)
     {
-    case 37: return I387_FCTRL_REGNUM;
-    case 38: return I387_FSTAT_REGNUM;
-    case 39: return I387_MXCSR_REGNUM;
+    case 37: return I387_FCTRL_REGNUM (tdep);
+    case 38: return I387_FSTAT_REGNUM (tdep);
+    case 39: return I387_MXCSR_REGNUM (tdep);
     case 40: return I386_ES_REGNUM;
     case 41: return I386_CS_REGNUM;
     case 42: return I386_SS_REGNUM;
     case 40: return I386_ES_REGNUM;
     case 41: return I386_CS_REGNUM;
     case 42: return I386_SS_REGNUM;
@@ -245,12 +238,9 @@ i386_svr4_reg_to_regnum (int reg)
     }
 
   /* This will hopefully provoke a warning.  */
     }
 
   /* This will hopefully provoke a warning.  */
-  return NUM_REGS + NUM_PSEUDO_REGS;
+  return gdbarch_num_regs (gdbarch) + gdbarch_num_pseudo_regs (gdbarch);
 }
 
 }
 
-#undef I387_ST0_REGNUM
-#undef I387_MM0_REGNUM
-#undef I387_NUM_XMM_REGS
 \f
 
 /* This is the variable that is set with "set disassembly-flavor", and
 \f
 
 /* This is the variable that is set with "set disassembly-flavor", and
@@ -278,13 +268,232 @@ static const char *disassembly_flavor = att_flavor;
    This function is 64-bit safe.  */
 
 static const gdb_byte *
    This function is 64-bit safe.  */
 
 static const gdb_byte *
-i386_breakpoint_from_pc (CORE_ADDR *pc, int *len)
+i386_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pc, int *len)
 {
   static gdb_byte break_insn[] = { 0xcc }; /* int 3 */
 
   *len = sizeof (break_insn);
   return break_insn;
 }
 {
   static gdb_byte break_insn[] = { 0xcc }; /* int 3 */
 
   *len = sizeof (break_insn);
   return break_insn;
 }
+\f
+/* Displaced instruction handling.  */
+
+
+static int
+i386_absolute_jmp_p (gdb_byte *insn)
+{
+  /* jmp far (absolute address in operand) */
+  if (insn[0] == 0xea)
+    return 1;
+
+  if (insn[0] == 0xff)
+    {
+      /* jump near, absolute indirect (/4) */
+      if ((insn[1] & 0x38) == 0x20)
+        return 1;
+
+      /* jump far, absolute indirect (/5) */
+      if ((insn[1] & 0x38) == 0x28)
+        return 1;
+    }
+
+  return 0;
+}
+
+static int
+i386_absolute_call_p (gdb_byte *insn)
+{
+  /* call far, absolute */
+  if (insn[0] == 0x9a)
+    return 1;
+
+  if (insn[0] == 0xff)
+    {
+      /* Call near, absolute indirect (/2) */
+      if ((insn[1] & 0x38) == 0x10)
+        return 1;
+
+      /* Call far, absolute indirect (/3) */
+      if ((insn[1] & 0x38) == 0x18)
+        return 1;
+    }
+
+  return 0;
+}
+
+static int
+i386_ret_p (gdb_byte *insn)
+{
+  switch (insn[0])
+    {
+    case 0xc2: /* ret near, pop N bytes */
+    case 0xc3: /* ret near */
+    case 0xca: /* ret far, pop N bytes */
+    case 0xcb: /* ret far */
+    case 0xcf: /* iret */
+      return 1;
+
+    default:
+      return 0;
+    }
+}
+
+static int
+i386_call_p (gdb_byte *insn)
+{
+  if (i386_absolute_call_p (insn))
+    return 1;
+
+  /* call near, relative */
+  if (insn[0] == 0xe8)
+    return 1;
+
+  return 0;
+}
+
+static int
+i386_breakpoint_p (gdb_byte *insn)
+{
+  return insn[0] == 0xcc;       /* int 3 */
+}
+
+/* Return non-zero if INSN is a system call, and set *LENGTHP to its
+   length in bytes.  Otherwise, return zero.  */
+static int
+i386_syscall_p (gdb_byte *insn, ULONGEST *lengthp)
+{
+  if (insn[0] == 0xcd)
+    {
+      *lengthp = 2;
+      return 1;
+    }
+
+  return 0;
+}
+
+/* Fix up the state of registers and memory after having single-stepped
+   a displaced instruction.  */
+void
+i386_displaced_step_fixup (struct gdbarch *gdbarch,
+                           struct displaced_step_closure *closure,
+                           CORE_ADDR from, CORE_ADDR to,
+                           struct regcache *regs)
+{
+  /* The offset we applied to the instruction's address.
+     This could well be negative (when viewed as a signed 32-bit
+     value), but ULONGEST won't reflect that, so take care when
+     applying it.  */
+  ULONGEST insn_offset = to - from;
+
+  /* Since we use simple_displaced_step_copy_insn, our closure is a
+     copy of the instruction.  */
+  gdb_byte *insn = (gdb_byte *) closure;
+
+  if (debug_displaced)
+    fprintf_unfiltered (gdb_stdlog,
+                        "displaced: fixup (0x%s, 0x%s), "
+                        "insn = 0x%02x 0x%02x ...\n",
+                        paddr_nz (from), paddr_nz (to), insn[0], insn[1]);
+
+  /* The list of issues to contend with here is taken from
+     resume_execution in arch/i386/kernel/kprobes.c, Linux 2.6.20.
+     Yay for Free Software!  */
+
+  /* Relocate the %eip, if necessary.  */
+
+  /* Except in the case of absolute or indirect jump or call
+     instructions, or a return instruction, the new eip is relative to
+     the displaced instruction; make it relative.  Well, signal
+     handler returns don't need relocation either, but we use the
+     value of %eip to recognize those; see below.  */
+  if (! i386_absolute_jmp_p (insn)
+      && ! i386_absolute_call_p (insn)
+      && ! i386_ret_p (insn))
+    {
+      ULONGEST orig_eip;
+      ULONGEST insn_len;
+
+      regcache_cooked_read_unsigned (regs, I386_EIP_REGNUM, &orig_eip);
+
+      /* A signal trampoline system call changes the %eip, resuming
+         execution of the main program after the signal handler has
+         returned.  That makes them like 'return' instructions; we
+         shouldn't relocate %eip.
+
+         But most system calls don't, and we do need to relocate %eip.
+
+         Our heuristic for distinguishing these cases: if stepping
+         over the system call instruction left control directly after
+         the instruction, the we relocate --- control almost certainly
+         doesn't belong in the displaced copy.  Otherwise, we assume
+         the instruction has put control where it belongs, and leave
+         it unrelocated.  Goodness help us if there are PC-relative
+         system calls.  */
+      if (i386_syscall_p (insn, &insn_len)
+          && orig_eip != to + insn_len)
+        {
+          if (debug_displaced)
+            fprintf_unfiltered (gdb_stdlog,
+                                "displaced: syscall changed %%eip; "
+                                "not relocating\n");
+        }
+      else
+        {
+          ULONGEST eip = (orig_eip - insn_offset) & 0xffffffffUL;
+
+          /* If we have stepped over a breakpoint, set the %eip to
+             point at the breakpoint instruction itself.
+
+             (gdbarch_decr_pc_after_break was never something the core
+             of GDB should have been concerned with; arch-specific
+             code should be making PC values consistent before
+             presenting them to GDB.)  */
+          if (i386_breakpoint_p (insn))
+            {
+              fprintf_unfiltered (gdb_stdlog,
+                                  "displaced: stepped breakpoint\n");
+              eip--;
+            }
+
+          regcache_cooked_write_unsigned (regs, I386_EIP_REGNUM, eip);
+
+          if (debug_displaced)
+            fprintf_unfiltered (gdb_stdlog,
+                                "displaced: "
+                                "relocated %%eip from 0x%s to 0x%s\n",
+                                paddr_nz (orig_eip), paddr_nz (eip));
+        }
+    }
+
+  /* If the instruction was PUSHFL, then the TF bit will be set in the
+     pushed value, and should be cleared.  We'll leave this for later,
+     since GDB already messes up the TF flag when stepping over a
+     pushfl.  */
+
+  /* If the instruction was a call, the return address now atop the
+     stack is the address following the copied instruction.  We need
+     to make it the address following the original instruction.  */
+  if (i386_call_p (insn))
+    {
+      ULONGEST esp;
+      ULONGEST retaddr;
+      const ULONGEST retaddr_len = 4;
+
+      regcache_cooked_read_unsigned (regs, I386_ESP_REGNUM, &esp);
+      retaddr = read_memory_unsigned_integer (esp, retaddr_len);
+      retaddr = (retaddr - insn_offset) & 0xffffffffUL;
+      write_memory_unsigned_integer (esp, retaddr_len, retaddr);
+
+      if (debug_displaced)
+        fprintf_unfiltered (gdb_stdlog,
+                            "displaced: relocated return addr at 0x%s "
+                            "to 0x%s\n",
+                            paddr_nz (esp),
+                            paddr_nz (retaddr));
+    }
+}
+
+
 \f
 #ifdef I386_REGNO_TO_SYMMETRY
 #error "The Sequent Symmetry is no longer supported."
 \f
 #ifdef I386_REGNO_TO_SYMMETRY
 #error "The Sequent Symmetry is no longer supported."
@@ -354,7 +563,7 @@ i386_follow_jump (CORE_ADDR pc)
   long delta = 0;
   int data16 = 0;
 
   long delta = 0;
   int data16 = 0;
 
-  read_memory_nobpt (pc, &op, 1);
+  target_read_memory (pc, &op, 1);
   if (op == 0x66)
     {
       data16 = 1;
   if (op == 0x66)
     {
       data16 = 1;
@@ -420,12 +629,12 @@ i386_analyze_struct_return (CORE_ADDR pc, CORE_ADDR current_pc,
   if (current_pc <= pc)
     return pc;
 
   if (current_pc <= pc)
     return pc;
 
-  read_memory_nobpt (pc, &op, 1);
+  target_read_memory (pc, &op, 1);
 
   if (op != 0x58)              /* popl %eax */
     return pc;
 
 
   if (op != 0x58)              /* popl %eax */
     return pc;
 
-  read_memory_nobpt (pc + 1, buf, 4);
+  target_read_memory (pc + 1, buf, 4);
   if (memcmp (buf, proto1, 3) != 0 && memcmp (buf, proto2, 4) != 0)
     return pc;
 
   if (memcmp (buf, proto1, 3) != 0 && memcmp (buf, proto2, 4) != 0)
     return pc;
 
@@ -464,7 +673,7 @@ i386_skip_probe (CORE_ADDR pc)
   gdb_byte buf[8];
   gdb_byte op;
 
   gdb_byte buf[8];
   gdb_byte op;
 
-  read_memory_nobpt (pc, &op, 1);
+  target_read_memory (pc, &op, 1);
 
   if (op == 0x68 || op == 0x6a)
     {
 
   if (op == 0x68 || op == 0x6a)
     {
@@ -497,6 +706,10 @@ static CORE_ADDR
 i386_analyze_stack_align (CORE_ADDR pc, CORE_ADDR current_pc,
                          struct i386_frame_cache *cache)
 {
 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 */
   static const gdb_byte insns_ecx[10] = { 
     0x8d, 0x4c, 0x24, 0x04,    /* leal  4(%esp), %ecx */
     0x83, 0xe4, 0xf0,          /* andl  $-16, %esp */
@@ -527,14 +740,14 @@ i386_analyze_stack_align (CORE_ADDR pc, CORE_ADDR current_pc,
 }
 
 /* Maximum instruction length we need to handle.  */
 }
 
 /* Maximum instruction length we need to handle.  */
-#define I386_MAX_INSN_LEN      6
+#define I386_MAX_MATCHED_INSN_LEN      6
 
 /* Instruction description.  */
 struct i386_insn
 {
   size_t len;
 
 /* Instruction description.  */
 struct i386_insn
 {
   size_t len;
-  gdb_byte insn[I386_MAX_INSN_LEN];
-  gdb_byte mask[I386_MAX_INSN_LEN];
+  gdb_byte insn[I386_MAX_MATCHED_INSN_LEN];
+  gdb_byte mask[I386_MAX_MATCHED_INSN_LEN];
 };
 
 /* Search for the instruction at PC in the list SKIP_INSNS.  Return
 };
 
 /* Search for the instruction at PC in the list SKIP_INSNS.  Return
@@ -547,20 +760,20 @@ i386_match_insn (CORE_ADDR pc, struct i386_insn *skip_insns)
   struct i386_insn *insn;
   gdb_byte op;
 
   struct i386_insn *insn;
   gdb_byte op;
 
-  read_memory_nobpt (pc, &op, 1);
+  target_read_memory (pc, &op, 1);
 
   for (insn = skip_insns; insn->len > 0; insn++)
     {
       if ((op & insn->mask[0]) == insn->insn[0])
        {
 
   for (insn = skip_insns; insn->len > 0; insn++)
     {
       if ((op & insn->mask[0]) == insn->insn[0])
        {
-         gdb_byte buf[I386_MAX_INSN_LEN - 1];
+         gdb_byte buf[I386_MAX_MATCHED_INSN_LEN - 1];
          int insn_matched = 1;
          size_t i;
 
          gdb_assert (insn->len > 1);
          int insn_matched = 1;
          size_t i;
 
          gdb_assert (insn->len > 1);
-         gdb_assert (insn->len <= I386_MAX_INSN_LEN);
+         gdb_assert (insn->len <= I386_MAX_MATCHED_INSN_LEN);
 
 
-         read_memory_nobpt (pc + 1, buf, insn->len - 1);
+         target_read_memory (pc + 1, buf, insn->len - 1);
          for (i = 1; i < insn->len; i++)
            {
              if ((buf[i - 1] & insn->mask[i]) != insn->insn[i])
          for (i = 1; i < insn->len; i++)
            {
              if ((buf[i - 1] & insn->mask[i]) != insn->insn[i])
@@ -630,6 +843,51 @@ struct i386_insn i386_frame_setup_skip_insns[] =
   { 0 }
 };
 
   { 0 }
 };
 
+
+/* Check whether PC points to a no-op instruction.  */
+static CORE_ADDR
+i386_skip_noop (CORE_ADDR pc)
+{
+  gdb_byte op;
+  int check = 1;
+
+  target_read_memory (pc, &op, 1);
+
+  while (check) 
+    {
+      check = 0;
+      /* Ignore `nop' instruction.  */
+      if (op == 0x90) 
+       {
+         pc += 1;
+         target_read_memory (pc, &op, 1);
+         check = 1;
+       }
+      /* Ignore no-op instruction `mov %edi, %edi'.
+        Microsoft system dlls often start with
+        a `mov %edi,%edi' instruction.
+        The 5 bytes before the function start are
+        filled with `nop' instructions.
+        This pattern can be used for hot-patching:
+        The `mov %edi, %edi' instruction can be replaced by a
+        near jump to the location of the 5 `nop' instructions
+        which can be replaced by a 32-bit jump to anywhere
+        in the 32-bit address space.  */
+
+      else if (op == 0x8b)
+       {
+         target_read_memory (pc + 1, &op, 1);
+         if (op == 0xff)
+           {
+             pc += 2;
+             target_read_memory (pc, &op, 1);
+             check = 1;
+           }
+       }
+    }
+  return pc; 
+}
+
 /* 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 up the frame or LIMIT,
 /* 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 up the frame or LIMIT,
@@ -646,7 +904,7 @@ i386_analyze_frame_setup (CORE_ADDR pc, CORE_ADDR limit,
   if (limit <= pc)
     return limit;
 
   if (limit <= pc)
     return limit;
 
-  read_memory_nobpt (pc, &op, 1);
+  target_read_memory (pc, &op, 1);
 
   if (op == 0x55)              /* pushl %ebp */
     {
 
   if (op == 0x55)              /* pushl %ebp */
     {
@@ -681,7 +939,7 @@ i386_analyze_frame_setup (CORE_ADDR pc, CORE_ADDR limit,
       if (limit <= pc + skip)
        return limit;
 
       if (limit <= pc + skip)
        return limit;
 
-      read_memory_nobpt (pc + skip, &op, 1);
+      target_read_memory (pc + skip, &op, 1);
 
       /* Check for `movl %esp, %ebp' -- can be written in two ways.  */
       switch (op)
 
       /* Check for `movl %esp, %ebp' -- can be written in two ways.  */
       switch (op)
@@ -715,7 +973,7 @@ i386_analyze_frame_setup (CORE_ADDR pc, CORE_ADDR limit,
 
         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.  */
 
         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.  */
-      read_memory_nobpt (pc, &op, 1);
+      target_read_memory (pc, &op, 1);
       if (op == 0x83)
        {
          /* `subl' with 8-bit immediate.  */
       if (op == 0x83)
        {
          /* `subl' with 8-bit immediate.  */
@@ -771,7 +1029,7 @@ i386_analyze_register_saves (CORE_ADDR pc, CORE_ADDR current_pc,
     offset -= cache->locals;
   for (i = 0; i < 8 && pc < current_pc; i++)
     {
     offset -= cache->locals;
   for (i = 0; i < 8 && pc < current_pc; i++)
     {
-      read_memory_nobpt (pc, &op, 1);
+      target_read_memory (pc, &op, 1);
       if (op < 0x50 || op > 0x57)
        break;
 
       if (op < 0x50 || op > 0x57)
        break;
 
@@ -815,6 +1073,7 @@ static CORE_ADDR
 i386_analyze_prologue (CORE_ADDR pc, CORE_ADDR current_pc,
                       struct i386_frame_cache *cache)
 {
 i386_analyze_prologue (CORE_ADDR pc, CORE_ADDR current_pc,
                       struct i386_frame_cache *cache)
 {
+  pc = i386_skip_noop (pc);
   pc = i386_follow_jump (pc);
   pc = i386_analyze_struct_return (pc, current_pc, cache);
   pc = i386_skip_probe (pc);
   pc = i386_follow_jump (pc);
   pc = i386_analyze_struct_return (pc, current_pc, cache);
   pc = i386_skip_probe (pc);
@@ -826,7 +1085,7 @@ i386_analyze_prologue (CORE_ADDR pc, CORE_ADDR current_pc,
 /* Return PC of first real instruction.  */
 
 static CORE_ADDR
 /* Return PC of first real instruction.  */
 
 static CORE_ADDR
-i386_skip_prologue (CORE_ADDR start_pc)
+i386_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR start_pc)
 {
   static gdb_byte pic_pat[6] =
   {
 {
   static gdb_byte pic_pat[6] =
   {
@@ -860,7 +1119,7 @@ i386_skip_prologue (CORE_ADDR start_pc)
 
   for (i = 0; i < 6; i++)
     {
 
   for (i = 0; i < 6; i++)
     {
-      read_memory_nobpt (pc + i, &op, 1);
+      target_read_memory (pc + i, &op, 1);
       if (pic_pat[i] != op)
        break;
     }
       if (pic_pat[i] != op)
        break;
     }
@@ -868,7 +1127,7 @@ i386_skip_prologue (CORE_ADDR start_pc)
     {
       int delta = 6;
 
     {
       int delta = 6;
 
-      read_memory_nobpt (pc + delta, &op, 1);
+      target_read_memory (pc + delta, &op, 1);
 
       if (op == 0x89)          /* movl %ebx, x(%ebp) */
        {
 
       if (op == 0x89)          /* movl %ebx, x(%ebp) */
        {
@@ -881,7 +1140,7 @@ i386_skip_prologue (CORE_ADDR start_pc)
          else                  /* Unexpected instruction.  */
            delta = 0;
 
          else                  /* Unexpected instruction.  */
            delta = 0;
 
-          read_memory_nobpt (pc + delta, &op, 1);
+          target_read_memory (pc + delta, &op, 1);
        }
 
       /* addl y,%ebx */
        }
 
       /* addl y,%ebx */
@@ -908,7 +1167,7 @@ i386_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
 {
   gdb_byte buf[8];
 
 {
   gdb_byte buf[8];
 
-  frame_unwind_register (next_frame, PC_REGNUM, buf);
+  frame_unwind_register (next_frame, gdbarch_pc_regnum (gdbarch), buf);
   return extract_typed_address (buf, builtin_type_void_func_ptr);
 }
 \f
   return extract_typed_address (buf, builtin_type_void_func_ptr);
 }
 \f
@@ -916,7 +1175,7 @@ i386_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
 /* Normal frames.  */
 
 static struct i386_frame_cache *
 /* Normal frames.  */
 
 static struct i386_frame_cache *
-i386_frame_cache (struct frame_info *next_frame, void **this_cache)
+i386_frame_cache (struct frame_info *this_frame, void **this_cache)
 {
   struct i386_frame_cache *cache;
   gdb_byte buf[4];
 {
   struct i386_frame_cache *cache;
   gdb_byte buf[4];
@@ -937,7 +1196,7 @@ i386_frame_cache (struct frame_info *next_frame, void **this_cache)
      They (usually) share their frame pointer with the frame that was
      in progress when the signal occurred.  */
 
      They (usually) share their frame pointer with the frame that was
      in progress when the signal occurred.  */
 
-  frame_unwind_register (next_frame, I386_EBP_REGNUM, buf);
+  get_frame_register (this_frame, I386_EBP_REGNUM, buf);
   cache->base = extract_unsigned_integer (buf, 4);
   if (cache->base == 0)
     return cache;
   cache->base = extract_unsigned_integer (buf, 4);
   if (cache->base == 0)
     return cache;
@@ -945,14 +1204,14 @@ 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;
 
   /* 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 = get_frame_func (this_frame);
   if (cache->pc != 0)
   if (cache->pc != 0)
-    i386_analyze_prologue (cache->pc, frame_pc_unwind (next_frame), cache);
+    i386_analyze_prologue (cache->pc, get_frame_pc (this_frame), cache);
 
   if (cache->stack_align)
     {
       /* Saved stack pointer has been saved in %ecx.  */
 
   if (cache->stack_align)
     {
       /* Saved stack pointer has been saved in %ecx.  */
-      frame_unwind_register (next_frame, I386_ECX_REGNUM, buf);
+      get_frame_register (this_frame, I386_ECX_REGNUM, buf);
       cache->saved_sp = extract_unsigned_integer(buf, 4);
     }
 
       cache->saved_sp = extract_unsigned_integer(buf, 4);
     }
 
@@ -977,7 +1236,7 @@ i386_frame_cache (struct frame_info *next_frame, void **this_cache)
        }
       else
        {
        }
       else
        {
-         frame_unwind_register (next_frame, I386_ESP_REGNUM, buf);
+         get_frame_register (this_frame, I386_ESP_REGNUM, buf);
          cache->base = extract_unsigned_integer (buf, 4) + cache->sp_offset;
        }
     }
          cache->base = extract_unsigned_integer (buf, 4) + cache->sp_offset;
        }
     }
@@ -997,10 +1256,10 @@ i386_frame_cache (struct frame_info *next_frame, void **this_cache)
 }
 
 static void
 }
 
 static void
-i386_frame_this_id (struct frame_info *next_frame, void **this_cache,
+i386_frame_this_id (struct frame_info *this_frame, void **this_cache,
                    struct frame_id *this_id)
 {
                    struct frame_id *this_id)
 {
-  struct i386_frame_cache *cache = i386_frame_cache (next_frame, this_cache);
+  struct i386_frame_cache *cache = i386_frame_cache (this_frame, this_cache);
 
   /* This marks the outermost frame.  */
   if (cache->base == 0)
 
   /* This marks the outermost frame.  */
   if (cache->base == 0)
@@ -1010,13 +1269,11 @@ i386_frame_this_id (struct frame_info *next_frame, void **this_cache,
   (*this_id) = frame_id_build (cache->base + 8, cache->pc);
 }
 
   (*this_id) = frame_id_build (cache->base + 8, cache->pc);
 }
 
-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, gdb_byte *valuep)
+static struct value *
+i386_frame_prev_register (struct frame_info *this_frame, void **this_cache,
+                         int regnum)
 {
 {
-  struct i386_frame_cache *cache = i386_frame_cache (next_frame, this_cache);
+  struct i386_frame_cache *cache = i386_frame_cache (this_frame, this_cache);
 
   gdb_assert (regnum >= 0);
 
 
   gdb_assert (regnum >= 0);
 
@@ -1041,93 +1298,43 @@ i386_frame_prev_register (struct frame_info *next_frame, void **this_cache,
 
   if (regnum == I386_EFLAGS_REGNUM)
     {
 
   if (regnum == I386_EFLAGS_REGNUM)
     {
-      *optimizedp = 0;
-      *lvalp = not_lval;
-      *addrp = 0;
-      *realnump = -1;
-      if (valuep)
-       {
-         ULONGEST val;
+      ULONGEST val;
 
 
-         /* Clear the direction flag.  */
-         val = frame_unwind_register_unsigned (next_frame,
-                                               I386_EFLAGS_REGNUM);
-         val &= ~(1 << 10);
-         store_unsigned_integer (valuep, 4, val);
-       }
-
-      return;
+      val = get_frame_register_unsigned (this_frame, regnum);
+      val &= ~(1 << 10);
+      return frame_unwind_got_constant (this_frame, regnum, val);
     }
 
   if (regnum == I386_EIP_REGNUM && cache->pc_in_eax)
     }
 
   if (regnum == I386_EIP_REGNUM && cache->pc_in_eax)
-    {
-      *optimizedp = 0;
-      *lvalp = lval_register;
-      *addrp = 0;
-      *realnump = I386_EAX_REGNUM;
-      if (valuep)
-       frame_unwind_register (next_frame, (*realnump), valuep);
-      return;
-    }
+    return frame_unwind_got_register (this_frame, regnum, I386_EAX_REGNUM);
 
   if (regnum == I386_ESP_REGNUM && cache->saved_sp)
 
   if (regnum == I386_ESP_REGNUM && cache->saved_sp)
-    {
-      *optimizedp = 0;
-      *lvalp = not_lval;
-      *addrp = 0;
-      *realnump = -1;
-      if (valuep)
-       {
-         /* Store the value.  */
-         store_unsigned_integer (valuep, 4, cache->saved_sp);
-       }
-      return;
-    }
+    return frame_unwind_got_constant (this_frame, regnum, cache->saved_sp);
 
   if (regnum < I386_NUM_SAVED_REGS && cache->saved_regs[regnum] != -1)
 
   if (regnum < I386_NUM_SAVED_REGS && cache->saved_regs[regnum] != -1)
-    {
-      *optimizedp = 0;
-      *lvalp = lval_memory;
-      *addrp = cache->saved_regs[regnum];
-      *realnump = -1;
-      if (valuep)
-       {
-         /* Read the value in from memory.  */
-         read_memory (*addrp, valuep,
-                      register_size (current_gdbarch, regnum));
-       }
-      return;
-    }
+    return frame_unwind_got_memory (this_frame, regnum,
+                                   cache->saved_regs[regnum]);
 
 
-  *optimizedp = 0;
-  *lvalp = lval_register;
-  *addrp = 0;
-  *realnump = regnum;
-  if (valuep)
-    frame_unwind_register (next_frame, (*realnump), valuep);
+  return frame_unwind_got_register (this_frame, regnum, regnum);
 }
 
 static const struct frame_unwind i386_frame_unwind =
 {
   NORMAL_FRAME,
   i386_frame_this_id,
 }
 
 static const struct frame_unwind i386_frame_unwind =
 {
   NORMAL_FRAME,
   i386_frame_this_id,
-  i386_frame_prev_register
+  i386_frame_prev_register,
+  NULL,
+  default_frame_sniffer
 };
 };
-
-static const struct frame_unwind *
-i386_frame_sniffer (struct frame_info *next_frame)
-{
-  return &i386_frame_unwind;
-}
 \f
 
 /* Signal trampolines.  */
 
 static struct i386_frame_cache *
 \f
 
 /* Signal trampolines.  */
 
 static struct i386_frame_cache *
-i386_sigtramp_frame_cache (struct frame_info *next_frame, void **this_cache)
+i386_sigtramp_frame_cache (struct frame_info *this_frame, void **this_cache)
 {
   struct i386_frame_cache *cache;
 {
   struct i386_frame_cache *cache;
-  struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+  struct gdbarch_tdep *tdep = gdbarch_tdep (get_frame_arch (this_frame));
   CORE_ADDR addr;
   gdb_byte buf[4];
 
   CORE_ADDR addr;
   gdb_byte buf[4];
 
@@ -1136,10 +1343,10 @@ i386_sigtramp_frame_cache (struct frame_info *next_frame, void **this_cache)
 
   cache = i386_alloc_frame_cache ();
 
 
   cache = i386_alloc_frame_cache ();
 
-  frame_unwind_register (next_frame, I386_ESP_REGNUM, buf);
+  get_frame_register (this_frame, I386_ESP_REGNUM, buf);
   cache->base = extract_unsigned_integer (buf, 4) - 4;
 
   cache->base = extract_unsigned_integer (buf, 4) - 4;
 
-  addr = tdep->sigcontext_addr (next_frame);
+  addr = tdep->sigcontext_addr (this_frame);
   if (tdep->sc_reg_offset)
     {
       int i;
   if (tdep->sc_reg_offset)
     {
       int i;
@@ -1161,70 +1368,70 @@ i386_sigtramp_frame_cache (struct frame_info *next_frame, void **this_cache)
 }
 
 static void
 }
 
 static void
-i386_sigtramp_frame_this_id (struct frame_info *next_frame, void **this_cache,
+i386_sigtramp_frame_this_id (struct frame_info *this_frame, void **this_cache,
                             struct frame_id *this_id)
 {
   struct i386_frame_cache *cache =
                             struct frame_id *this_id)
 {
   struct i386_frame_cache *cache =
-    i386_sigtramp_frame_cache (next_frame, this_cache);
+    i386_sigtramp_frame_cache (this_frame, this_cache);
 
   /* See the end of i386_push_dummy_call.  */
 
   /* See the end of i386_push_dummy_call.  */
-  (*this_id) = frame_id_build (cache->base + 8, frame_pc_unwind (next_frame));
+  (*this_id) = frame_id_build (cache->base + 8, get_frame_pc (this_frame));
 }
 
 }
 
-static void
-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, gdb_byte *valuep)
+static struct value *
+i386_sigtramp_frame_prev_register (struct frame_info *this_frame,
+                                  void **this_cache, int regnum)
 {
   /* Make sure we've initialized the cache.  */
 {
   /* Make sure we've initialized the cache.  */
-  i386_sigtramp_frame_cache (next_frame, this_cache);
+  i386_sigtramp_frame_cache (this_frame, this_cache);
 
 
-  i386_frame_prev_register (next_frame, this_cache, regnum,
-                           optimizedp, lvalp, addrp, realnump, valuep);
+  return i386_frame_prev_register (this_frame, this_cache, regnum);
 }
 
 }
 
-static const struct frame_unwind i386_sigtramp_frame_unwind =
-{
-  SIGTRAMP_FRAME,
-  i386_sigtramp_frame_this_id,
-  i386_sigtramp_frame_prev_register
-};
-
-static const struct frame_unwind *
-i386_sigtramp_frame_sniffer (struct frame_info *next_frame)
+static int
+i386_sigtramp_frame_sniffer (const struct frame_unwind *self,
+                            struct frame_info *this_frame,
+                            void **this_prologue_cache)
 {
 {
-  struct gdbarch_tdep *tdep = gdbarch_tdep (get_frame_arch (next_frame));
+  struct gdbarch_tdep *tdep = gdbarch_tdep (get_frame_arch (this_frame));
 
   /* We shouldn't even bother if we don't have a sigcontext_addr
      handler.  */
   if (tdep->sigcontext_addr == NULL)
 
   /* We shouldn't even bother if we don't have a sigcontext_addr
      handler.  */
   if (tdep->sigcontext_addr == NULL)
-    return NULL;
+    return 0;
 
   if (tdep->sigtramp_p != NULL)
     {
 
   if (tdep->sigtramp_p != NULL)
     {
-      if (tdep->sigtramp_p (next_frame))
-       return &i386_sigtramp_frame_unwind;
+      if (tdep->sigtramp_p (this_frame))
+       return 1;
     }
 
   if (tdep->sigtramp_start != 0)
     {
     }
 
   if (tdep->sigtramp_start != 0)
     {
-      CORE_ADDR pc = frame_pc_unwind (next_frame);
+      CORE_ADDR pc = get_frame_pc (this_frame);
 
       gdb_assert (tdep->sigtramp_end != 0);
       if (pc >= tdep->sigtramp_start && pc < tdep->sigtramp_end)
 
       gdb_assert (tdep->sigtramp_end != 0);
       if (pc >= tdep->sigtramp_start && pc < tdep->sigtramp_end)
-       return &i386_sigtramp_frame_unwind;
+       return 1;
     }
 
     }
 
-  return NULL;
+  return 0;
 }
 }
+
+static const struct frame_unwind i386_sigtramp_frame_unwind =
+{
+  SIGTRAMP_FRAME,
+  i386_sigtramp_frame_this_id,
+  i386_sigtramp_frame_prev_register,
+  NULL,
+  i386_sigtramp_frame_sniffer
+};
 \f
 
 static CORE_ADDR
 \f
 
 static CORE_ADDR
-i386_frame_base_address (struct frame_info *next_frame, void **this_cache)
+i386_frame_base_address (struct frame_info *this_frame, void **this_cache)
 {
 {
-  struct i386_frame_cache *cache = i386_frame_cache (next_frame, this_cache);
+  struct i386_frame_cache *cache = i386_frame_cache (this_frame, this_cache);
 
   return cache->base;
 }
 
   return cache->base;
 }
@@ -1238,16 +1445,14 @@ static const struct frame_base i386_frame_base =
 };
 
 static struct frame_id
 };
 
 static struct frame_id
-i386_unwind_dummy_id (struct gdbarch *gdbarch, struct frame_info *next_frame)
+i386_dummy_id (struct gdbarch *gdbarch, struct frame_info *this_frame)
 {
 {
-  gdb_byte buf[4];
   CORE_ADDR fp;
 
   CORE_ADDR fp;
 
-  frame_unwind_register (next_frame, I386_EBP_REGNUM, buf);
-  fp = extract_unsigned_integer (buf, 4);
+  fp = get_frame_register_unsigned (this_frame, I386_EBP_REGNUM);
 
   /* See the end of i386_push_dummy_call.  */
 
   /* See the end of i386_push_dummy_call.  */
-  return frame_id_build (fp + 8, frame_pc_unwind (next_frame));
+  return frame_id_build (fp + 8, get_frame_pc (this_frame));
 }
 \f
 
 }
 \f
 
@@ -1255,35 +1460,31 @@ i386_unwind_dummy_id (struct gdbarch *gdbarch, struct frame_info *next_frame)
    stack.  We expect the first arg to be a pointer to the jmp_buf
    structure from which we extract the address that we will land at.
    This address is copied into PC.  This routine returns non-zero on
    stack.  We expect the first arg to be a pointer to the jmp_buf
    structure from which we extract the address that we will land at.
    This address is copied into PC.  This routine returns non-zero on
-   success.
-
-   This function is 64-bit safe.  */
+   success.  */
 
 static int
 
 static int
-i386_get_longjmp_target (CORE_ADDR *pc)
+i386_get_longjmp_target (struct frame_info *frame, CORE_ADDR *pc)
 {
 {
-  gdb_byte buf[8];
+  gdb_byte buf[4];
   CORE_ADDR sp, jb_addr;
   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);
+  struct gdbarch *gdbarch = get_frame_arch (frame);
+  int jb_pc_offset = gdbarch_tdep (gdbarch)->jb_pc_offset;
 
   /* If JB_PC_OFFSET is -1, we have no way to find out where the
      longjmp will land.  */
   if (jb_pc_offset == -1)
     return 0;
 
 
   /* If JB_PC_OFFSET is -1, we have no way to find out where the
      longjmp will land.  */
   if (jb_pc_offset == -1)
     return 0;
 
-  /* Don't use I386_ESP_REGNUM here, since this function is also used
-     for AMD64.  */
-  regcache_cooked_read (current_regcache, SP_REGNUM, buf);
-  sp = extract_typed_address (buf, builtin_type_void_data_ptr);
-  if (target_read_memory (sp + len, buf, len))
+  get_frame_register (frame, I386_ESP_REGNUM, buf);
+  sp = extract_unsigned_integer (buf, 4);
+  if (target_read_memory (sp + 4, buf, 4))
     return 0;
 
     return 0;
 
-  jb_addr = extract_typed_address (buf, builtin_type_void_data_ptr);
-  if (target_read_memory (jb_addr + jb_pc_offset, buf, len))
+  jb_addr = extract_unsigned_integer (buf, 4);
+  if (target_read_memory (jb_addr + jb_pc_offset, buf, 4))
     return 0;
 
     return 0;
 
-  *pc = extract_typed_address (buf, builtin_type_void_func_ptr);
+  *pc = extract_unsigned_integer (buf, 4);
   return 1;
 }
 \f
   return 1;
 }
 \f
@@ -1335,7 +1536,7 @@ i386_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
 
   /* MarkK wrote: This "+ 8" is all over the place:
      (i386_frame_this_id, i386_sigtramp_frame_this_id,
 
   /* MarkK wrote: This "+ 8" is all over the place:
      (i386_frame_this_id, i386_sigtramp_frame_this_id,
-     i386_unwind_dummy_id).  It's there, since all frame unwinders for
+     i386_dummy_id).  It's there, since all frame unwinders for
      a given target have to agree (within a certain margin) on the
      definition of the stack address of a frame.  Otherwise
      frame_id_inner() won't work correctly.  Since DWARF2/GCC uses the
      a given target have to agree (within a certain margin) on the
      definition of the stack address of a frame.  Otherwise
      frame_id_inner() won't work correctly.  Since DWARF2/GCC uses the
@@ -1380,8 +1581,8 @@ i386_extract_return_value (struct gdbarch *gdbarch, struct type *type,
     }
   else
     {
     }
   else
     {
-      int low_size = register_size (current_gdbarch, LOW_RETURN_REGNUM);
-      int high_size = register_size (current_gdbarch, HIGH_RETURN_REGNUM);
+      int low_size = register_size (gdbarch, LOW_RETURN_REGNUM);
+      int high_size = register_size (gdbarch, HIGH_RETURN_REGNUM);
 
       if (len <= low_size)
        {
 
       if (len <= low_size)
        {
@@ -1411,10 +1612,6 @@ i386_store_return_value (struct gdbarch *gdbarch, struct type *type,
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
   int len = TYPE_LENGTH (type);
 
   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_FLT)
     {
       ULONGEST fstat;
   if (TYPE_CODE (type) == TYPE_CODE_FLT)
     {
       ULONGEST fstat;
@@ -1441,19 +1638,19 @@ i386_store_return_value (struct gdbarch *gdbarch, struct type *type,
          actual value doesn't really matter, but 7 is what a normal
          function return would end up with if the program started out
          with a freshly initialized FPU.  */
          actual value doesn't really matter, but 7 is what a normal
          function return would end up with if the program started out
          with a freshly initialized FPU.  */
-      regcache_raw_read_unsigned (regcache, I387_FSTAT_REGNUM, &fstat);
+      regcache_raw_read_unsigned (regcache, I387_FSTAT_REGNUM (tdep), &fstat);
       fstat |= (7 << 11);
       fstat |= (7 << 11);
-      regcache_raw_write_unsigned (regcache, I387_FSTAT_REGNUM, fstat);
+      regcache_raw_write_unsigned (regcache, I387_FSTAT_REGNUM (tdep), fstat);
 
       /* Mark %st(1) through %st(7) as empty.  Since we set the top of
          the floating-point register stack to 7, the appropriate value
          for the tag word is 0x3fff.  */
 
       /* Mark %st(1) through %st(7) as empty.  Since we set the top of
          the floating-point register stack to 7, the appropriate value
          for the tag word is 0x3fff.  */
-      regcache_raw_write_unsigned (regcache, I387_FTAG_REGNUM, 0x3fff);
+      regcache_raw_write_unsigned (regcache, I387_FTAG_REGNUM (tdep), 0x3fff);
     }
   else
     {
     }
   else
     {
-      int low_size = register_size (current_gdbarch, LOW_RETURN_REGNUM);
-      int high_size = register_size (current_gdbarch, HIGH_RETURN_REGNUM);
+      int low_size = register_size (gdbarch, LOW_RETURN_REGNUM);
+      int high_size = register_size (gdbarch, HIGH_RETURN_REGNUM);
 
       if (len <= low_size)
        regcache_raw_write_part (regcache, LOW_RETURN_REGNUM, 0, len, valbuf);
 
       if (len <= low_size)
        regcache_raw_write_part (regcache, LOW_RETURN_REGNUM, 0, len, valbuf);
@@ -1467,8 +1664,6 @@ i386_store_return_value (struct gdbarch *gdbarch, struct type *type,
        internal_error (__FILE__, __LINE__,
                        _("Cannot store return value of %d bytes long."), len);
     }
        internal_error (__FILE__, __LINE__,
                        _("Cannot store return value of %d bytes long."), len);
     }
-
-#undef I387_ST0_REGNUM
 }
 \f
 
 }
 \f
 
@@ -1525,16 +1720,18 @@ i386_reg_struct_return_p (struct gdbarch *gdbarch, struct type *type)
    from WRITEBUF into REGCACHE.  */
 
 static enum return_value_convention
    from WRITEBUF into REGCACHE.  */
 
 static enum return_value_convention
-i386_return_value (struct gdbarch *gdbarch, struct type *type,
-                  struct regcache *regcache, gdb_byte *readbuf,
-                  const gdb_byte *writebuf)
+i386_return_value (struct gdbarch *gdbarch, struct type *func_type,
+                  struct type *type, struct regcache *regcache,
+                  gdb_byte *readbuf, const gdb_byte *writebuf)
 {
   enum type_code code = TYPE_CODE (type);
 
 {
   enum type_code code = TYPE_CODE (type);
 
-  if ((code == TYPE_CODE_STRUCT
-       || code == TYPE_CODE_UNION
-       || code == TYPE_CODE_ARRAY)
-      && !i386_reg_struct_return_p (gdbarch, type))
+  if (((code == TYPE_CODE_STRUCT
+       || code == TYPE_CODE_UNION
+       || code == TYPE_CODE_ARRAY)
+       && !i386_reg_struct_return_p (gdbarch, type))
+      /* 128-bit decimal float uses the struct return convention.  */
+      || (code == TYPE_CODE_DECFLOAT && TYPE_LENGTH (type) == 16))
     {
       /* The System V ABI says that:
 
     {
       /* The System V ABI says that:
 
@@ -1574,7 +1771,8 @@ i386_return_value (struct gdbarch *gdbarch, struct type *type,
   if (code == TYPE_CODE_STRUCT && TYPE_NFIELDS (type) == 1)
     {
       type = check_typedef (TYPE_FIELD_TYPE (type, 0));
   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);
+      return i386_return_value (gdbarch, func_type, type, regcache,
+                               readbuf, writebuf);
     }
 
   if (readbuf)
     }
 
   if (readbuf)
@@ -1589,9 +1787,7 @@ i386_return_value (struct gdbarch *gdbarch, struct type *type,
 /* Type for %eflags.  */
 struct type *i386_eflags_type;
 
 /* 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;
+/* Type for %mxcsr.  */
 struct type *i386_mxcsr_type;
 
 /* Construct types for ISA-specific registers.  */
 struct type *i386_mxcsr_type;
 
 /* Construct types for ISA-specific registers.  */
@@ -1620,52 +1816,6 @@ i386_init_types (void)
   append_flags_type_flag (type, 21, "ID");
   i386_eflags_type = type;
 
   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");
   type = init_flags_type ("builtin_type_i386_mxcsr", 4);
   append_flags_type_flag (type, 0, "IE");
   append_flags_type_flag (type, 1, "DE");
@@ -1684,6 +1834,90 @@ i386_init_types (void)
   i386_mxcsr_type = type;
 }
 
   i386_mxcsr_type = type;
 }
 
+/* Construct vector type for MMX registers.  */
+struct type *
+i386_mmx_type (struct gdbarch *gdbarch)
+{
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+  if (!tdep->i386_mmx_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
+
+      struct type *t;
+
+      t = init_composite_type ("__gdb_builtin_type_vec64i", TYPE_CODE_UNION);
+      append_composite_type_field (t, "uint64", builtin_type_int64);
+      append_composite_type_field (t, "v2_int32",
+                                  init_vector_type (builtin_type_int32, 2));
+      append_composite_type_field (t, "v4_int16",
+                                  init_vector_type (builtin_type_int16, 4));
+      append_composite_type_field (t, "v8_int8",
+                                  init_vector_type (builtin_type_int8, 8));
+
+      TYPE_FLAGS (t) |= TYPE_FLAG_VECTOR;
+      TYPE_NAME (t) = "builtin_type_vec64i";
+      tdep->i386_mmx_type = t;
+    }
+
+  return tdep->i386_mmx_type;
+}
+
+struct type *
+i386_sse_type (struct gdbarch *gdbarch)
+{
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+  if (!tdep->i386_sse_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
+
+      struct type *t;
+
+      t = init_composite_type ("__gdb_builtin_type_vec128i", TYPE_CODE_UNION);
+      append_composite_type_field (t, "v4_float",
+                                  init_vector_type (builtin_type_float, 4));
+      append_composite_type_field (t, "v2_double",
+                                  init_vector_type (builtin_type_double, 2));
+      append_composite_type_field (t, "v16_int8",
+                                  init_vector_type (builtin_type_int8, 16));
+      append_composite_type_field (t, "v8_int16",
+                                  init_vector_type (builtin_type_int16, 8));
+      append_composite_type_field (t, "v4_int32",
+                                  init_vector_type (builtin_type_int32, 4));
+      append_composite_type_field (t, "v2_int64",
+                                  init_vector_type (builtin_type_int64, 2));
+      append_composite_type_field (t, "uint128", builtin_type_int128);
+
+      TYPE_FLAGS (t) |= TYPE_FLAG_VECTOR;
+      TYPE_NAME (t) = "builtin_type_vec128i";
+      tdep->i386_sse_type = t;
+    }
+
+  return tdep->i386_sse_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.  */
 /* 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.  */
@@ -1700,24 +1934,18 @@ i386_register_type (struct gdbarch *gdbarch, int regnum)
   if (regnum == I386_EBP_REGNUM || regnum == I386_ESP_REGNUM)
     return builtin_type_void_data_ptr;
 
   if (regnum == I386_EBP_REGNUM || regnum == I386_ESP_REGNUM)
     return builtin_type_void_data_ptr;
 
-  if (i386_fp_regnum_p (regnum))
+  if (i386_fp_regnum_p (gdbarch, regnum))
     return builtin_type_i387_ext;
 
   if (i386_mmx_regnum_p (gdbarch, regnum))
     return builtin_type_i387_ext;
 
   if (i386_mmx_regnum_p (gdbarch, regnum))
-    return i386_mmx_type;
+    return i386_mmx_type (gdbarch);
 
   if (i386_sse_regnum_p (gdbarch, regnum))
 
   if (i386_sse_regnum_p (gdbarch, regnum))
-    return i386_sse_type;
-
-#define I387_ST0_REGNUM I386_ST0_REGNUM
-#define I387_NUM_XMM_REGS (gdbarch_tdep (current_gdbarch)->num_xmm_regs)
+    return i386_sse_type (gdbarch);
 
 
-  if (regnum == I387_MXCSR_REGNUM)
+  if (regnum == I387_MXCSR_REGNUM (gdbarch_tdep (gdbarch)))
     return i386_mxcsr_type;
 
     return i386_mxcsr_type;
 
-#undef I387_ST0_REGNUM
-#undef I387_NUM_XMM_REGS
-
   return builtin_type_int;
 }
 
   return builtin_type_int;
 }
 
@@ -1732,18 +1960,12 @@ i386_mmx_regnum_to_fp_regnum (struct regcache *regcache, int regnum)
   ULONGEST fstat;
   int tos;
 
   ULONGEST fstat;
   int tos;
 
-  /* Define I387_ST0_REGNUM such that we use the proper definitions
-     for REGCACHE's architecture.  */
-#define I387_ST0_REGNUM tdep->st0_regnum
-
   mmxreg = regnum - tdep->mm0_regnum;
   mmxreg = regnum - tdep->mm0_regnum;
-  regcache_raw_read_unsigned (regcache, I387_FSTAT_REGNUM, &fstat);
+  regcache_raw_read_unsigned (regcache, I387_FSTAT_REGNUM (tdep), &fstat);
   tos = (fstat >> 11) & 0x7;
   fpreg = (mmxreg + tos) % 8;
 
   tos = (fstat >> 11) & 0x7;
   fpreg = (mmxreg + tos) % 8;
 
-  return (I387_ST0_REGNUM + fpreg);
-
-#undef I387_ST0_REGNUM
+  return (I387_ST0_REGNUM (tdep) + fpreg);
 }
 
 static void
 }
 
 static void
@@ -1817,7 +2039,7 @@ i386_next_regnum (int regnum)
    needs any special handling.  */
 
 static int
    needs any special handling.  */
 
 static int
-i386_convert_register_p (int regnum, struct type *type)
+i386_convert_register_p (struct gdbarch *gdbarch, int regnum, struct type *type)
 {
   int len = TYPE_LENGTH (type);
 
 {
   int len = TYPE_LENGTH (type);
 
@@ -1840,7 +2062,7 @@ i386_convert_register_p (int regnum, struct type *type)
        return 1;
     }
 
        return 1;
     }
 
-  return i386_fp_regnum_p (regnum);
+  return i387_convert_register_p (gdbarch, regnum, type);
 }
 
 /* Read a value of type TYPE from register REGNUM in frame FRAME, and
 }
 
 /* Read a value of type TYPE from register REGNUM in frame FRAME, and
@@ -1850,12 +2072,13 @@ static void
 i386_register_to_value (struct frame_info *frame, int regnum,
                        struct type *type, gdb_byte *to)
 {
 i386_register_to_value (struct frame_info *frame, int regnum,
                        struct type *type, gdb_byte *to)
 {
+  struct gdbarch *gdbarch = get_frame_arch (frame);
   int len = TYPE_LENGTH (type);
 
   /* FIXME: kettenis/20030609: What should we do if REGNUM isn't
      available in FRAME (i.e. if it wasn't saved)?  */
 
   int len = TYPE_LENGTH (type);
 
   /* FIXME: kettenis/20030609: What should we do if REGNUM isn't
      available in FRAME (i.e. if it wasn't saved)?  */
 
-  if (i386_fp_regnum_p (regnum))
+  if (i386_fp_regnum_p (gdbarch, regnum))
     {
       i387_register_to_value (frame, regnum, type, to);
       return;
     {
       i387_register_to_value (frame, regnum, type, to);
       return;
@@ -1868,7 +2091,7 @@ i386_register_to_value (struct frame_info *frame, int regnum,
   while (len > 0)
     {
       gdb_assert (regnum != -1);
   while (len > 0)
     {
       gdb_assert (regnum != -1);
-      gdb_assert (register_size (current_gdbarch, regnum) == 4);
+      gdb_assert (register_size (gdbarch, regnum) == 4);
 
       get_frame_register (frame, regnum, to);
       regnum = i386_next_regnum (regnum);
 
       get_frame_register (frame, regnum, to);
       regnum = i386_next_regnum (regnum);
@@ -1886,7 +2109,7 @@ i386_value_to_register (struct frame_info *frame, int regnum,
 {
   int len = TYPE_LENGTH (type);
 
 {
   int len = TYPE_LENGTH (type);
 
-  if (i386_fp_regnum_p (regnum))
+  if (i386_fp_regnum_p (get_frame_arch (frame), regnum))
     {
       i387_value_to_register (frame, regnum, type, from);
       return;
     {
       i387_value_to_register (frame, regnum, type, from);
       return;
@@ -1899,7 +2122,7 @@ i386_value_to_register (struct frame_info *frame, int regnum,
   while (len > 0)
     {
       gdb_assert (regnum != -1);
   while (len > 0)
     {
       gdb_assert (regnum != -1);
-      gdb_assert (register_size (current_gdbarch, regnum) == 4);
+      gdb_assert (register_size (get_frame_arch (frame), regnum) == 4);
 
       put_frame_register (frame, regnum, from);
       regnum = i386_next_regnum (regnum);
 
       put_frame_register (frame, regnum, from);
       regnum = i386_next_regnum (regnum);
@@ -2027,32 +2250,6 @@ i386_regset_from_core_section (struct gdbarch *gdbarch,
 }
 \f
 
 }
 \f
 
-#ifdef STATIC_TRANSFORM_NAME
-/* SunPRO encodes the static variables.  This is not related to C++
-   mangling, it is done for C too.  */
-
-char *
-sunpro_static_transform_name (char *name)
-{
-  char *p;
-  if (IS_STATIC_TRANSFORM_NAME (name))
-    {
-      /* For file-local statics there will be a period, a bunch of
-         junk (the contents of which match a string given in the
-         N_OPT), a period and the name.  For function-local statics
-         there will be a bunch of junk (which seems to change the
-         second character from 'A' to 'B'), a period, the name of the
-         function, and the name.  So just skip everything before the
-         last period.  */
-      p = strrchr (name, '.');
-      if (p != NULL)
-       name = p + 1;
-    }
-  return name;
-}
-#endif /* STATIC_TRANSFORM_NAME */
-\f
-
 /* Stuff for WIN32 PE style DLL's but is pretty generic really.  */
 
 CORE_ADDR
 /* Stuff for WIN32 PE style DLL's but is pretty generic really.  */
 
 CORE_ADDR
@@ -2076,13 +2273,13 @@ i386_pe_skip_trampoline_code (CORE_ADDR pc, char *name)
 }
 \f
 
 }
 \f
 
-/* Return whether the frame preceding NEXT_FRAME corresponds to a
-   sigtramp routine.  */
+/* Return whether the THIS_FRAME corresponds to a sigtramp
+   routine.  */
 
 static int
 
 static int
-i386_sigtramp_p (struct frame_info *next_frame)
+i386_sigtramp_p (struct frame_info *this_frame)
 {
 {
-  CORE_ADDR pc = frame_pc_unwind (next_frame);
+  CORE_ADDR pc = get_frame_pc (this_frame);
   char *name;
 
   find_pc_partial_function (pc, &name, NULL, NULL);
   char *name;
 
   find_pc_partial_function (pc, &name, NULL, NULL);
@@ -2102,7 +2299,6 @@ i386_print_insn (bfd_vma pc, struct disassemble_info *info)
   /* FIXME: kettenis/20020915: Until disassembler_options is properly
      constified, cast to prevent a compiler warning.  */
   info->disassembler_options = (char *) disassembly_flavor;
   /* FIXME: kettenis/20020915: Until disassembler_options is properly
      constified, cast to prevent a compiler warning.  */
   info->disassembler_options = (char *) disassembly_flavor;
-  info->mach = gdbarch_bfd_arch_info (current_gdbarch)->mach;
 
   return print_insn_i386 (pc, info);
 }
 
   return print_insn_i386 (pc, info);
 }
@@ -2115,13 +2311,13 @@ i386_print_insn (bfd_vma pc, struct disassemble_info *info)
 
 /* System V Release 4 (SVR4).  */
 
 
 /* System V Release 4 (SVR4).  */
 
-/* Return whether the frame preceding NEXT_FRAME corresponds to a SVR4
-   sigtramp routine.  */
+/* Return whether THIS_FRAME corresponds to a SVR4 sigtramp
+   routine.  */
 
 static int
 
 static int
-i386_svr4_sigtramp_p (struct frame_info *next_frame)
+i386_svr4_sigtramp_p (struct frame_info *this_frame)
 {
 {
-  CORE_ADDR pc = frame_pc_unwind (next_frame);
+  CORE_ADDR pc = get_frame_pc (this_frame);
   char *name;
 
   /* UnixWare uses _sigacthandler.  The origin of the other symbols is
   char *name;
 
   /* UnixWare uses _sigacthandler.  The origin of the other symbols is
@@ -2132,17 +2328,16 @@ i386_svr4_sigtramp_p (struct frame_info *next_frame)
                   || strcmp ("sigvechandler", name) == 0));
 }
 
                   || strcmp ("sigvechandler", name) == 0));
 }
 
-/* Assuming NEXT_FRAME is for a frame following a SVR4 sigtramp
-   routine, return the address of the associated sigcontext (ucontext)
-   structure.  */
+/* Assuming THIS_FRAME is for a SVR4 sigtramp routine, return the
+   address of the associated sigcontext (ucontext) structure.  */
 
 static CORE_ADDR
 
 static CORE_ADDR
-i386_svr4_sigcontext_addr (struct frame_info *next_frame)
+i386_svr4_sigcontext_addr (struct frame_info *this_frame)
 {
   gdb_byte buf[4];
   CORE_ADDR sp;
 
 {
   gdb_byte buf[4];
   CORE_ADDR sp;
 
-  frame_unwind_register (next_frame, I386_ESP_REGNUM, buf);
+  get_frame_register (this_frame, I386_ESP_REGNUM, buf);
   sp = extract_unsigned_integer (buf, 4);
 
   return read_memory_unsigned_integer (sp + 8, 4);
   sp = extract_unsigned_integer (buf, 4);
 
   return read_memory_unsigned_integer (sp + 8, 4);
@@ -2191,16 +2386,6 @@ i386_go32_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
 
   tdep->jb_pc_offset = 36;
 }
 
   tdep->jb_pc_offset = 36;
 }
-
-/* NetWare.  */
-
-static void
-i386_nw_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
-{
-  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
-
-  tdep->jb_pc_offset = 24;
-}
 \f
 
 /* i386 register groups.  In addition to the normal groups, add "mmx"
 \f
 
 /* i386 register groups.  In addition to the normal groups, add "mmx"
@@ -2236,8 +2421,8 @@ i386_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
 {
   int sse_regnum_p = (i386_sse_regnum_p (gdbarch, regnum)
                      || i386_mxcsr_regnum_p (gdbarch, regnum));
 {
   int sse_regnum_p = (i386_sse_regnum_p (gdbarch, regnum)
                      || i386_mxcsr_regnum_p (gdbarch, regnum));
-  int fp_regnum_p = (i386_fp_regnum_p (regnum)
-                    || i386_fpc_regnum_p (regnum));
+  int fp_regnum_p = (i386_fp_regnum_p (gdbarch, regnum)
+                    || i386_fpc_regnum_p (gdbarch, regnum));
   int mmx_regnum_p = (i386_mmx_regnum_p (gdbarch, regnum));
 
   if (group == i386_mmx_reggroup)
   int mmx_regnum_p = (i386_mmx_regnum_p (gdbarch, regnum));
 
   if (group == i386_mmx_reggroup)
@@ -2278,7 +2463,7 @@ i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
     return arches->gdbarch;
 
   /* Allocate space for the new architecture.  */
     return arches->gdbarch;
 
   /* Allocate space for the new architecture.  */
-  tdep = XMALLOC (struct gdbarch_tdep);
+  tdep = XCALLOC (1, struct gdbarch_tdep);
   gdbarch = gdbarch_alloc (&info, tdep);
 
   /* General-purpose registers.  */
   gdbarch = gdbarch_alloc (&info, tdep);
 
   /* General-purpose registers.  */
@@ -2329,7 +2514,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.  */
      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
 
   /* Although the i387 extended floating-point has only 80 significant
      bits, a `long double' actually takes up 96, probably to enforce
@@ -2386,7 +2571,7 @@ i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   set_gdbarch_dwarf_reg_to_regnum (gdbarch, i386_svr4_reg_to_regnum);
   set_gdbarch_dwarf2_reg_to_regnum (gdbarch, i386_svr4_reg_to_regnum);
 
   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
+  /* We don't set gdbarch_stab_reg_to_regnum, since ECOFF doesn't seem to
      be in use on any of the supported i386 targets.  */
 
   set_gdbarch_print_float_info (gdbarch, i387_print_float_info);
      be in use on any of the supported i386 targets.  */
 
   set_gdbarch_print_float_info (gdbarch, i387_print_float_info);
@@ -2409,6 +2594,7 @@ 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_breakpoint_from_pc (gdbarch, i386_breakpoint_from_pc);
   set_gdbarch_decr_pc_after_break (gdbarch, 1);
+  set_gdbarch_max_insn_length (gdbarch, I386_MAX_INSN_LEN);
 
   set_gdbarch_frame_args_skip (gdbarch, 8);
 
 
   set_gdbarch_frame_args_skip (gdbarch, 8);
 
@@ -2419,7 +2605,7 @@ i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 
   set_gdbarch_print_insn (gdbarch, i386_print_insn);
 
 
   set_gdbarch_print_insn (gdbarch, i386_print_insn);
 
-  set_gdbarch_unwind_dummy_id (gdbarch, i386_unwind_dummy_id);
+  set_gdbarch_dummy_id (gdbarch, i386_dummy_id);
 
   set_gdbarch_unwind_pc (gdbarch, i386_unwind_pc);
 
 
   set_gdbarch_unwind_pc (gdbarch, i386_unwind_pc);
 
@@ -2431,15 +2617,15 @@ i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   set_gdbarch_fetch_pointer_argument (gdbarch, i386_fetch_pointer_argument);
 
   /* Hook in the DWARF CFI frame unwinder.  */
   set_gdbarch_fetch_pointer_argument (gdbarch, i386_fetch_pointer_argument);
 
   /* Hook in the DWARF CFI frame unwinder.  */
-  frame_unwind_append_sniffer (gdbarch, dwarf2_frame_sniffer);
+  dwarf2_append_unwinders (gdbarch);
 
   frame_base_set_default (gdbarch, &i386_frame_base);
 
   /* Hook in ABI-specific overrides, if they have been registered.  */
   gdbarch_init_osabi (info, gdbarch);
 
 
   frame_base_set_default (gdbarch, &i386_frame_base);
 
   /* Hook in ABI-specific overrides, if they have been registered.  */
   gdbarch_init_osabi (info, gdbarch);
 
-  frame_unwind_append_sniffer (gdbarch, i386_sigtramp_frame_sniffer);
-  frame_unwind_append_sniffer (gdbarch, i386_frame_sniffer);
+  frame_unwind_append_unwinder (gdbarch, &i386_sigtramp_frame_unwind);
+  frame_unwind_append_unwinder (gdbarch, &i386_frame_unwind);
 
   /* If we have a register mapping, enable the generic core file
      support, unless it has already been enabled.  */
 
   /* If we have a register mapping, enable the generic core file
      support, unless it has already been enabled.  */
@@ -2465,12 +2651,6 @@ i386_coff_osabi_sniffer (bfd *abfd)
 
   return GDB_OSABI_UNKNOWN;
 }
 
   return GDB_OSABI_UNKNOWN;
 }
-
-static enum gdb_osabi
-i386_nlm_osabi_sniffer (bfd *abfd)
-{
-  return GDB_OSABI_NETWARE;
-}
 \f
 
 /* Provide a prototype to silence -Wmissing-prototypes.  */
 \f
 
 /* Provide a prototype to silence -Wmissing-prototypes.  */
@@ -2505,15 +2685,11 @@ is \"default\"."),
 
   gdbarch_register_osabi_sniffer (bfd_arch_i386, bfd_target_coff_flavour,
                                  i386_coff_osabi_sniffer);
 
   gdbarch_register_osabi_sniffer (bfd_arch_i386, bfd_target_coff_flavour,
                                  i386_coff_osabi_sniffer);
-  gdbarch_register_osabi_sniffer (bfd_arch_i386, bfd_target_nlm_flavour,
-                                 i386_nlm_osabi_sniffer);
 
   gdbarch_register_osabi (bfd_arch_i386, 0, GDB_OSABI_SVR4,
                          i386_svr4_init_abi);
   gdbarch_register_osabi (bfd_arch_i386, 0, GDB_OSABI_GO32,
                          i386_go32_init_abi);
 
   gdbarch_register_osabi (bfd_arch_i386, 0, GDB_OSABI_SVR4,
                          i386_svr4_init_abi);
   gdbarch_register_osabi (bfd_arch_i386, 0, GDB_OSABI_GO32,
                          i386_go32_init_abi);
-  gdbarch_register_osabi (bfd_arch_i386, 0, GDB_OSABI_NETWARE,
-                         i386_nw_init_abi);
 
   /* Initialize the i386-specific register groups & types.  */
   i386_init_reggroups ();
 
   /* Initialize the i386-specific register groups & types.  */
   i386_init_reggroups ();
This page took 0.045929 seconds and 4 git commands to generate.