Skip to content

Commit 30f8b55

Browse files
authored
Merge pull request swiftlang#31490 from slavapestov/fix-class-stub-arm64e
IRGen: Sign the class stub initialization callback pointer on arm64e
2 parents d0f8be1 + 8e35609 commit 30f8b55

File tree

10 files changed

+55
-40
lines changed

10 files changed

+55
-40
lines changed

include/swift/ABI/MetadataValues.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1164,6 +1164,9 @@ namespace SpecialPointerAuthDiscriminators {
11641164
/// they're important enough to be worth writing in one place.
11651165
const uint16_t OpaqueReadResumeFunction = 56769;
11661166
const uint16_t OpaqueModifyResumeFunction = 3909;
1167+
1168+
/// Resilient class stub initializer callback
1169+
const uint16_t ResilientClassStubInitCallback = 0xC671;
11671170
}
11681171

11691172
/// The number of arguments that will be passed directly to a generic

include/swift/AST/IRGenOptions.h

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

123123
/// Resumption functions from yield-many coroutines.
124124
PointerAuthSchema YieldManyResumeFunctions;
125+
126+
/// Resilient class stub initializer callbacks.
127+
PointerAuthSchema ResilientClassStubInitCallbacks;
125128
};
126129

127130
/// The set of options supported by IR generation.

lib/IRGen/GenClass.cpp

Lines changed: 24 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2097,41 +2097,44 @@ static llvm::Function *emitObjCMetadataUpdateFunction(IRGenModule &IGM,
20972097
/// We emit Objective-C class stubs for non-generic classes with resilient
20982098
/// ancestry. This lets us attach categories to the class even though it
20992099
/// does not have statically-emitted metadata.
2100-
bool irgen::hasObjCResilientClassStub(IRGenModule &IGM, ClassDecl *D) {
2101-
assert(IGM.getClassMetadataStrategy(D) == ClassMetadataStrategy::Resilient);
2102-
return IGM.ObjCInterop && !D->isGenericContext();
2100+
bool IRGenModule::hasObjCResilientClassStub(ClassDecl *D) {
2101+
assert(getClassMetadataStrategy(D) == ClassMetadataStrategy::Resilient);
2102+
return ObjCInterop && !D->isGenericContext();
21032103
}
21042104

2105-
void irgen::emitObjCResilientClassStub(IRGenModule &IGM, ClassDecl *D) {
2106-
assert(hasObjCResilientClassStub(IGM, D));
2105+
void IRGenModule::emitObjCResilientClassStub(ClassDecl *D) {
2106+
assert(hasObjCResilientClassStub(D));
21072107

2108-
llvm::Constant *fields[] = {
2109-
llvm::ConstantInt::get(IGM.SizeTy, 0), // reserved
2110-
llvm::ConstantInt::get(IGM.SizeTy, 1), // isa
2111-
IGM.getAddrOfObjCMetadataUpdateFunction(D, NotForDefinition)
2112-
};
2113-
auto init = llvm::ConstantStruct::get(IGM.ObjCFullResilientClassStubTy,
2114-
makeArrayRef(fields));
2108+
ConstantInitBuilder builder(*this);
2109+
auto fields = builder.beginStruct(ObjCFullResilientClassStubTy);
2110+
fields.addInt(SizeTy, 0); // reserved
2111+
fields.addInt(SizeTy, 1); // isa
2112+
auto *impl = getAddrOfObjCMetadataUpdateFunction(D, NotForDefinition);
2113+
const auto &schema =
2114+
getOptions().PointerAuth.ResilientClassStubInitCallbacks;
2115+
fields.addSignedPointer(impl, schema, PointerAuthEntity()); // callback
2116+
2117+
auto init = fields.finishAndCreateFuture();
21152118

21162119
// Define the full stub. This is a private symbol.
2120+
LinkEntity entity = LinkEntity::forObjCResilientClassStub(
2121+
D, TypeMetadataAddress::FullMetadata);
21172122
auto fullObjCStub = cast<llvm::GlobalVariable>(
2118-
IGM.getAddrOfObjCResilientClassStub(D, ForDefinition,
2119-
TypeMetadataAddress::FullMetadata));
2120-
fullObjCStub->setInitializer(init);
2123+
getAddrOfLLVMVariable(entity, init, DebugTypeInfo()));
21212124

21222125
// Emit the metadata update function referenced above.
2123-
emitObjCMetadataUpdateFunction(IGM, D);
2126+
emitObjCMetadataUpdateFunction(*this, D);
21242127

21252128
// Apply the offset.
2126-
auto *objcStub = llvm::ConstantExpr::getBitCast(fullObjCStub, IGM.Int8PtrTy);
2129+
auto *objcStub = llvm::ConstantExpr::getBitCast(fullObjCStub, Int8PtrTy);
21272130
objcStub = llvm::ConstantExpr::getInBoundsGetElementPtr(
2128-
IGM.Int8Ty, objcStub, IGM.getSize(IGM.getPointerSize()));
2131+
Int8Ty, objcStub, getSize(getPointerSize()));
21292132
objcStub = llvm::ConstantExpr::getPointerCast(objcStub,
2130-
IGM.ObjCResilientClassStubTy->getPointerTo());
2133+
ObjCResilientClassStubTy->getPointerTo());
21312134

2132-
auto entity = LinkEntity::forObjCResilientClassStub(
2135+
entity = LinkEntity::forObjCResilientClassStub(
21332136
D, TypeMetadataAddress::AddressPoint);
2134-
IGM.defineAlias(entity, objcStub);
2137+
defineAlias(entity, objcStub);
21352138
}
21362139

21372140
/// Emit the private data (RO-data) associated with a class.

lib/IRGen/GenClass.h

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -168,14 +168,6 @@ namespace irgen {
168168
llvm::Value *selfValue,
169169
llvm::Value *metadataValue);
170170

171-
/// We emit Objective-C class stubs for non-generic classes with resilient
172-
/// ancestry. This lets us attach categories to the class even though it
173-
/// does not have statically-emitted metadata.
174-
bool hasObjCResilientClassStub(IRGenModule &IGM, ClassDecl *D);
175-
176-
/// Emit a resilient class stub.
177-
void emitObjCResilientClassStub(IRGenModule &IGM, ClassDecl *D);
178-
179171
/// Emit the constant fragile offset of the given property inside an instance
180172
/// of the class.
181173
llvm::Constant *tryEmitConstantClassFragilePhysicalMemberOffset(

lib/IRGen/GenMeta.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1672,7 +1672,7 @@ namespace {
16721672
/ IGM.getPointerSize());
16731673
} else {
16741674
ExtraClassDescriptorFlags flags;
1675-
if (hasObjCResilientClassStub(IGM, getType()))
1675+
if (IGM.hasObjCResilientClassStub(getType()))
16761676
flags.setObjCResilientClassStub(true);
16771677
B.addInt32(flags.getOpaqueValue());
16781678
}
@@ -1694,7 +1694,7 @@ namespace {
16941694
ClassMetadataStrategy::Resilient)
16951695
return;
16961696

1697-
if (!hasObjCResilientClassStub(IGM, getType()))
1697+
if (!IGM.hasObjCResilientClassStub(getType()))
16981698
return;
16991699

17001700
B.addRelativeAddress(
@@ -3390,8 +3390,8 @@ void irgen::emitClassMetadata(IRGenModule &IGM, ClassDecl *classDecl,
33903390
// Even non-@objc classes can have Objective-C categories attached, so
33913391
// we always emit a resilient class stub as long as -enable-objc-interop
33923392
// is set.
3393-
if (hasObjCResilientClassStub(IGM, classDecl)) {
3394-
emitObjCResilientClassStub(IGM, classDecl);
3393+
if (IGM.hasObjCResilientClassStub(classDecl)) {
3394+
IGM.emitObjCResilientClassStub(classDecl);
33953395

33963396
if (classDecl->isObjC()) {
33973397
auto *stub = IGM.getAddrOfObjCResilientClassStub(

lib/IRGen/IRGen.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -660,6 +660,10 @@ static void setPointerAuthOptions(PointerAuthOptions &opts,
660660
PointerAuthSchema(codeKey, /*address*/ true, Discrimination::Type);
661661
opts.YieldOnceResumeFunctions =
662662
PointerAuthSchema(codeKey, /*address*/ true, Discrimination::Type);
663+
664+
opts.ResilientClassStubInitCallbacks =
665+
PointerAuthSchema(codeKey, /*address*/ true, Discrimination::Constant,
666+
SpecialPointerAuthDiscriminators::ResilientClassStubInitCallback);
663667
}
664668

665669
std::unique_ptr<llvm::TargetMachine>

lib/IRGen/IRGenModule.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1563,6 +1563,14 @@ private: \
15631563

15641564
void emitOpaqueTypeDescriptorAccessor(OpaqueTypeDecl *);
15651565

1566+
/// We emit Objective-C class stubs for non-generic classes with resilient
1567+
/// ancestry. This lets us attach categories to the class even though it
1568+
/// does not have statically-emitted metadata.
1569+
bool hasObjCResilientClassStub(ClassDecl *D);
1570+
1571+
/// Emit a resilient class stub.
1572+
void emitObjCResilientClassStub(ClassDecl *D);
1573+
15661574
private:
15671575
llvm::Constant *
15681576
getAddrOfSharedContextDescriptor(LinkEntity entity,

test/IRGen/class_update_callback_with_stub.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,21 +63,21 @@ import resilient_objc_class
6363
// CHECK-SAME: internal global %objc_full_class_stub {
6464
// CHECK-SAME: [[INT]] 0,
6565
// CHECK-SAME: [[INT]] 1,
66-
// CHECK-SAME: %objc_class* (%objc_class*, i8*)* @"$s31class_update_callback_with_stub17ResilientSubclassCMU"
66+
// CHECK-SAME: %objc_class* (%objc_class*, i8*)* {{.*}}@"$s31class_update_callback_with_stub17ResilientSubclassCMU{{(\.ptrauth)?}}"
6767
// CHECK-SAME: }
6868

6969
// CHECK-LABEL: @"$s31class_update_callback_with_stub25ResilientNSObjectSubclassCMt" =
7070
// CHECK-SAME: internal global %objc_full_class_stub {
7171
// CHECK-SAME: [[INT]] 0,
7272
// CHECK-SAME: [[INT]] 1,
73-
// CHECK-SAME: %objc_class* (%objc_class*, i8*)* @"$s31class_update_callback_with_stub25ResilientNSObjectSubclassCMU"
73+
// CHECK-SAME: %objc_class* (%objc_class*, i8*)* {{.*}}@"$s31class_update_callback_with_stub25ResilientNSObjectSubclassCMU{{(\.ptrauth)?}}"
7474
// CHECK-SAME: }
7575

7676
// CHECK-LABEL: @"$s31class_update_callback_with_stub27FixedLayoutNSObjectSubclassCMt" =
7777
// CHECK-SAME: internal global %objc_full_class_stub {
7878
// CHECK-SAME: [[INT]] 0,
7979
// CHECK-SAME: [[INT]] 1,
80-
// CHECK-SAME: %objc_class* (%objc_class*, i8*)* @"$s31class_update_callback_with_stub27FixedLayoutNSObjectSubclassCMU"
80+
// CHECK-SAME: %objc_class* (%objc_class*, i8*)* {{.*}}@"$s31class_update_callback_with_stub27FixedLayoutNSObjectSubclassCMU{{(\.ptrauth)?}}"
8181
// CHECK-SAME: }
8282

8383

validation-test/Runtime/class_stubs.m

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
// RUN: %target-build-swift -emit-library -emit-module -o %t/libfirst.dylib -emit-objc-header-path %t/first.h %S/Inputs/class-stubs-from-objc/first.swift -Xlinker -install_name -Xlinker @executable_path/libfirst.dylib -enable-library-evolution
66
// RUN: %target-build-swift -emit-library -o %t/libsecond.dylib -emit-objc-header-path %t/second.h -I %t %S/Inputs/class-stubs-from-objc/second.swift -Xlinker -install_name -Xlinker @executable_path/libsecond.dylib -lfirst -L %t -target %target-next-stable-abi-triple
77
// RUN: cp %S/Inputs/class-stubs-from-objc/module.map %t/
8-
// RUN: xcrun -sdk %sdk %clang %s -I %t -L %t -fmodules -fobjc-arc -o %t/main -lfirst -lsecond -Wl,-U,_objc_loadClassref -target %target-next-stable-abi-triple
8+
// RUN: xcrun -sdk %sdk %clang %s -I %t -L %t -fmodules -fobjc-arc -o %t/main -lfirst -lsecond -target %target-next-stable-abi-triple
99
// RUN: %target-codesign %t/main %t/libfirst.dylib %t/libsecond.dylib
1010
// RUN: %target-run %t/main %t/libfirst.dylib %t/libsecond.dylib
1111

@@ -31,7 +31,7 @@ + (int)classMethod {
3131

3232
int main(int argc, const char * const argv[]) {
3333
// Only test the new behavior on a new enough libobjc.
34-
if (!dlsym(RTLD_NEXT, "_objc_loadClassref")) {
34+
if (!dlsym(RTLD_NEXT, "objc_loadClassref")) {
3535
fprintf(stderr, "skipping evolution tests; OS too old\n");
3636
return EXIT_SUCCESS;
3737
}

validation-test/Runtime/class_stubs_weak.m

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
// RUN: cp %S/Inputs/class-stubs-weak/module.map %t/
88

99
// Note: This is the just-built Clang, not the system Clang.
10-
// RUN: xcrun -sdk %sdk %clang %s -I %t -L %t -fmodules -fobjc-arc -o %t/main -lfirst -lsecond -Wl,-U,_objc_loadClassref -target %target-triple
10+
// RUN: xcrun -sdk %sdk %clang %s -I %t -L %t -fmodules -fobjc-arc -o %t/main -lfirst -lsecond -target %target-triple
1111

1212
// Now rebuild the library, omitting the weak-exported class
1313
// RUN: %target-build-swift -emit-library -o %t/libsecond.dylib -I %t %S/Inputs/class-stubs-weak/second.swift -Xlinker -install_name -Xlinker @executable_path/libsecond.dylib -lfirst -L %t -target %target-next-stable-abi-triple
@@ -19,6 +19,8 @@
1919
// REQUIRES: objc_interop
2020
// REQUIRES: swift_stable_abi
2121

22+
// REQUIRES: rdar62692550
23+
2224
#import <dlfcn.h>
2325
#import <stdio.h>
2426
#import "second.h"
@@ -37,7 +39,7 @@ + (int)classMethod {
3739

3840
int main(int argc, const char * const argv[]) {
3941
// Only test the new behavior on a new enough libobjc.
40-
if (!dlsym(RTLD_NEXT, "_objc_loadClassref")) {
42+
if (!dlsym(RTLD_NEXT, "objc_loadClassref")) {
4143
fprintf(stderr, "skipping evolution tests; OS too old\n");
4244
return EXIT_SUCCESS;
4345
}

0 commit comments

Comments
 (0)