[gdb/testsuite] Add gdb.arch/ppc64-break-on-_exit.exp Add a regression test-case for commit a50bdb99afe "[gdb/tdep, rs6000] Don't skip system call in skip_prologue": - set a breakpoint on a local copy of glibc's _exit, and - verify that it triggers. The test-case uses an assembly file by default, but also has the possibility to use a C source file instead. Tested on ppc64le-linux. Verified that the test-case fails without aforementioned commit, and passes with the commit. Both with assembly and C source. --- gdb/testsuite/gdb.arch/ppc64-break-on-_exit-main.c | 27 +++++ gdb/testsuite/gdb.arch/ppc64-break-on-_exit.c | 112 +++++++++++++++++++++ gdb/testsuite/gdb.arch/ppc64-break-on-_exit.exp | 56 +++++++++++ gdb/testsuite/gdb.arch/ppc64-break-on-_exit.s | 108 ++++++++++++++++++++ 4 files changed, 303 insertions(+) diff --git a/gdb/testsuite/gdb.arch/ppc64-break-on-_exit-main.c b/gdb/testsuite/gdb.arch/ppc64-break-on-_exit-main.c new file mode 100644 index 00000000000..77253140e36 --- /dev/null +++ b/gdb/testsuite/gdb.arch/ppc64-break-on-_exit-main.c @@ -0,0 +1,27 @@ +/* This file is part of GDB, the GNU debugger. + + Copyright 2021 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 . */ + +#include + +__thread int __libc_errno; + +int +main () +{ + _exit (22); + return 0; +} diff --git a/gdb/testsuite/gdb.arch/ppc64-break-on-_exit.c b/gdb/testsuite/gdb.arch/ppc64-break-on-_exit.c new file mode 100644 index 00000000000..8638a7a6b70 --- /dev/null +++ b/gdb/testsuite/gdb.arch/ppc64-break-on-_exit.c @@ -0,0 +1,112 @@ +/* This file is part of GDB, the GNU debugger. + + Copyright 2021 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 file was generated from glibc's 2.31 _exit.c, by doing a glibc build + on ppc64le-linux, copying the command line, adding -g0 -save-temps and + recuding the _exit.i file. */ + +void _exit (int status); + +extern __thread int __libc_errno; + +void +_exit (int status) +{ + while (1) + { + ({ + long int sc_err __attribute__ ((unused)); + long int sc_ret + = ({ + register long int r0 __asm__ ("r0"); + register long int r3 __asm__ ("r3"); + register long int r4 __asm__ ("r4"); + register long int r5 __asm__ ("r5"); + register long int r6 __asm__ ("r6"); + register long int r7 __asm__ ("r7"); + register long int r8 __asm__ ("r8"); + long int arg1 = (long int) (status); + + r0 = 234; + + extern void __illegally_sized_syscall_arg1 (void); + if (__builtin_classify_type (status) != 5 && sizeof (status) > 8) + __illegally_sized_syscall_arg1 (); + + r3 = arg1; + __asm__ __volatile__ ("sc\n\t" "mfcr %0\n\t" "0:" + : "=&r" (r0), "=&r" (r3), "=&r" (r4), + "=&r" (r5), "=&r" (r6), "=&r" (r7), + "=&r" (r8) : "0" (r0), "1" (r3) + : "r9", "r10", "r11", "r12", "cr0", "ctr", "memory"); + sc_err = r0; + + r3; + }); + + if (((void) (sc_ret), __builtin_expect ((sc_err) & (1 << 28), 0))) + { + (__libc_errno = ((sc_ret))); + sc_ret = -1L; + } + + sc_ret; + }); + + ({ + long int sc_err __attribute__ ((unused)); + long int sc_ret + = ({ + register long int r0 __asm__ ("r0"); + register long int r3 __asm__ ("r3"); + register long int r4 __asm__ ("r4"); + register long int r5 __asm__ ("r5"); + register long int r6 __asm__ ("r6"); + register long int r7 __asm__ ("r7"); + register long int r8 __asm__ ("r8"); + long int arg1 = (long int) (status); + + r0 = 1; + + extern void __illegally_sized_syscall_arg1 (void); + if (__builtin_classify_type (status) != 5 && sizeof (status) > 8) + __illegally_sized_syscall_arg1 (); + + r3 = arg1; + __asm__ __volatile__ ("sc\n\t" "mfcr %0\n\t" "0:" + : "=&r" (r0), "=&r" (r3), "=&r" (r4), + "=&r" (r5), "=&r" (r6), "=&r" (r7), + "=&r" (r8) : "0" (r0), "1" (r3) + : "r9", "r10", "r11", "r12", "cr0", "ctr", "memory"); + sc_err = r0; + + r3; + }); + + if (((void) (sc_ret), __builtin_expect ((sc_err) & (1 << 28), 0))) + { + (__libc_errno = ((sc_ret))); + sc_ret = -1L; + } + + sc_ret; + }); + + + asm (".long 0"); + } +} diff --git a/gdb/testsuite/gdb.arch/ppc64-break-on-_exit.exp b/gdb/testsuite/gdb.arch/ppc64-break-on-_exit.exp new file mode 100644 index 00000000000..b2fef8e8b76 --- /dev/null +++ b/gdb/testsuite/gdb.arch/ppc64-break-on-_exit.exp @@ -0,0 +1,56 @@ +# Copyright 2021 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 . + +# Set a breakpoint on a local copy of glibc's _exit, and verify that it +# triggers. The function does a syscall immediately after the prologue, and +# if the breakpoint is set past the syscall due to faulty prologue skipping, +# the breakpoint will not trigger. +# +# In particular, we're trying to excercise the instruction analysis +# functionality of prologue skipping. If non-minimal symbols are +# read, then that functionality might not be used because f.i. +# line-info is used instead. So, we use nodebug. + +if {![istarget "powerpc*"] || ![is_lp64_target]} { + unsupported "Not powerpc64" + return +} + +set flags { nodebug } +if { 1 } { + standard_testfile .s -main.c +} else { + standard_testfile .c -main.c + lappend flags optimize=-O2 + lappend flags additional_flags=-fno-stack-protector + lappend flags additional_flags=-mlong-double-128 + lappend flags additional_flags=-fpic + lappend flags additional_flags=-ftls-model=initial-exec +} + +if { [prepare_for_testing "failed to prepare" ${testfile} \ + [list $srcfile $srcfile2] $flags] } { + return -1 +} + +if ![runto_main] then { + return 0 +} + +gdb_breakpoint "_exit" + +# If the skip_prologue analysis of _exit is too eager, we may not hit the +# breakpoint. +gdb_continue_to_breakpoint "_exit" "_exit \\(\\).*" diff --git a/gdb/testsuite/gdb.arch/ppc64-break-on-_exit.s b/gdb/testsuite/gdb.arch/ppc64-break-on-_exit.s new file mode 100644 index 00000000000..37a9ace2aff --- /dev/null +++ b/gdb/testsuite/gdb.arch/ppc64-break-on-_exit.s @@ -0,0 +1,108 @@ +/* This file is part of GDB, the GNU debugger. + + Copyright 2021 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 file was generated from ppc64-break-on-_exit.c. */ + + .file "ppc64-break-on-_exit.c" + .abiversion 2 + .section ".text" + .align 2 + .p2align 4,,15 + .globl _exit + .type _exit, @function +_exit: +.LCF0: +0: addis 2,12,.TOC.-.LCF0@ha + addi 2,2,.TOC.-.LCF0@l + .localentry _exit,.-_exit + addis 9,2,__libc_errno@got@tprel@ha + std 31,-8(1) + mr 31,3 + std 30,-16(1) + li 0,234 + ld 9,__libc_errno@got@tprel@l(9) + mr 3,31 + add 30,9,__libc_errno@tls +#APP + # 28 "src/gdb/testsuite/gdb.arch/ppc64-break-on-_exit.c" 1 + sc + mfcr 0 + 0: + # 0 "" 2 +#NO_APP + andis. 9,0,0x1000 + mr 9,3 + li 0,1 + mr 3,31 + bne 0,.L13 + .p2align 4,,15 +.L2: +#APP + # 67 "src/gdb/testsuite/gdb.arch/ppc64-break-on-_exit.c" 1 + sc + mfcr 0 + 0: + # 0 "" 2 +#NO_APP + andis. 9,0,0x1000 + bne 0,.L14 +.L3: +#APP + # 87 "src/gdb/testsuite/gdb.arch/ppc64-break-on-_exit.c" 1 + .long 0 + # 0 "" 2 +#NO_APP +.L15: + li 0,234 + mr 3,31 +#APP + # 28 "src/gdb/testsuite/gdb.arch/ppc64-break-on-_exit.c" 1 + sc + mfcr 0 + 0: + # 0 "" 2 +#NO_APP + andis. 9,0,0x1000 + mr 9,3 + li 0,1 + mr 3,31 + beq 0,.L2 +.L13: + stw 9,0(30) +#APP + # 67 "src/gdb/testsuite/gdb.arch/ppc64-break-on-_exit.c" 1 + sc + mfcr 0 + 0: + # 0 "" 2 +#NO_APP + andis. 9,0,0x1000 + beq 0,.L3 + .p2align 4,,15 +.L14: + stw 3,0(30) +#APP + # 87 "src/gdb/testsuite/gdb.arch/ppc64-break-on-_exit.c" 1 + .long 0 + # 0 "" 2 +#NO_APP + b .L15 + .long 0 + .byte 0,0,0,0,0,2,0,0 + .size _exit,.-_exit + .ident "GCC: (SUSE Linux) 7.5.0" + .section .note.GNU-stack,"",@progbits