--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.
This commit is contained in:
Alan Modra 2021-03-03 12:14:55 +10:30
parent 270f32fc50
commit 5789f845fb
9 changed files with 112 additions and 4 deletions

View File

@ -1,3 +1,10 @@
2021-03-03 Alan Modra <amodra@gmail.com>
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.
2021-03-03 Alan Modra <amodra@gmail.com> 2021-03-03 Alan Modra <amodra@gmail.com>
* reloc.c: Include x86_64.h rather than internal.h. * reloc.c: Include x86_64.h rather than internal.h.

View File

@ -13422,6 +13422,8 @@ _bfd_elf_gc_mark_rsec (struct bfd_link_info *info, asection *sec,
if (r_symndx >= cookie->locsymcount if (r_symndx >= cookie->locsymcount
|| ELF_ST_BIND (cookie->locsyms[r_symndx].st_info) != STB_LOCAL) || ELF_ST_BIND (cookie->locsyms[r_symndx].st_info) != STB_LOCAL)
{ {
bfd_boolean was_marked;
h = cookie->sym_hashes[r_symndx - cookie->extsymoff]; h = cookie->sym_hashes[r_symndx - cookie->extsymoff];
if (h == NULL) 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 while (h->root.type == bfd_link_hash_indirect
|| h->root.type == bfd_link_hash_warning) || h->root.type == bfd_link_hash_warning)
h = (struct elf_link_hash_entry *) h->root.u.i.link; h = (struct elf_link_hash_entry *) h->root.u.i.link;
was_marked = h->mark;
h->mark = 1; h->mark = 1;
/* Keep all aliases of the symbol too. If an object symbol /* Keep all aliases of the symbol too. If an object symbol
needs to be copied into .dynbss then all of its aliases 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; 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) if (info->start_stop_gc)
return NULL; return NULL;
@ -13455,7 +13459,7 @@ _bfd_elf_gc_mark_rsec (struct bfd_link_info *info, asection *sec,
else if (start_stop != NULL) else if (start_stop != NULL)
{ {
asection *s = h->u2.start_stop_section; asection *s = h->u2.start_stop_section;
*start_stop = !s->gc_mark; *start_stop = TRUE;
return s; return s;
} }
} }

View File

@ -1,3 +1,15 @@
2021-03-03 Alan Modra <amodra@gmail.com>
PR 27500
* 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.
2021-03-03 Alan Modra <amodra@gmail.com> 2021-03-03 Alan Modra <amodra@gmail.com>
* testsuite/ld-gc/gc.exp: Define UNDERSCORE in ASFLAGS. * testsuite/ld-gc/gc.exp: Define UNDERSCORE in ASFLAGS.

View File

@ -3986,8 +3986,6 @@ insert_undefined (const char *name)
h->type = bfd_link_hash_undefined; h->type = bfd_link_hash_undefined;
h->u.undef.abfd = NULL; h->u.undef.abfd = NULL;
h->non_ir_ref_regular = TRUE; h->non_ir_ref_regular = TRUE;
if (is_elf_hash_table (link_info.hash))
((struct elf_link_hash_entry *) h)->mark = 1;
bfd_link_add_undef (link_info.hash, h); bfd_link_add_undef (link_info.hash, h);
} }
} }
@ -4005,6 +4003,23 @@ lang_place_undefineds (void)
insert_undefined (ptr->name); insert_undefined (ptr->name);
} }
/* Mark -u symbols against garbage collection. */
static void
lang_mark_undefineds (void)
{
ldlang_undef_chain_list_type *ptr;
if (bfd_get_flavour (link_info.output_bfd) == bfd_target_elf_flavour)
for (ptr = ldlang_undef_chain_list_head; ptr != NULL; ptr = ptr->next)
{
struct elf_link_hash_entry *h = (struct elf_link_hash_entry *)
bfd_link_hash_lookup (link_info.hash, ptr->name, FALSE, FALSE, TRUE);
if (h != NULL)
h->mark = 1;
}
}
/* Structure used to build the list of symbols that the user has required /* Structure used to build the list of symbols that the user has required
be defined. */ be defined. */
@ -8116,6 +8131,8 @@ lang_process (void)
/* Remove unreferenced sections if asked to. */ /* Remove unreferenced sections if asked to. */
lang_gc_sections (); lang_gc_sections ();
lang_mark_undefineds ();
/* Check relocations. */ /* Check relocations. */
lang_check_relocs (); lang_check_relocs ();

View File

@ -101,6 +101,8 @@ if { [is_elf_format] } then {
run_dump_test "stop" run_dump_test "stop"
run_dump_test "start" run_dump_test "start"
run_dump_test "start2" run_dump_test "start2"
run_dump_test "start3"
run_dump_test "start4"
} }
if { [is_elf_format] && [check_shared_lib_support] } then { if { [is_elf_format] && [check_shared_lib_support] } then {

View File

@ -0,0 +1,9 @@
#name: --gc-sections with groups and start/stop syms
#ld: --gc-sections -e _start
#nm: -n
#notarget: [is_generic]
#xfail: bfin-*-*linux* frv-*-*linux* lm32-*-*linux*
#...
[0-9a-f]+ T +bar
#...

View File

@ -0,0 +1,29 @@
.text
.global _start
_start:
.dc.a foo
.ifdef UNDERSCORE
.dc.a ___start_xx, ___stop_xx
.else
.dc.a __start_xx, __stop_xx
.endif
.section .text,"axG",%progbits,foo_group
.global foo
foo:
.dc.a 0
.section xx,"aG",%progbits,foo_group
.global foo_xx
foo_xx:
.dc.a 1
.section .text,"axG",%progbits,bar_group
.global bar
bar:
.dc.a 2
.section xx,"aG",%progbits,bar_group
.global bar_xx
bar_xx:
.dc.a 3

View File

@ -0,0 +1,9 @@
#name: --gc-sections with other syms and start/stop syms
#ld: --gc-sections -e _start
#nm: -n
#target: [supports_gnu_unique]
#xfail: bfin-*-*linux* frv-*-*linux* lm32-*-*linux*
#...
[0-9a-f]+ R +bar_xx
#...

View File

@ -0,0 +1,19 @@
.text
.global _start
_start:
.dc.a foo_xx
.ifdef UNDERSCORE
.dc.a ___start_xx, ___stop_xx
.else
.dc.a __start_xx, __stop_xx
.endif
.section xx,"a",%progbits,unique,0
.global foo_xx
foo_xx:
.dc.a 1
.section xx,"a",%progbits,unique,1
.global bar_xx
bar_xx:
.dc.a 3