[ELF/AArch64] Fix correct TCB aligment calculation

This patch fixes the TLS local relocations alignment done by @238258.
As pointed out, the TLS size should not be considered, but rather the
TCB size based on maximum output segment alignment.  Although it has
not shown in the TLS simple cases for test-suite, more comprehensible
tests with more local TLS variable showed wrong relocations values
being generated.

The local TLS testcase is expanded to add more tls variable (both
exported and static) initialized or not.

llvm-svn: 238960
This commit is contained in:
Adhemerval Zanella 2015-06-03 20:39:30 +00:00
parent 90e0bd96ff
commit 4bcc13d988
4 changed files with 126 additions and 29 deletions

View File

@ -475,12 +475,12 @@ std::error_code AArch64TargetRelocationHandler::applyRelocation(
break;
case R_AARCH64_TLSLE_ADD_TPREL_HI12:
case R_AARCH64_TLSLE_ADD_TPREL_LO12_NC: {
_tlsSize = _layout.getAlignedTLSSize();
auto tpoffset = _layout.getTPOffset();
if (ref.kindValue() == R_AARCH64_TLSLE_ADD_TPREL_HI12)
return relocR_AARCH64_TLSLE_ADD_TPREL_HI12(loc, reloc, target + _tlsSize,
return relocR_AARCH64_TLSLE_ADD_TPREL_HI12(loc, reloc, target + tpoffset,
addend);
else
relocR_AARCH64_TLSLE_ADD_TPREL_LO12_NC(loc, reloc, target + _tlsSize,
relocR_AARCH64_TLSLE_ADD_TPREL_LO12_NC(loc, reloc, target + tpoffset,
addend);
} break;
default:

View File

@ -27,8 +27,6 @@ public:
const Reference &) const override;
private:
// Cached size of the TLS segment.
mutable uint64_t _tlsSize = 0;
AArch64TargetLayout &_layout;
};

View File

@ -20,16 +20,32 @@ namespace elf {
class AArch64LinkingContext;
class AArch64TargetLayout final : public TargetLayout<ELF64LE> {
typedef llvm::object::Elf_Shdr_Impl<ELF64LE> Elf_Shdr;
public:
AArch64TargetLayout(ELFLinkingContext &ctx) : TargetLayout(ctx) {}
uint64_t getAlignedTLSSize() const {
return llvm::RoundUpToAlignment(TCB_ALIGNMENT, this->getTLSSize());
uint64_t getTPOffset() {
std::call_once(_tpOffOnce, [this]() {
for (const auto &phdr : *_programHeader) {
if (phdr->p_type == llvm::ELF::PT_TLS) {
_tpOff = llvm::RoundUpToAlignment(TCB_SIZE, phdr->p_align);
break;
}
}
assert(_tpOff != 0 && "TLS segment not found");
});
return _tpOff;
}
private:
// Alignment requirement for TCB.
enum { TCB_ALIGNMENT = 0x10 };
enum {
TCB_SIZE = 16,
};
private:
uint64_t _tpOff = 0;
std::once_flag _tpOffOnce;
};
class AArch64TargetHandler final : public TargetHandler {

View File

@ -5,9 +5,24 @@
# 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)
# CHECK-NEXT: 4001dc 48d03bd5 08010091 08610091 090140b9 H.;......a....@.
# \_ | | <foo1>:
# \_ | add x8, x8, #0x0 (R_AARCH64_TLSLE_ADD_TPREL_HI12)
# \_ add x8, x8, #0x18 (R_AARCH64_TLSLE_ADD_TPREL_LO12_NC)
# CHECK-NEXT: 4001ec e003092a c0035fd6 48d03bd5 08010091 ...*.._.H.;.....
# \_ | <foo2>:
# \_ add x8, x8, #0x0 (R_AARCH64_TLSLE_ADD_TPREL_HI12)
# CHECK-NEXT: 4001fc 08710091 090140b9 e003092a c0035fd6 .q....@....*.._.
# \_ add x8, x8, #0x1c (R_AARCH64_TLSLE_ADD_TPREL_LO12_NC)
# CHECK-NEXT: 40020c 48d03bd5 08010091 08410091 090140b9 H.;......A....@.
# \_ | | <foo3>:
# \_ | add x8, x8, #0x0 (R_AARCH64_TLSLE_ADD_TPREL_HI12)
# \_ add x8, x8, #0x10 (R_AARCH64_TLSLE_ADD_TPREL_LO12_NC)
# CHECK-NEXT: 40021c e003092a c0035fd6 48d03bd5 08010091 ...*.._.H.;.....
# \_ | <foo3>:
# \_ add x8, x8, #0x0 (R_AARCH64_TLSLE_ADD_TPREL_HI12)
# CHECK-NEXT: 40022c 08510091 090140b9 e003092a c0035fd6 .Q....@....*.._.
# \_ add x8, x8, #0x14 (R_AARCH64_TLSLE_ADD_TPREL_LO12_NC)
---
FileHeader:
@ -21,7 +36,7 @@ Sections:
Type: SHT_PROGBITS
Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
AddressAlign: 0x0000000000000004
Content: 48D03BD50801009108010091090140B9E003092AC0035FD6FD7BBFA9FD030091FF4300D1BFC31FB8F6FFFF97BF030091FD7BC1A8C0035FD6
Content: 48D03BD50801009108010091090140B9E003092AC0035FD648D03BD50801009108010091090140B9E003092AC0035FD648D03BD50801009108010091090140B9E003092AC0035FD648D03BD50801009108010091090140B9E003092AC0035FD6FD7BBFA9FD030091FF8300D1BFC31FB8E4FFFF97A0831FB8E8FFFF97A0431FB8ECFFFF97E01300B9F0FFFF970800009008010091E00F00B9E00308AAA1835FB8A2435FB8E31340B9E40F40B900000094E1031F2AE00B00B9E003012ABF030091FD7BC1A8C0035FD6
- Name: .rela.text
Type: SHT_RELA
Link: .symtab
@ -29,11 +44,38 @@ Sections:
Info: .text
Relocations:
- Offset: 0x0000000000000004
Symbol: a
Symbol: v1
Type: R_AARCH64_TLSLE_ADD_TPREL_HI12
- Offset: 0x0000000000000008
Symbol: a
Symbol: v1
Type: R_AARCH64_TLSLE_ADD_TPREL_LO12_NC
- Offset: 0x000000000000001C
Symbol: v2
Type: R_AARCH64_TLSLE_ADD_TPREL_HI12
- Offset: 0x0000000000000020
Symbol: v2
Type: R_AARCH64_TLSLE_ADD_TPREL_LO12_NC
- Offset: 0x0000000000000034
Symbol: v3
Type: R_AARCH64_TLSLE_ADD_TPREL_HI12
- Offset: 0x0000000000000038
Symbol: v3
Type: R_AARCH64_TLSLE_ADD_TPREL_LO12_NC
- Offset: 0x000000000000004C
Symbol: v4
Type: R_AARCH64_TLSLE_ADD_TPREL_HI12
- Offset: 0x0000000000000050
Symbol: v4
Type: R_AARCH64_TLSLE_ADD_TPREL_LO12_NC
- Offset: 0x000000000000008C
Symbol: .rodata.str1.1
Type: R_AARCH64_ADR_PREL_PG_HI21
- Offset: 0x0000000000000090
Symbol: .rodata.str1.1
Type: R_AARCH64_ADD_ABS_LO12_NC
- Offset: 0x00000000000000AC
Symbol: printf
Type: R_AARCH64_CALL26
- Name: .data
Type: SHT_PROGBITS
Flags: [ SHF_WRITE, SHF_ALLOC ]
@ -48,12 +90,17 @@ Sections:
Type: SHT_PROGBITS
Flags: [ SHF_WRITE, SHF_ALLOC, SHF_TLS ]
AddressAlign: 0x0000000000000004
Content: '04000000'
- Name: .comment
Content: '0300000004000000'
- Name: .tbss
Type: SHT_NOBITS
Flags: [ SHF_WRITE, SHF_ALLOC, SHF_TLS ]
AddressAlign: 0x0000000000000004
Content: '2569202569202569'
- Name: .rodata.str1.1
Type: SHT_PROGBITS
Flags: [ SHF_MERGE, SHF_STRINGS ]
Flags: [ SHF_ALLOC, SHF_MERGE, SHF_STRINGS ]
AddressAlign: 0x0000000000000001
Content: 00636C616E672076657273696F6E20332E372E302028687474703A2F2F6C6C766D2E6F72672F6769742F636C616E672E6769742039636664333732343263346635623866393362636462343536366163636565373962306563653666292028687474703A2F2F6C6C766D2E6F72672F6769742F6C6C766D2E67697420653262383764656531656531393835396561383334313565616365333533666130323362646462302900
Content: 25692025692025692025690A00
- Name: .note.GNU-stack
Type: SHT_PROGBITS
AddressAlign: 0x0000000000000001
@ -64,9 +111,22 @@ Symbols:
Type: STT_TLS
Section: .tdata
- Name: '$d.2'
Section: .comment
Type: STT_TLS
Section: .tbss
- Name: '$d.3'
Section: .rodata.str1.1
- Name: '$x.0'
Section: .text
- Name: v2
Type: STT_TLS
Section: .tbss
Value: 0x0000000000000004
Size: 0x0000000000000004
- Name: v4
Type: STT_TLS
Section: .tdata
Value: 0x0000000000000004
Size: 0x0000000000000004
- Name: .text
Type: STT_SECTION
Section: .text
@ -79,24 +139,47 @@ Symbols:
- Name: .tdata
Type: STT_SECTION
Section: .tdata
- Name: .comment
- Name: .tbss
Type: STT_SECTION
Section: .comment
Section: .tbss
- Name: .rodata.str1.1
Type: STT_SECTION
Section: .rodata.str1.1
- Name: .note.GNU-stack
Type: STT_SECTION
Section: .note.GNU-stack
Global:
- Name: a
Type: STT_TLS
Section: .tdata
Size: 0x0000000000000004
- Name: foo
- Name: foo1
Type: STT_FUNC
Section: .text
Size: 0x0000000000000018
- Name: foo2
Type: STT_FUNC
Section: .text
Value: 0x0000000000000018
Size: 0x0000000000000018
- Name: foo3
Type: STT_FUNC
Section: .text
Value: 0x0000000000000030
Size: 0x0000000000000018
- Name: foo4
Type: STT_FUNC
Section: .text
Value: 0x0000000000000048
Size: 0x0000000000000018
- Name: main
Type: STT_FUNC
Section: .text
Value: 0x0000000000000018
Size: 0x0000000000000020
Value: 0x0000000000000060
Size: 0x0000000000000068
- Name: v1
Type: STT_TLS
Section: .tbss
Size: 0x0000000000000004
- Name: v3
Type: STT_TLS
Section: .tdata
Size: 0x0000000000000004
- Name: printf
...