* ia64-tdep.c: Remove commented out #define.
[deliverable/binutils-gdb.git] / gdb / ia64-tdep.c
index af4eff4064f0c630acc2587622b7fab2737d6675..aeec16939ceacae65bb52021926e510549ec64b1 100644 (file)
@@ -1,13 +1,13 @@
 /* Target-dependent code for the IA-64 for GDB, the GNU debugger.
 
-   Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
+   Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
    Free Software Foundation, Inc.
 
    This file is part of GDB.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
+   the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
 
    This program is distributed in the hope that it will be useful,
@@ -16,9 +16,7 @@
    GNU General Public License for more details.
 
    You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 51 Franklin Street, Fifth Floor,
-   Boston, MA 02110-1301, USA.  */
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include "defs.h"
 #include "inferior.h"
@@ -276,9 +274,6 @@ struct ia64_frame_cache
 
 };
 
-#define SIGCONTEXT_REGISTER_ADDRESS \
-  (gdbarch_tdep (current_gdbarch)->sigcontext_register_address)
-
 int
 ia64_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
                          struct reggroup *group)
@@ -303,7 +298,7 @@ ia64_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
 }
 
 static const char *
-ia64_register_name (int reg)
+ia64_register_name (struct gdbarch *gdbarch, int reg)
 {
   return ia64_register_names[reg];
 }
@@ -314,11 +309,11 @@ ia64_register_type (struct gdbarch *arch, int reg)
   if (reg >= IA64_FR0_REGNUM && reg <= IA64_FR127_REGNUM)
     return builtin_type_ia64_ext;
   else
-    return builtin_type_long;
+    return builtin_type (arch)->builtin_long;
 }
 
 static int
-ia64_dwarf_reg_to_regnum (int reg)
+ia64_dwarf_reg_to_regnum (struct gdbarch *gdbarch, int reg)
 {
   if (reg >= IA64_GR32_REGNUM && reg <= IA64_GR127_REGNUM)
     return V32_REGNUM + (reg - IA64_GR32_REGNUM);
@@ -334,7 +329,7 @@ floatformat_valid (const struct floatformat *fmt, const void *from)
 const struct floatformat floatformat_ia64_ext =
 {
   floatformat_little, 82, 0, 1, 17, 65535, 0x1ffff, 18, 64,
-  floatformat_intbit_yes, "floatformat_ia64_ext", floatformat_valid
+  floatformat_intbit_yes, "floatformat_ia64_ext", floatformat_valid, NULL
 };
 
 const struct floatformat *floatformats_ia64_ext[2] =
@@ -348,7 +343,7 @@ const struct floatformat *floatformats_ia64_ext[2] =
    bit ``from''.  */
 
 static long long
-extract_bit_field (char *bundle, int from, int len)
+extract_bit_field (const char *bundle, int from, int len)
 {
   long long result = 0LL;
   int to = from + len;
@@ -552,13 +547,11 @@ fetch_instruction (CORE_ADDR addr, instruction_type *it, long long *instr)
    pattern was used by the simulator that I was using.)  So I ended up
    using the pattern seen below. */
 
-#if 0
-#define IA64_BREAKPOINT 0x00002000040LL
-#endif
 #define IA64_BREAKPOINT 0x00003333300LL
 
 static int
-ia64_memory_insert_breakpoint (struct bp_target_info *bp_tgt)
+ia64_memory_insert_breakpoint (struct gdbarch *gdbarch,
+                              struct bp_target_info *bp_tgt)
 {
   CORE_ADDR addr = bp_tgt->placed_address;
   char bundle[BUNDLE_LEN];
@@ -593,7 +586,8 @@ ia64_memory_insert_breakpoint (struct bp_target_info *bp_tgt)
 }
 
 static int
-ia64_memory_remove_breakpoint (struct bp_target_info *bp_tgt)
+ia64_memory_remove_breakpoint (struct gdbarch *gdbarch,
+                              struct bp_target_info *bp_tgt)
 {
   CORE_ADDR addr = bp_tgt->placed_address;
   char bundle[BUNDLE_LEN];
@@ -601,9 +595,15 @@ ia64_memory_remove_breakpoint (struct bp_target_info *bp_tgt)
   long long instr;
   int val;
   int template;
+  struct cleanup *cleanup;
 
   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);
 
   /* Check for L type instruction in 2nd slot, if present then
@@ -619,13 +619,14 @@ ia64_memory_remove_breakpoint (struct bp_target_info *bp_tgt)
   if (val == 0)
     target_write_memory (addr, bundle, 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 (CORE_ADDR *pcptr, int *lenptr)
+ia64_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr, int *lenptr)
 {
   static unsigned char breakpoint[] =
     { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
@@ -717,10 +718,10 @@ ia64_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
            {
              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 (current_gdbarch, regnum), reg);
+             store_unsigned_integer (buf, register_size (gdbarch, regnum), reg);
            }
          else
-           store_unsigned_integer (buf, register_size (current_gdbarch, regnum), 0);
+           store_unsigned_integer (buf, register_size (gdbarch, regnum), 0);
        }
     }
   else if (IA64_NAT0_REGNUM <= regnum && regnum <= IA64_NAT31_REGNUM)
@@ -729,7 +730,7 @@ ia64_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
       ULONGEST unat;
       regcache_cooked_read_unsigned (regcache, IA64_UNAT_REGNUM, &unat);
       unatN_val = (unat & (1LL << (regnum - IA64_NAT0_REGNUM))) != 0;
-      store_unsigned_integer (buf, register_size (current_gdbarch, regnum), unatN_val);
+      store_unsigned_integer (buf, register_size (gdbarch, regnum), unatN_val);
     }
   else if (IA64_NAT32_REGNUM <= regnum && regnum <= IA64_NAT127_REGNUM)
     {
@@ -764,7 +765,7 @@ ia64_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
          natN_val = (nat_collection >> nat_bit) & 1;
        }
       
-      store_unsigned_integer (buf, register_size (current_gdbarch, regnum), natN_val);
+      store_unsigned_integer (buf, register_size (gdbarch, regnum), natN_val);
     }
   else if (regnum == VBOF_REGNUM)
     {
@@ -779,7 +780,7 @@ ia64_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
       /* 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 (current_gdbarch, regnum), vbsp);
+      store_unsigned_integer (buf, register_size (gdbarch, regnum), vbsp);
     }
   else if (VP0_REGNUM <= regnum && regnum <= VP63_REGNUM)
     {
@@ -801,10 +802,10 @@ ia64_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
                 + ((regnum - VP16_REGNUM) + rrb_pr) % 48;
        }
       prN_val = (pr & (1LL << (regnum - VP0_REGNUM))) != 0;
-      store_unsigned_integer (buf, register_size (current_gdbarch, regnum), prN_val);
+      store_unsigned_integer (buf, register_size (gdbarch, regnum), prN_val);
     }
   else
-    memset (buf, 0, register_size (current_gdbarch, regnum));
+    memset (buf, 0, register_size (gdbarch, regnum));
 }
 
 static void
@@ -831,7 +832,7 @@ ia64_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
     {
       ULONGEST unatN_val, unat, unatN_mask;
       regcache_cooked_read_unsigned (regcache, IA64_UNAT_REGNUM, &unat);
-      unatN_val = extract_unsigned_integer (buf, register_size (current_gdbarch, regnum)); 
+      unatN_val = extract_unsigned_integer (buf, register_size (gdbarch, regnum)); 
       unatN_mask = (1LL << (regnum - IA64_NAT0_REGNUM));
       if (unatN_val == 0)
        unat &= ~unatN_mask;
@@ -855,7 +856,7 @@ 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 (current_gdbarch, regnum)); 
+      natN_val = extract_unsigned_integer (buf, register_size (gdbarch, regnum)); 
 
       if (gr_addr != 0 && (natN_val == 0 || natN_val == 1))
        {
@@ -884,7 +885,7 @@ ia64_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
                nat_collection |= natN_mask;
              else
                nat_collection &= ~natN_mask;
-             store_unsigned_integer (nat_buf, register_size (current_gdbarch, regnum), nat_collection);
+             store_unsigned_integer (nat_buf, register_size (gdbarch, regnum), nat_collection);
              write_memory (nat_addr, nat_buf, 8);
            }
        }
@@ -909,7 +910,7 @@ ia64_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
          regnum = VP16_REGNUM 
                 + ((regnum - VP16_REGNUM) + rrb_pr) % 48;
        }
-      prN_val = extract_unsigned_integer (buf, register_size (current_gdbarch, regnum)); 
+      prN_val = extract_unsigned_integer (buf, register_size (gdbarch, regnum)); 
       prN_mask = (1LL << (regnum - VP0_REGNUM));
       if (prN_val == 0)
        pr &= ~prN_mask;
@@ -923,9 +924,10 @@ ia64_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
    and the special ia64 floating point register format.  */
 
 static int
-ia64_convert_register_p (int regno, struct type *type)
+ia64_convert_register_p (struct gdbarch *gdbarch, int regno, struct type *type)
 {
-  return (regno >= IA64_FR0_REGNUM && regno <= IA64_FR127_REGNUM);
+  return (regno >= IA64_FR0_REGNUM && regno <= IA64_FR127_REGNUM
+         && type != builtin_type_ia64_ext);
 }
 
 static void
@@ -969,6 +971,12 @@ refine_prologue_limit (CORE_ADDR pc, CORE_ADDR lim_pc, int *trust_limit)
 {
   struct symtab_and_line prologue_sal;
   CORE_ADDR start_pc = pc;
+  CORE_ADDR end_pc;
+
+  /* The prologue can not possibly go past the function end itself,
+     so we can already adjust LIM_PC accordingly.  */
+  if (find_pc_partial_function (pc, NULL, NULL, &end_pc) && end_pc < lim_pc)
+    lim_pc = end_pc;
 
   /* Start off not trusting the limit.  */
   *trust_limit = 0;
@@ -1050,7 +1058,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;
@@ -1101,7 +1111,7 @@ examine_prologue (CORE_ADDR pc, CORE_ADDR lim_pc, struct frame_info *next_frame,
         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 ||
+      if (!this_frame ||
          (sof == (cache->cfm & 0x7f) &&
           sol == ((cache->cfm >> 7) & 0x7f)))
        frameless = 0;
@@ -1219,9 +1229,9 @@ examine_prologue (CORE_ADDR pc, CORE_ADDR lim_pc, struct frame_info *next_frame,
              /* 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)
+             if (this_frame)
                {
-                 frame_unwind_register (next_frame, sp_regnum, buf);
+                 get_frame_register (this_frame, sp_regnum, buf);
                  saved_sp = extract_unsigned_integer (buf, 8);
                }
              spill_addr  = saved_sp
@@ -1230,7 +1240,7 @@ examine_prologue (CORE_ADDR pc, CORE_ADDR lim_pc, struct frame_info *next_frame,
              spill_reg   = rN;
              last_prologue_pc = next_pc;
            }
-         else if (qp == 0 && rM >= 32 && rM < 40 && !instores[rM] && 
+         else if (qp == 0 && rM >= 32 && rM < 40 && !instores[rM-32] && 
                   rN < 256 && imm == 0)
            {
              /* mov rN, rM where rM is an input register */
@@ -1421,10 +1431,11 @@ 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)
     {
       /* Extract the size of the rotating portion of the stack
         frame and the register rename base from the current
@@ -1463,7 +1474,7 @@ examine_prologue (CORE_ADDR pc, CORE_ADDR lim_pc, struct frame_info *next_frame,
        }
       else if (cfm_reg != 0)
        {
-         frame_unwind_register (next_frame, cfm_reg, buf);
+         get_frame_register (this_frame, cfm_reg, buf);
          cfm = extract_unsigned_integer (buf, 8);
        }
       cache->prev_cfm = cfm;
@@ -1475,8 +1486,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;
@@ -1510,7 +1522,7 @@ examine_prologue (CORE_ADDR pc, CORE_ADDR lim_pc, struct frame_info *next_frame,
 }
 
 CORE_ADDR
-ia64_skip_prologue (CORE_ADDR pc)
+ia64_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
 {
   struct ia64_frame_cache cache;
   cache.base = 0;
@@ -1526,7 +1538,7 @@ ia64_skip_prologue (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 ia64_frame_cache *cache;
   char buf[8];
@@ -1539,19 +1551,19 @@ ia64_frame_cache (struct frame_info *next_frame, void **this_cache)
   cache = ia64_alloc_frame_cache ();
   *this_cache = cache;
 
-  frame_unwind_register (next_frame, sp_regnum, buf);
+  get_frame_register (this_frame, sp_regnum, buf);
   cache->saved_sp = extract_unsigned_integer (buf, 8);
 
   /* 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);
+  get_frame_register (this_frame, IA64_BSP_REGNUM, buf);
   cache->bsp = extract_unsigned_integer (buf, 8);
   
-  frame_unwind_register (next_frame, IA64_PSR_REGNUM, buf);
+  get_frame_register (this_frame, IA64_PSR_REGNUM, buf);
   psr = extract_unsigned_integer (buf, 8);
 
-  frame_unwind_register (next_frame, IA64_CFM_REGNUM, buf);
+  get_frame_register (this_frame, IA64_CFM_REGNUM, buf);
   cfm = extract_unsigned_integer (buf, 8);
 
   cache->sof = (cfm & 0x7f);
@@ -1560,10 +1572,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;
 
@@ -1571,11 +1583,11 @@ 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 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)
@@ -1584,21 +1596,18 @@ ia64_frame_this_id (struct frame_info *next_frame, void **this_cache,
     (*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",
+                       "regular frame id: code 0x%s, stack 0x%s, special 0x%s, this_frame %p\n",
                        paddr_nz (this_id->code_addr), 
                        paddr_nz (this_id->stack_addr), 
-                       paddr_nz (cache->bsp), next_frame);
+                       paddr_nz (cache->bsp), 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 ia64_frame_cache *cache =
-    ia64_frame_cache (next_frame, this_cache);
-  char dummy_valp[MAX_REGISTER_SIZE];
+  struct gdbarch *gdbarch = get_frame_arch (this_frame);
+  struct ia64_frame_cache *cache = ia64_frame_cache (this_frame, this_cache);
   char buf[8];
 
   gdb_assert (regnum >= 0);
@@ -1606,86 +1615,63 @@ ia64_frame_prev_register (struct frame_info *next_frame, void **this_cache,
   if (!target_has_registers)
     error (_("No registers."));
 
-  *optimizedp = 0;
-  *addrp = 0;
-  *lvalp = not_lval;
-  *realnump = -1;
+  if (regnum == gdbarch_sp_regnum (gdbarch))
+    return frame_unwind_got_constant (this_frame, regnum, cache->base);
 
-  /* 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 (current_gdbarch, regnum));
-  if (regnum == gdbarch_sp_regnum (current_gdbarch))
-    {
-      /* Handle SP values for all frames but the topmost. */
-      store_unsigned_integer (valuep, register_size (current_gdbarch, 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);
       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 (current_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 (current_gdbarch, regnum));
-       }
-      else if (cache->prev_cfm)
-       store_unsigned_integer (valuep, register_size (current_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 (current_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
@@ -1693,28 +1679,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 (current_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 (current_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;
@@ -1722,8 +1704,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.  */
@@ -1731,14 +1713,15 @@ 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);
+         get_frame_register (this_frame, IA64_BSP_REGNUM, buf);
          bsp = extract_unsigned_integer (buf, 8); 
          if (nat_addr >= bsp)
            {
-             frame_unwind_register (next_frame, IA64_RNAT_REGNUM, buf);
+             get_frame_register (this_frame, IA64_RNAT_REGNUM, buf);
              nat_collection = extract_unsigned_integer (buf, 8);
            }
          else
@@ -1747,114 +1730,109 @@ ia64_frame_prev_register (struct frame_info *next_frame, void **this_cache,
          natval = (nat_collection >> nat_bit) & 1;
        }
 
-      store_unsigned_integer (valuep, register_size (current_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 (current_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);
+        }
       else if (cache->frameless)
        {
-         frame_unwind_register (next_frame, IA64_BR0_REGNUM, buf);
+         get_frame_register (this_frame, IA64_BR0_REGNUM, buf);
          pc = extract_unsigned_integer (buf, 8);
        }
       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);
+      get_frame_register (this_frame, IA64_PSR_REGNUM, buf);
       psr = extract_unsigned_integer (buf, 8);
 
       if (addr != 0)
        {
-         *lvalp = lval_memory;
-         *addrp = addr;
-         read_memory (addr, buf, register_size (current_gdbarch, IA64_IP_REGNUM));
+         read_memory (addr, buf, register_size (gdbarch, IA64_IP_REGNUM));
          pc = extract_unsigned_integer (buf, 8);
        }
       else if (cache->frameless)
        {
-         CORE_ADDR pc;
-         frame_unwind_register (next_frame, IA64_BR0_REGNUM, buf);
+         get_frame_register (this_frame, IA64_BR0_REGNUM, buf);
          pc = extract_unsigned_integer (buf, 8);
        }
       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 (current_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 (current_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);
+         reg_val = ia64_frame_prev_register (this_frame, this_cache,
+                                              IA64_BSP_REGNUM);
+         prev_bsp = extract_unsigned_integer (value_contents_all (reg_val),
+                                               8);
          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 (current_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
@@ -1870,80 +1848,68 @@ 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 (current_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,
   &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 ia64_frame_cache *cache)
+ia64_sigtramp_frame_init_saved_regs (struct frame_info *this_frame,
+                                    struct ia64_frame_cache *cache)
 {
-  if (SIGCONTEXT_REGISTER_ADDRESS)
+  struct gdbarch_tdep *tdep = gdbarch_tdep (get_frame_arch (this_frame));
+
+  if (tdep->sigcontext_register_address)
     {
       int regno;
 
       cache->saved_regs[IA64_VRAP_REGNUM] = 
-       SIGCONTEXT_REGISTER_ADDRESS (cache->base, IA64_IP_REGNUM);
+       tdep->sigcontext_register_address (cache->base, IA64_IP_REGNUM);
       cache->saved_regs[IA64_CFM_REGNUM] = 
-       SIGCONTEXT_REGISTER_ADDRESS (cache->base, IA64_CFM_REGNUM);
+       tdep->sigcontext_register_address (cache->base, IA64_CFM_REGNUM);
       cache->saved_regs[IA64_PSR_REGNUM] = 
-       SIGCONTEXT_REGISTER_ADDRESS (cache->base, IA64_PSR_REGNUM);
+       tdep->sigcontext_register_address (cache->base, IA64_PSR_REGNUM);
       cache->saved_regs[IA64_BSP_REGNUM] = 
-       SIGCONTEXT_REGISTER_ADDRESS (cache->base, IA64_BSP_REGNUM);
+       tdep->sigcontext_register_address (cache->base, IA64_BSP_REGNUM);
       cache->saved_regs[IA64_RNAT_REGNUM] = 
-       SIGCONTEXT_REGISTER_ADDRESS (cache->base, IA64_RNAT_REGNUM);
+       tdep->sigcontext_register_address (cache->base, IA64_RNAT_REGNUM);
       cache->saved_regs[IA64_CCV_REGNUM] = 
-       SIGCONTEXT_REGISTER_ADDRESS (cache->base, IA64_CCV_REGNUM);
+       tdep->sigcontext_register_address (cache->base, IA64_CCV_REGNUM);
       cache->saved_regs[IA64_UNAT_REGNUM] = 
-       SIGCONTEXT_REGISTER_ADDRESS (cache->base, IA64_UNAT_REGNUM);
+       tdep->sigcontext_register_address (cache->base, IA64_UNAT_REGNUM);
       cache->saved_regs[IA64_FPSR_REGNUM] = 
-       SIGCONTEXT_REGISTER_ADDRESS (cache->base, IA64_FPSR_REGNUM);
+       tdep->sigcontext_register_address (cache->base, IA64_FPSR_REGNUM);
       cache->saved_regs[IA64_PFS_REGNUM] = 
-       SIGCONTEXT_REGISTER_ADDRESS (cache->base, IA64_PFS_REGNUM);
+       tdep->sigcontext_register_address (cache->base, IA64_PFS_REGNUM);
       cache->saved_regs[IA64_LC_REGNUM] = 
-       SIGCONTEXT_REGISTER_ADDRESS (cache->base, IA64_LC_REGNUM);
+       tdep->sigcontext_register_address (cache->base, IA64_LC_REGNUM);
       for (regno = IA64_GR1_REGNUM; regno <= IA64_GR31_REGNUM; regno++)
        cache->saved_regs[regno] =
-         SIGCONTEXT_REGISTER_ADDRESS (cache->base, regno);
+         tdep->sigcontext_register_address (cache->base, regno);
       for (regno = IA64_BR0_REGNUM; regno <= IA64_BR7_REGNUM; regno++)
        cache->saved_regs[regno] =
-         SIGCONTEXT_REGISTER_ADDRESS (cache->base, regno);
+         tdep->sigcontext_register_address (cache->base, regno);
       for (regno = IA64_FR2_REGNUM; regno <= IA64_FR31_REGNUM; regno++)
        cache->saved_regs[regno] =
-         SIGCONTEXT_REGISTER_ADDRESS (cache->base, regno);
+         tdep->sigcontext_register_address (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 ia64_frame_cache *cache;
   CORE_ADDR addr;
@@ -1955,70 +1921,57 @@ ia64_sigtramp_frame_cache (struct frame_info *next_frame, void **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;
 
-  frame_unwind_register (next_frame, IA64_BSP_REGNUM, buf);
+  get_frame_register (this_frame, IA64_BSP_REGNUM, buf);
   cache->bsp = extract_unsigned_integer (buf, 8);
 
-  frame_unwind_register (next_frame, IA64_CFM_REGNUM, buf);
+  get_frame_register (this_frame, IA64_CFM_REGNUM, buf);
   cache->cfm = extract_unsigned_integer (buf, 8);
   cache->sof = cache->cfm & 0x7f;
 
-  ia64_sigtramp_frame_init_saved_regs (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 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",
+                       "sigtramp frame id: code 0x%s, stack 0x%s, special 0x%s, this_frame %p\n",
                        paddr_nz (this_id->code_addr), 
                        paddr_nz (this_id->stack_addr), 
-                       paddr_nz (cache->bsp), next_frame);
+                       paddr_nz (cache->bsp), 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 (this_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 (current_gdbarch, regnum));
   if (regnum == IA64_IP_REGNUM)
     {
       CORE_ADDR pc = 0;
@@ -2026,81 +1979,70 @@ ia64_sigtramp_frame_prev_register (struct frame_info *next_frame,
 
       if (addr != 0)
        {
-         *lvalp = lval_memory;
-         *addrp = addr;
-         read_memory (addr, buf, register_size (current_gdbarch, IA64_IP_REGNUM));
+         read_memory (addr, buf, register_size (gdbarch, IA64_IP_REGNUM));
          pc = extract_unsigned_integer (buf, 8);
        }
       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 (current_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 (current_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,
+  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;
 }
@@ -2219,7 +2161,7 @@ ia64_access_reg (unw_addr_space_t as, unw_regnum_t uw_regnum, unw_word_t *val,
 {
   int regnum = ia64_uw2gdb_regnum (uw_regnum);
   unw_word_t bsp, sof, sol, cfm, psr, ip;
-  struct frame_info *next_frame = arg;
+  struct frame_info *this_frame = arg;
   long new_sof, old_sof;
   char buf[MAX_REGISTER_SIZE];
   
@@ -2231,9 +2173,9 @@ 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);
+       get_frame_register (this_frame, IA64_IP_REGNUM, buf);
        ip = extract_unsigned_integer (buf, 8); 
-       frame_unwind_register (next_frame, IA64_PSR_REGNUM, buf);
+       get_frame_register (this_frame, IA64_PSR_REGNUM, buf);
        psr = extract_unsigned_integer (buf, 8); 
        *val = ip | ((psr >> 41) & 0x3);
        break;
@@ -2242,9 +2184,9 @@ ia64_access_reg (unw_addr_space_t as, unw_regnum_t uw_regnum, unw_word_t *val,
        /* 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);
+       get_frame_register (this_frame, IA64_BSP_REGNUM, buf);
        bsp = extract_unsigned_integer (buf, 8);
-       frame_unwind_register (next_frame, IA64_CFM_REGNUM, buf);
+       get_frame_register (this_frame, IA64_CFM_REGNUM, buf);
        cfm = extract_unsigned_integer (buf, 8); 
        sof = (cfm & 0x7f);
        *val = ia64_rse_skip_regs (bsp, -sof);
@@ -2253,13 +2195,13 @@ ia64_access_reg (unw_addr_space_t as, unw_regnum_t uw_regnum, unw_word_t *val,
       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);
+       get_frame_register (this_frame, IA64_BSP_REGNUM, buf);
        *val = extract_unsigned_integer (buf, 8);
        break;
 
       default:
        /* For all other registers, just unwind the value directly.  */
-       frame_unwind_register (next_frame, regnum, buf);
+       get_frame_register (this_frame, regnum, buf);
        *val = extract_unsigned_integer (buf, 8); 
        break;
     }
@@ -2279,12 +2221,12 @@ 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 = 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, (char *) val);
 
   return 0;
 }
@@ -2451,7 +2393,7 @@ get_kernel_table (unw_word_t ip, unw_dyn_info_t *di)
                        "segbase=0x%s, length=%s, gp=0x%s\n",
                        (char *) di->u.ti.name_ptr, 
                        paddr_nz (di->u.ti.segbase), 
-                       paddr_u (di->u.ti.table_len), 
+                       pulongest (di->u.ti.table_len), 
                        paddr_nz (di->gp));
   return 0;
 }
@@ -2560,7 +2502,7 @@ ia64_find_proc_info_x (unw_addr_space_t as, unw_word_t ip, unw_proc_info_t *pi,
                            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), 
+                           pulongest (di.u.ti.table_len), 
                            paddr_nz ((CORE_ADDR)di.u.ti.table_data));
     }
   else
@@ -2577,7 +2519,7 @@ ia64_find_proc_info_x (unw_addr_space_t as, unw_word_t ip, unw_proc_info_t *pi,
                            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), 
+                           pulongest (di.u.rti.table_len), 
                            paddr_nz (di.u.rti.table_data));
     }
 
@@ -2618,7 +2560,7 @@ ia64_get_dyn_info_list (unw_addr_space_t as,
       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)
        {
@@ -2646,18 +2588,15 @@ 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)
 {
+  struct frame_id id;
   char 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);
+  libunwind_frame_this_id (this_frame, this_cache, &id);
   if (frame_id_eq (id, null_frame_id))
     {
       (*this_id) = null_frame_id;
@@ -2666,36 +2605,25 @@ ia64_libunwind_frame_this_id (struct frame_info *next_frame, void **this_cache,
 
   /* We must add the bsp as the special address for frame comparison 
      purposes.  */
-  frame_unwind_register (next_frame, IA64_BSP_REGNUM, buf);
+  get_frame_register (this_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;
+  (*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",
+                       "libunwind frame id: code 0x%s, stack 0x%s, special 0x%s, this_frame %p\n",
                        paddr_nz (id.code_addr), paddr_nz (id.stack_addr), 
-                       paddr_nz (bsp), next_frame);
+                       paddr_nz (bsp), 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);
+  struct value *val;
 
   if (VP0_REGNUM <= regnum && regnum <= VP63_REGNUM)
     reg = IA64_PR_REGNUM;
@@ -2703,12 +2631,7 @@ ia64_libunwind_frame_prev_register (struct frame_info *next_frame,
     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)
     {
@@ -2722,61 +2645,59 @@ ia64_libunwind_frame_prev_register (struct frame_info *next_frame,
 
          /* Fetch predicate register rename base from current frame
             marker for this frame.  */
-         frame_unwind_register (next_frame, IA64_CFM_REGNUM, buf);
+         get_frame_register (this_frame, IA64_CFM_REGNUM, buf);
          cfm = extract_unsigned_integer (buf, 8); 
          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 (current_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 (current_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);
+      cfm_val = libunwind_frame_prev_register (this_frame, this_cache,
+                                               IA64_CFM_REGNUM);
+      prev_cfm = extract_unsigned_integer (value_contents_all (cfm_val), 8);
       prev_bsp = rse_address_add (prev_bsp, (prev_cfm & 0x7f));
 
-      store_unsigned_integer (valuep, register_size (current_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 =
@@ -2785,22 +2706,13 @@ static const struct frame_unwind ia64_libunwind_frame_unwind =
   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];
@@ -2808,7 +2720,7 @@ ia64_libunwind_sigtramp_frame_this_id (struct frame_info *next_frame, void **thi
   struct frame_id id;
   CORE_ADDR prev_ip;
 
-  libunwind_frame_this_id (next_frame, this_cache, &id);
+  libunwind_frame_this_id (this_frame, this_cache, &id);
   if (frame_id_eq (id, null_frame_id))
     {
       (*this_id) = null_frame_id;
@@ -2817,7 +2729,7 @@ ia64_libunwind_sigtramp_frame_this_id (struct frame_info *next_frame, void **thi
 
   /* We must add the bsp as the special address for frame comparison 
      purposes.  */
-  frame_unwind_register (next_frame, IA64_BSP_REGNUM, buf);
+  get_frame_register (this_frame, IA64_BSP_REGNUM, buf);
   bsp = extract_unsigned_integer (buf, 8);
 
   /* For a sigtramp frame, we don't make the check for previous ip being 0.  */
@@ -2825,62 +2737,58 @@ ia64_libunwind_sigtramp_frame_this_id (struct frame_info *next_frame, void **thi
 
   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",
+                       "libunwind sigtramp frame id: code 0x%s, stack 0x%s, special 0x%s, this_frame %p\n",
                        paddr_nz (id.code_addr), paddr_nz (id.stack_addr), 
-                       paddr_nz (bsp), next_frame);
+                       paddr_nz (bsp), 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 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);
 
   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,
+  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 =
 {
@@ -2922,14 +2830,18 @@ static struct libunwind_descr ia64_libunwind_descr =
 
 #endif /* HAVE_LIBUNWIND_IA64_H  */
 
-/* Should we use DEPRECATED_EXTRACT_STRUCT_VALUE_ADDRESS instead of
-   gdbarch_extract_return_value?  GCC_P is true if compiled with gcc and TYPE
-   is the type (which is known to be struct, union or array).  */
-int
-ia64_use_struct_convention (int gcc_p, struct type *type)
+static int
+ia64_use_struct_convention (struct type *type)
 {
   struct type *float_elt_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))
+    return 0;
+
   /* HFAs are structures (or arrays) consisting entirely of floating
      point values of the same length.  Up to 8 of these are returned
      in registers.  Don't use the struct convention when this is the
@@ -2944,7 +2856,7 @@ ia64_use_struct_convention (int gcc_p, struct type *type)
   return TYPE_LENGTH (type) > 32;
 }
 
-void
+static void
 ia64_extract_return_value (struct type *type, struct regcache *regcache,
                           gdb_byte *valbuf)
 {
@@ -2994,6 +2906,80 @@ ia64_extract_return_value (struct type *type, struct regcache *regcache,
     }
 }
 
+static void
+ia64_store_return_value (struct type *type, struct regcache *regcache, 
+                        const gdb_byte *valbuf)
+{
+  struct type *float_elt_type;
+
+  float_elt_type = is_float_or_hfa_type (type);
+  if (float_elt_type != NULL)
+    {
+      char to[MAX_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);
+         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 n = TYPE_LENGTH (type) / reglen;
+      int m = TYPE_LENGTH (type) % reglen;
+
+      while (n-- > 0)
+       {
+         ULONGEST val;
+         memcpy (&val, (char *)valbuf + offset, reglen);
+         regcache_cooked_write_unsigned (regcache, regnum, val);
+         offset += reglen;
+         regnum++;
+       }
+
+      if (m)
+       {
+         memcpy (&val, (char *)valbuf + offset, m);
+          regcache_cooked_write_unsigned (regcache, regnum, val);
+       }
+    }
+}
+  
+static enum return_value_convention
+ia64_return_value (struct gdbarch *gdbarch, struct type *func_type,
+                  struct type *valtype, struct regcache *regcache,
+                  gdb_byte *readbuf, const gdb_byte *writebuf)
+{
+  int struct_return = ia64_use_struct_convention (valtype);
+
+  if (writebuf != NULL)
+    {
+      gdb_assert (!struct_return);
+      ia64_store_return_value (valtype, regcache, writebuf);
+    }
+
+  if (readbuf != NULL)
+    {
+      gdb_assert (!struct_return);
+      ia64_extract_return_value (valtype, regcache, readbuf);
+    }
+
+  if (struct_return)
+    return RETURN_VALUE_STRUCT_CONVENTION;
+  else
+    return RETURN_VALUE_REGISTER_CONVENTION;
+}
 
 static int
 is_float_or_hfa_type_recurse (struct type *t, struct type **etp)
@@ -3106,10 +3092,12 @@ ia64_find_global_pointer (CORE_ADDR faddr)
 
       if (osect < faddr_sect->objfile->sections_end)
        {
-         CORE_ADDR addr;
+         CORE_ADDR addr, endaddr;
+
+         addr = obj_section_addr (osect);
+         endaddr = obj_section_endaddr (osect);
 
-         addr = osect->addr;
-         while (addr < osect->endaddr)
+         while (addr < endaddr)
            {
              int status;
              LONGEST tag;
@@ -3167,10 +3155,12 @@ 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;
@@ -3240,6 +3230,19 @@ ia64_convert_from_func_ptr_addr (struct gdbarch *gdbarch, CORE_ADDR addr,
   if (s && strcmp (s->the_bfd_section->name, ".opd") == 0)
     return read_memory_unsigned_integer (addr, 8);
 
+  /* 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.  */
+  if (s && (s->the_bfd_section->flags & SEC_CODE) == 0)
+    {
+      CORE_ADDR pc = read_memory_unsigned_integer (addr, 8);
+      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)
     {
@@ -3420,24 +3423,24 @@ ia64_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
 }
 
 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];
   CORE_ADDR sp, bsp;
 
-  frame_unwind_register (next_frame, sp_regnum, buf);
+  get_frame_register (this_frame, sp_regnum, buf);
   sp = extract_unsigned_integer (buf, 8);
 
-  frame_unwind_register (next_frame, IA64_BSP_REGNUM, buf);
+  get_frame_register (this_frame, IA64_BSP_REGNUM, buf);
   bsp = extract_unsigned_integer (buf, 8);
 
   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 (get_frame_pc (this_frame)),
                        paddr_nz (sp), paddr_nz (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 
@@ -3455,21 +3458,6 @@ ia64_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
   return pc;
 }
 
-static void
-ia64_store_return_value (struct type *type, struct regcache *regcache, 
-                       const gdb_byte *valbuf)
-{
-  if (TYPE_CODE (type) == TYPE_CODE_FLT)
-    {
-      char to[MAX_REGISTER_SIZE];
-      convert_typed_floating (valbuf, type, to, builtin_type_ia64_ext);
-      regcache_cooked_write (regcache, IA64_FR8_REGNUM, (void *)to);
-      target_store_registers (regcache, IA64_FR8_REGNUM);
-    }
-  else
-    regcache_cooked_write (regcache, IA64_GR8_REGNUM, valbuf);
-}
-
 static int
 ia64_print_insn (bfd_vma memaddr, struct disassemble_info *info)
 {
@@ -3494,12 +3482,6 @@ ia64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   tdep->sigcontext_register_address = 0;
   tdep->pc_in_sigtramp = 0;
 
-  /* 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;
-
   /* According to the ia64 specs, instructions that store long double
      floats in memory use a long-double format different than that
      used in the floating registers.  The memory format matches the
@@ -3525,9 +3507,6 @@ ia64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   set_gdbarch_fp0_regnum (gdbarch, IA64_FR0_REGNUM);
 
   set_gdbarch_register_name (gdbarch, ia64_register_name);
-  /* FIXME:  Following interface should not be needed, however, without it recurse.exp
-     gets a number of extra failures.  */
-  set_gdbarch_deprecated_register_size (gdbarch, 8);
   set_gdbarch_register_type (gdbarch, ia64_register_type);
 
   set_gdbarch_pseudo_register_read (gdbarch, ia64_pseudo_register_read);
@@ -3540,10 +3519,7 @@ ia64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 
   set_gdbarch_skip_prologue (gdbarch, ia64_skip_prologue);
 
-  set_gdbarch_deprecated_use_struct_convention (gdbarch, ia64_use_struct_convention);
-  set_gdbarch_extract_return_value (gdbarch, ia64_extract_return_value);
-
-  set_gdbarch_store_return_value (gdbarch, ia64_store_return_value);
+  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);
@@ -3554,17 +3530,19 @@ ia64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   /* Settings for calling functions in the inferior.  */
   set_gdbarch_push_dummy_call (gdbarch, ia64_push_dummy_call);
   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.  */
@@ -3588,5 +3566,11 @@ extern initialize_file_ftype _initialize_ia64_tdep; /* -Wmissing-prototypes */
 void
 _initialize_ia64_tdep (void)
 {
+  /* 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.049854 seconds and 4 git commands to generate.