change delegation for to_read_description
[deliverable/binutils-gdb.git] / gdb / dwarf2loc.c
index bb600d1243ca8bbb4f704078bd650134634b6adf..99a18a95ed68844e160a2e262ed3cbd861e5bea3 100644 (file)
@@ -1,6 +1,6 @@
 /* DWARF 2 location expression support for GDB.
 
-   Copyright (C) 2003-2013 Free Software Foundation, Inc.
+   Copyright (C) 2003-2014 Free Software Foundation, Inc.
 
    Contributed by Daniel Jacobowitz, MontaVista Software, Inc.
 
 #include "dwarf2loc.h"
 #include "dwarf2-frame.h"
 
-#include "gdb_string.h"
+#include <string.h>
 #include "gdb_assert.h"
 
-DEF_VEC_I(int);
-
 extern int dwarf2_always_disassemble;
 
 static void dwarf_expr_frame_base_1 (struct symbol *framefunc, CORE_ADDR pc,
@@ -315,7 +313,7 @@ struct dwarf_expr_baton
 /* Using the frame specified in BATON, return the value of register
    REGNUM, treated as a pointer.  */
 static CORE_ADDR
-dwarf_expr_read_reg (void *baton, int dwarf_regnum)
+dwarf_expr_read_addr_from_reg (void *baton, int dwarf_regnum)
 {
   struct dwarf_expr_baton *debaton = (struct dwarf_expr_baton *) baton;
   struct gdbarch *gdbarch = get_frame_arch (debaton->frame);
@@ -328,6 +326,18 @@ dwarf_expr_read_reg (void *baton, int dwarf_regnum)
   return result;
 }
 
+/* Implement struct dwarf_expr_context_funcs' "get_reg_value" callback.  */
+
+static struct value *
+dwarf_expr_get_reg_value (void *baton, struct type *type, int dwarf_regnum)
+{
+  struct dwarf_expr_baton *debaton = (struct dwarf_expr_baton *) baton;
+  struct gdbarch *gdbarch = get_frame_arch (debaton->frame);
+  int regnum = gdbarch_dwarf2_reg_to_regnum (gdbarch, dwarf_regnum);
+
+  return value_from_register (type, regnum, debaton->frame);
+}
+
 /* Read memory at ADDR (length LEN) into BUF.  */
 
 static void
@@ -751,8 +761,9 @@ chain_candidate (struct gdbarch *gdbarch, struct call_site_chain **resultp,
                                           * (length - 1));
       result->length = length;
       result->callers = result->callees = length;
-      memcpy (result->call_site, VEC_address (call_sitep, chain),
-             sizeof (*result->call_site) * length);
+      if (!VEC_empty (call_sitep, chain))
+       memcpy (result->call_site, VEC_address (call_sitep, chain),
+               sizeof (*result->call_site) * length);
       *resultp = result;
 
       if (entry_values_debug)
@@ -1403,14 +1414,14 @@ allocate_piece_closure (struct dwarf2_per_cu_data *per_cu,
                        int n_pieces, struct dwarf_expr_piece *pieces,
                        int addr_size)
 {
-  struct piece_closure *c = XZALLOC (struct piece_closure);
+  struct piece_closure *c = XCNEW (struct piece_closure);
   int i;
 
   c->refc = 1;
   c->per_cu = per_cu;
   c->n_pieces = n_pieces;
   c->addr_size = addr_size;
-  c->pieces = XCALLOC (n_pieces, struct dwarf_expr_piece);
+  c->pieces = XCNEWVEC (struct dwarf_expr_piece, n_pieces);
 
   memcpy (c->pieces, pieces, n_pieces * sizeof (struct dwarf_expr_piece));
   for (i = 0; i < n_pieces; ++i)
@@ -1698,7 +1709,7 @@ read_pieced_value (struct value *v)
                    if (optim)
                      set_value_optimized_out (v, 1);
                    if (unavail)
-                     mark_value_bytes_unavailable (v, offset, this_size);
+                     mark_value_bits_unavailable (v, offset, this_size_bits);
                  }
              }
            else
@@ -1882,9 +1893,10 @@ write_pieced_value (struct value *to, struct value *from)
                                                   &optim, &unavail))
                      {
                        if (optim)
-                         error (_("Can't do read-modify-write to "
-                                  "update bitfield; containing word has been "
-                                  "optimized out"));
+                         throw_error (OPTIMIZED_OUT_ERROR,
+                                      _("Can't do read-modify-write to "
+                                        "update bitfield; containing word "
+                                        "has been optimized out"));
                        if (unavail)
                          throw_error (NOT_AVAILABLE_ERROR,
                                       _("Can't do read-modify-write to update "
@@ -2183,7 +2195,8 @@ static const struct lval_funcs pieced_value_funcs = {
 
 static const struct dwarf_expr_context_funcs dwarf_expr_ctx_funcs =
 {
-  dwarf_expr_read_reg,
+  dwarf_expr_read_addr_from_reg,
+  dwarf_expr_get_reg_value,
   dwarf_expr_read_mem,
   dwarf_expr_frame_base,
   dwarf_expr_frame_cfa,
@@ -2285,17 +2298,28 @@ dwarf2_evaluate_loc_desc_full (struct type *type, struct frame_info *frame,
        case DWARF_VALUE_REGISTER:
          {
            struct gdbarch *arch = get_frame_arch (frame);
-           ULONGEST dwarf_regnum = value_as_long (dwarf_expr_fetch (ctx, 0));
+           int dwarf_regnum
+             = longest_to_int (value_as_long (dwarf_expr_fetch (ctx, 0)));
            int gdb_regnum = gdbarch_dwarf2_reg_to_regnum (arch, dwarf_regnum);
 
            if (byte_offset != 0)
              error (_("cannot use offset on synthetic pointer to register"));
            do_cleanups (value_chain);
-           if (gdb_regnum != -1)
-             retval = value_from_register (type, gdb_regnum, frame);
-           else
-             error (_("Unable to access DWARF register number %s"),
-                    paddress (arch, dwarf_regnum));
+          if (gdb_regnum == -1)
+             error (_("Unable to access DWARF register number %d"),
+                    dwarf_regnum);
+          retval = value_from_register (type, gdb_regnum, frame);
+          if (value_optimized_out (retval))
+            {
+              /* This means the register has undefined value / was
+                 not saved.  As we're computing the location of some
+                 variable etc. in the program, not a value for
+                 inspecting a register ($pc, $sp, etc.), return a
+                 generic optimized out value instead, so that we show
+                 <optimized out> instead of <not saved>.  */
+              do_cleanups (value_chain);
+              retval = allocate_optimized_out_value (type);
+            }
          }
          break;
 
@@ -2305,11 +2329,9 @@ dwarf2_evaluate_loc_desc_full (struct type *type, struct frame_info *frame,
            int in_stack_memory = dwarf_expr_fetch_in_stack_memory (ctx, 0);
 
            do_cleanups (value_chain);
-           retval = allocate_value_lazy (type);
-           VALUE_LVAL (retval) = lval_memory;
+           retval = value_at_lazy (type, address + byte_offset);
            if (in_stack_memory)
              set_value_stack (retval, 1);
-           set_value_address (retval, address + byte_offset);
          }
          break;
 
@@ -2420,7 +2442,7 @@ struct needs_frame_baton
 
 /* Reads from registers do require a frame.  */
 static CORE_ADDR
-needs_frame_read_reg (void *baton, int regnum)
+needs_frame_read_addr_from_reg (void *baton, int regnum)
 {
   struct needs_frame_baton *nf_baton = baton;
 
@@ -2428,6 +2450,18 @@ needs_frame_read_reg (void *baton, int regnum)
   return 1;
 }
 
+/* struct dwarf_expr_context_funcs' "get_reg_value" callback:
+   Reads from registers do require a frame.  */
+
+static struct value *
+needs_frame_get_reg_value (void *baton, struct type *type, int regnum)
+{
+  struct needs_frame_baton *nf_baton = baton;
+
+  nf_baton->needs_frame = 1;
+  return value_zero (type, not_lval);
+}
+
 /* Reads from memory do not require a frame.  */
 static void
 needs_frame_read_mem (void *baton, gdb_byte *buf, CORE_ADDR addr, size_t len)
@@ -2508,7 +2542,8 @@ needs_get_addr_index (void *baton, unsigned int index)
 
 static const struct dwarf_expr_context_funcs needs_frame_ctx_funcs =
 {
-  needs_frame_read_reg,
+  needs_frame_read_addr_from_reg,
+  needs_frame_get_reg_value,
   needs_frame_read_mem,
   needs_frame_frame_base,
   needs_frame_frame_cfa,
@@ -3490,7 +3525,7 @@ locexpr_describe_location_piece (struct symbol *symbol, struct ui_file *stream,
       fprintf_filtered (stream, 
                        _("a thread-local variable at offset 0x%s "
                          "in the thread-local storage for `%s'"),
-                       phex_nz (offset, addr_size), objfile->name);
+                       phex_nz (offset, addr_size), objfile_name (objfile));
 
       data += 1 + addr_size + 1;
     }
@@ -3513,7 +3548,7 @@ locexpr_describe_location_piece (struct symbol *symbol, struct ui_file *stream,
       fprintf_filtered (stream, 
                        _("a thread-local variable at offset 0x%s "
                          "in the thread-local storage for `%s'"),
-                       phex_nz (offset, addr_size), objfile->name);
+                       phex_nz (offset, addr_size), objfile_name (objfile));
       ++data;
     }
 
This page took 0.027633 seconds and 4 git commands to generate.