Initial support for writing thin archives.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@242269 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Rafael Espindola
2015-07-15 05:47:46 +00:00
parent 72d14a0792
commit 4c9cd28947
5 changed files with 45 additions and 18 deletions

View File

@@ -43,7 +43,8 @@ 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 Deterministic); bool WriteSymtab, object::Archive::Kind Kind, bool Deterministic,
bool Thin);
} }
#endif #endif

View File

@@ -142,7 +142,7 @@ 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); /*Deterministic*/ true, /*Thin*/ false);
if (Result.second) { if (Result.second) {
if (Result.first.empty()) if (Result.first.empty())

View File

@@ -135,15 +135,19 @@ static void printBSDMemberHeader(raw_fd_ostream &Out, StringRef Name,
Out.write(uint8_t(0)); Out.write(uint8_t(0));
} }
static bool useStringTable(bool Thin, StringRef Name) {
return Thin || Name.size() >= 16;
}
static void static void
printMemberHeader(raw_fd_ostream &Out, object::Archive::Kind Kind, printMemberHeader(raw_fd_ostream &Out, object::Archive::Kind Kind, bool Thin,
StringRef Name, StringRef Name,
std::vector<unsigned>::iterator &StringMapIndexIter, std::vector<unsigned>::iterator &StringMapIndexIter,
const sys::TimeValue &ModTime, unsigned UID, unsigned GID, const sys::TimeValue &ModTime, unsigned UID, unsigned GID,
unsigned Perms, unsigned Size) { unsigned Perms, unsigned Size) {
if (Kind == object::Archive::K_BSD) if (Kind == object::Archive::K_BSD)
return printBSDMemberHeader(Out, Name, ModTime, UID, GID, Perms, Size); return printBSDMemberHeader(Out, Name, ModTime, UID, GID, Perms, Size);
if (Name.size() < 16) if (!useStringTable(Thin, Name))
return printGNUSmallMemberHeader(Out, Name, ModTime, UID, GID, Perms, Size); return printGNUSmallMemberHeader(Out, Name, ModTime, UID, GID, Perms, Size);
Out << '/'; Out << '/';
printWithSpacePadding(Out, *StringMapIndexIter++, 15); printWithSpacePadding(Out, *StringMapIndexIter++, 15);
@@ -152,11 +156,12 @@ printMemberHeader(raw_fd_ostream &Out, object::Archive::Kind Kind,
static void writeStringTable(raw_fd_ostream &Out, static void writeStringTable(raw_fd_ostream &Out,
ArrayRef<NewArchiveIterator> Members, ArrayRef<NewArchiveIterator> Members,
std::vector<unsigned> &StringMapIndexes) { std::vector<unsigned> &StringMapIndexes,
bool Thin) {
unsigned StartOffset = 0; unsigned StartOffset = 0;
for (const NewArchiveIterator &I : Members) { for (const NewArchiveIterator &I : Members) {
StringRef Name = I.getName(); StringRef Name = I.getName();
if (Name.size() < 16) if (!useStringTable(Thin, Name))
continue; continue;
if (StartOffset == 0) { if (StartOffset == 0) {
printWithSpacePadding(Out, "//", 58); printWithSpacePadding(Out, "//", 58);
@@ -266,9 +271,11 @@ writeSymbolTable(raw_fd_ostream &Out, object::Archive::Kind Kind,
return BodyStartOffset + 4; return BodyStartOffset + 4;
} }
std::pair<StringRef, std::error_code> llvm::writeArchive( std::pair<StringRef, std::error_code>
StringRef ArcName, std::vector<NewArchiveIterator> &NewMembers, llvm::writeArchive(StringRef ArcName,
bool WriteSymtab, object::Archive::Kind Kind, bool Deterministic) { std::vector<NewArchiveIterator> &NewMembers,
bool WriteSymtab, object::Archive::Kind Kind,
bool Deterministic, bool Thin) {
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",
@@ -277,7 +284,10 @@ std::pair<StringRef, std::error_code> llvm::writeArchive(
tool_output_file Output(TmpArchive, TmpArchiveFD); tool_output_file Output(TmpArchive, TmpArchiveFD);
raw_fd_ostream &Out = Output.os(); raw_fd_ostream &Out = Output.os();
Out << "!<arch>\n"; if (Thin)
Out << "!<thin>\n";
else
Out << "!<arch>\n";
std::vector<unsigned> MemberOffsetRefs; std::vector<unsigned> MemberOffsetRefs;
@@ -328,7 +338,7 @@ std::pair<StringRef, std::error_code> llvm::writeArchive(
std::vector<unsigned> StringMapIndexes; std::vector<unsigned> StringMapIndexes;
if (Kind != object::Archive::K_BSD) if (Kind != object::Archive::K_BSD)
writeStringTable(Out, NewMembers, StringMapIndexes); writeStringTable(Out, NewMembers, StringMapIndexes, Thin);
unsigned MemberNum = 0; unsigned MemberNum = 0;
unsigned NewMemberNum = 0; unsigned NewMemberNum = 0;
@@ -366,16 +376,17 @@ std::pair<StringRef, std::error_code> llvm::writeArchive(
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, Thin, sys::path::filename(FileName),
StringMapIndexIter, ModTime, UID, GID, Perms, StringMapIndexIter, ModTime, UID, GID, Perms,
Status.getSize()); Status.getSize());
} else { } else {
object::Archive::child_iterator OldMember = I.getOld(); object::Archive::child_iterator OldMember = I.getOld();
printMemberHeader(Out, Kind, I.getName(), StringMapIndexIter, ModTime, printMemberHeader(Out, Kind, Thin, I.getName(), StringMapIndexIter,
UID, GID, Perms, OldMember->getSize()); ModTime, UID, GID, Perms, OldMember->getSize());
} }
Out << File.getBuffer(); if (!Thin)
Out << File.getBuffer();
if (Out.tell() % 2) if (Out.tell() % 2)
Out << '\n'; Out << '\n';

View File

@@ -27,3 +27,14 @@ BSD-NEXT: #1/20 0 0 0 644 24 `
BSD-NEXT: 0123456789abcde{{.....}}bar. BSD-NEXT: 0123456789abcde{{.....}}bar.
BSD-SAME: #1/16 0 0 0 644 20 ` BSD-SAME: #1/16 0 0 0 644 20 `
BSD-NEXT: 0123456789abcdefzed. BSD-NEXT: 0123456789abcdefzed.
RUN: rm -f %t.a
RUN: llvm-ar --format=gnu rcT %t.a 0123456789abcde 0123456789abcdef
RUN: cat %t.a | FileCheck -strict-whitespace --check-prefix=THIN %s
THIN: !<thin>
THIN-NEXT: // 36 `
THIN-NEXT: 0123456789abcde/
THIN-NEXT: 0123456789abcdef/{{$}}
THIN: {{^$}}
THIN: /0 0 0 0 644 4 `
THIN-NEXT: /17 0 0 0 644 4 `

View File

@@ -130,6 +130,7 @@ 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 static bool Deterministic = true; ///< 'D' and 'U' modifiers
static bool Thin = false; ///< 'T' modifier
// 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
@@ -252,6 +253,9 @@ static ArchiveOperation parseCommandLine() {
case 'U': case 'U':
Deterministic = false; Deterministic = false;
break; break;
case 'T':
Thin = true;
break;
default: default:
cl::PrintHelpMessage(); cl::PrintHelpMessage();
} }
@@ -590,15 +594,15 @@ performWriteOperation(ArchiveOperation Operation, object::Archive *OldArchive,
break; break;
} }
if (NewMembersP) { if (NewMembersP) {
std::pair<StringRef, std::error_code> Result = std::pair<StringRef, std::error_code> Result = writeArchive(
writeArchive(ArchiveName, *NewMembersP, Symtab, Kind, Deterministic); ArchiveName, *NewMembersP, Symtab, Kind, Deterministic, Thin);
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 = auto Result =
writeArchive(ArchiveName, NewMembers, Symtab, Kind, Deterministic); writeArchive(ArchiveName, NewMembers, Symtab, Kind, Deterministic, Thin);
failIfError(Result.second, Result.first); failIfError(Result.second, Result.first);
} }