From 2caa7ca0aa6cb3ac5c385089c2bce6418fc30d08 Mon Sep 17 00:00:00 2001 From: Bob Wilson Date: Mon, 27 Nov 2006 20:14:53 +0000 Subject: [PATCH] bfd/ * elf32-xtensa.c (elf_xtensa_special_sections): Add .xtensa.info. gas/ * config/tc-xtensa.c (XSHAL_ABI): Add default definition. (directive_state): Disable scheduling by default. (xtensa_add_config_info): New. (xtensa_end): Call xtensa_add_config_info. gas/testsuite/ * gas/elf/section2.e-xtensa: New file. * gas/elf/elf.exp: Use it. include/ * xtensa-config.h (XSHAL_ABI): New. (XTHAL_ABI_WINDOWED, XTHAL_ABI_CALL0): New. ld/ * emultempl/xtensaelf.em (XSHAL_ABI): Add default definition. (replace_insn_sec_with_prop_sec): Use bfd_make_section_with_flags. Delete redundant code to set sections flags and alignment. (xt_config_info_unpack_and_check, check_xtensa_info): New. (elf_xtensa_after_open): Iterate over input statements instead of link_info.input_bfds. (elf_xtensa_before_allocation): Likewise. Call check_xtensa_info for each input, and write a new .xtensa.info section in the output. --- bfd/ChangeLog | 4 + bfd/elf32-xtensa.c | 1 + gas/ChangeLog | 7 + gas/config/tc-xtensa.c | 59 ++++++++- gas/testsuite/ChangeLog | 5 + gas/testsuite/gas/elf/elf.exp | 3 + gas/testsuite/gas/elf/section2.e-xtensa | 9 ++ include/ChangeLog | 5 + include/xtensa-config.h | 11 +- ld/ChangeLog | 11 ++ ld/emultempl/xtensaelf.em | 218 +++++++++++++++++++++++++++----- 11 files changed, 301 insertions(+), 32 deletions(-) create mode 100644 gas/testsuite/gas/elf/section2.e-xtensa diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 4017151..03338f8 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,7 @@ +2006-11-27 Bob Wilson + + * elf32-xtensa.c (elf_xtensa_special_sections): Add .xtensa.info. + 2006-11-24 H.J. Lu * elf.c (IS_SECTION_IN_INPUT_SEGMENT): New. diff --git a/bfd/elf32-xtensa.c b/bfd/elf32-xtensa.c index 59ed4ba..bb19830 100644 --- a/bfd/elf32-xtensa.c +++ b/bfd/elf32-xtensa.c @@ -9801,6 +9801,7 @@ static const struct bfd_elf_special_section elf_xtensa_special_sections[] = { STRING_COMMA_LEN (".fini.literal"), 0, SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR }, { STRING_COMMA_LEN (".init.literal"), 0, SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR }, { STRING_COMMA_LEN (".literal"), 0, SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR }, + { STRING_COMMA_LEN (".xtensa.info"), 0, SHT_NOTE, 0 }, { NULL, 0, 0, 0, 0 } }; diff --git a/gas/ChangeLog b/gas/ChangeLog index 8e45803..ce26d2e 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,10 @@ +2006-11-27 Bob Wilson + + * config/tc-xtensa.c (XSHAL_ABI): Add default definition. + (directive_state): Disable scheduling by default. + (xtensa_add_config_info): New. + (xtensa_end): Call xtensa_add_config_info. + 2006-11-27 Eric Botcazou * config/tc-sparc.c (tc_gen_reloc): Turn aligned relocs into diff --git a/gas/config/tc-xtensa.c b/gas/config/tc-xtensa.c index 5f0d8a8..dbffac4 100644 --- a/gas/config/tc-xtensa.c +++ b/gas/config/tc-xtensa.c @@ -30,6 +30,11 @@ #include "struc-symbol.h" #include "xtensa-config.h" +/* Provide default values for new configuration settings. */ +#ifndef XSHAL_ABI +#define XSHAL_ABI 0 +#endif + #ifndef uint32 #define uint32 unsigned int #endif @@ -396,7 +401,7 @@ bfd_boolean directive_state[] = FALSE, /* freeregs */ FALSE, /* longcalls */ FALSE, /* literal_prefix */ - TRUE, /* schedule */ + FALSE, /* schedule */ #if XSHAL_USE_ABSOLUTE_LITERALS TRUE /* absolute_literals */ #else @@ -6859,6 +6864,7 @@ static void xtensa_fix_b_j_loop_end_frags (void); static void xtensa_fix_close_loop_end_frags (void); static void xtensa_fix_short_loop_frags (void); static void xtensa_sanity_check (void); +static void xtensa_add_config_info (void); void xtensa_end (void) @@ -6889,6 +6895,8 @@ xtensa_end (void) xtensa_mark_zcl_first_insns (); xtensa_sanity_check (); + + xtensa_add_config_info (); } @@ -7797,6 +7805,55 @@ is_local_forward_loop (const TInsn *insn, fragS *fragP) return FALSE; } + +#define XTINFO_NAME "Xtensa_Info" +#define XTINFO_NAMESZ 12 +#define XTINFO_TYPE 1 + +static void +xtensa_add_config_info (void) +{ + asection *info_sec; + char *data, *p; + int sz; + + info_sec = subseg_new (".xtensa.info", 0); + bfd_set_section_flags (stdoutput, info_sec, SEC_HAS_CONTENTS | SEC_READONLY); + + data = xmalloc (100); + sprintf (data, "USE_ABSOLUTE_LITERALS=%d\nABI=%d\n", + XSHAL_USE_ABSOLUTE_LITERALS, XSHAL_ABI); + sz = strlen (data) + 1; + + /* Add enough null terminators to pad to a word boundary. */ + do + data[sz++] = 0; + while ((sz & 3) != 0); + + /* Follow the standard note section layout: + First write the length of the name string. */ + p = frag_more (4); + md_number_to_chars (p, (valueT) XTINFO_NAMESZ, 4); + + /* Next comes the length of the "descriptor", i.e., the actual data. */ + p = frag_more (4); + md_number_to_chars (p, (valueT) sz, 4); + + /* Write the note type. */ + p = frag_more (4); + md_number_to_chars (p, (valueT) XTINFO_TYPE, 4); + + /* Write the name field. */ + p = frag_more (XTINFO_NAMESZ); + memcpy (p, XTINFO_NAME, XTINFO_NAMESZ); + + /* Finally, write the descriptor. */ + p = frag_more (sz); + memcpy (p, data, sz); + + free (data); +} + /* Alignment Functions. */ diff --git a/gas/testsuite/ChangeLog b/gas/testsuite/ChangeLog index ca48446..e3c14fc 100644 --- a/gas/testsuite/ChangeLog +++ b/gas/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2006-11-27 Bob Wilson + + * gas/elf/section2.e-xtensa: New file. + * gas/elf/elf.exp: Use it. + 2006-11-22 Daniel Jacobowitz * gas/arm/arm7t.d, gas/arm/neon-ldst-rm.d, gas/arm/thumb2_pool.d, diff --git a/gas/testsuite/gas/elf/elf.exp b/gas/testsuite/gas/elf/elf.exp index 0d51aa0..55cfa79 100644 --- a/gas/testsuite/gas/elf/elf.exp +++ b/gas/testsuite/gas/elf/elf.exp @@ -53,6 +53,9 @@ if { ([istarget "*-*-*elf*"] if {[istarget "score-*-*"]} then { set target_machine -score } + if {[istarget "xtensa-*-*"]} then { + set target_machine -xtensa + } if { ([istarget "*arm*-*-*"] || [istarget "xscale*-*-*"]) } { diff --git a/gas/testsuite/gas/elf/section2.e-xtensa b/gas/testsuite/gas/elf/section2.e-xtensa new file mode 100644 index 0000000..84463b1 --- /dev/null +++ b/gas/testsuite/gas/elf/section2.e-xtensa @@ -0,0 +1,9 @@ + +Symbol table '.symtab' contains 6 entries: + Num: Value[ ]* Size Type Bind Vis Ndx Name + 0: 0+0 0 NOTYPE LOCAL DEFAULT UND + 1: 0+0 0 SECTION LOCAL DEFAULT 1 + 2: 0+0 0 SECTION LOCAL DEFAULT 2 + 3: 0+0 0 SECTION LOCAL DEFAULT 3 + 4: 0+0 0 SECTION LOCAL DEFAULT 4 + 5: 0+0 0 SECTION LOCAL DEFAULT 5 diff --git a/include/ChangeLog b/include/ChangeLog index 63e80fd..8f827fa 100644 --- a/include/ChangeLog +++ b/include/ChangeLog @@ -1,5 +1,10 @@ 2006-11-27 Bob Wilson + * xtensa-config.h (XSHAL_ABI): New. + (XTHAL_ABI_WINDOWED, XTHAL_ABI_CALL0): New. + +2006-11-27 Bob Wilson + * xtensa-isa.h (STATIC_LIBISA): Delete. 2006-10-30 Paul Brook diff --git a/include/xtensa-config.h b/include/xtensa-config.h index 5c0315d..36f9719 100644 --- a/include/xtensa-config.h +++ b/include/xtensa-config.h @@ -1,5 +1,6 @@ /* Xtensa configuration settings. - Copyright (C) 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. + Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006 + Free Software Foundation, Inc. Contributed by Bob Wilson (bwilson@tensilica.com) at Tensilica. This program is free software; you can redistribute it and/or modify @@ -145,4 +146,12 @@ #undef XCHAL_INST_FETCH_WIDTH #define XCHAL_INST_FETCH_WIDTH 4 + +#undef XSHAL_ABI +#undef XTHAL_ABI_WINDOWED +#undef XTHAL_ABI_CALL0 +#define XSHAL_ABI XTHAL_ABI_WINDOWED +#define XTHAL_ABI_WINDOWED 0 +#define XTHAL_ABI_CALL0 1 + #endif /* !XTENSA_CONFIG_H */ diff --git a/ld/ChangeLog b/ld/ChangeLog index 1b8837c..73b4f6c 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,14 @@ +2006-11-27 Bob Wilson + + * emultempl/xtensaelf.em (XSHAL_ABI): Add default definition. + (replace_insn_sec_with_prop_sec): Use bfd_make_section_with_flags. + Delete redundant code to set sections flags and alignment. + (xt_config_info_unpack_and_check, check_xtensa_info): New. + (elf_xtensa_after_open): Iterate over input statements instead of + link_info.input_bfds. + (elf_xtensa_before_allocation): Likewise. Call check_xtensa_info for + each input, and write a new .xtensa.info section in the output. + 2006-11-22 Nick Clifton * configure.in (LINGUAS): Add ga. diff --git a/ld/emultempl/xtensaelf.em b/ld/emultempl/xtensaelf.em index cf3f774..bed39ba 100644 --- a/ld/emultempl/xtensaelf.em +++ b/ld/emultempl/xtensaelf.em @@ -16,7 +16,8 @@ # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. +# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, +# MA 02110-1301 USA. # # This file is sourced from elf32.em, and defines extra xtensa-elf @@ -30,6 +31,11 @@ cat >>e${EMULATION_NAME}.c <size = entry_count * 12; prop_contents = (bfd_byte *) bfd_zalloc (abfd, prop_sec->size); elf_section_data (prop_sec)->this_hdr.contents = prop_contents; @@ -297,17 +295,13 @@ replace_instruction_table_sections (bfd *abfd, asection *sec) static void elf_xtensa_after_open (void) { - bfd *abfd; - /* First call the ELF version. */ gld${EMULATION_NAME}_after_open (); /* Now search the input files looking for instruction table sections. */ - for (abfd = link_info.input_bfds; - abfd != NULL; - abfd = abfd->link_next) + LANG_FOR_EACH_INPUT_STATEMENT (f) { - asection *sec = abfd->sections; + asection *sec = f->the_bfd->sections; asection *next_sec; /* Do not use bfd_map_over_sections here since we are removing @@ -315,20 +309,122 @@ elf_xtensa_after_open (void) while (sec != NULL) { next_sec = sec->next; - replace_instruction_table_sections (abfd, sec); + replace_instruction_table_sections (f->the_bfd, sec); sec = next_sec; } } } +static bfd_boolean +xt_config_info_unpack_and_check (char *data, + bfd_boolean *pmismatch, + char **pmsg) +{ + char *d, *key; + unsigned num; + + *pmismatch = FALSE; + + d = data; + while (*d) + { + key = d; + d = strchr (d, '='); + if (! d) + goto error; + + /* Overwrite the equal sign. */ + *d++ = 0; + + /* Check if this is a quoted string or a number. */ + if (*d == '"') + { + /* No string values are currently checked by LD; + just skip over the quotes. */ + d++; + d = strchr (d, '"'); + if (! d) + goto error; + /* Overwrite the trailing quote. */ + *d++ = 0; + } + else + { + if (*d == 0) + goto error; + num = strtoul (d, &d, 0); + + if (! strcmp (key, "ABI")) + { + if (num != XSHAL_ABI) + { + *pmismatch = TRUE; + *pmsg = "ABI does not match"; + } + } + else if (! strcmp (key, "USE_ABSOLUTE_LITERALS")) + { + if (num != XSHAL_USE_ABSOLUTE_LITERALS) + { + *pmismatch = TRUE; + *pmsg = "incompatible use of the Extended L32R option"; + } + } + } + + if (*d++ != '\n') + goto error; + } + + return TRUE; + + error: + return FALSE; +} + + +#define XTINFO_NAME "Xtensa_Info" +#define XTINFO_NAMESZ 12 +#define XTINFO_TYPE 1 + +static void +check_xtensa_info (bfd *abfd, asection *info_sec) +{ + char *data, *errmsg = ""; + bfd_boolean mismatch; + + data = xmalloc (info_sec->size); + if (! bfd_get_section_contents (abfd, info_sec, data, 0, info_sec->size)) + einfo (_("%F%P:%B: cannot read contents of section %A\n"), abfd, info_sec); + + if (info_sec->size > 24 + && info_sec->size >= 24 + bfd_get_32 (abfd, data + 4) + && bfd_get_32 (abfd, data + 0) == XTINFO_NAMESZ + && bfd_get_32 (abfd, data + 8) == XTINFO_TYPE + && strcmp (data + 12, XTINFO_NAME) == 0 + && xt_config_info_unpack_and_check (data + 12 + XTINFO_NAMESZ, + &mismatch, &errmsg)) + { + if (mismatch) + einfo (_("%P:%B: warning: incompatible Xtensa configuration (%s)\n"), + abfd, errmsg); + } + else + einfo (_("%P:%B: warning: cannot parse .xtensa.info section\n"), abfd); + + free (data); +} + + /* This is called after the sections have been attached to output sections, but before any sizes or addresses have been set. */ static void elf_xtensa_before_allocation (void) { - bfd *in_bfd; + asection *info_sec, *first_info_sec; + bfd *first_bfd; bfd_boolean is_big_endian = XCHAL_HAVE_BE; /* Check that the output endianness matches the Xtensa @@ -349,18 +445,80 @@ elf_xtensa_before_allocation (void) "Xtensa configuration\n")); } - /* Check that the endianness for each input file matches the output. - The merge_private_bfd_data hook has already reported any mismatches - as errors, but those errors are not fatal. At this point, we - cannot go any further if there are any mismatches. */ + /* Keep track of the first input .xtensa.info section, and as a fallback, + the first input bfd where a .xtensa.info section could be created. + After the input .xtensa.info has been checked, the contents of the + first one will be replaced with the output .xtensa.info table. */ + first_info_sec = 0; + first_bfd = 0; + + LANG_FOR_EACH_INPUT_STATEMENT (f) + { + /* Check that the endianness for each input file matches the output. + The merge_private_bfd_data hook has already reported any mismatches + as errors, but those errors are not fatal. At this point, we + cannot go any further if there are any mismatches. */ + if ((is_big_endian && f->the_bfd->xvec->byteorder == BFD_ENDIAN_LITTLE) + || (!is_big_endian && f->the_bfd->xvec->byteorder == BFD_ENDIAN_BIG)) + einfo (_("%F%P: cross-endian linking for %B not supported\n"), + f->the_bfd); + + if (! first_bfd) + first_bfd = f->the_bfd; + + info_sec = bfd_get_section_by_name (f->the_bfd, ".xtensa.info"); + if (! info_sec) + continue; + + if (! first_info_sec) + first_info_sec = info_sec; + + /* Unpack the .xtensa.info section and check it against the current + Xtensa configuration. */ + check_xtensa_info (f->the_bfd, info_sec); + + /* Do not include this copy of .xtensa.info in the output. */ + info_sec->size = 0; + info_sec->flags |= SEC_EXCLUDE; + } - for (in_bfd = link_info.input_bfds; - in_bfd != NULL; - in_bfd = in_bfd->link_next) + /* Reuse the first .xtensa.info input section to hold the output + .xtensa.info; or, if none were found, create a new section in the + first input bfd (assuming there is one). */ + info_sec = first_info_sec; + if (! info_sec && first_bfd) + { + info_sec = bfd_make_section_with_flags (first_bfd, ".xtensa.info", + SEC_HAS_CONTENTS | SEC_READONLY); + if (! info_sec) + einfo (_("%F%P: failed to create .xtensa.info section\n")); + } + if (info_sec) { - if ((is_big_endian && in_bfd->xvec->byteorder == BFD_ENDIAN_LITTLE) - || (!is_big_endian && in_bfd->xvec->byteorder == BFD_ENDIAN_BIG)) - einfo (_("%F%P: cross-endian linking not supported\n")); + int xtensa_info_size; + char *data; + + info_sec->flags &= ~SEC_EXCLUDE; + info_sec->flags |= SEC_IN_MEMORY; + + data = xmalloc (100); + sprintf (data, "USE_ABSOLUTE_LITERALS=%d\nABI=%d\n", + XSHAL_USE_ABSOLUTE_LITERALS, XSHAL_ABI); + xtensa_info_size = strlen (data) + 1; + + /* Add enough null terminators to pad to a word boundary. */ + do + data[xtensa_info_size++] = 0; + while ((xtensa_info_size & 3) != 0); + + info_sec->size = 12 + XTINFO_NAMESZ + xtensa_info_size; + info_sec->contents = xmalloc (info_sec->size); + bfd_put_32 (info_sec->owner, XTINFO_NAMESZ, info_sec->contents + 0); + bfd_put_32 (info_sec->owner, xtensa_info_size, info_sec->contents + 4); + bfd_put_32 (info_sec->owner, XTINFO_TYPE, info_sec->contents + 8); + memcpy (info_sec->contents + 12, XTINFO_NAME, XTINFO_NAMESZ); + memcpy (info_sec->contents + 12 + XTINFO_NAMESZ, data, xtensa_info_size); + free (data); } /* Enable relaxation by default if the "--no-relax" option was not -- 2.7.4