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:
@@ -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
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user