This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB 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]

[rfc] Detect dwarf address size mismatch


I just fixed a gas bug which caused MIPS64 Linux kernels to have
corrupt DWARF information.  The .debug_info compilation unit header
listed the address size as 4, but the .debug_line section used 64-bit
addresses.  This caused GDB to parse the last four bits of each
address as if they were instructions in the line number program.

That version of GDB crashed when it got a bogus DW_LNS_set_file with
an out-of-bounds file number (which has already been fixed in HEAD).
But I think this patch is still useful, to detect the mismatch
promptly instead of going off into the woods parsing bad data.
I think I did get HEAD to crash once while testing.

A more intrusive patch could let GDB handle the bad files as their
producer intended, by reading an address of size extended_len - 1,
but I don't think it's worth it when we can fix gas.

Any comments on this patch, or shall I commit it?

-- 
Daniel Jacobowitz
CodeSourcery

2007-07-11  Daniel Jacobowitz  <dan@codesourcery.com>

	* dwarf2read.c (dwarf_decode_lines): Detect address size mismatches.

---
 gdb/dwarf2read.c |   10 ++++++++--
 1 files changed, 8 insertions(+), 2 deletions(-)

Index: gdb-6.6.50/gdb/dwarf2read.c
===================================================================
--- gdb-6.6.50.orig/gdb/dwarf2read.c	2007-07-10 13:25:33.000000000 -0700
+++ gdb-6.6.50/gdb/dwarf2read.c	2007-07-11 07:09:17.000000000 -0700
@@ -6660,7 +6660,7 @@ dwarf_decode_lines (struct line_header *
 {
   gdb_byte *line_ptr;
   gdb_byte *line_end;
-  unsigned int bytes_read;
+  unsigned int bytes_read, extended_len;
   unsigned char op_code, extended_op, adj_opcode;
   CORE_ADDR baseaddr;
   struct objfile *objfile = cu->objfile;
@@ -6730,7 +6730,7 @@ dwarf_decode_lines (struct line_header *
 	  else switch (op_code)
 	    {
 	    case DW_LNS_extended_op:
-	      read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
+	      extended_len = read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
 	      line_ptr += bytes_read;
 	      extended_op = read_1_byte (abfd, line_ptr);
 	      line_ptr += 1;
@@ -6746,6 +6746,12 @@ dwarf_decode_lines (struct line_header *
 		  address = read_address (abfd, line_ptr, cu, &bytes_read);
 		  line_ptr += bytes_read;
 		  address += baseaddr;
+		  if (bytes_read + 1 != extended_len)
+		    {
+		      complaint (&symfile_complaints,
+				 _("bad address size in .debug_line section"));
+		      return;
+		    }
 		  break;
 		case DW_LNE_define_file:
                   {


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