[Bug lto/78407] New: LTO breaks separate overriding of symbol aliases
srk31 at srcf dot ucam.org
gcc-bugzilla@gcc.gnu.org
Thu Nov 17 17:51:00 GMT 2016
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78407
Bug ID: 78407
Summary: LTO breaks separate overriding of symbol aliases
Product: gcc
Version: 5.2.1
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: lto
Assignee: unassigned at gcc dot gnu.org
Reporter: srk31 at srcf dot ucam.org
Target Milestone: ---
Created attachment 40073
--> https://gcc.gnu.org/bugzilla/attachment.cgi?id=40073&action=edit
Test case tarball
I have a library which tests, in a constructor function, whether another
library is overriding one of its symbols. If so, it skips initialization (since
the other library is taking care of it). This is necessary because constructors
cannot meaningfully be overridden.
To do this test, I create a hidden alias of the overridable symbol. This will
always point to our copy, even if the global alias gets overridden.
int foo = 0;
extern int our_foo __attribute__((visibility("hidden"),alias("foo")));
static void (__attribute__((constructor)) init)(void)
{
if (&our_foo != &foo)
{
/* skip init */
}
else
{
/* do init */
}
}
Building this library with LTO works fine on gcc 4.9.3 and earlier. On 5.x and
6.x the address comparison gets wrongly optimised away (tested on 5.2.1 and
6.2.0). In 4.9.x I get:
00000000000006c0 <init>:
6c0: 55 push %rbp
6c1: 48 89 e5 mov %rsp,%rbp
6c4: 48 8d 05 5e 09 20 00 lea 0x20095e(%rip),%rax
6cb: 48 8b 15 06 09 20 00 mov 0x200906(%rip),%rdx
6d2: 48 39 d0 cmp %rdx,%rax
6d5: 74 1a je 6f1 <init+0x31>
...
i.e. a cmp instruction, whereas with 5.2.1 there is none.
00000000000006b0 <init>:
6b0: 55 push %rbp
6b1: 48 89 e5 mov %rsp,%rbp
6b4: 48 8d 35 f5 ff ff ff lea -0xb(%rip),%rsi # 6b0 <init>
6bb: 48 8d 3d 17 00 00 00 lea 0x17(%rip),%rdi # 6d9 <_fini+0x9>
6c2: b8 00 00 00 00 mov $0x0,%eax
6c7: e8 c4 fe ff ff callq 590 <printf@plt@@Base>
6cc: 5d pop %rbp
6cd: c3 retq
Unless I'm mistaken: for any two ELF symbol aliases, if at least one has global
visibility, LTO cannot assume they will remain aliased at run time.
Tarball attached. On doing "make run", "lib1" should only claim to initialize
itself once, but it happens twice on 5.x+.
More information about the Gcc-bugs
mailing list