[ELF/X86_64] Fix handling of R_X86_64_GOTTPOFF relocation.

The aforementioned relocation generate a GOT entry with a
R_X86_64_TPOFF64. The new relocation is processed at startup
time by the loader. lld didn't generate the outstanding relocation,
now it does. This bug was found while trying to link ls(1) on FreeBSD.

Simplified repro:
#include <stdio.h>
#include <wchar.h>
#include <wctype.h>

int
main(void)
{
    wchar_t wc = 98;
    if (!iswprint(wc))
        printf("blah\n");
    else
        printf("foo\n");
    return (0);
}

which incorrectly outputs "blah" when linked with lld before this patch.

llvm-svn: 233051
This commit is contained in:
Davide Italiano 2015-03-24 06:22:45 +00:00
parent 70a1b816cc
commit 20f3da11e8
2 changed files with 121 additions and 0 deletions

View File

@ -49,6 +49,7 @@ public:
case llvm::ELF::R_X86_64_COPY:
case llvm::ELF::R_X86_64_DTPMOD64:
case llvm::ELF::R_X86_64_DTPOFF64:
case llvm::ELF::R_X86_64_TPOFF64:
return true;
default:
return false;

120
lld/test/elf/gottpoff.test Normal file
View File

@ -0,0 +1,120 @@
# Test that GOTTPOFF reloc generates an outstanding R_X86_64_TPOFF64
# to be processed at startup time.
# Reference: Ulrich Drepper's "ELF Handling for Thread-Local storage"
#RUN: yaml2obj -format=elf %s -o %t.o
#RUN: lld -flavor gnu -target x86_64 %t.o -o %t -e=main --defsym=__tls_get_addr=0
#RUN: llvm-readobj -r %t | FileCheck %s
#
#CHECK: Section (5) .rela.dyn {
#CHECK: 0x401098 R_X86_64_TPOFF64 - 0x0
#CHECK: }
---
FileHeader:
Class: ELFCLASS64
Data: ELFDATA2LSB
OSABI: ELFOSABI_FREEBSD
Type: ET_REL
Machine: EM_X86_64
Sections:
- Name: .text
Type: SHT_PROGBITS
Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
AddressAlign: 0x0000000000000010
Content: E819000000640304250000000064030425000000006403042500000000C3488B0500000000648B00C3488D3D00000000E800000000488D8000000000C3
- Name: .rela.text
Type: SHT_RELA
Link: .symtab
AddressAlign: 0x0000000000000008
Info: .text
Relocations:
- Offset: 0x0000000000000009
Symbol: tls1
Type: R_X86_64_TPOFF32
- Offset: 0x0000000000000011
Symbol: tls0
Type: R_X86_64_TPOFF32
- Offset: 0x0000000000000019
Symbol: tls2
Type: R_X86_64_TPOFF32
- Offset: 0x0000000000000021
Symbol: tls2
Type: R_X86_64_GOTTPOFF
Addend: -4
- Offset: 0x000000000000002C
Symbol: tls0
Type: R_X86_64_TLSLD
Addend: -4
- Offset: 0x0000000000000031
Symbol: __tls_get_addr
Type: R_X86_64_PLT32
Addend: -4
- Offset: 0x0000000000000038
Symbol: tls0
Type: R_X86_64_DTPOFF32
- Name: .data
Type: SHT_PROGBITS
Flags: [ SHF_WRITE, SHF_ALLOC ]
AddressAlign: 0x0000000000000004
Content: ''
- Name: .bss
Type: SHT_NOBITS
Flags: [ SHF_WRITE, SHF_ALLOC ]
AddressAlign: 0x0000000000000004
Content: ''
- Name: .tbss
Type: SHT_NOBITS
Flags: [ SHF_WRITE, SHF_ALLOC, SHF_TLS ]
AddressAlign: 0x0000000000000004
Content: '01000000002E7265'
- Name: .tdata
Type: SHT_PROGBITS
Flags: [ SHF_WRITE, SHF_ALLOC, SHF_TLS ]
AddressAlign: 0x0000000000000004
Content: '01000000'
Symbols:
Local:
- Name: .text
Type: STT_SECTION
Section: .text
- Name: .data
Type: STT_SECTION
Section: .data
- Name: .bss
Type: STT_SECTION
Section: .bss
- Name: .tbss
Type: STT_SECTION
Section: .tbss
- Name: .tdata
Type: STT_SECTION
Section: .tdata
Global:
- Name: GOTTPOFF
Type: STT_FUNC
Section: .text
Value: 0x000000000000001E
- Name: TLSLD
Type: STT_FUNC
Section: .text
Value: 0x0000000000000029
- Name: main
Type: STT_FUNC
Section: .text
- Name: tls0
Type: STT_TLS
Section: .tbss
Size: 0x0000000000000004
- Name: tls1
Type: STT_TLS
Section: .tbss
Value: 0x0000000000000004
Size: 0x0000000000000004
- Name: tls2
Type: STT_TLS
Section: .tdata
Size: 0x0000000000000004
- Name: _GLOBAL_OFFSET_TABLE_
- Name: __tls_get_addr
...