gdbtypes.resolve_dynamic_range: Add function description.
[deliverable/binutils-gdb.git] / gdb / dwarf2loc.c
index c875d3a4afa3bf43836107167c694d20a09003e5..5517442cc33e983dabbc7dacfcc575eea2b99459 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.
 
@@ -39,7 +39,7 @@
 #include "dwarf2loc.h"
 #include "dwarf2-frame.h"
 
-#include "gdb_string.h"
+#include <string.h>
 #include "gdb_assert.h"
 
 extern int dwarf2_always_disassemble;
@@ -313,17 +313,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.  */
@@ -543,7 +551,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)
@@ -557,7 +565,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);
@@ -576,23 +584,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:
@@ -688,7 +697,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));
            }
 
@@ -716,7 +725,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)));
 
 }
 
@@ -749,8 +758,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)
@@ -955,10 +965,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));
     }
 
@@ -1060,7 +1070,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);
     }
 
@@ -1073,7 +1083,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);
@@ -1089,9 +1099,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));
     }
 
@@ -1115,7 +1125,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;
@@ -1401,14 +1411,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)
@@ -1696,7 +1706,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
@@ -1880,9 +1890,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 "
@@ -2181,7 +2192,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,
@@ -2290,11 +2302,21 @@ dwarf2_evaluate_loc_desc_full (struct type *type, struct frame_info *frame,
            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
+          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;
 
@@ -2406,6 +2428,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.  */
 
@@ -2417,7 +2557,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;
 
@@ -2425,6 +2565,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)
@@ -2505,7 +2657,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,
This page took 0.028568 seconds and 4 git commands to generate.