diff options
Diffstat (limited to 'bfd/elflink.c')
-rw-r--r-- | bfd/elflink.c | 32 |
1 files changed, 31 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; } |