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 | |
parent | b879806f2fdd2eca7092d7b854d6cbbbbbd0493b (diff) | |
download | binutils-18cd5bce47dc4a33dd1d8e3036b99d2fa7e3234f.zip binutils-18cd5bce47dc4a33dd1d8e3036b99d2fa7e3234f.tar.gz binutils-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.
-rw-r--r-- | bfd/ChangeLog | 6 | ||||
-rw-r--r-- | bfd/elflink.c | 109 | ||||
-rw-r--r-- | ld/ChangeLog | 12 | ||||
-rw-r--r-- | ld/emultempl/sh64elf.em | 3 | ||||
-rw-r--r-- | ld/ldlang.c | 42 | ||||
-rw-r--r-- | ld/ldlang.h | 2 | ||||
-rw-r--r-- | ld/ldwrite.c | 1 |
7 files changed, 121 insertions, 54 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 1e08b87..4ee7c3d 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,5 +1,11 @@ 2014-08-14 Alan Modra <amodra@gmail.com> + PR 16563 + * elflink.c (bfd_elf_discard_info): Process .eh_frame and .stab + in the order they are mapped to output sections. + +2014-08-14 Alan Modra <amodra@gmail.com> + * configure.ac: Delete redundant plugin related checks. * configure: Regenerate. 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 diff --git a/ld/ChangeLog b/ld/ChangeLog index 5ffa96c..773afba 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,5 +1,17 @@ 2014-08-14 Alan Modra <amodra@gmail.com> + PR 16563 + * 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. + +2014-08-14 Alan Modra <amodra@gmail.com> + * configure.ac: Move AC_PROG_CC and other macros earlier. Delete plugin checks now done in config/plugins.m4. * config.in: Regenerate. diff --git a/ld/emultempl/sh64elf.em b/ld/emultempl/sh64elf.em index 3c82164..c49fbe8 100644 --- a/ld/emultempl/sh64elf.em +++ b/ld/emultempl/sh64elf.em @@ -248,6 +248,9 @@ sh64_elf_${EMULATION_NAME}_after_allocation (void) gld${EMULATION_NAME}_after_allocation (); + /* Needed, since we create link_orders here. */ + lang_clear_os_map (); + cranges = bfd_get_section_by_name (link_info.output_bfd, SH64_CRANGES_SECTION_NAME); diff --git a/ld/ldlang.c b/ld/ldlang.c index 419caa1..899f710 100644 --- a/ld/ldlang.c +++ b/ld/ldlang.c @@ -57,7 +57,7 @@ static struct obstack map_obstack; #define obstack_chunk_free free static const char *entry_symbol_default = "start"; static bfd_boolean placed_commons = FALSE; -static bfd_boolean stripped_excluded_sections = FALSE; +static bfd_boolean map_head_is_link_order = FALSE; static lang_output_section_statement_type *default_common_section; static bfd_boolean map_option_f; static bfd_vma print_dot; @@ -2412,7 +2412,7 @@ lang_add_section (lang_statement_list_type *ptr, section->output_section = output->bfd_section; if (!link_info.relocatable - && !stripped_excluded_sections) + && !map_head_is_link_order) { asection *s = output->bfd_section->map_tail.s; output->bfd_section->map_tail.s = section; @@ -3912,10 +3912,6 @@ strip_excluded_output_sections (void) } } - /* TODO: Don't just junk map_head.s, turn them into link_orders. */ - output_section->map_head.link_order = NULL; - output_section->map_tail.link_order = NULL; - if (exclude) { /* We don't set bfd_section to NULL since bfd_section of the @@ -3927,10 +3923,42 @@ strip_excluded_output_sections (void) link_info.output_bfd->section_count--; } } +} + +/* Called from ldwrite to clear out asection.map_head and + asection.map_tail for use as link_orders in ldwrite. + FIXME: Except for sh64elf.em which starts creating link_orders in + its after_allocation routine so needs to call it early. */ + +void +lang_clear_os_map (void) +{ + lang_output_section_statement_type *os; + + if (map_head_is_link_order) + return; + + for (os = &lang_output_section_statement.head->output_section_statement; + os != NULL; + os = os->next) + { + asection *output_section; + + if (os->constraint < 0) + continue; + + output_section = os->bfd_section; + if (output_section == NULL) + continue; + + /* TODO: Don't just junk map_head.s, turn them into link_orders. */ + output_section->map_head.link_order = NULL; + output_section->map_tail.link_order = NULL; + } /* Stop future calls to lang_add_section from messing with map_head and map_tail link_order fields. */ - stripped_excluded_sections = TRUE; + map_head_is_link_order = TRUE; } static void diff --git a/ld/ldlang.h b/ld/ldlang.h index 2afe283..5f6faae 100644 --- a/ld/ldlang.h +++ b/ld/ldlang.h @@ -636,6 +636,8 @@ extern void *stat_alloc (size_t); extern void strip_excluded_output_sections (void); +extern void lang_clear_os_map + (void); extern void dprint_statement (lang_statement_union_type *, int); extern void lang_size_sections diff --git a/ld/ldwrite.c b/ld/ldwrite.c index 963cb98..43bc40b 100644 --- a/ld/ldwrite.c +++ b/ld/ldwrite.c @@ -572,6 +572,7 @@ ldwrite (void) /* Reset error indicator, which can typically something like invalid format from opening up the .o files. */ bfd_set_error (bfd_error_no_error); + lang_clear_os_map (); lang_for_each_statement (build_link_order); if (config.split_by_reloc != (unsigned) -1 |