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

* Re: [PATCH] xtensa: add dynconfig option for ld/gas
  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
  0 siblings, 1 reply; 3+ messages in thread
From: Alexey Lapshin @ 2023-07-20 14:40 UTC (permalink / raw)
  To: binutils; +Cc: Alexey Gerenkov, Ivan Grokhotkov, jcmvbkbc

This patch is related to https://gcc.gnu.org/pipermail/gcc-patches/2023-July/625080.html

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

* [PATCH v2] xtensa: add dynconfig option for ld/gas
  2023-07-20 14:40 ` Alexey Lapshin
@ 2024-04-01 13:01   ` Alexey Lapshin
  0 siblings, 0 replies; 3+ messages in thread
From: Alexey Lapshin @ 2024-04-01 13:01 UTC (permalink / raw)
  To: binutils; +Cc: Alexey Gerenkov, Ivan Grokhotkov, jcmvbkbc

This needs to build xtensa multilib. Multilib can not operate with
environment variables but with compile options.

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     | 70 ++++++++++++++++++++++++++++++++++++--
 gas/config/tc-xtensa.c     | 16 ++++++++-
 include/xtensa-dynconfig.h |  3 ++
 ld/emultempl/xtensaelf.em  | 10 ++++++
 ld/ldlex.h                 |  1 +
 5 files changed, 97 insertions(+), 3 deletions(-)

diff --git a/bfd/xtensa-dynconfig.c b/bfd/xtensa-dynconfig.c
index 843f376326b..bd47798047e 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,70 @@ 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 = "";
+
+void xtensa_set_dynconfig_from_argv(int argc, char **argv)
+{
+  const char * const dynconfig_opt = "--dynconfig=";
+  for (int i = 1; i < argc; i++)
+    {
+      if (!strncmp (dynconfig_opt, argv[i], strlen(dynconfig_opt)))
+           {
+             xtensa_dynconfig_file = &argv[i][strlen(dynconfig_opt)];
+             break;
+           }
+    }
+}
+
+#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 +140,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 +173,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 e051bb9265b..9debd142fb4 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,8 @@ 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 +1057,10 @@ 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 +1095,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 library\n", stream);
 }
 
 \f
@@ -5270,6 +5280,10 @@ xg_init_global_config (void)
 void
 xtensa_init (int argc ATTRIBUTE_UNUSED, char **argv ATTRIBUTE_UNUSED)
 {
+  /* This function is called before AS arguments parsed.
+   * So, dynconfig file must be set first.  */
+  xtensa_set_dynconfig_from_argv(argc, argv);
+
   xg_init_global_config ();
 }
 
diff --git a/include/xtensa-dynconfig.h b/include/xtensa-dynconfig.h
index a0acffea236..a8556498254 100644
--- a/include/xtensa-dynconfig.h
+++ b/include/xtensa-dynconfig.h
@@ -129,6 +129,9 @@ extern const struct xtensa_config_v2 *xtensa_get_config_v2 (void);
 extern const struct xtensa_config_v3 *xtensa_get_config_v3 (void);
 extern const struct xtensa_config_v4 *xtensa_get_config_v4 (void);
 
+
+void xtensa_set_dynconfig_from_argv(int argc, char **argv);
+
 #ifdef XTENSA_CONFIG_DEFINITION
 
 #ifndef XCHAL_HAVE_MUL32_HIGH
diff --git a/ld/emultempl/xtensaelf.em b/ld/emultempl/xtensaelf.em
index 3508eb7f503..93277f2773d 100644
--- a/ld/emultempl/xtensaelf.em
+++ b/ld/emultempl/xtensaelf.em
@@ -61,6 +61,10 @@ static char *
 elf_xtensa_choose_target (int argc ATTRIBUTE_UNUSED,
 			  char **argv ATTRIBUTE_UNUSED)
 {
+  /* This function is called before LD arguments parsed.
+   * So, dynconfig file must be set first.  */
+  xtensa_set_dynconfig_from_argv(argc, argv);
+
   if (XCHAL_HAVE_BE)
     return "${BIG_OUTPUT_FORMAT}";
   else
@@ -1931,6 +1935,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='
@@ -1941,6 +1946,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 library\n"));
 '
 
 PARSE_AND_LIST_ARGS_CASES='
@@ -1959,6 +1966,9 @@ PARSE_AND_LIST_ARGS_CASES='
     case OPTION_ABI_CALL0:
       elf32xtensa_abi = XTHAL_ABI_CALL0;
       break;
+    case OPTION_DYNCONFIG:
+      /* Applied in elf_xtensa_choose_target()  */
+      break;
 '
 
 # Replace some of the standard ELF functions with our own versions.
diff --git a/ld/ldlex.h b/ld/ldlex.h
index d575562a357..f43ba4904c1 100644
--- a/ld/ldlex.h
+++ b/ld/ldlex.h
@@ -468,6 +468,7 @@ enum option_values
   OPTION_NO_LITERAL_MOVEMENT,
   OPTION_ABI_WINDOWED,
   OPTION_ABI_CALL0,
+  OPTION_DYNCONFIG,
 };
 
 /* The initial parser states.  */
-- 
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).