Skip to content

Commit 6581fec

Browse files
committed
[CoroutineAccessors] PtrAuth.
1 parent 35d06c3 commit 6581fec

File tree

14 files changed

+147
-25
lines changed

14 files changed

+147
-25
lines changed

include/swift/ABI/Metadata.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5094,9 +5094,9 @@ struct DynamicReplacementKey {
50945094
uint16_t getExtraDiscriminator() const {
50955095
return flags & 0x0000FFFF;
50965096
}
5097-
bool isAsync() const {
5098-
return ((flags >> 16 ) & 0x1);
5099-
}
5097+
bool isAsync() const { return ((flags >> 16) & 0x1); }
5098+
bool isCalleeAllocatedCoroutine() const { return ((flags >> 16) & 0x2); }
5099+
bool isData() const { return isAsync() || isCalleeAllocatedCoroutine(); }
51005100
};
51015101

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

include/swift/ABI/MetadataValues.h

Lines changed: 37 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
}
@@ -649,6 +666,26 @@ class ProtocolRequirementFlags {
649666

650667
bool isAsync() const { return Value & IsAsyncMask; }
651668

669+
bool isCalleeAllocatedCoroutine() const {
670+
switch (getKind()) {
671+
case Kind::BaseProtocol:
672+
case Kind::Method:
673+
case Kind::Init:
674+
case Kind::Getter:
675+
case Kind::Setter:
676+
case Kind::ReadCoroutine:
677+
case Kind::ModifyCoroutine:
678+
case Kind::AssociatedTypeAccessFunction:
679+
case Kind::AssociatedConformanceAccessFunction:
680+
return false;
681+
case Kind::Read2Coroutine:
682+
case Kind::Modify2Coroutine:
683+
return true;
684+
}
685+
}
686+
687+
bool isData() const { return isAsync() || isCalleeAllocatedCoroutine(); }
688+
652689
bool isSignedWithAddress() const {
653690
return getKind() != Kind::BaseProtocol;
654691
}

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 ? 0x20000
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: 5 additions & 4 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

@@ -2158,10 +2160,7 @@ static llvm::Value *emitPartialApplicationForwarder(
21582160
// It comes out of the context as an i8*. Cast to the function type.
21592161
fnPtr = subIGF.Builder.CreateBitCast(fnPtr, fnTy);
21602162

2161-
return FunctionPointer::createSigned(
2162-
origType->isAsync() ? FunctionPointer::Kind::AsyncFunctionPointer
2163-
: FunctionPointer::Kind::Function,
2164-
fnPtr, authInfo, origSig);
2163+
return FunctionPointer::createSigned(origType, fnPtr, authInfo, origSig);
21652164
}();
21662165

21672166
if (origType->isAsync())
@@ -2565,6 +2564,8 @@ std::optional<StackAddress> irgen::emitFunctionPartialApplication(
25652564
if (auto &schema =
25662565
origType->isAsync()
25672566
? IGF.getOptions().PointerAuth.AsyncPartialApplyCapture
2567+
: origType->isCalleeAllocatedCoroutine()
2568+
? IGF.getOptions().PointerAuth.CoroPartialApplyCapture
25682569
: IGF.getOptions().PointerAuth.PartialApplyCapture) {
25692570
auto schemaAuthInfo = PointerAuthInfo::emit(
25702571
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());
@@ -4530,9 +4535,13 @@ namespace {
45304535
VTableEntriesForVFE.push_back(std::pair<Size, SILDeclRef>(offset, fn));
45314536
}
45324537

4538+
auto *accessor = dyn_cast<AccessorDecl>(afd);
45334539
PointerAuthSchema schema =
45344540
afd->hasAsync() ? IGM.getOptions().PointerAuth.AsyncSwiftClassMethods
4535-
: IGM.getOptions().PointerAuth.SwiftClassMethods;
4541+
: accessor &&
4542+
requiresFeatureCoroutineAccessors(accessor->getAccessorKind())
4543+
? IGM.getOptions().PointerAuth.CoroSwiftClassMethods
4544+
: IGM.getOptions().PointerAuth.SwiftClassMethods;
45364545
B.addSignedPointer(ptr, schema, fn);
45374546
}
45384547

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);

0 commit comments

Comments
 (0)