summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorH.J. Lu <hjl.tools@gmail.com>2017-05-16 19:54:48 -0700
committerH.J. Lu <hjl.tools@gmail.com>2017-05-16 20:02:51 -0700
commitfd0cdba9cc66e24bd7db6e0791148aaf41d56c28 (patch)
tree570c3ea30affe4d9e64318cd85c63d4edc6d7c67
parent20224b8b18eff451f17ba2f434a56f5cbab969bd (diff)
downloadbinutils-gdb-users/hjl/pr20882.tar.gz
Mark debug sections referenced by kept debug sectionsusers/hjl/pr20882
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.
-rw-r--r--bfd/elflink.c32
-rw-r--r--ld/testsuite/ld-gc/gc.exp1
-rw-r--r--ld/testsuite/ld-gc/pr20882.d10
-rw-r--r--ld/testsuite/ld-gc/pr20882a.s8
-rw-r--r--ld/testsuite/ld-gc/pr20882b.s5
-rw-r--r--ld/testsuite/ld-gc/pr20882c.s5
6 files changed, 60 insertions, 1 deletions
diff --git a/bfd/elflink.c b/bfd/elflink.c
index 12e3a1687bb..bc1042839f7 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,6 +12986,8 @@ _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;
}
/* Look for CODE sections which are going to be discarded,
@@ -13002,6 +13023,15 @@ _bfd_elf_gc_mark_extra_sections (struct bfd_link_info *info,
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;
}
diff --git a/ld/testsuite/ld-gc/gc.exp b/ld/testsuite/ld-gc/gc.exp
index ba4f70b6228..ba5c46b64f8 100644
--- a/ld/testsuite/ld-gc/gc.exp
+++ b/ld/testsuite/ld-gc/gc.exp
@@ -104,6 +104,7 @@ run_dump_test "start"
run_dump_test "pr19167"
if { [is_elf_format] } then {
run_dump_test "all-debug-sections"
+ run_dump_test "pr20882"
}
if { [is_elf_format] && [check_shared_lib_support] } then {
diff --git a/ld/testsuite/ld-gc/pr20882.d b/ld/testsuite/ld-gc/pr20882.d
new file mode 100644
index 00000000000..55fa1414109
--- /dev/null
+++ b/ld/testsuite/ld-gc/pr20882.d
@@ -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 +.+\(
diff --git a/ld/testsuite/ld-gc/pr20882a.s b/ld/testsuite/ld-gc/pr20882a.s
new file mode 100644
index 00000000000..46bc1adce02
--- /dev/null
+++ b/ld/testsuite/ld-gc/pr20882a.s
@@ -0,0 +1,8 @@
+ .text
+ .globl main
+ .type main, %function
+main:
+ .byte 0
+
+ .section .debug_info,"",%progbits
+ .dc.a t.c.4903c230+2
diff --git a/ld/testsuite/ld-gc/pr20882b.s b/ld/testsuite/ld-gc/pr20882b.s
new file mode 100644
index 00000000000..ea0cf2e4ada
--- /dev/null
+++ b/ld/testsuite/ld-gc/pr20882b.s
@@ -0,0 +1,5 @@
+ .section .debug_info,"",%progbits
+ .hidden t.c.4903c230
+ .globl t.c.4903c230
+t.c.4903c230:
+ .byte 0x28
diff --git a/ld/testsuite/ld-gc/pr20882c.s b/ld/testsuite/ld-gc/pr20882c.s
new file mode 100644
index 00000000000..44d27349c4c
--- /dev/null
+++ b/ld/testsuite/ld-gc/pr20882c.s
@@ -0,0 +1,5 @@
+ .section .debug_info,"",%progbits
+ .hidden t.c.4903c231
+ .globl t.c.4903c231
+t.c.4903c231:
+ .byte 0x29