From eb09df162bafa67abee713be594a99bd20bd6825 Mon Sep 17 00:00:00 2001 From: "H.J. Lu" Date: Mon, 16 Aug 2021 06:46:44 -0700 Subject: as: Replace the removed symbol with the versioned symbol When a symbol removed by .symver is used in relocation and there is one and only one versioned symbol, don't remove the symbol. Instead, mark it to be removed and replace the removed symbol used in relocation with the versioned symbol before generating relocation. PR gas/28157 * symbols.c (symbol_flags): Add removed. (symbol_entry_find): Updated. (symbol_mark_removed): New function. (symbol_removed_p): Likewise. * symbols.h (symbol_mark_removed): New prototype. (symbol_removed_p): Likewise. * write.c (write_relocs): Call obj_fixup_removed_symbol on removed fixp->fx_addsy and fixp->fx_subsy if defined. (set_symtab): Don't add a symbol if symbol_removed_p returns true. * config/obj-elf.c (elf_frob_symbol): Don't remove the symbol if it is used on relocation. Instead, mark it as to be removed and issue an error if the symbol has more than one versioned name. (elf_fixup_removed_symbol): New function. * config/obj-elf.h (elf_fixup_removed_symbol): New prototype. (obj_fixup_removed_symbol): New. * testsuite/gas/symver/symver11.d: Updated expected error message. * testsuite/gas/symver/symver16.d: New file. * testsuite/gas/symver/symver16.s: Likewise. --- gas/write.c | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) (limited to 'gas/write.c') diff --git a/gas/write.c b/gas/write.c index 253dfc4..e2c7bf2 100644 --- a/gas/write.c +++ b/gas/write.c @@ -1289,6 +1289,13 @@ write_relocs (bfd *abfd ATTRIBUTE_UNUSED, asection *sec, as_bad_where (fixp->fx_file, fixp->fx_line, _("internal error: fixup not contained within frag")); +#ifdef obj_fixup_removed_symbol + if (fixp->fx_addsy && symbol_removed_p (fixp->fx_addsy)) + obj_fixup_removed_symbol (&fixp->fx_addsy); + if (fixp->fx_subsy && symbol_removed_p (fixp->fx_subsy)) + obj_fixup_removed_symbol (&fixp->fx_subsy); +#endif + #ifndef RELOC_EXPANSION_POSSIBLE *reloc = tc_gen_reloc (sec, fixp); #else @@ -1755,9 +1762,10 @@ set_symtab (void) two. Generate unused section symbols only if needed. */ nsyms = 0; for (symp = symbol_rootP; symp; symp = symbol_next (symp)) - if (bfd_keep_unused_section_symbols (stdoutput) - || !symbol_section_p (symp) - || symbol_used_in_reloc_p (symp)) + if (!symbol_removed_p (symp) + && (bfd_keep_unused_section_symbols (stdoutput) + || !symbol_section_p (symp) + || symbol_used_in_reloc_p (symp))) nsyms++; if (nsyms) @@ -1768,9 +1776,10 @@ set_symtab (void) asympp = (asymbol **) bfd_alloc (stdoutput, amt); symp = symbol_rootP; for (i = 0; i < nsyms; symp = symbol_next (symp)) - if (bfd_keep_unused_section_symbols (stdoutput) - || !symbol_section_p (symp) - || symbol_used_in_reloc_p (symp)) + if (!symbol_removed_p (symp) + && (bfd_keep_unused_section_symbols (stdoutput) + || !symbol_section_p (symp) + || symbol_used_in_reloc_p (symp))) { asympp[i] = symbol_get_bfdsym (symp); if (asympp[i]->flags != BSF_SECTION_SYM -- cgit v1.1