Skip to content

Commit 54fd6d5

Browse files
committed
Merge commit '7575bda7e190' from llvm.org/release/21.x into stable/21.x
2 parents ba56658 + 7575bda commit 54fd6d5

File tree

8 files changed

+99
-59
lines changed

8 files changed

+99
-59
lines changed

clang/include/clang/Basic/Features.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,7 @@ FEATURE(ptrauth_vtable_pointer_address_discrimination, LangOpts.PointerAuthVTPtr
165165
FEATURE(ptrauth_vtable_pointer_type_discrimination, LangOpts.PointerAuthVTPtrTypeDiscrimination)
166166
FEATURE(ptrauth_type_info_vtable_pointer_discrimination, LangOpts.PointerAuthTypeInfoVTPtrDiscrimination)
167167
FEATURE(ptrauth_member_function_pointer_type_discrimination, LangOpts.PointerAuthCalls)
168+
FEATURE(ptrauth_signed_block_descriptors, LangOpts.PointerAuthCalls)
168169
FEATURE(ptrauth_function_pointer_type_discrimination, LangOpts.PointerAuthFunctionTypeDiscrimination)
169170
FEATURE(ptrauth_indirect_gotos, LangOpts.PointerAuthIndirectGotos)
170171
FEATURE(ptrauth_init_fini, LangOpts.PointerAuthInitFini)

clang/include/clang/Basic/PointerAuthOptions.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,10 @@
2323

2424
namespace clang {
2525

26+
/// Constant discriminator to be used with block descriptor pointers. The value
27+
/// is ptrauth_string_discriminator("block_descriptor")
28+
constexpr uint16_t BlockDescriptorConstantDiscriminator = 0xC0BB;
29+
2630
/// Constant discriminator to be used with function pointers in .init_array and
2731
/// .fini_array. The value is ptrauth_string_discriminator("init_fini")
2832
constexpr uint16_t InitFiniPointerConstantDiscriminator = 0xD9D4;
@@ -285,6 +289,9 @@ struct PointerAuthOptions {
285289
/// The ABI for __block variable copy/destroy function pointers.
286290
PointerAuthSchema BlockByrefHelperFunctionPointers;
287291

292+
/// The ABI for pointers to block descriptors.
293+
PointerAuthSchema BlockDescriptorPointers;
294+
288295
/// The ABI for Objective-C method lists.
289296
PointerAuthSchema ObjCMethodListFunctionPointers;
290297

clang/lib/CodeGen/Address.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,11 @@ class Address {
176176
static Address invalid() { return Address(nullptr); }
177177
bool isValid() const { return Pointer.getPointer() != nullptr; }
178178

179+
llvm::Value *getPointerIfNotSigned() const {
180+
assert(isValid() && "pointer isn't valid");
181+
return !isSigned() ? Pointer.getPointer() : nullptr;
182+
}
183+
179184
/// This function is used in situations where the caller is doing some sort of
180185
/// opaque "laundering" of the pointer.
181186
void replaceBasePointer(llvm::Value *P) {

clang/lib/CodeGen/CGBlocks.cpp

Lines changed: 52 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -188,16 +188,14 @@ static llvm::Constant *buildBlockDescriptor(CodeGenModule &CGM,
188188
// Optional copy/dispose helpers.
189189
bool hasInternalHelper = false;
190190
if (blockInfo.NeedsCopyDispose) {
191-
auto &schema =
192-
CGM.getCodeGenOpts().PointerAuth.BlockHelperFunctionPointers;
193-
191+
auto &Schema = CGM.getCodeGenOpts().PointerAuth.BlockHelperFunctionPointers;
194192
// copy_func_helper_decl
195193
llvm::Constant *copyHelper = buildCopyHelper(CGM, blockInfo);
196-
elements.addSignedPointer(copyHelper, schema, GlobalDecl(), QualType());
194+
elements.addSignedPointer(copyHelper, Schema, GlobalDecl(), QualType());
197195

198196
// destroy_func_decl
199197
llvm::Constant *disposeHelper = buildDisposeHelper(CGM, blockInfo);
200-
elements.addSignedPointer(disposeHelper, schema, GlobalDecl(), QualType());
198+
elements.addSignedPointer(disposeHelper, Schema, GlobalDecl(), QualType());
201199

202200
if (cast<llvm::Function>(copyHelper->stripPointerCasts())
203201
->hasInternalLinkage() ||
@@ -570,9 +568,8 @@ static void computeBlockInfo(CodeGenModule &CGM, CodeGenFunction *CGF,
570568
llvm::StructType::get(CGM.getLLVMContext(), elementTypes, true);
571569
info.CanBeGlobal = true;
572570
return;
573-
}
574-
else if (C.getLangOpts().ObjC &&
575-
CGM.getLangOpts().getGC() == LangOptions::NonGC)
571+
} else if (C.getLangOpts().ObjC &&
572+
CGM.getLangOpts().getGC() == LangOptions::NonGC)
576573
info.HasCapturedVariableLayout = true;
577574

578575
if (block->doesNotEscape())
@@ -786,7 +783,7 @@ llvm::Value *CodeGenFunction::EmitBlockLiteral(const BlockExpr *blockExpr) {
786783

787784
llvm::Value *CodeGenFunction::EmitBlockLiteral(const CGBlockInfo &blockInfo) {
788785
bool IsOpenCL = CGM.getContext().getLangOpts().OpenCL;
789-
auto GenVoidPtrTy =
786+
llvm::PointerType *GenVoidPtrTy =
790787
IsOpenCL ? CGM.getOpenCLRuntime().getGenericVoidPointerType() : VoidPtrTy;
791788
LangAS GenVoidPtrAddr = IsOpenCL ? LangAS::opencl_generic : LangAS::Default;
792789
auto GenVoidPtrSize = CharUnits::fromQuantity(
@@ -820,9 +817,6 @@ llvm::Value *CodeGenFunction::EmitBlockLiteral(const CGBlockInfo &blockInfo) {
820817
: CGM.getNSConcreteStackBlock();
821818
isa = blockISA;
822819

823-
// Build the block descriptor.
824-
descriptor = buildBlockDescriptor(CGM, blockInfo);
825-
826820
// Compute the initial on-stack block flags.
827821
if (!CGM.getCodeGenOpts().DisableBlockSignatureString)
828822
flags = BLOCK_HAS_SIGNATURE;
@@ -836,6 +830,9 @@ llvm::Value *CodeGenFunction::EmitBlockLiteral(const CGBlockInfo &blockInfo) {
836830
flags |= BLOCK_USE_STRET;
837831
if (blockInfo.NoEscape)
838832
flags |= BLOCK_IS_NOESCAPE | BLOCK_IS_GLOBAL;
833+
834+
// Build the block descriptor.
835+
descriptor = buildBlockDescriptor(CGM, blockInfo);
839836
}
840837

841838
auto projectField = [&](unsigned index, const Twine &name) -> Address {
@@ -888,21 +885,20 @@ llvm::Value *CodeGenFunction::EmitBlockLiteral(const CGBlockInfo &blockInfo) {
888885
}
889886

890887
if (!IsOpenCL) {
891-
llvm::Value *blockFnPtr = llvm::ConstantExpr::getBitCast(InvokeFn, VoidPtrTy);
892-
auto blockFnPtrAddr = projectField(index, "block.invoke");
893-
if (auto &schema =
894-
CGM.getCodeGenOpts().PointerAuth.BlockInvocationFunctionPointers) {
895-
QualType type = blockInfo.getBlockExpr()->getType()
896-
->castAs<BlockPointerType>()->getPointeeType();
897-
auto authInfo = EmitPointerAuthInfo(
898-
schema, blockFnPtrAddr.emitRawPointer(*this), GlobalDecl(), type);
899-
blockFnPtr = EmitPointerAuthSign(authInfo, blockFnPtr);
900-
}
901-
Builder.CreateStore(blockFnPtr, blockFnPtrAddr);
902-
offset += getPointerSize();
903-
index++;
888+
llvm::Value *blockFnPtr =
889+
llvm::ConstantExpr::getBitCast(InvokeFn, VoidPtrTy);
890+
QualType type = blockInfo.getBlockExpr()
891+
->getType()
892+
->castAs<BlockPointerType>()
893+
->getPointeeType();
894+
addSignedHeaderField(
895+
blockFnPtr,
896+
CGM.getCodeGenOpts().PointerAuth.BlockInvocationFunctionPointers,
897+
GlobalDecl(), type, getPointerSize(), "block.invoke");
904898

905-
addHeaderField(descriptor, getPointerSize(), "block.descriptor");
899+
addSignedHeaderField(
900+
descriptor, CGM.getCodeGenOpts().PointerAuth.BlockDescriptorPointers,
901+
GlobalDecl(), type, getPointerSize(), "block.descriptor");
906902
} else if (auto *Helper =
907903
CGM.getTargetCodeGenInfo().getTargetOpenCLBlockHelper()) {
908904
addHeaderField(blockFn, GenVoidPtrSize, "block.invoke");
@@ -1234,11 +1230,12 @@ RValue CodeGenFunction::EmitBlockCallExpr(const CallExpr *E,
12341230
// Prepare the callee.
12351231
CGPointerAuthInfo PointerAuth;
12361232
if (auto &AuthSchema =
1237-
CGM.getCodeGenOpts().PointerAuth.BlockInvocationFunctionPointers) {
1233+
CGM.getCodeGenOpts().PointerAuth.BlockInvocationFunctionPointers) {
12381234
assert(FuncPtr != nullptr && "Missing function pointer for AuthInfo");
1239-
PointerAuth = EmitPointerAuthInfo(AuthSchema, FuncPtr,
1240-
GlobalDecl(), FnType);
1235+
PointerAuth =
1236+
EmitPointerAuthInfo(AuthSchema, FuncPtr, GlobalDecl(), FnType);
12411237
}
1238+
12421239
CGCallee Callee(CGCalleeInfo(), Func, PointerAuth);
12431240

12441241
// And call the block.
@@ -1323,14 +1320,15 @@ static llvm::Constant *buildGlobalBlock(CodeGenModule &CGM,
13231320

13241321
bool IsOpenCL = CGM.getLangOpts().OpenCL;
13251322
bool IsWindows = CGM.getTarget().getTriple().isOSWindows();
1323+
auto &CGOPointerAuth = CGM.getCodeGenOpts().PointerAuth;
13261324
if (!IsOpenCL) {
13271325
// isa
13281326
if (IsWindows)
13291327
fields.addNullPointer(CGM.Int8PtrPtrTy);
13301328
else
13311329
fields.addSignedPointer(CGM.getNSConcreteGlobalBlock(),
1332-
CGM.getCodeGenOpts().PointerAuth.ObjCIsaPointers,
1333-
GlobalDecl(), QualType());
1330+
CGOPointerAuth.ObjCIsaPointers, GlobalDecl(),
1331+
QualType());
13341332

13351333
// __flags
13361334
BlockFlags flags = BLOCK_IS_GLOBAL;
@@ -1343,28 +1341,26 @@ static llvm::Constant *buildGlobalBlock(CodeGenModule &CGM,
13431341

13441342
// Reserved
13451343
fields.addInt(CGM.IntTy, 0);
1346-
1347-
// Function
1348-
if (auto &schema =
1349-
CGM.getCodeGenOpts().PointerAuth.BlockInvocationFunctionPointers) {
1350-
QualType fnType = blockInfo.getBlockExpr()
1351-
->getType()
1352-
->castAs<BlockPointerType>()
1353-
->getPointeeType();
1354-
fields.addSignedPointer(blockFn, schema, GlobalDecl(), fnType);
1355-
} else {
1356-
fields.add(blockFn);
1357-
}
13581344
} else {
13591345
fields.addInt(CGM.IntTy, blockInfo.BlockSize.getQuantity());
13601346
fields.addInt(CGM.IntTy, blockInfo.BlockAlign.getQuantity());
1361-
// Function
1362-
fields.add(blockFn);
13631347
}
13641348

1349+
// Function
1350+
if (auto &Schema = CGOPointerAuth.BlockInvocationFunctionPointers) {
1351+
QualType FnType = blockInfo.getBlockExpr()
1352+
->getType()
1353+
->castAs<BlockPointerType>()
1354+
->getPointeeType();
1355+
fields.addSignedPointer(blockFn, Schema, GlobalDecl(), FnType);
1356+
} else
1357+
fields.add(blockFn);
1358+
13651359
if (!IsOpenCL) {
13661360
// Descriptor
1367-
fields.add(buildBlockDescriptor(CGM, blockInfo));
1361+
llvm::Constant *Descriptor = buildBlockDescriptor(CGM, blockInfo);
1362+
fields.addSignedPointer(Descriptor, CGOPointerAuth.BlockDescriptorPointers,
1363+
GlobalDecl(), QualType());
13681364
} else if (auto *Helper =
13691365
CGM.getTargetCodeGenInfo().getTargetOpenCLBlockHelper()) {
13701366
for (auto *I : Helper->getCustomFieldValues(CGM, blockInfo)) {
@@ -2034,8 +2030,8 @@ CodeGenFunction::GenerateCopyHelperFunction(const CGBlockInfo &blockInfo) {
20342030
// it. It's not quite worth the annoyance to avoid creating it in the
20352031
// first place.
20362032
if (!needsEHCleanup(captureType.isDestructedType()))
2037-
if (auto *I =
2038-
cast_or_null<llvm::Instruction>(dstField.getBasePointer()))
2033+
if (auto *I = cast_or_null<llvm::Instruction>(
2034+
dstField.getPointerIfNotSigned()))
20392035
I->eraseFromParent();
20402036
}
20412037
break;
@@ -2772,11 +2768,11 @@ void CodeGenFunction::emitByrefStructureInit(const AutoVarEmission &emission) {
27722768
const Twine &name, bool isFunction = false) {
27732769
auto fieldAddr = Builder.CreateStructGEP(addr, nextHeaderIndex, name);
27742770
if (isFunction) {
2775-
if (auto &schema = CGM.getCodeGenOpts().PointerAuth
2776-
.BlockByrefHelperFunctionPointers) {
2777-
auto pointerAuth = EmitPointerAuthInfo(
2778-
schema, fieldAddr.emitRawPointer(*this), GlobalDecl(), QualType());
2779-
value = EmitPointerAuthSign(pointerAuth, value);
2771+
if (auto &Schema = CGM.getCodeGenOpts()
2772+
.PointerAuth.BlockByrefHelperFunctionPointers) {
2773+
auto PointerAuth = EmitPointerAuthInfo(
2774+
Schema, fieldAddr.emitRawPointer(*this), GlobalDecl(), QualType());
2775+
value = EmitPointerAuthSign(PointerAuth, value);
27802776
}
27812777
}
27822778
Builder.CreateStore(value, fieldAddr);
@@ -2861,10 +2857,10 @@ void CodeGenFunction::emitByrefStructureInit(const AutoVarEmission &emission) {
28612857
storeHeaderField(V, getIntSize(), "byref.size");
28622858

28632859
if (helpers) {
2864-
storeHeaderField(helpers->CopyHelper, getPointerSize(),
2865-
"byref.copyHelper", /*function*/ true);
2860+
storeHeaderField(helpers->CopyHelper, getPointerSize(), "byref.copyHelper",
2861+
/*isFunction=*/true);
28662862
storeHeaderField(helpers->DisposeHelper, getPointerSize(),
2867-
"byref.disposeHelper", /*function*/ true);
2863+
"byref.disposeHelper", /*isFunction=*/true);
28682864
}
28692865

28702866
if (ByRefHasLifetime && HasByrefExtendedLayout) {

clang/lib/Driver/ToolChains/Clang.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1762,7 +1762,6 @@ void Clang::AddAArch64TargetArgs(const ArgList &Args,
17621762
options::OPT_fno_ptrauth_objc_interface_sel);
17631763
Args.addOptInFlag(CmdArgs, options::OPT_fptrauth_objc_class_ro,
17641764
options::OPT_fno_ptrauth_objc_class_ro);
1765-
17661765
if (Triple.getEnvironment() == llvm::Triple::PAuthTest)
17671766
handlePAuthABI(Args, CmdArgs);
17681767

clang/lib/Frontend/CompilerInvocation.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1739,6 +1739,9 @@ void CompilerInvocation::setDefaultPointerAuthOptions(
17391739
PointerAuthSchema(Key::ASIA, true, Discrimination::None);
17401740
Opts.BlockByrefHelperFunctionPointers =
17411741
PointerAuthSchema(Key::ASIA, true, Discrimination::None);
1742+
Opts.BlockDescriptorPointers =
1743+
PointerAuthSchema(Key::ASDA, true, Discrimination::Constant,
1744+
BlockDescriptorConstantDiscriminator);
17421745

17431746
Opts.ObjCMethodListFunctionPointers =
17441747
PointerAuthSchema(Key::ASIA, true, Discrimination::None);
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// RUN: %clang_cc1 -fobjc-arc -fblocks -fptrauth-calls -triple arm64e-apple-ios -emit-llvm -o - %s | FileCheck %s
2+
3+
_Static_assert(__has_feature(ptrauth_signed_block_descriptors), "-fptrauth-block-descriptor-pointers should set ptrauth_signed_block_descriptors");
4+
5+
void a() {
6+
// Test out a global block.
7+
void (^blk)(void) = ^{};
8+
}
9+
10+
// CHECK: [[BLOCK_DESCRIPTOR_NAME:@"__block_descriptor_.*"]] = linkonce_odr hidden unnamed_addr constant { i64, i64, ptr, ptr } { i64 0, i64 32, ptr @.str, ptr null }
11+
12+
13+
// CHECK: @__block_literal_global = internal constant { ptr, i32, i32, ptr, ptr } { ptr @_NSConcreteGlobalBlock, i32 1342177280, i32 0, ptr ptrauth (ptr @__a_block_invoke, i32 0, i64 0, ptr getelementptr inbounds ({ ptr, i32, i32, ptr, ptr }, ptr @__block_literal_global, i32 0, i32 3)), ptr ptrauth (ptr @"__block_descriptor_32_e5_v8\01?0l", i32 2, i64 49339, ptr getelementptr inbounds ({ ptr, i32, i32, ptr, ptr }, ptr @__block_literal_global, i32 0, i32 4)) }
14+
15+
void b(int p) {
16+
// CHECK-LABEL: define void @b
17+
18+
// Test out a stack block.
19+
void (^blk)(void) = ^{(void)p;};
20+
21+
// CHECK: [[BLOCK:%.*]] = alloca <{ ptr, i32, i32, ptr, ptr, i32 }>
22+
// CHECK: [[BLOCK_DESCRIPTOR_REF:%.*]] = getelementptr inbounds nuw <{ {{.*}} }>, ptr [[BLOCK]], i32 0, i32 4
23+
// CHECK: [[BLOCK_DESCRIPTOR_REF_INT:%.*]] = ptrtoint ptr [[BLOCK_DESCRIPTOR_REF]] to i64
24+
// CHECK: [[BLENDED:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[BLOCK_DESCRIPTOR_REF_INT]], i64 49339)
25+
// CHECK: [[SIGNED_REF:%.*]] = call i64 @llvm.ptrauth.sign(i64 ptrtoint (ptr @"__block_descriptor_36_e5_v8\01?0l" to i64), i32 2, i64 [[BLENDED]])
26+
// CHECK: [[SIGNED_REF_PTR:%.*]] = inttoptr i64 [[SIGNED_REF]] to ptr
27+
// CHECK: store ptr [[SIGNED_REF_PTR]], ptr [[BLOCK_DESCRIPTOR_REF]]
28+
}

clang/test/CodeGenObjC/ptrauth-block-isa.m

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1-
// RUN: %clang_cc1 -fptrauth-calls -fptrauth-objc-isa -fobjc-arc -fblocks -triple arm64e -emit-llvm %s -o - | FileCheck %s
1+
// RUN: %clang_cc1 -fptrauth-calls -fptrauth-objc-isa -fobjc-arc -fblocks -triple arm64e -emit-llvm %s -o - | FileCheck %s
22

33
void (^globalblock)(void) = ^{};
4-
// CHECK: [[GLOBAL_BLOCK:@.*]] = internal constant { ptr, i32, i32, ptr, ptr } { ptr ptrauth (ptr @_NSConcreteGlobalBlock, i32 2, i64 27361, ptr [[GLOBAL_BLOCK]]), i32 1342177280, i32 0, ptr @globalblock_block_invoke, ptr @"__block_descriptor_32_e5_v8\01?0l" }, align 8 #0
4+
// CHECK: [[BLOCK_DESCRIPTOR_NAME:@"__block_descriptor_.*"]] = linkonce_odr hidden unnamed_addr constant { i64, i64, ptr, ptr } { i64 0, i64 32, ptr @.str, ptr null }, comdat, align 8
5+
// CHECK: @__block_literal_global = internal constant { ptr, i32, i32, ptr, ptr } { ptr ptrauth (ptr @_NSConcreteGlobalBlock, i32 2, i64 27361, ptr @__block_literal_global), i32 1342177280, i32 0, ptr ptrauth (ptr @globalblock_block_invoke, i32 0, i64 0, ptr getelementptr inbounds ({ ptr, i32, i32, ptr, ptr }, ptr @__block_literal_global, i32 0, i32 3)), ptr ptrauth (ptr [[BLOCK_DESCRIPTOR_NAME]], i32 2, i64 49339, ptr getelementptr inbounds ({ ptr, i32, i32, ptr, ptr }, ptr @__block_literal_global, i32 0, i32 4)) }
56

67
@interface A
78
- (int) count;

0 commit comments

Comments
 (0)