binutils-gdb/gdb/testsuite/gdb.dwarf2/dw2-epilogue-begin.c.inc
Bernd Edlinger 730f5068f5 Handle two-linetable function in find_epilogue_using_linetable
Consider the following test-case:
...
$ cat hello.c
int main()
{
  printf("hello ");
  #include "world.inc"
$ cat world.inc
  printf("world\n");
  return 0;
}
$ gcc -g hello.c
...

The line table for the compilation unit, consisting just of
function main, is translated into these two gdb line tables, one for hello.c
and one for world.inc:
...
compunit_symtab: hello.c
symtab: hello.c
INDEX  LINE   REL-ADDRESS UNREL-ADDRESS IS-STMT PROLOGUE-END EPILOGUE-BEGIN
0      3      0x400557    0x400557      Y
1      4      0x40055b    0x40055b      Y
2      END    0x40056a    0x40056a      Y

compunit_symtab: hello.c
symtab: world.inc
INDEX  LINE   REL-ADDRESS UNREL-ADDRESS IS-STMT PROLOGUE-END EPILOGUE-BEGIN
0      1      0x40056a    0x40056a      Y
1      2      0x400574    0x400574      Y
2      3      0x400579    0x400579      Y
3      END    0x40057b    0x40057b      Y
...

The epilogue of main starts at 0x400579:
...
  400579:	5d                   	pop    %rbp
  40057a:	c3                   	ret
...

Now, say we have an epilogue_begin marker in the line table at 0x400579.

We won't find it using find_epilogue_using_linetable, because it does:
...
  const struct symtab_and_line sal = find_pc_line (start_pc, 0);
...
which gets us the line table for hello.c.

Fix this by using "find_pc_line (end_pc - 1, 0)" instead.

Tested on x86_64-linux.

Co-Authored-By: Tom de Vries <tdevries@suse.de>

PR symtab/31622
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=31622
2024-04-24 16:00:38 +02:00

52 lines
1.5 KiB
C++

/* Copyright 2023-2024 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/>. */
void
__attribute__((used))
trivial (void)
{
asm ("trivial_label: .global trivial_label"); /* trivial function */
}
char global;
void
watch (void)
{ /* watch start */
asm ("watch_label: .global watch_label");
asm ("mov $0x0, %rax");
int local = 0; /* watch prologue */
asm ("watch_start: .global watch_start");
asm ("mov $0x1, %rax");
local = 1; /* watch assign */
asm ("watch_reassign: .global watch_reassign");
asm ("mov $0x2, %rax");
local = 2; /* watch reassign */
asm ("watch_end: .global watch_end"); /* watch end */
}
int
main (void)
{ /* main prologue */
asm ("main_label: .global main_label");
global = 0;
asm ("main_fun_call: .global main_fun_call");
watch (); /* main function call */
asm ("main_epilogue: .global main_epilogue");
global = 10;
return 0; /* main end */
}