Mark debug sections referenced by kept debug sections

If a debug section is referenced by a kept debug section, it should
also be kept.

Some targets, like mips, keep input files when there are some special
sections, like .gnu.attributes, even if input file is unused otherwise.
In this case, all debug sections are kept.  The new test will fail on
such targets.  We can either fix those targets or XFAIL the test.

bfd/

	PR ld/20882
	* elflink.c (elf_gc_mark_debug_section): New function.
	(_bfd_elf_gc_mark_extra_sections): Mark any debug sections
	referenced by kept debug sections.

ld/

	PR ld/20882
	* testsuite/ld-gc/gc.exp: Run pr20882.
	* testsuite/ld-gc/pr20882.d: New file.
	* testsuite/ld-gc/pr20882a.s: Likewise.
	* testsuite/ld-gc/pr20882b.s: Likewise.
	* testsuite/ld-gc/pr20882c.s: Likewise.
This commit is contained in:
H.J. Lu
2017-05-17 07:57:15 -07:00
parent 0d5c69990c
commit b7c871edcd
8 changed files with 108 additions and 28 deletions

View File

@ -1,3 +1,10 @@
2017-05-17 H.J. Lu <hongjiu.lu@intel.com>
PR ld/20882
* elflink.c (elf_gc_mark_debug_section): New function.
(_bfd_elf_gc_mark_extra_sections): Mark any debug sections
referenced by kept debug sections.
2017-05-16 Alan Modra <amodra@gmail.com> 2017-05-16 Alan Modra <amodra@gmail.com>
* elf-m10300.c: Rename occurrences of non_ir_ref. * elf-m10300.c: Rename occurrences of non_ir_ref.

View File

@ -12669,6 +12669,24 @@ _bfd_elf_gc_mark_hook (asection *sec,
return NULL; return NULL;
} }
/* Return the global debug definition section. */
static asection *
elf_gc_mark_debug_section (asection *sec ATTRIBUTE_UNUSED,
struct bfd_link_info *info ATTRIBUTE_UNUSED,
Elf_Internal_Rela *rel ATTRIBUTE_UNUSED,
struct elf_link_hash_entry *h,
Elf_Internal_Sym *sym ATTRIBUTE_UNUSED)
{
if (h != NULL
&& (h->root.type == bfd_link_hash_defined
|| h->root.type == bfd_link_hash_defweak)
&& (h->root.u.def.section->flags & SEC_DEBUGGING) != 0)
return h->root.u.def.section;
return NULL;
}
/* For undefined __start_<name> and __stop_<name> symbols, return the /* For undefined __start_<name> and __stop_<name> symbols, return the
first input section matching <name>. Return NULL otherwise. */ first input section matching <name>. Return NULL otherwise. */
@ -12930,6 +12948,7 @@ _bfd_elf_gc_mark_extra_sections (struct bfd_link_info *info,
asection *isec; asection *isec;
bfd_boolean some_kept; bfd_boolean some_kept;
bfd_boolean debug_frag_seen; bfd_boolean debug_frag_seen;
bfd_boolean has_kept_debug_info;
if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour) if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour)
continue; continue;
@ -12937,7 +12956,7 @@ _bfd_elf_gc_mark_extra_sections (struct bfd_link_info *info,
/* Ensure all linker created sections are kept, /* Ensure all linker created sections are kept,
see if any other section is already marked, see if any other section is already marked,
and note if we have any fragmented debug sections. */ and note if we have any fragmented debug sections. */
debug_frag_seen = some_kept = FALSE; debug_frag_seen = some_kept = has_kept_debug_info = FALSE;
for (isec = ibfd->sections; isec != NULL; isec = isec->next) for (isec = ibfd->sections; isec != NULL; isec = isec->next)
{ {
if ((isec->flags & SEC_LINKER_CREATED) != 0) if ((isec->flags & SEC_LINKER_CREATED) != 0)
@ -12967,14 +12986,14 @@ _bfd_elf_gc_mark_extra_sections (struct bfd_link_info *info,
|| (isec->flags & (SEC_ALLOC | SEC_LOAD | SEC_RELOC)) == 0) || (isec->flags & (SEC_ALLOC | SEC_LOAD | SEC_RELOC)) == 0)
&& elf_next_in_group (isec) == NULL) && elf_next_in_group (isec) == NULL)
isec->gc_mark = 1; isec->gc_mark = 1;
if (isec->gc_mark && (isec->flags & SEC_DEBUGGING) != 0)
has_kept_debug_info = TRUE;
} }
if (! debug_frag_seen)
continue;
/* Look for CODE sections which are going to be discarded, /* Look for CODE sections which are going to be discarded,
and find and discard any fragmented debug sections which and find and discard any fragmented debug sections which
are associated with that code section. */ are associated with that code section. */
if (debug_frag_seen)
for (isec = ibfd->sections; isec != NULL; isec = isec->next) for (isec = ibfd->sections; isec != NULL; isec = isec->next)
if ((isec->flags & SEC_CODE) != 0 if ((isec->flags & SEC_CODE) != 0
&& isec->gc_mark == 0) && isec->gc_mark == 0)
@ -12984,10 +13003,10 @@ _bfd_elf_gc_mark_extra_sections (struct bfd_link_info *info,
ilen = strlen (isec->name); ilen = strlen (isec->name);
/* Association is determined by the name of the debug section /* Association is determined by the name of the debug
containing the name of the code section as a suffix. For section containing the name of the code section as
example .debug_line.text.foo is a debug section associated a suffix. For example .debug_line.text.foo is a
with .text.foo. */ debug section associated with .text.foo. */
for (dsec = ibfd->sections; dsec != NULL; dsec = dsec->next) for (dsec = ibfd->sections; dsec != NULL; dsec = dsec->next)
{ {
unsigned int dlen; unsigned int dlen;
@ -13001,11 +13020,18 @@ _bfd_elf_gc_mark_extra_sections (struct bfd_link_info *info,
if (dlen > ilen if (dlen > ilen
&& strncmp (dsec->name + (dlen - ilen), && strncmp (dsec->name + (dlen - ilen),
isec->name, ilen) == 0) isec->name, ilen) == 0)
{
dsec->gc_mark = 0; dsec->gc_mark = 0;
} }
} }
}
/* Mark debug sections referenced by kept debug sections. */
if (has_kept_debug_info)
for (isec = ibfd->sections; isec != NULL; isec = isec->next)
if (isec->gc_mark
&& (isec->flags & SEC_DEBUGGING) != 0)
if (!_bfd_elf_gc_mark (info, isec,
elf_gc_mark_debug_section))
return FALSE;
} }
return TRUE; return TRUE;
} }

View File

@ -1,3 +1,12 @@
2017-05-17 H.J. Lu <hongjiu.lu@intel.com>
PR ld/20882
* testsuite/ld-gc/gc.exp: Run pr20882.
* testsuite/ld-gc/pr20882.d: New file.
* testsuite/ld-gc/pr20882a.s: Likewise.
* testsuite/ld-gc/pr20882b.s: Likewise.
* testsuite/ld-gc/pr20882c.s: Likewise.
2017-05-16 H.J. Lu <hongjiu.lu@intel.com> 2017-05-16 H.J. Lu <hongjiu.lu@intel.com>
PR ld/21481 PR ld/21481

View File

@ -104,6 +104,7 @@ run_dump_test "start"
run_dump_test "pr19167" run_dump_test "pr19167"
if { [is_elf_format] } then { if { [is_elf_format] } then {
run_dump_test "all-debug-sections" run_dump_test "all-debug-sections"
run_dump_test "pr20882"
} }
if { [is_elf_format] && [check_shared_lib_support] } then { if { [is_elf_format] && [check_shared_lib_support] } then {

View File

@ -0,0 +1,10 @@
#name: --gc-sections with relocations in debug section
#source: pr20882a.s
#source: pr20882b.s
#source: pr20882c.s
#as: -gdwarf-sections
#ld: --gc-sections -e main
#readelf: -x .debug_info
#...
+0x0+ [0-9a-f ]+ 28 +.+\(

View File

@ -0,0 +1,11 @@
.text
.globl main
.type main, %function
main:
.byte 0
.section .debug_info,"",%progbits
.dc.a t.c.4903c230+2
.section .debug_line,"",%progbits
.byte 0

View File

@ -0,0 +1,8 @@
.section .debug_info,"",%progbits
.hidden t.c.4903c230
.globl t.c.4903c230
t.c.4903c230:
.byte 0x28
.section .debug_line,"",%progbits
.byte 0

View File

@ -0,0 +1,8 @@
.section .debug_info,"",%progbits
.hidden t.c.4903c231
.globl t.c.4903c231
t.c.4903c231:
.byte 0x29
.section .debug_line,"",%progbits
.byte 0