diff options
author | Clément Chigot <clement.chigot@atos.net> | 2021-12-17 14:46:01 +0100 |
---|---|---|
committer | Clément Chigot <clement.chigot@atos.net> | 2022-01-10 09:14:57 +0100 |
commit | 3c5038247c8a5fcff18fd81249b0801a95569939 (patch) | |
tree | 2705a789bb9771f4d0f6f8709e390bc5666b9070 /gas/config/tc-ppc.c | |
parent | 4cfa9e3f28c8c5156b9773cc94192233947d351c (diff) | |
download | fsf-binutils-gdb-3c5038247c8a5fcff18fd81249b0801a95569939.zip fsf-binutils-gdb-3c5038247c8a5fcff18fd81249b0801a95569939.tar.gz fsf-binutils-gdb-3c5038247c8a5fcff18fd81249b0801a95569939.tar.bz2 |
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.
Diffstat (limited to 'gas/config/tc-ppc.c')
-rw-r--r-- | gas/config/tc-ppc.c | 32 |
1 files changed, 19 insertions, 13 deletions
diff --git a/gas/config/tc-ppc.c b/gas/config/tc-ppc.c index c7af7b7..159d315 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 |