hrev50589 adds 1 changeset to branch 'master'
old head: 1df36f2ceee7b41a50386a9106a3614f3f075d34
new head: e340f717a422917491cebe4b693c6d30416ea0f0
overview:
http://cgit.haiku-os.org/haiku/log/?qt=range&q=e340f717a422+%5E1df36f2ceee7
----------------------------------------------------------------------------
e340f717a422: runtime_loader: add support for ELF init/term routine arrays.
* binutils 2.27 defaults to DT_INIT_ARRAY instead of DT_INIT.
[ Jérôme Duval <jerome.duval@xxxxxxxxx> ]
----------------------------------------------------------------------------
Revision: hrev50589
Commit: e340f717a422917491cebe4b693c6d30416ea0f0
URL: http://cgit.haiku-os.org/haiku/commit/?id=e340f717a422
Author: Jérôme Duval <jerome.duval@xxxxxxxxx>
Date: Tue Oct 11 20:26:06 2016 UTC
----------------------------------------------------------------------------
3 files changed, 57 insertions(+), 3 deletions(-)
headers/private/runtime_loader/runtime_loader.h | 6 +++++
src/system/runtime_loader/elf.cpp | 24 +++++++++++++++++
src/system/runtime_loader/elf_load_image.cpp | 30 ++++++++++++++++++---
----------------------------------------------------------------------------
diff --git a/headers/private/runtime_loader/runtime_loader.h
b/headers/private/runtime_loader/runtime_loader.h
index 6a754f2..d93f676 100644
--- a/headers/private/runtime_loader/runtime_loader.h
+++ b/headers/private/runtime_loader/runtime_loader.h
@@ -115,6 +115,12 @@ typedef struct image_t {
int rela_len;
elf_rel *pltrel;
int pltrel_len;
+ addr_t *init_array;
+ int init_array_len;
+ addr_t *preinit_array;
+ int preinit_array_len;
+ addr_t *term_array;
+ int term_array_len;
unsigned dso_tls_id;
diff --git a/src/system/runtime_loader/elf.cpp
b/src/system/runtime_loader/elf.cpp
index 6d30bbb..03b8bd1 100644
--- a/src/system/runtime_loader/elf.cpp
+++ b/src/system/runtime_loader/elf.cpp
@@ -257,9 +257,21 @@ 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++)
+
((init_term_function)image->preinit_array[j])(image->id);
+ }
+
if (image->init_routine != 0)
((init_term_function)image->init_routine)(image->id);
+ 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);
+ }
+
image_event(image, IMAGE_EVENT_INITIALIZED);
}
TRACE(("%ld: init done.\n", find_thread(NULL)));
@@ -633,6 +645,12 @@ unload_library(void* handle, image_id imageID, bool addOn)
image_event(image, IMAGE_EVENT_UNINITIALIZING);
+ 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);
+ }
+
if (image->term_routine)
((init_term_function)image->term_routine)(image->id);
@@ -1017,6 +1035,12 @@ terminate_program(void)
image_event(image, IMAGE_EVENT_UNINITIALIZING);
+ if (image->term_array) {
+ uint count_term = image->term_array_len /
sizeof(addr_t);
+ for (uint j = count_term; j-- > 0;)
+
((init_term_function)image->term_array[j])(image->id);
+ }
+
if (image->term_routine)
((init_term_function)image->term_routine)(image->id);
diff --git a/src/system/runtime_loader/elf_load_image.cpp
b/src/system/runtime_loader/elf_load_image.cpp
index 73ffad1..7181562 100644
--- a/src/system/runtime_loader/elf_load_image.cpp
+++ b/src/system/runtime_loader/elf_load_image.cpp
@@ -339,6 +339,33 @@ parse_dynamic_segment(image_t* image)
}
break;
}
+ case DT_INIT_ARRAY:
+ // array of pointers to initialization functions
+ image->init_array = (addr_t*)
+ (d[i].d_un.d_ptr +
image->regions[0].delta);
+ break;
+ case DT_INIT_ARRAYSZ:
+ // size in bytes of the array of initialization
functions
+ image->init_array_len = d[i].d_un.d_val;
+ break;
+ case DT_PREINIT_ARRAY:
+ // array of pointers to pre-initialization
functions
+ image->preinit_array = (addr_t*)
+ (d[i].d_un.d_ptr +
image->regions[0].delta);
+ break;
+ case DT_PREINIT_ARRAYSZ:
+ // size in bytes of the array of
pre-initialization functions
+ image->preinit_array_len = d[i].d_un.d_val;
+ break;
+ case DT_FINI_ARRAY:
+ // array of pointers to termination functions
+ image->term_array = (addr_t*)
+ (d[i].d_un.d_ptr +
image->regions[0].delta);
+ break;
+ case DT_FINI_ARRAYSZ:
+ // size in bytes of the array of termination
functions
+ image->term_array_len = d[i].d_un.d_val;
+ break;
default:
continue;
@@ -348,9 +375,6 @@ parse_dynamic_segment(image_t* image)
// DT_SYMENT: The size of a symbol table entry.
// DT_PLTREL: The type of the PLT relocation entries
(DT_JMPREL).
// DT_BIND_NOW/DF_BIND_NOW: No lazy binding allowed.
- // DT_INIT_ARRAY[SZ], DT_FINI_ARRAY[SZ]:
Initialization/termination
- // function arrays.
- // DT_PREINIT_ARRAY[SZ]: Preinitialization function
array.
// DT_RUNPATH: Library search path (supersedes
DT_RPATH).
// DT_TEXTREL/DF_TEXTREL: Indicates whether text
relocations are
// required (for optimization purposes
only).