From: Thiago Jung Bauermann Date: Sun, 20 Apr 2025 02:03:31 +0000 (-0300) Subject: Make register_type () use the correct frame when resolving dynamic types ... X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=75c318ad6058dd077bc0488e982d2ac8034694a0;p=thirdparty%2Fbinutils-gdb.git Make register_type () use the correct frame when resolving dynamic types ... ... for variable-size registers. --- diff --git a/gdb/dummy-frame.c b/gdb/dummy-frame.c index f8440b3077b..d4daa8ee358 100644 --- a/gdb/dummy-frame.c +++ b/gdb/dummy-frame.c @@ -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 diff --git a/gdb/eval.c b/gdb/eval.c index 984515a12c1..dcb391dd0e4 100644 --- a/gdb/eval.c +++ b/gdb/eval.c @@ -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 diff --git a/gdb/frame-unwind.c b/gdb/frame-unwind.c index f035b9b860e..d8cfd66e07a 100644 --- a/gdb/frame-unwind.c +++ b/gdb/frame-unwind.c @@ -283,7 +283,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); } @@ -306,7 +306,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; @@ -323,7 +324,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; @@ -336,7 +337,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 val_contents = reg_val->contents_raw (); /* The value's contents buffer is zeroed on allocation so if buf is @@ -363,10 +364,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; } diff --git a/gdb/regcache.c b/gdb/regcache.c index fb1a0d1597c..ab98db02109 100644 --- a/gdb/regcache.c +++ b/gdb/regcache.c @@ -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, ¤t_frame); - } + type = resolve_dynamic_type (type, {}, 0, this_frame); return type; } diff --git a/gdb/regcache.h b/gdb/regcache.h index ce7362b65ef..8688bfde862 100644 --- a/gdb/regcache.h +++ b/gdb/regcache.h @@ -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 diff --git a/gdb/value.c b/gdb/value.c index 5c0e5d83518..56b90b2fc23 100644 --- a/gdb/value.c +++ b/gdb/value.c @@ -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);