From 3a75ef9ad1db52cba9b96ddcdd03b35587e14057 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Duval?= Date: Sun, 10 Mar 2019 22:03:54 +0100 Subject: [PATCH] runtime_loader: call preinit_array before initializing dependencies. Change-Id: Ieed1af8ede83692d583d8e84bae92b1be29ddd1e Reviewed-on: https://review.haiku-os.org/c/1187 Reviewed-by: waddlesplash --- src/system/runtime_loader/elf.cpp | 12 +++--- .../test_suite/load_init_order1 | 43 +++++++++++++++++++ 2 files changed, 49 insertions(+), 6 deletions(-) create mode 100755 src/tests/system/runtime_loader/test_suite/load_init_order1 diff --git a/src/system/runtime_loader/elf.cpp b/src/system/runtime_loader/elf.cpp index c4fa305ee6..778064a8ef 100644 --- a/src/system/runtime_loader/elf.cpp +++ b/src/system/runtime_loader/elf.cpp @@ -228,6 +228,12 @@ init_dependencies(image_t *image, bool initHead) image_t **initList; ssize_t count, i; + if (initHead && image->preinit_array) { + uint count_preinit = image->preinit_array_len / sizeof(addr_t); + for (uint j = 0; j < count_preinit; j++) + ((initfini_array_function)image->preinit_array[j])(); + } + count = get_sorted_image_list(image, &initList, RFLAG_INITIALIZED); if (count <= 0) return; @@ -244,12 +250,6 @@ init_dependencies(image_t *image, bool initHead) TRACE(("%ld: init: %s\n", find_thread(NULL), image->name)); - if (image->preinit_array) { - uint count_preinit = image->preinit_array_len / sizeof(addr_t); - for (uint j = 0; j < count_preinit; j++) - ((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), diff --git a/src/tests/system/runtime_loader/test_suite/load_init_order1 b/src/tests/system/runtime_loader/test_suite/load_init_order1 new file mode 100755 index 0000000000..c4ddc1dd69 --- /dev/null +++ b/src/tests/system/runtime_loader/test_suite/load_init_order1 @@ -0,0 +1,43 @@ +#!/bin/sh + +# program +# <- liba.so +# Expected: preinit function in program runs before constructor in liba.so. + + +. ./test_setup + + +# create liba.so +cat > liba.c << EOI +extern int i; +void __attribute__((constructor)) a() { i = 2 * i + 1; } +EOI + +# build +compile_lib -o liba.so liba.c + +# create program +cat > program.c << EOI + +int i = 1; + +void b() { i = 4 * i + 1; } + +int +main() +{ + return i; +} + +__attribute__((section(".preinit_array"), used)) +void (*__local_b_preinit)(void) = b; + +EOI + +# build +compile_program -o program program.c ./liba.so -pie + +# run +test_run_ok ./program 11 +