Add a new option to the linker: --error-handling-script=<NAME>. Run the script <NAME> if an undefined symbol or unfound library error is encountered.
PR 26626 * ldmain.c (undefined_symbol): If an error handlign script is available, call it. * ldfile.c (error_handling_script): Declare. (ldfile_open_file): If a library cannot be found and an error handling script is available, call it. * ldmain.h (error_handling_script): Prototype. * ldlex.h (OPTION_ERROR_HANDLING_SCRIPT): Define. * lexsup.c (ld_options): Add --error-handling-script. (parse_args): Add support for --errror-handling-script. * ld.texi: Document the new feature. * configure.ac: Add --error-handling-script option to disable support for the new feature. * NEWS: Mention the new feature. * config.in: Regenerate. * configure: Regenerate.
This commit is contained in:
parent
472d09c18a
commit
23ae20f5e3
19
ld/ChangeLog
19
ld/ChangeLog
@ -1,3 +1,22 @@
|
||||
2020-10-16 Nick Clifton <nickc@redhat.com>
|
||||
|
||||
PR 26626
|
||||
* ldmain.c (undefined_symbol): If an error handlign script is
|
||||
available, call it.
|
||||
* ldfile.c (error_handling_script): Declare.
|
||||
(ldfile_open_file): If a library cannot be found and an error
|
||||
handling script is available, call it.
|
||||
* ldmain.h (error_handling_script): Prototype.
|
||||
* ldlex.h (OPTION_ERROR_HANDLING_SCRIPT): Define.
|
||||
* lexsup.c (ld_options): Add --error-handling-script.
|
||||
(parse_args): Add support for --errror-handling-script.
|
||||
* ld.texi: Document the new feature.
|
||||
* configure.ac: Add --error-handling-script option to disable
|
||||
support for the new feature.
|
||||
* NEWS: Mention the new feature.
|
||||
* config.in: Regenerate.
|
||||
* configure: Regenerate.
|
||||
|
||||
2020-10-16 Nelson Chu <nelson.chu@sifive.com>
|
||||
|
||||
* testsuite/ld-riscv-elf/ifunc-plt-got-overwrite.s: New testcase.
|
||||
|
5
ld/NEWS
5
ld/NEWS
@ -1,5 +1,10 @@
|
||||
-*- text -*-
|
||||
|
||||
* Add --error-handling-script=<NAME> command line option to allow a helper
|
||||
script to be invoked when an undefined symbol or a missing library is
|
||||
encountered. This option can be suppressed via the configure time
|
||||
switch: --enable-error-handling-script=no.
|
||||
|
||||
* Add -z x86-64-v[234] to the x86 ELF linker to mark x86-64-v[234] ISA
|
||||
level as needed.
|
||||
|
||||
|
@ -215,6 +215,10 @@
|
||||
/* Define if you can safely include both <string.h> and <strings.h>. */
|
||||
#undef STRING_WITH_STRINGS
|
||||
|
||||
/* Define to 1 if you want to support the --error-handling-script command line
|
||||
option. */
|
||||
#undef SUPPORT_ERROR_HANDLING_SCRIPT
|
||||
|
||||
/* Use b modifier when opening binary files? */
|
||||
#undef USE_BINARY_FOPEN
|
||||
|
||||
|
28
ld/configure
vendored
28
ld/configure
vendored
@ -835,6 +835,7 @@ enable_new_dtags
|
||||
enable_relro
|
||||
enable_textrel_check
|
||||
enable_separate_code
|
||||
enable_error_handling_script
|
||||
enable_default_hash_style
|
||||
enable_libctf
|
||||
enable_werror
|
||||
@ -1505,6 +1506,9 @@ Optional Features:
|
||||
--enable-textrel-check=[yes|no|warning|error]
|
||||
enable DT_TEXTREL check in ELF linker
|
||||
--enable-separate-code enable -z separate-code in ELF linker by default
|
||||
--enable-error-handling-script
|
||||
enable/disable support for the
|
||||
--error-handling-script option
|
||||
--enable-default-hash-style={sysv,gnu,both}
|
||||
use this default hash style
|
||||
--enable-libctf Handle .ctf type-info sections [default=yes]
|
||||
@ -12039,7 +12043,7 @@ else
|
||||
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
|
||||
lt_status=$lt_dlunknown
|
||||
cat > conftest.$ac_ext <<_LT_EOF
|
||||
#line 12042 "configure"
|
||||
#line 12046 "configure"
|
||||
#include "confdefs.h"
|
||||
|
||||
#if HAVE_DLFCN_H
|
||||
@ -12145,7 +12149,7 @@ else
|
||||
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
|
||||
lt_status=$lt_dlunknown
|
||||
cat > conftest.$ac_ext <<_LT_EOF
|
||||
#line 12148 "configure"
|
||||
#line 12152 "configure"
|
||||
#include "confdefs.h"
|
||||
|
||||
#if HAVE_DLFCN_H
|
||||
@ -15945,6 +15949,17 @@ esac
|
||||
fi
|
||||
|
||||
|
||||
# Decide if --error-handling-script should be supported.
|
||||
ac_support_error_handling_script=unset
|
||||
# Check whether --enable-error-handling-script was given.
|
||||
if test "${enable_error_handling_script+set}" = set; then :
|
||||
enableval=$enable_error_handling_script; case "${enableval}" in
|
||||
yes) ac_support_error_handling_script=1 ;;
|
||||
no) ac_support_error_handling_script=0 ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
|
||||
# Decide which "--hash-style" to use by default
|
||||
# Provide a configure time option to override our default.
|
||||
# Check whether --enable-default-hash-style was given.
|
||||
@ -17739,6 +17754,15 @@ cat >>confdefs.h <<_ACEOF
|
||||
_ACEOF
|
||||
|
||||
|
||||
if test "${ac_support_error_handling_script}" = unset; then
|
||||
ac_support_error_handling_script=1
|
||||
fi
|
||||
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define SUPPORT_ERROR_HANDLING_SCRIPT $ac_support_error_handling_script
|
||||
_ACEOF
|
||||
|
||||
|
||||
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define DEFAULT_EMIT_SYSV_HASH $ac_default_emit_sysv_hash
|
||||
|
@ -195,6 +195,16 @@ AC_ARG_ENABLE(separate-code,
|
||||
no) ac_default_ld_z_separate_code=0 ;;
|
||||
esac])
|
||||
|
||||
# Decide if --error-handling-script should be supported.
|
||||
ac_support_error_handling_script=unset
|
||||
AC_ARG_ENABLE(error-handling-script,
|
||||
AS_HELP_STRING([--enable-error-handling-script],
|
||||
[enable/disable support for the --error-handling-script option]),
|
||||
[case "${enableval}" in
|
||||
yes) ac_support_error_handling_script=1 ;;
|
||||
no) ac_support_error_handling_script=0 ;;
|
||||
esac])
|
||||
|
||||
# Decide which "--hash-style" to use by default
|
||||
# Provide a configure time option to override our default.
|
||||
AC_ARG_ENABLE([default-hash-style],
|
||||
@ -489,6 +499,13 @@ AC_DEFINE_UNQUOTED(DEFAULT_LD_Z_SEPARATE_CODE,
|
||||
$ac_default_ld_z_separate_code,
|
||||
[Define to 1 if you want to enable -z separate-code in ELF linker by default.])
|
||||
|
||||
if test "${ac_support_error_handling_script}" = unset; then
|
||||
ac_support_error_handling_script=1
|
||||
fi
|
||||
AC_DEFINE_UNQUOTED(SUPPORT_ERROR_HANDLING_SCRIPT,
|
||||
$ac_support_error_handling_script,
|
||||
[Define to 1 if you want to support the --error-handling-script command line option.])
|
||||
|
||||
AC_DEFINE_UNQUOTED([DEFAULT_EMIT_SYSV_HASH],
|
||||
[$ac_default_emit_sysv_hash],
|
||||
[Define to 1 if you want to emit sysv hash in the ELF linker by default.])
|
||||
|
15
ld/ld.texi
15
ld/ld.texi
@ -1923,6 +1923,21 @@ architecture. This is used, for example, to dynamically select an
|
||||
appropriate memset function.
|
||||
@end itemize
|
||||
|
||||
@kindex --error-handling-script=@var{scriptname}
|
||||
@item --error-handling-script=@var{scriptname}
|
||||
If this option is provided then the linker will invoke
|
||||
@var{scriptname} whenever an error is encountered. Currently however
|
||||
only two kinds of error are supported: missing symbols and missing
|
||||
libraries. Two arguments will be passed to script: the keyword
|
||||
``missing-symbol'' or `missing-lib'' and the @var{name} of the
|
||||
missing symbol or library. The intention is that the script will
|
||||
provide suggestions to the user as to where the symbol or library
|
||||
might be found. After the script has finished then the normal linker
|
||||
error message will be displayed.
|
||||
|
||||
The availability of this option is controlled by a configure time
|
||||
switch, so it may not be present in specific implementations.
|
||||
|
||||
@kindex --no-undefined-version
|
||||
@item --no-undefined-version
|
||||
Normally when a symbol has an undefined version, the linker will ignore
|
||||
|
34
ld/ldfile.c
34
ld/ldfile.c
@ -461,6 +461,39 @@ ldfile_open_file (lang_input_statement_type *entry)
|
||||
&& IS_ABSOLUTE_PATH (entry->local_sym_name))
|
||||
einfo (_("%P: cannot find %s inside %s\n"),
|
||||
entry->local_sym_name, ld_sysroot);
|
||||
#if SUPPORT_ERROR_HANDLING_SCRIPT
|
||||
else if (error_handling_script != NULL)
|
||||
{
|
||||
char * argv[4];
|
||||
const char * res;
|
||||
int status, err;
|
||||
|
||||
argv[0] = error_handling_script;
|
||||
argv[1] = "missing-lib";
|
||||
argv[2] = (char *) entry->local_sym_name;
|
||||
argv[3] = NULL;
|
||||
|
||||
if (verbose)
|
||||
einfo (_("%P: About to run error handling script '%s' with arguments: '%s' '%s'\n"),
|
||||
argv[0], argv[1], argv[2]);
|
||||
|
||||
res = pex_one (PEX_SEARCH, error_handling_script, argv,
|
||||
N_("error handling script"),
|
||||
NULL /* Send stdout to random, temp file. */,
|
||||
NULL /* Write to stderr. */,
|
||||
&status, &err);
|
||||
if (res != NULL)
|
||||
{
|
||||
einfo (_("%P: Failed to run error handling script '%s', reason: "),
|
||||
error_handling_script);
|
||||
/* FIXME: We assume here that errrno == err. */
|
||||
perror (res);
|
||||
}
|
||||
else /* We ignore the return status of the script
|
||||
and always print the error message. */
|
||||
einfo (_("%P: cannot find %s\n"), entry->local_sym_name);
|
||||
}
|
||||
#endif
|
||||
else
|
||||
einfo (_("%P: cannot find %s\n"), entry->local_sym_name);
|
||||
|
||||
@ -479,6 +512,7 @@ ldfile_open_file (lang_input_statement_type *entry)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
entry->flags.missing_file = TRUE;
|
||||
input_flags.missing_file = TRUE;
|
||||
}
|
||||
|
@ -116,6 +116,9 @@ enum option_values
|
||||
OPTION_ALLOW_SHLIB_UNDEFINED,
|
||||
OPTION_NO_ALLOW_SHLIB_UNDEFINED,
|
||||
OPTION_ALLOW_MULTIPLE_DEFINITION,
|
||||
#if SUPPORT_ERROR_HANDLING_SCRIPT
|
||||
OPTION_ERROR_HANDLING_SCRIPT,
|
||||
#endif
|
||||
OPTION_NO_UNDEFINED_VERSION,
|
||||
OPTION_DEFAULT_SYMVER,
|
||||
OPTION_DEFAULT_IMPORTED_SYMVER,
|
||||
|
38
ld/ldmain.c
38
ld/ldmain.c
@ -1382,6 +1382,10 @@ warning_find_reloc (bfd *abfd, asection *sec, void *iarg)
|
||||
free (relpp);
|
||||
}
|
||||
|
||||
#if SUPPORT_ERROR_HANDLING_SCRIPT
|
||||
char * error_handling_script = NULL;
|
||||
#endif
|
||||
|
||||
/* This is called when an undefined symbol is found. */
|
||||
|
||||
static void
|
||||
@ -1419,6 +1423,40 @@ undefined_symbol (struct bfd_link_info *info,
|
||||
error_name = xstrdup (name);
|
||||
}
|
||||
|
||||
#if SUPPORT_ERROR_HANDLING_SCRIPT
|
||||
if (error_handling_script != NULL
|
||||
&& error_count < MAX_ERRORS_IN_A_ROW)
|
||||
{
|
||||
char * argv[4];
|
||||
const char * res;
|
||||
int status, err;
|
||||
|
||||
argv[0] = error_handling_script;
|
||||
argv[1] = "missing-symbol";
|
||||
argv[2] = (char *) name;
|
||||
argv[3] = NULL;
|
||||
|
||||
if (verbose)
|
||||
einfo (_("%P: About to run error handling script '%s' with arguments: '%s' '%s'\n"),
|
||||
argv[0], argv[1], argv[2]);
|
||||
|
||||
res = pex_one (PEX_SEARCH, error_handling_script, argv,
|
||||
N_("error handling script"),
|
||||
NULL /* Send stdout to random, temp file. */,
|
||||
NULL /* Write to stderr. */,
|
||||
&status, &err);
|
||||
if (res != NULL)
|
||||
{
|
||||
einfo (_("%P: Failed to run error handling script '%s', reason: "),
|
||||
error_handling_script);
|
||||
/* FIXME: We assume here that errrno == err. */
|
||||
perror (res);
|
||||
}
|
||||
/* We ignore the return status of the script and
|
||||
carry on to issue the normal error message. */
|
||||
}
|
||||
#endif /* SUPPORT_ERROR_HANDLING_SCRIPT */
|
||||
|
||||
if (section != NULL)
|
||||
{
|
||||
if (error_count < MAX_ERRORS_IN_A_ROW)
|
||||
|
@ -37,6 +37,9 @@ extern int g_switch_value;
|
||||
extern const char *output_filename;
|
||||
extern struct bfd_link_info link_info;
|
||||
extern int overflow_cutoff_limit;
|
||||
#if SUPPORT_ERROR_HANDLING_SCRIPT
|
||||
extern char *error_handling_script;
|
||||
#endif
|
||||
|
||||
#define RELAXATION_DISABLED_BY_DEFAULT \
|
||||
(link_info.disable_target_specific_optimizations < 0)
|
||||
|
14
ld/lexsup.c
14
ld/lexsup.c
@ -386,6 +386,11 @@ static const struct ld_option ld_options[] =
|
||||
{ {"allow-multiple-definition", no_argument, NULL,
|
||||
OPTION_ALLOW_MULTIPLE_DEFINITION},
|
||||
'\0', NULL, N_("Allow multiple definitions"), TWO_DASHES },
|
||||
#if SUPPORT_ERROR_HANDLING_SCRIPT
|
||||
{ {"error-handling-script", required_argument, NULL,
|
||||
OPTION_ERROR_HANDLING_SCRIPT},
|
||||
'\0', N_("SCRIPT"), N_("Provide a script to help with undefined symbol errors"), TWO_DASHES},
|
||||
#endif
|
||||
{ {"no-undefined-version", no_argument, NULL, OPTION_NO_UNDEFINED_VERSION},
|
||||
'\0', NULL, N_("Disallow undefined version"), TWO_DASHES },
|
||||
{ {"default-symver", no_argument, NULL, OPTION_DEFAULT_SYMVER},
|
||||
@ -1043,6 +1048,15 @@ parse_args (unsigned argc, char **argv)
|
||||
case OPTION_ALLOW_MULTIPLE_DEFINITION:
|
||||
link_info.allow_multiple_definition = TRUE;
|
||||
break;
|
||||
|
||||
#if SUPPORT_ERROR_HANDLING_SCRIPT
|
||||
case OPTION_ERROR_HANDLING_SCRIPT:
|
||||
/* FIXME: Should we warn if the script is being overridden by another ?
|
||||
Or maybe they should be chained together ? */
|
||||
error_handling_script = optarg;
|
||||
break;
|
||||
#endif
|
||||
|
||||
case OPTION_NO_UNDEFINED_VERSION:
|
||||
link_info.allow_undefined_version = FALSE;
|
||||
break;
|
||||
|
Loading…
x
Reference in New Issue
Block a user