diff options
Diffstat (limited to 'llvm/tools/llvm-objcopy')
-rw-r--r-- | llvm/tools/llvm-objcopy/CMakeLists.txt | 15 | ||||
-rw-r--r-- | llvm/tools/llvm-objcopy/ObjcopyOpts.td (renamed from llvm/tools/llvm-objcopy/Opts.td) | 0 | ||||
-rw-r--r-- | llvm/tools/llvm-objcopy/StripOpts.td | 12 | ||||
-rw-r--r-- | llvm/tools/llvm-objcopy/llvm-objcopy.cpp | 98 |
4 files changed, 105 insertions, 20 deletions
diff --git a/llvm/tools/llvm-objcopy/CMakeLists.txt b/llvm/tools/llvm-objcopy/CMakeLists.txt index c2d2d798b38..b0cd66be5b3 100644 --- a/llvm/tools/llvm-objcopy/CMakeLists.txt +++ b/llvm/tools/llvm-objcopy/CMakeLists.txt @@ -5,18 +5,25 @@ set(LLVM_LINK_COMPONENTS MC ) -set(LLVM_TARGET_DEFINITIONS Opts.td) +set(LLVM_TARGET_DEFINITIONS ObjcopyOpts.td) +tablegen(LLVM ObjcopyOpts.inc -gen-opt-parser-defs) +add_public_tablegen_target(ObjcopyOptsTableGen) -tablegen(LLVM Opts.inc -gen-opt-parser-defs) -add_public_tablegen_target(ObjcopyTableGen) +set(LLVM_TARGET_DEFINITIONS StripOpts.td) +tablegen(LLVM StripOpts.inc -gen-opt-parser-defs) +add_public_tablegen_target(StripOptsTableGen) add_llvm_tool(llvm-objcopy llvm-objcopy.cpp Object.cpp DEPENDS - ObjcopyTableGen + ObjcopyOptsTableGen + StripOptsTableGen ) +add_llvm_tool_symlink(llvm-strip llvm-objcopy) + if(LLVM_INSTALL_BINUTILS_SYMLINKS) add_llvm_tool_symlink(objcopy llvm-objcopy) + add_llvm_tool_symlink(strip llvm-objcopy) endif() diff --git a/llvm/tools/llvm-objcopy/Opts.td b/llvm/tools/llvm-objcopy/ObjcopyOpts.td index 487a3125f00..487a3125f00 100644 --- a/llvm/tools/llvm-objcopy/Opts.td +++ b/llvm/tools/llvm-objcopy/ObjcopyOpts.td diff --git a/llvm/tools/llvm-objcopy/StripOpts.td b/llvm/tools/llvm-objcopy/StripOpts.td new file mode 100644 index 00000000000..3266c89bda0 --- /dev/null +++ b/llvm/tools/llvm-objcopy/StripOpts.td @@ -0,0 +1,12 @@ +include "llvm/Option/OptParser.td" + +multiclass Eq<string name> { + def NAME: Separate<["--", "-"], name>; + def NAME # _eq: Joined<["--", "-"], name # "=">, Alias<!cast<Separate>(NAME)>; +} + +def help : Flag<["-", "--"], "help">; + +def strip_debug : Flag<["-", "--"], "strip-debug">, + HelpText<"Remove debugging symbols only">; + diff --git a/llvm/tools/llvm-objcopy/llvm-objcopy.cpp b/llvm/tools/llvm-objcopy/llvm-objcopy.cpp index 900a11d04a1..295c9bf9285 100644 --- a/llvm/tools/llvm-objcopy/llvm-objcopy.cpp +++ b/llvm/tools/llvm-objcopy/llvm-objcopy.cpp @@ -28,6 +28,7 @@ #include "llvm/Support/ErrorOr.h" #include "llvm/Support/FileOutputBuffer.h" #include "llvm/Support/InitLLVM.h" +#include "llvm/Support/Path.h" #include "llvm/Support/raw_ostream.h" #include <algorithm> #include <cassert> @@ -45,17 +46,17 @@ using namespace ELF; namespace { -enum ID { +enum ObjcopyID { OBJCOPY_INVALID = 0, // This is not an option ID. #define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \ HELPTEXT, METAVAR, VALUES) \ OBJCOPY_##ID, -#include "Opts.inc" +#include "ObjcopyOpts.inc" #undef OPTION }; #define PREFIX(NAME, VALUE) const char *const NAME[] = VALUE; -#include "Opts.inc" +#include "ObjcopyOpts.inc" #undef PREFIX static const opt::OptTable::Info ObjcopyInfoTable[] = { @@ -65,7 +66,7 @@ static const opt::OptTable::Info ObjcopyInfoTable[] = { METAVAR, OBJCOPY_##ID, opt::Option::KIND##Class, \ PARAM, FLAGS, OBJCOPY_##GROUP, \ OBJCOPY_##ALIAS, ALIASARGS, VALUES}, -#include "Opts.inc" +#include "ObjcopyOpts.inc" #undef OPTION }; @@ -74,6 +75,31 @@ public: ObjcopyOptTable() : OptTable(ObjcopyInfoTable, true) {} }; +enum StripID { + STRIP_INVALID = 0, // This is not an option ID. +#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \ + HELPTEXT, METAVAR, VALUES) \ + STRIP_##ID, +#include "StripOpts.inc" +#undef OPTION +}; + +static const opt::OptTable::Info StripInfoTable[] = { +#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \ + HELPTEXT, METAVAR, VALUES) \ + {PREFIX, NAME, HELPTEXT, \ + METAVAR, STRIP_##ID, opt::Option::KIND##Class, \ + PARAM, FLAGS, STRIP_##GROUP, \ + STRIP_##ALIAS, ALIASARGS, VALUES}, +#include "StripOpts.inc" +#undef OPTION +}; + +class StripOptTable : public opt::OptTable { +public: + StripOptTable() : OptTable(StripInfoTable, true) {} +}; + } // namespace // The name this program was invoked as. @@ -122,16 +148,16 @@ struct CopyConfig { std::vector<StringRef> SymbolsToGlobalize; std::vector<StringRef> SymbolsToWeaken; StringMap<StringRef> SymbolsToRename; - bool StripAll; - bool StripAllGNU; - bool StripDebug; - bool StripSections; - bool StripNonAlloc; - bool StripDWO; - bool ExtractDWO; - bool LocalizeHidden; - bool Weaken; - bool DiscardAll; + bool StripAll = false; + bool StripAllGNU = false; + bool StripDebug = false; + bool StripSections = false; + bool StripNonAlloc = false; + bool StripDWO = false; + bool ExtractDWO = false; + bool LocalizeHidden = false; + bool Weaken = false; + bool DiscardAll = false; }; using SectionPred = std::function<bool(const SectionBase &Sec)>; @@ -449,10 +475,50 @@ CopyConfig ParseObjcopyOptions(ArrayRef<const char *> ArgsArr) { return Config; } +// ParseStripOptions returns the config and sets the input arguments. If a +// help flag is set then ParseStripOptions will print the help messege and +// exit. +CopyConfig ParseStripOptions(ArrayRef<const char *> ArgsArr) { + StripOptTable T; + unsigned MissingArgumentIndex, MissingArgumentCount; + llvm::opt::InputArgList InputArgs = + T.ParseArgs(ArgsArr, MissingArgumentIndex, MissingArgumentCount); + + if (InputArgs.size() == 0 || InputArgs.hasArg(STRIP_help)) { + T.PrintHelp(outs(), "llvm-strip <input> [ <output> ]", "strip tool"); + exit(0); + } + + SmallVector<const char *, 2> Positional; + for (auto Arg : InputArgs.filtered(STRIP_UNKNOWN)) + error("unknown argument '" + Arg->getAsString(InputArgs) + "'"); + for (auto Arg : InputArgs.filtered(STRIP_INPUT)) + Positional.push_back(Arg->getValue()); + + if (Positional.empty()) + error("No input file specified"); + + if (Positional.size() > 2) + error("Support for multiple input files is not implemented yet"); + + CopyConfig Config; + Config.InputFilename = Positional[0]; + Config.OutputFilename = Positional[0]; + + // Strip debug info only. + Config.StripDebug = InputArgs.hasArg(STRIP_strip_debug); + if (!Config.StripDebug) + Config.StripAll = true; + return Config; +} + int main(int argc, char **argv) { InitLLVM X(argc, argv); ToolName = argv[0]; - - CopyConfig Config = ParseObjcopyOptions(makeArrayRef(argv + 1, argc)); + CopyConfig Config; + if (sys::path::stem(ToolName).endswith_lower("strip")) + Config = ParseStripOptions(makeArrayRef(argv + 1, argc)); + else + Config = ParseObjcopyOptions(makeArrayRef(argv + 1, argc)); ExecuteElfObjcopy(Config); } |