Skip to content

Commit 0f2b659

Browse files
committed
[PtrAuth] Pass discriminator to swift_suspend_dispatch.
Previously, swift_suspend_dispatch was passed a pointer to a function and createAsyncDispatchFn was passed a FunctionPointer. The latter constructed a new FunctionPointer using the passed-in function pointer as the value, because the value inside the FunctionPointer was a value in a different function. That worked fine on platforms without pointer authentication. On arm64e, however, calling a function can use two values from a FunctionPointer: the pointer to the function and the discriminator. The result was that on arm64e, swift_suspend_dispatch failed verification because the discriminator value that was used in the call made by swift_suspend_dispatch did not originate in that function. Here, that problem is resolved by passing the discriminator to swift_suspend_dispatch. Now, createAsyncDispatchFn creates a FunctionPointer using not just the passed-in function pointer but also the passed-in discriminator. The result is that swift_suspend_dispatch no longer fails verification.
1 parent b8ec80a commit 0f2b659

File tree

2 files changed

+15
-3
lines changed

2 files changed

+15
-3
lines changed

lib/IRGen/GenCall.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2480,6 +2480,9 @@ class AsyncCallEmission final : public CallEmission {
24802480
Builder.CreateBitOrPointerCast(dispatchFn, IGM.Int8PtrTy));
24812481
arguments.push_back(
24822482
Builder.CreateBitOrPointerCast(fn.getRawPointer(), IGM.Int8PtrTy));
2483+
if (auto authInfo = fn.getAuthInfo()) {
2484+
arguments.push_back(fn.getAuthInfo().getDiscriminator());
2485+
}
24832486
for (auto arg: args)
24842487
arguments.push_back(arg);
24852488
return IGF.emitSuspendAsyncCall(arguments);

lib/IRGen/GenFunc.cpp

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2418,6 +2418,10 @@ IRGenFunction::createAsyncDispatchFn(const FunctionPointer &fnPtr,
24182418
ArrayRef<llvm::Type *> argTypes) {
24192419
SmallVector<llvm::Type*, 8> argTys;
24202420
argTys.push_back(IGM.Int8PtrTy); // Function pointer to be called.
2421+
auto originalAuthInfo = fnPtr.getAuthInfo();
2422+
if (fnPtr.getAuthInfo()) {
2423+
argTys.push_back(IGM.Int64Ty); // Discriminator for the function pointer.
2424+
}
24212425
for (auto ty : argTypes) {
24222426
argTys.push_back(ty);
24232427
}
@@ -2437,13 +2441,18 @@ IRGenFunction::createAsyncDispatchFn(const FunctionPointer &fnPtr,
24372441
IGM.DebugInfo->emitArtificialFunction(dispatchIGF, dispatch);
24382442
auto &Builder = dispatchIGF.Builder;
24392443
auto it = dispatchIGF.CurFn->arg_begin(), end = dispatchIGF.CurFn->arg_end();
2440-
llvm::Value *ptrArg = &*(it++);
2444+
llvm::Value *fnPtrArg = &*(it++);
2445+
llvm::Value *discriminatorArg = ((bool)originalAuthInfo) ? &*(it++) : nullptr;
24412446
SmallVector<llvm::Value *, 8> callArgs;
24422447
for (; it != end; ++it) {
24432448
callArgs.push_back(&*it);
24442449
}
2445-
ptrArg = Builder.CreateBitOrPointerCast(ptrArg, calleeFnPtrType);
2446-
auto callee = FunctionPointer(fnPtr.getKind(), ptrArg, fnPtr.getAuthInfo(),
2450+
fnPtrArg = Builder.CreateBitOrPointerCast(fnPtrArg, calleeFnPtrType);
2451+
PointerAuthInfo newAuthInfo =
2452+
((bool)originalAuthInfo)
2453+
? PointerAuthInfo(fnPtr.getAuthInfo().getKey(), discriminatorArg)
2454+
: originalAuthInfo;
2455+
auto callee = FunctionPointer(fnPtr.getKind(), fnPtrArg, newAuthInfo,
24472456
fnPtr.getSignature());
24482457
auto call = Builder.CreateCall(callee, callArgs);
24492458
call->setTailCall();

0 commit comments

Comments
 (0)