aboutsummaryrefslogtreecommitdiff
path: root/ld
diff options
context:
space:
mode:
authorNick Clifton <nickc@redhat.com>2020-10-16 11:37:26 +0100
committerNick Clifton <nickc@redhat.com>2020-10-16 11:37:26 +0100
commit23ae20f5e3afeeab9aa616c63ab3b357668476d5 (patch)
tree77fe952d842fc8b8f4a0efccbc006686a3b05e77 /ld
parent472d09c18a750f483ad974991f4f35ede3dfb10b (diff)
downloadgdb-23ae20f5e3afeeab9aa616c63ab3b357668476d5.zip
gdb-23ae20f5e3afeeab9aa616c63ab3b357668476d5.tar.gz
gdb-23ae20f5e3afeeab9aa616c63ab3b357668476d5.tar.bz2
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.
Diffstat (limited to 'ld')
-rw-r--r--ld/ChangeLog19
-rw-r--r--ld/NEWS5
-rw-r--r--ld/config.in4
-rwxr-xr-xld/configure28
-rw-r--r--ld/configure.ac17
-rw-r--r--ld/ld.texi15
-rw-r--r--ld/ldfile.c34
-rw-r--r--ld/ldlex.h3
-rw-r--r--ld/ldmain.c38
-rw-r--r--ld/ldmain.h3
-rw-r--r--ld/lexsup.c14
11 files changed, 178 insertions, 2 deletions
diff --git a/ld/ChangeLog b/ld/ChangeLog
index 780bb4b..18dc37b 100644
--- a/ld/ChangeLog
+++ b/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.
diff --git a/ld/NEWS b/ld/NEWS
index 2f20a5f..81c4419 100644
--- a/ld/NEWS
+++ b/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.
diff --git a/ld/config.in b/ld/config.in
index 2f4e5ea..7b60d77 100644
--- a/ld/config.in
+++ b/ld/config.in
@@ -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
diff --git a/ld/configure b/ld/configure
index b0b92a3..afe52ef 100755
--- a/ld/configure
+++ b/ld/configure
@@ -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
diff --git a/ld/configure.ac b/ld/configure.ac
index 74bcdfe..7676009 100644
--- a/ld/configure.ac
+++ b/ld/configure.ac
@@ -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.])
diff --git a/ld/ld.texi b/ld/ld.texi
index 66bede2..95f31ea 100644
--- a/ld/ld.texi
+++ b/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
diff --git a/ld/ldfile.c b/ld/ldfile.c
index e39170b..51f878d 100644
--- a/ld/ldfile.c
+++ b/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;
}
diff --git a/ld/ldlex.h b/ld/ldlex.h
index 6eac75c..bb38cca 100644
--- a/ld/ldlex.h
+++ b/ld/ldlex.h
@@ -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,
diff --git a/ld/ldmain.c b/ld/ldmain.c
index 08be903..cdb4fe5 100644
--- a/ld/ldmain.c
+++ b/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)
diff --git a/ld/ldmain.h b/ld/ldmain.h
index ac7db57..6863727 100644
--- a/ld/ldmain.h
+++ b/ld/ldmain.h
@@ -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)
diff --git a/ld/lexsup.c b/ld/lexsup.c
index 6894399..eae6493 100644
--- a/ld/lexsup.c
+++ b/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;