aboutsummaryrefslogtreecommitdiff
path: root/bfd/xcofflink.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 /bfd/xcofflink.c
parent4cfa9e3f28c8c5156b9773cc94192233947d351c (diff)
downloadgdb-3c5038247c8a5fcff18fd81249b0801a95569939.zip
gdb-3c5038247c8a5fcff18fd81249b0801a95569939.tar.gz
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 'bfd/xcofflink.c')
-rw-r--r--bfd/xcofflink.c55
1 files changed, 49 insertions, 6 deletions
diff --git a/bfd/xcofflink.c b/bfd/xcofflink.c
index a838c4b..ba07ba7 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;