pc-relative relocs on alpha

Alan Modra amodra@bigpond.net.au
Thu Sep 19 08:00:00 GMT 2002


This is turning out to be a major pain.  Keep in mind that fx_offset is
the addend we're going to use when emitting a reloc, at least for RELA
targets.  So `addsy - subsy' where subsy is in the current section (and
addsy isn't) needs to be done something like:

	  else if (sub_symbol_segment == this_segment
		   && !TC_FORCE_RELOCATION_SUB_LOCAL (fixP))
	    {
	      add_number -= S_GET_VALUE (fixP->fx_subsy);
	      fixP->fx_offset = add_number + fixP->dot_value;

	      /* Make it pc-relative.  If the back-end code has not
		 selected a pc-relative reloc, cancel the adjustment
		 we do later on all pc-relative relocs.  */
	      if (!fixP->fx_pcrel)
		add_number += MD_PCREL_FROM_SECTION (fixP, this_segment);
	      fixP->fx_subsy = NULL;
	      fixP->fx_pcrel = 1;
	    }

where dot_value is the value of `.' at the time the expression was
parsed.  This results in a pcrel fixup against addsy with an offset
of `. - subsy' which makes sense to me.  The trouble is that the value
of dot when the expression is parsed is typically *not* the value of
dot when fix_new is called.  By the time fix_new is called, most
backends have emitted opcodes, bumping dot.

The only half reasonable solution I can see is to arrange for
expression() to save away the current value of dot, which fix_new
can then save.  I'm trying that now, and will run tests overnight.

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre



More information about the Binutils mailing list