diff options
Diffstat (limited to 'gdb/testsuite/gdb.arch/amd64-extended-prologue-analysis.c')
-rw-r--r-- | gdb/testsuite/gdb.arch/amd64-extended-prologue-analysis.c | 56 |
1 files changed, 56 insertions, 0 deletions
diff --git a/gdb/testsuite/gdb.arch/amd64-extended-prologue-analysis.c b/gdb/testsuite/gdb.arch/amd64-extended-prologue-analysis.c new file mode 100644 index 0000000..707b4fb --- /dev/null +++ b/gdb/testsuite/gdb.arch/amd64-extended-prologue-analysis.c @@ -0,0 +1,56 @@ +/* This testcase is part of GDB, the GNU debugger. + + 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/>. */ + +int __attribute__ ((noinline)) +bar (int x) +{ + return x + x; +} + +/* This function should generate a prologue in shape of: + push %rbp + .cfi_def_cfa_offset 16 + .cfi_offset %rbp, -16 + mov %rsp, %rbp + .cfi_def_cfa_register %rbp + push %reg1 + push %reg2 + sub $XXX, %rsp + .cfi_offset %reg2, 32 + .cfi_offset %reg1, 24 + + So to be able to unwind a register, GDB needs to skip prologue past + register pushes and stack allocation (to access .cfi directives). */ +int __attribute__ ((noinline)) +foo (int a, int b, int c, int d) +{ + /* "volatile" alone isn't enough for clang to not optimize it out and + allocate space on the stack. */ + volatile char s[256]; + for (int i = 0; i < 256; i++) + s[i] = (char) (a + i); + + a += bar (a) + bar (b) + bar (c) + bar (d); + return a; +} + +int +main (int argc, char **argv) +{ + volatile int a = foo (argc, argc + 1, argc + 2, argc * 2); + return a; +} |