From 111cd669e90e5b2132187d36f8b141b11a671a8b Mon Sep 17 00:00:00 2001 From: Saleem Abdulrasool Date: Thu, 9 Feb 2017 19:29:35 +0000 Subject: [PATCH] Object: pad out BSD archive members to 8-bytes 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! llvm-svn: 294615 --- llvm/lib/Object/ArchiveWriter.cpp | 12 +++++++++++- llvm/test/Object/archive-format.test | 10 ++++++---- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/llvm/lib/Object/ArchiveWriter.cpp b/llvm/lib/Object/ArchiveWriter.cpp index 45047240c3b0..fc827d321d95 100644 --- a/llvm/lib/Object/ArchiveWriter.cpp +++ b/llvm/lib/Object/ArchiveWriter.cpp @@ -395,18 +395,28 @@ llvm::writeArchive(StringRef ArcName, std::vector 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'; } diff --git a/llvm/test/Object/archive-format.test b/llvm/test/Object/archive-format.test index b9562a36d67b..7505b1ffd5bd 100644 --- a/llvm/test/Object/archive-format.test +++ b/llvm/test/Object/archive-format.test @@ -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: ! -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