SAVEPREVSSP

保存上一个阴影 栈指针

stableVMJITAOTinstruction

编码

操作码指令Op/En64 位兼容/传统说明
F3 0F 01 EASAVEPREVSSPZO有效有效在先前的阴影堆栈中保存一个还原-阴影-存储符 。

实测开销

正在从 arch-data 加载实测数据...

说明

在下一个 8 字节对齐的边界上, 在上一个阴影堆栈上按下一个还原- 阴影- stack 符号 。 之前的SSP是从当前阴影堆栈顶部的先前ssp令牌获得的.

行动

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

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

FI;

IF SSP not aligned to 8 bytes
    THEN #GP(0); FI;

(* Pop the "previous-ssp" token from current shadow stack *)
previous_ssp_token = ShadowStackPop8B(SSP)

(* If the CF flag indicates there was a alignment hole on current shadow stack then pop that alignment hole *)
(* Note that the alignment hole must be zero and can be present only when in legacy/compatibility mode *)
IF RFLAGS.CF == 1 AND (IA32_EFER.LMA AND CS.L)

    #GP(0)
FI;
IF RFLAGS.CF == 1

    must_be_zero = ShadowStackPop4B(SSP)
    IF must_be_zero != 0 THEN #GP(0)
FI;

(* Previous SSP token must have the bit 1 set *)
IF ((previous_ssp_token & 0x02) == 0)

    THEN #GP(0); (* bit 1 was 0 *)

IF ((IA32_EFER.LMA AND CS.L) = 0 AND previous_ssp_token [63:32] != 0)
THEN #GP(0); FI; (* If compatibility/legacy mode and SSP not in 4G *)

(* Save Prev SSP from previous_ssp_token to the old shadow stack at next 8 byte aligned address *)
old_SSP = previous_ssp_token & ~0x03
temp := (old_SSP | (IA32_EFER.LMA & CS.L));
Shadow_stack_store 4 bytes of 0 to (old_SSP - 4)
old_SSP := old_SSP & ~0x07;


Shadow_stack_store 8 bytes of temp to (old_SSP - 8)

受影响的旗帜

None.

C/C++ 编译器 Intrinsic Equivalent SAVEPREVSSP 无效 saveprevssp(void) ;

异常

保护模式
#UD如果使用 LOCK 前缀,如果使用 CR4.CET = 0. IF CPL = 3, IA32_U_CET.SH_STK_EN = 0. IF CPL < 3, IA32_S_CET.SH_STK_EN = 0.
#GP(0)如果 SSP 不是 8 字节对齐。 如果阴影堆栈上的对齐孔不是 0 。 如果前一个 ssp 令牌的比特 1 不设为 1 。 如果在 32 位/ 兼容模式中, 在前一个 ssp 令牌中记录的 SSP 超过 4G 。 #PF(fault-code) 如果 页面错误 发生的话 。
实地址模式
#UDSAVEPREVSSP指令在实地址模式中不被识别.
虚拟 8086 模式
#UDSAVEPREVSSP指令在虚拟 8086 模式中不被识别.
兼容模式
与保护模式例外相同.
64 位模式
#UD如果LOCK前缀被使用。如果CR4.CET=0. 如果CPL=3个和IA32_U_CET.SH_STK_EN=0. 如果CPL <联合国IA32_S_CET.SH_STK_EN = 0.
#GP(0)如果 SSP 不是 8 字节对齐。 如果 进位标志 被设定。 如果前一个 ssp 令牌的比特 1 不设为 1. #PF(fault-code) 如果 页面错误 发生 。

来源