@@ -62,11 +62,6 @@ class RemoteRef {
62
62
return Address;
63
63
}
64
64
65
- template <typename Runtime>
66
- typename Runtime::StoredPointer getAddress () const {
67
- return (typename Runtime::StoredPointer)getAddressData ();
68
- }
69
-
70
65
const T *getLocalBuffer () const {
71
66
return LocalBuffer;
72
67
}
@@ -87,6 +82,26 @@ class RemoteRef {
87
82
bool operator !=(RemoteRef<T> other) const {
88
83
return !operator ==(other);
89
84
}
85
+
86
+ // / Project a reference for a field. The field must be projected from the same
87
+ // / LocalBuffer pointer as this RemoteRef.
88
+ template <typename U>
89
+ RemoteRef<U> getField (U &field) const {
90
+ auto offset = (intptr_t )&field - (intptr_t )LocalBuffer;
91
+ return RemoteRef<U>((uint64_t )(Address + (int64_t )offset), &field);
92
+ }
93
+
94
+ // / Resolve the remote address of a relative offset stored at the remote address.
95
+ uint64_t resolveRelativeAddressData () const {
96
+ int32_t offset;
97
+ memcpy (&offset, LocalBuffer, sizeof (int32_t ));
98
+ return Address + (int64_t )offset;
99
+ }
100
+
101
+ template <typename U>
102
+ uint64_t resolveRelativeFieldData (U &field) const {
103
+ return getField (field).resolveRelativeAddressData ();
104
+ }
90
105
};
91
106
92
107
// / A structure, designed for use with std::unique_ptr, which destroys
@@ -1077,14 +1092,13 @@ class MetadataReader {
1077
1092
return ClassMetadataBounds::forSwiftRootClass ();
1078
1093
1079
1094
auto rawSuperclass =
1080
- resolveNullableRelativeField (subclassRef,
1081
- subclass->getResilientSuperclass ());
1095
+ resolveRelativeField (subclassRef, subclass->getResilientSuperclass ());
1082
1096
if (!rawSuperclass) {
1083
1097
return ClassMetadataBounds::forSwiftRootClass ();
1084
1098
}
1085
1099
1086
1100
return forTypeReference<ClassMetadataBounds>(
1087
- subclass->getResilientSuperclassReferenceKind (), * rawSuperclass,
1101
+ subclass->getResilientSuperclassReferenceKind (), rawSuperclass,
1088
1102
[&](ContextDescriptorRef superclass)
1089
1103
-> Optional<ClassMetadataBounds> {
1090
1104
if (!isa<TargetClassDescriptor<Runtime>>(superclass))
@@ -1175,7 +1189,7 @@ class MetadataReader {
1175
1189
return None;
1176
1190
1177
1191
auto addressOfGenericArgAddress =
1178
- (Meta. template getAddress <Runtime>( ) +
1192
+ (getAddress (Meta ) +
1179
1193
*offsetToGenericArgs * sizeof (StoredPointer) +
1180
1194
index * sizeof (StoredPointer));
1181
1195
@@ -1246,31 +1260,6 @@ class MetadataReader {
1246
1260
}
1247
1261
1248
1262
protected:
1249
- template <typename Offset>
1250
- StoredPointer resolveRelativeOffset (StoredPointer targetAddress) {
1251
- Offset relative;
1252
- if (!Reader->readInteger (RemoteAddress (targetAddress), &relative))
1253
- return 0 ;
1254
- using SignedOffset = typename std::make_signed<Offset>::type;
1255
- using SignedPointer = typename std::make_signed<StoredPointer>::type;
1256
- auto signext = (SignedPointer)(SignedOffset)relative;
1257
- return targetAddress + signext;
1258
- }
1259
-
1260
- template <typename Offset>
1261
- Optional<StoredPointer>
1262
- resolveNullableRelativeOffset (StoredPointer targetAddress) {
1263
- Offset relative;
1264
- if (!Reader->readInteger (RemoteAddress (targetAddress), &relative))
1265
- return None;
1266
- if (relative == 0 )
1267
- return 0 ;
1268
- using SignedOffset = typename std::make_signed<Offset>::type;
1269
- using SignedPointer = typename std::make_signed<StoredPointer>::type;
1270
- auto signext = (SignedPointer)(SignedOffset)relative;
1271
- return targetAddress + signext;
1272
- }
1273
-
1274
1263
template <typename Offset>
1275
1264
Optional<StoredPointer>
1276
1265
resolveNullableRelativeIndirectableOffset (StoredPointer targetAddress) {
@@ -1299,33 +1288,44 @@ class MetadataReader {
1299
1288
return resultAddress;
1300
1289
}
1301
1290
1302
- template <typename Base, typename Field>
1303
- StoredPointer resolveRelativeField (
1304
- RemoteRef<Base> base, const Field &field) {
1305
- // Map the offset from within our local buffer to the remote address.
1306
- auto distance = (intptr_t )&field - (intptr_t )base.getLocalBuffer ();
1307
- return resolveRelativeOffset<int32_t >(
1308
- base.template getAddress <Runtime>() + distance);
1291
+ template <typename Base>
1292
+ StoredPointer getAddress (RemoteRef<Base> base) {
1293
+ return (StoredPointer)base.getAddressData ();
1309
1294
}
1310
1295
1311
1296
template <typename Base, typename Field>
1312
- Optional< StoredPointer> resolveNullableRelativeField (
1297
+ StoredPointer resolveRelativeField (
1313
1298
RemoteRef<Base> base, const Field &field) {
1314
- // Map the offset from within our local buffer to the remote address.
1315
- auto distance = (intptr_t )&field - (intptr_t )base.getLocalBuffer ();
1316
-
1317
- return resolveNullableRelativeOffset<int32_t >(
1318
- base.template getAddress <Runtime>() + distance);
1299
+ return (StoredPointer)base.resolveRelativeFieldData (field);
1319
1300
}
1320
-
1301
+
1321
1302
template <typename Base, typename Field>
1322
- Optional<StoredPointer> resolveNullableRelativeIndirectableField (
1303
+ Optional<StoredPointer> resolveRelativeIndirectableField (
1323
1304
RemoteRef<Base> base, const Field &field) {
1324
- // Map the offset from within our local buffer to the remote address.
1325
- auto distance = (intptr_t )&field - (intptr_t )base.getLocalBuffer ();
1305
+ auto fieldRef = base.getField (field);
1306
+ int32_t offset;
1307
+ memcpy (&offset, fieldRef.getLocalBuffer (), sizeof (int32_t ));
1308
+
1309
+ if (offset == 0 )
1310
+ return 0 ;
1311
+ bool indirect = offset & 1 ;
1312
+ offset &= ~1u ;
1326
1313
1327
- return resolveNullableRelativeIndirectableOffset<int32_t >(
1328
- base.template getAddress <Runtime>() + distance);
1314
+ using SignedPointer = typename std::make_signed<StoredPointer>::type;
1315
+
1316
+ StoredPointer resultAddress = getAddress (fieldRef) + (SignedPointer)offset;
1317
+
1318
+ // Low bit set in the offset indicates that the offset leads to the absolute
1319
+ // address in memory.
1320
+ if (indirect) {
1321
+ if (!Reader->readBytes (RemoteAddress (resultAddress),
1322
+ (uint8_t *)&resultAddress,
1323
+ sizeof (StoredPointer))) {
1324
+ return None;
1325
+ }
1326
+ }
1327
+
1328
+ return resultAddress;
1329
1329
}
1330
1330
1331
1331
// / Given a pointer to an Objective-C class, try to read its class name.
@@ -1532,8 +1532,7 @@ class MetadataReader {
1532
1532
// / Returns None if there was an error reading the parent descriptor.
1533
1533
Optional<ContextDescriptorRef>
1534
1534
readParentContextDescriptor (ContextDescriptorRef base) {
1535
- auto parentAddress =
1536
- resolveNullableRelativeIndirectableField (base, base->Parent );
1535
+ auto parentAddress = resolveRelativeIndirectableField (base, base->Parent );
1537
1536
if (!parentAddress)
1538
1537
return None;
1539
1538
if (!*parentAddress)
@@ -1849,8 +1848,7 @@ class MetadataReader {
1849
1848
const RelativeTargetProtocolDescriptorPointer<Runtime> &protocol) {
1850
1849
// Map the offset from within our local buffer to the remote address.
1851
1850
auto distance = (intptr_t )&protocol - (intptr_t )descriptor.getLocalBuffer ();
1852
- StoredPointer targetAddress (
1853
- descriptor.template getAddress <Runtime>() + distance);
1851
+ StoredPointer targetAddress (getAddress (descriptor) + distance);
1854
1852
1855
1853
// Read the relative offset.
1856
1854
int32_t relative;
@@ -2083,8 +2081,7 @@ class MetadataReader {
2083
2081
// address.
2084
2082
auto distance =
2085
2083
(intptr_t )&req.Layout - (intptr_t )descriptor.getLocalBuffer ();
2086
- StoredPointer targetAddress (
2087
- descriptor.template getAddress <Runtime>() + distance);
2084
+ StoredPointer targetAddress (getAddress (descriptor) + distance);
2088
2085
2089
2086
GenericRequirementLayoutKind kind;
2090
2087
if (!Reader->readBytes (RemoteAddress (targetAddress),
@@ -2282,7 +2279,7 @@ class MetadataReader {
2282
2279
if (!offsetToGenericArgs)
2283
2280
return {};
2284
2281
2285
- auto genericArgsAddr = metadata. template getAddress <Runtime>( )
2282
+ auto genericArgsAddr = getAddress (metadata )
2286
2283
+ sizeof (StoredPointer) * *offsetToGenericArgs;
2287
2284
2288
2285
std::vector<BuiltType> builtSubsts;
@@ -2340,7 +2337,7 @@ class MetadataReader {
2340
2337
// If we've skipped an artificial subclasses, check the cache at
2341
2338
// the superclass. (This also protects against recursion.)
2342
2339
if (skipArtificialSubclasses && metadata != origMetadata) {
2343
- auto it = TypeCache.find (metadata. template getAddress <Runtime>( ));
2340
+ auto it = TypeCache.find (getAddress (metadata ));
2344
2341
if (it != TypeCache.end ())
2345
2342
return it->second ;
2346
2343
}
@@ -2370,12 +2367,12 @@ class MetadataReader {
2370
2367
if (!nominal)
2371
2368
return BuiltType ();
2372
2369
2373
- TypeCache[metadata. template getAddress <Runtime>( )] = nominal;
2370
+ TypeCache[getAddress (metadata )] = nominal;
2374
2371
2375
2372
// If we've skipped an artificial subclass, remove the
2376
2373
// recursion-protection entry we made for it.
2377
2374
if (skipArtificialSubclasses && metadata != origMetadata) {
2378
- TypeCache.erase (origMetadata. template getAddress <Runtime>( ));
2375
+ TypeCache.erase (getAddress (origMetadata ));
2379
2376
}
2380
2377
2381
2378
return nominal;
@@ -2388,7 +2385,7 @@ class MetadataReader {
2388
2385
return readNominalTypeFromMetadata (origMetadata, skipArtificialSubclasses);
2389
2386
2390
2387
std::string className;
2391
- auto origMetadataPtr = origMetadata. template getAddress <Runtime>( );
2388
+ auto origMetadataPtr = getAddress (origMetadata );
2392
2389
if (!readObjCClassName (origMetadataPtr, className))
2393
2390
return BuiltType ();
2394
2391
0 commit comments