diff options
author | Alan Modra <amodra@gmail.com> | 2021-03-03 12:14:55 +1030 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2021-03-03 17:46:36 +1030 |
commit | 5789f845fbf67d271e0f5ff154eb03319b551211 (patch) | |
tree | d1cf1f67c603d4d4eb3ef237d7054fb351eeedbe /bfd/elflink.c | |
parent | 270f32fc50b465e84c214a17d4ad3aebc3161bae (diff) | |
download | gdb-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.c | 8 |
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; } } |