This is the mail archive of the binutils@sources.redhat.com 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]

_bfd_dwarf2_find_nearest_line returns wrong filename


On RELA targets the indirect string pointers in the DWARF2 debugging
sections need to be relocated.  Otherwise you'll get nonsensical file
names in _bfd_dwarf2_find_nearest_line.

Andreas.

2002-12-23  Andreas Schwab  <schwab@suse.de>

	* dwarf2.c (struct dwarf2_debug): Add relocs and reloc_count.
	(find_rela_addend): Take pointer to struct dwarf2_debug instead of
	section and symbols.  Cache reloc section there.  Don't check
	section in reloc, just compare offset.
	(read_indirect_string): Use find_rela_addend to relocate string
	offset.
	(parse_comp_unit): Adjust call to find_rela_addend.  Don't
	advance to next debug section until after
	comp_unit_find_nearest_line has been called.

--- bfd/dwarf2.c.~1.42.~	2002-12-12 23:42:14.000000000 +0100
+++ bfd/dwarf2.c	2002-12-23 23:46:16.000000000 +0100
@@ -104,6 +104,10 @@ struct dwarf2_debug
   /* Pointer to the symbol table.  */
   asymbol** syms;
 
+  /* Pointer to reloc section and number of relocs.  */
+  arelent **relocs;
+  long reloc_count;
+
   /* Pointer to the .debug_abbrev section loaded into memory.  */
   char* dwarf_abbrev_buffer;
 
@@ -246,7 +250,7 @@ static bfd_boolean lookup_address_in_fun
   PARAMS ((struct funcinfo *, bfd_vma, struct funcinfo **, const char **));
 static bfd_boolean scan_unit_for_functions PARAMS ((struct comp_unit *));
 static bfd_vma find_rela_addend
-  PARAMS ((bfd *, asection *, bfd_size_type, asymbol**));
+  PARAMS ((bfd *, struct dwarf2_debug *, bfd_size_type));
 static struct comp_unit *parse_comp_unit
   PARAMS ((bfd *, struct dwarf2_debug *, bfd_vma, unsigned int));
 static bfd_boolean comp_unit_contains_address
@@ -369,6 +373,7 @@ read_indirect_string (unit, buf, bytes_r
   else
     offset = read_8_bytes (unit->abfd, buf);
   *bytes_read_ptr = unit->offset_size;
+  offset += find_rela_addend (unit->abfd, stash, buf - stash->sec_info_ptr);
 
   if (! stash->dwarf_str_buffer)
     {
@@ -1521,57 +1526,50 @@ scan_unit_for_functions (unit)
   return TRUE;
 }
 
-/* Look for a RELA relocation to be applied on OFFSET of section SEC,
-   and return the addend if such a relocation is found.  Since this is
-   only used to find relocations referring to the .debug_abbrev
-   section, we make sure the relocation refers to this section, but
-   this is not strictly necessary, and it can probably be safely
-   removed if needed.  However, it is important to note that this
-   function only returns the addend, it doesn't serve the purpose of
-   applying a generic relocation.
+/* Look for a RELA relocation to be applied on OFFSET of section
+   STASH->sec, and return the addend if such a relocation is found.
+   However, it is important to note that this function only returns
+   the addend, it doesn't serve the purpose of applying a generic
+   relocation.
 
    If no suitable relocation is found, or if it is not a real RELA
    relocation, this function returns 0.  */
 
 static bfd_vma
-find_rela_addend (abfd, sec, offset, syms)
+find_rela_addend (abfd, stash, offset)
      bfd* abfd;
-     asection* sec;
+     struct dwarf2_debug* stash;
      bfd_size_type offset;
-     asymbol** syms;
 {
-  long reloc_size = bfd_get_reloc_upper_bound (abfd, sec);
-  arelent **relocs = NULL;
-  long reloc_count, relc;
+  long relc;
 
-  if (reloc_size <= 0)
-    return 0;
+  if (stash->relocs == NULL)
+    {
+      long reloc_size = bfd_get_reloc_upper_bound (abfd, stash->sec);
 
-  relocs = (arelent **) bfd_malloc ((bfd_size_type) reloc_size);
-  if (relocs == NULL)
-    return 0;
+      if (reloc_size <= 0)
+	return 0;
 
-  reloc_count = bfd_canonicalize_reloc (abfd, sec, relocs, syms);
+      stash->relocs = (arelent **) bfd_malloc ((bfd_size_type) reloc_size);
+      if (stash->relocs == NULL)
+	return 0;
 
-  if (reloc_count <= 0)
-    {
-      free (relocs);
-      return 0;
+      stash->reloc_count = bfd_canonicalize_reloc (abfd, stash->sec,
+						   stash->relocs,
+						   stash->syms);
+
+      if (stash->reloc_count <= 0)
+	return 0;
     }
 
-  for (relc = 0; relc < reloc_count; relc++)
-    if (relocs[relc]->address == offset
-	&& (*relocs[relc]->sym_ptr_ptr)->flags & BSF_SECTION_SYM
-	&& strcmp ((*relocs[relc]->sym_ptr_ptr)->name,
-		   ".debug_abbrev") == 0)
+  for (relc = 0; relc < stash->reloc_count; relc++)
+    if (stash->relocs[relc]->address == offset)
       {
-	bfd_vma addend = (relocs[relc]->howto->partial_inplace
-			  ? 0 : relocs[relc]->addend);
-	free (relocs);
+	bfd_vma addend = (stash->relocs[relc]->howto->partial_inplace
+			  ? 0 : stash->relocs[relc]->addend);
 	return addend;
       }
 
-  free (relocs);
   return 0;
 }
 
@@ -1616,7 +1614,7 @@ parse_comp_unit (abfd, stash, unit_lengt
      relocation and extract the addend to obtain the actual
      abbrev_offset, so do it here.  */
   off = info_ptr - stash->sec_info_ptr;
-  abbrev_offset += find_rela_addend (abfd, stash->sec, off, stash->syms);
+  abbrev_offset += find_rela_addend (abfd, stash, off);
   info_ptr += offset_size;
   addr_size = read_1_byte (abfd, info_ptr);
   info_ptr += 1;
@@ -1951,6 +1949,7 @@ _bfd_dwarf2_find_nearest_line (abfd, sec
       stash->sec = find_debug_info (abfd, NULL);
       stash->sec_info_ptr = stash->info_ptr;
       stash->syms = symbols;
+      stash->relocs = NULL;
     }
 
   /* FIXME: There is a problem with the contents of the
@@ -1984,7 +1983,7 @@ _bfd_dwarf2_find_nearest_line (abfd, sec
   while (stash->info_ptr < stash->info_ptr_end)
     {
       bfd_vma length;
-      bfd_boolean found;
+      bfd_boolean found = FALSE;
       unsigned int offset_size = addr_size;
 
       if (addr_size == 4)
@@ -2013,13 +2012,6 @@ _bfd_dwarf2_find_nearest_line (abfd, sec
 	  each = parse_comp_unit (abfd, stash, length, offset_size);
 	  stash->info_ptr += length;
 
-	  if ((bfd_vma) (stash->info_ptr - stash->sec_info_ptr)
-	      == stash->sec->_raw_size)
-	    {
-	      stash->sec = find_debug_info (abfd, stash->sec);
-	      stash->sec_info_ptr = stash->info_ptr;
-	    }
-
 	  if (each)
 	    {
 	      each->next_unit = stash->all_comp_units;
@@ -2033,11 +2025,11 @@ _bfd_dwarf2_find_nearest_line (abfd, sec
 	      if (each->arange.high > 0)
 		{
 		  if (comp_unit_contains_address (each, addr))
-		    return comp_unit_find_nearest_line (each, addr,
-						       filename_ptr,
-						       functionname_ptr,
-						       linenumber_ptr,
-						       stash);
+		    found = comp_unit_find_nearest_line (each, addr,
+							 filename_ptr,
+							 functionname_ptr,
+							 linenumber_ptr,
+							 stash);
 		}
 	      else
 		{
@@ -2046,11 +2038,22 @@ _bfd_dwarf2_find_nearest_line (abfd, sec
 						       functionname_ptr,
 						       linenumber_ptr,
 						       stash);
-		  if (found)
-		    return TRUE;
 		}
 	    }
 	}
+
+      if ((bfd_vma) (stash->info_ptr - stash->sec_info_ptr)
+	  == stash->sec->_raw_size)
+	{
+	  stash->sec = find_debug_info (abfd, stash->sec);
+	  stash->sec_info_ptr = stash->info_ptr;
+	  if (stash->relocs)
+	    free (stash->relocs);
+	  stash->relocs = NULL;
+	}
+
+      if (found)
+	return TRUE;
     }
 
   return FALSE;


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