diff options
author | Hans Wennborg <hans@hanshq.net> | 2019-02-08 10:16:45 +0000 |
---|---|---|
committer | Hans Wennborg <hans@hanshq.net> | 2019-02-08 10:16:45 +0000 |
commit | f5db715862f5471b74153f144d17f45f6f6981c5 (patch) | |
tree | d090395dbc45d7e4bf858bf0476dd773c7765e4f /llvm/lib/Object/ArchiveWriter.cpp | |
parent | 56dc218dc12030358b85ba9a9cafe8b0c8d3ff8e (diff) | |
download | bcm5719-llvm-f5db715862f5471b74153f144d17f45f6f6981c5.tar.gz bcm5719-llvm-f5db715862f5471b74153f144d17f45f6f6981c5.zip |
Revert r353424 "[llvm-ar][libObject] Fix relative paths when nesting thin archives."
This broke the Chromium build on Windows, see https://crbug.com/930058
> Summary:
> When adding one thin archive to another, we currently chop off the relative path to the flattened members. For instance, when adding `foo/child.a` (which contains `x.txt`) to `parent.a`, whe
> lattening it we should add it as `foo/x.txt` (which exists) instead of `x.txt` (which does not exist).
>
> As a note, this also undoes the `IsNew` parameter of handling relative paths in r288280. The unit test there still passes.
>
> This was reported as part of testing the kernel build with llvm-ar: https://patchwork.kernel.org/patch/10767545/ (see the second point).
>
> Reviewers: mstorsjo, pcc, ruiu, davide, david2050
>
> Subscribers: hiraditya, llvm-commits
>
> Tags: #llvm
>
> Differential Revision: https://reviews.llvm.org/D57842
This reverts commit bf990ab5aab03aa0aac53c9ef47ef264307804ed.
llvm-svn: 353507
Diffstat (limited to 'llvm/lib/Object/ArchiveWriter.cpp')
-rw-r--r-- | llvm/lib/Object/ArchiveWriter.cpp | 71 |
1 files changed, 59 insertions, 12 deletions
diff --git a/llvm/lib/Object/ArchiveWriter.cpp b/llvm/lib/Object/ArchiveWriter.cpp index 5650ca88f0c..d27233ec2f4 100644 --- a/llvm/lib/Object/ArchiveWriter.cpp +++ b/llvm/lib/Object/ArchiveWriter.cpp @@ -48,6 +48,7 @@ NewArchiveMember::getOldMember(const object::Archive::Child &OldMember, return BufOrErr.takeError(); NewArchiveMember M; + assert(M.IsNew == false); M.Buf = MemoryBuffer::getMemBuffer(*BufOrErr, false); M.MemberName = M.Buf->getBufferIdentifier(); if (!Deterministic) { @@ -97,6 +98,7 @@ Expected<NewArchiveMember> NewArchiveMember::getFile(StringRef FileName, return errorCodeToError(std::error_code(errno, std::generic_category())); NewArchiveMember M; + M.IsNew = true; M.Buf = std::move(*MemberBufferOrErr); M.MemberName = M.Buf->getBufferIdentifier(); if (!Deterministic) { @@ -189,6 +191,35 @@ static bool useStringTable(bool Thin, StringRef Name) { return Thin || Name.size() >= 16 || Name.contains('/'); } +// Compute the relative path from From to To. +static std::string computeRelativePath(StringRef From, StringRef To) { + if (sys::path::is_absolute(From) || sys::path::is_absolute(To)) + return To; + + StringRef DirFrom = sys::path::parent_path(From); + auto FromI = sys::path::begin(DirFrom); + auto ToI = sys::path::begin(To); + while (*FromI == *ToI) { + ++FromI; + ++ToI; + } + + SmallString<128> Relative; + for (auto FromE = sys::path::end(DirFrom); FromI != FromE; ++FromI) + sys::path::append(Relative, ".."); + + for (auto ToE = sys::path::end(To); ToI != ToE; ++ToI) + sys::path::append(Relative, *ToI); + +#ifdef _WIN32 + // Replace backslashes with slashes so that the path is portable between *nix + // and Windows. + std::replace(Relative.begin(), Relative.end(), '\\', '/'); +#endif + + return Relative.str(); +} + static bool is64BitKind(object::Archive::Kind Kind) { switch (Kind) { case object::Archive::K_GNU: @@ -203,11 +234,27 @@ static bool is64BitKind(object::Archive::Kind Kind) { llvm_unreachable("not supported for writting"); } -static void -printMemberHeader(raw_ostream &Out, uint64_t Pos, raw_ostream &StringTable, - StringMap<uint64_t> &MemberNames, object::Archive::Kind Kind, - bool Thin, const NewArchiveMember &M, - sys::TimePoint<std::chrono::seconds> ModTime, unsigned Size) { +static void addToStringTable(raw_ostream &Out, StringRef ArcName, + const NewArchiveMember &M, bool Thin) { + StringRef ID = M.Buf->getBufferIdentifier(); + if (Thin) { + if (M.IsNew) + Out << computeRelativePath(ArcName, ID); + else + Out << ID; + } else + Out << M.MemberName; + Out << "/\n"; +} + +static void printMemberHeader(raw_ostream &Out, uint64_t Pos, + raw_ostream &StringTable, + StringMap<uint64_t> &MemberNames, + object::Archive::Kind Kind, bool Thin, + StringRef ArcName, const NewArchiveMember &M, + sys::TimePoint<std::chrono::seconds> ModTime, + unsigned Size) { + if (isBSDLike(Kind)) return printBSDMemberHeader(Out, Pos, M.MemberName, ModTime, M.UID, M.GID, M.Perms, Size); @@ -218,12 +265,12 @@ printMemberHeader(raw_ostream &Out, uint64_t Pos, raw_ostream &StringTable, uint64_t NamePos; if (Thin) { NamePos = StringTable.tell(); - StringTable << M.MemberName << "/\n"; + addToStringTable(StringTable, ArcName, M, Thin); } else { auto Insertion = MemberNames.insert({M.MemberName, uint64_t(0)}); if (Insertion.second) { Insertion.first->second = StringTable.tell(); - StringTable << M.MemberName << "/\n"; + addToStringTable(StringTable, ArcName, M, Thin); } NamePos = Insertion.first->second; } @@ -385,8 +432,8 @@ getSymbols(MemoryBufferRef Buf, raw_ostream &SymNames, bool &HasObject) { static Expected<std::vector<MemberData>> computeMemberData(raw_ostream &StringTable, raw_ostream &SymNames, - object::Archive::Kind Kind, bool Thin, bool Deterministic, - ArrayRef<NewArchiveMember> NewMembers) { + object::Archive::Kind Kind, bool Thin, StringRef ArcName, + bool Deterministic, ArrayRef<NewArchiveMember> NewMembers) { static char PaddingData[8] = {'\n', '\n', '\n', '\n', '\n', '\n', '\n', '\n'}; // This ignores the symbol table, but we only need the value mod 8 and the @@ -473,8 +520,8 @@ computeMemberData(raw_ostream &StringTable, raw_ostream &SymNames, ModTime = sys::toTimePoint(FilenameCount[M.MemberName]++); else ModTime = M.ModTime; - printMemberHeader(Out, Pos, StringTable, MemberNames, Kind, Thin, M, - ModTime, Buf.getBufferSize() + MemberPadding); + printMemberHeader(Out, Pos, StringTable, MemberNames, Kind, Thin, ArcName, + M, ModTime, Buf.getBufferSize() + MemberPadding); Out.flush(); Expected<std::vector<unsigned>> Symbols = @@ -506,7 +553,7 @@ Error llvm::writeArchive(StringRef ArcName, raw_svector_ostream StringTable(StringTableBuf); Expected<std::vector<MemberData>> DataOrErr = computeMemberData( - StringTable, SymNames, Kind, Thin, Deterministic, NewMembers); + StringTable, SymNames, Kind, Thin, ArcName, Deterministic, NewMembers); if (Error E = DataOrErr.takeError()) return E; std::vector<MemberData> &Data = *DataOrErr; |