Rename dlopen() to cosmo_dlopen()

This commit is contained in:
Justine Tunney 2023-11-12 01:19:04 -08:00
parent c6d3802d3a
commit bd56a9cf51
No known key found for this signature in database
GPG key ID: BE714B4575D6E328
4 changed files with 81 additions and 10 deletions

View file

@ -17,7 +17,7 @@
/**
* @fileoverview cosmopolitan dynamic runtime linking demo
*
* Our dlopen() interface currently supports:
* Our cosmo_dlopen() interface currently supports:
*
* - x86-64 Linux w/ Glibc
* - x86-64 Linux w/ Musl Libc
@ -31,16 +31,16 @@
int main(int argc, char **argv, char **envp) {
// open the host system's zlib library
void *libc = dlopen("libz.so", RTLD_LAZY);
void *libc = cosmo_dlopen("libz.so", RTLD_LAZY);
if (!libc) {
tinyprint(2, dlerror(), "\n", NULL);
tinyprint(2, cosmo_dlerror(), "\n", NULL);
exit(1);
}
// load crc() function address
unsigned (*crc32)(unsigned, void *, int) = dlsym(libc, "crc32");
unsigned (*crc32)(unsigned, void *, int) = cosmo_dlsym(libc, "crc32");
if (!crc32) {
tinyprint(2, dlerror(), "\n", NULL);
tinyprint(2, cosmo_dlerror(), "\n", NULL);
exit(1);
}
@ -50,6 +50,6 @@ int main(int argc, char **argv, char **envp) {
tinyprint(1, "crc(hi) = ", ibuf, "\n", NULL);
// mop up
dlclose(libc);
cosmo_dlclose(libc);
exit(0);
}

View file

@ -18,6 +18,14 @@ void *dlsym(void *, const char *);
int dlclose(void *);
int dl_iterate_phdr(int (*)(void *, size_t, void *), void *);
#ifdef _COSMO_SOURCE
char *cosmo_dlerror(void);
void *cosmo_dlopen(const char *, int);
void *cosmo_dlsym(void *, const char *);
int cosmo_dlclose(void *);
int cosmo_dl_iterate_phdr(int (*)(void *, size_t, void *), void *);
#endif
COSMOPOLITAN_C_END_
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
#endif /* COSMOPOLITAN_LIBC_DLFCN_H_ */

View file

@ -19,6 +19,7 @@
#include "libc/atomic.h"
#include "libc/calls/calls.h"
#include "libc/calls/internal.h"
#include "libc/calls/struct/sigset.internal.h"
#include "libc/calls/syscall-sysv.internal.h"
#include "libc/calls/syscall_support-nt.internal.h"
#include "libc/cosmo.h"
@ -77,6 +78,7 @@ __static_yoink(".dlopen.aarch64.glibc.elf");
#define BEGIN_FOREIGN \
{ \
BLOCK_SIGNALS; \
struct CosmoTib *cosmo_tib = __get_tls(); \
pthread_mutex_lock(&foreign.lock); \
__set_tls(foreign.tib)
@ -84,6 +86,7 @@ __static_yoink(".dlopen.aarch64.glibc.elf");
#define END_FOREIGN \
__set_tls(cosmo_tib); \
pthread_mutex_unlock(&foreign.lock); \
ALLOW_SIGNALS; \
}
struct loaded {
@ -478,6 +481,27 @@ static void *dlopen_silicon(const char *path, int mode) {
* this wrapper will automatically change it to `.dll` or `.dylib` to
* increase its chance of successfully loading.
*
* WARNING: This isn't supported on MacOS x86-64, OpenBSD, and NetBSD.
*
* WARNING: This dlopen() implementation is highly limited. Cosmo
* binaries are always statically linked. You can import functions from
* dynamic shared objects, but you can't export any. This dlopen() won't
* work for language plugins, but might help you access GUI and GPU DRM.
*
* WARNING: Do not expect this dlopen() is in any way safe to use. It's
* mostly due to thread local storage. On Windows it should be safe. On
* Apple Silicon it should be safe so long as foreign functions don't
* issue callbacks. On libre OSes we currently only make dlopen() APIs
* safe to use. In order for it to be safe, four system calls need to be
* issued for every dlopen() related API call, and that's assuming this
* API is only used from the main of your program. Most importantly
* there are no safeguards added around imported functions, since it'd
* make them go 1000x slower. It's the responsibility of the caller to
* ensure that imported functions never touch TLS, don't install signal
* handlers, will never spawn threads, and don't issue callbacks. Care
* should also be taken on all platforms, to ensure dynamic memory is
* being passed to the correct malloc() and free() implementations.
*
* @param mode is a bitmask that can contain:
* - `RTLD_LOCAL` (default)
* - `RTLD_GLOBAL` (not supported on Windows)
@ -485,7 +509,7 @@ static void *dlopen_silicon(const char *path, int mode) {
* - `RTLD_NOW`
* @return dso handle, or NULL w/ dlerror()
*/
void *dlopen(const char *path, int mode) {
void *cosmo_dlopen(const char *path, int mode) {
void *res;
if (IsWindows()) {
res = dlopen_nt(path, mode);
@ -514,7 +538,7 @@ void *dlopen(const char *path, int mode) {
* @param handle was opened by dlopen()
* @return address of symbol, or NULL w/ dlerror()
*/
void *dlsym(void *handle, const char *name) {
void *cosmo_dlsym(void *handle, const char *name) {
void *res;
if (IsWindows()) {
res = dlsym_nt(handle, name);
@ -540,7 +564,7 @@ void *dlsym(void *handle, const char *name) {
* @param handle was opened by dlopen()
* @return 0 on success, or -1 w/ dlerror()
*/
int dlclose(void *handle) {
int cosmo_dlclose(void *handle) {
int res;
if (IsWindows()) {
res = dlclose_nt(handle);
@ -563,7 +587,7 @@ int dlclose(void *handle) {
/**
* Returns string describing last dlopen/dlsym/dlclose error.
*/
char *dlerror(void) {
char *cosmo_dlerror(void) {
char *res;
if (IsXnuSilicon()) {
res = __syslib->__dlerror();

39
libc/dlopen/stubs.c Normal file
View file

@ -0,0 +1,39 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2023 Justine Alexandra Roberts Tunney
Permission to use, copy, modify, and/or distribute this software for
any purpose with or without fee is hereby granted, provided that the
above copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/dlopen/dlfcn.h"
char *dlerror(void) {
return "dlopen() isn't supported by cosmo";
}
void *dlopen(const char *, int) {
return 0;
}
void *dlsym(void *, const char *) {
return 0;
}
int dlclose(void *) {
return -1;
}
int dl_iterate_phdr(int (*)(void *, size_t, void *), void *) {
return -1;
}