static bfd_reloc_code_real_type
aarch64_tls_transition_without_check (bfd_reloc_code_real_type r_type,
- struct elf_link_hash_entry *h)
+ struct elf_link_hash_entry *h,
+ struct bfd_link_info *info)
{
- bool is_local = h == NULL;
+ bool local_exec = bfd_link_executable (info)
+ && SYMBOL_REFERENCES_LOCAL (info, h);
switch (r_type)
{
case BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21:
case BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21:
- return (is_local
+ return (local_exec
? BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1
: BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21);
case BFD_RELOC_AARCH64_TLSDESC_ADR_PREL21:
- return (is_local
+ return (local_exec
? BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0_NC
: r_type);
case BFD_RELOC_AARCH64_TLSDESC_LD_PREL19:
- return (is_local
+ return (local_exec
? BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1
: BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19);
case BFD_RELOC_AARCH64_TLSDESC_LDR:
- return (is_local
+ return (local_exec
? BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0_NC
: BFD_RELOC_AARCH64_NONE);
case BFD_RELOC_AARCH64_TLSDESC_OFF_G0_NC:
- return (is_local
+ return (local_exec
? 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
+ return (local_exec
? 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
+ return (local_exec
? BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0_NC
: BFD_RELOC_AARCH64_TLSIE_LDNN_GOTTPREL_LO12_NC);
case BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21:
- return is_local ? BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1 : r_type;
+ return local_exec ? BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1 : r_type;
case BFD_RELOC_AARCH64_TLSIE_LDNN_GOTTPREL_LO12_NC:
- return is_local ? BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0_NC : r_type;
+ return local_exec ? BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0_NC : r_type;
case BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19:
return r_type;
case BFD_RELOC_AARCH64_TLSGD_ADR_PREL21:
- return (is_local
+ return (local_exec
? BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_HI12
: BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19);
case BFD_RELOC_AARCH64_TLSLD_ADD_LO12_NC:
case BFD_RELOC_AARCH64_TLSLD_ADR_PAGE21:
case BFD_RELOC_AARCH64_TLSLD_ADR_PREL21:
- return is_local ? BFD_RELOC_AARCH64_NONE : r_type;
+ return local_exec ? BFD_RELOC_AARCH64_NONE : r_type;
#if ARCH_SIZE == 64
case BFD_RELOC_AARCH64_TLSGD_MOVW_G0_NC:
- return is_local
+ return local_exec
? BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1_NC
: BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC;
case BFD_RELOC_AARCH64_TLSGD_MOVW_G1:
- return is_local
+ return local_exec
? BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G2
: BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G1;
#endif
if (! aarch64_can_relax_tls (input_bfd, info, bfd_r_type, h, r_symndx))
return bfd_r_type;
- return aarch64_tls_transition_without_check (bfd_r_type, h);
+ return aarch64_tls_transition_without_check (bfd_r_type, h, info);
}
/* Return the base VMA address which should be subtracted from real addresses
elfNN_aarch64_tls_relax (struct elf_aarch64_link_hash_table *globals,
bfd *input_bfd, asection *input_section,
bfd_byte *contents, Elf_Internal_Rela *rel,
- struct elf_link_hash_entry *h)
+ struct elf_link_hash_entry *h,
+ struct bfd_link_info *info)
{
- bool is_local = h == NULL;
+ bool local_exec = bfd_link_executable (info)
+ && SYMBOL_REFERENCES_LOCAL (info, h);
unsigned int r_type = ELFNN_R_TYPE (rel->r_info);
unsigned long insn;
{
case BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21:
case BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21:
- if (is_local)
+ if (local_exec)
{
/* GD->LE relaxation:
adrp x0, :tlsgd:var => movz R0, :tprel_g1:var
break;
case BFD_RELOC_AARCH64_TLSDESC_LD_PREL19:
- if (is_local)
+ if (local_exec)
{
/* Tiny TLSDESC->LE relaxation:
ldr x1, :tlsdesc:var => movz R0, #:tprel_g1:var
}
case BFD_RELOC_AARCH64_TLSGD_ADR_PREL21:
- if (is_local)
+ if (local_exec)
{
/* Tiny GD->LE relaxation:
adr x0, :tlsgd:var => mrs x1, tpidr_el0
BFD_ASSERT (rel->r_offset + 12 == rel[2].r_offset);
BFD_ASSERT (ELFNN_R_TYPE (rel[2].r_info) == AARCH64_R (CALL26));
- if (is_local)
+ if (local_exec)
{
/* Large GD->LE relaxation:
movz x0, #:tlsgd_g1:var => movz x0, #:tprel_g2:var, lsl #32
return bfd_reloc_continue;
case BFD_RELOC_AARCH64_TLSDESC_LDNN_LO12_NC:
- if (is_local)
+ if (local_exec)
{
/* GD->LE relaxation:
ldr xd, [x0, #:tlsdesc_lo12:var] => movk x0, :tprel_g0_nc:var
}
case BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC:
- if (is_local)
+ if (local_exec)
{
/* GD->LE relaxation
add x0, #:tlsgd_lo12:var => movk R0, :tprel_g0_nc:var
return bfd_reloc_ok;
case BFD_RELOC_AARCH64_TLSDESC_LDR:
- if (is_local)
+ if (local_exec)
{
/* GD->LE relaxation:
ldr xd, [gp, xn] => movk R0, #:tprel_g0_nc:var
movk xd, #:tlsdesc_off_g0_nc:var => movk Rd, #:gottprel_g0_nc:var
Where R is x for lp64 mode, and w for ILP32 mode. */
- if (is_local)
+ if (local_exec)
bfd_putl32 (ldr_hw_R0, contents + rel->r_offset);
return bfd_reloc_continue;
case BFD_RELOC_AARCH64_TLSDESC_OFF_G1:
- if (is_local)
+ if (local_exec)
{
/* GD->LE relaxation:
movz xd, #:tlsdesc_off_g1:var => movz R0, #:tprel_g2:var, lsl #32
adrp xd, :gottprel:var => movz Rd, :tprel_g1:var
Where R is x for lp64 mode, and w for ILP32 mode. */
- if (is_local)
+ if (local_exec)
{
insn = bfd_getl32 (contents + rel->r_offset);
bfd_putl32 (movz_R0 | (insn & 0x1f), contents + rel->r_offset);
ldr xd, [xm, #:gottprel_lo12:var] => movk Rd, :tprel_g0_nc:var
Where R is x for lp64 mode, and w for ILP32 mode. */
- if (is_local)
+ if (local_exec)
{
insn = bfd_getl32 (contents + rel->r_offset);
bfd_putl32 (movk_R0 | (insn & 0x1f), contents + rel->r_offset);
bl __tls_get_addr => add R0, R0, TCB_SIZE
Where R is x for lp64 mode, and w for ilp32 mode. */
- if (is_local)
+ if (local_exec)
{
BFD_ASSERT (rel->r_offset + 4 == rel[1].r_offset);
BFD_ASSERT (ELFNN_R_TYPE (rel[1].r_info) == AARCH64_R (CALL26));
/* LD->LE relaxation (small):
adrp x0, :tlsldm:x => mrs x0, tpidr_el0
*/
- if (is_local)
+ if (local_exec)
{
bfd_putl32 (0xd53bd040, contents + rel->r_offset);
return bfd_reloc_ok;
bl __tls_get_addr => nop
Where R is x for lp64 mode, and w for ilp32 mode. */
- if (is_local)
+ if (local_exec)
{
BFD_ASSERT (rel->r_offset + 4 == rel[1].r_offset);
BFD_ASSERT (ELFNN_R_TYPE (rel[1].r_info) == AARCH64_R (CALL26));
BFD_ASSERT (howto != NULL);
r_type = howto->type;
r = elfNN_aarch64_tls_relax (globals, input_bfd, input_section,
- contents, rel, h);
+ contents, rel, h, info);
unresolved_reloc = 0;
}
else
run_dump_test "tls-relax-gdesc-le"
run_dump_test "tls-relax-gdesc-le-now"
run_dump_test "tls-relax-gdesc-le-ilp32"
-run_dump_test "tls-relax-gd-ie"
-run_dump_test "tls-relax-gd-ie-ilp32"
-run_dump_test_lp64 "tls-relax-large-gd-ie"
-run_dump_test_lp64 "tls-relax-large-gd-ie-be"
run_dump_test_lp64 "tls-relax-large-gd-le"
run_dump_test_lp64 "tls-relax-large-gd-le-be"
-run_dump_test_lp64 "tls-relax-large-desc-ie"
-run_dump_test_lp64 "tls-relax-large-desc-ie-be"
-run_dump_test_lp64 "tls-relax-large-desc-le"
-run_dump_test_lp64 "tls-relax-large-desc-le-be"
-run_dump_test "tls-relax-gdesc-ie"
run_dump_test "tls-relax-ie-le"
run_dump_test "tls-relax-ie-le-ilp32"
run_dump_test "tls-relax-ld-le-small"
run_dump_test "tls-relax-ld-le-tiny-ilp32"
run_dump_test "tls-desc-ie"
run_dump_test "tls-desc-ie-ilp32"
-run_dump_test "tls-relax-gdesc-ie-2"
run_dump_test "tls-relax-gdesc-le-2"
run_dump_test "tls-relax-gdesc-le-2-ilp32"
run_dump_test "tls-relax-ie-le-2"
run_dump_test "tls-relax-ie-le-3"
run_dump_test "tls-relax-ie-le-3-ilp32"
run_dump_test "tls-tiny-gd"
-run_dump_test "tls-tiny-gd-ie"
-run_dump_test "tls-tiny-gd-ie-ilp32"
run_dump_test "tls-tiny-gd-le"
run_dump_test "tls-tiny-gd-le-ilp32"
run_dump_test "tls-tiny-desc"
-run_dump_test "tls-tiny-desc-ie"
-run_dump_test "tls-tiny-desc-ie-ilp32"
run_dump_test "tls-tiny-desc-le"
run_dump_test "tls-tiny-desc-le-ilp32"
run_dump_test "tls-tiny-ie"
run_dump_test_lp64 "pr22764"
run_dump_test_lp64 "pr20402"
+if {[check_shared_lib_support]
+ && [ld_assemble $as $srcdir/$subdir/tls-sharedlib.s tmpdir/tls-sharedlib.o]
+ && [ld_link $ld tmpdir/tls-sharedlib.so "-shared tmpdir/tls-sharedlib.o"] } {
+ run_dump_test "tls-relax-gd-ie"
+ run_dump_test_lp64 "tls-relax-large-gd-ie"
+ run_dump_test_lp64 "tls-relax-large-gd-ie-be"
+ run_dump_test_lp64 "tls-relax-large-desc-ie"
+ run_dump_test_lp64 "tls-relax-large-desc-ie-be"
+ run_dump_test_lp64 "tls-relax-large-desc-le"
+ run_dump_test_lp64 "tls-relax-large-desc-le-be"
+ run_dump_test "tls-relax-gdesc-ie"
+ run_dump_test "tls-relax-gdesc-ie-2"
+ run_dump_test "tls-tiny-gd-ie"
+ run_dump_test "tls-tiny-desc-ie"
+}
+if {[check_shared_lib_support]
+ && [ld_assemble_flags $as -mabi=ilp32 $srcdir/$subdir/tls-sharedlib.s tmpdir/tls-sharedlib.o]
+ && [ld_link $ld tmpdir/tls-sharedlib-ilp32.so "-shared tmpdir/tls-sharedlib.o -m [aarch64_choose_ilp32_emul]"] } {
+ run_dump_test "tls-relax-gd-ie-ilp32"
+ run_dump_test "tls-tiny-gd-ie-ilp32"
+ run_dump_test "tls-tiny-desc-ie-ilp32"
+}
+run_dump_test "tls-relax-gd-ie-2"
+run_dump_test "tls-relax-gd-ie-3"
+run_dump_test "tls-relax-ie-le-4"
+run_dump_test "tls-gd-symbolic"
+
# ifunc tests
run_dump_test "ifunc-1"
run_dump_test "ifunc-1-local"
--- /dev/null
+# Testcase to show that -Bsymbolic does not trigger any relaxation from general
+# dynamic or initial exec for global symbols.
+#target: [check_shared_lib_support]
+#ld: -shared -Bsymbolic
+#objdump: -d -j .text
+
+.*: file format .*
+
+
+Disassembly of section \.text:
+
+[0-9a-f]+ <_test_tls_desc>:
+ +[0-9a-f]+: ........ adrp x0, .*
+ +[0-9a-f]+: ........ ldr x1, \[x0, #.*\]
+ +[0-9a-f]+: ........ add x0, x0, .*
+ +[0-9a-f]+: d63f0020 blr x1
+
+[0-9a-f]+ <_test_tls_desc2>:
+ +[0-9a-f]+: ........ adrp x0, .*
+ +[0-9a-f]+: ........ ldr x0, \[x0, #.*\]
--- /dev/null
+ # Demonstrating TLS relaxation behavior for -Bsymbolic linking.
+ # (i.e. no extra relaxation when using -Bsymbolic).
+ .global tlsdescvar
+ .global tlsdescvar2
+ .section .tbss,"awT",%nobits
+ .align 2
+ .type tlsdescvar, %object
+ .size tlsdescvar, 4
+tlsdescvar:
+ .zero 4
+ .type tlsdescvar2, %object
+ .size tlsdescvar2, 4
+tlsdescvar2:
+ .zero 4
+.text
+_test_tls_desc:
+
+ adrp x0, :tlsdesc:tlsdescvar
+ ldr x1, [x0, :tlsdesc_lo12:tlsdescvar]
+ add x0, x0, :tlsdesc_lo12:tlsdescvar
+ .tlsdesccall tlsdescvar
+ blr x1
+
+_test_tls_desc2:
+
+ adrp x0, :gottprel:tlsdescvar2
+ ldr x0, [x0, #:gottprel_lo12:tlsdescvar2]
#...
+10000: a9bf7bfd stp x29, x30, \[sp, #-16\]!
+10004: 910003fd mov x29, sp
- +10008: 90000080 adrp x0, 20000 <_GLOBAL_OFFSET_TABLE_>
- +1000c: b9400400 ldr w0, \[x0, #4\]
+ +10008: 52a00000 movz w0, #0x0, lsl #16
+ +1000c: 72800100 movk w0, #0x8
+10010: d503201f nop
+10014: d503201f nop
+10018: d53bd041 mrs x1, tpidr_el0
+10038: 8b000040 add x0, x2, x0
+1003c: b9400000 ldr w0, \[x0\]
+10040: 0b000021 add w1, w1, w0
- +10044: 90000080 adrp x0, 20000 <_GLOBAL_OFFSET_TABLE_>
- +10048: b9400800 ldr w0, \[x0, #8\]
+ +10044: 52a00000 movz w0, #0x0, lsl #16
+ +10048: 72800200 movk w0, #0x10
+1004c: d53bd041 mrs x1, tpidr_el0
+10050: 0b000020 add w0, w1, w0
+10054: b9400000 ldr w0, \[x0\]
#...
+10000: a9bf7bfd stp x29, x30, \[sp, #-16\]!
+10004: 910003fd mov x29, sp
- +10008: 90000080 adrp x0, 20000 <_GLOBAL_OFFSET_TABLE_>
- +1000c: f9400400 ldr x0, \[x0, #8\]
+ +10008: d2a00000 movz x0, #0x0, lsl #16
+ +1000c: f2800200 movk x0, #0x10
+10010: d503201f nop
+10014: d503201f nop
+10018: d53bd041 mrs x1, tpidr_el0
+10038: 8b000040 add x0, x2, x0
+1003c: b9400000 ldr w0, \[x0\]
+10040: 0b000021 add w1, w1, w0
- +10044: 90000080 adrp x0, 20000 <_GLOBAL_OFFSET_TABLE_>
- +10048: f9400800 ldr x0, \[x0, #16\]
+ +10044: d2a00000 movz x0, #0x0, lsl #16
+ +10048: f2800300 movk x0, #0x18
+1004c: d53bd041 mrs x1, tpidr_el0
+10050: 8b000020 add x0, x1, x0
+10054: b9400000 ldr w0, \[x0\]
--- /dev/null
+# The linker recognises that if we have one IE access to a TLS symbol then all
+# accesses to that symbol could be IE. Here we are also interested to check
+# the linker does not also decide that a second access to that symbol could be
+# LE.
+#target: [check_shared_lib_support]
+#ld: -shared
+#objdump: -dr
+
+.*: file format .*
+
+
+Disassembly of section \.text:
+
+[0-9a-f]+ <foo>:
+ +[0-9a-f]+: d2800000 mov x0, #0x0 // #0
+ +[0-9a-f]+: d53bd041 mrs x1, tpidr_el0
+ +[0-9a-f]+: .* adrp x0, .*
+ +[0-9a-f]+: .* ldr x0, \[x0, #.*\]
+ +[0-9a-f]+: b8606820 ldr w0, \[x1, x0\]
+ +[0-9a-f]+: d53bd041 mrs x1, tpidr_el0
+ +[0-9a-f]+: 910003fd mov x29, sp
+ +[0-9a-f]+: .* adrp x0, .*
+ +[0-9a-f]+: .* ldr x0, \[x0, #.*\]
+ +[0-9a-f]+: d503201f nop
+ +[0-9a-f]+: d503201f nop
+ +[0-9a-f]+: b8606820 ldr w0, \[x1, x0\]
+ +[0-9a-f]+: d65f03c0 ret
--- /dev/null
+ .section .tbss,"awT",@nobits
+ .align 2
+ .type y, %object
+ .size y, 4
+y:
+ .zero 4
+
+
+
+
+ .text
+ .global foo
+ .type foo, @function
+foo:
+ # Access the local symbol with an IE access.
+ mov x0, 0
+ mrs x1, tpidr_el0
+ adrp x0, :gottprel:y
+ ldr x0, [x0, #:gottprel_lo12:y]
+ ldr w0, [x1, x0]
+
+ # Also access the same symbol with a General Dynamic access.
+ # The linker should be able to recognise that if we're already
+ # accessing this symbol with an Initial Exec access then this General
+ # Dynamic access could be relaxed to an Initial Exec one too.
+ mrs x1, tpidr_el0
+ mov x29, sp
+ adrp x0, :tlsdesc:y
+ ldr x2, [x0, #:tlsdesc_lo12:y]
+ add x0, x0, :tlsdesc_lo12:y
+ .tlsdesccall y
+ blr x2
+ ldr w0, [x1, x0]
+ ret
--- /dev/null
+# The linker recognises that if we have one IE access to a TLS symbol then all
+# accesses to that symbol could be IE. Here we are also interested to check
+# the linker does not also decide that a second access to that symbol could be
+# LE.
+#source: tls-relax-gd-ie-2.s
+#target: [check_shared_lib_support]
+#ld: -shared -Bsymbolic
+#objdump: -dr
+
+.*: file format .*
+
+
+Disassembly of section \.text:
+
+[0-9a-f]+ <foo>:
+ +[0-9a-f]+: d2800000 mov x0, #0x0 // #0
+ +[0-9a-f]+: d53bd041 mrs x1, tpidr_el0
+ +[0-9a-f]+: .* adrp x0, .*
+ +[0-9a-f]+: .* ldr x0, \[x0, #.*\]
+ +[0-9a-f]+: b8606820 ldr w0, \[x1, x0\]
+ +[0-9a-f]+: d53bd041 mrs x1, tpidr_el0
+ +[0-9a-f]+: 910003fd mov x29, sp
+ +[0-9a-f]+: .* adrp x0, .*
+ +[0-9a-f]+: .* ldr x0, \[x0, #.*\]
+ +[0-9a-f]+: d503201f nop
+ +[0-9a-f]+: d503201f nop
+ +[0-9a-f]+: b8606820 ldr w0, \[x1, x0\]
+ +[0-9a-f]+: d65f03c0 ret
+
#source: tls-relax-gd-ie.s
#as: -mabi=ilp32
-#ld: -m [aarch64_choose_ilp32_emul] -T relocs-ilp32.ld -e0
+#ld: -m [aarch64_choose_ilp32_emul] -T relocs-ilp32.ld -e0 tmpdir/tls-sharedlib-ilp32.so
#objdump: -dr
#...
+10000: 90000080 adrp x0, 20000 <_GLOBAL_OFFSET_TABLE_>
#source: tls-relax-gd-ie.s
-#ld: -T relocs.ld -e0
+#ld: -T relocs.ld -e0 tmpdir/tls-sharedlib.so
#objdump: -dr
#...
+10000: 90000080 adrp x0, 20000 <_GLOBAL_OFFSET_TABLE_>
- .global var
- .section .tdata,"awT",%progbits
-var:
- .word 2
.text
adrp x0, :tlsgd:var
add x0, x0, :tlsgd_lo12:var
#source: tls-relax-gdesc-ie-2.s
-#ld: -T relocs.ld -e0
+#ld: -T relocs.ld -e0 tmpdir/tls-sharedlib.so
#objdump: -dr
#...
+10000: 90000080 adrp x0, 20000 <_GLOBAL_OFFSET_TABLE_>
// Test TLS Desc to TLS IE relaxation when instructions are not consecutive.
- .global var
- .section .tdata
-var:
- .word 2
.text
adrp x0, :tlsdesc:var
nop
mrs x1, tpidr_el0
add x0, x1, x0
ldr w0, [x0]
- .global var
.section .tdata
#source: tls-relax-gdesc-ie.s
-#ld: -T relocs.ld -e0
+#ld: -T relocs.ld -e0 tmpdir/tls-sharedlib.so
#objdump: -dr
#...
+10000: 90000080 adrp x0, 20000 <_GLOBAL_OFFSET_TABLE_>
- .global var
- .section .tdata
-var:
- .word 2
.text
adrp x0, :tlsdesc:var
ldr x17, [x0, #:tlsdesc_lo12:var]
--- /dev/null
+# We already test that we relax an access to a local symbol, this testcase
+# checks that we relax an access to a global-binding symbol if the static linker
+# knows that the symbol will resolve to the executable local value.
+#
+# The access should be relaxed to a LE access.
+#ld:
+#objdump: -d
+
+.*: file format .*
+
+
+Disassembly of section \.text:
+
+[0-9a-f]+ <_start>:
+ +[0-9a-f]+: d2800000 mov x0, #0x0 // #0
+ +[0-9a-f]+: d53bd041 mrs x1, tpidr_el0
+ +[0-9a-f]+: d2a00000 movz x0, #0x0, lsl #16
+ +[0-9a-f]+: f2800200 movk x0, #0x10
+ +[0-9a-f]+: b8606820 ldr w0, \[x1, x0\]
+ +[0-9a-f]+: d65f03c0 ret
--- /dev/null
+# Test TLS IE to TLS LE relaxation for global symbols.
+ .section .tbss,"awT",@nobits
+ .global x
+ .align 2
+ .type x, %object
+ .size x, 4
+x:
+ .zero 4
+
+
+
+ .text
+ .global _start
+ .type _start, @function
+_start:
+ mov x0, 0
+ mrs x1, tpidr_el0
+ adrp x0, :gottprel:x
+ ldr x0, [x0, #:gottprel_lo12:x]
+ ldr w0, [x1, x0]
+ ret
+
#source: tls-relax-large-desc-ie.s
-#ld: -T relocs.ld -e0
+#ld: -T relocs.ld -e0 tmpdir/tls-sharedlib.so
#notarget: aarch64_be-*-*
#objdump: -dr
#...
- .global var
- .section .tdata,"awT",%progbits
-var:
- .word 2
-
.text
test:
ldr x1, .Lgot
#source: tls-relax-large-gd-ie.s
-#ld: -T relocs.ld -e0
+#ld: -T relocs.ld -e0 tmpdir/tls-sharedlib.so
#notarget: aarch64_be-*-*
#objdump: -dr
#...
- .global var
- .section .tdata,"awT",%progbits
-var:
- .word 2
-
.text
test:
ldr x1, .Lgot
--- /dev/null
+ .global var
+ .section .tdata,"awT",@progbits
+var:
+ .word 2
#source: tls-tiny-desc-ie.s
#as: -mabi=ilp32
-#ld: -m [aarch64_choose_ilp32_emul] -T relocs-ilp32.ld -e0
+#ld: -m [aarch64_choose_ilp32_emul] -T relocs-ilp32.ld -e0 tmpdir/tls-sharedlib-ilp32.so
#objdump: -dr
#...
Disassembly of section .text:
00010000 \<test\>:
- +10000: 18080020 ldr w0, 20004 \<_GLOBAL_OFFSET_TABLE_\+0x4\>
+ +10000: 18080020 ldr w0, 20004 \<var\>
+10004: d503201f nop
+10008: d503201f nop
#source: tls-tiny-desc-ie.s
-#ld: -T relocs.ld -e0
+#ld: -T relocs.ld -e0 tmpdir/tls-sharedlib.so
#objdump: -dr
#...
Disassembly of section .text:
0000000000010000 \<test\>:
- +10000: 58080040 ldr x0, 20008 \<_GLOBAL_OFFSET_TABLE_\+0x8\>
+ +10000: 58080040 ldr x0, 20008 \<var\>
+10004: d503201f nop
+10008: d503201f nop
- .global var
-
- .section .tbss,"awT",%nobits
- .align 2
- .type var, %object
- .size var, 4
-var:
- .zero 4
-
.text
test:
ldr x1, :tlsdesc:var
#source: tls-tiny-gd-ie.s
#as: -mabi=ilp32
-#ld: -m [aarch64_choose_ilp32_emul] -T relocs-ilp32.ld -e0
+#ld: -m [aarch64_choose_ilp32_emul] -T relocs-ilp32.ld -e0 tmpdir/tls-sharedlib-ilp32.so
#objdump: -dr
#...
Disassembly of section .text:
00010000 \<test\>:
- +10000: 18080020 ldr w0, 20004 \<_GLOBAL_OFFSET_TABLE_\+0x4\>
+ +10000: 18080020 ldr w0, 20004 \<var\>
+10004: d53bd041 mrs x1, tpidr_el0
+10008: 0b000020 add w0, w1, w0
#source: tls-tiny-gd-ie.s
-#ld: -T relocs.ld -e0
+#ld: -T relocs.ld -e0 tmpdir/tls-sharedlib.so
#objdump: -dr
#...
Disassembly of section .text:
0000000000010000 \<test\>:
- +10000: 58080040 ldr x0, 20008 \<_GLOBAL_OFFSET_TABLE_\+0x8\>
+ +10000: 58080040 ldr x0, 20008 \<var\>
+10004: d53bd041 mrs x1, tpidr_el0
+10008: 8b000020 add x0, x1, x0
- .global var
-
- .section .tbss,"awT",%nobits
- .align 2
- .type var, %object
- .size var, 4
-var:
- .zero 4
-
.text
test:
adr x0, :tlsgd:var