1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-23 11:13:28 +01:00

Reapply "More fixes to get good error messages for bad archives."

This reverts commit the revert commit r277627. The build errors
mentioned in r277627 were likely caused by an unclean build directory.
Sorry for the noise.

llvm-svn: 277630
This commit is contained in:
Vedant Kumar 2016-08-03 19:02:50 +00:00
parent bdf8805e8c
commit 225132d711
11 changed files with 143 additions and 37 deletions

View File

@ -44,14 +44,14 @@ public:
/// Members are not larger than 4GB. /// Members are not larger than 4GB.
Expected<uint32_t> getSize() const; Expected<uint32_t> getSize() const;
sys::fs::perms getAccessMode() const; Expected<sys::fs::perms> getAccessMode() const;
sys::TimeValue getLastModified() const; Expected<sys::TimeValue> getLastModified() const;
llvm::StringRef getRawLastModified() const { llvm::StringRef getRawLastModified() const {
return StringRef(ArMemHdr->LastModified, return StringRef(ArMemHdr->LastModified,
sizeof(ArMemHdr->LastModified)).rtrim(' '); sizeof(ArMemHdr->LastModified)).rtrim(' ');
} }
unsigned getUID() const; Expected<unsigned> getUID() const;
unsigned getGID() const; Expected<unsigned> getGID() const;
// This returns the size of the private struct ArMemHdrType // This returns the size of the private struct ArMemHdrType
uint64_t getSizeOf() const { uint64_t getSizeOf() const {
@ -102,15 +102,15 @@ public:
Expected<StringRef> getName() const; Expected<StringRef> getName() const;
ErrorOr<std::string> getFullName() const; ErrorOr<std::string> getFullName() const;
Expected<StringRef> getRawName() const { return Header.getRawName(); } Expected<StringRef> getRawName() const { return Header.getRawName(); }
sys::TimeValue getLastModified() const { Expected<sys::TimeValue> getLastModified() const {
return Header.getLastModified(); return Header.getLastModified();
} }
StringRef getRawLastModified() const { StringRef getRawLastModified() const {
return Header.getRawLastModified(); return Header.getRawLastModified();
} }
unsigned getUID() const { return Header.getUID(); } Expected<unsigned> getUID() const { return Header.getUID(); }
unsigned getGID() const { return Header.getGID(); } Expected<unsigned> getGID() const { return Header.getGID(); }
sys::fs::perms getAccessMode() const { Expected<sys::fs::perms> getAccessMode() const {
return Header.getAccessMode(); return Header.getAccessMode();
} }
/// \return the size of the archive member without the header or padding. /// \return the size of the archive member without the header or padding.

View File

@ -221,43 +221,81 @@ Expected<uint32_t> ArchiveMemberHeader::getSize() const {
return Ret; return Ret;
} }
sys::fs::perms ArchiveMemberHeader::getAccessMode() const { Expected<sys::fs::perms> ArchiveMemberHeader::getAccessMode() const {
unsigned Ret; unsigned Ret;
if (StringRef(ArMemHdr->AccessMode, if (StringRef(ArMemHdr->AccessMode,
sizeof(ArMemHdr->AccessMode)).rtrim(' ').getAsInteger(8, Ret)) sizeof(ArMemHdr->AccessMode)).rtrim(' ').getAsInteger(8, Ret)) {
llvm_unreachable("Access mode is not an octal number."); std::string Buf;
raw_string_ostream OS(Buf);
OS.write_escaped(llvm::StringRef(ArMemHdr->AccessMode,
sizeof(ArMemHdr->AccessMode)).rtrim(" "));
OS.flush();
uint64_t Offset = reinterpret_cast<const char *>(ArMemHdr) -
Parent->getData().data();
return malformedError("characters in AccessMode field in archive header "
"are not all decimal numbers: '" + Buf + "' for the "
"archive member header at offset " + Twine(Offset));
}
return static_cast<sys::fs::perms>(Ret); return static_cast<sys::fs::perms>(Ret);
} }
sys::TimeValue ArchiveMemberHeader::getLastModified() const { Expected<sys::TimeValue> ArchiveMemberHeader::getLastModified() const {
unsigned Seconds; unsigned Seconds;
if (StringRef(ArMemHdr->LastModified, if (StringRef(ArMemHdr->LastModified,
sizeof(ArMemHdr->LastModified)).rtrim(' ') sizeof(ArMemHdr->LastModified)).rtrim(' ')
.getAsInteger(10, Seconds)) .getAsInteger(10, Seconds)) {
llvm_unreachable("Last modified time not a decimal number."); std::string Buf;
raw_string_ostream OS(Buf);
OS.write_escaped(llvm::StringRef(ArMemHdr->LastModified,
sizeof(ArMemHdr->LastModified)).rtrim(" "));
OS.flush();
uint64_t Offset = reinterpret_cast<const char *>(ArMemHdr) -
Parent->getData().data();
return malformedError("characters in LastModified field in archive header "
"are not all decimal numbers: '" + Buf + "' for the "
"archive member header at offset " + Twine(Offset));
}
sys::TimeValue Ret; sys::TimeValue Ret;
Ret.fromEpochTime(Seconds); Ret.fromEpochTime(Seconds);
return Ret; return Ret;
} }
unsigned ArchiveMemberHeader::getUID() const { Expected<unsigned> ArchiveMemberHeader::getUID() const {
unsigned Ret; unsigned Ret;
StringRef User = StringRef(ArMemHdr->UID, sizeof(ArMemHdr->UID)).rtrim(' '); StringRef User = StringRef(ArMemHdr->UID, sizeof(ArMemHdr->UID)).rtrim(' ');
if (User.empty()) if (User.empty())
return 0; return 0;
if (User.getAsInteger(10, Ret)) if (User.getAsInteger(10, Ret)) {
llvm_unreachable("UID time not a decimal number."); std::string Buf;
raw_string_ostream OS(Buf);
OS.write_escaped(User);
OS.flush();
uint64_t Offset = reinterpret_cast<const char *>(ArMemHdr) -
Parent->getData().data();
return malformedError("characters in UID field in archive header "
"are not all decimal numbers: '" + Buf + "' for the "
"archive member header at offset " + Twine(Offset));
}
return Ret; return Ret;
} }
unsigned ArchiveMemberHeader::getGID() const { Expected<unsigned> ArchiveMemberHeader::getGID() const {
unsigned Ret; unsigned Ret;
StringRef Group = StringRef(ArMemHdr->GID, sizeof(ArMemHdr->GID)).rtrim(' '); StringRef Group = StringRef(ArMemHdr->GID, sizeof(ArMemHdr->GID)).rtrim(' ');
if (Group.empty()) if (Group.empty())
return 0; return 0;
if (Group.getAsInteger(10, Ret)) if (Group.getAsInteger(10, Ret)) {
llvm_unreachable("GID time not a decimal number."); std::string Buf;
raw_string_ostream OS(Buf);
OS.write_escaped(Group);
OS.flush();
uint64_t Offset = reinterpret_cast<const char *>(ArMemHdr) -
Parent->getData().data();
return malformedError("characters in GID field in archive header "
"are not all decimal numbers: '" + Buf + "' for the "
"archive member header at offset " + Twine(Offset));
}
return Ret; return Ret;
} }

View File

@ -47,10 +47,22 @@ NewArchiveMember::getOldMember(const object::Archive::Child &OldMember,
NewArchiveMember M; NewArchiveMember M;
M.Buf = MemoryBuffer::getMemBuffer(*BufOrErr, false); M.Buf = MemoryBuffer::getMemBuffer(*BufOrErr, false);
if (!Deterministic) { if (!Deterministic) {
M.ModTime = OldMember.getLastModified(); Expected<sys::TimeValue> ModTimeOrErr = OldMember.getLastModified();
M.UID = OldMember.getUID(); if (!ModTimeOrErr)
M.GID = OldMember.getGID(); return ModTimeOrErr.takeError();
M.Perms = OldMember.getAccessMode(); M.ModTime = ModTimeOrErr.get();
Expected<unsigned> UIDOrErr = OldMember.getUID();
if (!UIDOrErr)
return UIDOrErr.takeError();
M.UID = UIDOrErr.get();
Expected<unsigned> GIDOrErr = OldMember.getGID();
if (!GIDOrErr)
return GIDOrErr.takeError();
M.GID = GIDOrErr.get();
Expected<sys::fs::perms> AccessModeOrErr = OldMember.getAccessMode();
if (!AccessModeOrErr)
return AccessModeOrErr.takeError();
M.Perms = AccessModeOrErr.get();
} }
return std::move(M); return std::move(M);
} }

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -58,3 +58,31 @@
# RUN: 2>&1 | FileCheck -check-prefix=bogus10 %s # RUN: 2>&1 | FileCheck -check-prefix=bogus10 %s
# bogus10: libbogus10.a(???) truncated or malformed archive (long name offset 507 past the end of the string table for archive member header at offset 94) # bogus10: libbogus10.a(???) truncated or malformed archive (long name offset 507 past the end of the string table for archive member header at offset 94)
# RUN: not llvm-objdump -macho -archive-headers \
# RUN: %p/Inputs/libbogus11.a \
# RUN: 2>&1 | FileCheck -check-prefix=bogus11 %s
# bogus11: libbogus11.a(hello.c) truncated or malformed archive (characters in UID field in archive header are not all decimal numbers: '~97&' for the archive member header at offset 8)
# RUN: not llvm-objdump -macho -archive-headers \
# RUN: %p/Inputs/libbogus12.a \
# RUN: 2>&1 | FileCheck -check-prefix=bogus12 %s
# bogus12: libbogus12.a(hello.c) truncated or malformed archive (characters in GID field in archive header are not all decimal numbers: '#55!' for the archive member header at offset 8)
# RUN: not llvm-objdump -macho -archive-headers \
# RUN: %p/Inputs/libbogus13.a \
# RUN: 2>&1 | FileCheck -check-prefix=bogus13 %s
# bogus13: libbogus13.a(hello.c) truncated or malformed archive (characters in AccessMode field in archive header are not all decimal numbers: 'Feed' for the archive member header at offset 8)
# RUN: llvm-objdump -macho -archive-headers %p/Inputs/libbogus14.a \
# RUN: 2>&1 | FileCheck -check-prefix=bogus14 %s
# bogus14: -rw-r--r--124/0 102 (date: "1foobar273" contains non-decimal chars) hello.c
# RUN: not llvm-ar tv %p/Inputs/libbogus14.a \
# RUN: 2>&1 | FileCheck -check-prefix=bogus14a %s
# bogus14a: truncated or malformed archive (characters in LastModified field in archive header are not all decimal numbers: '1foobar273' for the archive member header at offset 8)

View File

@ -106,8 +106,11 @@ BinaryHolder::GetArchiveMemberBuffers(StringRef Filename,
for (auto Child : CurrentArchive->children(Err)) { for (auto Child : CurrentArchive->children(Err)) {
if (auto NameOrErr = Child.getName()) { if (auto NameOrErr = Child.getName()) {
if (*NameOrErr == Filename) { if (*NameOrErr == Filename) {
Expected<sys::TimeValue> ModTimeOrErr = Child.getLastModified();
if (!ModTimeOrErr)
return errorToErrorCode(ModTimeOrErr.takeError());
if (Timestamp != sys::TimeValue::PosixZeroTime() && if (Timestamp != sys::TimeValue::PosixZeroTime() &&
Timestamp != Child.getLastModified()) { Timestamp != ModTimeOrErr.get()) {
if (Verbose) if (Verbose)
outs() << "\tmember had timestamp mismatch.\n"; outs() << "\tmember had timestamp mismatch.\n";
continue; continue;

View File

@ -338,16 +338,24 @@ static void printMode(unsigned mode) {
// modification time are also printed. // modification time are also printed.
static void doDisplayTable(StringRef Name, const object::Archive::Child &C) { static void doDisplayTable(StringRef Name, const object::Archive::Child &C) {
if (Verbose) { if (Verbose) {
sys::fs::perms Mode = C.getAccessMode(); Expected<sys::fs::perms> ModeOrErr = C.getAccessMode();
failIfError(ModeOrErr.takeError());
sys::fs::perms Mode = ModeOrErr.get();
printMode((Mode >> 6) & 007); printMode((Mode >> 6) & 007);
printMode((Mode >> 3) & 007); printMode((Mode >> 3) & 007);
printMode(Mode & 007); printMode(Mode & 007);
outs() << ' ' << C.getUID(); Expected<unsigned> UIDOrErr = C.getUID();
outs() << '/' << C.getGID(); failIfError(UIDOrErr.takeError());
outs() << ' ' << UIDOrErr.get();
Expected<unsigned> GIDOrErr = C.getGID();
failIfError(GIDOrErr.takeError());
outs() << '/' << GIDOrErr.get();
Expected<uint64_t> Size = C.getSize(); Expected<uint64_t> Size = C.getSize();
failIfError(Size.takeError()); failIfError(Size.takeError());
outs() << ' ' << format("%6llu", Size.get()); outs() << ' ' << format("%6llu", Size.get());
outs() << ' ' << C.getLastModified().str(); Expected<sys::TimeValue> ModTimeOrErr = C.getLastModified();
failIfError(ModTimeOrErr.takeError());
outs() << ' ' << ModTimeOrErr.get().str();
outs() << ' '; outs() << ' ';
} }
outs() << Name << "\n"; outs() << Name << "\n";
@ -357,7 +365,9 @@ static void doDisplayTable(StringRef Name, const object::Archive::Child &C) {
// system. // system.
static void doExtract(StringRef Name, const object::Archive::Child &C) { static void doExtract(StringRef Name, const object::Archive::Child &C) {
// Retain the original mode. // Retain the original mode.
sys::fs::perms Mode = C.getAccessMode(); Expected<sys::fs::perms> ModeOrErr = C.getAccessMode();
failIfError(ModeOrErr.takeError());
sys::fs::perms Mode = ModeOrErr.get();
int FD; int FD;
failIfError(sys::fs::openFileForWrite(Name, FD, sys::fs::F_None, Mode), Name); failIfError(sys::fs::openFileForWrite(Name, FD, sys::fs::F_None, Mode), Name);
@ -374,9 +384,12 @@ static void doExtract(StringRef Name, const object::Archive::Child &C) {
// If we're supposed to retain the original modification times, etc. do so // If we're supposed to retain the original modification times, etc. do so
// now. // now.
if (OriginalDates) if (OriginalDates) {
Expected<sys::TimeValue> ModTimeOrErr = C.getLastModified();
failIfError(ModTimeOrErr.takeError());
failIfError( failIfError(
sys::fs::setLastModificationAndAccessTime(FD, C.getLastModified())); sys::fs::setLastModificationAndAccessTime(FD, ModTimeOrErr.get()));
}
if (close(FD)) if (close(FD))
fail("Could not close the file"); fail("Could not close the file");
@ -511,7 +524,9 @@ static InsertAction computeInsertAction(ArchiveOperation Operation,
// operation. // operation.
sys::fs::file_status Status; sys::fs::file_status Status;
failIfError(sys::fs::status(*MI, Status), *MI); failIfError(sys::fs::status(*MI, Status), *MI);
if (Status.getLastModificationTime() < Member.getLastModified()) { Expected<sys::TimeValue> ModTimeOrErr = Member.getLastModified();
failIfError(ModTimeOrErr.takeError());
if (Status.getLastModificationTime() < ModTimeOrErr.get()) {
if (PosName.empty()) if (PosName.empty())
return IA_AddOldMember; return IA_AddOldMember;
return IA_MoveOldMember; return IA_MoveOldMember;

View File

@ -1477,7 +1477,10 @@ static void printArchiveChild(StringRef Filename, const Archive::Child &C,
StringRef ArchitectureName = StringRef()) { StringRef ArchitectureName = StringRef()) {
if (print_offset) if (print_offset)
outs() << C.getChildOffset() << "\t"; outs() << C.getChildOffset() << "\t";
sys::fs::perms Mode = C.getAccessMode(); Expected<sys::fs::perms> ModeOrErr = C.getAccessMode();
if (!ModeOrErr)
report_error(Filename, C, ModeOrErr.takeError(), ArchitectureName);
sys::fs::perms Mode = ModeOrErr.get();
if (verbose) { if (verbose) {
// FIXME: this first dash, "-", is for (Mode & S_IFMT) == S_IFREG. // FIXME: this first dash, "-", is for (Mode & S_IFMT) == S_IFREG.
// But there is nothing in sys::fs::perms for S_IFMT or S_IFREG. // But there is nothing in sys::fs::perms for S_IFMT or S_IFREG.
@ -1495,9 +1498,15 @@ static void printArchiveChild(StringRef Filename, const Archive::Child &C,
outs() << format("0%o ", Mode); outs() << format("0%o ", Mode);
} }
unsigned UID = C.getUID(); Expected<unsigned> UIDOrErr = C.getUID();
if (!UIDOrErr)
report_error(Filename, C, UIDOrErr.takeError(), ArchitectureName);
unsigned UID = UIDOrErr.get();
outs() << format("%3d/", UID); outs() << format("%3d/", UID);
unsigned GID = C.getGID(); Expected<unsigned> GIDOrErr = C.getGID();
if (!GIDOrErr)
report_error(Filename, C, GIDOrErr.takeError(), ArchitectureName);
unsigned GID = GIDOrErr.get();
outs() << format("%-3d ", GID); outs() << format("%-3d ", GID);
Expected<uint64_t> Size = C.getRawSize(); Expected<uint64_t> Size = C.getRawSize();
if (!Size) if (!Size)
@ -1508,7 +1517,8 @@ static void printArchiveChild(StringRef Filename, const Archive::Child &C,
if (verbose) { if (verbose) {
unsigned Seconds; unsigned Seconds;
if (RawLastModified.getAsInteger(10, Seconds)) if (RawLastModified.getAsInteger(10, Seconds))
outs() << "(date: \"%s\" contains non-decimal chars) " << RawLastModified; outs() << "(date: \"" << RawLastModified
<< "\" contains non-decimal chars) ";
else { else {
// Since cime(3) returns a 26 character string of the form: // Since cime(3) returns a 26 character string of the form:
// "Sun Sep 16 01:03:52 1973\n\0" // "Sun Sep 16 01:03:52 1973\n\0"