aboutsummaryrefslogtreecommitdiff
path: root/gas/symbols.c
diff options
context:
space:
mode:
authorH.J. Lu <hjl.tools@gmail.com>2021-08-16 06:46:44 -0700
committerH.J. Lu <hjl.tools@gmail.com>2021-08-16 06:46:44 -0700
commiteb09df162bafa67abee713be594a99bd20bd6825 (patch)
tree8cea62798489a53661cacaa7eab76421d8340463 /gas/symbols.c
parent70069e7823d412a01d983379504222c557319cbd (diff)
downloadgdb-eb09df162bafa67abee713be594a99bd20bd6825.zip
gdb-eb09df162bafa67abee713be594a99bd20bd6825.tar.gz
gdb-eb09df162bafa67abee713be594a99bd20bd6825.tar.bz2
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.
Diffstat (limited to 'gas/symbols.c')
-rw-r--r--gas/symbols.c26
1 files changed, 25 insertions, 1 deletions
diff --git a/gas/symbols.c b/gas/symbols.c
index 302eb4b..3cb9425 100644
--- a/gas/symbols.c
+++ b/gas/symbols.c
@@ -78,6 +78,10 @@ struct symbol_flags
before. It is cleared as soon as any direct reference to the
symbol is present. */
unsigned int weakrefd : 1;
+
+ /* Whether the symbol has been marked to be removed by a .symver
+ directive. */
+ unsigned int removed : 1;
};
/* A pointer in the symbol may point to either a complete symbol
@@ -194,7 +198,7 @@ static void *
symbol_entry_find (htab_t table, const char *name)
{
hashval_t hash = htab_hash_string (name);
- symbol_entry_t needle = { { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ symbol_entry_t needle = { { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
hash, name, 0, 0, 0 } };
return htab_find_with_hash (table, &needle, hash);
}
@@ -2807,6 +2811,26 @@ symbol_written_p (symbolS *s)
return s->flags.written;
}
+/* Mark a symbol as to be removed. */
+
+void
+symbol_mark_removed (symbolS *s)
+{
+ if (s->flags.local_symbol)
+ return;
+ s->flags.removed = 1;
+}
+
+/* Return whether a symbol has been marked to be removed. */
+
+int
+symbol_removed_p (symbolS *s)
+{
+ if (s->flags.local_symbol)
+ return 0;
+ return s->flags.removed;
+}
+
/* Mark a symbol has having been resolved. */
void