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:
H.J. Lu 2017-05-22 11:02:46 -07:00
parent 25f9434737
commit 04ef582ace
21 changed files with 11157 additions and 10669 deletions

View File

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

View File

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

View File

@ -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*"]

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -566,6 +566,7 @@ static bitfield opcode_modifiers[] =
BITFIELD (FWait),
BITFIELD (IsString),
BITFIELD (BNDPrefixOk),
BITFIELD (NoTrackPrefixOk),
BITFIELD (IsLockable),
BITFIELD (RegKludge),
BITFIELD (FirstXmm0),

View File

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

View File

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

File diff suppressed because it is too large Load Diff