xtensa: allow runtime ABI selection
authorMax Filippov <jcmvbkbc@gmail.com>
Sun, 10 May 2020 15:03:08 +0000 (08:03 -0700)
committerMax Filippov <jcmvbkbc@gmail.com>
Mon, 15 Jun 2020 20:01:30 +0000 (13:01 -0700)
2020-06-15  Max Filippov  <jcmvbkbc@gmail.com>
bfd/
* elf32-xtensa.c (XSHAL_ABI, XTHAL_ABI_UNDEFINED)
(XTHAL_ABI_WINDOWED, XTHAL_ABI_CALL0): New macros.
(elf32xtensa_abi): New global variable.
(xtensa_abi_choice): New function.
(elf_xtensa_create_plt_entry): Use xtensa_abi_choice instead of
XSHAL_ABI to select PLT code.

gas/
* config/tc-xtensa.c (XTHAL_ABI_WINDOWED, XTHAL_ABI_CALL0): New
macros.
(elf32xtensa_abi): New declaration.
(option_abi_windowed, option_abi_call0): New enum constants.
(md_longopts): Add entries for --abi-windowed and --abi-call0.
(md_parse_option): Add handlers for --abi-windowed and
--abi-call0.
(xtensa_add_config_info): Use xtensa_abi_choice instead of
XSHAL_ABI to format ABI tag.
* doc/as.texi (Target Xtensa options): Add --abi-windowed and
--abi-call0 to the list of options.
* doc/c-xtensa.texi: Add description for options --abi-windowed
and --abi-call0.
* testsuite/gas/xtensa/abi-call0.d: New test definition.
* testsuite/gas/xtensa/abi-windowed.d: New test definition.
* testsuite/gas/xtensa/abi.s: New test source.

include/
* elf/xtensa.h (xtensa_abi_choice): New declaration.

ld/
* emultempl/xtensaelf.em (XSHAL_ABI): Remove macro definition.
(XTHAL_ABI_UNDEFINED, XTHAL_ABI_WINDOWED, XTHAL_ABI_CALL0): New
macros.
(elf32xtensa_abi): New declaration.
(xt_config_info_unpack_and_check): Set elf32xtensa_abi if it is
undefined.  Use xtensa_abi_choice instead of XSHAL_ABI to test
ABI tag consistency.
(xtensa_add_config_info): Use xtensa_abi_choice instead of
XSHAL_ABI to format ABI tag.
(PARSE_AND_LIST_PROLOGUE): Define OPTION_ABI_WINDOWED,
OPTION_ABI_CALL0 and declare elf32xtensa_abi.
(PARSE_AND_LIST_LONGOPTS): Add entries for --abi-windowed and
--abi-call0.
(PARSE_AND_LIST_OPTIONS): Add help text for --abi-windowed and
--abi-call0.
(PARSE_AND_LIST_ARGS_CASES): Add handlers for --abi-windowed and
--abi-call0.
* ld.texi: Add description for options --abi-windowed and
--abi-call0.

14 files changed:
bfd/ChangeLog
bfd/elf32-xtensa.c
gas/ChangeLog
gas/config/tc-xtensa.c
gas/doc/as.texi
gas/doc/c-xtensa.texi
gas/testsuite/gas/xtensa/abi-call0.d [new file with mode: 0644]
gas/testsuite/gas/xtensa/abi-windowed.d [new file with mode: 0644]
gas/testsuite/gas/xtensa/abi.s [new file with mode: 0644]
include/ChangeLog
include/elf/xtensa.h
ld/ChangeLog
ld/emultempl/xtensaelf.em
ld/ld.texi

index 741e96962b1df7a94f33404da53375920b76d1b8..ecd7f8d53ef5bd499e69f65ac506bc012580d863 100644 (file)
@@ -1,3 +1,12 @@
+2020-06-15  Max Filippov  <jcmvbkbc@gmail.com>
+
+       * elf32-xtensa.c (XSHAL_ABI, XTHAL_ABI_UNDEFINED)
+       (XTHAL_ABI_WINDOWED, XTHAL_ABI_CALL0): New macros.
+       (elf32xtensa_abi): New global variable.
+       (xtensa_abi_choice): New function.
+       (elf_xtensa_create_plt_entry): Use xtensa_abi_choice instead of
+       XSHAL_ABI to select PLT code.
+
 2020-06-15  Roland McGrath  <mcgrathr@google.com>
 
        * elflink.c (bfd_elf_define_start_stop): Use start_stop_visibility
index 9dc815edbb33eebb252b6f95a829b8929a13427f..b223424cce4e0c36b787aab144e7a28486fa3e65 100644 (file)
 
 #define XTENSA_NO_NOP_REMOVAL 0
 
+#ifndef XSHAL_ABI
+#define XSHAL_ABI 0
+#endif
+
+#ifndef XTHAL_ABI_UNDEFINED
+#define XTHAL_ABI_UNDEFINED -1
+#endif
+
+#ifndef XTHAL_ABI_WINDOWED
+#define XTHAL_ABI_WINDOWED 0
+#endif
+
+#ifndef XTHAL_ABI_CALL0
+#define XTHAL_ABI_CALL0 1
+#endif
+
 /* Local helper functions.  */
 
 static bfd_boolean add_extra_plt_sections (struct bfd_link_info *, int);
@@ -164,6 +180,10 @@ int elf32xtensa_no_literal_movement = 1;
 
 bfd_boolean elf32xtensa_separate_props = FALSE;
 
+/* Xtensa ABI.  It affects PLT entry code.  */
+
+int elf32xtensa_abi = XTHAL_ABI_UNDEFINED;
+
 /* Rename one of the generic section flags to better document how it
    is used here.  */
 /* Whether relocations have been processed.  */
@@ -2247,6 +2267,13 @@ bfd_elf_xtensa_reloc (bfd *abfd,
   return flag;
 }
 
+int xtensa_abi_choice (void)
+{
+  if (elf32xtensa_abi == XTHAL_ABI_UNDEFINED)
+    return XSHAL_ABI;
+  else
+    return elf32xtensa_abi;
+}
 
 /* Set up an entry in the procedure linkage table.  */
 
@@ -2259,6 +2286,7 @@ elf_xtensa_create_plt_entry (struct bfd_link_info *info,
   bfd_vma plt_base, got_base;
   bfd_vma code_offset, lit_offset, abi_offset;
   int chunk;
+  int abi = xtensa_abi_choice ();
 
   chunk = reloc_index / PLT_ENTRIES_PER_CHUNK;
   splt = elf_xtensa_get_plt_section (info, chunk);
@@ -2279,10 +2307,10 @@ elf_xtensa_create_plt_entry (struct bfd_link_info *info,
   /* Fill in the entry in the procedure linkage table.  */
   memcpy (splt->contents + code_offset,
          (bfd_big_endian (output_bfd)
-          ? elf_xtensa_be_plt_entry[XSHAL_ABI != XTHAL_ABI_WINDOWED]
-          : elf_xtensa_le_plt_entry[XSHAL_ABI != XTHAL_ABI_WINDOWED]),
+          ? elf_xtensa_be_plt_entry[abi != XTHAL_ABI_WINDOWED]
+          : elf_xtensa_le_plt_entry[abi != XTHAL_ABI_WINDOWED]),
          PLT_ENTRY_SIZE);
-  abi_offset = XSHAL_ABI == XTHAL_ABI_WINDOWED ? 3 : 0;
+  abi_offset = abi == XTHAL_ABI_WINDOWED ? 3 : 0;
   bfd_put_16 (output_bfd, l32r_offset (got_base + 0,
                                       plt_base + code_offset + abi_offset),
              splt->contents + code_offset + abi_offset + 1);
index 0c74415526fe781a0f5355315854a4c035adbd8b..b19576d027a17fce6d387629fff27cfab2be867d 100644 (file)
@@ -1,3 +1,22 @@
+2020-06-15  Max Filippov  <jcmvbkbc@gmail.com>
+
+       * config/tc-xtensa.c (XTHAL_ABI_WINDOWED, XTHAL_ABI_CALL0): New
+       macros.
+       (elf32xtensa_abi): New declaration.
+       (option_abi_windowed, option_abi_call0): New enum constants.
+       (md_longopts): Add entries for --abi-windowed and --abi-call0.
+       (md_parse_option): Add handlers for --abi-windowed and
+       --abi-call0.
+       (xtensa_add_config_info): Use xtensa_abi_choice instead of
+       XSHAL_ABI to format ABI tag.
+       * doc/as.texi (Target Xtensa options): Add --abi-windowed and
+       --abi-call0 to the list of options.
+       * doc/c-xtensa.texi: Add description for options --abi-windowed
+       and --abi-call0.
+       * testsuite/gas/xtensa/abi-call0.d: New test definition.
+       * testsuite/gas/xtensa/abi-windowed.d: New test definition.
+       * testsuite/gas/xtensa/abi.s: New test source.
+
 2020-06-14  H.J. Lu  <hongjiu.lu@intel.com>
 
        PR gas/26115
index 14a5a2a9497e45abdf2035b77f95e59970a327c5..b512f7a36bace6b48773f959469371dffbcf306f 100644 (file)
 #include "elf/xtensa.h"
 
 /* Provide default values for new configuration settings.  */
-#ifndef XSHAL_ABI
-#define XSHAL_ABI 0
+#ifndef XTHAL_ABI_WINDOWED
+#define XTHAL_ABI_WINDOWED 0
+#endif
+
+#ifndef XTHAL_ABI_CALL0
+#define XTHAL_ABI_CALL0 1
 #endif
 
 #ifndef XTENSA_MARCH_EARLIEST
@@ -648,6 +652,10 @@ static bfd_boolean workaround_all_short_loops = FALSE;
    This option is defined in BDF library.  */
 extern bfd_boolean elf32xtensa_separate_props;
 
+/* Xtensa ABI.
+   This option is defined in BDF library.  */
+extern int elf32xtensa_abi;
+
 static void
 xtensa_setup_hw_workarounds (int earliest, int latest)
 {
@@ -735,6 +743,9 @@ enum
 
   option_separate_props,
   option_no_separate_props,
+
+  option_abi_windowed,
+  option_abi_call0,
 };
 
 const char *md_shortopts = "";
@@ -816,6 +827,9 @@ struct option md_longopts[] =
 
   { "separate-prop-tables", no_argument, NULL, option_separate_props },
 
+  { "abi-windowed", no_argument, NULL, option_abi_windowed },
+  { "abi-call0", no_argument, NULL, option_abi_call0 },
+
   { NULL, no_argument, NULL, 0 }
 };
 
@@ -1044,6 +1058,14 @@ md_parse_option (int c, const char *arg)
       elf32xtensa_separate_props = FALSE;
       return 1;
 
+    case option_abi_windowed:
+      elf32xtensa_abi = XTHAL_ABI_WINDOWED;
+      return 1;
+
+    case option_abi_call0:
+      elf32xtensa_abi = XTHAL_ABI_CALL0;
+      return 1;
+
     default:
       return 0;
     }
@@ -8958,7 +8980,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
@@ -8975,7 +8996,7 @@ xtensa_add_config_info (void)
 
   data = XNEWVEC (char, 100);
   sprintf (data, "USE_ABSOLUTE_LITERALS=%d\nABI=%d\n",
-          XSHAL_USE_ABSOLUTE_LITERALS, XSHAL_ABI);
+          XSHAL_USE_ABSOLUTE_LITERALS, xtensa_abi_choice ());
   sz = strlen (data) + 1;
 
   /* Add enough null terminators to pad to a word boundary.  */
index dd6c96835f95189f5fa9007a7b544171f59c6ad3..f8d892eaa5c1771237189a6963285fb60e6a3197 100644 (file)
@@ -626,6 +626,7 @@ gcc(1), ld(1), and the Info entries for @file{binutils} and @file{ld}.
  [@b{--[no-]transform}]
  [@b{--rename-section} @var{oldname}=@var{newname}]
  [@b{--[no-]trampolines}]
+ [@b{--abi-windowed}|@b{--abi-call0}]
 @end ifset
 @ifset Z80
 
index e0c5e1ae288f6f72e83aa3714c5ca36dec22b480..b17ee83dbf4f1fa4372a60e9a96ec62b7aa088a8 100644 (file)
@@ -122,6 +122,14 @@ across a greater range of addresses.  @xref{Xtensa Jump Relaxation,
 potentially be out of range.  In the absence of such jumps this option
 does not affect code size or performance.  The default is
 @samp{--trampolines}.
+
+@item --abi-windowed | --abi-call0
+@kindex --abi-windowed
+@kindex --abi-call0
+Choose ABI tag written to the @code{.xtensa.info} section.  ABI tag
+indicates ABI of the assembly code.  A warning is issued by the linker
+on an attempt to link object files with inconsistent ABI tags.
+Default ABI is chosen by the Xtensa core configuration.
 @end table
 
 @c man end
diff --git a/gas/testsuite/gas/xtensa/abi-call0.d b/gas/testsuite/gas/xtensa/abi-call0.d
new file mode 100644 (file)
index 0000000..83ff10d
--- /dev/null
@@ -0,0 +1,7 @@
+#as: --abi-call0
+#objdump: -j .xtensa.info -s
+#source: abi.s
+
+#...
+.*ABI=1.*
+#...
diff --git a/gas/testsuite/gas/xtensa/abi-windowed.d b/gas/testsuite/gas/xtensa/abi-windowed.d
new file mode 100644 (file)
index 0000000..9f10fd0
--- /dev/null
@@ -0,0 +1,7 @@
+#as: --abi-windowed
+#objdump: -j .xtensa.info -s
+#source: abi.s
+
+#...
+.*ABI=0.*
+#...
diff --git a/gas/testsuite/gas/xtensa/abi.s b/gas/testsuite/gas/xtensa/abi.s
new file mode 100644 (file)
index 0000000..09cc1e1
--- /dev/null
@@ -0,0 +1 @@
+       .text
index f30e5e2a24a0c17192c33aacae26dc3d5bb89acc..7201be9f4d1ea64c882d6dfc0270cff0162d2734 100644 (file)
@@ -1,3 +1,7 @@
+2020-06-15  Max Filippov  <jcmvbkbc@gmail.com>
+
+       * elf/xtensa.h (xtensa_abi_choice): New declaration.
+
 2020-06-12  Roland McGrath  <mcgrathr@google.com>
 
        * bfdlink.h (struct bfd_link_info): New field start_stop_visibility.
index bd5c80d13777c5c4bd67b714c61dd4314a3a9dde..eac1a15dc33695b164ef2fa8098212a8e9721a3b 100644 (file)
@@ -225,6 +225,9 @@ xtensa_read_table_entries (bfd *abfd,
 extern int
 xtensa_compute_fill_extra_space (property_table_entry *entry);
 
+extern int
+xtensa_abi_choice (void);
+
 #ifdef __cplusplus
 }
 #endif
index 6700e727d83299ba18bd4b09e616995ed22c68ac..73a99a061e72d87c5155216ac722fd5362e5e577 100644 (file)
@@ -1,3 +1,25 @@
+2020-06-15  Max Filippov  <jcmvbkbc@gmail.com>
+
+       * emultempl/xtensaelf.em (XSHAL_ABI): Remove macro definition.
+       (XTHAL_ABI_UNDEFINED, XTHAL_ABI_WINDOWED, XTHAL_ABI_CALL0): New
+       macros.
+       (elf32xtensa_abi): New declaration.
+       (xt_config_info_unpack_and_check): Set elf32xtensa_abi if it is
+       undefined.  Use xtensa_abi_choice instead of XSHAL_ABI to test
+       ABI tag consistency.
+       (xtensa_add_config_info): Use xtensa_abi_choice instead of
+       XSHAL_ABI to format ABI tag.
+       (PARSE_AND_LIST_PROLOGUE): Define OPTION_ABI_WINDOWED,
+       OPTION_ABI_CALL0 and declare elf32xtensa_abi.
+       (PARSE_AND_LIST_LONGOPTS): Add entries for --abi-windowed and
+       --abi-call0.
+       (PARSE_AND_LIST_OPTIONS): Add help text for --abi-windowed and
+       --abi-call0.
+       (PARSE_AND_LIST_ARGS_CASES): Add handlers for --abi-windowed and
+       --abi-call0.
+       * ld.texi: Add description for options --abi-windowed and
+       --abi-call0.
+
 2020-06-15  Roland McGrath  <mcgrathr@google.com>
 
        * NEWS: Mention -z start-stop-visibility=... option for ELF.
index 932721c6f16d086c6854df5b199c191cb125bbc1..53f40c22830354eb44f9c3bddcc2de967b41a4c9 100644 (file)
@@ -30,8 +30,16 @@ fragment <<EOF
 #include "bfd.h"
 
 /* Provide default values for new configuration settings.  */
-#ifndef XSHAL_ABI
-#define XSHAL_ABI 0
+#ifndef XTHAL_ABI_UNDEFINED
+#define XTHAL_ABI_UNDEFINED -1
+#endif
+
+#ifndef XTHAL_ABI_WINDOWED
+#define XTHAL_ABI_WINDOWED 0
+#endif
+
+#ifndef XTHAL_ABI_CALL0
+#define XTHAL_ABI_CALL0 1
 #endif
 
 static void xtensa_wild_group_interleave (lang_statement_union_type *);
@@ -49,6 +57,10 @@ static bfd_boolean xtensa_use_literal_pages = FALSE;
 
 #define EXTRA_VALIDATION 0
 
+/* Xtensa ABI.
+   This option is defined in BDF library.  */
+extern int elf32xtensa_abi;
+
 
 static char *
 elf_xtensa_choose_target (int argc ATTRIBUTE_UNUSED,
@@ -306,7 +318,7 @@ xt_config_info_unpack_and_check (char *data,
                                 char **pmsg)
 {
   char *d, *key;
-  unsigned num;
+  int num;
 
   *pmismatch = FALSE;
 
@@ -341,7 +353,11 @@ xt_config_info_unpack_and_check (char *data,
 
          if (! strcmp (key, "ABI"))
            {
-             if (num != XSHAL_ABI)
+             if (elf32xtensa_abi == XTHAL_ABI_UNDEFINED)
+               {
+                 elf32xtensa_abi = num;
+               }
+             else if (num != elf32xtensa_abi)
                {
                  *pmismatch = TRUE;
                  *pmsg = "ABI does not match";
@@ -489,7 +505,7 @@ elf_xtensa_before_allocation (void)
 
       data = xmalloc (100);
       sprintf (data, "USE_ABSOLUTE_LITERALS=%d\nABI=%d\n",
-              XSHAL_USE_ABSOLUTE_LITERALS, XSHAL_ABI);
+              XSHAL_USE_ABSOLUTE_LITERALS, xtensa_abi_choice ());
       xtensa_info_size = strlen (data) + 1;
 
       /* Add enough null terminators to pad to a word boundary.  */
@@ -1920,20 +1936,29 @@ PARSE_AND_LIST_PROLOGUE='
 #define OPTION_OPT_SIZEOPT              (300)
 #define OPTION_LITERAL_MOVEMENT                (OPTION_OPT_SIZEOPT + 1)
 #define OPTION_NO_LITERAL_MOVEMENT     (OPTION_LITERAL_MOVEMENT + 1)
+#define OPTION_ABI_WINDOWED            (OPTION_NO_LITERAL_MOVEMENT + 1)
+#define OPTION_ABI_CALL0               (OPTION_ABI_WINDOWED + 1)
 extern int elf32xtensa_size_opt;
 extern int elf32xtensa_no_literal_movement;
+extern int elf32xtensa_abi;
 '
 
 PARSE_AND_LIST_LONGOPTS='
   { "size-opt", no_argument, NULL, OPTION_OPT_SIZEOPT},
   { "literal-movement", no_argument, NULL, OPTION_LITERAL_MOVEMENT},
   { "no-literal-movement", no_argument, NULL, OPTION_NO_LITERAL_MOVEMENT},
+  { "abi-windowed", no_argument, NULL, OPTION_ABI_WINDOWED},
+  { "abi-call0", no_argument, NULL, OPTION_ABI_CALL0},
 '
 
 PARSE_AND_LIST_OPTIONS='
   fprintf (file, _("\
   --size-opt                  When relaxing longcalls, prefer size\n\
                                 optimization over branch target alignment\n"));
+  fprintf (file, _("\
+  --abi-windowed              Choose windowed ABI for the output object\n"));
+  fprintf (file, _("\
+  --abi-call0                 Choose call0 ABI for the output object\n"));
 '
 
 PARSE_AND_LIST_ARGS_CASES='
@@ -1946,6 +1971,12 @@ PARSE_AND_LIST_ARGS_CASES='
     case OPTION_NO_LITERAL_MOVEMENT:
       elf32xtensa_no_literal_movement = 1;
       break;
+    case OPTION_ABI_WINDOWED:
+      elf32xtensa_abi = XTHAL_ABI_WINDOWED;
+      break;
+    case OPTION_ABI_CALL0:
+      elf32xtensa_abi = XTHAL_ABI_CALL0;
+      break;
 '
 
 # Replace some of the standard ELF functions with our own versions.
index b89c1a57c0b4e6476a003cec46e278bc8c29a2d5..ecdbf775eb3e9669e18b20634c99326beb7d4d0c 100644 (file)
@@ -8565,6 +8565,17 @@ more than performance.  With this option, the linker will not insert
 no-ops or widen density instructions to preserve branch target
 alignment.  There may still be some cases where no-ops are required to
 preserve the correctness of the code.
+
+@item --abi-windowed
+@itemx --abi-call0
+Choose ABI for the output object and for the generated PLT code.
+PLT code inserted by the linker must match ABI of the output object
+because windowed and call0 ABI use incompatible function call
+conventions.
+Default ABI is chosen by the ABI tag in the @code{.xtensa.info} section
+of the first input object.
+A warning is issued if ABI tags of input objects do not match each other
+or the chosen output object ABI.
 @end table
 
 @ifclear GENERIC