From: Fangrui Song Date: Tue, 14 Apr 2020 21:17:29 +0000 (-0700) Subject: [ELF] Refactor the way we handle -plugin-opt= (GCC collect2 or clang LTO related... X-Git-Tag: llvmorg-12-init~8963 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=cd5d5ce235081005173566c99c592550021de058;p=platform%2Fupstream%2Fllvm.git [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 --- diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp index 2aeeb84..d223ed4 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 83b9fa4..8dd5251 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 0370d45..2935bad 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'