public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
From: Zoran Zaric <Zoran.Zaric@amd.com>
To: gdb-patches@sourceware.org
Subject: [PATCH 25/43] Add deref method to location description classes
Date: Mon,  1 Mar 2021 14:46:02 +0000	[thread overview]
Message-ID: <20210301144620.103016-26-Zoran.Zaric@amd.com> (raw)
In-Reply-To: <20210301144620.103016-1-Zoran.Zaric@amd.com>

Looking at the DWARF standard, the concept of reading from a location
seems to be too low level. What the standard actually describes is a
concept of dereferencing where the type of the operation result can be
specified in advance.

This can be seen in the definition of the DW_OP_derefX family of
expression operations, but it is also happening implicitly in the case
of DW_OP_fbreg, DW_OP_regval_type and DW_OP_bregX family of operations.

Currently, the DW_OP_derefX operations will take the value from the
DWARF expression stack and implicitly convert it to a memory location
description (in reality treat it as a memory address for a given
target) and apply the dereference operation to it. When we allow any
location description on a DWARF expression stack, these operations need
to work in the same way.

The conclusion here is that we need an universal method that model the
dereference operation for any class derived from a location description
class.

It is worth mentioning that because of how the passed in buffers are
currently being implemented, we needed a specialisation for the deref
method of the dwarf_memory class to support them.

gdb/ChangeLog:

        * dwarf2/expr.c (dwarf_location::deref): New method.
        (dwarf_memory::deref): New method.
---
 gdb/dwarf2/expr.c | 119 ++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 119 insertions(+)

diff --git a/gdb/dwarf2/expr.c b/gdb/dwarf2/expr.c
index ef7adb1f959..ff9c88087d8 100644
--- a/gdb/dwarf2/expr.c
+++ b/gdb/dwarf2/expr.c
@@ -443,6 +443,18 @@ class dwarf_location : public dwarf_entry
 		      bool big_endian, int *optimized,
 		      int *unavailable) const = 0;
 
+  /* Apply dereference operation on the DWARF location description.
+     Operation returns a DWARF value of a given TYPE type while FRAME
+     contains a frame context information of the location.  ADDR_INFO
+     (if present) describes a passed in memory buffer if a regular
+     memory read is not desired for certain address range.  If the SIZE
+     is specified, it must be equal or smaller then the TYPE type size.
+     If SIZE is smaller then the type size, the value will be zero
+     extended to the difference.  */
+  virtual std::shared_ptr<dwarf_value> deref
+    (struct frame_info *frame, const struct property_addr_info *addr_info,
+     struct type *type, size_t size = 0) const;
+
 protected:
   /* Architecture of the location.  */
   struct gdbarch *m_arch;
@@ -458,6 +470,43 @@ class dwarf_location : public dwarf_entry
   bool m_initialised;
 };
 
+std::shared_ptr<dwarf_value>
+dwarf_location::deref (struct frame_info *frame,
+		       const struct property_addr_info *addr_info,
+		       struct type *type, size_t size) const
+{
+  bool big_endian = type_byte_order (type) == BFD_ENDIAN_BIG;
+  size_t actual_size = size != 0 ? size : TYPE_LENGTH (type);
+
+  if (actual_size > TYPE_LENGTH (type))
+    ill_formed_expression ();
+
+    /* If the size of the object read from memory is different
+     from the type length, we need to zero-extend it.  */
+  gdb::byte_vector read_buf (TYPE_LENGTH (type), 0);
+  gdb_byte *buf_ptr = read_buf.data ();
+  int optimized, unavailable;
+
+  if (big_endian)
+    buf_ptr += TYPE_LENGTH (type) - actual_size;
+
+  this->read (frame, buf_ptr, 0, actual_size * HOST_CHAR_BIT,
+	      0, 0, big_endian, &optimized, &unavailable);
+
+  if (optimized)
+    throw_error (OPTIMIZED_OUT_ERROR,
+		 _("Can't do read-modify-write to "
+		   "update bitfield; containing word "
+		   "has been optimized out"));
+  if (unavailable)
+    throw_error (NOT_AVAILABLE_ERROR,
+		 _("Can't dereference "
+		   "update bitfield; containing word "
+		   "is unavailable"));
+
+  return std::make_shared<dwarf_value> (read_buf.data (), type);
+}
+
 /* Value entry found on a DWARF expression evaluation stack.  */
 
 class dwarf_value : public dwarf_entry
@@ -594,6 +643,10 @@ class dwarf_memory : public dwarf_location
 	      size_t location_bit_limit, bool big_endian,
 	      int *optimized, int *unavailable) const override;
 
+  std::shared_ptr<dwarf_value> deref
+    (struct frame_info *frame, const struct property_addr_info *addr_info,
+     struct type *type, size_t size = 0) const override;
+
 private:
   /* True if the location belongs to a stack memory region.  */
   bool m_stack;
@@ -701,6 +754,72 @@ dwarf_memory::write (struct frame_info *frame, const gdb_byte *buf,
     }
 }
 
+std::shared_ptr<dwarf_value>
+dwarf_memory::deref (struct frame_info *frame,
+		     const struct property_addr_info *addr_info,
+		     struct type *type, size_t size) const
+{
+  bool big_endian = type_byte_order (type) == BFD_ENDIAN_BIG;
+  size_t actual_size = size != 0 ? size : TYPE_LENGTH (type);
+
+  if (actual_size > TYPE_LENGTH (type))
+    ill_formed_expression ();
+
+  gdb::byte_vector read_buf (TYPE_LENGTH (type), 0);
+  size_t size_in_bits = actual_size * HOST_CHAR_BIT;
+  gdb_byte *buf_ptr = read_buf.data ();
+  bool passed_in_buf = false;
+
+  if (big_endian)
+    buf_ptr += TYPE_LENGTH (type) - actual_size;
+
+  /* Covers the case where we have a passed in memory that is not
+     part of the target and requires for the location description
+     to address it instead of addressing the actual target
+     memory.  */
+  LONGEST this_size = bits_to_bytes (m_bit_suboffset, size_in_bits);
+
+  /* We shouldn't have a case where we read from a passed in
+     memory and the same memory being marked as stack. */
+  if (!m_stack && this_size && addr_info != nullptr)
+    {
+      CORE_ADDR offset = (CORE_ADDR) m_offset - addr_info->addr;
+      /* Using second buffer here because the copy_bitwise
+	 doesn't support in place copy.  */
+      gdb::byte_vector temp_buf (this_size);
+
+      if (offset < addr_info->valaddr.size ()
+	  && offset + this_size <= addr_info->valaddr.size ())
+	{
+	  memcpy (temp_buf.data (), addr_info->valaddr.data (), this_size);
+	  copy_bitwise (buf_ptr, 0, temp_buf.data (),
+			m_bit_suboffset, size_in_bits, big_endian);
+	  passed_in_buf = true;
+	}
+    }
+
+  if (!passed_in_buf)
+    {
+      int optimized, unavailable;
+
+      this->read (frame, buf_ptr, 0, size_in_bits, 0, 0,
+		  big_endian, &optimized, &unavailable);
+
+      if (optimized)
+	throw_error (OPTIMIZED_OUT_ERROR,
+		     _("Can't do read-modify-write to "
+		     "update bitfield; containing word "
+		     "has been optimized out"));
+      if (unavailable)
+	throw_error (NOT_AVAILABLE_ERROR,
+		     _("Can't dereference "
+		     "update bitfield; containing word "
+		     "is unavailable"));
+    }
+
+  return std::make_shared<dwarf_value> (read_buf.data (), type);
+}
+
 /* Register location description entry.  */
 
 class dwarf_register : public dwarf_location
-- 
2.17.1


  parent reply	other threads:[~2021-03-01 14:47 UTC|newest]

Thread overview: 86+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-03-01 14:45 [PATCH 00/43 V2] Allow location description on the DWARF stack Zoran Zaric
2021-03-01 14:45 ` [PATCH 01/43] Replace the symbol needs evaluator with a parser Zoran Zaric
2021-04-27  1:20   ` Simon Marchi
2021-04-28 10:17     ` Zoran Zaric
2021-04-28 14:08       ` Simon Marchi
2021-04-28 15:02         ` Zoran Zaric
2021-04-28 15:31         ` Zoran Zaric
2021-03-01 14:45 ` [PATCH 02/43] Cleanup of the dwarf_expr_context constructor Zoran Zaric
2021-04-27  1:23   ` Simon Marchi
2021-04-28 10:19     ` Zoran Zaric
2021-03-01 14:45 ` [PATCH 03/43] Move frame context info to dwarf_expr_context Zoran Zaric
2021-04-27  2:19   ` Simon Marchi
2021-04-28 10:51     ` Zoran Zaric
2021-04-28 14:14       ` Simon Marchi
2021-04-28 15:55         ` Zoran Zaric
2021-03-01 14:45 ` [PATCH 04/43] Remove get_frame_cfa from dwarf_expr_context Zoran Zaric
2021-03-01 14:45 ` [PATCH 05/43] Move compilation unit info to dwarf_expr_context Zoran Zaric
2021-04-27  2:58   ` Simon Marchi
2021-04-28 11:28     ` Zoran Zaric
2021-03-01 14:45 ` [PATCH 06/43] Move dwarf_call " Zoran Zaric
2021-03-01 14:45 ` [PATCH 07/43] Move get_object_address " Zoran Zaric
2021-04-27  3:12   ` Simon Marchi
2021-04-28 11:34     ` Zoran Zaric
2021-03-01 14:45 ` [PATCH 08/43] Move read_mem " Zoran Zaric
2021-03-01 14:45 ` [PATCH 09/43] Move push_dwarf_reg_entry_value to expr.c Zoran Zaric
2021-04-27  3:56   ` Simon Marchi
2021-04-28 11:36     ` Zoran Zaric
2021-03-01 14:45 ` [PATCH 10/43] Inline get_reg_value method of dwarf_expr_context Zoran Zaric
2021-03-01 14:45 ` [PATCH 11/43] Remove empty frame and full evaluators Zoran Zaric
2021-03-01 14:45 ` [PATCH 12/43] Merge evaluate_for_locexpr_baton evaluator Zoran Zaric
2021-04-28  1:33   ` Simon Marchi
2021-04-28 11:39     ` Zoran Zaric
2021-03-01 14:45 ` [PATCH 13/43] Move piece_closure and its support to expr.c Zoran Zaric
2021-04-28  1:56   ` Simon Marchi
2021-04-28 11:40     ` Zoran Zaric
2021-03-01 14:45 ` [PATCH 14/43] Make value_copy also copy the stack data member Zoran Zaric
2021-04-28  2:01   ` Simon Marchi
2021-04-28 11:43     ` Zoran Zaric
2021-03-01 14:45 ` [PATCH 15/43] Make DWARF evaluator return a single struct value Zoran Zaric
2021-04-28  2:21   ` Simon Marchi
2021-04-28 11:47     ` Zoran Zaric
2021-04-28 14:24       ` Simon Marchi
2021-03-01 14:45 ` [PATCH 16/43] Simplify dwarf_expr_context class interface Zoran Zaric
2021-04-28  2:45   ` Simon Marchi
2021-04-28 13:15     ` Zoran Zaric
2021-04-28 14:41       ` Simon Marchi
2021-04-28 15:39         ` Zoran Zaric
2021-04-28 19:19           ` Simon Marchi
2021-04-29 15:49       ` Simon Marchi
2021-04-29 15:55         ` Zoran Zaric
2021-03-01 14:45 ` [PATCH 17/43] Add as_lval argument to expression evaluator Zoran Zaric
2021-04-28  3:04   ` Simon Marchi
2021-04-28 13:16     ` Zoran Zaric
2021-04-28  3:30   ` Simon Marchi
2021-03-01 14:45 ` [PATCH 18/43] Add new register access interface to expr.c Zoran Zaric
2021-03-08 23:52   ` Lancelot SIX
2021-04-28  3:25   ` Simon Marchi
2021-04-28 13:29     ` Zoran Zaric
2021-04-28 14:48       ` Simon Marchi
2021-04-28 15:42         ` Zoran Zaric
2021-03-01 14:45 ` [PATCH 19/43] Add new memory " Zoran Zaric
2021-04-30 21:24   ` Simon Marchi
2021-03-01 14:45 ` [PATCH 20/43] Add new classes that model DWARF stack element Zoran Zaric
2021-03-01 14:45 ` [PATCH 21/43] Add to_location method to DWARF entry classes Zoran Zaric
2021-03-01 14:45 ` [PATCH 22/43] Add to_value " Zoran Zaric
2021-03-01 14:46 ` [PATCH 23/43] Add read method to location description classes Zoran Zaric
2021-03-01 14:46 ` [PATCH 24/43] Add write " Zoran Zaric
2021-03-01 14:46 ` Zoran Zaric [this message]
2021-03-01 14:46 ` [PATCH 26/43] Add read_from_gdb_value method to dwarf_location Zoran Zaric
2021-03-01 14:46 ` [PATCH 27/43] Add write_to_gdb_value " Zoran Zaric
2021-03-01 14:46 ` [PATCH 28/43] Add is_implicit_ptr_at " Zoran Zaric
2021-03-01 14:46 ` [PATCH 29/43] Add indirect_implicit_ptr to dwarf_location class Zoran Zaric
2021-03-01 14:46 ` [PATCH 30/43] Add new computed struct value callback interface Zoran Zaric
2021-03-01 14:46 ` [PATCH 31/43] Add to_gdb_value method to DWARF entry class Zoran Zaric
2021-03-01 14:46 ` [PATCH 32/43] Change DWARF stack to use new dwarf_entry classes Zoran Zaric
2021-03-01 14:46 ` [PATCH 33/43] Remove old computed struct value callbacks Zoran Zaric
2021-03-01 14:46 ` [PATCH 34/43] Comments cleanup between expr.h and expr.c Zoran Zaric
2021-03-01 14:46 ` [PATCH 35/43] Remove dwarf_expr_context from expr.h interface Zoran Zaric
2021-03-01 14:46 ` [PATCH 36/43] Move read_addr_from_reg function to frame.c Zoran Zaric
2021-03-01 14:46 ` [PATCH 37/43] Add frame info check to DW_OP_reg operations Zoran Zaric
2021-03-01 14:46 ` [PATCH 38/43] Remove DWARF expression composition check Zoran Zaric
2021-03-01 14:46 ` [PATCH 39/43] Change back the symbol needs to use the evaluator Zoran Zaric
2021-03-01 14:46 ` [PATCH 40/43] Add support for any location description in CFI Zoran Zaric
2021-03-01 14:46 ` [PATCH 41/43] Add DWARF operations for byte and bit offset Zoran Zaric
2021-03-01 14:46 ` [PATCH 42/43] Add support for DW_OP_LLVM_undefined operation Zoran Zaric
2021-03-01 14:46 ` [PATCH 43/43] Add support for nested composite locations Zoran Zaric

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210301144620.103016-26-Zoran.Zaric@amd.com \
    --to=zoran.zaric@amd.com \
    --cc=gdb-patches@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).