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]

Re: [PATCH] Eliminate duplicate dwarf2 data


Hi Daniel,

: With the new gcc, you have at least one .gnu.linkonce.wi, and at
: least one debug_info, unless your C++ app is fake.
: So this recode won't handle it.
: However,  changing the
: "msec = find_debug_info (" to "while (msec = find_debug_info )", and
: putting the rest in the while block, should work fine.

Well almost.  You need to be able to restart the search from after the
last section found, and you need to concatenate the sections' contents
into one stash for processing by the rest of the function.  The patch
below does both of these things.

Let me know what you think.

Cheers
	Nick

2000-08-29  Nick Clifton  <nickc@redhat.com>

	* dwarf2.c (find_debug_info): New function: Locate a section
	containing dwarf2 debug information.
	(bfd_dwarf2_find_nearest_line): Find all sections containing
	debug information and include them in the stash.

Index: bfd/dwarf2.c
===================================================================
RCS file: /cvs/src//src/bfd/dwarf2.c,v
retrieving revision 1.14
diff -p -r1.14 dwarf2.c
*** dwarf2.c	2000/04/19 10:53:01	1.14
--- dwarf2.c	2000/08/29 19:58:19
*************** comp_unit_find_nearest_line (unit, addr,
*** 1463,1468 ****
--- 1463,1505 ----
    return line_p || func_p;
  }
  
+ /* Locate a section in a BFD containing debugging info.  The search starts from the
+    section after AFTER_SEC, or from the first section in the BFD if AFTER_SEC is
+    NULL.  The search works by examining the names of the sections.  There are two
+    permissiable names.  The first is .debug_info.  This is the standard DWARF2 name.
+    The second is a prefix .gnu.linkonce.wi.  This is a variation on the .debug_info
+    section which has a checksum describing the contents appended onto the name.  This
+    allows the linker to identify and discard duplicate debugging sections for
+    different compilation units.  */
+ #define DWARF2_DEBUG_INFO ".debug_info"
+ #define GNU_LINKONCE_INFO ".gnu.linkonce.wi."
+ 
+ static asection *
+ find_debug_info (abfd, after_sec)
+      bfd * abfd;
+      asection * after_sec;
+ {
+   asection * msec;
+ 
+   if (after_sec)
+     msec = after_sec->next;
+   else
+     msec = abfd->sections;
+ 
+   while (msec)
+     {
+       if (strcmp (msec->name, DWARF2_DEBUG_INFO) == 0)
+ 	return msec;
+ 
+       if (strncmp (msec->name, GNU_LINKONCE_INFO, strlen (GNU_LINKONCE_INFO)) == 0)
+ 	return msec;
+ 
+       msec = msec->next;
+     }
+ 
+   return NULL;
+ }
+ 
  /* The DWARF2 version of find_nearest line.  Return true if the line
     is found without error.  ADDR_SIZE is the number of bytes in the
     initial .debug_info length field and in the abbreviation offset.
*************** _bfd_dwarf2_find_nearest_line (abfd, sec
*** 1514,1572 ****
    if (! stash)
      {
        asection *msec;
!       unsigned long size;
!       
        stash = elf_tdata (abfd)->dwarf2_find_line_info =
  	(struct dwarf2_debug*) bfd_zalloc (abfd, sizeof (struct dwarf2_debug));
!       
        if (! stash)
  	return false;
!       
!       msec = bfd_get_section_by_name (abfd, ".debug_info");
        if (! msec)
  	{
  	  /* No dwarf2 info.  Note that at this point the stash
  	     has been allocated, but contains zeros, this lets
! 	     future calls to this function fail quicker. */
  	  return false;
  	}
- 
-       size = msec->_raw_size;
-       if (size == 0)
- 	return false;
-       
-       stash->info_ptr = (char *) bfd_alloc (abfd, size);
-       
-       if (! stash->info_ptr)
- 	return false;
  
!       if (! bfd_get_section_contents (abfd, msec, stash->info_ptr, 0, size))
  	{
! 	  stash->info_ptr = 0;
! 	  return false;
! 	}
  
!       stash->info_ptr_end = stash->info_ptr + size;
  
!       /* FIXME: There is a problem with the contents of the
! 	 .debug_info section.  The 'low' and 'high' addresses of the
! 	 comp_units are computed by relocs against symbols in the
! 	 .text segment.  We need these addresses in order to determine
! 	 the nearest line number, and so we have to resolve the
! 	 relocs.  There is a similar problem when the .debug_line
! 	 section is processed as well (e.g., there may be relocs
! 	 against the operand of the DW_LNE_set_address operator).
! 	 
! 	 Unfortunately getting hold of the reloc information is hard...
! 
! 	 For now, this means that disassembling object files (as
! 	 opposed to fully executables) does not always work as well as
! 	 we would like.  */
      }
    
    /* A null info_ptr indicates that there is no dwarf2 info 
       (or that an error occured while setting up the stash). */
- 
    if (! stash->info_ptr)
      return false;
  
--- 1551,1615 ----
    if (! stash)
      {
        asection *msec;
! 
        stash = elf_tdata (abfd)->dwarf2_find_line_info =
  	(struct dwarf2_debug*) bfd_zalloc (abfd, sizeof (struct dwarf2_debug));
! 
        if (! stash)
  	return false;
! 
!       msec = find_debug_info (abfd, NULL);
        if (! msec)
  	{
  	  /* No dwarf2 info.  Note that at this point the stash
  	     has been allocated, but contains zeros, this lets
! 	     future calls to this function fail quicker.  */
  	  return false;
  	}
  
!       /* There can be more than one dwarf info section in a BFD these days.
!          Read them all in and produce one large stash.  */
!       do
  	{
! 	  unsigned long size;
! 	  unsigned long start;
! 
! 	  size = msec->_raw_size;
! 	  if (size == 0)
! 	    continue;
! 
! 	  start = stash->info_ptr_end - stash->info_ptr;
! 
! 	  stash->info_ptr = (char *) bfd_realloc ((PTR) stash->info_ptr, start + size);
  
! 	  if (! stash->info_ptr)
! 	    return false;
  
! 	  if (! bfd_get_section_contents (abfd, msec, stash->info_ptr + start, 0, size))
! 	    continue;
! 
! 	  stash->info_ptr_end = stash->info_ptr + start + size;
! 	}
!       while ((msec = find_debug_info (abfd, msec)) != NULL);
      }
+ 
+   /* FIXME: There is a problem with the contents of the
+      .debug_info section.  The 'low' and 'high' addresses of the
+      comp_units are computed by relocs against symbols in the
+      .text segment.  We need these addresses in order to determine
+      the nearest line number, and so we have to resolve the
+      relocs.  There is a similar problem when the .debug_line
+      section is processed as well (e.g., there may be relocs
+      against the operand of the DW_LNE_set_address operator).
+      
+      Unfortunately getting hold of the reloc information is hard...
+      
+      For now, this means that disassembling object files (as
+      opposed to fully executables) does not always work as well as
+      we would like.  */
    
    /* A null info_ptr indicates that there is no dwarf2 info 
       (or that an error occured while setting up the stash). */
    if (! stash->info_ptr)
      return false;
  

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