@@ -230,7 +230,35 @@ static int FindICULibs(char* symbolName, char* symbolVersion)
230230 return false;
231231}
232232
233- #else // !TARGET_WINDOWS && !TARGET_OSX && !TARGET_ANDROID
233+ #elif defined(TARGET_OPENBSD )
234+
235+ // OpenBSD uses ABI versioning in SONAME, not ICU version. Use unversioned dlopen.
236+ static int FindICULibs (char * symbolName , char * symbolVersion )
237+ {
238+ libicuuc = dlopen ("libicuuc.so" , RTLD_LAZY );
239+ if (libicuuc == NULL )
240+ return false;
241+
242+ libicui18n = dlopen ("libicui18n.so" , RTLD_LAZY );
243+ if (libicui18n == NULL )
244+ {
245+ dlclose (libicuuc );
246+ libicuuc = NULL ;
247+ return false;
248+ }
249+
250+ char symbolSuffix [SYMBOL_CUSTOM_SUFFIX_SIZE ]= "" ;
251+ if (FindSymbolVersion (-1 , -1 , -1 , symbolName , symbolVersion , MaxICUVersionStringLength , symbolSuffix ))
252+ return true;
253+
254+ dlclose (libicuuc );
255+ dlclose (libicui18n );
256+ libicuuc = NULL ;
257+ libicui18n = NULL ;
258+ return false;
259+ }
260+
261+ #else // !TARGET_WINDOWS && !TARGET_OSX && !TARGET_ANDROID && !TARGET_OPENBSD
234262
235263// Version ranges to search for each of the three version components
236264// The rationale for major version range is that we support versions higher or
@@ -442,6 +470,35 @@ static void InitializeUColClonePointers(char* symbolVersion)
442470 }
443471}
444472
473+ static void InitializeVariableMaxAndTopPointers (char * symbolVersion )
474+ {
475+ if (ucol_setMaxVariable_ptr != NULL )
476+ {
477+ return ;
478+ }
479+
480+ #if defined(TARGET_OSX ) || defined(TARGET_ANDROID )
481+ // OSX and Android always run against ICU version which has ucol_setMaxVariable.
482+ // We shouldn't come here.
483+ (void )symbolVersion ;
484+ assert (false);
485+ #elif defined(TARGET_WINDOWS )
486+ char symbolName [SYMBOL_NAME_SIZE ];
487+ sprintf_s (symbolName , SYMBOL_NAME_SIZE , "ucol_setVariableTop%s" , symbolVersion );
488+ ucol_setVariableTop_ptr = (ucol_setVariableTop_func )GetProcAddress ((HMODULE )libicui18n , symbolName );
489+ #else
490+ char symbolName [SYMBOL_NAME_SIZE ];
491+ snprintf (symbolName , SYMBOL_NAME_SIZE , "ucol_setVariableTop%s" , symbolVersion );
492+ ucol_setVariableTop_ptr = (ucol_setVariableTop_func )dlsym (libicui18n , symbolName );
493+ #endif // defined(TARGET_OSX) || defined(TARGET_ANDROID)
494+
495+ if (ucol_setVariableTop_ptr == NULL )
496+ {
497+ fprintf (stderr , "Cannot get the symbols of ICU APIs ucol_setMaxVariable or ucol_setVariableTop.\n" );
498+ abort ();
499+ }
500+ }
501+
445502// GlobalizationNative_LoadICU
446503// This method get called from the managed side during the globalization initialization.
447504// This method shouldn't get called at all if we are running in globalization invariant mode
@@ -458,7 +515,7 @@ int32_t GlobalizationNative_LoadICU(void)
458515 return false;
459516 }
460517
461- #elif defined(TARGET_ANDROID )
518+ #elif defined(TARGET_ANDROID ) || defined( TARGET_OPENBSD )
462519 if (!FindICULibs (symbolName , symbolVersion ))
463520 {
464521 return false;
@@ -479,6 +536,7 @@ int32_t GlobalizationNative_LoadICU(void)
479536 FOR_ALL_ICU_FUNCTIONS
480537 ValidateICUDataCanLoad ();
481538
539+ InitializeVariableMaxAndTopPointers (symbolVersion );
482540 InitializeUColClonePointers (symbolVersion );
483541
484542 return true;
@@ -535,6 +593,7 @@ void GlobalizationNative_InitICUFunctions(void* icuuc, void* icuin, const char*
535593 FOR_ALL_ICU_FUNCTIONS
536594 ValidateICUDataCanLoad ();
537595
596+ InitializeVariableMaxAndTopPointers (symbolVersion );
538597 InitializeUColClonePointers (symbolVersion );
539598}
540599
0 commit comments