x86: Add NOTRACK prefix support
For register indirect branches, NOTRACK prefix (0x3e), which is also the DS segment register prefix, can be used to ignore the CET indirect branch track. gas/ * config/tc-i386.c (REX_PREFIX): Changed to 7. (NOTRACK_PREFIX): New. (MAX_PREFIXES): Changed to 8. (_i386_insn): Add notrack_prefix. (PREFIX_GROUP): Add PREFIX_DS. (add_prefix): Return PREFIX_DS for DS_PREFIX_OPCODE. (md_assemble): Check if NOTRACK prefix is supported. (parse_insn): Set notrack_prefix and issue an error for other prefixes after NOTRACK prefix. * testsuite/gas/i386/i386.exp: Run tests for NOTRACK prefix. * testsuite/gas/i386/notrack-intel.d: New file. * testsuite/gas/i386/notrack.d: Likewise. * testsuite/gas/i386/notrack.s: Likewise. * testsuite/gas/i386/notrackbad.l: Likewise. * testsuite/gas/i386/notrackbad.s: Likewise. * testsuite/gas/i386/x86-64-notrack-intel.d: Likewise. * testsuite/gas/i386/x86-64-notrack.d: Likewise. * testsuite/gas/i386/x86-64-notrack.s: Likewise. * testsuite/gas/i386/x86-64-notrackbad.l: Likewise. * testsuite/gas/i386/x86-64-notrackbad.s: Likewise. include/ * include/opcode/i386.h (NOTRACK_PREFIX_OPCODE): New. opcodes/ * i386-dis.c (NOTRACK_Fixup): New. (NOTRACK): Likewise. (NOTRACK_PREFIX): Likewise. (last_active_prefix): Likewise. (reg_table): Use NOTRACK on indirect call and jmp. (ckprefix): Set last_active_prefix. (prefix_name): Return "notrack" for NOTRACK_PREFIX. * i386-gen.c (opcode_modifiers): Add NoTrackPrefixOk. * i386-opc.h (NoTrackPrefixOk): New. (i386_opcode_modifier): Add notrackprefixok. * i386-opc.tbl: Add NoTrackPrefixOk to indirect call and jmp. Add notrack. * i386-tbl.h: Regenerated.
This commit is contained in:
parent
25f9434737
commit
04ef582ace
|
@ -1,3 +1,26 @@
|
|||
2017-05-22 H.J. Lu <hongjiu.lu@intel.com>
|
||||
|
||||
* config/tc-i386.c (REX_PREFIX): Changed to 7.
|
||||
(NOTRACK_PREFIX): New.
|
||||
(MAX_PREFIXES): Changed to 8.
|
||||
(_i386_insn): Add notrack_prefix.
|
||||
(PREFIX_GROUP): Add PREFIX_DS.
|
||||
(add_prefix): Return PREFIX_DS for DS_PREFIX_OPCODE.
|
||||
(md_assemble): Check if NOTRACK prefix is supported.
|
||||
(parse_insn): Set notrack_prefix and issue an error for
|
||||
other prefixes after NOTRACK prefix.
|
||||
* testsuite/gas/i386/i386.exp: Run tests for NOTRACK prefix.
|
||||
* testsuite/gas/i386/notrack-intel.d: New file.
|
||||
* testsuite/gas/i386/notrack.d: Likewise.
|
||||
* testsuite/gas/i386/notrack.s: Likewise.
|
||||
* testsuite/gas/i386/notrackbad.l: Likewise.
|
||||
* testsuite/gas/i386/notrackbad.s: Likewise.
|
||||
* testsuite/gas/i386/x86-64-notrack-intel.d: Likewise.
|
||||
* testsuite/gas/i386/x86-64-notrack.d: Likewise.
|
||||
* testsuite/gas/i386/x86-64-notrack.s: Likewise.
|
||||
* testsuite/gas/i386/x86-64-notrackbad.l: Likewise.
|
||||
* testsuite/gas/i386/x86-64-notrackbad.s: Likewise.
|
||||
|
||||
2017-05-22 Jiong Wang <jiong.wang@arm.com>
|
||||
|
||||
* configure.tgt: Set "arch" to "aarch64" if ${cpu} equals "aarch64".
|
||||
|
|
|
@ -66,8 +66,11 @@
|
|||
#define HLE_PREFIX REP_PREFIX
|
||||
#define BND_PREFIX REP_PREFIX
|
||||
#define LOCK_PREFIX 5
|
||||
#define REX_PREFIX 6 /* must come last. */
|
||||
#define MAX_PREFIXES 7 /* max prefixes per opcode */
|
||||
/* Only one of NOTRACK_PREFIX and SEG_PREFIX can be used at the same
|
||||
time. */
|
||||
#define NOTRACK_PREFIX 6
|
||||
#define REX_PREFIX 7 /* must come last. */
|
||||
#define MAX_PREFIXES 8 /* max prefixes per opcode */
|
||||
|
||||
/* we define the syntax here (modulo base,index,scale syntax) */
|
||||
#define REGISTER_PREFIX '%'
|
||||
|
@ -388,6 +391,9 @@ struct _i386_insn
|
|||
/* Have BND prefix. */
|
||||
const char *bnd_prefix;
|
||||
|
||||
/* Have NOTRACK prefix. */
|
||||
const char *notrack_prefix;
|
||||
|
||||
/* Error message. */
|
||||
enum i386_error error;
|
||||
};
|
||||
|
@ -2144,6 +2150,7 @@ enum PREFIX_GROUP
|
|||
PREFIX_EXIST = 0,
|
||||
PREFIX_LOCK,
|
||||
PREFIX_REP,
|
||||
PREFIX_DS,
|
||||
PREFIX_OTHER
|
||||
};
|
||||
|
||||
|
@ -2152,7 +2159,8 @@ enum PREFIX_GROUP
|
|||
same class already exists.
|
||||
b. PREFIX_LOCK if lock prefix is added.
|
||||
c. PREFIX_REP if rep/repne prefix is added.
|
||||
d. PREFIX_OTHER if other prefix is added.
|
||||
d. PREFIX_DS if ds prefix is added.
|
||||
e. PREFIX_OTHER if other prefix is added.
|
||||
*/
|
||||
|
||||
static enum PREFIX_GROUP
|
||||
|
@ -2177,8 +2185,10 @@ add_prefix (unsigned int prefix)
|
|||
default:
|
||||
abort ();
|
||||
|
||||
case CS_PREFIX_OPCODE:
|
||||
case DS_PREFIX_OPCODE:
|
||||
ret = PREFIX_DS;
|
||||
/* Fall through. */
|
||||
case CS_PREFIX_OPCODE:
|
||||
case ES_PREFIX_OPCODE:
|
||||
case FS_PREFIX_OPCODE:
|
||||
case GS_PREFIX_OPCODE:
|
||||
|
@ -3702,6 +3712,15 @@ md_assemble (char *line)
|
|||
if (i.bnd_prefix && !i.tm.opcode_modifier.bndprefixok)
|
||||
as_bad (_("expecting valid branch instruction after `bnd'"));
|
||||
|
||||
/* Check NOTRACK prefix. */
|
||||
if (i.notrack_prefix
|
||||
&& (!i.tm.opcode_modifier.notrackprefixok
|
||||
|| i.reg_operands != 1
|
||||
|| i.disp_operands != 0
|
||||
|| i.mem_operands != 0
|
||||
|| i.imm_operands != 0))
|
||||
as_bad (_("expecting register indirect branch instruction after `notrack'"));
|
||||
|
||||
if (i.tm.cpu_flags.bitfield.cpumpx)
|
||||
{
|
||||
if (flag_code == CODE_64BIT && i.prefix[ADDR_PREFIX])
|
||||
|
@ -3964,20 +3983,42 @@ parse_insn (char *line, char *mnemonic)
|
|||
else
|
||||
{
|
||||
/* Add prefix, checking for repeated prefixes. */
|
||||
switch (add_prefix (current_templates->start->base_opcode))
|
||||
enum PREFIX_GROUP p
|
||||
= add_prefix (current_templates->start->base_opcode);
|
||||
if (p == PREFIX_DS
|
||||
&& current_templates->start->cpu_flags.bitfield.cpucet)
|
||||
{
|
||||
case PREFIX_EXIST:
|
||||
return NULL;
|
||||
case PREFIX_REP:
|
||||
if (current_templates->start->cpu_flags.bitfield.cpuhle)
|
||||
i.hle_prefix = current_templates->start->name;
|
||||
else if (current_templates->start->cpu_flags.bitfield.cpumpx)
|
||||
i.bnd_prefix = current_templates->start->name;
|
||||
else
|
||||
i.rep_prefix = current_templates->start->name;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
i.notrack_prefix = current_templates->start->name;
|
||||
/* Move NOTRACK_PREFIX_OPCODE to NOTRACK_PREFIX slot so
|
||||
that it is placed before others. */
|
||||
i.prefix[SEG_PREFIX] = 0;
|
||||
i.prefix[NOTRACK_PREFIX] = NOTRACK_PREFIX_OPCODE;
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (p)
|
||||
{
|
||||
case PREFIX_EXIST:
|
||||
return NULL;
|
||||
case PREFIX_REP:
|
||||
if (current_templates->start->cpu_flags.bitfield.cpuhle)
|
||||
i.hle_prefix = current_templates->start->name;
|
||||
else if (current_templates->start->cpu_flags.bitfield.cpumpx)
|
||||
i.bnd_prefix = current_templates->start->name;
|
||||
else
|
||||
i.rep_prefix = current_templates->start->name;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (i.notrack_prefix != NULL)
|
||||
{
|
||||
/* There must be no other prefixes after NOTRACK
|
||||
prefix. */
|
||||
as_bad (_("expecting no other prefixes after `notrack'"));
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Skip past PREFIX_SEPARATOR and reset token_start. */
|
||||
|
|
|
@ -385,6 +385,9 @@ if [expr ([istarget "i*86-*-*"] || [istarget "x86_64-*-*"]) && [gas_32_check]]
|
|||
run_dump_test "cet"
|
||||
run_dump_test "cet-intel"
|
||||
run_dump_test "pseudos"
|
||||
run_dump_test "notrack"
|
||||
run_dump_test "notrack-intel"
|
||||
run_list_test "notrackbad" "-al"
|
||||
|
||||
# These tests require support for 8 and 16 bit relocs,
|
||||
# so we only run them for ELF and COFF targets.
|
||||
|
@ -805,6 +808,9 @@ if [expr ([istarget "i*86-*-*"] || [istarget "x86_64-*-*"]) && [gas_64_check]] t
|
|||
run_dump_test "x86-64-cet"
|
||||
run_dump_test "x86-64-cet-intel"
|
||||
run_dump_test "x86-64-pseudos"
|
||||
run_dump_test "x86-64-notrack"
|
||||
run_dump_test "x86-64-notrack-intel"
|
||||
run_list_test "x86-64-notrackbad" "-al"
|
||||
|
||||
if { ![istarget "*-*-aix*"]
|
||||
&& ![istarget "*-*-beos*"]
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
#source: notrack.s
|
||||
#objdump: -dw -Mintel
|
||||
#name: i386 NOTRACK prefix (Intel disassembly)
|
||||
|
||||
.*: +file format .*
|
||||
|
||||
|
||||
Disassembly of section .text:
|
||||
|
||||
0+ <_start>:
|
||||
[ ]*[a-f0-9]+: 3e ff d0 notrack call eax
|
||||
[ ]*[a-f0-9]+: 66 3e ff d0 notrack call ax
|
||||
[ ]*[a-f0-9]+: 3e ff e0 notrack jmp eax
|
||||
[ ]*[a-f0-9]+: 66 3e ff e0 notrack jmp ax
|
||||
[ ]*[a-f0-9]+: f2 3e ff d0 bnd notrack call eax
|
||||
[ ]*[a-f0-9]+: 66 f2 3e ff d0 bnd notrack call ax
|
||||
[ ]*[a-f0-9]+: f2 3e ff e0 bnd notrack jmp eax
|
||||
[ ]*[a-f0-9]+: 66 f2 3e ff e0 bnd notrack jmp ax
|
||||
[ ]*[a-f0-9]+: 3e ff d0 notrack call eax
|
||||
[ ]*[a-f0-9]+: 66 3e ff d0 notrack call ax
|
||||
[ ]*[a-f0-9]+: 3e ff e0 notrack jmp eax
|
||||
[ ]*[a-f0-9]+: 66 3e ff e0 notrack jmp ax
|
||||
[ ]*[a-f0-9]+: f2 3e ff d0 bnd notrack call eax
|
||||
[ ]*[a-f0-9]+: 66 f2 3e ff d0 bnd notrack call ax
|
||||
[ ]*[a-f0-9]+: f2 3e ff e0 bnd notrack jmp eax
|
||||
[ ]*[a-f0-9]+: 66 f2 3e ff e0 bnd notrack jmp ax
|
||||
[ ]*[a-f0-9]+: 3e f2 ff d0 ds bnd call eax
|
||||
[ ]*[a-f0-9]+: 3e 66 ff d0 ds call ax
|
||||
#pass
|
|
@ -0,0 +1,28 @@
|
|||
#objdump: -dw
|
||||
#name: i386 NOTRACK prefix
|
||||
|
||||
.*: +file format .*
|
||||
|
||||
|
||||
Disassembly of section .text:
|
||||
|
||||
0+ <_start>:
|
||||
[ ]*[a-f0-9]+: 3e ff d0 notrack call \*%eax
|
||||
[ ]*[a-f0-9]+: 66 3e ff d0 notrack callw \*%ax
|
||||
[ ]*[a-f0-9]+: 3e ff e0 notrack jmp \*%eax
|
||||
[ ]*[a-f0-9]+: 66 3e ff e0 notrack jmpw \*%ax
|
||||
[ ]*[a-f0-9]+: f2 3e ff d0 bnd notrack call \*%eax
|
||||
[ ]*[a-f0-9]+: 66 f2 3e ff d0 bnd notrack callw \*%ax
|
||||
[ ]*[a-f0-9]+: f2 3e ff e0 bnd notrack jmp \*%eax
|
||||
[ ]*[a-f0-9]+: 66 f2 3e ff e0 bnd notrack jmpw \*%ax
|
||||
[ ]*[a-f0-9]+: 3e ff d0 notrack call \*%eax
|
||||
[ ]*[a-f0-9]+: 66 3e ff d0 notrack callw \*%ax
|
||||
[ ]*[a-f0-9]+: 3e ff e0 notrack jmp \*%eax
|
||||
[ ]*[a-f0-9]+: 66 3e ff e0 notrack jmpw \*%ax
|
||||
[ ]*[a-f0-9]+: f2 3e ff d0 bnd notrack call \*%eax
|
||||
[ ]*[a-f0-9]+: 66 f2 3e ff d0 bnd notrack callw \*%ax
|
||||
[ ]*[a-f0-9]+: f2 3e ff e0 bnd notrack jmp \*%eax
|
||||
[ ]*[a-f0-9]+: 66 f2 3e ff e0 bnd notrack jmpw \*%ax
|
||||
[ ]*[a-f0-9]+: 3e f2 ff d0 ds bnd call \*%eax
|
||||
[ ]*[a-f0-9]+: 3e 66 ff d0 ds callw \*%ax
|
||||
#pass
|
|
@ -0,0 +1,35 @@
|
|||
# Check 32bit NOTRACK prefix
|
||||
|
||||
.allow_index_reg
|
||||
.text
|
||||
_start:
|
||||
notrack call *%eax
|
||||
notrack call *%ax
|
||||
notrack jmp *%eax
|
||||
notrack jmp *%ax
|
||||
|
||||
bnd notrack call *%eax
|
||||
bnd notrack call *%ax
|
||||
bnd notrack jmp *%eax
|
||||
bnd notrack jmp *%ax
|
||||
|
||||
.intel_syntax noprefix
|
||||
notrack call eax
|
||||
notrack call ax
|
||||
notrack jmp eax
|
||||
notrack jmp ax
|
||||
|
||||
bnd notrack call eax
|
||||
bnd notrack call ax
|
||||
bnd notrack jmp eax
|
||||
bnd notrack jmp ax
|
||||
|
||||
.byte 0x3e
|
||||
.byte 0xf2
|
||||
.byte 0xff
|
||||
.byte 0xd0
|
||||
|
||||
.byte 0x3e
|
||||
.byte 0x66
|
||||
.byte 0xff
|
||||
.byte 0xd0
|
|
@ -0,0 +1,52 @@
|
|||
.*: Assembler messages:
|
||||
.*:6: Error: expecting register indirect branch instruction after `notrack'
|
||||
.*:6: Warning: skipping prefixes on this instruction
|
||||
.*:7: Error: expecting register indirect branch instruction after `notrack'
|
||||
.*:7: Warning: skipping prefixes on this instruction
|
||||
.*:9: Error: expecting register indirect branch instruction after `notrack'
|
||||
.*:10: Error: expecting register indirect branch instruction after `notrack'
|
||||
.*:11: Error: same type of prefix used twice
|
||||
.*:12: Error: expecting no other prefixes after `notrack'
|
||||
.*:13: Error: expecting no other prefixes after `notrack'
|
||||
.*:14: Error: expecting no other prefixes after `notrack'
|
||||
.*:17: Error: expecting register indirect branch instruction after `notrack'
|
||||
.*:18: Error: expecting register indirect branch instruction after `notrack'
|
||||
.*:19: Error: same type of prefix used twice
|
||||
.*:20: Error: expecting no other prefixes after `notrack'
|
||||
.*:21: Error: expecting no other prefixes after `notrack'
|
||||
.*:22: Error: expecting no other prefixes after `notrack'
|
||||
GAS LISTING .*
|
||||
|
||||
|
||||
[ ]*1[ ]+\# Check 32bit unsupported NOTRACK prefix
|
||||
[ ]*2[ ]+
|
||||
[ ]*3[ ]+\.allow_index_reg
|
||||
[ ]*4[ ]+\.text
|
||||
[ ]*5[ ]+_start:
|
||||
[ ]*6[ ]+\?\?\?\? E8FCFFFF notrack call foo
|
||||
\*\*\*\* Error: expecting register indirect branch instruction after `notrack'
|
||||
\*\*\*\* Warning: skipping prefixes on this instruction
|
||||
[ ]*6[ ]+FF
|
||||
[ ]*7[ ]+\?\?\?\? E9FCFFFF notrack jmp foo
|
||||
\*\*\*\* Error: expecting register indirect branch instruction after `notrack'
|
||||
\*\*\*\* Warning: skipping prefixes on this instruction
|
||||
[ ]*7[ ]+FF
|
||||
[ ]*8[ ]+
|
||||
[ ]*9[ ]+\?\?\?\? 3EFF10 notrack call \*\(%eax\)
|
||||
\*\*\*\* Error: expecting register indirect branch instruction after `notrack'
|
||||
[ ]*10[ ]+\?\?\?\? 3EFF20 notrack jmp \*\(%eax\)
|
||||
\*\*\*\* Error: expecting register indirect branch instruction after `notrack'
|
||||
[ ]*11[ ]+fs notrack call \*%eax
|
||||
[ ]*12[ ]+notrack fs call \*%eax
|
||||
[ ]*13[ ]+notrack bnd call \*%eax
|
||||
[ ]*14[ ]+notrack data16 call \*%eax
|
||||
[ ]*15[ ]+
|
||||
[ ]*16[ ]+\.intel_syntax noprefix
|
||||
[ ]*17[ ]+\?\?\?\? 3EFF10 notrack call \[eax\]
|
||||
\*\*\*\* Error: expecting register indirect branch instruction after `notrack'
|
||||
[ ]*18[ ]+\?\?\?\? 3EFF20 notrack jmp \[eax\]
|
||||
\*\*\*\* Error: expecting register indirect branch instruction after `notrack'
|
||||
[ ]*19[ ]+fs notrack call eax
|
||||
[ ]*20[ ]+notrack fs call eax
|
||||
[ ]*21[ ]+notrack bnd call eax
|
||||
[ ]*22[ ]+notrack data16 call eax
|
|
@ -0,0 +1,22 @@
|
|||
# Check 32bit unsupported NOTRACK prefix
|
||||
|
||||
.allow_index_reg
|
||||
.text
|
||||
_start:
|
||||
notrack call foo
|
||||
notrack jmp foo
|
||||
|
||||
notrack call *(%eax)
|
||||
notrack jmp *(%eax)
|
||||
fs notrack call *%eax
|
||||
notrack fs call *%eax
|
||||
notrack bnd call *%eax
|
||||
notrack data16 call *%eax
|
||||
|
||||
.intel_syntax noprefix
|
||||
notrack call [eax]
|
||||
notrack jmp [eax]
|
||||
fs notrack call eax
|
||||
notrack fs call eax
|
||||
notrack bnd call eax
|
||||
notrack data16 call eax
|
|
@ -0,0 +1,30 @@
|
|||
#source: x86-64-notrack.s
|
||||
#objdump: -dw -Mintel
|
||||
#name: x86-64 NOTRACK prefix (Intel disassembly)
|
||||
|
||||
.*: +file format .*
|
||||
|
||||
|
||||
Disassembly of section .text:
|
||||
|
||||
0+ <_start>:
|
||||
[ ]*[a-f0-9]+: 3e ff d0 notrack call rax
|
||||
[ ]*[a-f0-9]+: 3e 41 ff d0 notrack call r8
|
||||
[ ]*[a-f0-9]+: 3e ff e0 notrack jmp rax
|
||||
[ ]*[a-f0-9]+: 3e 41 ff e0 notrack jmp r8
|
||||
[ ]*[a-f0-9]+: f2 3e ff d0 bnd notrack call rax
|
||||
[ ]*[a-f0-9]+: f2 3e 41 ff d0 bnd notrack call r8
|
||||
[ ]*[a-f0-9]+: f2 3e ff e0 bnd notrack jmp rax
|
||||
[ ]*[a-f0-9]+: f2 3e 41 ff e0 bnd notrack jmp r8
|
||||
[ ]*[a-f0-9]+: 3e ff d0 notrack call rax
|
||||
[ ]*[a-f0-9]+: 3e 41 ff d0 notrack call r8
|
||||
[ ]*[a-f0-9]+: 3e ff e0 notrack jmp rax
|
||||
[ ]*[a-f0-9]+: 3e 41 ff e0 notrack jmp r8
|
||||
[ ]*[a-f0-9]+: f2 3e ff d0 bnd notrack call rax
|
||||
[ ]*[a-f0-9]+: f2 3e 41 ff d0 bnd notrack call r8
|
||||
[ ]*[a-f0-9]+: f2 3e ff e0 bnd notrack jmp rax
|
||||
[ ]*[a-f0-9]+: f2 3e 41 ff e0 bnd notrack jmp r8
|
||||
[ ]*[a-f0-9]+: 3e f2 ff d0 ds bnd call rax
|
||||
[ ]*[a-f0-9]+: 3e 66 ff d0 ds call ax
|
||||
[ ]*[a-f0-9]+: 66 3e ff d0 ds call ax
|
||||
#pass
|
|
@ -0,0 +1,29 @@
|
|||
#objdump: -dw
|
||||
#name: x86-64 NOTRACK prefix
|
||||
|
||||
.*: +file format .*
|
||||
|
||||
|
||||
Disassembly of section .text:
|
||||
|
||||
0+ <_start>:
|
||||
[ ]*[a-f0-9]+: 3e ff d0 notrack callq \*%rax
|
||||
[ ]*[a-f0-9]+: 3e 41 ff d0 notrack callq \*%r8
|
||||
[ ]*[a-f0-9]+: 3e ff e0 notrack jmpq \*%rax
|
||||
[ ]*[a-f0-9]+: 3e 41 ff e0 notrack jmpq \*%r8
|
||||
[ ]*[a-f0-9]+: f2 3e ff d0 bnd notrack callq \*%rax
|
||||
[ ]*[a-f0-9]+: f2 3e 41 ff d0 bnd notrack callq \*%r8
|
||||
[ ]*[a-f0-9]+: f2 3e ff e0 bnd notrack jmpq \*%rax
|
||||
[ ]*[a-f0-9]+: f2 3e 41 ff e0 bnd notrack jmpq \*%r8
|
||||
[ ]*[a-f0-9]+: 3e ff d0 notrack callq \*%rax
|
||||
[ ]*[a-f0-9]+: 3e 41 ff d0 notrack callq \*%r8
|
||||
[ ]*[a-f0-9]+: 3e ff e0 notrack jmpq \*%rax
|
||||
[ ]*[a-f0-9]+: 3e 41 ff e0 notrack jmpq \*%r8
|
||||
[ ]*[a-f0-9]+: f2 3e ff d0 bnd notrack callq \*%rax
|
||||
[ ]*[a-f0-9]+: f2 3e 41 ff d0 bnd notrack callq \*%r8
|
||||
[ ]*[a-f0-9]+: f2 3e ff e0 bnd notrack jmpq \*%rax
|
||||
[ ]*[a-f0-9]+: f2 3e 41 ff e0 bnd notrack jmpq \*%r8
|
||||
[ ]*[a-f0-9]+: 3e f2 ff d0 ds bnd callq \*%rax
|
||||
[ ]*[a-f0-9]+: 3e 66 ff d0 ds callw \*%ax
|
||||
[ ]*[a-f0-9]+: 66 3e ff d0 ds callw \*%ax
|
||||
#pass
|
|
@ -0,0 +1,40 @@
|
|||
# Check 64bit NOTRACK prefix
|
||||
|
||||
.allow_index_reg
|
||||
.text
|
||||
_start:
|
||||
notrack call *%rax
|
||||
notrack call *%r8
|
||||
notrack jmp *%rax
|
||||
notrack jmp *%r8
|
||||
|
||||
bnd notrack call *%rax
|
||||
bnd notrack call *%r8
|
||||
bnd notrack jmp *%rax
|
||||
bnd notrack jmp *%r8
|
||||
|
||||
.intel_syntax noprefix
|
||||
notrack call rax
|
||||
notrack call r8
|
||||
notrack jmp rax
|
||||
notrack jmp r8
|
||||
|
||||
bnd notrack call rax
|
||||
bnd notrack call r8
|
||||
bnd notrack jmp rax
|
||||
bnd notrack jmp r8
|
||||
|
||||
.byte 0x3e
|
||||
.byte 0xf2
|
||||
.byte 0xff
|
||||
.byte 0xd0
|
||||
|
||||
.byte 0x3e
|
||||
.byte 0x66
|
||||
.byte 0xff
|
||||
.byte 0xd0
|
||||
|
||||
.byte 0x66
|
||||
.byte 0x3e
|
||||
.byte 0xff
|
||||
.byte 0xd0
|
|
@ -0,0 +1,52 @@
|
|||
.*: Assembler messages:
|
||||
.*:6: Error: expecting register indirect branch instruction after `notrack'
|
||||
.*:6: Warning: skipping prefixes on this instruction
|
||||
.*:7: Error: expecting register indirect branch instruction after `notrack'
|
||||
.*:7: Warning: skipping prefixes on this instruction
|
||||
.*:9: Error: expecting register indirect branch instruction after `notrack'
|
||||
.*:10: Error: expecting register indirect branch instruction after `notrack'
|
||||
.*:11: Error: same type of prefix used twice
|
||||
.*:12: Error: expecting no other prefixes after `notrack'
|
||||
.*:13: Error: expecting no other prefixes after `notrack'
|
||||
.*:14: Error: expecting no other prefixes after `notrack'
|
||||
.*:17: Error: expecting register indirect branch instruction after `notrack'
|
||||
.*:18: Error: expecting register indirect branch instruction after `notrack'
|
||||
.*:19: Error: same type of prefix used twice
|
||||
.*:20: Error: expecting no other prefixes after `notrack'
|
||||
.*:21: Error: expecting no other prefixes after `notrack'
|
||||
.*:22: Error: expecting no other prefixes after `notrack'
|
||||
GAS LISTING .*
|
||||
|
||||
|
||||
[ ]*1[ ]+\# Check 64bit unsupported NOTRACK prefix
|
||||
[ ]*2[ ]+
|
||||
[ ]*3[ ]+\.allow_index_reg
|
||||
[ ]*4[ ]+\.text
|
||||
[ ]*5[ ]+_start:
|
||||
[ ]*6[ ]+\?\?\?\? E8000000 notrack call foo
|
||||
\*\*\*\* Error: expecting register indirect branch instruction after `notrack'
|
||||
\*\*\*\* Warning: skipping prefixes on this instruction
|
||||
[ ]*6[ ]+00
|
||||
[ ]*7[ ]+\?\?\?\? E9000000 notrack jmp foo
|
||||
\*\*\*\* Error: expecting register indirect branch instruction after `notrack'
|
||||
\*\*\*\* Warning: skipping prefixes on this instruction
|
||||
[ ]*7[ ]+00
|
||||
[ ]*8[ ]+
|
||||
[ ]*9[ ]+\?\?\?\? 3EFF10 notrack call \*\(%rax\)
|
||||
\*\*\*\* Error: expecting register indirect branch instruction after `notrack'
|
||||
[ ]*10[ ]+\?\?\?\? 3EFF20 notrack jmp \*\(%rax\)
|
||||
\*\*\*\* Error: expecting register indirect branch instruction after `notrack'
|
||||
[ ]*11[ ]+fs notrack call \*%rax
|
||||
[ ]*12[ ]+notrack fs call \*%rax
|
||||
[ ]*13[ ]+notrack bnd call \*%rax
|
||||
[ ]*14[ ]+notrack data16 call \*%rax
|
||||
[ ]*15[ ]+
|
||||
[ ]*16[ ]+\.intel_syntax noprefix
|
||||
[ ]*17[ ]+\?\?\?\? 3EFF10 notrack call \[rax\]
|
||||
\*\*\*\* Error: expecting register indirect branch instruction after `notrack'
|
||||
[ ]*18[ ]+\?\?\?\? 3EFF20 notrack jmp \[rax\]
|
||||
\*\*\*\* Error: expecting register indirect branch instruction after `notrack'
|
||||
[ ]*19[ ]+fs notrack call rax
|
||||
[ ]*20[ ]+notrack fs call rax
|
||||
[ ]*21[ ]+notrack bnd call rax
|
||||
[ ]*22[ ]+notrack data16 call rax
|
|
@ -0,0 +1,22 @@
|
|||
# Check 64bit unsupported NOTRACK prefix
|
||||
|
||||
.allow_index_reg
|
||||
.text
|
||||
_start:
|
||||
notrack call foo
|
||||
notrack jmp foo
|
||||
|
||||
notrack call *(%rax)
|
||||
notrack jmp *(%rax)
|
||||
fs notrack call *%rax
|
||||
notrack fs call *%rax
|
||||
notrack bnd call *%rax
|
||||
notrack data16 call *%rax
|
||||
|
||||
.intel_syntax noprefix
|
||||
notrack call [rax]
|
||||
notrack jmp [rax]
|
||||
fs notrack call rax
|
||||
notrack fs call rax
|
||||
notrack bnd call rax
|
||||
notrack data16 call rax
|
|
@ -1,3 +1,7 @@
|
|||
2017-05-22 H.J. Lu <hongjiu.lu@intel.com>
|
||||
|
||||
* include/opcode/i386.h (NOTRACK_PREFIX_OPCODE): New.
|
||||
|
||||
2017-05-19 Jose E. Marchesi <jose.marchesi@oracle.com>
|
||||
|
||||
* elf/sparc.h (ELF_SPARC_HWCAP2_SPARC6): Define.
|
||||
|
|
|
@ -77,6 +77,7 @@
|
|||
#define XACQUIRE_PREFIX_OPCODE 0xf2
|
||||
#define XRELEASE_PREFIX_OPCODE 0xf3
|
||||
#define BND_PREFIX_OPCODE 0xf2
|
||||
#define NOTRACK_PREFIX_OPCODE 0x3e
|
||||
|
||||
#define TWO_BYTE_OPCODE_ESCAPE 0x0f
|
||||
#define NOP_OPCODE (char) 0x90
|
||||
|
|
|
@ -1,3 +1,19 @@
|
|||
2017-05-22 H.J. Lu <hongjiu.lu@intel.com>
|
||||
|
||||
* i386-dis.c (NOTRACK_Fixup): New.
|
||||
(NOTRACK): Likewise.
|
||||
(NOTRACK_PREFIX): Likewise.
|
||||
(last_active_prefix): Likewise.
|
||||
(reg_table): Use NOTRACK on indirect call and jmp.
|
||||
(ckprefix): Set last_active_prefix.
|
||||
(prefix_name): Return "notrack" for NOTRACK_PREFIX.
|
||||
* i386-gen.c (opcode_modifiers): Add NoTrackPrefixOk.
|
||||
* i386-opc.h (NoTrackPrefixOk): New.
|
||||
(i386_opcode_modifier): Add notrackprefixok.
|
||||
* i386-opc.tbl: Add NoTrackPrefixOk to indirect call and jmp.
|
||||
Add notrack.
|
||||
* i386-tbl.h: Regenerated.
|
||||
|
||||
2017-05-19 Jose E. Marchesi <jose.marchesi@oracle.com>
|
||||
|
||||
* sparc-dis.c (MASK_V9): Include SPARC_OPCODE_ARCH_M8.
|
||||
|
|
|
@ -110,6 +110,7 @@ static void CMP_Fixup (int, int);
|
|||
static void BadOp (void);
|
||||
static void REP_Fixup (int, int);
|
||||
static void BND_Fixup (int, int);
|
||||
static void NOTRACK_Fixup (int, int);
|
||||
static void HLE_Fixup1 (int, int);
|
||||
static void HLE_Fixup2 (int, int);
|
||||
static void HLE_Fixup3 (int, int);
|
||||
|
@ -473,6 +474,7 @@ fetch_data (struct disassemble_info *info, bfd_byte *addr)
|
|||
#define Evh3 { HLE_Fixup3, v_mode }
|
||||
|
||||
#define BND { BND_Fixup, 0 }
|
||||
#define NOTRACK { NOTRACK_Fixup, 0 }
|
||||
|
||||
#define cond_jump_flag { NULL, cond_jump_mode }
|
||||
#define loop_jcxz_flag { NULL, loop_jcxz_mode }
|
||||
|
@ -3167,6 +3169,7 @@ static int last_data_prefix;
|
|||
static int last_addr_prefix;
|
||||
static int last_rex_prefix;
|
||||
static int last_seg_prefix;
|
||||
static int last_active_prefix;
|
||||
static int fwait_prefix;
|
||||
/* The active segment register prefix. */
|
||||
static int active_seg_prefix;
|
||||
|
@ -3549,9 +3552,9 @@ static const struct dis386 reg_table[][8] = {
|
|||
{
|
||||
{ "incQ", { Evh1 }, 0 },
|
||||
{ "decQ", { Evh1 }, 0 },
|
||||
{ "call{&|}", { indirEv, BND }, 0 },
|
||||
{ "call{&|}", { indirEv, NOTRACK, BND }, 0 },
|
||||
{ MOD_TABLE (MOD_FF_REG_3) },
|
||||
{ "jmp{&|}", { indirEv, BND }, 0 },
|
||||
{ "jmp{&|}", { indirEv, NOTRACK, BND }, 0 },
|
||||
{ MOD_TABLE (MOD_FF_REG_5) },
|
||||
{ "pushU", { stackEv }, 0 },
|
||||
{ Bad_Opcode },
|
||||
|
@ -12281,6 +12284,7 @@ static const struct dis386 rm_table[][8] = {
|
|||
#define XACQUIRE_PREFIX (0xf2 | 0x200)
|
||||
#define XRELEASE_PREFIX (0xf3 | 0x400)
|
||||
#define BND_PREFIX (0xf2 | 0x400)
|
||||
#define NOTRACK_PREFIX (0x3e | 0x100)
|
||||
|
||||
static int
|
||||
ckprefix (void)
|
||||
|
@ -12298,6 +12302,7 @@ ckprefix (void)
|
|||
last_addr_prefix = -1;
|
||||
last_rex_prefix = -1;
|
||||
last_seg_prefix = -1;
|
||||
last_active_prefix = -1;
|
||||
fwait_prefix = -1;
|
||||
active_seg_prefix = 0;
|
||||
for (i = 0; i < (int) ARRAY_SIZE (all_prefixes); i++)
|
||||
|
@ -12410,7 +12415,10 @@ ckprefix (void)
|
|||
return 1;
|
||||
}
|
||||
if (*codep != FWAIT_OPCODE)
|
||||
all_prefixes[i++] = *codep;
|
||||
{
|
||||
last_active_prefix = i;
|
||||
all_prefixes[i++] = *codep;
|
||||
}
|
||||
rex = newrex;
|
||||
codep++;
|
||||
length++;
|
||||
|
@ -12499,6 +12507,8 @@ prefix_name (int pref, int sizeflag)
|
|||
return "xrelease";
|
||||
case BND_PREFIX:
|
||||
return "bnd";
|
||||
case NOTRACK_PREFIX:
|
||||
return "notrack";
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
|
@ -16789,6 +16799,34 @@ BND_Fixup (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
|
|||
all_prefixes[last_repnz_prefix] = BND_PREFIX;
|
||||
}
|
||||
|
||||
/* For NOTRACK-prefixed instructions, 0x3E prefix should be displayed as
|
||||
"notrack". */
|
||||
|
||||
static void
|
||||
NOTRACK_Fixup (int bytemode ATTRIBUTE_UNUSED,
|
||||
int sizeflag ATTRIBUTE_UNUSED)
|
||||
{
|
||||
if (modrm.mod == 3
|
||||
&& active_seg_prefix == PREFIX_DS
|
||||
&& (address_mode != mode_64bit || last_data_prefix < 0))
|
||||
{
|
||||
/* NOTRACK prefix is only valid on register indirect branch
|
||||
instructions and it must be the last prefix before REX
|
||||
prefix and opcode. NB: DATA prefix is unsupported for
|
||||
Intel64. */
|
||||
if (last_active_prefix >= 0)
|
||||
{
|
||||
int notrack_prefix = last_active_prefix;
|
||||
if (last_rex_prefix == last_active_prefix)
|
||||
notrack_prefix--;
|
||||
if (all_prefixes[notrack_prefix] != NOTRACK_PREFIX_OPCODE)
|
||||
return;
|
||||
}
|
||||
active_seg_prefix = 0;
|
||||
all_prefixes[last_seg_prefix] = NOTRACK_PREFIX;
|
||||
}
|
||||
}
|
||||
|
||||
/* Similar to OP_E. But the 0xf2/0xf3 prefixes should be displayed as
|
||||
"xacquire"/"xrelease" for memory operand if there is a LOCK prefix.
|
||||
*/
|
||||
|
|
|
@ -566,6 +566,7 @@ static bitfield opcode_modifiers[] =
|
|||
BITFIELD (FWait),
|
||||
BITFIELD (IsString),
|
||||
BITFIELD (BNDPrefixOk),
|
||||
BITFIELD (NoTrackPrefixOk),
|
||||
BITFIELD (IsLockable),
|
||||
BITFIELD (RegKludge),
|
||||
BITFIELD (FirstXmm0),
|
||||
|
|
|
@ -407,6 +407,8 @@ enum
|
|||
IsString,
|
||||
/* quick test if branch instruction is MPX supported */
|
||||
BNDPrefixOk,
|
||||
/* quick test if NOTRACK prefix is supported */
|
||||
NoTrackPrefixOk,
|
||||
/* quick test for lockable instructions */
|
||||
IsLockable,
|
||||
/* fake an extra reg operand for clr, imul and special register
|
||||
|
@ -622,6 +624,7 @@ typedef struct i386_opcode_modifier
|
|||
unsigned int fwait:1;
|
||||
unsigned int isstring:1;
|
||||
unsigned int bndprefixok:1;
|
||||
unsigned int notrackprefixok:1;
|
||||
unsigned int islockable:1;
|
||||
unsigned int regkludge:1;
|
||||
unsigned int firstxmm0:1;
|
||||
|
|
|
@ -312,9 +312,9 @@ shrd, 2, 0xfad, None, 2, Cpu386, Modrm|CheckRegSize|No_bSuf|No_sSuf|No_ldSuf, {
|
|||
call, 1, 0xe8, None, 1, CpuNo64, JumpDword|DefaultSize|No_bSuf|No_sSuf|No_qSuf|No_ldSuf|BNDPrefixOk, { Disp16|Disp32 }
|
||||
call, 1, 0xe8, None, 1, Cpu64, AMD64|JumpDword|DefaultSize|No_bSuf|No_lSuf|No_sSuf|No_ldSuf|NoRex64|BNDPrefixOk, { Disp16|Disp32S }
|
||||
call, 1, 0xe8, None, 1, Cpu64, Intel64|JumpDword|DefaultSize|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_ldSuf|NoRex64|BNDPrefixOk, { Disp32S }
|
||||
call, 1, 0xff, 0x2, 1, CpuNo64, Modrm|DefaultSize|No_bSuf|No_sSuf|No_qSuf|No_ldSuf|BNDPrefixOk, { Reg16|Reg32|Word|Dword|Unspecified|BaseIndex|Disp8|Disp16|Disp32|JumpAbsolute }
|
||||
call, 1, 0xff, 0x2, 1, Cpu64, AMD64|Modrm|DefaultSize|No_bSuf|No_lSuf|No_sSuf|No_ldSuf|NoRex64|BNDPrefixOk, { Reg16|Reg64|Word|Qword|Unspecified|BaseIndex|Disp8|Disp32|Disp32S|JumpAbsolute }
|
||||
call, 1, 0xff, 0x2, 1, Cpu64, Intel64|Modrm|DefaultSize|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_ldSuf|NoRex64|BNDPrefixOk, { Reg64|Qword|Unspecified|BaseIndex|Disp8|Disp32|Disp32S|JumpAbsolute }
|
||||
call, 1, 0xff, 0x2, 1, CpuNo64, Modrm|DefaultSize|No_bSuf|No_sSuf|No_qSuf|No_ldSuf|BNDPrefixOk|NoTrackPrefixOk, { Reg16|Reg32|Word|Dword|Unspecified|BaseIndex|Disp8|Disp16|Disp32|JumpAbsolute }
|
||||
call, 1, 0xff, 0x2, 1, Cpu64, AMD64|Modrm|DefaultSize|No_bSuf|No_lSuf|No_sSuf|No_ldSuf|NoRex64|BNDPrefixOk|NoTrackPrefixOk, { Reg16|Reg64|Word|Qword|Unspecified|BaseIndex|Disp8|Disp32|Disp32S|JumpAbsolute }
|
||||
call, 1, 0xff, 0x2, 1, Cpu64, Intel64|Modrm|DefaultSize|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_ldSuf|NoRex64|BNDPrefixOk|NoTrackPrefixOk, { Reg64|Qword|Unspecified|BaseIndex|Disp8|Disp32|Disp32S|JumpAbsolute }
|
||||
// Intel Syntax
|
||||
call, 2, 0x9a, None, 1, CpuNo64, JumpInterSegment|DefaultSize|No_bSuf|No_sSuf|No_qSuf|No_ldSuf, { Imm16, Imm16|Imm32 }
|
||||
// Intel Syntax
|
||||
|
@ -325,9 +325,9 @@ lcall, 1, 0xff, 0x3, 1, 0, Modrm|DefaultSize|No_bSuf|No_sSuf|No_qSuf|No_ldSuf, {
|
|||
jmp, 1, 0xeb, None, 1, CpuNo64, Jump|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf|BNDPrefixOk, { Disp8|Disp16|Disp32 }
|
||||
jmp, 1, 0xeb, None, 1, Cpu64, AMD64|Jump|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf|BNDPrefixOk, { Disp8|Disp16|Disp32S }
|
||||
jmp, 1, 0xeb, None, 1, Cpu64, Intel64|Jump|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf|BNDPrefixOk, { Disp8|Disp32S }
|
||||
jmp, 1, 0xff, 0x4, 1, CpuNo64, Modrm|No_bSuf|No_sSuf|No_qSuf|No_ldSuf|BNDPrefixOk, { Reg16|Reg32|Word|Dword|Unspecified|BaseIndex|Disp8|Disp16|Disp32|JumpAbsolute }
|
||||
jmp, 1, 0xff, 0x4, 1, Cpu64, AMD64|Modrm|No_bSuf|No_lSuf|No_sSuf|No_ldSuf|NoRex64|BNDPrefixOk, { Reg16|Reg64|Word|Qword|Unspecified|BaseIndex|Disp8|Disp32|Disp32S|JumpAbsolute }
|
||||
jmp, 1, 0xff, 0x4, 1, Cpu64, Intel64|Modrm|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_ldSuf|NoRex64|BNDPrefixOk, { Reg64|Qword|Unspecified|BaseIndex|Disp8|Disp32|Disp32S|JumpAbsolute }
|
||||
jmp, 1, 0xff, 0x4, 1, CpuNo64, Modrm|No_bSuf|No_sSuf|No_qSuf|No_ldSuf|BNDPrefixOk|NoTrackPrefixOk, { Reg16|Reg32|Word|Dword|Unspecified|BaseIndex|Disp8|Disp16|Disp32|JumpAbsolute }
|
||||
jmp, 1, 0xff, 0x4, 1, Cpu64, AMD64|Modrm|No_bSuf|No_lSuf|No_sSuf|No_ldSuf|NoRex64|BNDPrefixOk|NoTrackPrefixOk, { Reg16|Reg64|Word|Qword|Unspecified|BaseIndex|Disp8|Disp32|Disp32S|JumpAbsolute }
|
||||
jmp, 1, 0xff, 0x4, 1, Cpu64, Intel64|Modrm|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_ldSuf|NoRex64|BNDPrefixOk|NoTrackPrefixOk, { Reg64|Qword|Unspecified|BaseIndex|Disp8|Disp32|Disp32S|JumpAbsolute }
|
||||
// Intel Syntax.
|
||||
jmp, 2, 0xea, None, 1, CpuNo64, JumpInterSegment|No_bSuf|No_sSuf|No_qSuf|No_ldSuf, { Imm16, Imm16|Imm32 }
|
||||
// Intel Syntax.
|
||||
|
@ -6024,4 +6024,7 @@ clrssbsy, 1, 0xf30fae, 0x6, 2, CpuCET, Modrm|IgnoreSize|No_bSuf|No_wSuf|No_lSuf|
|
|||
endbr64, 0, 0xf30f1efa, None, 3, CpuCET, IgnoreSize|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf, { 0 }
|
||||
endbr32, 0, 0xf30f1efb, None, 3, CpuCET, IgnoreSize|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf, { 0 }
|
||||
|
||||
// notrack prefix
|
||||
notrack, 0, 0x3e, None, 1, CpuCET, No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf|IsPrefix, { 0 }
|
||||
|
||||
// CET instructions end.
|
||||
|
|
21299
opcodes/i386-tbl.h
21299
opcodes/i386-tbl.h
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue