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;
|
int rela_len;
|
||||||
elf_rel *pltrel;
|
elf_rel *pltrel;
|
||||||
int pltrel_len;
|
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;
|
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));
|
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)
|
if (image->init_routine != 0)
|
||||||
((init_term_function)image->init_routine)(image->id);
|
((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);
|
image_event(image, IMAGE_EVENT_INITIALIZED);
|
||||||
}
|
}
|
||||||
TRACE(("%ld: init done.\n", find_thread(NULL)));
|
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);
|
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)
|
if (image->term_routine)
|
||||||
((init_term_function)image->term_routine)(image->id);
|
((init_term_function)image->term_routine)(image->id);
|
||||||
|
|
||||||
@ -1017,6 +1035,12 @@ terminate_program(void)
|
|||||||
|
|
||||||
image_event(image, IMAGE_EVENT_UNINITIALIZING);
|
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)
|
if (image->term_routine)
|
||||||
((init_term_function)image->term_routine)(image->id);
|
((init_term_function)image->term_routine)(image->id);
|
||||||
|
|
||||||
|
@ -339,6 +339,33 @@ parse_dynamic_segment(image_t* image)
|
|||||||
}
|
}
|
||||||
break;
|
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:
|
default:
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@ -348,9 +375,6 @@ parse_dynamic_segment(image_t* image)
|
|||||||
// DT_SYMENT: The size of a symbol table entry.
|
// DT_SYMENT: The size of a symbol table entry.
|
||||||
// DT_PLTREL: The type of the PLT relocation entries (DT_JMPREL).
|
// DT_PLTREL: The type of the PLT relocation entries (DT_JMPREL).
|
||||||
// DT_BIND_NOW/DF_BIND_NOW: No lazy binding allowed.
|
// 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_RUNPATH: Library search path (supersedes DT_RPATH).
|
||||||
// DT_TEXTREL/DF_TEXTREL: Indicates whether text relocations are
|
// DT_TEXTREL/DF_TEXTREL: Indicates whether text relocations are
|
||||||
// required (for optimization purposes only).
|
// required (for optimization purposes only).
|
||||||
|
Loading…
Reference in New Issue
Block a user