[PATCH 33/43] Remove old computed struct value callbacks

Zoran Zaric via Gdb-patches
2021-03-01T14:47:56Z

After changing the DWARF stack to use the new DWARF entry based
classes, the previous computed struct value callback
infrastructure is not used anymore and can be removed.

gdb/ChangeLog:

* dwarf2/expr.c (struct piece_closure): Remove structure.
(rw_pieced_value): Remove unused function.
(read_pieced_value): Remove unused function.
(write_pieced_value): Remove unused function.
(check_pieced_synthetic_pointer): Remove unused function.
(indirect_pieced_value): Remove unused function.
(coerce_pieced_ref): Remove unused function.
(copy_pieced_value_closure): Remove unused function.
(free_pieced_value_closure): Remove unused function.
* dwarf2/expr.h (class dwarf_entry): New declaration.
(struct dwarf_expr_piece): Remove structure.
(enum dwarf_value_location): Remove enumeration.
---
gdb/dwarf2/expr.c | 519 ----------------------------------------------
gdb/dwarf2/expr.h | 72 -------
2 files changed, 591 deletions(-)

diff --git a/gdb/dwarf2/expr.c b/gdb/dwarf2/expr.c
index d51366007ab..e45a7755ec5 100644
--- a/gdb/dwarf2/expr.c
+++ b/gdb/dwarf2/expr.c
@@ -2194,525 +2194,6 @@ gdb_value_to_dwarf_entry (struct gdbarch *arch, struct value *value)
}
}

-struct piece_closure
-{
- /* Reference count. */
- int refc = 0;
-
- /* The objfile from which this closure's expression came. */
- dwarf2_per_objfile *per_objfile = nullptr;
-
- /* The CU from which this closure's expression came. */
- struct dwarf2_per_cu_data *per_cu = NULL;
-
- /* The pieces describing this variable. */
- std::vector<dwarf_expr_piece> pieces;
-
- /* Frame ID of frame to which a register value is relative, used
- only by DWARF_VALUE_REGISTER. */
- struct frame_id frame_id;
-};
-
-/* Read or write a pieced value V. If FROM != NULL, operate in "write
- mode": copy FROM into the pieces comprising V. If FROM == NULL,
- operate in "read mode": fetch the contents of the (lazy) value V by
- composing it from its pieces. */
-
-static void
-rw_pieced_value (struct value *v, struct value *from)
-{
- int i;
- LONGEST offset = 0, max_offset;
- ULONGEST bits_to_skip;
- gdb_byte *v_contents;
- const gdb_byte *from_contents;
- struct piece_closure *c
- = (struct piece_closure *) value_computed_closure (v);
- gdb::byte_vector buffer;
- bool bits_big_endian = type_byte_order (value_type (v)) == BFD_ENDIAN_BIG;
-
- if (from != NULL)
- {
- from_contents = value_contents (from);
- v_contents = NULL;
- }
- else
- {
- if (value_type (v) != value_enclosing_type (v))
- internal_error (__FILE__, __LINE__,
- _("Should not be able to create a lazy value with "
- "an enclosing type"));
- v_contents = value_contents_raw (v);
- from_contents = NULL;
- }
-
- bits_to_skip = 8 * value_offset (v);
- if (value_bitsize (v))
- {
- bits_to_skip += (8 * value_offset (value_parent (v))
- + value_bitpos (v));
- if (from != NULL
- && (type_byte_order (value_type (from))
- == BFD_ENDIAN_BIG))
- {
- /* Use the least significant bits of FROM. */
- max_offset = 8 * TYPE_LENGTH (value_type (from));
- offset = max_offset - value_bitsize (v);
- }
- else
- max_offset = value_bitsize (v);
- }
- else
- max_offset = 8 * TYPE_LENGTH (value_type (v));
-
- /* Advance to the first non-skipped piece. */
- for (i = 0; i < c->pieces.size () && bits_to_skip >= c->pieces[i].size; i++)
- bits_to_skip -= c->pieces[i].size;
-
- for (; i < c->pieces.size () && offset < max_offset; i++)
- {
- struct dwarf_expr_piece *p = &c->pieces[i];
- size_t this_size_bits, this_size;
-
- this_size_bits = p->size - bits_to_skip;
- if (this_size_bits > max_offset - offset)
- this_size_bits = max_offset - offset;
-
- switch (p->location)
- {
- case DWARF_VALUE_REGISTER:
- {
- struct frame_info *frame = frame_find_by_id (c->frame_id);
- struct gdbarch *arch = get_frame_arch (frame);
- int gdb_regnum = dwarf_reg_to_regnum_or_error (arch, p->v.regno);
- ULONGEST reg_bits = 8 * register_size (arch, gdb_regnum);
- int optim, unavail;
-
- if (gdbarch_byte_order (arch) == BFD_ENDIAN_BIG
- && p->offset + p->size < reg_bits)
- {
- /* Big-endian, and we want less than full size. */
- bits_to_skip += reg_bits - (p->offset + p->size);
- }
- else
- bits_to_skip += p->offset;
-
- this_size = bits_to_bytes (bits_to_skip, this_size_bits);
- buffer.resize (this_size);
-
- if (from == NULL)
- {
- /* Read mode. */
- read_from_register (frame, gdb_regnum, bits_to_skip / 8,
- buffer, &optim, &unavail);
-
- if (optim)
- mark_value_bits_optimized_out (v, offset, this_size_bits);
- if (unavail)
- mark_value_bits_unavailable (v, offset, this_size_bits);
- /* Only copy data if valid. */
- if (!optim && !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)
- {
- /* Data is copied non-byte-aligned into the register.
- Need some bits from original register value. */
- 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 "
- "update bitfield; containing word "
- "has been optimized out"));
- if (unavail)
- throw_error (NOT_AVAILABLE_ERROR,
- _("Can't do read-modify-write to "
- "update bitfield; containing word "
- "is unavailable"));
- }
-
- copy_bitwise (buffer.data (), bits_to_skip % 8,
- from_contents, offset,
- this_size_bits, bits_big_endian);
- write_to_register (frame, gdb_regnum, bits_to_skip / 8,
- buffer, &optim, &unavail);
- }
- }
- break;
-
- case DWARF_VALUE_MEMORY:
- {
- 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 != NULL)
- write_to_memory (start_addr, (from_contents + offset / 8),
- this_size_bits / 8, in_stack_memory,
- &unavail);
- else
- read_from_memory (start_addr, (v_contents + offset / 8),
- this_size_bits / 8, in_stack_memory,
- &unavail);
- }
- else
- {
- this_size = bits_to_bytes (bits_to_skip, this_size_bits);
- buffer.resize (this_size);
-
- if (from == NULL)
- {
- /* 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)
- {
- 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);
- }
- }
-
- if (!unavail)
- {
- 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);
- }
- }
- }
-
- 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;
-
- case DWARF_VALUE_STACK:
- {
- if (from != NULL)
- {
- mark_value_bits_optimized_out (v, offset, this_size_bits);
- break;
- }
-
- gdbarch *objfile_gdbarch = c->per_objfile->objfile->arch ();
- ULONGEST stack_value_size_bits
- = 8 * TYPE_LENGTH (value_type (p->v.value));
-
- /* Use zeroes if piece reaches beyond stack value. */
- if (p->offset + p->size > stack_value_size_bits)
- break;
-
- /* Piece is anchored at least significant bit end. */
- if (gdbarch_byte_order (objfile_gdbarch) == BFD_ENDIAN_BIG)
- bits_to_skip += stack_value_size_bits - p->offset - p->size;
- else
- bits_to_skip += p->offset;
-
- copy_bitwise (v_contents, offset,
- value_contents_all (p->v.value),
- bits_to_skip,
- this_size_bits, bits_big_endian);
- }
- break;
-
- case DWARF_VALUE_LITERAL:
- {
- if (from != NULL)
- {
- mark_value_bits_optimized_out (v, offset, this_size_bits);
- break;
- }
-
- ULONGEST literal_size_bits = 8 * p->v.literal.length;
- size_t n = this_size_bits;
-
- /* Cut off at the end of the implicit value. */
- bits_to_skip += p->offset;
- if (bits_to_skip >= literal_size_bits)
- break;
- if (n > literal_size_bits - bits_to_skip)
- n = literal_size_bits - bits_to_skip;
-
- copy_bitwise (v_contents, offset,
- p->v.literal.data, bits_to_skip,
- n, bits_big_endian);
- }
- break;
-
- case DWARF_VALUE_IMPLICIT_POINTER:
- if (from != NULL)
- {
- mark_value_bits_optimized_out (v, offset, this_size_bits);
- break;
- }
-
- /* These bits show up as zeros -- but do not cause the value to
- be considered optimized-out. */
- break;
-
- case DWARF_VALUE_OPTIMIZED_OUT:
- mark_value_bits_optimized_out (v, offset, this_size_bits);
- break;
-
- default:
- internal_error (__FILE__, __LINE__, _("invalid location type"));
- }
-
- offset += this_size_bits;
- bits_to_skip = 0;
- }
-}
-
-static void
-read_pieced_value (struct value *v)
-{
- rw_pieced_value (v, NULL);
-}
-
-static void
-write_pieced_value (struct value *to, struct value *from)
-{
- rw_pieced_value (to, from);
-}
-
-/* An implementation of an lval_funcs method to see whether a value is
- a synthetic pointer. */
-
-static int
-check_pieced_synthetic_pointer (const struct value *value, LONGEST bit_offset,
- int bit_length)
-{
- struct piece_closure *c
- = (struct piece_closure *) value_computed_closure (value);
- int i;
-
- bit_offset += 8 * value_offset (value);
- if (value_bitsize (value))
- bit_offset += value_bitpos (value);
-
- for (i = 0; i < c->pieces.size () && bit_length > 0; i++)
- {
- struct dwarf_expr_piece *p = &c->pieces[i];
- size_t this_size_bits = p->size;
-
- if (bit_offset > 0)
- {
- if (bit_offset >= this_size_bits)
- {
- bit_offset -= this_size_bits;
- continue;
- }
-
- bit_length -= this_size_bits - bit_offset;
- bit_offset = 0;
- }
- else
- bit_length -= this_size_bits;
-
- if (p->location != DWARF_VALUE_IMPLICIT_POINTER)
- return 0;
- }
-
- return 1;
-}
-
-/* An implementation of an lval_funcs method to indirect through a
- pointer. This handles the synthetic pointer case when needed. */
-
-static struct value *
-indirect_pieced_value (struct value *value)
-{
- struct piece_closure *c
- = (struct piece_closure *) value_computed_closure (value);
- struct type *type;
- struct frame_info *frame;
- int i, bit_length;
- LONGEST bit_offset;
- struct dwarf_expr_piece *piece = NULL;
- LONGEST byte_offset;
- enum bfd_endian byte_order;
-
- type = check_typedef (value_type (value));
- if (type->code () != TYPE_CODE_PTR)
- return NULL;
-
- bit_length = 8 * TYPE_LENGTH (type);
- bit_offset = 8 * value_offset (value);
- if (value_bitsize (value))
- bit_offset += value_bitpos (value);
-
- for (i = 0; i < c->pieces.size () && bit_length > 0; i++)
- {
- struct dwarf_expr_piece *p = &c->pieces[i];
- size_t this_size_bits = p->size;
-
- if (bit_offset > 0)
- {
- if (bit_offset >= this_size_bits)
- {
- bit_offset -= this_size_bits;
- continue;
- }
-
- bit_length -= this_size_bits - bit_offset;
- bit_offset = 0;
- }
- else
- bit_length -= this_size_bits;
-
- if (p->location != DWARF_VALUE_IMPLICIT_POINTER)
- return NULL;
-
- if (bit_length != 0)
- error (_("Invalid use of DW_OP_implicit_pointer"));
-
- piece = p;
- break;
- }
-
- gdb_assert (piece != NULL && c->per_cu != nullptr);
- frame = get_selected_frame (_("No frame selected."));
-
- /* This is an offset requested by GDB, such as value subscripts.
- However, due to how synthetic pointers are implemented, this is
- always presented to us as a pointer type. This means we have to
- sign-extend it manually as appropriate. Use raw
- extract_signed_integer directly rather than value_as_address and
- sign extend afterwards on architectures that would need it
- (mostly everywhere except MIPS, which has signed addresses) as
- the later would go through gdbarch_pointer_to_address and thus
- return a CORE_ADDR with high bits set on architectures that
- encode address spaces and other things in CORE_ADDR. */
- byte_order = gdbarch_byte_order (get_frame_arch (frame));
- byte_offset = extract_signed_integer (value_contents (value),
- TYPE_LENGTH (type), byte_order);
- byte_offset += piece->v.ptr.offset;
-
- return indirect_synthetic_pointer (piece->v.ptr.die_sect_off,
- byte_offset, c->per_cu,
- c->per_objfile, frame, type);
-}
-
-/* Implementation of the coerce_ref method of lval_funcs for synthetic C++
- references. */
-
-static struct value *
-coerce_pieced_ref (const struct value *value)
-{
- struct type *type = check_typedef (value_type (value));
-
- if (value_bits_synthetic_pointer (value, value_embedded_offset (value),
- TARGET_CHAR_BIT * TYPE_LENGTH (type)))
- {
- const struct piece_closure *closure
- = (struct piece_closure *) value_computed_closure (value);
- struct frame_info *frame
- = get_selected_frame (_("No frame selected."));
-
- /* gdb represents synthetic pointers as pieced values with a single
- piece. */
- gdb_assert (closure != NULL);
- gdb_assert (closure->pieces.size () == 1);
-
- return indirect_synthetic_pointer
- (closure->pieces[0].v.ptr.die_sect_off,
- closure->pieces[0].v.ptr.offset,
- closure->per_cu, closure->per_objfile, frame, type);
- }
- else
- {
- /* Else: not a synthetic reference; do nothing. */
- return NULL;
- }
-}
-
-static void *
-copy_pieced_value_closure (const struct value *v)
-{
- struct piece_closure *c
- = (struct piece_closure *) value_computed_closure (v);
-
- ++c->refc;
- return c;
-}
-
-static void
-free_pieced_value_closure (struct value *v)
-{
- struct piece_closure *c
- = (struct piece_closure *) value_computed_closure (v);
-
- --c->refc;
- if (c->refc == 0)
- {
- for (dwarf_expr_piece &p : c->pieces)
- if (p.location == DWARF_VALUE_STACK)
- value_decref (p.v.value);
-
- delete c;
- }
-}
-
-/* Functions for accessing a variable described by DW_OP_piece. */
-static const struct lval_funcs pieced_value_funcs = {
- read_pieced_value,
- write_pieced_value,
- indirect_pieced_value,
- coerce_pieced_ref,
- check_pieced_synthetic_pointer,
- copy_pieced_value_closure,
- free_pieced_value_closure
-};
-
/* Given context CTX, section offset SECT_OFF, and compilation unit
data PER_CU, execute the "variable value" operation on the DIE
found at SECT_OFF. */
diff --git a/gdb/dwarf2/expr.h b/gdb/dwarf2/expr.h
index 2d24f4402db..3c404d8f83c 100644
--- a/gdb/dwarf2/expr.h
+++ b/gdb/dwarf2/expr.h
@@ -28,78 +28,6 @@
class dwarf_entry;
struct dwarf2_per_objfile;

-/* The location of a value. */
-enum dwarf_value_location
-{
- /* The piece is in memory.
- The value on the dwarf stack is its address. */
- DWARF_VALUE_MEMORY,
-
- /* The piece is in a register.
- The value on the dwarf stack is the register number. */
- DWARF_VALUE_REGISTER,
-
- /* The piece is on the dwarf stack. */
- DWARF_VALUE_STACK,
-
- /* The piece is a literal. */
- DWARF_VALUE_LITERAL,
-
- /* The piece was optimized out. */
- DWARF_VALUE_OPTIMIZED_OUT,
-
- /* The piece is an implicit pointer. */
- DWARF_VALUE_IMPLICIT_POINTER
-};
-
-/* A piece of an object, as recorded by DW_OP_piece or DW_OP_bit_piece. */
-struct dwarf_expr_piece
-{
- enum dwarf_value_location location;
-
- union
- {
- struct
- {
- /* This piece's address, for DWARF_VALUE_MEMORY pieces. */
- CORE_ADDR addr;
- /* Non-zero if the piece is known to be in memory and on
- the program's stack. */
- bool in_stack_memory;
- } mem;
-
- /* The piece's register number, for DWARF_VALUE_REGISTER pieces. */
- int regno;
-
- /* The piece's literal value, for DWARF_VALUE_STACK pieces. */
- struct value *value;
-
- struct
- {
- /* A pointer to the data making up this piece,
- for DWARF_VALUE_LITERAL pieces. */
- const gdb_byte *data;
- /* The length of the available data. */
- ULONGEST length;
- } literal;
-
- /* Used for DWARF_VALUE_IMPLICIT_POINTER. */
- struct
- {
- /* The referent DIE from DW_OP_implicit_pointer. */
- sect_offset die_sect_off;
- /* The byte offset into the resulting data. */
- LONGEST offset;
- } ptr;
- } v;
-
- /* The length of the piece, in bits. */
- ULONGEST size;
- /* The piece offset, in bits. */
- ULONGEST offset;
-};
-
-
/* The expression evaluator works with a dwarf_expr_context, describing
its current state and its callbacks. */
struct dwarf_expr_context
--
2.17.1