1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
|
// 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
// REQUIRES: CPU=arm64e
// REQUIRES: OS=ios
import Builtin
// CHECK: [[VOID_BLOCK_SIGNATURE:@.*]] = private unnamed_addr constant {{.*}} c"v8@?0\00"
// CHECK: [[TRIVIAL_BLOCK_DESCRIPTOR:@.*]] = internal constant { {{.*}} } { i64 0, i64 40, ptr [[VOID_BLOCK_SIGNATURE]] }
// CHECK: @block_copy_helper.ptrauth = private constant { ptr, i32, i64, i64 } { ptr @block_copy_helper, i32 0, i64 ptrtoint ({{.*}} getelementptr inbounds ({{.*}} [[NONTRIVIAL_BLOCK_DESCRIPTOR:@.*]], i32 0, i32 2) to i64), i64 0 }, section "llvm.ptrauth"
// CHECK: @block_destroy_helper.ptrauth = private constant { ptr, i32, i64, i64 } { ptr @block_destroy_helper, i32 0, i64 ptrtoint ({{.*}} getelementptr inbounds ({{.*}} [[NONTRIVIAL_BLOCK_DESCRIPTOR:@.*]], i32 0, i32 3) to i64), i64 0 }, section "llvm.ptrauth"
// CHECK: [[NONTRIVIAL_BLOCK_DESCRIPTOR]] = internal constant { {{.*}} } { i64 0, i64 40, ptr @block_copy_helper.ptrauth, {{.*}} @block_destroy_helper.ptrauth, ptr [[VOID_BLOCK_SIGNATURE]] }
sil @init_header_trivial : $@convention(thin) (@inout_aliasable @block_storage Builtin.RawPointer) -> @convention(block) () -> () {
entry(%0 : $*@block_storage Builtin.RawPointer):
%i = function_ref @invoke_trivial : $@convention(c) (@inout_aliasable @block_storage Builtin.RawPointer) -> ()
%b = init_block_storage_header %0 : $*@block_storage Builtin.RawPointer, invoke %i : $@convention(c) (@inout_aliasable @block_storage Builtin.RawPointer) -> (), type $@convention(block) () -> ()
return %b : $@convention(block) () -> ()
}
// CHECK-LABEL: define swiftcc ptr @init_header_trivial(ptr
// CHECK: [[HEADER:%.*]] = getelementptr inbounds { %objc_block, ptr }, ptr %0, i32 0, i32 0
// CHECK: [[SLOT:%.*]] = getelementptr inbounds %objc_block, ptr [[HEADER]], i32 0, i32 3
// CHECK: [[T0:%.*]] = ptrtoint ptr [[SLOT]] to i64
// CHECK: [[SIGNED:%.*]] = call i64 @llvm.ptrauth.sign(i64 ptrtoint (ptr @invoke_trivial to i64), i32 0, i64 [[T0]])
// CHECK: [[T0:%.*]] = inttoptr i64 [[SIGNED]] to ptr
// CHECK: store ptr [[T0]], ptr [[SLOT]],
// CHECK: [[SLOT:%.*]] = getelementptr inbounds %objc_block, ptr [[HEADER]], i32 0, i32 4
// CHECK: store ptr [[TRIVIAL_BLOCK_DESCRIPTOR]], ptr [[SLOT]]
sil @invoke_trivial : $@convention(c) (@inout_aliasable @block_storage Builtin.RawPointer) -> () {
entry(%0 : $*@block_storage Builtin.RawPointer):
%c = project_block_storage %0 : $*@block_storage Builtin.RawPointer
return undef : $()
}
sil @init_header_nontrivial : $@convention(thin) (@inout_aliasable @block_storage Builtin.NativeObject) -> @convention(block) () -> () {
entry(%0 : $*@block_storage Builtin.NativeObject):
%i = function_ref @invoke_nontrivial : $@convention(c) (@inout_aliasable @block_storage Builtin.NativeObject) -> ()
%b = init_block_storage_header %0 : $*@block_storage Builtin.NativeObject, invoke %i : $@convention(c) (@inout_aliasable @block_storage Builtin.NativeObject) -> (), type $@convention(block) () -> ()
return %b : $@convention(block) () -> ()
}
// CHECK-LABEL: define swiftcc ptr @init_header_nontrivial(ptr
// CHECK: [[HEADER:%.*]] = getelementptr inbounds { %objc_block, ptr }, ptr %0, i32 0, i32 0
// CHECK: [[SLOT:%.*]] = getelementptr inbounds %objc_block, ptr [[HEADER]], i32 0, i32 3
// CHECK: [[T0:%.*]] = ptrtoint ptr [[SLOT]] to i64
// CHECK: [[SIGNED:%.*]] = call i64 @llvm.ptrauth.sign(i64 ptrtoint (ptr @invoke_nontrivial to i64), i32 0, i64 [[T0]])
// CHECK: [[T0:%.*]] = inttoptr i64 [[SIGNED]] to ptr
// CHECK: store ptr [[T0]], ptr [[SLOT]],
// CHECK: [[SLOT:%.*]] = getelementptr inbounds %objc_block, ptr [[HEADER]], i32 0, i32 4
// CHECK: store ptr [[NONTRIVIAL_BLOCK_DESCRIPTOR]], ptr [[SLOT]]
sil @invoke_nontrivial : $@convention(c) (@inout_aliasable @block_storage Builtin.NativeObject) -> () {
entry(%0 : $*@block_storage Builtin.NativeObject):
%c = project_block_storage %0 : $*@block_storage Builtin.NativeObject
return undef : $()
}
sil @invoke_block : $@convention(thin) (@convention(block) () -> ()) -> () {
entry(%0 : $@convention(block) () -> ()):
apply %0() : $@convention(block) () -> ()
return undef : $()
}
// CHECK-LABEL: define swiftcc void @invoke_block(ptr %0)
// CHECK: [[SLOT:%.*]] = getelementptr inbounds %objc_block, ptr %0, i32 0, i32 3
// CHECK-NEXT: [[T0:%.*]] = load ptr, ptr [[SLOT]], align
// CHECK-NEXT: [[DISC:%.*]] = ptrtoint ptr [[SLOT]] to i64
// CHECK-NEXT: call void [[T0]](ptr %0) [ "ptrauth"(i32 0, i64 [[DISC]]) ]
|