* 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
144 lines
4.4 KiB
Diff
144 lines
4.4 KiB
Diff
From 69e165afa3d45cfac89ed6be298ac6465c84c0fd Mon Sep 17 00:00:00 2001
|
|
From: Tom de Vries <tdevries@suse.de>
|
|
Date: Wed, 15 Jan 2025 17:02:00 +0100
|
|
Subject: [PATCH 25/46] Fix gdb.base/store.exp on s390x
|
|
|
|
On s390x-linux, I get:
|
|
...
|
|
(gdb) print l^M
|
|
$29 = 0^M
|
|
(gdb) FAIL: gdb.base/store.exp: var doublest l; print old l, expecting -1
|
|
...
|
|
|
|
So, we're in wack_doublest trying to print l, which is a copy of parameter u:
|
|
...
|
|
register doublest l = u, r = v;
|
|
...
|
|
which does have the expected value:
|
|
...
|
|
(gdb) p u
|
|
$1 = -1
|
|
...
|
|
which is a long double, 16 bytes and looks like this:
|
|
...
|
|
(gdb) p /x u
|
|
$3 = 0xbfff0000000000000000000000000000
|
|
...
|
|
|
|
Parameter u is passed in two registers:
|
|
...
|
|
<2><6a5>: Abbrev Number: 15 (DW_TAG_formal_parameter)
|
|
<6a6> DW_AT_name : v
|
|
<69e> DW_AT_location : 6 byte block: 50 93 8 51 93 8 \
|
|
(DW_OP_reg0 (r0); DW_OP_piece: 8; DW_OP_reg1 (r1); DW_OP_piece: 8)
|
|
...
|
|
and indeed we find the msw in r0 and the lsw in r1:
|
|
...
|
|
(gdb) p /x $r0
|
|
$4 = 0xbfff000000000000
|
|
(gdb) p /x $r1
|
|
$5 = 0x0
|
|
(gdb)
|
|
...
|
|
|
|
Likewise, variable l consists of two registers:
|
|
...
|
|
<2><6b5>: Abbrev Number: 13 (DW_TAG_variable)
|
|
<6b6> DW_AT_name : l
|
|
<6be> DW_AT_location : 6 byte block: 68 93 8 69 93 8 \
|
|
(DW_OP_reg24 (f8); DW_OP_piece: 8; DW_OP_reg25 (f10); DW_OP_piece: 8)
|
|
...
|
|
and we find the same values there:
|
|
...
|
|
(gdb) p /x $f8
|
|
$6 = 0xbfff000000000000
|
|
(gdb) p /x $f10
|
|
$7 = 0x0
|
|
...
|
|
|
|
So, we get the expected results when fetching the value from two gprs, but not
|
|
when fetching the value from two fprs.
|
|
|
|
When fetching the values from the two fprs, we stumble upon a particularity of
|
|
the DWARF register numbers as defined by the s390x ABI [1]: dwarf register 24
|
|
maps to both floating-point register f8 (8 bytes), and vector register v8
|
|
(16 bytes).
|
|
|
|
In s390_dwarf_reg_to_regnum, it's determined which of the two is chosen, and
|
|
if available vector registers are preferred over floating-point registers, so
|
|
v8 is chosen, and used to fetch the value.
|
|
|
|
Since the size of the DW_OP_piece is 8 bytes, and the register size is 16
|
|
bytes, this bit in rw_pieced_value is activated:
|
|
...
|
|
/* If the piece is located in a register, but does not
|
|
occupy the entire register, the placement of the piece
|
|
within that register is defined by the ABI. */
|
|
bits_to_skip
|
|
+= 8 * gdbarch_dwarf2_reg_piece_offset (arch, gdb_regnum,
|
|
p->size / 8);
|
|
...
|
|
but since the default implemention default_dwarf2_reg_piece_offset does not
|
|
match the s390x ABI, we get the wrong answer.
|
|
|
|
This is a known problem, see FOSDEM 2018 presentation "DWARF Pieces And Other
|
|
DWARF Location Woes" [2].
|
|
|
|
Fix this by adding s390_dwarf2_reg_piece_offset, roughly implementing the same
|
|
logic as in s390_value_from_register.
|
|
|
|
Tested on s390x-linux.
|
|
|
|
Approved-By: Tom Tromey <tom@tromey.com>
|
|
|
|
[1] https://github.com/IBM/s390x-abi
|
|
[2] https://archive.fosdem.org/2018/schedule/event/dwarfpieces
|
|
---
|
|
gdb/s390-tdep.c | 23 +++++++++++++++++++++++
|
|
1 file changed, 23 insertions(+)
|
|
|
|
diff --git a/gdb/s390-tdep.c b/gdb/s390-tdep.c
|
|
index 2609b42f797..a7c58b37276 100644
|
|
--- a/gdb/s390-tdep.c
|
|
+++ b/gdb/s390-tdep.c
|
|
@@ -1260,6 +1260,28 @@ s390_value_from_register (gdbarch *gdbarch, type *type, int regnum,
|
|
return value;
|
|
}
|
|
|
|
+/* Implementation of the gdbarch_dwarf2_reg_piece_offset hook. */
|
|
+
|
|
+static ULONGEST
|
|
+s390_dwarf2_reg_piece_offset (gdbarch *gdbarch, int gdb_regnum, ULONGEST size)
|
|
+{
|
|
+ s390_gdbarch_tdep *tdep = gdbarch_tdep<s390_gdbarch_tdep> (gdbarch);
|
|
+
|
|
+ /* Floating point register. */
|
|
+ if (gdb_regnum >= S390_F0_REGNUM && gdb_regnum <= S390_F15_REGNUM)
|
|
+ return 0;
|
|
+
|
|
+ /* Vector register, v0 - v15. */
|
|
+ if (regnum_is_vxr_full (tdep, gdb_regnum))
|
|
+ return 0;
|
|
+
|
|
+ /* Vector register, v16 - v31. */
|
|
+ if (gdb_regnum >= S390_V16_REGNUM && gdb_regnum <= S390_V31_REGNUM)
|
|
+ return 0;
|
|
+
|
|
+ return default_dwarf2_reg_piece_offset (gdbarch, gdb_regnum, size);
|
|
+}
|
|
+
|
|
/* Implement pseudo_register_name tdesc method. */
|
|
|
|
static const char *
|
|
@@ -7259,6 +7281,7 @@ s390_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
|
|
set_gdbarch_stab_reg_to_regnum (gdbarch, s390_dwarf_reg_to_regnum);
|
|
set_gdbarch_dwarf2_reg_to_regnum (gdbarch, s390_dwarf_reg_to_regnum);
|
|
set_gdbarch_value_from_register (gdbarch, s390_value_from_register);
|
|
+ set_gdbarch_dwarf2_reg_piece_offset (gdbarch, s390_dwarf2_reg_piece_offset);
|
|
|
|
/* Pseudo registers. */
|
|
set_gdbarch_pseudo_register_read (gdbarch, s390_pseudo_register_read);
|
|
--
|
|
2.43.0
|
|
|