On Sun, Sep 14, 2025 at 12:45 PM Kees Cook <k...@kernel.org> wrote:
>
> On Sat, Sep 13, 2025 at 04:43:29PM -0700, Andrew Pinski wrote:
> > On Sat, Sep 13, 2025 at 4:28 PM Kees Cook <k...@kernel.org> wrote:
> > >
> > > Implement AArch64-specific KCFI backend.
> > >
> > > - Trap debugging through ESR (Exception Syndrome Register) encoding
> > >   in BRK instruction immediate values.
> > >
> > > - Scratch register allocation using w16/w17 (x16/x17) following
> > >   AArch64 procedure call standard for intra-procedure-call registers.
> >
> > How does this interact with BTI and sibcalls? Since for indirect
> > calls, x17 is already used for the address.
> > Why do you need/want to use a fixed register here for the load/compare
> > anyways? Why can't you use any free register?
>
> Ah, yeah, good point. I'm struggling with this on aarch32 too for Ard's
> suggestion about using an eor sequence. So, the problem I haven't been
> able to solve is that call instructions cannot have scratch register
> operands. Or rather, can't when there is register pressure like on
> aarch32, where a spill would be needed. This is in the LRA:
>
>   if (CALL_P (curr_insn))
>     no_output_reloads_p = true;
>
> And that does make perfect sense, there's no place (in the current
> design) to provide a place where the reload would happen. But I also
> can't let the kcfi check/call get split up arbitrarily.
>
> Is there some way I can convince LRA to let me do the restore manually?
>
> > > +const char *
> > > +aarch64_output_kcfi_insn (rtx_insn *insn, rtx *operands)
> > > +{
> > > +  /* KCFI is only supported in LP64 mode.  */
> > > +  if (TARGET_ILP32)
> > > +    {
> > > +      sorry ("%<-fsanitize=kcfi%> is not supported for %<-mabi=ilp32%>");
> >
> > You should reject -fsanitize=kcfi during option processing instead of
> > this late in the compilation.
>
> Where is best to do this on a per-arch basis?

In the case of aarch64, aarch64_override_options_internal looks like a
good place. There are already errors produced here when it comes to
incompatible options. Other targets will have a similar place too; I
was only reviewing the aarch64 specific changes here.

Thanks,
Andrew Pinski

>
> > > +  /* Get KCFI type ID from operand[3].  */
> > > +  uint32_t type_id = (uint32_t) INTVAL (operands[3]);
> >
> > Maybe an assert that `(int32_t)type_id == INTVAL (operands[3])`?
>
> Oh, hm, actually, I think I should be using UINTVAL instead?
>
> > > +  /* Load actual type into w16 from memory at offset using ldur.  */
> > > +  temp_operands[0] = gen_rtx_REG (SImode, R16_REGNUM);
> > > +  temp_operands[1] = target_reg;
> > > +  temp_operands[2] = GEN_INT (offset);
> > > +  output_asm_insn ("ldur\t%w0, [%1, #%2]", temp_operands);
> >
> > Since you are using a fixed register, you don't need the temp_operands[0] 
> > here.
> > Also what happens if target_reg is x16? Shouldn't there be an assert
> > on that here?
>
> Yeah, I need to solve the scratch register issue more generally.
>
> > > +  /* Output conditional branch to call label.  */
> > > +  fputs ("\tb.eq\t", asm_out_file);
> > > +  assemble_name (asm_out_file, call_name);
> > > +  fputc ('\n', asm_out_file);
> >
> > There has to be a better way of implementing this.
>
> I couldn't find one that would let me keep the custom label name. I'd
> love to have something better! :)
>
>
> --
> Kees Cook

Reply via email to