non-virtual thunk code produced without -fPIC (regardless if function has __attribute((visibility("hidden"))) or not) is (seems correct): _ZThn16_N18nsDirectoryService6AddRefEv: addq $-16, %rdi jmp _ZN18nsDirectoryService6AddRefEv The same thunk code produced with -fPIC for function w/o visibility("hidden") attribute (still seems correct): _ZThn16_N18nsDirectoryService6AddRefEv: addq $-16, %rdi jmp *_ZN18nsDirectoryService6AddRefEv@GOTPCREL(%rip) But with -fPIC for function with visibility("hidden") attribute it's: _ZThn16_N18nsDirectoryService6AddRefEv: addq $-16, %rdi jmp _ZN18nsDirectoryService6AddRefEv(%rip) i.e. indirect jump with function address, which tries to take function code as its address and jump there... causing SEGV. Tested with gcc 3.3.3 and 3.3.4.
Created attachment 6580 [details] preprocessed source used as testcase I don't know how to make gcc produce thunk code in simple C++ code, so here is original preprocessed source (from mozilla-1.7 code) on which I discovered wrong behaviour. Just assemble it with g++ -S [-fPIC] nsDirectoryService.ii and check thunk code.
One more thing - assembler messages for wrong code (generated by g++ -S -fPIC): $ gcc -c xpcom/io/nsDirectoryService.s xpcom/io/nsDirectoryService.s: Assembler messages: xpcom/io/nsDirectoryService.s:795: Warning: indirect jmp without `*' xpcom/io/nsDirectoryService.s:803: Warning: indirect jmp without `*' xpcom/io/nsDirectoryService.s:876: Warning: indirect jmp without `*' xpcom/io/nsDirectoryService.s:884: Warning: indirect jmp without `*' xpcom/io/nsDirectoryService.s:988: Warning: indirect jmp without `*' xpcom/io/nsDirectoryService.s:996: Warning: indirect jmp without `*' xpcom/io/nsDirectoryService.s:1059: Warning: indirect jmp without `*' xpcom/io/nsDirectoryService.s:1080: Warning: indirect jmp without `*' xpcom/io/nsDirectoryService.s:1405: Warning: indirect jmp without `*' xpcom/io/nsDirectoryService.s:1540: Warning: indirect jmp without `*' xpcom/io/nsDirectoryService.s:1630: Warning: indirect jmp without `*' xpcom/io/nsDirectoryService.s:2202: Warning: indirect jmp without `*' xpcom/io/nsDirectoryService.s:2246: Warning: indirect jmp without `*'
I think this is all fixed for 3.4.0 as the way thunks are outputted have changed. Can you try 3.4.0?
Yes, thunk code generated by gcc 3.4.0 is different and doesn't have this bug. However I haven't checked if mozilla built with gcc 3.4.0 behaves correctly as we already have libstdc++.so.5 (gcc 3.3.x) based system and won't change this now.
Was fixed by: <http://gcc.gnu.org/ml/gcc-patches/2003-06/msg02603.html> because of this reason. This will not change for 3.3.x as this is not a regression and this is an invasive change which also requires another. 3.4.0 is out there for a reason. For most x86_64 targets you can use the hammer branch which has this patch in it and others which is makes x86_64 more usable.
Created attachment 6587 [details] thunk fix backport for 3.3.4 Just in case... this change extracted from mentioned change in gcc 3.4 branch seems to fix reported bug in gcc 3.3.4.