This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
DWARF2 abstract origin issue
- From: "Dmitry Smirnov" <divis1969 at gmail dot com>
- To: binutils at sourceware dot org
- Date: Tue, 29 Jul 2008 19:16:18 +0400
- Subject: 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;