Files
swift-mirror/test/IRGen/ptrauth-value-witnesses.sil
Egor Zhdan b22057e637 [IRGen] Upstream pointer auth for value witness tables
This makes Swift emit a signed pointer to the value witness table in type metadata.

The original change was done by Varun Gandhi.
2024-07-01 16:38:06 +01:00

155 lines
8.9 KiB
Plaintext

// RUN: %swift -swift-version 4 -target arm64e-apple-ios12.0 -parse-stdlib -parse-as-library %s -emit-ir -module-name test -Xcc -Xclang -Xcc -fptrauth-calls | %FileCheck %s --check-prefix=CHECK
// RUN: %swift -swift-version 4 -target arm64e-apple-ios12.0 -parse-stdlib -parse-as-library %s -emit-ir -module-name test -Xcc -Xclang -Xcc -fptrauth-calls
// REQUIRES: CPU=arm64e
// REQUIRES: OS=ios
import Builtin
struct S { var a, b, c: Builtin.NativeObject }
// Check the constant discriminators for all value witnesses.
// CHECK: @"$s4test1SVwCP.ptrauth" = private constant {{.*}} i64 55882
// CHECK: @"$s4test1SVwxx.ptrauth" = private constant {{.*}} i64 1272
// CHECK: @"$s4test1SVwcp.ptrauth" = private constant {{.*}} i64 58298
// CHECK: @"$s4test1SVwca.ptrauth" = private constant {{.*}} i64 34641
// CHECK: @__swift_memcpy24_8.ptrauth = private constant {{.*}} i64 18648
// CHECK: @"$s4test1SVwta.ptrauth" = private constant {{.*}} i64 61402
// CHECK: @"$s4test1SVwet.ptrauth" = private constant {{.*}} i64 24816
// CHECK: @"$s4test1SVwst.ptrauth" = private constant {{.*}} i64 41169
// The pointer to the value witness table is signed too.
// 0x2e3f == 11839 is the constant discriminator for value witness tables.
// CHECK: @"$s4test1SVWV.ptrauth" = private constant {{.*}} i64 11839
sil @test_destroy : $@convention(thin) <T> (@in T) -> () {
bb0(%0 : $*T):
destroy_addr %0 : $*T
%result = tuple ()
return %result : $()
}
// CHECK-LABEL: define swiftcc void @test_destroy(
// CHECK: [[SIGNED_VWT_ADDR:%.*]] = getelementptr inbounds ptr, ptr {{%.*}}, i64 -1
// CHECK: [[SIGNED_VWT:%.*]] = load ptr, ptr [[SIGNED_VWT_ADDR]]
// CHECK: [[SIGNED_VWT_ADDR_INT:%.*]] = ptrtoint ptr [[SIGNED_VWT_ADDR]]
// CHECK: [[BLENDED_ADDR:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[SIGNED_VWT_ADDR_INT]], i64 11839)
// CHECK: [[SIGNED_VWT_INT:%.*]] = ptrtoint ptr [[SIGNED_VWT]]
// CHECK: [[AUTHENTICATED_VWT_INT:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[SIGNED_VWT_INT]], i32 2, i64 [[BLENDED_ADDR]])
// CHECK: [[AUTHENTICATED_VWT:%.*]] = inttoptr i64 [[AUTHENTICATED_VWT_INT]]
// CHECK-NEXT: [[SLOT:%.*]] = getelementptr inbounds ptr, ptr [[AUTHENTICATED_VWT]], i32
// CHECK-NEXT: [[T0:%.*]] = load ptr, ptr [[SLOT]], align
// CHECK-NEXT: [[T1:%.*]] = ptrtoint ptr [[SLOT]] to i64
// CHECK-NEXT: [[DISC:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[T1]], i64 1272)
// CHECK-NEXT: call void [[T0]](ptr noalias %0, ptr %T) {{#[0-9]+}} [ "ptrauth"(i32 0, i64 [[DISC]]) ]
// CHECK-NEXT: ret void
sil @test_copy_init : $@convention(thin) <T> (@in_guaranteed T) -> (@out T) {
bb0(%0 : $*T, %1 : $*T):
copy_addr %1 to [init] %0 : $*T
%result = tuple ()
return %result : $()
}
// CHECK-LABEL: define swiftcc void @test_copy_init(
// CHECK: [[SIGNED_VWT_ADDR:%.*]] = getelementptr inbounds ptr, ptr {{%.*}}, i64 -1
// CHECK: [[SIGNED_VWT:%.*]] = load ptr, ptr [[SIGNED_VWT_ADDR]]
// CHECK: [[SIGNED_VWT_ADDR_INT:%.*]] = ptrtoint ptr [[SIGNED_VWT_ADDR]]
// CHECK: [[BLENDED_ADDR:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[SIGNED_VWT_ADDR_INT]], i64 11839)
// CHECK: [[SIGNED_VWT_INT:%.*]] = ptrtoint ptr [[SIGNED_VWT]]
// CHECK: [[AUTHENTICATED_VWT_INT:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[SIGNED_VWT_INT]], i32 2, i64 [[BLENDED_ADDR]])
// CHECK: [[AUTHENTICATED_VWT:%.*]] = inttoptr i64 [[AUTHENTICATED_VWT_INT]]
// CHECK-NEXT: [[SLOT:%.*]] = getelementptr inbounds ptr, ptr [[AUTHENTICATED_VWT]], i32
// CHECK-NEXT: [[T0:%.*]] = load ptr, ptr [[SLOT]], align
// CHECK-NEXT: [[T1:%.*]] = ptrtoint ptr [[SLOT]] to i64
// CHECK-NEXT: [[DISC:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[T1]], i64 58298)
// CHECK-NEXT: call ptr [[T0]](ptr noalias %0, ptr noalias %1, ptr %T) {{#[0-9]+}} [ "ptrauth"(i32 0, i64 [[DISC]]) ]
// CHECK-NEXT: ret void
sil @test_take_init : $@convention(thin) <T> (@in T) -> (@out T) {
bb0(%0 : $*T, %1 : $*T):
copy_addr [take] %1 to [init] %0 : $*T
%result = tuple ()
return %result : $()
}
// CHECK-LABEL: define swiftcc void @test_take_init(
// CHECK: [[SIGNED_VWT_ADDR:%.*]] = getelementptr inbounds ptr, ptr {{%.*}}, i64 -1
// CHECK: [[SIGNED_VWT:%.*]] = load ptr, ptr [[SIGNED_VWT_ADDR]]
// CHECK: [[SIGNED_VWT_ADDR_INT:%.*]] = ptrtoint ptr [[SIGNED_VWT_ADDR]]
// CHECK: [[BLENDED_ADDR:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[SIGNED_VWT_ADDR_INT]], i64 11839)
// CHECK: [[SIGNED_VWT_INT:%.*]] = ptrtoint ptr [[SIGNED_VWT]]
// CHECK: [[AUTHENTICATED_VWT_INT:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[SIGNED_VWT_INT]], i32 2, i64 [[BLENDED_ADDR]])
// CHECK: [[AUTHENTICATED_VWT:%.*]] = inttoptr i64 [[AUTHENTICATED_VWT_INT]]
// CHECK-NEXT: [[SLOT:%.*]] = getelementptr inbounds ptr, ptr [[AUTHENTICATED_VWT]], i32
// CHECK-NEXT: [[T0:%.*]] = load ptr, ptr [[SLOT]], align
// CHECK-NEXT: [[T1:%.*]] = ptrtoint ptr [[SLOT]] to i64
// CHECK-NEXT: [[DISC:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[T1]], i64 18648)
// CHECK-NEXT: call ptr [[T0]](ptr noalias %0, ptr noalias %1, ptr %T) {{#[0-9]+}} [ "ptrauth"(i32 0, i64 [[DISC]]) ]
// CHECK-NEXT: ret void
sil @test_copy_assign : $@convention(thin) <T> (@inout T, @in_guaranteed T) -> () {
bb0(%0 : $*T, %1 : $*T):
copy_addr %1 to %0 : $*T
%result = tuple ()
return %result : $()
}
// CHECK-LABEL: define swiftcc void @test_copy_assign(
// CHECK: [[SIGNED_VWT_ADDR:%.*]] = getelementptr inbounds ptr, ptr {{%.*}}, i64 -1
// CHECK: [[SIGNED_VWT:%.*]] = load ptr, ptr [[SIGNED_VWT_ADDR]]
// CHECK: [[SIGNED_VWT_ADDR_INT:%.*]] = ptrtoint ptr [[SIGNED_VWT_ADDR]]
// CHECK: [[BLENDED_ADDR:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[SIGNED_VWT_ADDR_INT]], i64 11839)
// CHECK: [[SIGNED_VWT_INT:%.*]] = ptrtoint ptr [[SIGNED_VWT]]
// CHECK: [[AUTHENTICATED_VWT_INT:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[SIGNED_VWT_INT]], i32 2, i64 [[BLENDED_ADDR]])
// CHECK: [[AUTHENTICATED_VWT:%.*]] = inttoptr i64 [[AUTHENTICATED_VWT_INT]]
// CHECK-NEXT: [[SLOT:%.*]] = getelementptr inbounds ptr, ptr [[AUTHENTICATED_VWT]], i32
// CHECK-NEXT: [[T0:%.*]] = load ptr, ptr [[SLOT]], align
// CHECK-NEXT: [[T1:%.*]] = ptrtoint ptr [[SLOT]] to i64
// CHECK-NEXT: [[DISC:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[T1]], i64 34641)
// CHECK-NEXT: call ptr [[T0]](ptr %0, ptr %1, ptr %T) {{#[0-9]+}} [ "ptrauth"(i32 0, i64 [[DISC]]) ]
// CHECK-NEXT: ret void
sil @test_take_assign : $@convention(thin) <T> (@inout T, @in T) -> () {
bb0(%0 : $*T, %1 : $*T):
copy_addr [take] %1 to %0 : $*T
%result = tuple ()
return %result : $()
}
// CHECK-LABEL: define swiftcc void @test_take_assign(
// CHECK: [[SIGNED_VWT_ADDR:%.*]] = getelementptr inbounds ptr, ptr {{%.*}}, i64 -1
// CHECK: [[SIGNED_VWT:%.*]] = load ptr, ptr [[SIGNED_VWT_ADDR]]
// CHECK: [[SIGNED_VWT_ADDR_INT:%.*]] = ptrtoint ptr [[SIGNED_VWT_ADDR]]
// CHECK: [[BLENDED_ADDR:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[SIGNED_VWT_ADDR_INT]], i64 11839)
// CHECK: [[SIGNED_VWT_INT:%.*]] = ptrtoint ptr [[SIGNED_VWT]]
// CHECK: [[AUTHENTICATED_VWT_INT:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[SIGNED_VWT_INT]], i32 2, i64 [[BLENDED_ADDR]])
// CHECK: [[AUTHENTICATED_VWT:%.*]] = inttoptr i64 [[AUTHENTICATED_VWT_INT]]
// CHECK-NEXT: [[SLOT:%.*]] = getelementptr inbounds ptr, ptr [[AUTHENTICATED_VWT]], i32
// CHECK-NEXT: [[T0:%.*]] = load ptr, ptr [[SLOT]], align
// CHECK-NEXT: [[T1:%.*]] = ptrtoint ptr [[SLOT]] to i64
// CHECK-NEXT: [[DISC:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[T1]], i64 61402)
// CHECK-NEXT: call ptr [[T0]](ptr noalias %0, ptr noalias %1, ptr %T) {{#[0-9]+}} [ "ptrauth"(i32 0, i64 [[DISC]]) ]
// CHECK-NEXT: ret void
// Make sure that the local-type-data caching mechanism sets things up right.
sil @test_destroy_twice : $@convention(thin) <T> (@in T, @in T) -> () {
bb0(%0 : $*T, %1 : $*T):
destroy_addr %0 : $*T
destroy_addr %1 : $*T
%result = tuple ()
return %result : $()
}
// CHECK-LABEL: define swiftcc void @test_destroy_twice(
// CHECK: [[SIGNED_VWT_ADDR:%.*]] = getelementptr inbounds ptr, ptr {{%.*}}, i64 -1
// CHECK: [[SIGNED_VWT:%.*]] = load ptr, ptr [[SIGNED_VWT_ADDR]]
// CHECK: [[SIGNED_VWT_ADDR_INT:%.*]] = ptrtoint ptr [[SIGNED_VWT_ADDR]]
// CHECK: [[BLENDED_ADDR:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[SIGNED_VWT_ADDR_INT]], i64 11839)
// CHECK: [[SIGNED_VWT_INT:%.*]] = ptrtoint ptr [[SIGNED_VWT]]
// CHECK: [[AUTHENTICATED_VWT_INT:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[SIGNED_VWT_INT]], i32 2, i64 [[BLENDED_ADDR]])
// CHECK: [[AUTHENTICATED_VWT:%.*]] = inttoptr i64 [[AUTHENTICATED_VWT_INT]]
// CHECK-NEXT: [[SLOT:%.*]] = getelementptr inbounds ptr, ptr [[AUTHENTICATED_VWT]], i32
// CHECK-NEXT: [[T0:%.*]] = load ptr, ptr [[SLOT]], align
// CHECK-NEXT: [[T1:%.*]] = ptrtoint ptr [[SLOT]] to i64
// CHECK-NEXT: [[DISC:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[T1]], i64 1272)
// CHECK-NEXT: call void [[T0]](ptr noalias %0, ptr %T) {{#[0-9]+}} [ "ptrauth"(i32 0, i64 [[DISC]]) ]
// CHECK-NEXT: call void [[T0]](ptr noalias %1, ptr %T) {{#[0-9]+}} [ "ptrauth"(i32 0, i64 [[DISC]]) ]
// CHECK-NEXT: ret void