FRV Linux: Fill 'collect_regset' in regset structures.
[deliverable/binutils-gdb.git] / gdb / dwarf2loc.c
index 9e44096f575a521e61fd6b928b80f104dfe05312..1056e5daf75f41ce11725a21acb2e66aeed1ae49 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 "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,
@@ -279,7 +274,7 @@ dwarf2_find_location_expression (struct dwarf2_loclist_baton *baton,
          /* This is entry PC record present only at entry point
             of a function.  Verify it is really the function entry point.  */
 
-         struct block *pc_block = block_for_pc (pc);
+         const struct block *pc_block = block_for_pc (pc);
          struct symbol *pc_func = NULL;
 
          if (pc_block)
@@ -315,17 +310,25 @@ 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);
-  CORE_ADDR result;
-  int regnum;
+  int regnum = gdbarch_dwarf2_reg_to_regnum (gdbarch, dwarf_regnum);
 
-  regnum = gdbarch_dwarf2_reg_to_regnum (gdbarch, dwarf_regnum);
-  result = address_from_register (builtin_type (gdbarch)->builtin_data_ptr,
-                                 regnum, debaton->frame);
-  return result;
+  return address_from_register (regnum, debaton->frame);
+}
+
+/* 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.  */
@@ -347,7 +350,7 @@ dwarf_expr_frame_base (void *baton, const gdb_byte **start, size_t * length)
      this_base method.  */
   struct symbol *framefunc;
   struct dwarf_expr_baton *debaton = (struct dwarf_expr_baton *) baton;
-  struct block *bl = get_frame_block (debaton->frame, NULL);
+  const struct block *bl = get_frame_block (debaton->frame, NULL);
 
   if (bl == NULL)
     error (_("frame address is not available."));
@@ -545,7 +548,7 @@ call_site_to_target_addr (struct gdbarch *call_site_gdbarch,
                           "at %s in %s"),
                         paddress (call_site_gdbarch, call_site->pc),
                         (msym.minsym == NULL ? "???"
-                         : SYMBOL_PRINT_NAME (msym.minsym)));
+                         : MSYMBOL_PRINT_NAME (msym.minsym)));
                        
          }
        if (caller_frame == NULL)
@@ -559,7 +562,7 @@ call_site_to_target_addr (struct gdbarch *call_site_gdbarch,
                           "available at %s in %s"),
                         paddress (call_site_gdbarch, call_site->pc),
                         (msym.minsym == NULL ? "???"
-                         : SYMBOL_PRINT_NAME (msym.minsym)));
+                         : MSYMBOL_PRINT_NAME (msym.minsym)));
                        
          }
        caller_arch = get_frame_arch (caller_frame);
@@ -578,23 +581,24 @@ call_site_to_target_addr (struct gdbarch *call_site_gdbarch,
     case FIELD_LOC_KIND_PHYSNAME:
       {
        const char *physname;
-       struct minimal_symbol *msym;
+       struct bound_minimal_symbol msym;
 
        physname = FIELD_STATIC_PHYSNAME (call_site->target);
 
        /* Handle both the mangled and demangled PHYSNAME.  */
        msym = lookup_minimal_symbol (physname, NULL, NULL);
-       if (msym == NULL)
+       if (msym.minsym == NULL)
          {
-           msym = lookup_minimal_symbol_by_pc (call_site->pc - 1).minsym;
+           msym = lookup_minimal_symbol_by_pc (call_site->pc - 1);
            throw_error (NO_ENTRY_VALUE_ERROR,
                         _("Cannot find function \"%s\" for a call site target "
                           "at %s in %s"),
                         physname, paddress (call_site_gdbarch, call_site->pc),
-                        msym == NULL ? "???" : SYMBOL_PRINT_NAME (msym));
+                        (msym.minsym == NULL ? "???"
+                         : MSYMBOL_PRINT_NAME (msym.minsym)));
                        
          }
-       return SYMBOL_VALUE_ADDRESS (msym);
+       return BMSYMBOL_VALUE_ADDRESS (msym);
       }
 
     case FIELD_LOC_KIND_PHYSADDR:
@@ -690,7 +694,7 @@ func_verify_no_selftailcall (struct gdbarch *gdbarch, CORE_ADDR verify_addr)
                             "function \"%s\" at %s can call itself via tail "
                             "calls"),
                           (msym.minsym == NULL ? "???"
-                           : SYMBOL_PRINT_NAME (msym.minsym)),
+                           : MSYMBOL_PRINT_NAME (msym.minsym)),
                           paddress (gdbarch, verify_addr));
            }
 
@@ -718,7 +722,7 @@ tailcall_dump (struct gdbarch *gdbarch, const struct call_site *call_site)
 
   fprintf_unfiltered (gdb_stdlog, " %s(%s)", paddress (gdbarch, addr),
                      (msym.minsym == NULL ? "???"
-                      : SYMBOL_PRINT_NAME (msym.minsym)));
+                      : MSYMBOL_PRINT_NAME (msym.minsym)));
 
 }
 
@@ -751,8 +755,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)
@@ -957,10 +962,10 @@ call_site_find_chain_1 (struct gdbarch *gdbarch, CORE_ADDR caller_pc,
                     "callers or callees between caller function \"%s\" at %s "
                     "and callee function \"%s\" at %s"),
                   (msym_caller.minsym == NULL
-                   ? "???" : SYMBOL_PRINT_NAME (msym_caller.minsym)),
+                   ? "???" : MSYMBOL_PRINT_NAME (msym_caller.minsym)),
                   paddress (gdbarch, caller_pc),
                   (msym_callee.minsym == NULL
-                   ? "???" : SYMBOL_PRINT_NAME (msym_callee.minsym)),
+                   ? "???" : MSYMBOL_PRINT_NAME (msym_callee.minsym)),
                   paddress (gdbarch, callee_pc));
     }
 
@@ -1062,7 +1067,7 @@ dwarf_expr_reg_to_entry_parameter (struct frame_info *frame,
                   gdbarch_bfd_arch_info (gdbarch)->printable_name,
                   paddress (gdbarch, func_addr),
                   (msym.minsym == NULL ? "???"
-                   : SYMBOL_PRINT_NAME (msym.minsym)),
+                   : MSYMBOL_PRINT_NAME (msym.minsym)),
                   gdbarch_bfd_arch_info (caller_gdbarch)->printable_name);
     }
 
@@ -1075,7 +1080,7 @@ dwarf_expr_reg_to_entry_parameter (struct frame_info *frame,
                                           "requires caller of %s (%s)"),
                   paddress (gdbarch, func_addr),
                   (msym.minsym == NULL ? "???"
-                   : SYMBOL_PRINT_NAME (msym.minsym)));
+                   : MSYMBOL_PRINT_NAME (msym.minsym)));
     }
   caller_pc = get_frame_pc (caller_frame);
   call_site = call_site_for_pc (gdbarch, caller_pc);
@@ -1091,9 +1096,9 @@ dwarf_expr_reg_to_entry_parameter (struct frame_info *frame,
                   _("DW_OP_GNU_entry_value resolving expects callee %s at %s "
                     "but the called frame is for %s at %s"),
                   (target_msym == NULL ? "???"
-                                       : SYMBOL_PRINT_NAME (target_msym)),
+                                       : MSYMBOL_PRINT_NAME (target_msym)),
                   paddress (gdbarch, target_addr),
-                  func_msym == NULL ? "???" : SYMBOL_PRINT_NAME (func_msym),
+                  func_msym == NULL ? "???" : MSYMBOL_PRINT_NAME (func_msym),
                   paddress (gdbarch, func_addr));
     }
 
@@ -1117,7 +1122,7 @@ dwarf_expr_reg_to_entry_parameter (struct frame_info *frame,
       throw_error (NO_ENTRY_VALUE_ERROR, _("Cannot find matching parameter "
                                           "at DW_TAG_GNU_call_site %s at %s"),
                   paddress (gdbarch, caller_pc),
-                  msym == NULL ? "???" : SYMBOL_PRINT_NAME (msym)); 
+                  msym == NULL ? "???" : MSYMBOL_PRINT_NAME (msym)); 
     }
 
   *per_cu_return = call_site->per_cu;
@@ -1304,7 +1309,6 @@ value_of_dwarf_reg_entry (struct type *type, struct frame_info *frame,
   struct value *outer_val, *target_val, *val;
   struct call_site_parameter *parameter;
   struct dwarf2_per_cu_data *caller_per_cu;
-  CORE_ADDR addr;
 
   parameter = dwarf_expr_reg_to_entry_parameter (frame, kind, kind_u,
                                                 &caller_per_cu);
@@ -1327,14 +1331,6 @@ value_of_dwarf_reg_entry (struct type *type, struct frame_info *frame,
                                               target_type, caller_frame,
                                               caller_per_cu);
 
-  /* value_as_address dereferences TYPE_CODE_REF.  */
-  addr = extract_typed_address (value_contents (outer_val), checked_type);
-
-  /* The target entry value has artificial address of the entry value
-     reference.  */
-  VALUE_LVAL (target_val) = lval_memory;
-  set_value_address (target_val, addr);
-
   release_value (target_val);
   val = allocate_computed_value (type, &entry_data_value_funcs,
                                 target_val /* closure */);
@@ -1403,14 +1399,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)
@@ -1641,8 +1637,6 @@ read_pieced_value (struct value *v)
          bits_to_skip -= this_size_bits;
          continue;
        }
-      if (this_size_bits > type_len - offset)
-       this_size_bits = type_len - offset;
       if (bits_to_skip > 0)
        {
          dest_offset_bits = 0;
@@ -1655,6 +1649,8 @@ read_pieced_value (struct value *v)
          dest_offset_bits = offset;
          source_offset_bits = 0;
        }
+      if (this_size_bits > type_len - offset)
+       this_size_bits = type_len - offset;
 
       this_size = (this_size_bits + source_offset_bits % 8 + 7) / 8;
       source_offset = source_offset_bits / 8;
@@ -1698,7 +1694,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 +1878,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 "
@@ -2087,8 +2084,15 @@ indirect_pieced_value (struct value *value)
 
   frame = get_selected_frame (_("No frame selected."));
 
-  /* This is an offset requested by GDB, such as value subcripts.  */
+  /* This is an offset requested by GDB, such as value subscripts.
+     However, due to how synthetic pointers are implemented, this is
+     always presented to us as a pointer type.  This means we have to
+     sign-extend it manually as appropriate.  */
   byte_offset = value_as_address (value);
+  if (TYPE_LENGTH (value_type (value)) < sizeof (LONGEST))
+    byte_offset = gdb_sign_extend (byte_offset,
+                                  8 * TYPE_LENGTH (value_type (value)));
+  byte_offset += piece->v.ptr.offset;
 
   gdb_assert (piece);
   baton
@@ -2099,7 +2103,7 @@ indirect_pieced_value (struct value *value)
   if (baton.data != NULL)
     return dwarf2_evaluate_loc_desc_full (TYPE_TARGET_TYPE (type), frame,
                                          baton.data, baton.size, baton.per_cu,
-                                         piece->v.ptr.offset + byte_offset);
+                                         byte_offset);
 
   {
     struct obstack temp_obstack;
@@ -2176,7 +2180,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,
@@ -2278,17 +2283,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;
 
@@ -2298,11 +2314,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;
 
@@ -2402,6 +2416,124 @@ dwarf2_evaluate_loc_desc (struct type *type, struct frame_info *frame,
   return dwarf2_evaluate_loc_desc_full (type, frame, data, size, per_cu, 0);
 }
 
+/* Evaluates a dwarf expression and stores the result in VAL, expecting
+   that the dwarf expression only produces a single CORE_ADDR.  ADDR is a
+   context (location of a variable) and might be needed to evaluate the
+   location expression.
+   Returns 1 on success, 0 otherwise.   */
+
+static int
+dwarf2_locexpr_baton_eval (const struct dwarf2_locexpr_baton *dlbaton,
+                          CORE_ADDR *valp)
+{
+  struct dwarf_expr_context *ctx;
+  struct dwarf_expr_baton baton;
+  struct objfile *objfile;
+  struct cleanup *cleanup;
+
+  if (dlbaton == NULL || dlbaton->size == 0)
+    return 0;
+
+  ctx = new_dwarf_expr_context ();
+  cleanup = make_cleanup_free_dwarf_expr_context (ctx);
+
+  baton.frame = get_selected_frame (NULL);
+  baton.per_cu = dlbaton->per_cu;
+
+  objfile = dwarf2_per_cu_objfile (dlbaton->per_cu);
+
+  ctx->gdbarch = get_objfile_arch (objfile);
+  ctx->addr_size = dwarf2_per_cu_addr_size (dlbaton->per_cu);
+  ctx->ref_addr_size = dwarf2_per_cu_ref_addr_size (dlbaton->per_cu);
+  ctx->offset = dwarf2_per_cu_text_offset (dlbaton->per_cu);
+  ctx->funcs = &dwarf_expr_ctx_funcs;
+  ctx->baton = &baton;
+
+  dwarf_expr_eval (ctx, dlbaton->data, dlbaton->size);
+
+  switch (ctx->location)
+    {
+    case DWARF_VALUE_REGISTER:
+    case DWARF_VALUE_MEMORY:
+    case DWARF_VALUE_STACK:
+      *valp = dwarf_expr_fetch_address (ctx, 0);
+      if (ctx->location == DWARF_VALUE_REGISTER)
+       *valp = dwarf_expr_read_addr_from_reg (&baton, *valp);
+      do_cleanups (cleanup);
+      return 1;
+    case DWARF_VALUE_LITERAL:
+      *valp = extract_signed_integer (ctx->data, ctx->len,
+                                     gdbarch_byte_order (ctx->gdbarch));
+      do_cleanups (cleanup);
+      return 1;
+      /* Unsupported dwarf values.  */
+    case DWARF_VALUE_OPTIMIZED_OUT:
+    case DWARF_VALUE_IMPLICIT_POINTER:
+      break;
+    }
+
+  do_cleanups (cleanup);
+  return 0;
+}
+
+/* See dwarf2loc.h.  */
+
+int
+dwarf2_evaluate_property (const struct dynamic_prop *prop, CORE_ADDR *value)
+{
+  if (prop == NULL)
+    return 0;
+
+  switch (prop->kind)
+    {
+    case PROP_LOCEXPR:
+      {
+       const struct dwarf2_property_baton *baton = prop->data.baton;
+
+       if (dwarf2_locexpr_baton_eval (&baton->locexpr, value))
+         {
+           if (baton->referenced_type)
+             {
+               struct value *val = value_at (baton->referenced_type, *value);
+
+               *value = value_as_address (val);
+             }
+           return 1;
+         }
+      }
+      break;
+
+    case PROP_LOCLIST:
+      {
+       struct dwarf2_property_baton *baton = prop->data.baton;
+       struct frame_info *frame = get_selected_frame (NULL);
+       CORE_ADDR pc = get_frame_address_in_block (frame);
+       const gdb_byte *data;
+       struct value *val;
+       size_t size;
+
+       data = dwarf2_find_location_expression (&baton->loclist, &size, pc);
+       if (data != NULL)
+         {
+           val = dwarf2_evaluate_loc_desc (baton->referenced_type, frame, data,
+                                           size, baton->loclist.per_cu);
+           if (!value_optimized_out (val))
+             {
+               *value = value_as_address (val);
+               return 1;
+             }
+         }
+      }
+      break;
+
+    case PROP_CONST:
+      *value = prop->data.const_val;
+      return 1;
+    }
+
+  return 0;
+}
+
 \f
 /* Helper functions and baton for dwarf2_loc_desc_needs_frame.  */
 
@@ -2413,7 +2545,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;
 
@@ -2421,6 +2553,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)
@@ -2501,7 +2645,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,
@@ -2930,7 +3075,7 @@ dwarf2_compile_expr_to_ax (struct agent_expr *expr, struct axs_value *loc,
          {
            const gdb_byte *datastart;
            size_t datalen;
-           struct block *b;
+           const struct block *b;
            struct symbol *framefunc;
 
            b = block_for_pc (expr->scope);
@@ -3385,7 +3530,7 @@ locexpr_describe_location_piece (struct symbol *symbol, struct ui_file *stream,
     }
   else if (data[0] == DW_OP_fbreg)
     {
-      struct block *b;
+      const struct block *b;
       struct symbol *framefunc;
       int frame_reg = 0;
       int64_t frame_offset;
@@ -3483,7 +3628,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;
     }
@@ -3506,7 +3651,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.031627 seconds and 4 git commands to generate.