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
|
.section .init
|
||||||
FUNCTION(_init):
|
FUNCTION(_init):
|
||||||
bl __haiku_init_before
|
|
||||||
// crtbegin.o stuff comes here
|
// crtbegin.o stuff comes here
|
||||||
|
|
||||||
.section .fini
|
.section .fini
|
||||||
FUNCTION(_fini):
|
FUNCTION(_fini):
|
||||||
bl __haiku_term_before
|
|
||||||
// crtbegin.o stuff comes here
|
// crtbegin.o stuff comes here
|
||||||
|
@ -10,10 +10,8 @@
|
|||||||
|
|
||||||
.section .init
|
.section .init
|
||||||
// the image ID and program args are still on the stack
|
// the image ID and program args are still on the stack
|
||||||
bl __haiku_init_after
|
|
||||||
|
|
||||||
|
|
||||||
.section .fini
|
.section .fini
|
||||||
// the image ID and program args are still on the stack
|
// the image ID and program args are still on the stack
|
||||||
bl __haiku_term_after
|
|
||||||
|
|
||||||
|
@ -21,10 +21,8 @@
|
|||||||
|
|
||||||
.section .init
|
.section .init
|
||||||
FUNCTION(_init):
|
FUNCTION(_init):
|
||||||
jsr __haiku_init_before
|
|
||||||
// crtbegin.o stuff comes here
|
// crtbegin.o stuff comes here
|
||||||
|
|
||||||
.section .fini
|
.section .fini
|
||||||
FUNCTION(_fini):
|
FUNCTION(_fini):
|
||||||
jsr __haiku_term_before
|
|
||||||
// crtbegin.o stuff comes here
|
// crtbegin.o stuff comes here
|
||||||
|
@ -10,10 +10,8 @@
|
|||||||
|
|
||||||
.section .init
|
.section .init
|
||||||
// the image ID and program args are still on the stack
|
// the image ID and program args are still on the stack
|
||||||
jsr __haiku_init_after
|
|
||||||
rts
|
rts
|
||||||
|
|
||||||
.section .fini
|
.section .fini
|
||||||
// the image ID and program args are still on the stack
|
// the image ID and program args are still on the stack
|
||||||
jsr __haiku_term_after
|
|
||||||
rts
|
rts
|
||||||
|
@ -21,10 +21,8 @@
|
|||||||
|
|
||||||
.section .init
|
.section .init
|
||||||
FUNCTION(_init):
|
FUNCTION(_init):
|
||||||
bl __haiku_init_before
|
|
||||||
// crtbegin.o stuff comes here
|
// crtbegin.o stuff comes here
|
||||||
|
|
||||||
.section .fini
|
.section .fini
|
||||||
FUNCTION(_fini):
|
FUNCTION(_fini):
|
||||||
bl __haiku_term_before
|
|
||||||
// crtbegin.o stuff comes here
|
// crtbegin.o stuff comes here
|
||||||
|
@ -10,10 +10,8 @@
|
|||||||
|
|
||||||
.section .init
|
.section .init
|
||||||
// the image ID and program args are still on the stack
|
// the image ID and program args are still on the stack
|
||||||
bl __haiku_init_after
|
|
||||||
blr
|
blr
|
||||||
|
|
||||||
.section .fini
|
.section .fini
|
||||||
// the image ID and program args are still on the stack
|
// the image ID and program args are still on the stack
|
||||||
bl __haiku_term_after
|
|
||||||
blr
|
blr
|
||||||
|
@ -21,10 +21,8 @@
|
|||||||
|
|
||||||
.section .init
|
.section .init
|
||||||
FUNCTION(_init):
|
FUNCTION(_init):
|
||||||
jal __haiku_init_before
|
|
||||||
// crtbegin.o stuff comes here
|
// crtbegin.o stuff comes here
|
||||||
|
|
||||||
.section .fini
|
.section .fini
|
||||||
FUNCTION(_fini):
|
FUNCTION(_fini):
|
||||||
jal __haiku_term_before
|
|
||||||
// crtbegin.o stuff comes here
|
// crtbegin.o stuff comes here
|
||||||
|
@ -10,10 +10,8 @@
|
|||||||
|
|
||||||
.section .init
|
.section .init
|
||||||
// the image ID and program args are still on the stack
|
// the image ID and program args are still on the stack
|
||||||
jal __haiku_init_after
|
|
||||||
|
|
||||||
|
|
||||||
.section .fini
|
.section .fini
|
||||||
// the image ID and program args are still on the stack
|
// the image ID and program args are still on the stack
|
||||||
jal __haiku_term_after
|
|
||||||
|
|
||||||
|
@ -21,10 +21,8 @@
|
|||||||
|
|
||||||
.section .init
|
.section .init
|
||||||
FUNCTION(_init):
|
FUNCTION(_init):
|
||||||
jal __haiku_init_before
|
|
||||||
// crtbegin.o stuff comes here
|
// crtbegin.o stuff comes here
|
||||||
|
|
||||||
.section .fini
|
.section .fini
|
||||||
FUNCTION(_fini):
|
FUNCTION(_fini):
|
||||||
jal __haiku_term_before
|
|
||||||
// crtbegin.o stuff comes here
|
// crtbegin.o stuff comes here
|
||||||
|
@ -10,10 +10,8 @@
|
|||||||
|
|
||||||
.section .init
|
.section .init
|
||||||
// the image ID and program args are still on the stack
|
// the image ID and program args are still on the stack
|
||||||
jal __haiku_init_after
|
|
||||||
|
|
||||||
|
|
||||||
.section .fini
|
.section .fini
|
||||||
// the image ID and program args are still on the stack
|
// the image ID and program args are still on the stack
|
||||||
jal __haiku_term_after
|
|
||||||
|
|
||||||
|
@ -25,7 +25,6 @@ FUNCTION(_init):
|
|||||||
movl %esp, %ebp
|
movl %esp, %ebp
|
||||||
sub $4,%esp // Keep stack aligned
|
sub $4,%esp // Keep stack aligned
|
||||||
pushl 8(%ebp) // put image ID on the stack again
|
pushl 8(%ebp) // put image ID on the stack again
|
||||||
call __haiku_init_before
|
|
||||||
// crtbegin.o stuff comes here
|
// crtbegin.o stuff comes here
|
||||||
|
|
||||||
.section .fini
|
.section .fini
|
||||||
@ -34,5 +33,4 @@ FUNCTION(_fini):
|
|||||||
movl %esp, %ebp
|
movl %esp, %ebp
|
||||||
sub $4,%esp // Keep stack aligned
|
sub $4,%esp // Keep stack aligned
|
||||||
pushl 8(%ebp)
|
pushl 8(%ebp)
|
||||||
call __haiku_term_before
|
|
||||||
// crtend.o stuff comes here
|
// crtend.o stuff comes here
|
||||||
|
@ -10,14 +10,12 @@
|
|||||||
|
|
||||||
.section .init
|
.section .init
|
||||||
// the image ID is still on the stack
|
// the image ID is still on the stack
|
||||||
call __haiku_init_after
|
|
||||||
movl %ebp, %esp
|
movl %ebp, %esp
|
||||||
popl %ebp
|
popl %ebp
|
||||||
ret
|
ret
|
||||||
|
|
||||||
.section .fini
|
.section .fini
|
||||||
// the image ID is still on the stack
|
// the image ID is still on the stack
|
||||||
call __haiku_term_after
|
|
||||||
movl %ebp, %esp
|
movl %ebp, %esp
|
||||||
popl %ebp
|
popl %ebp
|
||||||
ret
|
ret
|
||||||
|
@ -15,7 +15,6 @@
|
|||||||
* stacked together like this:
|
* stacked together like this:
|
||||||
*
|
*
|
||||||
* crti.S entry point
|
* crti.S entry point
|
||||||
* call to _init_before/_term_before
|
|
||||||
* crtbegin.S GCC specific: constructors/destructors are called, ...
|
* crtbegin.S GCC specific: constructors/destructors are called, ...
|
||||||
* crtend.S
|
* crtend.S
|
||||||
* crtn.S call to _init_after/_term_after
|
* crtn.S call to _init_after/_term_after
|
||||||
@ -28,18 +27,18 @@ FUNCTION(_init):
|
|||||||
push %rbp
|
push %rbp
|
||||||
movq %rsp, %rbp
|
movq %rsp, %rbp
|
||||||
|
|
||||||
// Preserve image ID for call to __haiku_init_after.
|
// Preserve image ID.
|
||||||
push %rdi
|
push %rdi
|
||||||
sub $0x8, %rsp
|
sub $0x8, %rsp
|
||||||
|
|
||||||
call __haiku_init_before
|
|
||||||
// crtbegin.o stuff comes here
|
// crtbegin.o stuff comes here
|
||||||
|
|
||||||
.section .fini
|
.section .fini
|
||||||
FUNCTION(_fini):
|
FUNCTION(_fini):
|
||||||
push %rbp
|
push %rbp
|
||||||
movq %rsp, %rbp
|
movq %rsp, %rbp
|
||||||
|
|
||||||
push %rdi
|
push %rdi
|
||||||
sub $0x8, %rsp
|
sub $0x8, %rsp
|
||||||
call __haiku_term_before
|
|
||||||
// crtend.o stuff comes here
|
// crtend.o stuff comes here
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
// The image ID is preserved on the stack.
|
// The image ID is preserved on the stack.
|
||||||
add $0x8, %rsp
|
add $0x8, %rsp
|
||||||
pop %rdi
|
pop %rdi
|
||||||
call __haiku_init_after
|
|
||||||
movq %rbp, %rsp
|
movq %rbp, %rsp
|
||||||
pop %rbp
|
pop %rbp
|
||||||
ret
|
ret
|
||||||
@ -23,7 +23,7 @@
|
|||||||
.section .fini
|
.section .fini
|
||||||
add $0x8, %rsp
|
add $0x8, %rsp
|
||||||
pop %rdi
|
pop %rdi
|
||||||
call __haiku_term_after
|
|
||||||
movq %rbp, %rsp
|
movq %rbp, %rsp
|
||||||
pop %rbp
|
pop %rbp
|
||||||
ret
|
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.
|
* 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"
|
#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 (*init_term_function)(image_id);
|
||||||
|
typedef void (*initfini_array_function)();
|
||||||
|
|
||||||
bool gProgramLoaded = false;
|
bool gProgramLoaded = false;
|
||||||
image_t* gProgramImage;
|
image_t* gProgramImage;
|
||||||
@ -260,7 +261,14 @@ init_dependencies(image_t *image, bool initHead)
|
|||||||
if (image->preinit_array) {
|
if (image->preinit_array) {
|
||||||
uint count_preinit = image->preinit_array_len / sizeof(addr_t);
|
uint count_preinit = image->preinit_array_len / sizeof(addr_t);
|
||||||
for (uint j = 0; j < count_preinit; j++)
|
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)
|
if (image->init_routine != 0)
|
||||||
@ -269,12 +277,19 @@ init_dependencies(image_t *image, bool initHead)
|
|||||||
if (image->init_array) {
|
if (image->init_array) {
|
||||||
uint count_init = image->init_array_len / sizeof(addr_t);
|
uint count_init = image->init_array_len / sizeof(addr_t);
|
||||||
for (uint j = 0; j < count_init; j++)
|
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);
|
image_event(image, IMAGE_EVENT_INITIALIZED);
|
||||||
}
|
}
|
||||||
TRACE(("%ld: init done.\n", find_thread(NULL)));
|
TRACE(("%ld: init done.\n", find_thread(NULL)));
|
||||||
|
|
||||||
free(initList);
|
free(initList);
|
||||||
}
|
}
|
||||||
@ -645,15 +660,29 @@ unload_library(void* handle, image_id imageID, bool addOn)
|
|||||||
|
|
||||||
image_event(image, IMAGE_EVENT_UNINITIALIZING);
|
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) {
|
if (image->term_array) {
|
||||||
uint count_term = image->term_array_len / sizeof(addr_t);
|
uint count_term = image->term_array_len / sizeof(addr_t);
|
||||||
for (uint i = count_term; i-- > 0;)
|
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)
|
if (image->term_routine)
|
||||||
((init_term_function)image->term_routine)(image->id);
|
((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);
|
TLSBlockTemplates::Get().Unregister(image->dso_tls_id);
|
||||||
|
|
||||||
dequeue_disposable_image(image);
|
dequeue_disposable_image(image);
|
||||||
@ -812,6 +841,15 @@ get_symbol(image_id imageID, char const *symbolName, int32 symbolType,
|
|||||||
if (symbolName == NULL)
|
if (symbolName == NULL)
|
||||||
return B_BAD_VALUE;
|
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();
|
rld_lock();
|
||||||
// for now, just do stupid simple global locking
|
// for now, just do stupid simple global locking
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user