From 0cd3c003d10aa80549c405dd6dd2d696daa75409 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Mon, 26 Jun 2006 22:09:13 +0000 Subject: [PATCH] While investigating how our deals with doubled shared libs, I found two issues: * Our glue code was broken after all - it allowed Haiku apps to start under BeOS (and vice versa), but the initialization/termination functions were called with an invalid image ID - on *both* sides! As it turns out, the Be glue code did *something* with %ebx, but certainly didn't put the image ID in there, but just passed it on the stack, as we did before (just in the wrong order...). Therefore, the arch_call_init_term stuff is not necessary. * When unloading add-ons, their termination functions were never called, as the image (for get_image_symbol()) was already made inaccessible, and therefore the symbol couldn't be found. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@17928 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/system/glue/arch/x86/crti.S | 6 +-- src/system/runtime_loader/Jamfile | 3 +- .../arch/ppc/arch_call_init_term.c | 29 --------------- .../arch/x86/arch_call_init_term.c | 37 ------------------- src/system/runtime_loader/elf.c | 34 +++++++++++------ .../runtime_loader/runtime_loader_private.h | 2 - 6 files changed, 26 insertions(+), 85 deletions(-) delete mode 100644 src/system/runtime_loader/arch/ppc/arch_call_init_term.c delete mode 100644 src/system/runtime_loader/arch/x86/arch_call_init_term.c diff --git a/src/system/glue/arch/x86/crti.S b/src/system/glue/arch/x86/crti.S index 02c5d4c26c..553b7881ab 100644 --- a/src/system/glue/arch/x86/crti.S +++ b/src/system/glue/arch/x86/crti.S @@ -23,9 +23,7 @@ FUNCTION(_init): pushl %ebp movl %esp, %ebp - pushl %ebx - // BeOS unfortunately puts the image ID into %ebx instead of - // just passing it over the stack + pushl 8(%ebp) // put image ID on the stack again call _init_before // crtbegin.o stuff comes here @@ -33,6 +31,6 @@ FUNCTION(_init): FUNCTION(_fini): pushl %ebp movl %esp, %ebp - pushl %ebx + pushl 8(%ebp) call _term_before // crtend.o stuff comes here diff --git a/src/system/runtime_loader/Jamfile b/src/system/runtime_loader/Jamfile index 3b2e326743..38057f2cd0 100644 --- a/src/system/runtime_loader/Jamfile +++ b/src/system/runtime_loader/Jamfile @@ -62,11 +62,10 @@ Objects heap.c utility.cpp arch_relocate.c - arch_call_init_term.c ; Ld runtime_loader : - [ FGristFiles runtime_loader.o elf.o export.o heap.o utility.o arch_relocate.o arch_call_init_term.o ] + [ FGristFiles runtime_loader.o elf.o export.o heap.o utility.o arch_relocate.o ] libruntime_loader.a $(TARGET_GCC_LIBGCC) : $(HAIKU_TOP)/src/system/ldscripts/$(TARGET_ARCH)/runtime_loader.ld diff --git a/src/system/runtime_loader/arch/ppc/arch_call_init_term.c b/src/system/runtime_loader/arch/ppc/arch_call_init_term.c deleted file mode 100644 index f05ca91af2..0000000000 --- a/src/system/runtime_loader/arch/ppc/arch_call_init_term.c +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright 2006, Haiku, Inc. All Rights Reserved. - * Distributed under the terms of the MIT License. - * - * Authors: - * Axel Dörfler, axeld@pinc-software.de - * Ingo Weinhold, bonefish@cs.tu-berlin.de - */ - - -#include "runtime_loader_private.h" - - -typedef void (*init_term_function)(image_id); - - -void -arch_call_init(image_t *image) -{ - ((init_term_function)image->init_routine)(image->id); -} - - -void -arch_call_term(image_t *image) -{ - ((init_term_function)image->term_routine)(image->id); -} - diff --git a/src/system/runtime_loader/arch/x86/arch_call_init_term.c b/src/system/runtime_loader/arch/x86/arch_call_init_term.c deleted file mode 100644 index 8d04bd6dcd..0000000000 --- a/src/system/runtime_loader/arch/x86/arch_call_init_term.c +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright 2006, Haiku, Inc. All Rights Reserved. - * Distributed under the terms of the MIT License. - * - * Authors: - * Axel Dörfler, axeld@pinc-software.de - * Ingo Weinhold, bonefish@cs.tu-berlin.de - */ - - -#include "runtime_loader_private.h" - - -void -arch_call_init(image_t *image) -{ - // This calls the init code in crti.S (in glue/arch/x86/) - // It would have been too easy to just call this function with its arguments - // on the stack, so Be went the ugly way. Once more. - asm("push %%ebx;" - "mov %0, %%ebx;" - "call *%1;" - "pop %%ebx" - : : "g"(image->id), "g"(image->init_routine)); -} - - -void -arch_call_term(image_t *image) -{ - asm("push %%ebx;" - "mov %0, %%ebx;" - "call *%1;" - "pop %%ebx" - : : "g"(image->id), "g"(image->term_routine)); -} - diff --git a/src/system/runtime_loader/elf.c b/src/system/runtime_loader/elf.c index 6d46b42d30..55581198fe 100644 --- a/src/system/runtime_loader/elf.c +++ b/src/system/runtime_loader/elf.c @@ -67,6 +67,7 @@ enum { #define APP_OR_LIBRARY_TYPE (IMAGE_TYPE_TO_MASK(B_APP_IMAGE) \ | IMAGE_TYPE_TO_MASK(B_LIBRARY_IMAGE)) +typedef void (*init_term_function)(image_id); static image_queue_t sLoadedImages = {0, 0}; static image_queue_t sLoadingImages = {0, 0}; @@ -224,6 +225,13 @@ find_loaded_image_by_id(image_id id) return image; } + // For the termination routine, we need to look into the list of + // disposable images as well + for (image = sDisposableImages.head; image; image = image->next) { + if (image->id == id) + return image; + } + return NULL; } @@ -1126,8 +1134,12 @@ init_dependencies(image_t *image, bool initHead) TRACE(("%ld: init dependencies\n", find_thread(NULL))); for (i = 0; i < count; i++) { - TRACE(("%ld: init: %s\n", find_thread(NULL), initList[i]->name)); - arch_call_init(initList[i]); + image = initList[i]; + + TRACE(("%ld: init: %s\n", find_thread(NULL), image->name)); + + if (image->init_routine != NULL) + ((init_term_function)image->init_routine)(image->id); } TRACE(("%ld: init done.\n", find_thread(NULL))); @@ -1289,15 +1301,11 @@ unload_library(image_id imageID, bool addOn) rld_lock(); // for now, just do stupid simple global locking - /* - * we only check images that have been already initialized - */ + // we only check images that have been already initialized for (image = sLoadedImages.head; image; image = image->next) { if (image->id == imageID) { - /* - * do the unloading - */ + // unload image if (type == image->type) { put_image(image); status = B_OK; @@ -1311,7 +1319,7 @@ unload_library(image_id imageID, bool addOn) while ((image = sDisposableImages.head) != NULL) { // call image fini here... if (image->term_routine) - arch_call_term(image); + ((init_term_function)image->term_routine)(image->id); dequeue_image(&sDisposableImages, image); unmap_image(image); @@ -1432,8 +1440,12 @@ terminate_program(void) TRACE(("%ld: terminate dependencies\n", find_thread(NULL))); for (i = count; i-- > 0;) { - TRACE(("%ld: term: %s\n", find_thread(NULL), termList[i]->name)); - arch_call_term(termList[i]); + image_t *image = termList[i]; + + TRACE(("%ld: term: %s\n", find_thread(NULL), image->name)); + + if (image->term_routine) + ((init_term_function)image->term_routine)(image->id); } TRACE(("%ld: term done.\n", find_thread(NULL))); diff --git a/src/system/runtime_loader/runtime_loader_private.h b/src/system/runtime_loader/runtime_loader_private.h index af9e4d0b1d..4759c4bef5 100644 --- a/src/system/runtime_loader/runtime_loader_private.h +++ b/src/system/runtime_loader/runtime_loader_private.h @@ -48,8 +48,6 @@ void rldfree(void *p); // arch dependent prototypes status_t arch_relocate_image(image_t *image); -void arch_call_init(image_t *image); -void arch_call_term(image_t *image); #ifdef __cplusplus }