mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-11-27 12:03:41 +08:00
x86: correct decoding of nop/reserved space (0f18 ... 0x1f)
All encodings not used in this range are (reserved) NOPs. Hence their decoding should be fully consistent. For this to work the PREFIX_IGNORED logic needs slightly extending, such that the attribute will also - have an effect when used inside prefix_table[], yet without always falling back to using slot 0, - cause prefixes marked as ignored while decoding through prefix_table[] to no longer be considered decoded, when encountered in a subsequent decoding step. In adjacent code also drop meaningless PREFIX_OPCODE.
This commit is contained in:
parent
67b0f68480
commit
319419837c
@ -1,3 +1,12 @@
|
||||
2021-03-10 Jan Beulich <jbeulich@suse.com>
|
||||
|
||||
* testsuite/gas/i386/prefetch.d,
|
||||
testsuite/gas/i386/prefetch-intel.d,
|
||||
testsuite/gas/i386/x86-64-prefetch.d,
|
||||
testsuite/gas/i386/x86-64-prefetch-intel.d: Adjust expectations.
|
||||
* testsuite/gas/i386/nops-8.s, testsuite/gas/i386/nops-8.d: New.
|
||||
* testsuite/gas/i386/i386.exp: Run new test.
|
||||
|
||||
2021-03-09 Jan Beulich <jbeulich@suse.com>
|
||||
|
||||
* config/tc-i386.c (check_hle): Replace HLEPrefix* by Prefix*.
|
||||
|
@ -134,6 +134,7 @@ if [gas_32_check] then {
|
||||
run_dump_test "nops-5-i686"
|
||||
run_dump_test "nops-6"
|
||||
run_dump_test "nops-7"
|
||||
run_dump_test "nops-8"
|
||||
run_dump_test "noreg16"
|
||||
run_list_test "noreg16"
|
||||
run_dump_test "noreg16-data32"
|
||||
|
2327
gas/testsuite/gas/i386/nops-8.d
Normal file
2327
gas/testsuite/gas/i386/nops-8.d
Normal file
File diff suppressed because it is too large
Load Diff
19
gas/testsuite/gas/i386/nops-8.s
Normal file
19
gas/testsuite/gas/i386/nops-8.s
Normal file
@ -0,0 +1,19 @@
|
||||
.text
|
||||
.irp opc, 18, 19, 1a, 1b, 1c, 1d, 1e, 1f
|
||||
_0f\opc:
|
||||
.irp pfx, , 66, f3, f2
|
||||
.irp mod, 3, 0
|
||||
.irp reg, 0, 1, 2, 3, 4, 5, 6, 7
|
||||
.irp rm, 0, 1, 2, 3, 4, 5, 6, 7
|
||||
.if !\mod && \rm
|
||||
.exitm
|
||||
.endif
|
||||
.ifnb \pfx
|
||||
.byte 0x\pfx
|
||||
.endif
|
||||
.byte 0xf, 0x\opc, (\mod << 6) | (\reg << 3) | \rm
|
||||
.endr
|
||||
.endr
|
||||
.endr
|
||||
.endr
|
||||
.endr
|
@ -21,7 +21,7 @@ Disassembly of section .text:
|
||||
\s*[a-f0-9]+: 0f 18 08 prefetcht0 BYTE PTR \[eax\]
|
||||
\s*[a-f0-9]+: 0f 18 10 prefetcht1 BYTE PTR \[eax\]
|
||||
\s*[a-f0-9]+: 0f 18 18 prefetcht2 BYTE PTR \[eax\]
|
||||
\s*[a-f0-9]+: 0f 18 20 nop/reserved BYTE PTR \[eax\]
|
||||
\s*[a-f0-9]+: 0f 18 28 nop/reserved BYTE PTR \[eax\]
|
||||
\s*[a-f0-9]+: 0f 18 30 nop/reserved BYTE PTR \[eax\]
|
||||
\s*[a-f0-9]+: 0f 18 38 nop/reserved BYTE PTR \[eax\]
|
||||
\s*[a-f0-9]+: 0f 18 20 nop DWORD PTR \[eax\]
|
||||
\s*[a-f0-9]+: 0f 18 28 nop DWORD PTR \[eax\]
|
||||
\s*[a-f0-9]+: 0f 18 30 nop DWORD PTR \[eax\]
|
||||
\s*[a-f0-9]+: 0f 18 38 nop DWORD PTR \[eax\]
|
||||
|
@ -20,7 +20,7 @@ Disassembly of section .text:
|
||||
\s*[a-f0-9]+: 0f 18 08 prefetcht0 \(%eax\)
|
||||
\s*[a-f0-9]+: 0f 18 10 prefetcht1 \(%eax\)
|
||||
\s*[a-f0-9]+: 0f 18 18 prefetcht2 \(%eax\)
|
||||
\s*[a-f0-9]+: 0f 18 20 nop/reserved \(%eax\)
|
||||
\s*[a-f0-9]+: 0f 18 28 nop/reserved \(%eax\)
|
||||
\s*[a-f0-9]+: 0f 18 30 nop/reserved \(%eax\)
|
||||
\s*[a-f0-9]+: 0f 18 38 nop/reserved \(%eax\)
|
||||
\s*[a-f0-9]+: 0f 18 20 nopl \(%eax\)
|
||||
\s*[a-f0-9]+: 0f 18 28 nopl \(%eax\)
|
||||
\s*[a-f0-9]+: 0f 18 30 nopl \(%eax\)
|
||||
\s*[a-f0-9]+: 0f 18 38 nopl \(%eax\)
|
||||
|
@ -21,7 +21,7 @@ Disassembly of section .text:
|
||||
\s*[a-f0-9]+: 0f 18 08 prefetcht0 BYTE PTR \[rax\]
|
||||
\s*[a-f0-9]+: 0f 18 10 prefetcht1 BYTE PTR \[rax\]
|
||||
\s*[a-f0-9]+: 0f 18 18 prefetcht2 BYTE PTR \[rax\]
|
||||
\s*[a-f0-9]+: 0f 18 20 nop/reserved BYTE PTR \[rax\]
|
||||
\s*[a-f0-9]+: 0f 18 28 nop/reserved BYTE PTR \[rax\]
|
||||
\s*[a-f0-9]+: 0f 18 30 nop/reserved BYTE PTR \[rax\]
|
||||
\s*[a-f0-9]+: 0f 18 38 nop/reserved BYTE PTR \[rax\]
|
||||
\s*[a-f0-9]+: 0f 18 20 nop DWORD PTR \[rax\]
|
||||
\s*[a-f0-9]+: 0f 18 28 nop DWORD PTR \[rax\]
|
||||
\s*[a-f0-9]+: 0f 18 30 nop DWORD PTR \[rax\]
|
||||
\s*[a-f0-9]+: 0f 18 38 nop DWORD PTR \[rax\]
|
||||
|
@ -21,7 +21,7 @@ Disassembly of section .text:
|
||||
\s*[a-f0-9]+: 0f 18 08 prefetcht0 \(%rax\)
|
||||
\s*[a-f0-9]+: 0f 18 10 prefetcht1 \(%rax\)
|
||||
\s*[a-f0-9]+: 0f 18 18 prefetcht2 \(%rax\)
|
||||
\s*[a-f0-9]+: 0f 18 20 nop/reserved \(%rax\)
|
||||
\s*[a-f0-9]+: 0f 18 28 nop/reserved \(%rax\)
|
||||
\s*[a-f0-9]+: 0f 18 30 nop/reserved \(%rax\)
|
||||
\s*[a-f0-9]+: 0f 18 38 nop/reserved \(%rax\)
|
||||
\s*[a-f0-9]+: 0f 18 20 nopl \(%rax\)
|
||||
\s*[a-f0-9]+: 0f 18 28 nopl \(%rax\)
|
||||
\s*[a-f0-9]+: 0f 18 30 nopl \(%rax\)
|
||||
\s*[a-f0-9]+: 0f 18 38 nopl \(%rax\)
|
||||
|
@ -1,3 +1,19 @@
|
||||
2021-03-10 Jan Beulich <jbeulich@suse.com>
|
||||
|
||||
* opcodes/i386-dis.c (MOD_0F18_REG_4, MOD_0F18_REG_5,
|
||||
MOD_0F18_REG_6, MOD_0F18_REG_7): Delete.
|
||||
(reg_table): Don't link to mod_table[] where not needed. Add
|
||||
PREFIX_IGNORED to nop entries.
|
||||
(prefix_table): Replace PREFIX_OPCODE in nop entries.
|
||||
(mod_table): Add nop entries next to prefetch ones. Drop
|
||||
MOD_0F18_REG_4, MOD_0F18_REG_5, MOD_0F18_REG_6, and
|
||||
MOD_0F18_REG_7 entries. Add PREFIX_IGNORED to nop entries.
|
||||
(rm_table): Add PREFIX_IGNORED to nop entries. Drop
|
||||
PREFIX_OPCODE from endbr* entries.
|
||||
(get_valid_dis386): Also consider entry's name when zapping
|
||||
vindex.
|
||||
(print_insn): Handle PREFIX_IGNORED.
|
||||
|
||||
2021-03-09 Jan Beulich <jbeulich@suse.com>
|
||||
|
||||
* opcodes/i386-gen.c (opcode_modifiers): Delete NoTrackPrefixOk,
|
||||
|
@ -743,10 +743,6 @@ enum
|
||||
MOD_0F18_REG_1,
|
||||
MOD_0F18_REG_2,
|
||||
MOD_0F18_REG_3,
|
||||
MOD_0F18_REG_4,
|
||||
MOD_0F18_REG_5,
|
||||
MOD_0F18_REG_6,
|
||||
MOD_0F18_REG_7,
|
||||
MOD_0F1A_PREFIX_0,
|
||||
MOD_0F1B_PREFIX_0,
|
||||
MOD_0F1B_PREFIX_1,
|
||||
@ -2907,10 +2903,10 @@ static const struct dis386 reg_table[][8] = {
|
||||
{ MOD_TABLE (MOD_0F18_REG_1) },
|
||||
{ MOD_TABLE (MOD_0F18_REG_2) },
|
||||
{ MOD_TABLE (MOD_0F18_REG_3) },
|
||||
{ MOD_TABLE (MOD_0F18_REG_4) },
|
||||
{ MOD_TABLE (MOD_0F18_REG_5) },
|
||||
{ MOD_TABLE (MOD_0F18_REG_6) },
|
||||
{ MOD_TABLE (MOD_0F18_REG_7) },
|
||||
{ "nopQ", { Ev }, 0 },
|
||||
{ "nopQ", { Ev }, 0 },
|
||||
{ "nopQ", { Ev }, 0 },
|
||||
{ "nopQ", { Ev }, 0 },
|
||||
},
|
||||
/* REG_0F1C_P_0_MOD_0 */
|
||||
{
|
||||
@ -2925,13 +2921,13 @@ static const struct dis386 reg_table[][8] = {
|
||||
},
|
||||
/* REG_0F1E_P_1_MOD_3 */
|
||||
{
|
||||
{ "nopQ", { Ev }, 0 },
|
||||
{ "rdsspK", { Edq }, PREFIX_OPCODE },
|
||||
{ "nopQ", { Ev }, 0 },
|
||||
{ "nopQ", { Ev }, 0 },
|
||||
{ "nopQ", { Ev }, 0 },
|
||||
{ "nopQ", { Ev }, 0 },
|
||||
{ "nopQ", { Ev }, 0 },
|
||||
{ "nopQ", { Ev }, PREFIX_IGNORED },
|
||||
{ "rdsspK", { Edq }, 0 },
|
||||
{ "nopQ", { Ev }, PREFIX_IGNORED },
|
||||
{ "nopQ", { Ev }, PREFIX_IGNORED },
|
||||
{ "nopQ", { Ev }, PREFIX_IGNORED },
|
||||
{ "nopQ", { Ev }, PREFIX_IGNORED },
|
||||
{ "nopQ", { Ev }, PREFIX_IGNORED },
|
||||
{ RM_TABLE (RM_0F1E_P_1_MOD_3_REG_7) },
|
||||
},
|
||||
/* REG_0F38D8_PREFIX_1 */
|
||||
@ -3287,17 +3283,17 @@ static const struct dis386 prefix_table[][4] = {
|
||||
/* PREFIX_0F1C */
|
||||
{
|
||||
{ MOD_TABLE (MOD_0F1C_PREFIX_0) },
|
||||
{ "nopQ", { Ev }, PREFIX_OPCODE },
|
||||
{ "nopQ", { Ev }, PREFIX_OPCODE },
|
||||
{ "nopQ", { Ev }, PREFIX_OPCODE },
|
||||
{ "nopQ", { Ev }, PREFIX_IGNORED },
|
||||
{ "nopQ", { Ev }, 0 },
|
||||
{ "nopQ", { Ev }, PREFIX_IGNORED },
|
||||
},
|
||||
|
||||
/* PREFIX_0F1E */
|
||||
{
|
||||
{ "nopQ", { Ev }, PREFIX_OPCODE },
|
||||
{ "nopQ", { Ev }, 0 },
|
||||
{ MOD_TABLE (MOD_0F1E_PREFIX_1) },
|
||||
{ "nopQ", { Ev }, PREFIX_OPCODE },
|
||||
{ "nopQ", { Ev }, PREFIX_OPCODE },
|
||||
{ "nopQ", { Ev }, 0 },
|
||||
{ NULL, { XX }, PREFIX_IGNORED },
|
||||
},
|
||||
|
||||
/* PREFIX_0F2A */
|
||||
@ -8201,34 +8197,22 @@ static const struct dis386 mod_table[][2] = {
|
||||
{
|
||||
/* MOD_0F18_REG_0 */
|
||||
{ "prefetchnta", { Mb }, 0 },
|
||||
{ "nopQ", { Ev }, 0 },
|
||||
},
|
||||
{
|
||||
/* MOD_0F18_REG_1 */
|
||||
{ "prefetcht0", { Mb }, 0 },
|
||||
{ "nopQ", { Ev }, 0 },
|
||||
},
|
||||
{
|
||||
/* MOD_0F18_REG_2 */
|
||||
{ "prefetcht1", { Mb }, 0 },
|
||||
{ "nopQ", { Ev }, 0 },
|
||||
},
|
||||
{
|
||||
/* MOD_0F18_REG_3 */
|
||||
{ "prefetcht2", { Mb }, 0 },
|
||||
},
|
||||
{
|
||||
/* MOD_0F18_REG_4 */
|
||||
{ "nop/reserved", { Mb }, 0 },
|
||||
},
|
||||
{
|
||||
/* MOD_0F18_REG_5 */
|
||||
{ "nop/reserved", { Mb }, 0 },
|
||||
},
|
||||
{
|
||||
/* MOD_0F18_REG_6 */
|
||||
{ "nop/reserved", { Mb }, 0 },
|
||||
},
|
||||
{
|
||||
/* MOD_0F18_REG_7 */
|
||||
{ "nop/reserved", { Mb }, 0 },
|
||||
{ "nopQ", { Ev }, 0 },
|
||||
},
|
||||
{
|
||||
/* MOD_0F1A_PREFIX_0 */
|
||||
@ -8243,7 +8227,7 @@ static const struct dis386 mod_table[][2] = {
|
||||
{
|
||||
/* MOD_0F1B_PREFIX_1 */
|
||||
{ "bndmk", { Gbnd, Mv_bnd }, 0 },
|
||||
{ "nopQ", { Ev }, 0 },
|
||||
{ "nopQ", { Ev }, PREFIX_IGNORED },
|
||||
},
|
||||
{
|
||||
/* MOD_0F1C_PREFIX_0 */
|
||||
@ -8252,7 +8236,7 @@ static const struct dis386 mod_table[][2] = {
|
||||
},
|
||||
{
|
||||
/* MOD_0F1E_PREFIX_1 */
|
||||
{ "nopQ", { Ev }, 0 },
|
||||
{ "nopQ", { Ev }, PREFIX_IGNORED },
|
||||
{ REG_TABLE (REG_0F1E_P_1_MOD_3) },
|
||||
},
|
||||
{
|
||||
@ -9034,14 +9018,14 @@ static const struct dis386 rm_table[][8] = {
|
||||
},
|
||||
{
|
||||
/* RM_0F1E_P_1_MOD_3_REG_7 */
|
||||
{ "nopQ", { Ev }, 0 },
|
||||
{ "nopQ", { Ev }, 0 },
|
||||
{ "endbr64", { Skip_MODRM }, PREFIX_OPCODE },
|
||||
{ "endbr32", { Skip_MODRM }, PREFIX_OPCODE },
|
||||
{ "nopQ", { Ev }, 0 },
|
||||
{ "nopQ", { Ev }, 0 },
|
||||
{ "nopQ", { Ev }, 0 },
|
||||
{ "nopQ", { Ev }, 0 },
|
||||
{ "nopQ", { Ev }, PREFIX_IGNORED },
|
||||
{ "nopQ", { Ev }, PREFIX_IGNORED },
|
||||
{ "endbr64", { Skip_MODRM }, 0 },
|
||||
{ "endbr32", { Skip_MODRM }, 0 },
|
||||
{ "nopQ", { Ev }, PREFIX_IGNORED },
|
||||
{ "nopQ", { Ev }, PREFIX_IGNORED },
|
||||
{ "nopQ", { Ev }, PREFIX_IGNORED },
|
||||
{ "nopQ", { Ev }, PREFIX_IGNORED },
|
||||
},
|
||||
{
|
||||
/* RM_0F3A0F_P_1_MOD_3_REG_0 */
|
||||
@ -9471,7 +9455,8 @@ get_valid_dis386 (const struct dis386 *dp, disassemble_info *info)
|
||||
/* Check if prefix should be ignored. */
|
||||
if ((((prefix_table[dp->op[1].bytemode][vindex].prefix_requirement
|
||||
& PREFIX_IGNORED) >> PREFIX_IGNORED_SHIFT)
|
||||
& prefix) != 0)
|
||||
& prefix) != 0
|
||||
&& !prefix_table[dp->op[1].bytemode][vindex].name)
|
||||
vindex = 0;
|
||||
}
|
||||
|
||||
@ -10245,6 +10230,18 @@ print_insn (bfd_vma pc, disassemble_info *info)
|
||||
return end_codep - priv.the_buffer;
|
||||
}
|
||||
break;
|
||||
|
||||
case PREFIX_IGNORED:
|
||||
/* Zap data size and rep prefixes from used_prefixes and reinstate their
|
||||
origins in all_prefixes. */
|
||||
used_prefixes &= ~PREFIX_OPCODE;
|
||||
if (last_data_prefix >= 0)
|
||||
all_prefixes[last_repz_prefix] = 0x66;
|
||||
if (last_repz_prefix >= 0)
|
||||
all_prefixes[last_repz_prefix] = 0xf3;
|
||||
if (last_repnz_prefix >= 0)
|
||||
all_prefixes[last_repnz_prefix] = 0xf2;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Check if the REX prefix is used. */
|
||||
|
Loading…
Reference in New Issue
Block a user