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. */
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;
/* 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)
|| (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;
}