aboutsummaryrefslogtreecommitdiff
path: root/bfd/elflink.c
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2021-03-03 12:14:55 +1030
committerAlan Modra <amodra@gmail.com>2021-03-03 17:46:36 +1030
commit5789f845fbf67d271e0f5ff154eb03319b551211 (patch)
treed1cf1f67c603d4d4eb3ef237d7054fb351eeedbe /bfd/elflink.c
parent270f32fc50b465e84c214a17d4ad3aebc3161bae (diff)
downloadgdb-5789f845fbf67d271e0f5ff154eb03319b551211.zip
gdb-5789f845fbf67d271e0f5ff154eb03319b551211.tar.gz
gdb-5789f845fbf67d271e0f5ff154eb03319b551211.tar.bz2
--gc-sections with groups and start/stop syms
The testcases added here show situations where synthesized start/stop symbols don't cause their associated input sections to be marked. Fixed with the elflink.c and ldlang.c changes. bfd/ PR 27500 * elflink.c (_bfd_elf_gc_mark_rsec): Do special start/stop processing not when start/stop symbol section is unmarked but on first time a start/stop symbol is processed. ld/ * ldlang.c (insert_undefined): Don't mark symbols here. (lang_mark_undefineds): Do so here instead, new function. (lang_process): Call lang_mark_undefineds. * testsuite/ld-gc/start3.d, * testsuite/ld-gc/start3.s: New test. * testsuite/ld-gc/start4.d, * testsuite/ld-gc/start4.s: New test. * testsuite/ld-gc/gc.exp: Run them.
Diffstat (limited to 'bfd/elflink.c')
-rw-r--r--bfd/elflink.c8
1 files changed, 6 insertions, 2 deletions
diff --git a/bfd/elflink.c b/bfd/elflink.c
index 74b54c2..e1278a5 100644
--- a/bfd/elflink.c
+++ b/bfd/elflink.c
@@ -13422,6 +13422,8 @@ _bfd_elf_gc_mark_rsec (struct bfd_link_info *info, asection *sec,
if (r_symndx >= cookie->locsymcount
|| ELF_ST_BIND (cookie->locsyms[r_symndx].st_info) != STB_LOCAL)
{
+ bfd_boolean was_marked;
+
h = cookie->sym_hashes[r_symndx - cookie->extsymoff];
if (h == NULL)
{
@@ -13432,6 +13434,8 @@ _bfd_elf_gc_mark_rsec (struct bfd_link_info *info, asection *sec,
while (h->root.type == bfd_link_hash_indirect
|| h->root.type == bfd_link_hash_warning)
h = (struct elf_link_hash_entry *) h->root.u.i.link;
+
+ was_marked = h->mark;
h->mark = 1;
/* Keep all aliases of the symbol too. If an object symbol
needs to be copied into .dynbss then all of its aliases
@@ -13444,7 +13448,7 @@ _bfd_elf_gc_mark_rsec (struct bfd_link_info *info, asection *sec,
hw->mark = 1;
}
- if (h->start_stop && !h->root.ldscript_def)
+ if (!was_marked && h->start_stop && !h->root.ldscript_def)
{
if (info->start_stop_gc)
return NULL;
@@ -13455,7 +13459,7 @@ _bfd_elf_gc_mark_rsec (struct bfd_link_info *info, asection *sec,
else if (start_stop != NULL)
{
asection *s = h->u2.start_stop_section;
- *start_stop = !s->gc_mark;
+ *start_stop = TRUE;
return s;
}
}