From 6d96a5946d1ec76fea79bc36aa95d7d3dd304200 Mon Sep 17 00:00:00 2001 From: "T.K. Chia" Date: Mon, 5 Oct 2020 05:46:23 -0700 Subject: [PATCH] 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 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 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. --- gas/ChangeLog | 13 +++++++++++++ gas/NEWS | 3 +++ gas/config/tc-i386.c | 11 +++++++---- gas/testsuite/gas/i386/jump.d | 12 ++++++++++++ gas/testsuite/gas/i386/jump.s | 9 +++++++++ gas/testsuite/gas/i386/jump16.d | 12 ++++++++++++ gas/testsuite/gas/i386/jump16.e | 4 ++-- gas/testsuite/gas/i386/jump16.s | 9 +++++++++ ld/ChangeLog | 13 +++++++++++++ ld/testsuite/ld-i386/i386.exp | 2 ++ ld/testsuite/ld-i386/ljmp.s | 10 ++++++++++ ld/testsuite/ld-i386/ljmp1.d | 18 ++++++++++++++++++ ld/testsuite/ld-i386/ljmp1.s | 9 +++++++++ ld/testsuite/ld-i386/ljmp2.d | 7 +++++++ ld/testsuite/ld-i386/ljmp2.s | 9 +++++++++ ld/testsuite/ld-x86-64/ljmp1.d | 17 +++++++++++++++++ ld/testsuite/ld-x86-64/ljmp2.d | 6 ++++++ ld/testsuite/ld-x86-64/x86-64.exp | 2 ++ 18 files changed, 160 insertions(+), 6 deletions(-) create mode 100644 ld/testsuite/ld-i386/ljmp.s create mode 100644 ld/testsuite/ld-i386/ljmp1.d create mode 100644 ld/testsuite/ld-i386/ljmp1.s create mode 100644 ld/testsuite/ld-i386/ljmp2.d create mode 100644 ld/testsuite/ld-i386/ljmp2.s create mode 100644 ld/testsuite/ld-x86-64/ljmp1.d create mode 100644 ld/testsuite/ld-x86-64/ljmp2.d diff --git a/gas/ChangeLog b/gas/ChangeLog index bd0834016b9..b27e08bccb0 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,16 @@ +2020-10-05 T.K. Chia + + 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 PR binutils/26704 diff --git a/gas/NEWS b/gas/NEWS index 8f83beb15b2..1107725ea66 100644 --- 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. diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c index 8f798479baa..f3eaba6231e 100644 --- a/gas/config/tc-i386.c +++ b/gas/config/tc-i386.c @@ -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) diff --git a/gas/testsuite/gas/i386/jump.d b/gas/testsuite/gas/i386/jump.d index 6dcececc1f2..72e399599c7 100644 --- a/gas/testsuite/gas/i386/jump.d +++ b/gas/testsuite/gas/i386/jump.d @@ -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 diff --git a/gas/testsuite/gas/i386/jump.s b/gas/testsuite/gas/i386/jump.s index eec3f0ab639..5efe43882a8 100644 --- a/gas/testsuite/gas/i386/jump.s +++ b/gas/testsuite/gas/i386/jump.s @@ -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 diff --git a/gas/testsuite/gas/i386/jump16.d b/gas/testsuite/gas/i386/jump16.d index afb1c377e73..df4facc10c0 100644 --- a/gas/testsuite/gas/i386/jump16.d +++ b/gas/testsuite/gas/i386/jump16.d @@ -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 diff --git a/gas/testsuite/gas/i386/jump16.e b/gas/testsuite/gas/i386/jump16.e index 2ad7ea056b6..aa5c5aad653 100644 --- a/gas/testsuite/gas/i386/jump16.e +++ b/gas/testsuite/gas/i386/jump16.e @@ -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 diff --git a/gas/testsuite/gas/i386/jump16.s b/gas/testsuite/gas/i386/jump16.s index fb9e830c52b..42d150ff978 100644 --- a/gas/testsuite/gas/i386/jump16.s +++ b/gas/testsuite/gas/i386/jump16.s @@ -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 diff --git a/ld/ChangeLog b/ld/ChangeLog index 0d5953a11b7..c259b09c74a 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,16 @@ +2020-10-05 T.K. Chia + + 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 * lexsup.c (parse_args): Generate an error or warning message when diff --git a/ld/testsuite/ld-i386/i386.exp b/ld/testsuite/ld-i386/i386.exp index 164c099cbbb..d0b8ed77bd1 100644 --- a/ld/testsuite/ld-i386/i386.exp +++ b/ld/testsuite/ld-i386/i386.exp @@ -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 index 00000000000..4b27a25a18e --- /dev/null +++ b/ld/testsuite/ld-i386/ljmp.s @@ -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 index 00000000000..9708ad0e002 --- /dev/null +++ b/ld/testsuite/ld-i386/ljmp1.d @@ -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]+ : + +[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 index 00000000000..3ae6882de52 --- /dev/null +++ b/ld/testsuite/ld-i386/ljmp1.s @@ -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 index 00000000000..b599cf9868a --- /dev/null +++ b/ld/testsuite/ld-i386/ljmp2.d @@ -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 index 00000000000..f6a4227a225 --- /dev/null +++ b/ld/testsuite/ld-i386/ljmp2.s @@ -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 index 00000000000..eb378fb6079 --- /dev/null +++ b/ld/testsuite/ld-x86-64/ljmp1.d @@ -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]+ : + +[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 index 00000000000..b3581822ce6 --- /dev/null +++ b/ld/testsuite/ld-x86-64/ljmp2.d @@ -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 .* diff --git a/ld/testsuite/ld-x86-64/x86-64.exp b/ld/testsuite/ld-x86-64/x86-64.exp index 3c0b4347d02..2c2551fd62e 100644 --- a/ld/testsuite/ld-x86-64/x86-64.exp +++ b/ld/testsuite/ld-x86-64/x86-64.exp @@ -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" -- 2.30.2