* Fix 16.0 handling. - Patches added: * gdb-testsuite-fix-gdb.python-py-format-string.exp-wi.patch * gdb-testsuite-fix-gdb.python-py-mi-cmd.exp-with-pyth.patch * gdb-testsuite-fix-gdb.ada-mi_task_arg.exp-on-arm-lin.patch * gdb-testsuite-fix-regexp-in-gdb.ada-mi_var_access.ex.patch * gdb-testsuite-check-gnatmake-version-in-gdb.ada-scal.patch * gdb-testsuite-fix-gdb.arch-arm-pseudo-unwind.exp-wit.patch * gdb-symtab-fix-target-type-of-complex-long-double-on.patch * gdb-testsuite-don-t-use-set-auto-solib-add-off.patch * gdb-tdep-fix-arm-thumb2-hw-breakpoint.patch * gdb-testsuite-fix-gdb.cp-m-static.exp-on-arm.patch * gdb-testsuite-fix-gdb.dwarf2-dw2-fixed-point.exp-on-.patch * gdb-testsuite-fix-gdb.dwarf2-dw2-lines.exp-on-arm-li.patch * gdb-exp-fix-gdb.fortran-intrinsics.exp-fail-on-arm.patch * gdb-tdep-handle-sycall-statx-for-arm-linux.patch * gdb-tdep-fix-recording-of-t1-push.patch * gdb-tdep-handle-syscall-clock_gettime64-for-arm-linu.patch * fix-gdb.dwarf2-shortpiece.exp-on-s390x.patch * handle-address-class-annotation-for-s390x-in-some-te.patch * fix-gdb.dap-step-out.exp-on-s390x.patch * use-setvariable-in-gdb.dap-scopes.exp.patch * fix-gdb.base-finish-pretty.exp-on-s390x.patch * fix-gdb.base-readnever.exp-on-s390x.patch * add-dwarf_expr_piece.op.patch * add-gdbarch_dwarf2_reg_piece_offset-hook.patch * fix-gdb.base-store.exp-on-s390x.patch * fix-gdb.ada-o2_float_param.exp-on-s390x-linux.patch * gdb-testsuite-fix-gdb.base-branch-to-self.exp-on-arm.patch * gdb-tdep-fix-gdb.cp-non-trivial-retval.exp-on-riscv6.patch * gdb-testsuite-fix-gdb.cp-non-trivial-retval.exp-on-a.patch * gdb-testsuite-fix-gdb.rust-completion.exp-timeout-on.patch * gdb-testsuite-require-supports_process_record-in-gdb.patch * gdb-testsuite-fix-regexp-in-gdb.arch-i386-disp-step-.patch * gdb-testsuite-fix-gdb.arch-arm-single-step-kernel-he.patch * gdb-testsuite-fix-gdb.python-py-format-address.exp-o.patch * gdb-testsuite-fix-gdb.arch-riscv-tdesc-regs.exp.patch * gdb-testsuite-fix-gdb.base-list-dot-nodebug-and-make.patch * gdb-testsuite-fix-gdb.base-list-dot-nodebug.exp-on-o.patch * gdb-testsuite-fix-gdb.base-empty-host-env-vars.exp.patch * gdb-prune-inferior-after-switching-inferior.patch * gdb-testsuite-use-nostdlib-in-gdb.base-list-dot-node.patch * gdb-testsuite-fix-timeout-in-gdb.mi-mi-multi-command.patch * gdb-testsuite-require-can_spawn_for_attach-in-gdb.ba.patch * fixup-gdb-6.5-gcore-buffer-limit-test.patch * gdb-testsuite-fix-gdb.ada-big_packed_array.exp-on-s3.patch * gdb-testsuite-fix-gdb.ada-convvar_comp.exp-on-s390x-.patch * gdb-testsuite-fix-regexp-in-gdb.threads-stepi-over-c.patch OBS-URL: https://build.opensuse.org/package/show/devel:gcc/gdb?expand=0&rev=437
145 lines
4.8 KiB
Diff
145 lines
4.8 KiB
Diff
From 0ac8e9af3cd6713f4b230e9e335e1398c3161210 Mon Sep 17 00:00:00 2001
|
|
From: Tom de Vries <tdevries@suse.de>
|
|
Date: Fri, 10 Jan 2025 21:25:53 +0100
|
|
Subject: [PATCH 26/46] Fix gdb.ada/O2_float_param.exp on s390x-linux
|
|
|
|
With test-case gdb.ada/O2_float_param.exp on s390x-linux, I get:
|
|
...
|
|
(gdb) frame^M
|
|
#0 callee.increment (val=99.0, val@entry=<error reading variable: \
|
|
register has not been saved in frame>, msg=...) at callee.adb:19^M
|
|
19 procedure Increment (Val : in out Float; Msg: String) is^M
|
|
(gdb) FAIL: $exp: scenario=all: frame
|
|
...
|
|
|
|
The frame command calls read_frame_arg to get:
|
|
- the current value of val, and
|
|
- the value of val at function entry.
|
|
|
|
The first scenario succeeds, and the second scenario fails.
|
|
|
|
For context and contrast, let's also investigate the first scenario: getting
|
|
the current value of val.
|
|
|
|
Function parameter val:
|
|
...
|
|
<2><b51>: Abbrev Number: 4 (DW_TAG_formal_parameter)
|
|
<b52> DW_AT_name : val
|
|
<b58> DW_AT_type : <0xb86>
|
|
<b5c> DW_AT_location : 0xab (location list)
|
|
...
|
|
has location list:
|
|
...
|
|
000000ab 0000000001002928 0000000001002967
|
|
(DW_OP_reg16 (f0))
|
|
000000be 0000000001002967 0000000001002968
|
|
(DW_OP_reg24 (f8))
|
|
000000d1 0000000001002968 0000000001002974
|
|
(DW_OP_GNU_regval_type: 24 (f8) <0xb29>;
|
|
DW_OP_GNU_const_type: <0xb29> 4 byte block: 3f 80 0 0 ; DW_OP_plus;
|
|
DW_OP_stack_value)
|
|
000000ef 0000000001002974 0000000001002982
|
|
(DW_OP_GNU_entry_value: (DW_OP_GNU_regval_type: 16 (f0) <0xb29>);
|
|
DW_OP_GNU_const_type: <0xb29> 4 byte block: 3f 80 0 0 ; DW_OP_plus;
|
|
DW_OP_stack_value)
|
|
0000010f <End of list>
|
|
...
|
|
and since we're stopped at address 0x1002928:
|
|
...
|
|
(gdb) print $pc
|
|
$1 = (access procedure) 0x1002928 <callee.increment>
|
|
...
|
|
we get the value from dwarf register 16.
|
|
|
|
The s390x ABI [1] specifies that dwarf register 16 maps onto 8-byte register
|
|
f0 or 16-byte register v0 (where f0 is part of v0), and in this case (because
|
|
the v0 register is available) s390_dwarf_reg_to_regnum maps it to v0.
|
|
|
|
Val is only 4 bytes:
|
|
...
|
|
(gdb) ptype val
|
|
type = <4-byte float>
|
|
...
|
|
and s390_value_from_register takes care to get the value from the correct part
|
|
of v0.
|
|
|
|
The value of v0 is found in the prologue cache, and the value of parameter val
|
|
is printed.
|
|
|
|
Now the second scenario: getting the value of val at function entry.
|
|
|
|
FWIW, since we're stopped at function entry, we could simply return the same
|
|
value, reading the same register, but that's currently not implemented [2].
|
|
|
|
Instead we start from the fact that val is in dwarf reg 16 at function entry,
|
|
and then use call site information:
|
|
...
|
|
<4><cf7>: Abbrev Number: 13 (DW_TAG_GNU_call_site)
|
|
<cf8> DW_AT_low_pc : 0x1002a46
|
|
<d00> DW_AT_abstract_origin: <0xdda>
|
|
<5><d04>: Abbrev Number: 12 (DW_TAG_GNU_call_site_parameter)
|
|
<d05> DW_AT_location : 1 byte block: 60 (DW_OP_reg16 (f0))
|
|
<d07> DW_AT_GNU_call_site_value: 3 byte block: f5 18 2d \
|
|
(DW_OP_GNU_regval_type: 24 (f8) <0xc42>)
|
|
<5><d0b>: Abbrev Number: 12 (DW_TAG_GNU_call_site_parameter)
|
|
...
|
|
to conclude that the value we're looking for is in dwarf reg 24, which
|
|
s390_dwarf_reg_to_regnum maps to v8.
|
|
|
|
As before, s390_value_from_register takes care to get the value from the
|
|
correct part of v8.
|
|
|
|
However, v8 is not available in the prologue cache, and we take a different
|
|
path and end up in s390_unwind_pseudo_register, where v8 and similar
|
|
(regnum_is_vxr_full) is unhandled, and we get:
|
|
...
|
|
return value::allocate_optimized_out (type);
|
|
...
|
|
which eventually causes the "error reading variable: register has not been
|
|
saved in frame".
|
|
|
|
Fix this by handling the regnum_is_vxr_full case in
|
|
s390_unwind_pseudo_register, similar to how that is done in
|
|
s390_pseudo_register_read.
|
|
|
|
Tested on s390x-linux.
|
|
|
|
This also fixes test-case gdb.base/savedregs.exp.
|
|
|
|
[1] https://github.com/IBM/s390x-abi
|
|
[2] https://sourceware.org/pipermail/gdb-patches/2024-September/211589.html
|
|
---
|
|
gdb/s390-tdep.c | 16 ++++++++++++++++
|
|
1 file changed, 16 insertions(+)
|
|
|
|
diff --git a/gdb/s390-tdep.c b/gdb/s390-tdep.c
|
|
index a7c58b37276..31730296ef1 100644
|
|
--- a/gdb/s390-tdep.c
|
|
+++ b/gdb/s390-tdep.c
|
|
@@ -2332,6 +2332,22 @@ s390_unwind_pseudo_register (const frame_info_ptr &this_frame, int regnum)
|
|
return value_cast (type, val);
|
|
}
|
|
|
|
+ if (regnum_is_vxr_full (tdep, regnum))
|
|
+ {
|
|
+ struct value *val = value::allocate_register (this_frame, regnum);
|
|
+
|
|
+ int reg = regnum - tdep->v0_full_regnum;
|
|
+ struct value *val1
|
|
+ = frame_unwind_register_value (this_frame, S390_F0_REGNUM + reg);
|
|
+ struct value *val2
|
|
+ = frame_unwind_register_value (this_frame, S390_V0_LOWER_REGNUM + reg);
|
|
+
|
|
+ val1->contents_copy (val, 0, 0, 8);
|
|
+ val2->contents_copy (val, 8, 0, 8);
|
|
+
|
|
+ return value_cast (type, val);
|
|
+ }
|
|
+
|
|
return value::allocate_optimized_out (type);
|
|
}
|
|
|
|
--
|
|
2.43.0
|
|
|