]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
GDB: Allow passing regcache to resolve_dynamic_type ()
authorThiago Jung Bauermann <thiago.bauermann@linaro.org>
Mon, 28 Apr 2025 01:57:17 +0000 (22:57 -0300)
committerThiago Jung Bauermann <thiago.bauermann@linaro.org>
Thu, 23 Oct 2025 04:17:04 +0000 (01:17 -0300)
When reg_buffer::initialize_variable_size_registers () is called, there
may not be any frame available yet.  On the other hand, the reg_buffer
should already have any register values needed to calculate target
description parameter values and therefore resolve dynamic types.

So allow passing a regcache to resolve_dynamic_type (), and use it in
dwarf2_evaluate_property () when processing a target description
parameter property.

Because initialize_variable_size_registers () is a reg_buffer method,
dwarf2_evaluate_property () can't call tdesc_parameter_value () which is
a readable_regcache method.  So we need to add a
collect_tdesc_parameter () method to reg_buffer and check that the
collected parameter is valid.

gdb/dwarf2/loc.c
gdb/dwarf2/loc.h
gdb/frame.c
gdb/gdbtypes.c
gdb/gdbtypes.h
gdb/gnu-v3-abi.c
gdb/regcache.c
gdb/regcache.h

index 6ab3ca8609ab5329c3c2d780b6efe7d3c23e40b5..a1a71871e7338b6a63cc7d9f5bc275d4755834f3 100644 (file)
@@ -1642,6 +1642,7 @@ dwarf2_locexpr_baton_eval (const struct dwarf2_locexpr_baton *dlbaton,
 bool
 dwarf2_evaluate_property (const dynamic_prop *prop,
                          const frame_info_ptr &initial_frame,
+                         reg_buffer *regcache,
                          const property_addr_info *addr_stack,
                          CORE_ADDR *value,
                          gdb::array_view<CORE_ADDR> push_values)
@@ -1749,7 +1750,7 @@ dwarf2_evaluate_property (const dynamic_prop *prop,
          error (_("cannot find reference address for offset property"));
 
        struct field resolved_field = baton->field;
-       resolve_dynamic_field (resolved_field, pinfo, initial_frame);
+       resolve_dynamic_field (resolved_field, pinfo, initial_frame, regcache);
 
        /* Storage for memory if we need to read it.  */
        gdb::byte_vector memory;
@@ -1797,7 +1798,8 @@ dwarf2_evaluate_property (const dynamic_prop *prop,
 
       case PROP_TDESC_PARAMETER:
        {
-         gdbarch *gdbarch = get_frame_arch (frame);
+         gdbarch *gdbarch = (regcache == nullptr ?
+                             get_frame_arch (frame) : regcache->arch ());
          auto [feature, param_name, element_length] = prop->tdesc_parameter ();
          std::optional<unsigned int> param_id = tdesc_parameter_id (gdbarch,
                                                                     feature,
@@ -1805,7 +1807,21 @@ dwarf2_evaluate_property (const dynamic_prop *prop,
          if (!param_id.has_value ())
            return false;
 
-         return read_frame_tdesc_parameter_unsigned (frame, *param_id, value);
+         if (regcache == nullptr)
+           return read_frame_tdesc_parameter_unsigned (frame, *param_id, value);
+         else
+           {
+             if (regcache->get_tdesc_parameter_status (*param_id) != REG_VALID)
+               return false;
+
+             gdb::byte_vector buf (tdesc_parameter_size (gdbarch, *param_id));
+
+             regcache->collect_tdesc_parameter (*param_id, buf);
+
+             enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+             *value = extract_unsigned_integer (buf, byte_order);
+             return true;
+           }
        }
        break;
     }
index c67232069aea19669f9f01003db97685f5bd20ca..0a9a1a954f20cce8f8c28ba0af704bc7be402edb 100644 (file)
@@ -307,8 +307,10 @@ extern struct value *indirect_synthetic_pointer
    etc.  This means the during evaluation PUSH_VALUES[0] will be at the
    bottom of the stack.  */
 
+struct reg_buffer;
 bool dwarf2_evaluate_property (const struct dynamic_prop *prop,
                               const frame_info_ptr &frame,
+                              reg_buffer *regcache,
                               const property_addr_info *addr_stack,
                               CORE_ADDR *value,
                               gdb::array_view<CORE_ADDR> push_values = {});
index 4ecd25c3763a1eb995db4770943d93bbbcfc33a8..a58e81aea69ad24f09775a09474cd9b1bafe525e 100644 (file)
@@ -3259,7 +3259,8 @@ frame_follow_static_link (const frame_info_ptr &initial_frame)
 
   CORE_ADDR upper_frame_base;
 
-  if (!dwarf2_evaluate_property (static_link, initial_frame, NULL, &upper_frame_base))
+  if (!dwarf2_evaluate_property (static_link, initial_frame, nullptr, nullptr,
+                                &upper_frame_base))
     return {};
 
   /* Now climb up the stack frame until we reach the frame we are interested
index 850e22161b6eb85ac5f263b2b21380e07399c421..2c7f1358a36cbe19139d57e496bb5070d493500b 100644 (file)
@@ -2225,7 +2225,7 @@ is_dynamic_type (struct type *type)
 
 static struct type *resolve_dynamic_type_internal
   (struct type *type, const property_addr_info *addr_stack,
-   const frame_info_ptr &frame, bool top_level);
+   const frame_info_ptr &frame, reg_buffer *regcache, bool top_level);
 
 /* Given a dynamic range type (dyn_range_type) and a stack of
    struct property_addr_info elements, return a static version
@@ -2247,6 +2247,7 @@ static struct type *
 resolve_dynamic_range (struct type *dyn_range_type,
                       const property_addr_info *addr_stack,
                       const frame_info_ptr &frame,
+                      reg_buffer *regcache,
                       int rank, bool resolve_p = true)
 {
   CORE_ADDR value;
@@ -2259,7 +2260,7 @@ resolve_dynamic_range (struct type *dyn_range_type,
   const struct dynamic_prop *prop = &dyn_range_type->bounds ()->low;
   if (resolve_p)
     {
-      if (dwarf2_evaluate_property (prop, frame, addr_stack, &value,
+      if (dwarf2_evaluate_property (prop, frame, regcache, addr_stack, &value,
                                    { (CORE_ADDR) rank }))
        low_bound.set_const_val (value);
       else if (prop->kind () == PROP_UNDEFINED)
@@ -2273,7 +2274,7 @@ resolve_dynamic_range (struct type *dyn_range_type,
   prop = &dyn_range_type->bounds ()->high;
   if (resolve_p)
     {
-      if (dwarf2_evaluate_property (prop, frame, addr_stack, &value,
+      if (dwarf2_evaluate_property (prop, frame, regcache, addr_stack, &value,
                                    { (CORE_ADDR) rank }))
        {
          /* In the case of a vector with tdesc parameter in the range, we
@@ -2305,8 +2306,8 @@ resolve_dynamic_range (struct type *dyn_range_type,
 
   bool byte_stride_p = dyn_range_type->bounds ()->flag_is_byte_stride;
   prop = &dyn_range_type->bounds ()->stride;
-  if (resolve_p && dwarf2_evaluate_property (prop, frame, addr_stack, &value,
-                                            { (CORE_ADDR) rank }))
+  if (resolve_p && dwarf2_evaluate_property (prop, frame, regcache, addr_stack,
+                                            &value, { (CORE_ADDR) rank }))
     {
       stride.set_const_val (value);
 
@@ -2328,7 +2329,7 @@ resolve_dynamic_range (struct type *dyn_range_type,
 
   static_target_type
     = resolve_dynamic_type_internal (dyn_range_type->target_type (),
-                                    addr_stack, frame, false);
+                                    addr_stack, frame, regcache, false);
   LONGEST bias = dyn_range_type->bounds ()->bias;
   type_allocator alloc (dyn_range_type);
   static_range_type = create_range_type_with_stride
@@ -2362,6 +2363,7 @@ static struct type *
 resolve_dynamic_array_or_string_1 (struct type *type,
                                   const property_addr_info *addr_stack,
                                   const frame_info_ptr &frame,
+                                  reg_buffer *regcache,
                                   int rank, bool resolve_p)
 {
   CORE_ADDR value;
@@ -2391,7 +2393,7 @@ resolve_dynamic_array_or_string_1 (struct type *type,
      dimension of the array.  */
   prop = TYPE_ALLOCATED_PROP (type);
   if (prop != NULL && resolve_p
-      && dwarf2_evaluate_property (prop, frame, addr_stack, &value))
+      && dwarf2_evaluate_property (prop, frame, regcache, addr_stack, &value))
     {
       prop->set_const_val (value);
       if (value == 0)
@@ -2400,7 +2402,7 @@ resolve_dynamic_array_or_string_1 (struct type *type,
 
   prop = TYPE_ASSOCIATED_PROP (type);
   if (prop != NULL && resolve_p
-      && dwarf2_evaluate_property (prop, frame, addr_stack, &value))
+      && dwarf2_evaluate_property (prop, frame, regcache, addr_stack, &value))
     {
       prop->set_const_val (value);
       if (value == 0)
@@ -2409,14 +2411,15 @@ resolve_dynamic_array_or_string_1 (struct type *type,
 
   range_type = check_typedef (type->index_type ());
   range_type
-    = resolve_dynamic_range (range_type, addr_stack, frame, rank, resolve_p);
+    = resolve_dynamic_range (range_type, addr_stack, frame, regcache, rank,
+                            resolve_p);
 
   ary_dim = check_typedef (type->target_type ());
   if (ary_dim != NULL && ary_dim->code () == TYPE_CODE_ARRAY)
     {
       ary_dim = copy_type (ary_dim);
       elt_type = resolve_dynamic_array_or_string_1 (ary_dim, addr_stack,
-                                                   frame, rank - 1,
+                                                   frame, regcache, rank - 1,
                                                    resolve_p);
     }
   else if (ary_dim != nullptr && ary_dim->code () == TYPE_CODE_STRING)
@@ -2447,7 +2450,7 @@ resolve_dynamic_array_or_string_1 (struct type *type,
         Fortran, and hope that this doesn't cause problems for anyone
         else.  */
       elt_type = resolve_dynamic_type_internal (type->target_type (),
-                                               addr_stack, frame, 0);
+                                               addr_stack, frame, regcache, 0);
     }
   else
     elt_type = type->target_type ();
@@ -2457,7 +2460,7 @@ resolve_dynamic_array_or_string_1 (struct type *type,
     prop = nullptr;
   if (prop != NULL && resolve_p)
     {
-      if (dwarf2_evaluate_property (prop, frame, addr_stack, &value))
+      if (dwarf2_evaluate_property (prop, frame, regcache, addr_stack, &value))
        {
          type->remove_dyn_prop (DYN_PROP_BYTE_STRIDE);
          bit_stride = (unsigned int) (value * 8);
@@ -2489,7 +2492,8 @@ resolve_dynamic_array_or_string_1 (struct type *type,
 static struct type *
 resolve_dynamic_array_or_string (struct type *type,
                                 const property_addr_info *addr_stack,
-                                const frame_info_ptr &frame)
+                                const frame_info_ptr &frame,
+                                reg_buffer *regcache)
 {
   CORE_ADDR value;
   int rank = 0;
@@ -2503,7 +2507,7 @@ resolve_dynamic_array_or_string (struct type *type,
 
   /* Resolve the rank property to get rank value.  */
   struct dynamic_prop *prop = TYPE_RANK_PROP (type);
-  if (dwarf2_evaluate_property (prop, frame, addr_stack, &value))
+  if (dwarf2_evaluate_property (prop, frame, regcache, addr_stack, &value))
     {
       prop->set_const_val (value);
       rank = value;
@@ -2571,8 +2575,8 @@ resolve_dynamic_array_or_string (struct type *type,
      reduce the rank by 1 here.  */
   --rank;
 
-  return resolve_dynamic_array_or_string_1 (type, addr_stack, frame, rank,
-                                           true);
+  return resolve_dynamic_array_or_string_1 (type, addr_stack, frame, regcache,
+                                           rank, true);
 }
 
 /* Resolve dynamic bounds of members of the union TYPE to static
@@ -2582,7 +2586,8 @@ resolve_dynamic_array_or_string (struct type *type,
 static struct type *
 resolve_dynamic_union (struct type *type,
                       const property_addr_info *addr_stack,
-                      const frame_info_ptr &frame)
+                      const frame_info_ptr &frame,
+                      reg_buffer *regcache)
 {
   struct type *resolved_type;
   unsigned int max_len = 0;
@@ -2599,7 +2604,7 @@ resolve_dynamic_union (struct type *type,
        continue;
 
       t = resolve_dynamic_type_internal (field.type (), addr_stack,
-                                        frame, false);
+                                        frame, regcache, false);
       field.set_type (t);
 
       struct type *real_type = check_typedef (t);
@@ -2809,7 +2814,8 @@ apply_bit_offset_to_field (struct field &field, LONGEST bit_offset,
 void
 resolve_dynamic_field (struct field &field,
                       const property_addr_info *addr_stack,
-                      const frame_info_ptr &frame)
+                      const frame_info_ptr &frame,
+                      reg_buffer *regcache)
 {
   gdb_assert (!field.is_static ());
 
@@ -2827,7 +2833,7 @@ resolve_dynamic_field (struct field &field,
 
       CORE_ADDR vals[1] = {addr_stack->addr};
       CORE_ADDR addr_or_bitpos;
-      if (dwarf2_evaluate_property (&prop, frame, addr_stack,
+      if (dwarf2_evaluate_property (&prop, frame, regcache, addr_stack,
                                    &addr_or_bitpos, vals))
        {
          if (field.loc_kind () == FIELD_LOC_KIND_DWARF_BLOCK_ADDR)
@@ -2866,8 +2872,8 @@ resolve_dynamic_field (struct field &field,
   pinfo.addr = addr_stack->addr + offset;
   pinfo.next = addr_stack;
 
-  field.set_type (resolve_dynamic_type_internal (field.type (),
-                                                &pinfo, frame, false));
+  field.set_type (resolve_dynamic_type_internal (field.type (), &pinfo,
+                                                frame, regcache, false));
   gdb_assert (field.loc_kind () == FIELD_LOC_KIND_BITPOS);
 }
 
@@ -2878,7 +2884,8 @@ resolve_dynamic_field (struct field &field,
 static struct type *
 resolve_dynamic_struct (struct type *type,
                        const property_addr_info *addr_stack,
-                       const frame_info_ptr &frame)
+                       const frame_info_ptr &frame,
+                       reg_buffer *regcache)
 {
   struct type *resolved_type;
   unsigned resolved_type_bit_length = 0;
@@ -2908,7 +2915,7 @@ resolve_dynamic_struct (struct type *type,
       if (field.is_static ())
        continue;
 
-      resolve_dynamic_field (field, addr_stack, frame);
+      resolve_dynamic_field (field, addr_stack, frame, regcache);
 
       new_bit_length = field.loc_bitpos ();
       if (field.bitsize () != 0)
@@ -2951,6 +2958,7 @@ static struct type *
 resolve_dynamic_type_internal (struct type *type,
                               const property_addr_info *addr_stack,
                               const frame_info_ptr &frame,
+                              reg_buffer *regcache,
                               bool top_level)
 {
   struct type *real_type = check_typedef (type);
@@ -2964,7 +2972,7 @@ resolve_dynamic_type_internal (struct type *type,
   std::optional<CORE_ADDR> type_length;
   prop = TYPE_DYNAMIC_LENGTH (type);
   if (prop != NULL
-      && dwarf2_evaluate_property (prop, frame, addr_stack, &value))
+      && dwarf2_evaluate_property (prop, frame, regcache, addr_stack, &value))
     type_length = value;
 
   if (type->code () == TYPE_CODE_TYPEDEF)
@@ -2972,7 +2980,7 @@ resolve_dynamic_type_internal (struct type *type,
       resolved_type = copy_type (type);
       resolved_type->set_target_type
        (resolve_dynamic_type_internal (type->target_type (), addr_stack,
-                                       frame, top_level));
+                                       frame, regcache, top_level));
     }
   else
     {
@@ -3002,8 +3010,8 @@ resolve_dynamic_type_internal (struct type *type,
              {
                resolved_type = copy_type (type);
                resolved_type->set_target_type
-                 (resolve_dynamic_type_internal (type->target_type (),
-                                                 &pinfo, frame, true));
+                 (resolve_dynamic_type_internal (type->target_type (), &pinfo,
+                                                 frame, regcache, true));
              }
            break;
          }
@@ -3013,7 +3021,7 @@ resolve_dynamic_type_internal (struct type *type,
             treated as one here.  */
        case TYPE_CODE_ARRAY:
          resolved_type = resolve_dynamic_array_or_string (type, addr_stack,
-                                                          frame);
+                                                          frame, regcache);
          break;
 
        case TYPE_CODE_RANGE:
@@ -3022,15 +3030,18 @@ resolve_dynamic_type_internal (struct type *type,
             this rank value is not actually required for the resolution of
             the dynamic range, otherwise, we'd be resolving this range
             within the context of a dynamic array.  */
-         resolved_type = resolve_dynamic_range (type, addr_stack, frame, 0);
+         resolved_type = resolve_dynamic_range (type, addr_stack, frame,
+                                                regcache, 0);
          break;
 
        case TYPE_CODE_UNION:
-         resolved_type = resolve_dynamic_union (type, addr_stack, frame);
+         resolved_type = resolve_dynamic_union (type, addr_stack, frame,
+                                                regcache);
          break;
 
        case TYPE_CODE_STRUCT:
-         resolved_type = resolve_dynamic_struct (type, addr_stack, frame);
+         resolved_type = resolve_dynamic_struct (type, addr_stack, frame,
+                                                 regcache);
          break;
        }
     }
@@ -3047,7 +3058,7 @@ resolve_dynamic_type_internal (struct type *type,
   /* Resolve data_location attribute.  */
   prop = TYPE_DATA_LOCATION (resolved_type);
   if (prop != NULL
-      && dwarf2_evaluate_property (prop, frame, addr_stack, &value))
+      && dwarf2_evaluate_property (prop, frame, regcache, addr_stack, &value))
     {
       /* Start of Fortran hack.  See comment in f-lang.h for what is going
         on here.*/
@@ -3068,7 +3079,8 @@ struct type *
 resolve_dynamic_type (struct type *type,
                      gdb::array_view<const gdb_byte> valaddr,
                      CORE_ADDR addr,
-                     const frame_info_ptr *in_frame)
+                     const frame_info_ptr *in_frame,
+                     reg_buffer *regcache)
 {
   struct property_addr_info pinfo
     = {check_typedef (type), valaddr, addr, NULL};
@@ -3077,7 +3089,7 @@ resolve_dynamic_type (struct type *type,
   if (in_frame != nullptr)
     frame = *in_frame;
 
-  return resolve_dynamic_type_internal (type, &pinfo, frame, true);
+  return resolve_dynamic_type_internal (type, &pinfo, frame, regcache, true);
 }
 
 /* See gdbtypes.h  */
index 4ae86dcfbbbda6e8a0d1f45003e7b32ed4a420ed..1c88b278aefbaf8eaaea5b39a1d4ee7bf5c8e474 100644 (file)
@@ -59,6 +59,7 @@ struct language_defn;
 struct dwarf2_per_cu;
 struct dwarf2_per_objfile;
 struct dwarf2_property_baton;
+struct reg_buffer;
 
 /* * Different kinds of data types are distinguished by the `code'
    field.  */
@@ -2672,9 +2673,11 @@ extern CORE_ADDR get_pointer_type_max (struct type *);
    have a different type when resolved (depending on the contents of
    memory).  In this situation, 'is_dynamic_type' will still return
    true for the return value of this function.  */
+
 extern struct type *resolve_dynamic_type
   (struct type *type, gdb::array_view<const gdb_byte> valaddr,
-   CORE_ADDR addr, const frame_info_ptr *frame = nullptr);
+   CORE_ADDR addr, const frame_info_ptr *frame = nullptr,
+   reg_buffer *regcache = nullptr);
 
 /* * Predicate if the type has dynamic values, which are not resolved yet.
    See the caveat in 'resolve_dynamic_type' to understand a scenario
@@ -2692,7 +2695,8 @@ extern bool is_dynamic_type (struct type *type);
 
 extern void resolve_dynamic_field (struct field &field,
                                   const struct property_addr_info *addr_stack,
-                                  const frame_info_ptr &frame);
+                                  const frame_info_ptr &frame,
+                                  reg_buffer *regcache = nullptr);
 
 /* A helper function that handles the DWARF semantics for
    DW_AT_bit_offset.
index 700e271903e22086ebcff662edd8ba7699329d1c..1dfdc3ba8e620b024065f5d07cb23f784f9ffaa1 100644 (file)
@@ -494,7 +494,7 @@ gnuv3_baseclass_offset (struct type *type, int index,
       addr_stack.next = nullptr;
 
       CORE_ADDR result;
-      if (dwarf2_evaluate_property (&prop, nullptr, &addr_stack, &result,
+      if (dwarf2_evaluate_property (&prop, nullptr, nullptr, &addr_stack, &result,
                                    {addr_stack.addr}))
        return (int) (result - addr_stack.addr);
     }
index 70075d059afa8f3a9537a1d0e3af1d2f89ef0cf9..1d3e93e02f2c6160a5c6140cca332273ad99eb4c 100644 (file)
@@ -375,11 +375,9 @@ reg_buffer::initialize_variable_size_registers ()
          continue;
        }
 
-      /* Assume the register cache is for the current frame.  */
-      frame_info_ptr frame = get_current_frame ();
       m_variable_size_register_type[i]
        = resolve_dynamic_type (m_descr->register_type[i], {},
-                               /* Unused address.  */ 0, &frame);
+                               /* Unused address.  */ 0, nullptr, this);
 
       ULONGEST size = m_variable_size_register_type[i]->length ();
       gdb_assert (size != 0);
@@ -454,6 +452,18 @@ reg_buffer::invalidate_tdesc_parameter (unsigned int param_id)
 
 /* See regcache.h.  */
 
+void
+reg_buffer::collect_tdesc_parameter (unsigned int param_id,
+                                    gdb::array_view<gdb_byte> dst)
+{
+  gdb::array_view<gdb_byte> buf = tdesc_parameter_buffer (param_id);
+  gdb_assert (buf.size () == dst.size ());
+
+  copy (buf, dst);
+}
+
+/* See regcache.h.  */
+
 void
 reg_buffer::supply_parameter (unsigned int param_id,
                              gdb::array_view<const gdb_byte> src)
@@ -1421,8 +1431,6 @@ register_status
 readable_regcache::tdesc_parameter_value (unsigned int param_id,
                                          gdb::array_view<gdb_byte> dst)
 {
-  gdb_assert (param_id < m_tdesc_parameter_status.size ());
-
   ULONGEST size = tdesc_parameter_size (m_descr->gdbarch, param_id);
   gdb_assert (dst.size () == size);
 
index 4a23ddb9e227a0182f1a18de4e621b11fd68194b..777719ee14e98443505df914fa0c3cce82fd15b6 100644 (file)
@@ -271,6 +271,10 @@ public:
   /* See gdbsupport/common-regcache.h.  */
   int register_size (int regnum) const override;
 
+  /* FIXME: Document.  */
+  void collect_tdesc_parameter (unsigned int param_id,
+                               gdb::array_view<gdb_byte> dst);
+
   /* FIXME: Document.
      Assumes SRC contains an integer in target byte order.  */
   void supply_parameter (unsigned int param_id,