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