This is the mail archive of the binutils-cvs@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[binutils-gdb] bfd/dwarf: Improve use of previously loaded dwarf information


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=90ed9b8bc136c80116273d1aae5a31fbd415af27

commit 90ed9b8bc136c80116273d1aae5a31fbd415af27
Author: Andrew Burgess <andrew.burgess@embecosm.com>
Date:   Thu Dec 15 15:22:49 2016 +0000

    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.

Diff:
---
 bfd/ChangeLog                  |  9 +++++++++
 bfd/dwarf2.c                   | 23 +++++++++++++++++++++--
 ld/ChangeLog                   |  9 +++++++++
 ld/testsuite/ld-elf/dwarf.exp  |  6 ++++++
 ld/testsuite/ld-elf/dwarf2.err |  4 ++++
 ld/testsuite/ld-elf/dwarf2a.c  |  8 ++++++++
 ld/testsuite/ld-elf/dwarf2b.c  | 10 ++++++++++
 ld/testsuite/ld-elf/dwarf3.c   | 13 +++++++++++++
 ld/testsuite/ld-elf/dwarf3.err |  4 ++++
 9 files changed, 84 insertions(+), 2 deletions(-)

diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 0c45c44..01314bd 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -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>
 
 	PR 21000
diff --git a/bfd/dwarf2.c b/bfd/dwarf2.c
index 6b111d3..03447a9 100644
--- a/bfd/dwarf2.c
+++ b/bfd/dwarf2.c
@@ -100,6 +100,12 @@ struct dwarf2_debug
   /* Pointer to the end of the .debug_info section memory buffer.  */
   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
      section.  The bfd might be different than expected because of
      gnu_debuglink sections.  */
@@ -3897,8 +3903,20 @@ _bfd_dwarf2_slurp_debug_info (bfd *abfd, bfd *debug_bfd,
 
   if (stash != NULL)
     {
-      if (section_vma_same (abfd, stash))
-	return TRUE;
+      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 FALSE;
+        }
       _bfd_dwarf2_cleanup_debug_info (abfd, pinfo);
       memset (stash, 0, amt);
     }
@@ -3908,6 +3926,7 @@ _bfd_dwarf2_slurp_debug_info (bfd *abfd, bfd *debug_bfd,
       if (! stash)
 	return FALSE;
     }
+  stash->orig_bfd = abfd;
   stash->debug_sections = debug_sections;
   stash->syms = symbols;
   if (!save_section_vma (abfd, stash))
diff --git a/ld/ChangeLog b/ld/ChangeLog
index 8d49373..696e08af 100644
--- a/ld/ChangeLog
+++ b/ld/ChangeLog
@@ -1,5 +1,14 @@
 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>
+
 	* testsuite/lib/ld-lib.exp (run_cc_link_tests): Add warning,
 	error, warning_output, and error_output actions.  Remove separate
 	warnings parameter.
diff --git a/ld/testsuite/ld-elf/dwarf.exp b/ld/testsuite/ld-elf/dwarf.exp
index 529ebcc..25b0c9d 100644
--- a/ld/testsuite/ld-elf/dwarf.exp
+++ b/ld/testsuite/ld-elf/dwarf.exp
@@ -49,6 +49,12 @@ set build_tests {
   {"Build libdwarf1.so"
    "-s -shared" "-fPIC -g -feliminate-dwarf2-dups"
    {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 {
diff --git a/ld/testsuite/ld-elf/dwarf2.err b/ld/testsuite/ld-elf/dwarf2.err
new file mode 100644
index 0000000..872d282
--- /dev/null
+++ b/ld/testsuite/ld-elf/dwarf2.err
@@ -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
diff --git a/ld/testsuite/ld-elf/dwarf2a.c b/ld/testsuite/ld-elf/dwarf2a.c
new file mode 100644
index 0000000..1de5794
--- /dev/null
+++ b/ld/testsuite/ld-elf/dwarf2a.c
@@ -0,0 +1,8 @@
+int global_var = 3;
+int other_var = 4;
+
+int
+function (void)
+{
+  return 0;
+}
diff --git a/ld/testsuite/ld-elf/dwarf2b.c b/ld/testsuite/ld-elf/dwarf2b.c
new file mode 100644
index 0000000..c557978
--- /dev/null
+++ b/ld/testsuite/ld-elf/dwarf2b.c
@@ -0,0 +1,10 @@
+int global_var = 4;
+int other_var = 2;
+
+extern int function (void);
+
+int
+main ()
+{
+  return function ();
+}
diff --git a/ld/testsuite/ld-elf/dwarf3.c b/ld/testsuite/ld-elf/dwarf3.c
new file mode 100644
index 0000000..054eb9b
--- /dev/null
+++ b/ld/testsuite/ld-elf/dwarf3.c
@@ -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;
+}
diff --git a/ld/testsuite/ld-elf/dwarf3.err b/ld/testsuite/ld-elf/dwarf3.err
new file mode 100644
index 0000000..6027431
--- /dev/null
+++ b/ld/testsuite/ld-elf/dwarf3.err
@@ -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'
+#...
\ No newline at end of file


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]