* emultempl/xtensaelf.em (elf_xtensa_before_allocation): Call new
function to strip inconsistent linkonce sections. (input_section_linked_worker, input_section_linked): New. (is_inconsistent_linkonce_section): New. (xtensa_strip_inconsistent_linkonce_sections): New.
This commit is contained in:
parent
cd852561d0
commit
a255b6c7b0
2 changed files with 153 additions and 1 deletions
|
@ -1,3 +1,12 @@
|
||||||
|
2006-04-14 David Heine <dlheine@tensilica.com>
|
||||||
|
Bob Wilson <bob.wilson@acm.org>
|
||||||
|
|
||||||
|
* emultempl/xtensaelf.em (elf_xtensa_before_allocation): Call new
|
||||||
|
function to strip inconsistent linkonce sections.
|
||||||
|
(input_section_linked_worker, input_section_linked): New.
|
||||||
|
(is_inconsistent_linkonce_section): New.
|
||||||
|
(xtensa_strip_inconsistent_linkonce_sections): New.
|
||||||
|
|
||||||
2006-04-11 Diego Pettenò <flameeyes@gentoo.org>
|
2006-04-11 Diego Pettenò <flameeyes@gentoo.org>
|
||||||
|
|
||||||
* emultempl/elf32.em: Add support for elf-hints.h on FreeBSD
|
* emultempl/elf32.em: Add support for elf-hints.h on FreeBSD
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# This shell script emits a C file. -*- C -*-
|
# This shell script emits a C file. -*- C -*-
|
||||||
# Copyright 2003, 2004, 2005
|
# Copyright 2003, 2004, 2005, 2006
|
||||||
# Free Software Foundation, Inc.
|
# Free Software Foundation, Inc.
|
||||||
#
|
#
|
||||||
# This file is part of GLD, the Gnu Linker.
|
# This file is part of GLD, the Gnu Linker.
|
||||||
|
@ -32,6 +32,8 @@ cat >>e${EMULATION_NAME}.c <<EOF
|
||||||
|
|
||||||
static void xtensa_wild_group_interleave (lang_statement_union_type *);
|
static void xtensa_wild_group_interleave (lang_statement_union_type *);
|
||||||
static void xtensa_colocate_output_literals (lang_statement_union_type *);
|
static void xtensa_colocate_output_literals (lang_statement_union_type *);
|
||||||
|
static void xtensa_strip_inconsistent_linkonce_sections
|
||||||
|
(lang_statement_list_type *);
|
||||||
|
|
||||||
|
|
||||||
/* Flag for the emulation-specific "--no-relax" option. */
|
/* Flag for the emulation-specific "--no-relax" option. */
|
||||||
|
@ -370,6 +372,8 @@ elf_xtensa_before_allocation (void)
|
||||||
if (!disable_relaxation)
|
if (!disable_relaxation)
|
||||||
command_line.relax = TRUE;
|
command_line.relax = TRUE;
|
||||||
|
|
||||||
|
xtensa_strip_inconsistent_linkonce_sections (stat_ptr);
|
||||||
|
|
||||||
gld${EMULATION_NAME}_before_allocation ();
|
gld${EMULATION_NAME}_before_allocation ();
|
||||||
|
|
||||||
xtensa_wild_group_interleave (stat_ptr->head);
|
xtensa_wild_group_interleave (stat_ptr->head);
|
||||||
|
@ -1157,6 +1161,145 @@ ld_count_children (lang_statement_union_type *s)
|
||||||
#endif /* EXTRA_VALIDATION */
|
#endif /* EXTRA_VALIDATION */
|
||||||
|
|
||||||
|
|
||||||
|
/* Check if a particular section is included in the link. This will only
|
||||||
|
be true for one instance of a particular linkonce section. */
|
||||||
|
|
||||||
|
static bfd_boolean input_section_found = FALSE;
|
||||||
|
static asection *input_section_target = NULL;
|
||||||
|
|
||||||
|
static void
|
||||||
|
input_section_linked_worker (lang_statement_union_type *statement)
|
||||||
|
{
|
||||||
|
if ((statement->header.type == lang_input_section_enum
|
||||||
|
&& (statement->input_section.section == input_section_target)))
|
||||||
|
input_section_found = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bfd_boolean
|
||||||
|
input_section_linked (asection *sec)
|
||||||
|
{
|
||||||
|
input_section_found = FALSE;
|
||||||
|
input_section_target = sec;
|
||||||
|
lang_for_each_statement_worker (input_section_linked_worker, stat_ptr->head);
|
||||||
|
return input_section_found;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Strip out any linkonce literal sections or property tables where the
|
||||||
|
associated linkonce text is from a different object file. Normally,
|
||||||
|
a matching set of linkonce sections is taken from the same object file,
|
||||||
|
but sometimes the files are compiled differently so that some of the
|
||||||
|
linkonce sections are not present in all files. Stripping the
|
||||||
|
inconsistent sections like this is not completely robust -- a much
|
||||||
|
better solution is to use comdat groups. */
|
||||||
|
|
||||||
|
static int linkonce_len = sizeof (".gnu.linkonce.") - 1;
|
||||||
|
|
||||||
|
static bfd_boolean
|
||||||
|
is_inconsistent_linkonce_section (asection *sec)
|
||||||
|
{
|
||||||
|
bfd *abfd = sec->owner;
|
||||||
|
const char *sec_name = bfd_get_section_name (abfd, sec);
|
||||||
|
char *prop_tag = 0;
|
||||||
|
|
||||||
|
if ((bfd_get_section_flags (abfd, sec) & SEC_LINK_ONCE) == 0
|
||||||
|
|| strncmp (sec_name, ".gnu.linkonce.", linkonce_len) != 0)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
/* Check if this is an Xtensa property section. */
|
||||||
|
if (strncmp (sec_name + linkonce_len, "p.", 2) == 0)
|
||||||
|
prop_tag = "p.";
|
||||||
|
else if (strncmp (sec_name + linkonce_len, "prop.", 5) == 0)
|
||||||
|
prop_tag = "prop.";
|
||||||
|
if (prop_tag)
|
||||||
|
{
|
||||||
|
int tag_len = strlen (prop_tag);
|
||||||
|
char *dep_sec_name = xmalloc (strlen (sec_name));
|
||||||
|
asection *dep_sec;
|
||||||
|
|
||||||
|
/* Get the associated linkonce text section and check if it is
|
||||||
|
included in the link. If not, this section is inconsistent
|
||||||
|
and should be stripped. */
|
||||||
|
strcpy (dep_sec_name, ".gnu.linkonce.");
|
||||||
|
strcat (dep_sec_name, sec_name + linkonce_len + tag_len);
|
||||||
|
dep_sec = bfd_get_section_by_name (abfd, dep_sec_name);
|
||||||
|
if (dep_sec == NULL || ! input_section_linked (dep_sec))
|
||||||
|
{
|
||||||
|
free (dep_sec_name);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
free (dep_sec_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
xtensa_strip_inconsistent_linkonce_sections (lang_statement_list_type *slist)
|
||||||
|
{
|
||||||
|
lang_statement_union_type **s_p = &slist->head;
|
||||||
|
while (*s_p)
|
||||||
|
{
|
||||||
|
lang_statement_union_type *s = *s_p;
|
||||||
|
lang_statement_union_type *s_next = (*s_p)->header.next;
|
||||||
|
|
||||||
|
switch (s->header.type)
|
||||||
|
{
|
||||||
|
case lang_input_section_enum:
|
||||||
|
if (is_inconsistent_linkonce_section (s->input_section.section))
|
||||||
|
{
|
||||||
|
*s_p = s_next;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case lang_constructors_statement_enum:
|
||||||
|
xtensa_strip_inconsistent_linkonce_sections (&constructor_list);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case lang_output_section_statement_enum:
|
||||||
|
if (s->output_section_statement.children.head)
|
||||||
|
xtensa_strip_inconsistent_linkonce_sections
|
||||||
|
(&s->output_section_statement.children);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case lang_wild_statement_enum:
|
||||||
|
xtensa_strip_inconsistent_linkonce_sections
|
||||||
|
(&s->wild_statement.children);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case lang_group_statement_enum:
|
||||||
|
xtensa_strip_inconsistent_linkonce_sections
|
||||||
|
(&s->group_statement.children);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case lang_data_statement_enum:
|
||||||
|
case lang_reloc_statement_enum:
|
||||||
|
case lang_object_symbols_statement_enum:
|
||||||
|
case lang_output_statement_enum:
|
||||||
|
case lang_target_statement_enum:
|
||||||
|
case lang_input_statement_enum:
|
||||||
|
case lang_assignment_statement_enum:
|
||||||
|
case lang_padding_statement_enum:
|
||||||
|
case lang_address_statement_enum:
|
||||||
|
case lang_fill_statement_enum:
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
FAIL ();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
s_p = &(*s_p)->header.next;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Reset the tail of the list, in case the last entry was removed. */
|
||||||
|
if (s_p != slist->tail)
|
||||||
|
slist->tail = s_p;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
xtensa_wild_group_interleave_callback (lang_statement_union_type *statement)
|
xtensa_wild_group_interleave_callback (lang_statement_union_type *statement)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Reference in a new issue