]> granicus.if.org Git - llvm/commitdiff
Object: pad out BSD archive members to 8-bytes
authorSaleem Abdulrasool <compnerd@compnerd.org>
Thu, 9 Feb 2017 19:29:35 +0000 (19:29 +0000)
committerSaleem Abdulrasool <compnerd@compnerd.org>
Thu, 9 Feb 2017 19:29:35 +0000 (19:29 +0000)
ld64 requires its archive members to be 8-byte aligned for 64-bit
content and 4-byte aligned for 32-bit content.  Opt for the larger
alignment requirement.  This ensures that ld64 can consume archives
generated by llvm-ar.

Thanks to Kevin Enderby for the hint about the ld64/cctools behaviours!

Resolves PR28361!

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@294615 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Object/ArchiveWriter.cpp
test/Object/archive-format.test

index 45047240c3b0c5334366277b6c0fbac7902d294e..fc827d321d95d00acbd405fec718c655728fd8bb 100644 (file)
@@ -395,18 +395,28 @@ llvm::writeArchive(StringRef ArcName,
   std::vector<unsigned> MemberOffset;
   for (const NewArchiveMember &M : NewMembers) {
     MemoryBufferRef File = M.Buf->getMemBufferRef();
+    unsigned Padding = 0;
 
     unsigned Pos = Out.tell();
     MemberOffset.push_back(Pos);
 
+    // ld64 expects the members to be 8-byte aligned for 64-bit content and at
+    // least 4-byte aligned for 32-bit content.  Opt for the larger encoding
+    // uniformly.  This matches the behaviour with cctools and ensures that ld64
+    // is happy with archives that we generate.
+    if (Kind == object::Archive::K_BSD)
+      Padding = OffsetToAlignment(M.Buf->getBufferSize(), 8);
+
     printMemberHeader(Out, Kind, Thin,
                       sys::path::filename(M.Buf->getBufferIdentifier()),
                       StringMapIndexIter, M.ModTime, M.UID, M.GID, M.Perms,
-                      M.Buf->getBufferSize());
+                      M.Buf->getBufferSize() + Padding);
 
     if (!Thin)
       Out << File.getBuffer();
 
+    while (Padding--)
+      Out << '\n';
     if (Out.tell() % 2)
       Out << '\n';
   }
index b9562a36d67b5c9af9d0ae3da824d00f1d46fd1e..7505b1ffd5bd8467af35189abfe92cc942716f28 100644 (file)
@@ -32,10 +32,12 @@ RUN: llvm-ar --format=bsd rc %t.a 0123456789abcde 0123456789abcdef
 RUN: cat %t.a | FileCheck -strict-whitespace --check-prefix=BSD %s
 
 BSD:      !<arch>
-BSD-NEXT: #1/20           0           0     0     644     24        `
-BSD-NEXT: 0123456789abcde{{.....}}bar.
-BSD-SAME: #1/16           0           0     0     644     20        `
-BSD-NEXT: 0123456789abcdefzed.
+BSD-NEXT: #1/20           0           0     0     644     28        `
+Each [[:space:]] matches a newline.  We explicitly match 3 newlines, as the
+fourth newline is implicitly consumed by FileCheck and cannot be matched.
+BSD-NEXT: 0123456789abcde{{.....}}bar.{{[[:space:]][[:space:]][[:space:]]}}
+BSD-NEXT: #1/20           0           0     0     644     28        `
+BSD-NEXT: 0123456789abcdef{{....}}zed.
 
 RUN: rm -f test.a
 RUN: llvm-ar --format=gnu rcT test.a 0123456789abcde 0123456789abcdef