WRSSD, WRSSQ

Write to Shadow Stack

stableVMJITAOTinstruction

Encodings

OpcodeInstructionOp/En64-bitCompat/LegacyDescription
0F 38 F6 !(11):rrr:bbbWRSSD m32, r32MRValidValidWrite 4 bytes to shadow stack.
REX.W 0F 38 F6 !(11):rrr:bbbWRSSQ m64, r64MRValidNot encodableWrite 8 bytes to shadow stack.

Operand encoding

Each mode is a value of the Op/En column above. It says which field of the encoded instruction carries each operand, in the order they are written, and whether the instruction reads it, writes it or both.

MR

  1. modrm.rm escrituraModRM byte, r/m field (bits 2-0); with the SIB byte and the displacement when the mod field asks for them
  2. modrm.reg lecturaModRM byte, reg field (bits 5-3)

Measured cost

Loading measurements from arch-data...

Description

Writes bytes in register source to the shadow stack.

Operation

IF CPL = 3
    IF (CR4.CET & IA32_U_CET.SH_STK_EN) = 0
          THEN #UD; FI;
    IF (IA32_U_CET.WR_SHSTK_EN) = 0
          THEN #UD; FI;

ELSE
    IF (CR4.CET & IA32_S_CET.SH_STK_EN) = 0
          THEN #UD; FI;
    IF (IA32_S_CET.WR_SHSTK_EN) = 0
          THEN #UD; FI;

FI;
DEST_LA = Linear_Address(mem operand)
IF (operand size is 64 bit)

    THEN
          (* Destination not 8B aligned *)
          IF DEST_LA[2:0]
                THEN GP(0); FI;
          Shadow_stack_store 8 bytes of SRC to DEST_LA;

    ELSE
          (* Destination not 4B aligned *)
          IF DEST_LA[1:0]
                THEN GP(0); FI;
          Shadow_stack_store 4 bytes of SRC[31:0] to DEST_LA;

FI;

Flags affected

None.

C/C++ Compiler Intrinsic Equivalent

WRSSD void _wrssd(__int32, void ); WRSSQ void _wrssq(__int64, void );

Exceptions

Protected mode
#UDIf the LOCK prefix is used. If CR4.CET = 0. If CPL = 3 and IA32_U_CET.SH_STK_EN = 0. If CPL < 3 and IA32_S_CET.SH_STK_EN = 0. If CPL = 3 and IA32_U_CET.WR_SHSTK_EN = 0. If CPL < 3 and IA32_S_CET.WR_SHSTK_EN = 0.
#GP(0)If a memory operand effective address is outside the CS, DS, ES, FS, or GS segment limit. If destination is located in a non-writeable segment. If the DS, ES, FS, or GS register is used to access memory and it contains a NULL segment selector. If linear address of destination is not 4 byte aligned.
#SS(0)If a memory operand effective address is outside the SS segment limit.
#PF(fault-code)If a page fault occurs if destination is not a user shadow stack when CPL3 and not a supervisor shadow stack when CPL < 3. Other terminal and non-terminal faults.
Real address mode
#UDThe WRSS instruction is not recognized in real-address mode.
Virtual-8086 mode
#UDThe WRSS instruction is not recognized in virtual-8086 mode.
Compatibility mode
#UDIf the LOCK prefix is used. If CR4.CET = 0. If CPL = 3 and IA32_U_CET.SH_STK_EN = 0. If CPL < 3 and IA32_S_CET.SH_STK_EN = 0. If CPL = 3 and IA32_U_CET.WR_SHSTK_EN = 0. If CPL < 3 and IA32_S_CET.WR_SHSTK_EN = 0.
#PF(fault-code)If a page fault occurs if destination is not a user shadow stack when CPL3 and not a supervisor shadow stack when CPL < 3. Other terminal and non-terminal faults.
64-bit mode
#UDIf the LOCK prefix is used. If CR4.CET = 0. If CPL = 3 and IA32_U_CET.SH_STK_EN = 0. If CPL < 3 and IA32_S_CET.SH_STK_EN = 0. If CPL = 3 and IA32_U_CET.WR_SHSTK_EN = 0. If CPL < 3 and IA32_S_CET.WR_SHSTK_EN = 0.
#GP(0)If a memory address is in a non-canonical form. If linear address of destination is not 4 byte aligned.
#PF(fault-code)If a page fault occurs if destination is not a user shadow stack when CPL3 and not a supervisor shadow stack when CPL < 3. Other terminal and non-terminal faults.

Sources