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: RFC: Allow STT_SECTION + offset for SHF_MERGE sections


On Mon, Nov 19, 2001 at 07:06:55PM +1030, Alan Modra wrote:
> > --- bfd/elf32-i386.c.jj	Tue Nov 13 18:25:56 2001
> > +++ bfd/elf32-i386.c	Fri Nov 16 20:16:57 2001
> > @@ -1770,6 +1770,32 @@ elf_i386_relocate_section (output_bfd, i
> >  	  relocation = (sec->output_section->vma
> >  			+ sec->output_offset
> >  			+ sym->st_value);
> > +	  if ((sec->flags & SEC_MERGE)
> > +	      && ELF_ST_TYPE (sym->st_info) == STT_SECTION)
> > +	    {
> > +	      asection *msec;
> > +	      bfd_vma addend;
> > +
> > +	      if (howto->src_mask != 0xffffffff)
> > +		{
> > +		  (*_bfd_error_handler)
> > +		    (_("%s(%s+0x%lx): non-32bit relocation against SEC_MERGE section"),
> > +		     bfd_archive_filename (input_bfd),
> > +		     bfd_get_section_name (input_bfd, input_section),
> > +		     (long) rel->r_offset);
> > +		  return false;
> > +		}
> > +
> > +	      addend = bfd_get_32 (input_bfd, contents + rel->r_offset);
> > +	      msec = sec;
> > +	      addend =
> > +		_bfd_merged_section_offset (output_bfd, &msec,
> > +					    elf_section_data (sec)->merge_info,
> > +					    sym->st_value + addend, (bfd_vma) 0)
> > +		- relocation;
> > +	      addend += msec->output_section->vma + msec->output_offset;
> > +	      bfd_put_32 (input_bfd, addend, contents + rel->r_offset);
> > +	    }
> >  	}
> >        else
> >  	{
> 
> How about putting all the above into a function that is called instead of
> _bfd_final_link_relocate (and itself calls _bfd_final_link_relocate)?

This code differs between REL arches (where it is a lot backend dependent)
and RELA arches (where the code is basically the same, but the basic question
is whether it can modify rel->r_addend or not. If it could, it would mean
just calling a special routine which would do:

bfd_vma
_bfd_elf_rela_local_sym (abfd, sym, sec, rel)
     bfd *abfd;
     Elf_Internal_Sym *sym;
     asection *sec;
     Elf_Internal_Rela *rel;
{
  bfd_vma relocation;

  relocation = (sec->output_section->vma
		+ sec->output_offset
		+ sym->st_value);
  if ((sec->flags & SEC_MERGE)
      && ELF_ST_TYPE (sym->st_info) == STT_SECTION)
    {
      asection *msec;

      msec = sec;
      rel->r_addend =
	_bfd_merged_section_offset (abfd, &msec,
				    elf_section_data (sec)->merge_info,
				    sym->st_value + addend, (bfd_vma) 0)
	- relocation;
      rel->r_addend += msec->output_section->vma + msec->output_offset;
    }
  return relocation;
}

and replace
(1)	relocation = (sec->output_section->vma
		      + sec->output_offset
		      + sym->st_value);
with
(2)	relocation = _bfd_elf_rela_local_sym (output_bfd, sym, sec, rel);

I have checked and all RELA backends use code (1) so it would be pretty easy
to just replace it all with (2). The only exception is elf32-hppa.c, which
does:
          relocation = ((ELF_ST_TYPE (sym->st_info) == STT_SECTION
                           ? 0 : sym->st_value)
                         + sym_sec->output_offset
                         + sym_sec->output_section->vma);
instead. Are the STT_SECTION symbols ever having st_value != 0 in
relocatable objects on HPPA?
This IMHO cannot be done at _bfd_final_link_relocate time, since that is too
late (many backends might have created dynamic relocations from it already,
etc.) and _bfd_final_link_relocate wouldn't know if it gets the relocation
directly or whether backend didn't change it to GOT offset or whatever.

What do you think?

	Jakub


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