http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51113
--- Comment #8 from Nathan Sidwell <nathan at acm dot org> 2011-11-15 20:12:33 UTC --- On 11/15/11 10:03, markus at trippelsdorf dot de wrote: > http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51113 > > With your patch: > % c++ -shared -w -o /dev/null -fPIC -fno-rtti -pthread -pipe > -fprofile-generate -O0 test.ii > /usr/lib/gcc/x86_64-pc-linux-gnu/4.7.0/../../../../x86_64-pc-linux-gnu/bin/ld: > error: /tmp/cciGbsuB.o: requires dynamic R_X86_64_PC32 reloc against > '__gcov0__ZnwmPv' which may overflow at runtime; recompile with -fPIC Ok, I think I understand what's going on here. Here's a piece of code to explain: inline int *Foo () { static int x = 2; return &x; } int *(*Bar ()) () { return Foo; } although Foo::x is in the same comdat group as Foo, it is separately overridable at load time by another shared object. (of course such overriding completely breaks language semantics, but not ELF semantics). The linker's adhering to ELF semantics, and in this example the compiler emits: movq _ZZ3FoovE1x@GOTPCREL(%rip), %rax to get Foo::x's address. In the gcov case, it's emitting: movq __gcov0_js_malloc(%rip), %rax to access the first counter value. Although I think that's ok in a well-formed program, it's confusing the linker. that's unfortunate. (If you compile the above example with -fprofile-generate you'll see different access sequences for _ZZ3FoovE1x and __gcov0__Z3Foov.) I'm going to have to figure out why the right PIC sequence isn't being emitted.