This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
Re: objdump, 64-bit objects and Solaris kernel modules
Hi Nick, Steve
First step - download the latest binutils release (2.13.2) or the
latest CVS sources. It is possible that the problem has already been
fixed.
This problem exists for at least one year, when I noticed it first time.
It is not solved by the latest version.
I'm willing to help debug this problem, but I'll need some pointers
on where to start.
Have a look at binutils/objdump.c:show_line(). This is the function
that should display the source lines. The problem, however is most
likely to be with the function: bfd_find_nearest_line(). This is
vectored function whoes actual code depends upon the target you are
using, and the file formats and debug formats that it uses. I do not
know which debug format the Forte Developer package uses, but it is
probably generating ELF format binaries using either the DWARF or
STABS debug formats. So have a look at
bfd/elf.c:_bfd_elf_find_nearest_line() and follow the code from there.
You are right. The problem is in bfd_find_nearest_line. Hence, addr2line
cannot find the correct file and line number either.
The problem is not limited at 64-bit binaries. I had this problem with
32-bit binaries.
I just tried to solve it about 10 days ago and the problem is indeed in
_bfd_stab_section_find_nearest_line() in syms.c. Stabs is the debug
format used by the Sun Forte compiler.
The stab section contains a mix of debug info: N_SO (for files), N_FUN
(for routines), N_SLINE (for line info in text segment).
The code in _bfd_stab_section_find_nearest_line() expects to find the
absolute start address of the routine in the value field for N_FUN
entries. But the Sun compiler does not generate this value so it is
always zero. What I did was to search for the routine symbols in the
symbol table and compute their absolute start address from there.
More comments are in the patch that I attached. It is generated against
the cvs repository on 02/07/2003.
Gabriel
Index: bfd/syms.c
===================================================================
RCS file: /cvs/src/src/bfd/syms.c,v
retrieving revision 1.27
diff -c -3 -p -r1.27 syms.c
*** bfd/syms.c 30 Nov 2002 08:39:40 -0000 1.27
--- bfd/syms.c 7 Feb 2003 22:05:13 -0000
*************** _bfd_stab_section_find_nearest_line (abf
*** 1223,1230 ****
++i;
info->indextablesize = i;
! qsort (info->indextable, (size_t) i, sizeof (struct indexentry),
! cmpindexentry);
*pinfo = (PTR) info;
}
--- 1223,1272 ----
++i;
info->indextablesize = i;
!
! /* For binaries produced by the Sun compiler the field 'value'
! * in stabs is zero for all N_FUN type of entries. In this case the
! * find_nearest_line always returns the last N_SLINE entry in the stabs
! * because the binary search will always stop just at the end of the
! * table, before the last entry which has a special value (0xFFFFFFFF)
! * and after all the other entries with a value zero.
! * Try to find the value for each entry by searching in the symbols
! * array. This search is done only once so we can live with a linear,
! * unoptimized search. It is also possible to organize the symbols in
! * another data structure using the name as a key (hashtable or sorted
! * list).
! * In stabs, the function name in the case of a Sun compiler binary has
! * this format: symbolName:F... or symbolName:P... where ... means a
! * sequence of other characters. We are interested only in the entries
! * with the first format, I do not know what the second format means
! * and we can leave those at zero. - mgabi 28-01-2003
! */
! for (i=0 ; i<info->indextablesize ; i++)
! {
! char* pos;
! int k;
! asymbol *sym;
! if (info->indextable[i].val==0 && info->indextable[i].function_name
! && ((pos=strchr(info->indextable[i].function_name, ':'))==NULL
! || *(pos+1)=='F') )
! {
! if (pos) *pos = '\0';
! /* search for the symbol with this name */
! for (k=0 ; symbols[k] != NULL ; k++)
! {
! sym = symbols[k];
! if (!strcmp(info->indextable[i].function_name, sym->name))
! {
! info->indextable[i].val =
! sym->value + sym->section->vma;
! break;
! }
! }
! if (pos) *pos = ':';
! }
! }
! qsort (info->indextable, (size_t) info->indextablesize,
! sizeof (struct indexentry), cmpindexentry);
*pinfo = (PTR) info;
}