mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-12-15 22:00:47 +08:00
xtensa: add dynconfig option for ld/gas
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.
This commit is contained in:
@@ -20,6 +20,7 @@
|
|||||||
#include "sysdep.h"
|
#include "sysdep.h"
|
||||||
#include "bfd.h"
|
#include "bfd.h"
|
||||||
#include "libbfd.h"
|
#include "libbfd.h"
|
||||||
|
#include "libiberty.h"
|
||||||
|
|
||||||
#define XTENSA_CONFIG_DEFINITION
|
#define XTENSA_CONFIG_DEFINITION
|
||||||
#include "xtensa-config.h"
|
#include "xtensa-config.h"
|
||||||
@@ -64,6 +65,70 @@ dlerror (void)
|
|||||||
|
|
||||||
#define CONFIG_ENV_NAME "XTENSA_GNU_CONFIG"
|
#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
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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 *xtensa_load_config (const char *name ATTRIBUTE_UNUSED,
|
||||||
const void *no_plugin_def,
|
const void *no_plugin_def,
|
||||||
const void *no_name_def ATTRIBUTE_UNUSED)
|
const void *no_name_def ATTRIBUTE_UNUSED)
|
||||||
@@ -75,12 +140,13 @@ const void *xtensa_load_config (const char *name ATTRIBUTE_UNUSED,
|
|||||||
|
|
||||||
if (!init)
|
if (!init)
|
||||||
{
|
{
|
||||||
const char *path = getenv (CONFIG_ENV_NAME);
|
char *path = get_xtensa_dynconfig_file();
|
||||||
|
|
||||||
init = 1;
|
init = 1;
|
||||||
if (!path)
|
if (!path)
|
||||||
return no_plugin_def;
|
return no_plugin_def;
|
||||||
handle = dlopen (path, RTLD_LAZY);
|
handle = dlopen (path, RTLD_LAZY);
|
||||||
|
free (path);
|
||||||
if (!handle)
|
if (!handle)
|
||||||
{
|
{
|
||||||
_bfd_error_handler (_("%s is defined but could not be loaded: %s"),
|
_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
|
#else
|
||||||
if (!init)
|
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;
|
init = 1;
|
||||||
if (path)
|
if (path)
|
||||||
|
|||||||
@@ -733,6 +733,8 @@ enum
|
|||||||
|
|
||||||
option_abi_windowed,
|
option_abi_windowed,
|
||||||
option_abi_call0,
|
option_abi_call0,
|
||||||
|
|
||||||
|
option_dynconfig,
|
||||||
};
|
};
|
||||||
|
|
||||||
const char *md_shortopts = "";
|
const char *md_shortopts = "";
|
||||||
@@ -817,6 +819,7 @@ struct option md_longopts[] =
|
|||||||
{ "abi-windowed", no_argument, NULL, option_abi_windowed },
|
{ "abi-windowed", no_argument, NULL, option_abi_windowed },
|
||||||
{ "abi-call0", no_argument, NULL, option_abi_call0 },
|
{ "abi-call0", no_argument, NULL, option_abi_call0 },
|
||||||
|
|
||||||
|
{ "dynconfig=", required_argument, NULL, option_dynconfig },
|
||||||
{ NULL, no_argument, NULL, 0 }
|
{ NULL, no_argument, NULL, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1053,6 +1056,12 @@ md_parse_option (int c, const char *arg)
|
|||||||
elf32xtensa_abi = XTHAL_ABI_CALL0;
|
elf32xtensa_abi = XTHAL_ABI_CALL0;
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
case option_dynconfig:
|
||||||
|
{
|
||||||
|
/* Applied in xtensa_init() */
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -1087,7 +1096,9 @@ Xtensa options:\n\
|
|||||||
--[no-]separate-prop-tables\n\
|
--[no-]separate-prop-tables\n\
|
||||||
[Do not] place Xtensa property records into\n\
|
[Do not] place Xtensa property records into\n\
|
||||||
individual property sections for each section.\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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -5268,8 +5279,12 @@ xg_init_global_config (void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
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. */
|
||||||
|
xtensa_set_dynconfig_from_argv(argc, argv);
|
||||||
|
|
||||||
xg_init_global_config ();
|
xg_init_global_config ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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_v3 *xtensa_get_config_v3 (void);
|
||||||
extern const struct xtensa_config_v4 *xtensa_get_config_v4 (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
|
#ifdef XTENSA_CONFIG_DEFINITION
|
||||||
|
|
||||||
#ifndef XCHAL_HAVE_MUL32_HIGH
|
#ifndef XCHAL_HAVE_MUL32_HIGH
|
||||||
|
|||||||
@@ -61,6 +61,10 @@ static char *
|
|||||||
elf_xtensa_choose_target (int argc ATTRIBUTE_UNUSED,
|
elf_xtensa_choose_target (int argc ATTRIBUTE_UNUSED,
|
||||||
char **argv 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)
|
if (XCHAL_HAVE_BE)
|
||||||
return "${BIG_OUTPUT_FORMAT}";
|
return "${BIG_OUTPUT_FORMAT}";
|
||||||
else
|
else
|
||||||
@@ -1931,6 +1935,7 @@ PARSE_AND_LIST_LONGOPTS='
|
|||||||
{ "no-literal-movement", no_argument, NULL, OPTION_NO_LITERAL_MOVEMENT},
|
{ "no-literal-movement", no_argument, NULL, OPTION_NO_LITERAL_MOVEMENT},
|
||||||
{ "abi-windowed", no_argument, NULL, OPTION_ABI_WINDOWED},
|
{ "abi-windowed", no_argument, NULL, OPTION_ABI_WINDOWED},
|
||||||
{ "abi-call0", no_argument, NULL, OPTION_ABI_CALL0},
|
{ "abi-call0", no_argument, NULL, OPTION_ABI_CALL0},
|
||||||
|
{ "dynconfig=", required_argument, NULL, OPTION_DYNCONFIG},
|
||||||
'
|
'
|
||||||
|
|
||||||
PARSE_AND_LIST_OPTIONS='
|
PARSE_AND_LIST_OPTIONS='
|
||||||
@@ -1941,6 +1946,8 @@ PARSE_AND_LIST_OPTIONS='
|
|||||||
--abi-windowed Choose windowed ABI for the output object\n"));
|
--abi-windowed Choose windowed ABI for the output object\n"));
|
||||||
fprintf (file, _("\
|
fprintf (file, _("\
|
||||||
--abi-call0 Choose call0 ABI for the output object\n"));
|
--abi-call0 Choose call0 ABI for the output object\n"));
|
||||||
|
fprintf (file, _("\
|
||||||
|
--dynconfig=FILE Choose xtensa dynconfig file\n"));
|
||||||
'
|
'
|
||||||
|
|
||||||
PARSE_AND_LIST_ARGS_CASES='
|
PARSE_AND_LIST_ARGS_CASES='
|
||||||
@@ -1959,6 +1966,9 @@ PARSE_AND_LIST_ARGS_CASES='
|
|||||||
case OPTION_ABI_CALL0:
|
case OPTION_ABI_CALL0:
|
||||||
elf32xtensa_abi = XTHAL_ABI_CALL0;
|
elf32xtensa_abi = XTHAL_ABI_CALL0;
|
||||||
break;
|
break;
|
||||||
|
case OPTION_DYNCONFIG:
|
||||||
|
/* Applied in elf_xtensa_choose_target() */
|
||||||
|
break;
|
||||||
'
|
'
|
||||||
|
|
||||||
# Replace some of the standard ELF functions with our own versions.
|
# Replace some of the standard ELF functions with our own versions.
|
||||||
|
|||||||
@@ -471,6 +471,7 @@ enum option_values
|
|||||||
OPTION_NO_LITERAL_MOVEMENT,
|
OPTION_NO_LITERAL_MOVEMENT,
|
||||||
OPTION_ABI_WINDOWED,
|
OPTION_ABI_WINDOWED,
|
||||||
OPTION_ABI_CALL0,
|
OPTION_ABI_CALL0,
|
||||||
|
OPTION_DYNCONFIG,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* The initial parser states. */
|
/* The initial parser states. */
|
||||||
|
|||||||
Reference in New Issue
Block a user