This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Re: [PATCH 1/4] MIPS/GAS: Fix equated symbols in relaxation
"Maciej W. Rozycki" <macro@codesourcery.com> writes:
> On Tue, 27 Jul 2010, Richard Sandiford wrote:
>
>> > Equated symbols (defined with .eqv) are not yet fully resolved by the
>> > time relaxation is made. As a result, if used in a relaxed expression,
>> > they cause a failure as follows:
>> >
>> > branch-self.s:30: Error: attempt to get value of unresolved symbol `fnord'
>> >
>> > The fix is to manually walk the chain of symbols; we handle additive
>> > expressions involving constant (positive or negative) addends here only
>> > like elsewhere.
>> >
>> > 2010-07-26 Maciej W. Rozycki <macro@codesourcery.com>
>> >
>> > gas/
>> > * config/tc-mips.c: Include "struc-symbol.h".
>> > (md_convert_frag): Resolve equated symbols manually.
>>
>> Can you explain in more detail why the equated symbol handling
>> in resolve_symbol_value doesn't do the right thing?
>
> finalize_syms isn't set yet and hence resolve_symbol_value() won't make
> the final resolution of the symbol -- see write_object_file(). We get
> here from relax_seg() which is before finalize_syms is possibly set at the
> earliest. Try to assemble this program:
>
> .text
> .set mips16
> foo:
> .eqv bar, foo
> b bar
>
> to trigger it.
What I really meant (and I should have made it clearer) was: why can't
we simply use the value that resolve_symbol_value gives us? It looks to
me like it should be correct, and is more robust than an out-of-line loop.
The problem with the patch is that it makes us go into an infinite loop for:
.text
.set mips16
.eqv bar, foo
.eqv foo, bar
b bar
Richard
Index: gas/config/tc-mips.c
===================================================================
RCS file: /cvs/src/src/gas/config/tc-mips.c,v
retrieving revision 1.419
diff -u -p -r1.419 tc-mips.c
--- gas/config/tc-mips.c 28 Jun 2010 14:06:57 -0000 1.419
+++ gas/config/tc-mips.c 28 Jul 2010 19:39:34 -0000
@@ -14571,8 +14571,7 @@ md_convert_frag (bfd *abfd ATTRIBUTE_UNU
ext = FALSE;
}
- resolve_symbol_value (fragp->fr_symbol);
- val = S_GET_VALUE (fragp->fr_symbol);
+ val = resolve_symbol_value (fragp->fr_symbol);
if (op->pcrel)
{
addressT addr;