mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-07-22 23:24:59 +00:00
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:
@@ -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
|
||||||
|
@@ -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())
|
||||||
|
@@ -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';
|
||||||
|
@@ -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 `
|
||||||
|
@@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user