llvm-ar.cpp 46 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485
  1. //===-- llvm-ar.cpp - LLVM archive librarian utility ----------------------===//
  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. // Builds up (relatively) standard unix archive files (.a) containing LLVM
  10. // bitcode or other files.
  11. //
  12. //===----------------------------------------------------------------------===//
  13. #include "llvm/ADT/StringExtras.h"
  14. #include "llvm/ADT/StringSwitch.h"
  15. #include "llvm/ADT/Triple.h"
  16. #include "llvm/BinaryFormat/Magic.h"
  17. #include "llvm/IR/LLVMContext.h"
  18. #include "llvm/Object/Archive.h"
  19. #include "llvm/Object/ArchiveWriter.h"
  20. #include "llvm/Object/COFFImportFile.h"
  21. #include "llvm/Object/ELFObjectFile.h"
  22. #include "llvm/Object/IRObjectFile.h"
  23. #include "llvm/Object/MachO.h"
  24. #include "llvm/Object/ObjectFile.h"
  25. #include "llvm/Object/SymbolicFile.h"
  26. #include "llvm/Object/TapiFile.h"
  27. #include "llvm/Object/Wasm.h"
  28. #include "llvm/Object/XCOFFObjectFile.h"
  29. #include "llvm/Support/Chrono.h"
  30. #include "llvm/Support/CommandLine.h"
  31. #include "llvm/Support/ConvertUTF.h"
  32. #include "llvm/Support/Errc.h"
  33. #include "llvm/Support/FileSystem.h"
  34. #include "llvm/Support/Format.h"
  35. #include "llvm/Support/FormatVariadic.h"
  36. #include "llvm/Support/Host.h"
  37. #include "llvm/Support/InitLLVM.h"
  38. #include "llvm/Support/LineIterator.h"
  39. #include "llvm/Support/MemoryBuffer.h"
  40. #include "llvm/Support/Path.h"
  41. #include "llvm/Support/Process.h"
  42. #include "llvm/Support/StringSaver.h"
  43. #include "llvm/Support/TargetSelect.h"
  44. #include "llvm/Support/ToolOutputFile.h"
  45. #include "llvm/Support/WithColor.h"
  46. #include "llvm/Support/raw_ostream.h"
  47. #include "llvm/ToolDrivers/llvm-dlltool/DlltoolDriver.h"
  48. #include "llvm/ToolDrivers/llvm-lib/LibDriver.h"
  49. #if !defined(_MSC_VER) && !defined(__MINGW32__)
  50. #include <unistd.h>
  51. #else
  52. #include <io.h>
  53. #endif
  54. #ifdef _WIN32
  55. #include "llvm/Support/Windows/WindowsSupport.h"
  56. #endif
  57. using namespace llvm;
  58. using namespace llvm::object;
  59. // The name this program was invoked as.
  60. static StringRef ToolName;
  61. // The basename of this program.
  62. static StringRef Stem;
  63. static void printRanLibHelp(StringRef ToolName) {
  64. outs() << "OVERVIEW: LLVM ranlib\n\n"
  65. << "Generate an index for archives\n\n"
  66. << "USAGE: " + ToolName + " archive...\n\n"
  67. << "OPTIONS:\n"
  68. << " -h --help - Display available options\n"
  69. << " -v --version - Display the version of this program\n"
  70. << " -D - Use zero for timestamps and uids/gids "
  71. "(default)\n"
  72. << " -U - Use actual timestamps and uids/gids\n";
  73. }
  74. static void printArHelp(StringRef ToolName) {
  75. const char ArOptions[] =
  76. R"(OPTIONS:
  77. --format - archive format to create
  78. =default - default
  79. =gnu - gnu
  80. =darwin - darwin
  81. =bsd - bsd
  82. =bigarchive - big archive (AIX OS)
  83. --plugin=<string> - ignored for compatibility
  84. -h --help - display this help and exit
  85. --output - the directory to extract archive members to
  86. --rsp-quoting - quoting style for response files
  87. =posix - posix
  88. =windows - windows
  89. --thin - create a thin archive
  90. --version - print the version and exit
  91. -X{32|64|32_64|any} - object mode (only for AIX OS)
  92. @<file> - read options from <file>
  93. OPERATIONS:
  94. d - delete [files] from the archive
  95. m - move [files] in the archive
  96. p - print contents of [files] found in the archive
  97. q - quick append [files] to the archive
  98. r - replace or insert [files] into the archive
  99. s - act as ranlib
  100. t - display list of files in archive
  101. x - extract [files] from the archive
  102. MODIFIERS:
  103. [a] - put [files] after [relpos]
  104. [b] - put [files] before [relpos] (same as [i])
  105. [c] - do not warn if archive had to be created
  106. [D] - use zero for timestamps and uids/gids (default)
  107. [h] - display this help and exit
  108. [i] - put [files] before [relpos] (same as [b])
  109. [l] - ignored for compatibility
  110. [L] - add archive's contents
  111. [N] - use instance [count] of name
  112. [o] - preserve original dates
  113. [O] - display member offsets
  114. [P] - use full names when matching (implied for thin archives)
  115. [s] - create an archive index (cf. ranlib)
  116. [S] - do not build a symbol table
  117. [T] - deprecated, use --thin instead
  118. [u] - update only [files] newer than archive contents
  119. [U] - use actual timestamps and uids/gids
  120. [v] - be verbose about actions taken
  121. [V] - display the version and exit
  122. )";
  123. outs() << "OVERVIEW: LLVM Archiver\n\n"
  124. << "USAGE: " + ToolName +
  125. " [options] [-]<operation>[modifiers] [relpos] "
  126. "[count] <archive> [files]\n"
  127. << " " + ToolName + " -M [<mri-script]\n\n";
  128. outs() << ArOptions;
  129. }
  130. static void printHelpMessage() {
  131. if (Stem.contains_insensitive("ranlib"))
  132. printRanLibHelp(Stem);
  133. else if (Stem.contains_insensitive("ar"))
  134. printArHelp(Stem);
  135. }
  136. static unsigned MRILineNumber;
  137. static bool ParsingMRIScript;
  138. // Show the error plus the usage message, and exit.
  139. [[noreturn]] static void badUsage(Twine Error) {
  140. WithColor::error(errs(), ToolName) << Error << "\n";
  141. printHelpMessage();
  142. exit(1);
  143. }
  144. // Show the error message and exit.
  145. [[noreturn]] static void fail(Twine Error) {
  146. if (ParsingMRIScript) {
  147. WithColor::error(errs(), ToolName)
  148. << "script line " << MRILineNumber << ": " << Error << "\n";
  149. } else {
  150. WithColor::error(errs(), ToolName) << Error << "\n";
  151. }
  152. exit(1);
  153. }
  154. static void failIfError(std::error_code EC, Twine Context = "") {
  155. if (!EC)
  156. return;
  157. std::string ContextStr = Context.str();
  158. if (ContextStr.empty())
  159. fail(EC.message());
  160. fail(Context + ": " + EC.message());
  161. }
  162. static void failIfError(Error E, Twine Context = "") {
  163. if (!E)
  164. return;
  165. handleAllErrors(std::move(E), [&](const llvm::ErrorInfoBase &EIB) {
  166. std::string ContextStr = Context.str();
  167. if (ContextStr.empty())
  168. fail(EIB.message());
  169. fail(Context + ": " + EIB.message());
  170. });
  171. }
  172. static void warn(Twine Message) {
  173. WithColor::warning(errs(), ToolName) << Message << "\n";
  174. }
  175. static SmallVector<const char *, 256> PositionalArgs;
  176. static bool MRI;
  177. namespace {
  178. enum Format { Default, GNU, BSD, DARWIN, BIGARCHIVE, Unknown };
  179. }
  180. static Format FormatType = Default;
  181. static std::string Options;
  182. // This enumeration delineates the kinds of operations on an archive
  183. // that are permitted.
  184. enum ArchiveOperation {
  185. Print, ///< Print the contents of the archive
  186. Delete, ///< Delete the specified members
  187. Move, ///< Move members to end or as given by {a,b,i} modifiers
  188. QuickAppend, ///< Quickly append to end of archive
  189. ReplaceOrInsert, ///< Replace or Insert members
  190. DisplayTable, ///< Display the table of contents
  191. Extract, ///< Extract files back to file system
  192. CreateSymTab ///< Create a symbol table in an existing archive
  193. };
  194. enum class BitModeTy { Bit32, Bit64, Bit32_64, Any, Unknown };
  195. static BitModeTy BitMode = BitModeTy::Bit32;
  196. // Modifiers to follow operation to vary behavior
  197. static bool AddAfter = false; ///< 'a' modifier
  198. static bool AddBefore = false; ///< 'b' modifier
  199. static bool Create = false; ///< 'c' modifier
  200. static bool OriginalDates = false; ///< 'o' modifier
  201. static bool DisplayMemberOffsets = false; ///< 'O' modifier
  202. static bool CompareFullPath = false; ///< 'P' modifier
  203. static bool OnlyUpdate = false; ///< 'u' modifier
  204. static bool Verbose = false; ///< 'v' modifier
  205. static bool Symtab = true; ///< 's' modifier
  206. static bool Deterministic = true; ///< 'D' and 'U' modifiers
  207. static bool Thin = false; ///< 'T' modifier
  208. static bool AddLibrary = false; ///< 'L' modifier
  209. // Relative Positional Argument (for insert/move). This variable holds
  210. // the name of the archive member to which the 'a', 'b' or 'i' modifier
  211. // refers. Only one of 'a', 'b' or 'i' can be specified so we only need
  212. // one variable.
  213. static std::string RelPos;
  214. // Count parameter for 'N' modifier. This variable specifies which file should
  215. // match for extract/delete operations when there are multiple matches. This is
  216. // 1-indexed. A value of 0 is invalid, and implies 'N' is not used.
  217. static int CountParam = 0;
  218. // This variable holds the name of the archive file as given on the
  219. // command line.
  220. static std::string ArchiveName;
  221. // Output directory specified by --output.
  222. static std::string OutputDir;
  223. static std::vector<std::unique_ptr<MemoryBuffer>> ArchiveBuffers;
  224. static std::vector<std::unique_ptr<object::Archive>> Archives;
  225. // This variable holds the list of member files to proecess, as given
  226. // on the command line.
  227. static std::vector<StringRef> Members;
  228. // Static buffer to hold StringRefs.
  229. static BumpPtrAllocator Alloc;
  230. // Extract the member filename from the command line for the [relpos] argument
  231. // associated with a, b, and i modifiers
  232. static void getRelPos() {
  233. if (PositionalArgs.empty())
  234. fail("expected [relpos] for 'a', 'b', or 'i' modifier");
  235. RelPos = PositionalArgs[0];
  236. PositionalArgs.erase(PositionalArgs.begin());
  237. }
  238. // Extract the parameter from the command line for the [count] argument
  239. // associated with the N modifier
  240. static void getCountParam() {
  241. if (PositionalArgs.empty())
  242. badUsage("expected [count] for 'N' modifier");
  243. auto CountParamArg = StringRef(PositionalArgs[0]);
  244. if (CountParamArg.getAsInteger(10, CountParam))
  245. badUsage("value for [count] must be numeric, got: " + CountParamArg);
  246. if (CountParam < 1)
  247. badUsage("value for [count] must be positive, got: " + CountParamArg);
  248. PositionalArgs.erase(PositionalArgs.begin());
  249. }
  250. // Get the archive file name from the command line
  251. static void getArchive() {
  252. if (PositionalArgs.empty())
  253. badUsage("an archive name must be specified");
  254. ArchiveName = PositionalArgs[0];
  255. PositionalArgs.erase(PositionalArgs.begin());
  256. }
  257. static object::Archive &readLibrary(const Twine &Library) {
  258. auto BufOrErr = MemoryBuffer::getFile(Library, /*IsText=*/false,
  259. /*RequiresNullTerminator=*/false);
  260. failIfError(BufOrErr.getError(), "could not open library " + Library);
  261. ArchiveBuffers.push_back(std::move(*BufOrErr));
  262. auto LibOrErr =
  263. object::Archive::create(ArchiveBuffers.back()->getMemBufferRef());
  264. failIfError(errorToErrorCode(LibOrErr.takeError()),
  265. "could not parse library");
  266. Archives.push_back(std::move(*LibOrErr));
  267. return *Archives.back();
  268. }
  269. static void runMRIScript();
  270. // Parse the command line options as presented and return the operation
  271. // specified. Process all modifiers and check to make sure that constraints on
  272. // modifier/operation pairs have not been violated.
  273. static ArchiveOperation parseCommandLine() {
  274. if (MRI) {
  275. if (!PositionalArgs.empty() || !Options.empty())
  276. badUsage("cannot mix -M and other options");
  277. runMRIScript();
  278. }
  279. // Keep track of number of operations. We can only specify one
  280. // per execution.
  281. unsigned NumOperations = 0;
  282. // Keep track of the number of positional modifiers (a,b,i). Only
  283. // one can be specified.
  284. unsigned NumPositional = 0;
  285. // Keep track of which operation was requested
  286. ArchiveOperation Operation;
  287. bool MaybeJustCreateSymTab = false;
  288. for (unsigned i = 0; i < Options.size(); ++i) {
  289. switch (Options[i]) {
  290. case 'd':
  291. ++NumOperations;
  292. Operation = Delete;
  293. break;
  294. case 'm':
  295. ++NumOperations;
  296. Operation = Move;
  297. break;
  298. case 'p':
  299. ++NumOperations;
  300. Operation = Print;
  301. break;
  302. case 'q':
  303. ++NumOperations;
  304. Operation = QuickAppend;
  305. break;
  306. case 'r':
  307. ++NumOperations;
  308. Operation = ReplaceOrInsert;
  309. break;
  310. case 't':
  311. ++NumOperations;
  312. Operation = DisplayTable;
  313. break;
  314. case 'x':
  315. ++NumOperations;
  316. Operation = Extract;
  317. break;
  318. case 'c':
  319. Create = true;
  320. break;
  321. case 'l': /* accepted but unused */
  322. break;
  323. case 'o':
  324. OriginalDates = true;
  325. break;
  326. case 'O':
  327. DisplayMemberOffsets = true;
  328. break;
  329. case 'P':
  330. CompareFullPath = true;
  331. break;
  332. case 's':
  333. Symtab = true;
  334. MaybeJustCreateSymTab = true;
  335. break;
  336. case 'S':
  337. Symtab = false;
  338. break;
  339. case 'u':
  340. OnlyUpdate = true;
  341. break;
  342. case 'v':
  343. Verbose = true;
  344. break;
  345. case 'a':
  346. getRelPos();
  347. AddAfter = true;
  348. NumPositional++;
  349. break;
  350. case 'b':
  351. getRelPos();
  352. AddBefore = true;
  353. NumPositional++;
  354. break;
  355. case 'i':
  356. getRelPos();
  357. AddBefore = true;
  358. NumPositional++;
  359. break;
  360. case 'D':
  361. Deterministic = true;
  362. break;
  363. case 'U':
  364. Deterministic = false;
  365. break;
  366. case 'N':
  367. getCountParam();
  368. break;
  369. case 'T':
  370. Thin = true;
  371. break;
  372. case 'L':
  373. AddLibrary = true;
  374. break;
  375. case 'V':
  376. cl::PrintVersionMessage();
  377. exit(0);
  378. case 'h':
  379. printHelpMessage();
  380. exit(0);
  381. default:
  382. badUsage(std::string("unknown option ") + Options[i]);
  383. }
  384. }
  385. // Thin archives store path names, so P should be forced.
  386. if (Thin)
  387. CompareFullPath = true;
  388. // At this point, the next thing on the command line must be
  389. // the archive name.
  390. getArchive();
  391. // Everything on the command line at this point is a member.
  392. Members.assign(PositionalArgs.begin(), PositionalArgs.end());
  393. if (NumOperations == 0 && MaybeJustCreateSymTab) {
  394. NumOperations = 1;
  395. Operation = CreateSymTab;
  396. if (!Members.empty())
  397. badUsage("the 's' operation takes only an archive as argument");
  398. }
  399. // Perform various checks on the operation/modifier specification
  400. // to make sure we are dealing with a legal request.
  401. if (NumOperations == 0)
  402. badUsage("you must specify at least one of the operations");
  403. if (NumOperations > 1)
  404. badUsage("only one operation may be specified");
  405. if (NumPositional > 1)
  406. badUsage("you may only specify one of 'a', 'b', and 'i' modifiers");
  407. if (AddAfter || AddBefore)
  408. if (Operation != Move && Operation != ReplaceOrInsert)
  409. badUsage("the 'a', 'b' and 'i' modifiers can only be specified with "
  410. "the 'm' or 'r' operations");
  411. if (CountParam)
  412. if (Operation != Extract && Operation != Delete)
  413. badUsage("the 'N' modifier can only be specified with the 'x' or 'd' "
  414. "operations");
  415. if (OriginalDates && Operation != Extract)
  416. badUsage("the 'o' modifier is only applicable to the 'x' operation");
  417. if (OnlyUpdate && Operation != ReplaceOrInsert)
  418. badUsage("the 'u' modifier is only applicable to the 'r' operation");
  419. if (AddLibrary && Operation != QuickAppend)
  420. badUsage("the 'L' modifier is only applicable to the 'q' operation");
  421. if (!OutputDir.empty()) {
  422. if (Operation != Extract)
  423. badUsage("--output is only applicable to the 'x' operation");
  424. bool IsDir = false;
  425. // If OutputDir is not a directory, create_directories may still succeed if
  426. // all components of the path prefix are directories. Test is_directory as
  427. // well.
  428. if (!sys::fs::create_directories(OutputDir))
  429. sys::fs::is_directory(OutputDir, IsDir);
  430. if (!IsDir)
  431. fail("'" + OutputDir + "' is not a directory");
  432. }
  433. // Return the parsed operation to the caller
  434. return Operation;
  435. }
  436. // Implements the 'p' operation. This function traverses the archive
  437. // looking for members that match the path list.
  438. static void doPrint(StringRef Name, const object::Archive::Child &C) {
  439. if (Verbose)
  440. outs() << "Printing " << Name << "\n";
  441. Expected<StringRef> DataOrErr = C.getBuffer();
  442. failIfError(DataOrErr.takeError());
  443. StringRef Data = *DataOrErr;
  444. outs().write(Data.data(), Data.size());
  445. }
  446. // Utility function for printing out the file mode when the 't' operation is in
  447. // verbose mode.
  448. static void printMode(unsigned mode) {
  449. outs() << ((mode & 004) ? "r" : "-");
  450. outs() << ((mode & 002) ? "w" : "-");
  451. outs() << ((mode & 001) ? "x" : "-");
  452. }
  453. // Implement the 't' operation. This function prints out just
  454. // the file names of each of the members. However, if verbose mode is requested
  455. // ('v' modifier) then the file type, permission mode, user, group, size, and
  456. // modification time are also printed.
  457. static void doDisplayTable(StringRef Name, const object::Archive::Child &C) {
  458. if (Verbose) {
  459. Expected<sys::fs::perms> ModeOrErr = C.getAccessMode();
  460. failIfError(ModeOrErr.takeError());
  461. sys::fs::perms Mode = ModeOrErr.get();
  462. printMode((Mode >> 6) & 007);
  463. printMode((Mode >> 3) & 007);
  464. printMode(Mode & 007);
  465. Expected<unsigned> UIDOrErr = C.getUID();
  466. failIfError(UIDOrErr.takeError());
  467. outs() << ' ' << UIDOrErr.get();
  468. Expected<unsigned> GIDOrErr = C.getGID();
  469. failIfError(GIDOrErr.takeError());
  470. outs() << '/' << GIDOrErr.get();
  471. Expected<uint64_t> Size = C.getSize();
  472. failIfError(Size.takeError());
  473. outs() << ' ' << format("%6llu", Size.get());
  474. auto ModTimeOrErr = C.getLastModified();
  475. failIfError(ModTimeOrErr.takeError());
  476. // Note: formatv() only handles the default TimePoint<>, which is in
  477. // nanoseconds.
  478. // TODO: fix format_provider<TimePoint<>> to allow other units.
  479. sys::TimePoint<> ModTimeInNs = ModTimeOrErr.get();
  480. outs() << ' ' << formatv("{0:%b %e %H:%M %Y}", ModTimeInNs);
  481. outs() << ' ';
  482. }
  483. if (C.getParent()->isThin()) {
  484. if (!sys::path::is_absolute(Name)) {
  485. StringRef ParentDir = sys::path::parent_path(ArchiveName);
  486. if (!ParentDir.empty())
  487. outs() << sys::path::convert_to_slash(ParentDir) << '/';
  488. }
  489. outs() << Name;
  490. } else {
  491. outs() << Name;
  492. if (DisplayMemberOffsets)
  493. outs() << " 0x" << utohexstr(C.getDataOffset(), true);
  494. }
  495. outs() << '\n';
  496. }
  497. static std::string normalizePath(StringRef Path) {
  498. return CompareFullPath ? sys::path::convert_to_slash(Path)
  499. : std::string(sys::path::filename(Path));
  500. }
  501. static bool comparePaths(StringRef Path1, StringRef Path2) {
  502. // When on Windows this function calls CompareStringOrdinal
  503. // as Windows file paths are case-insensitive.
  504. // CompareStringOrdinal compares two Unicode strings for
  505. // binary equivalence and allows for case insensitivity.
  506. #ifdef _WIN32
  507. SmallVector<wchar_t, 128> WPath1, WPath2;
  508. failIfError(sys::windows::UTF8ToUTF16(normalizePath(Path1), WPath1));
  509. failIfError(sys::windows::UTF8ToUTF16(normalizePath(Path2), WPath2));
  510. return CompareStringOrdinal(WPath1.data(), WPath1.size(), WPath2.data(),
  511. WPath2.size(), true) == CSTR_EQUAL;
  512. #else
  513. return normalizePath(Path1) == normalizePath(Path2);
  514. #endif
  515. }
  516. // Implement the 'x' operation. This function extracts files back to the file
  517. // system.
  518. static void doExtract(StringRef Name, const object::Archive::Child &C) {
  519. // Retain the original mode.
  520. Expected<sys::fs::perms> ModeOrErr = C.getAccessMode();
  521. failIfError(ModeOrErr.takeError());
  522. sys::fs::perms Mode = ModeOrErr.get();
  523. StringRef outputFilePath;
  524. SmallString<128> path;
  525. if (OutputDir.empty()) {
  526. outputFilePath = sys::path::filename(Name);
  527. } else {
  528. sys::path::append(path, OutputDir, sys::path::filename(Name));
  529. outputFilePath = path.str();
  530. }
  531. if (Verbose)
  532. outs() << "x - " << outputFilePath << '\n';
  533. int FD;
  534. failIfError(sys::fs::openFileForWrite(outputFilePath, FD,
  535. sys::fs::CD_CreateAlways,
  536. sys::fs::OF_None, Mode),
  537. Name);
  538. {
  539. raw_fd_ostream file(FD, false);
  540. // Get the data and its length
  541. Expected<StringRef> BufOrErr = C.getBuffer();
  542. failIfError(BufOrErr.takeError());
  543. StringRef Data = BufOrErr.get();
  544. // Write the data.
  545. file.write(Data.data(), Data.size());
  546. }
  547. // If we're supposed to retain the original modification times, etc. do so
  548. // now.
  549. if (OriginalDates) {
  550. auto ModTimeOrErr = C.getLastModified();
  551. failIfError(ModTimeOrErr.takeError());
  552. failIfError(
  553. sys::fs::setLastAccessAndModificationTime(FD, ModTimeOrErr.get()));
  554. }
  555. if (close(FD))
  556. fail("Could not close the file");
  557. }
  558. static bool shouldCreateArchive(ArchiveOperation Op) {
  559. switch (Op) {
  560. case Print:
  561. case Delete:
  562. case Move:
  563. case DisplayTable:
  564. case Extract:
  565. case CreateSymTab:
  566. return false;
  567. case QuickAppend:
  568. case ReplaceOrInsert:
  569. return true;
  570. }
  571. llvm_unreachable("Missing entry in covered switch.");
  572. }
  573. static bool is64BitSymbolicFile(SymbolicFile &Obj) {
  574. if (auto *IRObj = dyn_cast<IRObjectFile>(&Obj))
  575. return Triple(IRObj->getTargetTriple()).isArch64Bit();
  576. if (isa<COFFObjectFile>(Obj) || isa<COFFImportFile>(Obj))
  577. return false;
  578. if (XCOFFObjectFile *XCOFFObj = dyn_cast<XCOFFObjectFile>(&Obj))
  579. return XCOFFObj->is64Bit();
  580. if (isa<WasmObjectFile>(Obj))
  581. return false;
  582. if (TapiFile *Tapi = dyn_cast<TapiFile>(&Obj))
  583. return Tapi->is64Bit();
  584. if (MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(&Obj))
  585. return MachO->is64Bit();
  586. if (ELFObjectFileBase *ElfO = dyn_cast<ELFObjectFileBase>(&Obj))
  587. return ElfO->getBytesInAddress() == 8;
  588. fail("unsupported file format");
  589. }
  590. static bool isValidInBitMode(Binary &Bin) {
  591. if (BitMode == BitModeTy::Bit32_64 || BitMode == BitModeTy::Any)
  592. return true;
  593. if (SymbolicFile *SymFile = dyn_cast<SymbolicFile>(&Bin)) {
  594. bool Is64Bit = is64BitSymbolicFile(*SymFile);
  595. if ((Is64Bit && (BitMode == BitModeTy::Bit32)) ||
  596. (!Is64Bit && (BitMode == BitModeTy::Bit64)))
  597. return false;
  598. }
  599. // In AIX "ar", non-object files are always considered to have a valid bit
  600. // mode.
  601. return true;
  602. }
  603. Expected<std::unique_ptr<Binary>> getAsBinary(const NewArchiveMember &NM,
  604. LLVMContext *Context) {
  605. auto BinaryOrErr = createBinary(NM.Buf->getMemBufferRef(), Context);
  606. if (BinaryOrErr)
  607. return std::move(*BinaryOrErr);
  608. return BinaryOrErr.takeError();
  609. }
  610. Expected<std::unique_ptr<Binary>> getAsBinary(const Archive::Child &C,
  611. LLVMContext *Context) {
  612. return C.getAsBinary(Context);
  613. }
  614. template <class A> static bool isValidInBitMode(const A &Member) {
  615. if (object::Archive::getDefaultKindForHost() != object::Archive::K_AIXBIG)
  616. return true;
  617. LLVMContext Context;
  618. Expected<std::unique_ptr<Binary>> BinOrErr = getAsBinary(Member, &Context);
  619. // In AIX "ar", if there is a non-object file member, it is never ignored due
  620. // to the bit mode setting.
  621. if (!BinOrErr) {
  622. consumeError(BinOrErr.takeError());
  623. return true;
  624. }
  625. return isValidInBitMode(*BinOrErr.get());
  626. }
  627. static void warnInvalidObjectForFileMode(Twine Name) {
  628. warn("'" + Name + "' is not valid with the current object file mode");
  629. }
  630. static void performReadOperation(ArchiveOperation Operation,
  631. object::Archive *OldArchive) {
  632. if (Operation == Extract && OldArchive->isThin())
  633. fail("extracting from a thin archive is not supported");
  634. bool Filter = !Members.empty();
  635. StringMap<int> MemberCount;
  636. {
  637. Error Err = Error::success();
  638. for (auto &C : OldArchive->children(Err)) {
  639. Expected<StringRef> NameOrErr = C.getName();
  640. failIfError(NameOrErr.takeError());
  641. StringRef Name = NameOrErr.get();
  642. // Check whether to ignore this object due to its bitness.
  643. if (!isValidInBitMode(C))
  644. continue;
  645. if (Filter) {
  646. auto I = find_if(Members, [Name](StringRef Path) {
  647. return comparePaths(Name, Path);
  648. });
  649. if (I == Members.end())
  650. continue;
  651. if (CountParam && ++MemberCount[Name] != CountParam)
  652. continue;
  653. Members.erase(I);
  654. }
  655. switch (Operation) {
  656. default:
  657. llvm_unreachable("Not a read operation");
  658. case Print:
  659. doPrint(Name, C);
  660. break;
  661. case DisplayTable:
  662. doDisplayTable(Name, C);
  663. break;
  664. case Extract:
  665. doExtract(Name, C);
  666. break;
  667. }
  668. }
  669. failIfError(std::move(Err));
  670. }
  671. if (Members.empty())
  672. return;
  673. for (StringRef Name : Members)
  674. WithColor::error(errs(), ToolName) << "'" << Name << "' was not found\n";
  675. exit(1);
  676. }
  677. static void addChildMember(std::vector<NewArchiveMember> &Members,
  678. const object::Archive::Child &M,
  679. bool FlattenArchive = false) {
  680. Expected<NewArchiveMember> NMOrErr =
  681. NewArchiveMember::getOldMember(M, Deterministic);
  682. failIfError(NMOrErr.takeError());
  683. // If the child member we're trying to add is thin, use the path relative to
  684. // the archive it's in, so the file resolves correctly.
  685. if (Thin && FlattenArchive) {
  686. StringSaver Saver(Alloc);
  687. Expected<std::string> FileNameOrErr(M.getName());
  688. failIfError(FileNameOrErr.takeError());
  689. if (sys::path::is_absolute(*FileNameOrErr)) {
  690. NMOrErr->MemberName = Saver.save(sys::path::convert_to_slash(*FileNameOrErr));
  691. } else {
  692. FileNameOrErr = M.getFullName();
  693. failIfError(FileNameOrErr.takeError());
  694. Expected<std::string> PathOrErr =
  695. computeArchiveRelativePath(ArchiveName, *FileNameOrErr);
  696. NMOrErr->MemberName = Saver.save(
  697. PathOrErr ? *PathOrErr : sys::path::convert_to_slash(*FileNameOrErr));
  698. }
  699. }
  700. if (FlattenArchive &&
  701. identify_magic(NMOrErr->Buf->getBuffer()) == file_magic::archive) {
  702. Expected<std::string> FileNameOrErr = M.getFullName();
  703. failIfError(FileNameOrErr.takeError());
  704. object::Archive &Lib = readLibrary(*FileNameOrErr);
  705. // When creating thin archives, only flatten if the member is also thin.
  706. if (!Thin || Lib.isThin()) {
  707. Error Err = Error::success();
  708. // Only Thin archives are recursively flattened.
  709. for (auto &Child : Lib.children(Err))
  710. addChildMember(Members, Child, /*FlattenArchive=*/Thin);
  711. failIfError(std::move(Err));
  712. return;
  713. }
  714. }
  715. Members.push_back(std::move(*NMOrErr));
  716. }
  717. static NewArchiveMember getArchiveMember(StringRef FileName) {
  718. Expected<NewArchiveMember> NMOrErr =
  719. NewArchiveMember::getFile(FileName, Deterministic);
  720. failIfError(NMOrErr.takeError(), FileName);
  721. StringSaver Saver(Alloc);
  722. // For regular archives, use the basename of the object path for the member
  723. // name. For thin archives, use the full relative paths so the file resolves
  724. // correctly.
  725. if (!Thin) {
  726. NMOrErr->MemberName = sys::path::filename(NMOrErr->MemberName);
  727. } else {
  728. if (sys::path::is_absolute(FileName))
  729. NMOrErr->MemberName = Saver.save(sys::path::convert_to_slash(FileName));
  730. else {
  731. Expected<std::string> PathOrErr =
  732. computeArchiveRelativePath(ArchiveName, FileName);
  733. NMOrErr->MemberName = Saver.save(
  734. PathOrErr ? *PathOrErr : sys::path::convert_to_slash(FileName));
  735. }
  736. }
  737. return std::move(*NMOrErr);
  738. }
  739. static void addMember(std::vector<NewArchiveMember> &Members,
  740. NewArchiveMember &NM) {
  741. Members.push_back(std::move(NM));
  742. }
  743. static void addMember(std::vector<NewArchiveMember> &Members,
  744. StringRef FileName, bool FlattenArchive = false) {
  745. NewArchiveMember NM = getArchiveMember(FileName);
  746. if (!isValidInBitMode(NM)) {
  747. warnInvalidObjectForFileMode(FileName);
  748. return;
  749. }
  750. if (FlattenArchive &&
  751. identify_magic(NM.Buf->getBuffer()) == file_magic::archive) {
  752. object::Archive &Lib = readLibrary(FileName);
  753. // When creating thin archives, only flatten if the member is also thin.
  754. if (!Thin || Lib.isThin()) {
  755. Error Err = Error::success();
  756. // Only Thin archives are recursively flattened.
  757. for (auto &Child : Lib.children(Err))
  758. addChildMember(Members, Child, /*FlattenArchive=*/Thin);
  759. failIfError(std::move(Err));
  760. return;
  761. }
  762. }
  763. Members.push_back(std::move(NM));
  764. }
  765. enum InsertAction {
  766. IA_AddOldMember,
  767. IA_AddNewMember,
  768. IA_Delete,
  769. IA_MoveOldMember,
  770. IA_MoveNewMember
  771. };
  772. static InsertAction computeInsertAction(ArchiveOperation Operation,
  773. const object::Archive::Child &Member,
  774. StringRef Name,
  775. std::vector<StringRef>::iterator &Pos,
  776. StringMap<int> &MemberCount) {
  777. if (!isValidInBitMode(Member))
  778. return IA_AddOldMember;
  779. if (Operation == QuickAppend || Members.empty())
  780. return IA_AddOldMember;
  781. auto MI = find_if(Members, [Name](StringRef Path) {
  782. if (Thin && !sys::path::is_absolute(Path)) {
  783. Expected<std::string> PathOrErr =
  784. computeArchiveRelativePath(ArchiveName, Path);
  785. return comparePaths(Name, PathOrErr ? *PathOrErr : Path);
  786. } else {
  787. return comparePaths(Name, Path);
  788. }
  789. });
  790. if (MI == Members.end())
  791. return IA_AddOldMember;
  792. Pos = MI;
  793. if (Operation == Delete) {
  794. if (CountParam && ++MemberCount[Name] != CountParam)
  795. return IA_AddOldMember;
  796. return IA_Delete;
  797. }
  798. if (Operation == Move)
  799. return IA_MoveOldMember;
  800. if (Operation == ReplaceOrInsert) {
  801. if (!OnlyUpdate) {
  802. if (RelPos.empty())
  803. return IA_AddNewMember;
  804. return IA_MoveNewMember;
  805. }
  806. // We could try to optimize this to a fstat, but it is not a common
  807. // operation.
  808. sys::fs::file_status Status;
  809. failIfError(sys::fs::status(*MI, Status), *MI);
  810. auto ModTimeOrErr = Member.getLastModified();
  811. failIfError(ModTimeOrErr.takeError());
  812. if (Status.getLastModificationTime() < ModTimeOrErr.get()) {
  813. if (RelPos.empty())
  814. return IA_AddOldMember;
  815. return IA_MoveOldMember;
  816. }
  817. if (RelPos.empty())
  818. return IA_AddNewMember;
  819. return IA_MoveNewMember;
  820. }
  821. llvm_unreachable("No such operation");
  822. }
  823. // We have to walk this twice and computing it is not trivial, so creating an
  824. // explicit std::vector is actually fairly efficient.
  825. static std::vector<NewArchiveMember>
  826. computeNewArchiveMembers(ArchiveOperation Operation,
  827. object::Archive *OldArchive) {
  828. std::vector<NewArchiveMember> Ret;
  829. std::vector<NewArchiveMember> Moved;
  830. int InsertPos = -1;
  831. if (OldArchive) {
  832. Error Err = Error::success();
  833. StringMap<int> MemberCount;
  834. for (auto &Child : OldArchive->children(Err)) {
  835. int Pos = Ret.size();
  836. Expected<StringRef> NameOrErr = Child.getName();
  837. failIfError(NameOrErr.takeError());
  838. std::string Name = std::string(NameOrErr.get());
  839. if (comparePaths(Name, RelPos) && isValidInBitMode(Child)) {
  840. assert(AddAfter || AddBefore);
  841. if (AddBefore)
  842. InsertPos = Pos;
  843. else
  844. InsertPos = Pos + 1;
  845. }
  846. std::vector<StringRef>::iterator MemberI = Members.end();
  847. InsertAction Action =
  848. computeInsertAction(Operation, Child, Name, MemberI, MemberCount);
  849. auto HandleNewMember = [](auto Member, auto &Members, auto &Child) {
  850. NewArchiveMember NM = getArchiveMember(*Member);
  851. if (isValidInBitMode(NM))
  852. addMember(Members, NM);
  853. else {
  854. // If a new member is not a valid object for the bit mode, add
  855. // the old member back.
  856. warnInvalidObjectForFileMode(*Member);
  857. addChildMember(Members, Child, /*FlattenArchive=*/Thin);
  858. }
  859. };
  860. switch (Action) {
  861. case IA_AddOldMember:
  862. addChildMember(Ret, Child, /*FlattenArchive=*/Thin);
  863. break;
  864. case IA_AddNewMember:
  865. HandleNewMember(MemberI, Ret, Child);
  866. break;
  867. case IA_Delete:
  868. break;
  869. case IA_MoveOldMember:
  870. addChildMember(Moved, Child, /*FlattenArchive=*/Thin);
  871. break;
  872. case IA_MoveNewMember:
  873. HandleNewMember(MemberI, Moved, Child);
  874. break;
  875. }
  876. // When processing elements with the count param, we need to preserve the
  877. // full members list when iterating over all archive members. For
  878. // instance, "llvm-ar dN 2 archive.a member.o" should delete the second
  879. // file named member.o it sees; we are not done with member.o the first
  880. // time we see it in the archive.
  881. if (MemberI != Members.end() && !CountParam)
  882. Members.erase(MemberI);
  883. }
  884. failIfError(std::move(Err));
  885. }
  886. if (Operation == Delete)
  887. return Ret;
  888. if (!RelPos.empty() && InsertPos == -1)
  889. fail("insertion point not found");
  890. if (RelPos.empty())
  891. InsertPos = Ret.size();
  892. assert(unsigned(InsertPos) <= Ret.size());
  893. int Pos = InsertPos;
  894. for (auto &M : Moved) {
  895. Ret.insert(Ret.begin() + Pos, std::move(M));
  896. ++Pos;
  897. }
  898. if (AddLibrary) {
  899. assert(Operation == QuickAppend);
  900. for (auto &Member : Members)
  901. addMember(Ret, Member, /*FlattenArchive=*/true);
  902. return Ret;
  903. }
  904. std::vector<NewArchiveMember> NewMembers;
  905. for (auto &Member : Members)
  906. addMember(NewMembers, Member, /*FlattenArchive=*/Thin);
  907. Ret.reserve(Ret.size() + NewMembers.size());
  908. std::move(NewMembers.begin(), NewMembers.end(),
  909. std::inserter(Ret, std::next(Ret.begin(), InsertPos)));
  910. return Ret;
  911. }
  912. static void performWriteOperation(ArchiveOperation Operation,
  913. object::Archive *OldArchive,
  914. std::unique_ptr<MemoryBuffer> OldArchiveBuf,
  915. std::vector<NewArchiveMember> *NewMembersP) {
  916. if (OldArchive) {
  917. if (Thin && !OldArchive->isThin())
  918. fail("cannot convert a regular archive to a thin one");
  919. if (OldArchive->isThin())
  920. Thin = true;
  921. }
  922. std::vector<NewArchiveMember> NewMembers;
  923. if (!NewMembersP)
  924. NewMembers = computeNewArchiveMembers(Operation, OldArchive);
  925. object::Archive::Kind Kind;
  926. switch (FormatType) {
  927. case Default:
  928. if (Thin)
  929. Kind = object::Archive::K_GNU;
  930. else if (OldArchive) {
  931. Kind = OldArchive->kind();
  932. if (Kind == object::Archive::K_BSD) {
  933. auto InferredKind = object::Archive::K_BSD;
  934. if (NewMembersP && !NewMembersP->empty())
  935. InferredKind = NewMembersP->front().detectKindFromObject();
  936. else if (!NewMembers.empty())
  937. InferredKind = NewMembers.front().detectKindFromObject();
  938. if (InferredKind == object::Archive::K_DARWIN)
  939. Kind = object::Archive::K_DARWIN;
  940. }
  941. } else if (NewMembersP)
  942. Kind = !NewMembersP->empty() ? NewMembersP->front().detectKindFromObject()
  943. : object::Archive::getDefaultKindForHost();
  944. else
  945. Kind = !NewMembers.empty() ? NewMembers.front().detectKindFromObject()
  946. : object::Archive::getDefaultKindForHost();
  947. break;
  948. case GNU:
  949. Kind = object::Archive::K_GNU;
  950. break;
  951. case BSD:
  952. if (Thin)
  953. fail("only the gnu format has a thin mode");
  954. Kind = object::Archive::K_BSD;
  955. break;
  956. case DARWIN:
  957. if (Thin)
  958. fail("only the gnu format has a thin mode");
  959. Kind = object::Archive::K_DARWIN;
  960. break;
  961. case BIGARCHIVE:
  962. if (Thin)
  963. fail("only the gnu format has a thin mode");
  964. Kind = object::Archive::K_AIXBIG;
  965. break;
  966. case Unknown:
  967. llvm_unreachable("");
  968. }
  969. Error E =
  970. writeArchive(ArchiveName, NewMembersP ? *NewMembersP : NewMembers, Symtab,
  971. Kind, Deterministic, Thin, std::move(OldArchiveBuf));
  972. failIfError(std::move(E), ArchiveName);
  973. }
  974. static void createSymbolTable(object::Archive *OldArchive) {
  975. // When an archive is created or modified, if the s option is given, the
  976. // resulting archive will have a current symbol table. If the S option
  977. // is given, it will have no symbol table.
  978. // In summary, we only need to update the symbol table if we have none.
  979. // This is actually very common because of broken build systems that think
  980. // they have to run ranlib.
  981. if (OldArchive->hasSymbolTable())
  982. return;
  983. if (OldArchive->isThin())
  984. Thin = true;
  985. performWriteOperation(CreateSymTab, OldArchive, nullptr, nullptr);
  986. }
  987. static void performOperation(ArchiveOperation Operation,
  988. object::Archive *OldArchive,
  989. std::unique_ptr<MemoryBuffer> OldArchiveBuf,
  990. std::vector<NewArchiveMember> *NewMembers) {
  991. switch (Operation) {
  992. case Print:
  993. case DisplayTable:
  994. case Extract:
  995. performReadOperation(Operation, OldArchive);
  996. return;
  997. case Delete:
  998. case Move:
  999. case QuickAppend:
  1000. case ReplaceOrInsert:
  1001. performWriteOperation(Operation, OldArchive, std::move(OldArchiveBuf),
  1002. NewMembers);
  1003. return;
  1004. case CreateSymTab:
  1005. createSymbolTable(OldArchive);
  1006. return;
  1007. }
  1008. llvm_unreachable("Unknown operation.");
  1009. }
  1010. static int performOperation(ArchiveOperation Operation) {
  1011. // Create or open the archive object.
  1012. ErrorOr<std::unique_ptr<MemoryBuffer>> Buf = MemoryBuffer::getFile(
  1013. ArchiveName, /*IsText=*/false, /*RequiresNullTerminator=*/false);
  1014. std::error_code EC = Buf.getError();
  1015. if (EC && EC != errc::no_such_file_or_directory)
  1016. fail("unable to open '" + ArchiveName + "': " + EC.message());
  1017. if (!EC) {
  1018. Expected<std::unique_ptr<object::Archive>> ArchiveOrError =
  1019. object::Archive::create(Buf.get()->getMemBufferRef());
  1020. if (!ArchiveOrError)
  1021. failIfError(ArchiveOrError.takeError(),
  1022. "unable to load '" + ArchiveName + "'");
  1023. std::unique_ptr<object::Archive> Archive = std::move(ArchiveOrError.get());
  1024. if (Archive->isThin())
  1025. CompareFullPath = true;
  1026. performOperation(Operation, Archive.get(), std::move(Buf.get()),
  1027. /*NewMembers=*/nullptr);
  1028. return 0;
  1029. }
  1030. assert(EC == errc::no_such_file_or_directory);
  1031. if (!shouldCreateArchive(Operation)) {
  1032. failIfError(EC, Twine("unable to load '") + ArchiveName + "'");
  1033. } else {
  1034. if (!Create) {
  1035. // Produce a warning if we should and we're creating the archive
  1036. warn("creating " + ArchiveName);
  1037. }
  1038. }
  1039. performOperation(Operation, nullptr, nullptr, /*NewMembers=*/nullptr);
  1040. return 0;
  1041. }
  1042. static void runMRIScript() {
  1043. enum class MRICommand { AddLib, AddMod, Create, CreateThin, Delete, Save, End, Invalid };
  1044. ErrorOr<std::unique_ptr<MemoryBuffer>> Buf = MemoryBuffer::getSTDIN();
  1045. failIfError(Buf.getError());
  1046. const MemoryBuffer &Ref = *Buf.get();
  1047. bool Saved = false;
  1048. std::vector<NewArchiveMember> NewMembers;
  1049. ParsingMRIScript = true;
  1050. for (line_iterator I(Ref, /*SkipBlanks*/ false), E; I != E; ++I) {
  1051. ++MRILineNumber;
  1052. StringRef Line = *I;
  1053. Line = Line.split(';').first;
  1054. Line = Line.split('*').first;
  1055. Line = Line.trim();
  1056. if (Line.empty())
  1057. continue;
  1058. StringRef CommandStr, Rest;
  1059. std::tie(CommandStr, Rest) = Line.split(' ');
  1060. Rest = Rest.trim();
  1061. if (!Rest.empty() && Rest.front() == '"' && Rest.back() == '"')
  1062. Rest = Rest.drop_front().drop_back();
  1063. auto Command = StringSwitch<MRICommand>(CommandStr.lower())
  1064. .Case("addlib", MRICommand::AddLib)
  1065. .Case("addmod", MRICommand::AddMod)
  1066. .Case("create", MRICommand::Create)
  1067. .Case("createthin", MRICommand::CreateThin)
  1068. .Case("delete", MRICommand::Delete)
  1069. .Case("save", MRICommand::Save)
  1070. .Case("end", MRICommand::End)
  1071. .Default(MRICommand::Invalid);
  1072. switch (Command) {
  1073. case MRICommand::AddLib: {
  1074. if (!Create)
  1075. fail("no output archive has been opened");
  1076. object::Archive &Lib = readLibrary(Rest);
  1077. {
  1078. if (Thin && !Lib.isThin())
  1079. fail("cannot add a regular archive's contents to a thin archive");
  1080. Error Err = Error::success();
  1081. for (auto &Member : Lib.children(Err))
  1082. addChildMember(NewMembers, Member, /*FlattenArchive=*/Thin);
  1083. failIfError(std::move(Err));
  1084. }
  1085. break;
  1086. }
  1087. case MRICommand::AddMod:
  1088. if (!Create)
  1089. fail("no output archive has been opened");
  1090. addMember(NewMembers, Rest);
  1091. break;
  1092. case MRICommand::CreateThin:
  1093. Thin = true;
  1094. [[fallthrough]];
  1095. case MRICommand::Create:
  1096. Create = true;
  1097. if (!ArchiveName.empty())
  1098. fail("editing multiple archives not supported");
  1099. if (Saved)
  1100. fail("file already saved");
  1101. ArchiveName = std::string(Rest);
  1102. if (ArchiveName.empty())
  1103. fail("missing archive name");
  1104. break;
  1105. case MRICommand::Delete: {
  1106. llvm::erase_if(NewMembers, [=](NewArchiveMember &M) {
  1107. return comparePaths(M.MemberName, Rest);
  1108. });
  1109. break;
  1110. }
  1111. case MRICommand::Save:
  1112. Saved = true;
  1113. break;
  1114. case MRICommand::End:
  1115. break;
  1116. case MRICommand::Invalid:
  1117. fail("unknown command: " + CommandStr);
  1118. }
  1119. }
  1120. ParsingMRIScript = false;
  1121. // Nothing to do if not saved.
  1122. if (Saved)
  1123. performOperation(ReplaceOrInsert, /*OldArchive=*/nullptr,
  1124. /*OldArchiveBuf=*/nullptr, &NewMembers);
  1125. exit(0);
  1126. }
  1127. static bool handleGenericOption(StringRef arg) {
  1128. if (arg == "--help" || arg == "-h") {
  1129. printHelpMessage();
  1130. return true;
  1131. }
  1132. if (arg == "--version") {
  1133. cl::PrintVersionMessage();
  1134. return true;
  1135. }
  1136. return false;
  1137. }
  1138. static BitModeTy getBitMode(const char *RawBitMode) {
  1139. return StringSwitch<BitModeTy>(RawBitMode)
  1140. .Case("32", BitModeTy::Bit32)
  1141. .Case("64", BitModeTy::Bit64)
  1142. .Case("32_64", BitModeTy::Bit32_64)
  1143. .Case("any", BitModeTy::Any)
  1144. .Default(BitModeTy::Unknown);
  1145. }
  1146. static const char *matchFlagWithArg(StringRef Expected,
  1147. ArrayRef<const char *>::iterator &ArgIt,
  1148. ArrayRef<const char *> Args) {
  1149. StringRef Arg = *ArgIt;
  1150. if (Arg.startswith("--"))
  1151. Arg = Arg.substr(2);
  1152. size_t len = Expected.size();
  1153. if (Arg == Expected) {
  1154. if (++ArgIt == Args.end())
  1155. fail(std::string(Expected) + " requires an argument");
  1156. return *ArgIt;
  1157. }
  1158. if (Arg.startswith(Expected) && Arg.size() > len && Arg[len] == '=')
  1159. return Arg.data() + len + 1;
  1160. return nullptr;
  1161. }
  1162. static cl::TokenizerCallback getRspQuoting(ArrayRef<const char *> ArgsArr) {
  1163. cl::TokenizerCallback Ret =
  1164. Triple(sys::getProcessTriple()).getOS() == Triple::Win32
  1165. ? cl::TokenizeWindowsCommandLine
  1166. : cl::TokenizeGNUCommandLine;
  1167. for (ArrayRef<const char *>::iterator ArgIt = ArgsArr.begin();
  1168. ArgIt != ArgsArr.end(); ++ArgIt) {
  1169. if (const char *Match = matchFlagWithArg("rsp-quoting", ArgIt, ArgsArr)) {
  1170. StringRef MatchRef = Match;
  1171. if (MatchRef == "posix")
  1172. Ret = cl::TokenizeGNUCommandLine;
  1173. else if (MatchRef == "windows")
  1174. Ret = cl::TokenizeWindowsCommandLine;
  1175. else
  1176. fail(std::string("Invalid response file quoting style ") + Match);
  1177. }
  1178. }
  1179. return Ret;
  1180. }
  1181. static int ar_main(int argc, char **argv) {
  1182. SmallVector<const char *, 0> Argv(argv + 1, argv + argc);
  1183. StringSaver Saver(Alloc);
  1184. cl::ExpandResponseFiles(Saver, getRspQuoting(ArrayRef(argv, argc)), Argv);
  1185. // Get BitMode from enviorment variable "OBJECT_MODE" for AIX OS, if
  1186. // specified.
  1187. if (object::Archive::getDefaultKindForHost() == object::Archive::K_AIXBIG) {
  1188. BitMode = getBitMode(getenv("OBJECT_MODE"));
  1189. if (BitMode == BitModeTy::Unknown)
  1190. BitMode = BitModeTy::Bit32;
  1191. }
  1192. for (ArrayRef<const char *>::iterator ArgIt = Argv.begin();
  1193. ArgIt != Argv.end(); ++ArgIt) {
  1194. const char *Match = nullptr;
  1195. if (handleGenericOption(*ArgIt))
  1196. return 0;
  1197. if (strcmp(*ArgIt, "--") == 0) {
  1198. ++ArgIt;
  1199. for (; ArgIt != Argv.end(); ++ArgIt)
  1200. PositionalArgs.push_back(*ArgIt);
  1201. break;
  1202. }
  1203. if (*ArgIt[0] != '-') {
  1204. if (Options.empty())
  1205. Options += *ArgIt;
  1206. else
  1207. PositionalArgs.push_back(*ArgIt);
  1208. continue;
  1209. }
  1210. if (strcmp(*ArgIt, "-M") == 0) {
  1211. MRI = true;
  1212. continue;
  1213. }
  1214. if (strcmp(*ArgIt, "--thin") == 0) {
  1215. Thin = true;
  1216. continue;
  1217. }
  1218. Match = matchFlagWithArg("format", ArgIt, Argv);
  1219. if (Match) {
  1220. FormatType = StringSwitch<Format>(Match)
  1221. .Case("default", Default)
  1222. .Case("gnu", GNU)
  1223. .Case("darwin", DARWIN)
  1224. .Case("bsd", BSD)
  1225. .Case("bigarchive", BIGARCHIVE)
  1226. .Default(Unknown);
  1227. if (FormatType == Unknown)
  1228. fail(std::string("Invalid format ") + Match);
  1229. continue;
  1230. }
  1231. if ((Match = matchFlagWithArg("output", ArgIt, Argv))) {
  1232. OutputDir = Match;
  1233. continue;
  1234. }
  1235. if (matchFlagWithArg("plugin", ArgIt, Argv) ||
  1236. matchFlagWithArg("rsp-quoting", ArgIt, Argv))
  1237. continue;
  1238. if (strncmp(*ArgIt, "-X", 2) == 0) {
  1239. if (object::Archive::getDefaultKindForHost() ==
  1240. object::Archive::K_AIXBIG) {
  1241. Match = *(*ArgIt + 2) != '\0' ? *ArgIt + 2 : *(++ArgIt);
  1242. BitMode = getBitMode(Match);
  1243. if (BitMode == BitModeTy::Unknown)
  1244. fail(Twine("invalid bit mode: ") + Match);
  1245. continue;
  1246. } else {
  1247. fail(Twine(*ArgIt) + " option not supported on non AIX OS");
  1248. }
  1249. }
  1250. Options += *ArgIt + 1;
  1251. }
  1252. return performOperation(parseCommandLine());
  1253. }
  1254. static int ranlib_main(int argc, char **argv) {
  1255. std::vector<StringRef> Archives;
  1256. for (int i = 1; i < argc; ++i) {
  1257. StringRef arg(argv[i]);
  1258. if (handleGenericOption(arg)) {
  1259. return 0;
  1260. } else if (arg.consume_front("-")) {
  1261. // Handle the -D/-U flag
  1262. while (!arg.empty()) {
  1263. if (arg.front() == 'D') {
  1264. Deterministic = true;
  1265. } else if (arg.front() == 'U') {
  1266. Deterministic = false;
  1267. } else if (arg.front() == 'h') {
  1268. printHelpMessage();
  1269. return 0;
  1270. } else if (arg.front() == 'v') {
  1271. cl::PrintVersionMessage();
  1272. return 0;
  1273. } else {
  1274. // TODO: GNU ranlib also supports a -t flag
  1275. fail("Invalid option: '-" + arg + "'");
  1276. }
  1277. arg = arg.drop_front(1);
  1278. }
  1279. } else {
  1280. Archives.push_back(arg);
  1281. }
  1282. }
  1283. for (StringRef Archive : Archives) {
  1284. ArchiveName = Archive.str();
  1285. performOperation(CreateSymTab);
  1286. }
  1287. if (Archives.empty())
  1288. badUsage("an archive name must be specified");
  1289. return 0;
  1290. }
  1291. int llvm_ar_main(int argc, char **argv) {
  1292. InitLLVM X(argc, argv);
  1293. ToolName = argv[0];
  1294. llvm::InitializeAllTargetInfos();
  1295. llvm::InitializeAllTargetMCs();
  1296. llvm::InitializeAllAsmParsers();
  1297. Stem = sys::path::stem(ToolName);
  1298. auto Is = [](StringRef Tool) {
  1299. // We need to recognize the following filenames.
  1300. //
  1301. // Lib.exe -> lib (see D44808, MSBuild runs Lib.exe)
  1302. // dlltool.exe -> dlltool
  1303. // arm-pokymllib32-linux-gnueabi-llvm-ar-10 -> ar
  1304. auto I = Stem.rfind_insensitive(Tool);
  1305. return I != StringRef::npos &&
  1306. (I + Tool.size() == Stem.size() || !isAlnum(Stem[I + Tool.size()]));
  1307. };
  1308. if (Is("dlltool"))
  1309. return dlltoolDriverMain(ArrayRef(argv, argc));
  1310. if (Is("ranlib"))
  1311. return ranlib_main(argc, argv);
  1312. if (Is("lib"))
  1313. return libDriverMain(ArrayRef(argv, argc));
  1314. if (Is("ar"))
  1315. return ar_main(argc, argv);
  1316. fail("not ranlib, ar, lib or dlltool");
  1317. }