diff options
author | Michael J. Spencer <bigcheesegs@gmail.com> | 2015-11-03 22:39:09 +0000 |
---|---|---|
committer | Michael J. Spencer <bigcheesegs@gmail.com> | 2015-11-03 22:39:09 +0000 |
commit | d77f0d2526e28611b09121324540e8faaa5cab1a (patch) | |
tree | 3f48354bb665064aff8c66de78cac0ab8efab906 | |
parent | 3bd1def3ecd425757373b44b01675eb1397bd58e (diff) | |
download | bcm5719-llvm-d77f0d2526e28611b09121324540e8faaa5cab1a.tar.gz bcm5719-llvm-d77f0d2526e28611b09121324540e8faaa5cab1a.zip |
[elf2] Implement R_X86_64_TPOFF32.
This does not support TPOFF32 relocations to local symbols as the address calculations are separate. Support for this will be a separate patch.
llvm-svn: 251998
-rw-r--r-- | lld/ELF/OutputSections.cpp | 3 | ||||
-rw-r--r-- | lld/ELF/OutputSections.h | 3 | ||||
-rw-r--r-- | lld/ELF/Target.cpp | 3 | ||||
-rw-r--r-- | lld/ELF/Writer.cpp | 4 | ||||
-rw-r--r-- | lld/test/elf2/tls.s | 64 |
5 files changed, 73 insertions, 4 deletions
diff --git a/lld/ELF/OutputSections.cpp b/lld/ELF/OutputSections.cpp index e3e3fef8be5..5007ba003fa 100644 --- a/lld/ELF/OutputSections.cpp +++ b/lld/ELF/OutputSections.cpp @@ -644,6 +644,9 @@ typename ELFFile<ELFT>::uintX_t lld::elf2::getSymVA(const SymbolBody &S) { case SymbolBody::DefinedRegularKind: { const auto &DR = cast<DefinedRegular<ELFT>>(S); InputSectionBase<ELFT> &SC = DR.Section; + if (DR.Sym.getType() == STT_TLS) + return SC.OutSec->getVA() + SC.getOffset(DR.Sym) - + Out<ELFT>::TlsInitImageVA; return SC.OutSec->getVA() + SC.getOffset(DR.Sym); } case SymbolBody::DefinedCommonKind: diff --git a/lld/ELF/OutputSections.h b/lld/ELF/OutputSections.h index 5a23c86411c..df173361da2 100644 --- a/lld/ELF/OutputSections.h +++ b/lld/ELF/OutputSections.h @@ -353,6 +353,7 @@ private: // globally accessible. Writer initializes them, so don't use them // until Writer is initialized. template <class ELFT> struct Out { + typedef typename llvm::object::ELFFile<ELFT>::uintX_t uintX_t; static DynamicSection<ELFT> *Dynamic; static GnuHashTableSection<ELFT> *GnuHashTab; static GotPltSection<ELFT> *GotPlt; @@ -370,6 +371,7 @@ template <class ELFT> struct Out { static StringTableSection<ELFT> *StrTab; static SymbolTableSection<ELFT> *DynSymTab; static SymbolTableSection<ELFT> *SymTab; + static uintX_t TlsInitImageVA; }; template <class ELFT> DynamicSection<ELFT> *Out<ELFT>::Dynamic; @@ -389,6 +391,7 @@ template <class ELFT> StringTableSection<ELFT> *Out<ELFT>::ShStrTab; template <class ELFT> StringTableSection<ELFT> *Out<ELFT>::StrTab; template <class ELFT> SymbolTableSection<ELFT> *Out<ELFT>::DynSymTab; template <class ELFT> SymbolTableSection<ELFT> *Out<ELFT>::SymTab; +template <class ELFT> typename Out<ELFT>::uintX_t Out<ELFT>::TlsInitImageVA; } } #endif diff --git a/lld/ELF/Target.cpp b/lld/ELF/Target.cpp index 0ebcf827d9d..7adc5c6de43 100644 --- a/lld/ELF/Target.cpp +++ b/lld/ELF/Target.cpp @@ -339,6 +339,9 @@ void X86_64TargetInfo::relocateOne(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type, error("R_X86_64_32S out of range"); write32le(Loc, SA); break; + case R_X86_64_TPOFF32: + write32le(Loc, SA); + break; default: error("unrecognized reloc " + Twine(Type)); } diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp index 4f8f623c740..fe87d926067 100644 --- a/lld/ELF/Writer.cpp +++ b/lld/ELF/Writer.cpp @@ -716,8 +716,10 @@ template <class ELFT> void Writer<ELFT>::assignAddresses() { } if ((Sec->getFlags() & SHF_ALLOC) && (Sec->getFlags() & SHF_TLS)) { - if (!TlsPhdr.p_vaddr) + if (!TlsPhdr.p_vaddr) { setPhdr(&TlsPhdr, PT_TLS, PF_R, FileOff, VA, 0, Sec->getAlign()); + Out<ELFT>::TlsInitImageVA = VA; + } if (Sec->getType() != SHT_NOBITS) VA = RoundUpToAlignment(VA, Sec->getAlign()); uintX_t TVA = RoundUpToAlignment(VA + ThreadBSSOffset, Sec->getAlign()); diff --git a/lld/test/elf2/tls.s b/lld/test/elf2/tls.s index 5b5fc4f822a..6b3cad13885 100644 --- a/lld/test/elf2/tls.s +++ b/lld/test/elf2/tls.s @@ -1,21 +1,34 @@ // REQUIRES: x86 // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t // RUN: ld.lld2 %t -o %tout -// RUN: llvm-readobj -sections -program-headers %tout | FileCheck %s +// RUN: llvm-readobj -symbols -sections -program-headers %tout | FileCheck %s +// RUN: llvm-objdump -d %tout | FileCheck %s --check-prefix=DIS .global _start _start: + movl %fs:a@tpoff, %eax + movl %fs:b@tpoff, %eax + movl %fs:c@tpoff, %eax + movl %fs:d@tpoff, %eax + .global a .section .tbss,"awT",@nobits +a: .long 0 + .global b .section .tdata,"awT",@progbits +b: .long 1 + .global c .section .thread_bss,"awT",@nobits +c: .long 0 + .global d .section .thread_data,"awT",@progbits +d: .long 2 // CHECK: Name: .tdata @@ -77,9 +90,9 @@ _start: // CHECK-NEXT: SHF_WRITE // CHECK-NEXT: ] -// 0x1100C = TBSS_ADDR + 4 +// 0x1200C = TBSS_ADDR + 4 -// CHECK-NEXT: Address: 0x1100C +// CHECK-NEXT: Address: 0x1200C // CHECK-NEXT: Offset: // CHECK-NEXT: Size: 4 // CHECK-NEXT: Link: @@ -88,11 +101,49 @@ _start: // CHECK-NEXT: EntrySize: // CHECK-NEXT: } +// CHECK: Symbols [ +// CHECK: Name: a +// CHECK-NEXT: Value: 0x8 +// CHECK-NEXT: Size: +// CHECK-NEXT: Binding: Global +// CHECK-NEXT: Type: TLS +// CHECK-NEXT: Other: 0 +// CHECK-NEXT: Section: .tbss +// CHECK-NEXT: } +// CHECK-NEXT: Symbol { +// CHECK-NEXT: Name: b +// CHECK-NEXT: Value: 0x0 +// CHECK-NEXT: Size: +// CHECK-NEXT: Binding: Global +// CHECK-NEXT: Type: TLS +// CHECK-NEXT: Other: 0 +// CHECK-NEXT: Section: .tdata +// CHECK-NEXT: } +// CHECK-NEXT: Symbol { +// CHECK-NEXT: Name: c +// CHECK-NEXT: Value: 0xC +// CHECK-NEXT: Size: +// CHECK-NEXT: Binding: Global +// CHECK-NEXT: Type: TLS +// CHECK-NEXT: Other: 0 +// CHECK-NEXT: Section: .thread_bss +// CHECK-NEXT: } +// CHECK-NEXT: Symbol { +// CHECK-NEXT: Name: d +// CHECK-NEXT: Value: 0x4 +// CHECK-NEXT: Size: +// CHECK-NEXT: Binding: Global +// CHECK-NEXT: Type: TLS +// CHECK-NEXT: Other: 0 +// CHECK-NEXT: Section: .thread_data +// CHECK-NEXT: } + // Check that the TLS NOBITS sections weren't added to the R/W PT_LOAD's size. // CHECK: ProgramHeaders [ // CHECK: Type: PT_LOAD // CHECK: Type: PT_LOAD +// CHECK: Type: PT_LOAD // CHECK: FileSize: 8 // CHECK-NEXT: MemSize: 8 // CHECK-NEXT: Flags [ @@ -110,3 +161,10 @@ _start: // CHECK-NEXT: ] // CHECK-NEXT: Alignment: // CHECK-NEXT: } + +// DIS: Disassembly of section .text: +// DIS-NEXT: _start: +// DIS-NEXT: 11000: {{.+}} movl %fs:8, %eax +// DIS-NEXT: 11008: {{.+}} movl %fs:0, %eax +// DIS-NEXT: 11010: {{.+}} movl %fs:12, %eax +// DIS-NEXT: 11018: {{.+}} movl %fs:4, %eax |