This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
Make readelf more helpful when it cannot find a comp unit
- From: Nick Clifton <nickc at redhat dot com>
- To: binutils at sources dot redhat dot com
- Date: Wed, 22 Dec 2004 11:10:24 +0000
- Subject: Make readelf more helpful when it cannot find a comp unit
Hi Guys,
Whilst looking at GCC bug 19124 I realised that readelf is not being
very helpful when it encounters a .debug_loc section which has more
comp_units than the .debug_info section. It really should issue a
warning message and then carry on to display the rest of the
section, rather than just stopping with an error message.
So I have written the attached patch to do just this. With this
patch applied the test case in gcc/19124 now produces this output
when run through "readelf -wo":
Contents of the .debug_loc section:
Offset Begin End Expression
00000000 00000000 0000000b (DW_OP_fbreg: 8)
00000000 0000000b 00000023 (DW_OP_reg3)
00000000 00000023 00000025 (DW_OP_fbreg: 8)
readelf: Warning: .debug_loc section has more comp units than .debug_info section
readelf: Warning: assuming that the pointer size is 4, from the last comp unit in .debug_info
0000002b 00000010 00000010 (DW_OP_reg1)
0000002b 0000001a 00000025 (DW_OP_reg1)
I will be committing this patch shortly.
Cheers
Nick
binutils/ChangeLog
2004-12-22 Nick Clifton <nickc@redhat.com>
* readelf.c (last_pointer_size, warned_about_missing_comp_units):
New variables associated with obtaining the pointer size for a
comp_unit.
(get_pointer_size_of_comp_unit): Add an extra parameter - the name
of the section requesting the pointer size. Use this name in
error messages. If there are not enough comp_units available
produce a warning message, but return the last known pointer size
so that section dumping can continue.
(get_debug_info): Reset the new variables.
(display_debug_lines): Add extra parameter to invocation of
get_pointer_size_of_comp_unit and remove error message when it
returns 0.
(display_debug_loc): Likewise.
Index: binutils/readelf.c
===================================================================
RCS file: /cvs/src/src/binutils/readelf.c,v
retrieving revision 1.267
diff -c -3 -p -r1.267 readelf.c
*** binutils/readelf.c 9 Dec 2004 06:19:12 -0000 1.267
--- binutils/readelf.c 22 Dec 2004 10:55:37 -0000
*************** debug_info;
*** 7079,7093 ****
static debug_info * debug_information = NULL;
static unsigned int num_debug_info_entries = 0;
static unsigned int
! get_pointer_size_of_comp_unit (unsigned int comp_unit)
{
! if (num_debug_info_entries == 0
! || comp_unit >= num_debug_info_entries)
! return 0;
- return debug_information [comp_unit].pointer_size;
}
/* Locate and scan the .debug_info section in the file and record the pointer
--- 7079,7114 ----
static debug_info * debug_information = NULL;
static unsigned int num_debug_info_entries = 0;
+ static unsigned int last_pointer_size = 0;
+ static int warned_about_missing_comp_units = FALSE;
static unsigned int
! get_pointer_size_of_comp_unit (unsigned int comp_unit,
! const char * section_name)
{
! if (num_debug_info_entries == 0)
! {
! error (_("%s section needs a populated .debug_info section\n"),
! section_name);
! return 0;
! }
!
! if (comp_unit >= num_debug_info_entries)
! {
! if (!warned_about_missing_comp_units)
! {
! warn (_("%s section has more comp units than .debug_info section\n"),
! section_name);
! warn (_("assuming that the pointer size is %d, from the last comp unit in .debug_info\n\n"),
! last_pointer_size);
! warned_about_missing_comp_units = TRUE;
! }
! }
! else
! last_pointer_size = debug_information [comp_unit].pointer_size;
!
! return last_pointer_size;
}
/* Locate and scan the .debug_info section in the file and record the pointer
*************** get_debug_info (FILE * file)
*** 7107,7112 ****
--- 7128,7139 ----
unsigned int num_units;
unsigned int unit;
+ /* Reset the last pointer size so that we can issue correct
+ error messages if we are displaying the contents of more
+ than one file. */
+ last_pointer_size = 0;
+ warned_about_missing_comp_units = FALSE;
+
/* If we already have the information there is nothing else to do. */
if (num_debug_info_entries > 0)
return num_debug_info_entries;
*************** display_debug_lines (Elf_Internal_Shdr *
*** 7275,7286 ****
/* Get the pointer size from the comp unit associated
with this block of line number information. */
! pointer_size = get_pointer_size_of_comp_unit (comp_unit);
! if (pointer_size == 0)
! {
! error (_("Not enough comp units for .debug_line section\n"));
! return 0;
! }
comp_unit ++;
printf (_(" Length: %ld\n"), info.li_length);
--- 7302,7309 ----
/* Get the pointer size from the comp unit associated
with this block of line number information. */
! pointer_size = get_pointer_size_of_comp_unit (comp_unit,
! ".debug_lines");
comp_unit ++;
printf (_(" Length: %ld\n"), info.li_length);
*************** display_debug_loc (Elf_Internal_Shdr *se
*** 8487,8498 ****
/* Get the pointer size from the comp unit associated
with this block of location information. */
! pointer_size = get_pointer_size_of_comp_unit (comp_unit);
! if (pointer_size == 0)
! {
! error (_("Not enough comp units for .debug_loc section\n"));
! return 0;
! }
comp_unit ++;
while (1)
--- 8510,8517 ----
/* Get the pointer size from the comp unit associated
with this block of location information. */
! pointer_size = get_pointer_size_of_comp_unit (comp_unit, ".debug_loc");
!
comp_unit ++;
while (1)