This is the mail archive of the binutils@sources.redhat.com mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: Another relocation problem - and patch


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)


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]