mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-03-03 07:29:23 +00:00
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:
parent
f224a55d57
commit
5e7137097d
1 changed files with 26 additions and 15 deletions
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue