Don't reset CXXFLAGS_FOR_TARGET
[deliverable/binutils-gdb.git] / gdb / dwarf2-frame.c
index c4f87715c1779853c5aba0c0e31ea11d66085d3c..8fb2ac77718ff3b47b06269eaf142b9c5145bcbc 100644 (file)
@@ -1,6 +1,6 @@
 /* Frame unwinder for frames with DWARF Call Frame Information.
 
-   Copyright (C) 2003-2013 Free Software Foundation, Inc.
+   Copyright (C) 2003-2015 Free Software Foundation, Inc.
 
    Contributed by Mark Kettenis.
 
 #include "objfiles.h"
 #include "regcache.h"
 #include "value.h"
-
-#include "gdb_assert.h"
-#include <string.h>
+#include "record.h"
 
 #include "complaints.h"
 #include "dwarf2-frame.h"
 #include "ax.h"
 #include "dwarf2loc.h"
-#include "exceptions.h"
 #include "dwarf2-frame-tailcall.h"
 
 struct comp_unit;
@@ -168,29 +165,34 @@ static CORE_ADDR read_encoded_value (struct comp_unit *unit, gdb_byte encoding,
                                     CORE_ADDR func_base);
 \f
 
+enum cfa_how_kind
+{
+  CFA_UNSET,
+  CFA_REG_OFFSET,
+  CFA_EXP
+};
+
+struct dwarf2_frame_state_reg_info
+{
+  struct dwarf2_frame_state_reg *reg;
+  int num_regs;
+
+  LONGEST cfa_offset;
+  ULONGEST cfa_reg;
+  enum cfa_how_kind cfa_how;
+  const gdb_byte *cfa_exp;
+
+  /* Used to implement DW_CFA_remember_state.  */
+  struct dwarf2_frame_state_reg_info *prev;
+};
+
 /* Structure describing a frame state.  */
 
 struct dwarf2_frame_state
 {
   /* Each register save state can be described in terms of a CFA slot,
      another register, or a location expression.  */
-  struct dwarf2_frame_state_reg_info
-  {
-    struct dwarf2_frame_state_reg *reg;
-    int num_regs;
-
-    LONGEST cfa_offset;
-    ULONGEST cfa_reg;
-    enum {
-      CFA_UNSET,
-      CFA_REG_OFFSET,
-      CFA_EXP
-    } cfa_how;
-    const gdb_byte *cfa_exp;
-
-    /* Used to implement DW_CFA_remember_state.  */
-    struct dwarf2_frame_state_reg_info *prev;
-  } regs;
+  struct dwarf2_frame_state_reg_info regs;
 
   /* The PC described by the current frame state.  */
   CORE_ADDR pc;
@@ -290,15 +292,9 @@ read_addr_from_reg (void *baton, int reg)
 {
   struct frame_info *this_frame = (struct frame_info *) baton;
   struct gdbarch *gdbarch = get_frame_arch (this_frame);
-  int regnum;
-  gdb_byte *buf;
-
-  regnum = gdbarch_dwarf2_reg_to_regnum (gdbarch, reg);
-
-  buf = alloca (register_size (gdbarch, regnum));
-  get_frame_register (this_frame, regnum, buf);
+  int regnum = gdbarch_dwarf2_reg_to_regnum (gdbarch, reg);
 
-  return unpack_pointer (register_type (gdbarch, regnum), buf);
+  return address_from_register (regnum, this_frame);
 }
 
 /* Implement struct dwarf_expr_context_funcs' "get_reg_value" callback.  */
@@ -518,7 +514,7 @@ execute_cfa_program (struct dwarf2_fde *fde, const gdb_byte *insn_ptr,
              {
                struct dwarf2_frame_state_reg_info *new_rs;
 
-               new_rs = XMALLOC (struct dwarf2_frame_state_reg_info);
+               new_rs = XNEW (struct dwarf2_frame_state_reg_info);
                *new_rs = fs->regs;
                fs->regs.reg = dwarf2_frame_state_copy_regs (&fs->regs);
                fs->regs.prev = new_rs;
@@ -861,13 +857,13 @@ static void
 dwarf2_frame_find_quirks (struct dwarf2_frame_state *fs,
                          struct dwarf2_fde *fde)
 {
-  struct symtab *s;
+  struct compunit_symtab *cust;
 
-  s = find_pc_symtab (fs->pc);
-  if (s == NULL)
+  cust = find_pc_compunit_symtab (fs->pc);
+  if (cust == NULL)
     return;
 
-  if (producer_is_realview (s->producer))
+  if (producer_is_realview (COMPUNIT_PRODUCER (cust)))
     {
       if (fde->cie->version == 1)
        fs->armcc_cfa_offsets_sf = 1;
@@ -882,7 +878,7 @@ dwarf2_frame_find_quirks (struct dwarf2_frame_state *fs,
         this problem is fixed (no quirk needed).  If the armcc
         augmentation is missing, the quirk is needed.  */
       if (fde->cie->version == 3
-         && (strncmp (fde->cie->augmentation, "armcc", 5) != 0
+         && (!startswith (fde->cie->augmentation, "armcc")
              || strchr (fde->cie->augmentation + 5, '+') == NULL))
        fs->armcc_cfa_offsets_reversed = 1;
 
@@ -891,11 +887,15 @@ dwarf2_frame_find_quirks (struct dwarf2_frame_state *fs,
 }
 \f
 
-void
-dwarf2_compile_cfa_to_ax (struct agent_expr *expr, struct axs_value *loc,
-                         struct gdbarch *gdbarch,
-                         CORE_ADDR pc,
-                         struct dwarf2_per_cu_data *data)
+/* See dwarf2-frame.h.  */
+
+int
+dwarf2_fetch_cfa_info (struct gdbarch *gdbarch, CORE_ADDR pc,
+                      struct dwarf2_per_cu_data *data,
+                      int *regnum_out, LONGEST *offset_out,
+                      CORE_ADDR *text_offset_out,
+                      const gdb_byte **cfa_start_out,
+                      const gdb_byte **cfa_end_out)
 {
   struct dwarf2_fde *fde;
   CORE_ADDR text_offset;
@@ -941,26 +941,20 @@ dwarf2_compile_cfa_to_ax (struct agent_expr *expr, struct axs_value *loc,
        if (regnum == -1)
          error (_("Unable to access DWARF register number %d"),
                 (int) fs.regs.cfa_reg); /* FIXME */
-       ax_reg (expr, regnum);
 
-       if (fs.regs.cfa_offset != 0)
-         {
-           if (fs.armcc_cfa_offsets_reversed)
-             ax_const_l (expr, -fs.regs.cfa_offset);
-           else
-             ax_const_l (expr, fs.regs.cfa_offset);
-           ax_simple (expr, aop_add);
-         }
+       *regnum_out = regnum;
+       if (fs.armcc_cfa_offsets_reversed)
+         *offset_out = -fs.regs.cfa_offset;
+       else
+         *offset_out = fs.regs.cfa_offset;
+       return 1;
       }
-      break;
 
     case CFA_EXP:
-      ax_const_l (expr, text_offset);
-      dwarf2_compile_expr_to_ax (expr, loc, gdbarch, addr_size,
-                                fs.regs.cfa_exp,
-                                fs.regs.cfa_exp + fs.regs.cfa_exp_len,
-                                data);
-      break;
+      *text_offset_out = text_offset;
+      *cfa_start_out = fs.regs.cfa_exp;
+      *cfa_end_out = fs.regs.cfa_exp + fs.regs.cfa_exp_len;
+      return 0;
 
     default:
       internal_error (__FILE__, __LINE__, _("Unknown CFA rule."));
@@ -1031,7 +1025,6 @@ dwarf2_frame_cache (struct frame_info *this_frame, void **this_cache)
   struct dwarf2_frame_cache *cache;
   struct dwarf2_frame_state *fs;
   struct dwarf2_fde *fde;
-  volatile struct gdb_exception ex;
   CORE_ADDR entry_pc;
   const gdb_byte *instr;
 
@@ -1045,7 +1038,7 @@ dwarf2_frame_cache (struct frame_info *this_frame, void **this_cache)
   reset_cache_cleanup = make_cleanup (clear_pointer_cleanup, this_cache);
 
   /* Allocate and initialize the frame state.  */
-  fs = XZALLOC (struct dwarf2_frame_state);
+  fs = XCNEW (struct dwarf2_frame_state);
   old_chain = make_cleanup (dwarf2_frame_state_free, fs);
 
   /* Unwind the PC.
@@ -1108,7 +1101,7 @@ dwarf2_frame_cache (struct frame_info *this_frame, void **this_cache)
   execute_cfa_program (fde, instr, fde->end, gdbarch,
                       get_frame_address_in_block (this_frame), fs);
 
-  TRY_CATCH (ex, RETURN_MASK_ERROR)
+  TRY
     {
       /* Calculate the CFA.  */
       switch (fs->regs.cfa_how)
@@ -1132,7 +1125,7 @@ dwarf2_frame_cache (struct frame_info *this_frame, void **this_cache)
          internal_error (__FILE__, __LINE__, _("Unknown CFA rule."));
        }
     }
-  if (ex.reason < 0)
+  CATCH (ex, RETURN_MASK_ERROR)
     {
       if (ex.error == NOT_AVAILABLE_ERROR)
        {
@@ -1144,6 +1137,7 @@ dwarf2_frame_cache (struct frame_info *this_frame, void **this_cache)
 
       throw_exception (ex);
     }
+  END_CATCH
 
   /* Initialize the register state.  */
   {
@@ -1275,12 +1269,11 @@ dwarf2_frame_this_id (struct frame_info *this_frame, void **this_cache,
     dwarf2_frame_cache (this_frame, this_cache);
 
   if (cache->unavailable_retaddr)
+    (*this_id) = frame_id_build_unavailable_stack (get_frame_func (this_frame));
+  else if (cache->undefined_retaddr)
     return;
-
-  if (cache->undefined_retaddr)
-    return;
-
-  (*this_id) = frame_id_build (cache->cfa, get_frame_func (this_frame));
+  else
+    (*this_id) = frame_id_build (cache->cfa, get_frame_func (this_frame));
 }
 
 static struct value *
@@ -1511,18 +1504,23 @@ dwarf2_frame_base_sniffer (struct frame_info *this_frame)
 CORE_ADDR
 dwarf2_frame_cfa (struct frame_info *this_frame)
 {
+  if (frame_unwinder_is (this_frame, &record_btrace_tailcall_frame_unwind)
+      || frame_unwinder_is (this_frame, &record_btrace_frame_unwind))
+    throw_error (NOT_AVAILABLE_ERROR,
+                _("cfa not available for record btrace target"));
+
   while (get_frame_type (this_frame) == INLINE_FRAME)
     this_frame = get_prev_frame (this_frame);
-  /* This restriction could be lifted if other unwinders are known to
-     compute the frame base in a way compatible with the DWARF
-     unwinder.  */
-  if (!frame_unwinder_is (this_frame, &dwarf2_frame_unwind)
-      && !frame_unwinder_is (this_frame, &dwarf2_tailcall_frame_unwind))
-    error (_("can't compute CFA for this frame"));
   if (get_frame_unwind_stop_reason (this_frame) == UNWIND_UNAVAILABLE)
     throw_error (NOT_AVAILABLE_ERROR,
-                _("can't compute CFA for this frame: "
-                  "required registers or memory are unavailable"));
+                _("can't compute CFA for this frame: "
+                  "required registers or memory are unavailable"));
+
+  if (get_frame_id (this_frame).stack_status != FID_STACK_VALID)
+    throw_error (NOT_AVAILABLE_ERROR,
+                _("can't compute CFA for this frame: "
+                  "frame base not available"));
+
   return get_frame_base (this_frame);
 }
 \f
@@ -1937,7 +1935,7 @@ decode_frame_entry_1 (struct comp_unit *unit, const gdb_byte *start,
 
       /* Ignore armcc augmentations.  We only use them for quirks,
         and that doesn't happen until later.  */
-      if (strncmp (augmentation, "armcc", 5) == 0)
+      if (startswith (augmentation, "armcc"))
        augmentation += strlen (augmentation);
 
       /* The GCC 2.x "eh" augmentation has a pointer immediately
@@ -2071,6 +2069,7 @@ decode_frame_entry_1 (struct comp_unit *unit, const gdb_byte *start,
     {
       /* This is a FDE.  */
       struct dwarf2_fde *fde;
+      CORE_ADDR addr;
 
       /* Check that an FDE was expected.  */
       if ((entry_type & EH_FDE_TYPE_ID) == 0)
@@ -2104,14 +2103,16 @@ decode_frame_entry_1 (struct comp_unit *unit, const gdb_byte *start,
 
       gdb_assert (fde->cie != NULL);
 
-      fde->initial_location =
-       read_encoded_value (unit, fde->cie->encoding, fde->cie->ptr_size,
-                           buf, &bytes_read, 0);
+      addr = read_encoded_value (unit, fde->cie->encoding, fde->cie->ptr_size,
+                                buf, &bytes_read, 0);
+      fde->initial_location = gdbarch_adjust_dwarf2_addr (gdbarch, addr);
       buf += bytes_read;
 
       fde->address_range =
        read_encoded_value (unit, fde->cie->encoding & 0x0f,
                            fde->cie->ptr_size, buf, &bytes_read, 0);
+      addr = gdbarch_adjust_dwarf2_addr (gdbarch, addr + fde->address_range);
+      fde->address_range = addr - fde->initial_location;
       buf += bytes_read;
 
       /* A 'z' augmentation in the CIE implies the presence of an
@@ -2268,7 +2269,6 @@ dwarf2_build_frame_info (struct objfile *objfile)
   struct dwarf2_cie_table cie_table;
   struct dwarf2_fde_table fde_table;
   struct dwarf2_fde_table *fde_table2;
-  volatile struct gdb_exception e;
 
   cie_table.num_entries = 0;
   cie_table.entries = NULL;
@@ -2310,7 +2310,7 @@ dwarf2_build_frame_info (struct objfile *objfile)
           if (txt)
             unit->tbase = txt->vma;
 
-         TRY_CATCH (e, RETURN_MASK_ERROR)
+         TRY
            {
              frame_ptr = unit->dwarf_frame_buffer;
              while (frame_ptr < unit->dwarf_frame_buffer + unit->dwarf_frame_size)
@@ -2319,7 +2319,7 @@ dwarf2_build_frame_info (struct objfile *objfile)
                                                EH_CIE_OR_FDE_TYPE_ID);
            }
 
-         if (e.reason < 0)
+         CATCH (e, RETURN_MASK_ERROR)
            {
              warning (_("skipping .eh_frame info of %s: %s"),
                       objfile_name (objfile), e.message);
@@ -2332,6 +2332,7 @@ dwarf2_build_frame_info (struct objfile *objfile)
                }
              /* The cie_table is discarded by the next if.  */
            }
+         END_CATCH
 
           if (cie_table.num_entries != 0)
             {
@@ -2351,7 +2352,7 @@ dwarf2_build_frame_info (struct objfile *objfile)
     {
       int num_old_fde_entries = fde_table.num_entries;
 
-      TRY_CATCH (e, RETURN_MASK_ERROR)
+      TRY
        {
          frame_ptr = unit->dwarf_frame_buffer;
          while (frame_ptr < unit->dwarf_frame_buffer + unit->dwarf_frame_size)
@@ -2359,7 +2360,7 @@ dwarf2_build_frame_info (struct objfile *objfile)
                                            &cie_table, &fde_table,
                                            EH_CIE_OR_FDE_TYPE_ID);
        }
-      if (e.reason < 0)
+      CATCH (e, RETURN_MASK_ERROR)
        {
          warning (_("skipping .debug_frame info of %s: %s"),
                   objfile_name (objfile), e.message);
@@ -2382,6 +2383,7 @@ dwarf2_build_frame_info (struct objfile *objfile)
          fde_table.num_entries = num_old_fde_entries;
          /* The cie_table is discarded by the next if.  */
        }
+      END_CATCH
     }
 
   /* Discard the cie_table, it is no longer needed.  */
This page took 0.031332 seconds and 4 git commands to generate.