summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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