http://sourceware.org/bugzilla/show_bug.cgi?id=13249
Bug #: 13249 Summary: gold creates incorrect RELATIVE dynamic relocation for local IFUNC GOT entries Product: binutils Version: 2.23 (HEAD) Status: NEW Severity: normal Priority: P2 Component: gold AssignedTo: i...@airs.com ReportedBy: ccout...@google.com CC: ccout...@google.com Classification: Unclassified The ifuncmain7pie test fails when built with optimization turned off. It turns out that optimization doesn't make the bug go away, it just hides it. When compiling main() in ifuncmain7.c with optimization, the assignment p = foo() returns a pointer to foo_ifunc() instead of the PLT stub, but the optimizer has determined that the call (*p)() always goes to foo, so it makes the call directly to the PLT stub, and it works: Dump of assembler code for function main: 0x00000000000006f0 <+0>: push %rbp 0x00000000000006f1 <+1>: push %rbx 0x00000000000006f2 <+2>: sub $0x8,%rsp 0x00000000000006f6 <+6>: callq 0x6e0 <get_foo> 0x00000000000006fb <+11>: cmp 0x18de(%rip),%rax # 0x1fe0 0x0000000000000702 <+18>: mov %rax,%rbx 0x0000000000000705 <+21>: jne 0x753 <main+99> 0x0000000000000707 <+23>: callq 0x5a0 <abort@plt+16> The callq to abort@plt+16 jumps straight to the PLT stub. With unoptimized code, we have this: Dump of assembler code for function main: 0x00000000000006f1 <+0>: push %rbp 0x00000000000006f2 <+1>: mov %rsp,%rbp 0x00000000000006f5 <+4>: sub $0x10,%rsp 0x00000000000006f9 <+8>: callq 0x6e4 <get_foo> 0x00000000000006fe <+13>: mov %rax,-0x8(%rbp) 0x0000000000000702 <+17>: mov 0x18d7(%rip),%rax # 0x1fe0 0x0000000000000709 <+24>: cmp %rax,-0x8(%rbp) 0x000000000000070d <+28>: je 0x714 <main+35> 0x000000000000070f <+30>: callq 0x590 <abort@plt> 0x0000000000000714 <+35>: mov -0x8(%rbp),%rax 0x0000000000000718 <+39>: callq *%rax Here, the call is jumping via the pointer returned by the call to get_foo. In both cases, get_foo is actually returning the wrong pointer, and that's because the RELATIVE relocation for the GOT entry at 0x1fe0 has the wrong addend: Offset Info Type Symbol's Value Symbol's Name + Addend 0000000000001fe0 0000000000000008 R_X86_64_RELATIVE 00000000000006c5 The initialized value of the GOT entry is 0x05a0, which is the address of the PLT stub for the IFUNC symbol: Hex dump of section '.got': 0x00001fb0 90070000 00000000 a0070000 00000000 ................ 0x00001fc0 f1060000 00000000 00000000 00000000 ................ 0x00001fd0 00000000 00000000 00000000 00000000 ................ 0x00001fe0 a0050000 00000000 ........ But once the program starts, the dynamic linker applies the dynamic relocation, using the wrong addend, and it ends up pointing to the relocated value of 0x6c5, which is actually the entry point to the routine foo_ifunc(). -- Configure bugmail: http://sourceware.org/bugzilla/userprefs.cgi?tab=email ------- You are receiving this mail because: ------- You are on the CC list for the bug. _______________________________________________ bug-binutils mailing list bug-binutils@gnu.org https://lists.gnu.org/mailman/listinfo/bug-binutils