Skip to content

Commit a317b87

Browse files
authored
Merge pull request swiftlang#30739 from mikeash/remote-mirror-fix-ownsaddress
[Reflection] Fix the ownsAddress function to claim heap-allocated Metadatas
2 parents d922041 + 5da118e commit a317b87

File tree

3 files changed

+46
-23
lines changed

3 files changed

+46
-23
lines changed

include/swift/Reflection/ReflectionContext.h

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -541,15 +541,35 @@ class ReflectionContext
541541
}
542542

543543
/// Returns true if the address falls within a registered image.
544-
bool ownsAddress(RemoteAddress Address) {
544+
bool ownsAddressRaw(RemoteAddress Address) {
545545
for (auto Range : imageRanges) {
546546
auto Start = std::get<0>(Range);
547547
auto End = std::get<1>(Range);
548548
if (Start.getAddressData() <= Address.getAddressData()
549549
&& Address.getAddressData() < End.getAddressData())
550550
return true;
551551
}
552-
552+
553+
return false;
554+
}
555+
556+
/// Returns true if the address is known to the reflection context.
557+
/// Currently, that means that either the address falls within a registered
558+
/// image, or the address points to a Metadata whose type context descriptor
559+
/// is within a registered image.
560+
bool ownsAddress(RemoteAddress Address) {
561+
if (ownsAddressRaw(Address))
562+
return true;
563+
564+
// This is usually called on a Metadata address which might have been
565+
// on the heap. Try reading it and looking up its type context descriptor
566+
// instead.
567+
if (auto Metadata = readMetadata(Address.getAddressData()))
568+
if (auto DescriptorAddress =
569+
super::readAddressOfNominalTypeDescriptor(Metadata, true))
570+
if (ownsAddressRaw(RemoteAddress(DescriptorAddress)))
571+
return true;
572+
553573
return false;
554574
}
555575

include/swift/Remote/MetadataReader.h

Lines changed: 23 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1682,32 +1682,16 @@ class MetadataReader {
16821682
return nullptr;
16831683
}
16841684

1685-
private:
1686-
template <template <class R> class M>
1687-
MetadataRef _readMetadata(StoredPointer address) {
1688-
return _readMetadata(address, sizeof(M<Runtime>));
1689-
}
1690-
1691-
MetadataRef _readMetadata(StoredPointer address, size_t sizeAfter) {
1692-
auto size = sizeAfter;
1693-
uint8_t *buffer = (uint8_t *) malloc(size);
1694-
if (!Reader->readBytes(RemoteAddress(address), buffer, size)) {
1695-
free(buffer);
1696-
return nullptr;
1697-
}
1698-
1699-
auto metadata = reinterpret_cast<TargetMetadata<Runtime>*>(buffer);
1700-
MetadataCache.insert(std::make_pair(address, OwnedMetadataRef(metadata)));
1701-
return MetadataRef(address, metadata);
1702-
}
1703-
17041685
StoredPointer
17051686
readAddressOfNominalTypeDescriptor(MetadataRef &metadata,
17061687
bool skipArtificialSubclasses = false) {
17071688
switch (metadata->getKind()) {
17081689
case MetadataKind::Class: {
17091690
auto classMeta = cast<TargetClassMetadata<Runtime>>(metadata);
17101691
while (true) {
1692+
if (!classMeta->isTypeMetadata())
1693+
return 0;
1694+
17111695
StoredSignedPointer descriptorAddressSigned = classMeta->getDescriptionAsSignedPointer();
17121696
StoredPointer descriptorAddress = stripSignedPointer(descriptorAddressSigned);
17131697

@@ -1753,7 +1737,26 @@ class MetadataReader {
17531737
return 0;
17541738
}
17551739
}
1756-
1740+
1741+
private:
1742+
template <template <class R> class M>
1743+
MetadataRef _readMetadata(StoredPointer address) {
1744+
return _readMetadata(address, sizeof(M<Runtime>));
1745+
}
1746+
1747+
MetadataRef _readMetadata(StoredPointer address, size_t sizeAfter) {
1748+
auto size = sizeAfter;
1749+
uint8_t *buffer = (uint8_t *) malloc(size);
1750+
if (!Reader->readBytes(RemoteAddress(address), buffer, size)) {
1751+
free(buffer);
1752+
return nullptr;
1753+
}
1754+
1755+
auto metadata = reinterpret_cast<TargetMetadata<Runtime>*>(buffer);
1756+
MetadataCache.insert(std::make_pair(address, OwnedMetadataRef(metadata)));
1757+
return MetadataRef(address, metadata);
1758+
}
1759+
17571760
/// Returns Optional(ParentContextDescriptorRef()) if there's no parent descriptor.
17581761
/// Returns None if there was an error reading the parent descriptor.
17591762
Optional<ParentContextDescriptorRef>

include/swift/SwiftRemoteMirror/SwiftRemoteMirror.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ SWIFT_REMOTE_MIRROR_LINKAGE
116116
int
117117
swift_reflection_ownsObject(SwiftReflectionContextRef ContextRef, uintptr_t Object);
118118

119-
/// Returns whether the given address is within an image added to this
119+
/// Returns whether the given address is associated with an image added to this
120120
/// library. Images must be added using swift_reflection_addImage, not
121121
/// swift_reflection_addReflectionInfo, for this function to work
122122
/// properly. If addReflectionInfo is used, the return value will always

0 commit comments

Comments
 (0)