diff --git a/sys/kern/kern_linker.c b/sys/kern/kern_linker.c --- a/sys/kern/kern_linker.c +++ b/sys/kern/kern_linker.c @@ -657,6 +657,7 @@ return (NULL); lf->ctors_addr = 0; lf->ctors_size = 0; + lf->ctors_invoked = false; lf->dtors_addr = 0; lf->dtors_size = 0; lf->refs = 1; diff --git a/sys/kern/link_elf.c b/sys/kern/link_elf.c --- a/sys/kern/link_elf.c +++ b/sys/kern/link_elf.c @@ -358,7 +358,7 @@ } static void -link_elf_invoke_ctors(caddr_t addr, size_t size) +link_elf_invoke_cbs(caddr_t addr, size_t size) { void (**ctor)(void); size_t i, cnt; @@ -373,6 +373,16 @@ } } +static void +link_elf_invoke_ctors(linker_file_t lf) +{ + KASSERT(!lf->ctors_invoked, + ("%s: ctors already invoked", __func__)); + + link_elf_invoke_cbs(lf->ctors_addr, lf->ctors_size); + lf->ctors_invoked = true; +} + /* * Actions performed after linking/loading both the preloaded kernel and any * modules; whether preloaded or dynamicly loaded. @@ -403,7 +413,7 @@ #endif /* Invoke .ctors */ - link_elf_invoke_ctors(lf->ctors_addr, lf->ctors_size); + link_elf_invoke_ctors(lf); return (0); } diff --git a/sys/kern/link_elf_obj.c b/sys/kern/link_elf_obj.c --- a/sys/kern/link_elf_obj.c +++ b/sys/kern/link_elf_obj.c @@ -658,6 +658,23 @@ } } +static void +link_elf_invoke_ctors(linker_file_t lf) +{ + KASSERT(!lf->ctors_invoked, + ("%s: ctors already invoked", __func__)); + + link_elf_invoke_cbs(lf->ctors_addr, lf->ctors_size); + lf->ctors_invoked = true; +} + +static void +link_elf_invoke_dtors(linker_file_t lf) +{ + if (lf->ctors_invoked) + link_elf_invoke_cbs(lf->dtors_addr, lf->dtors_size); +} + static int link_elf_link_preload_finish(linker_file_t lf) { @@ -684,7 +701,7 @@ /* Apply protections now that relocation processing is complete. */ link_elf_protect(ef); - link_elf_invoke_cbs(lf->ctors_addr, lf->ctors_size); + link_elf_invoke_ctors(lf); return (0); } @@ -1239,7 +1256,7 @@ #endif link_elf_protect(ef); - link_elf_invoke_cbs(lf->ctors_addr, lf->ctors_size); + link_elf_invoke_ctors(lf); *result = lf; out: @@ -1259,7 +1276,7 @@ elf_file_t ef = (elf_file_t) file; u_int i; - link_elf_invoke_cbs(file->dtors_addr, file->dtors_size); + link_elf_invoke_dtors(file); /* Notify MD code that a module is being unloaded. */ elf_cpu_unload_file(file); diff --git a/sys/sys/linker.h b/sys/sys/linker.h --- a/sys/sys/linker.h +++ b/sys/sys/linker.h @@ -82,6 +82,7 @@ size_t size; /* size of file */ caddr_t ctors_addr; /* address of .ctors/.init_array */ size_t ctors_size; /* size of .ctors/.init_array */ + bool ctors_invoked; /* have we run ctors yet? */ caddr_t dtors_addr; /* address of .dtors/.fini_array */ size_t dtors_size; /* size of .dtors/.fini_array */ int ndeps; /* number of dependencies */