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 v3 02/28] Add new memory access interface to expr.c
Date: Thu, 14 Oct 2021 10:32:09 +0100	[thread overview]
Message-ID: <20211014093235.69756-3-zoran.zaric@amd.com> (raw)
In-Reply-To: <20211014093235.69756-1-zoran.zaric@amd.com>

From: Zoran Zaric <Zoran.Zaric@amd.com>

DWARF expression evaluator is currently using a few different
interfaces for memory access: write_memory_with_notification,
read_value_memory, read_memory.

They all seem incosistent, while some of them even need a struct
value typed argument to be present.

This patch is simplifying that interface by replacing it with two new
low level functions: read_from_memory and write_to_memory.

The advantage of this new interface is that it behaves in the same way
as the register access interface from the previous patch. Both of these
have the same error returning policy, which will be usefull for the
following patches.

	* dwarf2/expr.c (xfer_memory):  New function.
	(read_from_memory): New function.
	(write_to_memory): New function.
	(rw_pieced_value): Now calls the read_from_memory and
	write_to_memory functions.
---
 gdb/dwarf2/expr.c | 190 +++++++++++++++++++++++++++++++++++-----------
 1 file changed, 146 insertions(+), 44 deletions(-)

diff --git a/gdb/dwarf2/expr.c b/gdb/dwarf2/expr.c
index 3dfba38bdb3..c0ca78ce236 100644
--- a/gdb/dwarf2/expr.c
+++ b/gdb/dwarf2/expr.c
@@ -33,6 +33,8 @@
 #include "gdbsupport/underlying.h"
 #include "gdbarch.h"
 #include "objfiles.h"
+#include "inferior.h"
+#include "observable.h"
 
 /* Cookie for gdbarch data.  */
 
@@ -189,6 +191,86 @@ write_to_register (frame_info *frame, int regnum,
   return;
 }
 
+/* Helper for read_from_memory and write_to_memory.  */
+
+static void
+xfer_memory (CORE_ADDR address, gdb_byte *readbuf,
+	     const gdb_byte *writebuf,
+	     size_t length, bool stack, int *unavailable)
+{
+  *unavailable = 0;
+
+  target_object object
+    = stack ? TARGET_OBJECT_STACK_MEMORY : TARGET_OBJECT_MEMORY;
+
+  ULONGEST xfered_total = 0;
+
+  while (xfered_total < length)
+    {
+      ULONGEST xfered_partial;
+
+      enum target_xfer_status status
+	= target_xfer_partial (current_inferior ()->top_target (),
+			       object, NULL,
+			       (readbuf != nullptr
+				? readbuf + xfered_total
+				: nullptr),
+			       (writebuf != nullptr
+				? writebuf + xfered_total
+				: nullptr),
+			       address + xfered_total, length - xfered_total,
+			       &xfered_partial);
+
+      if (status == TARGET_XFER_OK)
+	{
+	  xfered_total += xfered_partial;
+	  QUIT;
+	}
+      else if (status == TARGET_XFER_UNAVAILABLE)
+	{
+	  *unavailable = 1;
+	  return;
+	}
+      else if (status == TARGET_XFER_EOF)
+	memory_error (TARGET_XFER_E_IO, address + xfered_total);
+      else
+	memory_error (status, address + xfered_total);
+    }
+}
+
+/* Read LENGTH bytes of memory contents starting at ADDRESS.
+
+   The data read is copied to a caller-managed buffer BUF.  STACK
+   indicates whether the memory range specified belongs to a stack
+   memory region.
+
+   If the memory is unavailable, the UNAVAILABLE output is set.  */
+
+static void
+read_from_memory (CORE_ADDR address, gdb_byte *buffer,
+		  size_t length, bool stack, int *unavailable)
+{
+  xfer_memory (address, buffer, nullptr, length, stack, unavailable);
+}
+
+/* Write LENGTH bytes of memory contents starting at ADDRESS.
+
+   The data written is copied from a caller-managed buffer buf.  STACK
+   indicates whether the memory range specified belongs to a stack
+   memory region.
+
+   If the memory is unavailable, the UNAVAILABLE output is set.  */
+
+static void
+write_to_memory (CORE_ADDR address, const gdb_byte *buffer,
+		 size_t length, bool stack, int *unavailable)
+{
+  xfer_memory (address, nullptr, buffer, length, stack, unavailable);
+
+  gdb::observers::memory_changed.notify (current_inferior (), address,
+					 length, buffer);
+}
+
 struct piece_closure
 {
   /* Reference count.  */
@@ -387,66 +469,86 @@ rw_pieced_value (value *v, value *from, bool check_optimized)
 	    bits_to_skip += p->offset;
 
 	    CORE_ADDR start_addr = p->v.mem.addr + bits_to_skip / 8;
+	    bool in_stack_memory = p->v.mem.in_stack_memory;
+	    int unavail = 0;
 
 	    if (bits_to_skip % 8 == 0 && this_size_bits % 8 == 0
 		&& offset % 8 == 0)
 	      {
 		/* Everything is byte-aligned; no buffer needed.  */
-		if (from != nullptr)
-		  write_memory_with_notification (start_addr,
-						  (from_contents
-						   + offset / 8),
-						  this_size_bits / 8);
+		if (from != NULL)
+		  write_to_memory (start_addr, (from_contents + offset / 8),
+				   this_size_bits / 8, in_stack_memory,
+				   &unavail);
 		else
-		  read_value_memory (v, offset,
-				     p->v.mem.in_stack_memory,
-				     p->v.mem.addr + bits_to_skip / 8,
-				     v_contents + offset / 8,
-				     this_size_bits / 8);
-		break;
-	      }
-
-	    this_size = bits_to_bytes (bits_to_skip, this_size_bits);
-	    buffer.resize (this_size);
-
-	    if (from == nullptr)
-	      {
-		/* Read mode.  */
-		read_value_memory (v, offset,
-				   p->v.mem.in_stack_memory,
-				   p->v.mem.addr + bits_to_skip / 8,
-				   buffer.data (), this_size);
-		copy_bitwise (v_contents, offset,
-			      buffer.data (), bits_to_skip % 8,
-			      this_size_bits, bits_big_endian);
+		  read_from_memory (start_addr, (v_contents + offset / 8),
+				    this_size_bits / 8, in_stack_memory,
+				    &unavail);
 	      }
 	    else
 	      {
-		/* Write mode.  */
-		if (bits_to_skip % 8 != 0 || this_size_bits % 8 != 0)
+		this_size = bits_to_bytes (bits_to_skip, this_size_bits);
+		buffer.resize (this_size);
+
+		if (from == NULL)
 		  {
-		    if (this_size <= 8)
+		    /* Read mode.  */
+		    read_from_memory (start_addr, buffer.data (),
+				      this_size, in_stack_memory,
+				      &unavail);
+		    if (!unavail)
+		      copy_bitwise (v_contents, offset,
+				    buffer.data (), bits_to_skip % 8,
+				    this_size_bits, bits_big_endian);
+		  }
+		else
+		  {
+		    /* Write mode.  */
+		    if (bits_to_skip % 8 != 0 || this_size_bits % 8 != 0)
 		      {
-			/* Perform a single read for small sizes.  */
-			read_memory (start_addr, buffer.data (),
-				     this_size);
+			if (this_size <= 8)
+			  {
+			    /* Perform a single read for small sizes.  */
+			    read_from_memory (start_addr, buffer.data (),
+					      this_size, in_stack_memory,
+					      &unavail);
+			  }
+			else
+			  {
+			    /* Only the first and last bytes can possibly have
+			       any bits reused.  */
+			    read_from_memory (start_addr, buffer.data (),
+					      1, in_stack_memory,
+					      &unavail);
+			    if (!unavail)
+			      read_from_memory (start_addr + this_size - 1,
+						&buffer[this_size - 1], 1,
+						in_stack_memory, &unavail);
+			  }
 		      }
-		    else
+
+		    if (!unavail)
 		      {
-			/* Only the first and last bytes can possibly have
-			   any bits reused.  */
-			read_memory (start_addr, buffer.data (), 1);
-			read_memory (start_addr + this_size - 1,
-				     &buffer[this_size - 1], 1);
+			copy_bitwise (buffer.data (), bits_to_skip % 8,
+				      from_contents, offset,
+				      this_size_bits, bits_big_endian);
+			write_to_memory (start_addr, buffer.data (),
+					 this_size, in_stack_memory,
+					 &unavail);
 		      }
 		  }
+	      }
 
-		copy_bitwise (buffer.data (), bits_to_skip % 8,
-			      from_contents, offset,
-			      this_size_bits, bits_big_endian);
-		write_memory_with_notification (start_addr,
-						buffer.data (),
-						this_size);
+	    if (unavail)
+	      {
+		if (from == NULL)
+		  mark_value_bits_unavailable (v, (offset + bits_to_skip % 8),
+					       this_size_bits);
+		else
+		  throw_error (NOT_AVAILABLE_ERROR,
+			       _("Can't do read-modify-write to "
+				 "update bitfield; containing word "
+				 "is unavailable"));
 	      }
 	  }
 	  break;
-- 
2.17.1


  parent reply	other threads:[~2021-10-14  9:32 UTC|newest]

Thread overview: 62+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-10-14  9:32 [PATCH v3 00/28] Allow location description on the DWARF stack Zoran Zaric
2021-10-14  9:32 ` [PATCH v3 01/28] Add new register access interface to expr.c Zoran Zaric
2021-10-14  9:32 ` Zoran Zaric [this message]
2021-10-14  9:32 ` [PATCH v3 03/28] Add new classes that model DWARF stack element Zoran Zaric
2021-10-21 23:43   ` Lancelot SIX
2021-10-22 16:38     ` Zoran Zaric
2021-10-22 21:34       ` Lancelot SIX
2021-10-14  9:32 ` [PATCH v3 04/28] Add to_location method to DWARF entry classes Zoran Zaric
2021-10-22 21:21   ` Lancelot SIX
2021-10-25 21:23     ` Simon Marchi
2021-11-01 16:01       ` Zoran Zaric
2021-11-01 20:36         ` Simon Marchi
2021-11-01 16:00     ` Zoran Zaric
2021-11-01 17:48       ` Lancelot SIX
2021-10-14  9:32 ` [PATCH v3 05/28] Add to_value " Zoran Zaric
2021-10-14  9:32 ` [PATCH v3 06/28] Add read method to location description classes Zoran Zaric
2021-10-25 18:33   ` Lancelot SIX
2021-10-25 21:37     ` Simon Marchi
2021-11-02 14:26       ` Zoran Zaric
2021-11-03 19:03         ` Simon Marchi
2021-11-05 11:58           ` Zoran Zaric
2021-10-14  9:32 ` [PATCH v3 07/28] Add write " Zoran Zaric
2021-10-25 20:21   ` Lancelot SIX
2021-11-03 10:27     ` Zoran Zaric
2021-10-14  9:32 ` [PATCH v3 08/28] Add deref " Zoran Zaric
2021-10-25 22:31   ` Lancelot SIX
2021-11-03 10:51     ` Zoran Zaric
2021-11-03 17:37       ` Simon Marchi
2021-11-05 11:55         ` Zoran Zaric
2021-10-14  9:32 ` [PATCH v3 09/28] Add read_from_gdb_value method to dwarf_location Zoran Zaric
2021-10-14  9:32 ` [PATCH v3 10/28] Add write_to_gdb_value " Zoran Zaric
2021-10-14  9:32 ` [PATCH v3 11/28] Add is_implicit_ptr_at " Zoran Zaric
2021-10-14  9:32 ` [PATCH v3 12/28] Add indirect_implicit_ptr to dwarf_location class Zoran Zaric
2021-10-26 20:52   ` Lancelot SIX
2021-11-03 15:11     ` Zoran Zaric
2021-10-14  9:32 ` [PATCH v3 13/28] Add is_optimized_out " Zoran Zaric
2021-10-14  9:32 ` [PATCH v3 14/28] Add new computed struct value callback interface Zoran Zaric
2021-10-26 22:50   ` Lancelot SIX
2021-11-04 11:32     ` Zoran Zaric
2021-10-14  9:32 ` [PATCH v3 15/28] Add to_gdb_value method to DWARF entry class Zoran Zaric
2021-10-14  9:32 ` [PATCH v3 16/28] Change DWARF stack to use new dwarf_entry classes Zoran Zaric
2021-10-31 17:58   ` Lancelot SIX
2021-11-04 12:43     ` Zoran Zaric
2021-10-14  9:32 ` [PATCH v3 17/28] Remove old computed struct value callbacks Zoran Zaric
2021-10-14  9:32 ` [PATCH v3 18/28] Comments cleanup between expr.h and expr.c Zoran Zaric
2021-10-14  9:32 ` [PATCH v3 19/28] Remove dwarf_expr_context from expr.h interface Zoran Zaric
2021-10-14  9:32 ` [PATCH v3 20/28] Move read_addr_from_reg function to frame.c Zoran Zaric
2021-10-14  9:32 ` [PATCH v3 21/28] Add frame info check to DW_OP_reg operations Zoran Zaric
2021-10-14  9:32 ` [PATCH v3 22/28] Remove DWARF expression composition check Zoran Zaric
2021-10-14  9:32 ` [PATCH v3 23/28] Add support for any location description in CFI Zoran Zaric
2021-10-31 22:58   ` Lancelot SIX
2021-11-04 15:09     ` Zoran Zaric
2021-10-14  9:32 ` [PATCH v3 24/28] Add DWARF operations for byte and bit offset Zoran Zaric
2021-10-14  9:32 ` [PATCH v3 25/28] Add support for DW_OP_LLVM_undefined operation Zoran Zaric
2021-10-14  9:32 ` [PATCH v3 26/28] Add support for nested composite locations Zoran Zaric
2021-10-14  9:32 ` [PATCH v3 27/28] Add DW_OP_LLVM_extend DWARF operation Zoran Zaric
2021-11-01 21:48   ` Lancelot SIX
2021-11-04 16:26     ` Zoran Zaric
2021-10-14  9:32 ` [PATCH v3 28/28] Add DW_OP_LLVM_select_bit_piece " Zoran Zaric
2021-11-01 22:25   ` Lancelot SIX
2021-11-04 16:39     ` Zoran Zaric
2021-11-05 11:54 ` [PATCH v3 00/28] Allow location description on the DWARF stack Zaric, Zoran (Zare)

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=20211014093235.69756-3-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).