http://gcc.gnu.org/bugzilla/show_bug.cgi?id=55012
Bug #: 55012 Summary: Protected visibility wrongly uses GOT-relative addresses Classification: Unclassified Product: gcc Version: unknown Status: UNCONFIRMED Severity: normal Priority: P3 Component: target AssignedTo: unassig...@gcc.gnu.org ReportedBy: bug...@aerifal.cx Consider the shared library code: int a __attribute__((visibility("protected"))); int f() { return a; } For this (on i386 at least), gcc generates a GOT-relative (@GOTOFF) reference to "a" rather than a GOT lookup. This will then reference the wrong location if "a" is moved into the main program's data via a copy relocation, which will happen if the main program makes any references to "a". The issue is a subtlety in the semantics of protected visibility. As I understand it and as it's documented, it's supposed to convey the semantic that the definition will not be overridden in the sense of the abstract machine. Copy relocations are not a case of overriding the definition in the abstract machine, but an implementation detail used to support data objects in shared libraries when the main program is non-PIC. With the current behavior, GCC is requiring library authors using visibility to be aware of this implementation detail (which only applies on some targets) and avoid using visibility on these specific targets. That, in my mind, is unreasonable and buggy behavior. Note that where this came up is when trying to use #pragma to set visibility globally in a shared library; doing so broke global objects accessed from the main application, but otherwise behaved as expected.