aboutsummaryrefslogtreecommitdiff
path: root/gas/config/tc-ppc.c
diff options
context:
space:
mode:
authorClément Chigot <clement.chigot@atos.net>2021-12-17 14:46:01 +0100
committerClément Chigot <clement.chigot@atos.net>2022-01-10 09:14:57 +0100
commit3c5038247c8a5fcff18fd81249b0801a95569939 (patch)
tree2705a789bb9771f4d0f6f8709e390bc5666b9070 /gas/config/tc-ppc.c
parent4cfa9e3f28c8c5156b9773cc94192233947d351c (diff)
downloadfsf-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.c32
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