i386: Allow non-absolute segment values for lcall/ljmp

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.
This commit is contained in:
T.K. Chia
2020-10-05 05:46:23 -07:00
committed by H.J. Lu
parent 983d925db6
commit 6d96a5946d
18 changed files with 160 additions and 6 deletions

View 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

View File

@ -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.

View 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)

View 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

View File

@ -1,6 +1,7 @@
.psize 0
.text
.extern xxx
.extern yyy
1: jmp 1b
jmp xxx
@ -54,3 +55,11 @@
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

View 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

View 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

View File

@ -1,6 +1,7 @@
.psize 0
.text
.extern xxx
.extern yyy
.code16gcc
1: jmp 1b
@ -71,6 +72,14 @@
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

View 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

View 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"

View File

@ -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

View File

@ -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

View File

@ -0,0 +1,9 @@
.text
.code32
.global _start
_start:
movl %eax, %cr0
ljmp $seg1, $foo
foo:
ljmpw $seg2, $0
.p2align 4,0x90

View File

@ -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 .*

View File

@ -0,0 +1,9 @@
.text
.code32
.global _start
_start:
movl %eax, %cr0
ljmp $seg3, $foo
foo:
ljmpw $seg4, $0
.p2align 4,0x90

View File

@ -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

View File

@ -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 .*

View 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"