bti

Branch Target Identification

BTI {<target>}

Mark a valid target for an indirect branch (Control Flow Integrity).

Details

Marks a valid branch target for indirect branches as part of Control Flow Integrity (CFI). Encodes the expected branch target type (c=call, j=jump, jc=both) in the immediate field. Causes a PACM fault if the branch was not of the expected type. No condition flags are affected. AArch64-only; requires BTI extension.

Pseudocode Operation

if current_branch_type is not compatible with target then
  raise PACM_exception
else
  NOP

Example

BTI

Encoding

Binary Layout
11010101000000110010
0100
op2
11111
 
Format System
Opcode 0xD503241F
Extension BTI (Security)

Operands

  • target
    Type (c, j, jc)

Reference (Arm A64 ISA)

Instruction Forms

Encoding Instruction ISA Bit pattern
0xD503241F BTI {<targets>} A64 11010101000000110010 | 0100 | op2 | 11111

Description

Branch Target Identification. A BTI instruction is used to guard against the execution of instructions that are not the intended target of a branch. Outside of a guarded memory region, a BTI instruction executes as a NOP. Within a guarded memory region, while PSTATE.BTYPE != 0b00, a BTI instruction compatible with the current value of PSTATE.BTYPE will not generate a Branch Target Exception and will allow execution of subsequent instructions within the memory region. For more information, see PSTATE.BTYPE. The operand <targets> passed to a BTI instruction determines the values of PSTATE.BTYPE that the BTI instruction is compatible with.

Operation

case op of
    when SystemHintOp_YIELD
        Hint_Yield();

    when SystemHintOp_DGH
        Hint_DGH();

    when SystemHintOp_WFE
        integer localtimeout = 1 << 64;    // No local timeout event is generated
        Hint_WFE(localtimeout, WFxType_WFE);

    when SystemHintOp_WFI
        integer localtimeout = 1 << 64;    // No local timeout event is generated
        Hint_WFI(localtimeout, WFxType_WFI);

    when SystemHintOp_SEV
        SendEvent();

    when SystemHintOp_SEVL
        SendEventLocal();

    when SystemHintOp_ESB
        if IsFeatureImplemented(FEAT_TME) && TSTATE.depth > 0 then
            FailTransaction(TMFailure_ERR, FALSE);
        SynchronizeErrors();
        AArch64.ESBOperation();
        if PSTATE.EL IN {EL0, EL1} && EL2Enabled() then AArch64.vESBOperation();
        TakeUnmaskedSErrorInterrupts();

    when SystemHintOp_PSB
        ProfilingSynchronizationBarrier();

    when SystemHintOp_TSB
        TraceSynchronizationBarrier();

    when SystemHintOp_GCSB
        GCSSynchronizationBarrier();

    when SystemHintOp_CHKFEAT
        X[16, 64] = AArch64.ChkFeat(X[16, 64]);

    when SystemHintOp_CSDB
        ConsumptionOfSpeculativeDataBarrier();

    when SystemHintOp_CLRBHB
        Hint_CLRBHB();

    when SystemHintOp_BTI
        SetBTypeNext('00');

    when SystemHintOp_NOP
        return;    // do nothing

    otherwise
        Unreachable();