From 3c5038247c8a5fcff18fd81249b0801a95569939 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Cl=C3=A9ment=20Chigot?= Date: Fri, 17 Dec 2021 14:46:01 +0100 Subject: [PATCH] XCOFF: add support for TLS relocations on hidden symbols 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. --- bfd/coff-rs6000.c | 33 ++--- bfd/coff64-rs6000.c | 2 +- bfd/xcofflink.c | 55 ++++++- gas/config/tc-ppc.c | 32 ++-- gas/testsuite/gas/ppc/aix.exp | 4 +- gas/testsuite/gas/ppc/xcoff-tls-32.d | 106 ++++++++++++++ gas/testsuite/gas/ppc/xcoff-tls-64.d | 124 ++++++++++++++++ gas/testsuite/gas/ppc/xcoff-tls.s | 57 ++++++++ gas/testsuite/gas/ppc/xcoff-tlsm-32.d | 34 ----- gas/testsuite/gas/ppc/xcoff-tlsm-64.d | 36 ----- gas/testsuite/gas/ppc/xcoff-tlsm.s | 12 -- ld/testsuite/ld-powerpc/aix-tls-reloc-32.d | 35 ----- ld/testsuite/ld-powerpc/aix-tls-reloc-32.dd | 101 +++++++++++++ ld/testsuite/ld-powerpc/aix-tls-reloc-32.dt | 18 +++ ld/testsuite/ld-powerpc/aix-tls-reloc-64.d | 31 ---- ld/testsuite/ld-powerpc/aix-tls-reloc-64.dd | 119 +++++++++++++++ ld/testsuite/ld-powerpc/aix-tls-reloc-64.dt | 23 +++ ld/testsuite/ld-powerpc/aix-tls-reloc.s | 154 +++++++++++++++----- ld/testsuite/ld-powerpc/aix52.exp | 3 +- 19 files changed, 751 insertions(+), 228 deletions(-) create mode 100644 gas/testsuite/gas/ppc/xcoff-tls-32.d create mode 100644 gas/testsuite/gas/ppc/xcoff-tls-64.d create mode 100644 gas/testsuite/gas/ppc/xcoff-tls.s delete mode 100644 gas/testsuite/gas/ppc/xcoff-tlsm-32.d delete mode 100644 gas/testsuite/gas/ppc/xcoff-tlsm-64.d delete mode 100644 gas/testsuite/gas/ppc/xcoff-tlsm.s delete mode 100644 ld/testsuite/ld-powerpc/aix-tls-reloc-32.d create mode 100644 ld/testsuite/ld-powerpc/aix-tls-reloc-32.dd create mode 100644 ld/testsuite/ld-powerpc/aix-tls-reloc-32.dt delete mode 100644 ld/testsuite/ld-powerpc/aix-tls-reloc-64.d create mode 100644 ld/testsuite/ld-powerpc/aix-tls-reloc-64.dd create mode 100644 ld/testsuite/ld-powerpc/aix-tls-reloc-64.dt diff --git a/bfd/coff-rs6000.c b/bfd/coff-rs6000.c index 3248670db27..97e84a443b0 100644 --- a/bfd/coff-rs6000.c +++ b/bfd/coff-rs6000.c @@ -1106,7 +1106,7 @@ reloc_howto_type xcoff_howto_table[] = 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 */ @@ -3236,27 +3236,19 @@ xcoff_reloc_type_tls (bfd *input_bfd ATTRIBUTE_UNUSED, 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) @@ -3286,9 +3278,8 @@ xcoff_reloc_type_tls (bfd *input_bfd ATTRIBUTE_UNUSED, 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; @@ -3621,10 +3612,10 @@ xcoff_complain_overflow_unsigned_func (bfd *input_bfd, 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: diff --git a/bfd/coff64-rs6000.c b/bfd/coff64-rs6000.c index 6698f4345d8..01326d4503d 100644 --- a/bfd/coff64-rs6000.c +++ b/bfd/coff64-rs6000.c @@ -1350,7 +1350,7 @@ reloc_howto_type xcoff64_howto_table[] = 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 */ diff --git a/bfd/xcofflink.c b/bfd/xcofflink.c index a838c4b7726..ba07ba7f045 100644 --- a/bfd/xcofflink.c +++ b/bfd/xcofflink.c @@ -1178,6 +1178,26 @@ xcoff_find_reloc (struct internal_reloc *relocs, 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 @@ -1551,6 +1571,11 @@ xcoff_link_add_symbols (bfd *abfd, struct bfd_link_info *info) 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. */ @@ -1580,7 +1605,8 @@ xcoff_link_add_symbols (bfd *abfd, struct bfd_link_info *info) 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) @@ -1652,6 +1678,22 @@ xcoff_link_add_symbols (bfd *abfd, struct bfd_link_info *info) 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; + } + } } } @@ -1749,9 +1791,10 @@ xcoff_link_add_symbols (bfd *abfd, struct bfd_link_info *info) 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; @@ -1847,7 +1890,7 @@ xcoff_link_add_symbols (bfd *abfd, struct bfd_link_info *info) 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; @@ -1888,7 +1931,7 @@ xcoff_link_add_symbols (bfd *abfd, struct bfd_link_info *info) /* 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; diff --git a/gas/config/tc-ppc.c b/gas/config/tc-ppc.c index c7af7b76e08..159d3155b4c 100644 --- a/gas/config/tc-ppc.c +++ b/gas/config/tc-ppc.c @@ -7426,22 +7426,25 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg) 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; @@ -7519,12 +7522,15 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg) *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 diff --git a/gas/testsuite/gas/ppc/aix.exp b/gas/testsuite/gas/ppc/aix.exp index 85ed06e8a38..78f29f0674d 100644 --- a/gas/testsuite/gas/ppc/aix.exp +++ b/gas/testsuite/gas/ppc/aix.exp @@ -79,8 +79,8 @@ if { [istarget "powerpc*-*-aix*"] || [istarget "rs6000-*-aix*"] } then { 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" diff --git a/gas/testsuite/gas/ppc/xcoff-tls-32.d b/gas/testsuite/gas/ppc/xcoff-tls-32.d new file mode 100644 index 00000000000..eb71df09e41 --- /dev/null +++ b/gas/testsuite/gas/ppc/xcoff-tls-32.d @@ -0,0 +1,106 @@ +#as: -a32 +#source: xcoff-tls.s +#objdump: -Dr +#name: XCOFF TLS relocation (32 bit) + +.* +Disassembly of section .data: + +00000000 : + 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 : + 8: 00 00 00 58.* + 8: R_TLS_LD tdata_ext.* + +0000000c : + c: 00 00 00 58.* + c: R_TLS_IE tdata_ext.* + +00000010 : + 10: 00 00 00 58.* + 10: R_TLS_LE tdata_ext.* + +00000014 : + 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 : + 1c: 00 00 00 5c.* + 1c: R_TLS_LD tdata_int_csect.* + +00000020 : + 20: 00 00 00 5c.* + 20: R_TLS_IE tdata_int_csect.* + +00000024 : + 24: 00 00 00 5c.* + 24: R_TLS_LE tdata_int_csect.* + +00000028 : + 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 : + 30: 00 00 00 60.* + 30: R_TLS_LD tdata_int_csect.* + +00000034 : + 34: 00 00 00 60.* + 34: R_TLS_IE tdata_int_csect.* + +00000038 : + 38: 00 00 00 60.* + 38: R_TLS_LE tdata_int_csect.* + +0000003c : + 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 : + 44: 00 00 00 68.* + 44: R_TLS_LD tbss_ext.* + +00000048 : + 48: 00 00 00 68.* + 48: R_TLS_IE tbss_ext.* + +0000004c : + 4c: 00 00 00 68.* + 4c: R_TLS_LE tbss_ext.* + +00000050 <_\$TLSML>: + ... + 50: R_TLSML _\$TLSML.* + +Disassembly of section .tdata: + +00000058 : + 58: 00 00 00 01 .long 0x1 + +0000005c : + 5c: 00 00 00 02 .long 0x2 + 60: 00 00 00 03 .long 0x3 + 64:.* + +Disassembly of section .tbss: + +00000068 : + ... diff --git a/gas/testsuite/gas/ppc/xcoff-tls-64.d b/gas/testsuite/gas/ppc/xcoff-tls-64.d new file mode 100644 index 00000000000..7f3b6ebceb6 --- /dev/null +++ b/gas/testsuite/gas/ppc/xcoff-tls-64.d @@ -0,0 +1,124 @@ +#as: -a64 +#source: xcoff-tls.s +#objdump: -Dr +#name: XCOFF TLS relocation (64 bit) + +.* + + +Disassembly of section .data: + +0000000000000000 : + 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 : + 10: 00 00 00 00.* + 10: R_TLS_LD tdata_ext.* + 14: 00 00 00 a8.* + +0000000000000018 : + 18: 00 00 00 00.* + 18: R_TLS_IE tdata_ext.* + 1c: 00 00 00 a8.* + +0000000000000020 : + 20: 00 00 00 00.* + 20: R_TLS_LE tdata_ext.* + 24: 00 00 00 a8.* + +0000000000000028 : + 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 : + 38: 00 00 00 00.* + 38: R_TLS_LD tdata_int_csect.* + 3c: 00 00 00 ac.* + +0000000000000040 : + 40: 00 00 00 00.* + 40: R_TLS_IE tdata_int_csect.* + 44: 00 00 00 ac.* + +0000000000000048 : + 48: 00 00 00 00.* + 48: R_TLS_LE tdata_int_csect.* + 4c: 00 00 00 ac.* + +0000000000000050 : + 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 : + 60: 00 00 00 00.* + 60: R_TLS_LD tdata_int_csect.* + 64: 00 00 00 b0.* + +0000000000000068 : + 68: 00 00 00 00.* + 68: R_TLS_IE tdata_int_csect.* + 6c: 00 00 00 b0.* + +0000000000000070 : + 70: 00 00 00 00.* + 70: R_TLS_LE tdata_int_csect.* + 74: 00 00 00 b0.* + +0000000000000078 : + 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 : + 88: 00 00 00 00.* + 88: R_TLS_LD tbss_ext.* + 8c: 00 00 00 b8.* + +0000000000000090 : + 90: 00 00 00 00.* + 90: R_TLS_IE tbss_ext.* + 94: 00 00 00 b8.* + +0000000000000098 : + 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 : + a8: 00 00 00 01 .long 0x1 + +00000000000000ac : + ac: 00 00 00 02 .long 0x2 + b0: 00 00 00 03 .long 0x3 + b4:.* + +Disassembly of section .tbss: + +00000000000000b8 : + ... diff --git a/gas/testsuite/gas/ppc/xcoff-tls.s b/gas/testsuite/gas/ppc/xcoff-tls.s new file mode 100644 index 00000000000..83e77f19c1e --- /dev/null +++ b/gas/testsuite/gas/ppc/xcoff-tls.s @@ -0,0 +1,57 @@ +# 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 diff --git a/gas/testsuite/gas/ppc/xcoff-tlsm-32.d b/gas/testsuite/gas/ppc/xcoff-tlsm-32.d deleted file mode 100644 index a09dd1a2e4a..00000000000 --- a/gas/testsuite/gas/ppc/xcoff-tlsm-32.d +++ /dev/null @@ -1,34 +0,0 @@ -#as: -a32 -#source: xcoff-tlsm.s -#objdump: -Dr -#name: XCOFF TLSM relocation (32 bit) - -.* -Disassembly of section .data: - -00000000 : - 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 : - 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 : - 10: 00 00 00 01.* - ... - -Disassembly of section .tbss: - -00000020 : - ... diff --git a/gas/testsuite/gas/ppc/xcoff-tlsm-64.d b/gas/testsuite/gas/ppc/xcoff-tlsm-64.d deleted file mode 100644 index f447a517742..00000000000 --- a/gas/testsuite/gas/ppc/xcoff-tlsm-64.d +++ /dev/null @@ -1,36 +0,0 @@ -#as: -a64 -#source: xcoff-tlsm.s -#objdump: -Dr -#name: XCOFF TLSM relocation (64 bit) - -.* -Disassembly of section .data: - -0000000000000000 : - 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 : - 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 : - 20: 00 00 00 01.* - ... - -Disassembly of section .tbss: - -0000000000000030 : - ... diff --git a/gas/testsuite/gas/ppc/xcoff-tlsm.s b/gas/testsuite/gas/ppc/xcoff-tlsm.s deleted file mode 100644 index 0c857bf0aa9..00000000000 --- a/gas/testsuite/gas/ppc/xcoff-tlsm.s +++ /dev/null @@ -1,12 +0,0 @@ - .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 diff --git a/ld/testsuite/ld-powerpc/aix-tls-reloc-32.d b/ld/testsuite/ld-powerpc/aix-tls-reloc-32.d deleted file mode 100644 index 5103de50618..00000000000 --- a/ld/testsuite/ld-powerpc/aix-tls-reloc-32.d +++ /dev/null @@ -1,35 +0,0 @@ -#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 -.* diff --git a/ld/testsuite/ld-powerpc/aix-tls-reloc-32.dd b/ld/testsuite/ld-powerpc/aix-tls-reloc-32.dd new file mode 100644 index 00000000000..001a7f0c65e --- /dev/null +++ b/ld/testsuite/ld-powerpc/aix-tls-reloc-32.dd @@ -0,0 +1,101 @@ +#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: + +.* : +.* +.* +.* +.* +.* + +.* : +.*: ff ff 88 00 .* +.*: R_TLS tdata_ext.* + +.* <.tdata_ext_gd>: +.*: 00 00 00 00 .* +.*: R_TLSM tdata_ext.* + +.* : +.*: ff ff 88 00 .* +.*: R_TLS_LD tdata_ext.* + +.* : +.*: ff ff 88 00 .* +.*: R_TLS_IE tdata_ext.* + +.* : +.*: ff ff 88 00 .* +.*: R_TLS_LE tdata_ext.* + +.* : +.*: ff ff 88 04 .* +.*: R_TLS tdata_int_csect.* + +.* <.tdata_int1_gd>: +.*: 00 00 00 00 .* +.*: R_TLSM tdata_int_csect.* + +.* : +.*: ff ff 88 04 .* +.*: R_TLS_LD tdata_int_csect.* + +.* : +.*: ff ff 88 04 .* +.*: R_TLS_IE tdata_int_csect.* + +.* : +.*: ff ff 88 04 .* +.*: R_TLS_LE tdata_int_csect.* + +.* : +.*: ff ff 88 08 .* +.*: R_TLS tdata_int_csect.* + +.* <.tdata_int2_gd>: +.*: 00 00 00 00 .* +.*: R_TLSM tdata_int_csect.* + +.* : +.*: ff ff 88 08 .* +.*: R_TLS_LD tdata_int_csect.* + +.* : +.*: ff ff 88 08 .* +.*: R_TLS_IE tdata_int_csect.* + +.* : +.*: ff ff 88 08 .* +.*: R_TLS_LE tdata_int_csect.* + +.* : +.*: ff ff 88 10 .* +.*: R_TLS tbss_ext.* + +.* <.tbss_ext_gd>: +.*: 00 00 00 00 .* +.*: R_TLSM tbss_ext.* + +.* : +.*: ff ff 88 10 .* +.*: R_TLS_LD tbss_ext.* + +.* : +.*: ff ff 88 10 .* +.*: R_TLS_IE tbss_ext.* + +.* : +.*: ff ff 88 10 .* +.*: R_TLS_LE tbss_ext.* + +.* <_\$TLSML>: + ... +.*: R_TLSML _\$TLSML.* diff --git a/ld/testsuite/ld-powerpc/aix-tls-reloc-32.dt b/ld/testsuite/ld-powerpc/aix-tls-reloc-32.dt new file mode 100644 index 00000000000..91ceb669eb9 --- /dev/null +++ b/ld/testsuite/ld-powerpc/aix-tls-reloc-32.dt @@ -0,0 +1,18 @@ + +tmpdir/aix-tls-reloc.so: file format aixcoff-rs6000 + + +Disassembly of section .tdata: + +ffff8800 : +ffff8800: 00 00 00 01 .long 0x1 + +ffff8804 : +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 : + ... diff --git a/ld/testsuite/ld-powerpc/aix-tls-reloc-64.d b/ld/testsuite/ld-powerpc/aix-tls-reloc-64.d deleted file mode 100644 index 71f6302ec4d..00000000000 --- a/ld/testsuite/ld-powerpc/aix-tls-reloc-64.d +++ /dev/null @@ -1,31 +0,0 @@ -#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 -.* diff --git a/ld/testsuite/ld-powerpc/aix-tls-reloc-64.dd b/ld/testsuite/ld-powerpc/aix-tls-reloc-64.dd new file mode 100644 index 00000000000..dc0c48d1163 --- /dev/null +++ b/ld/testsuite/ld-powerpc/aix-tls-reloc-64.dd @@ -0,0 +1,119 @@ +#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: + +.* : +.* +.* +.* +.* +.* +.* +.* + +.* : +.*: ff ff ff ff .* +.*: R_TLS tdata_ext.* +.*: ff ff 88 00 .* + +.* <.tdata_ext_gd>: + ... +.*: R_TLSM tdata_ext.* + +.*: +.*: ff ff ff ff .* +.*: R_TLS_LD tdata_ext.* +.*: ff ff 88 00 .* + +.* : +.*: ff ff ff ff .* +.*: R_TLS_IE tdata_ext.* +.*: ff ff 88 00 .* + +.* : +.*: ff ff ff ff .* +.*: R_TLS_LE tdata_ext.* +.*: ff ff 88 00 .* + +.* : +.*: ff ff ff ff .* +.*: R_TLS tdata_int_csect.* +.*: ff ff 88 04 .* + +.* <.tdata_int1_gd>: + ... +.*: R_TLSM tdata_int_csect.* + +.* : +.*: ff ff ff ff .* +.*: R_TLS_LD tdata_int_csect.* +.*: ff ff 88 04 .* + +.* : +.*: ff ff ff ff .* +.*: R_TLS_IE tdata_int_csect.* +.*: ff ff 88 04 .* + +.* : +.*: ff ff ff ff .* +.*: R_TLS_LE tdata_int_csect.* +.*: ff ff 88 04 .* + +.* : +.*: ff ff ff ff .* +.*: R_TLS tdata_int_csect.* +.*: ff ff 88 08 .* + +.* <.tdata_int2_gd>: + ... +.*: R_TLSM tdata_int_csect.* + +.* : +.*: ff ff ff ff .* +.*: R_TLS_LD tdata_int_csect.* +.*: ff ff 88 08 .* + +.* : +.*: ff ff ff ff .* +.*: R_TLS_IE tdata_int_csect.* +.*: ff ff 88 08 .* + +.* : +.*: ff ff ff ff .* +.*: R_TLS_LE tdata_int_csect.* +.*: ff ff 88 08 .* + +.* : +.*: ff ff ff ff .* +.*: R_TLS tbss_ext.* +.*: ff ff 88 10 .* + +.* <.tbss_ext_gd>: + ... +.*: R_TLSM tbss_ext.* + +.* : +.*: ff ff ff ff .* +.*: R_TLS_LD tbss_ext.* +.*: ff ff 88 10 .* + +.* : +.*: ff ff ff ff .* +.*: R_TLS_IE tbss_ext.* +.*: ff ff 88 10 .* + +.* : +.*: ff ff ff ff .* +.*: R_TLS_LE tbss_ext.* +.*: ff ff 88 10 .* + +.* <_\$TLSML>: + ... +.*: R_TLSML _\$TLSML.* diff --git a/ld/testsuite/ld-powerpc/aix-tls-reloc-64.dt b/ld/testsuite/ld-powerpc/aix-tls-reloc-64.dt new file mode 100644 index 00000000000..9ddc5737e3a --- /dev/null +++ b/ld/testsuite/ld-powerpc/aix-tls-reloc-64.dt @@ -0,0 +1,23 @@ +#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 : +ffffffffffff8800:.* + +ffffffffffff8804 : +ffffffffffff8804:.* +ffffffffffff8808:.* +ffffffffffff880c:.* + +Disassembly of section .tbss: + +ffffffffffff8810 : + ... diff --git a/ld/testsuite/ld-powerpc/aix-tls-reloc.s b/ld/testsuite/ld-powerpc/aix-tls-reloc.s index 62ef73cdc34..062fc949846 100644 --- a/ld/testsuite/ld-powerpc/aix-tls-reloc.s +++ b/ld/testsuite/ld-powerpc/aix-tls-reloc.s @@ -1,65 +1,147 @@ - .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 diff --git a/ld/testsuite/ld-powerpc/aix52.exp b/ld/testsuite/ld-powerpc/aix52.exp index 8dccce50ff5..b49f3f5e1cf 100644 --- a/ld/testsuite/ld-powerpc/aix52.exp +++ b/ld/testsuite/ld-powerpc/aix52.exp @@ -284,7 +284,8 @@ set aix7tests { {"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" -- 2.30.2