[LD][AARCH64]Add TLSDESC support for large memory model.

bfd/

2015-10-02  Renlin Li <renlin.li@arm.com>

	* elfnn-aarch64.c (aarch64_tls_transition_without_check):  Add
	relax transitions for TLSDESC_ADD, TLSDESC_LDR, TLSDESC_OFF_G0_NC,
	TLSDESC_OFF_G1.
	(aarch64_tls_transition_without_check): Add relaxation support.
	(aarch64_reloc_got_type): Add support.
	(elfNN_aarch64_final_link_relocate): Likewise.
	(elfNN_aarch64_tls_relax): Likewise.
	(elfNN_aarch64_relocate_section): Likewise.
	(elfNN_aarch64_gc_sweep_hook): Likewise.
	(elfNN_aarch64_check_relocs): Likewise.
	* elfxx-aarch64.c (_bfd_aarch64_elf_put_addend): Likewise.
	(_bfd_aarch64_elf_resolve_relocation): Likewise.

ld/testsuite/

2015-10-02  Renlin Li <renlin.li@arm.com>

	* ld-aarch64/aarch64-elf.exp: Run new test.
	* ld-aarch64/tls-large-desc.d: New.
	* ld-aarch64/tls-large-desc.s: New.
	* ld-aarch64/tls-relax-large-desc-ie.d: New.
	* ld-aarch64/tls-relax-large-desc-ie.s: New.
	* ld-aarch64/tls-relax-large-desc-le.d: New.
	* ld-aarch64/tls-relax-large-desc-le.s: New.
This commit is contained in:
Renlin Li 2015-10-02 17:43:08 +01:00
parent 43a357f99f
commit 0484b4549e
11 changed files with 266 additions and 3 deletions

View File

@ -1,3 +1,18 @@
2015-10-02 Renlin Li <renlin.li@arm.com>
* elfnn-aarch64.c (aarch64_tls_transition_without_check): Add
relax transitions for TLSDESC_ADD, TLSDESC_LDR, TLSDESC_OFF_G0_NC,
TLSDESC_OFF_G1.
(aarch64_tls_transition_without_check): Add relaxation support.
(aarch64_reloc_got_type): Add support.
(elfNN_aarch64_final_link_relocate): Likewise.
(elfNN_aarch64_tls_relax): Likewise.
(elfNN_aarch64_relocate_section): Likewise.
(elfNN_aarch64_gc_sweep_hook): Likewise.
(elfNN_aarch64_check_relocs): Likewise.
* elfxx-aarch64.c (_bfd_aarch64_elf_put_addend): Likewise.
(_bfd_aarch64_elf_resolve_relocation): Likewise.
2015-10-02 Renlin Li <renlin.li@arm.com>
* elfnn-aarch64.c (elfNN_aarch64_howto_table): Check overflow for

View File

@ -209,12 +209,17 @@
|| IS_AARCH64_TLSDESC_RELOC ((R_TYPE)))
#define IS_AARCH64_TLS_RELAX_RELOC(R_TYPE) \
((R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_ADD_LO12_NC \
((R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_ADD \
|| (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_ADD_LO12_NC \
|| (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21 \
|| (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_ADR_PREL21 \
|| (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_CALL \
|| (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_LD_PREL19 \
|| (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_LDNN_LO12_NC \
|| (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_LDR \
|| (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_OFF_G0_NC \
|| (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_OFF_G1 \
|| (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_LDR \
|| (R_TYPE) == BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21 \
|| (R_TYPE) == BFD_RELOC_AARCH64_TLSGD_ADR_PREL21 \
|| (R_TYPE) == BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC \
@ -4432,6 +4437,21 @@ aarch64_tls_transition_without_check (bfd_reloc_code_real_type r_type,
? BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1
: BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19);
case BFD_RELOC_AARCH64_TLSDESC_LDR:
return (is_local
? BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0_NC
: BFD_RELOC_AARCH64_NONE);
case BFD_RELOC_AARCH64_TLSDESC_OFF_G0_NC:
return (is_local
? BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1_NC
: BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC);
case BFD_RELOC_AARCH64_TLSDESC_OFF_G1:
return (is_local
? BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G2
: BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G1);
case BFD_RELOC_AARCH64_TLSDESC_LDNN_LO12_NC:
case BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC:
return (is_local
@ -4452,6 +4472,7 @@ aarch64_tls_transition_without_check (bfd_reloc_code_real_type r_type,
? BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_HI12
: BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19);
case BFD_RELOC_AARCH64_TLSDESC_ADD:
case BFD_RELOC_AARCH64_TLSDESC_ADD_LO12_NC:
case BFD_RELOC_AARCH64_TLSDESC_CALL:
/* Instructions with these relocations will become NOPs. */
@ -4507,6 +4528,7 @@ aarch64_reloc_got_type (bfd_reloc_code_real_type r_type)
case BFD_RELOC_AARCH64_TLSLD_ADR_PREL21:
return GOT_TLS_GD;
case BFD_RELOC_AARCH64_TLSDESC_ADD:
case BFD_RELOC_AARCH64_TLSDESC_ADD_LO12_NC:
case BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21:
case BFD_RELOC_AARCH64_TLSDESC_ADR_PREL21:
@ -4514,6 +4536,9 @@ aarch64_reloc_got_type (bfd_reloc_code_real_type r_type)
case BFD_RELOC_AARCH64_TLSDESC_LD32_LO12_NC:
case BFD_RELOC_AARCH64_TLSDESC_LD64_LO12_NC:
case BFD_RELOC_AARCH64_TLSDESC_LD_PREL19:
case BFD_RELOC_AARCH64_TLSDESC_LDR:
case BFD_RELOC_AARCH64_TLSDESC_OFF_G0_NC:
case BFD_RELOC_AARCH64_TLSDESC_OFF_G1:
return GOT_TLSDESC_GD;
case BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21:
@ -5137,7 +5162,9 @@ elfNN_aarch64_final_link_relocate (reloc_howto_type *howto,
switch (bfd_r_type)
{
case BFD_RELOC_AARCH64_NONE:
case BFD_RELOC_AARCH64_TLSDESC_ADD:
case BFD_RELOC_AARCH64_TLSDESC_CALL:
case BFD_RELOC_AARCH64_TLSDESC_LDR:
*unresolved_reloc_p = FALSE;
return bfd_reloc_ok;
@ -5538,13 +5565,11 @@ elfNN_aarch64_final_link_relocate (reloc_howto_type *howto,
*unresolved_reloc_p = FALSE;
break;
case BFD_RELOC_AARCH64_TLSDESC_ADD:
case BFD_RELOC_AARCH64_TLSDESC_ADD_LO12_NC:
case BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21:
case BFD_RELOC_AARCH64_TLSDESC_ADR_PREL21:
case BFD_RELOC_AARCH64_TLSDESC_LD32_LO12_NC:
case BFD_RELOC_AARCH64_TLSDESC_LD64_LO12_NC:
case BFD_RELOC_AARCH64_TLSDESC_LDR:
case BFD_RELOC_AARCH64_TLSDESC_LD_PREL19:
if (globals->root.sgot == NULL)
return bfd_reloc_notsupported;
@ -5558,6 +5583,24 @@ elfNN_aarch64_final_link_relocate (reloc_howto_type *howto,
*unresolved_reloc_p = FALSE;
break;
case BFD_RELOC_AARCH64_TLSDESC_OFF_G0_NC:
case BFD_RELOC_AARCH64_TLSDESC_OFF_G1:
if (globals->root.sgot == NULL)
return bfd_reloc_notsupported;
value = (symbol_tlsdesc_got_offset (input_bfd, h, r_symndx)
+ globals->root.sgotplt->output_section->vma
+ globals->root.sgotplt->output_offset
+ globals->sgotplt_jump_table_size);
value -= (globals->root.sgot->output_section->vma
+ globals->root.sgot->output_offset);
value = _bfd_aarch64_elf_resolve_relocation (bfd_r_type, place, value,
0, weak_undef_p);
*unresolved_reloc_p = FALSE;
break;
default:
return bfd_reloc_notsupported;
}
@ -5817,6 +5860,7 @@ elfNN_aarch64_tls_relax (struct elf_aarch64_link_hash_table *globals,
return bfd_reloc_continue;
}
case BFD_RELOC_AARCH64_TLSDESC_ADD:
case BFD_RELOC_AARCH64_TLSDESC_ADD_LO12_NC:
case BFD_RELOC_AARCH64_TLSDESC_CALL:
/* GD->IE/LE relaxation:
@ -5826,6 +5870,55 @@ elfNN_aarch64_tls_relax (struct elf_aarch64_link_hash_table *globals,
bfd_putl32 (INSN_NOP, contents + rel->r_offset);
return bfd_reloc_ok;
case BFD_RELOC_AARCH64_TLSDESC_LDR:
if (is_local)
{
/* GD->LE relaxation:
ldr xd, [gp, xn] => movk x0, #:tprel_g0_nc:var
*/
bfd_putl32 (0xf2800000, contents + rel->r_offset);
return bfd_reloc_continue;
}
else
{
/* GD->IE relaxation:
ldr xd, [gp, xn] => ldr x0, [gp, xn]
*/
insn = bfd_getl32 (contents + rel->r_offset);
insn &= 0xffffffe0;
bfd_putl32 (insn, contents + rel->r_offset);
return bfd_reloc_ok;
}
case BFD_RELOC_AARCH64_TLSDESC_OFF_G0_NC:
/* GD->LE relaxation:
movk xd, #:tlsdesc_off_g0_nc:var => movk x0, #:tprel_g1_nc:var, lsl #16
GD->IE relaxation:
movk xd, #:tlsdesc_off_g0_nc:var => movk xd, #:gottprel_g0_nc:var
*/
if (is_local)
bfd_putl32 (0xf2a00000, contents + rel->r_offset);
return bfd_reloc_continue;
case BFD_RELOC_AARCH64_TLSDESC_OFF_G1:
if (is_local)
{
/* GD->LE relaxation:
movz xd, #:tlsdesc_off_g1:var => movz x0, #:tprel_g2:var, lsl #32
*/
bfd_putl32 (0xd2c00000, contents + rel->r_offset);
return bfd_reloc_continue;
}
else
{
/* GD->IE relaxation:
movz xd, #:tlsdesc_off_g1:var => movz xd, #:gottprel_g1:var, lsl #16
*/
insn = bfd_getl32 (contents + rel->r_offset);
bfd_putl32 (0xd2a00000 | (insn & 0x1f), contents + rel->r_offset);
return bfd_reloc_continue;
}
case BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21:
/* IE->LE relaxation:
adrp xd, :gottprel:var => movz xd, :tprel_g1:var
@ -6240,6 +6333,8 @@ elfNN_aarch64_relocate_section (bfd *output_bfd,
case BFD_RELOC_AARCH64_TLSDESC_ADR_PREL21:
case BFD_RELOC_AARCH64_TLSDESC_LDNN_LO12_NC:
case BFD_RELOC_AARCH64_TLSDESC_LD_PREL19:
case BFD_RELOC_AARCH64_TLSDESC_OFF_G0_NC:
case BFD_RELOC_AARCH64_TLSDESC_OFF_G1:
if (! symbol_tlsdesc_got_offset_mark_p (input_bfd, h, r_symndx))
{
bfd_boolean need_relocs = FALSE;
@ -6623,6 +6718,8 @@ elfNN_aarch64_gc_sweep_hook (bfd *abfd,
case BFD_RELOC_AARCH64_TLSDESC_LD32_LO12_NC:
case BFD_RELOC_AARCH64_TLSDESC_LD64_LO12_NC:
case BFD_RELOC_AARCH64_TLSDESC_LD_PREL19:
case BFD_RELOC_AARCH64_TLSDESC_OFF_G0_NC:
case BFD_RELOC_AARCH64_TLSDESC_OFF_G1:
case BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC:
case BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21:
case BFD_RELOC_AARCH64_TLSGD_ADR_PREL21:
@ -7100,6 +7197,8 @@ elfNN_aarch64_check_relocs (bfd *abfd, struct bfd_link_info *info,
case BFD_RELOC_AARCH64_TLSDESC_LD32_LO12_NC:
case BFD_RELOC_AARCH64_TLSDESC_LD64_LO12_NC:
case BFD_RELOC_AARCH64_TLSDESC_LD_PREL19:
case BFD_RELOC_AARCH64_TLSDESC_OFF_G0_NC:
case BFD_RELOC_AARCH64_TLSDESC_OFF_G1:
case BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC:
case BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21:
case BFD_RELOC_AARCH64_TLSGD_ADR_PREL21:

View File

@ -333,6 +333,8 @@ _bfd_aarch64_elf_put_addend (bfd *abfd,
case BFD_RELOC_AARCH64_MOVW_G3:
case BFD_RELOC_AARCH64_MOVW_GOTOFF_G0_NC:
case BFD_RELOC_AARCH64_MOVW_GOTOFF_G1:
case BFD_RELOC_AARCH64_TLSDESC_OFF_G0_NC:
case BFD_RELOC_AARCH64_TLSDESC_OFF_G1:
case BFD_RELOC_AARCH64_TLSGD_MOVW_G0_NC:
case BFD_RELOC_AARCH64_TLSGD_MOVW_G1:
case BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC:
@ -424,6 +426,8 @@ _bfd_aarch64_elf_resolve_relocation (bfd_reloc_code_real_type r_type,
case BFD_RELOC_AARCH64_MOVW_G3:
case BFD_RELOC_AARCH64_MOVW_GOTOFF_G0_NC:
case BFD_RELOC_AARCH64_MOVW_GOTOFF_G1:
case BFD_RELOC_AARCH64_TLSDESC_OFF_G0_NC:
case BFD_RELOC_AARCH64_TLSDESC_OFF_G1:
case BFD_RELOC_AARCH64_TLSGD_MOVW_G0_NC:
case BFD_RELOC_AARCH64_TLSGD_MOVW_G1:
case BFD_RELOC_AARCH64_TLSLD_ADD_DTPREL_HI12:

View File

@ -1,3 +1,13 @@
2015-10-02 Renlin Li <renlin.li@arm.com>
* ld-aarch64/aarch64-elf.exp: Run new test.
* ld-aarch64/tls-large-desc.d: New.
* ld-aarch64/tls-large-desc.s: New.
* ld-aarch64/tls-relax-large-desc-ie.d: New.
* ld-aarch64/tls-relax-large-desc-ie.s: New.
* ld-aarch64/tls-relax-large-desc-le.d: New.
* ld-aarch64/tls-relax-large-desc-le.s: New.
2015-10-02 Renlin Li <renlin.li@arm.com>
* ld-aarch64/aarch64-elf.exp: run new test

View File

@ -183,6 +183,8 @@ run_dump_test "tls-relax-gdesc-le"
run_dump_test "tls-relax-gd-ie"
run_dump_test "tls-relax-large-gd-ie"
run_dump_test "tls-relax-large-gd-le"
run_dump_test "tls-relax-large-desc-ie"
run_dump_test "tls-relax-large-desc-le"
run_dump_test "tls-relax-gdesc-ie"
run_dump_test "tls-relax-ie-le"
run_dump_test "tls-relax-ld-le-small"
@ -200,6 +202,7 @@ run_dump_test "tls-tiny-desc-ie"
run_dump_test "tls-tiny-desc-le"
run_dump_test "tls-tiny-ie"
run_dump_test "tls-large-ie"
run_dump_test "tls-large-desc"
run_dump_test "tls-tiny-ld"
run_dump_test "tls-small-ld"
run_dump_test "tlsle"

View File

@ -0,0 +1,38 @@
#source: tls-large-desc.s
#ld: -shared -T relocs.ld -e0
#objdump: -dr
#...
Disassembly of section .text:
0000000000010000 \<test\>:
+10000: 58000101 ldr x1, 10020 \<test\+0x20\>
+10004: 100000e2 adr x2, 10020 \<test\+0x20\>
+10008: 8b020032 add x18, x1, x2
+1000c: d2a00000 movz x0, #0x0, lsl #16
+10010: f2800500 movk x0, #0x28
+10014: f8606a41 ldr x1, \[x18,x0\]
+10018: 8b000240 add x0, x18, x0
+1001c: d63f0020 blr x1
+10020: 0000ffe0 .word 0x0000ffe0
+10024: 00000000 .word 0x00000000
Disassembly of section .plt:
0000000000010028 <.plt>:
+10028: a9bf7bf0 stp x16, x30, \[sp,#-16\]!
+1002c: 90000090 adrp x16, 20000 \<_GLOBAL_OFFSET_TABLE_\>
+10030: f9401211 ldr x17, \[x16,#32\]
+10034: 91008210 add x16, x16, #0x20
+10038: d61f0220 br x17
+1003c: d503201f nop
+10040: d503201f nop
+10044: d503201f nop
+10048: a9bf0fe2 stp x2, x3, \[sp,#-16\]!
+1004c: 90000082 adrp x2, 20000 \<_GLOBAL_OFFSET_TABLE_\>
+10050: 90000083 adrp x3, 20000 \<_GLOBAL_OFFSET_TABLE_\>
+10054: f9400442 ldr x2, \[x2,#8\]
+10058: 91004063 add x3, x3, #0x10
+1005c: d61f0040 br x2
+10060: d503201f nop
+10064: d503201f nop

View File

@ -0,0 +1,17 @@
.global var
.text
test:
ldr x1, .Lgot
adr x2, .Lgot
add x18, x1, x2
movz x0, #:tlsdesc_off_g1:var
movk x0, #:tlsdesc_off_g0_nc:var
.tlsdescldr var
ldr x1, [x18, x0]
.tlsdescadd var
add x0, x18, x0
.tlsdesccall var
blr x1
.Lgot: .xword _GLOBAL_OFFSET_TABLE_ - .

View File

@ -0,0 +1,18 @@
#source: tls-relax-large-desc-ie.s
#ld: -T relocs.ld -e0
#objdump: -dr
#...
Disassembly of section .text:
0000000000010000 <test>:
+10000: 58000101 ldr x1, 10020 \<test\+0x20\>
+10004: 100000e2 adr x2, 10020 \<test\+0x20\>
+10008: 8b020032 add x18, x1, x2
+1000c: d2a00000 movz x0, #0x0, lsl #16
+10010: f2800100 movk x0, #0x8
+10014: f8606a40 ldr x0, \[x18,x0\]
+10018: d503201f nop
+1001c: d503201f nop
+10020: 0000ffe0 .word 0x0000ffe0
+10024: 00000000 .word 0x00000000

View File

@ -0,0 +1,21 @@
.global var
.section .tdata,"awT",%progbits
var:
.word 2
.text
test:
ldr x1, .Lgot
adr x2, .Lgot
add x18, x1, x2
movz x0, #:tlsdesc_off_g1:var
movk x0, #:tlsdesc_off_g0_nc:var
.tlsdescldr var
ldr x1, [x18, x0]
.tlsdescadd var
add x0, x18, x0
.tlsdesccall var
blr x1
.Lgot: .xword _GLOBAL_OFFSET_TABLE_ - .

View File

@ -0,0 +1,18 @@
#source: tls-relax-large-desc-le.s
#ld: -T relocs.ld -e0
#objdump: -dr
#...
Disassembly of section .text:
0000000000010000 <test>:
+10000: 58000101 ldr x1, 10020 \<test\+0x20\>
+10004: 100000e2 adr x2, 10020 \<test\+0x20\>
+10008: 8b020032 add x18, x1, x2
+1000c: d2c00000 movz x0, #0x0, lsl #32
+10010: f2a00000 movk x0, #0x0, lsl #16
+10014: f2800200 movk x0, #0x10
+10018: d503201f nop
+1001c: d503201f nop
+10020: 0000ffe0 .word 0x0000ffe0
+10024: 00000000 .word 0x00000000

View File

@ -0,0 +1,20 @@
.section .tdata
var:
.word 2
.text
test:
ldr x1, .Lgot
adr x2, .Lgot
add x18, x1, x2
movz x0, #:tlsdesc_off_g1:var
movk x0, #:tlsdesc_off_g0_nc:var
.tlsdescldr var
ldr x1, [x18, x0]
.tlsdescadd var
add x0, x18, x0
.tlsdesccall var
blr x1
.Lgot: .xword _GLOBAL_OFFSET_TABLE_ - .