Skip to content

Commit 71be9f1

Browse files
committed
Add OpenBSD support for ICU library loading
OpenBSD uses ABI versioning in SONAME rather than ICU version numbering. Use unversioned dlopen calls and probe symbol versioning instead of attempting to load versioned library names.
1 parent 1547c9a commit 71be9f1

1 file changed

Lines changed: 61 additions & 2 deletions

File tree

src/native/libs/System.Globalization.Native/pal_icushim.c

Lines changed: 61 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)