Skip to content

Commit

Permalink
i#5505 kernel tracing: Support clac and stac in DR decoder (#6484)
Browse files Browse the repository at this point in the history
Adds encoding-decoding support for clac and stac which are observed in
kernel traces.

decode_fast does not need any change and already should get the 3-byte
size correctly.

Adds EFLAGS_READ_AC and EFLAGS_WRITE_AC to track reads/writes to the
Alignment Check flag.
Currently we try to avoid a major binary compatibility break by adding
them to the end. This makes
some code more complicated. Added a TODO with #6485 to re-number when
we're about to do the
next major release.

Issue: #5505
Fixes: #2103
  • Loading branch information
abhinav92003 authored Nov 30, 2023
1 parent 2093cd1 commit 30031e0
Show file tree
Hide file tree
Showing 11 changed files with 61 additions and 21 deletions.
3 changes: 0 additions & 3 deletions clients/drcachesim/drpt2trace/pt2ir.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -388,9 +388,6 @@ pt2ir_t::convert(DR_PARAM_IN const uint8_t *pt_data, DR_PARAM_IN size_t pt_data_
instr_valid = true;
instr_set_translation(instr, (app_pc)insn.ip);
instr_allocate_raw_bits(drir.get_drcontext(), instr, insn.size);
/* TODO i#2103: Currently, the PT raw data may contain 'STAC' and 'CLAC'
* instructions that are not supported by Dynamorio.
*/
if (!instr_valid) {
/* The decode() function will not correctly identify the raw bits for
* invalid instruction. So we need to set the raw bits of instr manually.
Expand Down
22 changes: 18 additions & 4 deletions core/ir/instr_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -2550,6 +2550,7 @@ instr_is_reg_spill_or_restore(void *drcontext, instr_t *instr, bool *tls DR_PARA
# define EFLAGS_READ_OF 0x00000100 /**< Reads OF (Overflow Flag). */
# define EFLAGS_READ_NT 0x00000200 /**< Reads NT (Nested Task). */
# define EFLAGS_READ_RF 0x00000400 /**< Reads RF (Resume Flag). */

# define EFLAGS_WRITE_CF 0x00000800 /**< Writes CF (Carry Flag). */
# define EFLAGS_WRITE_PF 0x00001000 /**< Writes PF (Parity Flag). */
# define EFLAGS_WRITE_AF 0x00002000 /**< Writes AF (Auxiliary Carry Flag). */
Expand All @@ -2562,9 +2563,18 @@ instr_is_reg_spill_or_restore(void *drcontext, instr_t *instr, bool *tls DR_PARA
# define EFLAGS_WRITE_NT 0x00100000 /**< Writes NT (Nested Task). */
# define EFLAGS_WRITE_RF 0x00200000 /**< Writes RF (Resume Flag). */

# define EFLAGS_READ_ALL 0x000007ff /**< Reads all flags. */
/* TODO i#6485: Re-number the following when a major binary compatibility break
* is more convenient.
*/
/* OP_clac and OP_stac both write the AC flag. Even though we do not have an
* opcode that reads it, we still add EFLAGS_READ_AC for parity.
*/
# define EFLAGS_READ_AC 0x00400000 /**< Reads AC (Alignment Check Flag). */
# define EFLAGS_WRITE_AC 0x00800000 /**< Writes AC (Alignment Check Flag). */

# define EFLAGS_READ_ALL 0x004007ff /**< Reads all flags. */
# define EFLAGS_READ_NON_PRED EFLAGS_READ_ALL /**< Flags not read by predicates. */
# define EFLAGS_WRITE_ALL 0x003ff800 /**< Writes all flags. */
# define EFLAGS_WRITE_ALL 0x00bff800 /**< Writes all flags. */
/* 6 most common flags ("arithmetic flags"): CF, PF, AF, ZF, SF, OF */
/** Reads all 6 arithmetic flags (CF, PF, AF, ZF, SF, OF). */
# define EFLAGS_READ_6 0x0000011f
Expand All @@ -2577,9 +2587,13 @@ instr_is_reg_spill_or_restore(void *drcontext, instr_t *instr, bool *tls DR_PARA
# define EFLAGS_WRITE_ARITH EFLAGS_WRITE_6

/** Converts an EFLAGS_WRITE_* value to the corresponding EFLAGS_READ_* value. */
# define EFLAGS_WRITE_TO_READ(x) ((x) >> 11)
# define EFLAGS_WRITE_TO_READ(x) \
((((x) & ((EFLAGS_WRITE_ALL) & ~(EFLAGS_WRITE_AC))) >> 11) | \
(((x) & (EFLAGS_WRITE_AC)) >> 1))
/** Converts an EFLAGS_READ_* value to the corresponding EFLAGS_WRITE_* value. */
# define EFLAGS_READ_TO_WRITE(x) ((x) << 11)
# define EFLAGS_READ_TO_WRITE(x) \
((((x) & ((EFLAGS_READ_ALL) & ~(EFLAGS_READ_AC))) << 11) | \
(((x) & (EFLAGS_READ_AC)) << 1))

/**
* The actual bits in the eflags register that we care about:\n<pre>
Expand Down
2 changes: 1 addition & 1 deletion core/ir/x86/decode_fast.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/* **********************************************************
* Copyright (c) 2011-2022 Google, Inc. All rights reserved.
* Copyright (c) 2011-2023 Google, Inc. All rights reserved.
* Copyright (c) 2001-2010 VMware, Inc. All rights reserved.
* **********************************************************/

Expand Down
10 changes: 8 additions & 2 deletions core/ir/x86/decode_table.c
Original file line number Diff line number Diff line change
Expand Up @@ -1623,6 +1623,10 @@ const instr_info_t * const op_instr[] =
/* AVX512 VPOPCNTDQ */
/* OP_vpopcntd, */ &evex_Wb_extensions[274][0],
/* OP_vpopcntq, */ &evex_Wb_extensions[274][2],

/* Supervisor Mode Access Prevention (SMAP) */
/* OP_clac */ &rm_extensions[1][2],
/* OP_stac */ &rm_extensions[1][3]
};


Expand Down Expand Up @@ -2079,6 +2083,7 @@ const instr_info_t * const op_instr[] =
#define fRO EFLAGS_READ_OF
#define fRN EFLAGS_READ_NT
#define fRR EFLAGS_READ_RF
#define fRAC EFLAGS_READ_AC
#define fRX EFLAGS_READ_ALL
#define fR6 EFLAGS_READ_6
#define fWC EFLAGS_WRITE_CF
Expand All @@ -2092,6 +2097,7 @@ const instr_info_t * const op_instr[] =
#define fWO EFLAGS_WRITE_OF
#define fWN EFLAGS_WRITE_NT
#define fWR EFLAGS_WRITE_RF
#define fWAC EFLAGS_WRITE_AC
#define fWX EFLAGS_WRITE_ALL
#define fW6 EFLAGS_WRITE_6
/* flags affected by OP_int*
Expand Down Expand Up @@ -7019,8 +7025,8 @@ const instr_info_t rm_extensions[][8] = {
/* XXX i#4013: Treat address in xax as IR memref? */
{OP_monitor, 0xc80f0171, catUncategorized, "monitor", xx, xx, axAX, ecx, edx, mrm, x, END_LIST},
{OP_mwait, 0xc90f0171, catUncategorized, "mwait", xx, xx, eax, ecx, xx, mrm, x, END_LIST},
{INVALID, 0x0f0131, catUncategorized, "(bad)", xx, xx, xx, xx, xx, no, x, NA},
{INVALID, 0x0f0131, catUncategorized, "(bad)", xx, xx, xx, xx, xx, no, x, NA},
{OP_clac, 0xca0f0171, catUncategorized, "clac", xx, xx, xx, xx, xx, no, fWAC, NA},
{OP_stac, 0xcb0f0171, catUncategorized, "stac", xx, xx, xx, xx, xx, no, fWAC, NA},
{INVALID, 0x0f0131, catUncategorized, "(bad)", xx, xx, xx, xx, xx, no, x, NA},
{INVALID, 0x0f0131, catUncategorized, "(bad)", xx, xx, xx, xx, xx, no, x, NA},
{INVALID, 0x0f0131, catUncategorized, "(bad)", xx, xx, xx, xx, xx, no, x, NA},
Expand Down
4 changes: 3 additions & 1 deletion core/ir/x86/instr_create_api.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/* **********************************************************
* Copyright (c) 2011-2022 Google, Inc. All rights reserved.
* Copyright (c) 2011-2023 Google, Inc. All rights reserved.
* Copyright (c) 2002-2010 VMware, Inc. All rights reserved.
* **********************************************************/

Expand Down Expand Up @@ -527,6 +527,8 @@
#define INSTR_CREATE_vzeroupper(dc) instr_create_0dst_0src((dc), OP_vzeroupper)
#define INSTR_CREATE_vzeroall(dc) instr_create_0dst_0src((dc), OP_vzeroall)
#define INSTR_CREATE_xtest(dc) instr_create_0dst_0src((dc), OP_xtest)
#define INSTR_CREATE_clac(dc) instr_create_0dst_0src((dc), OP_clac)
#define INSTR_CREATE_stac(dc) instr_create_0dst_0src((dc), OP_stac)
/** @} */ /* end doxygen group */

/* no destination, 1 source */
Expand Down
5 changes: 4 additions & 1 deletion core/ir/x86/opcode_api.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/* **********************************************************
* Copyright (c) 2011-2021 Google, Inc. All rights reserved.
* Copyright (c) 2011-2023 Google, Inc. All rights reserved.
* Copyright (c) 2000-2010 VMware, Inc. All rights reserved.
* **********************************************************/

Expand Down Expand Up @@ -1614,6 +1614,9 @@ enum {
/* 1433 */ OP_vpopcntd, /**< IA-32/AMD64 vpopcntd opcode. */
/* 1434 */ OP_vpopcntq, /**< IA-32/AMD64 vpopcntd opcode. */

/* Supervisor Mode Access Prevention (SMAP) */
/* 1435 */ OP_clac,
/* 1436 */ OP_stac,
OP_AFTER_LAST,
OP_FIRST = OP_add, /**< First real opcode. */
OP_LAST = OP_AFTER_LAST - 1, /**< Last real opcode. */
Expand Down
5 changes: 4 additions & 1 deletion suite/tests/api/ir_x86_0args.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/* **********************************************************
* Copyright (c) 2011-2016 Google, Inc. All rights reserved.
* Copyright (c) 2011-2023 Google, Inc. All rights reserved.
* Copyright (c) 2008-2010 VMware, Inc. All rights reserved.
* **********************************************************/

Expand Down Expand Up @@ -197,3 +197,6 @@ OPCODE(xtest, xtest, xtest, 0)

OPCODE(rdpkru, rdpkru, rdpkru, 0)
OPCODE(wrpkru, wrpkru, wrpkru, 0)

OPCODE(clac, clac, clac, 0)
OPCODE(stac, stac, stac, 0)
2 changes: 2 additions & 0 deletions third_party/binutils/test_decenc/drdecode_decenc_x86.expect
Original file line number Diff line number Diff line change
Expand Up @@ -138762,6 +138762,8 @@ test_s:
7b 00 00 00
62 f2 7d 29 91 b4 f5 vpgatherqd 0x0000007b(%ebp,%ymm6,8), %ymm6 {%k1} {%k1}
7b 00 00 00
0f 01 ca clac
0f 01 cb stac
90 nop
90 nop
90 nop
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102826,6 +102826,8 @@ test_x86_64_s:
c4 e2 59 53 11 vpdpwssds %xmm4, (%rcx), %xmm2
62 b2 5d 08 53 d6 vpdpwssds %xmm4, %xmm22, %xmm2 {%k0}
62 d2 5d 08 50 d4 vpdpbusd %xmm4, %xmm12, %xmm2 {%k0}
0f 01 ca clac
0f 01 cb stac
90 nop
90 nop
90 nop
Expand Down
14 changes: 10 additions & 4 deletions third_party/binutils/test_decenc/test_decenc_x86.asm
Original file line number Diff line number Diff line change
Expand Up @@ -298,10 +298,6 @@ GLOBAL_LABEL(FUNCNAME:)

/* arch_13.s */

/* clac, CPL 0 instruction. */
/* RAW(0f) RAW(01) RAW(ca) */
/* stac, CPL 0 instruction. */
/* RAW(0f) RAW(01) RAW(cb) */
RAW(66) RAW(0f) RAW(38) RAW(f6) RAW(ca)
RAW(f3) RAW(0f) RAW(38) RAW(f6) RAW(ca)
RAW(0f) RAW(c7) RAW(f8)
Expand Down Expand Up @@ -139592,6 +139588,16 @@ GLOBAL_LABEL(FUNCNAME:)
RAW(7b) RAW(00) RAW(00) RAW(00)
RAW(62) RAW(f2) RAW(7d) RAW(29) RAW(91) RAW(b4) RAW(f5)
RAW(7b) RAW(00) RAW(00) RAW(00)

/* TODO i#5505: Move the following back under
* arch_13.s in a separate PR to keep the huge
* diff isolated from PR #6484.
*/
/* clac, CPL 0 instruction. */
RAW(0f) RAW(01) RAW(ca)
/* stac, CPL 0 instruction. */
RAW(0f) RAW(01) RAW(cb)

END_OF_SUBTEST_MARKER

#ifdef DISABLED_UNTIL_BUG_3577_IS_FIXED
Expand Down
13 changes: 9 additions & 4 deletions third_party/binutils/test_decenc/test_decenc_x86_64.asm
Original file line number Diff line number Diff line change
Expand Up @@ -220,10 +220,6 @@ GLOBAL_LABEL(FUNCNAME:)

/* x86_64_arch_3.s */

/* clac, CPL 0 instruction. */
/* RAW(0f) RAW(01) RAW(ca) */
/* stac, CPL 0 instruction. */
/* RAW(0f) RAW(01) RAW(cb) */
RAW(66) RAW(0f) RAW(38) RAW(f6) RAW(ca)
RAW(f3) RAW(0f) RAW(38) RAW(f6) RAW(ca)
RAW(0f) RAW(c7) RAW(f8)
Expand Down Expand Up @@ -106655,5 +106651,14 @@ GLOBAL_LABEL(FUNCNAME:)
RAW(62) RAW(b2) RAW(5d) RAW(08) RAW(53) RAW(d6)
RAW(62) RAW(d2) RAW(5d) RAW(08) RAW(50) RAW(d4)

/* TODO i#5505: Move the following back under
* x86_64_arch_3.s in a separate PR to keep the huge
* diff isolated from PR #6484.
*/
/* clac, CPL 0 instruction. */
RAW(0f) RAW(01) RAW(ca)
/* stac, CPL 0 instruction. */
RAW(0f) RAW(01) RAW(cb)

END_OF_FUNCTION_MARKER
END_FUNC(FUNCNAME)

0 comments on commit 30031e0

Please sign in to comment.