On Sun, Feb 27, 2011 at 08:12:37 +0300, Valeriy E. Ushakov wrote: > On Fri, Feb 25, 2011 at 16:01:42 +0000, Antti Kantee wrote: > > > Module Name: src > > Committed By: pooka > > Date: Fri Feb 25 16:01:42 UTC 2011 > > > > Modified Files: > > src/lib/librumphijack: Makefile hijackdlsym.c > > > > Log Message: > > Ok, for reasons I can't begin to understand, the binaries I tested > > yesterday on powerpc broke overnight. Apparently adding one more > > function before the call to dlsym() fixes things again. I hope > > I don't have to add another one tomorrow .... > > > > > > To generate a diff of this commit: > > cvs rdiff -u -r1.7 -r1.8 src/lib/librumphijack/Makefile > > cvs rdiff -u -r1.1 -r1.2 src/lib/librumphijack/hijackdlsym.c > > I think this is caused by revision 1.121 of rtld.c (hi, mac!) that > added "hackish_return_address" for ppc. > > #ifdef __powerpc__ > static void * > hackish_return_address(void) > { > return __builtin_return_address(1); > } > #endif > > void * > dlsym(void *handle, const char *name) > { > ... > #ifdef __powerpc__ > retaddr = hackish_return_address(); > #else > retaddr = __builtin_return_address(0); > #endif > ... > } > > > hackish_return_address will be inlined (simple static function) and, > as far as I can tell, gcc does NOT adjust the "level" argument to > __builtin_return_address. > > The net effect is that dlsym uses caller's caller address to detect > which module the call comes from, and if caller's caller is in a > different module wrong things happen. > > That explains why you need an extra frame.
Actually, the real reason behind PR 37812 (that was supposed to be fixed by the hackish_return_address) might be similar to the issue with rumphijack_dlsym. If I read xorg-server/dist/hw/xfree86/loader correctly, you probably end up with dlsym being tail-called. My knowledge of ppc asm/abi is zero, so I can't really tell what goes on there or what went wrong in the original scenario, but I'd guess your hackish return gets inlined and with dlsym in tail-call position your caller's caller (unadjusted level "1") is in the main program and then luck is on your side, unless you do e.g. RTLD_NEXT. PS: <pooka> this probably calls for some atf tests for dlsym &co. -uwe