runtime_loader: Rework static initialization handling.
Previously, static initializers were just in ".ctors", which was handled by GCC's crtbeginS, and that was injected in-between crti and crtn. Now, however, binutils puts static initializers into init_array/fini_array by default, which runtime_loader handles, but of course as initialize_after and terminate_after are supposed to be called *after* all static initializers are called; and since runtime_loader called init_array after _init, they were not. Now, we get rid of the __haiku_init_before/etc. functions, and move their functionality inside runtime_loader. This is a "soft" ABI breakage, which is mitigated by adding another ABI breakage (runtime_loader now returns NULL for the initialize_before/etc. symbols, as otherwise old applications would have their initialize_before/etc. called twice; once by runtime_loader, and then once by __haiku_init_before/etc.) I don't see or know of any reason why an application would want to get those symbols at runtime, though, so this shouldn't have any adverse effects. Change-Id: I42344c63f69c6f8ef260f6c3ca30202b6dfb153e Reviewed-on: https://review.haiku-os.org/c/907 Reviewed-by: Jérôme Duval <jerome.duval@gmail.com> Reviewed-by: waddlesplash <waddlesplash@gmail.com>
This commit is contained in:
parent
d49942867b
commit
354b60af29
@ -21,10 +21,8 @@
|
||||
|
||||
.section .init
|
||||
FUNCTION(_init):
|
||||
bl __haiku_init_before
|
||||
// crtbegin.o stuff comes here
|
||||
|
||||
.section .fini
|
||||
FUNCTION(_fini):
|
||||
bl __haiku_term_before
|
||||
// crtbegin.o stuff comes here
|
||||
|
@ -10,10 +10,8 @@
|
||||
|
||||
.section .init
|
||||
// the image ID and program args are still on the stack
|
||||
bl __haiku_init_after
|
||||
|
||||
|
||||
.section .fini
|
||||
// the image ID and program args are still on the stack
|
||||
bl __haiku_term_after
|
||||
|
||||
|
@ -21,10 +21,8 @@
|
||||
|
||||
.section .init
|
||||
FUNCTION(_init):
|
||||
jsr __haiku_init_before
|
||||
// crtbegin.o stuff comes here
|
||||
|
||||
.section .fini
|
||||
FUNCTION(_fini):
|
||||
jsr __haiku_term_before
|
||||
// crtbegin.o stuff comes here
|
||||
|
@ -10,10 +10,8 @@
|
||||
|
||||
.section .init
|
||||
// the image ID and program args are still on the stack
|
||||
jsr __haiku_init_after
|
||||
rts
|
||||
|
||||
.section .fini
|
||||
// the image ID and program args are still on the stack
|
||||
jsr __haiku_term_after
|
||||
rts
|
||||
|
@ -21,10 +21,8 @@
|
||||
|
||||
.section .init
|
||||
FUNCTION(_init):
|
||||
bl __haiku_init_before
|
||||
// crtbegin.o stuff comes here
|
||||
|
||||
.section .fini
|
||||
FUNCTION(_fini):
|
||||
bl __haiku_term_before
|
||||
// crtbegin.o stuff comes here
|
||||
|
@ -10,10 +10,8 @@
|
||||
|
||||
.section .init
|
||||
// the image ID and program args are still on the stack
|
||||
bl __haiku_init_after
|
||||
blr
|
||||
|
||||
.section .fini
|
||||
// the image ID and program args are still on the stack
|
||||
bl __haiku_term_after
|
||||
blr
|
||||
|
@ -21,10 +21,8 @@
|
||||
|
||||
.section .init
|
||||
FUNCTION(_init):
|
||||
jal __haiku_init_before
|
||||
// crtbegin.o stuff comes here
|
||||
|
||||
.section .fini
|
||||
FUNCTION(_fini):
|
||||
jal __haiku_term_before
|
||||
// crtbegin.o stuff comes here
|
||||
|
@ -10,10 +10,8 @@
|
||||
|
||||
.section .init
|
||||
// the image ID and program args are still on the stack
|
||||
jal __haiku_init_after
|
||||
|
||||
|
||||
.section .fini
|
||||
// the image ID and program args are still on the stack
|
||||
jal __haiku_term_after
|
||||
|
||||
|
@ -21,10 +21,8 @@
|
||||
|
||||
.section .init
|
||||
FUNCTION(_init):
|
||||
jal __haiku_init_before
|
||||
// crtbegin.o stuff comes here
|
||||
|
||||
.section .fini
|
||||
FUNCTION(_fini):
|
||||
jal __haiku_term_before
|
||||
// crtbegin.o stuff comes here
|
||||
|
@ -10,10 +10,8 @@
|
||||
|
||||
.section .init
|
||||
// the image ID and program args are still on the stack
|
||||
jal __haiku_init_after
|
||||
|
||||
|
||||
.section .fini
|
||||
// the image ID and program args are still on the stack
|
||||
jal __haiku_term_after
|
||||
|
||||
|
@ -25,7 +25,6 @@ FUNCTION(_init):
|
||||
movl %esp, %ebp
|
||||
sub $4,%esp // Keep stack aligned
|
||||
pushl 8(%ebp) // put image ID on the stack again
|
||||
call __haiku_init_before
|
||||
// crtbegin.o stuff comes here
|
||||
|
||||
.section .fini
|
||||
@ -34,5 +33,4 @@ FUNCTION(_fini):
|
||||
movl %esp, %ebp
|
||||
sub $4,%esp // Keep stack aligned
|
||||
pushl 8(%ebp)
|
||||
call __haiku_term_before
|
||||
// crtend.o stuff comes here
|
||||
|
@ -10,14 +10,12 @@
|
||||
|
||||
.section .init
|
||||
// the image ID is still on the stack
|
||||
call __haiku_init_after
|
||||
movl %ebp, %esp
|
||||
popl %ebp
|
||||
ret
|
||||
|
||||
.section .fini
|
||||
// the image ID is still on the stack
|
||||
call __haiku_term_after
|
||||
movl %ebp, %esp
|
||||
popl %ebp
|
||||
ret
|
||||
|
@ -15,7 +15,6 @@
|
||||
* stacked together like this:
|
||||
*
|
||||
* crti.S entry point
|
||||
* call to _init_before/_term_before
|
||||
* crtbegin.S GCC specific: constructors/destructors are called, ...
|
||||
* crtend.S
|
||||
* crtn.S call to _init_after/_term_after
|
||||
@ -28,18 +27,18 @@ FUNCTION(_init):
|
||||
push %rbp
|
||||
movq %rsp, %rbp
|
||||
|
||||
// Preserve image ID for call to __haiku_init_after.
|
||||
// Preserve image ID.
|
||||
push %rdi
|
||||
sub $0x8, %rsp
|
||||
|
||||
call __haiku_init_before
|
||||
// crtbegin.o stuff comes here
|
||||
|
||||
.section .fini
|
||||
FUNCTION(_fini):
|
||||
push %rbp
|
||||
movq %rsp, %rbp
|
||||
|
||||
push %rdi
|
||||
sub $0x8, %rsp
|
||||
call __haiku_term_before
|
||||
|
||||
// crtend.o stuff comes here
|
||||
|
@ -15,7 +15,7 @@
|
||||
// The image ID is preserved on the stack.
|
||||
add $0x8, %rsp
|
||||
pop %rdi
|
||||
call __haiku_init_after
|
||||
|
||||
movq %rbp, %rsp
|
||||
pop %rbp
|
||||
ret
|
||||
@ -23,7 +23,7 @@
|
||||
.section .fini
|
||||
add $0x8, %rsp
|
||||
pop %rdi
|
||||
call __haiku_term_after
|
||||
|
||||
movq %rbp, %rsp
|
||||
pop %rbp
|
||||
ret
|
||||
|
@ -1,81 +1,6 @@
|
||||
/*
|
||||
* Copyright 2003-2006, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
|
||||
* Copyright 2019, Haiku, Inc. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
|
||||
#include <user_runtime.h>
|
||||
#include <image.h>
|
||||
|
||||
#include "init_term_dyn.h"
|
||||
|
||||
|
||||
// include the version glue -- it's separate for the kernel add-ons only
|
||||
#include "haiku_version_glue.c"
|
||||
|
||||
|
||||
/*! These functions are called from _init()/_fini() (in crti.S, crtn.S)
|
||||
__haiku_{init,term}_before() is called before crtbegin/end code is
|
||||
executed, __haiku_{init,term}_after() after this. crtbegin contains
|
||||
code to initialize all global constructors and other GCC related things
|
||||
(like exception frames).
|
||||
*/
|
||||
|
||||
|
||||
#define HIDDEN_FUNCTION(function) asm volatile(".hidden " #function)
|
||||
|
||||
|
||||
void
|
||||
__haiku_init_before(image_id id)
|
||||
{
|
||||
void (*before)(image_id);
|
||||
|
||||
HIDDEN_FUNCTION(__haiku_init_before);
|
||||
|
||||
if (get_image_symbol(id, B_INIT_BEFORE_FUNCTION_NAME, B_SYMBOL_TYPE_TEXT,
|
||||
(void**)&before) == B_OK) {
|
||||
before(id);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
__haiku_init_after(image_id id)
|
||||
{
|
||||
void (*after)(image_id);
|
||||
|
||||
HIDDEN_FUNCTION(__haiku_init_after);
|
||||
|
||||
if (get_image_symbol(id, B_INIT_AFTER_FUNCTION_NAME, B_SYMBOL_TYPE_TEXT,
|
||||
(void**)&after) == B_OK) {
|
||||
after(id);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
__haiku_term_before(image_id id)
|
||||
{
|
||||
void (*before)(image_id);
|
||||
|
||||
HIDDEN_FUNCTION(__haiku_term_before);
|
||||
|
||||
if (get_image_symbol(id, B_TERM_BEFORE_FUNCTION_NAME, B_SYMBOL_TYPE_TEXT,
|
||||
(void**)&before) == B_OK) {
|
||||
before(id);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
__haiku_term_after(image_id id)
|
||||
{
|
||||
void (*after)(image_id);
|
||||
|
||||
HIDDEN_FUNCTION(__haiku_term_after);
|
||||
|
||||
if (get_image_symbol(id, B_TERM_AFTER_FUNCTION_NAME, B_SYMBOL_TYPE_TEXT,
|
||||
(void**)&after) == B_OK) {
|
||||
after(id);
|
||||
}
|
||||
}
|
||||
|
@ -1,18 +0,0 @@
|
||||
/*
|
||||
* Copyright 2003-2006, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef INIT_TERM_DYN_H
|
||||
#define INIT_TERM_DYN_H
|
||||
|
||||
|
||||
#include <image.h>
|
||||
|
||||
|
||||
void __haiku_init_before(image_id id);
|
||||
void __haiku_init_after(image_id id);
|
||||
void __haiku_term_before(image_id id);
|
||||
void __haiku_term_after(image_id id);
|
||||
|
||||
|
||||
#endif /* INIT_TERM_DYN_H */
|
@ -42,6 +42,7 @@ static const char* const kLockName = "runtime loader";
|
||||
|
||||
|
||||
typedef void (*init_term_function)(image_id);
|
||||
typedef void (*initfini_array_function)();
|
||||
|
||||
bool gProgramLoaded = false;
|
||||
image_t* gProgramImage;
|
||||
@ -260,7 +261,14 @@ init_dependencies(image_t *image, bool initHead)
|
||||
if (image->preinit_array) {
|
||||
uint count_preinit = image->preinit_array_len / sizeof(addr_t);
|
||||
for (uint j = 0; j < count_preinit; j++)
|
||||
((init_term_function)image->preinit_array[j])(image->id);
|
||||
((initfini_array_function)image->preinit_array[j])();
|
||||
}
|
||||
|
||||
init_term_function before;
|
||||
if (find_symbol(image,
|
||||
SymbolLookupInfo(B_INIT_BEFORE_FUNCTION_NAME, B_SYMBOL_TYPE_TEXT),
|
||||
(void**)&before) == B_OK) {
|
||||
before(image->id);
|
||||
}
|
||||
|
||||
if (image->init_routine != 0)
|
||||
@ -269,12 +277,19 @@ init_dependencies(image_t *image, bool initHead)
|
||||
if (image->init_array) {
|
||||
uint count_init = image->init_array_len / sizeof(addr_t);
|
||||
for (uint j = 0; j < count_init; j++)
|
||||
((init_term_function)image->init_array[j])(image->id);
|
||||
((initfini_array_function)image->init_array[j])();
|
||||
}
|
||||
|
||||
init_term_function after;
|
||||
if (find_symbol(image,
|
||||
SymbolLookupInfo(B_INIT_AFTER_FUNCTION_NAME, B_SYMBOL_TYPE_TEXT),
|
||||
(void**)&after) == B_OK) {
|
||||
after(image->id);
|
||||
}
|
||||
|
||||
image_event(image, IMAGE_EVENT_INITIALIZED);
|
||||
}
|
||||
TRACE(("%ld: init done.\n", find_thread(NULL)));
|
||||
TRACE(("%ld: init done.\n", find_thread(NULL)));
|
||||
|
||||
free(initList);
|
||||
}
|
||||
@ -645,15 +660,29 @@ unload_library(void* handle, image_id imageID, bool addOn)
|
||||
|
||||
image_event(image, IMAGE_EVENT_UNINITIALIZING);
|
||||
|
||||
init_term_function before;
|
||||
if (find_symbol(image,
|
||||
SymbolLookupInfo(B_TERM_BEFORE_FUNCTION_NAME, B_SYMBOL_TYPE_TEXT),
|
||||
(void**)&before) == B_OK) {
|
||||
before(image->id);
|
||||
}
|
||||
|
||||
if (image->term_array) {
|
||||
uint count_term = image->term_array_len / sizeof(addr_t);
|
||||
for (uint i = count_term; i-- > 0;)
|
||||
((init_term_function)image->term_array[i])(image->id);
|
||||
((initfini_array_function)image->term_array[i])();
|
||||
}
|
||||
|
||||
if (image->term_routine)
|
||||
((init_term_function)image->term_routine)(image->id);
|
||||
|
||||
init_term_function after;
|
||||
if (find_symbol(image,
|
||||
SymbolLookupInfo(B_TERM_AFTER_FUNCTION_NAME, B_SYMBOL_TYPE_TEXT),
|
||||
(void**)&after) == B_OK) {
|
||||
after(image->id);
|
||||
}
|
||||
|
||||
TLSBlockTemplates::Get().Unregister(image->dso_tls_id);
|
||||
|
||||
dequeue_disposable_image(image);
|
||||
@ -812,6 +841,15 @@ get_symbol(image_id imageID, char const *symbolName, int32 symbolType,
|
||||
if (symbolName == NULL)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
// Previously, these functions were called in __haiku_init_before
|
||||
// and __haiku_init_after. Now we call them inside runtime_loader,
|
||||
// so we prevent applications from fetching them.
|
||||
if (strcmp(symbolName, B_INIT_BEFORE_FUNCTION_NAME) == 0
|
||||
|| strcmp(symbolName, B_INIT_AFTER_FUNCTION_NAME) == 0
|
||||
|| strcmp(symbolName, B_TERM_BEFORE_FUNCTION_NAME) == 0
|
||||
|| strcmp(symbolName, B_TERM_AFTER_FUNCTION_NAME) == 0)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
rld_lock();
|
||||
// for now, just do stupid simple global locking
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user