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.
This commit is contained in:
parent
b879806f2f
commit
18cd5bce47
@ -1,3 +1,9 @@
|
||||
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.
|
||||
|
123
bfd/elflink.c
123
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);
|
||||
o = bfd_get_section_by_name (output_bfd, ".stab");
|
||||
if (o != NULL)
|
||||
{
|
||||
asection *i;
|
||||
|
||||
for (i = o->map_head.s; i != NULL; i = i->map_head.s)
|
||||
{
|
||||
if (i->size == 0
|
||||
|| i->reloc_count == 0
|
||||
|| i->sec_info_type != SEC_INFO_TYPE_STABS)
|
||||
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;
|
||||
|
||||
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_for_section (&cookie, i);
|
||||
}
|
||||
}
|
||||
|
||||
o = NULL;
|
||||
if (!info->relocatable)
|
||||
o = bfd_get_section_by_name (output_bfd, ".eh_frame");
|
||||
if (o != NULL)
|
||||
{
|
||||
asection *i;
|
||||
|
||||
_bfd_elf_begin_eh_frame_parsing (info);
|
||||
for (i = o->map_head.s; i != NULL; i = i->map_head.s)
|
||||
{
|
||||
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_for_section (&cookie, i);
|
||||
}
|
||||
_bfd_elf_end_eh_frame_parsing (info);
|
||||
}
|
||||
|
||||
for (abfd = info->input_bfds; abfd != NULL; abfd = abfd->link.next)
|
||||
{
|
||||
const struct elf_backend_data *bed;
|
||||
|
||||
if (bfd_get_flavour (abfd) != bfd_target_elf_flavour)
|
||||
continue;
|
||||
|
||||
bed = get_elf_backend_data (abfd);
|
||||
|
||||
eh = NULL;
|
||||
if (!info->relocatable)
|
||||
if (bed->elf_backend_discard_info != NULL)
|
||||
{
|
||||
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);
|
||||
}
|
||||
if (!init_reloc_cookie (&cookie, info, abfd))
|
||||
return FALSE;
|
||||
|
||||
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 (stab == NULL
|
||||
&& eh == NULL
|
||||
&& bed->elf_backend_discard_info == NULL)
|
||||
continue;
|
||||
|
||||
if (!init_reloc_cookie (&cookie, info, abfd))
|
||||
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,
|
||||
bfd_elf_reloc_symbol_deleted_p,
|
||||
&cookie))
|
||||
if ((*bed->elf_backend_discard_info) (abfd, &cookie, info))
|
||||
ret = TRUE;
|
||||
fini_reloc_cookie_rels (&cookie, stab);
|
||||
|
||||
fini_reloc_cookie (&cookie, abfd);
|
||||
}
|
||||
|
||||
while (eh != NULL
|
||||
&& init_reloc_cookie_rels (&cookie, info, abfd, eh))
|
||||
{
|
||||
_bfd_elf_parse_eh_frame (abfd, info, eh, &cookie);
|
||||
if (_bfd_elf_discard_section_eh_frame (abfd, info, eh,
|
||||
bfd_elf_reloc_symbol_deleted_p,
|
||||
&cookie))
|
||||
ret = TRUE;
|
||||
fini_reloc_cookie_rels (&cookie, eh);
|
||||
eh = bfd_get_next_section_by_name (eh);
|
||||
}
|
||||
|
||||
if (bed->elf_backend_discard_info != NULL
|
||||
&& (*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
|
||||
|
12
ld/ChangeLog
12
ld/ChangeLog
@ -1,3 +1,15 @@
|
||||
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
|
||||
|
@ -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);
|
||||
|
||||
|
42
ld/ldlang.c
42
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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user