From 591d889006e80d3d87bcac200c4c454a878c9f24 Mon Sep 17 00:00:00 2001 From: Jordan Rupprecht Date: Wed, 5 Sep 2018 13:10:03 +0000 Subject: [llvm-strip] Support stripping multiple input files Summary: Allow strip to be called on multiple input files, which is interpreted as stripping N files in place. Using multiple input files is incompatible with -o. To allow this, create a `DriverConfig` struct which just wraps a list of `CopyConfigs`. objcopy will only ever have a single `CopyConfig`, but strip will have N (where N >= 1) CopyConfigs. Reviewers: alexshap, jakehehrlich Reviewed By: alexshap, jakehehrlich Subscribers: MaskRay, jakehehrlich, llvm-commits Differential Revision: https://reviews.llvm.org/D51660 llvm-svn: 341464 --- llvm/tools/llvm-objcopy/llvm-objcopy.cpp | 49 +++++++++++++++++++++++--------- 1 file changed, 35 insertions(+), 14 deletions(-) (limited to 'llvm/tools') diff --git a/llvm/tools/llvm-objcopy/llvm-objcopy.cpp b/llvm/tools/llvm-objcopy/llvm-objcopy.cpp index 72501f3eb98..8ffab544421 100644 --- a/llvm/tools/llvm-objcopy/llvm-objcopy.cpp +++ b/llvm/tools/llvm-objcopy/llvm-objcopy.cpp @@ -128,6 +128,7 @@ struct SectionRename { Optional NewFlags; }; +// Configuration for copying/stripping a single file. struct CopyConfig { // Main input/output options StringRef InputFilename; @@ -177,6 +178,13 @@ struct CopyConfig { bool Weaken = false; }; +// Configuration for the overall invocation of this tool. When invoked as +// objcopy, will always contain exactly one CopyConfig. When invoked as strip, +// will contain one or more CopyConfigs. +struct DriverConfig { + SmallVector CopyConfigs; +}; + using SectionPred = std::function; enum SectionFlag { @@ -818,7 +826,7 @@ static void addGlobalSymbolsFromFile(std::vector &Symbols, // ParseObjcopyOptions returns the config and sets the input arguments. If a // help flag is set then ParseObjcopyOptions will print the help messege and // exit. -static CopyConfig parseObjcopyOptions(ArrayRef ArgsArr) { +static DriverConfig parseObjcopyOptions(ArrayRef ArgsArr) { ObjcopyOptTable T; unsigned MissingArgumentIndex, MissingArgumentCount; llvm::opt::InputArgList InputArgs = @@ -918,13 +926,15 @@ static CopyConfig parseObjcopyOptions(ArrayRef ArgsArr) { Config.PreserveDates = InputArgs.hasArg(OBJCOPY_preserve_dates); - return Config; + DriverConfig DC; + DC.CopyConfigs.push_back(std::move(Config)); + return DC; } // ParseStripOptions returns the config and sets the input arguments. If a // help flag is set then ParseStripOptions will print the help messege and // exit. -static CopyConfig parseStripOptions(ArrayRef ArgsArr) { +static DriverConfig parseStripOptions(ArrayRef ArgsArr) { StripOptTable T; unsigned MissingArgumentIndex, MissingArgumentCount; llvm::opt::InputArgList InputArgs = @@ -949,14 +959,10 @@ static CopyConfig parseStripOptions(ArrayRef ArgsArr) { if (Positional.empty()) error("No input file specified"); - if (Positional.size() > 1) - error("Support for multiple input files is not implemented yet"); + if (Positional.size() > 1 && InputArgs.hasArg(STRIP_output)) + error("Multiple input files cannot be used in combination with -o"); CopyConfig Config; - Config.InputFilename = Positional[0]; - Config.OutputFilename = - InputArgs.getLastArgValue(STRIP_output, Positional[0]); - Config.StripDebug = InputArgs.hasArg(STRIP_strip_debug); Config.DiscardAll = InputArgs.hasArg(STRIP_discard_all); @@ -974,16 +980,31 @@ static CopyConfig parseStripOptions(ArrayRef ArgsArr) { Config.PreserveDates = InputArgs.hasArg(STRIP_preserve_dates); - return Config; + DriverConfig DC; + if (Positional.size() == 1) { + Config.InputFilename = Positional[0]; + Config.OutputFilename = + InputArgs.getLastArgValue(STRIP_output, Positional[0]); + DC.CopyConfigs.push_back(std::move(Config)); + } else { + for (const char *Filename : Positional) { + Config.InputFilename = Filename; + Config.OutputFilename = Filename; + DC.CopyConfigs.push_back(Config); + } + } + + return DC; } int main(int argc, char **argv) { InitLLVM X(argc, argv); ToolName = argv[0]; - CopyConfig Config; + DriverConfig DriverConfig; if (sys::path::stem(ToolName).endswith_lower("strip")) - Config = parseStripOptions(makeArrayRef(argv + 1, argc)); + DriverConfig = parseStripOptions(makeArrayRef(argv + 1, argc)); else - Config = parseObjcopyOptions(makeArrayRef(argv + 1, argc)); - executeElfObjcopy(Config); + DriverConfig = parseObjcopyOptions(makeArrayRef(argv + 1, argc)); + for (const CopyConfig &CopyConfig : DriverConfig.CopyConfigs) + executeElfObjcopy(CopyConfig); } -- cgit v1.2.3