aboutsummaryrefslogtreecommitdiff
path: root/bfd
diff options
context:
space:
mode:
authorH.J. Lu <hjl.tools@gmail.com>2017-05-17 07:57:15 -0700
committerH.J. Lu <hjl.tools@gmail.com>2017-05-17 07:57:26 -0700
commitb7c871edcd83ccdc5fcd8148a7f433efd6b52255 (patch)
treed1f43eadeeac5387cca51b23a1b8e9da8aa0fbb6 /bfd
parent0d5c69990c1992289f7b286600a43de4d5d44062 (diff)
downloadgdb-b7c871edcd83ccdc5fcd8148a7f433efd6b52255.zip
gdb-b7c871edcd83ccdc5fcd8148a7f433efd6b52255.tar.gz
gdb-b7c871edcd83ccdc5fcd8148a7f433efd6b52255.tar.bz2
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.
Diffstat (limited to 'bfd')
-rw-r--r--bfd/ChangeLog7
-rw-r--r--bfd/elflink.c82
2 files changed, 61 insertions, 28 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 532ba0c..31b3982 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -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>
* elf-m10300.c: Rename occurrences of non_ir_ref.
diff --git a/bfd/elflink.c b/bfd/elflink.c
index 60e0a32..bc10428 100644
--- a/bfd/elflink.c
+++ b/bfd/elflink.c
@@ -12669,6 +12669,24 @@ _bfd_elf_gc_mark_hook (asection *sec,
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
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;
bfd_boolean some_kept;
bfd_boolean debug_frag_seen;
+ bfd_boolean has_kept_debug_info;
if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour)
continue;
@@ -12937,7 +12956,7 @@ _bfd_elf_gc_mark_extra_sections (struct bfd_link_info *info,
/* Ensure all linker created sections are kept,
see if any other section is already marked,
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)
{
if ((isec->flags & SEC_LINKER_CREATED) != 0)
@@ -12967,45 +12986,52 @@ _bfd_elf_gc_mark_extra_sections (struct bfd_link_info *info,
|| (isec->flags & (SEC_ALLOC | SEC_LOAD | SEC_RELOC)) == 0)
&& elf_next_in_group (isec) == NULL)
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,
and find and discard any fragmented debug sections which
are associated with that code section. */
- for (isec = ibfd->sections; isec != NULL; isec = isec->next)
- if ((isec->flags & SEC_CODE) != 0
- && isec->gc_mark == 0)
- {
- unsigned int ilen;
- asection *dsec;
+ if (debug_frag_seen)
+ for (isec = ibfd->sections; isec != NULL; isec = isec->next)
+ if ((isec->flags & SEC_CODE) != 0
+ && isec->gc_mark == 0)
+ {
+ unsigned int ilen;
+ asection *dsec;
- ilen = strlen (isec->name);
+ ilen = strlen (isec->name);
- /* Association is determined by the name of the debug section
- containing the name of the code section as a suffix. For
- example .debug_line.text.foo is a debug section associated
- with .text.foo. */
- for (dsec = ibfd->sections; dsec != NULL; dsec = dsec->next)
- {
- unsigned int dlen;
+ /* Association is determined by the name of the debug
+ section containing the name of the code section as
+ a suffix. For example .debug_line.text.foo is a
+ debug section associated with .text.foo. */
+ for (dsec = ibfd->sections; dsec != NULL; dsec = dsec->next)
+ {
+ unsigned int dlen;
- if (dsec->gc_mark == 0
- || (dsec->flags & SEC_DEBUGGING) == 0)
- continue;
+ if (dsec->gc_mark == 0
+ || (dsec->flags & SEC_DEBUGGING) == 0)
+ continue;
- dlen = strlen (dsec->name);
+ dlen = strlen (dsec->name);
- if (dlen > ilen
- && strncmp (dsec->name + (dlen - ilen),
- isec->name, ilen) == 0)
- {
+ if (dlen > ilen
+ && strncmp (dsec->name + (dlen - ilen),
+ isec->name, ilen) == 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;
}