diff mbox series

Generalize -fuse-ld= to support absolute path or arbitrary ld.linker

Message ID 20200210000234.aemsyusopeatxb6i@google.com
State New
Headers show
Series Generalize -fuse-ld= to support absolute path or arbitrary ld.linker | expand

Commit Message

Li, Pan2 via Gcc-patches Feb. 10, 2020, 12:02 a.m. UTC
PR driver/93645
	* common.opt (-fuse-ld=): Delete -fuse-ld=[bfd|gold|lld]. Add -fuse-ld=.
	* opts.c (common_handle_option): Handle OPT_fuse_ld_.
	* gcc.c (driver_handle_option): Likewise.
	* collect2.c (main): Likewise.
---
 gcc/ChangeLog       |  8 ++++++
 gcc/collect2.c      | 67 ++++++++++++++++++++++++---------------------
 gcc/common.opt      | 14 ++--------
 gcc/doc/invoke.texi | 15 +++-------
 gcc/gcc.c           | 14 ++++------
 gcc/opts.c          |  4 +--
 6 files changed, 57 insertions(+), 65 deletions(-)

Comments

Li, Pan2 via Gcc-patches Feb. 13, 2020, 5:58 p.m. UTC | #1
On 2020-02-09, Fangrui Song wrote:
>	PR driver/93645
>	* common.opt (-fuse-ld=): Delete -fuse-ld=[bfd|gold|lld]. Add -fuse-ld=.
>	* opts.c (common_handle_option): Handle OPT_fuse_ld_.
>	* gcc.c (driver_handle_option): Likewise.
>	* collect2.c (main): Likewise.
>---
> gcc/ChangeLog       |  8 ++++++
> gcc/collect2.c      | 67 ++++++++++++++++++++++++---------------------
> gcc/common.opt      | 14 ++--------
> gcc/doc/invoke.texi | 15 +++-------
> gcc/gcc.c           | 14 ++++------
> gcc/opts.c          |  4 +--
> 6 files changed, 57 insertions(+), 65 deletions(-)
>
>diff --git a/gcc/ChangeLog b/gcc/ChangeLog
>index feb2d066d0b..6bcec12d841 100644
>--- a/gcc/ChangeLog
>+++ b/gcc/ChangeLog
>@@ -1,3 +1,11 @@
>+2020-02-09  Fangrui Song  <maskray@google.com>
>+
>+	PR driver/93645
>+	* common.opt (-fuse-ld=): Delete -fuse-ld=[bfd|gold|lld]. Add -fuse-ld=.
>+	* opts.c (common_handle_option): Handle OPT_fuse_ld_.
>+	* gcc.c (driver_handle_option): Likewise.
>+	* collect2.c (main): Likewise.
>+
> 2020-02-09  Uroš Bizjak  <ubizjak@gmail.com>
>
> 	* recog.c: Move pass_split_before_sched2 code in front of
>diff --git a/gcc/collect2.c b/gcc/collect2.c
>index 502d629141c..a3ef525a93b 100644
>--- a/gcc/collect2.c
>+++ b/gcc/collect2.c
>@@ -859,18 +859,12 @@ main (int argc, char **argv)
>     {
>       USE_DEFAULT_LD,
>       USE_PLUGIN_LD,
>-      USE_GOLD_LD,
>-      USE_BFD_LD,
>-      USE_LLD_LD,
>-      USE_LD_MAX
>+      USE_LD
>     } selected_linker = USE_DEFAULT_LD;
>-  static const char *const ld_suffixes[USE_LD_MAX] =
>+  static const char *const ld_suffixes[USE_LD] =
>     {
>       "ld",
>-      PLUGIN_LD_SUFFIX,
>-      "ld.gold",
>-      "ld.bfd",
>-      "ld.lld"
>+      PLUGIN_LD_SUFFIX
>     };
>   static const char *const real_ld_suffix = "real-ld";
>   static const char *const collect_ld_suffix = "collect-ld";
>@@ -882,7 +876,7 @@ main (int argc, char **argv)
>   static const char *const strip_suffix = "strip";
>   static const char *const gstrip_suffix = "gstrip";
>
>-  const char *full_ld_suffixes[USE_LD_MAX];
>+  const char *full_ld_suffixes[USE_LD];
> #ifdef CROSS_DIRECTORY_STRUCTURE
>   /* If we look for a program in the compiler directories, we just use
>      the short name, since these directories are already system-specific.
>@@ -924,6 +918,7 @@ main (int argc, char **argv)
>   const char **ld1;
>   bool use_plugin = false;
>   bool use_collect_ld = false;
>+  const char *use_ld = NULL;
>
>   /* The kinds of symbols we will have to consider when scanning the
>      outcome of a first pass link.  This is ALL to start with, then might
>@@ -948,7 +943,7 @@ main (int argc, char **argv)
> #endif
>   int i;
>
>-  for (i = 0; i < USE_LD_MAX; i++)
>+  for (i = 0; i < USE_LD; i++)
>     full_ld_suffixes[i]
> #ifdef CROSS_DIRECTORY_STRUCTURE
>       = concat (target_machine, "-", ld_suffixes[i], NULL);
>@@ -1041,12 +1036,11 @@ main (int argc, char **argv)
> 	    if (selected_linker == USE_DEFAULT_LD)
> 	      selected_linker = USE_PLUGIN_LD;
> 	  }
>-	else if (strcmp (argv[i], "-fuse-ld=bfd") == 0)
>-	  selected_linker = USE_BFD_LD;
>-	else if (strcmp (argv[i], "-fuse-ld=gold") == 0)
>-	  selected_linker = USE_GOLD_LD;
>-	else if (strcmp (argv[i], "-fuse-ld=lld") == 0)
>-	  selected_linker = USE_LLD_LD;
>+	else if (!strncmp (argv[i], "-fuse-ld=", 9))
>+	  {
>+	    use_ld = argv[i] + 9;
>+	    selected_linker = USE_LD;
>+	  }
> 	else if (strncmp (argv[i], "-o", 2) == 0)
> 	  {
> 	    /* Parse the output filename if it's given so that we can make
>@@ -1152,8 +1146,7 @@ main (int argc, char **argv)
>   /* Maybe we know the right file to use (if not cross).  */
>   ld_file_name = 0;
> #ifdef DEFAULT_LINKER
>-  if (selected_linker == USE_BFD_LD || selected_linker == USE_GOLD_LD ||
>-      selected_linker == USE_LLD_LD)
>+  if (!ld_file_name && selected_linker == USE_LD)
>     {
>       char *linker_name;
> # ifdef HOST_EXECUTABLE_SUFFIX
>@@ -1168,15 +1161,13 @@ main (int argc, char **argv)
> 	  if (! strcmp (&default_linker[len], HOST_EXECUTABLE_SUFFIX))
> 	    {
> 	      default_linker[len] = '\0';
>-	      linker_name = concat (default_linker,
>-				    &ld_suffixes[selected_linker][2],
>+	      linker_name = concat (default_linker, ".", use_ld,
> 				    HOST_EXECUTABLE_SUFFIX, NULL);
> 	    }
> 	}
>       if (linker_name == NULL)
> # endif
>-      linker_name = concat (DEFAULT_LINKER,
>-			    &ld_suffixes[selected_linker][2],
>+      linker_name = concat (DEFAULT_LINKER, ".", use_ld,
> 			    NULL);
>       if (access (linker_name, X_OK) == 0)
> 	ld_file_name = linker_name;
>@@ -1197,14 +1188,28 @@ main (int argc, char **argv)
>       ld_file_name = find_a_file (&cpath, collect_ld_suffix, X_OK);
>       use_collect_ld = ld_file_name != 0;
>     }
>-  /* Search the compiler directories for `ld'.  We have protection against
>-     recursive calls in find_a_file.  */
>-  if (ld_file_name == 0)
>-    ld_file_name = find_a_file (&cpath, ld_suffixes[selected_linker], X_OK);
>-  /* Search the ordinary system bin directories
>-     for `ld' (if native linking) or `TARGET-ld' (if cross).  */
>-  if (ld_file_name == 0)
>-    ld_file_name = find_a_file (&path, full_ld_suffixes[selected_linker], X_OK);
>+  if (selected_linker != USE_LD) {
>+    /* Search the compiler directories for `ld'.  We have protection against
>+       recursive calls in find_a_file.  */
>+    if (!ld_file_name)
>+      ld_file_name = find_a_file(&cpath, ld_suffixes[selected_linker], X_OK);
>+    /* Search the ordinary system bin directories
>+       for `ld' (if native linking) or `TARGET-ld' (if cross).  */
>+    if (!ld_file_name)
>+      ld_file_name = find_a_file(&path, full_ld_suffixes[selected_linker], X_OK);
>+  } else if (IS_ABSOLUTE_PATH(use_ld) && access(use_ld, X_OK) == 0) {
>+    ld_file_name = use_ld;
>+  } else {
>+    const char *linker_name = concat("ld.", use_ld, NULL);
>+    if (!ld_file_name)
>+      ld_file_name = find_a_file(&cpath, linker_name, X_OK);
>+    if (!ld_file_name) {
>+#ifdef CROSS_DIRECTORY_STRUCTURE
>+	linker_name = concat(target_machine, "-", linker_name, NULL);
>+#endif
>+	ld_file_name = find_a_file(&path, linker_name, X_OK);
>+    }
>+  }
>
> #ifdef REAL_NM_FILE_NAME
>   nm_file_name = find_a_file (&path, REAL_NM_FILE_NAME, X_OK);
>diff --git a/gcc/common.opt b/gcc/common.opt
>index 5692cd04374..a76ed6434bb 100644
>--- a/gcc/common.opt
>+++ b/gcc/common.opt
>@@ -2859,17 +2859,9 @@ funwind-tables
> Common Report Var(flag_unwind_tables) Optimization
> Just generate unwind tables for exception handling.
>
>-fuse-ld=bfd
>-Common Driver Negative(fuse-ld=gold)
>-Use the bfd linker instead of the default linker.
>-
>-fuse-ld=gold
>-Common Driver Negative(fuse-ld=bfd)
>-Use the gold linker instead of the default linker.
>-
>-fuse-ld=lld
>-Common Driver Negative(fuse-ld=lld)
>-Use the lld LLVM linker instead of the default linker.
>+fuse-ld=
>+Common Driver Joined
>+-fuse-ld=[bfd|gold|lld|<absolute path>]	Use the specified linker.
>
> fuse-linker-plugin
> Common Undocumented Var(flag_use_linker_plugin)
>diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
>index 35b341e759f..c2dd410c88f 100644
>--- a/gcc/doc/invoke.texi
>+++ b/gcc/doc/invoke.texi
>@@ -14128,17 +14128,10 @@ uses @samp{nolto-rel}. To maintain whole program optimization, it is
> recommended to link such objects into static library instead. Alternatively it
> is possible to use H.J. Lu's binutils with support for mixed objects.
>
>-@item -fuse-ld=bfd
>-@opindex fuse-ld=bfd
>-Use the @command{bfd} linker instead of the default linker.
>-
>-@item -fuse-ld=gold
>-@opindex fuse-ld=gold
>-Use the @command{gold} linker instead of the default linker.
>-
>-@item -fuse-ld=lld
>-@opindex fuse-ld=lld
>-Use the LLVM @command{lld} linker instead of the default linker.
>+@item -fuse-ld=@var{linker}
>+@opindex fuse-ld=linker
>+If @var{linker} is an absolute path, use it instead of the default linker;
>+otherwise use @command{ld.@var{linker}}.
>
> @cindex Libraries
> @item -l@var{library}
>diff --git a/gcc/gcc.c b/gcc/gcc.c
>index effc384f3ef..f9a6f10502d 100644
>--- a/gcc/gcc.c
>+++ b/gcc/gcc.c
>@@ -3989,12 +3989,8 @@ driver_handle_option (struct gcc_options *opts,
>       do_save = false;
>       break;
>
>-    case OPT_fuse_ld_bfd:
>-       use_ld = ".bfd";
>-       break;
>-
>-    case OPT_fuse_ld_gold:
>-       use_ld = ".gold";
>+    case OPT_fuse_ld_:
>+       use_ld = arg;
>        break;
>
>     case OPT_fcompare_debug_second:
>@@ -7903,20 +7899,20 @@ driver::maybe_print_and_exit () const
> 	      if (! strcmp (&default_linker[len], HOST_EXECUTABLE_SUFFIX))
> 		{
> 		  default_linker[len] = '\0';
>-		  ld = concat (default_linker, use_ld,
>+		  ld = concat (default_linker, ".", use_ld,
> 			       HOST_EXECUTABLE_SUFFIX, NULL);
> 		}
> 	    }
> 	  if (ld == NULL)
> # endif
>-	  ld = concat (DEFAULT_LINKER, use_ld, NULL);
>+	  ld = concat (DEFAULT_LINKER, ".", use_ld, NULL);
> 	  if (access (ld, X_OK) == 0)
> 	    {
> 	      printf ("%s\n", ld);
> 	      return (0);
> 	    }
> #endif
>-	  print_prog_name = concat (print_prog_name, use_ld, NULL);
>+	  print_prog_name = concat (print_prog_name, ".", use_ld, NULL);
> 	}
>       char *newname = find_a_file (&exec_prefixes, print_prog_name, X_OK, 0);
>       printf ("%s\n", (newname ? newname : print_prog_name));
>diff --git a/gcc/opts.c b/gcc/opts.c
>index 7affeb41a96..f50d365d517 100644
>--- a/gcc/opts.c
>+++ b/gcc/opts.c
>@@ -2763,9 +2763,7 @@ common_handle_option (struct gcc_options *opts,
>       dc->max_errors = value;
>       break;
>
>-    case OPT_fuse_ld_bfd:
>-    case OPT_fuse_ld_gold:
>-    case OPT_fuse_ld_lld:
>+    case OPT_fuse_ld_:
>     case OPT_fuse_linker_plugin:
>       /* No-op. Used by the driver and passed to us because it starts with f.*/
>       break;
>-- 
>2.25.0

Friendly ping:)
Li, Pan2 via Gcc-patches Feb. 24, 2020, 11:02 p.m. UTC | #2
On 2020-02-13, Fangrui Song wrote:
>On 2020-02-09, Fangrui Song wrote:
>>	PR driver/93645
>>	* common.opt (-fuse-ld=): Delete -fuse-ld=[bfd|gold|lld]. Add -fuse-ld=.
>>	* opts.c (common_handle_option): Handle OPT_fuse_ld_.
>>	* gcc.c (driver_handle_option): Likewise.
>>	* collect2.c (main): Likewise.
>>---
>>gcc/ChangeLog       |  8 ++++++
>>gcc/collect2.c      | 67 ++++++++++++++++++++++++---------------------
>>gcc/common.opt      | 14 ++--------
>>gcc/doc/invoke.texi | 15 +++-------
>>gcc/gcc.c           | 14 ++++------
>>gcc/opts.c          |  4 +--
>>6 files changed, 57 insertions(+), 65 deletions(-)
>>
>>diff --git a/gcc/ChangeLog b/gcc/ChangeLog
>>index feb2d066d0b..6bcec12d841 100644
>>--- a/gcc/ChangeLog
>>+++ b/gcc/ChangeLog
>>@@ -1,3 +1,11 @@
>>+2020-02-09  Fangrui Song  <maskray@google.com>
>>+
>>+	PR driver/93645
>>+	* common.opt (-fuse-ld=): Delete -fuse-ld=[bfd|gold|lld]. Add -fuse-ld=.
>>+	* opts.c (common_handle_option): Handle OPT_fuse_ld_.
>>+	* gcc.c (driver_handle_option): Likewise.
>>+	* collect2.c (main): Likewise.
>>+
>>2020-02-09  Uroš Bizjak  <ubizjak@gmail.com>
>>
>>	* recog.c: Move pass_split_before_sched2 code in front of
>>diff --git a/gcc/collect2.c b/gcc/collect2.c
>>index 502d629141c..a3ef525a93b 100644
>>--- a/gcc/collect2.c
>>+++ b/gcc/collect2.c
>>@@ -859,18 +859,12 @@ main (int argc, char **argv)
>>    {
>>      USE_DEFAULT_LD,
>>      USE_PLUGIN_LD,
>>-      USE_GOLD_LD,
>>-      USE_BFD_LD,
>>-      USE_LLD_LD,
>>-      USE_LD_MAX
>>+      USE_LD
>>    } selected_linker = USE_DEFAULT_LD;
>>-  static const char *const ld_suffixes[USE_LD_MAX] =
>>+  static const char *const ld_suffixes[USE_LD] =
>>    {
>>      "ld",
>>-      PLUGIN_LD_SUFFIX,
>>-      "ld.gold",
>>-      "ld.bfd",
>>-      "ld.lld"
>>+      PLUGIN_LD_SUFFIX
>>    };
>>  static const char *const real_ld_suffix = "real-ld";
>>  static const char *const collect_ld_suffix = "collect-ld";
>>@@ -882,7 +876,7 @@ main (int argc, char **argv)
>>  static const char *const strip_suffix = "strip";
>>  static const char *const gstrip_suffix = "gstrip";
>>
>>-  const char *full_ld_suffixes[USE_LD_MAX];
>>+  const char *full_ld_suffixes[USE_LD];
>>#ifdef CROSS_DIRECTORY_STRUCTURE
>>  /* If we look for a program in the compiler directories, we just use
>>     the short name, since these directories are already system-specific.
>>@@ -924,6 +918,7 @@ main (int argc, char **argv)
>>  const char **ld1;
>>  bool use_plugin = false;
>>  bool use_collect_ld = false;
>>+  const char *use_ld = NULL;
>>
>>  /* The kinds of symbols we will have to consider when scanning the
>>     outcome of a first pass link.  This is ALL to start with, then might
>>@@ -948,7 +943,7 @@ main (int argc, char **argv)
>>#endif
>>  int i;
>>
>>-  for (i = 0; i < USE_LD_MAX; i++)
>>+  for (i = 0; i < USE_LD; i++)
>>    full_ld_suffixes[i]
>>#ifdef CROSS_DIRECTORY_STRUCTURE
>>      = concat (target_machine, "-", ld_suffixes[i], NULL);
>>@@ -1041,12 +1036,11 @@ main (int argc, char **argv)
>>	    if (selected_linker == USE_DEFAULT_LD)
>>	      selected_linker = USE_PLUGIN_LD;
>>	  }
>>-	else if (strcmp (argv[i], "-fuse-ld=bfd") == 0)
>>-	  selected_linker = USE_BFD_LD;
>>-	else if (strcmp (argv[i], "-fuse-ld=gold") == 0)
>>-	  selected_linker = USE_GOLD_LD;
>>-	else if (strcmp (argv[i], "-fuse-ld=lld") == 0)
>>-	  selected_linker = USE_LLD_LD;
>>+	else if (!strncmp (argv[i], "-fuse-ld=", 9))
>>+	  {
>>+	    use_ld = argv[i] + 9;
>>+	    selected_linker = USE_LD;
>>+	  }
>>	else if (strncmp (argv[i], "-o", 2) == 0)
>>	  {
>>	    /* Parse the output filename if it's given so that we can make
>>@@ -1152,8 +1146,7 @@ main (int argc, char **argv)
>>  /* Maybe we know the right file to use (if not cross).  */
>>  ld_file_name = 0;
>>#ifdef DEFAULT_LINKER
>>-  if (selected_linker == USE_BFD_LD || selected_linker == USE_GOLD_LD ||
>>-      selected_linker == USE_LLD_LD)
>>+  if (!ld_file_name && selected_linker == USE_LD)
>>    {
>>      char *linker_name;
>># ifdef HOST_EXECUTABLE_SUFFIX
>>@@ -1168,15 +1161,13 @@ main (int argc, char **argv)
>>	  if (! strcmp (&default_linker[len], HOST_EXECUTABLE_SUFFIX))
>>	    {
>>	      default_linker[len] = '\0';
>>-	      linker_name = concat (default_linker,
>>-				    &ld_suffixes[selected_linker][2],
>>+	      linker_name = concat (default_linker, ".", use_ld,
>>				    HOST_EXECUTABLE_SUFFIX, NULL);
>>	    }
>>	}
>>      if (linker_name == NULL)
>># endif
>>-      linker_name = concat (DEFAULT_LINKER,
>>-			    &ld_suffixes[selected_linker][2],
>>+      linker_name = concat (DEFAULT_LINKER, ".", use_ld,
>>			    NULL);
>>      if (access (linker_name, X_OK) == 0)
>>	ld_file_name = linker_name;
>>@@ -1197,14 +1188,28 @@ main (int argc, char **argv)
>>      ld_file_name = find_a_file (&cpath, collect_ld_suffix, X_OK);
>>      use_collect_ld = ld_file_name != 0;
>>    }
>>-  /* Search the compiler directories for `ld'.  We have protection against
>>-     recursive calls in find_a_file.  */
>>-  if (ld_file_name == 0)
>>-    ld_file_name = find_a_file (&cpath, ld_suffixes[selected_linker], X_OK);
>>-  /* Search the ordinary system bin directories
>>-     for `ld' (if native linking) or `TARGET-ld' (if cross).  */
>>-  if (ld_file_name == 0)
>>-    ld_file_name = find_a_file (&path, full_ld_suffixes[selected_linker], X_OK);
>>+  if (selected_linker != USE_LD) {
>>+    /* Search the compiler directories for `ld'.  We have protection against
>>+       recursive calls in find_a_file.  */
>>+    if (!ld_file_name)
>>+      ld_file_name = find_a_file(&cpath, ld_suffixes[selected_linker], X_OK);
>>+    /* Search the ordinary system bin directories
>>+       for `ld' (if native linking) or `TARGET-ld' (if cross).  */
>>+    if (!ld_file_name)
>>+      ld_file_name = find_a_file(&path, full_ld_suffixes[selected_linker], X_OK);
>>+  } else if (IS_ABSOLUTE_PATH(use_ld) && access(use_ld, X_OK) == 0) {
>>+    ld_file_name = use_ld;
>>+  } else {
>>+    const char *linker_name = concat("ld.", use_ld, NULL);
>>+    if (!ld_file_name)
>>+      ld_file_name = find_a_file(&cpath, linker_name, X_OK);
>>+    if (!ld_file_name) {
>>+#ifdef CROSS_DIRECTORY_STRUCTURE
>>+	linker_name = concat(target_machine, "-", linker_name, NULL);
>>+#endif
>>+	ld_file_name = find_a_file(&path, linker_name, X_OK);
>>+    }
>>+  }
>>
>>#ifdef REAL_NM_FILE_NAME
>>  nm_file_name = find_a_file (&path, REAL_NM_FILE_NAME, X_OK);
>>diff --git a/gcc/common.opt b/gcc/common.opt
>>index 5692cd04374..a76ed6434bb 100644
>>--- a/gcc/common.opt
>>+++ b/gcc/common.opt
>>@@ -2859,17 +2859,9 @@ funwind-tables
>>Common Report Var(flag_unwind_tables) Optimization
>>Just generate unwind tables for exception handling.
>>
>>-fuse-ld=bfd
>>-Common Driver Negative(fuse-ld=gold)
>>-Use the bfd linker instead of the default linker.
>>-
>>-fuse-ld=gold
>>-Common Driver Negative(fuse-ld=bfd)
>>-Use the gold linker instead of the default linker.
>>-
>>-fuse-ld=lld
>>-Common Driver Negative(fuse-ld=lld)
>>-Use the lld LLVM linker instead of the default linker.
>>+fuse-ld=
>>+Common Driver Joined
>>+-fuse-ld=[bfd|gold|lld|<absolute path>]	Use the specified linker.
>>
>>fuse-linker-plugin
>>Common Undocumented Var(flag_use_linker_plugin)
>>diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
>>index 35b341e759f..c2dd410c88f 100644
>>--- a/gcc/doc/invoke.texi
>>+++ b/gcc/doc/invoke.texi
>>@@ -14128,17 +14128,10 @@ uses @samp{nolto-rel}. To maintain whole program optimization, it is
>>recommended to link such objects into static library instead. Alternatively it
>>is possible to use H.J. Lu's binutils with support for mixed objects.
>>
>>-@item -fuse-ld=bfd
>>-@opindex fuse-ld=bfd
>>-Use the @command{bfd} linker instead of the default linker.
>>-
>>-@item -fuse-ld=gold
>>-@opindex fuse-ld=gold
>>-Use the @command{gold} linker instead of the default linker.
>>-
>>-@item -fuse-ld=lld
>>-@opindex fuse-ld=lld
>>-Use the LLVM @command{lld} linker instead of the default linker.
>>+@item -fuse-ld=@var{linker}
>>+@opindex fuse-ld=linker
>>+If @var{linker} is an absolute path, use it instead of the default linker;
>>+otherwise use @command{ld.@var{linker}}.
>>
>>@cindex Libraries
>>@item -l@var{library}
>>diff --git a/gcc/gcc.c b/gcc/gcc.c
>>index effc384f3ef..f9a6f10502d 100644
>>--- a/gcc/gcc.c
>>+++ b/gcc/gcc.c
>>@@ -3989,12 +3989,8 @@ driver_handle_option (struct gcc_options *opts,
>>      do_save = false;
>>      break;
>>
>>-    case OPT_fuse_ld_bfd:
>>-       use_ld = ".bfd";
>>-       break;
>>-
>>-    case OPT_fuse_ld_gold:
>>-       use_ld = ".gold";
>>+    case OPT_fuse_ld_:
>>+       use_ld = arg;
>>       break;
>>
>>    case OPT_fcompare_debug_second:
>>@@ -7903,20 +7899,20 @@ driver::maybe_print_and_exit () const
>>	      if (! strcmp (&default_linker[len], HOST_EXECUTABLE_SUFFIX))
>>		{
>>		  default_linker[len] = '\0';
>>-		  ld = concat (default_linker, use_ld,
>>+		  ld = concat (default_linker, ".", use_ld,
>>			       HOST_EXECUTABLE_SUFFIX, NULL);
>>		}
>>	    }
>>	  if (ld == NULL)
>># endif
>>-	  ld = concat (DEFAULT_LINKER, use_ld, NULL);
>>+	  ld = concat (DEFAULT_LINKER, ".", use_ld, NULL);
>>	  if (access (ld, X_OK) == 0)
>>	    {
>>	      printf ("%s\n", ld);
>>	      return (0);
>>	    }
>>#endif
>>-	  print_prog_name = concat (print_prog_name, use_ld, NULL);
>>+	  print_prog_name = concat (print_prog_name, ".", use_ld, NULL);
>>	}
>>      char *newname = find_a_file (&exec_prefixes, print_prog_name, X_OK, 0);
>>      printf ("%s\n", (newname ? newname : print_prog_name));
>>diff --git a/gcc/opts.c b/gcc/opts.c
>>index 7affeb41a96..f50d365d517 100644
>>--- a/gcc/opts.c
>>+++ b/gcc/opts.c
>>@@ -2763,9 +2763,7 @@ common_handle_option (struct gcc_options *opts,
>>      dc->max_errors = value;
>>      break;
>>
>>-    case OPT_fuse_ld_bfd:
>>-    case OPT_fuse_ld_gold:
>>-    case OPT_fuse_ld_lld:
>>+    case OPT_fuse_ld_:
>>    case OPT_fuse_linker_plugin:
>>      /* No-op. Used by the driver and passed to us because it starts with f.*/
>>      break;
>>-- 
>>2.25.0
>
>Friendly ping:)

Patch ping https://gcc.gnu.org/ml/gcc-patches/2020-02/msg00510.html
Li, Pan2 via Gcc-patches March 10, 2020, 5:19 p.m. UTC | #3
On 2020-02-24, Fangrui Song wrote:
>On 2020-02-13, Fangrui Song wrote:
>>On 2020-02-09, Fangrui Song wrote:
>>>	PR driver/93645
>>>	* common.opt (-fuse-ld=): Delete -fuse-ld=[bfd|gold|lld]. Add -fuse-ld=.
>>>	* opts.c (common_handle_option): Handle OPT_fuse_ld_.
>>>	* gcc.c (driver_handle_option): Likewise.
>>>	* collect2.c (main): Likewise.
>>>---
>>>gcc/ChangeLog       |  8 ++++++
>>>gcc/collect2.c      | 67 ++++++++++++++++++++++++---------------------
>>>gcc/common.opt      | 14 ++--------
>>>gcc/doc/invoke.texi | 15 +++-------
>>>gcc/gcc.c           | 14 ++++------
>>>gcc/opts.c          |  4 +--
>>>6 files changed, 57 insertions(+), 65 deletions(-)
>>>
>>>diff --git a/gcc/ChangeLog b/gcc/ChangeLog
>>>index feb2d066d0b..6bcec12d841 100644
>>>--- a/gcc/ChangeLog
>>>+++ b/gcc/ChangeLog
>>>@@ -1,3 +1,11 @@
>>>+2020-02-09  Fangrui Song  <maskray@google.com>
>>>+
>>>+	PR driver/93645
>>>+	* common.opt (-fuse-ld=): Delete -fuse-ld=[bfd|gold|lld]. Add -fuse-ld=.
>>>+	* opts.c (common_handle_option): Handle OPT_fuse_ld_.
>>>+	* gcc.c (driver_handle_option): Likewise.
>>>+	* collect2.c (main): Likewise.
>>>+
>>>2020-02-09  Uroš Bizjak  <ubizjak@gmail.com>
>>>
>>>	* recog.c: Move pass_split_before_sched2 code in front of
>>>diff --git a/gcc/collect2.c b/gcc/collect2.c
>>>index 502d629141c..a3ef525a93b 100644
>>>--- a/gcc/collect2.c
>>>+++ b/gcc/collect2.c
>>>@@ -859,18 +859,12 @@ main (int argc, char **argv)
>>>   {
>>>     USE_DEFAULT_LD,
>>>     USE_PLUGIN_LD,
>>>-      USE_GOLD_LD,
>>>-      USE_BFD_LD,
>>>-      USE_LLD_LD,
>>>-      USE_LD_MAX
>>>+      USE_LD
>>>   } selected_linker = USE_DEFAULT_LD;
>>>-  static const char *const ld_suffixes[USE_LD_MAX] =
>>>+  static const char *const ld_suffixes[USE_LD] =
>>>   {
>>>     "ld",
>>>-      PLUGIN_LD_SUFFIX,
>>>-      "ld.gold",
>>>-      "ld.bfd",
>>>-      "ld.lld"
>>>+      PLUGIN_LD_SUFFIX
>>>   };
>>> static const char *const real_ld_suffix = "real-ld";
>>> static const char *const collect_ld_suffix = "collect-ld";
>>>@@ -882,7 +876,7 @@ main (int argc, char **argv)
>>> static const char *const strip_suffix = "strip";
>>> static const char *const gstrip_suffix = "gstrip";
>>>
>>>-  const char *full_ld_suffixes[USE_LD_MAX];
>>>+  const char *full_ld_suffixes[USE_LD];
>>>#ifdef CROSS_DIRECTORY_STRUCTURE
>>> /* If we look for a program in the compiler directories, we just use
>>>    the short name, since these directories are already system-specific.
>>>@@ -924,6 +918,7 @@ main (int argc, char **argv)
>>> const char **ld1;
>>> bool use_plugin = false;
>>> bool use_collect_ld = false;
>>>+  const char *use_ld = NULL;
>>>
>>> /* The kinds of symbols we will have to consider when scanning the
>>>    outcome of a first pass link.  This is ALL to start with, then might
>>>@@ -948,7 +943,7 @@ main (int argc, char **argv)
>>>#endif
>>> int i;
>>>
>>>-  for (i = 0; i < USE_LD_MAX; i++)
>>>+  for (i = 0; i < USE_LD; i++)
>>>   full_ld_suffixes[i]
>>>#ifdef CROSS_DIRECTORY_STRUCTURE
>>>     = concat (target_machine, "-", ld_suffixes[i], NULL);
>>>@@ -1041,12 +1036,11 @@ main (int argc, char **argv)
>>>	    if (selected_linker == USE_DEFAULT_LD)
>>>	      selected_linker = USE_PLUGIN_LD;
>>>	  }
>>>-	else if (strcmp (argv[i], "-fuse-ld=bfd") == 0)
>>>-	  selected_linker = USE_BFD_LD;
>>>-	else if (strcmp (argv[i], "-fuse-ld=gold") == 0)
>>>-	  selected_linker = USE_GOLD_LD;
>>>-	else if (strcmp (argv[i], "-fuse-ld=lld") == 0)
>>>-	  selected_linker = USE_LLD_LD;
>>>+	else if (!strncmp (argv[i], "-fuse-ld=", 9))
>>>+	  {
>>>+	    use_ld = argv[i] + 9;
>>>+	    selected_linker = USE_LD;
>>>+	  }
>>>	else if (strncmp (argv[i], "-o", 2) == 0)
>>>	  {
>>>	    /* Parse the output filename if it's given so that we can make
>>>@@ -1152,8 +1146,7 @@ main (int argc, char **argv)
>>> /* Maybe we know the right file to use (if not cross).  */
>>> ld_file_name = 0;
>>>#ifdef DEFAULT_LINKER
>>>-  if (selected_linker == USE_BFD_LD || selected_linker == USE_GOLD_LD ||
>>>-      selected_linker == USE_LLD_LD)
>>>+  if (!ld_file_name && selected_linker == USE_LD)
>>>   {
>>>     char *linker_name;
>>># ifdef HOST_EXECUTABLE_SUFFIX
>>>@@ -1168,15 +1161,13 @@ main (int argc, char **argv)
>>>	  if (! strcmp (&default_linker[len], HOST_EXECUTABLE_SUFFIX))
>>>	    {
>>>	      default_linker[len] = '\0';
>>>-	      linker_name = concat (default_linker,
>>>-				    &ld_suffixes[selected_linker][2],
>>>+	      linker_name = concat (default_linker, ".", use_ld,
>>>				    HOST_EXECUTABLE_SUFFIX, NULL);
>>>	    }
>>>	}
>>>     if (linker_name == NULL)
>>># endif
>>>-      linker_name = concat (DEFAULT_LINKER,
>>>-			    &ld_suffixes[selected_linker][2],
>>>+      linker_name = concat (DEFAULT_LINKER, ".", use_ld,
>>>			    NULL);
>>>     if (access (linker_name, X_OK) == 0)
>>>	ld_file_name = linker_name;
>>>@@ -1197,14 +1188,28 @@ main (int argc, char **argv)
>>>     ld_file_name = find_a_file (&cpath, collect_ld_suffix, X_OK);
>>>     use_collect_ld = ld_file_name != 0;
>>>   }
>>>-  /* Search the compiler directories for `ld'.  We have protection against
>>>-     recursive calls in find_a_file.  */
>>>-  if (ld_file_name == 0)
>>>-    ld_file_name = find_a_file (&cpath, ld_suffixes[selected_linker], X_OK);
>>>-  /* Search the ordinary system bin directories
>>>-     for `ld' (if native linking) or `TARGET-ld' (if cross).  */
>>>-  if (ld_file_name == 0)
>>>-    ld_file_name = find_a_file (&path, full_ld_suffixes[selected_linker], X_OK);
>>>+  if (selected_linker != USE_LD) {
>>>+    /* Search the compiler directories for `ld'.  We have protection against
>>>+       recursive calls in find_a_file.  */
>>>+    if (!ld_file_name)
>>>+      ld_file_name = find_a_file(&cpath, ld_suffixes[selected_linker], X_OK);
>>>+    /* Search the ordinary system bin directories
>>>+       for `ld' (if native linking) or `TARGET-ld' (if cross).  */
>>>+    if (!ld_file_name)
>>>+      ld_file_name = find_a_file(&path, full_ld_suffixes[selected_linker], X_OK);
>>>+  } else if (IS_ABSOLUTE_PATH(use_ld) && access(use_ld, X_OK) == 0) {
>>>+    ld_file_name = use_ld;
>>>+  } else {
>>>+    const char *linker_name = concat("ld.", use_ld, NULL);
>>>+    if (!ld_file_name)
>>>+      ld_file_name = find_a_file(&cpath, linker_name, X_OK);
>>>+    if (!ld_file_name) {
>>>+#ifdef CROSS_DIRECTORY_STRUCTURE
>>>+	linker_name = concat(target_machine, "-", linker_name, NULL);
>>>+#endif
>>>+	ld_file_name = find_a_file(&path, linker_name, X_OK);
>>>+    }
>>>+  }
>>>
>>>#ifdef REAL_NM_FILE_NAME
>>> nm_file_name = find_a_file (&path, REAL_NM_FILE_NAME, X_OK);
>>>diff --git a/gcc/common.opt b/gcc/common.opt
>>>index 5692cd04374..a76ed6434bb 100644
>>>--- a/gcc/common.opt
>>>+++ b/gcc/common.opt
>>>@@ -2859,17 +2859,9 @@ funwind-tables
>>>Common Report Var(flag_unwind_tables) Optimization
>>>Just generate unwind tables for exception handling.
>>>
>>>-fuse-ld=bfd
>>>-Common Driver Negative(fuse-ld=gold)
>>>-Use the bfd linker instead of the default linker.
>>>-
>>>-fuse-ld=gold
>>>-Common Driver Negative(fuse-ld=bfd)
>>>-Use the gold linker instead of the default linker.
>>>-
>>>-fuse-ld=lld
>>>-Common Driver Negative(fuse-ld=lld)
>>>-Use the lld LLVM linker instead of the default linker.
>>>+fuse-ld=
>>>+Common Driver Joined
>>>+-fuse-ld=[bfd|gold|lld|<absolute path>]	Use the specified linker.
>>>
>>>fuse-linker-plugin
>>>Common Undocumented Var(flag_use_linker_plugin)
>>>diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
>>>index 35b341e759f..c2dd410c88f 100644
>>>--- a/gcc/doc/invoke.texi
>>>+++ b/gcc/doc/invoke.texi
>>>@@ -14128,17 +14128,10 @@ uses @samp{nolto-rel}. To maintain whole program optimization, it is
>>>recommended to link such objects into static library instead. Alternatively it
>>>is possible to use H.J. Lu's binutils with support for mixed objects.
>>>
>>>-@item -fuse-ld=bfd
>>>-@opindex fuse-ld=bfd
>>>-Use the @command{bfd} linker instead of the default linker.
>>>-
>>>-@item -fuse-ld=gold
>>>-@opindex fuse-ld=gold
>>>-Use the @command{gold} linker instead of the default linker.
>>>-
>>>-@item -fuse-ld=lld
>>>-@opindex fuse-ld=lld
>>>-Use the LLVM @command{lld} linker instead of the default linker.
>>>+@item -fuse-ld=@var{linker}
>>>+@opindex fuse-ld=linker
>>>+If @var{linker} is an absolute path, use it instead of the default linker;
>>>+otherwise use @command{ld.@var{linker}}.
>>>
>>>@cindex Libraries
>>>@item -l@var{library}
>>>diff --git a/gcc/gcc.c b/gcc/gcc.c
>>>index effc384f3ef..f9a6f10502d 100644
>>>--- a/gcc/gcc.c
>>>+++ b/gcc/gcc.c
>>>@@ -3989,12 +3989,8 @@ driver_handle_option (struct gcc_options *opts,
>>>     do_save = false;
>>>     break;
>>>
>>>-    case OPT_fuse_ld_bfd:
>>>-       use_ld = ".bfd";
>>>-       break;
>>>-
>>>-    case OPT_fuse_ld_gold:
>>>-       use_ld = ".gold";
>>>+    case OPT_fuse_ld_:
>>>+       use_ld = arg;
>>>      break;
>>>
>>>   case OPT_fcompare_debug_second:
>>>@@ -7903,20 +7899,20 @@ driver::maybe_print_and_exit () const
>>>	      if (! strcmp (&default_linker[len], HOST_EXECUTABLE_SUFFIX))
>>>		{
>>>		  default_linker[len] = '\0';
>>>-		  ld = concat (default_linker, use_ld,
>>>+		  ld = concat (default_linker, ".", use_ld,
>>>			       HOST_EXECUTABLE_SUFFIX, NULL);
>>>		}
>>>	    }
>>>	  if (ld == NULL)
>>># endif
>>>-	  ld = concat (DEFAULT_LINKER, use_ld, NULL);
>>>+	  ld = concat (DEFAULT_LINKER, ".", use_ld, NULL);
>>>	  if (access (ld, X_OK) == 0)
>>>	    {
>>>	      printf ("%s\n", ld);
>>>	      return (0);
>>>	    }
>>>#endif
>>>-	  print_prog_name = concat (print_prog_name, use_ld, NULL);
>>>+	  print_prog_name = concat (print_prog_name, ".", use_ld, NULL);
>>>	}
>>>     char *newname = find_a_file (&exec_prefixes, print_prog_name, X_OK, 0);
>>>     printf ("%s\n", (newname ? newname : print_prog_name));
>>>diff --git a/gcc/opts.c b/gcc/opts.c
>>>index 7affeb41a96..f50d365d517 100644
>>>--- a/gcc/opts.c
>>>+++ b/gcc/opts.c
>>>@@ -2763,9 +2763,7 @@ common_handle_option (struct gcc_options *opts,
>>>     dc->max_errors = value;
>>>     break;
>>>
>>>-    case OPT_fuse_ld_bfd:
>>>-    case OPT_fuse_ld_gold:
>>>-    case OPT_fuse_ld_lld:
>>>+    case OPT_fuse_ld_:
>>>   case OPT_fuse_linker_plugin:
>>>     /* No-op. Used by the driver and passed to us because it starts with f.*/
>>>     break;
>>>-- 
>>>2.25.0
>>
>>Friendly ping:)
>
>Patch ping https://gcc.gnu.org/ml/gcc-patches/2020-02/msg00510.html

Friendly ping https://gcc.gnu.org/ml/gcc-patches/2020-02/msg00510.html
Martin Liška March 11, 2020, 12:55 p.m. UTC | #4
On 2/10/20 1:02 AM, Fangrui Song via gcc-patches wrote:

Hello.

Thank you for the patch. You haven't received a review because we are right now
in stage4 of the development cycle:
https://gcc.gnu.org/develop.html#stage4

Anyway, I'm going to provide a review (even though I'm not maintainer of that).

Can you please describe your test-case why you need such option? When using
a different ld, I typically export PATH=/path/to/binutils and then run configure
and make.

I noticed not ideal error message:

$ gcc -fuse-ld=pes /tmp/foo.c
collect2: fatal error: cannot find ‘ld’
compilation terminated.

while clang prints:

$clang -fuse-ld=pes /tmp/foo.c
clang-9.0: error: invalid linker name in argument '-fuse-ld=pes'

The rest of the patch is comment inline...

> 	PR driver/93645
> 	* common.opt (-fuse-ld=): Delete -fuse-ld=[bfd|gold|lld]. Add -fuse-ld=.
> 	* opts.c (common_handle_option): Handle OPT_fuse_ld_.
> 	* gcc.c (driver_handle_option): Likewise.
> 	* collect2.c (main): Likewise.
> ---
>   gcc/ChangeLog       |  8 ++++++
>   gcc/collect2.c      | 67 ++++++++++++++++++++++++---------------------
>   gcc/common.opt      | 14 ++--------
>   gcc/doc/invoke.texi | 15 +++-------
>   gcc/gcc.c           | 14 ++++------
>   gcc/opts.c          |  4 +--
>   6 files changed, 57 insertions(+), 65 deletions(-)
> 
> diff --git a/gcc/ChangeLog b/gcc/ChangeLog
> index feb2d066d0b..6bcec12d841 100644
> --- a/gcc/ChangeLog
> +++ b/gcc/ChangeLog
> @@ -1,3 +1,11 @@
> +2020-02-09  Fangrui Song  <maskray@google.com>
> +
> +	PR driver/93645
> +	* common.opt (-fuse-ld=): Delete -fuse-ld=[bfd|gold|lld]. Add -fuse-ld=.
> +	* opts.c (common_handle_option): Handle OPT_fuse_ld_.
> +	* gcc.c (driver_handle_option): Likewise.
> +	* collect2.c (main): Likewise.
> +
>   2020-02-09  Uroš Bizjak  <ubizjak@gmail.com>
>   
>   	* recog.c: Move pass_split_before_sched2 code in front of
> diff --git a/gcc/collect2.c b/gcc/collect2.c
> index 502d629141c..a3ef525a93b 100644
> --- a/gcc/collect2.c
> +++ b/gcc/collect2.c
> @@ -859,18 +859,12 @@ main (int argc, char **argv)
>       {
>         USE_DEFAULT_LD,
>         USE_PLUGIN_LD,
> -      USE_GOLD_LD,
> -      USE_BFD_LD,
> -      USE_LLD_LD,
> -      USE_LD_MAX
> +      USE_LD
>       } selected_linker = USE_DEFAULT_LD;
> -  static const char *const ld_suffixes[USE_LD_MAX] =
> +  static const char *const ld_suffixes[USE_LD] =
>       {
>         "ld",
> -      PLUGIN_LD_SUFFIX,
> -      "ld.gold",
> -      "ld.bfd",
> -      "ld.lld"
> +      PLUGIN_LD_SUFFIX
>       };
>     static const char *const real_ld_suffix = "real-ld";
>     static const char *const collect_ld_suffix = "collect-ld";
> @@ -882,7 +876,7 @@ main (int argc, char **argv)
>     static const char *const strip_suffix = "strip";
>     static const char *const gstrip_suffix = "gstrip";
>   
> -  const char *full_ld_suffixes[USE_LD_MAX];
> +  const char *full_ld_suffixes[USE_LD];
>   #ifdef CROSS_DIRECTORY_STRUCTURE
>     /* If we look for a program in the compiler directories, we just use
>        the short name, since these directories are already system-specific.
> @@ -924,6 +918,7 @@ main (int argc, char **argv)
>     const char **ld1;
>     bool use_plugin = false;
>     bool use_collect_ld = false;
> +  const char *use_ld = NULL;
>   
>     /* The kinds of symbols we will have to consider when scanning the
>        outcome of a first pass link.  This is ALL to start with, then might
> @@ -948,7 +943,7 @@ main (int argc, char **argv)
>   #endif
>     int i;
>   
> -  for (i = 0; i < USE_LD_MAX; i++)
> +  for (i = 0; i < USE_LD; i++)
>       full_ld_suffixes[i]
>   #ifdef CROSS_DIRECTORY_STRUCTURE
>         = concat (target_machine, "-", ld_suffixes[i], NULL);
> @@ -1041,12 +1036,11 @@ main (int argc, char **argv)
>   	    if (selected_linker == USE_DEFAULT_LD)
>   	      selected_linker = USE_PLUGIN_LD;
>   	  }
> -	else if (strcmp (argv[i], "-fuse-ld=bfd") == 0)
> -	  selected_linker = USE_BFD_LD;
> -	else if (strcmp (argv[i], "-fuse-ld=gold") == 0)
> -	  selected_linker = USE_GOLD_LD;
> -	else if (strcmp (argv[i], "-fuse-ld=lld") == 0)
> -	  selected_linker = USE_LLD_LD;
> +	else if (!strncmp (argv[i], "-fuse-ld=", 9))
> +	  {
> +	    use_ld = argv[i] + 9;
> +	    selected_linker = USE_LD;
> +	  }
>   	else if (strncmp (argv[i], "-o", 2) == 0)
>   	  {
>   	    /* Parse the output filename if it's given so that we can make
> @@ -1152,8 +1146,7 @@ main (int argc, char **argv)
>     /* Maybe we know the right file to use (if not cross).  */
>     ld_file_name = 0;
>   #ifdef DEFAULT_LINKER
> -  if (selected_linker == USE_BFD_LD || selected_linker == USE_GOLD_LD ||
> -      selected_linker == USE_LLD_LD)
> +  if (!ld_file_name && selected_linker == USE_LD)
>       {
>         char *linker_name;
>   # ifdef HOST_EXECUTABLE_SUFFIX
> @@ -1168,15 +1161,13 @@ main (int argc, char **argv)
>   	  if (! strcmp (&default_linker[len], HOST_EXECUTABLE_SUFFIX))
>   	    {
>   	      default_linker[len] = '\0';
> -	      linker_name = concat (default_linker,
> -				    &ld_suffixes[selected_linker][2],
> +	      linker_name = concat (default_linker, ".", use_ld,
>   				    HOST_EXECUTABLE_SUFFIX, NULL);
>   	    }
>   	}
>         if (linker_name == NULL)
>   # endif
> -      linker_name = concat (DEFAULT_LINKER,
> -			    &ld_suffixes[selected_linker][2],
> +      linker_name = concat (DEFAULT_LINKER, ".", use_ld,
>   			    NULL);
>         if (access (linker_name, X_OK) == 0)
>   	ld_file_name = linker_name;
> @@ -1197,14 +1188,28 @@ main (int argc, char **argv)
>         ld_file_name = find_a_file (&cpath, collect_ld_suffix, X_OK);
>         use_collect_ld = ld_file_name != 0;
>       }
> -  /* Search the compiler directories for `ld'.  We have protection against
> -     recursive calls in find_a_file.  */
> -  if (ld_file_name == 0)
> -    ld_file_name = find_a_file (&cpath, ld_suffixes[selected_linker], X_OK);
> -  /* Search the ordinary system bin directories
> -     for `ld' (if native linking) or `TARGET-ld' (if cross).  */
> -  if (ld_file_name == 0)
> -    ld_file_name = find_a_file (&path, full_ld_suffixes[selected_linker], X_OK);
> +  if (selected_linker != USE_LD) {
> +    /* Search the compiler directories for `ld'.  We have protection against
> +       recursive calls in find_a_file.  */
> +    if (!ld_file_name)
> +      ld_file_name = find_a_file(&cpath, ld_suffixes[selected_linker], X_OK);
> +    /* Search the ordinary system bin directories
> +       for `ld' (if native linking) or `TARGET-ld' (if cross).  */
> +    if (!ld_file_name)
> +      ld_file_name = find_a_file(&path, full_ld_suffixes[selected_linker], X_OK);
> +  } else if (IS_ABSOLUTE_PATH(use_ld) && access(use_ld, X_OK) == 0) {
> +    ld_file_name = use_ld;
> +  } else {
> +    const char *linker_name = concat("ld.", use_ld, NULL);

This leads to strange searches like:

$ strace -f -s512 gcc -fuse-ld=/x/y/z/pes /tmp/foo.c 2>&1 | grep pes
...
[pid 24295] stat("/home/marxin/bin/ld./x/y/z/pes", 0x7fffffffd1f0) = -1 ENOENT (No such file or directory)
[pid 24295] stat("/usr/local/bin/ld./x/y/z/pes", 0x7fffffffd1f0) = -1 ENOENT (No such file or directory)

Moreover, before the patch we only searched for suffixes 'ld.bfd', 'ld.gold' and 'ld.gold'. Now it
searches also for:

$ strace ... gcc -fuse-ld=xyz
...
[pid 24893] stat("/home/marxin/bin/ld.xyz", 0x7fffffffd200) = -1 ENOENT (No such file or directory)

> +    if (!ld_file_name)
> +      ld_file_name = find_a_file(&cpath, linker_name, X_OK);
> +    if (!ld_file_name) {
> +#ifdef CROSS_DIRECTORY_STRUCTURE
> +	linker_name = concat(target_machine, "-", linker_name, NULL);
> +#endif
> +	ld_file_name = find_a_file(&path, linker_name, X_OK);
> +    }
> +  }
>   
>   #ifdef REAL_NM_FILE_NAME
>     nm_file_name = find_a_file (&path, REAL_NM_FILE_NAME, X_OK);
> diff --git a/gcc/common.opt b/gcc/common.opt
> index 5692cd04374..a76ed6434bb 100644
> --- a/gcc/common.opt
> +++ b/gcc/common.opt
> @@ -2859,17 +2859,9 @@ funwind-tables
>   Common Report Var(flag_unwind_tables) Optimization
>   Just generate unwind tables for exception handling.
>   
> -fuse-ld=bfd
> -Common Driver Negative(fuse-ld=gold)
> -Use the bfd linker instead of the default linker.
> -
> -fuse-ld=gold
> -Common Driver Negative(fuse-ld=bfd)
> -Use the gold linker instead of the default linker.
> -
> -fuse-ld=lld
> -Common Driver Negative(fuse-ld=lld)
> -Use the lld LLVM linker instead of the default linker.
> +fuse-ld=
> +Common Driver Joined
> +-fuse-ld=[bfd|gold|lld|<absolute path>]	Use the specified linker.
>   
>   fuse-linker-plugin
>   Common Undocumented Var(flag_use_linker_plugin)
> diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
> index 35b341e759f..c2dd410c88f 100644
> --- a/gcc/doc/invoke.texi
> +++ b/gcc/doc/invoke.texi
> @@ -14128,17 +14128,10 @@ uses @samp{nolto-rel}. To maintain whole program optimization, it is
>   recommended to link such objects into static library instead. Alternatively it
>   is possible to use H.J. Lu's binutils with support for mixed objects.
>   
> -@item -fuse-ld=bfd
> -@opindex fuse-ld=bfd
> -Use the @command{bfd} linker instead of the default linker.
> -
> -@item -fuse-ld=gold
> -@opindex fuse-ld=gold
> -Use the @command{gold} linker instead of the default linker.
> -
> -@item -fuse-ld=lld
> -@opindex fuse-ld=lld
> -Use the LLVM @command{lld} linker instead of the default linker.
> +@item -fuse-ld=@var{linker}
> +@opindex fuse-ld=linker
> +If @var{linker} is an absolute path, use it instead of the default linker;
> +otherwise use @command{ld.@var{linker}}.

You should somehow mention the special values bfd,gold and ldd.

>   
>   @cindex Libraries
>   @item -l@var{library}
> diff --git a/gcc/gcc.c b/gcc/gcc.c
> index effc384f3ef..f9a6f10502d 100644
> --- a/gcc/gcc.c
> +++ b/gcc/gcc.c
> @@ -3989,12 +3989,8 @@ driver_handle_option (struct gcc_options *opts,
>         do_save = false;
>         break;
>   
> -    case OPT_fuse_ld_bfd:
> -       use_ld = ".bfd";
> -       break;
> -
> -    case OPT_fuse_ld_gold:
> -       use_ld = ".gold";
> +    case OPT_fuse_ld_:
> +       use_ld = arg;
>          break;
>   
>       case OPT_fcompare_debug_second:
> @@ -7903,20 +7899,20 @@ driver::maybe_print_and_exit () const
>   	      if (! strcmp (&default_linker[len], HOST_EXECUTABLE_SUFFIX))
>   		{
>   		  default_linker[len] = '\0';
> -		  ld = concat (default_linker, use_ld,
> +		  ld = concat (default_linker, ".", use_ld,
>   			       HOST_EXECUTABLE_SUFFIX, NULL);
>   		}
>   	    }
>   	  if (ld == NULL)
>   # endif
> -	  ld = concat (DEFAULT_LINKER, use_ld, NULL);
> +	  ld = concat (DEFAULT_LINKER, ".", use_ld, NULL);
>   	  if (access (ld, X_OK) == 0)
>   	    {
>   	      printf ("%s\n", ld);
>   	      return (0);
>   	    }
>   #endif
> -	  print_prog_name = concat (print_prog_name, use_ld, NULL);
> +	  print_prog_name = concat (print_prog_name, ".", use_ld, NULL);

In gcc.c you will probably have similar issues.

>   	}
>         char *newname = find_a_file (&exec_prefixes, print_prog_name, X_OK, 0);
>         printf ("%s\n", (newname ? newname : print_prog_name));
> diff --git a/gcc/opts.c b/gcc/opts.c
> index 7affeb41a96..f50d365d517 100644
> --- a/gcc/opts.c
> +++ b/gcc/opts.c
> @@ -2763,9 +2763,7 @@ common_handle_option (struct gcc_options *opts,
>         dc->max_errors = value;
>         break;
>   
> -    case OPT_fuse_ld_bfd:
> -    case OPT_fuse_ld_gold:
> -    case OPT_fuse_ld_lld:
> +    case OPT_fuse_ld_:
>       case OPT_fuse_linker_plugin:
>         /* No-op. Used by the driver and passed to us because it starts with f.*/
>         break;
>
Li, Pan2 via Gcc-patches April 5, 2020, 10:32 p.m. UTC | #5
On 2020-03-11, Martin Liška wrote:
>On 2/10/20 1:02 AM, Fangrui Song via gcc-patches wrote:
>
>Hello.
>
>Thank you for the patch. You haven't received a review because we are right now
>in stage4 of the development cycle:
>https://gcc.gnu.org/develop.html#stage4

Thanks for the review!
According to https://gcc.gnu.org/pipermail/gcc-patches/2020-April/543028.html "GCC 10.0 Status Report (2020-04-01)",
I guess GCC is not open for a new development cycle yet.
I will just answer a few questions instead of uploading a new patch.

>Anyway, I'm going to provide a review (even though I'm not maintainer of that).
>
>Can you please describe your test-case why you need such option? When using
>a different ld, I typically export PATH=/path/to/binutils and then run configure
>and make.

I would hope -fuse-ld=ld.bfd and -fuse-ld=ld.gold were used instead of
-fuse-ld=bfd and -fuse-ld=gold, then it would be more natural to have
-fuse-ld=/abs/path/to/ld . https://gcc.gnu.org/bugzilla/show_bug.cgi?id=55470

-fuse-ld=bfd, -fuse-ld=gold and -fuse-ld=lld are hard-coded in numerous
places. It is too late to change that.

One idea is to make

-fuse-ld=bfd
-fuse-ld=gold
-fuse-ld=lld

special. For any other value, e.g. -fuse-ld=foo or -fuse-ld=/abs/path, just searches the
executable named "foo" (instead of "ld.foo") or /abs/path .

Does the scheme sound good? If it is agreed, I can make a similar change to clang.

>I noticed not ideal error message:
>
>$ gcc -fuse-ld=pes /tmp/foo.c
>collect2: fatal error: cannot find ‘ld’
>compilation terminated.
>
>while clang prints:
>
>$clang -fuse-ld=pes /tmp/foo.c
>clang-9.0: error: invalid linker name in argument '-fuse-ld=pes'
>
>The rest of the patch is comment inline...

Thanks for all the comments.

>>	PR driver/93645
>>	* common.opt (-fuse-ld=): Delete -fuse-ld=[bfd|gold|lld]. Add -fuse-ld=.
>>	* opts.c (common_handle_option): Handle OPT_fuse_ld_.
>>	* gcc.c (driver_handle_option): Likewise.
>>	* collect2.c (main): Likewise.
>>---
>>  gcc/ChangeLog       |  8 ++++++
>>  gcc/collect2.c      | 67 ++++++++++++++++++++++++---------------------
>>  gcc/common.opt      | 14 ++--------
>>  gcc/doc/invoke.texi | 15 +++-------
>>  gcc/gcc.c           | 14 ++++------
>>  gcc/opts.c          |  4 +--
>>  6 files changed, 57 insertions(+), 65 deletions(-)
>>
>>diff --git a/gcc/ChangeLog b/gcc/ChangeLog
>>index feb2d066d0b..6bcec12d841 100644
>>--- a/gcc/ChangeLog
>>+++ b/gcc/ChangeLog
>>@@ -1,3 +1,11 @@
>>+2020-02-09  Fangrui Song  <maskray@google.com>
>>+
>>+	PR driver/93645
>>+	* common.opt (-fuse-ld=): Delete -fuse-ld=[bfd|gold|lld]. Add -fuse-ld=.
>>+	* opts.c (common_handle_option): Handle OPT_fuse_ld_.
>>+	* gcc.c (driver_handle_option): Likewise.
>>+	* collect2.c (main): Likewise.
>>+
>>  2020-02-09  Uroš Bizjak  <ubizjak@gmail.com>
>>  	* recog.c: Move pass_split_before_sched2 code in front of
>>diff --git a/gcc/collect2.c b/gcc/collect2.c
>>index 502d629141c..a3ef525a93b 100644
>>--- a/gcc/collect2.c
>>+++ b/gcc/collect2.c
>>@@ -859,18 +859,12 @@ main (int argc, char **argv)
>>      {
>>        USE_DEFAULT_LD,
>>        USE_PLUGIN_LD,
>>-      USE_GOLD_LD,
>>-      USE_BFD_LD,
>>-      USE_LLD_LD,
>>-      USE_LD_MAX
>>+      USE_LD
>>      } selected_linker = USE_DEFAULT_LD;
>>-  static const char *const ld_suffixes[USE_LD_MAX] =
>>+  static const char *const ld_suffixes[USE_LD] =
>>      {
>>        "ld",
>>-      PLUGIN_LD_SUFFIX,
>>-      "ld.gold",
>>-      "ld.bfd",
>>-      "ld.lld"
>>+      PLUGIN_LD_SUFFIX
>>      };
>>    static const char *const real_ld_suffix = "real-ld";
>>    static const char *const collect_ld_suffix = "collect-ld";
>>@@ -882,7 +876,7 @@ main (int argc, char **argv)
>>    static const char *const strip_suffix = "strip";
>>    static const char *const gstrip_suffix = "gstrip";
>>-  const char *full_ld_suffixes[USE_LD_MAX];
>>+  const char *full_ld_suffixes[USE_LD];
>>  #ifdef CROSS_DIRECTORY_STRUCTURE
>>    /* If we look for a program in the compiler directories, we just use
>>       the short name, since these directories are already system-specific.
>>@@ -924,6 +918,7 @@ main (int argc, char **argv)
>>    const char **ld1;
>>    bool use_plugin = false;
>>    bool use_collect_ld = false;
>>+  const char *use_ld = NULL;
>>    /* The kinds of symbols we will have to consider when scanning the
>>       outcome of a first pass link.  This is ALL to start with, then might
>>@@ -948,7 +943,7 @@ main (int argc, char **argv)
>>  #endif
>>    int i;
>>-  for (i = 0; i < USE_LD_MAX; i++)
>>+  for (i = 0; i < USE_LD; i++)
>>      full_ld_suffixes[i]
>>  #ifdef CROSS_DIRECTORY_STRUCTURE
>>        = concat (target_machine, "-", ld_suffixes[i], NULL);
>>@@ -1041,12 +1036,11 @@ main (int argc, char **argv)
>>  	    if (selected_linker == USE_DEFAULT_LD)
>>  	      selected_linker = USE_PLUGIN_LD;
>>  	  }
>>-	else if (strcmp (argv[i], "-fuse-ld=bfd") == 0)
>>-	  selected_linker = USE_BFD_LD;
>>-	else if (strcmp (argv[i], "-fuse-ld=gold") == 0)
>>-	  selected_linker = USE_GOLD_LD;
>>-	else if (strcmp (argv[i], "-fuse-ld=lld") == 0)
>>-	  selected_linker = USE_LLD_LD;
>>+	else if (!strncmp (argv[i], "-fuse-ld=", 9))
>>+	  {
>>+	    use_ld = argv[i] + 9;
>>+	    selected_linker = USE_LD;
>>+	  }
>>  	else if (strncmp (argv[i], "-o", 2) == 0)
>>  	  {
>>  	    /* Parse the output filename if it's given so that we can make
>>@@ -1152,8 +1146,7 @@ main (int argc, char **argv)
>>    /* Maybe we know the right file to use (if not cross).  */
>>    ld_file_name = 0;
>>  #ifdef DEFAULT_LINKER
>>-  if (selected_linker == USE_BFD_LD || selected_linker == USE_GOLD_LD ||
>>-      selected_linker == USE_LLD_LD)
>>+  if (!ld_file_name && selected_linker == USE_LD)
>>      {
>>        char *linker_name;
>>  # ifdef HOST_EXECUTABLE_SUFFIX
>>@@ -1168,15 +1161,13 @@ main (int argc, char **argv)
>>  	  if (! strcmp (&default_linker[len], HOST_EXECUTABLE_SUFFIX))
>>  	    {
>>  	      default_linker[len] = '\0';
>>-	      linker_name = concat (default_linker,
>>-				    &ld_suffixes[selected_linker][2],
>>+	      linker_name = concat (default_linker, ".", use_ld,
>>  				    HOST_EXECUTABLE_SUFFIX, NULL);
>>  	    }
>>  	}
>>        if (linker_name == NULL)
>>  # endif
>>-      linker_name = concat (DEFAULT_LINKER,
>>-			    &ld_suffixes[selected_linker][2],
>>+      linker_name = concat (DEFAULT_LINKER, ".", use_ld,
>>  			    NULL);
>>        if (access (linker_name, X_OK) == 0)
>>  	ld_file_name = linker_name;
>>@@ -1197,14 +1188,28 @@ main (int argc, char **argv)
>>        ld_file_name = find_a_file (&cpath, collect_ld_suffix, X_OK);
>>        use_collect_ld = ld_file_name != 0;
>>      }
>>-  /* Search the compiler directories for `ld'.  We have protection against
>>-     recursive calls in find_a_file.  */
>>-  if (ld_file_name == 0)
>>-    ld_file_name = find_a_file (&cpath, ld_suffixes[selected_linker], X_OK);
>>-  /* Search the ordinary system bin directories
>>-     for `ld' (if native linking) or `TARGET-ld' (if cross).  */
>>-  if (ld_file_name == 0)
>>-    ld_file_name = find_a_file (&path, full_ld_suffixes[selected_linker], X_OK);
>>+  if (selected_linker != USE_LD) {
>>+    /* Search the compiler directories for `ld'.  We have protection against
>>+       recursive calls in find_a_file.  */
>>+    if (!ld_file_name)
>>+      ld_file_name = find_a_file(&cpath, ld_suffixes[selected_linker], X_OK);
>>+    /* Search the ordinary system bin directories
>>+       for `ld' (if native linking) or `TARGET-ld' (if cross).  */
>>+    if (!ld_file_name)
>>+      ld_file_name = find_a_file(&path, full_ld_suffixes[selected_linker], X_OK);
>>+  } else if (IS_ABSOLUTE_PATH(use_ld) && access(use_ld, X_OK) == 0) {
>>+    ld_file_name = use_ld;
>>+  } else {
>>+    const char *linker_name = concat("ld.", use_ld, NULL);
>
>This leads to strange searches like:
>
>$ strace -f -s512 gcc -fuse-ld=/x/y/z/pes /tmp/foo.c 2>&1 | grep pes
>...
>[pid 24295] stat("/home/marxin/bin/ld./x/y/z/pes", 0x7fffffffd1f0) = -1 ENOENT (No such file or directory)
>[pid 24295] stat("/usr/local/bin/ld./x/y/z/pes", 0x7fffffffd1f0) = -1 ENOENT (No such file or directory)
>
>Moreover, before the patch we only searched for suffixes 'ld.bfd', 'ld.gold' and 'ld.gold'. Now it
>searches also for:
>
>$ strace ... gcc -fuse-ld=xyz
>...
>[pid 24893] stat("/home/marxin/bin/ld.xyz", 0x7fffffffd200) = -1 ENOENT (No such file or directory)
>
>>+    if (!ld_file_name)
>>+      ld_file_name = find_a_file(&cpath, linker_name, X_OK);
>>+    if (!ld_file_name) {
>>+#ifdef CROSS_DIRECTORY_STRUCTURE
>>+	linker_name = concat(target_machine, "-", linker_name, NULL);
>>+#endif
>>+	ld_file_name = find_a_file(&path, linker_name, X_OK);
>>+    }
>>+  }
>>  #ifdef REAL_NM_FILE_NAME
>>    nm_file_name = find_a_file (&path, REAL_NM_FILE_NAME, X_OK);
>>diff --git a/gcc/common.opt b/gcc/common.opt
>>index 5692cd04374..a76ed6434bb 100644
>>--- a/gcc/common.opt
>>+++ b/gcc/common.opt
>>@@ -2859,17 +2859,9 @@ funwind-tables
>>  Common Report Var(flag_unwind_tables) Optimization
>>  Just generate unwind tables for exception handling.
>>-fuse-ld=bfd
>>-Common Driver Negative(fuse-ld=gold)
>>-Use the bfd linker instead of the default linker.
>>-
>>-fuse-ld=gold
>>-Common Driver Negative(fuse-ld=bfd)
>>-Use the gold linker instead of the default linker.
>>-
>>-fuse-ld=lld
>>-Common Driver Negative(fuse-ld=lld)
>>-Use the lld LLVM linker instead of the default linker.
>>+fuse-ld=
>>+Common Driver Joined
>>+-fuse-ld=[bfd|gold|lld|<absolute path>]	Use the specified linker.
>>  fuse-linker-plugin
>>  Common Undocumented Var(flag_use_linker_plugin)
>>diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
>>index 35b341e759f..c2dd410c88f 100644
>>--- a/gcc/doc/invoke.texi
>>+++ b/gcc/doc/invoke.texi
>>@@ -14128,17 +14128,10 @@ uses @samp{nolto-rel}. To maintain whole program optimization, it is
>>  recommended to link such objects into static library instead. Alternatively it
>>  is possible to use H.J. Lu's binutils with support for mixed objects.
>>-@item -fuse-ld=bfd
>>-@opindex fuse-ld=bfd
>>-Use the @command{bfd} linker instead of the default linker.
>>-
>>-@item -fuse-ld=gold
>>-@opindex fuse-ld=gold
>>-Use the @command{gold} linker instead of the default linker.
>>-
>>-@item -fuse-ld=lld
>>-@opindex fuse-ld=lld
>>-Use the LLVM @command{lld} linker instead of the default linker.
>>+@item -fuse-ld=@var{linker}
>>+@opindex fuse-ld=linker
>>+If @var{linker} is an absolute path, use it instead of the default linker;
>>+otherwise use @command{ld.@var{linker}}.
>
>You should somehow mention the special values bfd,gold and ldd.
>>  @cindex Libraries
>>  @item -l@var{library}
>>diff --git a/gcc/gcc.c b/gcc/gcc.c
>>index effc384f3ef..f9a6f10502d 100644
>>--- a/gcc/gcc.c
>>+++ b/gcc/gcc.c
>>@@ -3989,12 +3989,8 @@ driver_handle_option (struct gcc_options *opts,
>>        do_save = false;
>>        break;
>>-    case OPT_fuse_ld_bfd:
>>-       use_ld = ".bfd";
>>-       break;
>>-
>>-    case OPT_fuse_ld_gold:
>>-       use_ld = ".gold";
>>+    case OPT_fuse_ld_:
>>+       use_ld = arg;
>>         break;
>>      case OPT_fcompare_debug_second:
>>@@ -7903,20 +7899,20 @@ driver::maybe_print_and_exit () const
>>  	      if (! strcmp (&default_linker[len], HOST_EXECUTABLE_SUFFIX))
>>  		{
>>  		  default_linker[len] = '\0';
>>-		  ld = concat (default_linker, use_ld,
>>+		  ld = concat (default_linker, ".", use_ld,
>>  			       HOST_EXECUTABLE_SUFFIX, NULL);
>>  		}
>>  	    }
>>  	  if (ld == NULL)
>>  # endif
>>-	  ld = concat (DEFAULT_LINKER, use_ld, NULL);
>>+	  ld = concat (DEFAULT_LINKER, ".", use_ld, NULL);
>>  	  if (access (ld, X_OK) == 0)
>>  	    {
>>  	      printf ("%s\n", ld);
>>  	      return (0);
>>  	    }
>>  #endif
>>-	  print_prog_name = concat (print_prog_name, use_ld, NULL);
>>+	  print_prog_name = concat (print_prog_name, ".", use_ld, NULL);
>
>In gcc.c you will probably have similar issues.
>
>>  	}
>>        char *newname = find_a_file (&exec_prefixes, print_prog_name, X_OK, 0);
>>        printf ("%s\n", (newname ? newname : print_prog_name));
>>diff --git a/gcc/opts.c b/gcc/opts.c
>>index 7affeb41a96..f50d365d517 100644
>>--- a/gcc/opts.c
>>+++ b/gcc/opts.c
>>@@ -2763,9 +2763,7 @@ common_handle_option (struct gcc_options *opts,
>>        dc->max_errors = value;
>>        break;
>>-    case OPT_fuse_ld_bfd:
>>-    case OPT_fuse_ld_gold:
>>-    case OPT_fuse_ld_lld:
>>+    case OPT_fuse_ld_:
>>      case OPT_fuse_linker_plugin:
>>        /* No-op. Used by the driver and passed to us because it starts with f.*/
>>        break;
>>
>
Martin Liška April 6, 2020, 7:18 a.m. UTC | #6
On 4/6/20 12:32 AM, Fangrui Song wrote:
> On 2020-03-11, Martin Liška wrote:
>> On 2/10/20 1:02 AM, Fangrui Song via gcc-patches wrote:
>>
>> Hello.
>>
>> Thank you for the patch. You haven't received a review because we are right now
>> in stage4 of the development cycle:
>> https://gcc.gnu.org/develop.html#stage4
> 
> Thanks for the review!
> According to https://gcc.gnu.org/pipermail/gcc-patches/2020-April/543028.html "GCC 10.0 Status Report (2020-04-01)",
> I guess GCC is not open for a new development cycle yet.

Yes, it's not opened, but I expect to be opened in 3 weeks from now.

> I will just answer a few questions instead of uploading a new patch.

Sure, but don't hesitate to send a patch. It can sit here and wait for next stage1 ;)

> 
>> Anyway, I'm going to provide a review (even though I'm not maintainer of that).
>>
>> Can you please describe your test-case why you need such option? When using
>> a different ld, I typically export PATH=/path/to/binutils and then run configure
>> and make.
> 
> I would hope -fuse-ld=ld.bfd and -fuse-ld=ld.gold were used instead of
> -fuse-ld=bfd and -fuse-ld=gold, then it would be more natural to have
> -fuse-ld=/abs/path/to/ld . https://gcc.gnu.org/bugzilla/show_bug.cgi?id=55470

Well, problem with that is that the option values are used and we want to preserve
backward compatibility of options (if possible). I mean we can't just rename
-fuse-ld=bfd to -fuse-ld=ld.bfd.

> 
> -fuse-ld=bfd, -fuse-ld=gold and -fuse-ld=lld are hard-coded in numerous
> places. It is too late to change that.
> 
> One idea is to make
> 
> -fuse-ld=bfd
> -fuse-ld=gold
> -fuse-ld=lld
> 
> special. For any other value, e.g. -fuse-ld=foo or -fuse-ld=/abs/path, just searches the
> executable named "foo" (instead of "ld.foo") or /abs/path .

Yes, that seems feasible to me.

> 
> Does the scheme sound good? If it is agreed, I can make a similar change to clang.

Yes, please send a patch and we can make another round of review process.

Thanks,
Martin

> 
>> I noticed not ideal error message:
>>
>> $ gcc -fuse-ld=pes /tmp/foo.c
>> collect2: fatal error: cannot find ‘ld’
>> compilation terminated.
>>
>> while clang prints:
>>
>> $clang -fuse-ld=pes /tmp/foo.c
>> clang-9.0: error: invalid linker name in argument '-fuse-ld=pes'
>>
>> The rest of the patch is comment inline...
> 
> Thanks for all the comments.
> 
>>>     PR driver/93645
>>>     * common.opt (-fuse-ld=): Delete -fuse-ld=[bfd|gold|lld]. Add -fuse-ld=.
>>>     * opts.c (common_handle_option): Handle OPT_fuse_ld_.
>>>     * gcc.c (driver_handle_option): Likewise.
>>>     * collect2.c (main): Likewise.
>>> ---
>>>  gcc/ChangeLog       |  8 ++++++
>>>  gcc/collect2.c      | 67 ++++++++++++++++++++++++---------------------
>>>  gcc/common.opt      | 14 ++--------
>>>  gcc/doc/invoke.texi | 15 +++-------
>>>  gcc/gcc.c           | 14 ++++------
>>>  gcc/opts.c          |  4 +--
>>>  6 files changed, 57 insertions(+), 65 deletions(-)
>>>
>>> diff --git a/gcc/ChangeLog b/gcc/ChangeLog
>>> index feb2d066d0b..6bcec12d841 100644
>>> --- a/gcc/ChangeLog
>>> +++ b/gcc/ChangeLog
>>> @@ -1,3 +1,11 @@
>>> +2020-02-09  Fangrui Song  <maskray@google.com>
>>> +
>>> +    PR driver/93645
>>> +    * common.opt (-fuse-ld=): Delete -fuse-ld=[bfd|gold|lld]. Add -fuse-ld=.
>>> +    * opts.c (common_handle_option): Handle OPT_fuse_ld_.
>>> +    * gcc.c (driver_handle_option): Likewise.
>>> +    * collect2.c (main): Likewise.
>>> +
>>>  2020-02-09  Uroš Bizjak  <ubizjak@gmail.com>
>>>      * recog.c: Move pass_split_before_sched2 code in front of
>>> diff --git a/gcc/collect2.c b/gcc/collect2.c
>>> index 502d629141c..a3ef525a93b 100644
>>> --- a/gcc/collect2.c
>>> +++ b/gcc/collect2.c
>>> @@ -859,18 +859,12 @@ main (int argc, char **argv)
>>>      {
>>>        USE_DEFAULT_LD,
>>>        USE_PLUGIN_LD,
>>> -      USE_GOLD_LD,
>>> -      USE_BFD_LD,
>>> -      USE_LLD_LD,
>>> -      USE_LD_MAX
>>> +      USE_LD
>>>      } selected_linker = USE_DEFAULT_LD;
>>> -  static const char *const ld_suffixes[USE_LD_MAX] =
>>> +  static const char *const ld_suffixes[USE_LD] =
>>>      {
>>>        "ld",
>>> -      PLUGIN_LD_SUFFIX,
>>> -      "ld.gold",
>>> -      "ld.bfd",
>>> -      "ld.lld"
>>> +      PLUGIN_LD_SUFFIX
>>>      };
>>>    static const char *const real_ld_suffix = "real-ld";
>>>    static const char *const collect_ld_suffix = "collect-ld";
>>> @@ -882,7 +876,7 @@ main (int argc, char **argv)
>>>    static const char *const strip_suffix = "strip";
>>>    static const char *const gstrip_suffix = "gstrip";
>>> -  const char *full_ld_suffixes[USE_LD_MAX];
>>> +  const char *full_ld_suffixes[USE_LD];
>>>  #ifdef CROSS_DIRECTORY_STRUCTURE
>>>    /* If we look for a program in the compiler directories, we just use
>>>       the short name, since these directories are already system-specific.
>>> @@ -924,6 +918,7 @@ main (int argc, char **argv)
>>>    const char **ld1;
>>>    bool use_plugin = false;
>>>    bool use_collect_ld = false;
>>> +  const char *use_ld = NULL;
>>>    /* The kinds of symbols we will have to consider when scanning the
>>>       outcome of a first pass link.  This is ALL to start with, then might
>>> @@ -948,7 +943,7 @@ main (int argc, char **argv)
>>>  #endif
>>>    int i;
>>> -  for (i = 0; i < USE_LD_MAX; i++)
>>> +  for (i = 0; i < USE_LD; i++)
>>>      full_ld_suffixes[i]
>>>  #ifdef CROSS_DIRECTORY_STRUCTURE
>>>        = concat (target_machine, "-", ld_suffixes[i], NULL);
>>> @@ -1041,12 +1036,11 @@ main (int argc, char **argv)
>>>          if (selected_linker == USE_DEFAULT_LD)
>>>            selected_linker = USE_PLUGIN_LD;
>>>        }
>>> -    else if (strcmp (argv[i], "-fuse-ld=bfd") == 0)
>>> -      selected_linker = USE_BFD_LD;
>>> -    else if (strcmp (argv[i], "-fuse-ld=gold") == 0)
>>> -      selected_linker = USE_GOLD_LD;
>>> -    else if (strcmp (argv[i], "-fuse-ld=lld") == 0)
>>> -      selected_linker = USE_LLD_LD;
>>> +    else if (!strncmp (argv[i], "-fuse-ld=", 9))
>>> +      {
>>> +        use_ld = argv[i] + 9;
>>> +        selected_linker = USE_LD;
>>> +      }
>>>      else if (strncmp (argv[i], "-o", 2) == 0)
>>>        {
>>>          /* Parse the output filename if it's given so that we can make
>>> @@ -1152,8 +1146,7 @@ main (int argc, char **argv)
>>>    /* Maybe we know the right file to use (if not cross).  */
>>>    ld_file_name = 0;
>>>  #ifdef DEFAULT_LINKER
>>> -  if (selected_linker == USE_BFD_LD || selected_linker == USE_GOLD_LD ||
>>> -      selected_linker == USE_LLD_LD)
>>> +  if (!ld_file_name && selected_linker == USE_LD)
>>>      {
>>>        char *linker_name;
>>>  # ifdef HOST_EXECUTABLE_SUFFIX
>>> @@ -1168,15 +1161,13 @@ main (int argc, char **argv)
>>>        if (! strcmp (&default_linker[len], HOST_EXECUTABLE_SUFFIX))
>>>          {
>>>            default_linker[len] = '\0';
>>> -          linker_name = concat (default_linker,
>>> -                    &ld_suffixes[selected_linker][2],
>>> +          linker_name = concat (default_linker, ".", use_ld,
>>>                      HOST_EXECUTABLE_SUFFIX, NULL);
>>>          }
>>>      }
>>>        if (linker_name == NULL)
>>>  # endif
>>> -      linker_name = concat (DEFAULT_LINKER,
>>> -                &ld_suffixes[selected_linker][2],
>>> +      linker_name = concat (DEFAULT_LINKER, ".", use_ld,
>>>                  NULL);
>>>        if (access (linker_name, X_OK) == 0)
>>>      ld_file_name = linker_name;
>>> @@ -1197,14 +1188,28 @@ main (int argc, char **argv)
>>>        ld_file_name = find_a_file (&cpath, collect_ld_suffix, X_OK);
>>>        use_collect_ld = ld_file_name != 0;
>>>      }
>>> -  /* Search the compiler directories for `ld'.  We have protection against
>>> -     recursive calls in find_a_file.  */
>>> -  if (ld_file_name == 0)
>>> -    ld_file_name = find_a_file (&cpath, ld_suffixes[selected_linker], X_OK);
>>> -  /* Search the ordinary system bin directories
>>> -     for `ld' (if native linking) or `TARGET-ld' (if cross).  */
>>> -  if (ld_file_name == 0)
>>> -    ld_file_name = find_a_file (&path, full_ld_suffixes[selected_linker], X_OK);
>>> +  if (selected_linker != USE_LD) {
>>> +    /* Search the compiler directories for `ld'.  We have protection against
>>> +       recursive calls in find_a_file.  */
>>> +    if (!ld_file_name)
>>> +      ld_file_name = find_a_file(&cpath, ld_suffixes[selected_linker], X_OK);
>>> +    /* Search the ordinary system bin directories
>>> +       for `ld' (if native linking) or `TARGET-ld' (if cross).  */
>>> +    if (!ld_file_name)
>>> +      ld_file_name = find_a_file(&path, full_ld_suffixes[selected_linker], X_OK);
>>> +  } else if (IS_ABSOLUTE_PATH(use_ld) && access(use_ld, X_OK) == 0) {
>>> +    ld_file_name = use_ld;
>>> +  } else {
>>> +    const char *linker_name = concat("ld.", use_ld, NULL);
>>
>> This leads to strange searches like:
>>
>> $ strace -f -s512 gcc -fuse-ld=/x/y/z/pes /tmp/foo.c 2>&1 | grep pes
>> ...
>> [pid 24295] stat("/home/marxin/bin/ld./x/y/z/pes", 0x7fffffffd1f0) = -1 ENOENT (No such file or directory)
>> [pid 24295] stat("/usr/local/bin/ld./x/y/z/pes", 0x7fffffffd1f0) = -1 ENOENT (No such file or directory)
>>
>> Moreover, before the patch we only searched for suffixes 'ld.bfd', 'ld.gold' and 'ld.gold'. Now it
>> searches also for:
>>
>> $ strace ... gcc -fuse-ld=xyz
>> ...
>> [pid 24893] stat("/home/marxin/bin/ld.xyz", 0x7fffffffd200) = -1 ENOENT (No such file or directory)
>>
>>> +    if (!ld_file_name)
>>> +      ld_file_name = find_a_file(&cpath, linker_name, X_OK);
>>> +    if (!ld_file_name) {
>>> +#ifdef CROSS_DIRECTORY_STRUCTURE
>>> +    linker_name = concat(target_machine, "-", linker_name, NULL);
>>> +#endif
>>> +    ld_file_name = find_a_file(&path, linker_name, X_OK);
>>> +    }
>>> +  }
>>>  #ifdef REAL_NM_FILE_NAME
>>>    nm_file_name = find_a_file (&path, REAL_NM_FILE_NAME, X_OK);
>>> diff --git a/gcc/common.opt b/gcc/common.opt
>>> index 5692cd04374..a76ed6434bb 100644
>>> --- a/gcc/common.opt
>>> +++ b/gcc/common.opt
>>> @@ -2859,17 +2859,9 @@ funwind-tables
>>>  Common Report Var(flag_unwind_tables) Optimization
>>>  Just generate unwind tables for exception handling.
>>> -fuse-ld=bfd
>>> -Common Driver Negative(fuse-ld=gold)
>>> -Use the bfd linker instead of the default linker.
>>> -
>>> -fuse-ld=gold
>>> -Common Driver Negative(fuse-ld=bfd)
>>> -Use the gold linker instead of the default linker.
>>> -
>>> -fuse-ld=lld
>>> -Common Driver Negative(fuse-ld=lld)
>>> -Use the lld LLVM linker instead of the default linker.
>>> +fuse-ld=
>>> +Common Driver Joined
>>> +-fuse-ld=[bfd|gold|lld|<absolute path>]    Use the specified linker.
>>>  fuse-linker-plugin
>>>  Common Undocumented Var(flag_use_linker_plugin)
>>> diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
>>> index 35b341e759f..c2dd410c88f 100644
>>> --- a/gcc/doc/invoke.texi
>>> +++ b/gcc/doc/invoke.texi
>>> @@ -14128,17 +14128,10 @@ uses @samp{nolto-rel}. To maintain whole program optimization, it is
>>>  recommended to link such objects into static library instead. Alternatively it
>>>  is possible to use H.J. Lu's binutils with support for mixed objects.
>>> -@item -fuse-ld=bfd
>>> -@opindex fuse-ld=bfd
>>> -Use the @command{bfd} linker instead of the default linker.
>>> -
>>> -@item -fuse-ld=gold
>>> -@opindex fuse-ld=gold
>>> -Use the @command{gold} linker instead of the default linker.
>>> -
>>> -@item -fuse-ld=lld
>>> -@opindex fuse-ld=lld
>>> -Use the LLVM @command{lld} linker instead of the default linker.
>>> +@item -fuse-ld=@var{linker}
>>> +@opindex fuse-ld=linker
>>> +If @var{linker} is an absolute path, use it instead of the default linker;
>>> +otherwise use @command{ld.@var{linker}}.
>>
>> You should somehow mention the special values bfd,gold and ldd.
>>>  @cindex Libraries
>>>  @item -l@var{library}
>>> diff --git a/gcc/gcc.c b/gcc/gcc.c
>>> index effc384f3ef..f9a6f10502d 100644
>>> --- a/gcc/gcc.c
>>> +++ b/gcc/gcc.c
>>> @@ -3989,12 +3989,8 @@ driver_handle_option (struct gcc_options *opts,
>>>        do_save = false;
>>>        break;
>>> -    case OPT_fuse_ld_bfd:
>>> -       use_ld = ".bfd";
>>> -       break;
>>> -
>>> -    case OPT_fuse_ld_gold:
>>> -       use_ld = ".gold";
>>> +    case OPT_fuse_ld_:
>>> +       use_ld = arg;
>>>         break;
>>>      case OPT_fcompare_debug_second:
>>> @@ -7903,20 +7899,20 @@ driver::maybe_print_and_exit () const
>>>            if (! strcmp (&default_linker[len], HOST_EXECUTABLE_SUFFIX))
>>>          {
>>>            default_linker[len] = '\0';
>>> -          ld = concat (default_linker, use_ld,
>>> +          ld = concat (default_linker, ".", use_ld,
>>>                     HOST_EXECUTABLE_SUFFIX, NULL);
>>>          }
>>>          }
>>>        if (ld == NULL)
>>>  # endif
>>> -      ld = concat (DEFAULT_LINKER, use_ld, NULL);
>>> +      ld = concat (DEFAULT_LINKER, ".", use_ld, NULL);
>>>        if (access (ld, X_OK) == 0)
>>>          {
>>>            printf ("%s\n", ld);
>>>            return (0);
>>>          }
>>>  #endif
>>> -      print_prog_name = concat (print_prog_name, use_ld, NULL);
>>> +      print_prog_name = concat (print_prog_name, ".", use_ld, NULL);
>>
>> In gcc.c you will probably have similar issues.
>>
>>>      }
>>>        char *newname = find_a_file (&exec_prefixes, print_prog_name, X_OK, 0);
>>>        printf ("%s\n", (newname ? newname : print_prog_name));
>>> diff --git a/gcc/opts.c b/gcc/opts.c
>>> index 7affeb41a96..f50d365d517 100644
>>> --- a/gcc/opts.c
>>> +++ b/gcc/opts.c
>>> @@ -2763,9 +2763,7 @@ common_handle_option (struct gcc_options *opts,
>>>        dc->max_errors = value;
>>>        break;
>>> -    case OPT_fuse_ld_bfd:
>>> -    case OPT_fuse_ld_gold:
>>> -    case OPT_fuse_ld_lld:
>>> +    case OPT_fuse_ld_:
>>>      case OPT_fuse_linker_plugin:
>>>        /* No-op. Used by the driver and passed to us because it starts with f.*/
>>>        break;
>>>
>>
diff mbox series

Patch

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index feb2d066d0b..6bcec12d841 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,11 @@ 
+2020-02-09  Fangrui Song  <maskray@google.com>
+
+	PR driver/93645
+	* common.opt (-fuse-ld=): Delete -fuse-ld=[bfd|gold|lld]. Add -fuse-ld=.
+	* opts.c (common_handle_option): Handle OPT_fuse_ld_.
+	* gcc.c (driver_handle_option): Likewise.
+	* collect2.c (main): Likewise.
+
 2020-02-09  Uroš Bizjak  <ubizjak@gmail.com>
 
 	* recog.c: Move pass_split_before_sched2 code in front of
diff --git a/gcc/collect2.c b/gcc/collect2.c
index 502d629141c..a3ef525a93b 100644
--- a/gcc/collect2.c
+++ b/gcc/collect2.c
@@ -859,18 +859,12 @@  main (int argc, char **argv)
     {
       USE_DEFAULT_LD,
       USE_PLUGIN_LD,
-      USE_GOLD_LD,
-      USE_BFD_LD,
-      USE_LLD_LD,
-      USE_LD_MAX
+      USE_LD
     } selected_linker = USE_DEFAULT_LD;
-  static const char *const ld_suffixes[USE_LD_MAX] =
+  static const char *const ld_suffixes[USE_LD] =
     {
       "ld",
-      PLUGIN_LD_SUFFIX,
-      "ld.gold",
-      "ld.bfd",
-      "ld.lld"
+      PLUGIN_LD_SUFFIX
     };
   static const char *const real_ld_suffix = "real-ld";
   static const char *const collect_ld_suffix = "collect-ld";
@@ -882,7 +876,7 @@  main (int argc, char **argv)
   static const char *const strip_suffix = "strip";
   static const char *const gstrip_suffix = "gstrip";
 
-  const char *full_ld_suffixes[USE_LD_MAX];
+  const char *full_ld_suffixes[USE_LD];
 #ifdef CROSS_DIRECTORY_STRUCTURE
   /* If we look for a program in the compiler directories, we just use
      the short name, since these directories are already system-specific.
@@ -924,6 +918,7 @@  main (int argc, char **argv)
   const char **ld1;
   bool use_plugin = false;
   bool use_collect_ld = false;
+  const char *use_ld = NULL;
 
   /* The kinds of symbols we will have to consider when scanning the
      outcome of a first pass link.  This is ALL to start with, then might
@@ -948,7 +943,7 @@  main (int argc, char **argv)
 #endif
   int i;
 
-  for (i = 0; i < USE_LD_MAX; i++)
+  for (i = 0; i < USE_LD; i++)
     full_ld_suffixes[i]
 #ifdef CROSS_DIRECTORY_STRUCTURE
       = concat (target_machine, "-", ld_suffixes[i], NULL);
@@ -1041,12 +1036,11 @@  main (int argc, char **argv)
 	    if (selected_linker == USE_DEFAULT_LD)
 	      selected_linker = USE_PLUGIN_LD;
 	  }
-	else if (strcmp (argv[i], "-fuse-ld=bfd") == 0)
-	  selected_linker = USE_BFD_LD;
-	else if (strcmp (argv[i], "-fuse-ld=gold") == 0)
-	  selected_linker = USE_GOLD_LD;
-	else if (strcmp (argv[i], "-fuse-ld=lld") == 0)
-	  selected_linker = USE_LLD_LD;
+	else if (!strncmp (argv[i], "-fuse-ld=", 9))
+	  {
+	    use_ld = argv[i] + 9;
+	    selected_linker = USE_LD;
+	  }
 	else if (strncmp (argv[i], "-o", 2) == 0)
 	  {
 	    /* Parse the output filename if it's given so that we can make
@@ -1152,8 +1146,7 @@  main (int argc, char **argv)
   /* Maybe we know the right file to use (if not cross).  */
   ld_file_name = 0;
 #ifdef DEFAULT_LINKER
-  if (selected_linker == USE_BFD_LD || selected_linker == USE_GOLD_LD ||
-      selected_linker == USE_LLD_LD)
+  if (!ld_file_name && selected_linker == USE_LD)
     {
       char *linker_name;
 # ifdef HOST_EXECUTABLE_SUFFIX
@@ -1168,15 +1161,13 @@  main (int argc, char **argv)
 	  if (! strcmp (&default_linker[len], HOST_EXECUTABLE_SUFFIX))
 	    {
 	      default_linker[len] = '\0';
-	      linker_name = concat (default_linker,
-				    &ld_suffixes[selected_linker][2],
+	      linker_name = concat (default_linker, ".", use_ld,
 				    HOST_EXECUTABLE_SUFFIX, NULL);
 	    }
 	}
       if (linker_name == NULL)
 # endif
-      linker_name = concat (DEFAULT_LINKER,
-			    &ld_suffixes[selected_linker][2],
+      linker_name = concat (DEFAULT_LINKER, ".", use_ld,
 			    NULL);
       if (access (linker_name, X_OK) == 0)
 	ld_file_name = linker_name;
@@ -1197,14 +1188,28 @@  main (int argc, char **argv)
       ld_file_name = find_a_file (&cpath, collect_ld_suffix, X_OK);
       use_collect_ld = ld_file_name != 0;
     }
-  /* Search the compiler directories for `ld'.  We have protection against
-     recursive calls in find_a_file.  */
-  if (ld_file_name == 0)
-    ld_file_name = find_a_file (&cpath, ld_suffixes[selected_linker], X_OK);
-  /* Search the ordinary system bin directories
-     for `ld' (if native linking) or `TARGET-ld' (if cross).  */
-  if (ld_file_name == 0)
-    ld_file_name = find_a_file (&path, full_ld_suffixes[selected_linker], X_OK);
+  if (selected_linker != USE_LD) {
+    /* Search the compiler directories for `ld'.  We have protection against
+       recursive calls in find_a_file.  */
+    if (!ld_file_name)
+      ld_file_name = find_a_file(&cpath, ld_suffixes[selected_linker], X_OK);
+    /* Search the ordinary system bin directories
+       for `ld' (if native linking) or `TARGET-ld' (if cross).  */
+    if (!ld_file_name)
+      ld_file_name = find_a_file(&path, full_ld_suffixes[selected_linker], X_OK);
+  } else if (IS_ABSOLUTE_PATH(use_ld) && access(use_ld, X_OK) == 0) {
+    ld_file_name = use_ld;
+  } else {
+    const char *linker_name = concat("ld.", use_ld, NULL);
+    if (!ld_file_name)
+      ld_file_name = find_a_file(&cpath, linker_name, X_OK);
+    if (!ld_file_name) {
+#ifdef CROSS_DIRECTORY_STRUCTURE
+	linker_name = concat(target_machine, "-", linker_name, NULL);
+#endif
+	ld_file_name = find_a_file(&path, linker_name, X_OK);
+    }
+  }
 
 #ifdef REAL_NM_FILE_NAME
   nm_file_name = find_a_file (&path, REAL_NM_FILE_NAME, X_OK);
diff --git a/gcc/common.opt b/gcc/common.opt
index 5692cd04374..a76ed6434bb 100644
--- a/gcc/common.opt
+++ b/gcc/common.opt
@@ -2859,17 +2859,9 @@  funwind-tables
 Common Report Var(flag_unwind_tables) Optimization
 Just generate unwind tables for exception handling.
 
-fuse-ld=bfd
-Common Driver Negative(fuse-ld=gold)
-Use the bfd linker instead of the default linker.
-
-fuse-ld=gold
-Common Driver Negative(fuse-ld=bfd)
-Use the gold linker instead of the default linker.
-
-fuse-ld=lld
-Common Driver Negative(fuse-ld=lld)
-Use the lld LLVM linker instead of the default linker.
+fuse-ld=
+Common Driver Joined
+-fuse-ld=[bfd|gold|lld|<absolute path>]	Use the specified linker.
 
 fuse-linker-plugin
 Common Undocumented Var(flag_use_linker_plugin)
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 35b341e759f..c2dd410c88f 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -14128,17 +14128,10 @@  uses @samp{nolto-rel}. To maintain whole program optimization, it is
 recommended to link such objects into static library instead. Alternatively it
 is possible to use H.J. Lu's binutils with support for mixed objects.
 
-@item -fuse-ld=bfd
-@opindex fuse-ld=bfd
-Use the @command{bfd} linker instead of the default linker.
-
-@item -fuse-ld=gold
-@opindex fuse-ld=gold
-Use the @command{gold} linker instead of the default linker.
-
-@item -fuse-ld=lld
-@opindex fuse-ld=lld
-Use the LLVM @command{lld} linker instead of the default linker.
+@item -fuse-ld=@var{linker}
+@opindex fuse-ld=linker
+If @var{linker} is an absolute path, use it instead of the default linker;
+otherwise use @command{ld.@var{linker}}.
 
 @cindex Libraries
 @item -l@var{library}
diff --git a/gcc/gcc.c b/gcc/gcc.c
index effc384f3ef..f9a6f10502d 100644
--- a/gcc/gcc.c
+++ b/gcc/gcc.c
@@ -3989,12 +3989,8 @@  driver_handle_option (struct gcc_options *opts,
       do_save = false;
       break;
 
-    case OPT_fuse_ld_bfd:
-       use_ld = ".bfd";
-       break;
-
-    case OPT_fuse_ld_gold:
-       use_ld = ".gold";
+    case OPT_fuse_ld_:
+       use_ld = arg;
        break;
 
     case OPT_fcompare_debug_second:
@@ -7903,20 +7899,20 @@  driver::maybe_print_and_exit () const
 	      if (! strcmp (&default_linker[len], HOST_EXECUTABLE_SUFFIX))
 		{
 		  default_linker[len] = '\0';
-		  ld = concat (default_linker, use_ld,
+		  ld = concat (default_linker, ".", use_ld,
 			       HOST_EXECUTABLE_SUFFIX, NULL);
 		}
 	    }
 	  if (ld == NULL)
 # endif
-	  ld = concat (DEFAULT_LINKER, use_ld, NULL);
+	  ld = concat (DEFAULT_LINKER, ".", use_ld, NULL);
 	  if (access (ld, X_OK) == 0)
 	    {
 	      printf ("%s\n", ld);
 	      return (0);
 	    }
 #endif
-	  print_prog_name = concat (print_prog_name, use_ld, NULL);
+	  print_prog_name = concat (print_prog_name, ".", use_ld, NULL);
 	}
       char *newname = find_a_file (&exec_prefixes, print_prog_name, X_OK, 0);
       printf ("%s\n", (newname ? newname : print_prog_name));
diff --git a/gcc/opts.c b/gcc/opts.c
index 7affeb41a96..f50d365d517 100644
--- a/gcc/opts.c
+++ b/gcc/opts.c
@@ -2763,9 +2763,7 @@  common_handle_option (struct gcc_options *opts,
       dc->max_errors = value;
       break;
 
-    case OPT_fuse_ld_bfd:
-    case OPT_fuse_ld_gold:
-    case OPT_fuse_ld_lld:
+    case OPT_fuse_ld_:
     case OPT_fuse_linker_plugin:
       /* No-op. Used by the driver and passed to us because it starts with f.*/
       break;