Files
binutils-gdb/gdb/testsuite/gdb.ada/return-small-char-array.exp
Tom de Vries 0e4fd060ee [gdb/tdep] Fix inferior call return of small char array for ppc64 v1 abi some more
PR tdep/33534 reports a regression due to commit 13f1820106 ("[gdb/tdep] Fix
inferior call return of small char array for ppc64 v1 abi").

The regression can be reproduced with the test-case introduced in the commit:
gdb.ada/return-small-char-array.exp, on a ppc64-linux setup with v1 elf abi
(cfarm121).

The commit contains two changes to a piece of code in
ppc64_sysv_abi_return_value:
...
   /* Small character arrays are returned, right justified, in r3.  */
-  if (valtype->code () == TYPE_CODE_ARRAY
+  if (tdep->elf_abi == POWERPC_ELF_V1
+      && valtype->code () == TYPE_CODE_ARRAY
       && !valtype->is_vector ()
       && valtype->length () <= 8
-      && valtype->target_type ()->code () == TYPE_CODE_INT
+      && (valtype->target_type ()->code () == TYPE_CODE_INT
+	  || valtype->target_type ()->code () == TYPE_CODE_CHAR)
       && valtype->target_type ()->length () == 1)
...

The first change limits the effect of the if clause to the v1 elf abi.  This
change doesn't affect the regression, since it's on a ppc64-linux setup with
v1 elf abi.  Furthermore, it's correct in the sense that the v2 elf abi
doesn't have this kind of special treatment of small character arrays.

The second change is the part that causes the regression.  The code itself
seems correct, in the sense that it enables gdb to recognize small char arrays
in ada.

The regression stems from the following discrepancy.

The comment in gdb states that "small character arrays are returned, right
justified, in r3".  This matches the v1 ABI [1].

OTOH, gcc produces code that is not in agreement with this.  Instead, it
passes the small character arrays in memory, in a caller-allocated storage
buffer pointed at by r3.  This turns out to be an gcc bug [2].

Fix this by treating this as an abi spec bug, and replacing the code handling
the "Small character arrays" case with a comment.

Doing so reveals that there are two problems in the test-case:
- missing fvar-tracking, and
- the "step 2" command doesn't land at the intended line.

Fix these by:
- adding fvar-tracking, and
- setting a breakpoint at the intended line, and continuing to it.

Tested on ppc64-linux (v1 abi), ppc64le-linux (v2 abi), and x86_64-linux.

Approved-By: Tom Tromey <tom@tromey.com>

Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=33534

[1] https://refspecs.linuxfoundation.org/ELF/ppc64/PPC-elf64abi-1.9.html.
[2] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=122282
2025-10-17 08:02:02 +02:00

51 lines
1.5 KiB
Plaintext

# Copyright 2025 Free Software Foundation, Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
load_lib "ada.exp"
require allow_ada_tests
standard_ada_testfile proc
set opts {}
lappend opts debug
if { [ada_fvar_tracking] } {
lappend opts "additional_flags=-fvar-tracking"
}
if { [gdb_compile_ada $srcfile $binfile executable $opts] != "" } {
return
}
clean_restart $testfile
set bp_location [gdb_get_line_number "STOP" $testdir/proc.adb]
runto "proc.adb:$bp_location"
gdb_test "print Value.Name(My_Value)" \
{ = "abcd"}
# Step into the function. Don't do this by stepping, but by setting a
# breakpoint and continuing to it, to avoid the problem that varying line info
# may require us to step a different amount of times to land at the same
# location.
set bp_location_2 [gdb_get_line_number "STOP" $testdir/value.adb]
gdb_breakpoint value.adb:$bp_location_2
gdb_continue_to_breakpoint "STOP"
# and finish.
gdb_test "finish" \
{ = "abcd"}