aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Tromey <tromey@adacore.com>2025-04-16 14:58:06 -0600
committerTom Tromey <tromey@adacore.com>2025-05-06 09:01:54 -0600
commit800f6f5f700587de5a4175df4aa974dabf5974d7 (patch)
tree67da71bb1591eb46c4d28f1f812f0ff3fb6d0513
parentb4b312d152318e9d56066074d19d5029cb97914f (diff)
downloadbinutils-800f6f5f700587de5a4175df4aa974dabf5974d7.zip
binutils-800f6f5f700587de5a4175df4aa974dabf5974d7.tar.gz
binutils-800f6f5f700587de5a4175df4aa974dabf5974d7.tar.bz2
Add resolve_dynamic_field
The final patch in this series will change one dynamic property approach to use a struct field rather than an offset and a field type. This is convenient because the reference in DWARF is indeed to a field -- and this approach lets us reuse the field-extraction logic that already exists in gdb. However, the field in question may have dynamic properties which must be resolved before it can be used. This patch prepares for this by introducing a separate resolve_dynamic_field function. This patch should cause no visible changes to behavior.
-rw-r--r--gdb/gdbtypes.c92
-rw-r--r--gdb/gdbtypes.h12
2 files changed, 62 insertions, 42 deletions
diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c
index adb4e72..0f01c97 100644
--- a/gdb/gdbtypes.c
+++ b/gdb/gdbtypes.c
@@ -2676,6 +2676,55 @@ compute_variant_fields (struct type *type,
}
}
+/* See gdbtypes.h. */
+
+void
+resolve_dynamic_field (struct field &field,
+ const property_addr_info *addr_stack,
+ const frame_info_ptr &frame)
+{
+ gdb_assert (!field.is_static ());
+
+ if (field.loc_kind () == FIELD_LOC_KIND_DWARF_BLOCK)
+ {
+ struct dwarf2_property_baton baton;
+ baton.property_type = lookup_pointer_type (field.type ());
+ baton.locexpr = *field.loc_dwarf_block ();
+
+ struct dynamic_prop prop;
+ prop.set_locexpr (&baton);
+
+ CORE_ADDR vals[1] = {addr_stack->addr};
+ CORE_ADDR addr;
+ if (dwarf2_evaluate_property (&prop, frame, addr_stack, &addr, vals))
+ field.set_loc_bitpos (TARGET_CHAR_BIT * (addr - addr_stack->addr));
+ }
+
+ /* As we know this field is not a static field, the field's
+ field_loc_kind should be FIELD_LOC_KIND_BITPOS. Verify
+ this is the case, but only trigger a simple error rather
+ than an internal error if that fails. While failing
+ that verification indicates a bug in our code, the error
+ is not severe enough to suggest to the user he stops
+ his debugging session because of it. */
+ if (field.loc_kind () != FIELD_LOC_KIND_BITPOS)
+ error (_("Cannot determine struct field location"
+ " (invalid location kind)"));
+
+ struct property_addr_info pinfo;
+ pinfo.type = check_typedef (field.type ());
+ size_t offset = field.loc_bitpos () / TARGET_CHAR_BIT;
+ pinfo.valaddr = addr_stack->valaddr;
+ if (!pinfo.valaddr.empty ())
+ pinfo.valaddr = pinfo.valaddr.slice (offset);
+ pinfo.addr = addr_stack->addr + offset;
+ pinfo.next = addr_stack;
+
+ field.set_type (resolve_dynamic_type_internal (field.type (),
+ &pinfo, frame, false));
+ gdb_assert (field.loc_kind () == FIELD_LOC_KIND_BITPOS);
+}
+
/* Resolve dynamic bounds of members of the struct TYPE to static
bounds. ADDR_STACK is a stack of struct property_addr_info to
be used if needed during the dynamic resolution. */
@@ -2710,52 +2759,11 @@ resolve_dynamic_struct (struct type *type,
for (i = 0; i < resolved_type->num_fields (); ++i)
{
unsigned new_bit_length;
- struct property_addr_info pinfo;
if (resolved_type->field (i).is_static ())
continue;
- if (resolved_type->field (i).loc_kind () == FIELD_LOC_KIND_DWARF_BLOCK)
- {
- struct dwarf2_property_baton baton;
- baton.property_type
- = lookup_pointer_type (resolved_type->field (i).type ());
- baton.locexpr = *resolved_type->field (i).loc_dwarf_block ();
-
- struct dynamic_prop prop;
- prop.set_locexpr (&baton);
-
- CORE_ADDR vals[1] = { addr_stack->addr };
- CORE_ADDR addr;
- if (dwarf2_evaluate_property (&prop, frame, addr_stack, &addr, vals))
- resolved_type->field (i).set_loc_bitpos
- (TARGET_CHAR_BIT * (addr - addr_stack->addr));
- }
-
- /* As we know this field is not a static field, the field's
- field_loc_kind should be FIELD_LOC_KIND_BITPOS. Verify
- this is the case, but only trigger a simple error rather
- than an internal error if that fails. While failing
- that verification indicates a bug in our code, the error
- is not severe enough to suggest to the user he stops
- his debugging session because of it. */
- if (resolved_type->field (i).loc_kind () != FIELD_LOC_KIND_BITPOS)
- error (_("Cannot determine struct field location"
- " (invalid location kind)"));
-
- pinfo.type = check_typedef (resolved_type->field (i).type ());
- size_t offset = resolved_type->field (i).loc_bitpos () / TARGET_CHAR_BIT;
- pinfo.valaddr = addr_stack->valaddr;
- if (!pinfo.valaddr.empty ())
- pinfo.valaddr = pinfo.valaddr.slice (offset);
- pinfo.addr = addr_stack->addr + offset;
- pinfo.next = addr_stack;
-
- resolved_type->field (i).set_type
- (resolve_dynamic_type_internal (resolved_type->field (i).type (),
- &pinfo, frame, false));
- gdb_assert (resolved_type->field (i).loc_kind ()
- == FIELD_LOC_KIND_BITPOS);
+ resolve_dynamic_field (resolved_type->field (i), addr_stack, frame);
new_bit_length = resolved_type->field (i).loc_bitpos ();
if (resolved_type->field (i).bitsize () != 0)
diff --git a/gdb/gdbtypes.h b/gdb/gdbtypes.h
index 5ee9deb..f973ba6 100644
--- a/gdb/gdbtypes.h
+++ b/gdb/gdbtypes.h
@@ -2629,6 +2629,18 @@ extern struct type *resolve_dynamic_type
"dynamic". */
extern bool is_dynamic_type (struct type *type);
+/* Resolve any dynamic components of FIELD. FIELD is updated.
+ ADDR_STACK and FRAME are used where necessary to supply information
+ for the resolution process; see resolve_dynamic_type.
+ Specifically, after calling this, the field's bit position will be
+ a constant, and the field's type will not have dynamic properties.
+
+ This function assumes that FIELD is not a static field. */
+
+extern void resolve_dynamic_field (struct field &field,
+ const struct property_addr_info *addr_stack,
+ const frame_info_ptr &frame);
+
extern struct type *check_typedef (struct type *);
extern void check_stub_method_group (struct type *, int);