Skip to content

Commit 50ef384

Browse files
committed
Fix the swift-inspect dump-generic-metadata operation.
ReflectionContext::allocationMetadataPointer() was reading the metadata pointer from a wrong offset because of the out-of-sync struct layouts and dump-generic-metadata was not working correctly. This change resync's the layouts and adds a static_assert to verify that the offsets match between GenericMetadataCacheEntry and GenericCacheEntry.
1 parent 4d1d8a9 commit 50ef384

File tree

4 files changed

+57
-11
lines changed

4 files changed

+57
-11
lines changed
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
//===--- GenericMetadataCacheEntry.h ----------------------------*- C++ -*-===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2023 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
//
13+
// Declares a struct that mirrors the layout of GenericCacheEntry in
14+
// Metadata.cpp and use a static assert to check that the offset of
15+
// the member Value match between the two.
16+
//
17+
//===----------------------------------------------------------------------===//
18+
19+
#ifndef SWIFT_REFLECTION_GENERICMETADATACACHEENTRY_H
20+
#define SWIFT_REFLECTION_GENERICMETADATACACHEENTRY_H
21+
22+
#include <cstdint>
23+
24+
namespace swift {
25+
26+
template<typename StoredPointer>
27+
struct GenericMetadataCacheEntry {
28+
StoredPointer TrackingInfo;
29+
uint16_t NumKeyParameters;
30+
uint16_t NumWitnessTables;
31+
uint16_t NumPacks;
32+
uint16_t NumShapeClasses;
33+
StoredPointer PackShapeDescriptors;
34+
uint32_t Hash;
35+
StoredPointer Value;
36+
};
37+
38+
} // namespace swift
39+
40+
#endif // SWIFT_REFLECTION_GENERICMETADATACACHEENTRY_H

include/swift/RemoteInspection/ReflectionContext.h

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#include "swift/Concurrency/Actor.h"
3131
#include "swift/Remote/MemoryReader.h"
3232
#include "swift/Remote/MetadataReader.h"
33+
#include "swift/RemoteInspection/GenericMetadataCacheEntry.h"
3334
#include "swift/RemoteInspection/Records.h"
3435
#include "swift/RemoteInspection/RuntimeInternals.h"
3536
#include "swift/RemoteInspection/TypeLowering.h"
@@ -1289,22 +1290,14 @@ class ReflectionContext
12891290
StoredPointer allocationMetadataPointer(
12901291
MetadataAllocation<Runtime> Allocation) {
12911292
if (Allocation.Tag == GenericMetadataCacheTag) {
1292-
struct GenericMetadataCacheEntry {
1293-
StoredPointer LockedStorage;
1294-
uint8_t LockedStorageKind;
1295-
uint8_t TrackingInfo;
1296-
uint16_t NumKeyParameters;
1297-
uint16_t NumWitnessTables;
1298-
uint32_t Hash;
1299-
StoredPointer Value;
1300-
};
13011293
auto AllocationBytes =
13021294
getReader().readBytes(RemoteAddress(Allocation.Ptr),
13031295
Allocation.Size);
13041296
if (!AllocationBytes)
13051297
return 0;
1306-
auto Entry = reinterpret_cast<const GenericMetadataCacheEntry *>(
1307-
AllocationBytes.get());
1298+
auto Entry =
1299+
reinterpret_cast<const GenericMetadataCacheEntry<StoredPointer> *>(
1300+
AllocationBytes.get());
13081301
return Entry->Value;
13091302
}
13101303
return 0;

stdlib/public/runtime/Metadata.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include "swift/Basic/Range.h"
2929
#include "swift/Basic/STLExtras.h"
3030
#include "swift/Demangling/Demangler.h"
31+
#include "swift/RemoteInspection/GenericMetadataCacheEntry.h"
3132
#include "swift/Runtime/Casting.h"
3233
#include "swift/Runtime/EnvironmentVariables.h"
3334
#include "swift/Runtime/ExistentialContainer.h"
@@ -427,6 +428,16 @@ namespace {
427428
};
428429
} // end anonymous namespace
429430

431+
namespace swift {
432+
struct StaticAssertGenericMetadataCacheEntryValueOffset {
433+
static_assert(
434+
offsetof(GenericCacheEntry, Value) ==
435+
offsetof(swift::GenericMetadataCacheEntry<InProcess::StoredPointer>,
436+
Value),
437+
"The generic metadata cache entry layout mismatch");
438+
};
439+
}
440+
430441
namespace {
431442
class GenericMetadataCache :
432443
public MetadataCache<GenericCacheEntry, GenericMetadataCacheTag> {

stdlib/public/runtime/MetadataCache.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1583,6 +1583,8 @@ class VariadicMetadataCacheEntryBase :
15831583
bool matchesKey(const MetadataCacheKey &key) const {
15841584
return key == getKey();
15851585
}
1586+
1587+
friend struct StaticAssertGenericMetadataCacheEntryValueOffset;
15861588
};
15871589

15881590
template <class EntryType, uint16_t Tag>

0 commit comments

Comments
 (0)