Copyright (C) Intel Corporation. All Rights Reserved.
# Notices and Disclaimers
Intel technologies may require enabled hardware, software or service activation.
No product or component can be absolutely secure.
Your costs and results may vary.
All product plans and roadmaps are subject to change without notice.
The products described may contain design defects or errors known as errata which may cause the product to deviate from published specifications. Current characterized errata are available on request.
Intel disclaims all express and implied warranties, including without limitation, the implied warranties of merchantability, fitness for a particular purpose, and non-infringement, as well as any warranty arising from course of performance, course of dealing, or usage in trade.
Code names are used by Intel to identify products, technologies, or services that are in development and not publicly available. These are not “commercial” names and not intended to function as trademarks.
No license (express or implied, by estoppel or otherwise) to any intellectual property rights is granted by this document, with the sole exception that a) you may publish an unmodified copy and b) code, identified as Sample Code in this document is licensed subject to the Zero-Clause BSD open source license (0BSD), [https://opensource.org/licenses/0BSD](https://opensource.org/licenses/0BSD). You may create software implementations based on this document and in compliance with the foregoing that are intended to execute on the Intel product(s) referenced in this document. No rights are granted to create modifications or derivatives of this document.
You may not use or facilitate the use of this document in connection with any infringement or other legal analysis concerning Intel products described herein. You agree to grant Intel a non-exclusive, royalty-free license to any patent claim thereafter drafted which includes subject matter disclosed herein.
If you give Intel any comments or suggestions related to this document or the information contained in it, Intel can use them in any way and disclose them to anyone, without payment or other obligations to you. You represent and warrant that you own, or have sufficient rights from the owner of, any such comments or suggestions, and the intellectual property rights in them, to grant the above permission.
© Intel Corporation. Intel, the Intel logo, and other Intel marks are trademarks of Intel Corporation or its subsidiaries. Other names and brands may be claimed as the property of others.
The code in this file is not 'Sample Code'.
Std::Bits::Add_int
Mem_Fetch
Report_Invalid_Opcode
Instr_RET_NEAR
Next_IP
let src := Mem_Fetch?(ip, 16);
LockPrefix
#UD
Next_IP := ip + 2;
Instr_RET_NEAR?(operand_size, stack_address_size, src);
imm16
src
var new_rsp : Bits(64);
var return_address : Bits(64) := Zero(64);
(return_address[0 +: operand_size], new_rsp) := Pop_Stack?(SS, RSP, operand_size, operand_size);
if CET::Is_Shadow_Stack_Enabled(CPL) then
SSP := CET::Check_Return_RIP?(operand_size, return_address);
endif;
Check_New_RIP?(CS, return_address);
Branch_Near(return_address);
RSP[0 +: stack_address_size] := new_rsp[0 +: stack_address_size] + Zero_Extend(src, stack_address_size);
Std::Integer::Le
Std::Bits::Add
Std::Bits::Zero_Extend
Std::Bits::Zero
Branch_Near
CET::Check_Return_RIP
CET::Is_Shadow_Stack_Enabled
Check_New_RIP
Pop_Stack
RSP
RSP_write
CS
CPL
SSP
SS
Std::Bits::Add_int
Mem_Fetch
Report_Invalid_Opcode
Instr_RET_FAR
Next_IP
let src := Mem_Fetch?(ip, 16);
LockPrefix
#UD
Next_IP := ip + 2;
Instr_RET_FAR?(operand_size, src);
imm16
src
let mode := Current_Mode();
var new_rsp : Bits(64);
var new_rip := Zero(64);
var new_cs : Segment;
// pop CS before RIP
// pop only 16 bits, but increment RSP by operand_size (high-order bits discarded)
(new_cs.selector, new_rsp) := Pop_Stack?(SS, RSP + (operand_size / 8), 16, operand_size);
(new_rip[0 +: operand_size], _) := Pop_Stack?(SS, RSP, operand_size, operand_size);
if mode in { Real_Address_Mode, Virtual_8086_Mode } then
new_cs := Load_Real_Or_VM86_Segment(mode, new_cs.selector, CS);
// handle optional operand to release parameters from the stack
new_rsp[0 +: 16] := new_rsp[0 +: 16] + src;
Check_New_RIP?(new_cs, new_rip);
Branch_Far(new_cs, new_rip);
RSP := new_rsp;
else
if Is_Null_Segment_Selector(new_cs.selector) then
Report_General_Protection_Exception!(Zero(32));
endif;
new_cs := Load_Segment_Descriptor?(new_cs.selector, CS);
if (CR4.FRED == 0b1 and Unsigned(new_cs.selector.RPL) > CPL)
or Unsigned(new_cs.selector.RPL) < CPL
or not Is_Valid_Code_Segment(new_cs, Unsigned(new_cs.selector.RPL))
then
Report_General_Protection_Exception!(Get_Error_Code_From_Selector(new_cs.selector));
endif;
Code_Segment_Checks?(new_cs);
if new_cs.descriptor.A == 0b0 then
new_cs := Set_Segment_Access_Bit?(new_cs);
endif;
new_rsp := Release_Parameters(SS, new_rsp, src);
if Unsigned(new_cs.selector.RPL) == CPL then
Return_To_Same_Privilege?(new_cs, new_rip, new_rsp);
else
Return_To_Less_Privilege?(new_cs, new_rip, new_rsp, operand_size, src);
endif;
endif;
Std::Boolean::Not
Std::Boolean::Strict_And
Std::Boolean::Strict_Or
Std::Integer::Eq
Std::Integer::Gt
Std::Integer::Le
Std::Integer::Lt
Std::Integer::Positive_Divide
Std::Bits::Add
Std::Bits::Add_int
Std::Bits::Unsigned
Std::Bits::Eq
Std::Bits::Zero
Branch_Far
Check_New_RIP
Code_Segment_Checks
Current_Mode
Get_Error_Code_From_Selector
Is_Null_Segment_Selector
Is_Valid_Code_Segment
Load_Real_Or_VM86_Segment
Load_Segment_Descriptor
Pop_Stack
Release_Parameters
Report_General_Protection_Exception
Return_To_Less_Privilege
Return_To_Same_Privilege
Set_Segment_Access_Bit
RSP
RSP_write
False
CS
Real_Address_Mode
CPL
Virtual_8086_Mode
CR4
SS
Std::Bits::Zero
Report_Invalid_Opcode
Instr_RET_NEAR
Next_IP
let src := Zero(16);
LockPrefix
#UD
Next_IP := ip;
Instr_RET_NEAR?(operand_size, stack_address_size, src);
src
Std::Bits::Zero
Report_Invalid_Opcode
Instr_RET_FAR
Next_IP
let src := Zero(16);
LockPrefix
#UD
Next_IP := ip;
Instr_RET_FAR?(operand_size, src);
src
branch/call