diff options
author | Kevin Enderby <enderby@apple.com> | 2016-06-27 21:39:39 +0000 |
---|---|---|
committer | Kevin Enderby <enderby@apple.com> | 2016-06-27 21:39:39 +0000 |
commit | 1051909df1a2dfc9e3b4b27d15b36b3019c21463 (patch) | |
tree | b7493e3ee6c0a1804ef7066f625fc0e99d20c416 | |
parent | f9e348bd59c441be9417507f9752c66716d2ab41 (diff) | |
download | bcm5719-llvm-1051909df1a2dfc9e3b4b27d15b36b3019c21463.tar.gz bcm5719-llvm-1051909df1a2dfc9e3b4b27d15b36b3019c21463.zip |
Change all but the last ErrorOr<...> use for MachOUniversalBinary to Expected<...> to
allow a good error message to be produced.
I added the one test case that the object file tools could produce an error
message. The other two errors can’t be triggered if the input file is passed
through sys::fs::identify_magic(). But the malformedError("bad magic number")
does get triggered by the logic in llvm-dsymutil when dealing with a normal
Mach-O file. The other "File too small ..." error would take a logic error
currently to produce and is not tested for.
llvm-svn: 273946
-rw-r--r-- | llvm/include/llvm/Object/MachOUniversal.h | 4 | ||||
-rw-r--r-- | llvm/lib/Object/Binary.cpp | 2 | ||||
-rw-r--r-- | llvm/lib/Object/MachOUniversal.cpp | 33 | ||||
-rw-r--r-- | llvm/test/Object/Inputs/macho-invalid-fat | bin | 0 -> 8 bytes | |||
-rw-r--r-- | llvm/test/Object/macho-invalid.test | 3 | ||||
-rw-r--r-- | llvm/tools/dsymutil/BinaryHolder.cpp | 6 |
6 files changed, 32 insertions, 16 deletions
diff --git a/llvm/include/llvm/Object/MachOUniversal.h b/llvm/include/llvm/Object/MachOUniversal.h index d384b5ff60b..f4c2eacf181 100644 --- a/llvm/include/llvm/Object/MachOUniversal.h +++ b/llvm/include/llvm/Object/MachOUniversal.h @@ -128,8 +128,8 @@ public: } }; - MachOUniversalBinary(MemoryBufferRef Souce, std::error_code &EC); - static ErrorOr<std::unique_ptr<MachOUniversalBinary>> + MachOUniversalBinary(MemoryBufferRef Souce, Error &Err); + static Expected<std::unique_ptr<MachOUniversalBinary>> create(MemoryBufferRef Source); object_iterator begin_objects() const { diff --git a/llvm/lib/Object/Binary.cpp b/llvm/lib/Object/Binary.cpp index 723b279d9e6..8d03a2a976b 100644 --- a/llvm/lib/Object/Binary.cpp +++ b/llvm/lib/Object/Binary.cpp @@ -65,7 +65,7 @@ Expected<std::unique_ptr<Binary>> object::createBinary(MemoryBufferRef Buffer, case sys::fs::file_magic::bitcode: return ObjectFile::createSymbolicFile(Buffer, Type, Context); case sys::fs::file_magic::macho_universal_binary: - return errorOrToExpected(MachOUniversalBinary::create(Buffer)); + return MachOUniversalBinary::create(Buffer); case sys::fs::file_magic::unknown: case sys::fs::file_magic::windows_resource: // Unrecognized object file format. diff --git a/llvm/lib/Object/MachOUniversal.cpp b/llvm/lib/Object/MachOUniversal.cpp index b3b0c251c10..e6880587cde 100644 --- a/llvm/lib/Object/MachOUniversal.cpp +++ b/llvm/lib/Object/MachOUniversal.cpp @@ -22,6 +22,13 @@ using namespace llvm; using namespace object; +static Error +malformedError(Twine Msg) { + std::string StringMsg = "truncated or malformed fat file (" + Msg.str() + ")"; + return make_error<GenericBinaryError>(std::move(StringMsg), + object_error::parse_failed); +} + template<typename T> static T getUniversalBinaryStruct(const char *Ptr) { T Res; @@ -92,22 +99,24 @@ MachOUniversalBinary::ObjectForArch::getAsArchive() const { void MachOUniversalBinary::anchor() { } -ErrorOr<std::unique_ptr<MachOUniversalBinary>> +Expected<std::unique_ptr<MachOUniversalBinary>> MachOUniversalBinary::create(MemoryBufferRef Source) { - std::error_code EC; + Error Err; std::unique_ptr<MachOUniversalBinary> Ret( - new MachOUniversalBinary(Source, EC)); - if (EC) - return EC; + new MachOUniversalBinary(Source, Err)); + if (Err) + return std::move(Err); return std::move(Ret); } -MachOUniversalBinary::MachOUniversalBinary(MemoryBufferRef Source, - std::error_code &ec) +MachOUniversalBinary::MachOUniversalBinary(MemoryBufferRef Source, Error &Err) : Binary(Binary::ID_MachOUniversalBinary, Source), Magic(0), NumberOfObjects(0) { + ErrorAsOutParameter ErrAsOutParam(Err); if (Data.getBufferSize() < sizeof(MachO::fat_header)) { - ec = object_error::invalid_file_type; + Err = make_error<GenericBinaryError>("File too small to be a Mach-O " + "universal file", + object_error::invalid_file_type); return; } // Check for magic value and sufficient header size. @@ -121,14 +130,16 @@ MachOUniversalBinary::MachOUniversalBinary(MemoryBufferRef Source, else if (Magic == MachO::FAT_MAGIC_64) MinSize += sizeof(MachO::fat_arch_64) * NumberOfObjects; else { - ec = object_error::parse_failed; + Err = malformedError("bad magic number"); return; } if (Buf.size() < MinSize) { - ec = object_error::parse_failed; + Err = malformedError("fat_arch" + + Twine(Magic == MachO::FAT_MAGIC ? "" : "_64") + + " structs would extend past the end of the file"); return; } - ec = std::error_code(); + Err = Error::success(); } Expected<std::unique_ptr<MachOObjectFile>> diff --git a/llvm/test/Object/Inputs/macho-invalid-fat b/llvm/test/Object/Inputs/macho-invalid-fat Binary files differnew file mode 100644 index 00000000000..1fa01903c53 --- /dev/null +++ b/llvm/test/Object/Inputs/macho-invalid-fat diff --git a/llvm/test/Object/macho-invalid.test b/llvm/test/Object/macho-invalid.test index 3fe6296645b..4c66f5c402e 100644 --- a/llvm/test/Object/macho-invalid.test +++ b/llvm/test/Object/macho-invalid.test @@ -94,3 +94,6 @@ INCOMPLETE-SEGMENT-LOADC-FAT: macho-universal-bad2.x86_64.i386 (for architecture RUN: not llvm-objdump -macho -private-headers -arch all %p/Inputs/macho-universal-archive-bad2.x86_64.i386 2>&1 | FileCheck -check-prefix INCOMPLETE-SEGMENT-LOADC-FAT-ARCHIVE %s INCOMPLETE-SEGMENT-LOADC-FAT-ARCHIVE: macho-universal-archive-bad2.x86_64.i386(macho64-invalid-incomplete-segment-load-command) (for architecture x86_64) truncated or malformed object (load commands extend past the end of the file) + +RUN: not llvm-objdump -macho -universal-headers %p/Inputs/macho-invalid-fat 2>&1 | FileCheck -check-prefix INVALID-FAT %s +INVALID-FAT: truncated or malformed fat file (fat_arch_64 structs would extend past the end of the file) diff --git a/llvm/tools/dsymutil/BinaryHolder.cpp b/llvm/tools/dsymutil/BinaryHolder.cpp index 32d176645bf..8f33657dd55 100644 --- a/llvm/tools/dsymutil/BinaryHolder.cpp +++ b/llvm/tools/dsymutil/BinaryHolder.cpp @@ -73,7 +73,8 @@ BinaryHolder::GetMemoryBuffersForFile(StringRef Filename, auto ErrOrFat = object::MachOUniversalBinary::create( CurrentMemoryBuffer->getMemBufferRef()); - if (ErrOrFat.getError()) { + if (!ErrOrFat) { + consumeError(ErrOrFat.takeError()); // Not a fat binary must be a standard one. Return a one element vector. return std::vector<MemoryBufferRef>{CurrentMemoryBuffer->getMemBufferRef()}; } @@ -145,7 +146,8 @@ BinaryHolder::MapArchiveAndGetMemberBuffers(StringRef Filename, std::vector<MemoryBufferRef> ArchiveBuffers; auto ErrOrFat = object::MachOUniversalBinary::create( CurrentMemoryBuffer->getMemBufferRef()); - if (ErrOrFat.getError()) { + if (!ErrOrFat) { + consumeError(ErrOrFat.takeError()); // Not a fat binary must be a standard one. ArchiveBuffers.push_back(CurrentMemoryBuffer->getMemBufferRef()); } else { |