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