This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
Re: Another relocation problem - and patch
- To: Mikulas Patocka <mikulas at artax dot karlin dot mff dot cuni dot cz>
- Subject: Re: Another relocation problem - and patch
- From: Alan Modra <alan at linuxcare dot com dot au>
- Date: Thu, 8 Mar 2001 23:55:29 +1100 (EST)
- cc: binutils at sources dot redhat dot com
On Tue, 6 Mar 2001, Alan Modra wrote:
> On Mon, 5 Mar 2001, Mikulas Patocka wrote:
>
> > It doesn't use optimal length but at least it doesn't create broken code.
>
> This patch is more or less OK, but I'm currently testing another patch
> to fix the previous problem you reported that happens to handle this case
> as well.
I got sidetracked with paying work. ;-) Here's the patch, which I won't
apply just yet as I'm not completely happy with it.
gas/ChangeLog
* config/tc-i386.c (md_assemble): Handle jumps and calls to an
absolute expression similarly to the way we do for jumps and calls
to a constant.
Alan Modra
--
Linuxcare
testcase:
.text
.extern z
nop
a: nop
b: nop
c=4
jmp a-b # ok
jmp a-c # ok
jmp d-a # ok
jmp a-e # ok
jmp z+5 # ok
jmp z+e # wrong, was bad before patch
jmp a+(d-b) # ok
jmp z+(d-b) # wrong, also bad before patch
d:
e=5
Index: gas/config/tc-i386.c
===================================================================
RCS file: /cvs/src/src/gas/config/tc-i386.c,v
retrieving revision 1.87
diff -u -p -r1.87 tc-i386.c
--- tc-i386.c 2001/02/28 12:49:40 1.87
+++ tc-i386.c 2001/03/06 06:48:10
@@ -2652,13 +2652,25 @@ md_assemble (line)
}
if ((i.tm.opcode_modifier & (Jump | JumpByte | JumpDword))
- && i.op[0].disps->X_op == O_constant)
+ && i.op[0].disps->X_op != O_symbol)
{
- /* Convert "jmp constant" (and "call constant") to a jump (call) to
- the absolute address given by the constant. Since ix86 jumps and
- calls are pc relative, we need to generate a reloc. */
- i.op[0].disps->X_add_symbol = &abs_symbol;
- i.op[0].disps->X_op = O_symbol;
+ if (i.op[0].disps->X_op == O_constant)
+ {
+ /* Convert "jmp constant" (and "call constant") to a jump (call)
+ to the absolute address given by the constant. */
+ i.op[0].disps->X_add_symbol = &abs_symbol;
+ i.op[0].disps->X_op = O_symbol;
+ }
+ else
+ {
+ /* Do the same for more complex expressions. */
+ symbolS *s = make_expr_symbol (i.op[0].disps);
+ s = expr_build_binary (O_add, &abs_symbol, s);
+ i.op[0].disps->X_add_symbol = s;
+ i.op[0].disps->X_op = O_symbol;
+ i.op[0].disps->X_add_number = 0;
+ i.op[0].disps->X_op_symbol = NULL;
+ }
}
if (i.tm.opcode_modifier & Rex64)