PATCH: binutils/2096: addr2line fails on linux-kernel
H. J. Lu
hjl@lucon.org
Sat Dec 31 20:25:00 GMT 2005
There are 2 bugs in dwarf2.c. BFD section's lvm is not very useful
for ELF since ELF section doesn't have it and it is made up by bfd:
[hjl@gnu-3 addr2line]$ readelf -S vmlinux
There are 41 section headers, starting at offset 0x20f06bc:
Section Headers:
[Nr] Name Type Addr Off Size ES Flg Lk Inf Al
[ 0] NULL 00000000 000000 000000 00 0 0 0
[ 1] .text PROGBITS c0100000 001000 226f60 00 AX 0 0 16
...
[hjl@gnu-3 addr2line]$ objdump -h vmlinux
vmlinux: file format elf32-i386
Sections:
Idx Name Size VMA LMA File off Algn
0 .text 00226f60 c0100000 00100000 00001000 2**4
CONTENTS, ALLOC, LOAD, READONLY, CODE
dwarf2.c should use vma for ELF.
The section bug is when comp_unit_contains_address return TRUE,
it doesn't necessary mean a compilation unit really contains the
given address. It may happen when "asm" is used to define functions
like arch/i386/kernel/semaphore.c in the Linux 2.6.14 kernel. My
patch checks the line info table to make sure that a compilation
unit really contains the given address.
H.J.
-------------- next part --------------
2005-12-31 H.J. Lu <hongjiu.lu@intel.com>
PR binutils/2096
* dwarf2.c (_bfd_dwarf2_find_nearest_line): Use section's vma,
instead of lvm for ELF.
--- bfd/dwarf2.c.addr 2005-12-27 12:35:54.000000000 -0800
+++ bfd/dwarf2.c 2005-12-31 12:05:36.000000000 -0800
@@ -2209,10 +2209,21 @@ _bfd_dwarf2_find_nearest_line (bfd *abfd
stash = *pinfo;
addr = offset;
- if (section->output_section)
- addr += section->output_section->lma + section->output_offset;
+ if (abfd->xvec->flavour == bfd_target_elf_flavour)
+ {
+ if (section->output_section)
+ addr += section->output_section->vma + section->output_offset;
+ else
+ addr += section->vma;
+ }
else
- addr += section->lma;
+ {
+ if (section->output_section)
+ addr += section->output_section->lma + section->output_offset;
+ else
+ addr += section->lma;
+ }
+
*filename_ptr = NULL;
*functionname_ptr = NULL;
*linenumber_ptr = 0;
@@ -2418,10 +2429,20 @@ _bfd_dwarf2_find_line (bfd *abfd,
section = bfd_get_section (symbol);
addr = symbol->value;
- if (section->output_section)
- addr += section->output_section->lma + section->output_offset;
+ if (abfd->xvec->flavour == bfd_target_elf_flavour)
+ {
+ if (section->output_section)
+ addr += section->output_section->vma + section->output_offset;
+ else
+ addr += section->vma;
+ }
else
- addr += section->lma;
+ {
+ if (section->output_section)
+ addr += section->output_section->lma + section->output_offset;
+ else
+ addr += section->lma;
+ }
*filename_ptr = NULL;
stash = *pinfo;
-------------- next part --------------
2005-12-31 H.J. Lu <hongjiu.lu@intel.com>
PR binutils/2096
* dwarf2.c (comp_unit_contains_address): Update comment.
(_bfd_dwarf2_find_nearest_line): Return TRUE only if both
comp_unit_contains_address and comp_unit_find_nearest_line
return TRUE.
--- bfd/dwarf2.c.unit 2005-12-31 09:12:48.000000000 -0800
+++ bfd/dwarf2.c 2005-12-31 11:49:06.000000000 -0800
@@ -2006,7 +2006,9 @@ parse_comp_unit (bfd *abfd,
return unit;
}
-/* Return TRUE if UNIT contains the address given by ADDR. */
+/* Return TRUE if UNIT may contain the address given by ADDR. We need
+ to consult the line info table to see if a compilation unit really
+ contains the given address. */
static bfd_boolean
comp_unit_contains_address (struct comp_unit *unit, bfd_vma addr)
@@ -2293,16 +2295,16 @@ _bfd_dwarf2_find_nearest_line (bfd *abfd
/* Check the previously read comp. units first. */
for (each = stash->all_comp_units; each; each = each->next_unit)
- if (comp_unit_contains_address (each, addr))
- return comp_unit_find_nearest_line (each, addr, filename_ptr,
- functionname_ptr, linenumber_ptr,
- stash);
+ if (comp_unit_contains_address (each, addr)
+ && comp_unit_find_nearest_line (each, addr, filename_ptr,
+ functionname_ptr,
+ linenumber_ptr, stash))
+ return TRUE;
/* Read each remaining comp. units checking each as they are read. */
while (stash->info_ptr < stash->info_ptr_end)
{
bfd_vma length;
- bfd_boolean found;
unsigned int offset_size = addr_size;
bfd_byte *info_ptr_unit = stash->info_ptr;
@@ -2358,25 +2360,14 @@ _bfd_dwarf2_find_nearest_line (bfd *abfd
unit->high == 0), we need to consult the line info
table to see if a compilation unit contains the given
address. */
- if (each->arange.high > 0)
- {
- if (comp_unit_contains_address (each, addr))
- return comp_unit_find_nearest_line (each, addr,
- filename_ptr,
- functionname_ptr,
- linenumber_ptr,
- stash);
- }
- else
- {
- found = comp_unit_find_nearest_line (each, addr,
- filename_ptr,
- functionname_ptr,
- linenumber_ptr,
- stash);
- if (found)
- return TRUE;
- }
+ if ((each->arange.high == 0
+ || comp_unit_contains_address (each, addr))
+ && comp_unit_find_nearest_line (each, addr,
+ filename_ptr,
+ functionname_ptr,
+ linenumber_ptr,
+ stash))
+ return TRUE;
}
}
}
More information about the Binutils
mailing list