@@ -308,6 +308,8 @@ struct reloc_entry
/* Typecheck: same, plus SVE registers. */ \
MULTI_REG_TYPE(SVE_BASE, REG_TYPE(R_64) | REG_TYPE(SP_64) \
| REG_TYPE(Z)) \
+ /* Typecheck: x[0-30], w[0-30]. */ \
+ MULTI_REG_TYPE(R, REG_TYPE(R_32) | REG_TYPE(R_64)) \
/* Typecheck: x[0-30], w[0-30] or [xw]zr. */ \
MULTI_REG_TYPE(R_ZR, REG_TYPE(R_32) | REG_TYPE(R_64) \
| REG_TYPE(ZR_32) | REG_TYPE(ZR_64)) \
@@ -6842,7 +6844,10 @@ parse_operands (char *str, const aarch64_opcode *opcode)
case AARCH64_OPND_PAIRREG:
case AARCH64_OPND_PAIRREG_OR_XZR:
case AARCH64_OPND_SVE_Rm:
- po_int_fp_reg_or_fail (REG_TYPE_R_ZR);
+ if (opcode->iclass == pauth_lr && operands[i] == AARCH64_OPND_Rd)
+ po_int_fp_reg_or_fail (REG_TYPE_R);
+ else
+ po_int_fp_reg_or_fail (REG_TYPE_R_ZR);
/* In LS64 load/store instructions Rt register number must be even
and <=22. */
new file mode 100644
@@ -0,0 +1,3 @@
+#source: pauth_lr-bad.s
+#as: -march=armv9.5-a+pauth-lr
+#error_output: pauth_lr-bad.l
new file mode 100644
@@ -0,0 +1,10 @@
+.*: Assembler messages:
+.*: Error: operand mismatch -- `autiasppcr w0'
+.*: Info: did you mean this\?
+.*: Info: autiasppcr x0
+.*: Error: expected an integer or zero register at operand 1 -- `autiasppcr sp'
+.*: Error: operand mismatch -- `retaasppcr w0'
+.*: Info: did you mean this\?
+.*: Info: retaasppcr x0
+.*: Error: unexpected register type at operand 1 -- `retaasppcr sp'
+.*: Error: unexpected register type at operand 1 -- `retaasppcr xzr'
new file mode 100644
@@ -0,0 +1,11 @@
+ /* FEAT_PAuth_LR Pointer Authentication instructions. */
+ .text
+
+lr_signing:
+
+ autiasppcr w0 // 32-bit registers not allowed
+ autiasppcr sp // stack pointer register not allowed
+
+ retaasppcr w0 // 32-bit registers not allowed
+ retaasppcr sp // SP not allowed
+ retaasppcr xzr // zero register not allowed
new file mode 100644
@@ -0,0 +1,25 @@
+#source: pauth_lr.s
+#as: -march=armv9.5-a+pauth-lr
+#objdump: -dr
+
+.*: file .*
+
+Disassembly of section \.text:
+
+0+ <.*>:
+.*: d50324ff pacm
+.*: dac1a3fe paciasppc
+.*: dac1a7fe pacibsppc
+.*: dac18bfe pacia171615
+.*: dac18ffe pacib171615
+.*: dac183fe pacnbiasppc
+.*: dac187fe pacnbibsppc
+.*: dac1bbfe autia171615
+.*: dac1bffe autib171615
+.*: dac1901e autiasppcr x0
+.*: dac193fe autiasppcr xzr
+.*: dac193de autiasppcr x30
+.*: dac1941e autibsppcr x0
+.*: d65f0be0 retaasppcr x0
+.*: d65f0bfe retaasppcr x30
+.*: d65f0fe0 retabsppcr x0
new file mode 100644
@@ -0,0 +1,31 @@
+ /* FEAT_PAuth_LR Pointer Authentication instructions. */
+ .text
+
+ // only NOP-space instruction to enable ComputePAC2() with PAuth instructions.
+ pacm
+
+ // Signing of LR using SP and PC as diversifiers.
+ paciasppc
+ pacibsppc
+
+ pacia171615
+ pacib171615
+
+ // When used along feature FEAT_BTI
+ pacnbiasppc
+ pacnbibsppc
+
+ // Authenticating the PAC in the address in register LR
+ autia171615
+ autib171615
+
+ // Variant with value of PC passed by register
+ autiasppcr x0
+ autiasppcr xzr
+ autiasppcr x30
+ autibsppcr x0
+
+ // Authentication + return
+ retaasppcr x0
+ retaasppcr x30
+ retabsppcr x0
@@ -1177,6 +1177,7 @@ enum aarch64_insn_class
lse_atomic,
lse128_atomic,
movewide,
+ pauth_lr,
pcreladdr,
ic_system,
sme_fp_sd,
@@ -1103,6 +1103,12 @@
QLF4(V_16B, V_16B, V_16B, imm_0_15), \
}
+/* e.g. AUTI<k>SPPCR Xn */
+#define QL_PAUTH_REG \
+{ \
+ QLF1(X), \
+}
+
/* e.g. . */
#define QL_V3SAMEHS \
{ \
@@ -4428,6 +4434,8 @@ const struct aarch64_opcode aarch64_opcode_table[] =
PAUTH_INSN ("retab", 0xd65f0fff, 0xffffffff, branch_reg, OP0 (), QL_0, F_BRANCH_RET),
PAUTH_INSN ("eretaa", 0xd69f0bff, 0xffffffff, branch_reg, OP0 (), QL_0, F_BRANCH_RET),
PAUTH_INSN ("eretab", 0xd69f0fff, 0xffffffff, branch_reg, OP0 (), QL_0, F_BRANCH_RET),
+ PAUTH_LR_INSN ("retaasppcr", 0xd65f0be0, 0xffffffe0, pauth_lr, OP1 (Rd), QL_PAUTH_REG, F_BRANCH_RET),
+ PAUTH_LR_INSN ("retabsppcr", 0xd65f0fe0, 0xffffffe0, pauth_lr, OP1 (Rd), QL_PAUTH_REG, F_BRANCH_RET),
/* Compare & branch (immediate). */
CORE_INSN ("cbz", 0x34000000, 0x7f000000, compbranch, 0, OP2 (Rt, ADDR_PCREL19), QL_R_PCREL, F_SF),
CORE_INSN ("cbnz", 0x35000000, 0x7f000000, compbranch, 0, OP2 (Rt, ADDR_PCREL19), QL_R_PCREL, F_SF),
@@ -4523,10 +4531,20 @@ const struct aarch64_opcode aarch64_opcode_table[] =
PAUTH_INSN ("pacib", 0xdac10400, 0xfffffc00, dp_1src, OP2 (Rd, Rn_SP), QL_I2SAMEX, 0),
PAUTH_INSN ("pacda", 0xdac10800, 0xfffffc00, dp_1src, OP2 (Rd, Rn_SP), QL_I2SAMEX, 0),
PAUTH_INSN ("pacdb", 0xdac10c00, 0xfffffc00, dp_1src, OP2 (Rd, Rn_SP), QL_I2SAMEX, 0),
+ PAUTH_LR_INSN ("paciasppc", 0xdac1a3fe, 0xffffffff, pauth_lr, OP0 (), {}, F_SUBCLASS_OTHER),
+ PAUTH_LR_INSN ("pacibsppc", 0xdac1a7fe, 0xffffffff, pauth_lr, OP0 (), {}, F_SUBCLASS_OTHER),
+ PAUTH_LR_INSN ("pacnbiasppc", 0xdac183fe, 0xffffffff, pauth_lr, OP0 (), {}, F_SUBCLASS_OTHER),
+ PAUTH_LR_INSN ("pacnbibsppc", 0xdac187fe, 0xffffffff, pauth_lr, OP0 (), {}, F_SUBCLASS_OTHER),
+ PAUTH_LR_INSN ("pacia171615", 0xdac18bfe, 0xffffffff, pauth_lr, OP0 (), {}, F_SUBCLASS_OTHER),
+ PAUTH_LR_INSN ("pacib171615", 0xdac18ffe, 0xffffffff, pauth_lr, OP0 (), {}, F_SUBCLASS_OTHER),
PAUTH_INSN ("autia", 0xdac11000, 0xfffffc00, dp_1src, OP2 (Rd, Rn_SP), QL_I2SAMEX, 0),
PAUTH_INSN ("autib", 0xdac11400, 0xfffffc00, dp_1src, OP2 (Rd, Rn_SP), QL_I2SAMEX, 0),
PAUTH_INSN ("autda", 0xdac11800, 0xfffffc00, dp_1src, OP2 (Rd, Rn_SP), QL_I2SAMEX, 0),
PAUTH_INSN ("autdb", 0xdac11c00, 0xfffffc00, dp_1src, OP2 (Rd, Rn_SP), QL_I2SAMEX, 0),
+ PAUTH_LR_INSN ("autiasppcr", 0xdac1901e, 0xfffffc1f, pauth_lr, OP1 (Rn), QL_PAUTH_REG, F_SUBCLASS_OTHER),
+ PAUTH_LR_INSN ("autibsppcr", 0xdac1941e, 0xfffffc1f, pauth_lr, OP1 (Rn), QL_PAUTH_REG, F_SUBCLASS_OTHER),
+ PAUTH_LR_INSN ("autia171615", 0xdac1bbfe, 0xffffffff, pauth_lr, OP0 (), {}, F_SUBCLASS_OTHER),
+ PAUTH_LR_INSN ("autib171615", 0xdac1bffe, 0xffffffff, pauth_lr, OP0 (), {}, F_SUBCLASS_OTHER),
PAUTH_INSN ("paciza", 0xdac123e0, 0xffffffe0, dp_1src, OP1 (Rd), QL_I1X, 0),
PAUTH_INSN ("pacizb", 0xdac127e0, 0xffffffe0, dp_1src, OP1 (Rd), QL_I1X, 0),
PAUTH_INSN ("pacdza", 0xdac12be0, 0xffffffe0, dp_1src, OP1 (Rd), QL_I1X, 0),