[lld] cd5d5ce - [ELF] Refactor the way we handle -plugin-opt= (GCC collect2 or clang LTO related options)

Fangrui Song via llvm-commits llvm-commits at lists.llvm.org
Wed Apr 15 08:01:09 PDT 2020


Author: Fangrui Song
Date: 2020-04-15T08:00:50-07:00
New Revision: cd5d5ce235081005173566c99c592550021de058

URL: https://github.com/llvm/llvm-project/commit/cd5d5ce235081005173566c99c592550021de058
DIFF: https://github.com/llvm/llvm-project/commit/cd5d5ce235081005173566c99c592550021de058.diff

LOG: [ELF] Refactor the way we handle -plugin-opt= (GCC collect2 or clang LTO related options)

GCC collect2 passes several options to the linker even if LTO is not used
(note, lld does not support GCC LTO). The lto-wrapper may be a relative
path (especially during development, when gcc is in a build directory), e.g.

  -plugin-opt=relative/path/to/lto-wrapper

We need to ignore such options, which are currently interpreted by
cl::ParseCommandLineOptions() and will fail with `error: --plugin-opt: ld.lld: Unknown command line argument 'relative/path/to/lto-wrapper'`
because the path is apparently not an option registered by an `llvm::cl::opt`.

See lto-plugin-ignore.s for how we interpret various -plugin-opt= options now.

Reviewed By: grimar, tejohnson

Differential Revision: https://reviews.llvm.org/D78158

Added: 
    

Modified: 
    lld/ELF/Driver.cpp
    lld/ELF/Options.td
    lld/test/ELF/lto-plugin-ignore.s

Removed: 
    


################################################################################
diff  --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp
index 2aeeb84f5af9..d223ed47b461 100644
--- a/lld/ELF/Driver.cpp
+++ b/lld/ELF/Driver.cpp
@@ -1035,8 +1035,16 @@ static void readConfigs(opt::InputArgList &args) {
     parseClangOption(saver.save("-mcpu=" + StringRef(arg->getValue())),
                      arg->getSpelling());
 
-  for (auto *arg : args.filtered(OPT_plugin_opt))
-    parseClangOption(arg->getValue(), arg->getSpelling());
+  for (opt::Arg *arg : args.filtered(OPT_plugin_opt_eq_minus))
+    parseClangOption(std::string("-") + arg->getValue(), arg->getSpelling());
+
+  // GCC collect2 passes -plugin-opt=path/to/lto-wrapper with an absolute or
+  // relative path. Just ignore. If not ended with "lto-wrapper", consider it an
+  // unsupported LLVMgold.so option and error.
+  for (opt::Arg *arg : args.filtered(OPT_plugin_opt_eq))
+    if (!StringRef(arg->getValue()).endswith("lto-wrapper"))
+      error(arg->getSpelling() + ": unknown plugin option '" + arg->getValue() +
+            "'");
 
   // Parse -mllvm options.
   for (auto *arg : args.filtered(OPT_mllvm))

diff  --git a/lld/ELF/Options.td b/lld/ELF/Options.td
index 83b9fa467033..8dd525130a70 100644
--- a/lld/ELF/Options.td
+++ b/lld/ELF/Options.td
@@ -504,7 +504,6 @@ def opt_remarks_with_hotness: Flag<["--"], "opt-remarks-with-hotness">,
   HelpText<"Include hotness information in the optimization remarks file">;
 def opt_remarks_format: Separate<["--"], "opt-remarks-format">,
   HelpText<"The format used for serializing remarks (default: YAML)">;
-defm plugin_opt: Eq<"plugin-opt", "specifies LTO options for compatibility with GNU linkers">;
 def save_temps: F<"save-temps">;
 def lto_basicblock_sections: J<"lto-basicblock-sections=">,
   HelpText<"Enable basic block sections for LTO">;
@@ -571,10 +570,17 @@ def: J<"plugin-opt=thinlto-prefix-replace=">,
 // --version output.
 defm plugin: Eq<"plugin", "Ignored for compatibility with GNU linkers">;
 
-def plugin_opt_fresolution_eq: J<"plugin-opt=-fresolution=">;
-def plugin_opt_pass_through_eq: J<"plugin-opt=-pass-through=">;
-def plugin_opt_thinlto: J<"plugin-opt=thinlto">;
-def plugin_opt_slash: J<"plugin-opt=/">;
+def plugin_opt_eq_minus: J<"plugin-opt=-">,
+  HelpText<"Specify an LLVM option for compatibility with LLVMgold.so">;
+def: J<"plugin-opt=thinlto">;
+
+// Ignore GCC collect2 LTO plugin related options. Note that we don't support
+// GCC LTO, but GCC collect2 passes these options even in non-LTO mode.
+def: J<"plugin-opt=-fresolution=">;
+def: J<"plugin-opt=-pass-through=">;
+// This may be either an unhandled LLVMgold.so feature or GCC passed
+// -plugin-opt=path/to/{liblto_plugin.so,lto-wrapper}
+def plugin_opt_eq : J<"plugin-opt=">;
 
 // Options listed below are silently ignored for now for compatibility.
 def: F<"detect-odr-violations">;

diff  --git a/lld/test/ELF/lto-plugin-ignore.s b/lld/test/ELF/lto-plugin-ignore.s
index 0370d458626b..2935bad149de 100644
--- a/lld/test/ELF/lto-plugin-ignore.s
+++ b/lld/test/ELF/lto-plugin-ignore.s
@@ -1,10 +1,28 @@
 # REQUIRES: x86
+## Test we ignore some LTO related options from clang/GCC collect2.
 
-# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
-# RUN: ld.lld %t -plugin-opt=/foo/bar -plugin-opt=-fresolution=zed \
-# RUN:   -plugin-opt=-pass-through=-lgcc -plugin-opt=-function-sections \
-# RUN:   -plugin-opt=-data-sections -plugin-opt=thinlto -o /dev/null
+# RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t.o
 
-# RUN: not ld.lld %t -plugin-opt=-abc -plugin-opt=-xyz 2>&1 | FileCheck %s
-# CHECK: ld.lld: error: --plugin-opt: ld.lld{{.*}}: Unknown command line argument '-abc'
-# CHECK: ld.lld: error: --plugin-opt: ld.lld{{.*}}: Unknown command line argument '-xyz'
+## GCC collect2 passes several LTO related options to the linker even if -flto is not used.
+## We need to ignore them. Note that the lto-wrapper path can be relative.
+# RUN: ld.lld %t.o -o /dev/null \
+# RUN:   -plugin path/to/liblto_plugin.so \
+# RUN:   -plugin-opt=/path/to/lto-wrapper \
+# RUN:   -plugin-opt=relative/path/to/lto-wrapper \
+# RUN:   -plugin-opt=-fresolution=zed \
+# RUN:   -plugin-opt=-pass-through=-lgcc \
+# RUN:   -plugin-opt=-pass-through=-lgcc_eh \
+# RUN:   -plugin-opt=-pass-through=-lc
+
+## Clang LTO passes several options to the linker, which are intended to be consumed by
+## LLVMgold.so. We need to ignore them.
+# RUN: ld.lld %t.o -o /dev/null -plugin /path/to/LLVMgold.so -plugin-opt=thinlto
+
+## Other -plugin-opt=- prefixed options are passed through to cl::ParseCommandLineOptions.
+# RUN: not ld.lld %t.o -o /dev/null -plugin-opt=-abc -plugin-opt=-xyz 2>&1 | FileCheck %s
+# CHECK: ld.lld: error: -plugin-opt=-: ld.lld{{.*}}: Unknown command line argument '-abc'
+# CHECK: ld.lld: error: -plugin-opt=-: ld.lld{{.*}}: Unknown command line argument '-xyz'
+
+## Error if the option is an unhandled LLVMgold.so feature.
+# RUN: not ld.lld %t.o -o /dev/null -plugin-opt=LLVMgold-feature 2>&1 | FileCheck --check-prefix=GOLD %s
+# GOLD: ld.lld: error: -plugin-opt=: unknown plugin option 'LLVMgold-feature'


        


More information about the llvm-commits mailing list