* Richard Henderson: > On 06/05/2017 10:50 PM, Florian Weimer wrote: >> * Steve Ellcey: >> >>> I have a question about the use of IFUNCs in libatomic. I was looking at >>> the >>> arm implementation and in gcc/libatomic/config/linux/arm/host-config.h I >>> see: >>> >>> extern bool libat_have_strexbhd HIDDEN; >>> # define IFUNC_COND_1 libat_have_strexbhd >>> >>> I also see that gcc/libatomic/config/linux/arm/init.c has: >>> >>> bool libat_have_strexbhd; >>> static void __attribute__((constructor)) >>> init_cpu_revision (void) >>> { >>> } >>> >>> What I don't see is any place that libat_have_strexbhd would ever get >>> set. What am I missing here? init_cpu_revision is going to get called >>> when libatomic is first loaded since it is a constructor but it doesn't >>> seem to do anything and it isn't going to set libat_have_strexbhd as far >>> as I can see. >> >> Setting the variable in the constructor wouldn't influence IFUNC >> resolver behavior because those can run before ELF constructors >> (even with lazy binding). > > With lazy binding, the constructors of libraries should run in graph > dependency order, which means this constructor should run before any > users.
Except when another shared object uses the function from its own ELF constructor, and the libatomic constructor has not yet run. This should not happen if the object has a proper DT_NEEDED reference on libatomic, but strange things happen once LD_PRELOAD is involved. (There might also exist relocations which cannot be lazily bound, even if the object wasn't linked with BIND_NOW.) > Once upon a time, we didn't really have a way to get at either > AT_HWCAP or AT_PLATFORM from here. Since then, glibc has grown the > getauxval function. getauxval does not work from IFUNC handlers because it itself requires a relocation (which may not have been processed at this point), and it relies on global data which might not have been initialized. I think we would have to pass ways to reach the relevant data as IFUNC resolver arguments, and in addition fix the relocation processing in ld.so to delay IFUNC resolution after all other relocation processing. (I have an unfinished patch for the latter; I posted it to libc-alpha a while back.)