From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from smtp.polymtl.ca (smtp.polymtl.ca [132.207.4.11]) by sourceware.org (Postfix) with ESMTPS id 030763858D1E for ; Wed, 8 Nov 2023 05:18:46 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 030763858D1E Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=polymtl.ca Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=polymtl.ca ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 030763858D1E Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=132.207.4.11 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1699420730; cv=none; b=EOHTm74cXz7xno/OXuPW6VOz49YR7eWUqXNllcgEbahSeBFrRrUXdN9Yms3NMC6nQ0AUhKlPGpTbMs5Fpv1TFzDEQkWuXUiFr8bxohdSdfdCiOuBJmpJ0PL6n/4QZ7VXdE3RiB0Z0lfXjgcUSuUY/DKyIAhIiWxS6ZGg6n3BDMw= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1699420730; c=relaxed/simple; bh=PEgTJMWarRkcrwY0IkrvsdX0Odv5/Lr/e23ibUYQ/e0=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=XW+dAT66gPcrhq+jTcN3V1T4wCqAStsWHQsl8wFzMdZ+rJVXOt8q3XtB+KGhgsQ/DNLhddDJJhz5ioKgAsePiFXAHEG+F24cOcUK7TIJmgNJDR9yI3Y0iN7fw7SzxdnX3/wWWPXr93F5otRVvK05UHhS+4uDk3JKMXDPzCBu5ys= ARC-Authentication-Results: i=1; server2.sourceware.org Received: from simark.ca (simark.ca [158.69.221.121]) (authenticated bits=0) by smtp.polymtl.ca (8.14.7/8.14.7) with ESMTP id 3A85IfIM016407 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Wed, 8 Nov 2023 00:18:45 -0500 DKIM-Filter: OpenDKIM Filter v2.11.0 smtp.polymtl.ca 3A85IfIM016407 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=polymtl.ca; s=default; t=1699420726; bh=WioefiLTgybxG7zkp8OYOwPbcB3a8iWBphWJnq9S4Z0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=dA8IBDU6uQGeqqIcFHcIsJJwGL799xNycm0l3NDyRUznSUZpNl3jkiuxvE6WHvdEv 8vAx7fpw9LcNc+Gktk7LJr+QQxHVZDAdB/9xF5fS7feiineY69wJVZQSxLGebnoVRz 0pwRBMdPYEhm5EP19hBbT2SldplRlDa4MsJBoMEI= Received: from simark.localdomain (modemcable238.237-201-24.mc.videotron.ca [24.201.237.238]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (prime256v1) server-digest SHA256) (No client certificate requested) by simark.ca (Postfix) with ESMTPSA id 2A2B61E098; Wed, 8 Nov 2023 00:18:41 -0500 (EST) From: Simon Marchi To: gdb-patches@sourceware.org Cc: Simon Marchi Subject: [PATCH 24/24] gdb/testsuite: add tests for unwinding of pseudo registers Date: Wed, 8 Nov 2023 00:01:08 -0500 Message-ID: <20231108051222.1275306-25-simon.marchi@polymtl.ca> X-Mailer: git-send-email 2.42.1 In-Reply-To: <20231108051222.1275306-1-simon.marchi@polymtl.ca> References: <20231108051222.1275306-1-simon.marchi@polymtl.ca> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Poly-FromMTA: (simark.ca [158.69.221.121]) at Wed, 8 Nov 2023 05:18:41 +0000 X-Spam-Status: No, score=-3188.6 required=5.0 tests=BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,GIT_PATCH_0,KAM_SHORT,RCVD_IN_MSPIKE_H3,RCVD_IN_MSPIKE_WL,SPF_HELO_PASS,SPF_PASS,TXREP,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: This patch adds tests to exercise the previous patches' changes. All three tests: - aarch64-pseudo-unwind - amd64-pseudo-unwind - arm-pseudo-unwind follow the same pattern, just with different registers. The other test, arm-pseudo-unwind-legacy, tests the special case where the unwind information contains an entry for a register considered a pseudo-register by GDB. Change-Id: Ic29ac040c5eb087b4a0d79f9d02f65b7979df30f --- .../gdb.arch/aarch64-pseudo-unwind-asm.S | 82 +++++++++++++++++ .../gdb.arch/aarch64-pseudo-unwind.c | 33 +++++++ .../gdb.arch/aarch64-pseudo-unwind.exp | 90 ++++++++++++++++++ .../gdb.arch/amd64-pseudo-unwind-asm.S | 66 ++++++++++++++ gdb/testsuite/gdb.arch/amd64-pseudo-unwind.c | 33 +++++++ .../gdb.arch/amd64-pseudo-unwind.exp | 91 +++++++++++++++++++ .../gdb.arch/arm-pseudo-unwind-asm.S | 81 +++++++++++++++++ .../gdb.arch/arm-pseudo-unwind-legacy-asm.S | 84 +++++++++++++++++ .../gdb.arch/arm-pseudo-unwind-legacy.c | 33 +++++++ .../gdb.arch/arm-pseudo-unwind-legacy.exp | 86 ++++++++++++++++++ gdb/testsuite/gdb.arch/arm-pseudo-unwind.c | 33 +++++++ gdb/testsuite/gdb.arch/arm-pseudo-unwind.exp | 88 ++++++++++++++++++ 12 files changed, 800 insertions(+) create mode 100644 gdb/testsuite/gdb.arch/aarch64-pseudo-unwind-asm.S create mode 100644 gdb/testsuite/gdb.arch/aarch64-pseudo-unwind.c create mode 100644 gdb/testsuite/gdb.arch/aarch64-pseudo-unwind.exp create mode 100644 gdb/testsuite/gdb.arch/amd64-pseudo-unwind-asm.S create mode 100644 gdb/testsuite/gdb.arch/amd64-pseudo-unwind.c create mode 100644 gdb/testsuite/gdb.arch/amd64-pseudo-unwind.exp create mode 100644 gdb/testsuite/gdb.arch/arm-pseudo-unwind-asm.S create mode 100644 gdb/testsuite/gdb.arch/arm-pseudo-unwind-legacy-asm.S create mode 100644 gdb/testsuite/gdb.arch/arm-pseudo-unwind-legacy.c create mode 100644 gdb/testsuite/gdb.arch/arm-pseudo-unwind-legacy.exp create mode 100644 gdb/testsuite/gdb.arch/arm-pseudo-unwind.c create mode 100644 gdb/testsuite/gdb.arch/arm-pseudo-unwind.exp diff --git a/gdb/testsuite/gdb.arch/aarch64-pseudo-unwind-asm.S b/gdb/testsuite/gdb.arch/aarch64-pseudo-unwind-asm.S new file mode 100644 index 000000000000..586642656296 --- /dev/null +++ b/gdb/testsuite/gdb.arch/aarch64-pseudo-unwind-asm.S @@ -0,0 +1,82 @@ +/* Copyright 2018-2023 Free Software Foundation, Inc. + + This file is part of GDB. + + 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 . */ + +.section .note.GNU-stack,"",%progbits + +.data +value_callee: +.quad 0x2021222324252627 +value_caller: +.quad 0x1011121314151617 + +.text +.global callee +callee: + /* Standard prologue: + - push fp (x29) and lr (x30) to the stack. + - mov sp to fp */ +.cfi_startproc + stp x29, x30, [sp, -16]! +.cfi_def_cfa 29, 16 +.cfi_offset 29, -16 +.cfi_offset 30, -8 + mov x29, sp + + /* Save caller's q8 value on the stack. */ +.cfi_offset 72, -32 + str q8, [sp, -16]! + + /* Put our own q8 value. */ + adr x0, value_callee + ld1 { v8.1d }, [x0] +break_here_asm: + + /* Restore caller's q8 value. */ + ldr q8, [sp], 16 + + /* Standard epilogue: + - pop fo (x29) and lr (x30) from the stack */ + ldp x29, x30, [sp], 16 + ret +.cfi_endproc + + +.global caller +caller: + /* Standard prologue. */ +.cfi_startproc + stp x29, x30, [sp, -16]! +.cfi_def_cfa 29, 16 +.cfi_offset x29, -16 +.cfi_offset x30, -8 + add x29, sp, 0 + + /* Put our own q8 value. */ + adr x0, value_caller + ld1 { v8.1d }, [x0] + + /* Call callee. */ + bl callee + + /* Store our q8 value in x0 to return it. */ + str q8, [sp, -16]! + ldr x0, [sp], 16 + + /* Standard epilogue. */ + ldp x29, x30, [sp], 16 + ret +.cfi_endproc diff --git a/gdb/testsuite/gdb.arch/aarch64-pseudo-unwind.c b/gdb/testsuite/gdb.arch/aarch64-pseudo-unwind.c new file mode 100644 index 000000000000..d18876fe3be3 --- /dev/null +++ b/gdb/testsuite/gdb.arch/aarch64-pseudo-unwind.c @@ -0,0 +1,33 @@ +/* Copyright 2018-2023 Free Software Foundation, Inc. + + This file is part of GDB. + + 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 . */ + +#include + +uint64_t caller (void); + +static void +break_here_c (uint64_t value) +{ +} + +int +main (void) +{ + uint64_t value = caller (); + break_here_c (value); + return 0; +} diff --git a/gdb/testsuite/gdb.arch/aarch64-pseudo-unwind.exp b/gdb/testsuite/gdb.arch/aarch64-pseudo-unwind.exp new file mode 100644 index 000000000000..685bebc9df1f --- /dev/null +++ b/gdb/testsuite/gdb.arch/aarch64-pseudo-unwind.exp @@ -0,0 +1,90 @@ +# Copyright 2018-2023 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 . + +# This test is equivalent to amd64-pseudo-unwind, but specific to AArch64. We +# use the raw register v8/q8 (it's the same register, but referred to differently +# depending on the instruction) which is 128 bits long (although we only load +# a 64-bits value, it's enough for the test). We use pseudo register s8, which +# is the low 32-bits of v8/q8. + +if { ![istarget aarch64-*-* ] } { + verbose "Skipping aarch64 pseudo register unwind." + return +} + +standard_testfile aarch64-pseudo-unwind.c aarch64-pseudo-unwind-asm.S + +if { [prepare_for_testing "failed to prepare" ${testfile} \ + "${srcfile} ${srcfile2}" {debug}] } { + return -1 +} + +clean_restart ${binfile} + +if ![runto_main] then { + fail "could not run to main" +} + +gdb_breakpoint break_here_asm temporary +gdb_continue_to_breakpoint "continue to callee" + +# Verify the value of v8/s8 in the inner frame (callee). +with_test_prefix "callee, before change" { + gdb_test "p/x \$v8.q.u" " = \\{0x2021222324252627\\}" + gdb_test "p/x \$s8.u" " = 0x24252627" +} + +# Verify that we can change the value of the pseudo register (s8) in the inner +# frame (callee). +gdb_test_no_output "set \$s8.u = 0x34353637" + +# Verify the value of v8/s8 in the inner frame (callee) after the change. +with_test_prefix "callee, after change" { + gdb_test "p/x \$v8.q.u" " = \\{0x34353637\\}" + gdb_test "p/x \$s8.u" " = 0x34353637" +} + +# Go up one frame (to caller) and do the same. +gdb_test "up" + +# Verify the value of v8/s8 in the outer frame (caller). +with_test_prefix "caller, before change" { + gdb_test "p/x \$v8.q.u" " = \\{0x1011121314151617\\}" + gdb_test "p/x \$s8.u" " = 0x14151617" +} + +# Verify that we can change the value of the pseudo register (s8) in the outer +# frame (caller). +gdb_test_no_output "set \$s8.u = 0x44454647" + +# Verify the value of v8/s8 in the outer frame (caller) after the change. +with_test_prefix "caller, after change" { + gdb_test "p/x \$v8.q.u" " = \\{0x44454647\\}" + gdb_test "p/x \$s8.u" " = 0x44454647" +} + +# Go back to frame 0 (callee), check that the change to the outer frame didn't +# mess up anything there. +gdb_test "down" +with_test_prefix "callee, after change in caller" { + gdb_test "p/x \$v8.q.u" " = \\{0x34353637\\}" + gdb_test "p/x \$s8.u" " = 0x34353637" +} + +# Verify that the value of the saved v8 we changed is correctly seen by the +# inferior. +gdb_breakpoint break_here_c temporary +gdb_continue_to_breakpoint "continue to break_here_c" +gdb_test "p/x value" " = 0x44454647" diff --git a/gdb/testsuite/gdb.arch/amd64-pseudo-unwind-asm.S b/gdb/testsuite/gdb.arch/amd64-pseudo-unwind-asm.S new file mode 100644 index 000000000000..c306b82e4864 --- /dev/null +++ b/gdb/testsuite/gdb.arch/amd64-pseudo-unwind-asm.S @@ -0,0 +1,66 @@ +/* Copyright 2018-2023 Free Software Foundation, Inc. + + This file is part of GDB. + + 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 . */ + +.section .note.GNU-stack,"",%progbits + +.text +.global callee +callee: + /* Standard prologue. */ +.cfi_startproc + push %rbp +.cfi_def_cfa rbp, 16 + mov %rsp, %rbp + + /* Save caller's rbx value on the stack. */ +.cfi_offset rbx, -24 + push %rbx + + /* Put our own rbx value. */ + mov $0x2021222324252627, %rbx +break_here_asm: + + /* Restore caller's rbx value. */ + pop %rbx + + /* Standard epilogue. */ + pop %rbp + ret +.cfi_endproc + + +.global caller +caller: +.cfi_startproc + /* Standard prologue. */ + push %rbp +.cfi_def_cfa_offset 16 + mov %rsp, %rbp + + /* Put our own rbx value. */ + mov $0x1011121314151617, %rbx + + /* Call callee. */ + call callee + + /* Store our rbx value in rax to return it. */ + mov %rbx, %rax + + /* Standard epilogue. */ + pop %rbp + ret +.cfi_endproc diff --git a/gdb/testsuite/gdb.arch/amd64-pseudo-unwind.c b/gdb/testsuite/gdb.arch/amd64-pseudo-unwind.c new file mode 100644 index 000000000000..d18876fe3be3 --- /dev/null +++ b/gdb/testsuite/gdb.arch/amd64-pseudo-unwind.c @@ -0,0 +1,33 @@ +/* Copyright 2018-2023 Free Software Foundation, Inc. + + This file is part of GDB. + + 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 . */ + +#include + +uint64_t caller (void); + +static void +break_here_c (uint64_t value) +{ +} + +int +main (void) +{ + uint64_t value = caller (); + break_here_c (value); + return 0; +} diff --git a/gdb/testsuite/gdb.arch/amd64-pseudo-unwind.exp b/gdb/testsuite/gdb.arch/amd64-pseudo-unwind.exp new file mode 100644 index 000000000000..45e9a3c96224 --- /dev/null +++ b/gdb/testsuite/gdb.arch/amd64-pseudo-unwind.exp @@ -0,0 +1,91 @@ +# Copyright 2018-2023 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 . + +# This test verifies that we can read and write the value of a pseudo register +# in unwound frames. For the test, we choose one raw register, rbx, and one +# pseudo register that is backed by rbx, ebx. We have two frames (the inner one, +# #0 and the outer one, #1) that each set a value for rbx. We verify that we +# can read both rbx and ebx correctly for each frame, and that when we write to +# ebx, rbx for that frame is correctly updated. + +if { ![istarget x86_64-*-* ] || ![is_lp64_target] } { + verbose "Skipping amd64 pseudo register unwind." + return +} + +standard_testfile amd64-pseudo-unwind.c amd64-pseudo-unwind-asm.S + +if { [prepare_for_testing "failed to prepare" ${testfile} \ + "${srcfile} ${srcfile2}" {debug}] } { + return -1 +} + +clean_restart ${binfile} + +if ![runto_main] then { + fail "could not run to main" +} + +gdb_breakpoint break_here_asm temporary +gdb_continue_to_breakpoint "continue to callee" + +# Verify the value of rbx/ebx in the inner frame (callee). +with_test_prefix "callee, before change" { + gdb_test "p/x \$rbx" " = 0x2021222324252627" + gdb_test "p/x \$ebx" " = 0x24252627" +} + +# Verify that we can change the value of the pseudo register (ebx) in the inner +# frame (callee). +gdb_test_no_output "set \$ebx = 0x34353637" + +# Verify the value of rbx/ebx in the inner frame (callee) after the change. +with_test_prefix "callee, after change" { + gdb_test "p/x \$rbx" " = 0x2021222334353637" + gdb_test "p/x \$ebx" " = 0x34353637" +} + +# Go up one frame, and do the same. +gdb_test "up" + +# Verify the value of rbx/ebx in the outer frame (caller). +with_test_prefix "caller, before change" { + gdb_test "p/x \$rbx" " = 0x1011121314151617" + gdb_test "p/x \$ebx" " = 0x14151617" +} + +# Verify that we can change the value of the pseudo register (ebx) in the outer +# frame (caller). +gdb_test_no_output "set \$ebx = 0x44454647" + +# Verify the value of rbx/ebx in the outer frame (caller) after the change. +with_test_prefix "caller, after change" { + gdb_test "p/x \$rbx" " = 0x1011121344454647" + gdb_test "p/x \$ebx" " = 0x44454647" +} + +# Go back to frame 0 (callee), check that the change to the outer frame didn't +# mess up anything there. +gdb_test "down" +with_test_prefix "callee, after change in caller" { + gdb_test "p/x \$rbx" " = 0x2021222334353637" + gdb_test "p/x \$ebx" " = 0x34353637" +} + +# Verify that the value of the saved rbx we changed is correctly seen by the +# inferior. +gdb_breakpoint break_here_c temporary +gdb_continue_to_breakpoint "continue to break_here_c" +gdb_test "p/x value" " = 0x1011121344454647" diff --git a/gdb/testsuite/gdb.arch/arm-pseudo-unwind-asm.S b/gdb/testsuite/gdb.arch/arm-pseudo-unwind-asm.S new file mode 100644 index 000000000000..8d78573cefe4 --- /dev/null +++ b/gdb/testsuite/gdb.arch/arm-pseudo-unwind-asm.S @@ -0,0 +1,81 @@ +/* Copyright 2018-2023 Free Software Foundation, Inc. + + This file is part of GDB. + + 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 . */ + +.section .note.GNU-stack,"",%progbits + +.data +value_callee: +.quad 0x2021222324252627 +value_caller: +.quad 0x1011121314151617 + +.text +.arm +.global callee +callee: + /* Standard prologue. */ +.cfi_startproc + push {fp, lr} +.cfi_def_cfa fp, 4 +.cfi_offset fp, -8 +.cfi_offset lr, -4 + add fp, sp, #4 + + /* Save caller's d8 value on the stack. */ +.cfi_offset d8, -16 + vpush {d8} + + /* Put our own d8 value. */ + ldr r0, =value_callee + vldr d8, [r0] +break_here_asm: + + /* Restore caller's d8 value. */ + vpop {d8} + + /* Standard epilogue. */ + pop {fp, pc} +.cfi_endproc + + +.global caller +caller: + /* Standard prologue. */ +.cfi_startproc + push {fp, lr} +.cfi_def_cfa fp, 4 +.cfi_offset fp, -8 +.cfi_offset lr, -4 + add fp, sp, #4 + + /* Put our own d8 value. */ + ldr r0, =value_caller + vldr d8, [r0] + + /* Call callee. */ + bl callee + + /* Store our d8 value in r0-r1 to return it. */ + vpush {d8} + pop {r0} + pop {r1} + + /* Standard epilogue. */ + pop {fp, pc} +.cfi_endproc + + diff --git a/gdb/testsuite/gdb.arch/arm-pseudo-unwind-legacy-asm.S b/gdb/testsuite/gdb.arch/arm-pseudo-unwind-legacy-asm.S new file mode 100644 index 000000000000..786e79a0543e --- /dev/null +++ b/gdb/testsuite/gdb.arch/arm-pseudo-unwind-legacy-asm.S @@ -0,0 +1,84 @@ +/* Copyright 2018-2023 Free Software Foundation, Inc. + + This file is part of GDB. + + 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 . */ + +/* The difference between this and arm-pseudo-unwind is that here, the CFI + directives use the obsolete DWARF number for the s16 register (a + pseudo-register in GDB), whereas arm-pseudo-unwind uses the number for the d8 + register (the underlying raw register for s16). */ + +.section .note.GNU-stack,"",%progbits + +.data +value_callee: +.quad 0x20212223 +value_caller: +.quad 0x10111213 + +.text +.arm +.global callee +callee: +.cfi_startproc + /* Standard prologue. */ + push {fp, lr} +.cfi_def_cfa fp, 4 +.cfi_offset fp, -8 +.cfi_offset lr, -4 + add fp, sp, #4 + + /* Save caller's s16 value on the stack. */ +.cfi_offset 80, -12 + vpush {s16} + + /* Put our own s16 value. */ + ldr r0, =value_callee + vldr s16, [r0] +break_here_asm: + + /* Restore caller's s16 value. */ + vpop {s16} + + /* Standard epilogue. */ + pop {fp, pc} +.cfi_endproc + + +.global caller +caller: +.cfi_startproc + /* Standard prologue. */ + push {fp, lr} +.cfi_def_cfa fp, 4 +.cfi_offset fp, -8 +.cfi_offset lr, -4 + add fp, sp, #4 + + /* Put our own s16 value. */ + ldr r0, =value_caller + vldr s16, [r0] + + /* Call callee. */ + bl callee + + /* Store our s16 value in r0-r1 to return it. */ + vpush {s16} + pop {r0} + mov r1, #0 + + /* Standard epilogue. */ + pop {fp, pc} +.cfi_endproc diff --git a/gdb/testsuite/gdb.arch/arm-pseudo-unwind-legacy.c b/gdb/testsuite/gdb.arch/arm-pseudo-unwind-legacy.c new file mode 100644 index 000000000000..d18876fe3be3 --- /dev/null +++ b/gdb/testsuite/gdb.arch/arm-pseudo-unwind-legacy.c @@ -0,0 +1,33 @@ +/* Copyright 2018-2023 Free Software Foundation, Inc. + + This file is part of GDB. + + 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 . */ + +#include + +uint64_t caller (void); + +static void +break_here_c (uint64_t value) +{ +} + +int +main (void) +{ + uint64_t value = caller (); + break_here_c (value); + return 0; +} diff --git a/gdb/testsuite/gdb.arch/arm-pseudo-unwind-legacy.exp b/gdb/testsuite/gdb.arch/arm-pseudo-unwind-legacy.exp new file mode 100644 index 000000000000..c3d0979799dc --- /dev/null +++ b/gdb/testsuite/gdb.arch/arm-pseudo-unwind-legacy.exp @@ -0,0 +1,86 @@ +# Copyright 2018-2023 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 . + +# This test is in the same vein as amd64-pseudo-unwind, making sure we can +# read write pseudo registers in outer frames. However, it tests a special +# case where the debug info includes unwind information for a pseudo register +# but not the underlying raw register. This can happen for the pseudo register +# s16, which is the bottom half of the raw register d8. +# +# See "DWARF for the ARM architecture": +# https://github.com/ARM-software/abi-aa/releases/download/2023Q3/aadwarf32.pdf + +if { ![istarget arm*-*-* ] } { + verbose "Skipping arm pseudo register unwind." + return +} + +standard_testfile arm-pseudo-unwind-legacy.c arm-pseudo-unwind-legacy-asm.S + +if { [prepare_for_testing "failed to prepare" ${testfile} \ + "${srcfile} ${srcfile2}" {debug additional_flags=-marm}] } { + return -1 +} + +clean_restart ${binfile} + +if ![runto_main] then { + fail "could not run to main" +} + +gdb_breakpoint break_here_asm temporary +gdb_continue_to_breakpoint "continue to callee" + +# Verify the value of s16 in the inner frame (callee). +with_test_prefix "callee, before change" { + gdb_test "p/x \$s16" " = 0x20212223" +} + +# Verify that we can change the value of s16 in the inner frame (callee). +gdb_test_no_output "set \$s16 = 1.0" + +# Verify the value of s16 in the inner frame (callee) after the change. +with_test_prefix "callee, after change" { + gdb_test "p/x \$s16" " = 0x3f800000" +} + +# Go up one frame, and do the same. +gdb_test "up" + +# Verify the value of s16 in the outer frame (caller). +with_test_prefix "caller, before change" { + gdb_test "p/x \$s16" " = 0x10111213" +} + +# Verify that we can change the value of s16 in the outer frame (caller). +gdb_test_no_output "set \$s16 = 2.0" + +# Verify the value of s16 in the outer frame (caller) after the change. +with_test_prefix "caller, after change" { + gdb_test "p/x \$s16" " = 0x40000000" +} + +# Go back to frame 0 (callee), check that the change to the outer frame didn't +# mess up anything there. +gdb_test "down" +with_test_prefix "callee, after change in caller" { + gdb_test "p/x \$s16" " = 0x3f800000" +} + +# Verify that the value of the saved s16 we changed is correctly seen by the +# inferior. +gdb_breakpoint break_here_c temporary +gdb_continue_to_breakpoint "continue to break_here_c" +gdb_test "p/x value" " = 0x40000000" diff --git a/gdb/testsuite/gdb.arch/arm-pseudo-unwind.c b/gdb/testsuite/gdb.arch/arm-pseudo-unwind.c new file mode 100644 index 000000000000..d18876fe3be3 --- /dev/null +++ b/gdb/testsuite/gdb.arch/arm-pseudo-unwind.c @@ -0,0 +1,33 @@ +/* Copyright 2018-2023 Free Software Foundation, Inc. + + This file is part of GDB. + + 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 . */ + +#include + +uint64_t caller (void); + +static void +break_here_c (uint64_t value) +{ +} + +int +main (void) +{ + uint64_t value = caller (); + break_here_c (value); + return 0; +} diff --git a/gdb/testsuite/gdb.arch/arm-pseudo-unwind.exp b/gdb/testsuite/gdb.arch/arm-pseudo-unwind.exp new file mode 100644 index 000000000000..bfe81b7d5f21 --- /dev/null +++ b/gdb/testsuite/gdb.arch/arm-pseudo-unwind.exp @@ -0,0 +1,88 @@ +# Copyright 2018-2023 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 . + +# This test is equivalent to amd64-pseudo-unwind, but specific to ARM. We +# use the raw register d8 which is 64 bits long. We use pseudo register s16, +# which is the low 32 bits of d8. + +if { ![istarget arm*-*-* ] } { + verbose "Skipping arm pseudo register unwind." + return +} + +standard_testfile arm-pseudo-unwind.c arm-pseudo-unwind-asm.S + +if { [prepare_for_testing "failed to prepare" ${testfile} \ + "${srcfile} ${srcfile2}" {debug additional_flags=-marm}] } { + return -1 +} + +clean_restart ${binfile} + +if ![runto_main] then { + fail "could not run to main" +} + +gdb_breakpoint break_here_asm temporary +gdb_continue_to_breakpoint "continue to callee" + +# Verify the value of d8/s16 in the inner frame (callee). +with_test_prefix "callee, before change" { + gdb_test "p/x \$d8" " = 0x2021222324252627" + gdb_test "p/x \$s16" " = 0x24252627" +} + +# Verify that we can change the value of the pseudo register (s16) in the inner +# frame (callee). +gdb_test_no_output "set \$s16 = 1.0" + +# Verify the value of d8/s16 in the inner frame (callee) after the change. +with_test_prefix "callee, after change" { + gdb_test "p/x \$d8" " = 0x202122233f800000" + gdb_test "p/x \$s16" " = 0x3f800000" +} + +# Go up one frame (to caller), and do the same. +gdb_test "up" + +# Verify the value of d8/s16 in the outer frame (caller). +with_test_prefix "caller, before change" { + gdb_test "p/x \$d8" " = 0x1011121314151617" + gdb_test "p/x \$s16" " = 0x14151617" +} + +# Verify that we can change the value of the pseudo register (s16) in the outer +# frame (caller). +gdb_test_no_output "set \$s16 = 2.0" + +# Verify the value of d8/s16 in the outer frame (caller) after the change. +with_test_prefix "caller, after change" { + gdb_test "p/x \$d8" " = 0x1011121340000000" + gdb_test "p/x \$s16" " = 0x40000000" +} + +# Go back to frame 0 (callee), check that the change to the outer frame didn't +# mess up anything there. +gdb_test "down" +with_test_prefix "callee, after change in caller" { + gdb_test "p/x \$d8" " = 0x202122233f800000" + gdb_test "p/x \$s16" " = 0x3f800000" +} + +# Verify that the value of the saved d8 we changed is correctly seen by the +# inferior. +gdb_breakpoint break_here_c temporary +gdb_continue_to_breakpoint "continue to break_here_c" +gdb_test "p/x value" " = 0x1011121340000000" -- 2.42.1