runtime_loader: add support for ELF init/term routine arrays.
* binutils 2.27 defaults to DT_INIT_ARRAY instead of DT_INIT.
This commit is contained in:
parent
1df36f2cee
commit
e340f717a4
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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).
|
||||
|
Loading…
Reference in New Issue
Block a user