gdb: add target_ops::supports_displaced_step
[deliverable/binutils-gdb.git] / gdb / ia64-tdep.c
index dd2064c9ba9ad91e639e1613e7cbc80f2f084238..1d1fd2e5f0ee479edfccd2da05442e06d43a03a5 100644 (file)
@@ -1,7 +1,6 @@
 /* Target-dependent code for the IA-64 for GDB, the GNU debugger.
 
-   Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
-   Free Software Foundation, Inc.
+   Copyright (C) 1999-2020 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -29,9 +28,8 @@
 #include "frame.h"
 #include "frame-base.h"
 #include "frame-unwind.h"
-#include "doublest.h"
+#include "target-float.h"
 #include "value.h"
-#include "gdb_assert.h"
 #include "objfiles.h"
 #include "elf/common.h"                /* for DT_PLTGOT value */
 #include "elf-bfd.h"
@@ -43,8 +41,7 @@
 
 #ifdef HAVE_LIBUNWIND_IA64_H
 #include "elf/ia64.h"           /* for PT_IA_64_UNWIND value */
-#include "libunwind-frame.h"
-#include "libunwind-ia64.h"
+#include "ia64-libunwind-tdep.h"
 
 /* Note: KERNEL_START is supposed to be an address which is not going
          to ever contain any valid unwind info.  For ia64 linux, the choice
@@ -72,6 +69,7 @@ struct ia64_table_entry
   };
 
 static struct ia64_table_entry *ktab = NULL;
+static gdb::optional<gdb::byte_vector> ktab_buf;
 
 #endif
 
@@ -102,14 +100,20 @@ typedef enum instruction_type
    is set to six (which is how it was set up initially). -- objdump
    displays pretty disassembly dumps with this value.  For our purposes,
    we'll set bytes_per_line to SLOT_MULTIPLIER. This is okay since we
-   never want to also display the raw bytes the way objdump does. */
+   never want to also display the raw bytes the way objdump does.  */
 
 #define SLOT_MULTIPLIER 1
 
-/* Length in bytes of an instruction bundle */
+/* Length in bytes of an instruction bundle */
 
 #define BUNDLE_LEN 16
 
+/* See the saved memory layout comment for ia64_memory_insert_breakpoint.  */
+
+#if BREAKPOINT_MAX < BUNDLE_LEN - 2
+# error "BREAKPOINT_MAX < BUNDLE_LEN - 2"
+#endif
+
 static gdbarch_init_ftype ia64_gdbarch_init;
 
 static gdbarch_register_name_ftype ia64_register_name;
@@ -117,26 +121,30 @@ static gdbarch_register_type_ftype ia64_register_type;
 static gdbarch_breakpoint_from_pc_ftype ia64_breakpoint_from_pc;
 static gdbarch_skip_prologue_ftype ia64_skip_prologue;
 static struct type *is_float_or_hfa_type (struct type *t);
-static CORE_ADDR ia64_find_global_pointer (CORE_ADDR faddr);
-
-static struct type *builtin_type_ia64_ext;
+static CORE_ADDR ia64_find_global_pointer (struct gdbarch *gdbarch,
+                                          CORE_ADDR faddr);
 
 #define NUM_IA64_RAW_REGS 462
 
+/* Big enough to hold a FP register in bytes.  */
+#define IA64_FP_REGISTER_SIZE 16
+
 static int sp_regnum = IA64_GR12_REGNUM;
-static int fp_regnum = IA64_VFP_REGNUM;
-static int lr_regnum = IA64_VRAP_REGNUM;
 
-/* NOTE: we treat the register stack registers r32-r127 as pseudo-registers because
-   they may not be accessible via the ptrace register get/set interfaces.  */
-enum pseudo_regs { FIRST_PSEUDO_REGNUM = NUM_IA64_RAW_REGS, VBOF_REGNUM = IA64_NAT127_REGNUM + 1, V32_REGNUM, 
+/* NOTE: we treat the register stack registers r32-r127 as
+   pseudo-registers because they may not be accessible via the ptrace
+   register get/set interfaces.  */
+
+enum pseudo_regs { FIRST_PSEUDO_REGNUM = NUM_IA64_RAW_REGS,
+                  VBOF_REGNUM = IA64_NAT127_REGNUM + 1, V32_REGNUM, 
                   V127_REGNUM = V32_REGNUM + 95, 
-                  VP0_REGNUM, VP16_REGNUM = VP0_REGNUM + 16, VP63_REGNUM = VP0_REGNUM + 63, LAST_PSEUDO_REGNUM };
+                  VP0_REGNUM, VP16_REGNUM = VP0_REGNUM + 16,
+                  VP63_REGNUM = VP0_REGNUM + 63, LAST_PSEUDO_REGNUM };
 
 /* Array of register names; There should be ia64_num_regs strings in
    the initializer.  */
 
-static char *ia64_register_names[] = 
+static const char *ia64_register_names[] =
 { "r0",   "r1",   "r2",   "r3",   "r4",   "r5",   "r6",   "r7",
   "r8",   "r9",   "r10",  "r11",  "r12",  "r13",  "r14",  "r15",
   "r16",  "r17",  "r18",  "r19",  "r20",  "r21",  "r22",  "r23",
@@ -254,27 +262,65 @@ struct ia64_frame_cache
   CORE_ADDR cfm;       /* cfm value for current frame */
   CORE_ADDR prev_cfm;   /* cfm value for previous frame */
   int   frameless;
-  int   sof;           /* Size of frame  (decoded from cfm value) */
-  int  sol;            /* Size of locals (decoded from cfm value) */
-  int  sor;            /* Number of rotating registers. (decoded from cfm value) */
+  int   sof;           /* Size of frame  (decoded from cfm value).  */
+  int  sol;            /* Size of locals (decoded from cfm value).  */
+  int  sor;            /* Number of rotating registers (decoded from
+                          cfm value).  */
   CORE_ADDR after_prologue;
   /* Address of first instruction after the last
      prologue instruction;  Note that there may
      be instructions from the function's body
-     intermingled with the prologue. */
+     intermingled with the prologue.  */
   int mem_stack_frame_size;
   /* Size of the memory stack frame (may be zero),
-     or -1 if it has not been determined yet. */
+     or -1 if it has not been determined yet.  */
   int  fp_reg;         /* Register number (if any) used a frame pointer
                           for this frame.  0 if no register is being used
-                          as the frame pointer. */
+                          as the frame pointer.  */
   
   /* Saved registers.  */
   CORE_ADDR saved_regs[NUM_IA64_RAW_REGS];
 
 };
 
-int
+static int
+floatformat_valid (const struct floatformat *fmt, const void *from)
+{
+  return 1;
+}
+
+static const struct floatformat floatformat_ia64_ext_little =
+{
+  floatformat_little, 82, 0, 1, 17, 65535, 0x1ffff, 18, 64,
+  floatformat_intbit_yes, "floatformat_ia64_ext_little", floatformat_valid, NULL
+};
+
+static const struct floatformat floatformat_ia64_ext_big =
+{
+  floatformat_big, 82, 46, 47, 17, 65535, 0x1ffff, 64, 64,
+  floatformat_intbit_yes, "floatformat_ia64_ext_big", floatformat_valid
+};
+
+static const struct floatformat *floatformats_ia64_ext[2] =
+{
+  &floatformat_ia64_ext_big,
+  &floatformat_ia64_ext_little
+};
+
+static struct type *
+ia64_ext_type (struct gdbarch *gdbarch)
+{
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+  if (!tdep->ia64_ext_type)
+    tdep->ia64_ext_type
+      = arch_float_type (gdbarch, 128, "builtin_type_ia64_ext",
+                        floatformats_ia64_ext);
+
+  return tdep->ia64_ext_type;
+}
+
+static int
 ia64_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
                          struct reggroup *group)
 {
@@ -284,7 +330,7 @@ ia64_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
   if (group == all_reggroup)
     return 1;
   vector_p = TYPE_VECTOR (register_type (gdbarch, regnum));
-  float_p = TYPE_CODE (register_type (gdbarch, regnum)) == TYPE_CODE_FLT;
+  float_p = register_type (gdbarch, regnum)->code () == TYPE_CODE_FLT;
   raw_p = regnum < NUM_IA64_RAW_REGS;
   if (group == float_reggroup)
     return float_p;
@@ -307,9 +353,9 @@ struct type *
 ia64_register_type (struct gdbarch *arch, int reg)
 {
   if (reg >= IA64_FR0_REGNUM && reg <= IA64_FR127_REGNUM)
-    return builtin_type_ia64_ext;
+    return ia64_ext_type (arch);
   else
-    return builtin_type_long;
+    return builtin_type (arch)->builtin_long;
 }
 
 static int
@@ -320,30 +366,12 @@ ia64_dwarf_reg_to_regnum (struct gdbarch *gdbarch, int reg)
   return reg;
 }
 
-static int
-floatformat_valid (const struct floatformat *fmt, const void *from)
-{
-  return 1;
-}
-
-const struct floatformat floatformat_ia64_ext =
-{
-  floatformat_little, 82, 0, 1, 17, 65535, 0x1ffff, 18, 64,
-  floatformat_intbit_yes, "floatformat_ia64_ext", floatformat_valid, NULL
-};
-
-const struct floatformat *floatformats_ia64_ext[2] =
-{
-  &floatformat_ia64_ext,
-  &floatformat_ia64_ext
-};
-
 
 /* Extract ``len'' bits from an instruction bundle starting at
    bit ``from''.  */
 
 static long long
-extract_bit_field (char *bundle, int from, int len)
+extract_bit_field (const gdb_byte *bundle, int from, int len)
 {
   long long result = 0LL;
   int to = from + len;
@@ -376,10 +404,10 @@ extract_bit_field (char *bundle, int from, int len)
   return result;
 }
 
-/* Replace the specified bits in an instruction bundle */
+/* Replace the specified bits in an instruction bundle */
 
 static void
-replace_bit_field (char *bundle, long long val, int from, int len)
+replace_bit_field (gdb_byte *bundle, long long val, int from, int len)
 {
   int to = from + len;
   int from_byte = from / 8;
@@ -426,23 +454,23 @@ replace_bit_field (char *bundle, long long val, int from, int len)
 }
 
 /* Return the contents of slot N (for N = 0, 1, or 2) in
-   and instruction bundle */
+   and instruction bundle */
 
 static long long
-slotN_contents (char *bundle, int slotnum)
+slotN_contents (gdb_byte *bundle, int slotnum)
 {
   return extract_bit_field (bundle, 5+41*slotnum, 41);
 }
 
-/* Store an instruction in an instruction bundle */
+/* Store an instruction in an instruction bundle */
 
 static void
-replace_slotN_contents (char *bundle, long long instr, int slotnum)
+replace_slotN_contents (gdb_byte *bundle, long long instr, int slotnum)
 {
   replace_bit_field (bundle, instr, 5+41*slotnum, 41);
 }
 
-static enum instruction_type template_encoding_table[32][3] =
+static const enum instruction_type template_encoding_table[32][3] =
 {
   { M, I, I },                         /* 00 */
   { M, I, I },                         /* 01 */
@@ -484,9 +512,9 @@ static enum instruction_type template_encoding_table[32][3] =
 static CORE_ADDR
 fetch_instruction (CORE_ADDR addr, instruction_type *it, long long *instr)
 {
-  char bundle[BUNDLE_LEN];
+  gdb_byte bundle[BUNDLE_LEN];
   int slotnum = (int) (addr & 0x0f) / SLOT_MULTIPLIER;
-  long long template;
+  long long templ;
   int val;
 
   /* Warn about slot numbers greater than 2.  We used to generate
@@ -517,8 +545,8 @@ fetch_instruction (CORE_ADDR addr, instruction_type *it, long long *instr)
     return 0;
 
   *instr = slotN_contents (bundle, slotnum);
-  template = extract_bit_field (bundle, 0, 5);
-  *it = template_encoding_table[(int)template][slotnum];
+  templ = extract_bit_field (bundle, 0, 5);
+  *it = template_encoding_table[(int)templ][slotnum];
 
   if (slotnum == 2 || (slotnum == 1 && *it == L))
     addr += 16;
@@ -545,45 +573,153 @@ fetch_instruction (CORE_ADDR addr, instruction_type *it, long long *instr)
    simulators.  So I changed the pattern slightly to do "break.i 0x080001"
    instead.  But that didn't work either (I later found out that this
    pattern was used by the simulator that I was using.)  So I ended up
-   using the pattern seen below. */
+   using the pattern seen below.
+
+   SHADOW_CONTENTS has byte-based addressing (PLACED_ADDRESS and SHADOW_LEN)
+   while we need bit-based addressing as the instructions length is 41 bits and
+   we must not modify/corrupt the adjacent slots in the same bundle.
+   Fortunately we may store larger memory incl. the adjacent bits with the
+   original memory content (not the possibly already stored breakpoints there).
+   We need to be careful in ia64_memory_remove_breakpoint to always restore
+   only the specific bits of this instruction ignoring any adjacent stored
+   bits.
+
+   We use the original addressing with the low nibble in the range <0..2> which
+   gets incorrectly interpreted by generic non-ia64 breakpoint_restore_shadows
+   as the direct byte offset of SHADOW_CONTENTS.  We store whole BUNDLE_LEN
+   bytes just without these two possibly skipped bytes to not to exceed to the
+   next bundle.
+
+   If we would like to store the whole bundle to SHADOW_CONTENTS we would have
+   to store already the base address (`address & ~0x0f') into PLACED_ADDRESS.
+   In such case there is no other place where to store
+   SLOTNUM (`adress & 0x0f', value in the range <0..2>).  We need to know
+   SLOTNUM in ia64_memory_remove_breakpoint.
+
+   There is one special case where we need to be extra careful:
+   L-X instructions, which are instructions that occupy 2 slots
+   (The L part is always in slot 1, and the X part is always in
+   slot 2).  We must refuse to insert breakpoints for an address
+   that points at slot 2 of a bundle where an L-X instruction is
+   present, since there is logically no instruction at that address.
+   However, to make things more interesting, the opcode of L-X
+   instructions is located in slot 2.  This means that, to insert
+   a breakpoint at an address that points to slot 1, we actually
+   need to write the breakpoint in slot 2!  Slot 1 is actually
+   the extended operand, so writing the breakpoint there would not
+   have the desired effect.  Another side-effect of this issue
+   is that we need to make sure that the shadow contents buffer
+   does save byte 15 of our instruction bundle (this is the tail
+   end of slot 2, which wouldn't be saved if we were to insert
+   the breakpoint in slot 1).
+   
+   ia64 16-byte bundle layout:
+   | 5 bits | slot 0 with 41 bits | slot 1 with 41 bits | slot 2 with 41 bits |
+   
+   The current addressing used by the code below:
+   original PC   placed_address   placed_size             required    covered
+                                  == bp_tgt->shadow_len   reqd \subset covered
+   0xABCDE0      0xABCDE0         0x10                    <0x0...0x5> <0x0..0xF>
+   0xABCDE1      0xABCDE1         0xF                     <0x5...0xA> <0x1..0xF>
+   0xABCDE2      0xABCDE2         0xE                     <0xA...0xF> <0x2..0xF>
+
+   L-X instructions are treated a little specially, as explained above:
+   0xABCDE1      0xABCDE1         0xF                     <0xA...0xF> <0x1..0xF>
+
+   `objdump -d' and some other tools show a bit unjustified offsets:
+   original PC   byte where starts the instruction   objdump offset
+   0xABCDE0      0xABCDE0                            0xABCDE0
+   0xABCDE1      0xABCDE5                            0xABCDE6
+   0xABCDE2      0xABCDEA                            0xABCDEC
+   */
 
-#if 0
-#define IA64_BREAKPOINT 0x00002000040LL
-#endif
 #define IA64_BREAKPOINT 0x00003333300LL
 
 static int
 ia64_memory_insert_breakpoint (struct gdbarch *gdbarch,
                               struct bp_target_info *bp_tgt)
 {
-  CORE_ADDR addr = bp_tgt->placed_address;
-  char bundle[BUNDLE_LEN];
-  int slotnum = (int) (addr & 0x0f) / SLOT_MULTIPLIER;
-  long long instr;
+  CORE_ADDR addr = bp_tgt->placed_address = bp_tgt->reqstd_address;
+  gdb_byte bundle[BUNDLE_LEN];
+  int slotnum = (int) (addr & 0x0f) / SLOT_MULTIPLIER, shadow_slotnum;
+  long long instr_breakpoint;
   int val;
-  int template;
+  int templ;
 
   if (slotnum > 2)
     error (_("Can't insert breakpoint for slot numbers greater than 2."));
 
   addr &= ~0x0f;
 
+  /* Enable the automatic memory restoration from breakpoints while
+     we read our instruction bundle for the purpose of SHADOW_CONTENTS.
+     Otherwise, we could possibly store into the shadow parts of the adjacent
+     placed breakpoints.  It is due to our SHADOW_CONTENTS overlapping the real
+     breakpoint instruction bits region.  */
+  scoped_restore restore_memory_0
+    = make_scoped_restore_show_memory_breakpoints (0);
   val = target_read_memory (addr, bundle, BUNDLE_LEN);
+  if (val != 0)
+    return val;
+
+  /* SHADOW_SLOTNUM saves the original slot number as expected by the caller
+     for addressing the SHADOW_CONTENTS placement.  */
+  shadow_slotnum = slotnum;
 
-  /* Check for L type instruction in 2nd slot, if present then
-     bump up the slot number to the 3rd slot */
-  template = extract_bit_field (bundle, 0, 5);
-  if (slotnum == 1 && template_encoding_table[template][1] == L)
+  /* Always cover the last byte of the bundle in case we are inserting
+     a breakpoint on an L-X instruction.  */
+  bp_tgt->shadow_len = BUNDLE_LEN - shadow_slotnum;
+
+  templ = extract_bit_field (bundle, 0, 5);
+  if (template_encoding_table[templ][slotnum] == X)
+    {
+      /* X unit types can only be used in slot 2, and are actually
+        part of a 2-slot L-X instruction.  We cannot break at this
+        address, as this is the second half of an instruction that
+        lives in slot 1 of that bundle.  */
+      gdb_assert (slotnum == 2);
+      error (_("Can't insert breakpoint for non-existing slot X"));
+    }
+  if (template_encoding_table[templ][slotnum] == L)
     {
+      /* L unit types can only be used in slot 1.  But the associated
+        opcode for that instruction is in slot 2, so bump the slot number
+        accordingly.  */
+      gdb_assert (slotnum == 1);
       slotnum = 2;
     }
 
-  instr = slotN_contents (bundle, slotnum);
-  memcpy (bp_tgt->shadow_contents, &instr, sizeof (instr));
-  bp_tgt->placed_size = bp_tgt->shadow_len = sizeof (instr);
+  /* Store the whole bundle, except for the initial skipped bytes by the slot
+     number interpreted as bytes offset in PLACED_ADDRESS.  */
+  memcpy (bp_tgt->shadow_contents, bundle + shadow_slotnum,
+         bp_tgt->shadow_len);
+
+  /* Re-read the same bundle as above except that, this time, read it in order
+     to compute the new bundle inside which we will be inserting the
+     breakpoint.  Therefore, disable the automatic memory restoration from
+     breakpoints while we read our instruction bundle.  Otherwise, the general
+     restoration mechanism kicks in and we would possibly remove parts of the
+     adjacent placed breakpoints.  It is due to our SHADOW_CONTENTS overlapping
+     the real breakpoint instruction bits region.  */
+  scoped_restore restore_memory_1
+    = make_scoped_restore_show_memory_breakpoints (1);
+  val = target_read_memory (addr, bundle, BUNDLE_LEN);
+  if (val != 0)
+    return val;
+
+  /* Breakpoints already present in the code will get detected and not get
+     reinserted by bp_loc_is_permanent.  Multiple breakpoints at the same
+     location cannot induce the internal error as they are optimized into
+     a single instance by update_global_location_list.  */
+  instr_breakpoint = slotN_contents (bundle, slotnum);
+  if (instr_breakpoint == IA64_BREAKPOINT)
+    internal_error (__FILE__, __LINE__,
+                   _("Address %s already contains a breakpoint."),
+                   paddress (gdbarch, bp_tgt->placed_address));
   replace_slotN_contents (bundle, IA64_BREAKPOINT, slotnum);
-  if (val == 0)
-    target_write_memory (addr, bundle, BUNDLE_LEN);
+
+  val = target_write_memory (addr + shadow_slotnum, bundle + shadow_slotnum,
+                            bp_tgt->shadow_len);
 
   return val;
 }
@@ -593,61 +729,161 @@ ia64_memory_remove_breakpoint (struct gdbarch *gdbarch,
                               struct bp_target_info *bp_tgt)
 {
   CORE_ADDR addr = bp_tgt->placed_address;
-  char bundle[BUNDLE_LEN];
-  int slotnum = (addr & 0x0f) / SLOT_MULTIPLIER;
-  long long instr;
+  gdb_byte bundle_mem[BUNDLE_LEN], bundle_saved[BUNDLE_LEN];
+  int slotnum = (addr & 0x0f) / SLOT_MULTIPLIER, shadow_slotnum;
+  long long instr_breakpoint, instr_saved;
   int val;
-  int template;
-  struct cleanup *cleanup;
+  int templ;
 
   addr &= ~0x0f;
 
   /* Disable the automatic memory restoration from breakpoints while
      we read our instruction bundle.  Otherwise, the general restoration
-     mechanism kicks in and ends up corrupting our bundle, because it
-     is not aware of the concept of instruction bundles.  */
-  cleanup = make_show_memory_breakpoints_cleanup (1);
-  val = target_read_memory (addr, bundle, BUNDLE_LEN);
+     mechanism kicks in and we would possibly remove parts of the adjacent
+     placed breakpoints.  It is due to our SHADOW_CONTENTS overlapping the real
+     breakpoint instruction bits region.  */
+  scoped_restore restore_memory_1
+    = make_scoped_restore_show_memory_breakpoints (1);
+  val = target_read_memory (addr, bundle_mem, BUNDLE_LEN);
+  if (val != 0)
+    return val;
+
+  /* SHADOW_SLOTNUM saves the original slot number as expected by the caller
+     for addressing the SHADOW_CONTENTS placement.  */
+  shadow_slotnum = slotnum;
+
+  templ = extract_bit_field (bundle_mem, 0, 5);
+  if (template_encoding_table[templ][slotnum] == X)
+    {
+      /* X unit types can only be used in slot 2, and are actually
+        part of a 2-slot L-X instruction.  We refuse to insert
+        breakpoints at this address, so there should be no reason
+        for us attempting to remove one there, except if the program's
+        code somehow got modified in memory.  */
+      gdb_assert (slotnum == 2);
+      warning (_("Cannot remove breakpoint at address %s from non-existing "
+                "X-type slot, memory has changed underneath"),
+              paddress (gdbarch, bp_tgt->placed_address));
+      return -1;
+    }
+  if (template_encoding_table[templ][slotnum] == L)
+    {
+      /* L unit types can only be used in slot 1.  But the breakpoint
+        was actually saved using slot 2, so update the slot number
+        accordingly.  */
+      gdb_assert (slotnum == 1);
+      slotnum = 2;
+    }
+
+  gdb_assert (bp_tgt->shadow_len == BUNDLE_LEN - shadow_slotnum);
 
-  /* Check for L type instruction in 2nd slot, if present then
-     bump up the slot number to the 3rd slot */
-  template = extract_bit_field (bundle, 0, 5);
-  if (slotnum == 1 && template_encoding_table[template][1] == L)
+  instr_breakpoint = slotN_contents (bundle_mem, slotnum);
+  if (instr_breakpoint != IA64_BREAKPOINT)
     {
-      slotnum = 2;
+      warning (_("Cannot remove breakpoint at address %s, "
+                "no break instruction at such address."),
+              paddress (gdbarch, bp_tgt->placed_address));
+      return -1;
     }
 
-  memcpy (&instr, bp_tgt->shadow_contents, sizeof instr);
-  replace_slotN_contents (bundle, instr, slotnum);
-  if (val == 0)
-    target_write_memory (addr, bundle, BUNDLE_LEN);
+  /* Extract the original saved instruction from SLOTNUM normalizing its
+     bit-shift for INSTR_SAVED.  */
+  memcpy (bundle_saved, bundle_mem, BUNDLE_LEN);
+  memcpy (bundle_saved + shadow_slotnum, bp_tgt->shadow_contents,
+         bp_tgt->shadow_len);
+  instr_saved = slotN_contents (bundle_saved, slotnum);
+
+  /* In BUNDLE_MEM, be careful to modify only the bits belonging to SLOTNUM
+     and not any of the other ones that are stored in SHADOW_CONTENTS.  */
+  replace_slotN_contents (bundle_mem, instr_saved, slotnum);
+  val = target_write_raw_memory (addr, bundle_mem, BUNDLE_LEN);
 
-  do_cleanups (cleanup);
   return val;
 }
 
-/* We don't really want to use this, but remote.c needs to call it in order
-   to figure out if Z-packets are supported or not.  Oh, well. */
-const unsigned char *
-ia64_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr, int *lenptr)
+/* Implement the breakpoint_kind_from_pc gdbarch method.  */
+
+static int
+ia64_breakpoint_kind_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr)
 {
-  static unsigned char breakpoint[] =
-    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
-  *lenptr = sizeof (breakpoint);
-#if 0
-  *pcptr &= ~0x0f;
-#endif
-  return breakpoint;
+  /* A place holder of gdbarch method breakpoint_kind_from_pc.   */
+  return 0;
+}
+
+/* As gdbarch_breakpoint_from_pc ranges have byte granularity and ia64
+   instruction slots ranges are bit-granular (41 bits) we have to provide an
+   extended range as described for ia64_memory_insert_breakpoint.  We also take
+   care of preserving the `break' instruction 21-bit (or 62-bit) parameter to
+   make a match for permanent breakpoints.  */
+
+static const gdb_byte *
+ia64_breakpoint_from_pc (struct gdbarch *gdbarch,
+                        CORE_ADDR *pcptr, int *lenptr)
+{
+  CORE_ADDR addr = *pcptr;
+  static gdb_byte bundle[BUNDLE_LEN];
+  int slotnum = (int) (*pcptr & 0x0f) / SLOT_MULTIPLIER, shadow_slotnum;
+  long long instr_fetched;
+  int val;
+  int templ;
+
+  if (slotnum > 2)
+    error (_("Can't insert breakpoint for slot numbers greater than 2."));
+
+  addr &= ~0x0f;
+
+  /* Enable the automatic memory restoration from breakpoints while
+     we read our instruction bundle to match bp_loc_is_permanent.  */
+  {
+    scoped_restore restore_memory_0
+      = make_scoped_restore_show_memory_breakpoints (0);
+    val = target_read_memory (addr, bundle, BUNDLE_LEN);
+  }
+
+  /* The memory might be unreachable.  This can happen, for instance,
+     when the user inserts a breakpoint at an invalid address.  */
+  if (val != 0)
+    return NULL;
+
+  /* SHADOW_SLOTNUM saves the original slot number as expected by the caller
+     for addressing the SHADOW_CONTENTS placement.  */
+  shadow_slotnum = slotnum;
+
+  /* Cover always the last byte of the bundle for the L-X slot case.  */
+  *lenptr = BUNDLE_LEN - shadow_slotnum;
+
+  /* Check for L type instruction in slot 1, if present then bump up the slot
+     number to the slot 2.  */
+  templ = extract_bit_field (bundle, 0, 5);
+  if (template_encoding_table[templ][slotnum] == X)
+    {
+      gdb_assert (slotnum == 2);
+      error (_("Can't insert breakpoint for non-existing slot X"));
+    }
+  if (template_encoding_table[templ][slotnum] == L)
+    {
+      gdb_assert (slotnum == 1);
+      slotnum = 2;
+    }
+
+  /* A break instruction has its all its opcode bits cleared except for
+     the parameter value.  For L+X slot pair we are at the X slot (slot 2) so
+     we should not touch the L slot - the upper 41 bits of the parameter.  */
+  instr_fetched = slotN_contents (bundle, slotnum);
+  instr_fetched &= 0x1003ffffc0LL;
+  replace_slotN_contents (bundle, instr_fetched, slotnum);
+
+  return bundle + shadow_slotnum;
 }
 
 static CORE_ADDR
-ia64_read_pc (struct regcache *regcache)
+ia64_read_pc (readable_regcache *regcache)
 {
   ULONGEST psr_value, pc_value;
   int slot_num;
 
-  regcache_cooked_read_unsigned (regcache, IA64_PSR_REGNUM, &psr_value);
-  regcache_cooked_read_unsigned (regcache, IA64_IP_REGNUM, &pc_value);
+  regcache->cooked_read (IA64_PSR_REGNUM, &psr_value);
+  regcache->cooked_read (IA64_IP_REGNUM, &pc_value);
   slot_num = (psr_value >> 41) & 3;
 
   return pc_value | (slot_num * SLOT_MULTIPLIER);
@@ -672,7 +908,7 @@ ia64_write_pc (struct regcache *regcache, CORE_ADDR new_pc)
 #define IS_NaT_COLLECTION_ADDR(addr) ((((addr) >> 3) & 0x3f) == 0x3f)
 
 /* Returns the address of the slot that's NSLOTS slots away from
-   the address ADDR. NSLOTS may be positive or negative. */
+   the address ADDR.  NSLOTS may be positive or negative.  */
 static CORE_ADDR
 rse_address_add(CORE_ADDR addr, int nslots)
 {
@@ -691,49 +927,66 @@ rse_address_add(CORE_ADDR addr, int nslots)
   return new_addr;
 }
 
-static void
-ia64_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
+static enum register_status
+ia64_pseudo_register_read (struct gdbarch *gdbarch, readable_regcache *regcache,
                            int regnum, gdb_byte *buf)
 {
+  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+  enum register_status status;
+
   if (regnum >= V32_REGNUM && regnum <= V127_REGNUM)
     {
 #ifdef HAVE_LIBUNWIND_IA64_H
-      /* First try and use the libunwind special reg accessor, otherwise fallback to
-        standard logic.  */
+      /* First try and use the libunwind special reg accessor,
+        otherwise fallback to standard logic.  */
       if (!libunwind_is_initialized ()
          || libunwind_get_reg_special (gdbarch, regcache, regnum, buf) != 0)
 #endif
        {
-         /* The fallback position is to assume that r32-r127 are found sequentially
-            in memory starting at $bof.  This isn't always true, but without libunwind,
-            this is the best we can do.  */
+         /* The fallback position is to assume that r32-r127 are
+            found sequentially in memory starting at $bof.  This
+            isn't always true, but without libunwind, this is the
+            best we can do.  */
          ULONGEST cfm;
          ULONGEST bsp;
          CORE_ADDR reg;
-         regcache_cooked_read_unsigned (regcache, IA64_BSP_REGNUM, &bsp);
-         regcache_cooked_read_unsigned (regcache, IA64_CFM_REGNUM, &cfm);
-         
+
+         status = regcache->cooked_read (IA64_BSP_REGNUM, &bsp);
+         if (status != REG_VALID)
+           return status;
+
+         status = regcache->cooked_read (IA64_CFM_REGNUM, &cfm);
+         if (status != REG_VALID)
+           return status;
+
          /* The bsp points at the end of the register frame so we
-            subtract the size of frame from it to get start of register frame.  */
+            subtract the size of frame from it to get start of
+            register frame.  */
          bsp = rse_address_add (bsp, -(cfm & 0x7f));
          
          if ((cfm & 0x7f) > regnum - V32_REGNUM) 
            {
              ULONGEST reg_addr = rse_address_add (bsp, (regnum - V32_REGNUM));
-             reg = read_memory_integer ((CORE_ADDR)reg_addr, 8);
-             store_unsigned_integer (buf, register_size (gdbarch, regnum), reg);
+             reg = read_memory_integer ((CORE_ADDR)reg_addr, 8, byte_order);
+             store_unsigned_integer (buf, register_size (gdbarch, regnum),
+                                     byte_order, reg);
            }
          else
-           store_unsigned_integer (buf, register_size (gdbarch, regnum), 0);
+           store_unsigned_integer (buf, register_size (gdbarch, regnum),
+                                   byte_order, 0);
        }
     }
   else if (IA64_NAT0_REGNUM <= regnum && regnum <= IA64_NAT31_REGNUM)
     {
       ULONGEST unatN_val;
       ULONGEST unat;
-      regcache_cooked_read_unsigned (regcache, IA64_UNAT_REGNUM, &unat);
+
+      status = regcache->cooked_read (IA64_UNAT_REGNUM, &unat);
+      if (status != REG_VALID)
+       return status;
       unatN_val = (unat & (1LL << (regnum - IA64_NAT0_REGNUM))) != 0;
-      store_unsigned_integer (buf, register_size (gdbarch, regnum), unatN_val);
+      store_unsigned_integer (buf, register_size (gdbarch, regnum),
+                             byte_order, unatN_val);
     }
   else if (IA64_NAT32_REGNUM <= regnum && regnum <= IA64_NAT127_REGNUM)
     {
@@ -741,8 +994,14 @@ ia64_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
       ULONGEST bsp;
       ULONGEST cfm;
       CORE_ADDR gr_addr = 0;
-      regcache_cooked_read_unsigned (regcache, IA64_BSP_REGNUM, &bsp);
-      regcache_cooked_read_unsigned (regcache, IA64_CFM_REGNUM, &cfm);
+
+      status = regcache->cooked_read (IA64_BSP_REGNUM, &bsp);
+      if (status != REG_VALID)
+       return status;
+
+      status = regcache->cooked_read (IA64_CFM_REGNUM, &cfm);
+      if (status != REG_VALID)
+       return status;
 
       /* The bsp points at the end of the register frame so we
         subtract the size of frame from it to get start of register frame.  */
@@ -755,71 +1014,85 @@ ia64_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
        {
          /* Compute address of nat collection bits.  */
          CORE_ADDR nat_addr = gr_addr | 0x1f8;
-         CORE_ADDR nat_collection;
+         ULONGEST nat_collection;
          int nat_bit;
          /* If our nat collection address is bigger than bsp, we have to get
             the nat collection from rnat.  Otherwise, we fetch the nat
             collection from the computed address.  */
          if (nat_addr >= bsp)
-           regcache_cooked_read_unsigned (regcache, IA64_RNAT_REGNUM, &nat_collection);
+           regcache->cooked_read (IA64_RNAT_REGNUM, &nat_collection);
          else
-           nat_collection = read_memory_integer (nat_addr, 8);
+           nat_collection = read_memory_integer (nat_addr, 8, byte_order);
          nat_bit = (gr_addr >> 3) & 0x3f;
          natN_val = (nat_collection >> nat_bit) & 1;
        }
       
-      store_unsigned_integer (buf, register_size (gdbarch, regnum), natN_val);
+      store_unsigned_integer (buf, register_size (gdbarch, regnum),
+                             byte_order, natN_val);
     }
   else if (regnum == VBOF_REGNUM)
     {
       /* A virtual register frame start is provided for user convenience.
-         It can be calculated as the bsp - sof (sizeof frame). */
+         It can be calculated as the bsp - sof (sizeof frame).  */
       ULONGEST bsp, vbsp;
       ULONGEST cfm;
-      CORE_ADDR reg;
-      regcache_cooked_read_unsigned (regcache, IA64_BSP_REGNUM, &bsp);
-      regcache_cooked_read_unsigned (regcache, IA64_CFM_REGNUM, &cfm);
+
+      status = regcache->cooked_read (IA64_BSP_REGNUM, &bsp);
+      if (status != REG_VALID)
+       return status;
+      status = regcache->cooked_read (IA64_CFM_REGNUM, &cfm);
+      if (status != REG_VALID)
+       return status;
 
       /* The bsp points at the end of the register frame so we
         subtract the size of frame from it to get beginning of frame.  */
       vbsp = rse_address_add (bsp, -(cfm & 0x7f));
-      store_unsigned_integer (buf, register_size (gdbarch, regnum), vbsp);
+      store_unsigned_integer (buf, register_size (gdbarch, regnum),
+                             byte_order, vbsp);
     }
   else if (VP0_REGNUM <= regnum && regnum <= VP63_REGNUM)
     {
       ULONGEST pr;
       ULONGEST cfm;
       ULONGEST prN_val;
-      CORE_ADDR reg;
-      regcache_cooked_read_unsigned (regcache, IA64_PR_REGNUM, &pr);
-      regcache_cooked_read_unsigned (regcache, IA64_CFM_REGNUM, &cfm);
+
+      status = regcache->cooked_read (IA64_PR_REGNUM, &pr);
+      if (status != REG_VALID)
+       return status;
+      status = regcache->cooked_read (IA64_CFM_REGNUM, &cfm);
+      if (status != REG_VALID)
+       return status;
 
       if (VP16_REGNUM <= regnum && regnum <= VP63_REGNUM)
        {
          /* Fetch predicate register rename base from current frame
-            marker for this frame. */
+            marker for this frame.  */
          int rrb_pr = (cfm >> 32) & 0x3f;
 
-         /* Adjust the register number to account for register rotation. */
+         /* Adjust the register number to account for register rotation.  */
          regnum = VP16_REGNUM 
                 + ((regnum - VP16_REGNUM) + rrb_pr) % 48;
        }
       prN_val = (pr & (1LL << (regnum - VP0_REGNUM))) != 0;
-      store_unsigned_integer (buf, register_size (gdbarch, regnum), prN_val);
+      store_unsigned_integer (buf, register_size (gdbarch, regnum),
+                             byte_order, prN_val);
     }
   else
     memset (buf, 0, register_size (gdbarch, regnum));
+
+  return REG_VALID;
 }
 
 static void
 ia64_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
                            int regnum, const gdb_byte *buf)
 {
+  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+
   if (regnum >= V32_REGNUM && regnum <= V127_REGNUM)
     {
       ULONGEST bsp;
       ULONGEST cfm;
-      CORE_ADDR reg;
       regcache_cooked_read_unsigned (regcache, IA64_BSP_REGNUM, &bsp);
       regcache_cooked_read_unsigned (regcache, IA64_CFM_REGNUM, &cfm);
 
@@ -828,14 +1101,16 @@ ia64_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
       if ((cfm & 0x7f) > regnum - V32_REGNUM) 
        {
          ULONGEST reg_addr = rse_address_add (bsp, (regnum - V32_REGNUM));
-         write_memory (reg_addr, (void *)buf, 8);
+         write_memory (reg_addr, buf, 8);
        }
     }
   else if (IA64_NAT0_REGNUM <= regnum && regnum <= IA64_NAT31_REGNUM)
     {
       ULONGEST unatN_val, unat, unatN_mask;
       regcache_cooked_read_unsigned (regcache, IA64_UNAT_REGNUM, &unat);
-      unatN_val = extract_unsigned_integer (buf, register_size (gdbarch, regnum)); 
+      unatN_val = extract_unsigned_integer (buf, register_size (gdbarch,
+                                                               regnum),
+                                           byte_order);
       unatN_mask = (1LL << (regnum - IA64_NAT0_REGNUM));
       if (unatN_val == 0)
        unat &= ~unatN_mask;
@@ -859,7 +1134,9 @@ ia64_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
       if ((cfm & 0x7f) > regnum - V32_REGNUM) 
        gr_addr = rse_address_add (bsp, (regnum - V32_REGNUM));
       
-      natN_val = extract_unsigned_integer (buf, register_size (gdbarch, regnum)); 
+      natN_val = extract_unsigned_integer (buf, register_size (gdbarch,
+                                                              regnum),
+                                          byte_order);
 
       if (gr_addr != 0 && (natN_val == 0 || natN_val == 1))
        {
@@ -873,22 +1150,26 @@ ia64_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
             collection from the computed address.  */
          if (nat_addr >= bsp)
            {
-             regcache_cooked_read_unsigned (regcache, IA64_RNAT_REGNUM, &nat_collection);
+             regcache_cooked_read_unsigned (regcache,
+                                            IA64_RNAT_REGNUM,
+                                            &nat_collection);
              if (natN_val)
                nat_collection |= natN_mask;
              else
                nat_collection &= ~natN_mask;
-             regcache_cooked_write_unsigned (regcache, IA64_RNAT_REGNUM, nat_collection);
+             regcache_cooked_write_unsigned (regcache, IA64_RNAT_REGNUM,
+                                             nat_collection);
            }
          else
            {
-             char nat_buf[8];
-             nat_collection = read_memory_integer (nat_addr, 8);
+             gdb_byte nat_buf[8];
+             nat_collection = read_memory_integer (nat_addr, 8, byte_order);
              if (natN_val)
                nat_collection |= natN_mask;
              else
                nat_collection &= ~natN_mask;
-             store_unsigned_integer (nat_buf, register_size (gdbarch, regnum), nat_collection);
+             store_unsigned_integer (nat_buf, register_size (gdbarch, regnum),
+                                     byte_order, nat_collection);
              write_memory (nat_addr, nat_buf, 8);
            }
        }
@@ -906,14 +1187,15 @@ ia64_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
       if (VP16_REGNUM <= regnum && regnum <= VP63_REGNUM)
        {
          /* Fetch predicate register rename base from current frame
-            marker for this frame. */
+            marker for this frame.  */
          int rrb_pr = (cfm >> 32) & 0x3f;
 
-         /* Adjust the register number to account for register rotation. */
+         /* Adjust the register number to account for register rotation.  */
          regnum = VP16_REGNUM 
                 + ((regnum - VP16_REGNUM) + rrb_pr) % 48;
        }
-      prN_val = extract_unsigned_integer (buf, register_size (gdbarch, regnum)); 
+      prN_val = extract_unsigned_integer (buf, register_size (gdbarch, regnum),
+                                         byte_order);
       prN_mask = (1LL << (regnum - VP0_REGNUM));
       if (prN_val == 0)
        pr &= ~prN_mask;
@@ -930,24 +1212,36 @@ static int
 ia64_convert_register_p (struct gdbarch *gdbarch, int regno, struct type *type)
 {
   return (regno >= IA64_FR0_REGNUM && regno <= IA64_FR127_REGNUM
-         && type != builtin_type_ia64_ext);
+         && type->code () == TYPE_CODE_FLT
+         && type != ia64_ext_type (gdbarch));
 }
 
-static void
+static int
 ia64_register_to_value (struct frame_info *frame, int regnum,
-                         struct type *valtype, gdb_byte *out)
+                       struct type *valtype, gdb_byte *out,
+                       int *optimizedp, int *unavailablep)
 {
-  char in[MAX_REGISTER_SIZE];
-  frame_register_read (frame, regnum, in);
-  convert_typed_floating (in, builtin_type_ia64_ext, out, valtype);
+  struct gdbarch *gdbarch = get_frame_arch (frame);
+  gdb_byte in[IA64_FP_REGISTER_SIZE];
+
+  /* Convert to TYPE.  */
+  if (!get_frame_register_bytes (frame, regnum, 0,
+                                register_size (gdbarch, regnum),
+                                in, optimizedp, unavailablep))
+    return 0;
+
+  target_float_convert (in, ia64_ext_type (gdbarch), out, valtype);
+  *optimizedp = *unavailablep = 0;
+  return 1;
 }
 
 static void
 ia64_value_to_register (struct frame_info *frame, int regnum,
                          struct type *valtype, const gdb_byte *in)
 {
-  char out[MAX_REGISTER_SIZE];
-  convert_typed_floating (in, valtype, out, builtin_type_ia64_ext);
+  struct gdbarch *gdbarch = get_frame_arch (frame);
+  gdb_byte out[IA64_FP_REGISTER_SIZE];
+  target_float_convert (in, valtype, out, ia64_ext_type (gdbarch));
   put_frame_register (frame, regnum, out);
 }
 
@@ -1061,7 +1355,9 @@ ia64_alloc_frame_cache (void)
 }
 
 static CORE_ADDR
-examine_prologue (CORE_ADDR pc, CORE_ADDR lim_pc, struct frame_info *next_frame, struct ia64_frame_cache *cache)
+examine_prologue (CORE_ADDR pc, CORE_ADDR lim_pc,
+                  struct frame_info *this_frame,
+                  struct ia64_frame_cache *cache)
 {
   CORE_ADDR next_pc;
   CORE_ADDR last_prologue_pc = pc;
@@ -1082,7 +1378,7 @@ examine_prologue (CORE_ADDR pc, CORE_ADDR lim_pc, struct frame_info *next_frame,
   int frameless = 1;
   int i;
   CORE_ADDR addr;
-  char buf[8];
+  gdb_byte buf[8];
   CORE_ADDR bof, sor, sol, sof, cfm, rrb_gr;
 
   memset (instores, 0, sizeof instores);
@@ -1102,19 +1398,18 @@ examine_prologue (CORE_ADDR pc, CORE_ADDR lim_pc, struct frame_info *next_frame,
       && it == M && ((instr & 0x1ee0000003fLL) == 0x02c00000000LL))
     {
       /* alloc - start of a regular function.  */
-      int sor = (int) ((instr & 0x00078000000LL) >> 27);
-      int sol = (int) ((instr & 0x00007f00000LL) >> 20);
-      int sof = (int) ((instr & 0x000000fe000LL) >> 13);
+      int sol_bits = (int) ((instr & 0x00007f00000LL) >> 20);
+      int sof_bits = (int) ((instr & 0x000000fe000LL) >> 13);
       int rN = (int) ((instr & 0x00000001fc0LL) >> 6);
 
       /* Verify that the current cfm matches what we think is the
         function start.  If we have somehow jumped within a function,
         we do not want to interpret the prologue and calculate the
-        addresses of various registers such as the return address.  
-        We will instead treat the frame as frameless. */
-      if (!next_frame ||
-         (sof == (cache->cfm & 0x7f) &&
-          sol == ((cache->cfm >> 7) & 0x7f)))
+        addresses of various registers such as the return address.
+        We will instead treat the frame as frameless.  */
+      if (!this_frame ||
+         (sof_bits == (cache->cfm & 0x7f) &&
+          sol_bits == ((cache->cfm >> 7) & 0x7f)))
        frameless = 0;
 
       cfm_reg = rN;
@@ -1137,7 +1432,7 @@ examine_prologue (CORE_ADDR pc, CORE_ADDR lim_pc, struct frame_info *next_frame,
          int qp = (int) (instr & 0x0000000003fLL);
          if (qp == 0 && rN == 2 && imm == 0 && rM == 12 && fp_reg == 0)
            {
-             /* mov r2, r12 - beginning of leaf routine */
+             /* mov r2, r12 - beginning of leaf routine */
              fp_reg = rN;
              last_prologue_pc = next_pc;
            }
@@ -1154,7 +1449,7 @@ examine_prologue (CORE_ADDR pc, CORE_ADDR lim_pc, struct frame_info *next_frame,
     }
 
   /* Loop, looking for prologue instructions, keeping track of
-     where preserved registers were spilled. */
+     where preserved registers were spilled.  */
   while (pc < lim_pc)
     {
       next_pc = fetch_instruction (pc, &it, &instr);
@@ -1163,7 +1458,7 @@ examine_prologue (CORE_ADDR pc, CORE_ADDR lim_pc, struct frame_info *next_frame,
 
       if (it == B && ((instr & 0x1e1f800003fLL) != 0x04000000000LL))
        {
-         /* Exit loop upon hitting a non-nop branch instruction. */ 
+         /* Exit loop upon hitting a non-nop branch instruction.  */ 
          if (trust_limit)
            lim_pc = pc;
          break;
@@ -1216,25 +1511,22 @@ examine_prologue (CORE_ADDR pc, CORE_ADDR lim_pc, struct frame_info *next_frame,
          else if (qp == 0 && rN == 2 
                && ((rM == fp_reg && fp_reg != 0) || rM == 12))
            {
-             char buf[MAX_REGISTER_SIZE];
              CORE_ADDR saved_sp = 0;
              /* adds r2, spilloffset, rFramePointer 
                   or
                 adds r2, spilloffset, r12
 
                 Get ready for stf.spill or st8.spill instructions.
-                The address to start spilling at is loaded into r2. 
+                The address to start spilling at is loaded into r2.
                 FIXME:  Why r2?  That's what gcc currently uses; it
                 could well be different for other compilers.  */
 
-             /* Hmm... whether or not this will work will depend on
+             /* Hmm...  whether or not this will work will depend on
                 where the pc is.  If it's still early in the prologue
                 this'll be wrong.  FIXME */
-             if (next_frame)
-               {
-                 frame_unwind_register (next_frame, sp_regnum, buf);
-                 saved_sp = extract_unsigned_integer (buf, 8);
-               }
+             if (this_frame)
+               saved_sp = get_frame_register_unsigned (this_frame,
+                                                       sp_regnum);
              spill_addr  = saved_sp
                          + (rM == 12 ? 0 : mem_stack_frame_size) 
                          + imm;
@@ -1244,7 +1536,7 @@ examine_prologue (CORE_ADDR pc, CORE_ADDR lim_pc, struct frame_info *next_frame,
          else if (qp == 0 && rM >= 32 && rM < 40 && !instores[rM-32] && 
                   rN < 256 && imm == 0)
            {
-             /* mov rN, rM where rM is an input register */
+             /* mov rN, rM where rM is an input register */
              reg_contents[rN] = rM;
              last_prologue_pc = next_pc;
            }
@@ -1276,7 +1568,7 @@ examine_prologue (CORE_ADDR pc, CORE_ADDR lim_pc, struct frame_info *next_frame,
               if ((instr & 0x1efc0000000LL) == 0x0eec0000000LL)
                spill_addr += imm;
              else
-               spill_addr = 0;         /* last one; must be done */
+               spill_addr = 0;         /* last one; must be done */
              last_prologue_pc = next_pc;
            }
        }
@@ -1293,7 +1585,7 @@ examine_prologue (CORE_ADDR pc, CORE_ADDR lim_pc, struct frame_info *next_frame,
          if (qp == 0 && isScratch (rN) && arM == 36 /* ar.unat */)
            {
              /* We have something like "mov.m r3 = ar.unat".  Remember the
-                r3 (or whatever) and watch for a store of this register... */
+                r3 (or whatever) and watch for a store of this register...  */
              unat_save_reg = rN;
              last_prologue_pc = next_pc;
            }
@@ -1326,16 +1618,16 @@ examine_prologue (CORE_ADDR pc, CORE_ADDR lim_pc, struct frame_info *next_frame,
              /* We've found a spill of either the UNAT register or the PR
                 register.  (Well, not exactly; what we've actually found is
                 a spill of the register that UNAT or PR was moved to).
-                Record that fact and move on... */
+                Record that fact and move on...  */
              if (rM == unat_save_reg)
                {
-                 /* Track UNAT register */
+                 /* Track UNAT register */
                  cache->saved_regs[IA64_UNAT_REGNUM] = spill_addr;
                  unat_save_reg = 0;
                }
              else
                {
-                 /* Track PR register */
+                 /* Track PR register */
                  cache->saved_regs[IA64_PR_REGNUM] = spill_addr;
                  pr_save_reg = 0;
                }
@@ -1343,12 +1635,12 @@ examine_prologue (CORE_ADDR pc, CORE_ADDR lim_pc, struct frame_info *next_frame,
                /* st8 [rN] = rM, imm9 */
                spill_addr += imm9(instr);
              else
-               spill_addr = 0;         /* must be done spilling */
+               spill_addr = 0;         /* Must be done spilling.  */
              last_prologue_pc = next_pc;
            }
          else if (qp == 0 && 32 <= rM && rM < 40 && !instores[rM-32])
            {
-             /* Allow up to one store of each input register. */
+             /* Allow up to one store of each input register.  */
              instores[rM-32] = 1;
              last_prologue_pc = next_pc;
            }
@@ -1369,8 +1661,8 @@ examine_prologue (CORE_ADDR pc, CORE_ADDR lim_pc, struct frame_info *next_frame,
               st8 [rN] = rM
             Note that the st8 case is handled in the clause above.
             
-            Advance over stores of input registers. One store per input
-            register is permitted. */
+            Advance over stores of input registers.  One store per input
+            register is permitted.  */
          int rM = (int) ((instr & 0x000000fe000LL) >> 13);
          int qp = (int) (instr & 0x0000000003fLL);
          int indirect = rM < 256 ? reg_contents[rM] : 0;
@@ -1395,7 +1687,7 @@ examine_prologue (CORE_ADDR pc, CORE_ADDR lim_pc, struct frame_info *next_frame,
               stfd [rN] = fM
 
             Advance over stores of floating point input registers.  Again
-            one store per register is permitted */
+            one store per register is permitted */
          int fM = (int) ((instr & 0x000000fe000LL) >> 13);
          int qp = (int) (instr & 0x0000000003fLL);
          if (qp == 0 && 8 <= fM && fM < 16 && !infpstores[fM - 8])
@@ -1418,13 +1710,13 @@ examine_prologue (CORE_ADDR pc, CORE_ADDR lim_pc, struct frame_info *next_frame,
            {
              /* We've found a spill of one of the preserved general purpose
                 regs.  Record the spill address and advance the spill
-                register if appropriate. */
+                register if appropriate.  */
              cache->saved_regs[IA64_GR0_REGNUM + rM] = spill_addr;
              if ((instr & 0x1efc0000000LL) == 0x0aec0000000LL)
                /* st8.spill [rN] = rM, imm9 */
                spill_addr += imm9(instr);
              else
-               spill_addr = 0;         /* Done spilling */
+               spill_addr = 0;         /* Done spilling */
              last_prologue_pc = next_pc;
            }
        }
@@ -1432,14 +1724,18 @@ examine_prologue (CORE_ADDR pc, CORE_ADDR lim_pc, struct frame_info *next_frame,
       pc = next_pc;
     }
 
-  /* If not frameless and we aren't called by skip_prologue, then we need to calculate
-     registers for the previous frame which will be needed later.  */
+  /* If not frameless and we aren't called by skip_prologue, then we need
+     to calculate registers for the previous frame which will be needed
+     later.  */
 
-  if (!frameless && next_frame)
+  if (!frameless && this_frame)
     {
+      struct gdbarch *gdbarch = get_frame_arch (this_frame);
+      enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+
       /* Extract the size of the rotating portion of the stack
         frame and the register rename base from the current
-        frame marker. */
+        frame marker.  */
       cfm = cache->cfm;
       sor = cache->sor;
       sof = cache->sof;
@@ -1465,17 +1761,18 @@ examine_prologue (CORE_ADDR pc, CORE_ADDR lim_pc, struct frame_info *next_frame,
            cache->saved_regs[IA64_VFP_REGNUM] = addr;
        }
 
-      /* For the previous argument registers we require the previous bof.  
+      /* For the previous argument registers we require the previous bof.
         If we can't find the previous cfm, then we can do nothing.  */
       cfm = 0;
       if (cache->saved_regs[IA64_CFM_REGNUM] != 0)
        {
-         cfm = read_memory_integer (cache->saved_regs[IA64_CFM_REGNUM], 8);
+         cfm = read_memory_integer (cache->saved_regs[IA64_CFM_REGNUM],
+                                    8, byte_order);
        }
       else if (cfm_reg != 0)
        {
-         frame_unwind_register (next_frame, cfm_reg, buf);
-         cfm = extract_unsigned_integer (buf, 8);
+         get_frame_register (this_frame, cfm_reg, buf);
+         cfm = extract_unsigned_integer (buf, 8, byte_order);
        }
       cache->prev_cfm = cfm;
       
@@ -1486,8 +1783,9 @@ examine_prologue (CORE_ADDR pc, CORE_ADDR lim_pc, struct frame_info *next_frame,
          sol = (cfm >> 7) & 0x7f;
          rrb_gr = (cfm >> 18) & 0x7f;
 
-         /* The previous bof only requires subtraction of the sol (size of locals)
-            due to the overlap between output and input of subsequent frames.  */
+         /* The previous bof only requires subtraction of the sol (size of
+             locals) due to the overlap between output and input of
+             subsequent frames.  */
          bof = rse_address_add (bof, -sol);
          
          for (i = 0, addr = bof;
@@ -1499,7 +1797,8 @@ examine_prologue (CORE_ADDR pc, CORE_ADDR lim_pc, struct frame_info *next_frame,
                  addr += 8;
                }
              if (i < sor)
-               cache->saved_regs[IA64_GR32_REGNUM + ((i + (sor - rrb_gr)) % sor)] 
+               cache->saved_regs[IA64_GR32_REGNUM
+                                 + ((i + (sor - rrb_gr)) % sor)] 
                  = addr;
              else
                cache->saved_regs[IA64_GR32_REGNUM + i] = addr;
@@ -1529,7 +1828,8 @@ ia64_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
   cache.cfm = 0;
   cache.bsp = 0;
 
-  /* Call examine_prologue with - as third argument since we don't have a next frame pointer to send.  */
+  /* Call examine_prologue with - as third argument since we don't
+     have a next frame pointer to send.  */
   return examine_prologue (pc, pc+1024, 0, &cache);
 }
 
@@ -1537,33 +1837,33 @@ ia64_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
 /* Normal frames.  */
 
 static struct ia64_frame_cache *
-ia64_frame_cache (struct frame_info *next_frame, void **this_cache)
+ia64_frame_cache (struct frame_info *this_frame, void **this_cache)
 {
+  struct gdbarch *gdbarch = get_frame_arch (this_frame);
+  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
   struct ia64_frame_cache *cache;
-  char buf[8];
-  CORE_ADDR cfm, sof, sol, bsp, psr;
-  int i;
+  gdb_byte buf[8];
+  CORE_ADDR cfm;
 
   if (*this_cache)
-    return *this_cache;
+    return (struct ia64_frame_cache *) *this_cache;
 
   cache = ia64_alloc_frame_cache ();
   *this_cache = cache;
 
-  frame_unwind_register (next_frame, sp_regnum, buf);
-  cache->saved_sp = extract_unsigned_integer (buf, 8);
+  get_frame_register (this_frame, sp_regnum, buf);
+  cache->saved_sp = extract_unsigned_integer (buf, 8, byte_order);
 
   /* We always want the bsp to point to the end of frame.
      This way, we can always get the beginning of frame (bof)
      by subtracting frame size.  */
-  frame_unwind_register (next_frame, IA64_BSP_REGNUM, buf);
-  cache->bsp = extract_unsigned_integer (buf, 8);
+  get_frame_register (this_frame, IA64_BSP_REGNUM, buf);
+  cache->bsp = extract_unsigned_integer (buf, 8, byte_order);
   
-  frame_unwind_register (next_frame, IA64_PSR_REGNUM, buf);
-  psr = extract_unsigned_integer (buf, 8);
+  get_frame_register (this_frame, IA64_PSR_REGNUM, buf);
 
-  frame_unwind_register (next_frame, IA64_CFM_REGNUM, buf);
-  cfm = extract_unsigned_integer (buf, 8);
+  get_frame_register (this_frame, IA64_CFM_REGNUM, buf);
+  cfm = extract_unsigned_integer (buf, 8, byte_order);
 
   cache->sof = (cfm & 0x7f);
   cache->sol = (cfm >> 7) & 0x7f;
@@ -1571,10 +1871,10 @@ ia64_frame_cache (struct frame_info *next_frame, void **this_cache)
 
   cache->cfm = cfm;
 
-  cache->pc = frame_func_unwind (next_frame, NORMAL_FRAME);
+  cache->pc = get_frame_func (this_frame);
 
   if (cache->pc != 0)
-    examine_prologue (cache->pc, frame_pc_unwind (next_frame), next_frame, cache);
+    examine_prologue (cache->pc, get_frame_pc (this_frame), this_frame, cache);
   
   cache->base = cache->saved_sp + cache->mem_stack_frame_size;
 
@@ -1582,122 +1882,98 @@ ia64_frame_cache (struct frame_info *next_frame, void **this_cache)
 }
 
 static void
-ia64_frame_this_id (struct frame_info *next_frame, void **this_cache,
+ia64_frame_this_id (struct frame_info *this_frame, void **this_cache,
                    struct frame_id *this_id)
 {
+  struct gdbarch *gdbarch = get_frame_arch (this_frame);
   struct ia64_frame_cache *cache =
-    ia64_frame_cache (next_frame, this_cache);
+    ia64_frame_cache (this_frame, this_cache);
 
   /* If outermost frame, mark with null frame id.  */
-  if (cache->base == 0)
-    (*this_id) = null_frame_id;
-  else
+  if (cache->base != 0)
     (*this_id) = frame_id_build_special (cache->base, cache->pc, cache->bsp);
   if (gdbarch_debug >= 1)
     fprintf_unfiltered (gdb_stdlog,
-                       "regular frame id: code 0x%s, stack 0x%s, special 0x%s, next_frame %p\n",
-                       paddr_nz (this_id->code_addr), 
-                       paddr_nz (this_id->stack_addr), 
-                       paddr_nz (cache->bsp), next_frame);
+                       "regular frame id: code %s, stack %s, "
+                       "special %s, this_frame %s\n",
+                       paddress (gdbarch, this_id->code_addr),
+                       paddress (gdbarch, this_id->stack_addr),
+                       paddress (gdbarch, cache->bsp),
+                       host_address_to_string (this_frame));
 }
 
-static void
-ia64_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 *
+ia64_frame_prev_register (struct frame_info *this_frame, void **this_cache,
+                         int regnum)
 {
-  struct gdbarch *gdbarch = get_frame_arch (next_frame);
-  struct ia64_frame_cache *cache =
-    ia64_frame_cache (next_frame, this_cache);
-  char dummy_valp[MAX_REGISTER_SIZE];
-  char buf[8];
+  struct gdbarch *gdbarch = get_frame_arch (this_frame);
+  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+  struct ia64_frame_cache *cache = ia64_frame_cache (this_frame, this_cache);
+  gdb_byte buf[8];
 
   gdb_assert (regnum >= 0);
 
   if (!target_has_registers)
     error (_("No registers."));
 
-  *optimizedp = 0;
-  *addrp = 0;
-  *lvalp = not_lval;
-  *realnump = -1;
-
-  /* Rather than check each time if valuep is non-null, supply a dummy buffer
-     when valuep is not supplied.  */
-  if (!valuep)
-    valuep = dummy_valp;
-  
-  memset (valuep, 0, register_size (gdbarch, regnum));
   if (regnum == gdbarch_sp_regnum (gdbarch))
-    {
-      /* Handle SP values for all frames but the topmost. */
-      store_unsigned_integer (valuep, register_size (gdbarch, regnum),
-                             cache->base);
-    }
+    return frame_unwind_got_constant (this_frame, regnum, cache->base);
+
   else if (regnum == IA64_BSP_REGNUM)
     {
-      char cfm_valuep[MAX_REGISTER_SIZE];
-      int  cfm_optim;
-      int  cfm_realnum;
-      enum lval_type cfm_lval;
-      CORE_ADDR cfm_addr;
-      CORE_ADDR bsp, prev_cfm, prev_bsp;
-
-      /* We want to calculate the previous bsp as the end of the previous register stack frame.
-        This corresponds to what the hardware bsp register will be if we pop the frame
-        back which is why we might have been called.  We know the beginning of the current
-        frame is cache->bsp - cache->sof.  This value in the previous frame points to
-        the start of the output registers.  We can calculate the end of that frame by adding
-        the size of output (sof (size of frame) - sol (size of locals)).  */
-      ia64_frame_prev_register (next_frame, this_cache, IA64_CFM_REGNUM,
-                               &cfm_optim, &cfm_lval, &cfm_addr, &cfm_realnum, cfm_valuep);
-      prev_cfm = extract_unsigned_integer (cfm_valuep, 8);
-
+      struct value *val;
+      CORE_ADDR prev_cfm, bsp, prev_bsp;
+
+      /* We want to calculate the previous bsp as the end of the previous
+         register stack frame.  This corresponds to what the hardware bsp
+         register will be if we pop the frame back which is why we might
+         have been called.  We know the beginning of the current frame is
+         cache->bsp - cache->sof.  This value in the previous frame points
+         to the start of the output registers.  We can calculate the end of
+         that frame by adding the size of output:
+            (sof (size of frame) - sol (size of locals)).  */
+      val = ia64_frame_prev_register (this_frame, this_cache, IA64_CFM_REGNUM);
+      prev_cfm = extract_unsigned_integer (value_contents_all (val),
+                                          8, byte_order);
       bsp = rse_address_add (cache->bsp, -(cache->sof));
-      prev_bsp = rse_address_add (bsp, (prev_cfm & 0x7f) - ((prev_cfm >> 7) & 0x7f));
+      prev_bsp =
+        rse_address_add (bsp, (prev_cfm & 0x7f) - ((prev_cfm >> 7) & 0x7f));
 
-      store_unsigned_integer (valuep, register_size (gdbarch, regnum), 
-                             prev_bsp);
+      return frame_unwind_got_constant (this_frame, regnum, prev_bsp);
     }
+
   else if (regnum == IA64_CFM_REGNUM)
     {
       CORE_ADDR addr = cache->saved_regs[IA64_CFM_REGNUM];
       
       if (addr != 0)
-       {
-         *lvalp = lval_memory;
-         *addrp = addr;
-         read_memory (addr, valuep, register_size (gdbarch, regnum));
-       }
-      else if (cache->prev_cfm)
-       store_unsigned_integer (valuep, register_size (gdbarch, regnum), cache->prev_cfm);
-      else if (cache->frameless)
-       {
-         CORE_ADDR cfm = 0;
-         frame_unwind_register (next_frame, IA64_PFS_REGNUM, valuep);
-       }
+        return frame_unwind_got_memory (this_frame, regnum, addr);
+
+      if (cache->prev_cfm)
+        return frame_unwind_got_constant (this_frame, regnum, cache->prev_cfm);
+
+      if (cache->frameless)
+        return frame_unwind_got_register (this_frame, IA64_PFS_REGNUM,
+                                          IA64_PFS_REGNUM);
+      return frame_unwind_got_register (this_frame, regnum, 0);
     }
+
   else if (regnum == IA64_VFP_REGNUM)
     {
       /* If the function in question uses an automatic register (r32-r127)
          for the frame pointer, it'll be found by ia64_find_saved_register()
         above.  If the function lacks one of these frame pointers, we can
         still provide a value since we know the size of the frame.  */
-      CORE_ADDR vfp = cache->base;
-      store_unsigned_integer (valuep, register_size (gdbarch, IA64_VFP_REGNUM), vfp);
+      return frame_unwind_got_constant (this_frame, regnum, cache->base);
     }
+
   else if (VP0_REGNUM <= regnum && regnum <= VP63_REGNUM)
     {
-      char pr_valuep[MAX_REGISTER_SIZE];
-      int  pr_optim;
-      int  pr_realnum;
-      enum lval_type pr_lval;
-      CORE_ADDR pr_addr;
-      ULONGEST prN_val;
-      ia64_frame_prev_register (next_frame, this_cache, IA64_PR_REGNUM,
-                               &pr_optim, &pr_lval, &pr_addr, &pr_realnum, pr_valuep);
+      struct value *pr_val;
+      ULONGEST prN;
+      
+      pr_val = ia64_frame_prev_register (this_frame, this_cache,
+                                         IA64_PR_REGNUM);
       if (VP16_REGNUM <= regnum && regnum <= VP63_REGNUM)
        {
          /* Fetch predicate register rename base from current frame
@@ -1705,28 +1981,24 @@ ia64_frame_prev_register (struct frame_info *next_frame, void **this_cache,
          int rrb_pr = (cache->cfm >> 32) & 0x3f;
 
          /* Adjust the register number to account for register rotation.  */
-         regnum = VP16_REGNUM 
-                + ((regnum - VP16_REGNUM) + rrb_pr) % 48;
+         regnum = VP16_REGNUM + ((regnum - VP16_REGNUM) + rrb_pr) % 48;
        }
-      prN_val = extract_bit_field ((unsigned char *) pr_valuep,
-                                   regnum - VP0_REGNUM, 1);
-      store_unsigned_integer (valuep, register_size (gdbarch, regnum), prN_val);
+      prN = extract_bit_field (value_contents_all (pr_val),
+                               regnum - VP0_REGNUM, 1);
+      return frame_unwind_got_constant (this_frame, regnum, prN);
     }
+
   else if (IA64_NAT0_REGNUM <= regnum && regnum <= IA64_NAT31_REGNUM)
     {
-      char unat_valuep[MAX_REGISTER_SIZE];
-      int  unat_optim;
-      int  unat_realnum;
-      enum lval_type unat_lval;
-      CORE_ADDR unat_addr;
-      ULONGEST unatN_val;
-      ia64_frame_prev_register (next_frame, this_cache, IA64_UNAT_REGNUM,
-                               &unat_optim, &unat_lval, &unat_addr, &unat_realnum, unat_valuep);
-      unatN_val = extract_bit_field ((unsigned char *) unat_valuep,
-                                   regnum - IA64_NAT0_REGNUM, 1);
-      store_unsigned_integer (valuep, register_size (gdbarch, regnum), 
-                              unatN_val);
+      struct value *unat_val;
+      ULONGEST unatN;
+      unat_val = ia64_frame_prev_register (this_frame, this_cache,
+                                           IA64_UNAT_REGNUM);
+      unatN = extract_bit_field (value_contents_all (unat_val),
+                                 regnum - IA64_NAT0_REGNUM, 1);
+      return frame_unwind_got_constant (this_frame, regnum, unatN);
     }
+
   else if (IA64_NAT32_REGNUM <= regnum && regnum <= IA64_NAT127_REGNUM)
     {
       int natval = 0;
@@ -1734,8 +2006,8 @@ ia64_frame_prev_register (struct frame_info *next_frame, void **this_cache,
          interested in.  */
       CORE_ADDR gr_addr;
 
-      gr_addr = cache->saved_regs[regnum - IA64_NAT0_REGNUM 
-                                 + IA64_GR0_REGNUM];
+      gr_addr = cache->saved_regs[regnum - IA64_NAT0_REGNUM + IA64_GR0_REGNUM];
+
       if (gr_addr != 0)
        {
          /* Compute address of nat collection bits.  */
@@ -1743,130 +2015,126 @@ ia64_frame_prev_register (struct frame_info *next_frame, void **this_cache,
          CORE_ADDR bsp;
          CORE_ADDR nat_collection;
          int nat_bit;
+
          /* If our nat collection address is bigger than bsp, we have to get
             the nat collection from rnat.  Otherwise, we fetch the nat
             collection from the computed address.  */
-         frame_unwind_register (next_frame, IA64_BSP_REGNUM, buf);
-         bsp = extract_unsigned_integer (buf, 8); 
+         get_frame_register (this_frame, IA64_BSP_REGNUM, buf);
+         bsp = extract_unsigned_integer (buf, 8, byte_order);
          if (nat_addr >= bsp)
            {
-             frame_unwind_register (next_frame, IA64_RNAT_REGNUM, buf);
-             nat_collection = extract_unsigned_integer (buf, 8);
+             get_frame_register (this_frame, IA64_RNAT_REGNUM, buf);
+             nat_collection = extract_unsigned_integer (buf, 8, byte_order);
            }
          else
-           nat_collection = read_memory_integer (nat_addr, 8);
+           nat_collection = read_memory_integer (nat_addr, 8, byte_order);
          nat_bit = (gr_addr >> 3) & 0x3f;
          natval = (nat_collection >> nat_bit) & 1;
        }
 
-      store_unsigned_integer (valuep, register_size (gdbarch, regnum), natval);
+      return frame_unwind_got_constant (this_frame, regnum, natval);
     }
+
   else if (regnum == IA64_IP_REGNUM)
     {
       CORE_ADDR pc = 0;
       CORE_ADDR addr = cache->saved_regs[IA64_VRAP_REGNUM];
 
       if (addr != 0)
-       {
-         *lvalp = lval_memory;
-         *addrp = addr;
-         read_memory (addr, buf, register_size (gdbarch, IA64_IP_REGNUM));
-         pc = extract_unsigned_integer (buf, 8);
-       }
+        {
+          read_memory (addr, buf, register_size (gdbarch, IA64_IP_REGNUM));
+          pc = extract_unsigned_integer (buf, 8, byte_order);
+        }
       else if (cache->frameless)
        {
-         frame_unwind_register (next_frame, IA64_BR0_REGNUM, buf);
-         pc = extract_unsigned_integer (buf, 8);
+         get_frame_register (this_frame, IA64_BR0_REGNUM, buf);
+         pc = extract_unsigned_integer (buf, 8, byte_order);
        }
       pc &= ~0xf;
-      store_unsigned_integer (valuep, 8, pc);
+      return frame_unwind_got_constant (this_frame, regnum, pc);
     }
+
   else if (regnum == IA64_PSR_REGNUM)
     {
-      /* We don't know how to get the complete previous PSR, but we need it for
-        the slot information when we unwind the pc (pc is formed of IP register
-        plus slot information from PSR).  To get the previous slot information, 
-        we mask it off the return address.  */
+      /* We don't know how to get the complete previous PSR, but we need it
+         for the slot information when we unwind the pc (pc is formed of IP
+         register plus slot information from PSR).  To get the previous
+         slot information, we mask it off the return address.  */
       ULONGEST slot_num = 0;
-      CORE_ADDR pc= 0;
+      CORE_ADDR pc = 0;
       CORE_ADDR psr = 0;
       CORE_ADDR addr = cache->saved_regs[IA64_VRAP_REGNUM];
 
-      frame_unwind_register (next_frame, IA64_PSR_REGNUM, buf);
-      psr = extract_unsigned_integer (buf, 8);
+      get_frame_register (this_frame, IA64_PSR_REGNUM, buf);
+      psr = extract_unsigned_integer (buf, 8, byte_order);
 
       if (addr != 0)
        {
-         *lvalp = lval_memory;
-         *addrp = addr;
          read_memory (addr, buf, register_size (gdbarch, IA64_IP_REGNUM));
-         pc = extract_unsigned_integer (buf, 8);
+         pc = extract_unsigned_integer (buf, 8, byte_order);
        }
       else if (cache->frameless)
        {
-         CORE_ADDR pc;
-         frame_unwind_register (next_frame, IA64_BR0_REGNUM, buf);
-         pc = extract_unsigned_integer (buf, 8);
+         get_frame_register (this_frame, IA64_BR0_REGNUM, buf);
+         pc = extract_unsigned_integer (buf, 8, byte_order);
        }
       psr &= ~(3LL << 41);
       slot_num = pc & 0x3LL;
       psr |= (CORE_ADDR)slot_num << 41;
-      store_unsigned_integer (valuep, 8, psr);
+      return frame_unwind_got_constant (this_frame, regnum, psr);
     }
+
   else if (regnum == IA64_BR0_REGNUM)
     {
-      CORE_ADDR br0 = 0;
       CORE_ADDR addr = cache->saved_regs[IA64_BR0_REGNUM];
+
       if (addr != 0)
-       {
-         *lvalp = lval_memory;
-         *addrp = addr;
-         read_memory (addr, buf, register_size (gdbarch, IA64_BR0_REGNUM));
-         br0 = extract_unsigned_integer (buf, 8);
-       }
-      store_unsigned_integer (valuep, 8, br0);
+        return frame_unwind_got_memory (this_frame, regnum, addr);
+
+      return frame_unwind_got_constant (this_frame, regnum, 0);
     }
- else if ((regnum >= IA64_GR32_REGNUM && regnum <= IA64_GR127_REGNUM) ||
-          (regnum >= V32_REGNUM && regnum <= V127_REGNUM))
+
+  else if ((regnum >= IA64_GR32_REGNUM && regnum <= IA64_GR127_REGNUM)
+           || (regnum >= V32_REGNUM && regnum <= V127_REGNUM))
     {
       CORE_ADDR addr = 0;
+
       if (regnum >= V32_REGNUM)
        regnum = IA64_GR32_REGNUM + (regnum - V32_REGNUM);
       addr = cache->saved_regs[regnum];
       if (addr != 0)
-       {
-         *lvalp = lval_memory;
-         *addrp = addr;
-         read_memory (addr, valuep, register_size (gdbarch, regnum));
-       }
-      else if (cache->frameless)
+        return frame_unwind_got_memory (this_frame, regnum, addr);
+
+      if (cache->frameless)
         {
-         char r_valuep[MAX_REGISTER_SIZE];
-         int  r_optim;
-         int  r_realnum;
-         enum lval_type r_lval;
-         CORE_ADDR r_addr;
-         CORE_ADDR prev_cfm, prev_bsp, prev_bof;
-         CORE_ADDR addr = 0;
+          struct value *reg_val;
+          CORE_ADDR prev_cfm, prev_bsp, prev_bof;
+
+          /* FIXME: brobecker/2008-05-01: Doesn't this seem redundant
+             with the same code above?  */
          if (regnum >= V32_REGNUM)
            regnum = IA64_GR32_REGNUM + (regnum - V32_REGNUM);
-         ia64_frame_prev_register (next_frame, this_cache, IA64_CFM_REGNUM,
-                                   &r_optim, &r_lval, &r_addr, &r_realnum, r_valuep); 
-         prev_cfm = extract_unsigned_integer (r_valuep, 8);
-         ia64_frame_prev_register (next_frame, this_cache, IA64_BSP_REGNUM,
-                                   &r_optim, &r_lval, &r_addr, &r_realnum, r_valuep);
-         prev_bsp = extract_unsigned_integer (r_valuep, 8);
+          reg_val = ia64_frame_prev_register (this_frame, this_cache,
+                                              IA64_CFM_REGNUM);
+         prev_cfm = extract_unsigned_integer (value_contents_all (reg_val),
+                                               8, byte_order);
+         reg_val = ia64_frame_prev_register (this_frame, this_cache,
+                                              IA64_BSP_REGNUM);
+         prev_bsp = extract_unsigned_integer (value_contents_all (reg_val),
+                                               8, byte_order);
          prev_bof = rse_address_add (prev_bsp, -(prev_cfm & 0x7f));
 
          addr = rse_address_add (prev_bof, (regnum - IA64_GR32_REGNUM));
-         *lvalp = lval_memory;
-         *addrp = addr;
-         read_memory (addr, valuep, register_size (gdbarch, regnum));
+          return frame_unwind_got_memory (this_frame, regnum, addr);
         }
+      
+      return frame_unwind_got_constant (this_frame, regnum, 0);
     }
-  else
+
+  else /* All other registers.  */
     {
       CORE_ADDR addr = 0;
+
       if (IA64_FR32_REGNUM <= regnum && regnum <= IA64_FR127_REGNUM)
        {
          /* Fetch floating point register rename base from current
@@ -1882,159 +2150,143 @@ ia64_frame_prev_register (struct frame_info *next_frame, void **this_cache,
       /* If we have stored a memory address, access the register.  */
       addr = cache->saved_regs[regnum];
       if (addr != 0)
-       {
-         *lvalp = lval_memory;
-         *addrp = addr;
-         read_memory (addr, valuep, register_size (gdbarch, regnum));
-       }
+        return frame_unwind_got_memory (this_frame, regnum, addr);
       /* Otherwise, punt and get the current value of the register.  */
       else 
-       frame_unwind_register (next_frame, regnum, valuep);
+        return frame_unwind_got_register (this_frame, regnum, regnum);
     }
-
-  if (gdbarch_debug >= 1)
-    fprintf_unfiltered (gdb_stdlog,
-                       "regular prev register <%d> <%s> is 0x%s\n", regnum, 
-                       (((unsigned) regnum <= IA64_NAT127_REGNUM)
-                        ? ia64_register_names[regnum] : "r??"), 
-                       paddr_nz (extract_unsigned_integer (valuep, 8)));
 }
  
 static const struct frame_unwind ia64_frame_unwind =
 {
   NORMAL_FRAME,
+  default_frame_unwind_stop_reason,
   &ia64_frame_this_id,
-  &ia64_frame_prev_register
+  &ia64_frame_prev_register,
+  NULL,
+  default_frame_sniffer
 };
 
-static const struct frame_unwind *
-ia64_frame_sniffer (struct frame_info *next_frame)
-{
-  return &ia64_frame_unwind;
-}
-
 /* Signal trampolines.  */
 
 static void
-ia64_sigtramp_frame_init_saved_regs (struct frame_info *next_frame,
+ia64_sigtramp_frame_init_saved_regs (struct frame_info *this_frame,
                                     struct ia64_frame_cache *cache)
 {
-  struct gdbarch_tdep *tdep = gdbarch_tdep (get_frame_arch (next_frame));
+  struct gdbarch *gdbarch = get_frame_arch (this_frame);
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
 
   if (tdep->sigcontext_register_address)
     {
       int regno;
 
-      cache->saved_regs[IA64_VRAP_REGNUM] = 
-       tdep->sigcontext_register_address (cache->base, IA64_IP_REGNUM);
-      cache->saved_regs[IA64_CFM_REGNUM] = 
-       tdep->sigcontext_register_address (cache->base, IA64_CFM_REGNUM);
-      cache->saved_regs[IA64_PSR_REGNUM] = 
-       tdep->sigcontext_register_address (cache->base, IA64_PSR_REGNUM);
-      cache->saved_regs[IA64_BSP_REGNUM] = 
-       tdep->sigcontext_register_address (cache->base, IA64_BSP_REGNUM);
-      cache->saved_regs[IA64_RNAT_REGNUM] = 
-       tdep->sigcontext_register_address (cache->base, IA64_RNAT_REGNUM);
-      cache->saved_regs[IA64_CCV_REGNUM] = 
-       tdep->sigcontext_register_address (cache->base, IA64_CCV_REGNUM);
-      cache->saved_regs[IA64_UNAT_REGNUM] = 
-       tdep->sigcontext_register_address (cache->base, IA64_UNAT_REGNUM);
-      cache->saved_regs[IA64_FPSR_REGNUM] = 
-       tdep->sigcontext_register_address (cache->base, IA64_FPSR_REGNUM);
-      cache->saved_regs[IA64_PFS_REGNUM] = 
-       tdep->sigcontext_register_address (cache->base, IA64_PFS_REGNUM);
-      cache->saved_regs[IA64_LC_REGNUM] = 
-       tdep->sigcontext_register_address (cache->base, IA64_LC_REGNUM);
+      cache->saved_regs[IA64_VRAP_REGNUM]
+       = tdep->sigcontext_register_address (gdbarch, cache->base,
+                                            IA64_IP_REGNUM);
+      cache->saved_regs[IA64_CFM_REGNUM]
+       = tdep->sigcontext_register_address (gdbarch, cache->base,
+                                            IA64_CFM_REGNUM);
+      cache->saved_regs[IA64_PSR_REGNUM]
+       = tdep->sigcontext_register_address (gdbarch, cache->base,
+                                            IA64_PSR_REGNUM);
+      cache->saved_regs[IA64_BSP_REGNUM]
+       = tdep->sigcontext_register_address (gdbarch, cache->base,
+                                            IA64_BSP_REGNUM);
+      cache->saved_regs[IA64_RNAT_REGNUM]
+       = tdep->sigcontext_register_address (gdbarch, cache->base,
+                                            IA64_RNAT_REGNUM);
+      cache->saved_regs[IA64_CCV_REGNUM]
+       = tdep->sigcontext_register_address (gdbarch, cache->base,
+                                            IA64_CCV_REGNUM);
+      cache->saved_regs[IA64_UNAT_REGNUM]
+       = tdep->sigcontext_register_address (gdbarch, cache->base,
+                                            IA64_UNAT_REGNUM);
+      cache->saved_regs[IA64_FPSR_REGNUM]
+       = tdep->sigcontext_register_address (gdbarch, cache->base,
+                                            IA64_FPSR_REGNUM);
+      cache->saved_regs[IA64_PFS_REGNUM]
+       = tdep->sigcontext_register_address (gdbarch, cache->base,
+                                            IA64_PFS_REGNUM);
+      cache->saved_regs[IA64_LC_REGNUM]
+       = tdep->sigcontext_register_address (gdbarch, cache->base,
+                                            IA64_LC_REGNUM);
+
       for (regno = IA64_GR1_REGNUM; regno <= IA64_GR31_REGNUM; regno++)
        cache->saved_regs[regno] =
-         tdep->sigcontext_register_address (cache->base, regno);
+         tdep->sigcontext_register_address (gdbarch, cache->base, regno);
       for (regno = IA64_BR0_REGNUM; regno <= IA64_BR7_REGNUM; regno++)
        cache->saved_regs[regno] =
-         tdep->sigcontext_register_address (cache->base, regno);
+         tdep->sigcontext_register_address (gdbarch, cache->base, regno);
       for (regno = IA64_FR2_REGNUM; regno <= IA64_FR31_REGNUM; regno++)
        cache->saved_regs[regno] =
-         tdep->sigcontext_register_address (cache->base, regno);
+         tdep->sigcontext_register_address (gdbarch, cache->base, regno);
     }
 }
 
 static struct ia64_frame_cache *
-ia64_sigtramp_frame_cache (struct frame_info *next_frame, void **this_cache)
+ia64_sigtramp_frame_cache (struct frame_info *this_frame, void **this_cache)
 {
+  struct gdbarch *gdbarch = get_frame_arch (this_frame);
+  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
   struct ia64_frame_cache *cache;
-  CORE_ADDR addr;
-  char buf[8];
-  int i;
+  gdb_byte buf[8];
 
   if (*this_cache)
-    return *this_cache;
+    return (struct ia64_frame_cache *) *this_cache;
 
   cache = ia64_alloc_frame_cache ();
 
-  frame_unwind_register (next_frame, sp_regnum, buf);
+  get_frame_register (this_frame, sp_regnum, buf);
   /* Note that frame size is hard-coded below.  We cannot calculate it
      via prologue examination.  */
-  cache->base = extract_unsigned_integer (buf, 8) + 16;
+  cache->base = extract_unsigned_integer (buf, 8, byte_order) + 16;
 
-  frame_unwind_register (next_frame, IA64_BSP_REGNUM, buf);
-  cache->bsp = extract_unsigned_integer (buf, 8);
+  get_frame_register (this_frame, IA64_BSP_REGNUM, buf);
+  cache->bsp = extract_unsigned_integer (buf, 8, byte_order);
 
-  frame_unwind_register (next_frame, IA64_CFM_REGNUM, buf);
-  cache->cfm = extract_unsigned_integer (buf, 8);
+  get_frame_register (this_frame, IA64_CFM_REGNUM, buf);
+  cache->cfm = extract_unsigned_integer (buf, 8, byte_order);
   cache->sof = cache->cfm & 0x7f;
 
-  ia64_sigtramp_frame_init_saved_regs (next_frame, cache);
+  ia64_sigtramp_frame_init_saved_regs (this_frame, cache);
 
   *this_cache = cache;
   return cache;
 }
 
 static void
-ia64_sigtramp_frame_this_id (struct frame_info *next_frame,
-                              void **this_cache, struct frame_id *this_id)
+ia64_sigtramp_frame_this_id (struct frame_info *this_frame,
+                            void **this_cache, struct frame_id *this_id)
 {
+  struct gdbarch *gdbarch = get_frame_arch (this_frame);
   struct ia64_frame_cache *cache =
-    ia64_sigtramp_frame_cache (next_frame, this_cache);
+    ia64_sigtramp_frame_cache (this_frame, this_cache);
 
-  (*this_id) = frame_id_build_special (cache->base, frame_pc_unwind (next_frame), cache->bsp);
+  (*this_id) = frame_id_build_special (cache->base,
+                                       get_frame_pc (this_frame),
+                                       cache->bsp);
   if (gdbarch_debug >= 1)
     fprintf_unfiltered (gdb_stdlog,
-                       "sigtramp frame id: code 0x%s, stack 0x%s, special 0x%s, next_frame %p\n",
-                       paddr_nz (this_id->code_addr), 
-                       paddr_nz (this_id->stack_addr), 
-                       paddr_nz (cache->bsp), next_frame);
+                       "sigtramp frame id: code %s, stack %s, "
+                       "special %s, this_frame %s\n",
+                       paddress (gdbarch, this_id->code_addr),
+                       paddress (gdbarch, this_id->stack_addr),
+                       paddress (gdbarch, cache->bsp),
+                       host_address_to_string (this_frame));
 }
 
-static void
-ia64_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 *
+ia64_sigtramp_frame_prev_register (struct frame_info *this_frame,
+                                  void **this_cache, int regnum)
 {
-  char dummy_valp[MAX_REGISTER_SIZE];
-  char buf[MAX_REGISTER_SIZE];
-
-  struct gdbarch *gdbarch = get_frame_arch (next_frame);
   struct ia64_frame_cache *cache =
-    ia64_sigtramp_frame_cache (next_frame, this_cache);
+    ia64_sigtramp_frame_cache (this_frame, this_cache);
 
   gdb_assert (regnum >= 0);
 
   if (!target_has_registers)
     error (_("No registers."));
 
-  *optimizedp = 0;
-  *addrp = 0;
-  *lvalp = not_lval;
-  *realnump = -1;
-
-  /* Rather than check each time if valuep is non-null, supply a dummy buffer
-     when valuep is not supplied.  */
-  if (!valuep)
-    valuep = dummy_valp;
-  
-  memset (valuep, 0, register_size (gdbarch, regnum));
   if (regnum == IA64_IP_REGNUM)
     {
       CORE_ADDR pc = 0;
@@ -2042,81 +2294,72 @@ ia64_sigtramp_frame_prev_register (struct frame_info *next_frame,
 
       if (addr != 0)
        {
-         *lvalp = lval_memory;
-         *addrp = addr;
-         read_memory (addr, buf, register_size (gdbarch, IA64_IP_REGNUM));
-         pc = extract_unsigned_integer (buf, 8);
+         struct gdbarch *gdbarch = get_frame_arch (this_frame);
+         enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+         pc = read_memory_unsigned_integer (addr, 8, byte_order);
        }
       pc &= ~0xf;
-      store_unsigned_integer (valuep, 8, pc);
+      return frame_unwind_got_constant (this_frame, regnum, pc);
     }
- else if ((regnum >= IA64_GR32_REGNUM && regnum <= IA64_GR127_REGNUM) ||
-          (regnum >= V32_REGNUM && regnum <= V127_REGNUM))
+
+  else if ((regnum >= IA64_GR32_REGNUM && regnum <= IA64_GR127_REGNUM)
+           || (regnum >= V32_REGNUM && regnum <= V127_REGNUM))
     {
       CORE_ADDR addr = 0;
+
       if (regnum >= V32_REGNUM)
        regnum = IA64_GR32_REGNUM + (regnum - V32_REGNUM);
       addr = cache->saved_regs[regnum];
       if (addr != 0)
-       {
-         *lvalp = lval_memory;
-         *addrp = addr;
-         read_memory (addr, valuep, register_size (gdbarch, regnum));
-       }
+        return frame_unwind_got_memory (this_frame, regnum, addr);
+
+      return frame_unwind_got_constant (this_frame, regnum, 0);
     }
-  else
+
+  else  /* All other registers not listed above.  */
     {
-      /* All other registers not listed above.  */
       CORE_ADDR addr = cache->saved_regs[regnum];
+
       if (addr != 0)
-       {
-         *lvalp = lval_memory;
-         *addrp = addr;
-         read_memory (addr, valuep, register_size (gdbarch, regnum));
-       }
-    }
+        return frame_unwind_got_memory (this_frame, regnum, addr);
 
-  if (gdbarch_debug >= 1)
-    fprintf_unfiltered (gdb_stdlog,
-                       "sigtramp prev register <%s> is 0x%s\n",
-                       (regnum < IA64_GR32_REGNUM
-                        || (regnum > IA64_GR127_REGNUM
-                            && regnum < LAST_PSEUDO_REGNUM))
-                        ? ia64_register_names[regnum]
-                        : (regnum < LAST_PSEUDO_REGNUM
-                           ? ia64_register_names[regnum-IA64_GR32_REGNUM+V32_REGNUM]
-                           : "OUT_OF_RANGE"),
-                       paddr_nz (extract_unsigned_integer (valuep, 8)));
+      return frame_unwind_got_constant (this_frame, regnum, 0);
+    }
 }
 
-static const struct frame_unwind ia64_sigtramp_frame_unwind =
-{
-  SIGTRAMP_FRAME,
-  ia64_sigtramp_frame_this_id,
-  ia64_sigtramp_frame_prev_register
-};
-
-static const struct frame_unwind *
-ia64_sigtramp_frame_sniffer (struct frame_info *next_frame)
+static int
+ia64_sigtramp_frame_sniffer (const struct frame_unwind *self,
+                             struct frame_info *this_frame,
+                             void **this_cache)
 {
-  struct gdbarch_tdep *tdep = gdbarch_tdep (get_frame_arch (next_frame));
+  struct gdbarch_tdep *tdep = gdbarch_tdep (get_frame_arch (this_frame));
   if (tdep->pc_in_sigtramp)
     {
-      CORE_ADDR pc = frame_pc_unwind (next_frame);
+      CORE_ADDR pc = get_frame_pc (this_frame);
 
       if (tdep->pc_in_sigtramp (pc))
-       return &ia64_sigtramp_frame_unwind;
+       return 1;
     }
 
-  return NULL;
+  return 0;
 }
+
+static const struct frame_unwind ia64_sigtramp_frame_unwind =
+{
+  SIGTRAMP_FRAME,
+  default_frame_unwind_stop_reason,
+  ia64_sigtramp_frame_this_id,
+  ia64_sigtramp_frame_prev_register,
+  NULL,
+  ia64_sigtramp_frame_sniffer
+};
+
 \f
 
 static CORE_ADDR
-ia64_frame_base_address (struct frame_info *next_frame, void **this_cache)
+ia64_frame_base_address (struct frame_info *this_frame, void **this_cache)
 {
-  struct ia64_frame_cache *cache =
-    ia64_frame_cache (next_frame, this_cache);
+  struct ia64_frame_cache *cache = ia64_frame_cache (this_frame, this_cache);
 
   return cache->base;
 }
@@ -2156,8 +2399,8 @@ ia64_rse_skip_regs (uint64_t addr, long num_regs)
   return addr + ((num_regs + delta/0x3f) << 3);
 }
   
-/* Gdb libunwind-frame callback function to convert from an ia64 gdb register 
-   number to a libunwind register number.  */
+/* Gdb ia64-libunwind-tdep callback function to convert from an ia64 gdb
+   register number to a libunwind register number.  */
 static int
 ia64_gdb2uw_regnum (int regnum)
 {
@@ -2189,8 +2432,8 @@ ia64_gdb2uw_regnum (int regnum)
     return -1;
 }
   
-/* Gdb libunwind-frame callback function to convert from a libunwind register 
-   number to a ia64 gdb register number.  */
+/* Gdb ia64-libunwind-tdep callback function to convert from a libunwind
+   register number to a ia64 gdb register number.  */
 static int
 ia64_uw2gdb_regnum (int uw_regnum)
 {
@@ -2220,24 +2463,23 @@ ia64_uw2gdb_regnum (int uw_regnum)
     return -1;
 }
 
-/* Gdb libunwind-frame callback function to reveal if register is a float 
-   register or not.  */
+/* Gdb ia64-libunwind-tdep callback function to reveal if register is
+   a float register or not.  */
 static int
 ia64_is_fpreg (int uw_regnum)
 {
   return unw_is_fpreg (uw_regnum);
 }
-  
+
 /* Libunwind callback accessor function for general registers.  */
 static int
 ia64_access_reg (unw_addr_space_t as, unw_regnum_t uw_regnum, unw_word_t *val, 
                 int write, void *arg)
 {
   int regnum = ia64_uw2gdb_regnum (uw_regnum);
-  unw_word_t bsp, sof, sol, cfm, psr, ip;
-  struct frame_info *next_frame = arg;
-  long new_sof, old_sof;
-  char buf[MAX_REGISTER_SIZE];
+  unw_word_t bsp, sof, cfm, psr, ip;
+  struct frame_info *this_frame = (struct frame_info *) arg;
+  struct gdbarch *gdbarch = get_frame_arch (this_frame);
   
   /* We never call any libunwind routines that need to write registers.  */
   gdb_assert (!write);
@@ -2247,74 +2489,68 @@ ia64_access_reg (unw_addr_space_t as, unw_regnum_t uw_regnum, unw_word_t *val,
       case UNW_REG_IP:
        /* Libunwind expects to see the pc value which means the slot number
           from the psr must be merged with the ip word address.  */
-       frame_unwind_register (next_frame, IA64_IP_REGNUM, buf);
-       ip = extract_unsigned_integer (buf, 8); 
-       frame_unwind_register (next_frame, IA64_PSR_REGNUM, buf);
-       psr = extract_unsigned_integer (buf, 8); 
+       ip = get_frame_register_unsigned (this_frame, IA64_IP_REGNUM);
+       psr = get_frame_register_unsigned (this_frame, IA64_PSR_REGNUM);
        *val = ip | ((psr >> 41) & 0x3);
        break;
  
       case UNW_IA64_AR_BSP:
-       /* Libunwind expects to see the beginning of the current register
-          frame so we must account for the fact that ptrace() will return a value
-          for bsp that points *after* the current register frame.  */
-       frame_unwind_register (next_frame, IA64_BSP_REGNUM, buf);
-       bsp = extract_unsigned_integer (buf, 8);
-       frame_unwind_register (next_frame, IA64_CFM_REGNUM, buf);
-       cfm = extract_unsigned_integer (buf, 8); 
-       sof = (cfm & 0x7f);
+       /* Libunwind expects to see the beginning of the current
+          register frame so we must account for the fact that
+          ptrace() will return a value for bsp that points *after*
+          the current register frame.  */
+       bsp = get_frame_register_unsigned (this_frame, IA64_BSP_REGNUM);
+       cfm = get_frame_register_unsigned (this_frame, IA64_CFM_REGNUM);
+       sof = gdbarch_tdep (gdbarch)->size_of_register_frame (this_frame, cfm);
        *val = ia64_rse_skip_regs (bsp, -sof);
        break;
 
       case UNW_IA64_AR_BSPSTORE:
        /* Libunwind wants bspstore to be after the current register frame.
           This is what ptrace() and gdb treats as the regular bsp value.  */
-       frame_unwind_register (next_frame, IA64_BSP_REGNUM, buf);
-       *val = extract_unsigned_integer (buf, 8);
+       *val = get_frame_register_unsigned (this_frame, IA64_BSP_REGNUM);
        break;
 
       default:
        /* For all other registers, just unwind the value directly.  */
-       frame_unwind_register (next_frame, regnum, buf);
-       *val = extract_unsigned_integer (buf, 8); 
+       *val = get_frame_register_unsigned (this_frame, regnum);
        break;
     }
       
   if (gdbarch_debug >= 1)
     fprintf_unfiltered (gdb_stdlog, 
-                       "  access_reg: from cache: %4s=0x%s\n",
+                       "  access_reg: from cache: %4s=%s\n",
                        (((unsigned) regnum <= IA64_NAT127_REGNUM)
                        ? ia64_register_names[regnum] : "r??"), 
-                       paddr_nz (*val));
+                       paddress (gdbarch, *val));
   return 0;
 }
 
 /* Libunwind callback accessor function for floating-point registers.  */
 static int
-ia64_access_fpreg (unw_addr_space_t as, unw_regnum_t uw_regnum, unw_fpreg_t *val, 
-                  int write, void *arg)
+ia64_access_fpreg (unw_addr_space_t as, unw_regnum_t uw_regnum,
+                  unw_fpreg_t *val, int write, void *arg)
 {
   int regnum = ia64_uw2gdb_regnum (uw_regnum);
-  struct frame_info *next_frame = arg;
+  struct frame_info *this_frame = (struct frame_info *) arg;
   
   /* We never call any libunwind routines that need to write registers.  */
   gdb_assert (!write);
 
-  frame_unwind_register (next_frame, regnum, (char *) val);
+  get_frame_register (this_frame, regnum, (gdb_byte *) val);
 
   return 0;
 }
 
 /* Libunwind callback accessor function for top-level rse registers.  */
 static int
-ia64_access_rse_reg (unw_addr_space_t as, unw_regnum_t uw_regnum, unw_word_t *val, 
-                    int write, void *arg)
+ia64_access_rse_reg (unw_addr_space_t as, unw_regnum_t uw_regnum,
+                    unw_word_t *val, int write, void *arg)
 {
   int regnum = ia64_uw2gdb_regnum (uw_regnum);
-  unw_word_t bsp, sof, sol, cfm, psr, ip;
-  struct regcache *regcache = arg;
-  long new_sof, old_sof;
-  char buf[MAX_REGISTER_SIZE];
+  unw_word_t bsp, sof, cfm, psr, ip;
+  struct regcache *regcache = (struct regcache *) arg;
+  struct gdbarch *gdbarch = regcache->arch ();
   
   /* We never call any libunwind routines that need to write registers.  */
   gdb_assert (!write);
@@ -2324,21 +2560,18 @@ ia64_access_rse_reg (unw_addr_space_t as, unw_regnum_t uw_regnum, unw_word_t *va
       case UNW_REG_IP:
        /* Libunwind expects to see the pc value which means the slot number
           from the psr must be merged with the ip word address.  */
-       regcache_cooked_read (regcache, IA64_IP_REGNUM, buf);
-       ip = extract_unsigned_integer (buf, 8); 
-       regcache_cooked_read (regcache, IA64_PSR_REGNUM, buf);
-       psr = extract_unsigned_integer (buf, 8); 
+       regcache_cooked_read_unsigned (regcache, IA64_IP_REGNUM, &ip);
+       regcache_cooked_read_unsigned (regcache, IA64_PSR_REGNUM, &psr);
        *val = ip | ((psr >> 41) & 0x3);
        break;
          
       case UNW_IA64_AR_BSP:
-       /* Libunwind expects to see the beginning of the current register
-          frame so we must account for the fact that ptrace() will return a value
-          for bsp that points *after* the current register frame.  */
-       regcache_cooked_read (regcache, IA64_BSP_REGNUM, buf);
-       bsp = extract_unsigned_integer (buf, 8);
-       regcache_cooked_read (regcache, IA64_CFM_REGNUM, buf);
-       cfm = extract_unsigned_integer (buf, 8); 
+       /* Libunwind expects to see the beginning of the current
+          register frame so we must account for the fact that
+          ptrace() will return a value for bsp that points *after*
+          the current register frame.  */
+       regcache_cooked_read_unsigned (regcache, IA64_BSP_REGNUM, &bsp);
+       regcache_cooked_read_unsigned (regcache, IA64_CFM_REGNUM, &cfm);
        sof = (cfm & 0x7f);
        *val = ia64_rse_skip_regs (bsp, -sof);
        break;
@@ -2346,23 +2579,21 @@ ia64_access_rse_reg (unw_addr_space_t as, unw_regnum_t uw_regnum, unw_word_t *va
       case UNW_IA64_AR_BSPSTORE:
        /* Libunwind wants bspstore to be after the current register frame.
           This is what ptrace() and gdb treats as the regular bsp value.  */
-       regcache_cooked_read (regcache, IA64_BSP_REGNUM, buf);
-       *val = extract_unsigned_integer (buf, 8);
+       regcache_cooked_read_unsigned (regcache, IA64_BSP_REGNUM, val);
        break;
 
       default:
         /* For all other registers, just unwind the value directly.  */
-       regcache_cooked_read (regcache, regnum, buf);
-       *val = extract_unsigned_integer (buf, 8); 
+       regcache_cooked_read_unsigned (regcache, regnum, val);
        break;
     }
       
   if (gdbarch_debug >= 1)
     fprintf_unfiltered (gdb_stdlog, 
-                       "  access_rse_reg: from cache: %4s=0x%s\n",
+                       "  access_rse_reg: from cache: %4s=%s\n",
                        (((unsigned) regnum <= IA64_NAT127_REGNUM)
                         ? ia64_register_names[regnum] : "r??"), 
-                       paddr_nz (*val));
+                       paddress (gdbarch, *val));
 
   return 0;
 }
@@ -2373,12 +2604,12 @@ ia64_access_rse_fpreg (unw_addr_space_t as, unw_regnum_t uw_regnum,
                       unw_fpreg_t *val, int write, void *arg)
 {
   int regnum = ia64_uw2gdb_regnum (uw_regnum);
-  struct regcache *regcache = arg;
+  struct regcache *regcache = (struct regcache *) arg;
   
   /* We never call any libunwind routines that need to write registers.  */
   gdb_assert (!write);
 
-  regcache_cooked_read (regcache, regnum, (char *) val);
+  regcache->cooked_read (regnum, (gdb_byte *) val);
 
   return 0;
 }
@@ -2403,17 +2634,15 @@ ia64_access_mem (unw_addr_space_t as,
 
   /* XXX do we need to normalize byte-order here?  */
   if (write)
-    return target_write_memory (addr, (char *) val, sizeof (unw_word_t));
+    return target_write_memory (addr, (gdb_byte *) val, sizeof (unw_word_t));
   else
-    return target_read_memory (addr, (char *) val, sizeof (unw_word_t));
+    return target_read_memory (addr, (gdb_byte *) val, sizeof (unw_word_t));
 }
 
 /* Call low-level function to access the kernel unwind table.  */
-static LONGEST
-getunwind_table (gdb_byte **buf_p)
+static gdb::optional<gdb::byte_vector>
+getunwind_table ()
 {
-  LONGEST x;
-
   /* FIXME drow/2005-09-10: This code used to call
      ia64_linux_xfer_unwind_table directly to fetch the unwind table
      for the currently running ia64-linux kernel.  That data should
@@ -2422,10 +2651,8 @@ getunwind_table (gdb_byte **buf_p)
      we should find a way to override the corefile layer's
      xfer_partial method.  */
 
-  x = target_read_alloc (&current_target, TARGET_OBJECT_UNWIND_TABLE,
-                        NULL, buf_p);
-
-  return x;
+  return target_read_alloc (current_top_target (), TARGET_OBJECT_UNWIND_TABLE,
+                           NULL);
 }
 
 /* Get the kernel unwind table.  */                             
@@ -2436,15 +2663,12 @@ get_kernel_table (unw_word_t ip, unw_dyn_info_t *di)
 
   if (!ktab) 
     {
-      gdb_byte *ktab_buf;
-      LONGEST size;
-
-      size = getunwind_table (&ktab_buf);
-      if (size <= 0)
+      ktab_buf = getunwind_table ();
+      if (!ktab_buf)
        return -UNW_ENOINFO;
 
-      ktab = (struct ia64_table_entry *) ktab_buf;
-      ktab_size = size;
+      ktab = (struct ia64_table_entry *) ktab_buf->data ();
+      ktab_size = ktab_buf->size ();
 
       for (etab = ktab; etab->start_offset; ++etab)
         etab->info_offset += KERNEL_START;
@@ -2464,11 +2688,11 @@ get_kernel_table (unw_word_t ip, unw_dyn_info_t *di)
   
   if (gdbarch_debug >= 1)
     fprintf_unfiltered (gdb_stdlog, "get_kernel_table: found table `%s': "
-                       "segbase=0x%s, length=%s, gp=0x%s\n",
+                       "segbase=%s, length=%s, gp=%s\n",
                        (char *) di->u.ti.name_ptr, 
-                       paddr_nz (di->u.ti.segbase), 
-                       paddr_u (di->u.ti.table_len), 
-                       paddr_nz (di->gp));
+                       hex_string (di->u.ti.segbase),
+                       pulongest (di->u.ti.table_len), 
+                       hex_string (di->gp));
   return 0;
 }
 
@@ -2489,7 +2713,7 @@ ia64_find_unwind_table (struct objfile *objfile, unw_word_t ip,
   ehdr = elf_tdata (bfd)->elf_header;
   phdr = elf_tdata (bfd)->phdr;
 
-  load_base = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+  load_base = objfile->text_section_offset ();
 
   for (i = 0; i < ehdr->e_phnum; ++i)
     {
@@ -2515,7 +2739,7 @@ ia64_find_unwind_table (struct objfile *objfile, unw_word_t ip,
 
   /* Verify that the segment that contains the IP also contains
      the static unwind table.  If not, we may be in the Linux kernel's
-     DSO gate page in which case the unwind table is another segment. 
+     DSO gate page in which case the unwind table is another segment.
      Otherwise, we are dealing with runtime-generated code, for which we 
      have no info here.  */
   segbase = p_text->p_vaddr + load_base;
@@ -2540,7 +2764,7 @@ ia64_find_unwind_table (struct objfile *objfile, unw_word_t ip,
 
   dip->start_ip = p_text->p_vaddr + load_base;
   dip->end_ip = dip->start_ip + p_text->p_memsz;
-  dip->gp = ia64_find_global_pointer (ip);
+  dip->gp = ia64_find_global_pointer (objfile->arch (), ip);
   dip->format = UNW_INFO_FORMAT_REMOTE_TABLE;
   dip->u.rti.name_ptr = (unw_word_t) bfd_get_filename (bfd);
   dip->u.rti.segbase = segbase;
@@ -2569,15 +2793,15 @@ ia64_find_proc_info_x (unw_addr_space_t as, unw_word_t ip, unw_proc_info_t *pi,
        return -UNW_ENOINFO;
 
       if (gdbarch_debug >= 1)
-       fprintf_unfiltered (gdb_stdlog, "ia64_find_proc_info_x: 0x%s -> "
-                           "(name=`%s',segbase=0x%s,start=0x%s,end=0x%s,gp=0x%s,"
-                           "length=%s,data=0x%s)\n",
-                           paddr_nz (ip), (char *)di.u.ti.name_ptr,
-                           paddr_nz (di.u.ti.segbase), 
-                           paddr_nz (di.start_ip), paddr_nz (di.end_ip),
-                           paddr_nz (di.gp), 
-                           paddr_u (di.u.ti.table_len), 
-                           paddr_nz ((CORE_ADDR)di.u.ti.table_data));
+       fprintf_unfiltered (gdb_stdlog, "ia64_find_proc_info_x: %s -> "
+                           "(name=`%s',segbase=%s,start=%s,end=%s,gp=%s,"
+                           "length=%s,data=%s)\n",
+                           hex_string (ip), (char *)di.u.ti.name_ptr,
+                           hex_string (di.u.ti.segbase),
+                           hex_string (di.start_ip), hex_string (di.end_ip),
+                           hex_string (di.gp),
+                           pulongest (di.u.ti.table_len), 
+                           hex_string ((CORE_ADDR)di.u.ti.table_data));
     }
   else
     {
@@ -2586,15 +2810,15 @@ ia64_find_proc_info_x (unw_addr_space_t as, unw_word_t ip, unw_proc_info_t *pi,
        return ret;
 
       if (gdbarch_debug >= 1)
-       fprintf_unfiltered (gdb_stdlog, "ia64_find_proc_info_x: 0x%s -> "
-                           "(name=`%s',segbase=0x%s,start=0x%s,end=0x%s,gp=0x%s,"
-                           "length=%s,data=0x%s)\n",
-                           paddr_nz (ip), (char *)di.u.rti.name_ptr,
-                           paddr_nz (di.u.rti.segbase), 
-                           paddr_nz (di.start_ip), paddr_nz (di.end_ip),
-                           paddr_nz (di.gp), 
-                           paddr_u (di.u.rti.table_len), 
-                           paddr_nz (di.u.rti.table_data));
+       fprintf_unfiltered (gdb_stdlog, "ia64_find_proc_info_x: %s -> "
+                           "(name=`%s',segbase=%s,start=%s,end=%s,gp=%s,"
+                           "length=%s,data=%s)\n",
+                           hex_string (ip), (char *)di.u.rti.name_ptr,
+                           hex_string (di.u.rti.segbase),
+                           hex_string (di.start_ip), hex_string (di.end_ip),
+                           hex_string (di.gp),
+                           pulongest (di.u.rti.table_len), 
+                           hex_string (di.u.rti.table_data));
     }
 
   ret = libunwind_search_unwind_table (&as, ip, &di, pi, need_unwind_info,
@@ -2621,7 +2845,6 @@ ia64_get_dyn_info_list (unw_addr_space_t as,
                        unw_word_t *dilap, void *arg)
 {
   struct obj_section *text_sec;
-  struct objfile *objfile;
   unw_word_t ip, addr;
   unw_dyn_info_t di;
   int ret;
@@ -2629,12 +2852,12 @@ ia64_get_dyn_info_list (unw_addr_space_t as,
   if (!libunwind_is_initialized ())
     return -UNW_ENOINFO;
 
-  for (objfile = object_files; objfile; objfile = objfile->next)
+  for (objfile *objfile : current_program_space->objfiles ())
     {
       void *buf = NULL;
 
       text_sec = objfile->sections + SECT_OFF_TEXT (objfile);
-      ip = text_sec->addr;
+      ip = obj_section_addr (text_sec);
       ret = ia64_find_unwind_table (objfile, ip, &di, &buf);
       if (ret >= 0)
        {
@@ -2647,9 +2870,9 @@ ia64_get_dyn_info_list (unw_addr_space_t as,
              if (gdbarch_debug >= 1)
                fprintf_unfiltered (gdb_stdlog,
                                    "dynamic unwind table in objfile %s "
-                                   "at 0x%s (gp=0x%s)\n",
+                                   "at %s (gp=%s)\n",
                                    bfd_get_filename (objfile->obfd),
-                                   paddr_nz (addr), paddr_nz (di.gp));
+                                   hex_string (addr), hex_string (di.gp));
              *dilap = addr;
              return 0;
            }
@@ -2662,70 +2885,55 @@ ia64_get_dyn_info_list (unw_addr_space_t as,
 /* Frame interface functions for libunwind.  */
 
 static void
-ia64_libunwind_frame_this_id (struct frame_info *next_frame, void **this_cache,
+ia64_libunwind_frame_this_id (struct frame_info *this_frame, void **this_cache,
                              struct frame_id *this_id)
 {
-  char buf[8];
+  struct gdbarch *gdbarch = get_frame_arch (this_frame);
+  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+  struct frame_id id = outer_frame_id;
+  gdb_byte buf[8];
   CORE_ADDR bsp;
-  struct frame_id id;
-  CORE_ADDR prev_ip, addr;
-  int realnum, optimized;
-  enum lval_type lval;
 
-
-  libunwind_frame_this_id (next_frame, this_cache, &id);
-  if (frame_id_eq (id, null_frame_id))
+  libunwind_frame_this_id (this_frame, this_cache, &id);
+  if (frame_id_eq (id, outer_frame_id))
     {
-      (*this_id) = null_frame_id;
+      (*this_id) = outer_frame_id;
       return;
     }
 
   /* We must add the bsp as the special address for frame comparison 
      purposes.  */
-  frame_unwind_register (next_frame, IA64_BSP_REGNUM, buf);
-  bsp = extract_unsigned_integer (buf, 8);
-
-  /* If the previous frame pc value is 0, then we are at the end of the stack
-     and don't want to unwind past this frame.  We return a null frame_id to
-     indicate this.  */
-  libunwind_frame_prev_register (next_frame, this_cache, IA64_IP_REGNUM, 
-                                &optimized, &lval, &addr, &realnum, buf);
-  prev_ip = extract_unsigned_integer (buf, 8);
-
-  if (prev_ip != 0)
-    (*this_id) = frame_id_build_special (id.stack_addr, id.code_addr, bsp);
-  else
-    (*this_id) = null_frame_id;
+  get_frame_register (this_frame, IA64_BSP_REGNUM, buf);
+  bsp = extract_unsigned_integer (buf, 8, byte_order);
+
+  (*this_id) = frame_id_build_special (id.stack_addr, id.code_addr, bsp);
 
   if (gdbarch_debug >= 1)
     fprintf_unfiltered (gdb_stdlog,
-                       "libunwind frame id: code 0x%s, stack 0x%s, special 0x%s, next_frame %p\n",
-                       paddr_nz (id.code_addr), paddr_nz (id.stack_addr), 
-                       paddr_nz (bsp), next_frame);
+                       "libunwind frame id: code %s, stack %s, "
+                       "special %s, this_frame %s\n",
+                       paddress (gdbarch, id.code_addr),
+                       paddress (gdbarch, id.stack_addr),
+                       paddress (gdbarch, bsp),
+                       host_address_to_string (this_frame));
 }
 
-static void
-ia64_libunwind_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 *
+ia64_libunwind_frame_prev_register (struct frame_info *this_frame,
+                                   void **this_cache, int regnum)
 {
   int reg = regnum;
+  struct gdbarch *gdbarch = get_frame_arch (this_frame);
+  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+  struct value *val;
 
-  struct gdbarch *gdbarch = get_frame_arch (next_frame);
   if (VP0_REGNUM <= regnum && regnum <= VP63_REGNUM)
     reg = IA64_PR_REGNUM;
   else if (IA64_NAT0_REGNUM <= regnum && regnum <= IA64_NAT127_REGNUM)
     reg = IA64_UNAT_REGNUM;
 
   /* Let libunwind do most of the work.  */
-  libunwind_frame_prev_register (next_frame, this_cache, reg,
-                                optimizedp, lvalp, addrp, realnump, valuep);
-
-  /* No more to do if the value is not supposed to be supplied.  */
-  if (!valuep)
-    return;
+  val = libunwind_frame_prev_register (this_frame, this_cache, reg);
 
   if (VP0_REGNUM <= regnum && regnum <= VP63_REGNUM)
     {
@@ -2735,171 +2943,165 @@ ia64_libunwind_frame_prev_register (struct frame_info *next_frame,
        {
          int rrb_pr = 0;
          ULONGEST cfm;
-         unsigned char buf[MAX_REGISTER_SIZE];
 
          /* Fetch predicate register rename base from current frame
             marker for this frame.  */
-         frame_unwind_register (next_frame, IA64_CFM_REGNUM, buf);
-         cfm = extract_unsigned_integer (buf, 8); 
+         cfm = get_frame_register_unsigned (this_frame, IA64_CFM_REGNUM);
          rrb_pr = (cfm >> 32) & 0x3f;
          
          /* Adjust the register number to account for register rotation.  */
-         regnum = VP16_REGNUM 
-           + ((regnum - VP16_REGNUM) + rrb_pr) % 48;
+         regnum = VP16_REGNUM + ((regnum - VP16_REGNUM) + rrb_pr) % 48;
        }
-      prN_val = extract_bit_field ((unsigned char *) valuep,
+      prN_val = extract_bit_field (value_contents_all (val),
                                   regnum - VP0_REGNUM, 1);
-      store_unsigned_integer (valuep, register_size (gdbarch, regnum), prN_val);
+      return frame_unwind_got_constant (this_frame, regnum, prN_val);
     }
+
   else if (IA64_NAT0_REGNUM <= regnum && regnum <= IA64_NAT127_REGNUM)
     {
       ULONGEST unatN_val;
 
-      unatN_val = extract_bit_field ((unsigned char *) valuep,
-                                   regnum - IA64_NAT0_REGNUM, 1);
-      store_unsigned_integer (valuep, register_size (gdbarch, regnum), 
-                              unatN_val);
+      unatN_val = extract_bit_field (value_contents_all (val),
+                                     regnum - IA64_NAT0_REGNUM, 1);
+      return frame_unwind_got_constant (this_frame, regnum, unatN_val);
     }
+
   else if (regnum == IA64_BSP_REGNUM)
     {
-      char cfm_valuep[MAX_REGISTER_SIZE];
-      int  cfm_optim;
-      int  cfm_realnum;
-      enum lval_type cfm_lval;
-      CORE_ADDR cfm_addr;
-      CORE_ADDR bsp, prev_cfm, prev_bsp;
-
-      /* We want to calculate the previous bsp as the end of the previous register stack frame.
-        This corresponds to what the hardware bsp register will be if we pop the frame
-        back which is why we might have been called.  We know that libunwind will pass us back
-        the beginning of the current frame so we should just add sof to it. */
-      prev_bsp = extract_unsigned_integer (valuep, 8);
-      libunwind_frame_prev_register (next_frame, this_cache, IA64_CFM_REGNUM,
-                                    &cfm_optim, &cfm_lval, &cfm_addr, &cfm_realnum, cfm_valuep);
-      prev_cfm = extract_unsigned_integer (cfm_valuep, 8);
+      struct value *cfm_val;
+      CORE_ADDR prev_bsp, prev_cfm;
+
+      /* We want to calculate the previous bsp as the end of the previous
+         register stack frame.  This corresponds to what the hardware bsp
+         register will be if we pop the frame back which is why we might
+         have been called.  We know that libunwind will pass us back the
+         beginning of the current frame so we should just add sof to it.  */
+      prev_bsp = extract_unsigned_integer (value_contents_all (val),
+                                          8, byte_order);
+      cfm_val = libunwind_frame_prev_register (this_frame, this_cache,
+                                               IA64_CFM_REGNUM);
+      prev_cfm = extract_unsigned_integer (value_contents_all (cfm_val),
+                                          8, byte_order);
       prev_bsp = rse_address_add (prev_bsp, (prev_cfm & 0x7f));
 
-      store_unsigned_integer (valuep, register_size (gdbarch, regnum), 
-                             prev_bsp);
+      return frame_unwind_got_constant (this_frame, regnum, prev_bsp);
     }
+  else
+    return val;
+}
 
-  if (gdbarch_debug >= 1)
-    fprintf_unfiltered (gdb_stdlog,
-                       "libunwind prev register <%s> is 0x%s\n",
-                       (regnum < IA64_GR32_REGNUM
-                        || (regnum > IA64_GR127_REGNUM
-                            && regnum < LAST_PSEUDO_REGNUM))
-                        ? ia64_register_names[regnum]
-                        : (regnum < LAST_PSEUDO_REGNUM
-                           ? ia64_register_names[regnum-IA64_GR32_REGNUM+V32_REGNUM]
-                           : "OUT_OF_RANGE"),
-                       paddr_nz (extract_unsigned_integer (valuep, 8)));
+static int
+ia64_libunwind_frame_sniffer (const struct frame_unwind *self,
+                              struct frame_info *this_frame,
+                              void **this_cache)
+{
+  if (libunwind_is_initialized ()
+      && libunwind_frame_sniffer (self, this_frame, this_cache))
+    return 1;
+
+  return 0;
 }
 
 static const struct frame_unwind ia64_libunwind_frame_unwind =
 {
   NORMAL_FRAME,
+  default_frame_unwind_stop_reason,
   ia64_libunwind_frame_this_id,
   ia64_libunwind_frame_prev_register,
   NULL,
-  NULL,
-  NULL,
+  ia64_libunwind_frame_sniffer,
   libunwind_frame_dealloc_cache
 };
 
-static const struct frame_unwind *
-ia64_libunwind_frame_sniffer (struct frame_info *next_frame)
-{
-  if (libunwind_is_initialized () && libunwind_frame_sniffer (next_frame))
-    return &ia64_libunwind_frame_unwind;
-
-  return NULL;
-}
-
 static void
-ia64_libunwind_sigtramp_frame_this_id (struct frame_info *next_frame, void **this_cache,
+ia64_libunwind_sigtramp_frame_this_id (struct frame_info *this_frame,
+                                       void **this_cache,
                                       struct frame_id *this_id)
 {
-  char buf[8];
+  struct gdbarch *gdbarch = get_frame_arch (this_frame);
+  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+  gdb_byte buf[8];
   CORE_ADDR bsp;
-  struct frame_id id;
-  CORE_ADDR prev_ip;
+  struct frame_id id = outer_frame_id;
 
-  libunwind_frame_this_id (next_frame, this_cache, &id);
-  if (frame_id_eq (id, null_frame_id))
+  libunwind_frame_this_id (this_frame, this_cache, &id);
+  if (frame_id_eq (id, outer_frame_id))
     {
-      (*this_id) = null_frame_id;
+      (*this_id) = outer_frame_id;
       return;
     }
 
   /* We must add the bsp as the special address for frame comparison 
      purposes.  */
-  frame_unwind_register (next_frame, IA64_BSP_REGNUM, buf);
-  bsp = extract_unsigned_integer (buf, 8);
+  get_frame_register (this_frame, IA64_BSP_REGNUM, buf);
+  bsp = extract_unsigned_integer (buf, 8, byte_order);
 
   /* For a sigtramp frame, we don't make the check for previous ip being 0.  */
   (*this_id) = frame_id_build_special (id.stack_addr, id.code_addr, bsp);
 
   if (gdbarch_debug >= 1)
     fprintf_unfiltered (gdb_stdlog,
-                       "libunwind sigtramp frame id: code 0x%s, stack 0x%s, special 0x%s, next_frame %p\n",
-                       paddr_nz (id.code_addr), paddr_nz (id.stack_addr), 
-                       paddr_nz (bsp), next_frame);
+                       "libunwind sigtramp frame id: code %s, "
+                       "stack %s, special %s, this_frame %s\n",
+                       paddress (gdbarch, id.code_addr),
+                       paddress (gdbarch, id.stack_addr),
+                       paddress (gdbarch, bsp),
+                       host_address_to_string (this_frame));
 }
 
-static void
-ia64_libunwind_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 *
+ia64_libunwind_sigtramp_frame_prev_register (struct frame_info *this_frame,
+                                            void **this_cache, int regnum)
 {
-  gdb_byte buf[8];
-  CORE_ADDR prev_ip, addr;
-  int realnum, optimized;
-  enum lval_type lval;
-
+  struct gdbarch *gdbarch = get_frame_arch (this_frame);
+  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+  struct value *prev_ip_val;
+  CORE_ADDR prev_ip;
 
   /* If the previous frame pc value is 0, then we want to use the SIGCONTEXT
      method of getting previous registers.  */
-  libunwind_frame_prev_register (next_frame, this_cache, IA64_IP_REGNUM, 
-                                &optimized, &lval, &addr, &realnum, buf);
-  prev_ip = extract_unsigned_integer (buf, 8);
+  prev_ip_val = libunwind_frame_prev_register (this_frame, this_cache,
+                                               IA64_IP_REGNUM);
+  prev_ip = extract_unsigned_integer (value_contents_all (prev_ip_val),
+                                     8, byte_order);
 
   if (prev_ip == 0)
     {
       void *tmp_cache = NULL;
-      ia64_sigtramp_frame_prev_register (next_frame, &tmp_cache, regnum, optimizedp, lvalp,
-                                        addrp, realnump, valuep);
+      return ia64_sigtramp_frame_prev_register (this_frame, &tmp_cache,
+                                                regnum);
     }
   else
-    ia64_libunwind_frame_prev_register (next_frame, this_cache, regnum, optimizedp, lvalp,
-                                       addrp, realnump, valuep);
+    return ia64_libunwind_frame_prev_register (this_frame, this_cache, regnum);
 }
 
-static const struct frame_unwind ia64_libunwind_sigtramp_frame_unwind =
-{
-  SIGTRAMP_FRAME,
-  ia64_libunwind_sigtramp_frame_this_id,
-  ia64_libunwind_sigtramp_frame_prev_register
-};
-
-static const struct frame_unwind *
-ia64_libunwind_sigtramp_frame_sniffer (struct frame_info *next_frame)
+static int
+ia64_libunwind_sigtramp_frame_sniffer (const struct frame_unwind *self,
+                                       struct frame_info *this_frame,
+                                       void **this_cache)
 {
   if (libunwind_is_initialized ())
     {
-      if (libunwind_sigtramp_frame_sniffer (next_frame))
-        return &ia64_libunwind_sigtramp_frame_unwind;
-      return NULL;
+      if (libunwind_sigtramp_frame_sniffer (self, this_frame, this_cache))
+        return 1;
+      return 0;
     }
   else
-    return ia64_sigtramp_frame_sniffer (next_frame);
+    return ia64_sigtramp_frame_sniffer (self, this_frame, this_cache);
 }
 
+static const struct frame_unwind ia64_libunwind_sigtramp_frame_unwind =
+{
+  SIGTRAMP_FRAME,
+  default_frame_unwind_stop_reason,
+  ia64_libunwind_sigtramp_frame_this_id,
+  ia64_libunwind_sigtramp_frame_prev_register,
+  NULL,
+  ia64_libunwind_sigtramp_frame_sniffer
+};
+
 /* Set of libunwind callback acccessor functions.  */
-static unw_accessors_t ia64_unw_accessors =
+unw_accessors_t ia64_unw_accessors =
 {
   ia64_find_proc_info_x,
   ia64_put_unwind_info,
@@ -2913,9 +3115,9 @@ static unw_accessors_t ia64_unw_accessors =
 
 /* Set of special libunwind callback acccessor functions specific for accessing
    the rse registers.  At the top of the stack, we want libunwind to figure out
-   how to read r32 - r127.  Though usually they are found sequentially in memory
-   starting from $bof, this is not always true.  */
-static unw_accessors_t ia64_unw_rse_accessors =
+   how to read r32 - r127.  Though usually they are found sequentially in
+   memory starting from $bof, this is not always true.  */
+unw_accessors_t ia64_unw_rse_accessors =
 {
   ia64_find_proc_info_x,
   ia64_put_unwind_info,
@@ -2927,8 +3129,9 @@ static unw_accessors_t ia64_unw_rse_accessors =
   /* get_proc_name */
 };
 
-/* Set of ia64 gdb libunwind-frame callbacks and data for generic libunwind-frame code to use.  */
-static struct libunwind_descr ia64_libunwind_descr =
+/* Set of ia64-libunwind-tdep gdb callbacks and data for generic
+   ia64-libunwind-tdep code to use.  */
+struct libunwind_descr ia64_libunwind_descr =
 {
   ia64_gdb2uw_regnum, 
   ia64_uw2gdb_regnum, 
@@ -2946,9 +3149,9 @@ ia64_use_struct_convention (struct type *type)
 
   /* Don't use the struct convention for anything but structure,
      union, or array types.  */
-  if (!(TYPE_CODE (type) == TYPE_CODE_STRUCT
-       || TYPE_CODE (type) == TYPE_CODE_UNION
-       || TYPE_CODE (type) == TYPE_CODE_ARRAY))
+  if (!(type->code () == TYPE_CODE_STRUCT
+       || type->code () == TYPE_CODE_UNION
+       || type->code () == TYPE_CODE_ARRAY))
     return 0;
 
   /* HFAs are structures (or arrays) consisting entirely of floating
@@ -2965,44 +3168,68 @@ ia64_use_struct_convention (struct type *type)
   return TYPE_LENGTH (type) > 32;
 }
 
+/* Return non-zero if TYPE is a structure or union type.  */
+
+static int
+ia64_struct_type_p (const struct type *type)
+{
+  return (type->code () == TYPE_CODE_STRUCT
+          || type->code () == TYPE_CODE_UNION);
+}
+
 static void
 ia64_extract_return_value (struct type *type, struct regcache *regcache,
                           gdb_byte *valbuf)
 {
+  struct gdbarch *gdbarch = regcache->arch ();
   struct type *float_elt_type;
 
   float_elt_type = is_float_or_hfa_type (type);
   if (float_elt_type != NULL)
     {
-      char from[MAX_REGISTER_SIZE];
+      gdb_byte from[IA64_FP_REGISTER_SIZE];
       int offset = 0;
       int regnum = IA64_FR8_REGNUM;
       int n = TYPE_LENGTH (type) / TYPE_LENGTH (float_elt_type);
 
       while (n-- > 0)
        {
-         regcache_cooked_read (regcache, regnum, from);
-         convert_typed_floating (from, builtin_type_ia64_ext,
-                                 (char *)valbuf + offset, float_elt_type);       
+         regcache->cooked_read (regnum, from);
+         target_float_convert (from, ia64_ext_type (gdbarch),
+                               valbuf + offset, float_elt_type);
          offset += TYPE_LENGTH (float_elt_type);
          regnum++;
        }
     }
+  else if (!ia64_struct_type_p (type) && TYPE_LENGTH (type) < 8)
+    {
+      /* This is an integral value, and its size is less than 8 bytes.
+         These values are LSB-aligned, so extract the relevant bytes,
+         and copy them into VALBUF.  */
+      /* brobecker/2005-12-30: Actually, all integral values are LSB aligned,
+        so I suppose we should also add handling here for integral values
+        whose size is greater than 8.  But I wasn't able to create such
+        a type, neither in C nor in Ada, so not worrying about these yet.  */
+      enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+      ULONGEST val;
+
+      regcache_cooked_read_unsigned (regcache, IA64_GR8_REGNUM, &val);
+      store_unsigned_integer (valbuf, TYPE_LENGTH (type), byte_order, val);
+    }
   else
     {
       ULONGEST val;
       int offset = 0;
       int regnum = IA64_GR8_REGNUM;
-      int reglen = TYPE_LENGTH (register_type (get_regcache_arch (regcache),
-                                              IA64_GR8_REGNUM));
+      int reglen = TYPE_LENGTH (register_type (gdbarch, IA64_GR8_REGNUM));
       int n = TYPE_LENGTH (type) / reglen;
       int m = TYPE_LENGTH (type) % reglen;
 
       while (n-- > 0)
        {
-         ULONGEST val;
-         regcache_cooked_read_unsigned (regcache, regnum, &val);
-         memcpy ((char *)valbuf + offset, &val, reglen);
+         ULONGEST regval;
+         regcache_cooked_read_unsigned (regcache, regnum, &regval);
+         memcpy ((char *)valbuf + offset, &regval, reglen);
          offset += reglen;
          regnum++;
        }
@@ -3019,32 +3246,31 @@ static void
 ia64_store_return_value (struct type *type, struct regcache *regcache, 
                         const gdb_byte *valbuf)
 {
+  struct gdbarch *gdbarch = regcache->arch ();
   struct type *float_elt_type;
 
   float_elt_type = is_float_or_hfa_type (type);
   if (float_elt_type != NULL)
     {
-      char to[MAX_REGISTER_SIZE];
+      gdb_byte to[IA64_FP_REGISTER_SIZE];
       int offset = 0;
       int regnum = IA64_FR8_REGNUM;
       int n = TYPE_LENGTH (type) / TYPE_LENGTH (float_elt_type);
 
       while (n-- > 0)
        {
-         convert_typed_floating ((char *)valbuf + offset, float_elt_type,
-                                 to, builtin_type_ia64_ext);
-         regcache_cooked_write (regcache, regnum, to);
+         target_float_convert (valbuf + offset, float_elt_type,
+                               to, ia64_ext_type (gdbarch));
+         regcache->cooked_write (regnum, to);
          offset += TYPE_LENGTH (float_elt_type);
          regnum++;
        }
     }
   else
     {
-      ULONGEST val;
       int offset = 0;
       int regnum = IA64_GR8_REGNUM;
-      int reglen = TYPE_LENGTH (register_type (get_regcache_arch (regcache),
-                                              IA64_GR8_REGNUM));
+      int reglen = TYPE_LENGTH (register_type (gdbarch, IA64_GR8_REGNUM));
       int n = TYPE_LENGTH (type) / reglen;
       int m = TYPE_LENGTH (type) % reglen;
 
@@ -3059,6 +3285,7 @@ ia64_store_return_value (struct type *type, struct regcache *regcache,
 
       if (m)
        {
+         ULONGEST val;
          memcpy (&val, (char *)valbuf + offset, m);
           regcache_cooked_write_unsigned (regcache, regnum, val);
        }
@@ -3066,7 +3293,7 @@ ia64_store_return_value (struct type *type, struct regcache *regcache,
 }
   
 static enum return_value_convention
-ia64_return_value (struct gdbarch *gdbarch, struct type *func_type,
+ia64_return_value (struct gdbarch *gdbarch, struct value *function,
                   struct type *valtype, struct regcache *regcache,
                   gdb_byte *readbuf, const gdb_byte *writebuf)
 {
@@ -3093,7 +3320,7 @@ ia64_return_value (struct gdbarch *gdbarch, struct type *func_type,
 static int
 is_float_or_hfa_type_recurse (struct type *t, struct type **etp)
 {
-  switch (TYPE_CODE (t))
+  switch (t->code ())
     {
     case TYPE_CODE_FLT:
       if (*etp)
@@ -3113,7 +3340,7 @@ is_float_or_hfa_type_recurse (struct type *t, struct type **etp)
       {
        int i;
 
-       for (i = 0; i < TYPE_NFIELDS (t); i++)
+       for (i = 0; i < t->num_fields (); i++)
          if (!is_float_or_hfa_type_recurse
              (check_typedef (TYPE_FIELD_TYPE (t, i)), etp))
            return 0;
@@ -3147,7 +3374,7 @@ is_float_or_hfa_type (struct type *t)
 static int
 slot_alignment_is_next_even (struct type *t)
 {
-  switch (TYPE_CODE (t))
+  switch (t->code ())
     {
     case TYPE_CODE_INT:
     case TYPE_CODE_FLT:
@@ -3162,7 +3389,7 @@ slot_alignment_is_next_even (struct type *t)
       {
        int i;
 
-       for (i = 0; i < TYPE_NFIELDS (t); i++)
+       for (i = 0; i < t->num_fields (); i++)
          if (slot_alignment_is_next_even
              (check_typedef (TYPE_FIELD_TYPE (t, i))))
            return 1;
@@ -3184,8 +3411,10 @@ slot_alignment_is_next_even (struct type *t)
    d_un.d_ptr value is the global pointer.  */
 
 static CORE_ADDR
-ia64_find_global_pointer (CORE_ADDR faddr)
+ia64_find_global_pointer_from_dynamic_section (struct gdbarch *gdbarch,
+                                              CORE_ADDR faddr)
 {
+  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
   struct obj_section *faddr_sect;
      
   faddr_sect = find_pc_section (faddr);
@@ -3201,19 +3430,21 @@ ia64_find_global_pointer (CORE_ADDR faddr)
 
       if (osect < faddr_sect->objfile->sections_end)
        {
-         CORE_ADDR addr;
+         CORE_ADDR addr, endaddr;
 
-         addr = osect->addr;
-         while (addr < osect->endaddr)
+         addr = obj_section_addr (osect);
+         endaddr = obj_section_endaddr (osect);
+
+         while (addr < endaddr)
            {
              int status;
              LONGEST tag;
-             char buf[8];
+             gdb_byte buf[8];
 
              status = target_read_memory (addr, buf, sizeof (buf));
              if (status != 0)
                break;
-             tag = extract_signed_integer (buf, sizeof (buf));
+             tag = extract_signed_integer (buf, sizeof (buf), byte_order);
 
              if (tag == DT_PLTGOT)
                {
@@ -3222,9 +3453,10 @@ ia64_find_global_pointer (CORE_ADDR faddr)
                  status = target_read_memory (addr + 8, buf, sizeof (buf));
                  if (status != 0)
                    break;
-                 global_pointer = extract_unsigned_integer (buf, sizeof (buf));
+                 global_pointer = extract_unsigned_integer (buf, sizeof (buf),
+                                                            byte_order);
 
-                 /* The payoff... */
+                 /* The payoff...  */
                  return global_pointer;
                }
 
@@ -3238,12 +3470,31 @@ ia64_find_global_pointer (CORE_ADDR faddr)
   return 0;
 }
 
+/* Attempt to find (and return) the global pointer for the given
+   function.  We first try the find_global_pointer_from_solib routine
+   from the gdbarch tdep vector, if provided.  And if that does not
+   work, then we try ia64_find_global_pointer_from_dynamic_section.  */
+
+static CORE_ADDR
+ia64_find_global_pointer (struct gdbarch *gdbarch, CORE_ADDR faddr)
+{
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  CORE_ADDR addr = 0;
+
+  if (tdep->find_global_pointer_from_solib)
+    addr = tdep->find_global_pointer_from_solib (gdbarch, faddr);
+  if (addr == 0)
+    addr = ia64_find_global_pointer_from_dynamic_section (gdbarch, faddr);
+  return addr;
+}
+
 /* Given a function's address, attempt to find (and return) the
    corresponding (canonical) function descriptor.  Return 0 if
    not found.  */
 static CORE_ADDR
-find_extant_func_descr (CORE_ADDR faddr)
+find_extant_func_descr (struct gdbarch *gdbarch, CORE_ADDR faddr)
 {
+  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
   struct obj_section *faddr_sect;
 
   /* Return early if faddr is already a function descriptor.  */
@@ -3262,19 +3513,21 @@ find_extant_func_descr (CORE_ADDR faddr)
 
       if (osect < faddr_sect->objfile->sections_end)
        {
-         CORE_ADDR addr;
+         CORE_ADDR addr, endaddr;
 
-         addr = osect->addr;
-         while (addr < osect->endaddr)
+         addr = obj_section_addr (osect);
+         endaddr = obj_section_endaddr (osect);
+
+         while (addr < endaddr)
            {
              int status;
              LONGEST faddr2;
-             char buf[8];
+             gdb_byte buf[8];
 
              status = target_read_memory (addr, buf, sizeof (buf));
              if (status != 0)
                break;
-             faddr2 = extract_signed_integer (buf, sizeof (buf));
+             faddr2 = extract_signed_integer (buf, sizeof (buf), byte_order);
 
              if (faddr == faddr2)
                return addr;
@@ -3293,26 +3546,28 @@ find_extant_func_descr (CORE_ADDR faddr)
 static CORE_ADDR
 find_func_descr (struct regcache *regcache, CORE_ADDR faddr, CORE_ADDR *fdaptr)
 {
+  struct gdbarch *gdbarch = regcache->arch ();
+  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
   CORE_ADDR fdesc;
 
-  fdesc = find_extant_func_descr (faddr);
+  fdesc = find_extant_func_descr (gdbarch, faddr);
 
   if (fdesc == 0)
     {
       ULONGEST global_pointer;
-      char buf[16];
+      gdb_byte buf[16];
 
       fdesc = *fdaptr;
       *fdaptr += 16;
 
-      global_pointer = ia64_find_global_pointer (faddr);
+      global_pointer = ia64_find_global_pointer (gdbarch, faddr);
 
       if (global_pointer == 0)
        regcache_cooked_read_unsigned (regcache,
                                       IA64_GR1_REGNUM, &global_pointer);
 
-      store_unsigned_integer (buf, 8, faddr);
-      store_unsigned_integer (buf + 8, 8, global_pointer);
+      store_unsigned_integer (buf, 8, byte_order, faddr);
+      store_unsigned_integer (buf + 8, 8, byte_order, global_pointer);
 
       write_memory (fdesc, buf, 16);
     }
@@ -3327,23 +3582,41 @@ static CORE_ADDR
 ia64_convert_from_func_ptr_addr (struct gdbarch *gdbarch, CORE_ADDR addr,
                                 struct target_ops *targ)
 {
+  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
   struct obj_section *s;
+  gdb_byte buf[8];
 
   s = find_pc_section (addr);
 
   /* check if ADDR points to a function descriptor.  */
   if (s && strcmp (s->the_bfd_section->name, ".opd") == 0)
-    return read_memory_unsigned_integer (addr, 8);
+    return read_memory_unsigned_integer (addr, 8, byte_order);
+
+  /* Normally, functions live inside a section that is executable.
+     So, if ADDR points to a non-executable section, then treat it
+     as a function descriptor and return the target address iff
+     the target address itself points to a section that is executable.
+     Check first the memory of the whole length of 8 bytes is readable.  */
+  if (s && (s->the_bfd_section->flags & SEC_CODE) == 0
+      && target_read_memory (addr, buf, 8) == 0)
+    {
+      CORE_ADDR pc = extract_unsigned_integer (buf, 8, byte_order);
+      struct obj_section *pc_section = find_pc_section (pc);
+
+      if (pc_section && (pc_section->the_bfd_section->flags & SEC_CODE))
+        return pc;
+    }
 
   /* There are also descriptors embedded in vtables.  */
   if (s)
     {
-      struct minimal_symbol *minsym;
+      struct bound_minimal_symbol minsym;
 
       minsym = lookup_minimal_symbol_by_pc (addr);
 
-      if (minsym && is_vtable_name (SYMBOL_LINKAGE_NAME (minsym)))
-       return read_memory_unsigned_integer (addr, 8);
+      if (minsym.minsym
+         && is_vtable_name (minsym.minsym->linkage_name ()))
+       return read_memory_unsigned_integer (addr, 8, byte_order);
     }
 
   return addr;
@@ -3355,20 +3628,63 @@ ia64_frame_align (struct gdbarch *gdbarch, CORE_ADDR sp)
   return sp & ~0xfLL;
 }
 
+/* The default "allocate_new_rse_frame" ia64_infcall_ops routine for ia64.  */
+
+static void
+ia64_allocate_new_rse_frame (struct regcache *regcache, ULONGEST bsp, int sof)
+{
+  ULONGEST cfm, pfs, new_bsp;
+
+  regcache_cooked_read_unsigned (regcache, IA64_CFM_REGNUM, &cfm);
+
+  new_bsp = rse_address_add (bsp, sof);
+  regcache_cooked_write_unsigned (regcache, IA64_BSP_REGNUM, new_bsp);
+
+  regcache_cooked_read_unsigned (regcache, IA64_PFS_REGNUM, &pfs);
+  pfs &= 0xc000000000000000LL;
+  pfs |= (cfm & 0xffffffffffffLL);
+  regcache_cooked_write_unsigned (regcache, IA64_PFS_REGNUM, pfs);
+
+  cfm &= 0xc000000000000000LL;
+  cfm |= sof;
+  regcache_cooked_write_unsigned (regcache, IA64_CFM_REGNUM, cfm);
+}
+
+/* The default "store_argument_in_slot" ia64_infcall_ops routine for
+   ia64.  */
+
+static void
+ia64_store_argument_in_slot (struct regcache *regcache, CORE_ADDR bsp,
+                            int slotnum, gdb_byte *buf)
+{
+  write_memory (rse_address_add (bsp, slotnum), buf, 8);
+}
+
+/* The default "set_function_addr" ia64_infcall_ops routine for ia64.  */
+
+static void
+ia64_set_function_addr (struct regcache *regcache, CORE_ADDR func_addr)
+{
+  /* Nothing needed.  */
+}
+
 static CORE_ADDR
 ia64_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)
+                     function_call_return_method return_method,
+                     CORE_ADDR struct_addr)
 {
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
   int argno;
   struct value *arg;
   struct type *type;
   int len, argoffset;
   int nslots, rseslots, memslots, slotnum, nfuncargs;
   int floatreg;
-  ULONGEST bsp, cfm, pfs, new_bsp;
-  CORE_ADDR funcdescaddr, pc, global_pointer;
+  ULONGEST bsp;
+  CORE_ADDR funcdescaddr, global_pointer;
   CORE_ADDR func_addr = find_function_addr (function, NULL);
 
   nslots = 0;
@@ -3383,7 +3699,7 @@ ia64_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
       if ((nslots & 1) && slot_alignment_is_next_even (type))
        nslots++;
 
-      if (TYPE_CODE (type) == TYPE_CODE_FUNC)
+      if (type->code () == TYPE_CODE_FUNC)
        nfuncargs++;
 
       nslots += (len + 7) / 8;
@@ -3394,20 +3710,8 @@ ia64_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
   memslots = nslots - rseslots;
 
   /* Allocate a new RSE frame.  */
-  regcache_cooked_read_unsigned (regcache, IA64_CFM_REGNUM, &cfm);
-
   regcache_cooked_read_unsigned (regcache, IA64_BSP_REGNUM, &bsp);
-  new_bsp = rse_address_add (bsp, rseslots);
-  regcache_cooked_write_unsigned (regcache, IA64_BSP_REGNUM, new_bsp);
-
-  regcache_cooked_read_unsigned (regcache, IA64_PFS_REGNUM, &pfs);
-  pfs &= 0xc000000000000000LL;
-  pfs |= (cfm & 0xffffffffffffLL);
-  regcache_cooked_write_unsigned (regcache, IA64_PFS_REGNUM, pfs);
-
-  cfm &= 0xc000000000000000LL;
-  cfm |= rseslots;
-  regcache_cooked_write_unsigned (regcache, IA64_CFM_REGNUM, cfm);
+  tdep->infcall_ops.allocate_new_rse_frame (regcache, bsp, rseslots);
   
   /* We will attempt to find function descriptors in the .opd segment,
      but if we can't we'll construct them ourselves.  That being the
@@ -3436,17 +3740,19 @@ ia64_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
       len = TYPE_LENGTH (type);
 
       /* Special handling for function parameters.  */
-      if (len == 8 
-          && TYPE_CODE (type) == TYPE_CODE_PTR 
-         && TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_FUNC)
+      if (len == 8
+          && type->code () == TYPE_CODE_PTR
+          && TYPE_TARGET_TYPE (type)->code () == TYPE_CODE_FUNC)
        {
-         char val_buf[8];
-         ULONGEST faddr = extract_unsigned_integer (value_contents (arg), 8);
-         store_unsigned_integer (val_buf, 8,
+         gdb_byte val_buf[8];
+         ULONGEST faddr = extract_unsigned_integer (value_contents (arg),
+                                                    8, byte_order);
+         store_unsigned_integer (val_buf, 8, byte_order,
                                  find_func_descr (regcache, faddr,
                                                   &funcdescaddr));
          if (slotnum < rseslots)
-           write_memory (rse_address_add (bsp, slotnum), val_buf, 8);
+           tdep->infcall_ops.store_argument_in_slot (regcache, bsp,
+                                                     slotnum, val_buf);
          else
            write_memory (sp + 16 + 8 * (slotnum - rseslots), val_buf, 8);
          slotnum++;
@@ -3462,13 +3768,37 @@ ia64_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
       argoffset = 0;
       while (len > 0)
        {
-         char val_buf[8];
+         gdb_byte val_buf[8];
 
          memset (val_buf, 0, 8);
-         memcpy (val_buf, value_contents (arg) + argoffset, (len > 8) ? 8 : len);
+          if (!ia64_struct_type_p (type) && len < 8)
+            {
+              /* Integral types are LSB-aligned, so we have to be careful
+                 to insert the argument on the correct side of the buffer.
+                 This is why we use store_unsigned_integer.  */
+              store_unsigned_integer
+                (val_buf, 8, byte_order,
+                 extract_unsigned_integer (value_contents (arg), len,
+                                          byte_order));
+            }
+          else
+            {
+              /* This is either an 8bit integral type, or an aggregate.
+                 For 8bit integral type, there is no problem, we just
+                 copy the value over.
+
+                 For aggregates, the only potentially tricky portion
+                 is to write the last one if it is less than 8 bytes.
+                 In this case, the data is Byte0-aligned.  Happy news,
+                 this means that we don't need to differentiate the
+                 handling of 8byte blocks and less-than-8bytes blocks.  */
+              memcpy (val_buf, value_contents (arg) + argoffset,
+                      (len > 8) ? 8 : len);
+            }
 
          if (slotnum < rseslots)
-           write_memory (rse_address_add (bsp, slotnum), val_buf, 8);
+           tdep->infcall_ops.store_argument_in_slot (regcache, bsp,
+                                                     slotnum, val_buf);
          else
            write_memory (sp + 16 + 8 * (slotnum - rseslots), val_buf, 8);
 
@@ -3485,10 +3815,11 @@ ia64_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
          len = TYPE_LENGTH (type);
          while (len > 0 && floatreg < IA64_FR16_REGNUM)
            {
-             char to[MAX_REGISTER_SIZE];
-             convert_typed_floating (value_contents (arg) + argoffset, float_elt_type,
-                                     to, builtin_type_ia64_ext);
-             regcache_cooked_write (regcache, floatreg, (void *)to);
+             gdb_byte to[IA64_FP_REGISTER_SIZE];
+             target_float_convert (value_contents (arg) + argoffset,
+                                   float_elt_type, to,
+                                   ia64_ext_type (gdbarch));
+             regcache->cooked_write (floatreg, to);
              floatreg++;
              argoffset += TYPE_LENGTH (float_elt_type);
              len -= TYPE_LENGTH (float_elt_type);
@@ -3497,54 +3828,69 @@ ia64_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
     }
 
   /* Store the struct return value in r8 if necessary.  */
-  if (struct_return)
-    {
-      regcache_cooked_write_unsigned (regcache, IA64_GR8_REGNUM, (ULONGEST)struct_addr);
-    }
+  if (return_method == return_method_struct)
+    regcache_cooked_write_unsigned (regcache, IA64_GR8_REGNUM,
+                                   (ULONGEST) struct_addr);
 
-  global_pointer = ia64_find_global_pointer (func_addr);
+  global_pointer = ia64_find_global_pointer (gdbarch, func_addr);
 
   if (global_pointer != 0)
     regcache_cooked_write_unsigned (regcache, IA64_GR1_REGNUM, global_pointer);
 
+  /* The following is not necessary on HP-UX, because we're using
+     a dummy code sequence pushed on the stack to make the call, and
+     this sequence doesn't need b0 to be set in order for our dummy
+     breakpoint to be hit.  Nonetheless, this doesn't interfere, and
+     it's needed for other OSes, so we do this unconditionaly.  */
   regcache_cooked_write_unsigned (regcache, IA64_BR0_REGNUM, bp_addr);
 
   regcache_cooked_write_unsigned (regcache, sp_regnum, sp);
 
+  tdep->infcall_ops.set_function_addr (regcache, func_addr);
+
   return sp;
 }
 
+static const struct ia64_infcall_ops ia64_infcall_ops =
+{
+  ia64_allocate_new_rse_frame,
+  ia64_store_argument_in_slot,
+  ia64_set_function_addr
+};
+
 static struct frame_id
-ia64_unwind_dummy_id (struct gdbarch *gdbarch, struct frame_info *next_frame)
+ia64_dummy_id (struct gdbarch *gdbarch, struct frame_info *this_frame)
 {
-  char buf[8];
+  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+  gdb_byte buf[8];
   CORE_ADDR sp, bsp;
 
-  frame_unwind_register (next_frame, sp_regnum, buf);
-  sp = extract_unsigned_integer (buf, 8);
+  get_frame_register (this_frame, sp_regnum, buf);
+  sp = extract_unsigned_integer (buf, 8, byte_order);
 
-  frame_unwind_register (next_frame, IA64_BSP_REGNUM, buf);
-  bsp = extract_unsigned_integer (buf, 8);
+  get_frame_register (this_frame, IA64_BSP_REGNUM, buf);
+  bsp = extract_unsigned_integer (buf, 8, byte_order);
 
   if (gdbarch_debug >= 1)
     fprintf_unfiltered (gdb_stdlog,
-                       "dummy frame id: code 0x%s, stack 0x%s, special 0x%s\n",
-                       paddr_nz (frame_pc_unwind (next_frame)), 
-                       paddr_nz (sp), paddr_nz (bsp));
+                       "dummy frame id: code %s, stack %s, special %s\n",
+                       paddress (gdbarch, get_frame_pc (this_frame)),
+                       paddress (gdbarch, sp), paddress (gdbarch, bsp));
 
-  return frame_id_build_special (sp, frame_pc_unwind (next_frame), bsp);
+  return frame_id_build_special (sp, get_frame_pc (this_frame), bsp);
 }
 
 static CORE_ADDR 
 ia64_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
 {
-  char buf[8];
+  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+  gdb_byte buf[8];
   CORE_ADDR ip, psr, pc;
 
   frame_unwind_register (next_frame, IA64_IP_REGNUM, buf);
-  ip = extract_unsigned_integer (buf, 8);
+  ip = extract_unsigned_integer (buf, 8, byte_order);
   frame_unwind_register (next_frame, IA64_PSR_REGNUM, buf);
-  psr = extract_unsigned_integer (buf, 8);
+  psr = extract_unsigned_integer (buf, 8, byte_order);
  
   pc = (ip & ~0xf) | ((psr >> 41) & 3);
   return pc;
@@ -3554,7 +3900,15 @@ static int
 ia64_print_insn (bfd_vma memaddr, struct disassemble_info *info)
 {
   info->bytes_per_line = SLOT_MULTIPLIER;
-  return print_insn_ia64 (memaddr, info);
+  return default_print_insn (memaddr, info);
+}
+
+/* The default "size_of_register_frame" gdbarch_tdep routine for ia64.  */
+
+static int
+ia64_size_of_register_frame (struct frame_info *this_frame, ULONGEST cfm)
+{
+  return (cfm & 0x7f);
 }
 
 static struct gdbarch *
@@ -3568,11 +3922,10 @@ ia64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   if (arches != NULL)
     return arches->gdbarch;
 
-  tdep = xmalloc (sizeof (struct gdbarch_tdep));
+  tdep = XCNEW (struct gdbarch_tdep);
   gdbarch = gdbarch_alloc (&info, tdep);
 
-  tdep->sigcontext_register_address = 0;
-  tdep->pc_in_sigtramp = 0;
+  tdep->size_of_register_frame = ia64_size_of_register_frame;
 
   /* According to the ia64 specs, instructions that store long double
      floats in memory use a long-double format different than that
@@ -3594,7 +3947,8 @@ ia64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   set_gdbarch_ptr_bit (gdbarch, 64);
 
   set_gdbarch_num_regs (gdbarch, NUM_IA64_RAW_REGS);
-  set_gdbarch_num_pseudo_regs (gdbarch, LAST_PSEUDO_REGNUM - FIRST_PSEUDO_REGNUM);
+  set_gdbarch_num_pseudo_regs (gdbarch,
+                              LAST_PSEUDO_REGNUM - FIRST_PSEUDO_REGNUM);
   set_gdbarch_sp_regnum (gdbarch, sp_regnum);
   set_gdbarch_fp0_regnum (gdbarch, IA64_FR0_REGNUM);
 
@@ -3613,33 +3967,40 @@ ia64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 
   set_gdbarch_return_value (gdbarch, ia64_return_value);
 
-  set_gdbarch_memory_insert_breakpoint (gdbarch, ia64_memory_insert_breakpoint);
-  set_gdbarch_memory_remove_breakpoint (gdbarch, ia64_memory_remove_breakpoint);
+  set_gdbarch_memory_insert_breakpoint (gdbarch,
+                                       ia64_memory_insert_breakpoint);
+  set_gdbarch_memory_remove_breakpoint (gdbarch,
+                                       ia64_memory_remove_breakpoint);
   set_gdbarch_breakpoint_from_pc (gdbarch, ia64_breakpoint_from_pc);
+  set_gdbarch_breakpoint_kind_from_pc (gdbarch, ia64_breakpoint_kind_from_pc);
   set_gdbarch_read_pc (gdbarch, ia64_read_pc);
   set_gdbarch_write_pc (gdbarch, ia64_write_pc);
 
   /* Settings for calling functions in the inferior.  */
   set_gdbarch_push_dummy_call (gdbarch, ia64_push_dummy_call);
+  tdep->infcall_ops = ia64_infcall_ops;
   set_gdbarch_frame_align (gdbarch, ia64_frame_align);
-  set_gdbarch_unwind_dummy_id (gdbarch, ia64_unwind_dummy_id);
+  set_gdbarch_dummy_id (gdbarch, ia64_dummy_id);
 
   set_gdbarch_unwind_pc (gdbarch, ia64_unwind_pc);
 #ifdef HAVE_LIBUNWIND_IA64_H
-  frame_unwind_append_sniffer (gdbarch, ia64_libunwind_sigtramp_frame_sniffer);
-  frame_unwind_append_sniffer (gdbarch, ia64_libunwind_frame_sniffer);
+  frame_unwind_append_unwinder (gdbarch,
+                                &ia64_libunwind_sigtramp_frame_unwind);
+  frame_unwind_append_unwinder (gdbarch, &ia64_libunwind_frame_unwind);
+  frame_unwind_append_unwinder (gdbarch, &ia64_sigtramp_frame_unwind);
   libunwind_frame_set_descr (gdbarch, &ia64_libunwind_descr);
 #else
-  frame_unwind_append_sniffer (gdbarch, ia64_sigtramp_frame_sniffer);
+  frame_unwind_append_unwinder (gdbarch, &ia64_sigtramp_frame_unwind);
 #endif
-  frame_unwind_append_sniffer (gdbarch, ia64_frame_sniffer);
+  frame_unwind_append_unwinder (gdbarch, &ia64_frame_unwind);
   frame_base_set_default (gdbarch, &ia64_frame_base);
 
   /* Settings that should be unnecessary.  */
   set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
 
   set_gdbarch_print_insn (gdbarch, ia64_print_insn);
-  set_gdbarch_convert_from_func_ptr_addr (gdbarch, ia64_convert_from_func_ptr_addr);
+  set_gdbarch_convert_from_func_ptr_addr (gdbarch,
+                                         ia64_convert_from_func_ptr_addr);
 
   /* The virtual table contains 16-byte descriptors, not pointers to
      descriptors.  */
@@ -3651,16 +4012,9 @@ ia64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   return gdbarch;
 }
 
-extern initialize_file_ftype _initialize_ia64_tdep; /* -Wmissing-prototypes */
-
+void _initialize_ia64_tdep ();
 void
-_initialize_ia64_tdep (void)
+_initialize_ia64_tdep ()
 {
-  /* Define the ia64 floating-point format to gdb.  */
-  builtin_type_ia64_ext =
-    init_type (TYPE_CODE_FLT, 128 / 8,
-               0, "builtin_type_ia64_ext", NULL);
-  TYPE_FLOATFORMAT (builtin_type_ia64_ext) = floatformats_ia64_ext;
-
   gdbarch_register (bfd_arch_ia64, ia64_gdbarch_init, NULL);
 }
This page took 0.0717 seconds and 4 git commands to generate.