]> 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>
Mon, 28 Apr 2025 04:52:53 +0000 (01:52 -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 9df9a453240c1190cb746681830ec6f3e011d0d6..acbb241c8e45f4798f55d0f9cda8174a12abc8e4 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)
@@ -1772,7 +1773,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,
@@ -1780,7 +1782,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 30c528b525d69f36528818c169d9573fc97a18ee..aba1d7ea184cafd453639ac33a9ff4dfbb18ff7e 100644 (file)
@@ -118,8 +118,10 @@ struct property_addr_info
    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 960e68844563c1a007f8813a626f6e35c81b61cc..e8c2b894e463e4d42e8dcf1d20ddf0168764d295 100644 (file)
@@ -3261,7 +3261,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 e6dd6d64e25b66d894302d324610aadc7779eb92..6472dda80342ef35ad1bb864cd211d12c5d80d85 100644 (file)
@@ -2207,7 +2207,7 @@ is_dynamic_type (struct type *type)
 
 static struct type *resolve_dynamic_type_internal
   (struct type *type, struct 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
@@ -2229,6 +2229,7 @@ static struct type *
 resolve_dynamic_range (struct type *dyn_range_type,
                       struct property_addr_info *addr_stack,
                       const frame_info_ptr &frame,
+                      reg_buffer *regcache,
                       int rank, bool resolve_p = true)
 {
   CORE_ADDR value;
@@ -2241,7 +2242,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)
@@ -2255,7 +2256,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
@@ -2287,8 +2288,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);
 
@@ -2310,7 +2311,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
@@ -2344,6 +2345,7 @@ static struct type *
 resolve_dynamic_array_or_string_1 (struct type *type,
                                   struct property_addr_info *addr_stack,
                                   const frame_info_ptr &frame,
+                                  reg_buffer *regcache,
                                   int rank, bool resolve_p)
 {
   CORE_ADDR value;
@@ -2373,7 +2375,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)
@@ -2382,7 +2384,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)
@@ -2391,14 +2393,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)
@@ -2429,7 +2432,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 ();
@@ -2439,7 +2442,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);
@@ -2471,7 +2474,8 @@ resolve_dynamic_array_or_string_1 (struct type *type,
 static struct type *
 resolve_dynamic_array_or_string (struct type *type,
                                 struct property_addr_info *addr_stack,
-                                const frame_info_ptr &frame)
+                                const frame_info_ptr &frame,
+                                reg_buffer *regcache)
 {
   CORE_ADDR value;
   int rank = 0;
@@ -2485,7 +2489,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;
@@ -2553,8 +2557,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
@@ -2564,7 +2568,8 @@ resolve_dynamic_array_or_string (struct type *type,
 static struct type *
 resolve_dynamic_union (struct type *type,
                       struct property_addr_info *addr_stack,
-                      const frame_info_ptr &frame)
+                      const frame_info_ptr &frame,
+                      reg_buffer *regcache)
 {
   struct type *resolved_type;
   int i;
@@ -2582,7 +2587,7 @@ resolve_dynamic_union (struct type *type,
        continue;
 
       t = resolve_dynamic_type_internal (resolved_type->field (i).type (),
-                                        addr_stack, frame, false);
+                                        addr_stack, frame, regcache, false);
       resolved_type->field (i).set_type (t);
 
       struct type *real_type = check_typedef (t);
@@ -2756,7 +2761,8 @@ compute_variant_fields (struct type *type,
 static struct type *
 resolve_dynamic_struct (struct type *type,
                        struct property_addr_info *addr_stack,
-                       const frame_info_ptr &frame)
+                       const frame_info_ptr &frame,
+                       reg_buffer *regcache)
 {
   struct type *resolved_type;
   int i;
@@ -2799,8 +2805,8 @@ resolve_dynamic_struct (struct type *type,
          prop.set_locexpr (&baton);
 
          CORE_ADDR addr;
-         if (dwarf2_evaluate_property (&prop, frame, addr_stack, &addr,
-                                       {addr_stack->addr}))
+         if (dwarf2_evaluate_property (&prop, frame, regcache, addr_stack,
+                                       &addr, {addr_stack->addr}))
            resolved_type->field (i).set_loc_bitpos
              (TARGET_CHAR_BIT * (addr - addr_stack->addr));
        }
@@ -2826,7 +2832,7 @@ resolve_dynamic_struct (struct type *type,
 
       resolved_type->field (i).set_type
        (resolve_dynamic_type_internal (resolved_type->field (i).type (),
-                                       &pinfo, frame, false));
+                                       &pinfo, frame, regcache, false));
       gdb_assert (resolved_type->field (i).loc_kind ()
                  == FIELD_LOC_KIND_BITPOS);
 
@@ -2872,6 +2878,7 @@ static struct type *
 resolve_dynamic_type_internal (struct type *type,
                               struct property_addr_info *addr_stack,
                               const frame_info_ptr &frame,
+                              reg_buffer *regcache,
                               bool top_level)
 {
   struct type *real_type = check_typedef (type);
@@ -2885,7 +2892,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)
@@ -2893,7 +2900,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
     {
@@ -2923,8 +2930,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;
          }
@@ -2934,7 +2941,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:
@@ -2943,15 +2950,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;
        }
     }
@@ -2968,7 +2978,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.*/
@@ -2989,7 +2999,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};
@@ -2998,7 +3009,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 3132e4478f092636344756ee31916a515a1bbce2..68ca02039a7af6eb8cfce7337f404d3b51965ce5 100644 (file)
@@ -2640,9 +2640,12 @@ 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.  */
+
+struct reg_buffer;
 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
index 4f53e9ff1549817e4ffea1cd78792b6f73360a50..b0c42e33d1b7fb60d5286a6e6466c3a47cff0d0e 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 120de8fd790b61e8460315c6a455e9ff90da2c80..8942722f803f0fe3a4da6105942fedd51a30526f 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 8fc82d1913bc64d71b88f1e003875a5d69669ba8..97552474a9cc692140aed41e43db5d7ae144d643 100644 (file)
@@ -272,6 +272,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,