This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
Re: Assertion in gas/tc_gen_reloc in dlx-elf, arc-elf, perhapsother targets under some conditions
- From: Nick Clifton <nickc at redhat dot com>
- To: "Dave Korn" <dk at artimi dot com>
- Cc: <binutils at sources dot redhat dot com>
- Date: Wed, 03 Mar 2004 12:56:17 +0000
- Subject: Re: Assertion in gas/tc_gen_reloc in dlx-elf, arc-elf, perhapsother targets under some conditions
- References: <NUTMEG00goZolmRBaYF0000000a@NUTMEG.CAM.ARTIMI.COM>
Hi Dave,
> There's this line in tc_gen_reloc for several targets:
> [snip]
> which is fired by this test case (stripped down from the
> sort of jump table sequences gcc produces):
The first thing to do is to submit this test as an addition to the GAS
testsuite. The assembler should definitely cope with such code
gracefully, rather than triggering an internal assert.
> To sum it up, the problem seems to me to be that fixup_segment does
> something broken, by setting the fx_pcrel flag without adjusting the
> fx_r_type to correspond to a pc-relative reloc type.
> But maybe it simply shouldn't be trying to make the fixup pc
> relative at all when the sum and difference symbols come from
> different sections?
Yes - I think that this is the right approach. For example please try
the patch below and let me know what you think.
Cheers
Nick
gas/ChangeLog
2004-03-03 Nick Clifton <nickc@redhat.com>
* write.c (fixup_segment): Do not convert a fixup to be
pc-relative if it involves two symbols in different sections.
Index: gas/write.c
===================================================================
RCS file: /cvs/src/src/gas/write.c,v
retrieving revision 1.76
diff -c -3 -p -r1.76 write.c
*** gas/write.c 6 Dec 2003 16:16:51 -0000 1.76
--- gas/write.c 3 Mar 2004 12:53:05 -0000
*************** fixup_segment (fixS *fixP, segT this_seg
*** 2614,2619 ****
--- 2614,2624 ----
fixP->fx_subsy = NULL;
}
else if (sub_symbol_segment == this_segment
+ /* If the fixup references another symbol, make
+ sure that it is in this section as well, as
+ otherwise it cannot be made PC-relative. */
+ && (fixP->fx_addsy == NULL
+ || S_GET_SEGMENT (fixP->fx_addsy) == this_segment)
&& !TC_FORCE_RELOCATION_SUB_LOCAL (fixP))
{
add_number -= S_GET_VALUE (fixP->fx_subsy);