When you dlopen() a shared object, is there a mechanism for having code in that DLL execute without being called explicitly? Specifically, C++ static initialization code for globals/statics which the caller of dlopen() might not know about? I'm pretty sure the answer should be "yes" but I don't remember what mechanism makes that happen, and how to utilize it for running arbitrary code.
Yes: dlopen respects an ELF binary format mechanism for running code at load time.
There are actually two such mechanisms:
.init and .finis sections, which contain an array of function pointers for dlopen and dlclose to call. Since the sections may not be present at runtime, there are also DT_INIT and DT_FINI dynamic tags which point to the corresponding sections..init_array and .fini_array and corresponding DT_INIT_ARRAY, DT_INIT_ARRAYSZ, DT_FINI_ARRAY and DT_FINI_ARRAYSZ dynamic tags.The difference between the two mechanisms is described here.
Going up to the source code level, if you decorate a C function with __attribute__((constructor)), the compiler will use one of those two mechanisms to make it run when the object is dlopened. The same goes for the construction code for global C++ objects requiring dynamic initialization.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With