[llvm] r241721 - Start adding support for writing archives in BSD format.

Rafael Espindola rafael.espindola at gmail.com
Wed Jul 8 13:47:33 PDT 2015


Author: rafael
Date: Wed Jul  8 15:47:32 2015
New Revision: 241721

URL: http://llvm.org/viewvc/llvm-project?rev=241721&view=rev
Log:
Start adding support for writing archives in BSD format.

No support for the symbol table yet (but will hopefully add it today).
We always use the long filename format so that we can align the member,
which is an advantage of the BSD format.

Modified:
    llvm/trunk/include/llvm/Object/ArchiveWriter.h
    llvm/trunk/lib/LibDriver/LibDriver.cpp
    llvm/trunk/lib/Object/ArchiveWriter.cpp
    llvm/trunk/test/Object/archive-format.test
    llvm/trunk/tools/llvm-ar/llvm-ar.cpp

Modified: llvm/trunk/include/llvm/Object/ArchiveWriter.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Object/ArchiveWriter.h?rev=241721&r1=241720&r2=241721&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Object/ArchiveWriter.h (original)
+++ llvm/trunk/include/llvm/Object/ArchiveWriter.h Wed Jul  8 15:47:32 2015
@@ -44,8 +44,7 @@ public:
 
 std::pair<StringRef, std::error_code>
 writeArchive(StringRef ArcName, std::vector<NewArchiveIterator> &NewMembers,
-             bool WriteSymtab);
-
+             bool WriteSymtab, object::Archive::Kind Kind);
 }
 
 #endif

Modified: llvm/trunk/lib/LibDriver/LibDriver.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/LibDriver/LibDriver.cpp?rev=241721&r1=241720&r2=241721&view=diff
==============================================================================
--- llvm/trunk/lib/LibDriver/LibDriver.cpp (original)
+++ llvm/trunk/lib/LibDriver/LibDriver.cpp Wed Jul  8 15:47:32 2015
@@ -139,8 +139,10 @@ int llvm::libDriverMain(llvm::ArrayRef<c
                          llvm::sys::path::filename(Arg->getValue()));
   }
 
-  std::pair<StringRef, std::error_code> Result = llvm::writeArchive(
-      getOutputPath(&Args, Members[0]), Members, /*WriteSymtab=*/true);
+  std::pair<StringRef, std::error_code> Result =
+      llvm::writeArchive(getOutputPath(&Args, Members[0]), Members,
+                         /*WriteSymtab=*/true, object::Archive::K_GNU);
+
   if (Result.second) {
     if (Result.first.empty())
       Result.first = ArgsArr[0];

Modified: llvm/trunk/lib/Object/ArchiveWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Object/ArchiveWriter.cpp?rev=241721&r1=241720&r2=241721&view=diff
==============================================================================
--- llvm/trunk/lib/Object/ArchiveWriter.cpp (original)
+++ llvm/trunk/lib/Object/ArchiveWriter.cpp Wed Jul  8 15:47:32 2015
@@ -117,10 +117,25 @@ static void printMemberHeader(raw_fd_ost
 }
 
 static void
-printMemberHeader(raw_fd_ostream &Out, StringRef Name,
+printMemberHeader(raw_fd_ostream &Out, object::Archive::Kind Kind,
+                  StringRef Name,
                   std::vector<unsigned>::iterator &StringMapIndexIter,
                   const sys::TimeValue &ModTime, unsigned UID, unsigned GID,
                   unsigned Perms, unsigned Size) {
+  if (Kind == object::Archive::K_BSD) {
+    uint64_t PosAfterHeader = Out.tell() + 60 + Name.size();
+    // Pad so that even 64 bit object files are aligned.
+    unsigned Pad = OffsetToAlignment(PosAfterHeader, 8);
+    unsigned NameWithPadding = Name.size() + Pad;
+    printWithSpacePadding(Out, Twine("#1/") + Twine(NameWithPadding), 16);
+    printRestOfMemberHeader(Out, ModTime, UID, GID, Perms,
+                            NameWithPadding + Size);
+    Out << Name;
+    assert(PosAfterHeader == Out.tell());
+    while (Pad--)
+      Out.write(uint8_t(0));
+    return;
+  }
   if (Name.size() < 16) {
     printMemberHeader(Out, Name, ModTime, UID, GID, Perms, Size);
     return;
@@ -160,9 +175,13 @@ static void writeStringTable(raw_fd_ostr
 
 // Returns the offset of the first reference to a member offset.
 static ErrorOr<unsigned>
-writeSymbolTable(raw_fd_ostream &Out, ArrayRef<NewArchiveIterator> Members,
+writeSymbolTable(raw_fd_ostream &Out, object::Archive::Kind Kind,
+                 ArrayRef<NewArchiveIterator> Members,
                  ArrayRef<MemoryBufferRef> Buffers,
                  std::vector<unsigned> &MemberOffsetRefs) {
+  if (Kind != object::Archive::K_GNU)
+    return 0;
+
   unsigned StartOffset = 0;
   unsigned MemberNum = 0;
   std::string NameBuf;
@@ -222,7 +241,7 @@ writeSymbolTable(raw_fd_ostream &Out, Ar
 std::pair<StringRef, std::error_code>
 llvm::writeArchive(StringRef ArcName,
                    std::vector<NewArchiveIterator> &NewMembers,
-                   bool WriteSymtab) {
+                   bool WriteSymtab, object::Archive::Kind Kind) {
   SmallString<128> TmpArchive;
   int TmpArchiveFD;
   if (auto EC = sys::fs::createUniqueFile(ArcName + ".temp-archive-%%%%%%%.a",
@@ -274,14 +293,15 @@ llvm::writeArchive(StringRef ArcName,
   unsigned MemberReferenceOffset = 0;
   if (WriteSymtab) {
     ErrorOr<unsigned> MemberReferenceOffsetOrErr =
-        writeSymbolTable(Out, NewMembers, Members, MemberOffsetRefs);
+        writeSymbolTable(Out, Kind, NewMembers, Members, MemberOffsetRefs);
     if (auto EC = MemberReferenceOffsetOrErr.getError())
       return std::make_pair(ArcName, EC);
     MemberReferenceOffset = MemberReferenceOffsetOrErr.get();
   }
 
   std::vector<unsigned> StringMapIndexes;
-  writeStringTable(Out, NewMembers, StringMapIndexes);
+  if (Kind != object::Archive::K_BSD)
+    writeStringTable(Out, NewMembers, StringMapIndexes);
 
   unsigned MemberNum = 0;
   unsigned NewMemberNum = 0;
@@ -296,13 +316,13 @@ llvm::writeArchive(StringRef ArcName,
     if (I.isNewMember()) {
       StringRef FileName = I.getNew();
       const sys::fs::file_status &Status = NewMemberStatus[NewMemberNum++];
-      printMemberHeader(Out, sys::path::filename(FileName), StringMapIndexIter,
-                        Status.getLastModificationTime(), Status.getUser(),
-                        Status.getGroup(), Status.permissions(),
-                        Status.getSize());
+      printMemberHeader(Out, Kind, sys::path::filename(FileName),
+                        StringMapIndexIter, Status.getLastModificationTime(),
+                        Status.getUser(), Status.getGroup(),
+                        Status.permissions(), Status.getSize());
     } else {
       object::Archive::child_iterator OldMember = I.getOld();
-      printMemberHeader(Out, I.getName(), StringMapIndexIter,
+      printMemberHeader(Out, Kind, I.getName(), StringMapIndexIter,
                         OldMember->getLastModified(), OldMember->getUID(),
                         OldMember->getGID(), OldMember->getAccessMode(),
                         OldMember->getSize());

Modified: llvm/trunk/test/Object/archive-format.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Object/archive-format.test?rev=241721&r1=241720&r2=241721&view=diff
==============================================================================
--- llvm/trunk/test/Object/archive-format.test (original)
+++ llvm/trunk/test/Object/archive-format.test Wed Jul  8 15:47:32 2015
@@ -17,3 +17,13 @@ CHECK-NEXT: 0123456789abcdef/
 CHECK-NEXT: 0123456789abcde/{{................................}}4         `
 CHECK-NEXT: bar./0              {{................................}}4         `
 CHECK-NEXT: zed.
+
+RUN: rm -f test-bsd.a
+RUN: llvm-ar --format=bsd rc test-bsd.a 0123456789abcde 0123456789abcdef
+RUN: cat test-bsd.a | FileCheck -strict-whitespace --check-prefix=BSD %s
+
+BSD:      !<arch>
+BSD-NEXT: #1/20           {{..............................}}  24        `
+BSD-NEXT: 0123456789abcde{{.....}}bar.
+BSD-SAME: #1/16           {{..............................}}  20        `
+BSD-NEXT: 0123456789abcdefzed.

Modified: llvm/trunk/tools/llvm-ar/llvm-ar.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-ar/llvm-ar.cpp?rev=241721&r1=241720&r2=241721&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-ar/llvm-ar.cpp (original)
+++ llvm/trunk/tools/llvm-ar/llvm-ar.cpp Wed Jul  8 15:47:32 2015
@@ -70,6 +70,16 @@ static cl::list<std::string>
 
 static cl::opt<bool> MRI("M", cl::desc(""));
 
+namespace {
+enum Format { Default, GNU, BSD };
+}
+
+static cl::opt<Format>
+    FormatOpt("format", cl::desc("Archive format to create"),
+              cl::values(clEnumValN(Default, "defalut", "default"),
+                         clEnumValN(GNU, "gnu", "gnu"),
+                         clEnumValN(BSD, "bsd", "bsd"), clEnumValEnd));
+
 std::string Options;
 
 // Provide additional help output explaining the operations and modifiers of
@@ -539,15 +549,27 @@ computeNewArchiveMembers(ArchiveOperatio
 static void
 performWriteOperation(ArchiveOperation Operation, object::Archive *OldArchive,
                       std::vector<NewArchiveIterator> *NewMembersP) {
+  object::Archive::Kind Kind;
+  switch (FormatOpt) {
+  case Default:
+    // FIXME: change as the support for other formats improve.
+    Kind = object::Archive::K_GNU;
+  case GNU:
+    Kind = object::Archive::K_GNU;
+    break;
+  case BSD:
+    Kind = object::Archive::K_BSD;
+    break;
+  }
   if (NewMembersP) {
     std::pair<StringRef, std::error_code> Result =
-        writeArchive(ArchiveName, *NewMembersP, Symtab);
+        writeArchive(ArchiveName, *NewMembersP, Symtab, Kind);
     failIfError(Result.second, Result.first);
     return;
   }
   std::vector<NewArchiveIterator> NewMembers =
       computeNewArchiveMembers(Operation, OldArchive);
-  auto Result = writeArchive(ArchiveName, NewMembers, Symtab);
+  auto Result = writeArchive(ArchiveName, NewMembers, Symtab, Kind);
   failIfError(Result.second, Result.first);
 }
 





More information about the llvm-commits mailing list