mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-27 06:17:47 +08:00
bfd/dwarf: Improve use of previously loaded dwarf information
When parsing DWARF data in order to report file/line type error messages we perform section placement to make section addresses unique within relocatable object files. Currently, if we reuse previously loaded (and cached) dwarf data then we neglect to perform section placement, the result is that the section addresses will not be unique, and we might, incorrectly associate an address with the wrong debug information, and so report an incorrect file and line number. Further we neglect to check that that bfd for which we are looking up debug information is actually the bfd for which the previous debug information was loaded, it is possible that we will reuse previously loaded debug information for a different bfd. And finally, due to following of gnu_debuglink links in one bfd to another, the process of checking that the cached debug information is valid requires us to track the original bfd in the cached debug information. The original debug information here is either the bfd that we're interested in, not the bfd we finally load the debug information from. bfd/ChangeLog: * dwarf2.c (struct dwarf2_debug): Add orig_bfd member. (_bfd_dwarf2_slurp_debug_info): If stashed debug information does not match current bfd, then reload debug information. Record bfd we're loading debug info for in the stash. If we have debug informatin in the cache then perform section placement before returning. ld/ChangeLog: * testsuite/ld-elf/dwarf.exp (build_tests): Add new tests. * testsuite/ld-elf/dwarf2.err: New file. * testsuite/ld-elf/dwarf2a.c: New file. * testsuite/ld-elf/dwarf2b.c: New file. * testsuite/ld-elf/dwarf3.c: New file. * testsuite/ld-elf/dwarf3.err: New file.
This commit is contained in:
@ -1,3 +1,12 @@
|
|||||||
|
2017-02-16 Andrew Burgess <andrew.burgess@embecosm.com>
|
||||||
|
|
||||||
|
* dwarf2.c (struct dwarf2_debug): Add orig_bfd member.
|
||||||
|
(_bfd_dwarf2_slurp_debug_info): If stashed debug information does
|
||||||
|
not match current bfd, then reload debug information. Record bfd
|
||||||
|
we're loading debug info for in the stash. If we have debug
|
||||||
|
informatin in the cache then perform section placement before
|
||||||
|
returning.
|
||||||
|
|
||||||
2017-02-16 Alan Modra <amodra@gmail.com>
|
2017-02-16 Alan Modra <amodra@gmail.com>
|
||||||
|
|
||||||
PR 21000
|
PR 21000
|
||||||
|
21
bfd/dwarf2.c
21
bfd/dwarf2.c
@ -100,6 +100,12 @@ struct dwarf2_debug
|
|||||||
/* Pointer to the end of the .debug_info section memory buffer. */
|
/* Pointer to the end of the .debug_info section memory buffer. */
|
||||||
bfd_byte *info_ptr_end;
|
bfd_byte *info_ptr_end;
|
||||||
|
|
||||||
|
/* Pointer to the original bfd for which debug was loaded. This is what
|
||||||
|
we use to compare and so check that the cached debug data is still
|
||||||
|
valid - it saves having to possibly dereference the gnu_debuglink each
|
||||||
|
time. */
|
||||||
|
bfd *orig_bfd;
|
||||||
|
|
||||||
/* Pointer to the bfd, section and address of the beginning of the
|
/* Pointer to the bfd, section and address of the beginning of the
|
||||||
section. The bfd might be different than expected because of
|
section. The bfd might be different than expected because of
|
||||||
gnu_debuglink sections. */
|
gnu_debuglink sections. */
|
||||||
@ -3897,8 +3903,20 @@ _bfd_dwarf2_slurp_debug_info (bfd *abfd, bfd *debug_bfd,
|
|||||||
|
|
||||||
if (stash != NULL)
|
if (stash != NULL)
|
||||||
{
|
{
|
||||||
if (section_vma_same (abfd, stash))
|
if (stash->orig_bfd == abfd
|
||||||
|
&& section_vma_same (abfd, stash))
|
||||||
|
{
|
||||||
|
/* Check that we did previously find some debug information
|
||||||
|
before attempting to make use of it. */
|
||||||
|
if (stash->bfd_ptr != NULL)
|
||||||
|
{
|
||||||
|
if (do_place && !place_sections (abfd, stash))
|
||||||
|
return FALSE;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
_bfd_dwarf2_cleanup_debug_info (abfd, pinfo);
|
_bfd_dwarf2_cleanup_debug_info (abfd, pinfo);
|
||||||
memset (stash, 0, amt);
|
memset (stash, 0, amt);
|
||||||
}
|
}
|
||||||
@ -3908,6 +3926,7 @@ _bfd_dwarf2_slurp_debug_info (bfd *abfd, bfd *debug_bfd,
|
|||||||
if (! stash)
|
if (! stash)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
stash->orig_bfd = abfd;
|
||||||
stash->debug_sections = debug_sections;
|
stash->debug_sections = debug_sections;
|
||||||
stash->syms = symbols;
|
stash->syms = symbols;
|
||||||
if (!save_section_vma (abfd, stash))
|
if (!save_section_vma (abfd, stash))
|
||||||
|
@ -1,3 +1,12 @@
|
|||||||
|
2017-02-16 Andrew Burgess <andrew.burgess@embecosm.com>
|
||||||
|
|
||||||
|
* testsuite/ld-elf/dwarf.exp (build_tests): Add new tests.
|
||||||
|
* testsuite/ld-elf/dwarf2.err: New file.
|
||||||
|
* testsuite/ld-elf/dwarf2a.c: New file.
|
||||||
|
* testsuite/ld-elf/dwarf2b.c: New file.
|
||||||
|
* testsuite/ld-elf/dwarf3.c: New file.
|
||||||
|
* testsuite/ld-elf/dwarf3.err: New file.
|
||||||
|
|
||||||
2017-02-16 Andrew Burgess <andrew.burgess@embecosm.com>
|
2017-02-16 Andrew Burgess <andrew.burgess@embecosm.com>
|
||||||
|
|
||||||
* testsuite/lib/ld-lib.exp (run_cc_link_tests): Add warning,
|
* testsuite/lib/ld-lib.exp (run_cc_link_tests): Add warning,
|
||||||
|
@ -49,6 +49,12 @@ set build_tests {
|
|||||||
{"Build libdwarf1.so"
|
{"Build libdwarf1.so"
|
||||||
"-s -shared" "-fPIC -g -feliminate-dwarf2-dups"
|
"-s -shared" "-fPIC -g -feliminate-dwarf2-dups"
|
||||||
{dwarf1.c} {} "libdwarf1.so"}
|
{dwarf1.c} {} "libdwarf1.so"}
|
||||||
|
{"DWARF parse during linker error"
|
||||||
|
"" "-fno-toplevel-reorder"
|
||||||
|
{dwarf2a.c dwarf2b.c} {{error_output "dwarf2.err"}} "dwarf2.x"}
|
||||||
|
{"Handle no DWARF information"
|
||||||
|
"" "-g0"
|
||||||
|
{dwarf3.c} {{error_output "dwarf3.err"}} "dwarf3.x"}
|
||||||
}
|
}
|
||||||
|
|
||||||
set run_tests {
|
set run_tests {
|
||||||
|
4
ld/testsuite/ld-elf/dwarf2.err
Normal file
4
ld/testsuite/ld-elf/dwarf2.err
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
tmpdir/dwarf2b\.o:\(\.data\+0x0\): multiple definition of `global_var'
|
||||||
|
tmpdir/dwarf2a\.o:\(\.data\+0x0\): first defined here
|
||||||
|
tmpdir/dwarf2b\.o:\(\.data\+0x4\): multiple definition of `other_var'
|
||||||
|
tmpdir/dwarf2a\.o:\(\.data\+0x4\): first defined here
|
8
ld/testsuite/ld-elf/dwarf2a.c
Normal file
8
ld/testsuite/ld-elf/dwarf2a.c
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
int global_var = 3;
|
||||||
|
int other_var = 4;
|
||||||
|
|
||||||
|
int
|
||||||
|
function (void)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
10
ld/testsuite/ld-elf/dwarf2b.c
Normal file
10
ld/testsuite/ld-elf/dwarf2b.c
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
int global_var = 4;
|
||||||
|
int other_var = 2;
|
||||||
|
|
||||||
|
extern int function (void);
|
||||||
|
|
||||||
|
int
|
||||||
|
main ()
|
||||||
|
{
|
||||||
|
return function ();
|
||||||
|
}
|
13
ld/testsuite/ld-elf/dwarf3.c
Normal file
13
ld/testsuite/ld-elf/dwarf3.c
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
/* This test is actually used to test for a segfault that came from the bfd
|
||||||
|
dwarf parsing code in the case when there is _no_ dwarf info. */
|
||||||
|
|
||||||
|
extern void bar (int a);
|
||||||
|
|
||||||
|
int
|
||||||
|
main ()
|
||||||
|
{
|
||||||
|
bar (1);
|
||||||
|
bar (2);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
4
ld/testsuite/ld-elf/dwarf3.err
Normal file
4
ld/testsuite/ld-elf/dwarf3.err
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
.*/dwarf3\.o: In function `main':
|
||||||
|
.*dwarf3.c:\(\.text.*\+0x[0-9a-f]+\): undefined reference to `bar'
|
||||||
|
.*dwarf3.c:\(\.text.*\+0x[0-9a-f]+\): undefined reference to `bar'
|
||||||
|
#...
|
Reference in New Issue
Block a user