kovdan01 wrote: @atrosinenko Here is a reproducer IR code.
<details> ``` define void @_ZN7myshape4moveEv(ptr %this) #0 { entry: %0 = load ptr, ptr %this, align 8 %vtable = load ptr, ptr %0, align 8 %1 = ptrtoint ptr %0 to i64 %2 = tail call i64 @llvm.ptrauth.blend(i64 %1, i64 50297) %3 = ptrtoint ptr %vtable to i64 %4 = tail call i64 @llvm.ptrauth.auth(i64 %3, i32 2, i64 %2) %5 = inttoptr i64 %4 to ptr %6 = load ptr, ptr %5, align 8 %7 = tail call i64 @llvm.ptrauth.blend(i64 %4, i64 36564) tail call void %6(ptr noundef nonnull align 8 dereferenceable(8) %0) [ "ptrauth"(i32 0, i64 %7) ] %r = getelementptr inbounds i8, ptr %this, i64 8 %8 = load ptr, ptr %r, align 8 %vtable2 = load ptr, ptr %8, align 8 %9 = ptrtoint ptr %8 to i64 %10 = tail call i64 @llvm.ptrauth.blend(i64 %9, i64 50297) %11 = ptrtoint ptr %vtable2 to i64 %12 = tail call i64 @llvm.ptrauth.auth(i64 %11, i32 2, i64 %10) %13 = inttoptr i64 %12 to ptr %14 = load ptr, ptr %13, align 8 %15 = tail call i64 @llvm.ptrauth.blend(i64 %12, i64 36564) tail call void %14(ptr noundef nonnull align 8 dereferenceable(8) %8) [ "ptrauth"(i32 0, i64 %15) ] ret void } declare i64 @llvm.ptrauth.blend(i64, i64) declare i64 @llvm.ptrauth.auth(i64, i32 immarg, i64) attributes #0 = { "ptrauth-auth-traps" "ptrauth-calls" "ptrauth-returns" } ``` </details> When compiled with `llc -O3 -mtriple aarch64-linux-gnu -mattr=+pauth`, the following assembly is generated. X16 register is clobbered during check inserted under `else if (Method == AuthCheckMethod::HighBitsNoTBI)`. The previous value (containing pointer for address discrimination) is not spilled before and not restored after that. So, the last `braa` instructio uses incorrect discrimination value in X16 register, which results in authentication failure and trying to pass control to an address with non-zero pac field, causing a segfault. nProbably, a different scratch register (e.g. X17) should be used for check sequence if X16 is already in use for address discrimination. <details> ``` _ZN7myshape4moveEv: // @_ZN7myshape4moveEv .cfi_startproc // %bb.0: // %entry .cfi_b_key_frame pacibsp stp x30, x19, [sp, #-16]! // 16-byte Folded Spill .cfi_negate_ra_state .cfi_def_cfa_offset 16 .cfi_offset w19, -8 .cfi_offset w30, -16 mov x19, x0 ldr x0, [x0] ldr x16, [x0] mov x17, x0 movk x17, #50297, lsl #48 autda x16, x17 mov x17, x16 xpacd x17 cmp x16, x17 b.eq .Lauth_success_0 brk #0xc472 .Lauth_success_0: ldr x9, [x16] mov x8, x16 mov x17, x8 movk x17, #36564, lsl #48 blraa x9, x17 ldr x0, [x19, #8] ldr x16, [x0] mov x17, x0 movk x17, #50297, lsl #48 autda x16, x17 mov x17, x16 xpacd x17 cmp x16, x17 b.eq .Lauth_success_1 brk #0xc472 .Lauth_success_1: ldr x1, [x16] ldp x30, x19, [sp], #16 // 16-byte Folded Reload autibsp eor x16, x30, x30, lsl #1 tbz x16, #62, .Lauth_success_2 brk #0xc471 .Lauth_success_2: movk x16, #36564, lsl #48 braa x1, x16 ``` </details> The IR corresponds to the following C++ code. <details> ``` struct shape { virtual void move() = 0; }; struct line : public shape { void move () override; }; struct myshape { line *l; line *r; void move(); }; void myshape::move() { l->move(); r->move(); } ``` </details> https://github.com/llvm/llvm-project/pull/110705 _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits