[ELF/AArch64] Fix local TLS relocations

This patch fixes the R_AARCH64_TLSLE_ADD_TPREL_HI12 and R_AARCH64_TLSLE_ADD_TPREL_LO12_NC
handling by using the correct offset by using the target layout along with
aarch64 alignments requirements.

It fixes the TLS test-suite SingleSource failures for aarch64:

* SingleSource/UnitTests/Threads/2010-12-08-tls.execution_time
* SingleSource/UnitTests/Threads/tls.execution_time

llvm-svn: 238258
This commit is contained in:
Adhemerval Zanella 2015-05-26 21:49:39 +00:00
parent eeb9f3ce15
commit f3c1c065aa
5 changed files with 137 additions and 7 deletions

View File

@ -474,10 +474,15 @@ std::error_code AArch64TargetRelocationHandler::applyRelocation(
relocR_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC(loc, reloc, target, addend);
break;
case R_AARCH64_TLSLE_ADD_TPREL_HI12:
return relocR_AARCH64_TLSLE_ADD_TPREL_HI12(loc, reloc, target, addend);
case R_AARCH64_TLSLE_ADD_TPREL_LO12_NC:
relocR_AARCH64_TLSLE_ADD_TPREL_LO12_NC(loc, reloc, target, addend);
break;
case R_AARCH64_TLSLE_ADD_TPREL_LO12_NC: {
_tlsSize = _layout.getAlignedTLSSize();
if (ref.kindValue() == R_AARCH64_TLSLE_ADD_TPREL_HI12)
return relocR_AARCH64_TLSLE_ADD_TPREL_HI12(loc, reloc, target + _tlsSize,
addend);
else
relocR_AARCH64_TLSLE_ADD_TPREL_LO12_NC(loc, reloc, target + _tlsSize,
addend);
} break;
default:
return make_unhandled_reloc_error();
}

View File

@ -15,11 +15,21 @@
namespace lld {
namespace elf {
class AArch64TargetLayout;
class AArch64TargetRelocationHandler final : public TargetRelocationHandler {
public:
AArch64TargetRelocationHandler(AArch64TargetLayout &layout)
: _layout(layout) {}
std::error_code applyRelocation(ELFWriter &, llvm::FileOutputBuffer &,
const AtomLayout &,
const Reference &) const override;
private:
// Cached size of the TLS segment.
mutable uint64_t _tlsSize = 0;
AArch64TargetLayout &_layout;
};
} // end namespace elf

View File

@ -17,8 +17,8 @@ using namespace lld;
using namespace elf;
AArch64TargetHandler::AArch64TargetHandler(AArch64LinkingContext &ctx)
: _ctx(ctx), _targetLayout(new TargetLayout<ELF64LE>(ctx)),
_relocationHandler(new AArch64TargetRelocationHandler()) {}
: _ctx(ctx), _targetLayout(new AArch64TargetLayout(ctx)),
_relocationHandler(new AArch64TargetRelocationHandler(*_targetLayout)) {}
std::unique_ptr<Writer> AArch64TargetHandler::getWriter() {
switch (this->_ctx.getOutputELFType()) {

View File

@ -19,6 +19,19 @@ namespace lld {
namespace elf {
class AArch64LinkingContext;
class AArch64TargetLayout final : public TargetLayout<ELF64LE> {
public:
AArch64TargetLayout(ELFLinkingContext &ctx) : TargetLayout(ctx) {}
uint64_t getAlignedTLSSize() const {
return llvm::RoundUpToAlignment(TCB_ALIGNMENT, this->getTLSSize());
}
private:
// Alignment requirement for TCB.
enum { TCB_ALIGNMENT = 0x10 };
};
class AArch64TargetHandler final : public TargetHandler {
public:
AArch64TargetHandler(AArch64LinkingContext &ctx);
@ -39,7 +52,7 @@ public:
private:
AArch64LinkingContext &_ctx;
std::unique_ptr<TargetLayout<ELF64LE>> _targetLayout;
std::unique_ptr<AArch64TargetLayout> _targetLayout;
std::unique_ptr<AArch64TargetRelocationHandler> _relocationHandler;
};

View File

@ -0,0 +1,102 @@
# Check for correct offsets when handling relocations for local TLS
# access (R_AARCH64_TLSLE_ADD_TPREL_HI12, R_AARCH64_TLSLE_ADD_TPREL_LO12_NC)
# RUN: yaml2obj -format=elf %s > %t-obj
# RUN: lld -flavor gnu -target arm64 --noinhibit-exec -o %t-exe %t-obj
# RUN: llvm-objdump -s -t %t-exe | FileCheck %s
# CHECK: Contents of section .text:
# CHECK-NEXT: 4001dc 48d03bd5 08010091 08410091 090140b9 H.;......A....@.
# \_ | add x8, x8, #0x0 (R_AARCH64_TLSLE_ADD_TPREL_HI12)
# \_ add x8, x8, #0x10 (R_AARCH64_TLSLE_ADD_TPREL_LO12_NC)
---
FileHeader:
Class: ELFCLASS64
Data: ELFDATA2LSB
OSABI: ELFOSABI_GNU
Type: ET_REL
Machine: EM_AARCH64
Sections:
- Name: .text
Type: SHT_PROGBITS
Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
AddressAlign: 0x0000000000000004
Content: 48D03BD50801009108010091090140B9E003092AC0035FD6FD7BBFA9FD030091FF4300D1BFC31FB8F6FFFF97BF030091FD7BC1A8C0035FD6
- Name: .rela.text
Type: SHT_RELA
Link: .symtab
AddressAlign: 0x0000000000000008
Info: .text
Relocations:
- Offset: 0x0000000000000004
Symbol: a
Type: R_AARCH64_TLSLE_ADD_TPREL_HI12
- Offset: 0x0000000000000008
Symbol: a
Type: R_AARCH64_TLSLE_ADD_TPREL_LO12_NC
- 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: .tdata
Type: SHT_PROGBITS
Flags: [ SHF_WRITE, SHF_ALLOC, SHF_TLS ]
AddressAlign: 0x0000000000000004
Content: '04000000'
- Name: .comment
Type: SHT_PROGBITS
Flags: [ SHF_MERGE, SHF_STRINGS ]
AddressAlign: 0x0000000000000001
Content: 00636C616E672076657273696F6E20332E372E302028687474703A2F2F6C6C766D2E6F72672F6769742F636C616E672E6769742039636664333732343263346635623866393362636462343536366163636565373962306563653666292028687474703A2F2F6C6C766D2E6F72672F6769742F6C6C766D2E67697420653262383764656531656531393835396561383334313565616365333533666130323362646462302900
- Name: .note.GNU-stack
Type: SHT_PROGBITS
AddressAlign: 0x0000000000000001
Content: ''
Symbols:
Local:
- Name: '$d.1'
Type: STT_TLS
Section: .tdata
- Name: '$d.2'
Section: .comment
- Name: '$x.0'
Section: .text
- Name: .text
Type: STT_SECTION
Section: .text
- Name: .data
Type: STT_SECTION
Section: .data
- Name: .bss
Type: STT_SECTION
Section: .bss
- Name: .tdata
Type: STT_SECTION
Section: .tdata
- Name: .comment
Type: STT_SECTION
Section: .comment
- Name: .note.GNU-stack
Type: STT_SECTION
Section: .note.GNU-stack
Global:
- Name: a
Type: STT_TLS
Section: .tdata
Size: 0x0000000000000004
- Name: foo
Type: STT_FUNC
Section: .text
Size: 0x0000000000000018
- Name: main
Type: STT_FUNC
Section: .text
Value: 0x0000000000000018
Size: 0x0000000000000020
...