This patch adds support for TLS relocation targeting C_HIDEXT symbols.
In gas, TLS relocations, except R_TLSM and R_TLMSL, must keep the value
of their target symbol.
In ld, it simply ensures that internal TLS symbols are added to the
linker hash table for xcoff_reloc_type_tls.
It also improves the tests made by both.
bfd/ChangeLog:
* coff-rs6000.c (xcoff_howto_table): Fix name of R_TLSML.
(xcoff_reloc_type_tls): Replace the error when h is NULL by
an assert.
(xcoff_complain_overflow_unsigned_func): Adjust comments.
* coff64-rs6000.c (xcoff64_howto_table): Fix name of R_TLSML.
* xcofflink.c (xcoff_link_add_symbols_to_hash_table): New
function.
(xcoff_link_add_symbols): Add C_HIDEXT TLS symbols to the linker
hash table.
gas/ChangeLog:
* config/tc-ppc.c (md_apply_fix): Enable support for TLS
relocation over internal symbols.
* testsuite/gas/ppc/aix.exp: Replace xcoff-tlms by xcoff-tls.
* testsuite/gas/ppc/xcoff-tlsm-32.d: Removed.
* testsuite/gas/ppc/xcoff-tlsm-64.d: Removed.
* testsuite/gas/ppc/xcoff-tlsm.s: Removed.
* testsuite/gas/ppc/xcoff-tls-32.d: New test.
* testsuite/gas/ppc/xcoff-tls-64.d: New test.
* testsuite/gas/ppc/xcoff-tls.s: New test.
ld/ChangeLog:
* testsuite/ld-powerpc/aix52.exp: Improve aix-tls-reloc test.
* testsuite/ld-powerpc/aix-tls-reloc.s: Likewise.
* testsuite/ld-powerpc/aix-tls-reloc-32.d: Removed.
* testsuite/ld-powerpc/aix-tls-reloc-64.d: Removed.
* testsuite/ld-powerpc/aix-tls-reloc-32.dd: New test.
* testsuite/ld-powerpc/aix-tls-reloc-32.dt: New test.
* testsuite/ld-powerpc/aix-tls-reloc-64.dd: New test.
* testsuite/ld-powerpc/aix-tls-reloc-64.dt: New test.
0, /* bitpos */
complain_overflow_bitfield, /* complain_on_overflow */
0, /* special_function */
- "R_TLSM", /* name */
+ "R_TLSML", /* name */
true, /* partial_inplace */
0xffffffff, /* src_mask */
0xffffffff, /* dst_mask */
h = obj_xcoff_sym_hashes (input_bfd)[rel->r_symndx];
- /* FIXME: R_TLSML is targeting a internal TOC symbol, which will
- make the following checks failing. It should be moved with
- R_TLSM bellow once it works. */
+ /* R_TLSML is handled by the loader but must be from a
+ TOC entry targeting itslef. This is already verified in
+ xcoff_link_add_symbols.
+ The value must be 0. */
if (howto->type == R_TLSML)
{
*relocation = 0;
return true;
}
- /* FIXME: h is sometimes null, if the TLS symbol is not exported. */
- if (!h)
- {
- char vaddr_buf[128];
-
- sprintf_vma (vaddr_buf, rel->r_vaddr);
- _bfd_error_handler
- (_("%pB: TLS relocation at 0x%s over internal symbols (C_HIDEXT) not yet possible\n"),
- input_bfd, vaddr_buf);
- return false;
- }
-
+ /* The target symbol should always be available even if it's not
+ exported. */
+ BFD_ASSERT (h != NULL);
/* TLS relocations must target a TLS symbol. */
if (h->smclas != XMC_TL && h->smclas != XMC_UL)
return false;
}
- /* R_TLSM and R_TLSML are relocations used by the loader.
- The value must be 0.
- FIXME: move R_TLSML here. */
+ /* R_TLSM are relocations used by the loader.
+ The value must be 0. */
if (howto->type == R_TLSM)
{
*relocation = 0;
R_TLS_LE:
Thread-local storage relocation using local-exec model.
- R_TLS:
+ R_TLSM:
Tread-local storage relocation used by the loader.
- R_TLSM:
+ R_TLSML:
Tread-local storage relocation used by the loader.
R_TOCU:
0, /* bitpos */
complain_overflow_bitfield, /* complain_on_overflow */
0, /* special_function */
- "R_TLSM", /* name */
+ "R_TLSML", /* name */
true, /* partial_inplace */
MINUS_ONE, /* src_mask */
MINUS_ONE, /* dst_mask */
return min;
}
+/* Return true if the symbol has to be added to the linker hash
+ table. */
+static bool
+xcoff_link_add_symbols_to_hash_table (struct internal_syment sym,
+ union internal_auxent aux)
+{
+ /* External symbols must be added. */
+ if (EXTERN_SYM_P (sym.n_sclass))
+ return true;
+
+ /* Hidden TLS symbols must be added to verify TLS relocations
+ in xcoff_reloc_type_tls. */
+ if (sym.n_sclass == C_HIDEXT
+ && ((aux.x_csect.x_smclas == XMC_TL
+ || aux.x_csect.x_smclas == XMC_UL)))
+ return true;
+
+ return false;
+}
+
/* Add all the symbols from an object file to the hash table.
XCOFF is a weird format. A normal XCOFF .o files will have three
32 bit has a csect length of 4 for TOC
64 bit has a csect length of 8 for TOC
+ An exception is made for TOC entries with a R_TLSML
+ relocation. This relocation is made for the loader.
+ We must check that the referenced symbol is the TOC entry
+ itself.
+
The conditions to get past the if-check are not that bad.
They are what is used to create the TOC csects in the first
place. */
64 bit R_POS r_size is 63 */
if (relindx < enclosing->reloc_count
&& rel->r_vaddr == (bfd_vma) sym.n_value
- && rel->r_type == R_POS
+ && (rel->r_type == R_POS ||
+ rel->r_type == R_TLSML)
&& ((bfd_xcoff_is_xcoff32 (abfd)
&& rel->r_size == 31)
|| (bfd_xcoff_is_xcoff64 (abfd)
set_toc = h;
}
}
+ else if (rel->r_type == R_TLSML)
+ {
+ csect_index = ((esym
+ - (bfd_byte *) obj_coff_external_syms (abfd))
+ / symesz);
+ if (((unsigned long) rel->r_symndx) != csect_index)
+ {
+ _bfd_error_handler
+ /* xgettext:c-format */
+ (_("%pB: TOC entry `%s' has a R_TLSML"
+ "relocation not targeting itself"),
+ abfd, name);
+ bfd_set_error (bfd_error_bad_value);
+ goto error_return;
+ }
+ }
}
}
if (first_csect == NULL)
first_csect = csect;
- /* If this symbol is external, we treat it as starting at the
- beginning of the newly created section. */
- if (EXTERN_SYM_P (sym.n_sclass))
+ /* If this symbol must be added to the linker hash table,
+ we treat it as starting at the beginning of the newly
+ created section. */
+ if (xcoff_link_add_symbols_to_hash_table (sym, aux))
{
section = csect;
value = 0;
if (first_csect == NULL)
first_csect = csect;
- if (EXTERN_SYM_P (sym.n_sclass))
+ if (xcoff_link_add_symbols_to_hash_table (sym, aux))
{
csect->flags |= SEC_IS_COMMON;
csect->size = 0;
/* Now we have enough information to add the symbol to the
linker hash table. */
- if (EXTERN_SYM_P (sym.n_sclass))
+ if (xcoff_link_add_symbols_to_hash_table (sym, aux))
{
bool copy, ok;
flagword flags;
case BFD_RELOC_PPC64_TLSM:
gas_assert (fixP->fx_addsy != NULL);
S_SET_THREAD_LOCAL (fixP->fx_addsy);
- fieldval = 0;
break;
- /* TLSML relocations are targeting a XMC_TC symbol named
- "_$TLSML". We can't check earlier because the relocation
- can target any symbol name which will be latter .rename
- to "_$TLSML". */
+ /* Officially, R_TLSML relocations must be from a TOC entry
+ targeting itself. In practice, this TOC entry is always
+ named (or .rename) "_$TLSML".
+ Thus, as it doesn't seem possible to retrieve the symbol
+ being relocated here, we simply check that the symbol
+ targeted by R_TLSML is indeed a TOC entry named "_$TLSML".
+ FIXME: Find a way to correctly check R_TLSML relocations
+ as described above. */
case BFD_RELOC_PPC_TLSML:
case BFD_RELOC_PPC64_TLSML:
gas_assert (fixP->fx_addsy != NULL);
- if (strcmp (symbol_get_tc (fixP->fx_addsy)->real_name, "_$TLSML") != 0)
- {
- as_bad_where (fixP->fx_file, fixP->fx_line,
- _("R_TLSML relocation doesn't target a "
- "symbol named \"_$TLSML\". %s"), S_GET_NAME(fixP->fx_addsy));
- }
+ if ((symbol_get_tc (fixP->fx_addsy)->symbol_class != XMC_TC
+ || symbol_get_tc (fixP->fx_addsy)->symbol_class != XMC_TE)
+ && strcmp (symbol_get_tc (fixP->fx_addsy)->real_name, "_$TLSML") != 0)
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("R_TLSML relocation doesn't target a "
+ "TOC entry named \"_$TLSML\": %s"), S_GET_NAME(fixP->fx_addsy));
fieldval = 0;
break;
*valP = value;
}
else if (fixP->fx_r_type == BFD_RELOC_PPC_TLSM
- || fixP->fx_r_type == BFD_RELOC_PPC64_TLSM)
+ || fixP->fx_r_type == BFD_RELOC_PPC64_TLSM
+ || fixP->fx_r_type == BFD_RELOC_PPC_TLSML
+ || fixP->fx_r_type == BFD_RELOC_PPC64_TLSML)
/* AIX ld expects the section contents for these relocations
to be zero. Arrange for that to occur when
bfd_install_relocation is called. */
fixP->fx_addnumber = (- bfd_section_vma (S_GET_SEGMENT (fixP->fx_addsy))
- - S_GET_VALUE (fixP->fx_addsy));
+ - S_GET_VALUE (fixP->fx_addsy)
+ - fieldval);
else
fixP->fx_addnumber = 0;
#endif
run_dump_test "xcoff-function-1-32"
run_dump_test "xcoff-function-1-64"
- run_dump_test "xcoff-tlsm-32"
- run_dump_test "xcoff-tlsm-64"
+ run_dump_test "xcoff-tls-32"
+ run_dump_test "xcoff-tls-64"
run_dump_test "xcoff-stsym-32"
run_dump_test "xcoff-stsym-64"
--- /dev/null
+#as: -a32
+#source: xcoff-tls.s
+#objdump: -Dr
+#name: XCOFF TLS relocation (32 bit)
+
+.*
+Disassembly of section .data:
+
+00000000 <TOC>:
+ 0: 00 00 00 58.*
+ 0: R_TLS tdata_ext.*
+
+00000004 <.tdata_ext_gd>:
+ 4: 00 00 00 00.*
+ 4: R_TLSM tdata_ext.*
+
+00000008 <tdata_ext_ld>:
+ 8: 00 00 00 58.*
+ 8: R_TLS_LD tdata_ext.*
+
+0000000c <tdata_ext_ie>:
+ c: 00 00 00 58.*
+ c: R_TLS_IE tdata_ext.*
+
+00000010 <tdata_ext_le>:
+ 10: 00 00 00 58.*
+ 10: R_TLS_LE tdata_ext.*
+
+00000014 <tdata_int1_gd>:
+ 14: 00 00 00 5c.*
+ 14: R_TLS tdata_int_csect.*
+
+00000018 <.tdata_int1_gd>:
+ 18: 00 00 00 00.*
+ 18: R_TLSM tdata_int_csect.*
+
+0000001c <tdata_int1_ld>:
+ 1c: 00 00 00 5c.*
+ 1c: R_TLS_LD tdata_int_csect.*
+
+00000020 <tdata_int1_ie>:
+ 20: 00 00 00 5c.*
+ 20: R_TLS_IE tdata_int_csect.*
+
+00000024 <tdata_int1_le>:
+ 24: 00 00 00 5c.*
+ 24: R_TLS_LE tdata_int_csect.*
+
+00000028 <tdata_int2_gd>:
+ 28: 00 00 00 60.*
+ 28: R_TLS tdata_int_csect.*
+
+0000002c <.tdata_int2_gd>:
+ 2c: 00 00 00 00.*
+ 2c: R_TLSM tdata_int_csect.*
+
+00000030 <tdata_int2_ld>:
+ 30: 00 00 00 60.*
+ 30: R_TLS_LD tdata_int_csect.*
+
+00000034 <tdata_int2_ie>:
+ 34: 00 00 00 60.*
+ 34: R_TLS_IE tdata_int_csect.*
+
+00000038 <tdata_int2_le>:
+ 38: 00 00 00 60.*
+ 38: R_TLS_LE tdata_int_csect.*
+
+0000003c <tbss_ext_gd>:
+ 3c: 00 00 00 68.*
+ 3c: R_TLS tbss_ext.*
+
+00000040 <.tbss_ext_gd>:
+ 40: 00 00 00 00.*
+ 40: R_TLSM tbss_ext.*
+
+00000044 <tbss_ext_ld>:
+ 44: 00 00 00 68.*
+ 44: R_TLS_LD tbss_ext.*
+
+00000048 <tbss_ext_ie>:
+ 48: 00 00 00 68.*
+ 48: R_TLS_IE tbss_ext.*
+
+0000004c <tbss_ext_le>:
+ 4c: 00 00 00 68.*
+ 4c: R_TLS_LE tbss_ext.*
+
+00000050 <_\$TLSML>:
+ ...
+ 50: R_TLSML _\$TLSML.*
+
+Disassembly of section .tdata:
+
+00000058 <tdata_ext>:
+ 58: 00 00 00 01 .long 0x1
+
+0000005c <tdata_int_csect>:
+ 5c: 00 00 00 02 .long 0x2
+ 60: 00 00 00 03 .long 0x3
+ 64:.*
+
+Disassembly of section .tbss:
+
+00000068 <tbss_ext>:
+ ...
--- /dev/null
+#as: -a64
+#source: xcoff-tls.s
+#objdump: -Dr
+#name: XCOFF TLS relocation (64 bit)
+
+.*
+
+
+Disassembly of section .data:
+
+0000000000000000 <TOC>:
+ 0: 00 00 00 00.*
+ 0: R_TLS tdata_ext.*
+ 4: 00 00 00 a8.*
+
+0000000000000008 <.tdata_ext_gd>:
+ ...
+ 8: R_TLSM tdata_ext.*
+
+0000000000000010 <tdata_ext_ld>:
+ 10: 00 00 00 00.*
+ 10: R_TLS_LD tdata_ext.*
+ 14: 00 00 00 a8.*
+
+0000000000000018 <tdata_ext_ie>:
+ 18: 00 00 00 00.*
+ 18: R_TLS_IE tdata_ext.*
+ 1c: 00 00 00 a8.*
+
+0000000000000020 <tdata_ext_le>:
+ 20: 00 00 00 00.*
+ 20: R_TLS_LE tdata_ext.*
+ 24: 00 00 00 a8.*
+
+0000000000000028 <tdata_int1_gd>:
+ 28: 00 00 00 00.*
+ 28: R_TLS tdata_int_csect.*
+ 2c: 00 00 00 ac.*
+
+0000000000000030 <.tdata_int1_gd>:
+ ...
+ 30: R_TLSM tdata_int_csect.*
+
+0000000000000038 <tdata_int1_ld>:
+ 38: 00 00 00 00.*
+ 38: R_TLS_LD tdata_int_csect.*
+ 3c: 00 00 00 ac.*
+
+0000000000000040 <tdata_int1_ie>:
+ 40: 00 00 00 00.*
+ 40: R_TLS_IE tdata_int_csect.*
+ 44: 00 00 00 ac.*
+
+0000000000000048 <tdata_int1_le>:
+ 48: 00 00 00 00.*
+ 48: R_TLS_LE tdata_int_csect.*
+ 4c: 00 00 00 ac.*
+
+0000000000000050 <tdata_int2_gd>:
+ 50: 00 00 00 00.*
+ 50: R_TLS tdata_int_csect.*
+ 54: 00 00 00 b0.*
+
+0000000000000058 <.tdata_int2_gd>:
+ ...
+ 58: R_TLSM tdata_int_csect.*
+
+0000000000000060 <tdata_int2_ld>:
+ 60: 00 00 00 00.*
+ 60: R_TLS_LD tdata_int_csect.*
+ 64: 00 00 00 b0.*
+
+0000000000000068 <tdata_int2_ie>:
+ 68: 00 00 00 00.*
+ 68: R_TLS_IE tdata_int_csect.*
+ 6c: 00 00 00 b0.*
+
+0000000000000070 <tdata_int2_le>:
+ 70: 00 00 00 00.*
+ 70: R_TLS_LE tdata_int_csect.*
+ 74: 00 00 00 b0.*
+
+0000000000000078 <tbss_ext_gd>:
+ 78: 00 00 00 00.*
+ 78: R_TLS tbss_ext.*
+ 7c: 00 00 00 b8.*
+
+0000000000000080 <.tbss_ext_gd>:
+ ...
+ 80: R_TLSM tbss_ext.*
+
+0000000000000088 <tbss_ext_ld>:
+ 88: 00 00 00 00.*
+ 88: R_TLS_LD tbss_ext.*
+ 8c: 00 00 00 b8.*
+
+0000000000000090 <tbss_ext_ie>:
+ 90: 00 00 00 00.*
+ 90: R_TLS_IE tbss_ext.*
+ 94: 00 00 00 b8.*
+
+0000000000000098 <tbss_ext_le>:
+ 98: 00 00 00 00.*
+ 98: R_TLS_LE tbss_ext.*
+ 9c: 00 00 00 b8.*
+
+00000000000000a0 <_\$TLSML>:
+ ...
+ a0: R_TLSML _\$TLSML-0xa0
+
+Disassembly of section .tdata:
+
+00000000000000a8 <tdata_ext>:
+ a8: 00 00 00 01 .long 0x1
+
+00000000000000ac <tdata_int_csect>:
+ ac: 00 00 00 02 .long 0x2
+ b0: 00 00 00 03 .long 0x3
+ b4:.*
+
+Disassembly of section .tbss:
+
+00000000000000b8 <tbss_ext>:
+ ...
--- /dev/null
+# An external tdata symbol
+ .globl tdata_ext[TL]
+ .csect tdata_ext[TL]
+ .long 1
+
+ .csect tdata_int_csect[TL]
+# A first internal tdata symbol
+tdata_int1:
+ .long 2
+# A second internal tdata symbol
+tdata_int2:
+ .long 3
+
+# Two external tbss symbols.
+# XCOFF doesn't seem to allow internal tbss
+# (or bss) symbols.
+ .comm tbss_ext[UL],8
+
+ .toc
+# TC entries targeting the external tdata symbol
+# Their value should be "tdata_ext" address,
+# except TLSM value which must be 0.
+# Their relocations should target it.
+ .tc tdata_ext_gd[TC],tdata_ext[TL]
+ .tc .tdata_ext_gd[TC],tdata_ext[TL]@m
+ .tc tdata_ext_ld[TC],tdata_ext[TL]@ld
+ .tc tdata_ext_ie[TC],tdata_ext[TL]@ie
+ .tc tdata_ext_le[TC],tdata_ext[TL]@le
+
+# TC entries targeting internal tdata symbols.
+# Their value should be "tdata_int1" or "tdata_int2"
+# addresses, except TLSM value which must be 0.
+# Their relocations should target "tdata_int_csect".
+ .tc tdata_int1_gd[TC],tdata_int1
+ .tc .tdata_int1_gd[TC],tdata_int1@m
+ .tc tdata_int1_ld[TC],tdata_int1@ld
+ .tc tdata_int1_ie[TC],tdata_int1@ie
+ .tc tdata_int1_le[TC],tdata_int1@le
+ .tc tdata_int2_gd[TC],tdata_int2
+ .tc .tdata_int2_gd[TC],tdata_int2@m
+ .tc tdata_int2_ld[TC],tdata_int2@ld
+ .tc tdata_int2_ie[TC],tdata_int2@ie
+ .tc tdata_int2_le[TC],tdata_int2@le
+
+# TC entries targeting the external tdata symbol
+# Their value should be "tbss_ext" address,
+# except TLSM value which must be 0.
+# Their relocations should target "tbss_ext".
+ .tc tbss_ext_gd[TC],tbss_ext[UL]
+ .tc .tbss_ext_gd[TC],tbss_ext[UL]@m
+ .tc tbss_ext_ld[TC],tbss_ext[UL]@ld
+ .tc tbss_ext_ie[TC],tbss_ext[UL]@ie
+ .tc tbss_ext_le[TC],tbss_ext[UL]@le
+
+# Module entry
+ .tc mh[TC],mh[TC]@ml
+.rename mh[TC], "_$TLSML" # Symbol for the module handle
+++ /dev/null
-#as: -a32
-#source: xcoff-tlsm.s
-#objdump: -Dr
-#name: XCOFF TLSM relocation (32 bit)
-
-.*
-Disassembly of section .data:
-
-00000000 <TOC>:
- 0: 00 00 00 10.*
- 0: R_TLS foo_tdata-0x10
-
-00000004 <.foo_tdata>:
- 4: 00 00 00 00.*
- 4: R_TLSM foo_tdata-0x10
-
-00000008 <foo_tbss>:
- 8: 00 00 00 20.*
- 8: R_TLS foo_tbss-0x20
-
-0000000c <.foo_tbss>:
- c: 00 00 00 00.*
- c: R_TLSM foo_tbss-0x20
-
-Disassembly of section .tdata:
-
-00000010 <foo_tdata>:
- 10: 00 00 00 01.*
- ...
-
-Disassembly of section .tbss:
-
-00000020 <foo_tbss>:
- ...
+++ /dev/null
-#as: -a64
-#source: xcoff-tlsm.s
-#objdump: -Dr
-#name: XCOFF TLSM relocation (64 bit)
-
-.*
-Disassembly of section .data:
-
-0000000000000000 <TOC>:
- 0: 00 00 00 00.*
- 0: R_TLS foo_tdata-0x20
- 4: 00 00 00 20.*
-
-0000000000000008 <.foo_tdata>:
- ...
- 8: R_TLSM foo_tdata-0x20
-
-0000000000000010 <foo_tbss>:
- 10: 00 00 00 00.*
- 10: R_TLS foo_tbss-0x30
- 14: 00 00 00 30.*
-
-0000000000000018 <.foo_tbss>:
- ...
- 18: R_TLSM foo_tbss-0x30
-
-Disassembly of section .tdata:
-
-0000000000000020 <foo_tdata>:
- 20: 00 00 00 01.*
- ...
-
-Disassembly of section .tbss:
-
-0000000000000030 <foo_tbss>:
- ...
+++ /dev/null
- .csect foo_tdata[TL],4
- .align 2
-foo_tdata:
- .long 1
-
- .comm foo_tbss[UL],8
-
- .toc
- .tc foo_tdata[TC],foo_tdata[TL]
- .tc .foo_tdata[TC],foo_tdata[TL]@m
- .tc foo_tbss[TC],foo_tbss[UL]
- .tc .foo_tbss[TC],foo_tbss[UL]@m
+++ /dev/null
-#source: aix-tls-reloc.s
-#as: -a32
-#ld: -b32 -shared -bE:aix-tls-reloc.ex
-#objdump: -dr
-#target: [is_xcoff_format]
-
-.*
-
-Disassembly of section \.text:
-
-.* <\.foo>:
-.*: 80 82 00 00 l r4,0\(r2\)
-.*: R_TOC gd-.*
-.*: 80 62 00 04 l r3,4\(r2\)
-.*: R_TOC .gd-.*
-.*: 48 00 00 03 bla 0 <\.foo-.*>
-.*: R_BA_26 __tls_get_addr
-.*: 80 62 00 0c l r3,12\(r2\)
-.*: R_TOC _\$TLSML-.*
-.*: 48 00 00 03 bla 0 <\.foo-.*>
-.*: R_BA_26 __tls_get_mod
-.*: 80 82 00 08 l r4,8\(r2\)
-.*: R_TOC ld-.*
-.*: 7c a3 22 14 cax r5,r3,r4
-.*: 48 00 00 03 bla 0 <\.foo-.*>
-.*: R_BA_26 __get_tpointer
-.*: 80 82 00 10 l r4,16\(r2\)
-.*: R_TOC ie-.*
-.*: 7c a3 22 14 cax r5,r3,r4
-.*: 48 00 00 03 bla 0 <\.foo-.*>
-.*: R_BA_26 __get_tpointer
-.*: 80 82 00 14 l r4,20\(r2\)
-.*: R_TOC le-.*
-.*: 7c a3 22 14 cax r5,r3,r4
-.*
--- /dev/null
+#source: aix-tls-reloc.s
+#as: -a32
+#ld: -b32 -shared -bE:aix-tls-reloc.ex
+#objdump: -dr -j.data
+#target: [is_xcoff_format]
+
+.*
+
+
+Disassembly of section .data:
+
+.* <foo>:
+.*
+.*
+.*
+.*
+.*
+
+.* <TOC>:
+.*: ff ff 88 00 .*
+.*: R_TLS tdata_ext.*
+
+.* <.tdata_ext_gd>:
+.*: 00 00 00 00 .*
+.*: R_TLSM tdata_ext.*
+
+.* <tdata_ext_ld>:
+.*: ff ff 88 00 .*
+.*: R_TLS_LD tdata_ext.*
+
+.* <tdata_ext_ie>:
+.*: ff ff 88 00 .*
+.*: R_TLS_IE tdata_ext.*
+
+.* <tdata_ext_le>:
+.*: ff ff 88 00 .*
+.*: R_TLS_LE tdata_ext.*
+
+.* <tdata_int1_gd>:
+.*: ff ff 88 04 .*
+.*: R_TLS tdata_int_csect.*
+
+.* <.tdata_int1_gd>:
+.*: 00 00 00 00 .*
+.*: R_TLSM tdata_int_csect.*
+
+.* <tdata_int1_ld>:
+.*: ff ff 88 04 .*
+.*: R_TLS_LD tdata_int_csect.*
+
+.* <tdata_int1_ie>:
+.*: ff ff 88 04 .*
+.*: R_TLS_IE tdata_int_csect.*
+
+.* <tdata_int1_le>:
+.*: ff ff 88 04 .*
+.*: R_TLS_LE tdata_int_csect.*
+
+.* <tdata_int2_gd>:
+.*: ff ff 88 08 .*
+.*: R_TLS tdata_int_csect.*
+
+.* <.tdata_int2_gd>:
+.*: 00 00 00 00 .*
+.*: R_TLSM tdata_int_csect.*
+
+.* <tdata_int2_ld>:
+.*: ff ff 88 08 .*
+.*: R_TLS_LD tdata_int_csect.*
+
+.* <tdata_int2_ie>:
+.*: ff ff 88 08 .*
+.*: R_TLS_IE tdata_int_csect.*
+
+.* <tdata_int2_le>:
+.*: ff ff 88 08 .*
+.*: R_TLS_LE tdata_int_csect.*
+
+.* <tbss_ext_gd>:
+.*: ff ff 88 10 .*
+.*: R_TLS tbss_ext.*
+
+.* <.tbss_ext_gd>:
+.*: 00 00 00 00 .*
+.*: R_TLSM tbss_ext.*
+
+.* <tbss_ext_ld>:
+.*: ff ff 88 10 .*
+.*: R_TLS_LD tbss_ext.*
+
+.* <tbss_ext_ie>:
+.*: ff ff 88 10 .*
+.*: R_TLS_IE tbss_ext.*
+
+.* <tbss_ext_le>:
+.*: ff ff 88 10 .*
+.*: R_TLS_LE tbss_ext.*
+
+.* <_\$TLSML>:
+ ...
+.*: R_TLSML _\$TLSML.*
--- /dev/null
+
+tmpdir/aix-tls-reloc.so: file format aixcoff-rs6000
+
+
+Disassembly of section .tdata:
+
+ffff8800 <tdata_ext>:
+ffff8800: 00 00 00 01 .long 0x1
+
+ffff8804 <tdata_int_csect>:
+ffff8804: 00 00 00 02 .long 0x2
+ffff8808: 00 00 00 03 .long 0x3
+ffff880c: 00 00 00 00 .long 0x0
+
+Disassembly of section .tbss:
+
+ffff8810 <tbss_ext>:
+ ...
+++ /dev/null
-#source: aix-tls-reloc.s
-#as: -a32
-#ld: -b32 -shared -bE:aix-tls-reloc.ex
-#objdump: -dr
-#target: [is_xcoff_format]
-
-.*
-
-Disassembly of section \.text:
-
-.* <\.foo>:
-.*: e8 82 00 00 ld r4,0\(r2\)
-.*: R_TOC gd-.*
-.*: e8 62 00 08 ld r3,8\(r2\)
-.*: R_TOC .gd-.*
-.*: 48 00 00 03 bla 0 <\.foo-.*>
-.*: R_BA_26 __tls_get_addr
-.*: e8 62 00 18 ld r3,24\(r2\)
-.*: R_TOC _\$TLSML-.*
-.*: 48 00 00 03 bla 0 <\.foo-.*>
-.*: R_BA_26 __tls_get_mod
-.*: 80 82 00 10 lwz r4,16\(r2\)
-.*: R_TOC ld-.*
-.*: 7c a3 22 14 add r5,r3,r4
-.*: e8 82 00 20 ld r4,32\(r2\)
-.*: R_TOC ie-.*
-.*: 7c a4 6a 14 add r5,r4,r13
-.*: e8 82 00 28 ld r4,40\(r2\)
-.*: R_TOC le-.*
-.*: 7c a3 6a 14 add r5,r3,r13
-.*
--- /dev/null
+#source: aix-tls-reloc.s
+#as: -a64
+#ld: -b64 -shared -bE:aix-tls-reloc.ex
+#objdump: -dr -j.data
+#target: [is_xcoff_format]
+
+.*
+
+
+Disassembly of section .data:
+
+.* <foo>:
+.*
+.*
+.*
+.*
+.*
+.*
+.*
+
+.* <TOC>:
+.*: ff ff ff ff .*
+.*: R_TLS tdata_ext.*
+.*: ff ff 88 00 .*
+
+.* <.tdata_ext_gd>:
+ ...
+.*: R_TLSM tdata_ext.*
+
+.*<tdata_ext_ld>:
+.*: ff ff ff ff .*
+.*: R_TLS_LD tdata_ext.*
+.*: ff ff 88 00 .*
+
+.* <tdata_ext_ie>:
+.*: ff ff ff ff .*
+.*: R_TLS_IE tdata_ext.*
+.*: ff ff 88 00 .*
+
+.* <tdata_ext_le>:
+.*: ff ff ff ff .*
+.*: R_TLS_LE tdata_ext.*
+.*: ff ff 88 00 .*
+
+.* <tdata_int1_gd>:
+.*: ff ff ff ff .*
+.*: R_TLS tdata_int_csect.*
+.*: ff ff 88 04 .*
+
+.* <.tdata_int1_gd>:
+ ...
+.*: R_TLSM tdata_int_csect.*
+
+.* <tdata_int1_ld>:
+.*: ff ff ff ff .*
+.*: R_TLS_LD tdata_int_csect.*
+.*: ff ff 88 04 .*
+
+.* <tdata_int1_ie>:
+.*: ff ff ff ff .*
+.*: R_TLS_IE tdata_int_csect.*
+.*: ff ff 88 04 .*
+
+.* <tdata_int1_le>:
+.*: ff ff ff ff .*
+.*: R_TLS_LE tdata_int_csect.*
+.*: ff ff 88 04 .*
+
+.* <tdata_int2_gd>:
+.*: ff ff ff ff .*
+.*: R_TLS tdata_int_csect.*
+.*: ff ff 88 08 .*
+
+.* <.tdata_int2_gd>:
+ ...
+.*: R_TLSM tdata_int_csect.*
+
+.* <tdata_int2_ld>:
+.*: ff ff ff ff .*
+.*: R_TLS_LD tdata_int_csect.*
+.*: ff ff 88 08 .*
+
+.* <tdata_int2_ie>:
+.*: ff ff ff ff .*
+.*: R_TLS_IE tdata_int_csect.*
+.*: ff ff 88 08 .*
+
+.* <tdata_int2_le>:
+.*: ff ff ff ff .*
+.*: R_TLS_LE tdata_int_csect.*
+.*: ff ff 88 08 .*
+
+.* <tbss_ext_gd>:
+.*: ff ff ff ff .*
+.*: R_TLS tbss_ext.*
+.*: ff ff 88 10 .*
+
+.* <.tbss_ext_gd>:
+ ...
+.*: R_TLSM tbss_ext.*
+
+.* <tbss_ext_ld>:
+.*: ff ff ff ff .*
+.*: R_TLS_LD tbss_ext.*
+.*: ff ff 88 10 .*
+
+.* <tbss_ext_ie>:
+.*: ff ff ff ff .*
+.*: R_TLS_IE tbss_ext.*
+.*: ff ff 88 10 .*
+
+.* <tbss_ext_le>:
+.*: ff ff ff ff .*
+.*: R_TLS_LE tbss_ext.*
+.*: ff ff 88 10 .*
+
+.* <_\$TLSML>:
+ ...
+.*: R_TLSML _\$TLSML.*
--- /dev/null
+#source: aix-tls-reloc.s
+#as: -a64
+#ld: -b64 -shared -bE:aix-tls-reloc.ex
+#objdump: -d -j.tdata -j.tbss
+#target: [is_xcoff_format]
+
+.*
+
+
+Disassembly of section .tdata:
+
+ffffffffffff8800 <tdata_ext>:
+ffffffffffff8800:.*
+
+ffffffffffff8804 <tdata_int_csect>:
+ffffffffffff8804:.*
+ffffffffffff8808:.*
+ffffffffffff880c:.*
+
+Disassembly of section .tbss:
+
+ffffffffffff8810 <tbss_ext>:
+ ...
- .globl bar[TL]
- .csect bar[TL]
+# An external tdata symbol
+ .globl tdata_ext[TL]
+ .csect tdata_ext[TL]
.long 1
+ .csect tdata_int_csect[TL]
+# A first internal tdata symbol
+tdata_int1:
+ .long 2
+# A second internal tdata symbol
+tdata_int2:
+ .long 3
+
+# Two external tbss symbols.
+# XCOFF doesn't seem to allow internal tbss
+# (or bss) symbols.
+ .comm tbss_ext[UL],8
+
.toc
- .tc gd[TC],bar[TL]
- .tc .gd[TC],bar[TL]@m
- .tc ld[TC],bar[TL]@ld
- .tc mh[TC],mh[TC]@ml
- .tc ie[TC],bar[TL]@ie
- .tc le[TC],bar[TL]@le
+# TC entries targeting the external tdata symbol
+# Their value should be "tdata_ext" address,
+# except TLSM value which must be 0.
+# Their relocations should target it.
+ .tc tdata_ext_gd[TC],tdata_ext[TL]
+ .tc .tdata_ext_gd[TC],tdata_ext[TL]@m
+ .tc tdata_ext_ld[TC],tdata_ext[TL]@ld
+ .tc tdata_ext_ie[TC],tdata_ext[TL]@ie
+ .tc tdata_ext_le[TC],tdata_ext[TL]@le
- .globl foo
- .globl .foo
- .csect foo[DS],3
-foo:
- .if size == 32
- .long .foo, TOC[tc0], 0
- .else
- .llong .foo, TOC[tc0], 0
- .endif
+# TC entries targeting internal tdata symbols.
+# Their value should be "tdata_int1" or "tdata_int2"
+# addresses, except TLSM value which must be 0.
+# Their relocations should target "tdata_int_csect".
+ .tc tdata_int1_gd[TC],tdata_int1
+ .tc .tdata_int1_gd[TC],tdata_int1@m
+ .tc tdata_int1_ld[TC],tdata_int1@ld
+ .tc tdata_int1_ie[TC],tdata_int1@ie
+ .tc tdata_int1_le[TC],tdata_int1@le
+ .tc tdata_int2_gd[TC],tdata_int2
+ .tc .tdata_int2_gd[TC],tdata_int2@m
+ .tc tdata_int2_ld[TC],tdata_int2@ld
+ .tc tdata_int2_ie[TC],tdata_int2@ie
+ .tc tdata_int2_le[TC],tdata_int2@le
- .csect foo[PR]
-.foo:
- #GD
+# TC entries targeting the external tdata symbol
+# Their value should be "tbss_ext" address,
+# except TLSM value which must be 0.
+# Their relocations should target "tbss_ext".
+ .tc tbss_ext_gd[TC],tbss_ext[UL]
+ .tc .tbss_ext_gd[TC],tbss_ext[UL]@m
+ .tc tbss_ext_ld[TC],tbss_ext[UL]@ld
+ .tc tbss_ext_ie[TC],tbss_ext[UL]@ie
+ .tc tbss_ext_le[TC],tbss_ext[UL]@le
+
+# Module entry
+ .tc mh[TC],mh[TC]@ml
+ .rename mh[TC], "_$TLSML" # Symbol for the module handle
+
+# Macros
+ .macro gd_macro,sym
.if size == 32
- lwz 4, gd[TC](2)
- lwz 3, .gd[TC](2)
+ lwz 4, \sym\()[TC](2)
+ lwz 3, .\sym\()[TC](2)
.else
- ld 4, gd[TC](2)
- ld 3, .gd[TC](2)
+ ld 4, \sym\()[TC](2)
+ ld 3, .\sym\()[TC](2)
.endif
bla __tls_get_addr
+ .endm
- #LD
+ .macro ld_macro, sym
.if size == 32
- lwz 3, mh[TC](2)
+ lwz 4, \sym\()[TC](2)
.else
- ld 3, mh[TC](2)
+ ld 4, \sym\()[TC](2)
.endif
- bla __tls_get_mod
- lwz 4, ld[TC](2)
add 5,3,4
+ .endm
- #IE
+ .macro ie_macro, sym
.if size == 32
bla __get_tpointer
- lwz 4, ie[TC](2)
+ lwz 4, \sym\()[TC](2)
add 5,3,4
.else
- ld 4, ie[TC](2)
+ ld 4, \sym\()[TC](2)
add 5,4,13
.endif
+ .endm
- #LE
+ .macro le_macro, sym
.if size == 32
bla __get_tpointer
- lwz 4, le[TC](2)
+ lwz 4, \sym\()[TC](2)
add 5,3,4
.else
- ld 4, le[TC](2)
+ ld 4, \sym\()[TC](2)
add 5,3,13
.endif
+ .endm
+
+
+# As TLS relocations are made in for TC symbols,
+# this function only aims to avoid garbage collection
+# of these symbols, especially hidden ones.
+ .globl foo
+ .globl .foo
+ .csect foo[DS],3
+foo:
+ .if size == 32
+ .long .foo, TOC[tc0], 0
+ .else
+ .llong .foo, TOC[tc0], 0
+ .endif
+
+ .csect foo[PR]
+.foo:
+ # External syms
+ #GD
+ gd_macro tdata_ext_gd
+ gd_macro tdata_int1_gd
+ gd_macro tdata_int2_gd
+ gd_macro tbss_ext_gd
+
+ #LD
+ .if size == 32
+ lwz 3, mh[TC](2)
+ .else
+ ld 3, mh[TC](2)
+ .endif
+ bla __tls_get_mod
+ ld_macro tdata_ext_ld
+ ld_macro tdata_int1_ld
+ ld_macro tdata_int2_ld
+ ld_macro tbss_ext_ld
-.rename mh[TC], "_$TLSML" # Symbol for the module handle
+ #IE
+ ie_macro tdata_ext_ie
+ ie_macro tdata_int1_ie
+ ie_macro tdata_int2_ie
+ ie_macro tbss_ext_ie
+
+ #LE
+ le_macro tdata_ext_le
+ le_macro tdata_int1_le
+ le_macro tdata_int2_le
+ le_macro tbss_ext_le
{"TLS relocations" "-shared -bE:aix-tls-reloc.ex"
"" {aix-tls-reloc.s}
- {{objdump -dr aix-tls-reloc-SIZE.d}}
+ {{objdump {-dr -j.data} aix-tls-reloc-SIZE.dd}
+ {objdump {-dr -j.tdata -j.tbss} aix-tls-reloc-SIZE.dt}}
"aix-tls-reloc.so"}
{"TLS section" "-shared -bE:aix-tls-section.ex"