Make breaking change to cosmo_dlsym()

The cosmo_dlsym() function now returns the raw function address. You
need to call cosmo_dltramp() on the result, to make it safe to call.
This change is important, because cosmo_dltramp() magic can't always
work; for some tricky functions, you need to translate ABIs by hand.
This commit is contained in:
Justine Tunney 2024-01-06 15:45:26 -08:00
parent f224a55d57
commit 5e7137097d
No known key found for this signature in database
GPG key ID: BE714B4575D6E328

View file

@ -774,13 +774,10 @@ static void *dlopen_silicon(const char *path, int mode) {
* WARNING: Our API uses a different naming because cosmo_dlopen() lacks
* many of the features one would reasonably expect from a UNIX dlopen()
* implementation; and we don't want to lead ./configure scripts astray.
* You're limited to 5 integral function parameters maximum. Calling an
* imported function currently goes much slower than a normal function
* call. You can't pass callback function pointers to foreign libraries
* safely. Foreign libraries also can't link symbols defined by your
* executable; that means using this for high-level language plugins is
* completely out of the question. What cosmo_dlopen() can do is help
* you talk to GPU and GUI libraries like CUDA and SDL.
* Foreign libraries also can't link symbols defined by your executable,
* which means using this for high-level language plugins is completely
* out of the question. What cosmo_dlopen() can do is help you talk to
* GPU and GUI libraries like CUDA and SDL.
*
* @param mode is a bitmask that can contain:
* - `RTLD_LOCAL` (default)
@ -818,8 +815,26 @@ void *cosmo_dlopen(const char *path, int mode) {
/**
* Obtains address of symbol from dynamic shared object.
*
* On Windows you can only use this to lookup function addresses.
* Returned functions are trampolined to conform to System V ABI.
* WARNING: You almost always want to say this:
*
* pFunction = cosmo_dltramp(cosmo_dlsym(dso, "function"));
*
* That will generate code at runtime for automatically translating to
* Microsoft's x64 calling convention when appropriate. However the
* automated solution doesn't always work. For example, the prototype:
*
* void func(int, float);
*
* Won't be translated correctly, due to the differences in ABI. We're
* able to smooth over most of them, but that's just one of several
* examples where we can't. A good rule of thumb is:
*
* - More than four float/double args is problematic
* - Having both integral and floating point parameters is bad
*
* For those kinds of functions, you need to translate the ABI by hand.
* This can be accomplished using the GCC `__ms_abi__` attribute, where
* you'd have two function pointer types branched upon `IsWindows()`.
*
* @param handle was opened by dlopen()
* @return address of symbol, or NULL w/ dlerror()
@ -829,16 +844,12 @@ void *cosmo_dlsym(void *handle, const char *name) {
if (IsWindows()) {
func = dlsym_nt(handle, name);
} else if (IsXnuSilicon()) {
if ((func = __syslib->__dlsym(handle, name))) {
func = foreign_thunk_sysv(func);
}
func = __syslib->__dlsym(handle, name);
} else if (IsXnu()) {
dlerror_set("dlopen() isn't supported on x86-64 MacOS");
func = 0;
} else if (foreign_init()) {
if ((func = __foreign.dlsym(handle, name))) {
func = foreign_thunk_sysv(func);
}
func = __foreign.dlsym(handle, name);
} else {
func = 0;
}