]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
Make register_type () use the correct frame when resolving dynamic types ...
authorThiago Jung Bauermann <thiago.bauermann@linaro.org>
Sun, 20 Apr 2025 02:03:31 +0000 (23:03 -0300)
committerThiago Jung Bauermann <thiago.bauermann@linaro.org>
Thu, 23 Oct 2025 02:47:59 +0000 (23:47 -0300)
... for variable-size registers.

gdb/dummy-frame.c
gdb/eval.c
gdb/frame-unwind.c
gdb/regcache.c
gdb/regcache.h
gdb/value.c

index 37ee60cb0e0562ebe4a0c4f76de1f8e5756751bc..e23b7664edec981e7f0a7e8c5089b725c4af0cc9 100644 (file)
@@ -347,7 +347,8 @@ dummy_frame_prev_register (const frame_info_ptr &this_frame,
 
   /* Describe the register's location.  Generic dummy frames always
      have the register value in an ``expression''.  */
-  reg_val = value::zero (register_type (gdbarch, regnum), not_lval);
+  reg_val = value::zero (register_type (gdbarch, regnum, &this_frame),
+                        not_lval);
 
   /* Use the regcache_cooked_read() method so that it, on the fly,
      constructs either a raw or pseudo register from the raw
index 9b0cf20211010a9e3916ce6d721a9f5ffc130a29..5d80e0764576fac56db63467b60013b2d5406046 100644 (file)
@@ -1137,18 +1137,21 @@ eval_op_register (struct type *expect_type, struct expression *exp,
   if (regno == -1)
     error (_("Register $%s not available."), name);
 
+  frame_info_ptr selected_frame = get_selected_frame ();
   /* In EVAL_AVOID_SIDE_EFFECTS mode, we only need to return a value with
      the appropriate register type.  Unfortunately, we don't have easy
      access to the type of user registers and variable-size registers.  So
      for these registers, we fetch the register value regardless of the
      evaluation mode.  */
+  // FIXME: Maybe this works for variable-size registers now?
   if (noside == EVAL_AVOID_SIDE_EFFECTS
       && regno < gdbarch_num_cooked_regs (exp->gdbarch)
       && !register_is_variable_size (exp->gdbarch, regno))
-    val = value::zero (register_type (exp->gdbarch, regno), not_lval);
+    val = value::zero (register_type (exp->gdbarch, regno, &selected_frame),
+                      not_lval);
   else
-    val = value_of_register
-      (regno, get_next_frame_sentinel_okay (get_selected_frame ()));
+    val = value_of_register (regno,
+                            get_next_frame_sentinel_okay (selected_frame));
   if (val == NULL)
     error (_("Value of register %s not available."), name);
   else
index af7382a8108ae052e9f20cacba4b902272854c18..8f86fdc4825dcc7aaabc71ed549f7458596ffdd0 100644 (file)
@@ -285,7 +285,7 @@ struct value *
 frame_unwind_got_optimized (const frame_info_ptr &frame, int regnum)
 {
   struct gdbarch *gdbarch = frame_unwind_arch (frame);
-  struct type *type = register_type (gdbarch, regnum);
+  struct type *type = register_type (gdbarch, regnum, &frame);
 
   return value::allocate_optimized_out (type);
 }
@@ -316,7 +316,8 @@ struct value *
 frame_unwind_got_memory (const frame_info_ptr &frame, int regnum, CORE_ADDR addr)
 {
   struct gdbarch *gdbarch = frame_unwind_arch (frame);
-  struct value *v = value_at_lazy (register_type (gdbarch, regnum), addr);
+  struct value *v = value_at_lazy (register_type (gdbarch, regnum, &frame),
+                                  addr);
 
   v->set_stack (true);
   return v;
@@ -333,7 +334,7 @@ frame_unwind_got_constant (const frame_info_ptr &frame, int regnum,
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
   struct value *reg_val;
 
-  reg_val = value::zero (register_type (gdbarch, regnum), not_lval);
+  reg_val = value::zero (register_type (gdbarch, regnum, &frame), not_lval);
   store_unsigned_integer (reg_val->contents_writeable ().data (),
                          register_size (gdbarch, regnum), byte_order, val);
   return reg_val;
@@ -346,7 +347,7 @@ frame_unwind_got_bytes (const frame_info_ptr &frame, int regnum,
   struct gdbarch *gdbarch = frame_unwind_arch (frame);
   struct value *reg_val;
 
-  reg_val = value::zero (register_type (gdbarch, regnum), not_lval);
+  reg_val = value::zero (register_type (gdbarch, regnum, &frame), not_lval);
   gdb::array_view<gdb_byte> val_contents = reg_val->contents_raw ();
 
   /* The value's contents buffer is zeroed on allocation so if buf is
@@ -373,10 +374,10 @@ frame_unwind_got_address (const frame_info_ptr &frame, int regnum,
 {
   struct gdbarch *gdbarch = frame_unwind_arch (frame);
   struct value *reg_val;
+  struct type *type = register_type (gdbarch, regnum, &frame);
 
-  reg_val = value::zero (register_type (gdbarch, regnum), not_lval);
-  pack_long (reg_val->contents_writeable ().data (),
-            register_type (gdbarch, regnum), addr);
+  reg_val = value::zero (type, not_lval);
+  pack_long (reg_val->contents_writeable ().data (), type, addr);
   return reg_val;
 }
 
index 28572b0b4b493477f1d3d204bad1e2501f806033..3cd913edebe15bd316dbb68c7667a0c0efa61261 100644 (file)
@@ -206,7 +206,8 @@ regcache_descr (struct gdbarch *gdbarch)
 /* See gdb/regcache.h.  */
 
 struct type *
-register_type (struct gdbarch *gdbarch, int regnum)
+register_type (struct gdbarch *gdbarch, int regnum,
+              const frame_info_ptr *this_frame)
 {
   struct regcache_descr *descr = regcache_descr (gdbarch);
 
@@ -215,10 +216,7 @@ register_type (struct gdbarch *gdbarch, int regnum)
   struct type *type = descr->register_type[regnum];
 
   if (descr->register_is_variable_size[regnum])
-    {
-      frame_info_ptr current_frame = get_current_frame ();
-      type = resolve_dynamic_type (type, {}, 0, &current_frame);
-    }
+    type = resolve_dynamic_type (type, {}, 0, this_frame);
 
   return type;
 }
index 9f2e21ba2c0bb401af69e780d0ede313a761c4b6..db650f855c396ad6dfb83297ada8c3951aca2320 100644 (file)
@@ -162,7 +162,8 @@ extern bool regcache_map_supplies (const struct regcache_map_entry *map,
    then its gdbarch vector counterpart since it returns a precomputed
    value stored in a table.  */
 
-extern struct type *register_type (struct gdbarch *gdbarch, int regnum);
+extern struct type *register_type (struct gdbarch *gdbarch, int regnum,
+                                  const frame_info_ptr *this_frame = nullptr);
 
 /* Return the size of register REGNUM.  FRAME is needed in case regnum is a
    variable-size register.  */
index b8808dc6fe8f63c2864efa6bd2053995e0586bbc..57e0a0e9d81475194b00df6c96ec0b20fb834adb 100644 (file)
@@ -975,7 +975,11 @@ value::allocate_register_lazy (const frame_info_ptr &initial_next_frame,
                               int regnum, struct type *type)
 {
   if (type == nullptr)
-    type = register_type (frame_unwind_arch (initial_next_frame), regnum);
+    {
+      frame_info_ptr this_frame = get_prev_frame (initial_next_frame);
+      type = register_type (frame_unwind_arch (initial_next_frame), regnum,
+                           &this_frame);
+    }
 
   value *result = value::allocate_lazy (type);