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", DebugCompressionType::Z)
733               .Default(DebugCompressionType::None);
734       if (Config.CompressionType == DebugCompressionType::None)
735         return createStringError(
736             errc::invalid_argument,
737             "invalid or unsupported --compress-debug-sections format: %s",
738             InputArgs.getLastArgValue(OBJCOPY_compress_debug_sections_eq)
739                 .str()
740                 .c_str());
741     }
742     if (!compression::zlib::isAvailable())
743       return createStringError(
744           errc::invalid_argument,
745           "LLVM was not compiled with LLVM_ENABLE_ZLIB: can not compress");
746   }
747 
748   Config.AddGnuDebugLink = InputArgs.getLastArgValue(OBJCOPY_add_gnu_debuglink);
749   // The gnu_debuglink's target is expected to not change or else its CRC would
750   // become invalidated and get rejected. We can avoid recalculating the
751   // checksum for every target file inside an archive by precomputing the CRC
752   // here. This prevents a significant amount of I/O.
753   if (!Config.AddGnuDebugLink.empty()) {
754     auto DebugOrErr = MemoryBuffer::getFile(Config.AddGnuDebugLink);
755     if (!DebugOrErr)
756       return createFileError(Config.AddGnuDebugLink, DebugOrErr.getError());
757     auto Debug = std::move(*DebugOrErr);
758     Config.GnuDebugLinkCRC32 =
759         llvm::crc32(arrayRefFromStringRef(Debug->getBuffer()));
760   }
761   Config.SplitDWO = InputArgs.getLastArgValue(OBJCOPY_split_dwo);
762   Config.SymbolsPrefix = InputArgs.getLastArgValue(OBJCOPY_prefix_symbols);
763   Config.AllocSectionsPrefix =
764       InputArgs.getLastArgValue(OBJCOPY_prefix_alloc_sections);
765   if (auto Arg = InputArgs.getLastArg(OBJCOPY_extract_partition))
766     Config.ExtractPartition = Arg->getValue();
767 
768   for (auto Arg : InputArgs.filtered(OBJCOPY_redefine_symbol)) {
769     if (!StringRef(Arg->getValue()).contains('='))
770       return createStringError(errc::invalid_argument,
771                                "bad format for --redefine-sym");
772     auto Old2New = StringRef(Arg->getValue()).split('=');
773     if (!Config.SymbolsToRename.insert(Old2New).second)
774       return createStringError(errc::invalid_argument,
775                                "multiple redefinition of symbol '%s'",
776                                Old2New.first.str().c_str());
777   }
778 
779   for (auto Arg : InputArgs.filtered(OBJCOPY_redefine_symbols))
780     if (Error E = addSymbolsToRenameFromFile(Config.SymbolsToRename, DC.Alloc,
781                                              Arg->getValue()))
782       return std::move(E);
783 
784   for (auto Arg : InputArgs.filtered(OBJCOPY_rename_section)) {
785     Expected<SectionRename> SR =
786         parseRenameSectionValue(StringRef(Arg->getValue()));
787     if (!SR)
788       return SR.takeError();
789     if (!Config.SectionsToRename.try_emplace(SR->OriginalName, *SR).second)
790       return createStringError(errc::invalid_argument,
791                                "multiple renames of section '%s'",
792                                SR->OriginalName.str().c_str());
793   }
794   for (auto Arg : InputArgs.filtered(OBJCOPY_set_section_alignment)) {
795     Expected<std::pair<StringRef, uint64_t>> NameAndAlign =
796         parseSetSectionAlignment(Arg->getValue());
797     if (!NameAndAlign)
798       return NameAndAlign.takeError();
799     Config.SetSectionAlignment[NameAndAlign->first] = NameAndAlign->second;
800   }
801   for (auto Arg : InputArgs.filtered(OBJCOPY_set_section_flags)) {
802     Expected<SectionFlagsUpdate> SFU =
803         parseSetSectionFlagValue(Arg->getValue());
804     if (!SFU)
805       return SFU.takeError();
806     if (!Config.SetSectionFlags.try_emplace(SFU->Name, *SFU).second)
807       return createStringError(
808           errc::invalid_argument,
809           "--set-section-flags set multiple times for section '%s'",
810           SFU->Name.str().c_str());
811   }
812   // Prohibit combinations of --set-section-flags when the section name is used
813   // as the destination of a --rename-section.
814   for (const auto &E : Config.SectionsToRename) {
815     const SectionRename &SR = E.second;
816     if (Config.SetSectionFlags.count(SR.NewName))
817       return createStringError(
818           errc::invalid_argument,
819           "--set-section-flags=%s conflicts with --rename-section=%s=%s",
820           SR.NewName.str().c_str(), SR.OriginalName.str().c_str(),
821           SR.NewName.str().c_str());
822   }
823 
824   for (auto Arg : InputArgs.filtered(OBJCOPY_remove_section))
825     if (Error E = Config.ToRemove.addMatcher(NameOrPattern::create(
826             Arg->getValue(), SectionMatchStyle, ErrorCallback)))
827       return std::move(E);
828   for (auto Arg : InputArgs.filtered(OBJCOPY_keep_section))
829     if (Error E = Config.KeepSection.addMatcher(NameOrPattern::create(
830             Arg->getValue(), SectionMatchStyle, ErrorCallback)))
831       return std::move(E);
832   for (auto Arg : InputArgs.filtered(OBJCOPY_only_section))
833     if (Error E = Config.OnlySection.addMatcher(NameOrPattern::create(
834             Arg->getValue(), SectionMatchStyle, ErrorCallback)))
835       return std::move(E);
836   for (auto Arg : InputArgs.filtered(OBJCOPY_add_section)) {
837     if (Error Err = loadNewSectionData(Arg->getValue(), "--add-section",
838                                        Config.AddSection))
839       return std::move(Err);
840   }
841   for (auto Arg : InputArgs.filtered(OBJCOPY_update_section)) {
842     if (Error Err = loadNewSectionData(Arg->getValue(), "--update-section",
843                                        Config.UpdateSection))
844       return std::move(Err);
845   }
846   for (auto *Arg : InputArgs.filtered(OBJCOPY_dump_section)) {
847     StringRef Value(Arg->getValue());
848     if (Value.split('=').second.empty())
849       return createStringError(
850           errc::invalid_argument,
851           "bad format for --dump-section, expected section=file");
852     Config.DumpSection.push_back(Value);
853   }
854   Config.StripAll = InputArgs.hasArg(OBJCOPY_strip_all);
855   Config.StripAllGNU = InputArgs.hasArg(OBJCOPY_strip_all_gnu);
856   Config.StripDebug = InputArgs.hasArg(OBJCOPY_strip_debug);
857   Config.StripDWO = InputArgs.hasArg(OBJCOPY_strip_dwo);
858   Config.StripSections = InputArgs.hasArg(OBJCOPY_strip_sections);
859   Config.StripNonAlloc = InputArgs.hasArg(OBJCOPY_strip_non_alloc);
860   Config.StripUnneeded = InputArgs.hasArg(OBJCOPY_strip_unneeded);
861   Config.ExtractDWO = InputArgs.hasArg(OBJCOPY_extract_dwo);
862   Config.ExtractMainPartition =
863       InputArgs.hasArg(OBJCOPY_extract_main_partition);
864   ELFConfig.LocalizeHidden = InputArgs.hasArg(OBJCOPY_localize_hidden);
865   Config.Weaken = InputArgs.hasArg(OBJCOPY_weaken);
866   if (auto *Arg =
867           InputArgs.getLastArg(OBJCOPY_discard_all, OBJCOPY_discard_locals)) {
868     Config.DiscardMode = Arg->getOption().matches(OBJCOPY_discard_all)
869                              ? DiscardType::All
870                              : DiscardType::Locals;
871   }
872   Config.OnlyKeepDebug = InputArgs.hasArg(OBJCOPY_only_keep_debug);
873   ELFConfig.KeepFileSymbols = InputArgs.hasArg(OBJCOPY_keep_file_symbols);
874   MachOConfig.KeepUndefined = InputArgs.hasArg(OBJCOPY_keep_undefined);
875   Config.DecompressDebugSections =
876       InputArgs.hasArg(OBJCOPY_decompress_debug_sections);
877   if (Config.DiscardMode == DiscardType::All) {
878     Config.StripDebug = true;
879     ELFConfig.KeepFileSymbols = true;
880   }
881   for (auto Arg : InputArgs.filtered(OBJCOPY_localize_symbol))
882     if (Error E = Config.SymbolsToLocalize.addMatcher(NameOrPattern::create(
883             Arg->getValue(), SymbolMatchStyle, ErrorCallback)))
884       return std::move(E);
885   for (auto Arg : InputArgs.filtered(OBJCOPY_localize_symbols))
886     if (Error E = addSymbolsFromFile(Config.SymbolsToLocalize, DC.Alloc,
887                                      Arg->getValue(), SymbolMatchStyle,
888                                      ErrorCallback))
889       return std::move(E);
890   for (auto Arg : InputArgs.filtered(OBJCOPY_keep_global_symbol))
891     if (Error E = Config.SymbolsToKeepGlobal.addMatcher(NameOrPattern::create(
892             Arg->getValue(), SymbolMatchStyle, ErrorCallback)))
893       return std::move(E);
894   for (auto Arg : InputArgs.filtered(OBJCOPY_keep_global_symbols))
895     if (Error E = addSymbolsFromFile(Config.SymbolsToKeepGlobal, DC.Alloc,
896                                      Arg->getValue(), SymbolMatchStyle,
897                                      ErrorCallback))
898       return std::move(E);
899   for (auto Arg : InputArgs.filtered(OBJCOPY_globalize_symbol))
900     if (Error E = Config.SymbolsToGlobalize.addMatcher(NameOrPattern::create(
901             Arg->getValue(), SymbolMatchStyle, ErrorCallback)))
902       return std::move(E);
903   for (auto Arg : InputArgs.filtered(OBJCOPY_globalize_symbols))
904     if (Error E = addSymbolsFromFile(Config.SymbolsToGlobalize, DC.Alloc,
905                                      Arg->getValue(), SymbolMatchStyle,
906                                      ErrorCallback))
907       return std::move(E);
908   for (auto Arg : InputArgs.filtered(OBJCOPY_weaken_symbol))
909     if (Error E = Config.SymbolsToWeaken.addMatcher(NameOrPattern::create(
910             Arg->getValue(), SymbolMatchStyle, ErrorCallback)))
911       return std::move(E);
912   for (auto Arg : InputArgs.filtered(OBJCOPY_weaken_symbols))
913     if (Error E = addSymbolsFromFile(Config.SymbolsToWeaken, DC.Alloc,
914                                      Arg->getValue(), SymbolMatchStyle,
915                                      ErrorCallback))
916       return std::move(E);
917   for (auto Arg : InputArgs.filtered(OBJCOPY_strip_symbol))
918     if (Error E = Config.SymbolsToRemove.addMatcher(NameOrPattern::create(
919             Arg->getValue(), SymbolMatchStyle, ErrorCallback)))
920       return std::move(E);
921   for (auto Arg : InputArgs.filtered(OBJCOPY_strip_symbols))
922     if (Error E = addSymbolsFromFile(Config.SymbolsToRemove, DC.Alloc,
923                                      Arg->getValue(), SymbolMatchStyle,
924                                      ErrorCallback))
925       return std::move(E);
926   for (auto Arg : InputArgs.filtered(OBJCOPY_strip_unneeded_symbol))
927     if (Error E =
928             Config.UnneededSymbolsToRemove.addMatcher(NameOrPattern::create(
929                 Arg->getValue(), SymbolMatchStyle, ErrorCallback)))
930       return std::move(E);
931   for (auto Arg : InputArgs.filtered(OBJCOPY_strip_unneeded_symbols))
932     if (Error E = addSymbolsFromFile(Config.UnneededSymbolsToRemove, DC.Alloc,
933                                      Arg->getValue(), SymbolMatchStyle,
934                                      ErrorCallback))
935       return std::move(E);
936   for (auto Arg : InputArgs.filtered(OBJCOPY_keep_symbol))
937     if (Error E = Config.SymbolsToKeep.addMatcher(NameOrPattern::create(
938             Arg->getValue(), SymbolMatchStyle, ErrorCallback)))
939       return std::move(E);
940   for (auto Arg : InputArgs.filtered(OBJCOPY_keep_symbols))
941     if (Error E =
942             addSymbolsFromFile(Config.SymbolsToKeep, DC.Alloc, Arg->getValue(),
943                                SymbolMatchStyle, ErrorCallback))
944       return std::move(E);
945   for (auto *Arg : InputArgs.filtered(OBJCOPY_add_symbol)) {
946     Expected<NewSymbolInfo> SymInfo = parseNewSymbolInfo(Arg->getValue());
947     if (!SymInfo)
948       return SymInfo.takeError();
949 
950     Config.SymbolsToAdd.push_back(*SymInfo);
951   }
952 
953   ELFConfig.AllowBrokenLinks = InputArgs.hasArg(OBJCOPY_allow_broken_links);
954 
955   Config.DeterministicArchives = InputArgs.hasFlag(
956       OBJCOPY_enable_deterministic_archives,
957       OBJCOPY_disable_deterministic_archives, /*default=*/true);
958 
959   Config.PreserveDates = InputArgs.hasArg(OBJCOPY_preserve_dates);
960 
961   if (Config.PreserveDates &&
962       (Config.OutputFilename == "-" || Config.InputFilename == "-"))
963     return createStringError(errc::invalid_argument,
964                              "--preserve-dates requires a file");
965 
966   for (auto Arg : InputArgs)
967     if (Arg->getOption().matches(OBJCOPY_set_start)) {
968       auto EAddr = getAsInteger<uint64_t>(Arg->getValue());
969       if (!EAddr)
970         return createStringError(
971             EAddr.getError(), "bad entry point address: '%s'", Arg->getValue());
972 
973       ELFConfig.EntryExpr = [EAddr](uint64_t) { return *EAddr; };
974     } else if (Arg->getOption().matches(OBJCOPY_change_start)) {
975       auto EIncr = getAsInteger<int64_t>(Arg->getValue());
976       if (!EIncr)
977         return createStringError(EIncr.getError(),
978                                  "bad entry point increment: '%s'",
979                                  Arg->getValue());
980       auto Expr = ELFConfig.EntryExpr ? std::move(ELFConfig.EntryExpr)
981                                       : [](uint64_t A) { return A; };
982       ELFConfig.EntryExpr = [Expr, EIncr](uint64_t EAddr) {
983         return Expr(EAddr) + *EIncr;
984       };
985     }
986 
987   if (Config.DecompressDebugSections &&
988       Config.CompressionType != DebugCompressionType::None) {
989     return createStringError(
990         errc::invalid_argument,
991         "cannot specify both --compress-debug-sections and "
992         "--decompress-debug-sections");
993   }
994 
995   if (Config.DecompressDebugSections && !compression::zlib::isAvailable())
996     return createStringError(
997         errc::invalid_argument,
998         "LLVM was not compiled with LLVM_ENABLE_ZLIB: cannot decompress");
999 
1000   if (Config.ExtractPartition && Config.ExtractMainPartition)
1001     return createStringError(errc::invalid_argument,
1002                              "cannot specify --extract-partition together with "
1003                              "--extract-main-partition");
1004 
1005   DC.CopyConfigs.push_back(std::move(ConfigMgr));
1006   return std::move(DC);
1007 }
1008 
1009 // parseInstallNameToolOptions returns the config and sets the input arguments.
1010 // If a help flag is set then parseInstallNameToolOptions will print the help
1011 // messege and exit.
1012 Expected<DriverConfig>
1013 objcopy::parseInstallNameToolOptions(ArrayRef<const char *> ArgsArr) {
1014   DriverConfig DC;
1015   ConfigManager ConfigMgr;
1016   CommonConfig &Config = ConfigMgr.Common;
1017   MachOConfig &MachOConfig = ConfigMgr.MachO;
1018   InstallNameToolOptTable T;
1019   unsigned MissingArgumentIndex, MissingArgumentCount;
1020   llvm::opt::InputArgList InputArgs =
1021       T.ParseArgs(ArgsArr, MissingArgumentIndex, MissingArgumentCount);
1022 
1023   if (MissingArgumentCount)
1024     return createStringError(
1025         errc::invalid_argument,
1026         "missing argument to " +
1027             StringRef(InputArgs.getArgString(MissingArgumentIndex)) +
1028             " option");
1029 
1030   if (InputArgs.size() == 0) {
1031     printHelp(T, errs(), ToolType::InstallNameTool);
1032     exit(1);
1033   }
1034 
1035   if (InputArgs.hasArg(INSTALL_NAME_TOOL_help)) {
1036     printHelp(T, outs(), ToolType::InstallNameTool);
1037     exit(0);
1038   }
1039 
1040   if (InputArgs.hasArg(INSTALL_NAME_TOOL_version)) {
1041     outs() << "llvm-install-name-tool, compatible with cctools "
1042               "install_name_tool\n";
1043     cl::PrintVersionMessage();
1044     exit(0);
1045   }
1046 
1047   for (auto Arg : InputArgs.filtered(INSTALL_NAME_TOOL_add_rpath))
1048     MachOConfig.RPathToAdd.push_back(Arg->getValue());
1049 
1050   for (auto *Arg : InputArgs.filtered(INSTALL_NAME_TOOL_prepend_rpath))
1051     MachOConfig.RPathToPrepend.push_back(Arg->getValue());
1052 
1053   for (auto Arg : InputArgs.filtered(INSTALL_NAME_TOOL_delete_rpath)) {
1054     StringRef RPath = Arg->getValue();
1055 
1056     // Cannot add and delete the same rpath at the same time.
1057     if (is_contained(MachOConfig.RPathToAdd, RPath))
1058       return createStringError(
1059           errc::invalid_argument,
1060           "cannot specify both -add_rpath '%s' and -delete_rpath '%s'",
1061           RPath.str().c_str(), RPath.str().c_str());
1062     if (is_contained(MachOConfig.RPathToPrepend, RPath))
1063       return createStringError(
1064           errc::invalid_argument,
1065           "cannot specify both -prepend_rpath '%s' and -delete_rpath '%s'",
1066           RPath.str().c_str(), RPath.str().c_str());
1067 
1068     MachOConfig.RPathsToRemove.insert(RPath);
1069   }
1070 
1071   for (auto *Arg : InputArgs.filtered(INSTALL_NAME_TOOL_rpath)) {
1072     StringRef Old = Arg->getValue(0);
1073     StringRef New = Arg->getValue(1);
1074 
1075     auto Match = [=](StringRef RPath) { return RPath == Old || RPath == New; };
1076 
1077     // Cannot specify duplicate -rpath entries
1078     auto It1 = find_if(
1079         MachOConfig.RPathsToUpdate,
1080         [&Match](const DenseMap<StringRef, StringRef>::value_type &OldNew) {
1081           return Match(OldNew.getFirst()) || Match(OldNew.getSecond());
1082         });
1083     if (It1 != MachOConfig.RPathsToUpdate.end())
1084       return createStringError(errc::invalid_argument,
1085                                "cannot specify both -rpath '" +
1086                                    It1->getFirst() + "' '" + It1->getSecond() +
1087                                    "' and -rpath '" + Old + "' '" + New + "'");
1088 
1089     // Cannot specify the same rpath under both -delete_rpath and -rpath
1090     auto It2 = find_if(MachOConfig.RPathsToRemove, Match);
1091     if (It2 != MachOConfig.RPathsToRemove.end())
1092       return createStringError(errc::invalid_argument,
1093                                "cannot specify both -delete_rpath '" + *It2 +
1094                                    "' and -rpath '" + Old + "' '" + New + "'");
1095 
1096     // Cannot specify the same rpath under both -add_rpath and -rpath
1097     auto It3 = find_if(MachOConfig.RPathToAdd, Match);
1098     if (It3 != MachOConfig.RPathToAdd.end())
1099       return createStringError(errc::invalid_argument,
1100                                "cannot specify both -add_rpath '" + *It3 +
1101                                    "' and -rpath '" + Old + "' '" + New + "'");
1102 
1103     // Cannot specify the same rpath under both -prepend_rpath and -rpath.
1104     auto It4 = find_if(MachOConfig.RPathToPrepend, Match);
1105     if (It4 != MachOConfig.RPathToPrepend.end())
1106       return createStringError(errc::invalid_argument,
1107                                "cannot specify both -prepend_rpath '" + *It4 +
1108                                    "' and -rpath '" + Old + "' '" + New + "'");
1109 
1110     MachOConfig.RPathsToUpdate.insert({Old, New});
1111   }
1112 
1113   if (auto *Arg = InputArgs.getLastArg(INSTALL_NAME_TOOL_id)) {
1114     MachOConfig.SharedLibId = Arg->getValue();
1115     if (MachOConfig.SharedLibId->empty())
1116       return createStringError(errc::invalid_argument,
1117                                "cannot specify an empty id");
1118   }
1119 
1120   for (auto *Arg : InputArgs.filtered(INSTALL_NAME_TOOL_change))
1121     MachOConfig.InstallNamesToUpdate.insert(
1122         {Arg->getValue(0), Arg->getValue(1)});
1123 
1124   MachOConfig.RemoveAllRpaths =
1125       InputArgs.hasArg(INSTALL_NAME_TOOL_delete_all_rpaths);
1126 
1127   SmallVector<StringRef, 2> Positional;
1128   for (auto Arg : InputArgs.filtered(INSTALL_NAME_TOOL_UNKNOWN))
1129     return createStringError(errc::invalid_argument, "unknown argument '%s'",
1130                              Arg->getAsString(InputArgs).c_str());
1131   for (auto Arg : InputArgs.filtered(INSTALL_NAME_TOOL_INPUT))
1132     Positional.push_back(Arg->getValue());
1133   if (Positional.empty())
1134     return createStringError(errc::invalid_argument, "no input file specified");
1135   if (Positional.size() > 1)
1136     return createStringError(
1137         errc::invalid_argument,
1138         "llvm-install-name-tool expects a single input file");
1139   Config.InputFilename = Positional[0];
1140   Config.OutputFilename = Positional[0];
1141 
1142   DC.CopyConfigs.push_back(std::move(ConfigMgr));
1143   return std::move(DC);
1144 }
1145 
1146 Expected<DriverConfig>
1147 objcopy::parseBitcodeStripOptions(ArrayRef<const char *> ArgsArr,
1148                                   function_ref<Error(Error)> ErrorCallback) {
1149   DriverConfig DC;
1150   ConfigManager ConfigMgr;
1151   CommonConfig &Config = ConfigMgr.Common;
1152   MachOConfig &MachOConfig = ConfigMgr.MachO;
1153   BitcodeStripOptTable T;
1154   unsigned MissingArgumentIndex, MissingArgumentCount;
1155   opt::InputArgList InputArgs =
1156       T.ParseArgs(ArgsArr, MissingArgumentIndex, MissingArgumentCount);
1157 
1158   if (InputArgs.size() == 0) {
1159     printHelp(T, errs(), ToolType::BitcodeStrip);
1160     exit(1);
1161   }
1162 
1163   if (InputArgs.hasArg(BITCODE_STRIP_help)) {
1164     printHelp(T, outs(), ToolType::BitcodeStrip);
1165     exit(0);
1166   }
1167 
1168   if (InputArgs.hasArg(BITCODE_STRIP_version)) {
1169     outs() << "llvm-bitcode-strip, compatible with cctools "
1170               "bitcode_strip\n";
1171     cl::PrintVersionMessage();
1172     exit(0);
1173   }
1174 
1175   for (auto *Arg : InputArgs.filtered(BITCODE_STRIP_UNKNOWN))
1176     return createStringError(errc::invalid_argument, "unknown argument '%s'",
1177                              Arg->getAsString(InputArgs).c_str());
1178 
1179   SmallVector<StringRef, 2> Positional;
1180   for (auto *Arg : InputArgs.filtered(BITCODE_STRIP_INPUT))
1181     Positional.push_back(Arg->getValue());
1182   if (Positional.size() > 1)
1183     return createStringError(errc::invalid_argument,
1184                              "llvm-bitcode-strip expects a single input file");
1185   assert(!Positional.empty());
1186   Config.InputFilename = Positional[0];
1187 
1188   if (!InputArgs.hasArg(BITCODE_STRIP_output)) {
1189     return createStringError(errc::invalid_argument,
1190                              "-o is a required argument");
1191   }
1192   Config.OutputFilename = InputArgs.getLastArgValue(BITCODE_STRIP_output);
1193 
1194   if (!InputArgs.hasArg(BITCODE_STRIP_remove))
1195     return createStringError(errc::invalid_argument, "no action specified");
1196 
1197   // We only support -r for now, which removes all bitcode sections and
1198   // the __LLVM segment if it's now empty.
1199   cantFail(Config.ToRemove.addMatcher(NameOrPattern::create(
1200       "__LLVM,__bundle", MatchStyle::Literal, ErrorCallback)));
1201   MachOConfig.EmptySegmentsToRemove.insert("__LLVM");
1202 
1203   DC.CopyConfigs.push_back(std::move(ConfigMgr));
1204   return std::move(DC);
1205 }
1206 
1207 // parseStripOptions returns the config and sets the input arguments. If a
1208 // help flag is set then parseStripOptions will print the help messege and
1209 // exit.
1210 Expected<DriverConfig>
1211 objcopy::parseStripOptions(ArrayRef<const char *> RawArgsArr,
1212                            function_ref<Error(Error)> ErrorCallback) {
1213   const char *const *DashDash =
1214       std::find_if(RawArgsArr.begin(), RawArgsArr.end(),
1215                    [](StringRef Str) { return Str == "--"; });
1216   ArrayRef<const char *> ArgsArr = makeArrayRef(RawArgsArr.begin(), DashDash);
1217   if (DashDash != RawArgsArr.end())
1218     DashDash = std::next(DashDash);
1219 
1220   StripOptTable T;
1221   unsigned MissingArgumentIndex, MissingArgumentCount;
1222   llvm::opt::InputArgList InputArgs =
1223       T.ParseArgs(ArgsArr, MissingArgumentIndex, MissingArgumentCount);
1224 
1225   if (InputArgs.size() == 0 && DashDash == RawArgsArr.end()) {
1226     printHelp(T, errs(), ToolType::Strip);
1227     exit(1);
1228   }
1229 
1230   if (InputArgs.hasArg(STRIP_help)) {
1231     printHelp(T, outs(), ToolType::Strip);
1232     exit(0);
1233   }
1234 
1235   if (InputArgs.hasArg(STRIP_version)) {
1236     outs() << "llvm-strip, compatible with GNU strip\n";
1237     cl::PrintVersionMessage();
1238     exit(0);
1239   }
1240 
1241   SmallVector<StringRef, 2> Positional;
1242   for (auto Arg : InputArgs.filtered(STRIP_UNKNOWN))
1243     return createStringError(errc::invalid_argument, "unknown argument '%s'",
1244                              Arg->getAsString(InputArgs).c_str());
1245   for (auto Arg : InputArgs.filtered(STRIP_INPUT))
1246     Positional.push_back(Arg->getValue());
1247   std::copy(DashDash, RawArgsArr.end(), std::back_inserter(Positional));
1248 
1249   if (Positional.empty())
1250     return createStringError(errc::invalid_argument, "no input file specified");
1251 
1252   if (Positional.size() > 1 && InputArgs.hasArg(STRIP_output))
1253     return createStringError(
1254         errc::invalid_argument,
1255         "multiple input files cannot be used in combination with -o");
1256 
1257   ConfigManager ConfigMgr;
1258   CommonConfig &Config = ConfigMgr.Common;
1259   ELFConfig &ELFConfig = ConfigMgr.ELF;
1260   MachOConfig &MachOConfig = ConfigMgr.MachO;
1261 
1262   if (InputArgs.hasArg(STRIP_regex) && InputArgs.hasArg(STRIP_wildcard))
1263     return createStringError(errc::invalid_argument,
1264                              "--regex and --wildcard are incompatible");
1265   MatchStyle SectionMatchStyle =
1266       InputArgs.hasArg(STRIP_regex) ? MatchStyle::Regex : MatchStyle::Wildcard;
1267   MatchStyle SymbolMatchStyle
1268       = InputArgs.hasArg(STRIP_regex)    ? MatchStyle::Regex
1269       : InputArgs.hasArg(STRIP_wildcard) ? MatchStyle::Wildcard
1270                                          : MatchStyle::Literal;
1271   ELFConfig.AllowBrokenLinks = InputArgs.hasArg(STRIP_allow_broken_links);
1272   Config.StripDebug = InputArgs.hasArg(STRIP_strip_debug);
1273 
1274   if (auto *Arg = InputArgs.getLastArg(STRIP_discard_all, STRIP_discard_locals))
1275     Config.DiscardMode = Arg->getOption().matches(STRIP_discard_all)
1276                              ? DiscardType::All
1277                              : DiscardType::Locals;
1278   Config.StripSections = InputArgs.hasArg(STRIP_strip_sections);
1279   Config.StripUnneeded = InputArgs.hasArg(STRIP_strip_unneeded);
1280   if (auto Arg = InputArgs.getLastArg(STRIP_strip_all, STRIP_no_strip_all))
1281     Config.StripAll = Arg->getOption().getID() == STRIP_strip_all;
1282   Config.StripAllGNU = InputArgs.hasArg(STRIP_strip_all_gnu);
1283   MachOConfig.StripSwiftSymbols = InputArgs.hasArg(STRIP_strip_swift_symbols);
1284   Config.OnlyKeepDebug = InputArgs.hasArg(STRIP_only_keep_debug);
1285   ELFConfig.KeepFileSymbols = InputArgs.hasArg(STRIP_keep_file_symbols);
1286   MachOConfig.KeepUndefined = InputArgs.hasArg(STRIP_keep_undefined);
1287 
1288   for (auto Arg : InputArgs.filtered(STRIP_keep_section))
1289     if (Error E = Config.KeepSection.addMatcher(NameOrPattern::create(
1290             Arg->getValue(), SectionMatchStyle, ErrorCallback)))
1291       return std::move(E);
1292 
1293   for (auto Arg : InputArgs.filtered(STRIP_remove_section))
1294     if (Error E = Config.ToRemove.addMatcher(NameOrPattern::create(
1295             Arg->getValue(), SectionMatchStyle, ErrorCallback)))
1296       return std::move(E);
1297 
1298   for (auto Arg : InputArgs.filtered(STRIP_strip_symbol))
1299     if (Error E = Config.SymbolsToRemove.addMatcher(NameOrPattern::create(
1300             Arg->getValue(), SymbolMatchStyle, ErrorCallback)))
1301       return std::move(E);
1302 
1303   for (auto Arg : InputArgs.filtered(STRIP_keep_symbol))
1304     if (Error E = Config.SymbolsToKeep.addMatcher(NameOrPattern::create(
1305             Arg->getValue(), SymbolMatchStyle, ErrorCallback)))
1306       return std::move(E);
1307 
1308   if (!InputArgs.hasArg(STRIP_no_strip_all) && !Config.StripDebug &&
1309       !Config.OnlyKeepDebug && !Config.StripUnneeded &&
1310       Config.DiscardMode == DiscardType::None && !Config.StripAllGNU &&
1311       Config.SymbolsToRemove.empty())
1312     Config.StripAll = true;
1313 
1314   if (Config.DiscardMode == DiscardType::All) {
1315     Config.StripDebug = true;
1316     ELFConfig.KeepFileSymbols = true;
1317   }
1318 
1319   Config.DeterministicArchives =
1320       InputArgs.hasFlag(STRIP_enable_deterministic_archives,
1321                         STRIP_disable_deterministic_archives, /*default=*/true);
1322 
1323   Config.PreserveDates = InputArgs.hasArg(STRIP_preserve_dates);
1324   Config.InputFormat = FileFormat::Unspecified;
1325   Config.OutputFormat = FileFormat::Unspecified;
1326 
1327   DriverConfig DC;
1328   if (Positional.size() == 1) {
1329     Config.InputFilename = Positional[0];
1330     Config.OutputFilename =
1331         InputArgs.getLastArgValue(STRIP_output, Positional[0]);
1332     DC.CopyConfigs.push_back(std::move(ConfigMgr));
1333   } else {
1334     StringMap<unsigned> InputFiles;
1335     for (StringRef Filename : Positional) {
1336       if (InputFiles[Filename]++ == 1) {
1337         if (Filename == "-")
1338           return createStringError(
1339               errc::invalid_argument,
1340               "cannot specify '-' as an input file more than once");
1341         if (Error E = ErrorCallback(createStringError(
1342                 errc::invalid_argument, "'%s' was already specified",
1343                 Filename.str().c_str())))
1344           return std::move(E);
1345       }
1346       Config.InputFilename = Filename;
1347       Config.OutputFilename = Filename;
1348       DC.CopyConfigs.push_back(ConfigMgr);
1349     }
1350   }
1351 
1352   if (Config.PreserveDates && (is_contained(Positional, "-") ||
1353                                InputArgs.getLastArgValue(STRIP_output) == "-"))
1354     return createStringError(errc::invalid_argument,
1355                              "--preserve-dates requires a file");
1356 
1357   return std::move(DC);
1358 }
1359