A call to a protected symbols is generating a R_X86_64_PC32 relocation even though the linker cannot resolve that when generating a shared library. $ cat protected.c void __attribute__ ((visibility ("protected"))) foo (void) {} void bar (void) { return foo (); } $ gcc -fPIC protected.c $ objdump -r protected.o protected.o: file format elf64-x86-64 RELOCATION RECORDS FOR [.text]: OFFSET TYPE VALUE 000000000000000b R_X86_64_PC32 foo+0xfffffffffffffffc RELOCATION RECORDS FOR [.eh_frame]: OFFSET TYPE VALUE 0000000000000020 R_X86_64_PC32 .text 0000000000000040 R_X86_64_PC32 .text+0x0000000000000006 $ gcc -shared protected.o /usr/lib64/gcc-lib/x86_64-suse-linux/3.3.4/../../../../x86_64-suse-linux/bin/ld: protected.o: relocation R_X86_64_PC32 against `foo' can not be used when making a shared object; recompile with -fPIC /usr/lib64/gcc-lib/x86_64-suse-linux/3.3.4/../../../../x86_64-suse-linux/bin/ld: final link failed: Bad value collect2: ld returned 1 exit status
The error message is wrong. I don't see anything wrong with an input file having an R_X86_64_PC32 to a protected symbol. The linker should resolve this without emitting a dynamic relocation to the shared lib.
It is too bad that you can't tell if a relocation is for branch or for load/store.
Fixed by http://sourceware.org/ml/binutils-cvs/2005-02/msg00011.html