[llvm] r273946 - Change all but the last ErrorOr<...> use for MachOUniversalBinary to Expected<...> to

Kevin Enderby via llvm-commits llvm-commits at lists.llvm.org
Mon Jun 27 14:39:40 PDT 2016


Author: enderby
Date: Mon Jun 27 16:39:39 2016
New Revision: 273946

URL: http://llvm.org/viewvc/llvm-project?rev=273946&view=rev
Log:
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.

Added:
    llvm/trunk/test/Object/Inputs/macho-invalid-fat   (with props)
Modified:
    llvm/trunk/include/llvm/Object/MachOUniversal.h
    llvm/trunk/lib/Object/Binary.cpp
    llvm/trunk/lib/Object/MachOUniversal.cpp
    llvm/trunk/test/Object/macho-invalid.test
    llvm/trunk/tools/dsymutil/BinaryHolder.cpp

Modified: llvm/trunk/include/llvm/Object/MachOUniversal.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Object/MachOUniversal.h?rev=273946&r1=273945&r2=273946&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Object/MachOUniversal.h (original)
+++ llvm/trunk/include/llvm/Object/MachOUniversal.h Mon Jun 27 16:39:39 2016
@@ -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 {

Modified: llvm/trunk/lib/Object/Binary.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Object/Binary.cpp?rev=273946&r1=273945&r2=273946&view=diff
==============================================================================
--- llvm/trunk/lib/Object/Binary.cpp (original)
+++ llvm/trunk/lib/Object/Binary.cpp Mon Jun 27 16:39:39 2016
@@ -65,7 +65,7 @@ Expected<std::unique_ptr<Binary>> object
     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.

Modified: llvm/trunk/lib/Object/MachOUniversal.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Object/MachOUniversal.cpp?rev=273946&r1=273945&r2=273946&view=diff
==============================================================================
--- llvm/trunk/lib/Object/MachOUniversal.cpp (original)
+++ llvm/trunk/lib/Object/MachOUniversal.cpp Mon Jun 27 16:39:39 2016
@@ -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::get
 
 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::MachOUniversalBina
   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>>

Added: llvm/trunk/test/Object/Inputs/macho-invalid-fat
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Object/Inputs/macho-invalid-fat?rev=273946&view=auto
==============================================================================
Binary file - no diff available.

Propchange: llvm/trunk/test/Object/Inputs/macho-invalid-fat
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Modified: llvm/trunk/test/Object/macho-invalid.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Object/macho-invalid.test?rev=273946&r1=273945&r2=273946&view=diff
==============================================================================
--- llvm/trunk/test/Object/macho-invalid.test (original)
+++ llvm/trunk/test/Object/macho-invalid.test Mon Jun 27 16:39:39 2016
@@ -94,3 +94,6 @@ INCOMPLETE-SEGMENT-LOADC-FAT: macho-univ
 
 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)

Modified: llvm/trunk/tools/dsymutil/BinaryHolder.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/dsymutil/BinaryHolder.cpp?rev=273946&r1=273945&r2=273946&view=diff
==============================================================================
--- llvm/trunk/tools/dsymutil/BinaryHolder.cpp (original)
+++ llvm/trunk/tools/dsymutil/BinaryHolder.cpp Mon Jun 27 16:39:39 2016
@@ -73,7 +73,8 @@ BinaryHolder::GetMemoryBuffersForFile(St
 
   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::MapArchiveAndGetMemberBuff
   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 {




More information about the llvm-commits mailing list