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
This commit is contained in:
Axel Dörfler
2006-06-26 22:09:13 +00:00
parent 58ad2aba29
commit 0cd3c003d1
6 changed files with 26 additions and 85 deletions
+2 -4
View File
@@ -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
+1 -2
View File
@@ -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
@@ -1,29 +0,0 @@
/*
* Copyright 2006, Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Axel Dörfler, [email protected]
* Ingo Weinhold, [email protected]
*/
#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);
}
@@ -1,37 +0,0 @@
/*
* Copyright 2006, Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Axel Dörfler, [email protected]
* Ingo Weinhold, [email protected]
*/
#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));
}
+23 -11
View File
@@ -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)));
@@ -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
}