diff options
author | Alan Modra <amodra@gmail.com> | 2014-08-14 13:49:31 +0930 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2014-08-14 13:49:31 +0930 |
commit | 18cd5bce47dc4a33dd1d8e3036b99d2fa7e3234f (patch) | |
tree | a45e5b4efa46052d1f8bf538e0695e2b264795a5 /bfd/elflink.c | |
parent | b879806f2fdd2eca7092d7b854d6cbbbbbd0493b (diff) | |
download | gdb-18cd5bce47dc4a33dd1d8e3036b99d2fa7e3234f.zip gdb-18cd5bce47dc4a33dd1d8e3036b99d2fa7e3234f.tar.gz gdb-18cd5bce47dc4a33dd1d8e3036b99d2fa7e3234f.tar.bz2 |
Linker part of PR16563 fix
Presents .eh_frame input sections to the optimisation machinery in
elf-eh-frame.c in the order they are given by the linker script.
PR 16563
bfd/
* elflink.c (bfd_elf_discard_info): Process .eh_frame and .stab
in the order they are mapped to output sections.
ld/
* ldlang.c (map_head_is_link_order): Rename from
stripped_excluded_sections.
(lang_clear_os_map): New function, extracted from..
(strip_excluded_output_sections): ..here.
* ldlang.h (lang_clear_os_map): Declare.
* ldwrite.c (ldwrite): Call lang_clear_os_map.
* emultempl/sh64elf.em (sh64_elf_${EMULATION_NAME}_after_allocation):
Likewise.
Diffstat (limited to 'bfd/elflink.c')
-rw-r--r-- | bfd/elflink.c | 109 |
1 files changed, 62 insertions, 47 deletions
diff --git a/bfd/elflink.c b/bfd/elflink.c index de0a734..5e5af32 100644 --- a/bfd/elflink.c +++ b/bfd/elflink.c @@ -12637,8 +12637,7 @@ bfd_boolean bfd_elf_discard_info (bfd *output_bfd, struct bfd_link_info *info) { struct elf_reloc_cookie cookie; - asection *stab, *eh; - const struct elf_backend_data *bed; + asection *o; bfd *abfd; bfd_boolean ret = FALSE; @@ -12646,70 +12645,86 @@ bfd_elf_discard_info (bfd *output_bfd, struct bfd_link_info *info) || !is_elf_hash_table (info->hash)) return FALSE; - _bfd_elf_begin_eh_frame_parsing (info); - for (abfd = info->input_bfds; abfd != NULL; abfd = abfd->link.next) + o = bfd_get_section_by_name (output_bfd, ".stab"); + if (o != NULL) { - if (bfd_get_flavour (abfd) != bfd_target_elf_flavour) - continue; + asection *i; - bed = get_elf_backend_data (abfd); - - eh = NULL; - if (!info->relocatable) + for (i = o->map_head.s; i != NULL; i = i->map_head.s) { - eh = bfd_get_section_by_name (abfd, ".eh_frame"); - while (eh != NULL - && (eh->size == 0 - || bfd_is_abs_section (eh->output_section))) - eh = bfd_get_next_section_by_name (eh); - } - - stab = bfd_get_section_by_name (abfd, ".stab"); - if (stab != NULL - && (stab->size == 0 - || bfd_is_abs_section (stab->output_section) - || stab->sec_info_type != SEC_INFO_TYPE_STABS)) - stab = NULL; + if (i->size == 0 + || i->reloc_count == 0 + || i->sec_info_type != SEC_INFO_TYPE_STABS) + continue; - if (stab == NULL - && eh == NULL - && bed->elf_backend_discard_info == NULL) - continue; + abfd = i->owner; + if (bfd_get_flavour (abfd) != bfd_target_elf_flavour) + continue; - if (!init_reloc_cookie (&cookie, info, abfd)) - return FALSE; + if (!init_reloc_cookie_for_section (&cookie, info, i)) + return FALSE; - if (stab != NULL - && stab->reloc_count > 0 - && init_reloc_cookie_rels (&cookie, info, abfd, stab)) - { - if (_bfd_discard_section_stabs (abfd, stab, - elf_section_data (stab)->sec_info, + if (_bfd_discard_section_stabs (abfd, i, + elf_section_data (i)->sec_info, bfd_elf_reloc_symbol_deleted_p, &cookie)) ret = TRUE; - fini_reloc_cookie_rels (&cookie, stab); + + fini_reloc_cookie_for_section (&cookie, i); } + } + + o = NULL; + if (!info->relocatable) + o = bfd_get_section_by_name (output_bfd, ".eh_frame"); + if (o != NULL) + { + asection *i; - while (eh != NULL - && init_reloc_cookie_rels (&cookie, info, abfd, eh)) + _bfd_elf_begin_eh_frame_parsing (info); + for (i = o->map_head.s; i != NULL; i = i->map_head.s) { - _bfd_elf_parse_eh_frame (abfd, info, eh, &cookie); - if (_bfd_elf_discard_section_eh_frame (abfd, info, eh, + if (i->size == 0) + continue; + + abfd = i->owner; + if (bfd_get_flavour (abfd) != bfd_target_elf_flavour) + continue; + + if (!init_reloc_cookie_for_section (&cookie, info, i)) + return FALSE; + + _bfd_elf_parse_eh_frame (abfd, info, i, &cookie); + if (_bfd_elf_discard_section_eh_frame (abfd, info, i, bfd_elf_reloc_symbol_deleted_p, &cookie)) ret = TRUE; - fini_reloc_cookie_rels (&cookie, eh); - eh = bfd_get_next_section_by_name (eh); + + fini_reloc_cookie_for_section (&cookie, i); } + _bfd_elf_end_eh_frame_parsing (info); + } - if (bed->elf_backend_discard_info != NULL - && (*bed->elf_backend_discard_info) (abfd, &cookie, info)) - ret = TRUE; + for (abfd = info->input_bfds; abfd != NULL; abfd = abfd->link.next) + { + const struct elf_backend_data *bed; - fini_reloc_cookie (&cookie, abfd); + if (bfd_get_flavour (abfd) != bfd_target_elf_flavour) + continue; + + bed = get_elf_backend_data (abfd); + + if (bed->elf_backend_discard_info != NULL) + { + if (!init_reloc_cookie (&cookie, info, abfd)) + return FALSE; + + if ((*bed->elf_backend_discard_info) (abfd, &cookie, info)) + ret = TRUE; + + fini_reloc_cookie (&cookie, abfd); + } } - _bfd_elf_end_eh_frame_parsing (info); if (info->eh_frame_hdr && !info->relocatable |