Skip to content

Commit e06c978

Browse files
committed
[Runtime] NULL/availability check shared cache calls.
Avoid a dynamic linker failure if the calls aren't available at runtime. rdar://74965969
1 parent 109a33c commit e06c978

File tree

1 file changed

+51
-40
lines changed

1 file changed

+51
-40
lines changed

stdlib/public/runtime/ProtocolConformance.cpp

Lines changed: 51 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -291,29 +291,39 @@ struct ConformanceState {
291291
auto uintPtr = reinterpret_cast<uintptr_t>(ptr);
292292
return dyldSharedCacheStart <= uintPtr && uintPtr < dyldSharedCacheEnd;
293293
}
294+
295+
bool sharedCacheOptimizationsActive() { return dyldSharedCacheStart != 0; }
296+
#else
297+
bool sharedCacheOptimizationsActive() { return false; }
294298
#endif
295299

296300
ConformanceState() {
297301
scanSectionsBackwards =
298302
runtime::bincompat::workaroundProtocolConformanceReverseIteration();
299303

300304
#if USE_DYLD_SHARED_CACHE_CONFORMANCE_TABLES
301-
if (_dyld_swift_optimizations_version() ==
302-
DYLD_EXPECTED_SWIFT_OPTIMIZATIONS_VERSION) {
303-
size_t length;
304-
dyldSharedCacheStart = (uintptr_t)_dyld_get_shared_cache_range(&length);
305-
dyldSharedCacheEnd =
306-
dyldSharedCacheStart ? dyldSharedCacheStart + length : 0;
307-
validateSharedCacheResults = runtime::environment::
308-
SWIFT_DEBUG_VALIDATE_SHARED_CACHE_PROTOCOL_CONFORMANCES();
309-
SHARED_CACHE_LOG("Shared cache range is %#lx-%#lx", dyldSharedCacheStart,
310-
dyldSharedCacheEnd);
311-
} else {
312-
SHARED_CACHE_LOG("Disabling shared cache optimizations due to unknown "
313-
"optimizations version %u",
314-
_dyld_swift_optimizations_version());
315-
dyldSharedCacheStart = 0;
316-
dyldSharedCacheEnd = 0;
305+
if (__builtin_available(macOS 9999, iOS 9999, tvOS 9999, watchOS 9999, *)) {
306+
if (&_dyld_swift_optimizations_version) {
307+
if (_dyld_swift_optimizations_version() ==
308+
DYLD_EXPECTED_SWIFT_OPTIMIZATIONS_VERSION) {
309+
size_t length;
310+
dyldSharedCacheStart =
311+
(uintptr_t)_dyld_get_shared_cache_range(&length);
312+
dyldSharedCacheEnd =
313+
dyldSharedCacheStart ? dyldSharedCacheStart + length : 0;
314+
validateSharedCacheResults = runtime::environment::
315+
SWIFT_DEBUG_VALIDATE_SHARED_CACHE_PROTOCOL_CONFORMANCES();
316+
SHARED_CACHE_LOG("Shared cache range is %#lx-%#lx",
317+
dyldSharedCacheStart, dyldSharedCacheEnd);
318+
} else {
319+
SHARED_CACHE_LOG(
320+
"Disabling shared cache optimizations due to unknown "
321+
"optimizations version %u",
322+
_dyld_swift_optimizations_version());
323+
dyldSharedCacheStart = 0;
324+
dyldSharedCacheEnd = 0;
325+
}
326+
}
317327
}
318328
#endif
319329

@@ -570,7 +580,7 @@ static void validateSharedCacheResults(
570580
const WitnessTable *dyldCachedWitnessTable,
571581
const ProtocolConformanceDescriptor *dyldCachedConformanceDescriptor) {
572582
#if USE_DYLD_SHARED_CACHE_CONFORMANCE_TABLES
573-
if (!C.validateSharedCacheResults)
583+
if (!C.sharedCacheOptimizationsActive() || !C.validateSharedCacheResults)
574584
return;
575585

576586
llvm::SmallVector<const ProtocolConformanceDescriptor *, 8> conformances;
@@ -726,29 +736,30 @@ swift_conformsToProtocolImpl(const Metadata *const type,
726736

727737
// Search the shared cache tables for a conformance for this type, and for
728738
// superclasses (if it's a class).
729-
const Metadata *dyldSearchType = type;
730-
do {
731-
bool definitiveFailure;
732-
std::tie(dyldCachedWitnessTable, dyldCachedConformanceDescriptor,
733-
definitiveFailure) =
734-
findSharedCacheConformance(C, dyldSearchType, protocol);
735-
736-
if (definitiveFailure)
737-
return nullptr;
738-
739-
dyldSearchType = _swift_class_getSuperclass(dyldSearchType);
740-
} while (dyldSearchType && !dyldCachedWitnessTable &&
741-
!dyldCachedConformanceDescriptor);
742-
743-
validateSharedCacheResults(C, type, protocol, dyldCachedWitnessTable,
744-
dyldCachedConformanceDescriptor);
745-
746-
// Return a cached result if we got a witness table. We can't do this if
747-
// scanSectionsBackwards is set, since a scanned conformance can override a
748-
// cached result in that case.
749-
if (!C.scanSectionsBackwards)
750-
if (dyldCachedWitnessTable)
751-
return dyldCachedWitnessTable;
739+
if (C.sharedCacheOptimizationsActive()) {
740+
const Metadata *dyldSearchType = type;
741+
do {
742+
bool definitiveFailure;
743+
std::tie(dyldCachedWitnessTable, dyldCachedConformanceDescriptor,
744+
definitiveFailure) =
745+
findSharedCacheConformance(C, dyldSearchType, protocol);
746+
747+
if (definitiveFailure)
748+
return nullptr;
749+
750+
dyldSearchType = _swift_class_getSuperclass(dyldSearchType);
751+
} while (dyldSearchType && !dyldCachedWitnessTable &&
752+
!dyldCachedConformanceDescriptor);
753+
754+
validateSharedCacheResults(C, type, protocol, dyldCachedWitnessTable,
755+
dyldCachedConformanceDescriptor);
756+
// Return a cached result if we got a witness table. We can't do this if
757+
// scanSectionsBackwards is set, since a scanned conformance can override a
758+
// cached result in that case.
759+
if (!C.scanSectionsBackwards)
760+
if (dyldCachedWitnessTable)
761+
return dyldCachedWitnessTable;
762+
}
752763

753764
// See if we have an authoritative cached conformance. The
754765
// ConcurrentReadableHashMap data structure allows us to search the map

0 commit comments

Comments
 (0)