From: Zoran Zaric Date: Thu, 25 Feb 2021 10:36:10 +0000 (+0000) Subject: Add indirect_implicit_ptr to dwarf_location class X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=f10d92ca887e0d51bf458a7f58fac679f33bf9d8;p=thirdparty%2Fbinutils-gdb.git Add indirect_implicit_ptr to dwarf_location class Similarly to the is_implicit_ptr_at method, the existing function callback interface of the computed struct value, requiers a way to apply indirection to an implicit pointer on a given offset of a given length of an underlying location description. This is different than reading from a struct value object (previously described write_to_gdb_value method) in a way that the result of this operation is expected to be a struct value of a pointed source level variable instead of reading the value of that variable. In the same way this is also different operation than the deref method because the deref returns a read value of a given type from that location description. gdb/ChangeLog: * dwarf2/expr.c (dwarf_location::indirect_implicit_ptr): New method. (dwarf_implicit_pointer::indirect_implicit_ptr): New method. (dwarf_composite::indirect_implicit_ptr): New method. --- diff --git a/gdb/dwarf2/expr.c b/gdb/dwarf2/expr.c index a933ca2797d..185324f1d2d 100644 --- a/gdb/dwarf2/expr.c +++ b/gdb/dwarf2/expr.c @@ -465,6 +465,24 @@ public: return false; } + /* Recursive indirecting of the implicit pointer location description + if that location is or encapsulates an implicit pointer. The + operation is performed in a given FRAME context, using the TYPE as + the type of the pointer. Where POINTER_OFFSET is an offset + applied to that implicit pointer location description before the + operation. BIT_OFFSET is a bit offset applied to the location and + BIT_LENGTH is a bit length of the read. + + Indirecting is only performed on the implicit pointer location + description parts of the location. */ + virtual value *indirect_implicit_ptr (frame_info *frame, struct type *type, + LONGEST pointer_offset = 0, + LONGEST bit_offset = 0, + int bit_length = 0) const + { + return nullptr; + } + protected: /* Architecture of the location. */ gdbarch *m_arch; @@ -1101,6 +1119,11 @@ public: return true; } + value *indirect_implicit_ptr (frame_info *frame, struct type *type, + LONGEST pointer_offset = 0, + LONGEST bit_offset = 0, + int bit_length = 0) const override; + private: /* Per object file data of the implicit pointer. */ dwarf2_per_objfile *m_per_objfile; @@ -1153,6 +1176,17 @@ dwarf_implicit_pointer::read (frame_info *frame, gdb_byte *buf, } } +value * +dwarf_implicit_pointer::indirect_implicit_ptr (frame_info *frame, + struct type *type, + LONGEST pointer_offset, + LONGEST bit_offset, + int bit_length) const +{ + return indirect_synthetic_pointer (m_die_offset, m_offset + pointer_offset, + m_per_cu, m_per_objfile, frame, type); +} + /* Composite location description entry. */ class dwarf_composite final : public dwarf_location @@ -1189,6 +1223,11 @@ public: bool is_implicit_ptr_at (LONGEST bit_offset, int bit_length) const override; + value *indirect_implicit_ptr (frame_info *frame, struct type *type, + LONGEST pointer_offset = 0, + LONGEST bit_offset = 0, + int bit_length = 0) const override; + private: /* Composite piece that contains a piece location description and it's size. */ @@ -1422,6 +1461,40 @@ dwarf_composite::is_implicit_ptr_at (LONGEST bit_offset, int bit_length) const return false; } +value * +dwarf_composite::indirect_implicit_ptr (frame_info *frame, struct type *type, + LONGEST pointer_offset, + LONGEST bit_offset, + int bit_length) const +{ + LONGEST total_bit_offset = HOST_CHAR_BIT * m_offset + + m_bit_suboffset + bit_offset; + + /* Advance to the first non-skipped piece. */ + for (const piece &piece : m_pieces) + { + ULONGEST read_bit_length = piece.size; + + if (total_bit_offset >= read_bit_length) + { + total_bit_offset -= read_bit_length; + continue; + } + + read_bit_length -= total_bit_offset; + + if (bit_length < read_bit_length) + read_bit_length = bit_length; + + return piece.location->indirect_implicit_ptr (frame, type, + pointer_offset, + total_bit_offset, + read_bit_length); + } + + return nullptr; +} + struct piece_closure { /* Reference count. */