This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC 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


Nick Clifton <nickc@redhat.com> writes:

> Hi Daniel,
> 
> > 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.
> 
> : Maybe i'm just stupid today, but i can't see why we need to
> : concatenate them into one stash. Doesn't the rest of the code
> : already handle walking through multiple compilation units to find
> : the info needed for debug_line?
> 
> : It has to, because we've always had multiple compilation units in
> : the executable if you linked >1 .o file with dwarf2 info in it.
> : Given this, I don't see what's changed besides the name of the
> : section that requires special processing. Like i said, maybe i'm
> : just daft today.  Or maybe i never tried to set a breakpoint in
> : something that was really in a seperate CU generated specifically by
> : this patch.
> 
> The point is that the 'stash' is actually a saved copy of the contents
> of the .debug_info section for the BFD concerned.

Oh, okay.
>   This stash may/will
> contain debug info for multiple compilation units, as you say, but the
> pre-patch code only expects there to be ONE .debug_info section in the
> BFD, so it only allocates & reads in the stash once.
> 

Makes sense now.
I just never looked all that hard at the code, i guess. I was mainly
grepping for places that were looking for debug info in .debug_info,
and changing them to also look at the linkonce sections.

> With the new scheme there will be multiple debug info sections in the
> BFD, so it is necessary to read them all in, build one large "stash"
> and then pass this stash off to the rest of the function so that it
> can process the compilation units in them.  (The rest of the function
> does not care where the compilation unit info came from).

Gotcha.
> 
> Hence the realloc'ing and the do...while loop in my patch.
> 
> : Thanks for doing all the hard work. I was actually going to submit
> : the binutils stuff seperately, and was only really including it so
> : people could try out the gcc part of the patch, but when i leave for
> : 5 seconds, you take a hack and make it work properly. :)
> 
> he he he
> 
> I have tweaked the patch a little bit to avoid the calls to
> bfd_realloc, by creating two passes over the section list.  This
> should speed things up slightly.  New patch below.  I am going to
> apply this patch to the repository.

Please, do.

Is it possible to up the bfd or ld minor version number for this? I can
detect whether we support the new linkonce sections other ways (test
link, then grep to see if the linkonce.wi section is still in there),
but it might make sense since it changes all the linker scripts and
whatnot, so if someone is building RPM's/debs/etc from the binutils
CVS, they can tell that there really was an important change.
--Dan

> 
> Cheers
> 	Nick
> 
> 2000-09-02  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/09/02 20:07:36
> *************** 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
> *** 1513,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;
> 
> --- 1550,1623 ----
> 
>     if (! stash)
>       {
> +       unsigned long total_size;
>         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 DWARF2 info section in a BFD these days.
> !          Read them all in and produce one large stash.  We do this in two
> ! 	 passes - in the first pass we just accumulate the section sizes.
> ! 	 In the second pass we read in the section's contents.  The allows
> ! 	 us to avoid reallocing the data as we add sections to the stash.  */
> !       for (total_size = 0; msec; msec = find_debug_info (abfd, msec))
> ! 	total_size += msec->_raw_size;
> 
> !       stash->info_ptr = (char *) bfd_alloc (abfd, total_size);
> !       if (stash->info_ptr == NULL)
>   	return false;
> 
> !       stash->info_ptr_end = stash->info_ptr;
> ! 
> !       for (msec = find_debug_info (abfd, NULL);
> ! 	   msec;
> ! 	   msec = find_debug_info (abfd, msec))
>   	{
> ! 	  unsigned long size;
> ! 	  unsigned long start;
> ! 
> ! 	  size = msec->_raw_size;
> ! 	  if (size == 0)
> ! 	    continue;
> ! 
> ! 	  start = stash->info_ptr_end - stash->info_ptr;
> 
> ! 	  if (! bfd_get_section_contents (abfd, msec, stash->info_ptr + start, 0, size))
> ! 	    continue;
> 
> ! 	  stash->info_ptr_end = stash->info_ptr + start + size;
> ! 	}
> ! 
> !       BFD_ASSERT (stash->info_ptr_end = stash->info_ptr + total_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;


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