This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
PATCH: PR gas/10740: Intel syntax far jumps broken
- From: "H.J. Lu" <hongjiu dot lu at intel dot com>
- To: binutils at sources dot redhat dot com
- Date: Tue, 13 Oct 2009 09:21:45 -0700
- Subject: PATCH: PR gas/10740: Intel syntax far jumps broken
- Reply-to: "H.J. Lu" <hjl dot tools at gmail dot com>
Hi,
I am checking in this patch to restore Intel syntax far jumps.
H.J.
---
gas/
2009-10-13 H.J. Lu <hongjiu.lu@intel.com>
PR gas/10740
* config/tc-i386-intel.c (i386_intel_operand): Handle call
and jump with 2 immediate operands.
* config/tc-i386.c (i386_finalize_immediate): Don't generate
error message if operand string is NULL.
gas/testsuite/
2009-10-13 H.J. Lu <hongjiu.lu@intel.com>
PR gas/10740
* gas/i386/jump.s: Add new tests.
* gas/i386/jump16.s: Likewise.
* gas/i386/jump.d: Updated.
* gas/i386/jump16.d: Likewise.
diff --git a/gas/config/tc-i386-intel.c b/gas/config/tc-i386-intel.c
index 5d5e0c1..df749b8 100644
--- a/gas/config/tc-i386-intel.c
+++ b/gas/config/tc-i386-intel.c
@@ -721,6 +721,51 @@ i386_intel_operand (char *operand_string, int got_a_float)
if (i.mem_operands
>= 2 - !current_templates->start->opcode_modifier.isstring)
{
+ /* Handle
+
+ call 0x9090,0x90909090
+ lcall 0x9090,0x90909090
+ jmp 0x9090,0x90909090
+ ljmp 0x9090,0x90909090
+ */
+
+ if ((current_templates->start->opcode_modifier.jumpintersegment
+ || current_templates->start->opcode_modifier.jumpdword
+ || current_templates->start->opcode_modifier.jump)
+ && this_operand == 1
+ && intel_state.seg == NULL
+ && i.mem_operands == 1
+ && i.disp_operands == 1
+ && intel_state.op_modifier == O_absent)
+ {
+ /* Try to process the first operand as immediate, */
+ this_operand = 0;
+ if (i386_finalize_immediate (exp_seg, i.op[0].imms,
+ intel_state.reloc_types,
+ NULL))
+ {
+ this_operand = 1;
+ expP = &im_expressions[0];
+ i.op[this_operand].imms = expP;
+ *expP = exp;
+
+ /* Try to process the second operand as immediate, */
+ if (i386_finalize_immediate (exp_seg, expP,
+ intel_state.reloc_types,
+ NULL))
+ {
+ i.mem_operands = 0;
+ i.disp_operands = 0;
+ i.imm_operands = 2;
+ i.types[0].bitfield.mem = 0;
+ i.types[0].bitfield.disp16 = 0;
+ i.types[0].bitfield.disp32 = 0;
+ i.types[0].bitfield.disp32s = 0;
+ return 1;
+ }
+ }
+ }
+
as_bad (_("too many memory references for `%s'"),
current_templates->start->name);
return 0;
diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c
index 5c288ea..54edb1b 100644
--- a/gas/config/tc-i386.c
+++ b/gas/config/tc-i386.c
@@ -6287,8 +6287,9 @@ i386_finalize_immediate (segT exp_seg ATTRIBUTE_UNUSED, expressionS *exp,
{
if (exp->X_op == O_absent || exp->X_op == O_illegal || exp->X_op == O_big)
{
- as_bad (_("missing or invalid immediate expression `%s'"),
- imm_start);
+ if (imm_start)
+ as_bad (_("missing or invalid immediate expression `%s'"),
+ imm_start);
return 0;
}
else if (exp->X_op == O_constant)
@@ -6316,7 +6317,8 @@ i386_finalize_immediate (segT exp_seg ATTRIBUTE_UNUSED, expressionS *exp,
#endif
else if (!intel_syntax && exp->X_op == O_register)
{
- as_bad (_("illegal immediate register operand %s"), imm_start);
+ if (imm_start)
+ as_bad (_("illegal immediate register operand %s"), imm_start);
return 0;
}
else
diff --git a/gas/testsuite/gas/i386/jump.d b/gas/testsuite/gas/i386/jump.d
index 0802785..e53f09d 100644
--- a/gas/testsuite/gas/i386/jump.d
+++ b/gas/testsuite/gas/i386/jump.d
@@ -36,4 +36,20 @@ Disassembly of section .text:
[ ]*[a-f0-9]+: 90 nop
[ ]*[a-f0-9]+: eb 00 jmp (0x)?7e( <.text(\+0x7e)?>)?
[ ]*[a-f0-9]+: 90 nop
+[ ]*[a-f0-9]+: 9a 90 90 90 90 90 90 lcall \$0x9090,\$0x90909090
+[ ]*[a-f0-9]+: 9a 90 90 90 90 90 90 lcall \$0x9090,\$0x90909090
+[ ]*[a-f0-9]+: 9a 00 00 00 00 90 90 lcall \$0x9090,\$0x0 8e: (R_386_)?(dir)?32 xxx
+[ ]*[a-f0-9]+: 9a 00 00 00 00 90 90 lcall \$0x9090,\$0x0 95: (R_386_)?(dir)?32 xxx
+[ ]*[a-f0-9]+: 9a 90 90 90 90 90 90 lcall \$0x9090,\$0x90909090
+[ ]*[a-f0-9]+: 9a 90 90 90 90 90 90 lcall \$0x9090,\$0x90909090
+[ ]*[a-f0-9]+: 9a 00 00 00 00 90 90 lcall \$0x9090,\$0x0 aa: (R_386_)?(dir)?32 xxx
+[ ]*[a-f0-9]+: 9a 00 00 00 00 90 90 lcall \$0x9090,\$0x0 b1: (R_386_)?(dir)?32 xxx
+[ ]*[a-f0-9]+: ea 90 90 90 90 90 90 ljmp \$0x9090,\$0x90909090
+[ ]*[a-f0-9]+: ea 90 90 90 90 90 90 ljmp \$0x9090,\$0x90909090
+[ ]*[a-f0-9]+: ea 00 00 00 00 90 90 ljmp \$0x9090,\$0x0 c6: (R_386_)?(dir)?32 xxx
+[ ]*[a-f0-9]+: ea 00 00 00 00 90 90 ljmp \$0x9090,\$0x0 cd: (R_386_)?(dir)?32 xxx
+[ ]*[a-f0-9]+: ea 90 90 90 90 90 90 ljmp \$0x9090,\$0x90909090
+[ ]*[a-f0-9]+: ea 90 90 90 90 90 90 ljmp \$0x9090,\$0x90909090
+[ ]*[a-f0-9]+: ea 00 00 00 00 90 90 ljmp \$0x9090,\$0x0 e2: (R_386_)?(dir)?32 xxx
+[ ]*[a-f0-9]+: ea 00 00 00 00 90 90 ljmp \$0x9090,\$0x0 e9: (R_386_)?(dir)?32 xxx
#pass
diff --git a/gas/testsuite/gas/i386/jump.s b/gas/testsuite/gas/i386/jump.s
index 71693ce..8ce459f 100644
--- a/gas/testsuite/gas/i386/jump.s
+++ b/gas/testsuite/gas/i386/jump.s
@@ -35,3 +35,20 @@
nop
jmp .+2
nop
+
+ lcall 0x9090,0x90909090
+ lcall 0x9090:0x90909090
+ lcall 0x9090,xxx
+ lcall 0x9090:xxx
+ call 0x9090,0x90909090
+ call 0x9090:0x90909090
+ call 0x9090,xxx
+ call 0x9090:xxx
+ ljmp 0x9090,0x90909090
+ ljmp 0x9090:0x90909090
+ ljmp 0x9090,xxx
+ ljmp 0x9090:xxx
+ jmp 0x9090,0x90909090
+ jmp 0x9090:0x90909090
+ jmp 0x9090,xxx
+ jmp 0x9090:xxx
diff --git a/gas/testsuite/gas/i386/jump16.d b/gas/testsuite/gas/i386/jump16.d
index db5d44a..c91c8ae 100644
--- a/gas/testsuite/gas/i386/jump16.d
+++ b/gas/testsuite/gas/i386/jump16.d
@@ -7,48 +7,64 @@ Disassembly of section .text:
0+ <.text>:
[ ]*[a-f0-9]+: eb fe jmp (0x0|0 <.text>)
-[ ]*[a-f0-9]+: e9 fe ff jmp 0x3 3: R_386_PC16 xxx
-[ ]*[a-f0-9]+: ff 26 00 00 jmp \*0x0 7: R_386_16 xxx
+[ ]*[a-f0-9]+: e9 f(e|b) ff jmp (0x3|0 <.text>) 3: (R_386_PC)?(DISP)?16 xxx
+[ ]*[a-f0-9]+: ff 26 00 00 jmp \*0x0 7: (R_386_)?16 xxx
[ ]*[a-f0-9]+: 66 ff e7 jmpl \*%edi
[ ]*[a-f0-9]+: 67 ff 27 addr32 jmp \*\(%edi\)
[ ]*[a-f0-9]+: 67 ff af 00 00 00 00 addr32 ljmp \*0x0\(%edi\) 12: (R_386_)?(dir)?32 xxx
-[ ]*[a-f0-9]+: ff 2e 00 00 ljmp \*0x0 18: R_386_16 xxx
-[ ]*[a-f0-9]+: ea 00 00 34 12 ljmp \$0x1234,\$0x0 1b: R_386_16 xxx
-[ ]*[a-f0-9]+: 66 e8 db ff ff ff calll 0x0
-[ ]*[a-f0-9]+: 66 e8 fc ff ff ff calll 0x27 27: (R_386_PC)?(DISP)?32 xxx
-[ ]*[a-f0-9]+: 66 ff 16 00 00 calll \*0x0 2e: R_386_16 xxx
+[ ]*[a-f0-9]+: ff 2e 00 00 ljmp \*0x0 18: (R_386_)?16 xxx
+[ ]*[a-f0-9]+: ea 00 00 34 12 ljmp \$0x1234,\$0x0 1b: (R_386_)?16 xxx
+[ ]*[a-f0-9]+: 66 e8 db ff ff ff calll (0x0|0 <.text>)
+[ ]*[a-f0-9]+: 66 e8 (fc|d5) ff ff ff calll (0x27|0 <.text>) 27: (R_386_PC)?(DISP)?32 xxx
+[ ]*[a-f0-9]+: 66 ff 16 00 00 calll \*0x0 2e: (R_386_)?16 xxx
[ ]*[a-f0-9]+: 66 ff d7 calll \*%edi
[ ]*[a-f0-9]+: 67 66 ff 17 addr32 calll \*\(%edi\)
[ ]*[a-f0-9]+: 67 66 ff 9f 00 00 00 00 addr32 lcalll \*0x0\(%edi\) 3b: (R_386_)?(dir)?32 xxx
-[ ]*[a-f0-9]+: 66 ff 1e 00 00 lcalll \*0x0 42: R_386_16 xxx
+[ ]*[a-f0-9]+: 66 ff 1e 00 00 lcalll \*0x0 42: (R_386_)?16 xxx
[ ]*[a-f0-9]+: 66 9a 00 00 00 00 34 12 lcalll \$0x1234,\$0x0 46: (R_386_)?(dir)?32 xxx
[ ]*[a-f0-9]+: eb b2 jmp (0x0|0 <.text>)
-[ ]*[a-f0-9]+: ff 26 00 00 jmp \*0x0 50: R_386_16 xxx
+[ ]*[a-f0-9]+: ff 26 00 00 jmp \*0x0 50: (R_386_)?16 xxx
[ ]*[a-f0-9]+: ff e7 jmp \*%di
[ ]*[a-f0-9]+: ff 25 jmp \*\(%di\)
-[ ]*[a-f0-9]+: ff ad 00 00 ljmp \*0x0\(%di\) 58: R_386_16 xxx
-[ ]*[a-f0-9]+: 66 ff ad 00 00 ljmpl \*0x0\(%di\) 5d: R_386_16 xxx
-[ ]*[a-f0-9]+: ff 2e 00 00 ljmp \*0x0 61: R_386_16 xxx
-[ ]*[a-f0-9]+: 66 ff 2e 00 00 ljmpl \*0x0 66: R_386_16 xxx
-[ ]*[a-f0-9]+: ea 00 00 34 12 ljmp \$0x1234,\$0x0 69: R_386_16 xxx
+[ ]*[a-f0-9]+: ff ad 00 00 ljmp \*0x0\(%di\) 58: (R_386_)?16 xxx
+[ ]*[a-f0-9]+: 66 ff ad 00 00 ljmpl \*0x0\(%di\) 5d: (R_386_)?16 xxx
+[ ]*[a-f0-9]+: ff 2e 00 00 ljmp \*0x0 61: (R_386_)?16 xxx
+[ ]*[a-f0-9]+: 66 ff 2e 00 00 ljmpl \*0x0 66: (R_386_)?16 xxx
+[ ]*[a-f0-9]+: ea 00 00 34 12 ljmp \$0x1234,\$0x0 69: (R_386_)?16 xxx
[ ]*[a-f0-9]+: e8 90 ff call (0x0|0 <.text>)
-[ ]*[a-f0-9]+: e8 fe ff call 0x71 71: R_386_PC16 xxx
-[ ]*[a-f0-9]+: ff 16 00 00 call \*0x0 75: R_386_16 xxx
+[ ]*[a-f0-9]+: e8 (fe|8d) ff call (0x71|0 <.text>) 71: (R_386_PC)?(DISP)?16 xxx
+[ ]*[a-f0-9]+: ff 16 00 00 call \*0x0 75: (R_386_)?16 xxx
[ ]*[a-f0-9]+: ff d7 call \*%di
[ ]*[a-f0-9]+: ff 15 call \*\(%di\)
-[ ]*[a-f0-9]+: ff 9d 00 00 lcall \*0x0\(%di\) 7d: R_386_16 xxx
-[ ]*[a-f0-9]+: 66 ff 9d 00 00 lcalll \*0x0\(%di\) 82: R_386_16 xxx
-[ ]*[a-f0-9]+: ff 1e 00 00 lcall \*0x0 86: R_386_16 xxx
-[ ]*[a-f0-9]+: 66 ff 1e 00 00 lcalll \*0x0 8b: R_386_16 xxx
-[ ]*[a-f0-9]+: 9a 00 00 34 12 lcall \$0x1234,\$0x0 8e: R_386_16 xxx
+[ ]*[a-f0-9]+: ff 9d 00 00 lcall \*0x0\(%di\) 7d: (R_386_)?16 xxx
+[ ]*[a-f0-9]+: 66 ff 9d 00 00 lcalll \*0x0\(%di\) 82: (R_386_)?16 xxx
+[ ]*[a-f0-9]+: ff 1e 00 00 lcall \*0x0 86: (R_386_)?16 xxx
+[ ]*[a-f0-9]+: 66 ff 1e 00 00 lcalll \*0x0 8b: (R_386_)?16 xxx
+[ ]*[a-f0-9]+: 9a 00 00 34 12 lcall \$0x1234,\$0x0 8e: (R_386_)?16 xxx
[ ]*[a-f0-9]+: ff 17 call \*\(%bx\)
[ ]*[a-f0-9]+: ff 1f lcall \*\(%bx\)
[ ]*[a-f0-9]+: 66 ff 1f lcalll \*\(%bx\)
[ ]*[a-f0-9]+: ff 27 jmp \*\(%bx\)
[ ]*[a-f0-9]+: ff 2f ljmp \*\(%bx\)
[ ]*[a-f0-9]+: 66 ff 2f ljmpl \*\(%bx\)
-[ ]*[a-f0-9]+: eb 00 jmp 0xa2
+[ ]*[a-f0-9]+: eb 00 jmp (0xa2|a2 <.text\+0xa2>)
[ ]*[a-f0-9]+: 90 nop
-[ ]*[a-f0-9]+: eb 00 jmp 0xa5
+[ ]*[a-f0-9]+: eb 00 jmp (0xa5|a5 <.text\+0xa5>)
[ ]*[a-f0-9]+: 90 nop
+[ ]*[a-f0-9]+: 9a 10 10 90 90 lcall \$0x9090,\$0x1010
+[ ]*[a-f0-9]+: 9a 10 10 90 90 lcall \$0x9090,\$0x1010
+[ ]*[a-f0-9]+: 9a 00 00 90 90 lcall \$0x9090,\$0x0 b1: (R_386_)?16 xxx
+[ ]*[a-f0-9]+: 9a 00 00 90 90 lcall \$0x9090,\$0x0 b6: (R_386_)?16 xxx
+[ ]*[a-f0-9]+: 9a 10 10 90 90 lcall \$0x9090,\$0x1010
+[ ]*[a-f0-9]+: 9a 10 10 90 90 lcall \$0x9090,\$0x1010
+[ ]*[a-f0-9]+: 9a 00 00 90 90 lcall \$0x9090,\$0x0 c5: (R_386_)?16 xxx
+[ ]*[a-f0-9]+: 9a 00 00 90 90 lcall \$0x9090,\$0x0 ca: (R_386_)?16 xxx
+[ ]*[a-f0-9]+: ea 10 10 90 90 ljmp \$0x9090,\$0x1010
+[ ]*[a-f0-9]+: ea 10 10 90 90 ljmp \$0x9090,\$0x1010
+[ ]*[a-f0-9]+: ea 00 00 90 90 ljmp \$0x9090,\$0x0 d9: (R_386_)?16 xxx
+[ ]*[a-f0-9]+: ea 00 00 90 90 ljmp \$0x9090,\$0x0 de: (R_386_)?16 xxx
+[ ]*[a-f0-9]+: ea 10 10 90 90 ljmp \$0x9090,\$0x1010
+[ ]*[a-f0-9]+: ea 10 10 90 90 ljmp \$0x9090,\$0x1010
+[ ]*[a-f0-9]+: ea 00 00 90 90 ljmp \$0x9090,\$0x0 ed: (R_386_)?16 xxx
+[ ]*[a-f0-9]+: ea 00 00 90 90 ljmp \$0x9090,\$0x0 f2: (R_386_)?16 xxx
#pass
diff --git a/gas/testsuite/gas/i386/jump16.s b/gas/testsuite/gas/i386/jump16.s
index 7ad9c6b..f8bc0ea 100644
--- a/gas/testsuite/gas/i386/jump16.s
+++ b/gas/testsuite/gas/i386/jump16.s
@@ -54,3 +54,20 @@
nop
jmp .+2
nop
+
+ lcall 0x9090,0x1010
+ lcall 0x9090:0x1010
+ lcall 0x9090,xxx
+ lcall 0x9090:xxx
+ call 0x9090,0x1010
+ call 0x9090:0x1010
+ call 0x9090,xxx
+ call 0x9090:xxx
+ ljmp 0x9090,0x1010
+ ljmp 0x9090:0x1010
+ ljmp 0x9090,xxx
+ ljmp 0x9090:xxx
+ jmp 0x9090,0x1010
+ jmp 0x9090:0x1010
+ jmp 0x9090,xxx
+ jmp 0x9090:xxx