I just read about init and fini sections in ELF files and gave it a try:
#include
int main(){
puts(\"main\");
return 0;
}
void init(){
put
It is not a bug in ld
but in the glibc startup code for the main executable. For shared objects the function set by the -init
option is called.
ld
adding the options -init
and -fini
.
_init
function of the program isn't called from file glibc-2.21/elf/dl-init.c:58 by the DT_INIT
entry by the dynamic linker, but called from __libc_csu_init
in file glibc-2.21/csu/elf-init.c:83 by the main executable.
That is, the function pointer in DT_INIT
of the program is ignored by the startup.
If you compile with -static
, fini
isn't called, too.
DT_INIT
and DT_FINI
should definitely not be used, because they are old-style, see line 255.
The following works:
#include
static void preinit(int argc, char **argv, char **envp) {
puts(__FUNCTION__);
}
static void init(int argc, char **argv, char **envp) {
puts(__FUNCTION__);
}
static void fini(void) {
puts(__FUNCTION__);
}
__attribute__((section(".preinit_array"), used)) static typeof(preinit) *preinit_p = preinit;
__attribute__((section(".init_array"), used)) static typeof(init) *init_p = init;
__attribute__((section(".fini_array"), used)) static typeof(fini) *fini_p = fini;
int main(void) {
puts(__FUNCTION__);
return 0;
}
$ gcc -Wall a.c
$ ./a.out
preinit
init
main
fini
$