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] Allows the binutils to cope with PE binaries where the section addresses have been changed, but the


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

commit 425bd9e1bb32b25881dd20d76678d041f7bf04f8
Author: Nick Clifton <nickc@redhat.com>
Date:   Thu Mar 5 12:14:26 2015 +0000

    Allows the binutils to cope with PE binaries where the section addresses have been changed, but the DWARF debug info has not been altered.
    
    	PR binutils/18025
    	* coffgen.c (coff_find_nearest_line_with_names): If the dwarf2
    	lookup fails, check for an address bias in the dwarf info, and if
    	one exists, retry the lookup with the biased value.
    	* dwarf2.c (_bfd_dwarf2_find_symbol_bias): New function.
    	Determines if a bias exists bewteen the addresses of functions
    	based on DWARF information vs symbol table information.
    	* libbfd-in.h (_bfd_dwarf2_find_symbol_bias): Prototype.
    	* libbfd.h: Regenerate.

Diff:
---
 bfd/ChangeLog   | 12 ++++++++++++
 bfd/coffgen.c   | 20 ++++++++++++++++++++
 bfd/dwarf2.c    | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++
 bfd/libbfd-in.h |  4 ++++
 bfd/libbfd.h    |  4 ++++
 5 files changed, 91 insertions(+)

diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index db02752..3f8cc86 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,15 @@
+2015-03-05  Nick Clifton  <nickc@redhat.com>
+
+	PR binutils/18025
+	* coffgen.c (coff_find_nearest_line_with_names): If the dwarf2
+	lookup fails, check for an address bias in the dwarf info, and if
+	one exists, retry the lookup with the biased value.
+	* dwarf2.c (_bfd_dwarf2_find_symbol_bias): New function.
+	Determines if a bias exists bewteen the addresses of functions
+	based on DWARF information vs symbol table information.
+	* libbfd-in.h (_bfd_dwarf2_find_symbol_bias): Prototype.
+	* libbfd.h: Regenerate.
+
 2015-03-04  Marcus Shawcroft  <marcus.shawcroft@arm.com>
 
 	* elfxx-aarch64.c (decode_add_imm, decode_movw_imm)
diff --git a/bfd/coffgen.c b/bfd/coffgen.c
index 83673d4..5c664a4 100644
--- a/bfd/coffgen.c
+++ b/bfd/coffgen.c
@@ -2245,6 +2245,26 @@ coff_find_nearest_line_with_names (bfd *abfd,
 				     &coff_data(abfd)->dwarf2_find_line_info))
     return TRUE;
 
+  /* If the DWARF lookup failed, but there is DWARF information available
+     then the problem might be that the file has been rebased.  This tool
+     changes the VMAs of all the sections, but it does not update the DWARF
+     information.  So try again, using a bias against the address sought.  */
+  if (coff_data (abfd)->dwarf2_find_line_info != NULL)
+    {
+      bfd_signed_vma bias;
+
+      bias = _bfd_dwarf2_find_symbol_bias (symbols,
+					   & coff_data (abfd)->dwarf2_find_line_info);
+      
+      if (bias
+	  && _bfd_dwarf2_find_nearest_line (abfd, symbols, NULL, section,
+					    offset + bias,
+					    filename_ptr, functionname_ptr,
+					    line_ptr, NULL, debug_sections, 0,
+					    &coff_data(abfd)->dwarf2_find_line_info))
+	return TRUE;
+    }
+
   *filename_ptr = 0;
   *functionname_ptr = 0;
   *line_ptr = 0;
diff --git a/bfd/dwarf2.c b/bfd/dwarf2.c
index 0a5d1ce..cbd4cf6 100644
--- a/bfd/dwarf2.c
+++ b/bfd/dwarf2.c
@@ -3788,6 +3788,57 @@ _bfd_dwarf2_slurp_debug_info (bfd *abfd, bfd *debug_bfd,
   return TRUE;
 }
 
+/* Scan the debug information in PINFO looking for a DW_TAG_subprogram
+   abbrev with a DW_AT_low_pc attached to it.  Then lookup that same
+   symbol in SYMBOLS and return the difference between the low_pc and
+   the symbol's address.  Returns 0 if no suitable symbol could be found.  */
+
+bfd_signed_vma
+_bfd_dwarf2_find_symbol_bias (asymbol ** symbols, void ** pinfo)
+{
+  struct dwarf2_debug *stash;
+  struct comp_unit * unit;
+
+  stash = (struct dwarf2_debug *) *pinfo;
+
+  if (stash == NULL)
+    return 0;
+
+  for (unit = stash->all_comp_units; unit; unit = unit->next_unit)
+    {
+      struct funcinfo * func;
+
+      if (unit->function_table == NULL)
+	{
+	  if (unit->line_table == NULL)
+	    unit->line_table = decode_line_info (unit, stash);
+	  if (unit->line_table != NULL)
+	    scan_unit_for_symbols (unit);
+	}
+
+      for (func = unit->function_table; func != NULL; func = func->prev_func)
+	if (func->name && func->arange.low)
+	  {
+	    asymbol ** psym;
+
+	    /* FIXME: Do we need to scan the aranges looking for the lowest pc value ?  */
+
+	    for (psym = symbols; * psym != NULL; psym++)
+	      {
+		asymbol * sym = * psym;
+
+		if (sym->flags & BSF_FUNCTION
+		    && sym->section != NULL
+		    && strcmp (sym->name, func->name) == 0)
+		  return ((bfd_signed_vma) func->arange.low) -
+		    ((bfd_signed_vma) (sym->value + sym->section->vma));
+	      }
+	  }
+    }
+
+  return 0;
+}
+
 /* Find the source code location of SYMBOL.  If SYMBOL is NULL
    then find the nearest source code location corresponding to
    the address SECTION + OFFSET.
diff --git a/bfd/libbfd-in.h b/bfd/libbfd-in.h
index 7c661e3..06fa652 100644
--- a/bfd/libbfd-in.h
+++ b/bfd/libbfd-in.h
@@ -551,6 +551,10 @@ extern bfd_boolean _bfd_dwarf2_find_nearest_line
    const char **, const char **, unsigned int *, unsigned int *,
    const struct dwarf_debug_section *, unsigned int, void **);
 
+/* Find the bias between DWARF addresses and real addresses.  */
+extern bfd_signed_vma _bfd_dwarf2_find_symbol_bias
+  (asymbol **, void **);
+  
 /* Find inliner info after calling bfd_find_nearest_line. */
 extern bfd_boolean _bfd_dwarf2_find_inliner_info
   (bfd *, const char **, const char **, unsigned int *, void **);
diff --git a/bfd/libbfd.h b/bfd/libbfd.h
index 2aafecf..14600aa 100644
--- a/bfd/libbfd.h
+++ b/bfd/libbfd.h
@@ -556,6 +556,10 @@ extern bfd_boolean _bfd_dwarf2_find_nearest_line
    const char **, const char **, unsigned int *, unsigned int *,
    const struct dwarf_debug_section *, unsigned int, void **);
 
+/* Find the bias between DWARF addresses and real addresses.  */
+extern bfd_signed_vma _bfd_dwarf2_find_symbol_bias
+  (asymbol **, void **);
+  
 /* Find inliner info after calling bfd_find_nearest_line. */
 extern bfd_boolean _bfd_dwarf2_find_inliner_info
   (bfd *, const char **, const char **, unsigned int *, void **);


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