@@ -1493,33 +1493,33 @@ class MetadataReader {
14931493 break ;
14941494 case ContextDescriptorKind::Extension:
14951495 success =
1496- readFullContextDescriptor <TargetExtensionContextDescriptor<Runtime>>(
1497- remoteAddress, ptr);
1496+ readFullTrailingObjects <TargetExtensionContextDescriptor<Runtime>>(
1497+ remoteAddress, ptr, sizeof (TargetContextDescriptor<Runtime>) );
14981498 break ;
14991499 case ContextDescriptorKind::Anonymous:
15001500 success =
1501- readFullContextDescriptor <TargetAnonymousContextDescriptor<Runtime>>(
1502- remoteAddress, ptr);
1501+ readFullTrailingObjects <TargetAnonymousContextDescriptor<Runtime>>(
1502+ remoteAddress, ptr, sizeof (TargetContextDescriptor<Runtime>) );
15031503 break ;
15041504 case ContextDescriptorKind::Class:
1505- success = readFullContextDescriptor <TargetClassDescriptor<Runtime>>(
1506- remoteAddress, ptr);
1505+ success = readFullTrailingObjects <TargetClassDescriptor<Runtime>>(
1506+ remoteAddress, ptr, sizeof (TargetContextDescriptor<Runtime>) );
15071507 break ;
15081508 case ContextDescriptorKind::Enum:
1509- success = readFullContextDescriptor <TargetEnumDescriptor<Runtime>>(
1510- remoteAddress, ptr);
1509+ success = readFullTrailingObjects <TargetEnumDescriptor<Runtime>>(
1510+ remoteAddress, ptr, sizeof (TargetContextDescriptor<Runtime>) );
15111511 break ;
15121512 case ContextDescriptorKind::Struct:
1513- success = readFullContextDescriptor <TargetStructDescriptor<Runtime>>(
1514- remoteAddress, ptr);
1513+ success = readFullTrailingObjects <TargetStructDescriptor<Runtime>>(
1514+ remoteAddress, ptr, sizeof (TargetContextDescriptor<Runtime>) );
15151515 break ;
15161516 case ContextDescriptorKind::Protocol:
1517- success = readFullContextDescriptor <TargetProtocolDescriptor<Runtime>>(
1518- remoteAddress, ptr);
1517+ success = readFullTrailingObjects <TargetProtocolDescriptor<Runtime>>(
1518+ remoteAddress, ptr, sizeof (TargetContextDescriptor<Runtime>) );
15191519 break ;
15201520 case ContextDescriptorKind::OpaqueType:
1521- success = readFullContextDescriptor <TargetOpaqueTypeDescriptor<Runtime>>(
1522- remoteAddress, ptr);
1521+ success = readFullTrailingObjects <TargetOpaqueTypeDescriptor<Runtime>>(
1522+ remoteAddress, ptr, sizeof (TargetContextDescriptor<Runtime>) );
15231523 break ;
15241524 default :
15251525 // We don't know about this kind of context.
@@ -1535,12 +1535,18 @@ class MetadataReader {
15351535 return ContextDescriptorRef (remoteAddress, descriptor);
15361536 }
15371537
1538- template <typename DescriptorTy>
1539- bool readFullContextDescriptor (RemoteAddress address,
1540- MemoryReader::ReadBytesResult &ptr) {
1538+ // / Read all memory occupied by a value with TrailingObjects. This will
1539+ // / incrementally read pieces of the object to figure out the full size of it.
1540+ // / - address: The address of the value.
1541+ // / - ptr: The bytes that have been read so far. On return, the full object.
1542+ // / - existingByteCount: The number of bytes in ptr.
1543+ template <typename BaseTy>
1544+ bool readFullTrailingObjects (RemoteAddress address,
1545+ MemoryReader::ReadBytesResult &ptr,
1546+ size_t existingByteCount) {
15411547 // Read the full base descriptor if it's bigger than what we have so far.
1542- if (sizeof (DescriptorTy ) > sizeof (TargetContextDescriptor<Runtime>) ) {
1543- ptr = Reader->template readObj <DescriptorTy >(address);
1548+ if (sizeof (BaseTy ) > existingByteCount ) {
1549+ ptr = Reader->template readObj <BaseTy >(address);
15441550 if (!ptr)
15451551 return false ;
15461552 }
@@ -1556,13 +1562,17 @@ class MetadataReader {
15561562 // size. Once we've walked through all the trailing objects, we've read
15571563 // everything.
15581564
1559- size_t sizeSoFar = sizeof (DescriptorTy );
1565+ size_t sizeSoFar = sizeof (BaseTy );
15601566
1561- for (size_t i = 0 ; i < DescriptorTy ::trailingTypeCount (); i++) {
1562- const DescriptorTy *descriptorSoFar =
1563- reinterpret_cast <const DescriptorTy *>(ptr.get ());
1567+ for (size_t i = 0 ; i < BaseTy ::trailingTypeCount (); i++) {
1568+ const BaseTy *descriptorSoFar =
1569+ reinterpret_cast <const BaseTy *>(ptr.get ());
15641570 size_t thisSize = descriptorSoFar->sizeWithTrailingTypeCount (i);
15651571 if (thisSize > sizeSoFar) {
1572+ // Make sure we haven't ended up with a ridiculous size.
1573+ if (thisSize > MaxMetadataSize)
1574+ return false ;
1575+
15661576 ptr = Reader->readBytes (address, thisSize);
15671577 if (!ptr)
15681578 return false ;
@@ -2141,45 +2151,22 @@ class MetadataReader {
21412151
21422152 switch (getEnumeratedMetadataKind (KindValue)) {
21432153 case MetadataKind::Class:
2144-
2145- return _readMetadata<TargetClassMetadataType>(address);
2146-
2154+ return _readMetadataFixedSize<TargetClassMetadataType>(address);
21472155 case MetadataKind::Enum:
2148- return _readMetadata <TargetEnumMetadata>(address);
2156+ return _readMetadataFixedSize <TargetEnumMetadata>(address);
21492157 case MetadataKind::ErrorObject:
2150- return _readMetadata<TargetEnumMetadata>(address);
2151- case MetadataKind::Existential: {
2152- RemoteAddress flagsAddress = address + sizeof (StoredPointer);
2153-
2154- ExistentialTypeFlags::int_type flagsData;
2155- if (!Reader->readInteger (flagsAddress, &flagsData))
2156- return nullptr ;
2157-
2158- ExistentialTypeFlags flags (flagsData);
2159-
2160- RemoteAddress numProtocolsAddress = flagsAddress + sizeof (flagsData);
2161- uint32_t numProtocols;
2162- if (!Reader->readInteger (numProtocolsAddress, &numProtocols))
2163- return nullptr ;
2164-
2165- // Make sure the number of protocols is reasonable
2166- if (numProtocols >= 256 )
2167- return nullptr ;
2168-
2169- auto totalSize = sizeof (TargetExistentialTypeMetadata<Runtime>)
2170- + numProtocols *
2171- sizeof (ConstTargetMetadataPointer<Runtime, TargetProtocolDescriptor>);
2172-
2173- if (flags.hasSuperclassConstraint ())
2174- totalSize += sizeof (StoredPointer);
2175-
2176- return _readMetadata (address, totalSize);
2177- }
2158+ return _readMetadataFixedSize<TargetMetadata>(address);
2159+ case MetadataKind::Existential:
2160+ return _readMetadataVariableSize<TargetExistentialTypeMetadata>(
2161+ address);
21782162 case MetadataKind::ExistentialMetatype:
2179- return _readMetadata<TargetExistentialMetatypeMetadata>(address);
2163+ return _readMetadataFixedSize<TargetExistentialMetatypeMetadata>(
2164+ address);
21802165 case MetadataKind::ExtendedExistential: {
21812166 // We need to read the shape in order to figure out how large
2182- // the generalization arguments are.
2167+ // the generalization arguments are. This prevents us from using
2168+ // _readMetadataVariableSize, which requires the Shape field to be
2169+ // dereferenceable here.
21832170 RemoteAddress shapeAddress = address + sizeof (StoredPointer);
21842171 RemoteAddress signedShapePtr;
21852172 if (!Reader->template readRemoteAddress <StoredPointer>(shapeAddress,
@@ -2198,46 +2185,24 @@ class MetadataReader {
21982185 return _readMetadata (address, totalSize);
21992186 }
22002187 case MetadataKind::ForeignClass:
2201- return _readMetadata <TargetForeignClassMetadata>(address);
2188+ return _readMetadataFixedSize <TargetForeignClassMetadata>(address);
22022189 case MetadataKind::ForeignReferenceType:
2203- return _readMetadata<TargetForeignReferenceTypeMetadata>(address);
2204- case MetadataKind::Function: {
2205- StoredSize flagsValue;
2206- auto flagsAddr =
2207- address + TargetFunctionTypeMetadata<Runtime>::OffsetToFlags;
2208- if (!Reader->readInteger (flagsAddr, &flagsValue))
2209- return nullptr ;
2210-
2211- auto flags =
2212- TargetFunctionTypeFlags<StoredSize>::fromIntValue (flagsValue);
2213-
2214- auto totalSize =
2215- sizeof (TargetFunctionTypeMetadata<Runtime>) +
2216- flags.getNumParameters () * sizeof (FunctionTypeMetadata::Parameter);
2217-
2218- if (flags.hasParameterFlags ())
2219- totalSize += flags.getNumParameters () * sizeof (uint32_t );
2220-
2221- if (flags.isDifferentiable ())
2222- totalSize = roundUpToAlignment (totalSize, sizeof (StoredPointer)) +
2223- sizeof (TargetFunctionMetadataDifferentiabilityKind<
2224- typename Runtime::StoredSize>);
2225-
2226- return _readMetadata (address,
2227- roundUpToAlignment (totalSize, sizeof (StoredPointer)));
2228- }
2190+ return _readMetadataFixedSize<TargetForeignReferenceTypeMetadata>(
2191+ address);
2192+ case MetadataKind::Function:
2193+ return _readMetadataVariableSize<TargetFunctionTypeMetadata>(address);
22292194 case MetadataKind::HeapGenericLocalVariable:
2230- return _readMetadata <TargetGenericBoxHeapMetadata>(address);
2195+ return _readMetadataFixedSize <TargetGenericBoxHeapMetadata>(address);
22312196 case MetadataKind::HeapLocalVariable:
2232- return _readMetadata <TargetHeapLocalVariableMetadata>(address);
2197+ return _readMetadataFixedSize <TargetHeapLocalVariableMetadata>(address);
22332198 case MetadataKind::Metatype:
2234- return _readMetadata <TargetMetatypeMetadata>(address);
2199+ return _readMetadataFixedSize <TargetMetatypeMetadata>(address);
22352200 case MetadataKind::ObjCClassWrapper:
2236- return _readMetadata <TargetObjCClassWrapperMetadata>(address);
2201+ return _readMetadataFixedSize <TargetObjCClassWrapperMetadata>(address);
22372202 case MetadataKind::Optional:
2238- return _readMetadata <TargetEnumMetadata>(address);
2203+ return _readMetadataFixedSize <TargetEnumMetadata>(address);
22392204 case MetadataKind::Struct:
2240- return _readMetadata <TargetStructMetadata>(address);
2205+ return _readMetadataFixedSize <TargetStructMetadata>(address);
22412206 case MetadataKind::Tuple: {
22422207 auto numElementsAddress = address +
22432208 TargetTupleTypeMetadata<Runtime>::getOffsetToNumElements ();
@@ -2255,7 +2220,7 @@ class MetadataReader {
22552220 }
22562221 case MetadataKind::Opaque:
22572222 default :
2258- return _readMetadata <TargetOpaqueMetadata>(address);
2223+ return _readMetadataFixedSize <TargetOpaqueMetadata>(address);
22592224 }
22602225
22612226 // We can fall out here if the value wasn't actually a valid
@@ -2333,20 +2298,39 @@ class MetadataReader {
23332298
23342299private:
23352300 template <template <class R > class M >
2336- MetadataRef _readMetadata (RemoteAddress address) {
2301+ MetadataRef _readMetadataFixedSize (RemoteAddress address) {
2302+ static_assert (!ABI::typeHasTrailingObjects<M<Runtime>>(),
2303+ " Type must not have trailing objects. Use "
2304+ " _readMetadataVariableSize for types that have them." );
2305+
23372306 return _readMetadata (address, sizeof (M<Runtime>));
23382307 }
23392308
2309+ template <template <class R > class M >
2310+ MetadataRef _readMetadataVariableSize (RemoteAddress address) {
2311+ static_assert (ABI::typeHasTrailingObjects<M<Runtime>>(),
2312+ " Type must have trailing objects. Use _readMetadataFixedSize "
2313+ " for types that don't." );
2314+
2315+ MemoryReader::ReadBytesResult bytes;
2316+ auto readResult = readFullTrailingObjects<M<Runtime>>(address, bytes, 0 );
2317+ if (!readResult)
2318+ return nullptr ;
2319+ return _cacheMetadata (address, bytes);
2320+ }
2321+
23402322 MetadataRef _readMetadata (RemoteAddress address, size_t sizeAfter) {
23412323 if (sizeAfter > MaxMetadataSize)
23422324 return nullptr ;
23432325 auto readResult = Reader->readBytes (address, sizeAfter);
2344- if (! readResult)
2345- return nullptr ;
2326+ return _cacheMetadata (address, readResult);
2327+ }
23462328
2329+ MetadataRef _cacheMetadata (RemoteAddress address,
2330+ MemoryReader::ReadBytesResult &bytes) {
23472331 auto metadata =
2348- reinterpret_cast <const TargetMetadata<Runtime> *>(readResult .get ());
2349- MetadataCache.insert (std::make_pair (address, std::move (readResult )));
2332+ reinterpret_cast <const TargetMetadata<Runtime> *>(bytes .get ());
2333+ MetadataCache.insert (std::make_pair (address, std::move (bytes )));
23502334 return MetadataRef (address, metadata);
23512335 }
23522336
0 commit comments