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>
|
2014-08-14 Alan Modra <amodra@gmail.com>
|
||||||
|
|
||||||
* configure.ac: Delete redundant plugin related checks.
|
* configure.ac: Delete redundant plugin related checks.
|
||||||
|
115
bfd/elflink.c
115
bfd/elflink.c
@ -12637,8 +12637,7 @@ bfd_boolean
|
|||||||
bfd_elf_discard_info (bfd *output_bfd, struct bfd_link_info *info)
|
bfd_elf_discard_info (bfd *output_bfd, struct bfd_link_info *info)
|
||||||
{
|
{
|
||||||
struct elf_reloc_cookie cookie;
|
struct elf_reloc_cookie cookie;
|
||||||
asection *stab, *eh;
|
asection *o;
|
||||||
const struct elf_backend_data *bed;
|
|
||||||
bfd *abfd;
|
bfd *abfd;
|
||||||
bfd_boolean ret = FALSE;
|
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))
|
|| !is_elf_hash_table (info->hash))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
|
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);
|
_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)
|
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)
|
if (bfd_get_flavour (abfd) != bfd_target_elf_flavour)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
bed = get_elf_backend_data (abfd);
|
bed = get_elf_backend_data (abfd);
|
||||||
|
|
||||||
eh = NULL;
|
if (bed->elf_backend_discard_info != NULL)
|
||||||
if (!info->relocatable)
|
|
||||||
{
|
{
|
||||||
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 (stab == NULL
|
|
||||||
&& eh == NULL
|
|
||||||
&& bed->elf_backend_discard_info == NULL)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (!init_reloc_cookie (&cookie, info, abfd))
|
if (!init_reloc_cookie (&cookie, info, abfd))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
if (stab != NULL
|
if ((*bed->elf_backend_discard_info) (abfd, &cookie, info))
|
||||||
&& 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))
|
|
||||||
ret = TRUE;
|
|
||||||
fini_reloc_cookie_rels (&cookie, stab);
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
ret = TRUE;
|
||||||
|
|
||||||
fini_reloc_cookie (&cookie, abfd);
|
fini_reloc_cookie (&cookie, abfd);
|
||||||
}
|
}
|
||||||
_bfd_elf_end_eh_frame_parsing (info);
|
}
|
||||||
|
|
||||||
if (info->eh_frame_hdr
|
if (info->eh_frame_hdr
|
||||||
&& !info->relocatable
|
&& !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>
|
2014-08-14 Alan Modra <amodra@gmail.com>
|
||||||
|
|
||||||
* configure.ac: Move AC_PROG_CC and other macros earlier. Delete
|
* 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 ();
|
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,
|
cranges = bfd_get_section_by_name (link_info.output_bfd,
|
||||||
SH64_CRANGES_SECTION_NAME);
|
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
|
#define obstack_chunk_free free
|
||||||
static const char *entry_symbol_default = "start";
|
static const char *entry_symbol_default = "start";
|
||||||
static bfd_boolean placed_commons = FALSE;
|
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 lang_output_section_statement_type *default_common_section;
|
||||||
static bfd_boolean map_option_f;
|
static bfd_boolean map_option_f;
|
||||||
static bfd_vma print_dot;
|
static bfd_vma print_dot;
|
||||||
@ -2412,7 +2412,7 @@ lang_add_section (lang_statement_list_type *ptr,
|
|||||||
section->output_section = output->bfd_section;
|
section->output_section = output->bfd_section;
|
||||||
|
|
||||||
if (!link_info.relocatable
|
if (!link_info.relocatable
|
||||||
&& !stripped_excluded_sections)
|
&& !map_head_is_link_order)
|
||||||
{
|
{
|
||||||
asection *s = output->bfd_section->map_tail.s;
|
asection *s = output->bfd_section->map_tail.s;
|
||||||
output->bfd_section->map_tail.s = section;
|
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)
|
if (exclude)
|
||||||
{
|
{
|
||||||
/* We don't set bfd_section to NULL since bfd_section of the
|
/* 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--;
|
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
|
/* Stop future calls to lang_add_section from messing with map_head
|
||||||
and map_tail link_order fields. */
|
and map_tail link_order fields. */
|
||||||
stripped_excluded_sections = TRUE;
|
map_head_is_link_order = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -636,6 +636,8 @@ extern void *stat_alloc
|
|||||||
(size_t);
|
(size_t);
|
||||||
extern void strip_excluded_output_sections
|
extern void strip_excluded_output_sections
|
||||||
(void);
|
(void);
|
||||||
|
extern void lang_clear_os_map
|
||||||
|
(void);
|
||||||
extern void dprint_statement
|
extern void dprint_statement
|
||||||
(lang_statement_union_type *, int);
|
(lang_statement_union_type *, int);
|
||||||
extern void lang_size_sections
|
extern void lang_size_sections
|
||||||
|
@ -572,6 +572,7 @@ ldwrite (void)
|
|||||||
/* Reset error indicator, which can typically something like invalid
|
/* Reset error indicator, which can typically something like invalid
|
||||||
format from opening up the .o files. */
|
format from opening up the .o files. */
|
||||||
bfd_set_error (bfd_error_no_error);
|
bfd_set_error (bfd_error_no_error);
|
||||||
|
lang_clear_os_map ();
|
||||||
lang_for_each_statement (build_link_order);
|
lang_for_each_statement (build_link_order);
|
||||||
|
|
||||||
if (config.split_by_reloc != (unsigned) -1
|
if (config.split_by_reloc != (unsigned) -1
|
||||||
|
Loading…
Reference in New Issue
Block a user