]>
Commit | Line | Data |
---|---|---|
4ed5ab9d JK |
1 | |
2 | # HG changeset patch | |
3 | # User Ryan C. Gordon <icculus@icculus.org> | |
4 | # Date 1526575846 14400 | |
5 | # Node ID 7babfecee045fac18d95e5936fede534ca54ed24 | |
6 | # Parent 9e46f3dd75fd2e85e0e3ebb8a77329bc74a16e70 | |
7 | dynapi: don't let system loader resolve the initializer to the wrong version. | |
8 | ||
9 | Fixes problems launching Firewatch on Linux (which statically links SDL but | |
10 | also dynamically loads a system-wide copy from a plugin shared library) with | |
11 | a newer SDL build. | |
12 | ||
13 | diff -r 9e46f3dd75fd -r 7babfecee045 src/dynapi/SDL_dynapi.c | |
14 | --- a/src/dynapi/SDL_dynapi.c Fri May 11 09:37:00 2018 +0300 | |
15 | +++ b/src/dynapi/SDL_dynapi.c Thu May 17 12:50:46 2018 -0400 | |
16 | @@ -167,15 +167,10 @@ | |
17 | #error Write me. | |
18 | #endif | |
19 | ||
20 | - | |
21 | - | |
22 | -/* Here's the exported entry point that fills in the jump table. */ | |
23 | -/* Use specific types when an "int" might suffice to keep this sane. */ | |
24 | -typedef Sint32 (SDLCALL *SDL_DYNAPI_ENTRYFN)(Uint32 apiver, void *table, Uint32 tablesize); | |
25 | -extern DECLSPEC Sint32 SDLCALL SDL_DYNAPI_entry(Uint32, void *, Uint32); | |
26 | - | |
27 | -Sint32 | |
28 | -SDL_DYNAPI_entry(Uint32 apiver, void *table, Uint32 tablesize) | |
29 | +/* we make this a static function so we can call the correct one without the | |
30 | + system's dynamic linker resolving to the wrong version of this. */ | |
31 | +static Sint32 | |
32 | +initialize_jumptable(Uint32 apiver, void *table, Uint32 tablesize) | |
33 | { | |
34 | SDL_DYNAPI_jump_table *output_jump_table = (SDL_DYNAPI_jump_table *) table; | |
35 | ||
36 | @@ -202,6 +197,18 @@ | |
37 | } | |
38 | ||
39 | ||
40 | +/* Here's the exported entry point that fills in the jump table. */ | |
41 | +/* Use specific types when an "int" might suffice to keep this sane. */ | |
42 | +typedef Sint32 (SDLCALL *SDL_DYNAPI_ENTRYFN)(Uint32 apiver, void *table, Uint32 tablesize); | |
43 | +extern DECLSPEC Sint32 SDLCALL SDL_DYNAPI_entry(Uint32, void *, Uint32); | |
44 | + | |
45 | +Sint32 | |
46 | +SDL_DYNAPI_entry(Uint32 apiver, void *table, Uint32 tablesize) | |
47 | +{ | |
48 | + return initialize_jumptable(apiver, table, tablesize); | |
49 | +} | |
50 | + | |
51 | + | |
52 | /* Obviously we can't use SDL_LoadObject() to load SDL. :) */ | |
53 | /* Also obviously, we never close the loaded library. */ | |
54 | #if defined(WIN32) || defined(_WIN32) || defined(__CYGWIN__) | |
55 | @@ -260,7 +267,7 @@ | |
56 | SDL_InitDynamicAPILocked(void) | |
57 | { | |
58 | const char *libname = SDL_getenv_REAL("SDL_DYNAMIC_API"); | |
59 | - SDL_DYNAPI_ENTRYFN entry = SDL_DYNAPI_entry; /* funcs from here by default. */ | |
60 | + SDL_DYNAPI_ENTRYFN entry = NULL; /* funcs from here by default. */ | |
61 | ||
62 | if (libname) { | |
63 | entry = (SDL_DYNAPI_ENTRYFN) get_sdlapi_entry(libname, "SDL_DYNAPI_entry"); | |
64 | @@ -268,16 +275,15 @@ | |
65 | /* !!! FIXME: fail to startup here instead? */ | |
66 | /* !!! FIXME: definitely warn user. */ | |
67 | /* Just fill in the function pointers from this library. */ | |
68 | - entry = SDL_DYNAPI_entry; | |
69 | } | |
70 | } | |
71 | ||
72 | - if (entry(SDL_DYNAPI_VERSION, &jump_table, sizeof (jump_table)) < 0) { | |
73 | + if (!entry || (entry(SDL_DYNAPI_VERSION, &jump_table, sizeof (jump_table)) < 0)) { | |
74 | /* !!! FIXME: fail to startup here instead? */ | |
75 | /* !!! FIXME: definitely warn user. */ | |
76 | /* Just fill in the function pointers from this library. */ | |
77 | - if (entry != SDL_DYNAPI_entry) { | |
78 | - if (!SDL_DYNAPI_entry(SDL_DYNAPI_VERSION, &jump_table, sizeof (jump_table))) { | |
79 | + if (!entry) { | |
80 | + if (!initialize_jumptable(SDL_DYNAPI_VERSION, &jump_table, sizeof (jump_table))) { | |
81 | /* !!! FIXME: now we're screwed. Should definitely abort now. */ | |
82 | } | |
83 | } | |
84 |