* configure.ac: Use AC_CHECK_DECLS instead of gcc_AC_CHECK_DECLS
[deliverable/binutils-gdb.git] / gdb / dwarf2-frame.c
index 39722cc1bc0a3b3786241966ce50954f90d45070..fc0ac8b709eb996f759a7efcb096d668b47824af 100644 (file)
@@ -162,7 +162,7 @@ dwarf2_frame_state_alloc_regs (struct dwarf2_frame_state_reg_info *rs,
 static struct dwarf2_frame_state_reg *
 dwarf2_frame_state_copy_regs (struct dwarf2_frame_state_reg_info *rs)
 {
-  size_t size = rs->num_regs * sizeof (struct dwarf2_frame_state_reg_info);
+  size_t size = rs->num_regs * sizeof (struct dwarf2_frame_state_reg);
   struct dwarf2_frame_state_reg *reg;
 
   reg = (struct dwarf2_frame_state_reg *) xmalloc (size);
@@ -471,6 +471,10 @@ struct dwarf2_frame_ops
 {
   /* Pre-initialize the register state REG for register REGNUM.  */
   void (*init_reg) (struct gdbarch *, int, struct dwarf2_frame_state_reg *);
+
+  /* Check whether the frame preceding NEXT_FRAME will be a signal
+     trampoline.  */
+  int (*signal_frame_p) (struct gdbarch *, struct frame_info *);
 };
 
 /* Default architecture-specific register state initialization
@@ -547,6 +551,33 @@ dwarf2_frame_init_reg (struct gdbarch *gdbarch, int regnum,
 
   ops->init_reg (gdbarch, regnum, reg);
 }
+
+/* Set the architecture-specific signal trampoline recognition
+   function for GDBARCH to SIGNAL_FRAME_P.  */
+
+void
+dwarf2_frame_set_signal_frame_p (struct gdbarch *gdbarch,
+                                int (*signal_frame_p) (struct gdbarch *,
+                                                       struct frame_info *))
+{
+  struct dwarf2_frame_ops *ops = gdbarch_data (gdbarch, dwarf2_frame_data);
+
+  ops->signal_frame_p = signal_frame_p;
+}
+
+/* Query the architecture-specific signal frame recognizer for
+   NEXT_FRAME.  */
+
+static int
+dwarf2_frame_signal_frame_p (struct gdbarch *gdbarch,
+                            struct frame_info *next_frame)
+{
+  struct dwarf2_frame_ops *ops = gdbarch_data (gdbarch, dwarf2_frame_data);
+
+  if (ops->signal_frame_p == NULL)
+    return 0;
+  return ops->signal_frame_p (gdbarch, next_frame);
+}
 \f
 
 struct dwarf2_frame_cache
@@ -674,9 +705,13 @@ dwarf2_frame_cache (struct frame_info *next_frame, void **this_cache)
           table.  We need a way of iterating through all the valid
           DWARF2 register numbers.  */
        if (fs->regs.reg[column].how == DWARF2_FRAME_REG_UNSPECIFIED)
-         complaint (&symfile_complaints,
-                    "Incomplete CFI data; unspecified registers at 0x%s",
-                    paddr (fs->pc));
+         {
+           if (cache->reg[regnum].how == DWARF2_FRAME_REG_UNSPECIFIED)
+             complaint (&symfile_complaints, "\
+incomplete CFI data; unspecified registers (e.g., %s) at 0x%s",
+                        gdbarch_register_name (gdbarch, regnum),
+                        paddr_nz (fs->pc));
+         }
        else
          cache->reg[regnum] = fs->regs.reg[column];
       }
@@ -841,6 +876,13 @@ static const struct frame_unwind dwarf2_frame_unwind =
   dwarf2_frame_prev_register
 };
 
+static const struct frame_unwind dwarf2_signal_frame_unwind =
+{
+  SIGTRAMP_FRAME,
+  dwarf2_frame_this_id,
+  dwarf2_frame_prev_register
+};
+
 const struct frame_unwind *
 dwarf2_frame_sniffer (struct frame_info *next_frame)
 {
@@ -848,10 +890,18 @@ dwarf2_frame_sniffer (struct frame_info *next_frame)
      function.  frame_pc_unwind(), for a no-return next function, can
      end up returning something past the end of this function's body.  */
   CORE_ADDR block_addr = frame_unwind_address_in_block (next_frame);
-  if (dwarf2_frame_find_fde (&block_addr))
-    return &dwarf2_frame_unwind;
+  if (!dwarf2_frame_find_fde (&block_addr))
+    return NULL;
 
-  return NULL;
+  /* On some targets, signal trampolines may have unwind information.
+     We need to recognize them so that we set the frame type
+     correctly.  */
+
+  if (dwarf2_frame_signal_frame_p (get_frame_arch (next_frame),
+                                  next_frame))
+    return &dwarf2_signal_frame_unwind;
+
+  return &dwarf2_frame_unwind;
 }
 \f
 
@@ -1126,7 +1176,7 @@ read_encoded_value (struct comp_unit *unit, unsigned char encoding,
       {
        ULONGEST value;
        unsigned char *end_buf = buf + (sizeof (value) + 1) * 8 / 7;
-       *bytes_read_ptr = read_uleb128 (buf, end_buf, &value) - buf;
+       *bytes_read_ptr += read_uleb128 (buf, end_buf, &value) - buf;
        return base + value;
       }
     case DW_EH_PE_udata2:
@@ -1142,7 +1192,7 @@ read_encoded_value (struct comp_unit *unit, unsigned char encoding,
       {
        LONGEST value;
        char *end_buf = buf + (sizeof (value) + 1) * 8 / 7;
-       *bytes_read_ptr = read_sleb128 (buf, end_buf, &value) - buf;
+       *bytes_read_ptr += read_sleb128 (buf, end_buf, &value) - buf;
        return base + value;
       }
     case DW_EH_PE_sdata2:
@@ -1380,8 +1430,8 @@ decode_frame_entry_1 (struct comp_unit *unit, char *start, int eh_frame_p)
          /* "P" indicates a personality routine in the CIE augmentation.  */
          else if (*augmentation == 'P')
            {
-             /* Skip.  */
-             unsigned char encoding = *buf++;
+             /* Skip.  Avoid indirection since we throw away the result.  */
+             unsigned char encoding = (*buf++) & ~DW_EH_PE_indirect;
              read_encoded_value (unit, encoding, buf, &bytes_read);
              buf += bytes_read;
              augmentation++;
This page took 0.02479 seconds and 4 git commands to generate.