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

Reply via email to