From: Zoran Zaric <zoran.zaric@amd.com>
To: <gdb-patches@sourceware.org>
Subject: [PATCH v4 01/28] Add new register access interface to expr.c
Date: Fri, 5 Nov 2021 11:38:22 +0000 [thread overview]
Message-ID: <20211105113849.118800-2-zoran.zaric@amd.com> (raw)
In-Reply-To: <20211105113849.118800-1-zoran.zaric@amd.com>
From: Zoran Zaric <Zoran.Zaric@amd.com>
DWARF expression evaluator is currently using get_frame_register_bytes
and put_frame_register_bytes interface for register access.
The problem with evaluator using this interface is that it allows a
bleed out register access. This means that if the caller specifies a
larger amount of data then the size of a specified register, the
operation will continue accessing the neighboring registers until a
full amount of data has been reached.
DWARF specification does not define this behavior, so a new simplified
register access interface is needed instead.
* dwarf2/expr.c (read_from_register): New function.
(write_to_register): New function.
(rw_pieced_value): Now calls the read_from_register and
write_to_register functions.
---
gdb/dwarf2/expr.c | 127 ++++++++++++++++++++++++++++++++++++++--------
1 file changed, 105 insertions(+), 22 deletions(-)
diff --git a/gdb/dwarf2/expr.c b/gdb/dwarf2/expr.c
index 652161955d5..0ca8528298a 100644
--- a/gdb/dwarf2/expr.c
+++ b/gdb/dwarf2/expr.c
@@ -99,6 +99,96 @@ read_addr_from_reg (frame_info *frame, int reg)
return address_from_register (regnum, frame);
}
+/* Read register REGNUM's contents in a given FRAME context.
+
+ The data read is offsetted by OFFSET, and the number of bytes read
+ is defined by LENGTH. The data is then copied into the
+ caller-managed buffer BUF.
+
+ If the register is optimized out or unavailable for the given
+ FRAME, the OPTIMIZED and UNAVAILABLE outputs are set
+ accordingly */
+
+static void
+read_from_register (frame_info *frame, int regnum,
+ CORE_ADDR offset, gdb::array_view<gdb_byte> buf,
+ int *optimized, int *unavailable)
+{
+ gdbarch *arch = get_frame_arch (frame);
+ int regsize = register_size (arch, regnum);
+ int numregs = gdbarch_num_cooked_regs (arch);
+ int length = buf.size ();
+
+ /* If a register is wholly inside the OFFSET, skip it. */
+ if (frame == NULL || !regsize
+ || offset + length > regsize || numregs < regnum)
+ {
+ *optimized = 0;
+ *unavailable = 1;
+ return;
+ }
+
+ gdb::byte_vector temp_buf (regsize);
+ enum lval_type lval;
+ CORE_ADDR address;
+ int realnum;
+
+ frame_register (frame, regnum, optimized, unavailable,
+ &lval, &address, &realnum, temp_buf.data ());
+
+ if (!*optimized && !*unavailable)
+ memcpy (buf.data (), (char *) temp_buf.data () + offset, length);
+
+ return;
+}
+
+/* Write register REGNUM's contents in a given FRAME context.
+
+ The data written is offsetted by OFFSET, and the number of bytes
+ written is defined by LENGTH. The data is copied from
+ caller-managed buffer BUF.
+
+ If the register is optimized out or unavailable for the given
+ FRAME, the OPTIMIZED and UNAVAILABLE outputs are set
+ accordingly. */
+
+static void
+write_to_register (frame_info *frame, int regnum,
+ CORE_ADDR offset, gdb::array_view<gdb_byte> buf,
+ int *optimized, int *unavailable)
+{
+ gdbarch *arch = get_frame_arch (frame);
+ int regsize = register_size (arch, regnum);
+ int numregs = gdbarch_num_cooked_regs (arch);
+ int length = buf.size ();
+
+ /* If a register is wholly inside of OFFSET, skip it. */
+ if (frame == NULL || !regsize
+ || offset + length > regsize || numregs < regnum)
+ {
+ *optimized = 0;
+ *unavailable = 1;
+ return;
+ }
+
+ gdb::byte_vector temp_buf (regsize);
+ enum lval_type lval;
+ CORE_ADDR address;
+ int realnum;
+
+ frame_register (frame, regnum, optimized, unavailable,
+ &lval, &address, &realnum, temp_buf.data ());
+
+ if (!*optimized && !*unavailable)
+ {
+ memcpy ((char *) temp_buf.data () + offset, buf.data (), length);
+
+ put_frame_register (frame, regnum, temp_buf.data ());
+ }
+
+ return;
+}
+
struct piece_closure
{
/* Reference count. */
@@ -242,24 +332,19 @@ rw_pieced_value (value *v, value *from, bool check_optimized)
if (from == nullptr)
{
/* Read mode. */
- if (!get_frame_register_bytes (frame, gdb_regnum,
- bits_to_skip / 8,
- buffer, &optim, &unavail))
+ read_from_register (frame, gdb_regnum, bits_to_skip / 8,
+ buffer, &optim, &unavail);
+
+ if (optim)
{
- if (optim)
- {
- if (check_optimized)
- return true;
- mark_value_bits_optimized_out (v, offset,
- this_size_bits);
- }
- if (unavail && !check_optimized)
- mark_value_bits_unavailable (v, offset,
- this_size_bits);
- break;
+ if (check_optimized)
+ return true;
+ mark_value_bits_optimized_out (v, offset, this_size_bits);
}
-
- if (!check_optimized)
+ if (unavail)
+ mark_value_bits_unavailable (v, offset, this_size_bits);
+ /* Only copy data if valid. */
+ if (!optim && !unavail && !check_optimized)
copy_bitwise (v_contents, offset,
buffer.data (), bits_to_skip % 8,
this_size_bits, bits_big_endian);
@@ -271,9 +356,8 @@ rw_pieced_value (value *v, value *from, bool check_optimized)
{
/* Data is copied non-byte-aligned into the register.
Need some bits from original register value. */
- get_frame_register_bytes (frame, gdb_regnum,
- bits_to_skip / 8,
- buffer, &optim, &unavail);
+ read_from_register (frame, gdb_regnum, bits_to_skip / 8,
+ buffer, &optim, &unavail);
if (optim)
throw_error (OPTIMIZED_OUT_ERROR,
_("Can't do read-modify-write to "
@@ -289,9 +373,8 @@ rw_pieced_value (value *v, value *from, bool check_optimized)
copy_bitwise (buffer.data (), bits_to_skip % 8,
from_contents, offset,
this_size_bits, bits_big_endian);
- put_frame_register_bytes (frame, gdb_regnum,
- bits_to_skip / 8,
- buffer);
+ write_to_register (frame, gdb_regnum, bits_to_skip / 8,
+ buffer, &optim, &unavail);
}
}
break;
--
2.17.1
next prev parent reply other threads:[~2021-11-05 11:39 UTC|newest]
Thread overview: 38+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-11-05 11:38 [PATCH v4 00/28] Allow location description on the DWARF stack Zoran Zaric
2021-11-05 11:38 ` Zoran Zaric [this message]
2021-12-14 20:34 ` [PATCH v4 01/28] Add new register access interface to expr.c Tom Tromey
2021-11-05 11:38 ` [PATCH v4 02/28] Add new memory " Zoran Zaric
2021-12-14 20:42 ` Tom Tromey
2021-11-05 11:38 ` [PATCH v4 03/28] Add new classes that model DWARF stack element Zoran Zaric
2021-12-14 21:10 ` Tom Tromey
2022-01-12 10:23 ` Zoran Zaric
2021-11-05 11:38 ` [PATCH v4 04/28] Add to_location method to dwarf_value class Zoran Zaric
2021-12-14 21:16 ` Tom Tromey
2022-01-12 10:51 ` Zoran Zaric
2021-11-05 11:38 ` [PATCH v4 05/28] Add to_value method to dwarf_location class Zoran Zaric
2021-12-14 21:34 ` Tom Tromey
2022-01-12 12:14 ` Zoran Zaric
2022-01-12 18:42 ` Zoran Zaric
2021-11-05 11:38 ` [PATCH v4 06/28] Add read method to location description classes Zoran Zaric
2021-11-05 11:38 ` [PATCH v4 07/28] Add write " Zoran Zaric
2021-11-05 11:38 ` [PATCH v4 08/28] Add deref " Zoran Zaric
2021-11-05 11:38 ` [PATCH v4 09/28] Add read_from_gdb_value method to dwarf_location Zoran Zaric
2021-11-05 11:38 ` [PATCH v4 10/28] Add write_to_gdb_value " Zoran Zaric
2021-11-05 11:38 ` [PATCH v4 11/28] Add is_implicit_ptr_at " Zoran Zaric
2021-11-05 11:38 ` [PATCH v4 12/28] Add indirect_implicit_ptr to dwarf_location class Zoran Zaric
2021-11-05 11:38 ` [PATCH v4 13/28] Add is_optimized_out " Zoran Zaric
2021-11-05 11:38 ` [PATCH v4 14/28] Add new computed struct value callback interface Zoran Zaric
2021-11-05 11:38 ` [PATCH v4 15/28] Add to_gdb_value method to DWARF entry class Zoran Zaric
2021-11-05 11:38 ` [PATCH v4 16/28] Change DWARF stack to use new dwarf_entry classes Zoran Zaric
2021-11-05 11:38 ` [PATCH v4 17/28] Remove old computed struct value callbacks Zoran Zaric
2021-11-05 11:38 ` [PATCH v4 18/28] Comments cleanup between expr.h and expr.c Zoran Zaric
2021-11-05 11:38 ` [PATCH v4 19/28] Remove dwarf_expr_context from expr.h interface Zoran Zaric
2021-11-05 11:38 ` [PATCH v4 20/28] Move read_addr_from_reg function to frame.c Zoran Zaric
2021-11-05 11:38 ` [PATCH v4 21/28] Add frame info check to DW_OP_reg operations Zoran Zaric
2021-11-05 11:38 ` [PATCH v4 22/28] Remove DWARF expression composition check Zoran Zaric
2021-11-05 11:38 ` [PATCH v4 23/28] Add support for any location description in CFI Zoran Zaric
2021-11-05 11:38 ` [PATCH v4 24/28] Add DWARF operations for byte and bit offset Zoran Zaric
2021-11-05 11:38 ` [PATCH v4 25/28] Add support for DW_OP_LLVM_undefined operation Zoran Zaric
2021-11-05 11:38 ` [PATCH v4 26/28] Add support for nested composite locations Zoran Zaric
2021-11-05 11:38 ` [PATCH v4 27/28] Add DW_OP_LLVM_extend DWARF operation Zoran Zaric
2021-11-05 11:38 ` [PATCH v4 28/28] Add DW_OP_LLVM_select_bit_piece " 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=20211105113849.118800-2-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).