From 1a912d4c206b12b6153f863da6b98a7022ed31ba Mon Sep 17 00:00:00 2001 From: Bob Wilson Date: Fri, 25 Aug 2006 00:08:54 +0000 Subject: bfd/ * elf32-xtensa.c (xtensa_get_property_section_name): Delete. (xtensa_get_property_section): New. (xtensa_read_table_entries): Use xtensa_get_property_section. (relax_property_section, xtensa_get_property_predef_flags): Handle group name suffixes in property section names. (match_section_group): New. gas/ * config/tc-xtensa.c (FINI_LITERAL_SECTION_NAME): Delete. (INIT_LITERAL_SECTION_NAME): Delete. (lit_state struct): Remove segment names, init_lit_seg, and fini_lit_seg. Add lit_prefix and current_text_seg. (init_literal_head_h, init_literal_head): Delete. (fini_literal_head_h, fini_literal_head): Delete. (xtensa_begin_directive): Move argument parsing to xtensa_literal_prefix function. (xtensa_end_directive): Deallocate lit_prefix field of lit_state. (xtensa_literal_prefix): Parse the directive argument here and record it in the lit_prefix field. Remove code to derive literal section names. (linkonce_len): New. (get_is_linkonce_section): Use linkonce_len. Check for any ".gnu.linkonce.*" section, not just text sections. (md_begin): Remove initialization of deleted lit_state fields. (xtensa_reorder_segments, xtensa_post_relax_hook): Remove references to init_literal_head and fini_literal_head. (xtensa_move_literals): Likewise. Skip literals for .init and .fini when traversing literal_head list. (match_section_group): New. (cache_literal_section): Rewrite to determine the literal section name on the fly, create the section and return it. (xtensa_switch_to_literal_fragment): Adjust for cache_literal_section. (xtensa_switch_to_non_abs_literal_fragment): Likewise. (xtensa_create_property_segments, xtensa_create_xproperty_segments): Use xtensa_get_property_section from bfd. (retrieve_xtensa_section): Delete. * doc/c-xtensa.texi (Xtensa Options): Fix --text-section-literals description to refer to plural literal sections and add xref to the Literal Directive section. (Literal Directive): Describe new rules for deriving literal section names. Add footnote for special case of .init/.fini with --text-section-literals. (Literal Prefix Directive): Replace old naming rules with xref to the Literal Directive section. ld/ * emulparams/elf32xtensa.sh (.xt.prop): Add .xt.prop.*. * scripttempl/elfxtensa.sc (.text): Add .literal.*. --- bfd/elf32-xtensa.c | 76 ++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 62 insertions(+), 14 deletions(-) (limited to 'bfd/elf32-xtensa.c') diff --git a/bfd/elf32-xtensa.c b/bfd/elf32-xtensa.c index 5efdcbac962..88365ddd32a 100644 --- a/bfd/elf32-xtensa.c +++ b/bfd/elf32-xtensa.c @@ -106,7 +106,7 @@ static bfd_boolean xtensa_is_property_section (asection *); static bfd_boolean xtensa_is_littable_section (asection *); static int internal_reloc_compare (const void *, const void *); static int internal_reloc_matches (const void *, const void *); -extern char *xtensa_get_property_section_name (asection *, const char *); +extern asection *xtensa_get_property_section (asection *, const char *); static flagword xtensa_get_property_predef_flags (asection *); /* Other functions called directly by the linker. */ @@ -571,7 +571,6 @@ xtensa_read_table_entries (bfd *abfd, bfd_boolean output_addr) { asection *table_section; - char *table_section_name; bfd_size_type table_size = 0; bfd_byte *table_data; property_table_entry *blocks; @@ -590,9 +589,7 @@ xtensa_read_table_entries (bfd *abfd, return 0; } - table_section_name = xtensa_get_property_section_name (section, sec_name); - table_section = bfd_get_section_by_name (abfd, table_section_name); - free (table_section_name); + table_section = xtensa_get_property_section (section, sec_name); if (table_section) table_size = table_section->size; @@ -8857,7 +8854,8 @@ relax_property_section (bfd *abfd, } is_full_prop_section = - ((strcmp (sec->name, XTENSA_PROP_SEC_NAME) == 0) + ((strncmp (sec->name, XTENSA_PROP_SEC_NAME, + sizeof (XTENSA_PROP_SEC_NAME) - 1) == 0) || (strncmp (sec->name, ".gnu.linkonce.prop.", sizeof ".gnu.linkonce.prop." - 1) == 0)); @@ -9593,13 +9591,42 @@ internal_reloc_matches (const void *ap, const void *bp) } -char * -xtensa_get_property_section_name (asection *sec, const char *base_name) +/* Predicate function used to look up a section in a particular group. */ + +static bfd_boolean +match_section_group (bfd *abfd ATTRIBUTE_UNUSED, asection *sec, void *inf) +{ + const char *gname = inf; + const char *group_name = elf_group_name (sec); + + return (group_name == gname + || (group_name != NULL + && gname != NULL + && strcmp (group_name, gname) == 0)); +} + + +asection * +xtensa_get_property_section (asection *sec, const char *base_name) { - if (strncmp (sec->name, ".gnu.linkonce.", linkonce_len) == 0) + const char *suffix, *group_name; + char *prop_sec_name; + asection *prop_sec; + + group_name = elf_group_name (sec); + if (group_name) + { + suffix = strrchr (sec->name, '.'); + if (suffix == sec->name) + suffix = 0; + prop_sec_name = (char *) bfd_malloc (strlen (base_name) + 1 + + (suffix ? strlen (suffix) : 0)); + strcpy (prop_sec_name, base_name); + if (suffix) + strcat (prop_sec_name, suffix); + } + else if (strncmp (sec->name, ".gnu.linkonce.", linkonce_len) == 0) { - char *prop_sec_name; - const char *suffix; char *linkonce_kind = 0; if (strcmp (base_name, XTENSA_INSN_SEC_NAME) == 0) @@ -9622,18 +9649,39 @@ xtensa_get_property_section_name (asection *sec, const char *base_name) if (strncmp (suffix, "t.", 2) == 0 && linkonce_kind[1] == '.') suffix += 2; strcat (prop_sec_name + linkonce_len, suffix); + } + else + prop_sec_name = strdup (base_name); + + /* Check if the section already exists. */ + prop_sec = bfd_get_section_by_name_if (sec->owner, prop_sec_name, + match_section_group, + (void *) group_name); + /* If not, create it. */ + if (! prop_sec) + { + flagword flags = (SEC_RELOC | SEC_HAS_CONTENTS | SEC_READONLY); + flags |= (bfd_get_section_flags (sec->owner, sec) + & (SEC_LINK_ONCE | SEC_LINK_DUPLICATES)); + + prop_sec = bfd_make_section_anyway_with_flags + (sec->owner, strdup (prop_sec_name), flags); + if (! prop_sec) + return 0; - return prop_sec_name; + elf_group_name (prop_sec) = group_name; } - return strdup (base_name); + free (prop_sec_name); + return prop_sec; } flagword xtensa_get_property_predef_flags (asection *sec) { - if (strcmp (sec->name, XTENSA_INSN_SEC_NAME) == 0 + if (strncmp (sec->name, XTENSA_INSN_SEC_NAME, + sizeof (XTENSA_INSN_SEC_NAME) - 1) == 0 || strncmp (sec->name, ".gnu.linkonce.x.", sizeof ".gnu.linkonce.x." - 1) == 0) return (XTENSA_PROP_INSN -- cgit v1.2.1