mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-07-23 14:25:07 +00:00
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
This commit is contained in:
@@ -43,7 +43,7 @@ public:
|
|||||||
|
|
||||||
std::pair<StringRef, std::error_code>
|
std::pair<StringRef, std::error_code>
|
||||||
writeArchive(StringRef ArcName, std::vector<NewArchiveIterator> &NewMembers,
|
writeArchive(StringRef ArcName, std::vector<NewArchiveIterator> &NewMembers,
|
||||||
bool WriteSymtab, object::Archive::Kind Kind);
|
bool WriteSymtab, object::Archive::Kind Kind, bool Deterministic);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@@ -141,7 +141,8 @@ int llvm::libDriverMain(llvm::ArrayRef<const char*> ArgsArr) {
|
|||||||
|
|
||||||
std::pair<StringRef, std::error_code> Result =
|
std::pair<StringRef, std::error_code> Result =
|
||||||
llvm::writeArchive(getOutputPath(&Args, Members[0]), Members,
|
llvm::writeArchive(getOutputPath(&Args, Members[0]), Members,
|
||||||
/*WriteSymtab=*/true, object::Archive::K_GNU);
|
/*WriteSymtab=*/true, object::Archive::K_GNU,
|
||||||
|
/*Deterministic*/ true);
|
||||||
|
|
||||||
if (Result.second) {
|
if (Result.second) {
|
||||||
if (Result.first.empty())
|
if (Result.first.empty())
|
||||||
|
@@ -178,12 +178,20 @@ static void writeStringTable(raw_fd_ostream &Out,
|
|||||||
Out.seek(Pos);
|
Out.seek(Pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static sys::TimeValue now(bool Deterministic) {
|
||||||
|
if (!Deterministic)
|
||||||
|
return sys::TimeValue::now();
|
||||||
|
sys::TimeValue TV;
|
||||||
|
TV.fromEpochTime(0);
|
||||||
|
return TV;
|
||||||
|
}
|
||||||
|
|
||||||
// Returns the offset of the first reference to a member offset.
|
// Returns the offset of the first reference to a member offset.
|
||||||
static ErrorOr<unsigned>
|
static ErrorOr<unsigned>
|
||||||
writeSymbolTable(raw_fd_ostream &Out, object::Archive::Kind Kind,
|
writeSymbolTable(raw_fd_ostream &Out, object::Archive::Kind Kind,
|
||||||
ArrayRef<NewArchiveIterator> Members,
|
ArrayRef<NewArchiveIterator> Members,
|
||||||
ArrayRef<MemoryBufferRef> Buffers,
|
ArrayRef<MemoryBufferRef> Buffers,
|
||||||
std::vector<unsigned> &MemberOffsetRefs) {
|
std::vector<unsigned> &MemberOffsetRefs, bool Deterministic) {
|
||||||
unsigned HeaderStartOffset = 0;
|
unsigned HeaderStartOffset = 0;
|
||||||
unsigned BodyStartOffset = 0;
|
unsigned BodyStartOffset = 0;
|
||||||
SmallString<128> NameBuf;
|
SmallString<128> NameBuf;
|
||||||
@@ -201,10 +209,9 @@ writeSymbolTable(raw_fd_ostream &Out, object::Archive::Kind Kind,
|
|||||||
if (!HeaderStartOffset) {
|
if (!HeaderStartOffset) {
|
||||||
HeaderStartOffset = Out.tell();
|
HeaderStartOffset = Out.tell();
|
||||||
if (Kind == object::Archive::K_GNU)
|
if (Kind == object::Archive::K_GNU)
|
||||||
printGNUSmallMemberHeader(Out, "", sys::TimeValue::now(), 0, 0, 0, 0);
|
printGNUSmallMemberHeader(Out, "", now(Deterministic), 0, 0, 0, 0);
|
||||||
else
|
else
|
||||||
printBSDMemberHeader(Out, "__.SYMDEF", sys::TimeValue::now(), 0, 0, 0,
|
printBSDMemberHeader(Out, "__.SYMDEF", now(Deterministic), 0, 0, 0, 0);
|
||||||
0);
|
|
||||||
BodyStartOffset = Out.tell();
|
BodyStartOffset = Out.tell();
|
||||||
print32(Out, Kind, 0); // number of entries or bytes
|
print32(Out, Kind, 0); // number of entries or bytes
|
||||||
}
|
}
|
||||||
@@ -261,10 +268,9 @@ writeSymbolTable(raw_fd_ostream &Out, object::Archive::Kind Kind,
|
|||||||
return BodyStartOffset + 4;
|
return BodyStartOffset + 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<StringRef, std::error_code>
|
std::pair<StringRef, std::error_code> llvm::writeArchive(
|
||||||
llvm::writeArchive(StringRef ArcName,
|
StringRef ArcName, std::vector<NewArchiveIterator> &NewMembers,
|
||||||
std::vector<NewArchiveIterator> &NewMembers,
|
bool WriteSymtab, object::Archive::Kind Kind, bool Deterministic) {
|
||||||
bool WriteSymtab, object::Archive::Kind Kind) {
|
|
||||||
SmallString<128> TmpArchive;
|
SmallString<128> TmpArchive;
|
||||||
int TmpArchiveFD;
|
int TmpArchiveFD;
|
||||||
if (auto EC = sys::fs::createUniqueFile(ArcName + ".temp-archive-%%%%%%%.a",
|
if (auto EC = sys::fs::createUniqueFile(ArcName + ".temp-archive-%%%%%%%.a",
|
||||||
@@ -315,8 +321,8 @@ llvm::writeArchive(StringRef ArcName,
|
|||||||
|
|
||||||
unsigned MemberReferenceOffset = 0;
|
unsigned MemberReferenceOffset = 0;
|
||||||
if (WriteSymtab) {
|
if (WriteSymtab) {
|
||||||
ErrorOr<unsigned> MemberReferenceOffsetOrErr =
|
ErrorOr<unsigned> MemberReferenceOffsetOrErr = writeSymbolTable(
|
||||||
writeSymbolTable(Out, Kind, NewMembers, Members, MemberOffsetRefs);
|
Out, Kind, NewMembers, Members, MemberOffsetRefs, Deterministic);
|
||||||
if (auto EC = MemberReferenceOffsetOrErr.getError())
|
if (auto EC = MemberReferenceOffsetOrErr.getError())
|
||||||
return std::make_pair(ArcName, EC);
|
return std::make_pair(ArcName, EC);
|
||||||
MemberReferenceOffset = MemberReferenceOffsetOrErr.get();
|
MemberReferenceOffset = MemberReferenceOffsetOrErr.get();
|
||||||
@@ -336,19 +342,39 @@ llvm::writeArchive(StringRef ArcName,
|
|||||||
unsigned Pos = Out.tell();
|
unsigned Pos = Out.tell();
|
||||||
MemberOffset.push_back(Pos);
|
MemberOffset.push_back(Pos);
|
||||||
|
|
||||||
|
sys::TimeValue ModTime;
|
||||||
|
unsigned UID;
|
||||||
|
unsigned GID;
|
||||||
|
unsigned Perms;
|
||||||
|
if (Deterministic) {
|
||||||
|
ModTime.fromEpochTime(0);
|
||||||
|
UID = 0;
|
||||||
|
GID = 0;
|
||||||
|
Perms = 0644;
|
||||||
|
} else if (I.isNewMember()) {
|
||||||
|
const sys::fs::file_status &Status = NewMemberStatus[NewMemberNum];
|
||||||
|
ModTime = Status.getLastModificationTime();
|
||||||
|
UID = Status.getUser();
|
||||||
|
GID = Status.getGroup();
|
||||||
|
Perms = Status.permissions();
|
||||||
|
} else {
|
||||||
|
object::Archive::child_iterator OldMember = I.getOld();
|
||||||
|
ModTime = OldMember->getLastModified();
|
||||||
|
UID = OldMember->getUID();
|
||||||
|
GID = OldMember->getGID();
|
||||||
|
Perms = OldMember->getAccessMode();
|
||||||
|
}
|
||||||
|
|
||||||
if (I.isNewMember()) {
|
if (I.isNewMember()) {
|
||||||
StringRef FileName = I.getNew();
|
StringRef FileName = I.getNew();
|
||||||
const sys::fs::file_status &Status = NewMemberStatus[NewMemberNum++];
|
const sys::fs::file_status &Status = NewMemberStatus[NewMemberNum++];
|
||||||
printMemberHeader(Out, Kind, sys::path::filename(FileName),
|
printMemberHeader(Out, Kind, sys::path::filename(FileName),
|
||||||
StringMapIndexIter, Status.getLastModificationTime(),
|
StringMapIndexIter, ModTime, UID, GID, Perms,
|
||||||
Status.getUser(), Status.getGroup(),
|
Status.getSize());
|
||||||
Status.permissions(), Status.getSize());
|
|
||||||
} else {
|
} else {
|
||||||
object::Archive::child_iterator OldMember = I.getOld();
|
object::Archive::child_iterator OldMember = I.getOld();
|
||||||
printMemberHeader(Out, Kind, I.getName(), StringMapIndexIter,
|
printMemberHeader(Out, Kind, I.getName(), StringMapIndexIter, ModTime,
|
||||||
OldMember->getLastModified(), OldMember->getUID(),
|
UID, GID, Perms, OldMember->getSize());
|
||||||
OldMember->getGID(), OldMember->getAccessMode(),
|
|
||||||
OldMember->getSize());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Out << File.getBuffer();
|
Out << File.getBuffer();
|
||||||
|
@@ -7,23 +7,23 @@ RUN: cd %t
|
|||||||
RUN: echo -n bar. > 0123456789abcde
|
RUN: echo -n bar. > 0123456789abcde
|
||||||
RUN: echo -n zed. > 0123456789abcdef
|
RUN: echo -n zed. > 0123456789abcdef
|
||||||
|
|
||||||
RUN: rm -f test.a
|
RUN: rm -f %t.a
|
||||||
RUN: llvm-ar --format=gnu rc test.a 0123456789abcde 0123456789abcdef
|
RUN: llvm-ar --format=gnu rc %t.a 0123456789abcde 0123456789abcdef
|
||||||
RUN: cat test.a | FileCheck -strict-whitespace %s
|
RUN: cat %t.a | FileCheck -strict-whitespace %s
|
||||||
|
|
||||||
CHECK: !<arch>
|
CHECK: !<arch>
|
||||||
CHECK-NEXT: // 18 `
|
CHECK-NEXT: // 18 `
|
||||||
CHECK-NEXT: 0123456789abcdef/
|
CHECK-NEXT: 0123456789abcdef/
|
||||||
CHECK-NEXT: 0123456789abcde/{{................................}}4 `
|
CHECK-NEXT: 0123456789abcde/0 0 0 644 4 `
|
||||||
CHECK-NEXT: bar./0 {{................................}}4 `
|
CHECK-NEXT: bar./0 0 0 0 644 4 `
|
||||||
CHECK-NEXT: zed.
|
CHECK-NEXT: zed.
|
||||||
|
|
||||||
RUN: rm -f test-bsd.a
|
RUN: rm -f %t.a
|
||||||
RUN: llvm-ar --format=bsd rc test-bsd.a 0123456789abcde 0123456789abcdef
|
RUN: llvm-ar --format=bsd rc %t.a 0123456789abcde 0123456789abcdef
|
||||||
RUN: cat test-bsd.a | FileCheck -strict-whitespace --check-prefix=BSD %s
|
RUN: cat %t.a | FileCheck -strict-whitespace --check-prefix=BSD %s
|
||||||
|
|
||||||
BSD: !<arch>
|
BSD: !<arch>
|
||||||
BSD-NEXT: #1/20 {{..............................}} 24 `
|
BSD-NEXT: #1/20 0 0 0 644 24 `
|
||||||
BSD-NEXT: 0123456789abcde{{.....}}bar.
|
BSD-NEXT: 0123456789abcde{{.....}}bar.
|
||||||
BSD-SAME: #1/16 {{..............................}} 20 `
|
BSD-SAME: #1/16 0 0 0 644 20 `
|
||||||
BSD-NEXT: 0123456789abcdefzed.
|
BSD-NEXT: 0123456789abcdefzed.
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
RUN: rm -f %t.a
|
RUN: rm -f %t.a
|
||||||
RUN: llvm-ar rcs %t.a %p/Inputs/trivial-object-test.elf-x86-64 %p/Inputs/trivial-object-test2.elf-x86-64
|
RUN: llvm-ar rcsU %t.a %p/Inputs/trivial-object-test.elf-x86-64 %p/Inputs/trivial-object-test2.elf-x86-64
|
||||||
RUN: llvm-nm -M %t.a | FileCheck %s
|
RUN: llvm-nm -M %t.a | FileCheck %s
|
||||||
|
|
||||||
CHECK: Archive map
|
CHECK: Archive map
|
||||||
@@ -19,7 +19,7 @@ CHECK-NEXT: 0000000000000006 T foo
|
|||||||
CHECK-NEXT: 0000000000000016 T main
|
CHECK-NEXT: 0000000000000016 T main
|
||||||
|
|
||||||
RUN: rm -f %t.a
|
RUN: rm -f %t.a
|
||||||
RUN: llvm-ar rcS %t.a %p/Inputs/trivial-object-test.elf-x86-64 %p/Inputs/trivial-object-test2.elf-x86-64
|
RUN: llvm-ar rcSU %t.a %p/Inputs/trivial-object-test.elf-x86-64 %p/Inputs/trivial-object-test2.elf-x86-64
|
||||||
RUN: llvm-nm -M %t.a | FileCheck %s --check-prefix=NOMAP
|
RUN: llvm-nm -M %t.a | FileCheck %s --check-prefix=NOMAP
|
||||||
|
|
||||||
NOMAP-NOT: Archive map
|
NOMAP-NOT: Archive map
|
||||||
@@ -54,7 +54,7 @@ RUN: llvm-nm -M %t.a | FileCheck %s --check-prefix=CORRUPT
|
|||||||
repeate the test with llvm-ranlib
|
repeate the test with llvm-ranlib
|
||||||
|
|
||||||
RUN: rm -f %t.a
|
RUN: rm -f %t.a
|
||||||
RUN: llvm-ar rcS %t.a %p/Inputs/trivial-object-test.elf-x86-64 %p/Inputs/trivial-object-test2.elf-x86-64
|
RUN: llvm-ar rcSU %t.a %p/Inputs/trivial-object-test.elf-x86-64 %p/Inputs/trivial-object-test2.elf-x86-64
|
||||||
RUN: llvm-nm -M %t.a | FileCheck %s --check-prefix=NOMAP
|
RUN: llvm-nm -M %t.a | FileCheck %s --check-prefix=NOMAP
|
||||||
|
|
||||||
RUN: llvm-ranlib %t.a
|
RUN: llvm-ranlib %t.a
|
||||||
@@ -68,7 +68,7 @@ BSD-MachO: _bar in bar.o
|
|||||||
BSD-MachO: _foo in foo.o
|
BSD-MachO: _foo in foo.o
|
||||||
|
|
||||||
RUN: rm -f %t.a
|
RUN: rm -f %t.a
|
||||||
RUN: llvm-ar --format=bsd rcs %t.a %p/Inputs/trivial-object-test.macho-x86-64 %p/Inputs/trivial-object-test2.macho-x86-64
|
RUN: llvm-ar --format=bsd rcsU %t.a %p/Inputs/trivial-object-test.macho-x86-64 %p/Inputs/trivial-object-test2.macho-x86-64
|
||||||
RUN: llvm-nm -M %t.a | FileCheck --check-prefix=MACHO %s
|
RUN: llvm-nm -M %t.a | FileCheck --check-prefix=MACHO %s
|
||||||
|
|
||||||
MACHO: Archive map
|
MACHO: Archive map
|
||||||
@@ -91,7 +91,7 @@ MACHO-NEXT: 0000000000000002 T _main
|
|||||||
Test that we pad the symbol table so that it ends in a multiple of 4 bytes:
|
Test that we pad the symbol table so that it ends in a multiple of 4 bytes:
|
||||||
8 + 60 + 36 == 104
|
8 + 60 + 36 == 104
|
||||||
RUN: rm -f %t.a
|
RUN: rm -f %t.a
|
||||||
RUN: llvm-ar --format=bsd rcs %t.a %p/Inputs/trivial-object-test.macho-x86-64
|
RUN: llvm-ar --format=bsd rcsU %t.a %p/Inputs/trivial-object-test.macho-x86-64
|
||||||
RUN: FileCheck --check-prefix=MACHO-SYMTAB-ALIGN %s < %t.a
|
RUN: FileCheck --check-prefix=MACHO-SYMTAB-ALIGN %s < %t.a
|
||||||
MACHO-SYMTAB-ALIGN: !<arch>
|
MACHO-SYMTAB-ALIGN: !<arch>
|
||||||
MACHO-SYMTAB-ALIGN-NEXT: #1/12 {{..........}} 0 0 0 36 `
|
MACHO-SYMTAB-ALIGN-NEXT: #1/12 {{..........}} 0 0 0 36 `
|
||||||
|
@@ -16,19 +16,19 @@ RUN: echo newer > %t.newer/evenlen
|
|||||||
RUN: touch %t.newer/evenlen
|
RUN: touch %t.newer/evenlen
|
||||||
|
|
||||||
Create an achive with the newest file
|
Create an achive with the newest file
|
||||||
RUN: llvm-ar r %t.a %t.newer/evenlen
|
RUN: llvm-ar rU %t.a %t.newer/evenlen
|
||||||
RUN: llvm-ar p %t.a | FileCheck --check-prefix=NEWER %s
|
RUN: llvm-ar p %t.a | FileCheck --check-prefix=NEWER %s
|
||||||
|
|
||||||
Check that without the 'u' option the member is replaced with an older file.
|
Check that without the 'u' option the member is replaced with an older file.
|
||||||
RUN: llvm-ar r %t.a %t.older/evenlen
|
RUN: llvm-ar rU %t.a %t.older/evenlen
|
||||||
RUN: llvm-ar p %t.a | FileCheck --check-prefix=OLDER %s
|
RUN: llvm-ar p %t.a | FileCheck --check-prefix=OLDER %s
|
||||||
|
|
||||||
Check that with the 'u' option the member is replaced with a newer file.
|
Check that with the 'u' option the member is replaced with a newer file.
|
||||||
RUN: llvm-ar ru %t.a %t.newer/evenlen
|
RUN: llvm-ar ruU %t.a %t.newer/evenlen
|
||||||
RUN: llvm-ar p %t.a | FileCheck --check-prefix=NEWER %s
|
RUN: llvm-ar p %t.a | FileCheck --check-prefix=NEWER %s
|
||||||
|
|
||||||
Check that with the 'u' option the member is not replaced with an older file.
|
Check that with the 'u' option the member is not replaced with an older file.
|
||||||
RUN: llvm-ar ru %t.a %t.older/evenlen
|
RUN: llvm-ar ruU %t.a %t.older/evenlen
|
||||||
RUN: llvm-ar p %t.a | FileCheck --check-prefix=NEWER %s
|
RUN: llvm-ar p %t.a | FileCheck --check-prefix=NEWER %s
|
||||||
|
|
||||||
NEWER: newer
|
NEWER: newer
|
||||||
|
@@ -39,7 +39,7 @@
|
|||||||
; RUN: rm -f very_long_bytecode_file_name.bc
|
; RUN: rm -f very_long_bytecode_file_name.bc
|
||||||
; RUN: llvm-ar xo %p/Inputs/GNU.a very_long_bytecode_file_name.bc
|
; RUN: llvm-ar xo %p/Inputs/GNU.a very_long_bytecode_file_name.bc
|
||||||
; RUN: rm -f %t.a
|
; RUN: rm -f %t.a
|
||||||
; RUN: llvm-ar rc %t.a very_long_bytecode_file_name.bc
|
; RUN: llvm-ar rcU %t.a very_long_bytecode_file_name.bc
|
||||||
; RUN: env TZ=GMT llvm-ar tv %t.a | FileCheck %s
|
; RUN: env TZ=GMT llvm-ar tv %t.a | FileCheck %s
|
||||||
|
|
||||||
CHECK: 1465 2004-11-19 03:01:31.000000000 very_long_bytecode_file_name.bc
|
CHECK: 1465 2004-11-19 03:01:31.000000000 very_long_bytecode_file_name.bc
|
||||||
|
@@ -129,6 +129,7 @@ static bool OriginalDates = false; ///< 'o' modifier
|
|||||||
static bool OnlyUpdate = false; ///< 'u' modifier
|
static bool OnlyUpdate = false; ///< 'u' modifier
|
||||||
static bool Verbose = false; ///< 'v' modifier
|
static bool Verbose = false; ///< 'v' modifier
|
||||||
static bool Symtab = true; ///< 's' modifier
|
static bool Symtab = true; ///< 's' modifier
|
||||||
|
static bool Deterministic = true; ///< 'D' and 'U' modifiers
|
||||||
|
|
||||||
// Relative Positional Argument (for insert/move). This variable holds
|
// Relative Positional Argument (for insert/move). This variable holds
|
||||||
// the name of the archive member to which the 'a', 'b' or 'i' modifier
|
// the name of the archive member to which the 'a', 'b' or 'i' modifier
|
||||||
@@ -245,6 +246,12 @@ static ArchiveOperation parseCommandLine() {
|
|||||||
AddBefore = true;
|
AddBefore = true;
|
||||||
NumPositional++;
|
NumPositional++;
|
||||||
break;
|
break;
|
||||||
|
case 'D':
|
||||||
|
Deterministic = true;
|
||||||
|
break;
|
||||||
|
case 'U':
|
||||||
|
Deterministic = false;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
cl::PrintHelpMessage();
|
cl::PrintHelpMessage();
|
||||||
}
|
}
|
||||||
@@ -570,13 +577,14 @@ performWriteOperation(ArchiveOperation Operation, object::Archive *OldArchive,
|
|||||||
}
|
}
|
||||||
if (NewMembersP) {
|
if (NewMembersP) {
|
||||||
std::pair<StringRef, std::error_code> Result =
|
std::pair<StringRef, std::error_code> Result =
|
||||||
writeArchive(ArchiveName, *NewMembersP, Symtab, Kind);
|
writeArchive(ArchiveName, *NewMembersP, Symtab, Kind, Deterministic);
|
||||||
failIfError(Result.second, Result.first);
|
failIfError(Result.second, Result.first);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
std::vector<NewArchiveIterator> NewMembers =
|
std::vector<NewArchiveIterator> NewMembers =
|
||||||
computeNewArchiveMembers(Operation, OldArchive);
|
computeNewArchiveMembers(Operation, OldArchive);
|
||||||
auto Result = writeArchive(ArchiveName, NewMembers, Symtab, Kind);
|
auto Result =
|
||||||
|
writeArchive(ArchiveName, NewMembers, Symtab, Kind, Deterministic);
|
||||||
failIfError(Result.second, Result.first);
|
failIfError(Result.second, Result.first);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user