* Make rpm matching yet more precise. - Update patch: * gdb-tdep-fix-powerpc-ieee-128-bit-format-arg-passing.patch - Add patches: * gdb-handle-pending-c-after-rl_callback_read_char.patch * gdb-testsuite-fix-have_mpx-test.patch * gdb-symtab-fix-handling-of-dw_tag_unspecified_type.patch * gdb-testsuite-fix-gdb.dwarf2-dw2-unspecified-type-foo.c-with-m32.patch OBS-URL: https://build.opensuse.org/package/show/devel:gcc/gdb?expand=0&rev=333
150 lines
4.8 KiB
Diff
150 lines
4.8 KiB
Diff
[gdb/tdep] Fix PowerPC IEEE 128-bit format arg passing
|
|
|
|
On a powerpc system with gcc 12 built to default to 128-bit IEEE long double,
|
|
I run into:
|
|
...
|
|
(gdb) print find_max_long_double_real(4, ldc1, ldc2, ldc3, ldc4)^M
|
|
$8 = 0 + 0i^M
|
|
(gdb) FAIL: gdb.base/varargs.exp: print \
|
|
find_max_long_double_real(4, ldc1, ldc2, ldc3, ldc4)
|
|
...
|
|
|
|
This is due to incorrect handling of the argument in ppc64_sysv_abi_push_param.
|
|
|
|
Fix this and similar cases, and expand the test-case to test handling of
|
|
homogeneous aggregates.
|
|
|
|
Tested on ppc64le-linux, power 10.
|
|
|
|
Co-Authored-By: Ulrich Weigand <uweigand@de.ibm.com>
|
|
Tested-by: Carl Love <cel@us.ibm.com>
|
|
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=29543
|
|
|
|
---
|
|
gdb/ppc-sysv-tdep.c | 25 +++++++++++++++++++------
|
|
gdb/testsuite/gdb.base/varargs.c | 28 ++++++++++++++++++++++++++++
|
|
gdb/testsuite/gdb.base/varargs.exp | 2 ++
|
|
3 files changed, 49 insertions(+), 6 deletions(-)
|
|
|
|
diff --git a/gdb/ppc-sysv-tdep.c b/gdb/ppc-sysv-tdep.c
|
|
index b7106542b5d..5a8761d64e7 100644
|
|
--- a/gdb/ppc-sysv-tdep.c
|
|
+++ b/gdb/ppc-sysv-tdep.c
|
|
@@ -1444,7 +1444,7 @@ ppc64_sysv_abi_push_param (struct gdbarch *gdbarch,
|
|
== floatformats_ia64_quad))
|
|
{
|
|
/* IEEE FLOAT128, args in vector registers. */
|
|
- ppc64_sysv_abi_push_val (gdbarch, val, TYPE_LENGTH (type), 0, argpos);
|
|
+ ppc64_sysv_abi_push_val (gdbarch, val, TYPE_LENGTH (type), 16, argpos);
|
|
ppc64_sysv_abi_push_vreg (gdbarch, val, argpos);
|
|
}
|
|
else if (type->code () == TYPE_CODE_FLT
|
|
@@ -1514,7 +1514,10 @@ ppc64_sysv_abi_push_param (struct gdbarch *gdbarch,
|
|
}
|
|
else
|
|
{
|
|
- ppc64_sysv_abi_push_val (gdbarch, val, TYPE_LENGTH (type), 0, argpos);
|
|
+ /* Align == 0 is correct for ppc64_sysv_abi_push_freg,
|
|
+ Align == 16 is correct for ppc64_sysv_abi_push_vreg.
|
|
+ Default to 0. */
|
|
+ int align = 0;
|
|
|
|
/* The ABI (version 1.9) specifies that structs containing a
|
|
single floating-point value, at any level of nesting of
|
|
@@ -1532,7 +1535,10 @@ ppc64_sysv_abi_push_param (struct gdbarch *gdbarch,
|
|
if (TYPE_LENGTH (type) == 16
|
|
&& (gdbarch_long_double_format (gdbarch)
|
|
== floatformats_ia64_quad))
|
|
- ppc64_sysv_abi_push_vreg (gdbarch, val, argpos);
|
|
+ {
|
|
+ ppc64_sysv_abi_push_vreg (gdbarch, val, argpos);
|
|
+ align = 16;
|
|
+ }
|
|
else
|
|
ppc64_sysv_abi_push_freg (gdbarch, type, val, argpos);
|
|
}
|
|
@@ -1556,8 +1562,10 @@ ppc64_sysv_abi_push_param (struct gdbarch *gdbarch,
|
|
&& (gdbarch_long_double_format (gdbarch)
|
|
== floatformats_ia64_quad))
|
|
/* IEEE FLOAT128, args in vector registers. */
|
|
- ppc64_sysv_abi_push_vreg (gdbarch, elval, argpos);
|
|
-
|
|
+ {
|
|
+ ppc64_sysv_abi_push_vreg (gdbarch, elval, argpos);
|
|
+ align = 16;
|
|
+ }
|
|
else if (eltype->code () == TYPE_CODE_FLT
|
|
|| eltype->code () == TYPE_CODE_DECFLOAT)
|
|
/* IBM long double and all other floats and decfloats, args
|
|
@@ -1567,9 +1575,14 @@ ppc64_sysv_abi_push_param (struct gdbarch *gdbarch,
|
|
&& eltype->is_vector ()
|
|
&& tdep->vector_abi == POWERPC_VEC_ALTIVEC
|
|
&& TYPE_LENGTH (eltype) == 16)
|
|
- ppc64_sysv_abi_push_vreg (gdbarch, elval, argpos);
|
|
+ {
|
|
+ ppc64_sysv_abi_push_vreg (gdbarch, elval, argpos);
|
|
+ align = 16;
|
|
+ }
|
|
}
|
|
}
|
|
+
|
|
+ ppc64_sysv_abi_push_val (gdbarch, val, TYPE_LENGTH (type), align, argpos);
|
|
}
|
|
}
|
|
|
|
diff --git a/gdb/testsuite/gdb.base/varargs.c b/gdb/testsuite/gdb.base/varargs.c
|
|
index cacb29d89e7..fcadcee6fb3 100644
|
|
--- a/gdb/testsuite/gdb.base/varargs.c
|
|
+++ b/gdb/testsuite/gdb.base/varargs.c
|
|
@@ -45,6 +45,16 @@ long double _Complex ldc2 = 2.0L + 2.0Li;
|
|
long double _Complex ldc3 = 3.0L + 3.0Li;
|
|
long double _Complex ldc4 = 4.0L + 4.0Li;
|
|
|
|
+struct sldc
|
|
+{
|
|
+ long double _Complex ldc;
|
|
+};
|
|
+
|
|
+struct sldc sldc1 = { 1.0L + 1.0Li };
|
|
+struct sldc sldc2 = { 2.0L + 2.0Li };
|
|
+struct sldc sldc3 = { 3.0L + 3.0Li };
|
|
+struct sldc sldc4 = { 4.0L + 4.0Li };
|
|
+
|
|
#endif
|
|
|
|
int
|
|
@@ -201,4 +211,22 @@ find_max_long_double_real (int num_vals, ...)
|
|
}
|
|
|
|
|
|
+long double _Complex
|
|
+find_max_struct_long_double_real (int num_vals, ...)
|
|
+{
|
|
+ long double _Complex max = 0.0L + 0.0iL;
|
|
+ struct sldc x;
|
|
+ va_list argp;
|
|
+ int i;
|
|
+
|
|
+ va_start(argp, num_vals);
|
|
+ for (i = 0; i < num_vals; i++)
|
|
+ {
|
|
+ x = va_arg (argp, struct sldc);
|
|
+ if (creall (max) < creal (x.ldc)) max = x.ldc;
|
|
+ }
|
|
+
|
|
+ return max;
|
|
+}
|
|
+
|
|
#endif /* TEST_COMPLEX */
|
|
diff --git a/gdb/testsuite/gdb.base/varargs.exp b/gdb/testsuite/gdb.base/varargs.exp
|
|
index e778af031cf..f3d413e4de6 100644
|
|
--- a/gdb/testsuite/gdb.base/varargs.exp
|
|
+++ b/gdb/testsuite/gdb.base/varargs.exp
|
|
@@ -107,4 +107,6 @@ if [support_complex_tests] {
|
|
set test "print find_max_long_double_real(4, ldc1, ldc2, ldc3, ldc4)"
|
|
gdb_test $test ".*= 4 \\+ 4i"
|
|
|
|
+ set test "print find_max_struct_long_double_real(4, sldc1, sldc2, sldc3, sldc4)"
|
|
+ gdb_test $test ".*= 4 \\+ 4i"
|
|
}
|