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]

64-bit dwarf3 mis-read if 8-byte addr_size explicitly specified


The current code in _bfd_dwarf2_find_nearest_line() relied on the
assumption that addr_size would be passed as 0 or 4 for the DWARF3
64-bit format detection code to work.  However,
elfxx-mips.c:_bfd_mips_elf_find_nearest_line passed addr_size down as
8 if ABI_64_P, so, when the linker attempted to emit error messages
referencing symbols, file names or line numbers, it would often
complain about invalid DWARF2 debugging info.  This patch fixes this
problem, by attempting to recognize the special combinations
regardless of the given addr_size, and using addr_size only as a
fallback for backward-compatibility with pre-DWARF3 non-IRIX6 systems.
Ok to install?

Index: bfd/ChangeLog
from  Alexandre Oliva  <aoliva at redhat dot com>

	* dwarf2.c (_bfd_dwarf2_find_nearest_line): Try DWARF3-standard
	and IRIX-specific shift-to-64-bit 4-byte lengths before following
	addr_size.

Index: bfd/dwarf2.c
===================================================================
RCS file: /cvs/src/src/bfd/dwarf2.c,v
retrieving revision 1.47
diff -u -p -r1.47 dwarf2.c
--- bfd/dwarf2.c 1 Apr 2003 10:49:02 -0000 1.47
+++ bfd/dwarf2.c 8 Apr 2003 08:32:20 -0000
@@ -1927,26 +1927,34 @@ _bfd_dwarf2_find_nearest_line (abfd, sec
       bfd_boolean found;
       unsigned int offset_size = addr_size;
 
-      if (addr_size == 4)
+      length = read_4_bytes (abfd, stash->info_ptr);
+      /* A 0xffffff length is the DWARF3 way of indicating we use
+	 64-bit offsets, instead of 32-bit offsets.  */
+      if (length == 0xffffffff)
 	{
-	  length = read_4_bytes (abfd, stash->info_ptr);
-	  if (length == 0xffffffff)
-	    {
-	      offset_size = 8;
-	      length = read_8_bytes (abfd, stash->info_ptr + 4);
-	      stash->info_ptr += 8;
-	    }
-	  else if (length == 0)
-	    {
-	      /* Handle (non-standard) 64-bit DWARF2 formats.  */
-	      offset_size = 8;
-	      length = read_4_bytes (abfd, stash->info_ptr + 4);
-	      stash->info_ptr += 4;
-	    }
+	  offset_size = 8;
+	  length = read_8_bytes (abfd, stash->info_ptr + 4);
+	  stash->info_ptr += 12;
+	}
+      /* A zero length is the IRIX way of indicating 64-bit offsets,
+	 mostly because the 64-bit length will generally fit in 32
+	 bits, and the endianness helps.  */
+      else if (length == 0)
+	{
+	  offset_size = 8;
+	  length = read_4_bytes (abfd, stash->info_ptr + 4);
+	  stash->info_ptr += 8;
+	}
+      /* In the absence of the hints above, we assume addr_size-sized
+	 offsets, for backward-compatibility with pre-DWARF3 64-bit
+	 platforms.  */
+      else if (addr_size == 8)
+	{
+	  length = read_8_bytes (abfd, stash->info_ptr);
+	  stash->info_ptr = 8;
 	}
       else
-	length = read_8_bytes (abfd, stash->info_ptr);
-      stash->info_ptr += addr_size;
+	stash->info_ptr += 4;
 
       if (length > 0)
 	{
-- 
Alexandre Oliva   Enjoy Guarana', see http://www.ic.unicamp.br/~oliva/
Red Hat GCC Developer                 aoliva at {redhat dot com, gcc.gnu.org}
CS PhD student at IC-Unicamp        oliva at {lsd dot ic dot unicamp dot br, gnu.org}
Free Software Evangelist                Professional serial bug killer

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