Skip to content

Commit 7865e3a

Browse files
committed
[CoroutineAccessors] PtrAuth.
1 parent 05ae42c commit 7865e3a

File tree

14 files changed

+126
-21
lines changed

14 files changed

+126
-21
lines changed

include/swift/ABI/Metadata.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5034,9 +5034,9 @@ struct DynamicReplacementKey {
50345034
uint16_t getExtraDiscriminator() const {
50355035
return flags & 0x0000FFFF;
50365036
}
5037-
bool isAsync() const {
5038-
return ((flags >> 16 ) & 0x1);
5039-
}
5037+
bool isAsync() const { return ((flags >> 16) & 0x1); }
5038+
bool isCalleeAllocatedCoroutine() const { return ((flags >> 16) & 0x10); }
5039+
bool isData() const { return isAsync() || isCalleeAllocatedCoroutine(); }
50405040
};
50415041

50425042
/// A record describing a dynamic function replacement.

include/swift/ABI/MetadataValues.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -438,6 +438,23 @@ class MethodDescriptorFlags {
438438

439439
bool isAsync() const { return Value & IsAsyncMask; }
440440

441+
bool isCalleeAllocatedCoroutine() const {
442+
switch (getKind()) {
443+
case Kind::Method:
444+
case Kind::Init:
445+
case Kind::Getter:
446+
case Kind::Setter:
447+
case Kind::ModifyCoroutine:
448+
case Kind::ReadCoroutine:
449+
return false;
450+
case Kind::Read2Coroutine:
451+
case Kind::Modify2Coroutine:
452+
return true;
453+
}
454+
}
455+
456+
bool isData() const { return isAsync() || isCalleeAllocatedCoroutine(); }
457+
441458
uint16_t getExtraDiscriminator() const {
442459
return (Value >> ExtraDiscriminatorShift);
443460
}

include/swift/AST/IRGenOptions.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,26 @@ struct PointerAuthOptions : clang::PointerAuthOptions {
230230

231231
/// Type layout string descriminator.
232232
PointerAuthSchema TypeLayoutString;
233+
234+
/// Like SwiftFunctionPointers but for use with CoroFunctionPointer values.
235+
PointerAuthSchema CoroSwiftFunctionPointers;
236+
237+
/// Like SwiftClassMethods but for use with CoroFunctionPointer values.
238+
PointerAuthSchema CoroSwiftClassMethods;
239+
240+
/// Like ProtocolWitnesses but for use with CoroFunctionPointer values.
241+
PointerAuthSchema CoroProtocolWitnesses;
242+
243+
/// Like SwiftClassMethodPointers but for use with CoroFunctionPointer
244+
/// values.
245+
PointerAuthSchema CoroSwiftClassMethodPointers;
246+
247+
/// Like SwiftDynamicReplacements but for use with CoroFunctionPointer
248+
/// values.
249+
PointerAuthSchema CoroSwiftDynamicReplacements;
250+
251+
/// Like PartialApplyCapture but for use with CoroFunctionPointer values.
252+
PointerAuthSchema CoroPartialApplyCapture;
233253
};
234254

235255
enum class JITDebugArtifact : unsigned {

lib/IRGen/GenClass.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3093,6 +3093,8 @@ FunctionPointer irgen::emitVirtualMethodValue(IRGenFunction &IGF,
30933093
auto fnPtr = emitVTableSlotLoad(IGF, slot, method, signature);
30943094
auto &schema = methodType->isAsync()
30953095
? IGF.getOptions().PointerAuth.AsyncSwiftClassMethods
3096+
: methodType->isCalleeAllocatedCoroutine()
3097+
? IGF.getOptions().PointerAuth.CoroSwiftClassMethods
30963098
: IGF.getOptions().PointerAuth.SwiftClassMethods;
30973099
auto authInfo =
30983100
PointerAuthInfo::emit(IGF, schema, slot.getAddress(), method);

lib/IRGen/GenDecl.cpp

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1823,9 +1823,15 @@ static llvm::GlobalVariable *getChainEntryForDynamicReplacement(
18231823
IGM.DynamicReplacementLinkEntryTy, linkEntry, indices);
18241824
bool isAsyncFunction =
18251825
entity.hasSILFunction() && entity.getSILFunction()->isAsync();
1826+
bool isCalleeAllocatedCoroutine =
1827+
entity.hasSILFunction() && entity.getSILFunction()
1828+
->getLoweredFunctionType()
1829+
->isCalleeAllocatedCoroutine();
18261830
auto &schema =
18271831
isAsyncFunction
18281832
? IGM.getOptions().PointerAuth.AsyncSwiftDynamicReplacements
1833+
: isCalleeAllocatedCoroutine
1834+
? IGM.getOptions().PointerAuth.CoroSwiftDynamicReplacements
18291835
: IGM.getOptions().PointerAuth.SwiftDynamicReplacements;
18301836
assert(entity.hasSILFunction() || entity.isOpaqueTypeDescriptorAccessor());
18311837
auto authEntity = entity.hasSILFunction()
@@ -2945,8 +2951,14 @@ static llvm::GlobalVariable *createGlobalForDynamicReplacementFunctionKey(
29452951
B.addRelativeAddress(linkEntry);
29462952
bool isAsyncFunction =
29472953
keyEntity.hasSILFunction() && keyEntity.getSILFunction()->isAsync();
2954+
bool isCalleeAllocatedCoroutine =
2955+
keyEntity.hasSILFunction() && keyEntity.getSILFunction()
2956+
->getLoweredFunctionType()
2957+
->isCalleeAllocatedCoroutine();
29482958
auto schema = isAsyncFunction
29492959
? IGM.getOptions().PointerAuth.AsyncSwiftDynamicReplacements
2960+
: isCalleeAllocatedCoroutine
2961+
? IGM.getOptions().PointerAuth.CoroSwiftDynamicReplacements
29502962
: IGM.getOptions().PointerAuth.SwiftDynamicReplacements;
29512963
if (schema) {
29522964
assert(keyEntity.hasSILFunction() ||
@@ -2957,7 +2969,9 @@ static llvm::GlobalVariable *createGlobalForDynamicReplacementFunctionKey(
29572969
B.addInt32((uint32_t)PointerAuthInfo::getOtherDiscriminator(IGM, schema,
29582970
authEntity)
29592971
->getZExtValue() |
2960-
((uint32_t)isAsyncFunction ? 0x10000 : 0x0));
2972+
((uint32_t)isAsyncFunction ? 0x10000
2973+
: isCalleeAllocatedCoroutine ? 0x100000
2974+
: 0x0));
29612975
} else
29622976
B.addInt32(0);
29632977
B.finishAndSetAsInitializer(key);
@@ -3009,6 +3023,8 @@ void IRGenModule::createReplaceableProlog(IRGenFunction &IGF, SILFunction *f) {
30093023

30103024
auto &schema = f->isAsync()
30113025
? getOptions().PointerAuth.AsyncSwiftDynamicReplacements
3026+
: f->getLoweredFunctionType()->isCalleeAllocatedCoroutine()
3027+
? getOptions().PointerAuth.CoroSwiftDynamicReplacements
30123028
: getOptions().PointerAuth.SwiftDynamicReplacements;
30133029
llvm::Value *ReplFn = nullptr, *hasReplFn = nullptr;
30143030

@@ -3227,9 +3243,15 @@ static void emitDynamicallyReplaceableThunk(IRGenModule &IGM,
32273243
forwardedArgs.push_back(&arg);
32283244
bool isAsyncFunction =
32293245
keyEntity.hasSILFunction() && keyEntity.getSILFunction()->isAsync();
3246+
bool isCalleeAllocatedCoroutine =
3247+
keyEntity.hasSILFunction() && keyEntity.getSILFunction()
3248+
->getLoweredFunctionType()
3249+
->isCalleeAllocatedCoroutine();
32303250
auto &schema =
32313251
isAsyncFunction
32323252
? IGM.getOptions().PointerAuth.AsyncSwiftDynamicReplacements
3253+
: isCalleeAllocatedCoroutine
3254+
? IGM.getOptions().PointerAuth.CoroSwiftDynamicReplacements
32333255
: IGM.getOptions().PointerAuth.SwiftDynamicReplacements;
32343256
assert(keyEntity.hasSILFunction() ||
32353257
keyEntity.isOpaqueTypeDescriptorAccessor());
@@ -3356,6 +3378,8 @@ void IRGenModule::emitDynamicReplacementOriginalFunctionThunk(SILFunction *f) {
33563378

33573379
auto &schema = f->isAsync()
33583380
? getOptions().PointerAuth.AsyncSwiftDynamicReplacements
3381+
: f->getLoweredFunctionType()->isCalleeAllocatedCoroutine()
3382+
? getOptions().PointerAuth.CoroSwiftDynamicReplacements
33593383
: getOptions().PointerAuth.SwiftDynamicReplacements;
33603384
auto authInfo = PointerAuthInfo::emit(
33613385
IGF, schema, fnPtrAddr,

lib/IRGen/GenFunc.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2148,6 +2148,8 @@ static llvm::Value *emitPartialApplicationForwarder(
21482148
subIGF,
21492149
origType->isAsync()
21502150
? IGM.getOptions().PointerAuth.AsyncPartialApplyCapture
2151+
: origType->isCalleeAllocatedCoroutine()
2152+
? IGM.getOptions().PointerAuth.CoroPartialApplyCapture
21512153
: IGM.getOptions().PointerAuth.PartialApplyCapture,
21522154
lastCapturedFieldPtr, PointerAuthEntity::Special::PartialApplyCapture);
21532155

@@ -2565,6 +2567,8 @@ std::optional<StackAddress> irgen::emitFunctionPartialApplication(
25652567
if (auto &schema =
25662568
origType->isAsync()
25672569
? IGF.getOptions().PointerAuth.AsyncPartialApplyCapture
2570+
: origType->isCalleeAllocatedCoroutine()
2571+
? IGF.getOptions().PointerAuth.CoroPartialApplyCapture
25682572
: IGF.getOptions().PointerAuth.PartialApplyCapture) {
25692573
auto schemaAuthInfo = PointerAuthInfo::emit(
25702574
IGF, schema, fieldAddr.getAddress(),

lib/IRGen/GenMeta.cpp

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -298,10 +298,15 @@ static void buildMethodDescriptorFields(IRGenModule &IGM,
298298
if (func->shouldUseObjCDispatch())
299299
flags = flags.withIsDynamic(true);
300300

301+
auto *accessor = dyn_cast<AccessorDecl>(func);
302+
301303
// Include the pointer-auth discriminator.
302-
if (auto &schema = func->hasAsync()
303-
? IGM.getOptions().PointerAuth.AsyncSwiftClassMethods
304-
: IGM.getOptions().PointerAuth.SwiftClassMethods) {
304+
if (auto &schema =
305+
func->hasAsync() ? IGM.getOptions().PointerAuth.AsyncSwiftClassMethods
306+
: accessor &&
307+
requiresFeatureCoroutineAccessors(accessor->getAccessorKind())
308+
? IGM.getOptions().PointerAuth.CoroSwiftClassMethods
309+
: IGM.getOptions().PointerAuth.SwiftClassMethods) {
305310
auto discriminator =
306311
PointerAuthInfo::getOtherDiscriminator(IGM, schema, fn);
307312
flags = flags.withExtraDiscriminator(discriminator->getZExtValue());
@@ -4491,9 +4496,13 @@ namespace {
44914496
VTableEntriesForVFE.push_back(std::pair<Size, SILDeclRef>(offset, fn));
44924497
}
44934498

4499+
auto *accessor = dyn_cast<AccessorDecl>(afd);
44944500
PointerAuthSchema schema =
44954501
afd->hasAsync() ? IGM.getOptions().PointerAuth.AsyncSwiftClassMethods
4496-
: IGM.getOptions().PointerAuth.SwiftClassMethods;
4502+
: accessor &&
4503+
requiresFeatureCoroutineAccessors(accessor->getAccessorKind())
4504+
? IGM.getOptions().PointerAuth.CoroSwiftClassMethods
4505+
: IGM.getOptions().PointerAuth.SwiftClassMethods;
44974506
B.addSignedPointer(ptr, schema, fn);
44984507
}
44994508

lib/IRGen/GenPointerAuth.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,8 @@ static const PointerAuthSchema &getFunctionPointerSchema(IRGenModule &IGM,
193193
case SILFunctionTypeRepresentation::KeyPathAccessorHash:
194194
if (fnType->isAsync()) {
195195
return options.AsyncSwiftFunctionPointers;
196+
} else if (fnType->isCalleeAllocatedCoroutine()) {
197+
return options.CoroSwiftFunctionPointers;
196198
}
197199

198200
return options.SwiftFunctionPointers;

lib/IRGen/GenProto.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1682,6 +1682,8 @@ class AccessorConformanceInfo : public ConformanceInfo {
16821682
PointerAuthSchema schema =
16831683
isAsyncRequirement
16841684
? IGM.getOptions().PointerAuth.AsyncProtocolWitnesses
1685+
: isCalleeAllocatedCoroutineRequirement
1686+
? IGM.getOptions().PointerAuth.CoroProtocolWitnesses
16851687
: IGM.getOptions().PointerAuth.ProtocolWitnesses;
16861688
Table.addSignedPointer(witness, schema, requirement);
16871689

@@ -4387,6 +4389,8 @@ FunctionPointer irgen::emitWitnessMethodValue(IRGenFunction &IGF,
43874389

43884390
auto &schema = fnType->isAsync()
43894391
? IGF.getOptions().PointerAuth.AsyncProtocolWitnesses
4392+
: fnType->isCalleeAllocatedCoroutine()
4393+
? IGF.getOptions().PointerAuth.CoroProtocolWitnesses
43904394
: IGF.getOptions().PointerAuth.ProtocolWitnesses;
43914395
auto authInfo = PointerAuthInfo::emit(IGF, schema, slot.getAddress(), member);
43924396

lib/IRGen/GenThunk.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -805,6 +805,10 @@ void IRGenModule::emitMethodLookupFunction(ClassDecl *classDecl) {
805805
if (auto &schema =
806806
entry->getImplementation()->getLoweredFunctionType()->isAsync()
807807
? IGM.getOptions().PointerAuth.AsyncSwiftClassMethods
808+
: entry->getImplementation()
809+
->getLoweredFunctionType()
810+
->isCalleeAllocatedCoroutine()
811+
? IGM.getOptions().PointerAuth.CoroSwiftClassMethods
808812
: IGM.getOptions().PointerAuth.SwiftClassMethods) {
809813
auto discriminator =
810814
PointerAuthInfo::getOtherDiscriminator(IGM, schema, method);

lib/IRGen/IRGen.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -923,6 +923,24 @@ static void setPointerAuthOptions(PointerAuthOptions &opts,
923923
opts.RelativeProtocolWitnessTable = PointerAuthSchema(
924924
dataKey, /*address*/ false, Discrimination::Constant,
925925
SpecialPointerAuthDiscriminators::RelativeProtocolWitnessTable);
926+
927+
opts.CoroSwiftFunctionPointers =
928+
PointerAuthSchema(dataKey, /*address*/ false, Discrimination::Type);
929+
930+
opts.CoroSwiftClassMethods =
931+
PointerAuthSchema(dataKey, /*address*/ true, Discrimination::Decl);
932+
933+
opts.CoroProtocolWitnesses =
934+
PointerAuthSchema(dataKey, /*address*/ true, Discrimination::Decl);
935+
936+
opts.CoroSwiftClassMethodPointers =
937+
PointerAuthSchema(dataKey, /*address*/ false, Discrimination::Decl);
938+
939+
opts.CoroSwiftDynamicReplacements =
940+
PointerAuthSchema(dataKey, /*address*/ true, Discrimination::Decl);
941+
942+
opts.CoroPartialApplyCapture =
943+
PointerAuthSchema(nonABIDataKey, /*address*/ true, Discrimination::Decl);
926944
}
927945

928946
std::unique_ptr<llvm::TargetMachine>

lib/IRGen/IRGenSIL.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8369,6 +8369,8 @@ void IRGenSILFunction::visitSuperMethodInst(swift::SuperMethodInst *i) {
83698369

83708370
auto &schema = methodType->isAsync()
83718371
? getOptions().PointerAuth.AsyncSwiftClassMethodPointers
8372+
: methodType->isCalleeAllocatedCoroutine()
8373+
? getOptions().PointerAuth.CoroSwiftClassMethodPointers
83728374
: getOptions().PointerAuth.SwiftClassMethodPointers;
83738375
auto authInfo =
83748376
PointerAuthInfo::emit(*this, schema, /*storageAddress=*/nullptr, method);

stdlib/public/runtime/Metadata.cpp

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -410,7 +410,7 @@ static void swift_objc_classCopyFixupHandler(Class oldClass, Class newClass) {
410410
reinterpret_cast<void **>(&dest[i]),
411411
reinterpret_cast<void *const *>(&src[i]),
412412
descriptors[i].Flags.getExtraDiscriminator(),
413-
!descriptors[i].Flags.isAsync(),
413+
!descriptors[i].Flags.isData(),
414414
/*allowNull*/ true); // NULL allowed for VFE (methods in the vtable
415415
// might be proven unused and null'ed)
416416
}
@@ -3609,7 +3609,7 @@ static void copySuperclassMetadataToSubclass(ClassMetadata *theClass,
36093609
reinterpret_cast<void **>(&dest[i]),
36103610
reinterpret_cast<void *const *>(&src[i]),
36113611
descriptors[i].Flags.getExtraDiscriminator(),
3612-
!descriptors[i].Flags.isAsync(),
3612+
!descriptors[i].Flags.isData(),
36133613
/*allowNull*/ true); // NULL allowed for VFE (methods in the vtable
36143614
// might be proven unused and null'ed)
36153615
}
@@ -3659,7 +3659,7 @@ static void initClassVTable(ClassMetadata *self) {
36593659
swift_ptrauth_init_code_or_data(
36603660
&classWords[vtableOffset + i], methodDescription.getImpl(),
36613661
methodDescription.Flags.getExtraDiscriminator(),
3662-
!methodDescription.Flags.isAsync());
3662+
!methodDescription.Flags.isData());
36633663
}
36643664
}
36653665

@@ -3697,10 +3697,9 @@ static void initClassVTable(ClassMetadata *self) {
36973697
auto baseVTable = baseClass->getVTableDescriptor();
36983698
auto offset = (baseVTable->getVTableOffset(baseClass) +
36993699
(baseMethod - baseClassMethods.data()));
3700-
swift_ptrauth_init_code_or_data(&classWords[offset],
3701-
descriptor.getImpl(),
3700+
swift_ptrauth_init_code_or_data(&classWords[offset], descriptor.getImpl(),
37023701
baseMethod->Flags.getExtraDiscriminator(),
3703-
!baseMethod->Flags.isAsync());
3702+
!baseMethod->Flags.isData());
37043703
}
37053704
}
37063705
}
@@ -4352,7 +4351,7 @@ swift::swift_lookUpClassMethod(const ClassMetadata *metadata,
43524351
#if SWIFT_PTRAUTH
43534352
// Re-sign the return value without the address.
43544353
unsigned extra = method->Flags.getExtraDiscriminator();
4355-
if (method->Flags.isAsync()) {
4354+
if (method->Flags.isData()) {
43564355
return ptrauth_auth_and_resign(
43574356
*methodPtr, ptrauth_key_process_independent_data,
43584357
ptrauth_blend_discriminator(methodPtr, extra),
@@ -6097,7 +6096,7 @@ static void initProtocolWitness(void **slot, void *witness,
60976096
case ProtocolRequirementFlags::Kind::Modify2Coroutine:
60986097
swift_ptrauth_init_code_or_data(slot, witness,
60996098
reqt.Flags.getExtraDiscriminator(),
6100-
!reqt.Flags.isAsync());
6099+
!reqt.Flags.isData());
61016100
return;
61026101

61036102
case ProtocolRequirementFlags::Kind::AssociatedConformanceAccessFunction:
@@ -6139,7 +6138,7 @@ static void copyProtocolWitness(void **dest, void * const *src,
61396138
case ProtocolRequirementFlags::Kind::ModifyCoroutine:
61406139
case ProtocolRequirementFlags::Kind::Modify2Coroutine:
61416140
swift_ptrauth_copy_code_or_data(
6142-
dest, src, reqt.Flags.getExtraDiscriminator(), !reqt.Flags.isAsync(),
6141+
dest, src, reqt.Flags.getExtraDiscriminator(), !reqt.Flags.isData(),
61436142
/*allowNull*/ true); // NULL allowed for VFE (methods in the vtable
61446143
// might be proven unused and null'ed)
61456144
return;

stdlib/public/runtime/MetadataLookup.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3722,7 +3722,7 @@ void DynamicReplacementDescriptor::enableReplacement() const {
37223722
reinterpret_cast<void **>(&chainRoot->implementationFunction),
37233723
reinterpret_cast<void *const *>(&previous->implementationFunction),
37243724
replacedFunctionKey->getExtraDiscriminator(),
3725-
!replacedFunctionKey->isAsync(), /*allowNull*/ false);
3725+
!replacedFunctionKey->isData(), /*allowNull*/ false);
37263726
}
37273727

37283728
// First populate the current replacement's chain entry.
@@ -3733,7 +3733,7 @@ void DynamicReplacementDescriptor::enableReplacement() const {
37333733
reinterpret_cast<void **>(&currentEntry->implementationFunction),
37343734
reinterpret_cast<void *const *>(&chainRoot->implementationFunction),
37353735
replacedFunctionKey->getExtraDiscriminator(),
3736-
!replacedFunctionKey->isAsync(), /*allowNull*/ false);
3736+
!replacedFunctionKey->isData(), /*allowNull*/ false);
37373737

37383738
currentEntry->next = chainRoot->next;
37393739

@@ -3744,7 +3744,7 @@ void DynamicReplacementDescriptor::enableReplacement() const {
37443744
reinterpret_cast<void **>(&chainRoot->implementationFunction),
37453745
reinterpret_cast<void *>(getReplacementFunction()),
37463746
replacedFunctionKey->getExtraDiscriminator(),
3747-
!replacedFunctionKey->isAsync());
3747+
!replacedFunctionKey->isData());
37483748
}
37493749

37503750
void DynamicReplacementDescriptor::disableReplacement() const {
@@ -3769,7 +3769,7 @@ void DynamicReplacementDescriptor::disableReplacement() const {
37693769
reinterpret_cast<void **>(&previous->implementationFunction),
37703770
reinterpret_cast<void *const *>(&thisEntry->implementationFunction),
37713771
replacedFunctionKey->getExtraDiscriminator(),
3772-
!replacedFunctionKey->isAsync(), /*allowNull*/ false);
3772+
!replacedFunctionKey->isData(), /*allowNull*/ false);
37733773
}
37743774

37753775
/// An automatic dynamic replacement entry.

0 commit comments

Comments
 (0)