From: Zoran Zaric Date: Wed, 24 Feb 2021 16:31:10 +0000 (+0000) Subject: Add write_to_gdb_value method to dwarf_location X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=7bd280514ce16294159f988125b9a98029e418c5;p=thirdparty%2Fbinutils-gdb.git Add write_to_gdb_value method to dwarf_location Similar story behind the previous read_from_gdb_value method applies to the new write_to_gdb_value. In the same way, reading the data from a location described and writing that data to a struct value object, can be different from just generic read the data from a buffer (location description read method). To make this distinction clear, a new write_to_gdb_value method is added to classes that derive from location description class. gdb/ChangeLog: * dwarf2/expr.c (dwarf_location::write_to_gdb_value): New method. (dwarf_composite::write_to_gdb_value): New method. --- diff --git a/gdb/dwarf2/expr.c b/gdb/dwarf2/expr.c index e79d57fbfd4..b2fb0099b0e 100644 --- a/gdb/dwarf2/expr.c +++ b/gdb/dwarf2/expr.c @@ -441,6 +441,22 @@ public: LONGEST bits_to_skip, size_t bit_size, size_t location_bit_limit) const; +/* Write data to the VALUE contents from the location specified by the + location description. + + The write operation is performed in the context of a FRAME. + BIT_SIZE is the number of bits to read. VALUE_BIT_OFFSET is a bit + offset into a VALUE content and BITS_TO_SKIP is a bit offset into + the location. 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 read without a FRAME context. */ + virtual void write_to_gdb_value (frame_info *frame, struct value *value, + int value_bit_offset, + LONGEST bits_to_skip, size_t bit_size, + size_t location_bit_limit) const; + protected: /* Architecture of the location. */ gdbarch *m_arch; @@ -483,6 +499,25 @@ dwarf_location::read_from_gdb_value (frame_info *frame, struct value *value, "is unavailable")); } +void +dwarf_location::write_to_gdb_value (frame_info *frame, struct value *value, + int value_bit_offset, + LONGEST bits_to_skip, size_t bit_size, + size_t location_bit_limit) const +{ + int optimized, unavailable; + bool big_endian = type_byte_order (value_type (value)) == BFD_ENDIAN_BIG; + + this->read (frame, value_contents_raw (value).data (), value_bit_offset, + bit_size, bits_to_skip, location_bit_limit, + big_endian, &optimized, &unavailable); + + if (optimized) + mark_value_bits_optimized_out (value, value_bit_offset, bit_size); + if (unavailable) + mark_value_bits_unavailable (value, value_bit_offset, bit_size); +} + /* Value entry found on a DWARF expression evaluation stack. */ class dwarf_value final : public dwarf_entry @@ -1047,6 +1082,12 @@ public: mark_value_bits_optimized_out (value, bits_to_skip, bit_size); } + void write_to_gdb_value (frame_info *frame, struct value *value, + int value_bit_offset, + LONGEST bits_to_skip, size_t bit_size, + size_t location_bit_limit) const override + {} + private: /* Per object file data of the implicit pointer. */ dwarf2_per_objfile *m_per_objfile; @@ -1128,6 +1169,11 @@ public: LONGEST bits_to_skip, size_t bit_size, size_t location_bit_limit) const override; + void write_to_gdb_value (frame_info *frame, struct value *value, + int value_bit_offset, + LONGEST bits_to_skip, size_t bit_size, + size_t location_bit_limit) const override; + private: /* Composite piece that contains a piece location description and it's size. */ @@ -1281,6 +1327,49 @@ dwarf_composite::read_from_gdb_value (frame_info *frame, struct value *value, } } +void +dwarf_composite::write_to_gdb_value (frame_info *frame, struct value *value, + int value_bit_offset, + LONGEST bits_to_skip, size_t bit_size, + size_t location_bit_limit) const +{ + ULONGEST total_bits_to_skip + = bits_to_skip + HOST_CHAR_BIT * m_offset + m_bit_suboffset; + ULONGEST remaining_bit_size = bit_size; + ULONGEST bit_offset = value_bit_offset; + unsigned int pieces_num = m_pieces.size (); + unsigned int i; + + /* Advance to the first non-skipped piece. */ + for (i = 0; i < pieces_num; i++) + { + ULONGEST 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++) + { + const dwarf_location &location = *m_pieces[i].location; + ULONGEST piece_bit_size = m_pieces[i].size; + size_t this_bit_size = piece_bit_size - total_bits_to_skip; + + if (this_bit_size > remaining_bit_size) + this_bit_size = remaining_bit_size; + + location.write_to_gdb_value (frame, value, bit_offset, + total_bits_to_skip, this_bit_size, + piece_bit_size); + + bit_offset += this_bit_size; + remaining_bit_size -= this_bit_size; + total_bits_to_skip = 0; + } +} + struct piece_closure { /* Reference count. */