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]

Re: [drow@mvista.com: Re: _bfd_dwarf2_find_nearest_line returns wrong filename]


Ping?

On Mon, Feb 24, 2003 at 11:57:05PM -0500, Daniel Jacobowitz wrote:
> This was buried in my discussion with Andreas; would someone mind
> reviewing the final patch?
> 
> ----- Forwarded message from Daniel Jacobowitz <drow at mvista dot com> -----
> 
> Date: Tue, 4 Feb 2003 10:37:05 -0500
> From: Daniel Jacobowitz <drow at mvista dot com>
> Subject: Re: _bfd_dwarf2_find_nearest_line returns wrong filename
> To: binutils at sources dot redhat dot com
> Mail-Followup-To: binutils at sources dot redhat dot com
> 
> On Sun, Jan 19, 2003 at 06:00:21PM +0100, Andreas Schwab wrote:
> > Daniel Jacobowitz <drow at mvista dot com> writes:
> > 
> > |> On Fri, Jan 03, 2003 at 03:39:40PM +0100, Andreas Schwab wrote:
> > |> > Daniel Jacobowitz <drow at mvista dot com> writes:
> > |> > 
> > |> > |> No regressions, but some pertinent facts:
> > |> > |> 
> > |> > |>  - Examine the ld.log with this patch applied.  Grep for BFD.  You'll
> > |> > |>    find several assertion failures indicating that the DWARF-2 data
> > |> > |>    is incorrect.  It's kind of sad that the testsuite doesn't notice any
> > |> > |>    of these.
> > |> > 
> > |> > I have now tried it on ia64, and it is getting worse.  They are using
> > |> > R_IA64_SECREL32LS relocations in .debug_info, which is causing
> > |> > bfd_perform_relocation to return bfd_reloc_outofrange, and
> > |> > bfd_generic_get_relocated_section_contents is aborting on that.
> > |> 
> > |> We needed to save and restore outputs in order to get the right answers
> > |> on i386 in some cases.  We also needed some other fixes to ia64 - I
> > |> missed it when I swept the hash table create functions to make them use
> > |> bfd_malloc, I guess - and to weaken an abort in elfNN_ia64_reloc.  But
> > |> now it works.
> > 
> > This does not seem to work in the linker, it doesn't emit any filename
> > prefixes any more.  This also causes testsuite failures, the ld-elfvsb
> > tests depend on the filename part of the error messages.
> 
> I had the right idea, but I wasn't thorough enough implementing it.  In
> addition to dummying the output offsets, we also have to dummy the
> output sections.  Otherwise .debug_info thinks that a function starts
> up past 0x08400000, and the rest of the linker thinks that it starts at
> 0x18.
> 
> Andreas, thanks for your continued patience.  Would you mind testing
> this version?
> 
> -- 
> Daniel Jacobowitz
> MontaVista Software                         Debian GNU/Linux Developer
> 
> 2003-02-04  Andreas Schwab  <schwab at suse dot de>
> 	    Daniel Jacobowitz  <drow at mvista dot com>
> 
> 	* simple.c (bfd_simple_get_relocated_section_contents): Add
> 	parameter symbol_table.  Optionally use it instead of the symbol
> 	table from the bfd.  Save and restore output offsets and output
> 	sections  around bfd_get_relocated_section_contents.  Fix a memory
> 	leak.
> 	(simple_save_output_info, simple_restore_output_info): New
> 	functions.
> 	* bfd-in2.h: Regenerate.
> 	* dwarf2.c (read_abbrevs): Use
> 	bfd_simple_get_relocated_section_contents instead of
> 	bfd_get_section_contents.
> 	(decode_line_info): Likewise.
> 	(_bfd_dwarf2_find_nearest_line): Likewise.  Don't call
> 	find_rela_addend.
> 	(find_rela_addend): Remove.
> 	* elfxx-ia64.c (elfNN_ia64_reloc): Weaken sanity check for
> 	debugging sections.
> 	(elfNN_ia64_hash_table_create): Create the hash table with malloc,
> 	not bfd_zalloc.
> 
> Index: bfd/dwarf2.c
> ===================================================================
> RCS file: /big/fsf/rsync/src-cvs/src/bfd/dwarf2.c,v
> retrieving revision 1.42
> diff -u -p -r1.42 dwarf2.c
> --- bfd/dwarf2.c	12 Dec 2002 10:26:01 -0000	1.42
> +++ bfd/dwarf2.c	16 Jan 2003 20:52:45 -0000
> @@ -245,8 +245,6 @@ static bfd_boolean lookup_address_in_lin
>  static bfd_boolean lookup_address_in_function_table
>    PARAMS ((struct funcinfo *, bfd_vma, struct funcinfo **, const char **));
>  static bfd_boolean scan_unit_for_functions PARAMS ((struct comp_unit *));
> -static bfd_vma find_rela_addend
> -  PARAMS ((bfd *, asection *, bfd_size_type, asymbol**));
>  static struct comp_unit *parse_comp_unit
>    PARAMS ((bfd *, struct dwarf2_debug *, bfd_vma, unsigned int));
>  static bfd_boolean comp_unit_contains_address
> @@ -546,13 +544,11 @@ read_abbrevs (abfd, offset, stash)
>  	}
>  
>        stash->dwarf_abbrev_size = msec->_raw_size;
> -      stash->dwarf_abbrev_buffer = (char*) bfd_alloc (abfd, msec->_raw_size);
> +      stash->dwarf_abbrev_buffer
> +	= bfd_simple_get_relocated_section_contents (abfd, msec, NULL,
> +						     stash->syms);
>        if (! stash->dwarf_abbrev_buffer)
>  	  return 0;
> -
> -      if (! bfd_get_section_contents (abfd, msec, stash->dwarf_abbrev_buffer,
> -				      (bfd_vma) 0, msec->_raw_size))
> -	return 0;
>      }
>  
>    if (offset >= stash->dwarf_abbrev_size)
> @@ -1019,21 +1015,15 @@ decode_line_info (unit, stash)
>  	}
>  
>        stash->dwarf_line_size = msec->_raw_size;
> -      stash->dwarf_line_buffer = (char *) bfd_alloc (abfd, msec->_raw_size);
> +      stash->dwarf_line_buffer
> +	= bfd_simple_get_relocated_section_contents (abfd, msec, NULL,
> +						     stash->syms);
>        if (! stash->dwarf_line_buffer)
>  	return 0;
> -
> -      if (! bfd_get_section_contents (abfd, msec, stash->dwarf_line_buffer,
> -				      (bfd_vma) 0, msec->_raw_size))
> -	return 0;
> -
> -      /* FIXME: We ought to apply the relocs against this section before
> -	 we process it...  */
>      }
>  
> -  /* Since we are using un-relocated data, it is possible to get a bad value
> -     for the line_offset.  Validate it here so that we won't get a segfault
> -     below.  */
> +  /* It is possible to get a bad value for the line_offset.  Validate
> +     it here so that we won't get a segfault below.  */
>    if (unit->line_offset >= stash->dwarf_line_size)
>      {
>        (*_bfd_error_handler) (_("Dwarf Error: Line offset (%lu) greater than or equal to .debug_line size (%lu)."),
> @@ -1521,60 +1511,6 @@ scan_unit_for_functions (unit)
>    return TRUE;
>  }
>  
> -/* Look for a RELA relocation to be applied on OFFSET of section SEC,
> -   and return the addend if such a relocation is found.  Since this is
> -   only used to find relocations referring to the .debug_abbrev
> -   section, we make sure the relocation refers to this section, but
> -   this is not strictly necessary, and it can probably be safely
> -   removed if needed.  However, it is important to note that this
> -   function only returns the addend, it doesn't serve the purpose of
> -   applying a generic relocation.
> -
> -   If no suitable relocation is found, or if it is not a real RELA
> -   relocation, this function returns 0.  */
> -
> -static bfd_vma
> -find_rela_addend (abfd, sec, offset, syms)
> -     bfd* abfd;
> -     asection* sec;
> -     bfd_size_type offset;
> -     asymbol** syms;
> -{
> -  long reloc_size = bfd_get_reloc_upper_bound (abfd, sec);
> -  arelent **relocs = NULL;
> -  long reloc_count, relc;
> -
> -  if (reloc_size <= 0)
> -    return 0;
> -
> -  relocs = (arelent **) bfd_malloc ((bfd_size_type) reloc_size);
> -  if (relocs == NULL)
> -    return 0;
> -
> -  reloc_count = bfd_canonicalize_reloc (abfd, sec, relocs, syms);
> -
> -  if (reloc_count <= 0)
> -    {
> -      free (relocs);
> -      return 0;
> -    }
> -
> -  for (relc = 0; relc < reloc_count; relc++)
> -    if (relocs[relc]->address == offset
> -	&& (*relocs[relc]->sym_ptr_ptr)->flags & BSF_SECTION_SYM
> -	&& strcmp ((*relocs[relc]->sym_ptr_ptr)->name,
> -		   ".debug_abbrev") == 0)
> -      {
> -	bfd_vma addend = (relocs[relc]->howto->partial_inplace
> -			  ? 0 : relocs[relc]->addend);
> -	free (relocs);
> -	return addend;
> -      }
> -
> -  free (relocs);
> -  return 0;
> -}
> -
>  /* Parse a DWARF2 compilation unit starting at INFO_PTR.  This
>     includes the compilation unit header that proceeds the DIE's, but
>     does not include the length field that preceeds each compilation
> @@ -1602,7 +1538,6 @@ parse_comp_unit (abfd, stash, unit_lengt
>    char *info_ptr = stash->info_ptr;
>    char *end_ptr = info_ptr + unit_length;
>    bfd_size_type amt;
> -  bfd_size_type off;
>  
>    version = read_2_bytes (abfd, info_ptr);
>    info_ptr += 2;
> @@ -1611,12 +1546,6 @@ parse_comp_unit (abfd, stash, unit_lengt
>      abbrev_offset = read_4_bytes (abfd, info_ptr);
>    else
>      abbrev_offset = read_8_bytes (abfd, info_ptr);
> -  /* The abbrev offset is generally a relocation pointing to
> -     .debug_abbrev+offset.  On RELA targets, we have to find the
> -     relocation and extract the addend to obtain the actual
> -     abbrev_offset, so do it here.  */
> -  off = info_ptr - stash->sec_info_ptr;
> -  abbrev_offset += find_rela_addend (abfd, stash->sec, off, stash->syms);
>    info_ptr += offset_size;
>    addr_size = read_1_byte (abfd, info_ptr);
>    info_ptr += 1;
> @@ -1939,8 +1868,8 @@ _bfd_dwarf2_find_nearest_line (abfd, sec
>  
>  	  start = stash->info_ptr_end - stash->info_ptr;
>  
> -	  if (! bfd_get_section_contents (abfd, msec, stash->info_ptr + start,
> -					  (bfd_vma) 0, size))
> +	  if ((bfd_simple_get_relocated_section_contents
> +	       (abfd, msec, stash->info_ptr + start, symbols)) == NULL)
>  	    continue;
>  
>  	  stash->info_ptr_end = stash->info_ptr + start + size;
> @@ -1953,21 +1882,6 @@ _bfd_dwarf2_find_nearest_line (abfd, sec
>        stash->syms = symbols;
>      }
>  
> -  /* 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)
> @@ -2034,10 +1948,10 @@ _bfd_dwarf2_find_nearest_line (abfd, sec
>  		{
>  		  if (comp_unit_contains_address (each, addr))
>  		    return comp_unit_find_nearest_line (each, addr,
> -						       filename_ptr,
> -						       functionname_ptr,
> -						       linenumber_ptr,
> -						       stash);
> +							filename_ptr,
> +							functionname_ptr,
> +							linenumber_ptr,
> +							stash);
>  		}
>  	      else
>  		{
> Index: bfd/elfxx-ia64.c
> ===================================================================
> RCS file: /big/fsf/rsync/src-cvs/src/bfd/elfxx-ia64.c,v
> retrieving revision 1.66
> diff -u -p -r1.66 elfxx-ia64.c
> --- bfd/elfxx-ia64.c	17 Jan 2003 23:27:55 -0000	1.66
> +++ bfd/elfxx-ia64.c	4 Feb 2003 15:31:06 -0000
> @@ -346,6 +346,10 @@ elfNN_ia64_reloc (abfd, reloc, sym, data
>        reloc->address += input_section->output_offset;
>        return bfd_reloc_ok;
>      }
> +
> +  if (input_section->flags & SEC_DEBUGGING)
> +    return bfd_reloc_continue;
> +
>    *error_message = "Unsupported call to elfNN_ia64_reloc";
>    return bfd_reloc_notsupported;
>  }
> @@ -1701,19 +1705,25 @@ elfNN_ia64_hash_table_create (abfd)
>  {
>    struct elfNN_ia64_link_hash_table *ret;
>  
> -  ret = bfd_zalloc (abfd, (bfd_size_type) sizeof (*ret));
> +  ret = bfd_malloc ((bfd_size_type) sizeof (*ret));
>    if (!ret)
>      return 0;
> +  memset (ret, 0, sizeof (*ret));
> +
>    if (!_bfd_elf_link_hash_table_init (&ret->root, abfd,
>  				      elfNN_ia64_new_elf_hash_entry))
>      {
> -      bfd_release (abfd, ret);
> +      free (ret);
>        return 0;
>      }
>  
>    if (!elfNN_ia64_local_hash_table_init (&ret->loc_hash_table, abfd,
>  				         elfNN_ia64_new_loc_hash_entry))
> -    return 0;
> +    {
> +      free (ret);
> +      return 0;
> +    }
> +
>    return &ret->root.root;
>  }
>  
> Index: bfd/simple.c
> ===================================================================
> RCS file: /big/fsf/rsync/src-cvs/src/bfd/simple.c,v
> retrieving revision 1.5
> diff -u -p -r1.5 simple.c
> --- bfd/simple.c	30 Nov 2002 08:39:40 -0000	1.5
> +++ bfd/simple.c	4 Feb 2003 15:28:20 -0000
> @@ -42,8 +42,14 @@ static bfd_boolean simple_dummy_reloc_da
>  static bfd_boolean simple_dummy_unattached_reloc
>    PARAMS ((struct bfd_link_info *, const char *, bfd *, asection *, bfd_vma));
>  
> +static void simple_save_output_info
> +  PARAMS ((bfd *, asection *, PTR));
> +
> +static void simple_restore_output_info
> +  PARAMS ((bfd *, asection *, PTR));
> +
>  bfd_byte * bfd_simple_get_relocated_section_contents
> -  PARAMS ((bfd *, asection *, bfd_byte *));
> +  PARAMS ((bfd *, asection *, bfd_byte *, asymbol **));
>  
>  static bfd_boolean
>  simple_dummy_warning (link_info, warning, symbol, abfd, section, address)
> @@ -105,17 +111,48 @@ simple_dummy_unattached_reloc (link_info
>    return TRUE;
>  }
>  
> +struct saved_output_info
> +{
> +  bfd_vma offset;
> +  asection *section;
> +};
> +
> +static void
> +simple_save_output_info (abfd, section, ptr)
> +     bfd *abfd ATTRIBUTE_UNUSED;
> +     asection *section;
> +     PTR ptr;
> +{
> +  struct saved_output_info *output_info = (struct saved_output_info *) ptr;
> +  output_info[section->index].offset = section->output_offset;
> +  output_info[section->index].section = section->output_section;
> +  section->output_offset = 0;
> +  section->output_section = section;
> +}
> +
> +static void
> +simple_restore_output_info (abfd, section, ptr)
> +     bfd *abfd ATTRIBUTE_UNUSED;
> +     asection *section;
> +     PTR ptr;
> +{
> +  struct saved_output_info *output_info = (struct saved_output_info *) ptr;
> +  section->output_offset = output_info[section->index].offset;
> +  section->output_section = output_info[section->index].section;
> +}
> +
>  /*
>  FUNCTION
>  	bfd_simple_relocate_secton
>  
>  SYNOPSIS
> -	bfd_byte *bfd_simple_get_relocated_section_contents (bfd *abfd, asection *sec, bfd_byte *outbuf);
> +	bfd_byte *bfd_simple_get_relocated_section_contents (bfd *abfd, asection *sec, bfd_byte *outbuf, asymbol **symbol_table);
>  
>  DESCRIPTION
> -	Returns the relocated contents of section @var{sec}.  Only symbols
> -	from @var{abfd} and the output offsets assigned to sections in
> -	@var{abfd} are used.  The result will be stored at @var{outbuf}
> +	Returns the relocated contents of section @var{sec}.  The symbols in
> +	@var{symbol_table} will be used, or the symbols from @var{abfd} if
> +	@var{symbol_table} is NULL.  The output offsets for all sections will
> +	be temporarily reset to 0.  The result will be stored at @var{outbuf}
>  	or allocated with @code{bfd_malloc} if @var{outbuf} is @code{NULL}.
>  
>  	Generally all sections in @var{abfd} should have their
> @@ -126,17 +163,18 @@ DESCRIPTION
>  */
>  
>  bfd_byte *
> -bfd_simple_get_relocated_section_contents (abfd, sec, outbuf)
> +bfd_simple_get_relocated_section_contents (abfd, sec, outbuf, symbol_table)
>       bfd *abfd;
>       asection *sec;
>       bfd_byte *outbuf;
> +     asymbol **symbol_table;
>  {
>    struct bfd_link_info link_info;
>    struct bfd_link_order link_order;
>    struct bfd_link_callbacks callbacks;
>    bfd_byte *contents, *data;
>    int storage_needed, number_of_symbols;
> -  asymbol **symbol_table;
> +  PTR saved_offsets;
>  
>    if (! (sec->flags & SEC_RELOC))
>      {
> @@ -183,11 +221,36 @@ bfd_simple_get_relocated_section_content
>  	return NULL;
>        outbuf = data;
>      }
> -  bfd_link_add_symbols (abfd, &link_info);
>  
> -  storage_needed = bfd_get_symtab_upper_bound (abfd);
> -  symbol_table = (asymbol **) bfd_malloc (storage_needed);
> -  number_of_symbols = bfd_canonicalize_symtab (abfd, symbol_table);
> +  /* The sections in ABFD may already have output sections and offsets set.
> +     Because this function is primarily for debug sections, and GCC uses the
> +     knowledge that debug sections will generally have VMA 0 when emiting
> +     relocations between DWARF-2 sections (which are supposed to be
> +     section-relative offsets anyway), we need to reset the output offsets
> +     to zero.  We also need to arrange for section->output_section->vma plus
> +     section->output_offset to equal section->vma, which we do by setting
> +     section->output_section to point back to section.  Save the original
> +     output offset and output section to restore later.  */
> +  saved_offsets = malloc (sizeof (struct saved_output_info)
> +			  * abfd->section_count);
> +  if (saved_offsets == NULL)
> +    {
> +      if (data)
> +	free (data);
> +      return NULL;
> +    }
> +  bfd_map_over_sections (abfd, simple_save_output_info, saved_offsets);
> +
> +  if (symbol_table == NULL)
> +    {
> +      bfd_link_add_symbols (abfd, &link_info);
> +
> +      storage_needed = bfd_get_symtab_upper_bound (abfd);
> +      symbol_table = (asymbol **) bfd_malloc (storage_needed);
> +      number_of_symbols = bfd_canonicalize_symtab (abfd, symbol_table);
> +    }
> +  else
> +    storage_needed = 0;
>  
>    contents = bfd_get_relocated_section_contents (abfd,
>  						 &link_info,
> @@ -197,6 +260,12 @@ bfd_simple_get_relocated_section_content
>  						 symbol_table);
>    if (contents == NULL && data != NULL)
>      free (data);
> +
> +  if (storage_needed != 0)
> +    free (symbol_table);
> +
> +  bfd_map_over_sections (abfd, simple_restore_output_info, saved_offsets);
> +  free (saved_offsets);
>  
>    /* Foul hack to prevent bfd_section_size aborts.  This flag only controls
>       that macro (and the related size macros), selecting between _raw_size
> 
> 
> ----- End forwarded message -----
> 
> -- 
> Daniel Jacobowitz
> MontaVista Software                         Debian GNU/Linux Developer
> 

-- 
Daniel Jacobowitz
MontaVista Software                         Debian GNU/Linux Developer


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