llvm.org GIT mirror llvm / 4c9cd28
Initial support for writing thin archives. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@242269 91177308-0d34-0410-b5e6-96231b3b80d8 Rafael Espindola 4 years ago
5 changed file(s) with 47 addition(s) and 20 deletion(s). Raw diff Collapse all Expand all
4242
4343 std::pair
4444 writeArchive(StringRef ArcName, std::vector &NewMembers,
45 bool WriteSymtab, object::Archive::Kind Kind, bool Deterministic);
45 bool WriteSymtab, object::Archive::Kind Kind, bool Deterministic,
46 bool Thin);
4647 }
4748
4849 #endif
141141 std::pair Result =
142142 llvm::writeArchive(getOutputPath(&Args, Members[0]), Members,
143143 /*WriteSymtab=*/true, object::Archive::K_GNU,
144 /*Deterministic*/ true);
144 /*Deterministic*/ true, /*Thin*/ false);
145145
146146 if (Result.second) {
147147 if (Result.first.empty())
134134 Out.write(uint8_t(0));
135135 }
136136
137 static bool useStringTable(bool Thin, StringRef Name) {
138 return Thin || Name.size() >= 16;
139 }
140
137141 static void
138 printMemberHeader(raw_fd_ostream &Out, object::Archive::Kind Kind,
142 printMemberHeader(raw_fd_ostream &Out, object::Archive::Kind Kind, bool Thin,
139143 StringRef Name,
140144 std::vector::iterator &StringMapIndexIter,
141145 const sys::TimeValue &ModTime, unsigned UID, unsigned GID,
142146 unsigned Perms, unsigned Size) {
143147 if (Kind == object::Archive::K_BSD)
144148 return printBSDMemberHeader(Out, Name, ModTime, UID, GID, Perms, Size);
145 if (Name.size() < 16)
149 if (!useStringTable(Thin, Name))
146150 return printGNUSmallMemberHeader(Out, Name, ModTime, UID, GID, Perms, Size);
147151 Out << '/';
148152 printWithSpacePadding(Out, *StringMapIndexIter++, 15);
151155
152156 static void writeStringTable(raw_fd_ostream &Out,
153157 ArrayRef Members,
154 std::vector &StringMapIndexes) {
158 std::vector &StringMapIndexes,
159 bool Thin) {
155160 unsigned StartOffset = 0;
156161 for (const NewArchiveIterator &I : Members) {
157162 StringRef Name = I.getName();
158 if (Name.size() < 16)
163 if (!useStringTable(Thin, Name))
159164 continue;
160165 if (StartOffset == 0) {
161166 printWithSpacePadding(Out, "//", 58);
265270 return BodyStartOffset + 4;
266271 }
267272
268 std::pair llvm::writeArchive(
269 StringRef ArcName, std::vector &NewMembers,
270 bool WriteSymtab, object::Archive::Kind Kind, bool Deterministic) {
273 std::pair
274 llvm::writeArchive(StringRef ArcName,
275 std::vector &NewMembers,
276 bool WriteSymtab, object::Archive::Kind Kind,
277 bool Deterministic, bool Thin) {
271278 SmallString<128> TmpArchive;
272279 int TmpArchiveFD;
273280 if (auto EC = sys::fs::createUniqueFile(ArcName + ".temp-archive-%%%%%%%.a",
276283
277284 tool_output_file Output(TmpArchive, TmpArchiveFD);
278285 raw_fd_ostream &Out = Output.os();
279 Out << "!\n";
286 if (Thin)
287 Out << "!\n";
288 else
289 Out << "!\n";
280290
281291 std::vector MemberOffsetRefs;
282292
327337
328338 std::vector StringMapIndexes;
329339 if (Kind != object::Archive::K_BSD)
330 writeStringTable(Out, NewMembers, StringMapIndexes);
340 writeStringTable(Out, NewMembers, StringMapIndexes, Thin);
331341
332342 unsigned MemberNum = 0;
333343 unsigned NewMemberNum = 0;
365375 if (I.isNewMember()) {
366376 StringRef FileName = I.getNew();
367377 const sys::fs::file_status &Status = NewMemberStatus[NewMemberNum++];
368 printMemberHeader(Out, Kind, sys::path::filename(FileName),
378 printMemberHeader(Out, Kind, Thin, sys::path::filename(FileName),
369379 StringMapIndexIter, ModTime, UID, GID, Perms,
370380 Status.getSize());
371381 } else {
372382 object::Archive::child_iterator OldMember = I.getOld();
373 printMemberHeader(Out, Kind, I.getName(), StringMapIndexIter, ModTime,
374 UID, GID, Perms, OldMember->getSize());
375 }
376
377 Out << File.getBuffer();
383 printMemberHeader(Out, Kind, Thin, I.getName(), StringMapIndexIter,
384 ModTime, UID, GID, Perms, OldMember->getSize());
385 }
386
387 if (!Thin)
388 Out << File.getBuffer();
378389
379390 if (Out.tell() % 2)
380391 Out << '\n';
2626 BSD-NEXT: 0123456789abcde{{.....}}bar.
2727 BSD-SAME: #1/16 0 0 0 644 20 `
2828 BSD-NEXT: 0123456789abcdefzed.
29
30 RUN: rm -f %t.a
31 RUN: llvm-ar --format=gnu rcT %t.a 0123456789abcde 0123456789abcdef
32 RUN: cat %t.a | FileCheck -strict-whitespace --check-prefix=THIN %s
33 THIN: !
34 THIN-NEXT: // 36 `
35 THIN-NEXT: 0123456789abcde/
36 THIN-NEXT: 0123456789abcdef/{{$}}
37 THIN: {{^$}}
38 THIN: /0 0 0 0 644 4 `
39 THIN-NEXT: /17 0 0 0 644 4 `
129129 static bool Verbose = false; ///< 'v' modifier
130130 static bool Symtab = true; ///< 's' modifier
131131 static bool Deterministic = true; ///< 'D' and 'U' modifiers
132 static bool Thin = false; ///< 'T' modifier
132133
133134 // Relative Positional Argument (for insert/move). This variable holds
134135 // the name of the archive member to which the 'a', 'b' or 'i' modifier
250251 break;
251252 case 'U':
252253 Deterministic = false;
254 break;
255 case 'T':
256 Thin = true;
253257 break;
254258 default:
255259 cl::PrintHelpMessage();
589593 break;
590594 }
591595 if (NewMembersP) {
592 std::pair Result =
593 writeArchive(ArchiveName, *NewMembersP, Symtab, Kind, Deterministic);
596 std::pair Result = writeArchive(
597 ArchiveName, *NewMembersP, Symtab, Kind, Deterministic, Thin);
594598 failIfError(Result.second, Result.first);
595599 return;
596600 }
597601 std::vector NewMembers =
598602 computeNewArchiveMembers(Operation, OldArchive);
599603 auto Result =
600 writeArchive(ArchiveName, NewMembers, Symtab, Kind, Deterministic);
604 writeArchive(ArchiveName, NewMembers, Symtab, Kind, Deterministic, Thin);
601605 failIfError(Result.second, Result.first);
602606 }
603607