gdb/fix-gdb.base-store.exp-on-s390x.patch
Tom de Vries f61a679e8e - Maintenance script qa.sh:
* 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
2025-02-13 14:36:11 +00:00

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