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):
|
FUNCTION(_init):
|
||||||
pushl %ebp
|
pushl %ebp
|
||||||
movl %esp, %ebp
|
movl %esp, %ebp
|
||||||
pushl %ebx
|
pushl 8(%ebp) // put image ID on the stack again
|
||||||
// BeOS unfortunately puts the image ID into %ebx instead of
|
|
||||||
// just passing it over the stack
|
|
||||||
call _init_before
|
call _init_before
|
||||||
// crtbegin.o stuff comes here
|
// crtbegin.o stuff comes here
|
||||||
|
|
||||||
@@ -33,6 +31,6 @@ FUNCTION(_init):
|
|||||||
FUNCTION(_fini):
|
FUNCTION(_fini):
|
||||||
pushl %ebp
|
pushl %ebp
|
||||||
movl %esp, %ebp
|
movl %esp, %ebp
|
||||||
pushl %ebx
|
pushl 8(%ebp)
|
||||||
call _term_before
|
call _term_before
|
||||||
// crtend.o stuff comes here
|
// crtend.o stuff comes here
|
||||||
|
|||||||
@@ -62,11 +62,10 @@ Objects
|
|||||||
heap.c
|
heap.c
|
||||||
utility.cpp
|
utility.cpp
|
||||||
arch_relocate.c
|
arch_relocate.c
|
||||||
arch_call_init_term.c
|
|
||||||
;
|
;
|
||||||
|
|
||||||
Ld runtime_loader :
|
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
|
libruntime_loader.a
|
||||||
$(TARGET_GCC_LIBGCC)
|
$(TARGET_GCC_LIBGCC)
|
||||||
: $(HAIKU_TOP)/src/system/ldscripts/$(TARGET_ARCH)/runtime_loader.ld
|
: $(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) \
|
#define APP_OR_LIBRARY_TYPE (IMAGE_TYPE_TO_MASK(B_APP_IMAGE) \
|
||||||
| IMAGE_TYPE_TO_MASK(B_LIBRARY_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 sLoadedImages = {0, 0};
|
||||||
static image_queue_t sLoadingImages = {0, 0};
|
static image_queue_t sLoadingImages = {0, 0};
|
||||||
@@ -224,6 +225,13 @@ find_loaded_image_by_id(image_id id)
|
|||||||
return image;
|
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;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1126,8 +1134,12 @@ init_dependencies(image_t *image, bool initHead)
|
|||||||
|
|
||||||
TRACE(("%ld: init dependencies\n", find_thread(NULL)));
|
TRACE(("%ld: init dependencies\n", find_thread(NULL)));
|
||||||
for (i = 0; i < count; i++) {
|
for (i = 0; i < count; i++) {
|
||||||
TRACE(("%ld: init: %s\n", find_thread(NULL), initList[i]->name));
|
image = initList[i];
|
||||||
arch_call_init(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)));
|
TRACE(("%ld: init done.\n", find_thread(NULL)));
|
||||||
|
|
||||||
@@ -1289,15 +1301,11 @@ unload_library(image_id imageID, bool addOn)
|
|||||||
rld_lock();
|
rld_lock();
|
||||||
// for now, just do stupid simple global locking
|
// 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) {
|
for (image = sLoadedImages.head; image; image = image->next) {
|
||||||
if (image->id == imageID) {
|
if (image->id == imageID) {
|
||||||
/*
|
// unload image
|
||||||
* do the unloading
|
|
||||||
*/
|
|
||||||
if (type == image->type) {
|
if (type == image->type) {
|
||||||
put_image(image);
|
put_image(image);
|
||||||
status = B_OK;
|
status = B_OK;
|
||||||
@@ -1311,7 +1319,7 @@ unload_library(image_id imageID, bool addOn)
|
|||||||
while ((image = sDisposableImages.head) != NULL) {
|
while ((image = sDisposableImages.head) != NULL) {
|
||||||
// call image fini here...
|
// call image fini here...
|
||||||
if (image->term_routine)
|
if (image->term_routine)
|
||||||
arch_call_term(image);
|
((init_term_function)image->term_routine)(image->id);
|
||||||
|
|
||||||
dequeue_image(&sDisposableImages, image);
|
dequeue_image(&sDisposableImages, image);
|
||||||
unmap_image(image);
|
unmap_image(image);
|
||||||
@@ -1432,8 +1440,12 @@ terminate_program(void)
|
|||||||
|
|
||||||
TRACE(("%ld: terminate dependencies\n", find_thread(NULL)));
|
TRACE(("%ld: terminate dependencies\n", find_thread(NULL)));
|
||||||
for (i = count; i-- > 0;) {
|
for (i = count; i-- > 0;) {
|
||||||
TRACE(("%ld: term: %s\n", find_thread(NULL), termList[i]->name));
|
image_t *image = termList[i];
|
||||||
arch_call_term(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)));
|
TRACE(("%ld: term done.\n", find_thread(NULL)));
|
||||||
|
|
||||||
|
|||||||
@@ -48,8 +48,6 @@ void rldfree(void *p);
|
|||||||
|
|
||||||
// arch dependent prototypes
|
// arch dependent prototypes
|
||||||
status_t arch_relocate_image(image_t *image);
|
status_t arch_relocate_image(image_t *image);
|
||||||
void arch_call_init(image_t *image);
|
|
||||||
void arch_call_term(image_t *image);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user