Skip to content

Commit 752f0fb

Browse files
committed
[ExternalGenericMetadataBuilder] Fix pointer targets, exports, and recursive metadata.
Use exports, not symbols, when emitting a pointer target. Exports are what the linker can actually work with. When searching for a nearby export to use for a pointer target, accept anything within the same segment, not just the same section. Only segments can be rearranged relative to each other, not sections within a segment, so this is safe and allows for more possible targets. Disallow pointer targets with no export within the same segment. We attempted to emit a target that's relative to the section starting point in this case, but that didn't work. We'll revisit if it looks useful to do so. In order to make this work, we resolve the export when writing a pointer instead of when emitting JSON, and make the writePointer functions failable. If writePointer fails, we'll fail to build the metadata and skip it. Correctly handle the case where the names JSON contains a metadata we already constructed as part of a prior name. Previously we'd emit it twice, now it checks to see if it's already been built and do nothing in that case. Also save errors when a metadata can't be built, so subsequent attempts to build it can fail immediately. When emitting fixups with ptrauth attributes, use the correct target kind "arm64_auth_ptr". Fix the VerifyExternalMetadata.swift test not to load an arm64e runtime slice when testing arm64. That's normally fine, but we depend on loading the exact same dylib that we built prespecializations for. rdar://122968337
1 parent 5ce824f commit 752f0fb

File tree

6 files changed

+363
-263
lines changed

6 files changed

+363
-263
lines changed

include/swift/Runtime/GenericMetadataBuilder.h

Lines changed: 59 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -296,9 +296,11 @@ class GenericMetadataBuilder {
296296
patternPointers->resolvePointer(&patternPointers->ptr[i]);
297297
if (!patternPointer)
298298
return *patternPointer.getError();
299-
data.writePointer(
299+
auto writeResult = data.writePointer(
300300
&metadataExtraData[i + extraDataPattern->OffsetInWords],
301301
patternPointer->template cast<const StoredPointer>());
302+
if (!writeResult)
303+
return *writeResult.getError();
302304
}
303305
}
304306

@@ -310,7 +312,10 @@ class GenericMetadataBuilder {
310312
if (!valueWitnesses)
311313
return *valueWitnesses.getError();
312314
METADATA_BUILDER_LOG("Setting initial value witnesses");
313-
data.writePointer(&fullMetadata->ValueWitnesses, *valueWitnesses);
315+
auto writeResult =
316+
data.writePointer(&fullMetadata->ValueWitnesses, *valueWitnesses);
317+
if (!writeResult)
318+
return *writeResult.getError();
314319

315320
// Set the metadata kind.
316321
METADATA_BUILDER_LOG("Setting metadata kind %#x",
@@ -319,7 +324,9 @@ class GenericMetadataBuilder {
319324

320325
// Set the type descriptor.
321326
METADATA_BUILDER_LOG("Setting descriptor");
322-
data.writePointer(&metadata->Description, descriptionBuffer);
327+
writeResult = data.writePointer(&metadata->Description, descriptionBuffer);
328+
if (!writeResult)
329+
return *writeResult.getError();
323330

324331
return {{}};
325332
}
@@ -353,8 +360,11 @@ class GenericMetadataBuilder {
353360
header.NumKeyArguments,
354361
getGenericArgumentOffset(
355362
descriptionBuffer.template cast<const TypeContextDescriptor>()));
356-
for (unsigned i = 0; i < header.NumKeyArguments; i++)
357-
data.writePointer(&dst[i], arguments[i]);
363+
for (unsigned i = 0; i < header.NumKeyArguments; i++) {
364+
auto writeResult = data.writePointer(&dst[i], arguments[i]);
365+
if (!writeResult)
366+
return *writeResult.getError();
367+
}
358368

359369
// TODO: parameter pack support.
360370

@@ -495,7 +505,11 @@ class GenericMetadataBuilder {
495505
auto LOWER_ID##_Buffer = from.resolveFunctionPointer(&from.ptr->LOWER_ID); \
496506
if (!LOWER_ID##_Buffer) \
497507
return *LOWER_ID##_Buffer.getError(); \
498-
vwtBuffer.writeFunctionPointer(&vwtBuffer.ptr->LOWER_ID, *LOWER_ID##_Buffer);
508+
if (auto *error = vwtBuffer \
509+
.writeFunctionPointer(&vwtBuffer.ptr->LOWER_ID, \
510+
*LOWER_ID##_Buffer) \
511+
.getError()) \
512+
return *error;
499513
#define DATA_VALUE_WITNESS(LOWER_ID, UPPER_ID, TYPE)
500514
#include "swift/ABI/ValueWitness.def"
501515

@@ -520,40 +534,56 @@ class GenericMetadataBuilder {
520534
(size_t)flags.getAlignmentMask());
521535
switch (sizeWithAlignmentMask(layout.size, flags.getAlignmentMask(),
522536
hasExtraInhabitants)) {
523-
default:
537+
default: {
524538
// For uncommon layouts, use value witnesses that work with an arbitrary
525539
// size and alignment.
526540
METADATA_BUILDER_LOG("Uncommon layout case, flags.isInlineStorage=%s",
527541
flags.isInlineStorage() ? "true" : "false");
528542
if (flags.isInlineStorage()) {
529543
if (!pod_direct_initializeBufferWithCopyOfBuffer)
530544
return *pod_direct_initializeBufferWithCopyOfBuffer.getError();
531-
vwtBuffer.writeFunctionPointer(
545+
auto writeResult = vwtBuffer.writeFunctionPointer(
532546
&vwtBuffer.ptr->initializeBufferWithCopyOfBuffer,
533547
*pod_direct_initializeBufferWithCopyOfBuffer);
548+
if (!writeResult)
549+
return *writeResult.getError();
534550
} else {
535551
if (!pod_indirect_initializeBufferWithCopyOfBuffer)
536552
return *pod_indirect_initializeBufferWithCopyOfBuffer.getError();
537-
vwtBuffer.writeFunctionPointer(
553+
auto writeResult = vwtBuffer.writeFunctionPointer(
538554
&vwtBuffer.ptr->initializeBufferWithCopyOfBuffer,
539555
*pod_indirect_initializeBufferWithCopyOfBuffer);
556+
if (!writeResult)
557+
return *writeResult.getError();
540558
}
541559
if (!pod_destroy)
542560
return *pod_destroy.getError();
543561
if (!pod_copy)
544562
return *pod_copy.getError();
545-
vwtBuffer.writeFunctionPointer(&vwtBuffer.ptr->destroy, *pod_destroy);
546-
vwtBuffer.writeFunctionPointer(&vwtBuffer.ptr->initializeWithCopy,
547-
*pod_copy);
548-
vwtBuffer.writeFunctionPointer(&vwtBuffer.ptr->initializeWithTake,
549-
*pod_copy);
550-
vwtBuffer.writeFunctionPointer(&vwtBuffer.ptr->assignWithCopy,
551-
*pod_copy);
552-
vwtBuffer.writeFunctionPointer(&vwtBuffer.ptr->assignWithTake,
553-
*pod_copy);
563+
auto writeResult = vwtBuffer.writeFunctionPointer(
564+
&vwtBuffer.ptr->destroy, *pod_destroy);
565+
if (!writeResult)
566+
return *writeResult.getError();
567+
writeResult = vwtBuffer.writeFunctionPointer(
568+
&vwtBuffer.ptr->initializeWithCopy, *pod_copy);
569+
if (!writeResult)
570+
return *writeResult.getError();
571+
writeResult = vwtBuffer.writeFunctionPointer(
572+
&vwtBuffer.ptr->initializeWithTake, *pod_copy);
573+
if (!writeResult)
574+
return *writeResult.getError();
575+
writeResult = vwtBuffer.writeFunctionPointer(
576+
&vwtBuffer.ptr->assignWithCopy, *pod_copy);
577+
if (!writeResult)
578+
return *writeResult.getError();
579+
writeResult = vwtBuffer.writeFunctionPointer(
580+
&vwtBuffer.ptr->assignWithTake, *pod_copy);
581+
if (!writeResult)
582+
return *writeResult.getError();
554583
// getEnumTagSinglePayload and storeEnumTagSinglePayload are not
555584
// interestingly optimizable based on POD-ness.
556585
return {{}};
586+
}
557587

558588
case sizeWithAlignmentMask(1, 0, 0): {
559589
METADATA_BUILDER_LOG("case sizeWithAlignmentMask(1, 0, 0)");
@@ -629,8 +659,10 @@ class GenericMetadataBuilder {
629659
// Use POD value witnesses for operations that do an initializeWithTake.
630660
if (!pod_copy)
631661
return *pod_copy.getError();
632-
vwtBuffer.writeFunctionPointer(&vwtBuffer.ptr->initializeWithTake,
633-
*pod_copy);
662+
auto writeResult = vwtBuffer.writeFunctionPointer(
663+
&vwtBuffer.ptr->initializeWithTake, *pod_copy);
664+
if (!writeResult)
665+
return *writeResult.getError();
634666
}
635667
return {{}};
636668
}
@@ -761,7 +793,10 @@ class GenericMetadataBuilder {
761793
auto fptr = oldVWTBuffer->resolveFunctionPointer(&oldVWT->LOWER_ID); \
762794
if (!fptr) \
763795
return *fptr.getError(); \
764-
newVWTData.writeFunctionPointer(&newVWT->LOWER_ID, *fptr); \
796+
if (auto *error = \
797+
newVWTData.writeFunctionPointer(&newVWT->LOWER_ID, *fptr) \
798+
.getError()) \
799+
return *error; \
765800
}
766801
#include "swift/ABI/ValueWitness.def"
767802

@@ -774,9 +809,11 @@ class GenericMetadataBuilder {
774809
newVWT->extraInhabitantCount = layout.extraInhabitantCount;
775810
newVWT->flags = layout.flags;
776811

777-
metadataBuffer.writePointer(
812+
auto writeResult = metadataBuffer.writePointer(
778813
&metadataBuffer.ptr->ValueWitnesses,
779814
newVWTData.template cast<const ValueWitnessTable>());
815+
if (!writeResult)
816+
return *writeResult.getError();
780817
return {{}}; // success
781818
}
782819

0 commit comments

Comments
 (0)