summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Object
diff options
context:
space:
mode:
authorKevin Enderby <enderby@apple.com>2016-08-02 22:58:55 +0000
committerKevin Enderby <enderby@apple.com>2016-08-02 22:58:55 +0000
commit395cc09444b114bfb0f860bcd5c3d0365e7ca18c (patch)
tree4226a5b54049be8f2c34517cc70b6c84bb52535c /llvm/lib/Object
parentee0627fd1b9f89d6320b186f038bf14fbf6e8468 (diff)
downloadbcm5719-llvm-395cc09444b114bfb0f860bcd5c3d0365e7ca18c.tar.gz
bcm5719-llvm-395cc09444b114bfb0f860bcd5c3d0365e7ca18c.zip
More fixes to get good error messages for bad archives.
Fixed the last incorrect uses of llvm_unreachable() in the code which were actually just cases of errors in the input Archives. llvm-svn: 277540
Diffstat (limited to 'llvm/lib/Object')
-rw-r--r--llvm/lib/Object/Archive.cpp62
-rw-r--r--llvm/lib/Object/ArchiveWriter.cpp20
2 files changed, 66 insertions, 16 deletions
diff --git a/llvm/lib/Object/Archive.cpp b/llvm/lib/Object/Archive.cpp
index 586f9c1da81..827affebf43 100644
--- a/llvm/lib/Object/Archive.cpp
+++ b/llvm/lib/Object/Archive.cpp
@@ -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;
}
diff --git a/llvm/lib/Object/ArchiveWriter.cpp b/llvm/lib/Object/ArchiveWriter.cpp
index 922d1b78667..4ede536169e 100644
--- a/llvm/lib/Object/ArchiveWriter.cpp
+++ b/llvm/lib/Object/ArchiveWriter.cpp
@@ -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);
}
OpenPOWER on IntegriCloud