public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* [PATCH] xtensa: add dynconfig option for ld/gas
@ 2023-07-20 14:39 Alexey Lapshin
  2023-07-20 14:40 ` Alexey Lapshin
  0 siblings, 1 reply; 3+ messages in thread
From: Alexey Lapshin @ 2023-07-20 14:39 UTC (permalink / raw)
  To: binutils; +Cc: Alexey Gerenkov, Ivan Grokhotkov, jcmvbkbc

bfd/
        * bfd/xtensa-dynconfig.c: Add xtensa_dynconfig_file variable.

gas/
        * gas/config/tc-xtensa.c: Add dynconfig option.

ld/
        * ld/emultempl/xtensaelf.em: Add dynconfig option.
---
 bfd/xtensa-dynconfig.c    | 57 +++++++++++++++++++++++++++++++++++++--
 gas/config/tc-xtensa.c    | 29 ++++++++++++++++++--
 ld/emultempl/xtensaelf.em | 10 +++++++
 3 files changed, 92 insertions(+), 4 deletions(-)

diff --git a/bfd/xtensa-dynconfig.c b/bfd/xtensa-dynconfig.c
index ebf4098f59c..0140936e98e 100644
--- a/bfd/xtensa-dynconfig.c
+++ b/bfd/xtensa-dynconfig.c
@@ -20,6 +20,7 @@
 #include "sysdep.h"
 #include "bfd.h"
 #include "libbfd.h"
+#include "libiberty.h"
 
 #define XTENSA_CONFIG_DEFINITION
 #include "xtensa-config.h"
@@ -64,6 +65,57 @@ dlerror (void)
 
 #define CONFIG_ENV_NAME "XTENSA_GNU_CONFIG"
 
+/* this variable can be changed with input option for gas/ld  */
+const char *xtensa_dynconfig_file = "";
+
+#ifdef BFD_SUPPORTS_PLUGINS
+
+static char *get_xtensa_dynconfig_file (void)
+{
+  const char *xtensa_dynconfig_env = getenv (CONFIG_ENV_NAME);
+  if (!strlen (xtensa_dynconfig_file))
+    {
+      if (xtensa_dynconfig_env && !strlen (lbasename (xtensa_dynconfig_env)))
+	{
+	  /* XTENSA_GNU_CONFIG has directory path, but dynconfig file is not set */
+	  return NULL;
+	}
+      else if (xtensa_dynconfig_env)
+	{
+	  /* XTENSA_GNU_CONFIG has filepath */
+	  return xstrdup (xtensa_dynconfig_env);
+	}
+      /* dynconfig is not set */
+      return NULL;
+    }
+  if (!xtensa_dynconfig_env)
+    {
+      /* XTENSA_GNU_CONFIG has filepath */
+      return xstrdup (xtensa_dynconfig_file);
+    }
+  if (!strlen (lbasename (xtensa_dynconfig_env)))
+    {
+      /* XTENSA_GNU_CONFIG has directory path and dynconfig file is set */
+      const size_t len = strlen (xtensa_dynconfig_env) +
+                         strlen (xtensa_dynconfig_file) + 1;
+      char *path = ( char *) xmalloc (len);
+      strcpy (path, xtensa_dynconfig_env);
+      strcat (path, xtensa_dynconfig_file);
+      return path;
+    }
+  if (strcmp (lbasename (xtensa_dynconfig_env),
+              lbasename (xtensa_dynconfig_file)))
+    {
+      _bfd_error_handler (_("Both %s and \"-dynconfig=\" specified but pointed different files: \"%s\" \"%s\""),
+			      CONFIG_ENV_NAME, xtensa_dynconfig_env, xtensa_dynconfig_file);
+      abort ();
+    }
+  /* XTENSA_GNU_CONFIG and mdynconfig option point to the same file */
+  return xstrdup (xtensa_dynconfig_env);
+}
+
+#endif /* BFD_SUPPORTS_PLUGINS  */
+
 const void *xtensa_load_config (const char *name ATTRIBUTE_UNUSED,
 				const void *no_plugin_def,
 				const void *no_name_def ATTRIBUTE_UNUSED)
@@ -75,12 +127,13 @@ const void *xtensa_load_config (const char *name ATTRIBUTE_UNUSED,
 
   if (!init)
     {
-      const char *path = getenv (CONFIG_ENV_NAME);
+      char *path = get_xtensa_dynconfig_file();
 
       init = 1;
       if (!path)
 	return no_plugin_def;
       handle = dlopen (path, RTLD_LAZY);
+      free (path);
       if (!handle)
 	{
 	  _bfd_error_handler (_("%s is defined but could not be loaded: %s"),
@@ -107,7 +160,7 @@ const void *xtensa_load_config (const char *name ATTRIBUTE_UNUSED,
 #else
   if (!init)
     {
-      const char *path = getenv (CONFIG_ENV_NAME);
+      const char *path = strcmp(xtensa_dynconfig_file, "") ? xtensa_dynconfig_file : getenv (CONFIG_ENV_NAME);
 
       init = 1;
       if (path)
diff --git a/gas/config/tc-xtensa.c b/gas/config/tc-xtensa.c
index 550c8256e3f..d9ba8bc8690 100644
--- a/gas/config/tc-xtensa.c
+++ b/gas/config/tc-xtensa.c
@@ -733,6 +733,8 @@ enum
 
   option_abi_windowed,
   option_abi_call0,
+
+  option_dynconfig,
 };
 
 const char *md_shortopts = "";
@@ -817,6 +819,7 @@ struct option md_longopts[] =
   { "abi-windowed", no_argument, NULL, option_abi_windowed },
   { "abi-call0", no_argument, NULL, option_abi_call0 },
 
+  { "dynconfig=", required_argument, NULL, option_dynconfig },
   { NULL, no_argument, NULL, 0 }
 };
 
@@ -1053,6 +1056,12 @@ md_parse_option (int c, const char *arg)
       elf32xtensa_abi = XTHAL_ABI_CALL0;
       return 1;
 
+    case option_dynconfig:
+      {
+	    /* Applied in xtensa_init()  */
+	    return 1;
+      }
+
     default:
       return 0;
     }
@@ -1087,7 +1096,9 @@ Xtensa options:\n\
   --[no-]separate-prop-tables\n\
                           [Do not] place Xtensa property records into\n\
                           individual property sections for each section.\n\
-                          Default is to generate single property section.\n", stream);
+                          Default is to generate single property section.\n\
+  --dynconfig=<file>\n\
+                          Use xtensa dynconfig options\n", stream);
 }
 
 \f
@@ -5268,8 +5279,22 @@ xg_init_global_config (void)
 }
 
 void
-xtensa_init (int argc ATTRIBUTE_UNUSED, char **argv ATTRIBUTE_UNUSED)
+xtensa_init (int argc, char **argv)
 {
+  /* This function is called before AS arguments parsed.
+   * So, dynconfig file must be set first.
+   */
+  int i;
+  const char * const dynconfig_opt = "--dynconfig=";
+  for (i = 1; i < argc; i++)
+    {
+      if (!strncmp (dynconfig_opt, argv[i], strlen(dynconfig_opt)))
+	    {
+	      extern const char* xtensa_dynconfig_file;
+	      xtensa_dynconfig_file = &argv[i][strlen(dynconfig_opt)];
+	      break;
+	    }
+    }
   xg_init_global_config ();
 }
 
diff --git a/ld/emultempl/xtensaelf.em b/ld/emultempl/xtensaelf.em
index 4cb9bda8f92..615bde5655b 100644
--- a/ld/emultempl/xtensaelf.em
+++ b/ld/emultempl/xtensaelf.em
@@ -1930,6 +1930,7 @@ PARSE_AND_LIST_PROLOGUE='
 #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)
+#define OPTION_DYNCONFIG		(OPTION_ABI_CALL0 + 1)
 extern int elf32xtensa_size_opt;
 extern int elf32xtensa_no_literal_movement;
 extern int elf32xtensa_abi;
@@ -1941,6 +1942,7 @@ PARSE_AND_LIST_LONGOPTS='
   { "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},
+  { "dynconfig=", required_argument, NULL, OPTION_DYNCONFIG},
 '
 
 PARSE_AND_LIST_OPTIONS='
@@ -1951,6 +1953,8 @@ PARSE_AND_LIST_OPTIONS='
   --abi-windowed              Choose windowed ABI for the output object\n"));
   fprintf (file, _("\
   --abi-call0                 Choose call0 ABI for the output object\n"));
+  fprintf (file, _("\
+  --dynconfig=FILE            Choose xtensa dynconfig file\n"));
 '
 
 PARSE_AND_LIST_ARGS_CASES='
@@ -1969,6 +1973,12 @@ PARSE_AND_LIST_ARGS_CASES='
     case OPTION_ABI_CALL0:
       elf32xtensa_abi = XTHAL_ABI_CALL0;
       break;
+    case OPTION_DYNCONFIG:
+      {
+	extern const char* xtensa_dynconfig_file;
+	xtensa_dynconfig_file = optarg;
+	break;
+      }
 '
 
 # Replace some of the standard ELF functions with our own versions.
-- 
2.34.1


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2024-04-01 13:01 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-07-20 14:39 [PATCH] xtensa: add dynconfig option for ld/gas Alexey Lapshin
2023-07-20 14:40 ` Alexey Lapshin
2024-04-01 13:01   ` [PATCH v2] " Alexey Lapshin

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).