Just refactor the common code to easy maintain.
---
bfd/elf32-xtensa.c | 108 +++++++++++++++++++++++++++++++++++
gas/config/tc-xtensa.c | 7 +--
include/elf/xtensa.h | 18 ++++++
ld/emultempl/xtensaelf.em | 116 ++++++--------------------------------
4 files changed, 144 insertions(+), 105 deletions(-)
+ einfo (_("%P: %pB: warning: Xtensa incompatible use of the
Extended L32R option (%d != %d)\n"),
+ abfd, entries->use_absolute_literals,
XSHAL_USE_ABSOLUTE_LITERALS);
+ }
}
@@ -423,6 +340,7 @@ check_xtensa_info (bfd *abfd, asection *info_sec)
static void
elf_xtensa_before_allocation (void)
{
+ xtensa_info_entries xtensa_info;
asection *info_sec, *first_info_sec;
bfd *first_bfd;
bool is_big_endian = XCHAL_HAVE_BE;
@@ -477,7 +395,8 @@ elf_xtensa_before_allocation (void)
/* Unpack the .xtensa.info section and check it against the
current
Xtensa configuration. */
- check_xtensa_info (f->the_bfd, info_sec);
+ if (read_xtensa_info (f->the_bfd, info_sec, &xtensa_info))
+ check_xtensa_info (f->the_bfd, &xtensa_info);
/* Do not include this copy of .xtensa.info in the output. */
info_sec->size = 0;
@@ -504,8 +423,7 @@ elf_xtensa_before_allocation (void)
info_sec->flags |= SEC_IN_MEMORY;
data = xmalloc (100);
- sprintf (data, "USE_ABSOLUTE_LITERALS=%d\nABI=%d\n",
- XSHAL_USE_ABSOLUTE_LITERALS, xtensa_abi_choice ());
+ fill_xtensa_info (&data);
xtensa_info_size = strlen (data) + 1;
/* Add enough null terminators to pad to a word boundary. */
--
2.34.1
@@ -11495,6 +11495,114 @@ xtensa_callback_required_dependence (bfd
*abfd,
return ok;
}
+static void
+xtensa_info_set_entry (char *key, int value, xtensa_info_entries
*entries)
+{
+ if (! strcmp (key, "ABI"))
+ {
+ entries->abi = value;
+ }
+ else if (! strcmp (key, "USE_ABSOLUTE_LITERALS"))
+ {
+ entries->use_absolute_literals = value;
+ }
+}
+
+static bool
+xtensa_info_parse (char *data, xtensa_info_entries *entries)
+{
+ char *d, *key;
+
+ 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;
+ /* Skip the trailing quote. */
+ d++;
+ }
+ else if( *d >= '0' && *d <= '9' )
+ {
+ int value = strtoul (d, &d, 0);
+ xtensa_info_set_entry (key, value, entries);
+ }
+ else
+ goto error;
+
+ if (*d++ != '\n')
+ goto error;
+ }
+
+ return true;
+
+error:
+ return false;
+}
+
+bool
+read_xtensa_info (bfd *abfd, asection *info_sec, xtensa_info_entries
*entries)
+{
+ bool ret = false;
+ char *data = (char *) bfd_malloc (info_sec->size);
+
+ /* initialize values */
+ entries->abi = XSHAL_ABI;
+ entries->use_absolute_literals = XSHAL_USE_ABSOLUTE_LITERALS;
+
+ if (! bfd_get_section_contents (abfd, info_sec, data, 0, info_sec-
>size))
+ {
+ fprintf (stderr, _("%pB: cannot read contents of section
%pA\n"),
+ abfd, info_sec);
+ goto exit;
+ }
+
+ 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
+ && xtensa_info_parse (data + 12 + XTINFO_NAMESZ, entries)
+ )
+ )
+ {
+ fprintf (stderr,
+ _("%pB: warning: cannot parse .xtensa.info section\n"),
+ abfd);
+ goto exit;
+ }
+
+ ret = true;
+
+exit:
+ free (data);
+ return ret;
+}
+
+void
+fill_xtensa_info (char **data)
+{
+ sprintf (*data,
+ "USE_ABSOLUTE_LITERALS=%d\n"
+ "ABI=%d\n",
+ XSHAL_USE_ABSOLUTE_LITERALS,
+ xtensa_abi_choice ());
+}
+
/* The default literal sections should always be marked as "code"
(i.e.,
SHF_EXECINSTR). This is particularly important for the Linux
kernel
module loader so that the literals are not placed after the text.
*/
@@ -8982,10 +8982,6 @@ 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)
{
@@ -8997,8 +8993,7 @@ xtensa_add_config_info (void)
bfd_set_section_flags (info_sec, SEC_HAS_CONTENTS | SEC_READONLY);
data = XNEWVEC (char, 100);
- sprintf (data, "USE_ABSOLUTE_LITERALS=%d\nABI=%d\n",
- XSHAL_USE_ABSOLUTE_LITERALS, xtensa_abi_choice ());
+ fill_xtensa_info (&data);
sz = strlen (data) + 1;
/* Add enough null terminators to pad to a word boundary. */
@@ -138,6 +138,18 @@ typedef struct property_table_entry_t
flagword flags;
} property_table_entry;
+/* .xtensa.info section related definitions */
+
+#define XTINFO_NAME "Xtensa_Info"
+#define XTINFO_NAMESZ sizeof(XTINFO_NAME)
+#define XTINFO_TYPE 1
+
+typedef struct xtensa_info_entries_t
+{
+ int abi;
+ int use_absolute_literals;
+} xtensa_info_entries;
+
/* Flags in the property tables to specify whether blocks of memory
are
literals, instructions, data, or unreachable. For instructions,
blocks that begin loop targets and branch targets are designated.
@@ -228,6 +240,12 @@ xtensa_compute_fill_extra_space
(property_table_entry *entry);
extern int
xtensa_abi_choice (void);
+extern void
+fill_xtensa_info (char **data);
+
+extern bool
+read_xtensa_info (bfd *abfd, asection *info_sec, xtensa_info_entries
*entries);
+
#ifdef __cplusplus
}
#endif
@@ -312,108 +312,25 @@ elf_xtensa_after_open (void)
}
-static bool
-xt_config_info_unpack_and_check (char *data,
- bool *pmismatch,
- char **pmsg)
+static void
+check_xtensa_info (bfd *abfd, xtensa_info_entries *entries)
{
- char *d, *key;
- int num;
-
- *pmismatch = false;
-
- d = data;
- while (*d)
+ /* Check ABI */
+ if (elf32xtensa_abi == XTHAL_ABI_UNDEFINED)
{
- 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 (elf32xtensa_abi == XTHAL_ABI_UNDEFINED)
- {
- elf32xtensa_abi = num;
- }
- else if (num != elf32xtensa_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;
+ elf32xtensa_abi = entries->abi;
}
-
- 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 = "";
- bool mismatch;
-
- data = xmalloc (info_sec->size);
- if (! bfd_get_section_contents (abfd, info_sec, data, 0, info_sec-
>size))
- einfo (_("%F%P: %pB: cannot read contents of section %pA\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))
+ else if (entries->abi != elf32xtensa_abi)
{
- if (mismatch)
- einfo (_("%P: %pB: warning: incompatible Xtensa configuration
(%s)\n"),
- abfd, errmsg);
+ einfo (_("%P: %pB: warning: Xtensa ABI does not match\n"),
abfd);
}
- else
- einfo (_("%P: %pB: warning: cannot parse .xtensa.info section\n"),
abfd);
- free (data);
+ /* Check USE_ABSOLUTE_LITERALS */
+ if (entries->use_absolute_literals != XSHAL_USE_ABSOLUTE_LITERALS)
+ {