Weak undefined symbol doesn't work proper with PIE. I see it on x86, x86-64 and IPF. See http://gcc.gnu.org/ml/gcc/2006-01/msg01007.html The bug is in both ld.so and ld. I opened a ld bug, PR 2218.
Created attachment 854 [details] A testcase PIE built with the fixed linker, I got gcc -B./ -c -fPIC -g bar.c gcc -B./ -shared -o libbar.so bar.o #-z nocombreloc gcc -B./ -c -fPIC -g foo.c gcc -B./ -c -fPIC -g main.c gcc -B./ -c -fPIC -g dummy.c gcc -B./ -shared -o libdummy.so dummy.o #-z nocombreloc gcc -B./ -pie -o pie foo.o main.o libdummy.so -Wl,-z,nocombreloc -Wl,-rpath,. gcc -B./ -o exec foo.o main.o libdummy.so -Wl,-z,nocombreloc -Wl,-rpath,. cp -af libbar.so libdummy.so ./exec main foo PASSED ./pie main foo FAILED That is undefined weak symbol in PIE is resolved to a definition in libdummy.so unlike the normal executable.
A patch is posted at http://sources.redhat.com/ml/libc-alpha/2006-01/msg00152.html
I completely disagree. The main executable references undef_func. It's not available at link time. That's fine, it's a weak reference. Like every other weak reference every user has to check whether the pointer is NULL or not. But the fact that the symbol is not defined doesn't mean it should not be found at runtime. It should be treated like every other symbol not found in the executable itself (sans the error message from the linker). This means, the correct behavior is for the linker to emit a relocation for the symbol in which case the exec test case would also print FAILED. This is a bug in binutils.