Bug 37611

Summary: invalid relocation R_386_GOTOFF when using protected function pointers
Product: gcc Reporter: Gernot Hillier, Siemens CT SE 2 <gernot.hillier>
Component: targetAssignee: Not yet assigned to anyone <unassigned>
Status: UNCONFIRMED ---    
Severity: normal CC: 3b87w8mt2n, gcc-bugs, jay.krell
Priority: P3    
Version: 4.3.2   
Target Milestone: ---   
See Also: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=19520
https://sourceware.org/bugzilla/show_bug.cgi?id=28875
https://sourceware.org/bugzilla/show_bug.cgi?id=28877
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98112
Host: i686-pc-linux-gnu Target: i686-pc-linux-gnu
Build: i686-pc-linux-gnu Known to work:
Known to fail: Last reconfirmed:
Bug Depends on: 35513    
Bug Blocks:    
Attachments: C file showing the problem
preprocessed version of the code triggering the bug

Description Gernot Hillier, Siemens CT SE 2 2008-09-22 07:16:39 UTC
When I try to use protected function pointers in a shared library, I experience strange behaviour: directly passing a function name triggers an invalid relocation during linking stage while it works when assigning the function name to a global variable first.

This report might be a duplicate to the old bug 19520, but I'm not sure as my knowledge about ELF internals is rather limited and I don't understand most of the discussion there, sorry. If this is a duplicate, please excuse.

Here's the output during compilation. Sources will follow in a few seconds:

$ LANG="" gcc -v -save-temps -Wall test2.c -o libtest2.so -shared -fPIC -fvisibility=hidden
Using built-in specs.
Target: i686-pc-linux-gnu
Configured with: ./configure --enable-languages=c,c++
Thread model: posix
gcc version 4.3.2 (GCC) 
COLLECT_GCC_OPTIONS='-v' '-save-temps' '-Wall' '-o' 'libtest2.so' '-shared' '-fPIC' '-fvisibility=hidden' '-mtune=generic'
 /usr/local/libexec/gcc/i686-pc-linux-gnu/4.3.2/cc1 -E -quiet -v test2.c -mtune=generic -Wall -fPIC -fvisibility=hidden -fpch-preprocess -o test2.i
ignoring nonexistent directory "/usr/local/lib/gcc/i686-pc-linux-gnu/4.3.2/../../../../i686-pc-linux-gnu/include"
#include "..." search starts here:
#include <...> search starts here:
 /usr/local/include
 /usr/local/lib/gcc/i686-pc-linux-gnu/4.3.2/include
 /usr/local/lib/gcc/i686-pc-linux-gnu/4.3.2/include-fixed
 /usr/include
End of search list.
COLLECT_GCC_OPTIONS='-v' '-save-temps' '-Wall' '-o' 'libtest2.so' '-shared' '-fPIC' '-fvisibility=hidden' '-mtune=generic'
 /usr/local/libexec/gcc/i686-pc-linux-gnu/4.3.2/cc1 -fpreprocessed test2.i -quiet -dumpbase test2.c -mtune=generic -auxbase test2 -Wall -version -fPIC -fvisibility=hidden -o test2.s
GNU C (GCC) version 4.3.2 (i686-pc-linux-gnu)
	compiled by GNU C version 4.3.2, GMP version 4.2.2, MPFR version 2.3.1.
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
Compiler executable checksum: 53913b99eaa90e1de01474d5b5d32b19
COLLECT_GCC_OPTIONS='-v' '-save-temps' '-Wall' '-o' 'libtest2.so' '-shared' '-fPIC' '-fvisibility=hidden' '-mtune=generic'
 as -V -Qy -o test2.o test2.s
GNU assembler version 2.18.0 (i486-linux-gnu) using BFD version (GNU Binutils for Ubuntu) 2.18.0.20080103
COMPILER_PATH=/usr/local/libexec/gcc/i686-pc-linux-gnu/4.3.2/:/usr/local/libexec/gcc/i686-pc-linux-gnu/4.3.2/:/usr/local/libexec/gcc/i686-pc-linux-gnu/:/usr/local/lib/gcc/i686-pc-linux-gnu/4.3.2/:/usr/local/lib/gcc/i686-pc-linux-gnu/
LIBRARY_PATH=/usr/local/lib/gcc/i686-pc-linux-gnu/4.3.2/:/usr/local/lib/gcc/i686-pc-linux-gnu/4.3.2/../../../:/lib/:/usr/lib/
COLLECT_GCC_OPTIONS='-v' '-save-temps' '-Wall' '-o' 'libtest2.so' '-shared' '-fPIC' '-fvisibility=hidden' '-mtune=generic'
 /usr/local/libexec/gcc/i686-pc-linux-gnu/4.3.2/collect2 --eh-frame-hdr -m elf_i386 -shared -o libtest2.so /usr/lib/crti.o /usr/local/lib/gcc/i686-pc-linux-gnu/4.3.2/crtbeginS.o -L/usr/local/lib/gcc/i686-pc-linux-gnu/4.3.2 -L/usr/local/lib/gcc/i686-pc-linux-gnu/4.3.2/../../.. test2.o -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed /usr/local/lib/gcc/i686-pc-linux-gnu/4.3.2/crtendS.o /usr/lib/crtn.o
/usr/bin/ld: test2.o: relocation R_386_GOTOFF against protected function `f2' can not be used when making a shared object
/usr/bin/ld: final link failed: Bad value
collect2: ld returned 1 exit status
Comment 1 Gernot Hillier, Siemens CT SE 2 2008-09-22 07:19:05 UTC
Created attachment 16375 [details]
C file showing the problem

See the body of f1 for the two cases. Using "f3( f2)" triggers the problem while "f3 (x)" works.
Comment 2 Gernot Hillier, Siemens CT SE 2 2008-09-22 07:21:49 UTC
Created attachment 16376 [details]
preprocessed version of the code triggering the bug
Comment 3 Drake Wilson 2010-01-06 21:01:15 UTC
As a data point, this occurs for me with GCC 4.3.4 (Debian 4.3.4-6) on AMD64 (x86_64), compiling the given test file as C:

$ gcc -c -o test2.o test2.c && gcc -shared -o test2.so test2.o
/usr/bin/ld: test2.o: relocation R_X86_64_32 against `f2' can not be used when making a shared object; recompile with -fPIC
test2.o: could not read symbols: Bad value
collect2: ld returned 1 exit status
Comment 4 Drake Wilson 2010-01-06 21:27:34 UTC
Er, sorry, that's the message from the wrong run.  Here's the right one:

$ gcc -fPIC -c -o test2.o test2.c && gcc -shared -o test2.so test2.o
/usr/bin/ld: test2.o: relocation R_X86_64_PC32 against protected symbol `f2' can not be used when making a shared object
/usr/bin/ld: final link failed: Bad value
collect2: ld returned 1 exit status
Comment 5 H.J. Lu 2010-01-06 23:27:07 UTC
Function pointer != function address in shared library.
"f2" is protected and the one defined in shared library
will be called. But its function pointer can be out
side of shared library. That is why R_X86_64_PC32
can't be used.

This bug can be fixed if PR 35513 is resolved.
Comment 6 Andrew Pinski 2010-05-17 13:49:28 UTC
*** Bug 44166 has been marked as a duplicate of this bug. ***