llvm.org GIT mirror llvm / 168b1be
Add support deterministic output in llvm-ar and make it the default. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@242061 91177308-0d34-0410-b5e6-96231b3b80d8 Rafael Espindola 4 years ago
8 changed file(s) with 76 addition(s) and 41 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);
45 bool WriteSymtab, object::Archive::Kind Kind, bool Deterministic);
4646 }
4747
4848 #endif
140140
141141 std::pair Result =
142142 llvm::writeArchive(getOutputPath(&Args, Members[0]), Members,
143 /*WriteSymtab=*/true, object::Archive::K_GNU);
143 /*WriteSymtab=*/true, object::Archive::K_GNU,
144 /*Deterministic*/ true);
144145
145146 if (Result.second) {
146147 if (Result.first.empty())
177177 Out.seek(Pos);
178178 }
179179
180 static sys::TimeValue now(bool Deterministic) {
181 if (!Deterministic)
182 return sys::TimeValue::now();
183 sys::TimeValue TV;
184 TV.fromEpochTime(0);
185 return TV;
186 }
187
180188 // Returns the offset of the first reference to a member offset.
181189 static ErrorOr
182190 writeSymbolTable(raw_fd_ostream &Out, object::Archive::Kind Kind,
183191 ArrayRef Members,
184192 ArrayRef Buffers,
185 std::vector &MemberOffsetRefs) {
193 std::vector &MemberOffsetRefs, bool Deterministic) {
186194 unsigned HeaderStartOffset = 0;
187195 unsigned BodyStartOffset = 0;
188196 SmallString<128> NameBuf;
200208 if (!HeaderStartOffset) {
201209 HeaderStartOffset = Out.tell();
202210 if (Kind == object::Archive::K_GNU)
203 printGNUSmallMemberHeader(Out, "", sys::TimeValue::now(), 0, 0, 0, 0);
211 printGNUSmallMemberHeader(Out, "", now(Deterministic), 0, 0, 0, 0);
204212 else
205 printBSDMemberHeader(Out, "__.SYMDEF", sys::TimeValue::now(), 0, 0, 0,
206 0);
213 printBSDMemberHeader(Out, "__.SYMDEF", now(Deterministic), 0, 0, 0, 0);
207214 BodyStartOffset = Out.tell();
208215 print32(Out, Kind, 0); // number of entries or bytes
209216 }
260267 return BodyStartOffset + 4;
261268 }
262269
263 std::pair
264 llvm::writeArchive(StringRef ArcName,
265 std::vector &NewMembers,
266 bool WriteSymtab, object::Archive::Kind Kind) {
270 std::pair llvm::writeArchive(
271 StringRef ArcName, std::vector &NewMembers,
272 bool WriteSymtab, object::Archive::Kind Kind, bool Deterministic) {
267273 SmallString<128> TmpArchive;
268274 int TmpArchiveFD;
269275 if (auto EC = sys::fs::createUniqueFile(ArcName + ".temp-archive-%%%%%%%.a",
314320
315321 unsigned MemberReferenceOffset = 0;
316322 if (WriteSymtab) {
317 ErrorOr MemberReferenceOffsetOrErr =
318 writeSymbolTable(Out, Kind, NewMembers, Members, MemberOffsetRefs);
323 ErrorOr MemberReferenceOffsetOrErr = writeSymbolTable(
324 Out, Kind, NewMembers, Members, MemberOffsetRefs, Deterministic);
319325 if (auto EC = MemberReferenceOffsetOrErr.getError())
320326 return std::make_pair(ArcName, EC);
321327 MemberReferenceOffset = MemberReferenceOffsetOrErr.get();
335341 unsigned Pos = Out.tell();
336342 MemberOffset.push_back(Pos);
337343
344 sys::TimeValue ModTime;
345 unsigned UID;
346 unsigned GID;
347 unsigned Perms;
348 if (Deterministic) {
349 ModTime.fromEpochTime(0);
350 UID = 0;
351 GID = 0;
352 Perms = 0644;
353 } else if (I.isNewMember()) {
354 const sys::fs::file_status &Status = NewMemberStatus[NewMemberNum];
355 ModTime = Status.getLastModificationTime();
356 UID = Status.getUser();
357 GID = Status.getGroup();
358 Perms = Status.permissions();
359 } else {
360 object::Archive::child_iterator OldMember = I.getOld();
361 ModTime = OldMember->getLastModified();
362 UID = OldMember->getUID();
363 GID = OldMember->getGID();
364 Perms = OldMember->getAccessMode();
365 }
366
338367 if (I.isNewMember()) {
339368 StringRef FileName = I.getNew();
340369 const sys::fs::file_status &Status = NewMemberStatus[NewMemberNum++];
341370 printMemberHeader(Out, Kind, sys::path::filename(FileName),
342 StringMapIndexIter, Status.getLastModificationTime(),
343 Status.getUser(), Status.getGroup(),
344 Status.permissions(), Status.getSize());
371 StringMapIndexIter, ModTime, UID, GID, Perms,
372 Status.getSize());
345373 } else {
346374 object::Archive::child_iterator OldMember = I.getOld();
347 printMemberHeader(Out, Kind, I.getName(), StringMapIndexIter,
348 OldMember->getLastModified(), OldMember->getUID(),
349 OldMember->getGID(), OldMember->getAccessMode(),
350 OldMember->getSize());
375 printMemberHeader(Out, Kind, I.getName(), StringMapIndexIter, ModTime,
376 UID, GID, Perms, OldMember->getSize());
351377 }
352378
353379 Out << File.getBuffer();
66 RUN: echo -n bar. > 0123456789abcde
77 RUN: echo -n zed. > 0123456789abcdef
88
9 RUN: rm -f test.a
10 RUN: llvm-ar --format=gnu rc test.a 0123456789abcde 0123456789abcdef
11 RUN: cat test.a | FileCheck -strict-whitespace %s
9 RUN: rm -f %t.a
10 RUN: llvm-ar --format=gnu rc %t.a 0123456789abcde 0123456789abcdef
11 RUN: cat %t.a | FileCheck -strict-whitespace %s
1212
1313 CHECK: !
1414 CHECK-NEXT: // 18 `
1515 CHECK-NEXT: 0123456789abcdef/
16 CHECK-NEXT: 0123456789abcde/{{................................}}4 `
17 CHECK-NEXT: bar./0 {{................................}}4 `
16 CHECK-NEXT: 0123456789abcde/0 0 0 644 4 `
17 CHECK-NEXT: bar./0 0 0 0 644 4 `
1818 CHECK-NEXT: zed.
1919
20 RUN: rm -f test-bsd.a
21 RUN: llvm-ar --format=bsd rc test-bsd.a 0123456789abcde 0123456789abcdef
22 RUN: cat test-bsd.a | FileCheck -strict-whitespace --check-prefix=BSD %s
20 RUN: rm -f %t.a
21 RUN: llvm-ar --format=bsd rc %t.a 0123456789abcde 0123456789abcdef
22 RUN: cat %t.a | FileCheck -strict-whitespace --check-prefix=BSD %s
2323
2424 BSD: !
25 BSD-NEXT: #1/20 {{..............................}} 24 `
25 BSD-NEXT: #1/20 0 0 0 644 24 `
2626 BSD-NEXT: 0123456789abcde{{.....}}bar.
27 BSD-SAME: #1/16 {{..............................}} 20 `
27 BSD-SAME: #1/16 0 0 0 644 20 `
2828 BSD-NEXT: 0123456789abcdefzed.
0 RUN: rm -f %t.a
1 RUN: llvm-ar rcs %t.a %p/Inputs/trivial-object-test.elf-x86-64 %p/Inputs/trivial-object-test2.elf-x86-64
1 RUN: llvm-ar rcsU %t.a %p/Inputs/trivial-object-test.elf-x86-64 %p/Inputs/trivial-object-test2.elf-x86-64
22 RUN: llvm-nm -M %t.a | FileCheck %s
33
44 CHECK: Archive map
1818 CHECK-NEXT: 0000000000000016 T main
1919
2020 RUN: rm -f %t.a
21 RUN: llvm-ar rcS %t.a %p/Inputs/trivial-object-test.elf-x86-64 %p/Inputs/trivial-object-test2.elf-x86-64
21 RUN: llvm-ar rcSU %t.a %p/Inputs/trivial-object-test.elf-x86-64 %p/Inputs/trivial-object-test2.elf-x86-64
2222 RUN: llvm-nm -M %t.a | FileCheck %s --check-prefix=NOMAP
2323
2424 NOMAP-NOT: Archive map
5353 repeate the test with llvm-ranlib
5454
5555 RUN: rm -f %t.a
56 RUN: llvm-ar rcS %t.a %p/Inputs/trivial-object-test.elf-x86-64 %p/Inputs/trivial-object-test2.elf-x86-64
56 RUN: llvm-ar rcSU %t.a %p/Inputs/trivial-object-test.elf-x86-64 %p/Inputs/trivial-object-test2.elf-x86-64
5757 RUN: llvm-nm -M %t.a | FileCheck %s --check-prefix=NOMAP
5858
5959 RUN: llvm-ranlib %t.a
6767 BSD-MachO: _foo in foo.o
6868
6969 RUN: rm -f %t.a
70 RUN: llvm-ar --format=bsd rcs %t.a %p/Inputs/trivial-object-test.macho-x86-64 %p/Inputs/trivial-object-test2.macho-x86-64
70 RUN: llvm-ar --format=bsd rcsU %t.a %p/Inputs/trivial-object-test.macho-x86-64 %p/Inputs/trivial-object-test2.macho-x86-64
7171 RUN: llvm-nm -M %t.a | FileCheck --check-prefix=MACHO %s
7272
7373 MACHO: Archive map
9090 Test that we pad the symbol table so that it ends in a multiple of 4 bytes:
9191 8 + 60 + 36 == 104
9292 RUN: rm -f %t.a
93 RUN: llvm-ar --format=bsd rcs %t.a %p/Inputs/trivial-object-test.macho-x86-64
93 RUN: llvm-ar --format=bsd rcsU %t.a %p/Inputs/trivial-object-test.macho-x86-64
9494 RUN: FileCheck --check-prefix=MACHO-SYMTAB-ALIGN %s < %t.a
9595 MACHO-SYMTAB-ALIGN: !
9696 MACHO-SYMTAB-ALIGN-NEXT: #1/12 {{..........}} 0 0 0 36 `
1515 RUN: touch %t.newer/evenlen
1616
1717 Create an achive with the newest file
18 RUN: llvm-ar r %t.a %t.newer/evenlen
18 RUN: llvm-ar rU %t.a %t.newer/evenlen
1919 RUN: llvm-ar p %t.a | FileCheck --check-prefix=NEWER %s
2020
2121 Check that without the 'u' option the member is replaced with an older file.
22 RUN: llvm-ar r %t.a %t.older/evenlen
22 RUN: llvm-ar rU %t.a %t.older/evenlen
2323 RUN: llvm-ar p %t.a | FileCheck --check-prefix=OLDER %s
2424
2525 Check that with the 'u' option the member is replaced with a newer file.
26 RUN: llvm-ar ru %t.a %t.newer/evenlen
26 RUN: llvm-ar ruU %t.a %t.newer/evenlen
2727 RUN: llvm-ar p %t.a | FileCheck --check-prefix=NEWER %s
2828
2929 Check that with the 'u' option the member is not replaced with an older file.
30 RUN: llvm-ar ru %t.a %t.older/evenlen
30 RUN: llvm-ar ruU %t.a %t.older/evenlen
3131 RUN: llvm-ar p %t.a | FileCheck --check-prefix=NEWER %s
3232
3333 NEWER: newer
3838 ; RUN: rm -f very_long_bytecode_file_name.bc
3939 ; RUN: llvm-ar xo %p/Inputs/GNU.a very_long_bytecode_file_name.bc
4040 ; RUN: rm -f %t.a
41 ; RUN: llvm-ar rc %t.a very_long_bytecode_file_name.bc
41 ; RUN: llvm-ar rcU %t.a very_long_bytecode_file_name.bc
4242 ; RUN: env TZ=GMT llvm-ar tv %t.a | FileCheck %s
4343
4444 CHECK: 1465 2004-11-19 03:01:31.000000000 very_long_bytecode_file_name.bc
128128 static bool OnlyUpdate = false; ///< 'u' modifier
129129 static bool Verbose = false; ///< 'v' modifier
130130 static bool Symtab = true; ///< 's' modifier
131 static bool Deterministic = true; ///< 'D' and 'U' modifiers
131132
132133 // Relative Positional Argument (for insert/move). This variable holds
133134 // the name of the archive member to which the 'a', 'b' or 'i' modifier
243244 getRelPos();
244245 AddBefore = true;
245246 NumPositional++;
247 break;
248 case 'D':
249 Deterministic = true;
250 break;
251 case 'U':
252 Deterministic = false;
246253 break;
247254 default:
248255 cl::PrintHelpMessage();
569576 }
570577 if (NewMembersP) {
571578 std::pair Result =
572 writeArchive(ArchiveName, *NewMembersP, Symtab, Kind);
579 writeArchive(ArchiveName, *NewMembersP, Symtab, Kind, Deterministic);
573580 failIfError(Result.second, Result.first);
574581 return;
575582 }
576583 std::vector NewMembers =
577584 computeNewArchiveMembers(Operation, OldArchive);
578 auto Result = writeArchive(ArchiveName, NewMembers, Symtab, Kind);
585 auto Result =
586 writeArchive(ArchiveName, NewMembers, Symtab, Kind, Deterministic);
579587 failIfError(Result.second, Result.first);
580588 }
581589