* frame-unwind.c (frame_unwind_got_bytes): New function.
authorJoel Brobecker <brobecker@gnat.com>
Tue, 6 May 2008 18:37:46 +0000 (18:37 +0000)
committerJoel Brobecker <brobecker@gnat.com>
Tue, 6 May 2008 18:37:46 +0000 (18:37 +0000)
        * frame-unwind.h (frame_unwind_got_bytes): Add declaration.
        * libunwind-frame.h, libunwind-frame.c, ia64-tdep.c: Update
        for unwinder changes.

gdb/ChangeLog
gdb/frame-unwind.c
gdb/frame-unwind.h
gdb/ia64-tdep.c
gdb/libunwind-frame.c
gdb/libunwind-frame.h

index 7120c0a..87950a4 100644 (file)
@@ -1,3 +1,10 @@
+2008-05-06  Joel Brobecker  <brobecker@adacore.com>
+
+       * frame-unwind.c (frame_unwind_got_bytes): New function.
+       * frame-unwind.h (frame_unwind_got_bytes): Add declaration.
+       * libunwind-frame.h, libunwind-frame.c, ia64-tdep.c: Update
+       for unwinder changes.
+
 2008-05-05  Doug Evans  <dje@google.com>
 
        * NEWS: Mention new /m modifier for disassemble command.
index 7384259..cb79f4c 100644 (file)
@@ -170,6 +170,17 @@ frame_unwind_got_constant (struct frame_info *frame, int regnum,
   return reg_val;
 }
 
+struct value *
+frame_unwind_got_bytes (struct frame_info *frame, int regnum, gdb_byte *buf)
+{
+  struct gdbarch *gdbarch = get_frame_arch (frame);
+  struct value *reg_val;
+
+  reg_val = value_zero (register_type (gdbarch, regnum), not_lval);
+  memcpy (value_contents_raw (reg_val), buf, register_size (gdbarch, regnum));
+  return reg_val;
+}
+
 /* Return a value which indicates that FRAME's saved version of REGNUM
    has a known constant (computed) value of ADDR.  Convert the
    CORE_ADDR to a target address if necessary.  */
index 3a35aa1..bd45fa9 100644 (file)
@@ -183,6 +183,13 @@ struct value *frame_unwind_got_memory (struct frame_info *frame, int regnum,
 struct value *frame_unwind_got_constant (struct frame_info *frame, int regnum,
                                         ULONGEST val);
 
+/* Return a value which indicates that FRAME's saved version of
+   REGNUM has a known constant (computed) value which is stored
+   inside BUF.  */
+
+struct value *frame_unwind_got_bytes (struct frame_info *frame, int regnum,
+                                      gdb_byte *buf);
+
 /* Return a value which indicates that FRAME's saved version of REGNUM
    has a known constant (computed) value of ADDR.  Convert the
    CORE_ADDR to a target address if necessary.  */
index ebde4dc..499213a 100644 (file)
@@ -343,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;
@@ -1061,7 +1061,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;
@@ -1112,7 +1114,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;
@@ -1230,9 +1232,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
@@ -1432,10 +1434,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
@@ -1474,7 +1477,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;
@@ -1486,8 +1489,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;
@@ -1537,7 +1541,7 @@ 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 ia64_frame_cache *cache;
   char buf[8];
@@ -1550,19 +1554,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);
@@ -1571,10 +1575,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,11 +1586,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)
@@ -1595,22 +1599,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 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];
+  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);
@@ -1618,86 +1618,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;
-
-  /* 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);
       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 +1682,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 +1707,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,14 +1716,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
@@ -1759,114 +1733,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 (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);
+        }
       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 (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 (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);
+         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 (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,44 +1851,29 @@ 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,
   &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_tdep *tdep = gdbarch_tdep (get_frame_arch (this_frame));
 
   if (tdep->sigcontext_register_address)
     {
@@ -1958,7 +1912,7 @@ ia64_sigtramp_frame_init_saved_regs (struct frame_info *next_frame,
 }
 
 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;
@@ -1970,71 +1924,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 (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 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 (next_frame);
+  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 (gdbarch, regnum));
   if (regnum == IA64_IP_REGNUM)
     {
       CORE_ADDR pc = 0;
@@ -2042,81 +1982,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 (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 (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,
+  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;
 }
@@ -2235,7 +2164,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];
   
@@ -2247,9 +2176,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;
@@ -2258,9 +2187,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);
@@ -2269,13 +2198,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;
     }
@@ -2295,12 +2224,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;
 }
@@ -2662,18 +2591,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;
@@ -2682,50 +2608,33 @@ 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;
 
-  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)
     {
@@ -2739,61 +2648,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 (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);
+      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 (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 =
@@ -2802,21 +2709,13 @@ static const struct frame_unwind ia64_libunwind_frame_unwind =
   ia64_libunwind_frame_this_id,
   ia64_libunwind_frame_prev_register,
   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];
@@ -2824,7 +2723,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;
@@ -2833,7 +2732,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.  */
@@ -2841,62 +2740,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 =
 {
@@ -3514,24 +3409,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 (frame_pc_unwind (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 
@@ -3621,17 +3516,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.  */
index 223c3c0..d580b51 100644 (file)
@@ -66,9 +66,9 @@ struct libunwind_frame_cache
   unw_addr_space_t as;
 };
 
-/* We need to qualify the function names with a platform-specific prefix to match 
-   the names used by the libunwind library.  The UNW_OBJ macro is provided by the
-   libunwind.h header file.  */
+/* We need to qualify the function names with a platform-specific prefix
+   to match the names used by the libunwind library.  The UNW_OBJ macro is
+   provided by the libunwind.h header file.  */
 #define STRINGIFY2(name)       #name
 #define STRINGIFY(name)                STRINGIFY2(name)
 
@@ -128,7 +128,7 @@ libunwind_frame_set_descr (struct gdbarch *gdbarch, struct libunwind_descr *desc
 }
 
 static struct libunwind_frame_cache *
-libunwind_frame_cache (struct frame_info *next_frame, void **this_cache)
+libunwind_frame_cache (struct frame_info *this_frame, void **this_cache)
 {
   unw_accessors_t *acc;
   unw_addr_space_t as;
@@ -136,7 +136,7 @@ libunwind_frame_cache (struct frame_info *next_frame, void **this_cache)
   unw_regnum_t uw_sp_regnum;
   struct libunwind_frame_cache *cache;
   struct libunwind_descr *descr;
-  struct gdbarch *gdbarch = get_frame_arch (next_frame);
+  struct gdbarch *gdbarch = get_frame_arch (this_frame);
   int i, ret;
 
   if (*this_cache)
@@ -148,20 +148,23 @@ libunwind_frame_cache (struct frame_info *next_frame, void **this_cache)
   /* We can assume we are unwinding a normal frame.  Even if this is
      for a signal trampoline, ia64 signal "trampolines" use a normal
      subroutine call to start the signal handler.  */
-  cache->func_addr = frame_func_unwind (next_frame, NORMAL_FRAME);
+  cache->func_addr = get_frame_func (this_frame);
   if (cache->func_addr == 0
-      && frame_relative_level (next_frame) > 0
-      && get_frame_type (next_frame) != SIGTRAMP_FRAME)
+      && get_next_frame (this_frame)
+      && get_frame_type (get_next_frame (this_frame)) == NORMAL_FRAME)
     return NULL;
 
-  /* Get a libunwind cursor to the previous frame.  We do this by initializing
-     a cursor.  Libunwind treats a new cursor as the top of stack and will get
-     the current register set via the libunwind register accessor.  Now, we
-     provide the platform-specific accessors and we set up the register accessor to use
-     the frame register unwinding interfaces so that we properly get the registers for
-     the current frame rather than the top.  We then use the  unw_step function to 
-     move the libunwind cursor back one frame.  We can later use this cursor to find previous 
-     registers via the unw_get_reg interface which will invoke libunwind's special logic.  */
+  /* Get a libunwind cursor to the previous frame.
+  
+     We do this by initializing a cursor.  Libunwind treats a new cursor
+     as the top of stack and will get the current register set via the
+     libunwind register accessor.  Now, we provide the platform-specific
+     accessors and we set up the register accessor to use the frame
+     register unwinding interfaces so that we properly get the registers
+     for the current frame rather than the top.  We then use the unw_step
+     function to move the libunwind cursor back one frame.  We can later
+     use this cursor to find previous registers via the unw_get_reg
+     interface which will invoke libunwind's special logic.  */
   descr = libunwind_descr (gdbarch);
   acc = descr->accessors;
   as =  unw_create_addr_space_p (acc,
@@ -170,7 +173,7 @@ libunwind_frame_cache (struct frame_info *next_frame, void **this_cache)
                                 ? __BIG_ENDIAN
                                 : __LITTLE_ENDIAN);
 
-  unw_init_remote_p (&cache->cursor, as, next_frame);
+  unw_init_remote_p (&cache->cursor, as, this_frame);
   if (unw_step_p (&cache->cursor) < 0)
     {
       unw_destroy_addr_space_p (as);
@@ -213,26 +216,28 @@ static const struct frame_unwind libunwind_frame_unwind =
   libunwind_frame_this_id,
   libunwind_frame_prev_register,
   NULL,
-  NULL,
-  libunwind_frame_dealloc_cache
+  libunwind_frame_sniffer,
+  libunwind_frame_dealloc_cache,
 };
 
 /* Verify if there is sufficient libunwind information for the frame to use
    libunwind frame unwinding.  */
-const struct frame_unwind *
-libunwind_frame_sniffer (struct frame_info *next_frame)
+int
+libunwind_frame_sniffer (const struct frame_unwind *self,
+                         struct frame_info *this_frame, void **this_cache)
 {
   unw_cursor_t cursor;
   unw_accessors_t *acc;
   unw_addr_space_t as;
   struct libunwind_descr *descr;
-  struct gdbarch *gdbarch = get_frame_arch (next_frame);
+  struct gdbarch *gdbarch = get_frame_arch (this_frame);
   int i, ret;
 
-  /* To test for libunwind unwind support, initialize a cursor to the current frame and try to back
-     up.  We use this same method when setting up the frame cache (see libunwind_frame_cache()).
-     If libunwind returns success for this operation, it means that it has found sufficient
-     libunwind unwinding information to do so.  */
+  /* To test for libunwind unwind support, initialize a cursor to
+     the current frame and try to back up.  We use this same method
+     when setting up the frame cache (see libunwind_frame_cache()).
+     If libunwind returns success for this operation, it means that
+     it has found sufficient libunwind unwinding information to do so.  */
 
   descr = libunwind_descr (gdbarch);
   acc = descr->accessors;
@@ -242,12 +247,12 @@ libunwind_frame_sniffer (struct frame_info *next_frame)
                                 ? __BIG_ENDIAN
                                 : __LITTLE_ENDIAN);
 
-  ret = unw_init_remote_p (&cursor, as, next_frame);
+  ret = unw_init_remote_p (&cursor, as, this_frame);
 
   if (ret < 0)
     {
       unw_destroy_addr_space_p (as);
-      return NULL;
+      return 0;
     }
 
  
@@ -258,17 +263,17 @@ libunwind_frame_sniffer (struct frame_info *next_frame)
   unw_destroy_addr_space_p (as);
 
   if (ret < 0)
-    return NULL;
+    return 0;
 
-  return &libunwind_frame_unwind;
+  return 1;
 }
 
 void
-libunwind_frame_this_id (struct frame_info *next_frame, void **this_cache,
-                     struct frame_id *this_id)
+libunwind_frame_this_id (struct frame_info *this_frame, void **this_cache,
+                        struct frame_id *this_id)
 {
   struct libunwind_frame_cache *cache =
-    libunwind_frame_cache (next_frame, this_cache);
+    libunwind_frame_cache (this_frame, this_cache);
 
   if (cache != NULL)
     (*this_id) = frame_id_build (cache->base, cache->func_addr);
@@ -276,15 +281,13 @@ libunwind_frame_this_id (struct frame_info *next_frame, void **this_cache,
     (*this_id) = null_frame_id;
 }
 
-void
-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)
+struct value *
+libunwind_frame_prev_register (struct frame_info *this_frame,
+                               void **this_cache, int regnum)
 {
   struct libunwind_frame_cache *cache =
-    libunwind_frame_cache (next_frame, this_cache);
-  struct gdbarch *gdbarch = get_frame_arch (next_frame);
+    libunwind_frame_cache (this_frame, this_cache);
+  struct gdbarch *gdbarch = get_frame_arch (this_frame);
 
   void *ptr;
   unw_cursor_t *c;
@@ -294,12 +297,13 @@ libunwind_frame_prev_register (struct frame_info *next_frame, void **this_cache,
   unw_fpreg_t fpval;
   unw_regnum_t uw_regnum;
   struct libunwind_descr *descr;
+  struct value *val = NULL;
 
   if (cache == NULL)
-    return;
+    return frame_unwind_got_constant (this_frame, regnum, 0);
   
   /* Convert from gdb register number to libunwind register number.  */
-  descr = libunwind_descr (get_frame_arch (next_frame));
+  descr = libunwind_descr (get_frame_arch (this_frame));
   uw_regnum = descr->gdb2uw (regnum);
 
   gdb_assert (regnum >= 0);
@@ -307,63 +311,55 @@ libunwind_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 (valuep)
-    memset (valuep, 0, register_size (gdbarch, regnum));
-
   if (uw_regnum < 0)
-    return;
-
-  /* To get the previous register, we use the libunwind register APIs with
-     the cursor we have already pushed back to the previous frame.  */
-
-  if (descr->is_fpreg (uw_regnum))
-    {
-      ret = unw_get_fpreg_p (&cache->cursor, uw_regnum, &fpval);
-      ptr = &fpval;
-    }
-  else
-    {
-      ret = unw_get_reg_p (&cache->cursor, uw_regnum, &intval);
-      ptr = &intval;
-    }
-
-  if (ret < 0)
-    return;
-
-  if (valuep)
-    memcpy (valuep, ptr, register_size (gdbarch, regnum));
+    return frame_unwind_got_constant (this_frame, regnum, 0);
 
   if (unw_get_saveloc_p (&cache->cursor, uw_regnum, &sl) < 0)
-    return;
+    return frame_unwind_got_constant (this_frame, regnum, 0);
 
   switch (sl.type)
     {
-    case UNW_SLT_NONE:
-      *optimizedp = 1;
-      break;
-
     case UNW_SLT_MEMORY:
-      *lvalp = lval_memory;
-      *addrp = sl.u.addr;
+      val = frame_unwind_got_memory (this_frame, regnum, sl.u.addr);
       break;
 
     case UNW_SLT_REG:
-      *lvalp = lval_register;
-      *realnump = regnum;
+      val = frame_unwind_got_register (this_frame, regnum,
+                                       descr->uw2gdb (sl.u.regnum));
       break;
+    case UNW_SLT_NONE:
+      {
+        /* The register is not stored at a specific memory address nor
+           inside another register.  So use libunwind to fetch the register
+           value for us, and create a constant value with the result.  */
+        if (descr->is_fpreg (uw_regnum))
+          {
+            ret = unw_get_fpreg_p (&cache->cursor, uw_regnum, &fpval);
+            if (ret < 0)
+              return frame_unwind_got_constant (this_frame, regnum, 0);
+            val = frame_unwind_got_bytes (this_frame, regnum,
+                                          (gdb_byte *) &fpval);
+          }
+        else
+          {
+            ret = unw_get_reg_p (&cache->cursor, uw_regnum, &intval);
+            if (ret < 0)
+              return frame_unwind_got_constant (this_frame, regnum, 0);
+            val = frame_unwind_got_constant (this_frame, regnum, intval);
+          }
+        set_value_optimized_out (val, 1);
+        break;
+      }
     }
+
+  return val;
 } 
 
 CORE_ADDR
-libunwind_frame_base_address (struct frame_info *next_frame, void **this_cache)
+libunwind_frame_base_address (struct frame_info *this_frame, void **this_cache)
 {
   struct libunwind_frame_cache *cache =
-    libunwind_frame_cache (next_frame, this_cache);
+    libunwind_frame_cache (this_frame, this_cache);
 
   if (cache == NULL)
     return (CORE_ADDR)NULL;
@@ -381,14 +377,16 @@ libunwind_search_unwind_table (void *as, long ip, void *di,
 }
 
 /* Verify if we are in a sigtramp frame and we can use libunwind to unwind.  */
-const struct frame_unwind *
-libunwind_sigtramp_frame_sniffer (struct frame_info *next_frame)
+int
+libunwind_sigtramp_frame_sniffer (const struct frame_unwind *self,
+                                  struct frame_info *this_frame,
+                                  void **this_cache)
 {
   unw_cursor_t cursor;
   unw_accessors_t *acc;
   unw_addr_space_t as;
   struct libunwind_descr *descr;
-  struct gdbarch *gdbarch = get_frame_arch (next_frame);
+  struct gdbarch *gdbarch = get_frame_arch (this_frame);
   int i, ret;
 
   /* To test for libunwind unwind support, initialize a cursor to the
@@ -406,21 +404,21 @@ libunwind_sigtramp_frame_sniffer (struct frame_info *next_frame)
                                 ? __BIG_ENDIAN
                                 : __LITTLE_ENDIAN);
 
-  ret = unw_init_remote_p (&cursor, as, next_frame);
+  ret = unw_init_remote_p (&cursor, as, this_frame);
 
   if (ret < 0)
     {
       unw_destroy_addr_space_p (as);
-      return NULL;
+      return 0;
     }
 
   /* Check to see if we are in a signal frame.  */
   ret = unw_is_signal_frame_p (&cursor);
   unw_destroy_addr_space_p (as);
   if (ret > 0)
-    return &libunwind_frame_unwind;
+    return 1;
 
-  return NULL;
+  return 0;
 }
 
 /* The following routine is for accessing special registers of the top frame.
index b6b1159..876b92b 100644 (file)
@@ -40,19 +40,23 @@ struct libunwind_descr
   void *special_accessors;
 };
 
-const struct frame_unwind *libunwind_frame_sniffer (struct frame_info *next_frame);
-const struct frame_unwind *libunwind_sigtramp_frame_sniffer (struct frame_info *next_frame);
+int libunwind_frame_sniffer (const struct frame_unwind *self,
+                             struct frame_info *this_frame,
+                             void **this_cache);
+                          
+int libunwind_sigtramp_frame_sniffer (const struct frame_unwind *self,
+                                      struct frame_info *this_frame,
+                                      void **this_cache);
 
 void libunwind_frame_set_descr (struct gdbarch *arch, struct libunwind_descr *descr);
 
-void libunwind_frame_this_id (struct frame_info *next_frame, void **this_cache,
+void libunwind_frame_this_id (struct frame_info *this_frame, void **this_cache,
                              struct frame_id *this_id);
-void 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);
+struct value *libunwind_frame_prev_register (struct frame_info *this_frame,
+                                             void **this_cache, int regnum);
 void libunwind_frame_dealloc_cache (struct frame_info *self, void *cache);
-CORE_ADDR libunwind_frame_base_address (struct frame_info *next_frame, void **this_cache);
+CORE_ADDR libunwind_frame_base_address (struct frame_info *this_frame,
+                                        void **this_cache);
 
 int libunwind_is_initialized (void);