diff options
author | Alexander Shaposhnikov <shal1t712@gmail.com> | 2018-05-07 19:32:09 +0000 |
---|---|---|
committer | Alexander Shaposhnikov <shal1t712@gmail.com> | 2018-05-07 19:32:09 +0000 |
commit | cca69985045e00a1fe5612e11587cf8065b6e8be (patch) | |
tree | cfbfd41e5a243405ab05b0323e65e4fea704a8bb /llvm/tools/llvm-objcopy/llvm-objcopy.cpp | |
parent | 440d76c5597c5f56ce2d1099d072282cb918818a (diff) | |
download | bcm5719-llvm-cca69985045e00a1fe5612e11587cf8065b6e8be.tar.gz bcm5719-llvm-cca69985045e00a1fe5612e11587cf8065b6e8be.zip |
[tools] Introduce llvm-strip
llvm-strip is supposed to be a drop-in replacement for binutils strip.
To start the ball rolling this diff adds the initial bits for llvm-strip,
more features will be added incrementally over time.
Test plan: make check-all
Differential revision: https://reviews.llvm.org/D46407
llvm-svn: 331663
Diffstat (limited to 'llvm/tools/llvm-objcopy/llvm-objcopy.cpp')
-rw-r--r-- | llvm/tools/llvm-objcopy/llvm-objcopy.cpp | 98 |
1 files changed, 82 insertions, 16 deletions
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); } |