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]

DWARF2 abstract origin issue


Hi,

While using BFD (from binutils-2.18) for retriving debug info from ELF
file generated by ADS 1.2 compiler, I've encountered a problem with
DW_AT_abstract_origin processing.
In my case, this attribute is used to refer a function using
DW_FORM_ref_addr reference. Function find_abstract_instance_name (file
dwarf2.c) totally ignores this and tries to use the value as is:
  info_ptr = unit->info_ptr_unit + die_ref;

This caused BFD to crash while attempting to find a name.

I had changed this function in such way:

find_abstract_instance_name (struct comp_unit *unit, bfd_uint64_t
die_ref, enum dwarf_form form)
{
...
  if(form == DW_FORM_ref_addr)
  {
    info_ptr = unit->stash->info_ptr_start + (int)(die_ref);
    if(info_ptr >= unit->stash->info_ptr_end)
    {
      (*_bfd_error_handler) (_("Dwarf Error: reference addr is over
limits %u."),
          die_ref);
    }
  }
  else
  {
    info_ptr = unit->info_ptr_unit + die_ref;
  }

Not sure this is correct fix since I've just learned DWARF2 for couple
hours. Nevertheless, it works for me.

Perhaps, it can be used in future BFD versions.

Dmitry

Here is the whole patch:

--- dwarf2.c	2008-07-16 23:24:49.359375000 +0400
+++ dwarf2.c	2008-07-17 00:59:54.093750000 +0400
@@ -96,6 +96,7 @@

   /* Pointer to the end of the .debug_info section memory buffer.  */
   bfd_byte *info_ptr_end;
+  bfd_byte *info_ptr_start;

   /* Pointer to the bfd, section and address of the beginning of the
      section.  The bfd might be different than expected because of
@@ -1710,7 +1711,7 @@
 }

 static char *
-find_abstract_instance_name (struct comp_unit *unit, bfd_uint64_t die_ref)
+find_abstract_instance_name (struct comp_unit *unit, bfd_uint64_t
die_ref, enum dwarf_form form)
 {
   bfd *abfd = unit->abfd;
   bfd_byte *info_ptr;
@@ -1721,7 +1722,12 @@

   if(form == DW_FORM_ref_addr)
   {
-    info_ptr = unit->stash->info_ptr + die_ref;
+    info_ptr = unit->stash->info_ptr_start + (int)(die_ref);
+    if(info_ptr >= unit->stash->info_ptr_end)
+    {
+      (*_bfd_error_handler) (_("Dwarf Error: reference addr is over
limits %u."),
+          die_ref);
+    }
   }
   else
   {
@@ -1753,7 +1759,7 @@
 		    name = attr.u.str;
 		  break;
 		case DW_AT_specification:
-		  name = find_abstract_instance_name (unit, attr.u.val);
+		  name = find_abstract_instance_name (unit, attr.u.val, attr.form);
 		  break;
 		case DW_AT_MIPS_linkage_name:
 		  name = attr.u.str;
@@ -1915,7 +1921,7 @@
 		  break;

 		case DW_AT_abstract_origin:
-		  func->name = find_abstract_instance_name (unit, attr.u.val);
+		  func->name = find_abstract_instance_name (unit, attr.u.val, attr.form);
 		  break;

 		case DW_AT_name:
@@ -2926,6 +2932,7 @@
 	goto done;

       stash->info_ptr_end = stash->info_ptr;
+      stash->info_ptr_start = stash->info_ptr;

       for (msec = find_debug_info (debug_bfd, NULL);
 	   msec;


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