summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Object/ArchiveWriter.cpp
diff options
context:
space:
mode:
authorHans Wennborg <hans@hanshq.net>2019-02-08 10:16:45 +0000
committerHans Wennborg <hans@hanshq.net>2019-02-08 10:16:45 +0000
commitf5db715862f5471b74153f144d17f45f6f6981c5 (patch)
treed090395dbc45d7e4bf858bf0476dd773c7765e4f /llvm/lib/Object/ArchiveWriter.cpp
parent56dc218dc12030358b85ba9a9cafe8b0c8d3ff8e (diff)
downloadbcm5719-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.cpp71
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;
OpenPOWER on IntegriCloud