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]

A bug in bfd_elf_generic_reloc.


Here is bfd_elf_generic_reloc in elf.c:

/* ELF relocs are against symbols.  If we are producing relocateable
   output, and the reloc is against an external symbol, and nothing
   has given us any additional addend, the resulting reloc will also
   be against the same symbol.  In such a case, we don't want to
   change anything about the way the reloc is handled, since it will
   all be done at final link time.  Rather than put special case code
   into bfd_perform_relocation, all the reloc types use this howto
   function.  It just short circuits the reloc if producing
   relocateable output against an external symbol.  */

bfd_reloc_status_type
bfd_elf_generic_reloc (abfd,
		       reloc_entry,
		       symbol,
		       data,
		       input_section,
		       output_bfd,
		       error_message)
     bfd *abfd ATTRIBUTE_UNUSED;
     arelent *reloc_entry;
     asymbol *symbol;
     PTR data ATTRIBUTE_UNUSED;
     asection *input_section;
     bfd *output_bfd;
     char **error_message ATTRIBUTE_UNUSED;
{
  if (output_bfd != (bfd *) NULL
      && (symbol->flags & BSF_SECTION_SYM) == 0
      && (! reloc_entry->howto->partial_inplace
	  || reloc_entry->addend == 0))
    {
      reloc_entry->address += input_section->output_offset;
      return bfd_reloc_ok;
    }

  return bfd_reloc_continue;
}


But bfd_perform_relocation in reloc.c has

  if (howto->special_function)
    {
      bfd_reloc_status_type cont;

      cont = howto->special_function (abfd, reloc_entry, symbol,
				      /* XXX - Non-portable! */
				      ((bfd_byte *) data_start
				       - data_start_offset),
				      input_section, abfd, error_message);
      if (cont != bfd_reloc_continue)
	return cont;
    }

  ...

  if (howto->partial_inplace == false)
    {
      reloc_entry->addend = relocation;
      reloc_entry->address += input_section->output_offset;
      return flag;
    }
  else
    {
      reloc_entry->address += input_section->output_offset;

      /* WTF?? */
      if (abfd->xvec->flavour == bfd_target_coff_flavour
	  && strcmp (abfd->xvec->name, "coff-Intel-little") != 0
	  && strcmp (abfd->xvec->name, "coff-Intel-big") != 0)
	{
	  reloc_entry->addend = 0;
	}
      else
	{
	  reloc_entry->addend = relocation;
	}
    }

It is possible that reloc_entry->addend may be changed to zero to none
zero. What is the best way to fix it?


H.J.


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