Bug 55012 - Protected visibility wrongly uses GOT-relative addresses
Summary: Protected visibility wrongly uses GOT-relative addresses
Status: RESOLVED DUPLICATE of bug 65248
Alias: None
Product: gcc
Classification: Unclassified
Component: target (show other bugs)
Version: unknown
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
Keywords: visibility
Depends on: 19520
  Show dependency treegraph
Reported: 2012-10-21 18:36 UTC by Rich Felker
Modified: 2019-06-14 18:09 UTC (History)
0 users

See Also:
Known to work:
Known to fail:
Last reconfirmed:


Note You need to log in before you can comment on or make changes to this bug.
Description Rich Felker 2012-10-21 18:36:44 UTC
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.
Comment 1 Rich Felker 2012-10-21 22:06:39 UTC
I'm not sure whether the fix should be in gcc/varasm.c, default_binds_local_p_1(), or in the config/i386/predicates.md, local_symbolic_operand predicate.

In the former, all non-default-visibility symbols are considered "local". In the latter, this "local" flag is used to determine that a got-relative offset would be allowed.

If varasm.c is modified, it should be to make protected symbols considered non-local. I don't know if this would hurt code generation on other archs that don't use copy relocations, however.

If predicated.md is to be modified, I don't see a good way, since the information on visibility seems to be lost at this point. Hidden symbols must continue to be considered local, but protected ones should not.
Comment 2 H.J. Lu 2015-03-06 13:28:11 UTC

*** This bug has been marked as a duplicate of bug 65248 ***