Skip to content

Commit e697e49

Browse files
committed
[concurrency] IRGen:: do ptrauth for hop_to_executor
Sign the resume-function pointer which is stored in AsyncTask.ResumeTask
1 parent 8f136f3 commit e697e49

File tree

4 files changed

+30
-5
lines changed

4 files changed

+30
-5
lines changed

include/swift/AST/IRGenOptions.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,9 @@ struct PointerAuthOptions : clang::PointerAuthOptions {
143143

144144
/// The function to call to resume running in the parent context.
145145
PointerAuthSchema AsyncContextResume;
146+
147+
/// The resume function stored in AsyncTask.
148+
PointerAuthSchema TaskResumeFunction;
146149
};
147150

148151
enum class JITDebugArtifact : unsigned {

lib/IRGen/GenFunc.cpp

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2462,7 +2462,16 @@ IRGenFunction::createAsyncDispatchFn(const FunctionPointer &fnPtr,
24622462

24632463
void IRGenFunction::emitSuspensionPoint(llvm::Value *toExecutor,
24642464
llvm::Value *asyncResume) {
2465-
// TODO: pointerauth
2465+
2466+
llvm::Value *task = getAsyncTask();
2467+
llvm::Value *callableResume = asyncResume;
2468+
2469+
if (auto schema = IGM.getOptions().PointerAuth.TaskResumeFunction) {
2470+
auto *resumeAddr = Builder.CreateStructGEP(task, 4);
2471+
auto authInfo = PointerAuthInfo::emit(
2472+
*this, schema, resumeAddr, PointerAuthEntity());
2473+
callableResume = emitPointerAuthSign(*this, asyncResume, authInfo);
2474+
}
24662475

24672476
// Setup the suspend point.
24682477
SmallVector<llvm::Value *, 8> arguments;
@@ -2474,10 +2483,10 @@ void IRGenFunction::emitSuspensionPoint(llvm::Value *toExecutor,
24742483
arguments.push_back(
24752484
Builder.CreateBitOrPointerCast(suspendFn, IGM.Int8PtrTy));
24762485

2477-
arguments.push_back(asyncResume);
2486+
arguments.push_back(callableResume);
24782487
arguments.push_back(
24792488
Builder.CreateBitOrPointerCast(toExecutor, getAsyncExecutor()->getType()));
2480-
arguments.push_back(getAsyncTask());
2489+
arguments.push_back(task);
24812490
arguments.push_back(getAsyncExecutor());
24822491
arguments.push_back(getAsyncContext());
24832492

lib/IRGen/IRGen.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -696,6 +696,10 @@ static void setPointerAuthOptions(PointerAuthOptions &opts,
696696
opts.AsyncContextResume =
697697
PointerAuthSchema(codeKey, /*address*/ true, Discrimination::Constant,
698698
SpecialPointerAuthDiscriminators::AsyncContextResume);
699+
700+
opts.TaskResumeFunction =
701+
PointerAuthSchema(codeKey, /*address*/ true, Discrimination::Constant,
702+
SpecialPointerAuthDiscriminators::TaskResumeFunction);
699703
}
700704

701705
std::unique_ptr<llvm::TargetMachine>

test/IRGen/async/hop_to_executor.sil

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: %target-swift-frontend -enable-experimental-concurrency -primary-file %s -module-name=test -disable-llvm-optzns -disable-swift-specific-llvm-optzns -emit-ir -sil-verify-all | %FileCheck %s
1+
// RUN: %target-swift-frontend -enable-experimental-concurrency -primary-file %s -module-name=test -disable-llvm-optzns -disable-swift-specific-llvm-optzns -emit-ir -sil-verify-all | %FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-%target-cpu
22

33
// REQUIRES: concurrency
44

@@ -15,12 +15,21 @@ final actor class MyActor {
1515
}
1616

1717
// CHECK-LABEL: define{{.*}} void @test_simple(%swift.task* %0, %swift.executor* %1, %swift.context* %2)
18+
// CHECK: [[TASK_LOC:%[0-9]+]] = alloca %swift.task*
1819
// CHECK: [[CTX:%[0-9]+]] = bitcast %swift.context* %2
1920
// CHECK: [[ACTOR_ADDR:%[0-9]+]] = getelementptr {{.*}} [[CTX]], i32 0, i32 6
2021
// CHECK: [[ACTOR:%[0-9]+]] = load %T4test7MyActorC*, %T4test7MyActorC** [[ACTOR_ADDR]]
2122
// CHECK: [[RESUME:%[0-9]+]] = call i8* @llvm.coro.async.resume()
23+
// CHECK: [[TASK:%[0-9]+]] = load %swift.task*, %swift.task** [[TASK_LOC]]
24+
// CHECK-arm64e: [[RESUME_ADDR:%[0-9]+]] = getelementptr inbounds %swift.task, %swift.task* [[TASK]], i32 0, i32 4
25+
// CHECK-arm64e: [[RESUME_ADDR_INT:%[0-9]+]] = ptrtoint i8** [[RESUME_ADDR]] to i64
26+
// CHECK-arm64e: [[PTRAUTH_BLEND:%[0-9]+]] = call i64 @llvm.ptrauth.blend.i64(i64 [[RESUME_ADDR_INT]], i64 11330)
27+
// CHECK-arm64e: [[RESUME_INT:%[0-9]+]] = ptrtoint i8* [[RESUME]] to i64
28+
// CHECK-arm64e: [[SIGNED_INT:%[0-9]+]] = call i64 @llvm.ptrauth.sign.i64(i64 [[RESUME_INT]], i32 0, i64 [[PTRAUTH_BLEND]])
29+
// CHECK-arm64e: [[SIGNED_RESUME:%[0-9]+]] = inttoptr i64 [[SIGNED_INT]] to i8*
2230
// CHECK: [[CAST_ACTOR:%[0-9]+]] = bitcast %T4test7MyActorC* [[ACTOR]] to %swift.executor*
23-
// CHECK: call {{.*}} @llvm.coro.suspend.async(i8* [[RESUME]], i8* bitcast (i8* (i8*)* @__swift_async_resume_get_context to i8*), i8* bitcast (void (i8*, %swift.executor*, %swift.task*, %swift.executor*, %swift.context*)* @__swift_suspend_point to i8*), i8* [[RESUME]], %swift.executor* [[CAST_ACTOR]], %swift.task* {{%[0-9]+}}, %swift.executor* {{%[0-9]+}}, %swift.context* {{%[0-9]+}})
31+
// CHECK-x86_64: call {{.*}} @llvm.coro.suspend.async(i8* [[RESUME]], i8* bitcast (i8* (i8*)* @__swift_async_resume_get_context to i8*), i8* bitcast (void (i8*, %swift.executor*, %swift.task*, %swift.executor*, %swift.context*)* @__swift_suspend_point to i8*), i8* [[RESUME]], %swift.executor* [[CAST_ACTOR]], %swift.task* [[TASK]], %swift.executor* {{%[0-9]+}}, %swift.context* {{%[0-9]+}})
32+
// CHECK-arm64e: call {{.*}} @llvm.coro.suspend.async(i8* [[SIGNED_RESUME]], i8* bitcast (i8* (i8*)* @__swift_async_resume_get_context to i8*), i8* bitcast (void (i8*, %swift.executor*, %swift.task*, %swift.executor*, %swift.context*)* @__swift_suspend_point to i8*), i8* [[SIGNED_RESUME]], %swift.executor* [[CAST_ACTOR]], %swift.task* [[TASK]], %swift.executor* {{%[0-9]+}}, %swift.context* {{%[0-9]+}})
2433
sil @test_simple : $@convention(method) @async (@guaranteed MyActor) -> () {
2534
bb0(%0 : $MyActor):
2635
hop_to_executor %0 : $MyActor

0 commit comments

Comments
 (0)