2828#include " llvm/Support/ErrorOr.h"
2929#include " llvm/Support/FileOutputBuffer.h"
3030#include " llvm/Support/InitLLVM.h"
31+ #include " llvm/Support/Path.h"
3132#include " llvm/Support/raw_ostream.h"
3233#include < algorithm>
3334#include < cassert>
@@ -45,17 +46,17 @@ using namespace ELF;
4546
4647namespace {
4748
48- enum ID {
49+ enum ObjcopyID {
4950 OBJCOPY_INVALID = 0 , // This is not an option ID.
5051#define OPTION (PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
5152 HELPTEXT, METAVAR, VALUES) \
5253 OBJCOPY_##ID,
53- #include " Opts .inc"
54+ #include " ObjcopyOpts .inc"
5455#undef OPTION
5556};
5657
5758#define PREFIX (NAME, VALUE ) const char *const NAME[] = VALUE;
58- #include " Opts .inc"
59+ #include " ObjcopyOpts .inc"
5960#undef PREFIX
6061
6162static const opt::OptTable::Info ObjcopyInfoTable[] = {
@@ -65,7 +66,7 @@ static const opt::OptTable::Info ObjcopyInfoTable[] = {
6566 METAVAR, OBJCOPY_##ID, opt::Option::KIND##Class, \
6667 PARAM, FLAGS, OBJCOPY_##GROUP, \
6768 OBJCOPY_##ALIAS, ALIASARGS, VALUES},
68- #include " Opts .inc"
69+ #include " ObjcopyOpts .inc"
6970#undef OPTION
7071};
7172
@@ -74,6 +75,31 @@ class ObjcopyOptTable : public opt::OptTable {
7475 ObjcopyOptTable () : OptTable(ObjcopyInfoTable, true ) {}
7576};
7677
78+ enum StripID {
79+ STRIP_INVALID = 0 , // This is not an option ID.
80+ #define OPTION (PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
81+ HELPTEXT, METAVAR, VALUES) \
82+ STRIP_##ID,
83+ #include " StripOpts.inc"
84+ #undef OPTION
85+ };
86+
87+ static const opt::OptTable::Info StripInfoTable[] = {
88+ #define OPTION (PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
89+ HELPTEXT, METAVAR, VALUES) \
90+ {PREFIX, NAME, HELPTEXT, \
91+ METAVAR, STRIP_##ID, opt::Option::KIND##Class, \
92+ PARAM, FLAGS, STRIP_##GROUP, \
93+ STRIP_##ALIAS, ALIASARGS, VALUES},
94+ #include " StripOpts.inc"
95+ #undef OPTION
96+ };
97+
98+ class StripOptTable : public opt ::OptTable {
99+ public:
100+ StripOptTable () : OptTable(StripInfoTable, true ) {}
101+ };
102+
77103} // namespace
78104
79105// The name this program was invoked as.
@@ -122,16 +148,16 @@ struct CopyConfig {
122148 std::vector<StringRef> SymbolsToGlobalize;
123149 std::vector<StringRef> SymbolsToWeaken;
124150 StringMap<StringRef> SymbolsToRename;
125- bool StripAll;
126- bool StripAllGNU;
127- bool StripDebug;
128- bool StripSections;
129- bool StripNonAlloc;
130- bool StripDWO;
131- bool ExtractDWO;
132- bool LocalizeHidden;
133- bool Weaken;
134- bool DiscardAll;
151+ bool StripAll = false ;
152+ bool StripAllGNU = false ;
153+ bool StripDebug = false ;
154+ bool StripSections = false ;
155+ bool StripNonAlloc = false ;
156+ bool StripDWO = false ;
157+ bool ExtractDWO = false ;
158+ bool LocalizeHidden = false ;
159+ bool Weaken = false ;
160+ bool DiscardAll = false ;
135161};
136162
137163using SectionPred = std::function<bool (const SectionBase &Sec)>;
@@ -449,10 +475,50 @@ CopyConfig ParseObjcopyOptions(ArrayRef<const char *> ArgsArr) {
449475 return Config;
450476}
451477
478+ // ParseStripOptions returns the config and sets the input arguments. If a
479+ // help flag is set then ParseStripOptions will print the help messege and
480+ // exit.
481+ CopyConfig ParseStripOptions (ArrayRef<const char *> ArgsArr) {
482+ StripOptTable T;
483+ unsigned MissingArgumentIndex, MissingArgumentCount;
484+ llvm::opt::InputArgList InputArgs =
485+ T.ParseArgs (ArgsArr, MissingArgumentIndex, MissingArgumentCount);
486+
487+ if (InputArgs.size () == 0 || InputArgs.hasArg (STRIP_help)) {
488+ T.PrintHelp (outs (), " llvm-strip <input> [ <output> ]" , " strip tool" );
489+ exit (0 );
490+ }
491+
492+ SmallVector<const char *, 2 > Positional;
493+ for (auto Arg : InputArgs.filtered (STRIP_UNKNOWN))
494+ error (" unknown argument '" + Arg->getAsString (InputArgs) + " '" );
495+ for (auto Arg : InputArgs.filtered (STRIP_INPUT))
496+ Positional.push_back (Arg->getValue ());
497+
498+ if (Positional.empty ())
499+ error (" No input file specified" );
500+
501+ if (Positional.size () > 2 )
502+ error (" Support for multiple input files is not implemented yet" );
503+
504+ CopyConfig Config;
505+ Config.InputFilename = Positional[0 ];
506+ Config.OutputFilename = Positional[0 ];
507+
508+ // Strip debug info only.
509+ Config.StripDebug = InputArgs.hasArg (STRIP_strip_debug);
510+ if (!Config.StripDebug )
511+ Config.StripAll = true ;
512+ return Config;
513+ }
514+
452515int main (int argc, char **argv) {
453516 InitLLVM X (argc, argv);
454517 ToolName = argv[0 ];
455-
456- CopyConfig Config = ParseObjcopyOptions (makeArrayRef (argv + 1 , argc));
518+ CopyConfig Config;
519+ if (sys::path::stem (ToolName).endswith_lower (" strip" ))
520+ Config = ParseStripOptions (makeArrayRef (argv + 1 , argc));
521+ else
522+ Config = ParseObjcopyOptions (makeArrayRef (argv + 1 , argc));
457523 ExecuteElfObjcopy (Config);
458524}
0 commit comments