Skip to content
This repository has been archived by the owner on Apr 23, 2020. It is now read-only.

Commit

Permalink
[llvm-ar] Make llvm-lib behave more like the MSVC archiver
Browse files Browse the repository at this point in the history
Summary:
Use the filepath used to open the archive member as the archive member
name instead of the file basename. This path might be absolute or
relative.  This is important because the archive member name will show
up in the PDB, and we want our PDBs to look as much like MSVC's as
possible.

This also helps avoid an issue in our PDB module descriptor writing
code, which assumes that all module names are unique. Relative paths
still aren't guaranteed to be unique, but they're much better than
basenames, which definitely aren't unique.

Reviewers: ruiu, zturner

Subscribers: llvm-commits

Differential Revision: https://reviews.llvm.org/D33575

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@305223 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
rnk committed Jun 12, 2017
1 parent b31b7dc commit 0e34c35
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 6 deletions.
1 change: 1 addition & 0 deletions include/llvm/Object/ArchiveWriter.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ namespace llvm {

struct NewArchiveMember {
std::unique_ptr<MemoryBuffer> Buf;
StringRef MemberName;
sys::TimePoint<std::chrono::seconds> ModTime;
unsigned UID = 0, GID = 0, Perms = 0644;

Expand Down
14 changes: 8 additions & 6 deletions lib/Object/ArchiveWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@
using namespace llvm;

NewArchiveMember::NewArchiveMember(MemoryBufferRef BufRef)
: Buf(MemoryBuffer::getMemBuffer(BufRef, false)) {}
: Buf(MemoryBuffer::getMemBuffer(BufRef, false)),
MemberName(BufRef.getBufferIdentifier()) {}

Expected<NewArchiveMember>
NewArchiveMember::getOldMember(const object::Archive::Child &OldMember,
Expand All @@ -48,6 +49,7 @@ NewArchiveMember::getOldMember(const object::Archive::Child &OldMember,
NewArchiveMember M;
assert(M.IsNew == false);
M.Buf = MemoryBuffer::getMemBuffer(*BufOrErr, false);
M.MemberName = M.Buf->getBufferIdentifier();
if (!Deterministic) {
auto ModTimeOrErr = OldMember.getLastModified();
if (!ModTimeOrErr)
Expand Down Expand Up @@ -97,6 +99,7 @@ Expected<NewArchiveMember> NewArchiveMember::getFile(StringRef FileName,
NewArchiveMember M;
M.IsNew = true;
M.Buf = std::move(*MemberBufferOrErr);
M.MemberName = M.Buf->getBufferIdentifier();
if (!Deterministic) {
M.ModTime = std::chrono::time_point_cast<std::chrono::seconds>(
Status.getLastModificationTime());
Expand Down Expand Up @@ -185,7 +188,7 @@ printBSDMemberHeader(raw_fd_ostream &Out, StringRef Name,
}

static bool useStringTable(bool Thin, StringRef Name) {
return Thin || Name.size() >= 16;
return Thin || Name.size() >= 16 || Name.contains('/');
}

static void
Expand Down Expand Up @@ -239,7 +242,7 @@ static void writeStringTable(raw_fd_ostream &Out, StringRef ArcName,
unsigned StartOffset = 0;
for (const NewArchiveMember &M : Members) {
StringRef Path = M.Buf->getBufferIdentifier();
StringRef Name = sys::path::filename(Path);
StringRef Name = M.MemberName;
if (!useStringTable(Thin, Name))
continue;
if (StartOffset == 0) {
Expand Down Expand Up @@ -423,9 +426,8 @@ llvm::writeArchive(StringRef ArcName,
if (Kind == object::Archive::K_DARWIN)
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,
printMemberHeader(Out, Kind, Thin, M.MemberName, StringMapIndexIter,
M.ModTime, M.UID, M.GID, M.Perms,
M.Buf->getBufferSize() + Padding);

if (!Thin)
Expand Down
24 changes: 24 additions & 0 deletions test/LibDriver/use-paths.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
llvm-lib should behave like "link.exe /lib" and use relative paths to describe
archive members.

First, get in a clean working directory.
RUN: rm -rf %t && mkdir -p %t && cd %t

Make foo/a.obj and foo/b.obj.
RUN: mkdir foo
RUN: llvm-mc -triple=x86_64-pc-windows-msvc -filetype=obj -o foo/a.obj %S/Inputs/a.s
RUN: llvm-mc -triple=x86_64-pc-windows-msvc -filetype=obj -o foo/b.obj %S/Inputs/b.s

RUN: llvm-lib -out:foo.lib foo/a.obj foo/b.obj
RUN: llvm-ar t foo.lib | FileCheck %s

FIXME: We should probably use backslashes on Windows to better match MSVC tools.
CHECK: foo/a.obj
CHECK: foo/b.obj

Do it again with absolute paths and see that we get something.
RUN: llvm-lib -out:foo.lib %t/foo/a.obj %t/foo/b.obj
RUN: llvm-ar t foo.lib | FileCheck %s --check-prefix=ABS

ABS: {{.*}}/foo/a.obj
ABS: {{.*}}/foo/b.obj
4 changes: 4 additions & 0 deletions tools/llvm-ar/llvm-ar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -473,6 +473,10 @@ static void addMember(std::vector<NewArchiveMember> &Members,
Expected<NewArchiveMember> NMOrErr =
NewArchiveMember::getFile(FileName, Deterministic);
failIfError(NMOrErr.takeError(), FileName);

// Use the basename of the object path for the member name.
NMOrErr->MemberName = sys::path::filename(NMOrErr->MemberName);

if (Pos == -1)
Members.push_back(std::move(*NMOrErr));
else
Expand Down

0 comments on commit 0e34c35

Please sign in to comment.