28
28
#include " llvm/Support/ErrorOr.h"
29
29
#include " llvm/Support/FileOutputBuffer.h"
30
30
#include " llvm/Support/InitLLVM.h"
31
+ #include " llvm/Support/Path.h"
31
32
#include " llvm/Support/raw_ostream.h"
32
33
#include < algorithm>
33
34
#include < cassert>
@@ -45,17 +46,17 @@ using namespace ELF;
45
46
46
47
namespace {
47
48
48
- enum ID {
49
+ enum ObjcopyID {
49
50
OBJCOPY_INVALID = 0 , // This is not an option ID.
50
51
#define OPTION (PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
51
52
HELPTEXT, METAVAR, VALUES) \
52
53
OBJCOPY_##ID,
53
- #include " Opts .inc"
54
+ #include " ObjcopyOpts .inc"
54
55
#undef OPTION
55
56
};
56
57
57
58
#define PREFIX (NAME, VALUE ) const char *const NAME[] = VALUE;
58
- #include " Opts .inc"
59
+ #include " ObjcopyOpts .inc"
59
60
#undef PREFIX
60
61
61
62
static const opt::OptTable::Info ObjcopyInfoTable[] = {
@@ -65,7 +66,7 @@ static const opt::OptTable::Info ObjcopyInfoTable[] = {
65
66
METAVAR, OBJCOPY_##ID, opt::Option::KIND##Class, \
66
67
PARAM, FLAGS, OBJCOPY_##GROUP, \
67
68
OBJCOPY_##ALIAS, ALIASARGS, VALUES},
68
- #include " Opts .inc"
69
+ #include " ObjcopyOpts .inc"
69
70
#undef OPTION
70
71
};
71
72
@@ -74,6 +75,31 @@ class ObjcopyOptTable : public opt::OptTable {
74
75
ObjcopyOptTable () : OptTable(ObjcopyInfoTable, true ) {}
75
76
};
76
77
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
+
77
103
} // namespace
78
104
79
105
// The name this program was invoked as.
@@ -122,16 +148,16 @@ struct CopyConfig {
122
148
std::vector<StringRef> SymbolsToGlobalize;
123
149
std::vector<StringRef> SymbolsToWeaken;
124
150
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 ;
135
161
};
136
162
137
163
using SectionPred = std::function<bool (const SectionBase &Sec)>;
@@ -449,10 +475,50 @@ CopyConfig ParseObjcopyOptions(ArrayRef<const char *> ArgsArr) {
449
475
return Config;
450
476
}
451
477
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
+
452
515
int main (int argc, char **argv) {
453
516
InitLLVM X (argc, argv);
454
517
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));
457
523
ExecuteElfObjcopy (Config);
458
524
}
0 commit comments