From 9f8b3ddf1c0e9066c0e70d6b08409ba748337c25 Mon Sep 17 00:00:00 2001
From: Ozkan Sezer <[EMAIL REDACTED]>
Date: Sat, 22 Oct 2022 17:56:10 +0300
Subject: [PATCH] os2 loadso improvements:
- SDL_LoadObject: upon failure, strip the .dll extension and retry,
but only if module name has no path.
- SDL_LoadFunction: upon failure, retry with an underscore prepended,
e.g. for gcc-built dlls.
- General tidy-up.
---
src/loadso/os2/SDL_sysloadso.c | 55 +++++++++++++++++++++++-----------
1 file changed, 38 insertions(+), 17 deletions(-)
diff --git a/src/loadso/os2/SDL_sysloadso.c b/src/loadso/os2/SDL_sysloadso.c
index c2d991175..6830b0536 100644
--- a/src/loadso/os2/SDL_sysloadso.c
+++ b/src/loadso/os2/SDL_sysloadso.c
@@ -36,37 +36,58 @@
void *SDL_LoadObject(const char *sofile)
{
HMODULE handle = NULLHANDLE;
- char buf[512];
+ char buf[256];
APIRET ulrc = DosLoadModule(buf, sizeof (buf), (char *) sofile, &handle);
+ if (ulrc != NO_ERROR && !SDL_strrchr(sofile, '\\') && !SDL_strrchr(sofile, '/')) {
+ /* strip .dll extension and retry only if name has no path. */
+ size_t len = SDL_strlen(sofile);
+ if (len > 4 && SDL_strcasecmp(&sofile[len - 4], ".dll") == 0) {
+ char *ptr = SDL_stack_alloc(char, len);
+ SDL_memcpy(ptr, sofile, len);
+ ptr[len-4] = '\0';
+ ulrc = DosLoadModule(buf, sizeof (buf), ptr, &handle);
+ SDL_stack_free(ptr);
+ }
+ }
+
/* Generate an error message if all loads failed */
- if ((ulrc != NO_ERROR) || (handle == NULLHANDLE))
+ if (ulrc != NO_ERROR) {
SDL_SetError("Failed loading %s: %s", sofile, buf);
+ handle = NULLHANDLE;
+ }
- return((void *) handle);
+ return (void *)handle;
}
void *SDL_LoadFunction(void *handle, const char *name)
{
- const char *loaderror = "Unknown error";
PFN symbol = NULL;
- APIRET ulrc = DosQueryProcAddr((HMODULE)handle, 0, (char *)name, &symbol);
-
- if (ulrc == ERROR_INVALID_HANDLE)
- loaderror = "Invalid module handle";
- else if (ulrc == ERROR_INVALID_NAME)
- loaderror = "Symbol not found";
-
- if (symbol == NULL)
- SDL_SetError("Failed loading %s: %s", name, loaderror);
-
- return((void *) symbol);
+ APIRET ulrc = DosQueryProcAddr((HMODULE)handle, 0, name, &symbol);
+
+ if (ulrc != NO_ERROR) {
+ /* retry with an underscore prepended, e.g. for gcc-built dlls. */
+ size_t len = SDL_strlen(name) + 1;
+ char *_name = SDL_stack_alloc(char, len + 1);
+ _name[0] = '_';
+ SDL_memcpy(&_name[1], name, len);
+ ulrc = DosQueryProcAddr((HMODULE)handle, 0, _name, &symbol);
+ SDL_stack_free(_name);
+ }
+
+ if (ulrc != NO_ERROR) {
+ SDL_SetError("Failed loading procedure %s (E%u)", name, ulrc);
+ symbol = NULL;
+ }
+
+ return (void *)symbol;
}
void SDL_UnloadObject(void *handle)
{
- if ( handle != NULL )
- DosFreeModule((HMODULE) handle);
+ if (handle != NULL) {
+ DosFreeModule((HMODULE)handle);
+ }
}
#endif /* SDL_LOADSO_OS2 */