Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions arch/arm64/arch_arm64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -399,6 +399,10 @@ class Arm64Architecture : public Architecture
case ARM64_RET:
case ARM64_RETAA:
case ARM64_RETAB:
case ARM64_RETAASPPC:
case ARM64_RETABSPPC:
case ARM64_RETAASPPCR:
case ARM64_RETABSPPCR:
result.AddBranch(FunctionReturn);
break;
case ARM64_SVC:
Expand Down Expand Up @@ -961,6 +965,14 @@ class Arm64Architecture : public Architecture
return "__autia";
case ARM64_INTRIN_AUTIB:
return "__autib";
case ARM64_INTRIN_AUTIA2:
return "__autia2";
case ARM64_INTRIN_AUTIB2:
return "__autib2";
case ARM64_INTRIN_PACIA2:
return "__pacia2";
case ARM64_INTRIN_PACIB2:
return "__pacib2";
case ARM64_INTRIN_ISB:
return "__isb";
case ARM64_INTRIN_WFE:
Expand Down Expand Up @@ -993,6 +1005,8 @@ class Arm64Architecture : public Architecture
return "SystemHintOp_CSDB";
case ARM64_INTRIN_HINT_BTI:
return "SystemHintOp_BTI";
case ARM64_INTRIN_HINT_PACM:
return "SystemHintOp_PACM";
case ARM64_INTRIN_SEV:
return "__sev";
case ARM64_INTRIN_SEVL:
Expand Down Expand Up @@ -1157,6 +1171,12 @@ class Arm64Architecture : public Architecture
case ARM64_INTRIN_PACIA: // reads <Xd>, <Xn>
case ARM64_INTRIN_PACIB: // reads <Xd>, <Xn>
return {NameAndType(Type::IntegerType(8, false)), NameAndType(Type::IntegerType(8, false))};
case ARM64_INTRIN_AUTIA2: // reads <Xd>, modifier, modifier2
case ARM64_INTRIN_AUTIB2: // reads <Xd>, modifier, modifier2
case ARM64_INTRIN_PACIA2: // reads <Xd>, modifier, modifier2
case ARM64_INTRIN_PACIB2: // reads <Xd>, modifier, modifier2
return {NameAndType(Type::IntegerType(8, false)), NameAndType(Type::IntegerType(8, false)),
NameAndType(Type::IntegerType(8, false))};
case ARM64_INTRIN_TLBI: // reads <tlbi_op>, <Xn>
return {
NameAndType("tlbi_op", Confidence<Ref<Type>>(Type::EnumerationType(this, get_tlbi_op_enum(), 4, false), BN_FULL_CONFIDENCE))
Expand Down Expand Up @@ -1206,6 +1226,10 @@ class Arm64Architecture : public Architecture
case ARM64_INTRIN_PACIA: // writes <Xd>
case ARM64_INTRIN_PACGA: // writes <Xd>
case ARM64_INTRIN_PACIB: // writes <Xd>
case ARM64_INTRIN_AUTIA2: // writes <Xd>
case ARM64_INTRIN_AUTIB2: // writes <Xd>
case ARM64_INTRIN_PACIA2: // writes <Xd>
case ARM64_INTRIN_PACIB2: // writes <Xd>
case ARM64_INTRIN_XPACD: // writes <Xd>
case ARM64_INTRIN_XPACI: // writes <Xd>
case ARM64_INTRIN_CNT: // writes <Xd>
Expand Down
98 changes: 97 additions & 1 deletion arch/arm64/arm64test.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,22 @@
# retab (example of encoding: RETAB_64E_branch_reg)
(b'\xFF\x0F\x5F\xD6', 'LLIL_RET(LLIL_REG.q(lr))', ATTR_PTR_AUTH),

# RETURN FROM SUBROUTINE, WITH POINTER AUTHENTICATION AGAINST SP AND PC (FEAT_PAuth_LR)
# the operand is part of the authentication modifier rather than the address returned to, which
# is always lr
# retaasppc <label> (example of encoding: RETAASPPC_only_miscbranch)
(b'\x3F\x00\x00\x55', 'LLIL_RET(LLIL_REG.q(lr))', ATTR_PTR_AUTH),
# retabsppc <label> (example of encoding: RETABSPPC_only_miscbranch)
(b'\x3F\x00\x20\x55', 'LLIL_RET(LLIL_REG.q(lr))', ATTR_PTR_AUTH),
# retaasppcr x3 (example of encoding: RETAASPPCR_64M_branch_reg)
(b'\xE3\x0B\x5F\xD6', 'LLIL_RET(LLIL_REG.q(lr))', ATTR_PTR_AUTH),
# retabsppcr x12 (example of encoding: RETABSPPCR_64M_branch_reg)
(b'\xEC\x0F\x5F\xD6', 'LLIL_RET(LLIL_REG.q(lr))', ATTR_PTR_AUTH),

# HINT THAT A DIFFERENT POINTER AUTHENTICATION MODIFIER IS IN USE (FEAT_PAuth_LR)
# pacm (example of encoding: PACM_HI_hints)
(b'\xFF\x24\x03\xD5', 'LLIL_INTRINSIC([],SystemHintOp_PACM,[])'),

# mixed instructions from old tests
# BLRAA_64P_branch_reg 1101011100111111000010xxxxxxxxxx
(b'\x14\x0B\x3F\xD7', 'LLIL_CALL(LLIL_REG.q(x24))', ATTR_PTR_AUTH), # blraa x24, x20
Expand Down Expand Up @@ -187,6 +203,24 @@
# xpaci x25 (example of encoding: XPACI_64Z_dp_1src)
(b'\xF9\x43\xC1\xDA', 'LLIL_INTRINSIC([x25],__xpaci,[LLIL_REG.q(x25)])'),

# SIGN OR AUTHENTICATE AGAINST TWO MODIFIERS (FEAT_PAuth_LR)
# the 171615 forms take x17 as the address and x16 and x15 as the modifiers
# the sppcr forms take x30 as the address and sp and <Xn> as the modifiers
# the forms whose second modifier is the instruction's own address are position dependent, so
# they are in tests_pac_position_dependent instead
# pacia171615 (example of encoding: PACIA171615_64LR_dp_1src)
(b'\xFE\x8B\xC1\xDA', 'LLIL_INTRINSIC([x17],__pacia2,[LLIL_REG.q(x17),LLIL_REG.q(x16),LLIL_REG.q(x15)])'),
# pacib171615 (example of encoding: PACIB171615_64LR_dp_1src)
(b'\xFE\x8F\xC1\xDA', 'LLIL_INTRINSIC([x17],__pacib2,[LLIL_REG.q(x17),LLIL_REG.q(x16),LLIL_REG.q(x15)])'),
# autia171615 (example of encoding: AUTIA171615_64LR_dp_1src)
(b'\xFE\xBB\xC1\xDA', 'LLIL_INTRINSIC([x17],__autia2,[LLIL_REG.q(x17),LLIL_REG.q(x16),LLIL_REG.q(x15)])'),
# autib171615 (example of encoding: AUTIB171615_64LR_dp_1src)
(b'\xFE\xBF\xC1\xDA', 'LLIL_INTRINSIC([x17],__autib2,[LLIL_REG.q(x17),LLIL_REG.q(x16),LLIL_REG.q(x15)])'),
# autiasppcr x5 (example of encoding: AUTIASPPCR_64LRR_dp_1src)
(b'\xBE\x90\xC1\xDA', 'LLIL_INTRINSIC([lr],__autia2,[LLIL_REG.q(lr),LLIL_REG.q(sp),LLIL_REG.q(x5)])'),
# autibsppcr x9 (example of encoding: AUTIBSPPCR_64LRR_dp_1src)
(b'\x3E\x95\xC1\xDA', 'LLIL_INTRINSIC([lr],__autib2,[LLIL_REG.q(lr),LLIL_REG.q(sp),LLIL_REG.q(x9)])'),

# mixed instructions from old tests
# PACDA_64P_dp_1src 1101101011000001000010xxxxxxxxxx
(b'\xAC\x0B\xC1\xDA', 'LLIL_INTRINSIC([x12],__pacda,[LLIL_REG.q(x12),LLIL_REG.q(fp)])'), # pacda x12, x29
Expand Down Expand Up @@ -237,6 +271,28 @@
# XPACLRI_HI_hints 11010101000000110010000xxxxxxxxx
(b'\xFF\x20\x03\xD5', 'LLIL_INTRINSIC([lr],__xpaci,[LLIL_REG.q(lr)])'), # xpaclri
])

# The remaining FEAT_PAuth_LR signing and authenticating instructions take the instruction's own
# address as their second modifier, so the address they are lifted at reaches the IL. Each case
# gives the address to lift at and the IL that must be produced there, and is appended to
# tests_position_dependent below.
tests_pac_position_dependent = [
# paciasppc (example of encoding: PACIASPPC_64LR_dp_1src)
(b'\xFE\xA3\xC1\xDA', 0x1000, 'LLIL_INTRINSIC([lr],__pacia2,[LLIL_REG.q(lr),LLIL_REG.q(sp),LLIL_CONST.q(0x1000)])'),
(b'\xFE\xA3\xC1\xDA', 0x2004, 'LLIL_INTRINSIC([lr],__pacia2,[LLIL_REG.q(lr),LLIL_REG.q(sp),LLIL_CONST.q(0x2004)])'),
# pacibsppc (example of encoding: PACIBSPPC_64LR_dp_1src)
(b'\xFE\xA7\xC1\xDA', 0x1000, 'LLIL_INTRINSIC([lr],__pacib2,[LLIL_REG.q(lr),LLIL_REG.q(sp),LLIL_CONST.q(0x1000)])'),
# pacnbiasppc, which signs without setting the branch target (example of encoding: PACNBIASPPC_64LR_dp_1src)
(b'\xFE\x83\xC1\xDA', 0x1000, 'LLIL_INTRINSIC([lr],__pacia2,[LLIL_REG.q(lr),LLIL_REG.q(sp),LLIL_CONST.q(0x1000)])'),
# pacnbibsppc (example of encoding: PACNBIBSPPC_64LR_dp_1src)
(b'\xFE\x87\xC1\xDA', 0x1000, 'LLIL_INTRINSIC([lr],__pacib2,[LLIL_REG.q(lr),LLIL_REG.q(sp),LLIL_CONST.q(0x1000)])'),
# autiasppc <label> -- the label is the address minus the encoded offset, here 4
# (example of encoding: AUTIASPPC_only_dp_1src_imm)
(b'\x3F\x00\x80\xF3', 0x1000, 'LLIL_INTRINSIC([lr],__autia2,[LLIL_REG.q(lr),LLIL_REG.q(sp),LLIL_CONST.q(0xFFC)])'),
(b'\x3F\x00\x80\xF3', 0x2004, 'LLIL_INTRINSIC([lr],__autia2,[LLIL_REG.q(lr),LLIL_REG.q(sp),LLIL_CONST.q(0x2000)])'),
# autibsppc <label> (example of encoding: AUTIBSPPC_only_dp_1src_imm)
(b'\x3F\x00\xA0\xF3', 0x1000, 'LLIL_INTRINSIC([lr],__autib2,[LLIL_REG.q(lr),LLIL_REG.q(sp),LLIL_CONST.q(0xFFC)])'),
]
# DO NOT LIFT PAC AS INTRINSIC
else:
print('testing that select PAC instructions lift to NOP', file=sys.stderr)
Expand Down Expand Up @@ -294,8 +350,25 @@
(b'\xE2\x43\xC1\xDA', 'LLIL_NOP()', ATTR_PTR_AUTH), # xpaci x2
(b'\xE7\x43\xC1\xDA', 'LLIL_NOP()', ATTR_PTR_AUTH), # xpaci x7
(b'\xFF\x20\x03\xD5', 'LLIL_NOP()', ATTR_PTR_AUTH), # xpaclri
# The FEAT_PAuth_LR sign and authenticate instructions, which take a second modifier.
(b'\xFE\x8B\xC1\xDA', 'LLIL_NOP()', ATTR_PTR_AUTH), # pacia171615
(b'\xFE\x8F\xC1\xDA', 'LLIL_NOP()', ATTR_PTR_AUTH), # pacib171615
(b'\xFE\xBB\xC1\xDA', 'LLIL_NOP()', ATTR_PTR_AUTH), # autia171615
(b'\xFE\xBF\xC1\xDA', 'LLIL_NOP()', ATTR_PTR_AUTH), # autib171615
(b'\xBE\x90\xC1\xDA', 'LLIL_NOP()', ATTR_PTR_AUTH), # autiasppcr x5
(b'\x3E\x95\xC1\xDA', 'LLIL_NOP()', ATTR_PTR_AUTH), # autibsppcr x9
(b'\xFE\xA3\xC1\xDA', 'LLIL_NOP()', ATTR_PTR_AUTH), # paciasppc
(b'\xFE\xA7\xC1\xDA', 'LLIL_NOP()', ATTR_PTR_AUTH), # pacibsppc
(b'\xFE\x83\xC1\xDA', 'LLIL_NOP()', ATTR_PTR_AUTH), # pacnbiasppc
(b'\xFE\x87\xC1\xDA', 'LLIL_NOP()', ATTR_PTR_AUTH), # pacnbibsppc
(b'\x3F\x00\x80\xF3', 'LLIL_NOP()', ATTR_PTR_AUTH), # autiasppc <label>
(b'\x3F\x00\xA0\xF3', 'LLIL_NOP()', ATTR_PTR_AUTH), # autibsppc <label>
])

# Lifted as a NOP none of these carry an address, so they are position independent and are
# covered above rather than in tests_position_dependent.
tests_pac_position_dependent = []

tests_load_acquire_store_release = [
# LDAPURB <Wt>, [<Xn|SP>{, #<simm>}]
(b'\xBE\xE3\x53\x19', 'LLIL_SET_REG.d(w30,LLIL_ZX.d(LLIL_LOAD.b(LLIL_ADD.q(LLIL_REG.q(fp),LLIL_CONST.q(0xFFFFFFFFFFFFFF3E)))))'), # ldapurb w30, [fp, #-0xc2]
Expand Down Expand Up @@ -12881,6 +12954,29 @@
# op 17 is the enable/disable pair, whose operand selects between them
(b'\x20\x12\x20\x00', 'amx_set '),
(b'\x21\x12\x20\x00', 'amx_clr '),

# FEAT_PAuth_LR. Most of these lift to a NOP, so their operands only show up here.
# the registers each of these works on are fixed by the encoding, leaving no operands to render
(b'\xfe\xa3\xc1\xda', 'paciasppc '),
(b'\xfe\xa7\xc1\xda', 'pacibsppc '),
(b'\xfe\x83\xc1\xda', 'pacnbiasppc '),
(b'\xfe\x87\xc1\xda', 'pacnbibsppc '),
(b'\xfe\x8b\xc1\xda', 'pacia171615 '),
(b'\xfe\x8f\xc1\xda', 'pacib171615 '),
(b'\xfe\xbb\xc1\xda', 'autia171615 '),
(b'\xfe\xbf\xc1\xda', 'autib171615 '),
(b'\xff\x24\x03\xd5', 'pacm '),
# the modifier is a register
(b'\xbe\x90\xc1\xda', 'autiasppcr x5'),
(b'\x3e\x95\xc1\xda', 'autibsppcr x9'),
(b'\xe3\x0b\x5f\xd6', 'retaasppcr x3'),
(b'\xec\x0f\x5f\xd6', 'retabsppcr x12'),
# the modifier is a label the encoding reaches by subtracting from the address, here by 4, so at
# address 0 it is the address just below zero rather than one just above it
(b'\x3f\x00\x80\xf3', 'autiasppc 0xfffffffffffffffc'),
(b'\x3f\x00\xa0\xf3', 'autibsppc 0xfffffffffffffffc'),
(b'\x3f\x00\x00\x55', 'retaasppc 0xfffffffffffffffc'),
(b'\x3f\x00\x20\x55', 'retabsppc 0xfffffffffffffffc'),
]

test_cases = \
Expand Down Expand Up @@ -12959,7 +13055,7 @@
(b'\x06\x01\x00\x98', 0x0, 'LLIL_SET_REG.q(x6,LLIL_SX.q(LLIL_LOAD.d(LLIL_CONST.q(0x20))))'),
(b'\x06\x01\x00\x98', 0x8000, 'LLIL_SET_REG.q(x6,LLIL_SX.q(LLIL_LOAD.d(LLIL_CONST.q(0x8020))))'),
(b'\x06\x01\x00\x98', 0x8004, 'LLIL_SET_REG.q(x6,LLIL_SX.q(LLIL_LOAD.d(LLIL_CONST.q(0x8024))))'),
]
] + tests_pac_position_dependent

# The encodings above, which must not be lifted from the shared view.
position_dependent_encodings = {data for data, _, _ in tests_position_dependent}
Expand Down
31 changes: 30 additions & 1 deletion arch/arm64/disassembler/decode_scratchpad.c
Original file line number Diff line number Diff line change
Expand Up @@ -1574,10 +1574,12 @@ int decode_scratchpad(context* ctx, Instruction* instr)

switch (instr->encoding)
{
/* instrucitons with no operands */
/* instructions with no operands */
case ENC_AUTIA171615_64LR_DP_1SRC:
case ENC_AUTIA1716_HI_HINTS:
case ENC_AUTIASP_HI_HINTS:
case ENC_AUTIAZ_HI_HINTS:
case ENC_AUTIB171615_64LR_DP_1SRC:
case ENC_AUTIB1716_HI_HINTS:
case ENC_AUTIBSP_HI_HINTS:
case ENC_AUTIBZ_HI_HINTS:
Expand All @@ -1591,12 +1593,19 @@ int decode_scratchpad(context* ctx, Instruction* instr)
case ENC_ERET_64E_BRANCH_REG:
case ENC_ESB_HI_HINTS:
case ENC_NOP_HI_HINTS:
case ENC_PACIA171615_64LR_DP_1SRC:
case ENC_PACIA1716_HI_HINTS:
case ENC_PACIASP_HI_HINTS:
case ENC_PACIASPPC_64LR_DP_1SRC:
case ENC_PACIAZ_HI_HINTS:
case ENC_PACIB171615_64LR_DP_1SRC:
case ENC_PACIB1716_HI_HINTS:
case ENC_PACIBSP_HI_HINTS:
case ENC_PACIBSPPC_64LR_DP_1SRC:
case ENC_PACIBZ_HI_HINTS:
case ENC_PACM_HI_HINTS:
case ENC_PACNBIASPPC_64LR_DP_1SRC:
case ENC_PACNBIBSPPC_64LR_DP_1SRC:
case ENC_RETAA_64E_BRANCH_REG:
case ENC_RETAB_64E_BRANCH_REG:
case ENC_SEVL_HI_HINTS:
Expand Down Expand Up @@ -6037,6 +6046,8 @@ int decode_scratchpad(context* ctx, Instruction* instr)
}
break;
}
case ENC_AUTIASPPCR_64LRR_DP_1SRC:
case ENC_AUTIBSPPCR_64LRR_DP_1SRC:
case ENC_BLRAAZ_64_BRANCH_REG:
case ENC_BLRABZ_64_BRANCH_REG:
case ENC_BLR_64_BRANCH_REG:
Expand Down Expand Up @@ -7770,6 +7781,24 @@ int decode_scratchpad(context* ctx, Instruction* instr)
ADD_OPERAND_LABEL;
break;
}
case ENC_RETAASPPCR_64M_BRANCH_REG:
case ENC_RETABSPPCR_64M_BRANCH_REG:
{
// <Xm>
ADD_OPERAND_XM;
break;
}
case ENC_AUTIASPPC_ONLY_DP_1SRC_IMM:
case ENC_AUTIBSPPC_ONLY_DP_1SRC_IMM:
case ENC_RETAASPPC_ONLY_MISCBRANCH:
case ENC_RETABSPPC_ONLY_MISCBRANCH:
{
/* these encode a negative offset: the modifier is PC minus <offset> */
uint64_t eaddr = ctx->address - ctx->offset;
// <label>
ADD_OPERAND_LABEL;
break;
}
case ENC_SYS_CR_SYSTEMINSTRS:
{
// sys #<op1>,<Cn>,<Cm>, #<op2>{,<Xt>}
Expand Down
72 changes: 72 additions & 0 deletions arch/arm64/il.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1263,6 +1263,14 @@ enum Arm64Intrinsic operation_to_intrinsic(int operation)
case ARM64_AUTIBZ:
case ARM64_AUTIZB:
return ARM64_INTRIN_AUTIB;
case ARM64_AUTIA171615:
case ARM64_AUTIASPPC:
case ARM64_AUTIASPPCR:
return ARM64_INTRIN_AUTIA2;
case ARM64_AUTIB171615:
case ARM64_AUTIBSPPC:
case ARM64_AUTIBSPPCR:
return ARM64_INTRIN_AUTIB2;
case ARM64_PACDA:
case ARM64_PACDZA:
return ARM64_INTRIN_PACDA;
Expand All @@ -1283,6 +1291,14 @@ enum Arm64Intrinsic operation_to_intrinsic(int operation)
case ARM64_PACIBZ:
case ARM64_PACIZB:
return ARM64_INTRIN_PACIB;
case ARM64_PACIA171615:
case ARM64_PACIASPPC:
case ARM64_PACNBIASPPC:
return ARM64_INTRIN_PACIA2;
case ARM64_PACIB171615:
case ARM64_PACIBSPPC:
case ARM64_PACNBIBSPPC:
return ARM64_INTRIN_PACIB2;
case ARM64_XPACD:
return ARM64_INTRIN_XPACD;
case ARM64_XPACI:
Expand Down Expand Up @@ -3065,6 +3081,38 @@ bool GetLowLevelILForInstruction(
il.AddInstruction(il.Intrinsic({RegisterOrFlag::Register(REG_X30)},
operation_to_intrinsic(instr.operation), {il.Register(8, REG_X30), il.Register(8, REG_SP)}));
break;
case ARM64_AUTIA171615:
case ARM64_AUTIB171615:
case ARM64_PACIA171615:
case ARM64_PACIB171615:
// x17 is address, x16 and x15 are the modifiers
il.AddInstruction(il.Intrinsic({RegisterOrFlag::Register(REG_X17)},
operation_to_intrinsic(instr.operation),
{il.Register(8, REG_X17), il.Register(8, REG_X16), il.Register(8, REG_X15)}));
break;
case ARM64_PACIASPPC:
case ARM64_PACIBSPPC:
case ARM64_PACNBIASPPC:
case ARM64_PACNBIBSPPC:
// x30 is address, sp and this instruction's own address are the modifiers
il.AddInstruction(il.Intrinsic({RegisterOrFlag::Register(REG_X30)},
operation_to_intrinsic(instr.operation),
{il.Register(8, REG_X30), il.Register(8, REG_SP), il.ConstPointer(addrSize, addr)}));
break;
case ARM64_AUTIASPPCR:
case ARM64_AUTIBSPPCR:
// x30 is address, sp and <Xn> are the modifiers
il.AddInstruction(il.Intrinsic({RegisterOrFlag::Register(REG_X30)},
operation_to_intrinsic(instr.operation),
{il.Register(8, REG_X30), il.Register(8, REG_SP), ILREG_O(operand1)}));
break;
case ARM64_AUTIASPPC:
case ARM64_AUTIBSPPC:
// x30 is address, sp and <label> (already resolved to pc-offset by the decoder) are the modifiers
il.AddInstruction(il.Intrinsic({RegisterOrFlag::Register(REG_X30)},
operation_to_intrinsic(instr.operation),
{il.Register(8, REG_X30), il.Register(8, REG_SP), il.ConstPointer(addrSize, IMM_O(operand1))}));
break;
#else
case ARM64_AUTDA:
case ARM64_AUTDB:
Expand Down Expand Up @@ -3098,6 +3146,18 @@ bool GetLowLevelILForInstruction(
case ARM64_AUTIBSP:
case ARM64_PACIASP:
case ARM64_PACIBSP:
case ARM64_AUTIA171615:
case ARM64_AUTIB171615:
case ARM64_PACIA171615:
case ARM64_PACIB171615:
case ARM64_AUTIASPPC:
case ARM64_AUTIBSPPC:
case ARM64_AUTIASPPCR:
case ARM64_AUTIBSPPCR:
case ARM64_PACIASPPC:
case ARM64_PACIBSPPC:
case ARM64_PACNBIASPPC:
case ARM64_PACNBIBSPPC:
il.AddInstruction(il.Nop());
ApplyAttributeToLastInstruction(il, SrcInstructionUsesPointerAuth);
break;
Expand Down Expand Up @@ -3160,6 +3220,15 @@ bool GetLowLevelILForInstruction(
case ARM64_PSB:
il.AddInstruction(il.Intrinsic({}, ARM64_INTRIN_PSBCSYNC, {}));
break;
case ARM64_RETAASPPC:
case ARM64_RETABSPPC:
case ARM64_RETAASPPCR:
case ARM64_RETABSPPCR:
// Unlike RET, the operand here is an authentication modifier. These always
// return to x30.
il.AddInstruction(il.Return(il.Register(8, REG_X30)));
ApplyAttributeToLastInstruction(il, SrcInstructionUsesPointerAuth);
break;
case ARM64_RETAA:
case ARM64_RETAB:
SetPacAttr = true;
Expand Down Expand Up @@ -4167,6 +4236,9 @@ bool GetLowLevelILForInstruction(
case ARM64_CSDB:
il.AddInstruction(il.Intrinsic({}, ARM64_INTRIN_HINT_CSDB, {}));
break;
case ARM64_PACM:
il.AddInstruction(il.Intrinsic({}, ARM64_INTRIN_HINT_PACM, {}));
break;
case ARM64_HINT:
if ((IMM_O(operand1) & ~0b110) == 0b100000)
il.AddInstruction(il.Intrinsic({}, ARM64_INTRIN_HINT_BTI, {}));
Expand Down
6 changes: 6 additions & 0 deletions arch/arm64/il.h
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,12 @@ enum Arm64Intrinsic : uint32_t
ARM64_INTRIN_SUBG,
ARM64_INTRIN_SUBP,
ARM64_INTRIN_SUBPS,
/* FEAT_PAuth_LR: sign/authenticate against two modifiers (AddPAC*2 / Auth*2) */
ARM64_INTRIN_HINT_PACM,
ARM64_INTRIN_AUTIA2,
ARM64_INTRIN_AUTIB2,
ARM64_INTRIN_PACIA2,
ARM64_INTRIN_PACIB2,
ARM64_INTRIN_NORMAL_END, /* needed so intrinsics can be extended by other lists, like neon
intrinsics */
ARM64_INTRIN_INVALID = 0xFFFFFFFF,
Expand Down