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

[PATCH] Teach ld about the new DWARF4 DW_FORM_* forms


Hi!

And here is a patch for ld dwarf support.  In addition to adding support
for these the patch fixes a very serious bug - if an unknown form is
encountered and ld needs to emit some warning it would just report it
and set error flag, but not return NULL and soon afterwards ld eats
gigabytes of memory until OOM killed.  After returning NULL it behaves just
fine.

Ok to commit?

2010-03-31  Jakub Jelinek  <jakub@redhat.com>

	* dwarf2.c (read_attribute_value): Handle CU version 4
	for DW_FORM_ref_addr, handle DW_FORM_sec_offset, DW_FORM_exprloc
	and DW_FORM_flag_present.  For unknown form value return NULL.
	(scan_unit_for_symbols): For DW_AT_location handle DW_FORM_exprloc
	like DW_FORM_block.
	(parse_comp_unit): Allow CU version 4.

--- bfd/dwarf2.c.jj	2010-03-23 11:41:24.000000000 +0100
+++ bfd/dwarf2.c	2010-03-31 19:01:18.000000000 +0200
@@ -760,7 +760,7 @@ read_attribute_value (struct attribute *
     case DW_FORM_ref_addr:
       /* DW_FORM_ref_addr is an address in DWARF2, and an offset in
 	 DWARF3.  */
-      if (unit->version == 3)
+      if (unit->version == 3 || unit->version == 4)
 	{
 	  if (unit->offset_size == 4)
 	    attr->u.val = read_4_bytes (unit->abfd, info_ptr);
@@ -774,6 +774,13 @@ read_attribute_value (struct attribute *
       attr->u.val = read_address (unit, info_ptr);
       info_ptr += unit->addr_size;
       break;
+    case DW_FORM_sec_offset:
+      if (unit->offset_size == 4)
+	attr->u.val = read_4_bytes (unit->abfd, info_ptr);
+      else
+	attr->u.val = read_8_bytes (unit->abfd, info_ptr);
+      info_ptr += unit->offset_size;
+      break;
     case DW_FORM_block2:
       amt = sizeof (struct dwarf_block);
       blk = (struct dwarf_block *) bfd_alloc (abfd, amt);
@@ -816,6 +823,7 @@ read_attribute_value (struct attribute *
       attr->u.str = read_indirect_string (unit, info_ptr, &bytes_read);
       info_ptr += bytes_read;
       break;
+    case DW_FORM_exprloc:
     case DW_FORM_block:
       amt = sizeof (struct dwarf_block);
       blk = (struct dwarf_block *) bfd_alloc (abfd, amt);
@@ -846,6 +854,9 @@ read_attribute_value (struct attribute *
       attr->u.val = read_1_byte (abfd, info_ptr);
       info_ptr += 1;
       break;
+    case DW_FORM_flag_present:
+      attr->u.val = 1;
+      break;
     case DW_FORM_sdata:
       attr->u.sval = read_signed_leb128 (abfd, info_ptr, &bytes_read);
       info_ptr += bytes_read;
@@ -887,6 +898,7 @@ read_attribute_value (struct attribute *
       (*_bfd_error_handler) (_("Dwarf Error: Invalid or unhandled FORM value: %u."),
 			     form);
       bfd_set_error (bfd_error_bad_value);
+      return NULL;
     }
   return info_ptr;
 }
@@ -2113,6 +2125,7 @@ scan_unit_for_symbols (struct comp_unit 
 		    case DW_FORM_block1:
 		    case DW_FORM_block2:
 		    case DW_FORM_block4:
+		    case DW_FORM_exprloc:
 		      if (*attr.u.blk->data == DW_OP_addr)
 			{
 			  var->stack = 0;
@@ -2216,9 +2229,9 @@ parse_comp_unit (struct dwarf2_debug *st
   addr_size = read_1_byte (abfd, info_ptr);
   info_ptr += 1;
 
-  if (version != 2 && version != 3)
+  if (version != 2 && version != 3 && version != 4)
     {
-      (*_bfd_error_handler) (_("Dwarf Error: found dwarf version '%u', this reader only handles version 2 and 3 information."), version);
+      (*_bfd_error_handler) (_("Dwarf Error: found dwarf version '%u', this reader only handles version 2, 3 and 4 information."), version);
       bfd_set_error (bfd_error_bad_value);
       return 0;
     }

	Jakub


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