Message ID | 20200210000234.aemsyusopeatxb6i@google.com |
---|---|
State | New |
Headers | show |
Series | Generalize -fuse-ld= to support absolute path or arbitrary ld.linker | expand |
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:)
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
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
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; >
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; >> >
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 --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;