On Thu, Nov 20, 2025 at 03:10:41PM -0800, Andrew Pinski wrote:
> On Thu, Nov 20, 2025 at 2:57 PM Andrew Pinski
> <[email protected]> wrote:
> > Also I am still trying to figure out and understand the interaction
> > between x16 and x17 in some cases.
> > Because I thought indirect calls/jumps will be using x16/x17 for those
> > to support BTI.
>
> Oh yes:
> (define_register_constraint "Ucr"
> "aarch64_harden_sls_blr_p () ? STUB_REGS : GENERAL_REGS"
> "@internal Registers to be used for an indirect call.
> This is usually the general registers, but when we are hardening against
> Straight Line Speculation we disallow x16, x17, and x30 so we can use
> indirection stubs. These indirection stubs cannot use the above registers
> since they will be reached by a BL that may have to go through a linker
> veneer.")
>
> But you don't change Ucr so in theory x16/x17 could be used for
> call_value_insn.
> (I can't get that one using x16/x17 right now).
>
> Oh and sibcall_insn uses Ucs which is defined as:
> (define_register_constraint "Ucs" "TAILCALL_ADDR_REGS"
> "@internal Registers suitable for an indirect tail call")
> TAILCALL_ADDR_REGS is a register class which just contains x16/x17.
Hm, I will need to study this more closely. I wonder if both kcfi and sls
hardening end up being self-contained users of the scratch registers? I'll
double check that my kernel test builds have SLS hardening enabled. (And
I'll likely need to add some aarch64-specific sibcall tests with/without
SLS hardening to see the resulting asm.)
> I don't see a testcase for indirect sibcall either.
>
> ```
> typedef void (*fptr)(void);
> void f(fptr a)
> {
> a();
> }
> ```
> Is a testcase for the indirect sibcall case.
I did include basic tests for a variety of sibcalls in the patch that
added the general tests; see gcc/testsuite/gcc.dg/kcfi/kcfi-tail-calls.c
(though I named it "tail calls"), and the fptr test includes an argument
(the comment is x86-specific, but it should be a valid test for all archs):
+/* Indirect call through function pointer parameter. */
+int test_param_indirect_call(func_ptr_t handler, int x) {
+ /* This is an indirect call that should be converted to tail call:
+ Without -fno-optimize-sibling-calls should become "jmp *%rdi"
+ With -fno-optimize-sibling-calls should be "call *%rdi" */
+ return handler(x);
+}
-Kees
--
Kees Cook