Bug 22063 - link failure involving symbol visibility
Summary: link failure involving symbol visibility
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 4.0.1
: P2 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
Keywords: visibility
Depends on:
Reported: 2005-06-14 14:18 UTC by Dirk Mueller
Modified: 2006-04-19 19:23 UTC (History)
2 users (show)

See Also:
Target: i386-suse-linux
Known to work:
Known to fail:
Last reconfirmed:

testcase (3.61 KB, application/x-tbz)
2005-06-14 14:19 UTC, Dirk Mueller

Note You need to log in before you can comment on or make changes to this bug.
Description Dirk Mueller 2005-06-14 14:18:45 UTC
I'm experiencing a build failure in a rather complex project which boils  
down to a class compiled with two different visibilities. it fails with this  
error, but only when using -fPIC  
linkfoo.o: In function `foo::foo()': 
linkfoo.cc:(.gnu.linkonce.t._ZN3fooC1Ev[foo::foo()]+0x11): undefined reference 
to `vtable for foo' 
liblinkfoo.so: hidden symbol `vtable for foo' isn't defined 
/usr/lib/gcc/i586-suse-linux/4.0.1/../../../../i586-suse-linux/bin/ld: final 
link failed: Nonrepresentable section on output 
collect2: ld returned 1 exit status 
attaching testcase.
Comment 1 Dirk Mueller 2005-06-14 14:19:23 UTC
Created attachment 9088 [details]
Comment 2 Andrew Pinski 2005-06-14 15:49:38 UTC
I don't see anything wrong with the link error as you are saying that the class foo is only in liblinkfoo.so 
which is not true as the vtable is in libfoo.so.
Comment 3 Michael Matz 2005-06-14 16:13:09 UTC
No. The vtable itself (as all methods of class foo) is implemented in 
libfoo.so with default visibility, i.e. exported just fine: 
    25: 000017d8    12 OBJECT  WEAK   DEFAULT   20 vtable for foo 
Then there is liblinkfoo, which just refers to the vtable.  It is compiled 
with the pragma visibility in effect in the declaration of class foo (i.e. 
simulating a header declaring a class of a library, where the pragma 
was in effect).  That lib is linked against the above libfoo.so. 
And this results in the mentioned link error.  The reference to the vtable 
from linkfoo.o also looks just fine: 
    14: 00000000     0 NOTYPE  GLOBAL DEFAULT  UND vtable for foo 
i.e., UNDEF (and of course global, but that's irrelevant for a undef). 
This should not happen.  I could theorize, that this has something to do 
with the two definitions of the foo::foo ctor (in linkfoo.o it's hidden 
of course).  The "unresolvable" relocation is from that hidden implementation 
of foo::foo to the (global, exported in the other lib) vtable.  That 
implementation is also placed in a linkonce section, so that might be 
the reason too.  I changed the testcase a bit to implement the 
ctor out-of class, and removed the breakme method, i.e. it looks like so: 
#pragma GCC visibility push( hidden ) 
class foo { 
   virtual void bar(); 
foo::foo() {} 
(this is linkfoo.cc)  together with the other virtualclass.cc this 
still reproduces the same error.  Here no linkonce sections are involved. 
The only thing is that the foo ctor is defined twice (but in different 
shared libs, so no problem), in the second lib hidden.  It still has a 
reference to the vtable defined in the first lib, which is exported. 
Comment 4 Jason Merrill 2006-03-21 03:24:51 UTC
I believe that 'hidden' references must bind to a definition in the current .so, so this is not a bug.
Comment 5 Michael Matz 2006-03-21 13:59:55 UTC
There is no such thing as a hidden reference.  A symbol can be hidden,
then it's not exported and all references from inside DSO are directly bound
to it.  That's not the situation we have here.  We have a global exported
symbol ('vtable of foo') in libfoo.so, which somehow is not found by
the reference from inside liblinkfoo.so.  This might also be a linker error,
I don't know.
Comment 6 Geoff Keating 2006-04-19 19:23:55 UTC
I believe that the problem here is that you haven't defined foo::bar in linkfoo.so.  Because the foo in linkfoo.so is hidden, it is not the same foo as the foo in liblinkfoo.so.