This is the mail archive of the binutils@sources.redhat.com 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]

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)

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