Add dwarf2_per_objfile to dwarf_expr_context and dwarf2_frame_cache
[deliverable/binutils-gdb.git] / gdb / dwarf2 / loc.c
index ecd83ec4b9c38320785c4cf66767a738936b4374..964726e862581e5974405684177c4b3c7b479f6d 100644 (file)
@@ -317,8 +317,9 @@ const gdb_byte *
 dwarf2_find_location_expression (struct dwarf2_loclist_baton *baton,
                                 size_t *locexpr_length, CORE_ADDR pc)
 {
-  struct objfile *objfile = baton->per_cu->objfile ();
-  struct gdbarch *gdbarch = get_objfile_arch (objfile);
+  dwarf2_per_objfile *per_objfile = baton->per_objfile;
+  struct objfile *objfile = per_objfile->objfile;
+  struct gdbarch *gdbarch = objfile->arch ();
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
   unsigned int addr_size = baton->per_cu->addr_size ();
   int signed_addr_p = bfd_get_sign_extend_vma (objfile->obfd);
@@ -605,8 +606,8 @@ sect_variable_value (struct dwarf_expr_context *ctx, sect_offset sect_off,
 
   /* Note: Things still work when the following test is removed.  This
      test and error is here to conform to the proposed specification.  */
-  if (TYPE_CODE (die_type) != TYPE_CODE_INT
-      && TYPE_CODE (die_type) != TYPE_CODE_PTR)
+  if (die_type->code () != TYPE_CODE_INT
+      && die_type->code () != TYPE_CODE_PTR)
     error (_("Type of DW_OP_GNU_variable_value DIE must be an integer or pointer."));
 
   struct type *type = lookup_pointer_type (die_type);
@@ -616,7 +617,10 @@ sect_variable_value (struct dwarf_expr_context *ctx, sect_offset sect_off,
 
 class dwarf_evaluate_loc_desc : public dwarf_expr_context
 {
- public:
+public:
+  dwarf_evaluate_loc_desc (dwarf2_per_objfile *per_objfile)
+    : dwarf_expr_context (per_objfile)
+  {}
 
   struct frame_info *frame;
   struct dwarf2_per_cu_data *per_cu;
@@ -729,11 +733,9 @@ class dwarf_evaluate_loc_desc : public dwarf_expr_context
                                                        (CORE_ADDR) 0);
 
     scoped_restore save_arch = make_scoped_restore (&this->gdbarch);
-    this->gdbarch = get_objfile_arch (per_cu->objfile ());
+    this->gdbarch = per_cu->objfile ()->arch ();
     scoped_restore save_addr_size = make_scoped_restore (&this->addr_size);
     this->addr_size = per_cu->addr_size ();
-    scoped_restore save_offset = make_scoped_restore (&this->offset);
-    this->offset = per_cu->text_offset ();
 
     this->eval (data_src, size);
   }
@@ -915,7 +917,7 @@ func_addr_to_tail_call_list (struct gdbarch *gdbarch, CORE_ADDR addr)
                 paddress (gdbarch, addr));
 
   type = SYMBOL_TYPE (sym);
-  gdb_assert (TYPE_CODE (type) == TYPE_CODE_FUNC);
+  gdb_assert (type->code () == TYPE_CODE_FUNC);
   gdb_assert (TYPE_SPECIFIC_FIELD (type) == TYPE_SPECIFIC_FUNC);
 
   return sym;
@@ -1552,6 +1554,9 @@ struct piece_closure
   /* Reference count.  */
   int refc = 0;
 
+  /* The objfile from which this closure's expression came.  */
+  dwarf2_per_objfile *per_objfile = nullptr;
+
   /* The CU from which this closure's expression came.  */
   struct dwarf2_per_cu_data *per_cu = NULL;
 
@@ -1574,6 +1579,8 @@ allocate_piece_closure (struct dwarf2_per_cu_data *per_cu,
   struct piece_closure *c = new piece_closure;
 
   c->refc = 1;
+  /* We must capture this here due to sharing of DWARF state.  */
+  c->per_objfile = per_cu->dwarf2_per_objfile;
   c->per_cu = per_cu;
   c->pieces = std::move (pieces);
   if (frame == NULL)
@@ -1816,7 +1823,7 @@ rw_pieced_value (struct value *v, struct value *from)
              }
 
            struct objfile *objfile = c->per_cu->objfile ();
-           struct gdbarch *objfile_gdbarch = get_objfile_arch (objfile);
+           struct gdbarch *objfile_gdbarch = objfile->arch ();
            ULONGEST stack_value_size_bits
              = 8 * TYPE_LENGTH (value_type (p->v.value));
 
@@ -2027,7 +2034,7 @@ indirect_pieced_value (struct value *value)
   enum bfd_endian byte_order;
 
   type = check_typedef (value_type (value));
-  if (TYPE_CODE (type) != TYPE_CODE_PTR)
+  if (type->code () != TYPE_CODE_PTR)
     return NULL;
 
   bit_length = 8 * TYPE_LENGTH (type);
@@ -2185,17 +2192,17 @@ dwarf2_evaluate_loc_desc_full (struct type *type, struct frame_info *frame,
   if (size == 0)
     return allocate_optimized_out_value (subobj_type);
 
-  dwarf_evaluate_loc_desc ctx;
+  dwarf2_per_objfile *per_objfile = get_dwarf2_per_objfile (objfile);
+  dwarf_evaluate_loc_desc ctx (per_objfile);
   ctx.frame = frame;
   ctx.per_cu = per_cu;
   ctx.obj_address = 0;
 
   scoped_value_mark free_values;
 
-  ctx.gdbarch = get_objfile_arch (objfile);
+  ctx.gdbarch = objfile->arch ();
   ctx.addr_size = per_cu->addr_size ();
   ctx.ref_addr_size = per_cu->ref_addr_size ();
-  ctx.offset = per_cu->text_offset ();
 
   try
     {
@@ -2289,7 +2296,7 @@ dwarf2_evaluate_loc_desc_full (struct type *type, struct frame_info *frame,
               the operation.  Therefore, we do the conversion here
               since the type is readily available.  */
 
-           switch (TYPE_CODE (subobj_type))
+           switch (subobj_type->code ())
              {
                case TYPE_CODE_FUNC:
                case TYPE_CODE_METHOD:
@@ -2315,7 +2322,7 @@ dwarf2_evaluate_loc_desc_full (struct type *type, struct frame_info *frame,
            size_t n = TYPE_LENGTH (value_type (value));
            size_t len = TYPE_LENGTH (subobj_type);
            size_t max = TYPE_LENGTH (type);
-           struct gdbarch *objfile_gdbarch = get_objfile_arch (objfile);
+           struct gdbarch *objfile_gdbarch = objfile->arch ();
 
            if (subobj_byte_offset + len > max)
              invalid_synthetic_pointer ();
@@ -2384,35 +2391,85 @@ dwarf2_evaluate_loc_desc (struct type *type, struct frame_info *frame,
                                        NULL, 0);
 }
 
-/* Evaluates a dwarf expression and stores the result in VAL, expecting
-   that the dwarf expression only produces a single CORE_ADDR.  FRAME is the
-   frame in which the expression is evaluated.  ADDR is a context (location of
-   a variable) and might be needed to evaluate the location expression.
-   Returns 1 on success, 0 otherwise.   */
+/* A specialization of dwarf_evaluate_loc_desc that is used by
+   dwarf2_locexpr_baton_eval.  This subclass exists to handle the case
+   where a caller of dwarf2_locexpr_baton_eval passes in some data,
+   but with the address being 0.  In this situation, we arrange for
+   memory reads to come from the passed-in buffer.  */
+
+struct evaluate_for_locexpr_baton : public dwarf_evaluate_loc_desc
+{
+  evaluate_for_locexpr_baton (dwarf2_per_objfile *per_objfile)
+    : dwarf_evaluate_loc_desc (per_objfile)
+  {}
+
+  /* The data that was passed in.  */
+  gdb::array_view<const gdb_byte> data_view;
+
+  CORE_ADDR get_object_address () override
+  {
+    if (data_view.data () == nullptr && obj_address == 0)
+      error (_("Location address is not set."));
+    return obj_address;
+  }
+
+  void read_mem (gdb_byte *buf, CORE_ADDR addr, size_t len) override
+  {
+    if (len == 0)
+      return;
+
+    /* Prefer the passed-in memory, if it exists.  */
+    CORE_ADDR offset = addr - obj_address;
+    if (offset < data_view.size () && offset + len <= data_view.size ())
+      {
+       memcpy (buf, data_view.data (), len);
+       return;
+      }
+
+    read_memory (addr, buf, len);
+  }
+};
+
+/* Evaluates a dwarf expression and stores the result in VAL,
+   expecting that the dwarf expression only produces a single
+   CORE_ADDR.  FRAME is the frame in which the expression is
+   evaluated.  ADDR_STACK is a context (location of a variable) and
+   might be needed to evaluate the location expression.
+   PUSH_INITIAL_VALUE is true if the address (either from ADDR_STACK,
+   or the default of 0) should be pushed on the DWARF expression
+   evaluation stack before evaluating the expression; this is required
+   by certain forms of DWARF expression.  Returns 1 on success, 0
+   otherwise.  */
 
 static int
 dwarf2_locexpr_baton_eval (const struct dwarf2_locexpr_baton *dlbaton,
                           struct frame_info *frame,
-                          CORE_ADDR addr,
-                          CORE_ADDR *valp)
+                          const struct property_addr_info *addr_stack,
+                          CORE_ADDR *valp,
+                          bool push_initial_value)
 {
-  struct objfile *objfile;
-
   if (dlbaton == NULL || dlbaton->size == 0)
     return 0;
 
-  dwarf_evaluate_loc_desc ctx;
+  dwarf2_per_objfile *per_objfile = dlbaton->per_objfile;
+  evaluate_for_locexpr_baton ctx (per_objfile);
 
   ctx.frame = frame;
   ctx.per_cu = dlbaton->per_cu;
-  ctx.obj_address = addr;
-
-  objfile = dlbaton->per_cu->objfile ();
+  if (addr_stack == nullptr)
+    ctx.obj_address = 0;
+  else
+    {
+      ctx.obj_address = addr_stack->addr;
+      ctx.data_view = addr_stack->valaddr;
+    }
 
-  ctx.gdbarch = get_objfile_arch (objfile);
+  ctx.gdbarch = per_objfile->objfile->arch ();
   ctx.addr_size = dlbaton->per_cu->addr_size ();
   ctx.ref_addr_size = dlbaton->per_cu->ref_addr_size ();
-  ctx.offset = dlbaton->per_cu->text_offset ();
+
+  if (push_initial_value)
+    ctx.push_address (ctx.obj_address, false);
 
   try
     {
@@ -2462,7 +2519,8 @@ bool
 dwarf2_evaluate_property (const struct dynamic_prop *prop,
                          struct frame_info *frame,
                          const struct property_addr_info *addr_stack,
-                         CORE_ADDR *value)
+                         CORE_ADDR *value,
+                         bool push_initial_value)
 {
   if (prop == NULL)
     return false;
@@ -2478,9 +2536,8 @@ dwarf2_evaluate_property (const struct dynamic_prop *prop,
          = (const struct dwarf2_property_baton *) prop->data.baton;
        gdb_assert (baton->property_type != NULL);
 
-       if (dwarf2_locexpr_baton_eval (&baton->locexpr, frame,
-                                      addr_stack ? addr_stack->addr : 0,
-                                      value))
+       if (dwarf2_locexpr_baton_eval (&baton->locexpr, frame, addr_stack,
+                                      value, push_initial_value))
          {
            if (baton->locexpr.is_reference)
              {
@@ -2562,10 +2619,10 @@ dwarf2_evaluate_property (const struct dynamic_prop *prop,
          }
        if (pinfo == NULL)
          error (_("cannot find reference address for offset property"));
-       if (pinfo->valaddr != NULL)
+       if (pinfo->valaddr.data () != NULL)
          val = value_from_contents
                  (baton->offset_info.type,
-                  pinfo->valaddr + baton->offset_info.offset);
+                  pinfo->valaddr.data () + baton->offset_info.offset);
        else
          val = value_at (baton->offset_info.type,
                          pinfo->addr + baton->offset_info.offset);
@@ -2619,7 +2676,10 @@ dwarf2_compile_property_to_c (string_file *stream,
 
 class symbol_needs_eval_context : public dwarf_expr_context
 {
- public:
+public:
+  symbol_needs_eval_context (dwarf2_per_objfile *per_objfile)
+    : dwarf_expr_context (per_objfile)
+  {}
 
   enum symbol_needs_kind needs;
   struct dwarf2_per_cu_data *per_cu;
@@ -2736,14 +2796,13 @@ dwarf2_loc_desc_get_symbol_read_needs (const gdb_byte *data, size_t size,
 
   scoped_value_mark free_values;
 
-  symbol_needs_eval_context ctx;
+  symbol_needs_eval_context ctx (get_dwarf2_per_objfile (objfile));
 
   ctx.needs = SYMBOL_NEEDS_NONE;
   ctx.per_cu = per_cu;
-  ctx.gdbarch = get_objfile_arch (objfile);
+  ctx.gdbarch = objfile->arch ();
   ctx.addr_size = per_cu->addr_size ();
   ctx.ref_addr_size = per_cu->ref_addr_size ();
-  ctx.offset = per_cu->text_offset ();
 
   ctx.eval (data, size);
 
@@ -3638,7 +3697,7 @@ locexpr_describe_location_piece (struct symbol *symbol, struct ui_file *stream,
                                 const gdb_byte *data, const gdb_byte *end,
                                 unsigned int addr_size)
 {
-  struct gdbarch *gdbarch = get_objfile_arch (objfile);
+  struct gdbarch *gdbarch = objfile->arch ();
   size_t leb128_size;
 
   if (data[0] >= DW_OP_reg0 && data[0] <= DW_OP_reg31)
@@ -4234,7 +4293,7 @@ locexpr_describe_location_1 (struct symbol *symbol, CORE_ADDR addr,
        {
          fprintf_filtered (stream, _("a complex DWARF expression:\n"));
          data = disassemble_dwarf_expression (stream,
-                                              get_objfile_arch (objfile),
+                                              objfile->arch (),
                                               addr_size, offset_size, data,
                                               data, end, 0,
                                               dwarf_always_disassemble,
@@ -4298,7 +4357,8 @@ locexpr_describe_location (struct symbol *symbol, CORE_ADDR addr,
 {
   struct dwarf2_locexpr_baton *dlbaton
     = (struct dwarf2_locexpr_baton *) SYMBOL_LOCATION_BATON (symbol);
-  struct objfile *objfile = dlbaton->per_cu->objfile ();
+  dwarf2_per_objfile *per_objfile = dlbaton->per_objfile;
+  struct objfile *objfile = per_objfile->objfile;
   unsigned int addr_size = dlbaton->per_cu->addr_size ();
   int offset_size = dlbaton->per_cu->offset_size ();
 
@@ -4435,8 +4495,9 @@ loclist_describe_location (struct symbol *symbol, CORE_ADDR addr,
   struct dwarf2_loclist_baton *dlbaton
     = (struct dwarf2_loclist_baton *) SYMBOL_LOCATION_BATON (symbol);
   const gdb_byte *loc_ptr, *buf_end;
-  struct objfile *objfile = dlbaton->per_cu->objfile ();
-  struct gdbarch *gdbarch = get_objfile_arch (objfile);
+  dwarf2_per_objfile *per_objfile = dlbaton->per_objfile;
+  struct objfile *objfile = per_objfile->objfile;
+  struct gdbarch *gdbarch = objfile->arch ();
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
   unsigned int addr_size = dlbaton->per_cu->addr_size ();
   int offset_size = dlbaton->per_cu->offset_size ();
@@ -4459,15 +4520,20 @@ loclist_describe_location (struct symbol *symbol, CORE_ADDR addr,
       enum debug_loc_kind kind;
       const gdb_byte *new_ptr = NULL; /* init for gcc -Wall */
 
-      if (dlbaton->from_dwo)
+      if (dlbaton->per_cu->version () < 5 && dlbaton->from_dwo)
        kind = decode_debug_loc_dwo_addresses (dlbaton->per_cu,
                                               loc_ptr, buf_end, &new_ptr,
                                               &low, &high, byte_order);
-      else
+      else if (dlbaton->per_cu->version () < 5)
        kind = decode_debug_loc_addresses (loc_ptr, buf_end, &new_ptr,
                                           &low, &high,
                                           byte_order, addr_size,
                                           signed_addr_p);
+      else
+       kind = decode_debug_loclists_addresses (dlbaton->per_cu,
+                                               loc_ptr, buf_end, &new_ptr,
+                                               &low, &high, byte_order,
+                                               addr_size, signed_addr_p);
       loc_ptr = new_ptr;
       switch (kind)
        {
@@ -4481,6 +4547,7 @@ loclist_describe_location (struct symbol *symbol, CORE_ADDR addr,
          continue;
        case DEBUG_LOC_START_END:
        case DEBUG_LOC_START_LENGTH:
+       case DEBUG_LOC_OFFSET_PAIR:
          break;
        case DEBUG_LOC_BUFFER_OVERFLOW:
        case DEBUG_LOC_INVALID_ENTRY:
@@ -4497,8 +4564,17 @@ loclist_describe_location (struct symbol *symbol, CORE_ADDR addr,
       low = gdbarch_adjust_dwarf2_addr (gdbarch, low);
       high = gdbarch_adjust_dwarf2_addr (gdbarch, high);
 
-      length = extract_unsigned_integer (loc_ptr, 2, byte_order);
-      loc_ptr += 2;
+      if (dlbaton->per_cu->version () < 5)
+        {
+          length = extract_unsigned_integer (loc_ptr, 2, byte_order);
+          loc_ptr += 2;
+        }
+      else
+        {
+          unsigned int bytes_read;
+          length = read_unsigned_leb128 (NULL, loc_ptr, &bytes_read);
+          loc_ptr += bytes_read;
+        }
 
       /* (It would improve readability to print only the minimum
         necessary digits of the second number of the range.)  */
This page took 0.03031 seconds and 4 git commands to generate.