* dwarf2-frame.h: Update copyrigh year.
authorMark Kettenis <kettenis@gnu.org>
Fri, 25 Mar 2005 16:51:40 +0000 (16:51 +0000)
committerMark Kettenis <kettenis@gnu.org>
Fri, 25 Mar 2005 16:51:40 +0000 (16:51 +0000)
(enum dwarf2_frame_reg_rule): Add DWARF2_FRAME_REG_RA_OFFSET.
* dwarf2-frame.c: Update copyright year.
(struct dwarf2_frame_cache): Add member `retaddr_reg'.
(dwarf2_frame_cache): Deal with DWARF2_FRAME_REG_RA_OFFSET.
(dwarf2_frame_prev_register): Handle DWARF2_FRAME_REG_RA_OFFSET.

gdb/ChangeLog
gdb/dwarf2-frame.c
gdb/dwarf2-frame.h

index 920928f62c3d7f56b5734d23d6b3df0bf7b2d9cd..03d511504aac7becac4cb318fbf9ccef82ca6e62 100644 (file)
@@ -1,3 +1,12 @@
+2005-03-25  Mark Kettenis  <kettenis@gnu.org>
+
+       * dwarf2-frame.h: Update copyrigh year.
+       (enum dwarf2_frame_reg_rule): Add DWARF2_FRAME_REG_RA_OFFSET.
+       * dwarf2-frame.c: Update copyright year.
+       (struct dwarf2_frame_cache): Add member `retaddr_reg'.
+       (dwarf2_frame_cache): Deal with DWARF2_FRAME_REG_RA_OFFSET.
+       (dwarf2_frame_prev_register): Handle DWARF2_FRAME_REG_RA_OFFSET.
+
 2005-03-23  Martin Hunt  <hunt@redhat.com>
 
        * configure.ac: Remove -fwritable-strings from CFLAGS.
index cedeaa1f547f42cb3e90106299a763b3321c8714..7b46c78dbaaee59754e78b42b9b078f401956133 100644 (file)
@@ -1,6 +1,6 @@
 /* Frame unwinder for frames with DWARF Call Frame Information.
 
-   Copyright 2003, 2004 Free Software Foundation, Inc.
+   Copyright 2003, 2004, 2005 Free Software Foundation, Inc.
 
    Contributed by Mark Kettenis.
 
@@ -588,6 +588,9 @@ struct dwarf2_frame_cache
   /* Saved registers, indexed by GDB register number, not by DWARF
      register number.  */
   struct dwarf2_frame_state_reg *reg;
+
+  /* Return address register.  */
+  struct dwarf2_frame_state_reg retaddr_reg;
 };
 
 static struct dwarf2_frame_cache *
@@ -717,13 +720,15 @@ incomplete CFI data; unspecified registers (e.g., %s) at 0x%s"),
       }
   }
 
-  /* Eliminate any DWARF2_FRAME_REG_RA rules.  */
+  /* Eliminate any DWARF2_FRAME_REG_RA rules, and save the information
+     we need for evaluating DWARF2_FRAME_REG_RA_OFFSET rules.  */
   {
     int regnum;
 
     for (regnum = 0; regnum < num_regs; regnum++)
       {
-       if (cache->reg[regnum].how == DWARF2_FRAME_REG_RA)
+       if (cache->reg[regnum].how == DWARF2_FRAME_REG_RA
+           || cache->reg[regnum].how == DWARF2_FRAME_REG_RA_OFFSET)
          {
            struct dwarf2_frame_state_reg *retaddr_reg =
              &fs->regs.reg[fs->retaddr_column];
@@ -733,16 +738,29 @@ incomplete CFI data; unspecified registers (e.g., %s) at 0x%s"),
                what GCC does on some targets.  It turns out that GCC
                assumes that the return address can be found in the
                register corresponding to the return address column.
-               Incidentally, that's how should treat a return address
-               column specifying "same value" too.  */
+               Incidentally, that's how we should treat a return
+               address column specifying "same value" too.  */
            if (fs->retaddr_column < fs->regs.num_regs
                && retaddr_reg->how != DWARF2_FRAME_REG_UNSPECIFIED
                && retaddr_reg->how != DWARF2_FRAME_REG_SAME_VALUE)
-             cache->reg[regnum] = *retaddr_reg;
+             {
+               if (cache->reg[regnum].how == DWARF2_FRAME_REG_RA)
+                 cache->reg[regnum] = *retaddr_reg;
+               else
+                 cache->retaddr_reg = *retaddr_reg;
+             }
            else
              {
-               cache->reg[regnum].loc.reg = fs->retaddr_column;
-               cache->reg[regnum].how = DWARF2_FRAME_REG_SAVED_REG;
+               if (cache->reg[regnum].how == DWARF2_FRAME_REG_RA)
+                 {
+                   cache->reg[regnum].loc.reg = fs->retaddr_column;
+                   cache->reg[regnum].how = DWARF2_FRAME_REG_SAVED_REG;
+                 }
+               else
+                 {
+                   cache->retaddr_reg.loc.reg = fs->retaddr_column;
+                   cache->retaddr_reg.how = DWARF2_FRAME_REG_SAVED_REG;
+                 }
              }
          }
       }
@@ -864,6 +882,21 @@ dwarf2_frame_prev_register (struct frame_info *next_frame, void **this_cache,
        }
       break;
 
+    case DWARF2_FRAME_REG_RA_OFFSET:
+      *optimizedp = 0;
+      *lvalp = not_lval;
+      *addrp = 0;
+      *realnump = -1;
+      if (valuep)
+        {
+          CORE_ADDR pc = cache->reg[regnum].loc.offset;
+
+          regnum = DWARF2_REG_TO_REGNUM (cache->retaddr_reg.loc.reg);
+          pc += frame_unwind_register_unsigned (next_frame, regnum);
+          store_typed_address (valuep, builtin_type_void_func_ptr, pc);
+        }
+      break;
+
     default:
       internal_error (__FILE__, __LINE__, _("Unknown register rule."));
     }
index 5191c0e8d497eab835a009d5992440611dc9480d..7f951e7c6da3581f9b825c7b83e2606c657fd7e9 100644 (file)
@@ -1,6 +1,6 @@
 /* Frame unwinder for frames with DWARF Call Frame Information.
 
-   Copyright 2003, 2004 Free Software Foundation, Inc.
+   Copyright 2003, 2004, 2005 Free Software Foundation, Inc.
 
    Contributed by Mark Kettenis.
 
@@ -54,6 +54,7 @@ enum dwarf2_frame_reg_rule
   /* These aren't defined by the DWARF2 CFI specification, but are
      used internally by GDB.  */
   DWARF2_FRAME_REG_RA,         /* Return Address.  */
+  DWARF2_FRAME_REG_RA_OFFSET,  /* Return Address with offset.  */
   DWARF2_FRAME_REG_CFA         /* Call Frame Address.  */
 };