From aeab2b26dbea33221db4debaf31c97277cfaea5e Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Thu, 30 Jan 2020 11:36:33 +0100 Subject: x86-64: honor vendor specifics for near RET While vendors agree about default operand size (64 bits) and hence unavilability of a 32-bit form, AMD honors a 16-bit operand size override (0x66) while Intel doesn't. --- gas/ChangeLog | 10 +++++++ gas/testsuite/gas/i386/ilp32/x86-64-branch.d | 8 +++-- gas/testsuite/gas/i386/x86-64-branch-2.d | 2 ++ gas/testsuite/gas/i386/x86-64-branch-2.s | 3 ++ gas/testsuite/gas/i386/x86-64-branch-4.l | 44 ++++++++++++++++------------ gas/testsuite/gas/i386/x86-64-branch-4.s | 4 +++ gas/testsuite/gas/i386/x86-64-branch.d | 8 +++-- gas/testsuite/gas/i386/x86-64-branch.s | 5 ++++ opcodes/ChangeLog | 9 ++++++ opcodes/i386-dis.c | 18 ++++++++++-- opcodes/i386-opc.tbl | 6 ++-- opcodes/i386-tbl.h | 28 ++++++++++++++++-- 12 files changed, 117 insertions(+), 28 deletions(-) diff --git a/gas/ChangeLog b/gas/ChangeLog index 91d8728..d2a31b5 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,5 +1,15 @@ 2020-01-30 Jan Beulich + * testsuite/gas/i386/x86-64-branch-2.s, + testsuite/gas/i386/x86-64-branch-4.s, + testsuite/gas/i386/x86-64-branch.s: Add RETW cases. + * testsuite/gas/i386/ilp32/x86-64-branch.d, + testsuite/gas/i386/x86-64-branch-2.d, + testsuite/gas/i386/x86-64-branch-4.l, + testsuite/gas/i386/x86-64-branch.d: Adjust expectations. + +2020-01-30 Jan Beulich + * config/tc-i386.c (process_suffix): . testsuite/gas/i386/noreg64.s: Add IRET and LRET cases. testsuite/gas/i386/x86-64-opcode.s: Add suffix to IRET and LRET. diff --git a/gas/testsuite/gas/i386/ilp32/x86-64-branch.d b/gas/testsuite/gas/i386/ilp32/x86-64-branch.d index 45ab617..5bfa2a4 100644 --- a/gas/testsuite/gas/i386/ilp32/x86-64-branch.d +++ b/gas/testsuite/gas/i386/ilp32/x86-64-branch.d @@ -23,6 +23,8 @@ Disassembly of section .text: [ ]*[a-f0-9]+: 66 e8 00 00 00 00 data16 callq 0x2a 26: R_X86_64_PLT32 foo-0x4 [ ]*[a-f0-9]+: 66 e9 00 00 00 00 data16 jmpq 0x30 2c: R_X86_64_PLT32 foo-0x4 [ ]*[a-f0-9]+: 66 0f 82 00 00 00 00 data16 jb 0x37 33: R_X86_64_PLT32 foo-0x4 +[ ]*[a-f0-9]+: 66 c3 data16 retq * +[ ]*[a-f0-9]+: 66 c2 08 00 data16 retq \$0x8 [ ]*[a-f0-9]+: ff d0 callq \*%rax [ ]*[a-f0-9]+: ff d0 callq \*%rax [ ]*[a-f0-9]+: 66 ff d0 data16 callq \*%rax @@ -33,6 +35,8 @@ Disassembly of section .text: [ ]*[a-f0-9]+: 66 ff e0 data16 jmpq \*%rax [ ]*[a-f0-9]+: 66 ff e0 data16 jmpq \*%rax [ ]*[a-f0-9]+: 66 ff 20 data16 jmpq \*\(%rax\) -[ ]*[a-f0-9]+: e8 00 00 00 00 callq 0x56 52: R_X86_64_PC32 \*ABS\*\+0x10003c -[ ]*[a-f0-9]+: e9 00 00 00 00 jmpq 0x5b 57: R_X86_64_PC32 \*ABS\*\+0x10003c +[ ]*[a-f0-9]+: e8 00 00 00 00 callq 0x[0-9a-f]* [0-9a-f]*: R_X86_64_PC32 \*ABS\*\+0x10003c +[ ]*[a-f0-9]+: e9 00 00 00 00 jmpq 0x[0-9a-f]* [0-9a-f]*: R_X86_64_PC32 \*ABS\*\+0x10003c +[ ]*[a-f0-9]+: 66 c3 data16 retq * +[ ]*[a-f0-9]+: 66 c2 08 00 data16 retq \$0x8 #pass diff --git a/gas/testsuite/gas/i386/x86-64-branch-2.d b/gas/testsuite/gas/i386/x86-64-branch-2.d index 196fa8e..be9aae4 100644 --- a/gas/testsuite/gas/i386/x86-64-branch-2.d +++ b/gas/testsuite/gas/i386/x86-64-branch-2.d @@ -14,4 +14,6 @@ Disassembly of section .text: [ ]*[a-f0-9]+: 89 c3 mov %eax,%ebx [ ]*[a-f0-9]+: 66 e8 00 00 callw 11 f: R_X86_64_PC16 foo-0x2 [ ]*[a-f0-9]+: 66 48 e8 00 00 00 00 data16 callq 18 14: R_X86_64_PLT32 foo-0x4 +[ ]*[a-f0-9]+: 66 c3 retw * +[ ]*[a-f0-9]+: 66 c2 08 00 retw \$0x8 #pass diff --git a/gas/testsuite/gas/i386/x86-64-branch-2.s b/gas/testsuite/gas/i386/x86-64-branch-2.s index 3a4911b..a383a8f 100644 --- a/gas/testsuite/gas/i386/x86-64-branch-2.s +++ b/gas/testsuite/gas/i386/x86-64-branch-2.s @@ -7,3 +7,6 @@ bar: data16 call foo data16 rex.w call foo + + retw + retw $8 diff --git a/gas/testsuite/gas/i386/x86-64-branch-4.l b/gas/testsuite/gas/i386/x86-64-branch-4.l index 8f681f8..54e3230 100644 --- a/gas/testsuite/gas/i386/x86-64-branch-4.l +++ b/gas/testsuite/gas/i386/x86-64-branch-4.l @@ -4,14 +4,18 @@ .*:4: Error: operand type mismatch for `jmp' .*:5: Error: invalid instruction suffix for `jmp' .*:6: Error: invalid instruction suffix for `jmp' -.*:9: Error: operand type mismatch for `call' -.*:10: Error: invalid instruction suffix for `call' -.*:11: Error: invalid instruction suffix for `call' -.*:12: Error: operand size mismatch for `call' -.*:13: Error: operand type mismatch for `jmp' -.*:14: Error: invalid instruction suffix for `jmp' -.*:15: Error: invalid instruction suffix for `jmp' -.*:16: Error: operand size mismatch for `jmp' +.*:7: Error: invalid instruction suffix for `ret' +.*:8: Error: invalid instruction suffix for `ret' +.*:11: Error: operand type mismatch for `call' +.*:12: Error: invalid instruction suffix for `call' +.*:13: Error: invalid instruction suffix for `call' +.*:14: Error: operand size mismatch for `call' +.*:15: Error: operand type mismatch for `jmp' +.*:16: Error: invalid instruction suffix for `jmp' +.*:17: Error: invalid instruction suffix for `jmp' +.*:18: Error: operand size mismatch for `jmp' +.*:19: Error: invalid instruction suffix for `ret' +.*:20: Error: invalid instruction suffix for `ret' GAS LISTING .* #... [ ]*1[ ]+\.text @@ -20,14 +24,18 @@ GAS LISTING .* [ ]*4[ ]+jmp \*%ax [ ]*5[ ]+jmpw \*%ax [ ]*6[ ]+jmpw \*\(%rax\) -[ ]*7[ ]+ -[ ]*8[ ]+\.intel_syntax noprefix -[ ]*9[ ]+call ax -[ ]*10[ ]+callw ax -[ ]*11[ ]+callw \[rax\] -[ ]*12[ ]+call WORD PTR \[rax\] -[ ]*13[ ]+jmp ax -[ ]*14[ ]+jmpw ax -[ ]*15[ ]+jmpw \[rax\] -[ ]*16[ ]+jmp WORD PTR \[rax\] +[ ]*7[ ]+retw +[ ]*8[ ]+retw \$8 +[ ]*9[ ]+ +[ ]*10[ ]+\.intel_syntax noprefix +[ ]*11[ ]+call ax +[ ]*12[ ]+callw ax +[ ]*13[ ]+callw \[rax\] +[ ]*14[ ]+call WORD PTR \[rax\] +[ ]*15[ ]+jmp ax +[ ]*16[ ]+jmpw ax +[ ]*17[ ]+jmpw \[rax\] +[ ]*18[ ]+jmp WORD PTR \[rax\] +[ ]*19[ ]+retw +[ ]*20[ ]+retw 8 #pass diff --git a/gas/testsuite/gas/i386/x86-64-branch-4.s b/gas/testsuite/gas/i386/x86-64-branch-4.s index 67d6e1f..ab8c56b 100644 --- a/gas/testsuite/gas/i386/x86-64-branch-4.s +++ b/gas/testsuite/gas/i386/x86-64-branch-4.s @@ -4,6 +4,8 @@ jmp *%ax jmpw *%ax jmpw *(%rax) + retw + retw $8 .intel_syntax noprefix call ax @@ -14,3 +16,5 @@ jmpw ax jmpw [rax] jmp WORD PTR [rax] + retw + retw 8 diff --git a/gas/testsuite/gas/i386/x86-64-branch.d b/gas/testsuite/gas/i386/x86-64-branch.d index 773ce71..8b98814 100644 --- a/gas/testsuite/gas/i386/x86-64-branch.d +++ b/gas/testsuite/gas/i386/x86-64-branch.d @@ -22,6 +22,8 @@ Disassembly of section .text: [ ]*[a-f0-9]+: 66 e8 00 00 00 00 data16 callq (0x2a|2a <.text\+0x2a>) [ ]*[a-f0-9]+: 66 e9 00 00 00 00 data16 jmpq (0x30|30 <.text\+0x30>) [ ]*[a-f0-9]+: 66 0f 82 00 00 00 00 data16 jb (0x37|37 <.text\+0x37>) +[ ]*[a-f0-9]+: 66 c3 data16 retq * +[ ]*[a-f0-9]+: 66 c2 08 00 data16 retq \$0x8 [ ]*[a-f0-9]+: ff d0 callq \*%rax [ ]*[a-f0-9]+: ff d0 callq \*%rax [ ]*[a-f0-9]+: 66 ff d0 data16 callq \*%rax @@ -32,6 +34,8 @@ Disassembly of section .text: [ ]*[a-f0-9]+: 66 ff e0 data16 jmpq \*%rax [ ]*[a-f0-9]+: 66 ff e0 data16 jmpq \*%rax [ ]*[a-f0-9]+: 66 ff 20 data16 jmpq \*\(%rax\) -[ ]*[a-f0-9]+: e8 (00|92) 00 (00|10) 00 callq (0x56|1000e8 <.text\+0x1000e8>) -[ ]*[a-f0-9]+: e9 (00|97) 00 (00|10) 00 jmpq (0x5b|1000f2 <.text\+0x1000f2>) +[ ]*[a-f0-9]+: e8 .. 00 (00|10) 00 callq (0x[0-9a-f]*|100[0-9a-f]* <.text\+0x100[0-9a-f]*>) +[ ]*[a-f0-9]+: e9 .. 00 (00|10) 00 jmpq (0x[0-9a-f]*|100[0-9a-f]* <.text\+0x100[0-9a-f]*>) +[ ]*[a-f0-9]+: 66 c3 data16 retq * +[ ]*[a-f0-9]+: 66 c2 08 00 data16 retq \$0x8 #pass diff --git a/gas/testsuite/gas/i386/x86-64-branch.s b/gas/testsuite/gas/i386/x86-64-branch.s index 9451d76..eb40dd4 100644 --- a/gas/testsuite/gas/i386/x86-64-branch.s +++ b/gas/testsuite/gas/i386/x86-64-branch.s @@ -19,6 +19,9 @@ .byte 0x66 jb foo + retw + retw $8 + .intel_syntax noprefix call rax callq rax @@ -32,3 +35,5 @@ jmpw [rax] call 0x100040 jmp 0x100040 + retw + retw 8 diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog index 3748121..19c2772 100644 --- a/opcodes/ChangeLog +++ b/opcodes/ChangeLog @@ -1,5 +1,14 @@ 2020-01-30 Jan Beulich + * i386-dis.c (X86_64_C2, X86_64_C3): New enumerators. + (dis386): Use them to replace C2/C3 table entries. + (x86_64_table): Add X86_64_C2 and X86_64_C3 entries. + * i386-opc.tbl (ret): Split Cpu64 entries into AMD64 and Intel64 + ones. Use Size64 instead of DefaultSize on Intel64 ones. + * i386-tbl.h: Re-generate. + +2020-01-30 Jan Beulich + * i386-opc.tbl (call): Drop DefaultSize from Intel64 JumpDword forms. (fldenv, fnstenv, fstenv, fnsave, fsave, frstor): Drop diff --git a/opcodes/i386-dis.c b/opcodes/i386-dis.c index e6f73bf..d3746b0 100644 --- a/opcodes/i386-dis.c +++ b/opcodes/i386-dis.c @@ -1764,6 +1764,8 @@ enum X86_64_6F, X86_64_82, X86_64_9A, + X86_64_C2, + X86_64_C3, X86_64_C4, X86_64_C5, X86_64_CE, @@ -2586,8 +2588,8 @@ static const struct dis386 dis386[] = { /* c0 */ { REG_TABLE (REG_C0) }, { REG_TABLE (REG_C1) }, - { "retT", { Iw, BND }, 0 }, - { "retT", { BND }, 0 }, + { X86_64_TABLE (X86_64_C2) }, + { X86_64_TABLE (X86_64_C3) }, { X86_64_TABLE (X86_64_C4) }, { X86_64_TABLE (X86_64_C5) }, { REG_TABLE (REG_C6) }, @@ -6901,6 +6903,18 @@ static const struct dis386 x86_64_table[][2] = { { "Jcall{T|}", { Ap }, 0 }, }, + /* X86_64_C2 */ + { + { "retP", { Iw, BND }, 0 }, + { "ret@", { Iw, BND }, 0 }, + }, + + /* X86_64_C3 */ + { + { "retP", { BND }, 0 }, + { "ret@", { BND }, 0 }, + }, + /* X86_64_C4 */ { { MOD_TABLE (MOD_C4_32BIT) }, diff --git a/opcodes/i386-opc.tbl b/opcodes/i386-opc.tbl index d2343fc..1dff2dd 100644 --- a/opcodes/i386-opc.tbl +++ b/opcodes/i386-opc.tbl @@ -400,8 +400,10 @@ ljmp, 1, 0xff, 0x5, 1, 0, Modrm|JumpAbsolute|No_bSuf|No_sSuf|No_qSuf|No_ldSuf, { ret, 0, 0xc3, None, 1, CpuNo64, DefaultSize|No_bSuf|No_sSuf|No_qSuf|No_ldSuf|RepPrefixOk|BNDPrefixOk, { 0 } ret, 1, 0xc2, None, 1, CpuNo64, DefaultSize|No_bSuf|No_sSuf|No_qSuf|No_ldSuf|RepPrefixOk|BNDPrefixOk, { Imm16 } -ret, 0, 0xc3, None, 1, Cpu64, DefaultSize|No_bSuf|No_lSuf|No_sSuf|No_ldSuf|NoRex64|RepPrefixOk|BNDPrefixOk, { 0 } -ret, 1, 0xc2, None, 1, Cpu64, DefaultSize|No_bSuf|No_lSuf|No_sSuf|No_ldSuf|NoRex64|RepPrefixOk|BNDPrefixOk, { Imm16 } +ret, 0, 0xc3, None, 1, Cpu64, AMD64|DefaultSize|No_bSuf|No_lSuf|No_sSuf|No_ldSuf|NoRex64|RepPrefixOk|BNDPrefixOk, { 0 } +ret, 1, 0xc2, None, 1, Cpu64, AMD64|DefaultSize|No_bSuf|No_lSuf|No_sSuf|No_ldSuf|NoRex64|RepPrefixOk|BNDPrefixOk, { Imm16 } +ret, 0, 0xc3, None, 1, Cpu64, Intel64|Size64|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_ldSuf|NoRex64|RepPrefixOk|BNDPrefixOk, { 0 } +ret, 1, 0xc2, None, 1, Cpu64, Intel64|Size64|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_ldSuf|NoRex64|RepPrefixOk|BNDPrefixOk, { Imm16 } lret, 0, 0xcb, None, 1, 0, DefaultSize|No_bSuf|No_sSuf|No_ldSuf, { 0 } lret, 1, 0xca, None, 1, 0, DefaultSize|No_bSuf|No_sSuf|No_ldSuf, { Imm16 } // Intel Syntax. diff --git a/opcodes/i386-tbl.h b/opcodes/i386-tbl.h index be51051..b393407 100644 --- a/opcodes/i386-tbl.h +++ b/opcodes/i386-tbl.h @@ -2965,7 +2965,7 @@ const insn_template i386_optab[] = 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 } }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0 }, { { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } } } }, { "ret", 0xc2, None, 1, 1, @@ -2977,7 +2977,31 @@ const insn_template i386_optab[] = 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 } }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0 }, + { { { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 } } } }, + { "ret", 0xc3, None, 1, 0, + { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 } }, + { 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }, + { { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 } } } }, + { "ret", 0xc2, None, 1, 1, + { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 } }, + { 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }, { { { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } } } }, { "lret", 0xcb, None, 1, 0, -- cgit v1.1