From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from lndn.lancelotsix.com (vps-42846194.vps.ovh.net [IPv6:2001:41d0:801:2000::2400]) by sourceware.org (Postfix) with ESMTPS id 71F113858C3A for ; Mon, 25 Oct 2021 20:21:08 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 71F113858C3A Received: from ubuntu.lan (cust120-dsl54.idnet.net [212.69.54.120]) by lndn.lancelotsix.com (Postfix) with ESMTPSA id AC4A3818C0; Mon, 25 Oct 2021 20:21:07 +0000 (UTC) Date: Mon, 25 Oct 2021 20:21:03 +0000 From: Lancelot SIX To: Zoran Zaric Cc: gdb-patches@sourceware.org Subject: Re: [PATCH v3 07/28] Add write method to location description classes Message-ID: <20211025201954.byy37iugzedp664l@ubuntu.lan> References: <20211014093235.69756-1-zoran.zaric@amd.com> <20211014093235.69756-8-zoran.zaric@amd.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20211014093235.69756-8-zoran.zaric@amd.com> X-Greylist: Sender succeeded SMTP AUTH, not delayed by milter-greylist-4.5.11 (lndn.lancelotsix.com [0.0.0.0]); Mon, 25 Oct 2021 20:21:07 +0000 (UTC) X-Spam-Status: No, score=-10.2 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_SBL_CSS, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 25 Oct 2021 20:21:11 -0000 On Thu, Oct 14, 2021 at 10:32:14AM +0100, Zoran Zaric via Gdb-patches wrote: > From: Zoran Zaric > > After adding the interface for reading from the location, it also > makes sense to add the interface for writing. > > To be clear, DWARF standard doesn't have a concept of writting to a > location, but because of the way how callback functions are used to > interact with the opeque implementation of the computed struct value Hi, Probably a small typo here. opeque -> opaque ? Best, Lancelot. > objects, the choice was to either use the existing DWARF entry classes > or to invent another way of representing the complexity behind those > computed objects. > > Adding a write method seems to be a simpler option of the two. > > gdb/ChangeLog: > > * dwarf2/expr.c (dwarf_location::write): New method. > (dwarf_undefined::write): New method. > (dwarf_memory::write): New method. > (dwarf_register::write): New method. > (dwarf_implicit::write): New method. > (dwarf_implicit_pointer::write): New method. > (dwarf_composite::write): New method. > --- > gdb/dwarf2/expr.c | 211 ++++++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 211 insertions(+) > > diff --git a/gdb/dwarf2/expr.c b/gdb/dwarf2/expr.c > index 3f3e09db7cc..83a2db028ca 100644 > --- a/gdb/dwarf2/expr.c > +++ b/gdb/dwarf2/expr.c > @@ -400,6 +400,28 @@ class dwarf_location : public dwarf_entry > bool big_endian, int *optimized, > int *unavailable) const = 0; > > + /* Write contents to a described location. > + > + The write operation is performed in the context of a FRAME. > + BIT_SIZE is the number of bits written. The data written is > + copied from the caller-managed BUF buffer. BIG_ENDIAN defines an > + endianness of the target. BITS_TO_SKIP is a bit offset into the > + location and BUF_BIT_OFFSET is buffer BUF's bit offset. > + LOCATION_BIT_LIMIT is a maximum number of bits that location can > + hold, where value zero signifies that there is no such > + restriction. > + > + Note that some location types can be written without a FRAME > + context. > + > + If the location is optimized out or unavailable, the OPTIMIZED and > + UNAVAILABLE outputs are set. */ > + virtual void write (frame_info *frame, const gdb_byte *buf, > + int buf_bit_offset, size_t bit_size, > + LONGEST bits_to_skip, size_t location_bit_limit, > + bool big_endian, int *optimized, > + int *unavailable) const = 0; > + > protected: > /* Architecture of the location. */ > gdbarch *m_arch; > @@ -485,6 +507,14 @@ class dwarf_undefined final : public dwarf_location > *unavailable = 0; > *optimized = 1; > } > + > + void write (frame_info *frame, const gdb_byte *buf, int buf_bit_offset, > + size_t bit_size, LONGEST bits_to_skip, size_t location_bit_limit, > + bool big_endian, int *optimized, int *unavailable) const override > + { > + *unavailable = 0; > + *optimized = 1; > + } > }; > > class dwarf_memory final : public dwarf_location > @@ -506,6 +536,11 @@ class dwarf_memory final : public dwarf_location > size_t location_bit_limit, bool big_endian, > int *optimized, int *unavailable) const override; > > + void write (frame_info *frame, const gdb_byte *buf, > + int buf_bit_offset, size_t bit_size, LONGEST bits_to_skip, > + size_t location_bit_limit, bool big_endian, > + int *optimized, int *unavailable) const override; > + > private: > /* True if the location belongs to a stack memory region. */ > bool m_stack; > @@ -572,6 +607,62 @@ dwarf_memory::read (frame_info *frame, gdb_byte *buf, > } > } > > +void > +dwarf_memory::write (frame_info *frame, const gdb_byte *buf, > + int buf_bit_offset, size_t bit_size, > + LONGEST bits_to_skip, size_t location_bit_limit, > + bool big_endian, int *optimized, int *unavailable) const > +{ > + LONGEST total_bits_to_skip = bits_to_skip; > + CORE_ADDR start_address > + = m_offset + (m_bit_suboffset + total_bits_to_skip) / HOST_CHAR_BIT; > + gdb::byte_vector temp_buf; > + > + total_bits_to_skip += m_bit_suboffset; > + *optimized = 0; > + > + if (total_bits_to_skip % HOST_CHAR_BIT == 0 > + && bit_size % HOST_CHAR_BIT == 0 > + && buf_bit_offset % HOST_CHAR_BIT == 0) > + { > + /* Everything is byte-aligned; no buffer needed. */ > + write_to_memory (start_address, buf + buf_bit_offset / HOST_CHAR_BIT, > + bit_size / HOST_CHAR_BIT, m_stack, unavailable); > + } > + else > + { > + LONGEST this_size = bits_to_bytes (total_bits_to_skip, bit_size); > + temp_buf.resize (this_size); > + > + if (total_bits_to_skip % HOST_CHAR_BIT != 0 > + || bit_size % HOST_CHAR_BIT != 0) > + { > + if (this_size <= HOST_CHAR_BIT) > + /* Perform a single read for small sizes. */ > + read_from_memory (start_address, temp_buf.data (), > + this_size, m_stack, unavailable); > + else > + { > + /* Only the first and last bytes can possibly have > + any bits reused. */ > + read_from_memory (start_address, temp_buf.data (), > + 1, m_stack, unavailable); > + > + if (!*unavailable) > + read_from_memory (start_address + this_size - 1, > + &temp_buf[this_size - 1], 1, > + m_stack, unavailable); > + } > + } > + > + copy_bitwise (temp_buf.data (), total_bits_to_skip % HOST_CHAR_BIT, > + buf, buf_bit_offset, bit_size, big_endian); > + > + write_to_memory (start_address, temp_buf.data (), this_size, > + m_stack, unavailable); > + } > +} > + > /* Register location description entry. */ > > class dwarf_register final : public dwarf_location > @@ -585,6 +676,11 @@ class dwarf_register final : public dwarf_location > size_t bit_size, LONGEST bits_to_skip, size_t location_bit_limit, > bool big_endian, int *optimized, int *unavailable) const override; > > + void write (frame_info *frame, const gdb_byte *buf, > + int buf_bit_offset, size_t bit_size, LONGEST bits_to_skip, > + size_t location_bit_limit, bool big_endian, > + int *optimized, int *unavailable) const override; > + > private: > /* DWARF register number. */ > unsigned int m_regnum; > @@ -631,6 +727,53 @@ dwarf_register::read (frame_info *frame, gdb_byte *buf, > total_bits_to_skip % HOST_CHAR_BIT, bit_size, big_endian); > } > > +void > +dwarf_register::write (frame_info *frame, const gdb_byte *buf, > + int buf_bit_offset, size_t bit_size, > + LONGEST bits_to_skip, size_t location_bit_limit, > + bool big_endian, int *optimized, int *unavailable) const > +{ > + LONGEST total_bits_to_skip = bits_to_skip; > + size_t write_bit_limit = location_bit_limit; > + gdbarch *frame_arch = get_frame_arch (frame); > + int reg = dwarf_reg_to_regnum_or_error (frame_arch, m_regnum); > + ULONGEST reg_bits = HOST_CHAR_BIT * register_size (frame_arch, reg); > + gdb::byte_vector temp_buf; > + > + if (frame == NULL) > + internal_error (__FILE__, __LINE__, _("invalid frame information")); > + > + if (big_endian) > + { > + if (!write_bit_limit || reg_bits <= write_bit_limit) > + write_bit_limit = bit_size; > + > + total_bits_to_skip += reg_bits - (m_offset * HOST_CHAR_BIT > + + m_bit_suboffset + write_bit_limit); > + } > + else > + total_bits_to_skip += m_offset * HOST_CHAR_BIT + m_bit_suboffset; > + > + LONGEST this_size = bits_to_bytes (total_bits_to_skip, bit_size); > + temp_buf.resize (this_size); > + > + if (total_bits_to_skip % HOST_CHAR_BIT != 0 > + || bit_size % HOST_CHAR_BIT != 0) > + { > + /* Contents is copied non-byte-aligned into the register. > + Need some bits from original register value. */ > + read_from_register (frame, reg, > + total_bits_to_skip / HOST_CHAR_BIT, > + temp_buf, optimized, unavailable); > + } > + > + copy_bitwise (temp_buf.data (), total_bits_to_skip % HOST_CHAR_BIT, buf, > + buf_bit_offset, bit_size, big_endian); > + > + write_to_register (frame, reg, total_bits_to_skip / HOST_CHAR_BIT, > + temp_buf, optimized, unavailable); > +} > + > /* Implicit location description entry. Describes a location > description not found on the target but instead saved in a > gdb-allocated buffer. */ > @@ -650,6 +793,15 @@ class dwarf_implicit final : public dwarf_location > size_t bit_size, LONGEST bits_to_skip, size_t location_bit_limit, > bool big_endian, int *optimized, int *unavailable) const override; > > + void write (frame_info *frame, const gdb_byte *buf, > + int buf_bit_offset, size_t bit_size, > + LONGEST bits_to_skip, size_t location_bit_limit, > + bool big_endian, int* optimized, int* unavailable) const override > + { > + *optimized = 1; > + *unavailable = 0; > + } > + > private: > /* Implicit location contents as a stream of bytes in target byte-order. */ > gdb::byte_vector m_contents; > @@ -716,6 +868,15 @@ class dwarf_implicit_pointer final : public dwarf_location > size_t bit_size, LONGEST bits_to_skip, size_t location_bit_limit, > bool big_endian, int *optimized, int *unavailable) const override; > > + void write (frame_info *frame, const gdb_byte *buf, > + int buf_bit_offset, size_t bit_size, LONGEST bits_to_skip, > + size_t location_bit_limit, bool big_endian, > + int* optimized, int* unavailable) const override > + { > + *optimized = 1; > + *unavailable = 0; > + } > + > private: > /* Per object file data of the implicit pointer. */ > dwarf2_per_objfile *m_per_objfile; > @@ -787,6 +948,11 @@ class dwarf_composite final : public dwarf_location > size_t bit_size, LONGEST bits_to_skip, size_t location_bit_limit, > bool big_endian, int *optimized, int *unavailable) const override; > > + void write (frame_info *frame, const gdb_byte *buf, > + int buf_bit_offset, size_t bit_size, LONGEST bits_to_skip, > + size_t location_bit_limit, bool big_endian, > + int *optimized, int *unavailable) const override; > + > private: > /* Composite piece that contains a piece location > description and it's size. */ > @@ -852,6 +1018,51 @@ dwarf_composite::read (frame_info *frame, gdb_byte *buf, > } > } > > +void > +dwarf_composite::write (frame_info *frame, const gdb_byte *buf, > + int buf_bit_offset, size_t bit_size, > + LONGEST bits_to_skip, size_t location_bit_limit, > + bool big_endian, int *optimized, > + int *unavailable) const > +{ > + LONGEST total_bits_to_skip = bits_to_skip; > + unsigned int pieces_num = m_pieces.size (); > + unsigned int i; > + > + total_bits_to_skip += m_offset * HOST_CHAR_BIT + m_bit_suboffset; > + > + /* Skip pieces covered by the write offset. */ > + for (i = 0; i < pieces_num; i++) > + { > + LONGEST piece_bit_size = m_pieces[i].size; > + > + if (total_bits_to_skip < piece_bit_size) > + break; > + > + total_bits_to_skip -= piece_bit_size; > + } > + > + for (; i < pieces_num; i++) > + { > + LONGEST piece_bit_size = m_pieces[i].size; > + LONGEST actual_bit_size = piece_bit_size; > + > + if (actual_bit_size > bit_size) > + actual_bit_size = bit_size; > + > + m_pieces[i].location->write (frame, buf, buf_bit_offset, > + actual_bit_size, total_bits_to_skip, > + piece_bit_size, big_endian, > + optimized, unavailable); > + > + if (bit_size == actual_bit_size || *optimized || *unavailable) > + break; > + > + buf_bit_offset += actual_bit_size; > + bit_size -= actual_bit_size; > + } > +} > + > struct piece_closure > { > /* Reference count. */ > -- > 2.17.1 >