aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavide Italiano <davide@freebsd.org>2015-03-24 06:22:45 +0000
committerDavide Italiano <davide@freebsd.org>2015-03-24 06:22:45 +0000
commit20f3da11e8760c994a0c9db9cab08f7442937201 (patch)
treeb3d28c29a1e635f3eafc6a5c15305bac74c6f22a
parent70a1b816cc0f7a58044dee0460f1a068ac8faf31 (diff)
downloadllvm-20f3da11e8760c994a0c9db9cab08f7442937201.zip
llvm-20f3da11e8760c994a0c9db9cab08f7442937201.tar.gz
llvm-20f3da11e8760c994a0c9db9cab08f7442937201.tar.bz2
[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
-rw-r--r--lld/lib/ReaderWriter/ELF/X86_64/X86_64LinkingContext.h1
-rw-r--r--lld/test/elf/gottpoff.test120
2 files changed, 121 insertions, 0 deletions
diff --git a/lld/lib/ReaderWriter/ELF/X86_64/X86_64LinkingContext.h b/lld/lib/ReaderWriter/ELF/X86_64/X86_64LinkingContext.h
index 8dd1738..2cc799a 100644
--- a/lld/lib/ReaderWriter/ELF/X86_64/X86_64LinkingContext.h
+++ b/lld/lib/ReaderWriter/ELF/X86_64/X86_64LinkingContext.h
@@ -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;
diff --git a/lld/test/elf/gottpoff.test b/lld/test/elf/gottpoff.test
new file mode 100644
index 0000000..9841ee1
--- /dev/null
+++ b/lld/test/elf/gottpoff.test
@@ -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
+...