diff options
author | Bob Wilson <bob.wilson@acm.org> | 2006-08-25 00:08:55 +0000 |
---|---|---|
committer | Bob Wilson <bob.wilson@acm.org> | 2006-08-25 00:08:55 +0000 |
commit | 74869ac7a4dcde1530155889456cbaa37f87b60c (patch) | |
tree | 32cc691da7fb5deb179c941ac93ec9c1455a0052 /bfd/elf32-xtensa.c | |
parent | ca0ef6cdf077270a80c887eafe8a41806a6bd8ad (diff) | |
download | gdb-74869ac7a4dcde1530155889456cbaa37f87b60c.zip gdb-74869ac7a4dcde1530155889456cbaa37f87b60c.tar.gz gdb-74869ac7a4dcde1530155889456cbaa37f87b60c.tar.bz2 |
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.*.
Diffstat (limited to 'bfd/elf32-xtensa.c')
-rw-r--r-- | bfd/elf32-xtensa.c | 76 |
1 files changed, 62 insertions, 14 deletions
diff --git a/bfd/elf32-xtensa.c b/bfd/elf32-xtensa.c index 5efdcba..88365dd 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 |