]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
Simplify dwarf_expr_context class interface
authorZoran Zaric <Zoran.Zaric@amd.com>
Mon, 7 Dec 2020 19:00:15 +0000 (19:00 +0000)
committerSimon Marchi <simon.marchi@polymtl.ca>
Tue, 8 Dec 2020 16:16:19 +0000 (11:16 -0500)
Idea of this patch is to get a clean and simple public interface for
the dwarf_expr_context class, looking like:

- constructor,
- destructor,
- push_address method and
- eval_exp method.

Where constructor should only ever require a target architecture
information. This information is held in per object file
(dwarf2_per_objfile) structure, so it makes sense to keep that
structure as a constructor argument. It also makes sense to get the
address size from that structure, but unfortunately that interface
doesn't exist at the moment, so the dwarf_expr_context class user
needs to provide that information.

The push_address method is used to push a CORE_ADDR as a value on
top of the DWARF stack before the evaluation. This method can be
later changed to push any struct value object on the stack.

The eval_exp method is the method that evaluates a DWARF expression
and provides the evaluation result, in a form of a single struct
value object that describes a location. To do this, the method requires
a context of the evaluation, as well as expected result type
information. If the type information is not provided, the DWARF generic
type will be used instead.

gdb/ChangeLog:

* dwarf2/expr.c (dwarf_expr_context::dwarf_expr_context): Add
address size argument.
(dwarf_expr_context::read_mem): Change to use property_addr_info
structure.
(dwarf_expr_context::eval_exp): New function.
(dwarf_expr_context::execute_stack_op): Change to use
property_addr_info structure.
* dwarf2/expr.h (struct dwarf_expr_context): New eval_exp
declaration. Change eval and fetch_result method to private.
* dwarf2/frame.c (execute_stack_op): Change to call eval_exp
method.
* dwarf2/loc.c (dwarf2_evaluate_loc_desc_full): Change to call
eval_exp method.
(dwarf2_locexpr_baton_eval): Change to call eval_exp method.

Change-Id: I8abd0dbf93e74a8a5adce143bfdea83c802233c3

gdb/dwarf2/expr.c
gdb/dwarf2/expr.h
gdb/dwarf2/frame.c
gdb/dwarf2/loc.c

index 7f8e8134a4f3e922ca2081fa808b8dbafcaaf262..5e99a98e1e3c6d473890226559e160fcb7f3f712 100644 (file)
@@ -693,9 +693,10 @@ dwarf_expr_context::address_type () const
 
 /* Create a new context for the expression evaluator.  */
 
-dwarf_expr_context::dwarf_expr_context (dwarf2_per_objfile *per_objfile)
-: gdbarch (NULL),
-  addr_size (0),
+dwarf_expr_context::dwarf_expr_context (dwarf2_per_objfile *per_objfile,
+                                       int addr_size)
+: gdbarch (per_objfile->objfile->arch ()),
+  addr_size (addr_size),
   ref_addr_size (0),
   recursion_depth (0),
   max_recursion_depth (0x100),
@@ -706,7 +707,7 @@ dwarf_expr_context::dwarf_expr_context (dwarf2_per_objfile *per_objfile)
   per_objfile (per_objfile),
   frame (nullptr),
   per_cu (nullptr),
-  obj_address (0)
+  addr_info (nullptr)
 {
 }
 
@@ -831,13 +832,17 @@ dwarf_expr_context::read_mem (gdb_byte *buf, CORE_ADDR addr,
     return;
 
   /* Prefer the passed-in memory, if it exists.  */
-  CORE_ADDR offset = addr - obj_address;
+  if (addr_info != nullptr)
+    {
+      CORE_ADDR offset = addr - addr_info->addr;
 
-  if (offset < data_view.size () && offset + length <= data_view.size ())
+      if (offset < addr_info->valaddr.size ()
+         && offset + length <= addr_info->valaddr.size ())
     {
-      memcpy (buf, data_view.data (), length);
+      memcpy (buf, addr_info->valaddr.data (), length);
       return;
     }
+    }
 
   read_memory (addr, buf, length);
 }
@@ -880,8 +885,8 @@ dwarf_expr_context::push_dwarf_reg_entry_value
                                                   caller_frame);
   scoped_restore save_per_cu = make_scoped_restore (&this->per_cu,
                                                    caller_per_cu);
-  scoped_restore save_obj_addr = make_scoped_restore (&this->obj_address,
-                                                     (CORE_ADDR) 0);
+  scoped_restore save_addr_info = make_scoped_restore (&this->addr_info,
+                                                      nullptr);
   scoped_restore save_per_objfile = make_scoped_restore (&this->per_objfile,
                                                         caller_per_objfile);
 
@@ -1049,6 +1054,28 @@ dwarf_expr_context::fetch_result (struct type *type,
   return retval;
 }
 
+/* See expr.h.  */
+
+struct value *
+dwarf_expr_context::eval_exp (const gdb_byte *addr, size_t len,
+                             struct dwarf2_per_cu_data *per_cu,
+                             struct frame_info *frame,
+                             const struct property_addr_info *addr_info,
+                             struct type *type,
+                             struct type *subobj_type,
+                             LONGEST subobj_offset)
+{
+  this->per_cu = per_cu;
+  this->frame = frame;
+  this->addr_info = addr_info;
+
+  if (per_cu != nullptr)
+    this->ref_addr_size = per_cu->ref_addr_size ();
+
+  eval (addr, len);
+  return fetch_result (type, subobj_type, subobj_offset);
+}
+
 /* Require that TYPE be an integral type; throw an exception if not.  */
 
 static void
@@ -2319,11 +2346,11 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr,
 
        case DW_OP_push_object_address:
          /* Return the address of the object we are currently observing.  */
-         if (this->data_view.data () == nullptr
-             && this->obj_address == 0)
+         if (addr_info == nullptr)
            error (_("Location address is not set."));
 
-         result_val = value_from_ulongest (address_type, this->obj_address);
+         result_val
+           = value_from_ulongest (address_type, this->addr_info->addr);
          break;
 
        default:
index b7605ffd28c67ee48700c02ee47c46f308d0ad03..69a043da50efc74d2f0a45469040b24aa4b3da8a 100644 (file)
@@ -119,19 +119,30 @@ struct dwarf_stack_value
    its current state and its callbacks.  */
 struct dwarf_expr_context
 {
-  dwarf_expr_context (dwarf2_per_objfile *per_objfile);
+  /* We should ever only pass in the PER_OBJFILE, while the ADDR_SIZE
+     information should be retrievable from there.  The PER_OBJFILE
+     contains a pointer to the PER_BFD information anyway and the
+     address size information must be the same for the whole BFD.  */
+  dwarf_expr_context (struct dwarf2_per_objfile *per_objfile,
+                     int addr_size);
   virtual ~dwarf_expr_context () = default;
 
   void push_address (CORE_ADDR value, bool in_stack_memory);
-  void eval (const gdb_byte *addr, size_t len);
 
-  /* Fetch the result of the expression evaluation in a form of
-     a struct value, where TYPE, SUBOBJ_TYPE and SUBOBJ_OFFSET
-     describe the source level representation of that result.  */
-  struct value *fetch_result (struct type *type = nullptr,
-                             struct type *subobj_type = nullptr,
-                             LONGEST subobj_offset = 0);
+  /* Evaluate the expression at ADDR (LEN bytes long) in a given PER_CU
+     FRAME context.  Where TYPE, SUBOBJ_TYPE and SUBOBJ_OFFSET describe
+     expected struct value representation of the evaluation result.
+     The ADDR_INFO property can be specified to override the range of
+     memory addresses with the passed in buffer.  */
+  struct value *eval_exp (const gdb_byte *addr, size_t len,
+                         struct dwarf2_per_cu_data *per_cu,
+                         struct frame_info *frame,
+                         const struct property_addr_info *addr_info = nullptr,
+                         struct type *type = nullptr,
+                         struct type *subobj_type = nullptr,
+                         LONGEST subobj_offset = 0);
 
+private:
   /* The stack of values.  */
   std::vector<dwarf_stack_value> stack;
 
@@ -196,14 +207,10 @@ struct dwarf_expr_context
   /* Compilation unit used for the evaluation.  */
   struct dwarf2_per_cu_data *per_cu;
 
-  /* Object address used for the evaluation.  */
-  CORE_ADDR obj_address;
-
-  /* The data that was passed in.  */
-  gdb::array_view<const gdb_byte> data_view;
-
-private:
+  /* Property address info used for the evaluation.  */
+  const struct property_addr_info *addr_info;
 
+  void eval (const gdb_byte *addr, size_t len);
   struct type *address_type () const;
   void push (struct value *value, bool in_stack_memory);
   bool stack_empty_p () const;
@@ -214,6 +221,13 @@ private:
   CORE_ADDR fetch_address (int n);
   bool fetch_in_stack_memory (int n);
 
+  /* Fetch the result of the expression evaluation in a form of
+     a struct value, where TYPE, SUBOBJ_TYPE and SUBOBJ_OFFSET
+     describe the source level representation of that result.  */
+  struct value *fetch_result (struct type *type,
+                             struct type *subobj_type,
+                             LONGEST subobj_offset);
+
   /* Return the location expression for the frame base attribute, in
      START and LENGTH.  The result must be live until the current
      expression evaluation is complete.  */
index 039990dea34bb21a707828bc0ce5fdd6df96032f..228c48f3877608591fe89764fe224d7acecafe52 100644 (file)
@@ -228,26 +228,16 @@ execute_stack_op (const gdb_byte *exp, ULONGEST len, int addr_size,
                  struct frame_info *this_frame, CORE_ADDR initial,
                  int initial_in_stack_memory, dwarf2_per_objfile *per_objfile)
 {
-  dwarf_expr_context ctx (per_objfile);
+  dwarf_expr_context ctx (per_objfile, addr_size);
   scoped_value_mark free_values;
 
-  ctx.frame = this_frame;
-  ctx.gdbarch = get_frame_arch (this_frame);
-  ctx.addr_size = addr_size;
-  ctx.ref_addr_size = -1;
-
   ctx.push_address (initial, initial_in_stack_memory);
-  ctx.eval (exp, len);
-
-  CORE_ADDR result;
-  struct value *result_val = ctx.fetch_result ();
+  struct value *result_val = ctx.eval_exp (exp, len, nullptr, this_frame);
 
   if (VALUE_LVAL (result_val) == lval_memory)
-    result = value_address (result_val);
+    return value_address (result_val);
   else
-    result = value_as_address (result_val);
-
-  return result;
+    return value_as_address (result_val);
 }
 \f
 
index 90ab2077c6d0dbaac08bd1192a22c103fe663553..fdf8385933608bebc60b860c0d11bdaa21457d28 100644 (file)
@@ -1430,8 +1430,6 @@ dwarf2_evaluate_loc_desc_full (struct type *type, struct frame_info *frame,
                               struct type *subobj_type,
                               LONGEST subobj_byte_offset)
 {
-  struct value *retval;
-
   if (subobj_type == NULL)
     {
       subobj_type = type;
@@ -1443,22 +1441,15 @@ dwarf2_evaluate_loc_desc_full (struct type *type, struct frame_info *frame,
   if (size == 0)
     return allocate_optimized_out_value (subobj_type);
 
-  dwarf_expr_context ctx (per_objfile);
-  ctx.frame = frame;
-  ctx.per_cu = per_cu;
-  ctx.obj_address = 0;
+  dwarf_expr_context ctx (per_objfile, per_cu->addr_size ());
 
+  struct value *retval;
   scoped_value_mark free_values;
 
-  ctx.gdbarch = per_objfile->objfile->arch ();
-  ctx.addr_size = per_cu->addr_size ();
-  ctx.ref_addr_size = per_cu->ref_addr_size ();
-
   try
     {
-      ctx.eval (data, size);
-      retval = ctx.fetch_result (type, subobj_type,
-                                subobj_byte_offset);
+      retval = ctx.eval_exp (data, size, per_cu, frame, nullptr, type,
+                            subobj_type, subobj_byte_offset);
     }
   catch (const gdb_exception_error &ex)
     {
@@ -1528,30 +1519,24 @@ dwarf2_locexpr_baton_eval (const struct dwarf2_locexpr_baton *dlbaton,
     return 0;
 
   dwarf2_per_objfile *per_objfile = dlbaton->per_objfile;
-  dwarf_expr_context ctx (per_objfile);
+  struct dwarf2_per_cu_data *per_cu = dlbaton->per_cu;
+  dwarf_expr_context ctx (per_objfile, per_cu->addr_size ());
 
   struct value *result;
   scoped_value_mark free_values;
 
-  ctx.frame = frame;
-  ctx.per_cu = dlbaton->per_cu;
-  if (addr_stack != nullptr)
+  if (push_initial_value)
     {
-      ctx.obj_address = addr_stack->addr;
-      ctx.data_view = addr_stack->valaddr;
+      if (addr_stack != nullptr)
+       ctx.push_address (addr_stack->addr, false);
+      else
+       ctx.push_address (0, false);
     }
 
-  ctx.gdbarch = per_objfile->objfile->arch ();
-  ctx.addr_size = dlbaton->per_cu->addr_size ();
-  ctx.ref_addr_size = dlbaton->per_cu->ref_addr_size ();
-
-  if (push_initial_value)
-    ctx.push_address (ctx.obj_address, false);
-
   try
     {
-      ctx.eval (dlbaton->data, dlbaton->size);
-      result = ctx.fetch_result ();
+      result = ctx.eval_exp (dlbaton->data, dlbaton->size,
+                            per_cu, frame, addr_stack);
     }
   catch (const gdb_exception_error &ex)
     {