@@ -32,9 +32,85 @@ using namespace swift;
3232
3333static std::atomic<bool > disablePrespecializedMetadata = false ;
3434
35+ static bool prespecializedLoggingEnabled = false ;
36+
37+ #define LOG (fmt, ...) \
38+ do { \
39+ if (SWIFT_UNLIKELY (prespecializedLoggingEnabled)) \
40+ fprintf (stderr, " Prespecializations library: " fmt " \n " , __VA_ARGS__); \
41+ } while (0 )
42+
43+ static bool environmentProcessListContainsProcess (const char *list,
44+ const char *progname) {
45+ auto prognameLen = strlen (progname);
46+
47+ const char *cursor = list;
48+ while (true ) {
49+ const char *next = strchr (cursor, ' :' );
50+ if (!next) {
51+ // Last entry in the list. Compare with the entire rest of the string.
52+ return strcmp (progname, cursor) == 0 ;
53+ }
54+
55+ // Entry at beginning or middle of the list. Compare against this substring.
56+ size_t len = next - cursor;
57+ if (len == prognameLen && strncmp (cursor, progname, len) == 0 )
58+ return true ;
59+
60+ cursor = next + 1 ;
61+ }
62+ }
63+
64+ static bool isThisProcessEnabled (const LibPrespecializedData<InProcess> *data) {
65+ extern const char *__progname;
66+
67+ if (!__progname)
68+ return true ;
69+
70+ auto envEnabledProcesses =
71+ runtime::environment::SWIFT_DEBUG_LIB_PRESPECIALIZED_ENABLED_PROCESSES ();
72+ if (envEnabledProcesses && *envEnabledProcesses) {
73+ if (environmentProcessListContainsProcess (envEnabledProcesses,
74+ __progname)) {
75+ LOG (" Found %s in SWIFT_DEBUG_LIB_PRESPECIALIZED_ENABLED_PROCESSES, "
76+ " enabling" ,
77+ __progname);
78+ return true ;
79+ }
80+ }
81+
82+ auto envDisabledProcesses =
83+ runtime::environment::SWIFT_DEBUG_LIB_PRESPECIALIZED_DISABLED_PROCESSES ();
84+ if (envDisabledProcesses && *envDisabledProcesses) {
85+ if (environmentProcessListContainsProcess (envDisabledProcesses,
86+ __progname)) {
87+ LOG (" Found %s in SWIFT_DEBUG_LIB_PRESPECIALIZED_DISABLED_PROCESSES, "
88+ " disabling" ,
89+ __progname);
90+ return false ;
91+ }
92+ }
93+
94+ if (auto *disabledProcesses = data->getDisabledProcessesTable ()) {
95+ auto *cursor = disabledProcesses;
96+ while (auto *name = *cursor) {
97+ if (strcmp (name, __progname) == 0 ) {
98+ LOG (" Found %s in disabled processes list, disabling" , name);
99+ return false ;
100+ }
101+ cursor++;
102+ }
103+ }
104+
105+ return true ;
106+ }
107+
35108static const LibPrespecializedData<InProcess> *findLibPrespecialized () {
36- if (!runtime::environment::SWIFT_DEBUG_ENABLE_LIB_PRESPECIALIZED ())
109+ if (!runtime::environment::SWIFT_DEBUG_ENABLE_LIB_PRESPECIALIZED ()) {
110+ LOG (" Disabling, SWIFT_DEBUG_ENABLE_LIB_PRESPECIALIZED = %d" ,
111+ runtime::environment::SWIFT_DEBUG_ENABLE_LIB_PRESPECIALIZED ());
37112 return nullptr ;
113+ }
38114
39115 const void *dataPtr = nullptr ;
40116#if USE_DLOPEN
@@ -51,15 +127,22 @@ static const LibPrespecializedData<InProcess> *findLibPrespecialized() {
51127 }
52128
53129 dataPtr = dlsym (handle, LIB_PRESPECIALIZED_TOP_LEVEL_SYMBOL_NAME);
130+ LOG (" Loaded custom library from %s, found dataPtr %p" , path, dataPtr);
54131 }
55132#if DYLD_GET_SWIFT_PRESPECIALIZED_DATA_DEFINED
56133 else if (SWIFT_RUNTIME_WEAK_CHECK (_dyld_get_swift_prespecialized_data)) {
57134 // Disable the prespecializations library if anything in the shared cache is
58135 // overridden. Eventually we want to be cleverer and only disable the
59136 // prespecializations that have been invalidated, but we'll start with the
60137 // simplest approach.
61- if (!dyld_shared_cache_some_image_overridden ())
138+ if (!dyld_shared_cache_some_image_overridden ()) {
62139 dataPtr = SWIFT_RUNTIME_WEAK_USE (_dyld_get_swift_prespecialized_data ());
140+ LOG (" Got dataPtr %p from _dyld_get_swift_prespecialized_data" , dataPtr);
141+ } else {
142+ LOG (" Not calling _dyld_get_swift_prespecialized_data "
143+ " dyld_shared_cache_some_image_overridden = %d" ,
144+ dyld_shared_cache_some_image_overridden ());
145+ }
63146 }
64147#endif
65148#endif
@@ -70,8 +153,16 @@ static const LibPrespecializedData<InProcess> *findLibPrespecialized() {
70153 auto *data =
71154 reinterpret_cast <const LibPrespecializedData<InProcess> *>(dataPtr);
72155 if (data->majorVersion !=
73- LibPrespecializedData<InProcess>::currentMajorVersion)
156+ LibPrespecializedData<InProcess>::currentMajorVersion) {
157+ LOG (" Unknown major version %" PRIu32 " , disabling" , data->majorVersion );
74158 return nullptr ;
159+ }
160+
161+ if (!isThisProcessEnabled (data))
162+ return nullptr ;
163+
164+ LOG (" Returning data %p, major version %" PRIu32 " minor %" PRIu32, data,
165+ data->majorVersion , data->minorVersion );
75166
76167 return data;
77168}
@@ -85,13 +176,12 @@ struct LibPrespecializedState {
85176 }
86177 };
87178
88- bool loggingEnabled;
89179 const LibPrespecializedData<InProcess> *data;
90180 AddressRange sharedCacheRange{0 , 0 };
91181 AddressRange metadataAllocatorInitialPoolRange{0 , 0 };
92182
93183 LibPrespecializedState () {
94- loggingEnabled =
184+ prespecializedLoggingEnabled =
95185 runtime::environment::SWIFT_DEBUG_ENABLE_LIB_PRESPECIALIZED_LOGGING ();
96186 data = findLibPrespecialized ();
97187
@@ -112,12 +202,6 @@ struct LibPrespecializedState {
112202
113203static Lazy<LibPrespecializedState> LibPrespecialized;
114204
115- #define LOG (fmt, ...) \
116- do { \
117- if (SWIFT_UNLIKELY (prespecialized.loggingEnabled )) \
118- fprintf (stderr, " Prespecializations library: " fmt " \n " , __VA_ARGS__); \
119- } while (0 )
120-
121205const LibPrespecializedData<InProcess> *swift::getLibPrespecializedData () {
122206 return SWIFT_LAZY_CONSTANT (findLibPrespecialized ());
123207}
0 commit comments