Add a new option to the linker: --error-handling-script=<NAME>. Run the script ...
authorNick Clifton <nickc@redhat.com>
Fri, 16 Oct 2020 10:37:26 +0000 (11:37 +0100)
committerNick Clifton <nickc@redhat.com>
Fri, 16 Oct 2020 10:37:26 +0000 (11:37 +0100)
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.

ld/ChangeLog
ld/NEWS
ld/config.in
ld/configure
ld/configure.ac
ld/ld.texi
ld/ldfile.c
ld/ldlex.h
ld/ldmain.c
ld/ldmain.h
ld/lexsup.c

index 780bb4b5958df516e8b78a1f1f65e6de38d9a274..18dc37bdd865b91d2f5ff05b17ec909783ed3dbf 100644 (file)
@@ -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 2f20a5fbcd0242212841afc0ccfc2493772557b2..81c44191d2bac9f44dd447cd346acff5f7b9a15a 100644 (file)
--- 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.
 
index 2f4e5ea33e36b8f9d3bdde991d637ee5e1b76cb7..7b60d77858730fb63c2f6601fdbe7f986bdfc23e 100644 (file)
 /* 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
 
index b0b92a3cbfb6b20e4c79b41fa5e4314481dd8a88..afe52ef5efa2014872367525a6b9022cdf180d33 100755 (executable)
@@ -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
index 74bcdfec36dbc4a02747e5b52c4a0cd1925bc1af..7676009d910ad917117074f309241d4889c272ba 100644 (file)
@@ -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.])
index 66bede283e8adf039081e41c786f839de7fe13a2..95f31ea530be225fc57c43caf68d6b80f24f2d94 100644 (file)
@@ -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
index e39170b5d94d53b491f3536f80e9ed85ed533140..51f878de958616729186eeb1a8b80a814aaece58 100644 (file)
@@ -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;
        }
index 6eac75cef531860d0e5cb72bb54ee9170f5679d3..bb38cca4d6e7c010dbc88b7b65851c9b3bd7d113 100644 (file)
@@ -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,
index 08be9030cb57e3835b6ba88b259caf5e7460e873..cdb4fe58d915feafc309c313dd24d9cc31d2749f 100644 (file)
@@ -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)
index ac7db5720d5729d95577fc97008fe95ba7fe5d1e..6863727473a95fad2adee5706bb2f64e3ed364f4 100644 (file)
@@ -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)
index 68943994846950839e213e16565020cc8f908a89..eae64932dfcbeaeec4391fc613bfa459eda56bcb 100644 (file)
@@ -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;
This page took 0.048489 seconds and 4 git commands to generate.