https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63842
Bug ID: 63842
Summary: x86-64 large PIC model may load the GOT base into the
wrong register
Product: gcc
Version: 5.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: target
Assignee: unassigned at gcc dot gnu.org
Reporter: hjl.tools at gmail dot com
CC: ubizjak at gmail dot com
Target: x86-64
According to x86-64 psABI, when PLT is more 2GB from GOT, linker must use
large model PLT layout:
PLT0: pushq 8(%r15) # GOT[1]
jmpq *16(%r15) # GOT[2]
That is fpr large PIC mode, if a function calls another function via PLT,
it must load GOT base into %r15 before making function call. However,
GCC generates:
[hjl@gnu-6 pr17592]$ cat foo.c
#include <stdio.h>
void
foo (void)
{
printf ("hello\n");
}
[hjl@gnu-6 pr17592]$ make foo.s
gcc -O2 -mcmodel=large -fpic -S foo.c
[hjl@gnu-6 pr17592]$ cat foo.s
.file "foo.c"
.section .rodata.str1.1,"aMS",@progbits,1
.LC0:
.string "hello"
.text
.p2align 4,,15
.globl foo
.type foo, @function
foo:
.LFB11:
.cfi_startproc
.L2:
leaq .L2(%rip), %rcx
movabsq $_GLOBAL_OFFSET_TABLE_-.L2, %r11
movabsq $.LC0@GOTOFF, %rax
addq %r11, %rcx
leaq (%rcx,%rax), %rdi
movabsq $puts@PLTOFF, %rax
addq %rcx, %rax
jmp *%rax
.cfi_endproc
.LFE11:
.size foo, .-foo
.ident "GCC: (GNU) 4.8.3 20140911 (Red Hat 4.8.3-7)"
.section .note.GNU-stack,"",@progbits
[hjl@gnu-6 pr17592]$
It works fine as long as large PLT layout isn't used. But it fails
when large PLT layout is used. Since puts is called via PLT, GCC
must load GOT base into %r15, instead of %r11.