1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-23 03:02:36 +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.
Expected<uint32_t> getSize() const;
sys::fs::perms getAccessMode() const;
sys::TimeValue getLastModified() const;
Expected<sys::fs::perms> getAccessMode() const;
Expected<sys::TimeValue> getLastModified() const;
llvm::StringRef getRawLastModified() const {
return StringRef(ArMemHdr->LastModified,
sizeof(ArMemHdr->LastModified)).rtrim(' ');
}
unsigned getUID() const;
unsigned getGID() const;
Expected<unsigned> getUID() const;
Expected<unsigned> getGID() const;
// This returns the size of the private struct ArMemHdrType
uint64_t getSizeOf() const {
@ -102,15 +102,15 @@ public:
Expected<StringRef> getName() const;
ErrorOr<std::string> getFullName() const;
Expected<StringRef> getRawName() const { return Header.getRawName(); }
sys::TimeValue getLastModified() const {
Expected<sys::TimeValue> getLastModified() const {
return Header.getLastModified();
}
StringRef getRawLastModified() const {
return Header.getRawLastModified();
}
unsigned getUID() const { return Header.getUID(); }
unsigned getGID() const { return Header.getGID(); }
sys::fs::perms getAccessMode() const {
Expected<unsigned> getUID() const { return Header.getUID(); }
Expected<unsigned> getGID() const { return Header.getGID(); }
Expected<sys::fs::perms> getAccessMode() const {
return Header.getAccessMode();
}
/// \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;
}
sys::fs::perms ArchiveMemberHeader::getAccessMode() const {
Expected<sys::fs::perms> ArchiveMemberHeader::getAccessMode() const {
unsigned Ret;
if (StringRef(ArMemHdr->AccessMode,
sizeof(ArMemHdr->AccessMode)).rtrim(' ').getAsInteger(8, Ret))
llvm_unreachable("Access mode is not an octal number.");
sizeof(ArMemHdr->AccessMode)).rtrim(' ').getAsInteger(8, Ret)) {
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);
}
sys::TimeValue ArchiveMemberHeader::getLastModified() const {
Expected<sys::TimeValue> ArchiveMemberHeader::getLastModified() const {
unsigned Seconds;
if (StringRef(ArMemHdr->LastModified,
sizeof(ArMemHdr->LastModified)).rtrim(' ')
.getAsInteger(10, Seconds))
llvm_unreachable("Last modified time not a decimal number.");
.getAsInteger(10, Seconds)) {
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;
Ret.fromEpochTime(Seconds);
return Ret;
}
unsigned ArchiveMemberHeader::getUID() const {
Expected<unsigned> ArchiveMemberHeader::getUID() const {
unsigned Ret;
StringRef User = StringRef(ArMemHdr->UID, sizeof(ArMemHdr->UID)).rtrim(' ');
if (User.empty())
return 0;
if (User.getAsInteger(10, Ret))
llvm_unreachable("UID time not a decimal number.");
if (User.getAsInteger(10, Ret)) {
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;
}
unsigned ArchiveMemberHeader::getGID() const {
Expected<unsigned> ArchiveMemberHeader::getGID() const {
unsigned Ret;
StringRef Group = StringRef(ArMemHdr->GID, sizeof(ArMemHdr->GID)).rtrim(' ');
if (Group.empty())
return 0;
if (Group.getAsInteger(10, Ret))
llvm_unreachable("GID time not a decimal number.");
if (Group.getAsInteger(10, Ret)) {
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;
}

View File

@ -47,10 +47,22 @@ NewArchiveMember::getOldMember(const object::Archive::Child &OldMember,
NewArchiveMember M;
M.Buf = MemoryBuffer::getMemBuffer(*BufOrErr, false);
if (!Deterministic) {
M.ModTime = OldMember.getLastModified();
M.UID = OldMember.getUID();
M.GID = OldMember.getGID();
M.Perms = OldMember.getAccessMode();
Expected<sys::TimeValue> ModTimeOrErr = OldMember.getLastModified();
if (!ModTimeOrErr)
return ModTimeOrErr.takeError();
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);
}

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
# 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)) {
if (auto NameOrErr = Child.getName()) {
if (*NameOrErr == Filename) {
Expected<sys::TimeValue> ModTimeOrErr = Child.getLastModified();
if (!ModTimeOrErr)
return errorToErrorCode(ModTimeOrErr.takeError());
if (Timestamp != sys::TimeValue::PosixZeroTime() &&
Timestamp != Child.getLastModified()) {
Timestamp != ModTimeOrErr.get()) {
if (Verbose)
outs() << "\tmember had timestamp mismatch.\n";
continue;

View File

@ -338,16 +338,24 @@ static void printMode(unsigned mode) {
// modification time are also printed.
static void doDisplayTable(StringRef Name, const object::Archive::Child &C) {
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 >> 3) & 007);
printMode(Mode & 007);
outs() << ' ' << C.getUID();
outs() << '/' << C.getGID();
Expected<unsigned> UIDOrErr = C.getUID();
failIfError(UIDOrErr.takeError());
outs() << ' ' << UIDOrErr.get();
Expected<unsigned> GIDOrErr = C.getGID();
failIfError(GIDOrErr.takeError());
outs() << '/' << GIDOrErr.get();
Expected<uint64_t> Size = C.getSize();
failIfError(Size.takeError());
outs() << ' ' << format("%6llu", Size.get());
outs() << ' ' << C.getLastModified().str();
Expected<sys::TimeValue> ModTimeOrErr = C.getLastModified();
failIfError(ModTimeOrErr.takeError());
outs() << ' ' << ModTimeOrErr.get().str();
outs() << ' ';
}
outs() << Name << "\n";
@ -357,7 +365,9 @@ static void doDisplayTable(StringRef Name, const object::Archive::Child &C) {
// system.
static void doExtract(StringRef Name, const object::Archive::Child &C) {
// 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;
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
// now.
if (OriginalDates)
if (OriginalDates) {
Expected<sys::TimeValue> ModTimeOrErr = C.getLastModified();
failIfError(ModTimeOrErr.takeError());
failIfError(
sys::fs::setLastModificationAndAccessTime(FD, C.getLastModified()));
sys::fs::setLastModificationAndAccessTime(FD, ModTimeOrErr.get()));
}
if (close(FD))
fail("Could not close the file");
@ -511,7 +524,9 @@ static InsertAction computeInsertAction(ArchiveOperation Operation,
// operation.
sys::fs::file_status Status;
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())
return IA_AddOldMember;
return IA_MoveOldMember;

View File

@ -1477,7 +1477,10 @@ static void printArchiveChild(StringRef Filename, const Archive::Child &C,
StringRef ArchitectureName = StringRef()) {
if (print_offset)
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) {
// 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.
@ -1495,9 +1498,15 @@ static void printArchiveChild(StringRef Filename, const Archive::Child &C,
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);
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);
Expected<uint64_t> Size = C.getRawSize();
if (!Size)
@ -1508,7 +1517,8 @@ static void printArchiveChild(StringRef Filename, const Archive::Child &C,
if (verbose) {
unsigned Seconds;
if (RawLastModified.getAsInteger(10, Seconds))
outs() << "(date: \"%s\" contains non-decimal chars) " << RawLastModified;
outs() << "(date: \"" << RawLastModified
<< "\" contains non-decimal chars) ";
else {
// Since cime(3) returns a 26 character string of the form:
// "Sun Sep 16 01:03:52 1973\n\0"