Another relocation problem - and patch
Alan Modra
alan@linuxcare.com.au
Thu Mar 8 04:55:00 GMT 2001
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)
More information about the Binutils
mailing list