Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
87 changes: 33 additions & 54 deletions system/lib/libc/dynlink.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,12 @@

//#define DYLINK_DEBUG

#ifdef DYLINK_DEBUG
#define dbg(fmt, ...) _emscripten_errf("%p: " fmt, pthread_self(), ##__VA_ARGS__)
#else
#define dbg(fmt, ...)
#endif

struct async_data {
em_dlopen_callback onsuccess;
em_arg_callback_func onerror;
Expand Down Expand Up @@ -66,16 +72,13 @@ int __dl_invalid_handle(void* h) {
}

static void load_library_done(struct dso* p) {
#ifdef DYLINK_DEBUG
_emscripten_errf("%p: load_library_done: dso=%p mem_addr=%p mem_size=%zu "
"table_addr=%p table_size=%zu",
pthread_self(),
p,
p->mem_addr,
p->mem_size,
p->table_addr,
p->table_size);
#endif
dbg("load_library_done: dso=%p mem_addr=%p mem_size=%zu "
"table_addr=%p table_size=%zu",
p,
p->mem_addr,
p->mem_size,
p->table_addr,
p->table_size);

// insert into linked list
p->prev = tail;
Expand Down Expand Up @@ -106,23 +109,18 @@ static struct dso* load_library_start(const char* name, int flags) {
}

static void dlopen_js_onsuccess(struct dso* dso, struct async_data* data) {
#ifdef DYLINK_DEBUG
_emscripten_errf("%p: dlopen_js_onsuccess: dso=%p mem_addr=%p mem_size=%zu",
pthread_self(),
dso,
dso->mem_addr,
dso->mem_size);
#endif
dbg("dlopen_js_onsuccess: dso=%p mem_addr=%p mem_size=%zu",
dso,
dso->mem_addr,
dso->mem_size);
load_library_done(dso);
pthread_rwlock_unlock(&lock);
data->onsuccess(data->user_data, dso);
free(data);
}

static void dlopen_js_onerror(struct dso* dso, struct async_data* data) {
#ifdef DYLINK_DEBUG
_emscripten_errf("%p: dlopen_js_onerror: dso=%p", pthread_self(), dso);
#endif
dbg("dlopen_js_onerror: dso=%p", dso);
pthread_rwlock_unlock(&lock);
data->onerror(data->user_data);
free(dso);
Expand Down Expand Up @@ -153,9 +151,7 @@ void* dlopen(const char* file, int flags) {
if (!file) {
return head;
}
#ifdef DYLINK_DEBUG
_emscripten_errf("%p: dlopen: %s [%d]", pthread_self(), file, flags);
#endif
dbg("dlopen: %s [%d]", file, flags);

struct dso* p;
int cs;
Expand All @@ -165,9 +161,7 @@ void* dlopen(const char* file, int flags) {
/* Search for the name to see if it's already loaded */
for (p = head; p; p = p->next) {
if (!strcmp(p->name, file)) {
#ifdef DYLINK_DEBUG
_emscripten_errf("%p: dlopen: already opened: %p", pthread_self(), p);
#endif
dbg("dlopen: already opened: %p", p);
goto end;
}
}
Expand All @@ -178,16 +172,12 @@ void* dlopen(const char* file, int flags) {
}
void* success = _dlopen_js(p);
if (!success) {
#ifdef DYLINK_DEBUG
_emscripten_errf("%p: dlopen_js: failed: %p", pthread_self(), p);
#endif
dbg("dlopen_js: failed: %p", p);
free(p);
p = NULL;
goto end;
}
#ifdef DYLINK_DEBUG
_emscripten_errf("%p: dlopen_js: success: %p", pthread_self(), p);
#endif
dbg("dlopen_js: success: %p", p);
load_library_done(p);
end:
pthread_rwlock_unlock(&lock);
Expand Down Expand Up @@ -216,17 +206,13 @@ void emscripten_dlopen(const char* filename, int flags, void* user_data,
d->onsuccess = onsuccess;
d->onerror = onerror;

#ifdef DYLINK_DEBUG
_emscripten_errf("%p: calling emscripten_dlopen_js %p", pthread_self(), p);
#endif
dbg("calling emscripten_dlopen_js %p", p);
// Unlock happens in dlopen_js_onsuccess/dlopen_js_onerror
_emscripten_dlopen_js(p, dlopen_js_onsuccess, dlopen_js_onerror, d);
}

void* __dlsym(void* restrict p, const char* restrict s, void* restrict ra) {
#ifdef DYLINK_DEBUG
_emscripten_errf("%p: __dlsym dso:%p sym:%s", pthread_self(), p, s);
#endif
dbg("__dlsym dso:%p sym:%s", p, s);
if (p != RTLD_DEFAULT && p != RTLD_NEXT && __dl_invalid_handle(p)) {
return 0;
}
Expand Down Expand Up @@ -259,9 +245,7 @@ void _emscripten_thread_sync_code() {
syncing = true;
ensure_init();
if (thread_local_tail == tail) {
#ifdef DYLINK_DEBUG
_emscripten_errf("%p: emscripten_thread_sync_code: already in sync", pthread_self());
#endif
dbg("emscripten_thread_sync_code: already in sync");
goto done;
}
pthread_rwlock_rdlock(&lock);
Expand All @@ -270,16 +254,13 @@ void _emscripten_thread_sync_code() {
}
while (thread_local_tail->next) {
struct dso* p = thread_local_tail->next;
#ifdef DYLINK_DEBUG
_emscripten_errf("%p: emscripten_thread_sync_code: %s mem_addr=%p "
"mem_size=%zu table_addr=%p table_size=%zu",
pthread_self(),
p->name,
p->mem_addr,
p->mem_size,
p->table_addr,
p->table_size);
#endif
dbg("emscripten_thread_sync_code: %s mem_addr=%p "
"mem_size=%zu table_addr=%p table_size=%zu",
p->name,
p->mem_addr,
p->mem_size,
p->table_addr,
p->table_size);
void* success = _dlopen_js(p);
if (!success) {
// If any on the libraries fails to load here then we give up.
Expand All @@ -292,9 +273,7 @@ void _emscripten_thread_sync_code() {
thread_local_tail = p;
}
pthread_rwlock_unlock(&lock);
#ifdef DYLINK_DEBUG
_emscripten_errf("%p: emscripten_thread_sync_code done", pthread_self());
#endif
dbg("emscripten_thread_sync_code done");

done:
syncing = false;
Expand Down