ObjcopyOptions.cpp 57 KB

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