i386: Allow non-absolute segment values for lcall/ljmp
authorT.K. Chia <u1049321969@caramail.com>
Mon, 5 Oct 2020 12:46:23 +0000 (05:46 -0700)
committerH.J. Lu <hjl.tools@gmail.com>
Mon, 5 Oct 2020 12:58:33 +0000 (05:58 -0700)
Allow an unresolved or non-absolute symbol as the segment operand of an
immediate far jump (`ljmp SEG, OFF') or far call (`lcall SEG, OFF').

gas/

2020-10-05  T.K. Chia  <u1049321969@caramail.com>

PR gas/26694
* NEWS: Updated for i386 lcall and ljmp change.
* config/tc-i386.c (output_interseg_jump): Allow non-absolute
segment operand for immediate lcall and ljmp.
* testsuite/gas/i386/jump.d,
* testsuite/gas/i386/jump.s,
* testsuite/gas/i386/jump16.d,
* testsuite/gas/i386/jump16.e,
* testsuite/gas/i386/jump16.s: Add tests for non-absolute
segment operand for immediate ljmp.

ld/

2020-10-05  T.K. Chia  <u1049321969@caramail.com>

PR gas/26694
* testsuite/ld-i386/ljmp.s,
* testsuite/ld-i386/ljmp1.d,
* testsuite/ld-i386/ljmp1.s,
* testsuite/ld-i386/ljmp2.d,
* testsuite/ld-i386/ljmp2.s,
* testsuite/ld-x86-64/ljmp1.d,
* testsuite/ld-x86-64/ljmp2.d: New testcases.
* testsuite/ld-i386/i386.exp,
* testsuite/ld-x86-64/x86-64.exp: Run them.

18 files changed:
gas/ChangeLog
gas/NEWS
gas/config/tc-i386.c
gas/testsuite/gas/i386/jump.d
gas/testsuite/gas/i386/jump.s
gas/testsuite/gas/i386/jump16.d
gas/testsuite/gas/i386/jump16.e
gas/testsuite/gas/i386/jump16.s
ld/ChangeLog
ld/testsuite/ld-i386/i386.exp
ld/testsuite/ld-i386/ljmp.s [new file with mode: 0644]
ld/testsuite/ld-i386/ljmp1.d [new file with mode: 0644]
ld/testsuite/ld-i386/ljmp1.s [new file with mode: 0644]
ld/testsuite/ld-i386/ljmp2.d [new file with mode: 0644]
ld/testsuite/ld-i386/ljmp2.s [new file with mode: 0644]
ld/testsuite/ld-x86-64/ljmp1.d [new file with mode: 0644]
ld/testsuite/ld-x86-64/ljmp2.d [new file with mode: 0644]
ld/testsuite/ld-x86-64/x86-64.exp

index bd0834016b95e9713e51e4a895858fa0a4ffba61..b27e08bccb0266fde40a9879ebc6b89896ae7101 100644 (file)
@@ -1,3 +1,16 @@
+2020-10-05  T.K. Chia  <u1049321969@caramail.com>
+
+       PR gas/26694
+       * NEWS: Updated for i386 lcall and ljmp change.
+       * config/tc-i386.c (output_interseg_jump): Allow non-absolute
+       segment operand for immediate lcall and ljmp.
+       * testsuite/gas/i386/jump.d,
+       * testsuite/gas/i386/jump.s,
+       * testsuite/gas/i386/jump16.d,
+       * testsuite/gas/i386/jump16.e,
+       * testsuite/gas/i386/jump16.s: Add tests for non-absolute
+       segment operand for immediate ljmp.
+
 2020-10-05  H.J. Lu  <hongjiu.lu@intel.com>
 
        PR binutils/26704
index 8f83beb15b2fa6675e38b9b472e81a3d7c7335ed..1107725ea669afa2e3c2eb1c09ff1280a4cbf7da 100644 (file)
--- a/gas/NEWS
+++ b/gas/NEWS
@@ -1,4 +1,7 @@
 -*- text -*-
+
+* Support non-absolute segment values for i386 lcall and ljmp.
+
 * When setting the link order attribute of ELF sections, it is now possible to
   use a numeric section index instead of symbol name.
 
index 8f798479baa1cd138482d1ee3c96926b7468ceaf..f3eaba6231e95f7c7711dbc2bace1b08bd9c5bca 100644 (file)
@@ -8776,10 +8776,13 @@ output_interseg_jump (void)
   else
     fix_new_exp (frag_now, p - frag_now->fr_literal, size,
                 i.op[1].imms, 0, reloc (size, 0, 0, i.reloc[1]));
-  if (i.op[0].imms->X_op != O_constant)
-    as_bad (_("can't handle non absolute segment in `%s'"),
-           i.tm.name);
-  md_number_to_chars (p + size, (valueT) i.op[0].imms->X_add_number, 2);
+
+  p += size;
+  if (i.op[0].imms->X_op == O_constant)
+    md_number_to_chars (p, (valueT) i.op[0].imms->X_add_number, 2);
+  else
+    fix_new_exp (frag_now, p - frag_now->fr_literal, 2,
+                i.op[0].imms, 0, reloc (2, 0, 0, i.reloc[0]));
 }
 
 #if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
index 6dcececc1f2d0545e27ed39ff3e947ae5f52e080..72e399599c789ef1db0c7d8dce085daf753c517e 100644 (file)
@@ -54,4 +54,16 @@ Disassembly of section .text:
 [      ]*[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[  ]+[a-f0-9]+: (R_386_)?(dir)?32  xxx
 [      ]*[a-f0-9]+:    ea 00 00 00 00 90 90    ljmp   \$0x9090,\$0x0[  ]+[a-f0-9]+: (R_386_)?(dir)?32  xxx
+[      ]*[a-f0-9]+:    ea 90 90 90 90 00 00    ljmp   \$0x0,\$0x90909090[      ]+[a-f0-9]+: (R_386_)?(dir)?16  yyy
+[      ]*[a-f0-9]+:    ea 90 90 90 90 00 00    ljmp   \$0x0,\$0x90909090[      ]+[a-f0-9]+: (R_386_)?(dir)?16  yyy
+[      ]*[a-f0-9]+:    ea 00 00 00 00 00 00    ljmp   \$0x0,\$0x0[     ]+[a-f0-9]+: (R_386_)?(dir)?32  xxx
+[      ]+[a-f0-9]+: (R_386_)?(dir)?16  yyy
+[      ]*[a-f0-9]+:    ea 00 00 00 00 00 00    ljmp   \$0x0,\$0x0[     ]+[a-f0-9]+: (R_386_)?(dir)?32  xxx
+[      ]+[a-f0-9]+: (R_386_)?(dir)?16  yyy
+[      ]*[a-f0-9]+:    ea 90 90 90 90 00 00    ljmp   \$0x0,\$0x90909090[      ]+[a-f0-9]+: (R_386_)?(dir)?16  yyy
+[      ]*[a-f0-9]+:    ea 90 90 90 90 00 00    ljmp   \$0x0,\$0x90909090[      ]+[a-f0-9]+: (R_386_)?(dir)?16  yyy
+[      ]*[a-f0-9]+:    ea 00 00 00 00 00 00    ljmp   \$0x0,\$0x0[     ]+[a-f0-9]+: (R_386_)?(dir)?32  xxx
+[      ]+[a-f0-9]+: (R_386_)?(dir)?16  yyy
+[      ]*[a-f0-9]+:    ea 00 00 00 00 00 00    ljmp   \$0x0,\$0x0[     ]+[a-f0-9]+: (R_386_)?(dir)?32  xxx
+[      ]+[a-f0-9]+: (R_386_)?(dir)?16  yyy
 #pass
index eec3f0ab6393c70dba010bcf38eab06cf1f1cf8a..5efe43882a8ad6e449228f7bd0e1999ce4715389 100644 (file)
@@ -1,6 +1,7 @@
 .psize 0
 .text
 .extern xxx
+.extern yyy
 
 1:     jmp     1b
        jmp     xxx
        jmp     0x9090:0x90909090
        jmp     0x9090,xxx
        jmp     0x9090:xxx
+       ljmp    yyy,0x90909090
+       ljmp    yyy:0x90909090
+       ljmp    yyy,xxx
+       ljmp    yyy:xxx
+       jmp     yyy,0x90909090
+       jmp     yyy:0x90909090
+       jmp     yyy,xxx
+       jmp     yyy:xxx
index afb1c377e73de14b568ad256f18e618456ff4bc7..df4facc10c07011879aae223c1037b4b000321c6 100644 (file)
@@ -68,6 +68,18 @@ Disassembly of section .text:
 [      ]*[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
+[      ]*[a-f0-9]+:    ea 10 10 00 00          ljmp   \$0x0,\$0x1010   f9: (R_386_)?16 yyy
+[      ]*[a-f0-9]+:    ea 10 10 00 00          ljmp   \$0x0,\$0x1010   fe: (R_386_)?16 yyy
+[      ]*[a-f0-9]+:    ea 00 00 00 00          ljmp   \$0x0,\$0x0      101: (R_386_)?16        xxx
+[      ]+103: (R_386_)?16      yyy
+[      ]*[a-f0-9]+:    ea 00 00 00 00          ljmp   \$0x0,\$0x0      106: (R_386_)?16        xxx
+[      ]+108: (R_386_)?16      yyy
+[      ]*[a-f0-9]+:    ea 10 10 00 00          ljmp   \$0x0,\$0x1010   10d: (R_386_)?16        yyy
+[      ]*[a-f0-9]+:    ea 10 10 00 00          ljmp   \$0x0,\$0x1010   112: (R_386_)?16        yyy
+[      ]*[a-f0-9]+:    ea 00 00 00 00          ljmp   \$0x0,\$0x0      115: (R_386_)?16        xxx
+[      ]+117: (R_386_)?16      yyy
+[      ]*[a-f0-9]+:    ea 00 00 00 00          ljmp   \$0x0,\$0x0      11a: (R_386_)?16        xxx
+[      ]+11c: (R_386_)?16      yyy
 [      ]*[a-f0-9]+:    cf                      iret   
 [      ]*[a-f0-9]+:    cf                      iret   
 [      ]*[a-f0-9]+:    66 cf                   iretl  
index 2ad7ea056b61ae59a843f845323f637c4840b26e..aa5c5aad6536cb48ecea0ea76b49ceb9c8f2b4a3 100644 (file)
@@ -1,3 +1,3 @@
 .*: Assembler messages:
-.*:77: Warning: generating 16-bit `iret' for .code16gcc directive
-.*:88: Warning: generating 16-bit `iret' for .code16gcc directive
+.*:86: Warning: generating 16-bit `iret' for .code16gcc directive
+.*:97: Warning: generating 16-bit `iret' for .code16gcc directive
index fb9e830c52b532fed1fe5ae46d70c8049bad63ac..42d150ff978e51105dfa27bfd64ab0f1633184fd 100644 (file)
@@ -1,6 +1,7 @@
 .psize 0
 .text
 .extern xxx
+.extern yyy
 
 .code16gcc
 1:     jmp     1b
        jmp     0x9090:0x1010
        jmp     0x9090,xxx
        jmp     0x9090:xxx
+       ljmp    yyy,0x1010
+       ljmp    yyy:0x1010
+       ljmp    yyy,xxx
+       ljmp    yyy:xxx
+       jmp     yyy,0x1010
+       jmp     yyy:0x1010
+       jmp     yyy,xxx
+       jmp     yyy:xxx
 
        .att_syntax
 .code16gcc
index 0d5953a11b76d9e2dd99d0379bbefcbeae41e108..c259b09c74a553ad35c993499a7b5cf7090f5395 100644 (file)
@@ -1,3 +1,16 @@
+2020-10-05  T.K. Chia  <u1049321969@caramail.com>
+
+       PR gas/26694
+       * testsuite/ld-i386/ljmp.s,
+       * testsuite/ld-i386/ljmp1.d,
+       * testsuite/ld-i386/ljmp1.s,
+       * testsuite/ld-i386/ljmp2.d,
+       * testsuite/ld-i386/ljmp2.s,
+       * testsuite/ld-x86-64/ljmp1.d,
+       * testsuite/ld-x86-64/ljmp2.d: New testcases.
+       * testsuite/ld-i386/i386.exp,
+       * testsuite/ld-x86-64/x86-64.exp: Run them.
+
 2020-10-05  Nick Clifton  <nickc@redhat.com>
 
        * lexsup.c (parse_args): Generate an error or warning message when
index 164c099cbbb90fb28c10c28a6213959ae14fabdb..d0b8ed77bd1747fccd953e265df42cc71a7b68e3 100644 (file)
@@ -342,6 +342,8 @@ run_dump_test "call3g"
 run_dump_test "call3h"
 run_dump_test "jmp1"
 run_dump_test "jmp2"
+run_dump_test "ljmp1"
+run_dump_test "ljmp2"
 run_dump_test "load1"
 run_dump_test "load2"
 run_dump_test "load3"
diff --git a/ld/testsuite/ld-i386/ljmp.s b/ld/testsuite/ld-i386/ljmp.s
new file mode 100644 (file)
index 0000000..4b27a25
--- /dev/null
@@ -0,0 +1,10 @@
+ .global seg1
+ .equiv seg1, 8
+ .global seg2
+ .equiv seg2, 0x18
+       /* Bad IA-16 segment values --- will overflow R_386_16 (and
+          R_X86_64_16). */
+ .global seg3
+ .equiv seg3, 0x10000
+ .global seg4
+ .equiv seg4, -0x10001
diff --git a/ld/testsuite/ld-i386/ljmp1.d b/ld/testsuite/ld-i386/ljmp1.d
new file mode 100644 (file)
index 0000000..9708ad0
--- /dev/null
@@ -0,0 +1,18 @@
+#name: Absolute non-overflowing relocs in ljmp segments
+#as: --32
+#source: ljmp1.s
+#source: ljmp.s
+#ld: -melf_i386 -z noseparate-code
+#objdump: -dw
+
+.*: +file format .*
+
+
+Disassembly of section .text:
+
+0+[a-f0-9]+ <_start>:
+ +[a-f0-9]+:   0f 22 c0                mov    %eax,%cr0
+ +[a-f0-9]+:   ea ([0-9a-f]{2} ){4}08 00       ljmp   \$0x8,\$0x[a-f0-9]+
+
+0+[a-f0-9]+ <foo>:
+ +[a-f0-9]+:   66 ea 00 00 18 00       ljmpw  \$0x18,\$0x0
diff --git a/ld/testsuite/ld-i386/ljmp1.s b/ld/testsuite/ld-i386/ljmp1.s
new file mode 100644 (file)
index 0000000..3ae6882
--- /dev/null
@@ -0,0 +1,9 @@
+ .text
+.code32
+ .global _start
+_start:
+       movl    %eax, %cr0
+       ljmp    $seg1, $foo
+foo:
+       ljmpw   $seg2, $0
+ .p2align 4,0x90
diff --git a/ld/testsuite/ld-i386/ljmp2.d b/ld/testsuite/ld-i386/ljmp2.d
new file mode 100644 (file)
index 0000000..b599cf9
--- /dev/null
@@ -0,0 +1,7 @@
+#name: ljmp segment value overflow
+#as: --32
+#source: ljmp2.s
+#source: ljmp.s
+#ld: -melf_i386 -z noseparate-code
+#error: .*relocation truncated to fit: R_386_16 .*
+#error: .*relocation truncated to fit: R_386_16 .*
diff --git a/ld/testsuite/ld-i386/ljmp2.s b/ld/testsuite/ld-i386/ljmp2.s
new file mode 100644 (file)
index 0000000..f6a4227
--- /dev/null
@@ -0,0 +1,9 @@
+ .text
+.code32
+ .global _start
+_start:
+       movl    %eax, %cr0
+       ljmp    $seg3, $foo
+foo:
+       ljmpw   $seg4, $0
+ .p2align 4,0x90
diff --git a/ld/testsuite/ld-x86-64/ljmp1.d b/ld/testsuite/ld-x86-64/ljmp1.d
new file mode 100644 (file)
index 0000000..eb378fb
--- /dev/null
@@ -0,0 +1,17 @@
+#name: Absolute non-overflowing relocs in ljmp segments
+#source: ../ld-i386/ljmp1.s
+#source: ../ld-i386/ljmp.s
+#ld: -z noseparate-code
+#objdump: -Mi386 -dw
+
+.*: +file format .*
+
+
+Disassembly of section .text:
+
+0+[a-f0-9]+ <_start>:
+ +[a-f0-9]+:   0f 22 c0                mov    %eax,%cr0
+ +[a-f0-9]+:   ea ([0-9a-f]{2} ){4}08 00       ljmp   \$0x8,\$0x[a-f0-9]+
+
+0+[a-f0-9]+ <foo>:
+ +[a-f0-9]+:   66 ea 00 00 18 00       ljmpw  \$0x18,\$0x0
diff --git a/ld/testsuite/ld-x86-64/ljmp2.d b/ld/testsuite/ld-x86-64/ljmp2.d
new file mode 100644 (file)
index 0000000..b358182
--- /dev/null
@@ -0,0 +1,6 @@
+#name: ljmp segment value overflow
+#source: ../ld-i386/ljmp2.s
+#source: ../ld-i386/ljmp.s
+#ld: -z noseparate-code
+#error: .*relocation truncated to fit: R_X86_64_16 .*
+#error: .*relocation truncated to fit: R_X86_64_16 .*
index 3c0b4347d023e2572a81d0e2a598453e289c041a..2c2551fd62e7f24336e40c93c85a35963b2818e0 100644 (file)
@@ -519,6 +519,8 @@ run_dump_test "mov2a"
 run_dump_test "mov2b"
 run_dump_test "mov2c"
 run_dump_test "mov2d"
+run_dump_test "ljmp1"
+run_dump_test "ljmp2"
 run_dump_test "load1a"
 run_dump_test "load1b"
 run_dump_test "load1c"