xref: /llvm-project/llvm/tools/llvm-objcopy/ObjcopyOptions.cpp (revision 10772807ab72ce2b68d76816f8753219b2acbac3)
1 //===- ObjcopyOptions.cpp -------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "ObjcopyOptions.h"
10 #include "llvm/ADT/SmallVector.h"
11 #include "llvm/ADT/StringExtras.h"
12 #include "llvm/ADT/StringRef.h"
13 #include "llvm/ADT/StringSwitch.h"
14 #include "llvm/BinaryFormat/COFF.h"
15 #include "llvm/ObjCopy/CommonConfig.h"
16 #include "llvm/ObjCopy/ConfigManager.h"
17 #include "llvm/ObjCopy/MachO/MachOConfig.h"
18 #include "llvm/Object/Binary.h"
19 #include "llvm/Option/Arg.h"
20 #include "llvm/Option/ArgList.h"
21 #include "llvm/Support/CRC.h"
22 #include "llvm/Support/CommandLine.h"
23 #include "llvm/Support/Compression.h"
24 #include "llvm/Support/Errc.h"
25 #include "llvm/Support/Error.h"
26 #include "llvm/Support/MemoryBuffer.h"
27 
28 using namespace llvm;
29 using namespace llvm::objcopy;
30 using namespace llvm::object;
31 using namespace llvm::opt;
32 
33 namespace {
34 enum ObjcopyID {
35   OBJCOPY_INVALID = 0, // This is not an option ID.
36 #define OPTION(...) LLVM_MAKE_OPT_ID_WITH_ID_PREFIX(OBJCOPY_, __VA_ARGS__),
37 #include "ObjcopyOpts.inc"
38 #undef OPTION
39 };
40 
41 namespace objcopy_opt {
42 #define OPTTABLE_STR_TABLE_CODE
43 #include "ObjcopyOpts.inc"
44 #undef OPTTABLE_STR_TABLE_CODE
45 
46 #define OPTTABLE_PREFIXES_TABLE_CODE
47 #include "ObjcopyOpts.inc"
48 #undef OPTTABLE_PREFIXES_TABLE_CODE
49 
50 static constexpr opt::OptTable::Info ObjcopyInfoTable[] = {
51 #define OPTION(...)                                                            \
52   LLVM_CONSTRUCT_OPT_INFO_WITH_ID_PREFIX(OBJCOPY_, __VA_ARGS__),
53 #include "ObjcopyOpts.inc"
54 #undef OPTION
55 };
56 } // namespace objcopy_opt
57 
58 class ObjcopyOptTable : public opt::GenericOptTable {
59 public:
60   ObjcopyOptTable()
61       : opt::GenericOptTable(objcopy_opt::OptionStrTable,
62                              objcopy_opt::OptionPrefixesTable,
63                              objcopy_opt::ObjcopyInfoTable) {
64     setGroupedShortOptions(true);
65     setDashDashParsing(true);
66   }
67 };
68 
69 enum InstallNameToolID {
70   INSTALL_NAME_TOOL_INVALID = 0, // This is not an option ID.
71 #define OPTION(...)                                                            \
72   LLVM_MAKE_OPT_ID_WITH_ID_PREFIX(INSTALL_NAME_TOOL_, __VA_ARGS__),
73 #include "InstallNameToolOpts.inc"
74 #undef OPTION
75 };
76 
77 namespace install_name_tool {
78 #define OPTTABLE_STR_TABLE_CODE
79 #include "InstallNameToolOpts.inc"
80 #undef OPTTABLE_STR_TABLE_CODE
81 
82 #define OPTTABLE_PREFIXES_TABLE_CODE
83 #include "InstallNameToolOpts.inc"
84 #undef OPTTABLE_PREFIXES_TABLE_CODE
85 
86 static constexpr opt::OptTable::Info InstallNameToolInfoTable[] = {
87 #define OPTION(...)                                                            \
88   LLVM_CONSTRUCT_OPT_INFO_WITH_ID_PREFIX(INSTALL_NAME_TOOL_, __VA_ARGS__),
89 #include "InstallNameToolOpts.inc"
90 #undef OPTION
91 };
92 } // namespace install_name_tool
93 
94 class InstallNameToolOptTable : public opt::GenericOptTable {
95 public:
96   InstallNameToolOptTable()
97       : GenericOptTable(install_name_tool::OptionStrTable,
98                         install_name_tool::OptionPrefixesTable,
99                         install_name_tool::InstallNameToolInfoTable) {}
100 };
101 
102 enum BitcodeStripID {
103   BITCODE_STRIP_INVALID = 0, // This is not an option ID.
104 #define OPTION(...)                                                            \
105   LLVM_MAKE_OPT_ID_WITH_ID_PREFIX(BITCODE_STRIP_, __VA_ARGS__),
106 #include "BitcodeStripOpts.inc"
107 #undef OPTION
108 };
109 
110 namespace bitcode_strip {
111 #define OPTTABLE_STR_TABLE_CODE
112 #include "BitcodeStripOpts.inc"
113 #undef OPTTABLE_STR_TABLE_CODE
114 
115 #define OPTTABLE_PREFIXES_TABLE_CODE
116 #include "BitcodeStripOpts.inc"
117 #undef OPTTABLE_PREFIXES_TABLE_CODE
118 
119 static constexpr opt::OptTable::Info BitcodeStripInfoTable[] = {
120 #define OPTION(...)                                                            \
121   LLVM_CONSTRUCT_OPT_INFO_WITH_ID_PREFIX(BITCODE_STRIP_, __VA_ARGS__),
122 #include "BitcodeStripOpts.inc"
123 #undef OPTION
124 };
125 } // namespace bitcode_strip
126 
127 class BitcodeStripOptTable : public opt::GenericOptTable {
128 public:
129   BitcodeStripOptTable()
130       : opt::GenericOptTable(bitcode_strip::OptionStrTable,
131                              bitcode_strip::OptionPrefixesTable,
132                              bitcode_strip::BitcodeStripInfoTable) {}
133 };
134 
135 enum StripID {
136   STRIP_INVALID = 0, // This is not an option ID.
137 #define OPTION(...) LLVM_MAKE_OPT_ID_WITH_ID_PREFIX(STRIP_, __VA_ARGS__),
138 #include "StripOpts.inc"
139 #undef OPTION
140 };
141 
142 namespace strip {
143 #define OPTTABLE_STR_TABLE_CODE
144 #include "StripOpts.inc"
145 #undef OPTTABLE_STR_TABLE_CODE
146 
147 #define OPTTABLE_PREFIXES_TABLE_CODE
148 #include "StripOpts.inc"
149 #undef OPTTABLE_PREFIXES_TABLE_CODE
150 
151 static constexpr opt::OptTable::Info StripInfoTable[] = {
152 #define OPTION(...) LLVM_CONSTRUCT_OPT_INFO_WITH_ID_PREFIX(STRIP_, __VA_ARGS__),
153 #include "StripOpts.inc"
154 #undef OPTION
155 };
156 } // namespace strip
157 
158 class StripOptTable : public opt::GenericOptTable {
159 public:
160   StripOptTable()
161       : GenericOptTable(strip::OptionStrTable, strip::OptionPrefixesTable,
162                         strip::StripInfoTable) {
163     setGroupedShortOptions(true);
164   }
165 };
166 
167 } // namespace
168 
169 static SectionFlag parseSectionRenameFlag(StringRef SectionName) {
170   return llvm::StringSwitch<SectionFlag>(SectionName)
171       .CaseLower("alloc", SectionFlag::SecAlloc)
172       .CaseLower("load", SectionFlag::SecLoad)
173       .CaseLower("noload", SectionFlag::SecNoload)
174       .CaseLower("readonly", SectionFlag::SecReadonly)
175       .CaseLower("debug", SectionFlag::SecDebug)
176       .CaseLower("code", SectionFlag::SecCode)
177       .CaseLower("data", SectionFlag::SecData)
178       .CaseLower("rom", SectionFlag::SecRom)
179       .CaseLower("merge", SectionFlag::SecMerge)
180       .CaseLower("strings", SectionFlag::SecStrings)
181       .CaseLower("contents", SectionFlag::SecContents)
182       .CaseLower("share", SectionFlag::SecShare)
183       .CaseLower("exclude", SectionFlag::SecExclude)
184       .CaseLower("large", SectionFlag::SecLarge)
185       .Default(SectionFlag::SecNone);
186 }
187 
188 static Expected<SectionFlag>
189 parseSectionFlagSet(ArrayRef<StringRef> SectionFlags) {
190   SectionFlag ParsedFlags = SectionFlag::SecNone;
191   for (StringRef Flag : SectionFlags) {
192     SectionFlag ParsedFlag = parseSectionRenameFlag(Flag);
193     if (ParsedFlag == SectionFlag::SecNone)
194       return createStringError(
195           errc::invalid_argument,
196           "unrecognized section flag '%s'. Flags supported for GNU "
197           "compatibility: alloc, load, noload, readonly, exclude, debug, "
198           "code, data, rom, share, contents, merge, strings, large",
199           Flag.str().c_str());
200     ParsedFlags |= ParsedFlag;
201   }
202 
203   return ParsedFlags;
204 }
205 
206 static Expected<SectionRename> parseRenameSectionValue(StringRef FlagValue) {
207   if (!FlagValue.contains('='))
208     return createStringError(errc::invalid_argument,
209                              "bad format for --rename-section: missing '='");
210 
211   // Initial split: ".foo" = ".bar,f1,f2,..."
212   auto Old2New = FlagValue.split('=');
213   SectionRename SR;
214   SR.OriginalName = Old2New.first;
215 
216   // Flags split: ".bar" "f1" "f2" ...
217   SmallVector<StringRef, 6> NameAndFlags;
218   Old2New.second.split(NameAndFlags, ',');
219   SR.NewName = NameAndFlags[0];
220 
221   if (NameAndFlags.size() > 1) {
222     Expected<SectionFlag> ParsedFlagSet =
223         parseSectionFlagSet(ArrayRef(NameAndFlags).drop_front());
224     if (!ParsedFlagSet)
225       return ParsedFlagSet.takeError();
226     SR.NewFlags = *ParsedFlagSet;
227   }
228 
229   return SR;
230 }
231 
232 static Expected<std::pair<StringRef, uint64_t>>
233 parseSetSectionAttribute(StringRef Option, StringRef FlagValue) {
234   if (!FlagValue.contains('='))
235     return make_error<StringError>("bad format for " + Option + ": missing '='",
236                                    errc::invalid_argument);
237   auto Split = StringRef(FlagValue).split('=');
238   if (Split.first.empty())
239     return make_error<StringError>("bad format for " + Option +
240                                        ": missing section name",
241                                    errc::invalid_argument);
242   uint64_t Value;
243   if (Split.second.getAsInteger(0, Value))
244     return make_error<StringError>("invalid value for " + Option + ": '" +
245                                        Split.second + "'",
246                                    errc::invalid_argument);
247   return std::make_pair(Split.first, Value);
248 }
249 
250 static Expected<SectionFlagsUpdate>
251 parseSetSectionFlagValue(StringRef FlagValue) {
252   if (!StringRef(FlagValue).contains('='))
253     return createStringError(errc::invalid_argument,
254                              "bad format for --set-section-flags: missing '='");
255 
256   // Initial split: ".foo" = "f1,f2,..."
257   auto Section2Flags = StringRef(FlagValue).split('=');
258   SectionFlagsUpdate SFU;
259   SFU.Name = Section2Flags.first;
260 
261   // Flags split: "f1" "f2" ...
262   SmallVector<StringRef, 6> SectionFlags;
263   Section2Flags.second.split(SectionFlags, ',');
264   Expected<SectionFlag> ParsedFlagSet = parseSectionFlagSet(SectionFlags);
265   if (!ParsedFlagSet)
266     return ParsedFlagSet.takeError();
267   SFU.NewFlags = *ParsedFlagSet;
268 
269   return SFU;
270 }
271 
272 static Expected<uint8_t> parseVisibilityType(StringRef VisType) {
273   const uint8_t Invalid = 0xff;
274   uint8_t type = StringSwitch<uint8_t>(VisType)
275                      .Case("default", ELF::STV_DEFAULT)
276                      .Case("hidden", ELF::STV_HIDDEN)
277                      .Case("internal", ELF::STV_INTERNAL)
278                      .Case("protected", ELF::STV_PROTECTED)
279                      .Default(Invalid);
280   if (type == Invalid)
281     return createStringError(errc::invalid_argument,
282                              "'%s' is not a valid symbol visibility",
283                              VisType.str().c_str());
284   return type;
285 }
286 
287 namespace {
288 struct TargetInfo {
289   FileFormat Format;
290   MachineInfo Machine;
291 };
292 } // namespace
293 
294 // FIXME: consolidate with the bfd parsing used by lld.
295 static const StringMap<MachineInfo> TargetMap{
296     // Name, {EMachine, 64bit, LittleEndian}
297     // x86
298     {"elf32-i386", {ELF::EM_386, false, true}},
299     {"elf32-x86-64", {ELF::EM_X86_64, false, true}},
300     {"elf64-x86-64", {ELF::EM_X86_64, true, true}},
301     // Intel MCU
302     {"elf32-iamcu", {ELF::EM_IAMCU, false, true}},
303     // ARM
304     {"elf32-littlearm", {ELF::EM_ARM, false, true}},
305     // ARM AArch64
306     {"elf64-aarch64", {ELF::EM_AARCH64, true, true}},
307     {"elf64-littleaarch64", {ELF::EM_AARCH64, true, true}},
308     // RISC-V
309     {"elf32-littleriscv", {ELF::EM_RISCV, false, true}},
310     {"elf64-littleriscv", {ELF::EM_RISCV, true, true}},
311     // PowerPC
312     {"elf32-powerpc", {ELF::EM_PPC, false, false}},
313     {"elf32-powerpcle", {ELF::EM_PPC, false, true}},
314     {"elf64-powerpc", {ELF::EM_PPC64, true, false}},
315     {"elf64-powerpcle", {ELF::EM_PPC64, true, true}},
316     // MIPS
317     {"elf32-bigmips", {ELF::EM_MIPS, false, false}},
318     {"elf32-ntradbigmips", {ELF::EM_MIPS, false, false}},
319     {"elf32-ntradlittlemips", {ELF::EM_MIPS, false, true}},
320     {"elf32-tradbigmips", {ELF::EM_MIPS, false, false}},
321     {"elf32-tradlittlemips", {ELF::EM_MIPS, false, true}},
322     {"elf64-tradbigmips", {ELF::EM_MIPS, true, false}},
323     {"elf64-tradlittlemips", {ELF::EM_MIPS, true, true}},
324     // SPARC
325     {"elf32-sparc", {ELF::EM_SPARC, false, false}},
326     {"elf32-sparcel", {ELF::EM_SPARC, false, true}},
327     // Hexagon
328     {"elf32-hexagon", {ELF::EM_HEXAGON, false, true}},
329     // LoongArch
330     {"elf32-loongarch", {ELF::EM_LOONGARCH, false, true}},
331     {"elf64-loongarch", {ELF::EM_LOONGARCH, true, true}},
332     // SystemZ
333     {"elf64-s390", {ELF::EM_S390, true, false}},
334 };
335 
336 static Expected<TargetInfo>
337 getOutputTargetInfoByTargetName(StringRef TargetName) {
338   StringRef OriginalTargetName = TargetName;
339   bool IsFreeBSD = TargetName.consume_back("-freebsd");
340   auto Iter = TargetMap.find(TargetName);
341   if (Iter == std::end(TargetMap))
342     return createStringError(errc::invalid_argument,
343                              "invalid output format: '%s'",
344                              OriginalTargetName.str().c_str());
345   MachineInfo MI = Iter->getValue();
346   if (IsFreeBSD)
347     MI.OSABI = ELF::ELFOSABI_FREEBSD;
348 
349   FileFormat Format;
350   if (TargetName.starts_with("elf"))
351     Format = FileFormat::ELF;
352   else
353     // This should never happen because `TargetName` is valid (it certainly
354     // exists in the TargetMap).
355     llvm_unreachable("unknown target prefix");
356 
357   return {TargetInfo{Format, MI}};
358 }
359 
360 static Error addSymbolsFromFile(NameMatcher &Symbols, BumpPtrAllocator &Alloc,
361                                 StringRef Filename, MatchStyle MS,
362                                 function_ref<Error(Error)> ErrorCallback) {
363   StringSaver Saver(Alloc);
364   SmallVector<StringRef, 16> Lines;
365   auto BufOrErr = MemoryBuffer::getFile(Filename);
366   if (!BufOrErr)
367     return createFileError(Filename, BufOrErr.getError());
368 
369   BufOrErr.get()->getBuffer().split(Lines, '\n');
370   for (StringRef Line : Lines) {
371     // Ignore everything after '#', trim whitespace, and only add the symbol if
372     // it's not empty.
373     auto TrimmedLine = Line.split('#').first.trim();
374     if (!TrimmedLine.empty())
375       if (Error E = Symbols.addMatcher(NameOrPattern::create(
376               Saver.save(TrimmedLine), MS, ErrorCallback)))
377         return E;
378   }
379 
380   return Error::success();
381 }
382 
383 static Error addSymbolsToRenameFromFile(StringMap<StringRef> &SymbolsToRename,
384                                         BumpPtrAllocator &Alloc,
385                                         StringRef Filename) {
386   StringSaver Saver(Alloc);
387   SmallVector<StringRef, 16> Lines;
388   auto BufOrErr = MemoryBuffer::getFile(Filename);
389   if (!BufOrErr)
390     return createFileError(Filename, BufOrErr.getError());
391 
392   BufOrErr.get()->getBuffer().split(Lines, '\n');
393   size_t NumLines = Lines.size();
394   for (size_t LineNo = 0; LineNo < NumLines; ++LineNo) {
395     StringRef TrimmedLine = Lines[LineNo].split('#').first.trim();
396     if (TrimmedLine.empty())
397       continue;
398 
399     std::pair<StringRef, StringRef> Pair = Saver.save(TrimmedLine).split(' ');
400     StringRef NewName = Pair.second.trim();
401     if (NewName.empty())
402       return createStringError(errc::invalid_argument,
403                                "%s:%zu: missing new symbol name",
404                                Filename.str().c_str(), LineNo + 1);
405     SymbolsToRename.insert({Pair.first, NewName});
406   }
407   return Error::success();
408 }
409 
410 template <class T> static ErrorOr<T> getAsInteger(StringRef Val) {
411   T Result;
412   if (Val.getAsInteger(0, Result))
413     return errc::invalid_argument;
414   return Result;
415 }
416 
417 namespace {
418 
419 enum class ToolType { Objcopy, Strip, InstallNameTool, BitcodeStrip };
420 
421 } // anonymous namespace
422 
423 static void printHelp(const opt::OptTable &OptTable, raw_ostream &OS,
424                       ToolType Tool) {
425   StringRef HelpText, ToolName;
426   switch (Tool) {
427   case ToolType::Objcopy:
428     ToolName = "llvm-objcopy";
429     HelpText = " [options] input [output]";
430     break;
431   case ToolType::Strip:
432     ToolName = "llvm-strip";
433     HelpText = " [options] inputs...";
434     break;
435   case ToolType::InstallNameTool:
436     ToolName = "llvm-install-name-tool";
437     HelpText = " [options] input";
438     break;
439   case ToolType::BitcodeStrip:
440     ToolName = "llvm-bitcode-strip";
441     HelpText = " [options] input";
442     break;
443   }
444   OptTable.printHelp(OS, (ToolName + HelpText).str().c_str(),
445                      (ToolName + " tool").str().c_str());
446   // TODO: Replace this with libOption call once it adds extrahelp support.
447   // The CommandLine library has a cl::extrahelp class to support this,
448   // but libOption does not have that yet.
449   OS << "\nPass @FILE as argument to read options from FILE.\n";
450 }
451 
452 static Expected<NewSymbolInfo> parseNewSymbolInfo(StringRef FlagValue) {
453   // Parse value given with --add-symbol option and create the
454   // new symbol if possible. The value format for --add-symbol is:
455   //
456   // <name>=[<section>:]<value>[,<flags>]
457   //
458   // where:
459   // <name> - symbol name, can be empty string
460   // <section> - optional section name. If not given ABS symbol is created
461   // <value> - symbol value, can be decimal or hexadecimal number prefixed
462   //           with 0x.
463   // <flags> - optional flags affecting symbol type, binding or visibility.
464   NewSymbolInfo SI;
465   StringRef Value;
466   std::tie(SI.SymbolName, Value) = FlagValue.split('=');
467   if (Value.empty())
468     return createStringError(
469         errc::invalid_argument,
470         "bad format for --add-symbol, missing '=' after '%s'",
471         SI.SymbolName.str().c_str());
472 
473   if (Value.contains(':')) {
474     std::tie(SI.SectionName, Value) = Value.split(':');
475     if (SI.SectionName.empty() || Value.empty())
476       return createStringError(
477           errc::invalid_argument,
478           "bad format for --add-symbol, missing section name or symbol value");
479   }
480 
481   SmallVector<StringRef, 6> Flags;
482   Value.split(Flags, ',');
483   if (Flags[0].getAsInteger(0, SI.Value))
484     return createStringError(errc::invalid_argument, "bad symbol value: '%s'",
485                              Flags[0].str().c_str());
486 
487   using Functor = std::function<void()>;
488   SmallVector<StringRef, 6> UnsupportedFlags;
489   for (size_t I = 1, NumFlags = Flags.size(); I < NumFlags; ++I)
490     static_cast<Functor>(
491         StringSwitch<Functor>(Flags[I])
492             .CaseLower("global",
493                        [&] { SI.Flags.push_back(SymbolFlag::Global); })
494             .CaseLower("local", [&] { SI.Flags.push_back(SymbolFlag::Local); })
495             .CaseLower("weak", [&] { SI.Flags.push_back(SymbolFlag::Weak); })
496             .CaseLower("default",
497                        [&] { SI.Flags.push_back(SymbolFlag::Default); })
498             .CaseLower("hidden",
499                        [&] { SI.Flags.push_back(SymbolFlag::Hidden); })
500             .CaseLower("protected",
501                        [&] { SI.Flags.push_back(SymbolFlag::Protected); })
502             .CaseLower("file", [&] { SI.Flags.push_back(SymbolFlag::File); })
503             .CaseLower("section",
504                        [&] { SI.Flags.push_back(SymbolFlag::Section); })
505             .CaseLower("object",
506                        [&] { SI.Flags.push_back(SymbolFlag::Object); })
507             .CaseLower("function",
508                        [&] { SI.Flags.push_back(SymbolFlag::Function); })
509             .CaseLower(
510                 "indirect-function",
511                 [&] { SI.Flags.push_back(SymbolFlag::IndirectFunction); })
512             .CaseLower("debug", [&] { SI.Flags.push_back(SymbolFlag::Debug); })
513             .CaseLower("constructor",
514                        [&] { SI.Flags.push_back(SymbolFlag::Constructor); })
515             .CaseLower("warning",
516                        [&] { SI.Flags.push_back(SymbolFlag::Warning); })
517             .CaseLower("indirect",
518                        [&] { SI.Flags.push_back(SymbolFlag::Indirect); })
519             .CaseLower("synthetic",
520                        [&] { SI.Flags.push_back(SymbolFlag::Synthetic); })
521             .CaseLower("unique-object",
522                        [&] { SI.Flags.push_back(SymbolFlag::UniqueObject); })
523             .StartsWithLower("before=",
524                              [&] {
525                                StringRef SymNamePart =
526                                    Flags[I].split('=').second;
527 
528                                if (!SymNamePart.empty())
529                                  SI.BeforeSyms.push_back(SymNamePart);
530                              })
531             .Default([&] { UnsupportedFlags.push_back(Flags[I]); }))();
532   if (!UnsupportedFlags.empty())
533     return createStringError(errc::invalid_argument,
534                              "unsupported flag%s for --add-symbol: '%s'",
535                              UnsupportedFlags.size() > 1 ? "s" : "",
536                              join(UnsupportedFlags, "', '").c_str());
537 
538   return SI;
539 }
540 
541 static Expected<RemoveNoteInfo> parseRemoveNoteInfo(StringRef FlagValue) {
542   // Parse value given with --remove-note option. The format is:
543   //
544   // [name/]type_id
545   //
546   // where:
547   // <name>    - optional note name. If not given, all notes with the specified
548   //             <type_id> are removed.
549   // <type_id> - note type value, can be decimal or hexadecimal number prefixed
550   //             with 0x.
551   RemoveNoteInfo NI;
552   StringRef TypeIdStr;
553   if (auto Idx = FlagValue.find('/'); Idx != StringRef::npos) {
554     if (Idx == 0)
555       return createStringError(
556           errc::invalid_argument,
557           "bad format for --remove-note, note name is empty");
558     NI.Name = FlagValue.slice(0, Idx);
559     TypeIdStr = FlagValue.substr(Idx + 1);
560   } else {
561     TypeIdStr = FlagValue;
562   }
563   if (TypeIdStr.empty())
564     return createStringError(errc::invalid_argument,
565                              "bad format for --remove-note, missing type_id");
566   if (TypeIdStr.getAsInteger(0, NI.TypeId))
567     return createStringError(errc::invalid_argument,
568                              "bad note type_id for --remove-note: '%s'",
569                              TypeIdStr.str().c_str());
570   return NI;
571 }
572 
573 // Parse input option \p ArgValue and load section data. This function
574 // extracts section name and name of the file keeping section data from
575 // ArgValue, loads data from the file, and stores section name and data
576 // into the vector of new sections \p NewSections.
577 static Error loadNewSectionData(StringRef ArgValue, StringRef OptionName,
578                                 SmallVector<NewSectionInfo, 0> &NewSections) {
579   if (!ArgValue.contains('='))
580     return createStringError(errc::invalid_argument,
581                              "bad format for " + OptionName + ": missing '='");
582 
583   std::pair<StringRef, StringRef> SecPair = ArgValue.split("=");
584   if (SecPair.second.empty())
585     return createStringError(errc::invalid_argument, "bad format for " +
586                                                          OptionName +
587                                                          ": missing file name");
588 
589   ErrorOr<std::unique_ptr<MemoryBuffer>> BufOrErr =
590       MemoryBuffer::getFile(SecPair.second);
591   if (!BufOrErr)
592     return createFileError(SecPair.second,
593                            errorCodeToError(BufOrErr.getError()));
594 
595   NewSections.push_back({SecPair.first, std::move(*BufOrErr)});
596   return Error::success();
597 }
598 
599 static Expected<int64_t> parseChangeSectionLMA(StringRef ArgValue,
600                                                StringRef OptionName) {
601   StringRef StringValue;
602   if (ArgValue.starts_with("*+")) {
603     StringValue = ArgValue.substr(2);
604   } else if (ArgValue.starts_with("*-")) {
605     StringValue = ArgValue.substr(1);
606   } else if (ArgValue.contains("=")) {
607     return createStringError(errc::invalid_argument,
608                              "bad format for " + OptionName +
609                                  ": changing LMA to a specific value is not "
610                                  "supported. Use *+val or *-val instead");
611   } else if (ArgValue.contains("+") || ArgValue.contains("-")) {
612     return createStringError(errc::invalid_argument,
613                              "bad format for " + OptionName +
614                                  ": changing a specific section LMA is not "
615                                  "supported. Use *+val or *-val instead");
616   }
617   if (StringValue.empty())
618     return createStringError(errc::invalid_argument,
619                              "bad format for " + OptionName +
620                                  ": missing LMA offset");
621 
622   auto LMAValue = getAsInteger<int64_t>(StringValue);
623   if (!LMAValue)
624     return createStringError(LMAValue.getError(),
625                              "bad format for " + OptionName + ": value after " +
626                                  ArgValue.slice(0, 2) + " is " + StringValue +
627                                  " when it should be an integer");
628   return *LMAValue;
629 }
630 
631 static Expected<SectionPatternAddressUpdate>
632 parseChangeSectionAddr(StringRef ArgValue, StringRef OptionName,
633                        MatchStyle SectionMatchStyle,
634                        function_ref<Error(Error)> ErrorCallback) {
635   SectionPatternAddressUpdate PatternUpdate;
636 
637   size_t LastSymbolIndex = ArgValue.find_last_of("+-=");
638   if (LastSymbolIndex == StringRef::npos)
639     return createStringError(errc::invalid_argument,
640                              "bad format for " + OptionName +
641                                  ": argument value " + ArgValue +
642                                  " is invalid. See --help");
643   char UpdateSymbol = ArgValue[LastSymbolIndex];
644 
645   StringRef SectionPattern = ArgValue.slice(0, LastSymbolIndex);
646   if (SectionPattern.empty())
647     return createStringError(
648         errc::invalid_argument,
649         "bad format for " + OptionName +
650             ": missing section pattern to apply address change to");
651   if (Error E = PatternUpdate.SectionPattern.addMatcher(NameOrPattern::create(
652           SectionPattern, SectionMatchStyle, ErrorCallback)))
653     return std::move(E);
654 
655   StringRef Value = ArgValue.substr(LastSymbolIndex + 1);
656   if (Value.empty()) {
657     switch (UpdateSymbol) {
658     case '+':
659     case '-':
660       return createStringError(errc::invalid_argument,
661                                "bad format for " + OptionName +
662                                    ": missing value of offset after '" +
663                                    std::string({UpdateSymbol}) + "'");
664 
665     case '=':
666       return createStringError(errc::invalid_argument,
667                                "bad format for " + OptionName +
668                                    ": missing address value after '='");
669     }
670   }
671   auto AddrValue = getAsInteger<uint64_t>(Value);
672   if (!AddrValue)
673     return createStringError(AddrValue.getError(),
674                              "bad format for " + OptionName + ": value after " +
675                                  std::string({UpdateSymbol}) + " is " + Value +
676                                  " when it should be a 64-bit integer");
677 
678   switch (UpdateSymbol) {
679   case '+':
680     PatternUpdate.Update.Kind = AdjustKind::Add;
681     break;
682   case '-':
683     PatternUpdate.Update.Kind = AdjustKind::Subtract;
684     break;
685   case '=':
686     PatternUpdate.Update.Kind = AdjustKind::Set;
687   }
688 
689   PatternUpdate.Update.Value = *AddrValue;
690   return PatternUpdate;
691 }
692 
693 // parseObjcopyOptions returns the config and sets the input arguments. If a
694 // help flag is set then parseObjcopyOptions will print the help messege and
695 // exit.
696 Expected<DriverConfig>
697 objcopy::parseObjcopyOptions(ArrayRef<const char *> ArgsArr,
698                              function_ref<Error(Error)> ErrorCallback) {
699   DriverConfig DC;
700   ObjcopyOptTable T;
701 
702   unsigned MissingArgumentIndex, MissingArgumentCount;
703   llvm::opt::InputArgList InputArgs =
704       T.ParseArgs(ArgsArr, MissingArgumentIndex, MissingArgumentCount);
705 
706   if (MissingArgumentCount)
707     return createStringError(
708         errc::invalid_argument,
709         "argument to '%s' is missing (expected %d value(s))",
710         InputArgs.getArgString(MissingArgumentIndex), MissingArgumentCount);
711 
712   if (InputArgs.size() == 0) {
713     printHelp(T, errs(), ToolType::Objcopy);
714     exit(1);
715   }
716 
717   if (InputArgs.hasArg(OBJCOPY_help)) {
718     printHelp(T, outs(), ToolType::Objcopy);
719     exit(0);
720   }
721 
722   if (InputArgs.hasArg(OBJCOPY_version)) {
723     outs() << "llvm-objcopy, compatible with GNU objcopy\n";
724     cl::PrintVersionMessage();
725     exit(0);
726   }
727 
728   SmallVector<const char *, 2> Positional;
729 
730   for (auto *Arg : InputArgs.filtered(OBJCOPY_UNKNOWN))
731     return createStringError(errc::invalid_argument, "unknown argument '%s'",
732                              Arg->getAsString(InputArgs).c_str());
733 
734   for (auto *Arg : InputArgs.filtered(OBJCOPY_INPUT))
735     Positional.push_back(Arg->getValue());
736 
737   if (Positional.empty())
738     return createStringError(errc::invalid_argument, "no input file specified");
739 
740   if (Positional.size() > 2)
741     return createStringError(errc::invalid_argument,
742                              "too many positional arguments");
743 
744   ConfigManager ConfigMgr;
745   CommonConfig &Config = ConfigMgr.Common;
746   COFFConfig &COFFConfig = ConfigMgr.COFF;
747   ELFConfig &ELFConfig = ConfigMgr.ELF;
748   MachOConfig &MachOConfig = ConfigMgr.MachO;
749   Config.InputFilename = Positional[0];
750   Config.OutputFilename = Positional[Positional.size() == 1 ? 0 : 1];
751   if (InputArgs.hasArg(OBJCOPY_target) &&
752       (InputArgs.hasArg(OBJCOPY_input_target) ||
753        InputArgs.hasArg(OBJCOPY_output_target)))
754     return createStringError(
755         errc::invalid_argument,
756         "--target cannot be used with --input-target or --output-target");
757 
758   if (InputArgs.hasArg(OBJCOPY_regex) && InputArgs.hasArg(OBJCOPY_wildcard))
759     return createStringError(errc::invalid_argument,
760                              "--regex and --wildcard are incompatible");
761 
762   MatchStyle SectionMatchStyle = InputArgs.hasArg(OBJCOPY_regex)
763                                      ? MatchStyle::Regex
764                                      : MatchStyle::Wildcard;
765   MatchStyle SymbolMatchStyle
766       = InputArgs.hasArg(OBJCOPY_regex)    ? MatchStyle::Regex
767       : InputArgs.hasArg(OBJCOPY_wildcard) ? MatchStyle::Wildcard
768                                            : MatchStyle::Literal;
769   StringRef InputFormat, OutputFormat;
770   if (InputArgs.hasArg(OBJCOPY_target)) {
771     InputFormat = InputArgs.getLastArgValue(OBJCOPY_target);
772     OutputFormat = InputArgs.getLastArgValue(OBJCOPY_target);
773   } else {
774     InputFormat = InputArgs.getLastArgValue(OBJCOPY_input_target);
775     OutputFormat = InputArgs.getLastArgValue(OBJCOPY_output_target);
776   }
777 
778   // FIXME:  Currently, we ignore the target for non-binary/ihex formats
779   // explicitly specified by -I option (e.g. -Ielf32-x86-64) and guess the
780   // format by llvm::object::createBinary regardless of the option value.
781   Config.InputFormat = StringSwitch<FileFormat>(InputFormat)
782                            .Case("binary", FileFormat::Binary)
783                            .Case("ihex", FileFormat::IHex)
784                            .Default(FileFormat::Unspecified);
785 
786   if (InputArgs.hasArg(OBJCOPY_new_symbol_visibility)) {
787     const uint8_t Invalid = 0xff;
788     StringRef VisibilityStr =
789         InputArgs.getLastArgValue(OBJCOPY_new_symbol_visibility);
790 
791     ELFConfig.NewSymbolVisibility = StringSwitch<uint8_t>(VisibilityStr)
792                                         .Case("default", ELF::STV_DEFAULT)
793                                         .Case("hidden", ELF::STV_HIDDEN)
794                                         .Case("internal", ELF::STV_INTERNAL)
795                                         .Case("protected", ELF::STV_PROTECTED)
796                                         .Default(Invalid);
797 
798     if (ELFConfig.NewSymbolVisibility == Invalid)
799       return createStringError(errc::invalid_argument,
800                                "'%s' is not a valid symbol visibility",
801                                VisibilityStr.str().c_str());
802   }
803 
804   for (const auto *Arg : InputArgs.filtered(OBJCOPY_subsystem)) {
805     StringRef Subsystem, Version;
806     std::tie(Subsystem, Version) = StringRef(Arg->getValue()).split(':');
807     COFFConfig.Subsystem =
808         StringSwitch<unsigned>(Subsystem.lower())
809             .Case("boot_application",
810                   COFF::IMAGE_SUBSYSTEM_WINDOWS_BOOT_APPLICATION)
811             .Case("console", COFF::IMAGE_SUBSYSTEM_WINDOWS_CUI)
812             .Cases("efi_application", "efi-app",
813                    COFF::IMAGE_SUBSYSTEM_EFI_APPLICATION)
814             .Cases("efi_boot_service_driver", "efi-bsd",
815                    COFF::IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER)
816             .Case("efi_rom", COFF::IMAGE_SUBSYSTEM_EFI_ROM)
817             .Cases("efi_runtime_driver", "efi-rtd",
818                    COFF::IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER)
819             .Case("native", COFF::IMAGE_SUBSYSTEM_NATIVE)
820             .Case("posix", COFF::IMAGE_SUBSYSTEM_POSIX_CUI)
821             .Case("windows", COFF::IMAGE_SUBSYSTEM_WINDOWS_GUI)
822             .Default(COFF::IMAGE_SUBSYSTEM_UNKNOWN);
823     if (*COFFConfig.Subsystem == COFF::IMAGE_SUBSYSTEM_UNKNOWN)
824       return createStringError(errc::invalid_argument,
825                                "'%s' is not a valid subsystem",
826                                Subsystem.str().c_str());
827     if (!Version.empty()) {
828       StringRef Major, Minor;
829       std::tie(Major, Minor) = Version.split('.');
830       unsigned Number;
831       if (Major.getAsInteger(10, Number))
832         return createStringError(errc::invalid_argument,
833                                  "'%s' is not a valid subsystem major version",
834                                  Major.str().c_str());
835       COFFConfig.MajorSubsystemVersion = Number;
836       Number = 0;
837       if (!Minor.empty() && Minor.getAsInteger(10, Number))
838         return createStringError(errc::invalid_argument,
839                                  "'%s' is not a valid subsystem minor version",
840                                  Minor.str().c_str());
841       COFFConfig.MinorSubsystemVersion = Number;
842     }
843   }
844 
845   Config.OutputFormat = StringSwitch<FileFormat>(OutputFormat)
846                             .Case("binary", FileFormat::Binary)
847                             .Case("ihex", FileFormat::IHex)
848                             .Case("srec", FileFormat::SREC)
849                             .Default(FileFormat::Unspecified);
850   if (Config.OutputFormat == FileFormat::Unspecified) {
851     if (OutputFormat.empty()) {
852       Config.OutputFormat = Config.InputFormat;
853     } else {
854       Expected<TargetInfo> Target =
855           getOutputTargetInfoByTargetName(OutputFormat);
856       if (!Target)
857         return Target.takeError();
858       Config.OutputFormat = Target->Format;
859       Config.OutputArch = Target->Machine;
860     }
861   }
862 
863   if (const auto *A = InputArgs.getLastArg(OBJCOPY_compress_debug_sections)) {
864     Config.CompressionType = StringSwitch<DebugCompressionType>(A->getValue())
865                                  .Case("zlib", DebugCompressionType::Zlib)
866                                  .Case("zstd", DebugCompressionType::Zstd)
867                                  .Default(DebugCompressionType::None);
868     if (Config.CompressionType == DebugCompressionType::None) {
869       return createStringError(
870           errc::invalid_argument,
871           "invalid or unsupported --compress-debug-sections format: %s",
872           A->getValue());
873     }
874     if (const char *Reason = compression::getReasonIfUnsupported(
875             compression::formatFor(Config.CompressionType)))
876       return createStringError(errc::invalid_argument, Reason);
877   }
878 
879   for (const auto *A : InputArgs.filtered(OBJCOPY_compress_sections)) {
880     SmallVector<StringRef, 0> Fields;
881     StringRef(A->getValue()).split(Fields, '=');
882     if (Fields.size() != 2 || Fields[1].empty()) {
883       return createStringError(
884           errc::invalid_argument,
885           A->getSpelling() +
886               ": parse error, not 'section-glob=[none|zlib|zstd]'");
887     }
888 
889     auto Type = StringSwitch<DebugCompressionType>(Fields[1])
890                     .Case("zlib", DebugCompressionType::Zlib)
891                     .Case("zstd", DebugCompressionType::Zstd)
892                     .Default(DebugCompressionType::None);
893     if (Type == DebugCompressionType::None && Fields[1] != "none") {
894       return createStringError(
895           errc::invalid_argument,
896           "invalid or unsupported --compress-sections format: %s",
897           A->getValue());
898     }
899 
900     auto &P = Config.compressSections.emplace_back();
901     P.second = Type;
902     auto Matcher =
903         NameOrPattern::create(Fields[0], SectionMatchStyle, ErrorCallback);
904     // =none allows overriding a previous =zlib or =zstd. Reject negative
905     // patterns, which would be confusing.
906     if (Matcher && !Matcher->isPositiveMatch()) {
907       return createStringError(
908           errc::invalid_argument,
909           "--compress-sections: negative pattern is unsupported");
910     }
911     if (Error E = P.first.addMatcher(std::move(Matcher)))
912       return std::move(E);
913   }
914 
915   Config.AddGnuDebugLink = InputArgs.getLastArgValue(OBJCOPY_add_gnu_debuglink);
916   // The gnu_debuglink's target is expected to not change or else its CRC would
917   // become invalidated and get rejected. We can avoid recalculating the
918   // checksum for every target file inside an archive by precomputing the CRC
919   // here. This prevents a significant amount of I/O.
920   if (!Config.AddGnuDebugLink.empty()) {
921     auto DebugOrErr = MemoryBuffer::getFile(Config.AddGnuDebugLink);
922     if (!DebugOrErr)
923       return createFileError(Config.AddGnuDebugLink, DebugOrErr.getError());
924     auto Debug = std::move(*DebugOrErr);
925     Config.GnuDebugLinkCRC32 =
926         llvm::crc32(arrayRefFromStringRef(Debug->getBuffer()));
927   }
928   Config.SplitDWO = InputArgs.getLastArgValue(OBJCOPY_split_dwo);
929 
930   Config.SymbolsPrefix = InputArgs.getLastArgValue(OBJCOPY_prefix_symbols);
931   Config.SymbolsPrefixRemove =
932       InputArgs.getLastArgValue(OBJCOPY_remove_symbol_prefix);
933 
934   Config.AllocSectionsPrefix =
935       InputArgs.getLastArgValue(OBJCOPY_prefix_alloc_sections);
936   if (auto Arg = InputArgs.getLastArg(OBJCOPY_extract_partition))
937     Config.ExtractPartition = Arg->getValue();
938 
939   if (const auto *A = InputArgs.getLastArg(OBJCOPY_gap_fill)) {
940     if (Config.OutputFormat != FileFormat::Binary)
941       return createStringError(
942           errc::invalid_argument,
943           "'--gap-fill' is only supported for binary output");
944     ErrorOr<uint64_t> Val = getAsInteger<uint64_t>(A->getValue());
945     if (!Val)
946       return createStringError(Val.getError(), "--gap-fill: bad number: %s",
947                                A->getValue());
948     uint8_t ByteVal = Val.get();
949     if (ByteVal != Val.get())
950       return createStringError(std::errc::value_too_large,
951                                "gap-fill value %s is out of range (0 to 0xff)",
952                                A->getValue());
953     Config.GapFill = ByteVal;
954   }
955 
956   if (const auto *A = InputArgs.getLastArg(OBJCOPY_pad_to)) {
957     if (Config.OutputFormat != FileFormat::Binary)
958       return createStringError(
959           errc::invalid_argument,
960           "'--pad-to' is only supported for binary output");
961     ErrorOr<uint64_t> Addr = getAsInteger<uint64_t>(A->getValue());
962     if (!Addr)
963       return createStringError(Addr.getError(), "--pad-to: bad number: %s",
964                                A->getValue());
965     Config.PadTo = *Addr;
966   }
967 
968   if (const auto *Arg = InputArgs.getLastArg(OBJCOPY_change_section_lma)) {
969     Expected<int64_t> LMAValue =
970         parseChangeSectionLMA(Arg->getValue(), Arg->getSpelling());
971     if (!LMAValue)
972       return LMAValue.takeError();
973     Config.ChangeSectionLMAValAll = *LMAValue;
974   }
975 
976   for (auto *Arg : InputArgs.filtered(OBJCOPY_change_section_address)) {
977     Expected<SectionPatternAddressUpdate> AddressUpdate =
978         parseChangeSectionAddr(Arg->getValue(), Arg->getSpelling(),
979                                SectionMatchStyle, ErrorCallback);
980     if (!AddressUpdate)
981       return AddressUpdate.takeError();
982     Config.ChangeSectionAddress.push_back(*AddressUpdate);
983   }
984 
985   for (auto *Arg : InputArgs.filtered(OBJCOPY_redefine_symbol)) {
986     if (!StringRef(Arg->getValue()).contains('='))
987       return createStringError(errc::invalid_argument,
988                                "bad format for --redefine-sym");
989     auto Old2New = StringRef(Arg->getValue()).split('=');
990     if (!Config.SymbolsToRename.insert(Old2New).second)
991       return createStringError(errc::invalid_argument,
992                                "multiple redefinition of symbol '%s'",
993                                Old2New.first.str().c_str());
994   }
995 
996   for (auto *Arg : InputArgs.filtered(OBJCOPY_redefine_symbols))
997     if (Error E = addSymbolsToRenameFromFile(Config.SymbolsToRename, DC.Alloc,
998                                              Arg->getValue()))
999       return std::move(E);
1000 
1001   for (auto *Arg : InputArgs.filtered(OBJCOPY_rename_section)) {
1002     Expected<SectionRename> SR =
1003         parseRenameSectionValue(StringRef(Arg->getValue()));
1004     if (!SR)
1005       return SR.takeError();
1006     if (!Config.SectionsToRename.try_emplace(SR->OriginalName, *SR).second)
1007       return createStringError(errc::invalid_argument,
1008                                "multiple renames of section '%s'",
1009                                SR->OriginalName.str().c_str());
1010   }
1011   for (auto *Arg : InputArgs.filtered(OBJCOPY_set_section_alignment)) {
1012     Expected<std::pair<StringRef, uint64_t>> NameAndAlign =
1013         parseSetSectionAttribute("--set-section-alignment", Arg->getValue());
1014     if (!NameAndAlign)
1015       return NameAndAlign.takeError();
1016     Config.SetSectionAlignment[NameAndAlign->first] = NameAndAlign->second;
1017   }
1018   for (auto *Arg : InputArgs.filtered(OBJCOPY_set_section_flags)) {
1019     Expected<SectionFlagsUpdate> SFU =
1020         parseSetSectionFlagValue(Arg->getValue());
1021     if (!SFU)
1022       return SFU.takeError();
1023     if (!Config.SetSectionFlags.try_emplace(SFU->Name, *SFU).second)
1024       return createStringError(
1025           errc::invalid_argument,
1026           "--set-section-flags set multiple times for section '%s'",
1027           SFU->Name.str().c_str());
1028   }
1029   for (auto *Arg : InputArgs.filtered(OBJCOPY_set_section_type)) {
1030     Expected<std::pair<StringRef, uint64_t>> NameAndType =
1031         parseSetSectionAttribute("--set-section-type", Arg->getValue());
1032     if (!NameAndType)
1033       return NameAndType.takeError();
1034     Config.SetSectionType[NameAndType->first] = NameAndType->second;
1035   }
1036   // Prohibit combinations of --set-section-{flags,type} when the section name
1037   // is used as the destination of a --rename-section.
1038   for (const auto &E : Config.SectionsToRename) {
1039     const SectionRename &SR = E.second;
1040     auto Err = [&](const char *Option) {
1041       return createStringError(
1042           errc::invalid_argument,
1043           "--set-section-%s=%s conflicts with --rename-section=%s=%s", Option,
1044           SR.NewName.str().c_str(), SR.OriginalName.str().c_str(),
1045           SR.NewName.str().c_str());
1046     };
1047     if (Config.SetSectionFlags.count(SR.NewName))
1048       return Err("flags");
1049     if (Config.SetSectionType.count(SR.NewName))
1050       return Err("type");
1051   }
1052 
1053   for (auto *Arg : InputArgs.filtered(OBJCOPY_remove_section))
1054     if (Error E = Config.ToRemove.addMatcher(NameOrPattern::create(
1055             Arg->getValue(), SectionMatchStyle, ErrorCallback)))
1056       return std::move(E);
1057   for (auto *Arg : InputArgs.filtered(OBJCOPY_keep_section))
1058     if (Error E = Config.KeepSection.addMatcher(NameOrPattern::create(
1059             Arg->getValue(), SectionMatchStyle, ErrorCallback)))
1060       return std::move(E);
1061   for (auto *Arg : InputArgs.filtered(OBJCOPY_only_section))
1062     if (Error E = Config.OnlySection.addMatcher(NameOrPattern::create(
1063             Arg->getValue(), SectionMatchStyle, ErrorCallback)))
1064       return std::move(E);
1065   for (auto *Arg : InputArgs.filtered(OBJCOPY_add_section)) {
1066     if (Error Err = loadNewSectionData(Arg->getValue(), "--add-section",
1067                                        Config.AddSection))
1068       return std::move(Err);
1069   }
1070   for (auto *Arg : InputArgs.filtered(OBJCOPY_update_section)) {
1071     if (Error Err = loadNewSectionData(Arg->getValue(), "--update-section",
1072                                        Config.UpdateSection))
1073       return std::move(Err);
1074   }
1075   for (auto *Arg : InputArgs.filtered(OBJCOPY_dump_section)) {
1076     StringRef Value(Arg->getValue());
1077     if (Value.split('=').second.empty())
1078       return createStringError(
1079           errc::invalid_argument,
1080           "bad format for --dump-section, expected section=file");
1081     Config.DumpSection.push_back(Value);
1082   }
1083   Config.StripAll = InputArgs.hasArg(OBJCOPY_strip_all);
1084   Config.StripAllGNU = InputArgs.hasArg(OBJCOPY_strip_all_gnu);
1085   Config.StripDebug = InputArgs.hasArg(OBJCOPY_strip_debug);
1086   Config.StripDWO = InputArgs.hasArg(OBJCOPY_strip_dwo);
1087   Config.StripSections = InputArgs.hasArg(OBJCOPY_strip_sections);
1088   Config.StripNonAlloc = InputArgs.hasArg(OBJCOPY_strip_non_alloc);
1089   Config.StripUnneeded = InputArgs.hasArg(OBJCOPY_strip_unneeded);
1090   Config.ExtractDWO = InputArgs.hasArg(OBJCOPY_extract_dwo);
1091   Config.ExtractMainPartition =
1092       InputArgs.hasArg(OBJCOPY_extract_main_partition);
1093   ELFConfig.LocalizeHidden = InputArgs.hasArg(OBJCOPY_localize_hidden);
1094   Config.Weaken = InputArgs.hasArg(OBJCOPY_weaken);
1095   if (auto *Arg =
1096           InputArgs.getLastArg(OBJCOPY_discard_all, OBJCOPY_discard_locals)) {
1097     Config.DiscardMode = Arg->getOption().matches(OBJCOPY_discard_all)
1098                              ? DiscardType::All
1099                              : DiscardType::Locals;
1100   }
1101 
1102   ELFConfig.VerifyNoteSections = InputArgs.hasFlag(
1103       OBJCOPY_verify_note_sections, OBJCOPY_no_verify_note_sections, true);
1104 
1105   Config.OnlyKeepDebug = InputArgs.hasArg(OBJCOPY_only_keep_debug);
1106   ELFConfig.KeepFileSymbols = InputArgs.hasArg(OBJCOPY_keep_file_symbols);
1107   MachOConfig.KeepUndefined = InputArgs.hasArg(OBJCOPY_keep_undefined);
1108   Config.DecompressDebugSections =
1109       InputArgs.hasArg(OBJCOPY_decompress_debug_sections);
1110   if (Config.DiscardMode == DiscardType::All) {
1111     Config.StripDebug = true;
1112     ELFConfig.KeepFileSymbols = true;
1113   }
1114   for (auto *Arg : InputArgs.filtered(OBJCOPY_localize_symbol))
1115     if (Error E = Config.SymbolsToLocalize.addMatcher(NameOrPattern::create(
1116             Arg->getValue(), SymbolMatchStyle, ErrorCallback)))
1117       return std::move(E);
1118   for (auto *Arg : InputArgs.filtered(OBJCOPY_localize_symbols))
1119     if (Error E = addSymbolsFromFile(Config.SymbolsToLocalize, DC.Alloc,
1120                                      Arg->getValue(), SymbolMatchStyle,
1121                                      ErrorCallback))
1122       return std::move(E);
1123   for (auto *Arg : InputArgs.filtered(OBJCOPY_keep_global_symbol))
1124     if (Error E = Config.SymbolsToKeepGlobal.addMatcher(NameOrPattern::create(
1125             Arg->getValue(), SymbolMatchStyle, ErrorCallback)))
1126       return std::move(E);
1127   for (auto *Arg : InputArgs.filtered(OBJCOPY_keep_global_symbols))
1128     if (Error E = addSymbolsFromFile(Config.SymbolsToKeepGlobal, DC.Alloc,
1129                                      Arg->getValue(), SymbolMatchStyle,
1130                                      ErrorCallback))
1131       return std::move(E);
1132   for (auto *Arg : InputArgs.filtered(OBJCOPY_globalize_symbol))
1133     if (Error E = Config.SymbolsToGlobalize.addMatcher(NameOrPattern::create(
1134             Arg->getValue(), SymbolMatchStyle, ErrorCallback)))
1135       return std::move(E);
1136   for (auto *Arg : InputArgs.filtered(OBJCOPY_globalize_symbols))
1137     if (Error E = addSymbolsFromFile(Config.SymbolsToGlobalize, DC.Alloc,
1138                                      Arg->getValue(), SymbolMatchStyle,
1139                                      ErrorCallback))
1140       return std::move(E);
1141   for (auto *Arg : InputArgs.filtered(OBJCOPY_weaken_symbol))
1142     if (Error E = Config.SymbolsToWeaken.addMatcher(NameOrPattern::create(
1143             Arg->getValue(), SymbolMatchStyle, ErrorCallback)))
1144       return std::move(E);
1145   for (auto *Arg : InputArgs.filtered(OBJCOPY_weaken_symbols))
1146     if (Error E = addSymbolsFromFile(Config.SymbolsToWeaken, DC.Alloc,
1147                                      Arg->getValue(), SymbolMatchStyle,
1148                                      ErrorCallback))
1149       return std::move(E);
1150   for (auto *Arg : InputArgs.filtered(OBJCOPY_strip_symbol))
1151     if (Error E = Config.SymbolsToRemove.addMatcher(NameOrPattern::create(
1152             Arg->getValue(), SymbolMatchStyle, ErrorCallback)))
1153       return std::move(E);
1154   for (auto *Arg : InputArgs.filtered(OBJCOPY_strip_symbols))
1155     if (Error E = addSymbolsFromFile(Config.SymbolsToRemove, DC.Alloc,
1156                                      Arg->getValue(), SymbolMatchStyle,
1157                                      ErrorCallback))
1158       return std::move(E);
1159   for (auto *Arg : InputArgs.filtered(OBJCOPY_strip_unneeded_symbol))
1160     if (Error E =
1161             Config.UnneededSymbolsToRemove.addMatcher(NameOrPattern::create(
1162                 Arg->getValue(), SymbolMatchStyle, ErrorCallback)))
1163       return std::move(E);
1164   for (auto *Arg : InputArgs.filtered(OBJCOPY_strip_unneeded_symbols))
1165     if (Error E = addSymbolsFromFile(Config.UnneededSymbolsToRemove, DC.Alloc,
1166                                      Arg->getValue(), SymbolMatchStyle,
1167                                      ErrorCallback))
1168       return std::move(E);
1169   for (auto *Arg : InputArgs.filtered(OBJCOPY_keep_symbol))
1170     if (Error E = Config.SymbolsToKeep.addMatcher(NameOrPattern::create(
1171             Arg->getValue(), SymbolMatchStyle, ErrorCallback)))
1172       return std::move(E);
1173   for (auto *Arg : InputArgs.filtered(OBJCOPY_keep_symbols))
1174     if (Error E =
1175             addSymbolsFromFile(Config.SymbolsToKeep, DC.Alloc, Arg->getValue(),
1176                                SymbolMatchStyle, ErrorCallback))
1177       return std::move(E);
1178   for (auto *Arg : InputArgs.filtered(OBJCOPY_skip_symbol))
1179     if (Error E = Config.SymbolsToSkip.addMatcher(NameOrPattern::create(
1180             Arg->getValue(), SymbolMatchStyle, ErrorCallback)))
1181       return std::move(E);
1182   for (auto *Arg : InputArgs.filtered(OBJCOPY_skip_symbols))
1183     if (Error E =
1184             addSymbolsFromFile(Config.SymbolsToSkip, DC.Alloc, Arg->getValue(),
1185                                SymbolMatchStyle, ErrorCallback))
1186       return std::move(E);
1187   for (auto *Arg : InputArgs.filtered(OBJCOPY_add_symbol)) {
1188     Expected<NewSymbolInfo> SymInfo = parseNewSymbolInfo(Arg->getValue());
1189     if (!SymInfo)
1190       return SymInfo.takeError();
1191 
1192     Config.SymbolsToAdd.push_back(*SymInfo);
1193   }
1194   for (auto *Arg : InputArgs.filtered(OBJCOPY_set_symbol_visibility)) {
1195     if (!StringRef(Arg->getValue()).contains('='))
1196       return createStringError(errc::invalid_argument,
1197                                "bad format for --set-symbol-visibility");
1198     auto [Sym, Visibility] = StringRef(Arg->getValue()).split('=');
1199     Expected<uint8_t> Type = parseVisibilityType(Visibility);
1200     if (!Type)
1201       return Type.takeError();
1202     ELFConfig.SymbolsToSetVisibility.emplace_back(NameMatcher(), *Type);
1203     if (Error E = ELFConfig.SymbolsToSetVisibility.back().first.addMatcher(
1204             NameOrPattern::create(Sym, SymbolMatchStyle, ErrorCallback)))
1205       return std::move(E);
1206   }
1207   for (auto *Arg : InputArgs.filtered(OBJCOPY_set_symbols_visibility)) {
1208     if (!StringRef(Arg->getValue()).contains('='))
1209       return createStringError(errc::invalid_argument,
1210                                "bad format for --set-symbols-visibility");
1211     auto [File, Visibility] = StringRef(Arg->getValue()).split('=');
1212     Expected<uint8_t> Type = parseVisibilityType(Visibility);
1213     if (!Type)
1214       return Type.takeError();
1215     ELFConfig.SymbolsToSetVisibility.emplace_back(NameMatcher(), *Type);
1216     if (Error E =
1217             addSymbolsFromFile(ELFConfig.SymbolsToSetVisibility.back().first,
1218                                DC.Alloc, File, SymbolMatchStyle, ErrorCallback))
1219       return std::move(E);
1220   }
1221 
1222   ELFConfig.AllowBrokenLinks = InputArgs.hasArg(OBJCOPY_allow_broken_links);
1223 
1224   Config.DeterministicArchives = InputArgs.hasFlag(
1225       OBJCOPY_enable_deterministic_archives,
1226       OBJCOPY_disable_deterministic_archives, /*default=*/true);
1227 
1228   Config.PreserveDates = InputArgs.hasArg(OBJCOPY_preserve_dates);
1229 
1230   if (Config.PreserveDates &&
1231       (Config.OutputFilename == "-" || Config.InputFilename == "-"))
1232     return createStringError(errc::invalid_argument,
1233                              "--preserve-dates requires a file");
1234 
1235   for (auto *Arg : InputArgs)
1236     if (Arg->getOption().matches(OBJCOPY_set_start)) {
1237       auto EAddr = getAsInteger<uint64_t>(Arg->getValue());
1238       if (!EAddr)
1239         return createStringError(
1240             EAddr.getError(), "bad entry point address: '%s'", Arg->getValue());
1241 
1242       ELFConfig.EntryExpr = [EAddr](uint64_t) { return *EAddr; };
1243     } else if (Arg->getOption().matches(OBJCOPY_change_start)) {
1244       auto EIncr = getAsInteger<int64_t>(Arg->getValue());
1245       if (!EIncr)
1246         return createStringError(EIncr.getError(),
1247                                  "bad entry point increment: '%s'",
1248                                  Arg->getValue());
1249       auto Expr = ELFConfig.EntryExpr ? std::move(ELFConfig.EntryExpr)
1250                                       : [](uint64_t A) { return A; };
1251       ELFConfig.EntryExpr = [Expr, EIncr](uint64_t EAddr) {
1252         return Expr(EAddr) + *EIncr;
1253       };
1254     }
1255 
1256   for (auto *Arg : InputArgs.filtered(OBJCOPY_remove_note)) {
1257     Expected<RemoveNoteInfo> NoteInfo = parseRemoveNoteInfo(Arg->getValue());
1258     if (!NoteInfo)
1259       return NoteInfo.takeError();
1260 
1261     ELFConfig.NotesToRemove.push_back(*NoteInfo);
1262   }
1263 
1264   if (!ELFConfig.NotesToRemove.empty()) {
1265     if (!Config.ToRemove.empty())
1266       return createStringError(
1267           errc::invalid_argument,
1268           "cannot specify both --remove-note and --remove-section");
1269     if (!Config.AddSection.empty())
1270       return createStringError(
1271           errc::invalid_argument,
1272           "cannot specify both --remove-note and --add-section");
1273     if (!Config.UpdateSection.empty())
1274       return createStringError(
1275           errc::invalid_argument,
1276           "cannot specify both --remove-note and --update-section");
1277   }
1278 
1279   if (Config.DecompressDebugSections &&
1280       Config.CompressionType != DebugCompressionType::None) {
1281     return createStringError(
1282         errc::invalid_argument,
1283         "cannot specify both --compress-debug-sections and "
1284         "--decompress-debug-sections");
1285   }
1286 
1287   if (Config.ExtractPartition && Config.ExtractMainPartition)
1288     return createStringError(errc::invalid_argument,
1289                              "cannot specify --extract-partition together with "
1290                              "--extract-main-partition");
1291 
1292   DC.CopyConfigs.push_back(std::move(ConfigMgr));
1293   return std::move(DC);
1294 }
1295 
1296 // parseInstallNameToolOptions returns the config and sets the input arguments.
1297 // If a help flag is set then parseInstallNameToolOptions will print the help
1298 // messege and exit.
1299 Expected<DriverConfig>
1300 objcopy::parseInstallNameToolOptions(ArrayRef<const char *> ArgsArr) {
1301   DriverConfig DC;
1302   ConfigManager ConfigMgr;
1303   CommonConfig &Config = ConfigMgr.Common;
1304   MachOConfig &MachOConfig = ConfigMgr.MachO;
1305   InstallNameToolOptTable T;
1306   unsigned MissingArgumentIndex, MissingArgumentCount;
1307   llvm::opt::InputArgList InputArgs =
1308       T.ParseArgs(ArgsArr, MissingArgumentIndex, MissingArgumentCount);
1309 
1310   if (MissingArgumentCount)
1311     return createStringError(
1312         errc::invalid_argument,
1313         "missing argument to " +
1314             StringRef(InputArgs.getArgString(MissingArgumentIndex)) +
1315             " option");
1316 
1317   if (InputArgs.size() == 0) {
1318     printHelp(T, errs(), ToolType::InstallNameTool);
1319     exit(1);
1320   }
1321 
1322   if (InputArgs.hasArg(INSTALL_NAME_TOOL_help)) {
1323     printHelp(T, outs(), ToolType::InstallNameTool);
1324     exit(0);
1325   }
1326 
1327   if (InputArgs.hasArg(INSTALL_NAME_TOOL_version)) {
1328     outs() << "llvm-install-name-tool, compatible with cctools "
1329               "install_name_tool\n";
1330     cl::PrintVersionMessage();
1331     exit(0);
1332   }
1333 
1334   for (auto *Arg : InputArgs.filtered(INSTALL_NAME_TOOL_add_rpath))
1335     MachOConfig.RPathToAdd.push_back(Arg->getValue());
1336 
1337   for (auto *Arg : InputArgs.filtered(INSTALL_NAME_TOOL_prepend_rpath))
1338     MachOConfig.RPathToPrepend.push_back(Arg->getValue());
1339 
1340   for (auto *Arg : InputArgs.filtered(INSTALL_NAME_TOOL_delete_rpath)) {
1341     StringRef RPath = Arg->getValue();
1342 
1343     // Cannot add and delete the same rpath at the same time.
1344     if (is_contained(MachOConfig.RPathToAdd, RPath))
1345       return createStringError(
1346           errc::invalid_argument,
1347           "cannot specify both -add_rpath '%s' and -delete_rpath '%s'",
1348           RPath.str().c_str(), RPath.str().c_str());
1349     if (is_contained(MachOConfig.RPathToPrepend, RPath))
1350       return createStringError(
1351           errc::invalid_argument,
1352           "cannot specify both -prepend_rpath '%s' and -delete_rpath '%s'",
1353           RPath.str().c_str(), RPath.str().c_str());
1354 
1355     MachOConfig.RPathsToRemove.insert(RPath);
1356   }
1357 
1358   for (auto *Arg : InputArgs.filtered(INSTALL_NAME_TOOL_rpath)) {
1359     StringRef Old = Arg->getValue(0);
1360     StringRef New = Arg->getValue(1);
1361 
1362     auto Match = [=](StringRef RPath) { return RPath == Old || RPath == New; };
1363 
1364     // Cannot specify duplicate -rpath entries
1365     auto It1 = find_if(
1366         MachOConfig.RPathsToUpdate,
1367         [&Match](const DenseMap<StringRef, StringRef>::value_type &OldNew) {
1368           return Match(OldNew.getFirst()) || Match(OldNew.getSecond());
1369         });
1370     if (It1 != MachOConfig.RPathsToUpdate.end())
1371       return createStringError(errc::invalid_argument,
1372                                "cannot specify both -rpath '" +
1373                                    It1->getFirst() + "' '" + It1->getSecond() +
1374                                    "' and -rpath '" + Old + "' '" + New + "'");
1375 
1376     // Cannot specify the same rpath under both -delete_rpath and -rpath
1377     auto It2 = find_if(MachOConfig.RPathsToRemove, Match);
1378     if (It2 != MachOConfig.RPathsToRemove.end())
1379       return createStringError(errc::invalid_argument,
1380                                "cannot specify both -delete_rpath '" + *It2 +
1381                                    "' and -rpath '" + Old + "' '" + New + "'");
1382 
1383     // Cannot specify the same rpath under both -add_rpath and -rpath
1384     auto It3 = find_if(MachOConfig.RPathToAdd, Match);
1385     if (It3 != MachOConfig.RPathToAdd.end())
1386       return createStringError(errc::invalid_argument,
1387                                "cannot specify both -add_rpath '" + *It3 +
1388                                    "' and -rpath '" + Old + "' '" + New + "'");
1389 
1390     // Cannot specify the same rpath under both -prepend_rpath and -rpath.
1391     auto It4 = find_if(MachOConfig.RPathToPrepend, Match);
1392     if (It4 != MachOConfig.RPathToPrepend.end())
1393       return createStringError(errc::invalid_argument,
1394                                "cannot specify both -prepend_rpath '" + *It4 +
1395                                    "' and -rpath '" + Old + "' '" + New + "'");
1396 
1397     MachOConfig.RPathsToUpdate.insert({Old, New});
1398   }
1399 
1400   if (auto *Arg = InputArgs.getLastArg(INSTALL_NAME_TOOL_id)) {
1401     MachOConfig.SharedLibId = Arg->getValue();
1402     if (MachOConfig.SharedLibId->empty())
1403       return createStringError(errc::invalid_argument,
1404                                "cannot specify an empty id");
1405   }
1406 
1407   for (auto *Arg : InputArgs.filtered(INSTALL_NAME_TOOL_change))
1408     MachOConfig.InstallNamesToUpdate.insert(
1409         {Arg->getValue(0), Arg->getValue(1)});
1410 
1411   MachOConfig.RemoveAllRpaths =
1412       InputArgs.hasArg(INSTALL_NAME_TOOL_delete_all_rpaths);
1413 
1414   SmallVector<StringRef, 2> Positional;
1415   for (auto *Arg : InputArgs.filtered(INSTALL_NAME_TOOL_UNKNOWN))
1416     return createStringError(errc::invalid_argument, "unknown argument '%s'",
1417                              Arg->getAsString(InputArgs).c_str());
1418   for (auto *Arg : InputArgs.filtered(INSTALL_NAME_TOOL_INPUT))
1419     Positional.push_back(Arg->getValue());
1420   if (Positional.empty())
1421     return createStringError(errc::invalid_argument, "no input file specified");
1422   if (Positional.size() > 1)
1423     return createStringError(
1424         errc::invalid_argument,
1425         "llvm-install-name-tool expects a single input file");
1426   Config.InputFilename = Positional[0];
1427   Config.OutputFilename = Positional[0];
1428 
1429   Expected<OwningBinary<Binary>> BinaryOrErr =
1430       createBinary(Config.InputFilename);
1431   if (!BinaryOrErr)
1432     return createFileError(Config.InputFilename, BinaryOrErr.takeError());
1433   auto *Binary = (*BinaryOrErr).getBinary();
1434   if (!Binary->isMachO() && !Binary->isMachOUniversalBinary())
1435     return createStringError(errc::invalid_argument,
1436                              "input file: %s is not a Mach-O file",
1437                              Config.InputFilename.str().c_str());
1438 
1439   DC.CopyConfigs.push_back(std::move(ConfigMgr));
1440   return std::move(DC);
1441 }
1442 
1443 Expected<DriverConfig>
1444 objcopy::parseBitcodeStripOptions(ArrayRef<const char *> ArgsArr,
1445                                   function_ref<Error(Error)> ErrorCallback) {
1446   DriverConfig DC;
1447   ConfigManager ConfigMgr;
1448   CommonConfig &Config = ConfigMgr.Common;
1449   MachOConfig &MachOConfig = ConfigMgr.MachO;
1450   BitcodeStripOptTable T;
1451   unsigned MissingArgumentIndex, MissingArgumentCount;
1452   opt::InputArgList InputArgs =
1453       T.ParseArgs(ArgsArr, MissingArgumentIndex, MissingArgumentCount);
1454 
1455   if (InputArgs.size() == 0) {
1456     printHelp(T, errs(), ToolType::BitcodeStrip);
1457     exit(1);
1458   }
1459 
1460   if (InputArgs.hasArg(BITCODE_STRIP_help)) {
1461     printHelp(T, outs(), ToolType::BitcodeStrip);
1462     exit(0);
1463   }
1464 
1465   if (InputArgs.hasArg(BITCODE_STRIP_version)) {
1466     outs() << "llvm-bitcode-strip, compatible with cctools "
1467               "bitcode_strip\n";
1468     cl::PrintVersionMessage();
1469     exit(0);
1470   }
1471 
1472   for (auto *Arg : InputArgs.filtered(BITCODE_STRIP_UNKNOWN))
1473     return createStringError(errc::invalid_argument, "unknown argument '%s'",
1474                              Arg->getAsString(InputArgs).c_str());
1475 
1476   SmallVector<StringRef, 2> Positional;
1477   for (auto *Arg : InputArgs.filtered(BITCODE_STRIP_INPUT))
1478     Positional.push_back(Arg->getValue());
1479   if (Positional.size() > 1)
1480     return createStringError(errc::invalid_argument,
1481                              "llvm-bitcode-strip expects a single input file");
1482   assert(!Positional.empty());
1483   Config.InputFilename = Positional[0];
1484 
1485   if (!InputArgs.hasArg(BITCODE_STRIP_output)) {
1486     return createStringError(errc::invalid_argument,
1487                              "-o is a required argument");
1488   }
1489   Config.OutputFilename = InputArgs.getLastArgValue(BITCODE_STRIP_output);
1490 
1491   if (!InputArgs.hasArg(BITCODE_STRIP_remove))
1492     return createStringError(errc::invalid_argument, "no action specified");
1493 
1494   // We only support -r for now, which removes all bitcode sections and
1495   // the __LLVM segment if it's now empty.
1496   cantFail(Config.ToRemove.addMatcher(NameOrPattern::create(
1497       "__LLVM,__asm", MatchStyle::Literal, ErrorCallback)));
1498   cantFail(Config.ToRemove.addMatcher(NameOrPattern::create(
1499       "__LLVM,__bitcode", MatchStyle::Literal, ErrorCallback)));
1500   cantFail(Config.ToRemove.addMatcher(NameOrPattern::create(
1501       "__LLVM,__bundle", MatchStyle::Literal, ErrorCallback)));
1502   cantFail(Config.ToRemove.addMatcher(NameOrPattern::create(
1503       "__LLVM,__cmdline", MatchStyle::Literal, ErrorCallback)));
1504   cantFail(Config.ToRemove.addMatcher(NameOrPattern::create(
1505       "__LLVM,__swift_cmdline", MatchStyle::Literal, ErrorCallback)));
1506   MachOConfig.EmptySegmentsToRemove.insert("__LLVM");
1507 
1508   DC.CopyConfigs.push_back(std::move(ConfigMgr));
1509   return std::move(DC);
1510 }
1511 
1512 // parseStripOptions returns the config and sets the input arguments. If a
1513 // help flag is set then parseStripOptions will print the help messege and
1514 // exit.
1515 Expected<DriverConfig>
1516 objcopy::parseStripOptions(ArrayRef<const char *> RawArgsArr,
1517                            function_ref<Error(Error)> ErrorCallback) {
1518   const char *const *DashDash =
1519       llvm::find_if(RawArgsArr, [](StringRef Str) { return Str == "--"; });
1520   ArrayRef<const char *> ArgsArr = ArrayRef(RawArgsArr.begin(), DashDash);
1521   if (DashDash != RawArgsArr.end())
1522     DashDash = std::next(DashDash);
1523 
1524   StripOptTable T;
1525   unsigned MissingArgumentIndex, MissingArgumentCount;
1526   llvm::opt::InputArgList InputArgs =
1527       T.ParseArgs(ArgsArr, MissingArgumentIndex, MissingArgumentCount);
1528 
1529   if (InputArgs.size() == 0 && DashDash == RawArgsArr.end()) {
1530     printHelp(T, errs(), ToolType::Strip);
1531     exit(1);
1532   }
1533 
1534   if (InputArgs.hasArg(STRIP_help)) {
1535     printHelp(T, outs(), ToolType::Strip);
1536     exit(0);
1537   }
1538 
1539   if (InputArgs.hasArg(STRIP_version)) {
1540     outs() << "llvm-strip, compatible with GNU strip\n";
1541     cl::PrintVersionMessage();
1542     exit(0);
1543   }
1544 
1545   SmallVector<StringRef, 2> Positional;
1546   for (auto *Arg : InputArgs.filtered(STRIP_UNKNOWN))
1547     return createStringError(errc::invalid_argument, "unknown argument '%s'",
1548                              Arg->getAsString(InputArgs).c_str());
1549   for (auto *Arg : InputArgs.filtered(STRIP_INPUT))
1550     Positional.push_back(Arg->getValue());
1551   std::copy(DashDash, RawArgsArr.end(), std::back_inserter(Positional));
1552 
1553   if (Positional.empty())
1554     return createStringError(errc::invalid_argument, "no input file specified");
1555 
1556   if (Positional.size() > 1 && InputArgs.hasArg(STRIP_output))
1557     return createStringError(
1558         errc::invalid_argument,
1559         "multiple input files cannot be used in combination with -o");
1560 
1561   ConfigManager ConfigMgr;
1562   CommonConfig &Config = ConfigMgr.Common;
1563   ELFConfig &ELFConfig = ConfigMgr.ELF;
1564   MachOConfig &MachOConfig = ConfigMgr.MachO;
1565 
1566   if (InputArgs.hasArg(STRIP_regex) && InputArgs.hasArg(STRIP_wildcard))
1567     return createStringError(errc::invalid_argument,
1568                              "--regex and --wildcard are incompatible");
1569   MatchStyle SectionMatchStyle =
1570       InputArgs.hasArg(STRIP_regex) ? MatchStyle::Regex : MatchStyle::Wildcard;
1571   MatchStyle SymbolMatchStyle
1572       = InputArgs.hasArg(STRIP_regex)    ? MatchStyle::Regex
1573       : InputArgs.hasArg(STRIP_wildcard) ? MatchStyle::Wildcard
1574                                          : MatchStyle::Literal;
1575   ELFConfig.AllowBrokenLinks = InputArgs.hasArg(STRIP_allow_broken_links);
1576   Config.StripDebug = InputArgs.hasArg(STRIP_strip_debug);
1577 
1578   if (auto *Arg = InputArgs.getLastArg(STRIP_discard_all, STRIP_discard_locals))
1579     Config.DiscardMode = Arg->getOption().matches(STRIP_discard_all)
1580                              ? DiscardType::All
1581                              : DiscardType::Locals;
1582   Config.StripSections = InputArgs.hasArg(STRIP_strip_sections);
1583   Config.StripUnneeded = InputArgs.hasArg(STRIP_strip_unneeded);
1584   if (auto Arg = InputArgs.getLastArg(STRIP_strip_all, STRIP_no_strip_all))
1585     Config.StripAll = Arg->getOption().getID() == STRIP_strip_all;
1586   Config.StripAllGNU = InputArgs.hasArg(STRIP_strip_all_gnu);
1587   MachOConfig.StripSwiftSymbols = InputArgs.hasArg(STRIP_strip_swift_symbols);
1588   Config.OnlyKeepDebug = InputArgs.hasArg(STRIP_only_keep_debug);
1589   ELFConfig.KeepFileSymbols = InputArgs.hasArg(STRIP_keep_file_symbols);
1590   MachOConfig.KeepUndefined = InputArgs.hasArg(STRIP_keep_undefined);
1591 
1592   for (auto *Arg : InputArgs.filtered(STRIP_keep_section))
1593     if (Error E = Config.KeepSection.addMatcher(NameOrPattern::create(
1594             Arg->getValue(), SectionMatchStyle, ErrorCallback)))
1595       return std::move(E);
1596 
1597   for (auto *Arg : InputArgs.filtered(STRIP_remove_section))
1598     if (Error E = Config.ToRemove.addMatcher(NameOrPattern::create(
1599             Arg->getValue(), SectionMatchStyle, ErrorCallback)))
1600       return std::move(E);
1601 
1602   for (auto *Arg : InputArgs.filtered(STRIP_strip_symbol))
1603     if (Error E = Config.SymbolsToRemove.addMatcher(NameOrPattern::create(
1604             Arg->getValue(), SymbolMatchStyle, ErrorCallback)))
1605       return std::move(E);
1606 
1607   for (auto *Arg : InputArgs.filtered(STRIP_keep_symbol))
1608     if (Error E = Config.SymbolsToKeep.addMatcher(NameOrPattern::create(
1609             Arg->getValue(), SymbolMatchStyle, ErrorCallback)))
1610       return std::move(E);
1611 
1612   if (!InputArgs.hasArg(STRIP_no_strip_all) && !Config.StripDebug &&
1613       !Config.OnlyKeepDebug && !Config.StripUnneeded &&
1614       Config.DiscardMode == DiscardType::None && !Config.StripAllGNU &&
1615       Config.SymbolsToRemove.empty())
1616     Config.StripAll = true;
1617 
1618   if (Config.DiscardMode == DiscardType::All) {
1619     Config.StripDebug = true;
1620     ELFConfig.KeepFileSymbols = true;
1621   }
1622 
1623   Config.DeterministicArchives =
1624       InputArgs.hasFlag(STRIP_enable_deterministic_archives,
1625                         STRIP_disable_deterministic_archives, /*default=*/true);
1626 
1627   Config.PreserveDates = InputArgs.hasArg(STRIP_preserve_dates);
1628   Config.InputFormat = FileFormat::Unspecified;
1629   Config.OutputFormat = FileFormat::Unspecified;
1630 
1631   DriverConfig DC;
1632   if (Positional.size() == 1) {
1633     Config.InputFilename = Positional[0];
1634     Config.OutputFilename =
1635         InputArgs.getLastArgValue(STRIP_output, Positional[0]);
1636     DC.CopyConfigs.push_back(std::move(ConfigMgr));
1637   } else {
1638     StringMap<unsigned> InputFiles;
1639     for (StringRef Filename : Positional) {
1640       if (InputFiles[Filename]++ == 1) {
1641         if (Filename == "-")
1642           return createStringError(
1643               errc::invalid_argument,
1644               "cannot specify '-' as an input file more than once");
1645         if (Error E = ErrorCallback(createStringError(
1646                 errc::invalid_argument, "'%s' was already specified",
1647                 Filename.str().c_str())))
1648           return std::move(E);
1649       }
1650       Config.InputFilename = Filename;
1651       Config.OutputFilename = Filename;
1652       DC.CopyConfigs.push_back(ConfigMgr);
1653     }
1654   }
1655 
1656   if (Config.PreserveDates && (is_contained(Positional, "-") ||
1657                                InputArgs.getLastArgValue(STRIP_output) == "-"))
1658     return createStringError(errc::invalid_argument,
1659                              "--preserve-dates requires a file");
1660 
1661   return std::move(DC);
1662 }
1663