[llvm] r298292 - Add the rest of the error checking for Mach-O dyld compact bind entry errors

Kevin Enderby via llvm-commits llvm-commits at lists.llvm.org
Mon Mar 20 12:46:56 PDT 2017


Author: enderby
Date: Mon Mar 20 14:46:55 2017
New Revision: 298292

URL: http://llvm.org/viewvc/llvm-project?rev=298292&view=rev
Log:
Add the rest of the error checking for Mach-O dyld compact bind entry errors
and test cases for each of the error checks.

To do this more plumbing was needed so that the segment indexes and
segment offsets can be checked.  Basically what was done was the SegInfo
from llvm-objdump’s MachODump.cpp was moved into libObject for Mach-O
objects as BindRebaseSegInfo and it is only created when an iterator for
bind or rebase entries are created.

This commit really only adds the error checking and test cases for the
bind table entires and the checking for the lazy bind and weak bind entries
are still to be fully done as well as the rebase entires.  Though some of
the plumbing for those are added with this commit.  Those other error
checks and test cases will be added in follow on commits.

Note, the two llvm_unreachable() calls should now actually be unreachable
with the error checks in place and would take a logic bug in the error
checking code to be reached if the segment indexes and segment
offsets are used from a checked bind entry.  Comments have been added
to the methods that require the arguments to have been checked
prior to calling.

Added:
    llvm/trunk/test/tools/llvm-objdump/Inputs/macho-bind-add-addr-imm-scaled   (with props)
    llvm/trunk/test/tools/llvm-objdump/Inputs/macho-bind-add_addr_uleb   (with props)
    llvm/trunk/test/tools/llvm-objdump/Inputs/macho-bind-bad-opcode-value   (with props)
    llvm/trunk/test/tools/llvm-objdump/Inputs/macho-bind-bind-add-addr-uleb   (with props)
    llvm/trunk/test/tools/llvm-objdump/Inputs/macho-bind-do-bind-no-segIndex   (with props)
    llvm/trunk/test/tools/llvm-objdump/Inputs/macho-bind-dylib-ordinal-uleb   (with props)
    llvm/trunk/test/tools/llvm-objdump/Inputs/macho-bind-dylib-ordinal-uleb-malformed-uleb128   (with props)
    llvm/trunk/test/tools/llvm-objdump/Inputs/macho-bind-dylib-ordinal-uleb-too-big   (with props)
    llvm/trunk/test/tools/llvm-objdump/Inputs/macho-bind-dylib-special-imm   (with props)
    llvm/trunk/test/tools/llvm-objdump/Inputs/macho-bind-seg-too-big   (with props)
    llvm/trunk/test/tools/llvm-objdump/Inputs/macho-bind-segoff-too-big   (with props)
    llvm/trunk/test/tools/llvm-objdump/Inputs/macho-bind-set-addend-sleb   (with props)
    llvm/trunk/test/tools/llvm-objdump/Inputs/macho-bind-set-symbol   (with props)
    llvm/trunk/test/tools/llvm-objdump/Inputs/macho-bind-set-type-imm   (with props)
    llvm/trunk/test/tools/llvm-objdump/Inputs/macho-bind-uleb-times-skipping-uleb   (with props)
    llvm/trunk/test/tools/llvm-objdump/Inputs/macho-do-bind-no-dylib-ordinal   (with props)
    llvm/trunk/test/tools/llvm-objdump/Inputs/macho-do-bind-no-symbol   (with props)
    llvm/trunk/test/tools/llvm-objdump/macho-bad-bind.test
Modified:
    llvm/trunk/include/llvm/Object/MachO.h
    llvm/trunk/include/llvm/Support/LEB128.h
    llvm/trunk/lib/Object/MachOObjectFile.cpp
    llvm/trunk/test/tools/llvm-objdump/X86/malformed-machos.test
    llvm/trunk/tools/llvm-objdump/MachODump.cpp
    llvm/trunk/tools/llvm-objdump/llvm-objdump.cpp
    llvm/trunk/tools/llvm-objdump/llvm-objdump.h

Modified: llvm/trunk/include/llvm/Object/MachO.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Object/MachO.h?rev=298292&r1=298291&r2=298292&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Object/MachO.h (original)
+++ llvm/trunk/include/llvm/Object/MachO.h Mon Mar 20 14:46:55 2017
@@ -100,18 +100,58 @@ private:
 };
 typedef content_iterator<ExportEntry> export_iterator;
 
+// Segment info so SegIndex/SegOffset pairs in a Mach-O Bind or Rebase entry
+// can be checked and translated.  Only the SegIndex/SegOffset pairs from
+// checked entries are to be used with the segmentName(), sectionName() and
+// address() methods below.
+class BindRebaseSegInfo {
+public:
+  BindRebaseSegInfo(const object::MachOObjectFile *Obj);
+
+  // Used to check a Mach-O Bind or Rebase entry for errors when iterating.
+  const char *checkSegAndOffset(int32_t SegIndex, uint64_t SegOffset,
+                                bool endInvalid);
+  const char *checkCountAndSkip(uint32_t Count, uint32_t Skip,
+                                uint8_t PointerSize, int32_t SegIndex,
+                                uint64_t SegOffset);
+  // Used with valid SegIndex/SegOffset values from checked entries.
+  StringRef segmentName(int32_t SegIndex);
+  StringRef sectionName(int32_t SegIndex, uint64_t SegOffset);
+  uint64_t address(uint32_t SegIndex, uint64_t SegOffset);
+
+private:
+  struct SectionInfo {
+    uint64_t Address;
+    uint64_t Size;
+    StringRef SectionName;
+    StringRef SegmentName;
+    uint64_t OffsetInSegment;
+    uint64_t SegmentStartAddress;
+    int32_t SegmentIndex;
+  };
+  const SectionInfo &findSection(int32_t SegIndex, uint64_t SegOffset);
+  SmallVector<SectionInfo, 32> Sections;
+  int32_t MaxSegIndex;
+};
+
 /// MachORebaseEntry encapsulates the current state in the decompression of
 /// rebasing opcodes. This allows you to iterate through the compressed table of
 /// rebasing using:
-///    for (const llvm::object::MachORebaseEntry &Entry : Obj->rebaseTable()) {
+///    Error Err;
+///    for (const llvm::object::MachORebaseEntry &Entry : Obj->rebaseTable(&Err)) {
 ///    }
+///    if (Err) { report error ...
 class MachORebaseEntry {
 public:
-  MachORebaseEntry(ArrayRef<uint8_t> opcodes, bool is64Bit);
+  MachORebaseEntry(Error *Err, const MachOObjectFile *O,
+                   ArrayRef<uint8_t> opcodes, bool is64Bit);
 
   uint32_t segmentIndex() const;
   uint64_t segmentOffset() const;
   StringRef typeName() const;
+  StringRef segmentName() const;
+  StringRef sectionName() const;
+  uint64_t address() const;
 
   bool operator==(const MachORebaseEntry &) const;
 
@@ -123,6 +163,8 @@ private:
   void moveToEnd();
   uint64_t readULEB128();
 
+  Error *E;
+  const MachOObjectFile *O;
   ArrayRef<uint8_t> Opcodes;
   const uint8_t *Ptr;
   uint64_t SegmentOffset;
@@ -150,7 +192,7 @@ public:
   MachOBindEntry(Error *Err, const MachOObjectFile *O,
                  ArrayRef<uint8_t> Opcodes, bool is64Bit, MachOBindEntry::Kind);
 
-  uint32_t segmentIndex() const;
+  int32_t segmentIndex() const;
   uint64_t segmentOffset() const;
   StringRef typeName() const;
   StringRef symbolName() const;
@@ -158,6 +200,10 @@ public:
   int64_t addend() const;
   int ordinal() const;
 
+  StringRef segmentName() const;
+  StringRef sectionName() const;
+  uint64_t address() const;
+
   bool operator==(const MachOBindEntry &) const;
 
   void moveNext();
@@ -166,16 +212,17 @@ private:
   friend class MachOObjectFile;
   void moveToFirst();
   void moveToEnd();
-  uint64_t readULEB128();
-  int64_t readSLEB128();
+  uint64_t readULEB128(const char **error);
+  int64_t readSLEB128(const char **error);
 
   Error *E;
   const MachOObjectFile *O;
   ArrayRef<uint8_t> Opcodes;
   const uint8_t *Ptr;
   uint64_t SegmentOffset;
-  uint32_t SegmentIndex;
+  int32_t  SegmentIndex;
   StringRef SymbolName;
+  bool     LibraryOrdinalSet;
   int      Ordinal;
   uint32_t Flags;
   int64_t  Addend;
@@ -291,28 +338,63 @@ public:
   static iterator_range<export_iterator> exports(ArrayRef<uint8_t> Trie);
 
   /// For use iterating over all rebase table entries.
-  iterator_range<rebase_iterator> rebaseTable() const;
+  iterator_range<rebase_iterator> rebaseTable(Error &Err);
 
-  /// For use examining rebase opcodes not in a MachOObjectFile.
-  static iterator_range<rebase_iterator> rebaseTable(ArrayRef<uint8_t> Opcodes,
+  /// For use examining rebase opcodes in a MachOObjectFile.
+  static iterator_range<rebase_iterator> rebaseTable(Error &Err,
+                                                     MachOObjectFile *O,
+                                                     ArrayRef<uint8_t> Opcodes,
                                                      bool is64);
 
   /// For use iterating over all bind table entries.
-  iterator_range<bind_iterator> bindTable(Error &Err) const;
+  iterator_range<bind_iterator> bindTable(Error &Err);
 
   /// For use iterating over all lazy bind table entries.
-  iterator_range<bind_iterator> lazyBindTable(Error &Err) const;
+  iterator_range<bind_iterator> lazyBindTable(Error &Err);
 
   /// For use iterating over all weak bind table entries.
-  iterator_range<bind_iterator> weakBindTable(Error &Err) const;
+  iterator_range<bind_iterator> weakBindTable(Error &Err);
 
-  /// For use examining bind opcodes not in a MachOObjectFile.
+  /// For use examining bind opcodes in a MachOObjectFile.
   static iterator_range<bind_iterator> bindTable(Error &Err,
-                                                 const MachOObjectFile *O,
+                                                 MachOObjectFile *O,
                                                  ArrayRef<uint8_t> Opcodes,
                                                  bool is64,
                                                  MachOBindEntry::Kind);
 
+  /// For use with a SegIndex,SegOffset pair in MachOBindEntry::moveNext() to
+  /// validate a MachOBindEntry.
+  const char *BindEntryCheckSegAndOffset(int32_t SegIndex, uint64_t SegOffset,
+                                         bool endInvalid) const {
+    return BindRebaseSectionTable->checkSegAndOffset(SegIndex, SegOffset,
+                                                     endInvalid);
+  }
+  /// For use in MachOBindEntry::moveNext() to validate a MachOBindEntry for
+  /// the BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB opcode.
+  const char *BindEntryCheckCountAndSkip(uint32_t Count, uint32_t Skip,
+                                         uint8_t PointerSize, int32_t SegIndex,
+                                         uint64_t SegOffset) const {
+    return BindRebaseSectionTable->checkCountAndSkip(Count, Skip, PointerSize,
+                                                     SegIndex, SegOffset);
+  }
+
+  /// For use with the SegIndex of a checked Mach-O Bind or Rebase entry to
+  /// get the segment name.
+  StringRef BindRebaseSegmentName(int32_t SegIndex) const {
+    return BindRebaseSectionTable->segmentName(SegIndex);
+  }
+
+  /// For use with a SegIndex,SegOffset pair from a checked Mach-O Bind or
+  /// Rebase entry to get the section name.
+  StringRef BindRebaseSectionName(uint32_t SegIndex, uint64_t SegOffset) const {
+    return BindRebaseSectionTable->sectionName(SegIndex, SegOffset);
+  }
+
+  /// For use with a SegIndex,SegOffset pair from a checked Mach-O Bind or
+  /// Rebase entry to get the address.
+  uint64_t BindRebaseAddress(uint32_t SegIndex, uint64_t SegOffset) const {
+    return BindRebaseSectionTable->address(SegIndex, SegOffset);
+  }
 
   // In a MachO file, sections have a segment name. This is used in the .o
   // files. They have a single segment, but this field specifies which segment
@@ -519,6 +601,7 @@ private:
   using BuildToolList = SmallVector<const char*, 1>;
   BuildToolList BuildTools;
   mutable LibraryShortName LibrariesShortNames;
+  std::unique_ptr<BindRebaseSegInfo> BindRebaseSectionTable;
   const char *SymtabLoadCmd;
   const char *DysymtabLoadCmd;
   const char *DataInCodeLoadCmd;

Modified: llvm/trunk/include/llvm/Support/LEB128.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/LEB128.h?rev=298292&r1=298291&r2=298292&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Support/LEB128.h (original)
+++ llvm/trunk/include/llvm/Support/LEB128.h Mon Mar 20 14:46:55 2017
@@ -113,11 +113,30 @@ inline unsigned encodeULEB128(uint64_t V
 
 
 /// Utility function to decode a ULEB128 value.
-inline uint64_t decodeULEB128(const uint8_t *p, unsigned *n = nullptr) {
+inline uint64_t decodeULEB128(const uint8_t *p, unsigned *n = nullptr,
+                              const uint8_t *end = nullptr,
+                              const char **error = nullptr) {
   const uint8_t *orig_p = p;
   uint64_t Value = 0;
   unsigned Shift = 0;
+  if(error)
+    *error = nullptr;
   do {
+    if(end && p == end){
+      if(error)
+        *error = "malformed uleb128, extends past end";
+      if (n)
+        *n = (unsigned)(p - orig_p);
+      return 0;
+    }
+    uint64_t Slice = *p & 0x7f;
+    if(Shift >= 64 || Slice << Shift >> Shift != Slice){
+      if(error)
+        *error = "uleb128 too big for uint64";
+      if (n)
+        *n = (unsigned)(p - orig_p);
+      return 0;
+    }
     Value += uint64_t(*p & 0x7f) << Shift;
     Shift += 7;
   } while (*p++ >= 128);
@@ -127,12 +146,21 @@ inline uint64_t decodeULEB128(const uint
 }
 
 /// Utility function to decode a SLEB128 value.
-inline int64_t decodeSLEB128(const uint8_t *p, unsigned *n = nullptr) {
+inline int64_t decodeSLEB128(const uint8_t *p, unsigned *n = nullptr,
+                             const uint8_t *end = nullptr,
+                             const char **error = nullptr) {
   const uint8_t *orig_p = p;
   int64_t Value = 0;
   unsigned Shift = 0;
   uint8_t Byte;
   do {
+    if(end && p == end){
+      if(error)
+        *error = "malformed sleb128, extends past end";
+      if (n)
+        *n = (unsigned)(p - orig_p);
+      return 0;
+    }
     Byte = *p++;
     Value |= ((Byte & 0x7f) << Shift);
     Shift += 7;

Modified: llvm/trunk/lib/Object/MachOObjectFile.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Object/MachOObjectFile.cpp?rev=298292&r1=298291&r2=298292&view=diff
==============================================================================
--- llvm/trunk/lib/Object/MachOObjectFile.cpp (original)
+++ llvm/trunk/lib/Object/MachOObjectFile.cpp Mon Mar 20 14:46:55 2017
@@ -2755,9 +2755,10 @@ iterator_range<export_iterator> MachOObj
   return exports(getDyldInfoExportsTrie());
 }
 
-MachORebaseEntry::MachORebaseEntry(ArrayRef<uint8_t> Bytes, bool is64Bit)
-    : Opcodes(Bytes), Ptr(Bytes.begin()), SegmentOffset(0), SegmentIndex(0),
-      RemainingLoopCount(0), AdvanceAmount(0), RebaseType(0),
+MachORebaseEntry::MachORebaseEntry(Error *E, const MachOObjectFile *O,
+                                   ArrayRef<uint8_t> Bytes, bool is64Bit)
+    : E(E), O(O), Opcodes(Bytes), Ptr(Bytes.begin()), SegmentOffset(0),
+      SegmentIndex(0), RemainingLoopCount(0), AdvanceAmount(0), RebaseType(0),
       PointerSize(is64Bit ? 8 : 4), Malformed(false), Done(false) {}
 
 void MachORebaseEntry::moveToFirst() {
@@ -2903,6 +2904,24 @@ StringRef MachORebaseEntry::typeName() c
   return "unknown";
 }
 
+// For use with the SegIndex of a checked Mach-O Rebase entry
+// to get the segment name.
+StringRef MachORebaseEntry::segmentName() const {
+  return O->BindRebaseSegmentName(SegmentIndex);
+}
+
+// For use with a SegIndex,SegOffset pair from a checked Mach-O Rebase entry
+// to get the section name.
+StringRef MachORebaseEntry::sectionName() const {
+  return O->BindRebaseSectionName(SegmentIndex, SegmentOffset);
+}
+
+// For use with a SegIndex,SegOffset pair from a checked Mach-O Rebase entry
+// to get the address.
+uint64_t MachORebaseEntry::address() const {
+  return O->BindRebaseAddress(SegmentIndex, SegmentOffset);
+}
+
 bool MachORebaseEntry::operator==(const MachORebaseEntry &Other) const {
 #ifdef EXPENSIVE_CHECKS
   assert(Opcodes == Other.Opcodes && "compare iterators of different files");
@@ -2915,26 +2934,30 @@ bool MachORebaseEntry::operator==(const
 }
 
 iterator_range<rebase_iterator>
-MachOObjectFile::rebaseTable(ArrayRef<uint8_t> Opcodes, bool is64) {
-  MachORebaseEntry Start(Opcodes, is64);
+MachOObjectFile::rebaseTable(Error &Err, MachOObjectFile *O,
+                             ArrayRef<uint8_t> Opcodes, bool is64) {
+  if (O->BindRebaseSectionTable == nullptr)
+    O->BindRebaseSectionTable = llvm::make_unique<BindRebaseSegInfo>(O);
+  MachORebaseEntry Start(&Err, O, Opcodes, is64);
   Start.moveToFirst();
 
-  MachORebaseEntry Finish(Opcodes, is64);
+  MachORebaseEntry Finish(&Err, O, Opcodes, is64);
   Finish.moveToEnd();
 
   return make_range(rebase_iterator(Start), rebase_iterator(Finish));
 }
 
-iterator_range<rebase_iterator> MachOObjectFile::rebaseTable() const {
-  return rebaseTable(getDyldInfoRebaseOpcodes(), is64Bit());
+iterator_range<rebase_iterator> MachOObjectFile::rebaseTable(Error &Err) {
+  return rebaseTable(Err, this, getDyldInfoRebaseOpcodes(), is64Bit());
 }
 
 MachOBindEntry::MachOBindEntry(Error *E, const MachOObjectFile *O,
                                ArrayRef<uint8_t> Bytes, bool is64Bit, Kind BK)
-    : E(E), O(O), Opcodes(Bytes), Ptr(Bytes.begin()), SegmentOffset(0), SegmentIndex(0),
-      Ordinal(0), Flags(0), Addend(0), RemainingLoopCount(0), AdvanceAmount(0),
-      BindType(0), PointerSize(is64Bit ? 8 : 4),
-      TableKind(BK), Malformed(false), Done(false) {}
+    : E(E), O(O), Opcodes(Bytes), Ptr(Bytes.begin()), SegmentOffset(0),
+      SegmentIndex(-1), LibraryOrdinalSet(false), Ordinal(0), Flags(0),
+      Addend(0), RemainingLoopCount(0), AdvanceAmount(0), BindType(0),
+      PointerSize(is64Bit ? 8 : 4), TableKind(BK), Malformed(false),
+      Done(false) {}
 
 void MachOBindEntry::moveToFirst() {
   Ptr = Opcodes.begin();
@@ -2968,6 +2991,8 @@ void MachOBindEntry::moveNext() {
     uint8_t Opcode = Byte & MachO::BIND_OPCODE_MASK;
     int8_t SignExtended;
     const uint8_t *SymStart;
+    uint32_t Count, Skip;
+    const char *error = nullptr;
     switch (Opcode) {
     case MachO::BIND_OPCODE_DONE:
       if (TableKind == Kind::Lazy) {
@@ -2989,6 +3014,7 @@ void MachOBindEntry::moveNext() {
       break;
     case MachO::BIND_OPCODE_SET_DYLIB_ORDINAL_IMM:
       Ordinal = ImmValue;
+      LibraryOrdinalSet = true;
       if (ImmValue > O->getLibraryCount()) {
         *E = malformedError("for BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB bad "
              "library ordinal: " + Twine((int)ImmValue) + " (max " +
@@ -3003,7 +3029,23 @@ void MachOBindEntry::moveNext() {
                        << "Ordinal=" << Ordinal << "\n");
       break;
     case MachO::BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB:
-      Ordinal = readULEB128();
+      Ordinal = readULEB128(&error);
+      LibraryOrdinalSet = true;
+      if (error) {
+        *E = malformedError("for BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB " +
+             Twine(error) + " for opcode at: 0x" +
+             utohexstr(OpcodeStart - Opcodes.begin()));
+        moveToEnd();
+        return;
+      }
+      if (Ordinal > (int)O->getLibraryCount()) {
+        *E = malformedError("for BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB bad "
+             "library ordinal: " + Twine((int)Ordinal) + " (max " +
+             Twine((int)O->getLibraryCount()) + ") for opcode at: 0x" +
+             utohexstr(OpcodeStart - Opcodes.begin()));
+        moveToEnd();
+        return;
+      }
       DEBUG_WITH_TYPE(
           "mach-o-bind",
           llvm::dbgs() << "BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB: "
@@ -3013,6 +3055,14 @@ void MachOBindEntry::moveNext() {
       if (ImmValue) {
         SignExtended = MachO::BIND_OPCODE_MASK | ImmValue;
         Ordinal = SignExtended;
+        LibraryOrdinalSet = true;
+        if (Ordinal < MachO::BIND_SPECIAL_DYLIB_FLAT_LOOKUP) {
+          *E = malformedError("for BIND_OPCODE_SET_DYLIB_SPECIAL_IMM unknown "
+               "special ordinal: " + Twine((int)Ordinal) + " for opcode at: "
+               "0x" + utohexstr(OpcodeStart - Opcodes.begin()));
+          moveToEnd();
+          return;
+        }
       } else
         Ordinal = 0;
       DEBUG_WITH_TYPE(
@@ -3023,9 +3073,16 @@ void MachOBindEntry::moveNext() {
     case MachO::BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM:
       Flags = ImmValue;
       SymStart = Ptr;
-      while (*Ptr) {
+      while (*Ptr && (Ptr < Opcodes.end())) {
         ++Ptr;
       }
+      if (Ptr == Opcodes.end()) {
+          *E = malformedError("for BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM "
+               "symbol name extends past opcodes for opcode at: 0x" +
+               utohexstr(OpcodeStart - Opcodes.begin()));
+          moveToEnd();
+          return;
+      }
       SymbolName = StringRef(reinterpret_cast<const char*>(SymStart),
                              Ptr-SymStart);
       ++Ptr;
@@ -3040,13 +3097,27 @@ void MachOBindEntry::moveNext() {
       break;
     case MachO::BIND_OPCODE_SET_TYPE_IMM:
       BindType = ImmValue;
+      if (ImmValue > MachO::BIND_TYPE_TEXT_PCREL32) {
+          *E = malformedError("for BIND_OPCODE_SET_TYPE_IMM bad bind type: " +
+               Twine((int)ImmValue) + " for opcode at: 0x" +
+               utohexstr(OpcodeStart - Opcodes.begin()));
+          moveToEnd();
+          return;
+      }
       DEBUG_WITH_TYPE(
           "mach-o-bind",
           llvm::dbgs() << "BIND_OPCODE_SET_TYPE_IMM: "
                        << "BindType=" << (int)BindType << "\n");
       break;
     case MachO::BIND_OPCODE_SET_ADDEND_SLEB:
-      Addend = readSLEB128();
+      Addend = readSLEB128(&error);
+      if (error) {
+        *E = malformedError("for BIND_OPCODE_SET_ADDEND_SLEB " +
+             Twine(error) + " for opcode at: 0x" +
+             utohexstr(OpcodeStart - Opcodes.begin()));
+        moveToEnd();
+        return;
+      }
       if (TableKind == Kind::Lazy)
         Malformed = true;
       DEBUG_WITH_TYPE(
@@ -3056,7 +3127,22 @@ void MachOBindEntry::moveNext() {
       break;
     case MachO::BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB:
       SegmentIndex = ImmValue;
-      SegmentOffset = readULEB128();
+      SegmentOffset = readULEB128(&error);
+      if (error) {
+        *E = malformedError("for BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB " +
+             Twine(error) + " for opcode at: 0x" +
+             utohexstr(OpcodeStart - Opcodes.begin()));
+        moveToEnd();
+        return;
+      }
+      error = O->BindEntryCheckSegAndOffset(SegmentIndex, SegmentOffset, true);
+      if (error) {
+        *E = malformedError("for BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB " +
+             Twine(error) + " for opcode at: 0x" +
+             utohexstr(OpcodeStart - Opcodes.begin()));
+        moveToEnd();
+        return;
+      }
       DEBUG_WITH_TYPE(
           "mach-o-bind",
           llvm::dbgs() << "BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB: "
@@ -3065,7 +3151,22 @@ void MachOBindEntry::moveNext() {
                        << "\n");
       break;
     case MachO::BIND_OPCODE_ADD_ADDR_ULEB:
-      SegmentOffset += readULEB128();
+      SegmentOffset += readULEB128(&error);
+      if (error) {
+        *E = malformedError("for BIND_OPCODE_ADD_ADDR_ULEB " +
+             Twine(error) + " for opcode at: 0x" +
+             utohexstr(OpcodeStart - Opcodes.begin()));
+        moveToEnd();
+        return;
+      }
+      error = O->BindEntryCheckSegAndOffset(SegmentIndex, SegmentOffset, true);
+      if (error) {
+        *E = malformedError("for BIND_OPCODE_ADD_ADDR_ULEB " +
+             Twine(error) + " for opcode at: 0x" +
+             utohexstr(OpcodeStart - Opcodes.begin()));
+        moveToEnd();
+        return;
+      }
       DEBUG_WITH_TYPE("mach-o-bind",
                       llvm::dbgs() << "BIND_OPCODE_ADD_ADDR_ULEB: "
                                    << format("SegmentOffset=0x%06X",
@@ -3074,13 +3175,75 @@ void MachOBindEntry::moveNext() {
     case MachO::BIND_OPCODE_DO_BIND:
       AdvanceAmount = PointerSize;
       RemainingLoopCount = 0;
+      error = O->BindEntryCheckSegAndOffset(SegmentIndex, SegmentOffset, true);
+      if (error) {
+        *E = malformedError("for BIND_OPCODE_DO_BIND " + Twine(error) +
+             " for opcode at: 0x" + utohexstr(OpcodeStart - Opcodes.begin()));
+        moveToEnd();
+        return;
+      }
+      if (SymbolName == StringRef()) {
+        *E = malformedError("for BIND_OPCODE_DO_BIND missing preceding "
+             "BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM for opcode at: 0x" +
+             utohexstr(OpcodeStart - Opcodes.begin()));
+        moveToEnd();
+        return;
+      }
+      if (!LibraryOrdinalSet && TableKind != Kind::Weak) {
+        *E = malformedError("for BIND_OPCODE_DO_BIND missing preceding "
+             "BIND_OPCODE_SET_DYLIB_ORDINAL_* for opcode at: 0x" +
+             utohexstr(OpcodeStart - Opcodes.begin()));
+        moveToEnd();
+        return;
+      }
       DEBUG_WITH_TYPE("mach-o-bind",
                       llvm::dbgs() << "BIND_OPCODE_DO_BIND: "
                                    << format("SegmentOffset=0x%06X",
                                              SegmentOffset) << "\n");
       return;
      case MachO::BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB:
-      AdvanceAmount = readULEB128() + PointerSize;
+      error = O->BindEntryCheckSegAndOffset(SegmentIndex, SegmentOffset, true);
+      if (error) {
+        *E = malformedError("for BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB " +
+             Twine(error) + " for opcode at: 0x" +
+             utohexstr(OpcodeStart - Opcodes.begin()));
+        moveToEnd();
+        return;
+      }
+      if (SymbolName == StringRef()) {
+        *E = malformedError("for BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB missing "
+             "preceding BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM for opcode "
+             "at: 0x" + utohexstr(OpcodeStart - Opcodes.begin()));
+        moveToEnd();
+        return;
+      }
+      if (!LibraryOrdinalSet && TableKind != Kind::Weak) {
+        *E = malformedError("for BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB missing "
+             "preceding BIND_OPCODE_SET_DYLIB_ORDINAL_* for opcode at: 0x" +
+             utohexstr(OpcodeStart - Opcodes.begin()));
+        moveToEnd();
+        return;
+      }
+      AdvanceAmount = readULEB128(&error) + PointerSize;
+      if (error) {
+        *E = malformedError("for BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB " +
+             Twine(error) + " for opcode at: 0x" +
+             utohexstr(OpcodeStart - Opcodes.begin()));
+        moveToEnd();
+        return;
+      }
+      // Note, this is not really an error until the next bind but make no sense
+      // for a BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB to not be followed by another
+      // bind operation.
+      error = O->BindEntryCheckSegAndOffset(SegmentIndex, SegmentOffset +
+                                            AdvanceAmount, false);
+      if (error) {
+        *E = malformedError("for BIND_OPCODE_ADD_ADDR_ULEB (after adding "
+             "ULEB) " + Twine(error) + " for opcode at: 0x" +
+             utohexstr(OpcodeStart - Opcodes.begin()));
+        moveToEnd();
+        return;
+      }
       RemainingLoopCount = 0;
       if (TableKind == Kind::Lazy)
         Malformed = true;
@@ -3093,8 +3256,40 @@ void MachOBindEntry::moveNext() {
                        << "\n");
       return;
     case MachO::BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED:
+      error = O->BindEntryCheckSegAndOffset(SegmentIndex, SegmentOffset, true);
+      if (error) {
+        *E = malformedError("for BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED " +
+             Twine(error) + " for opcode at: 0x" +
+             utohexstr(OpcodeStart - Opcodes.begin()));
+        moveToEnd();
+        return;
+      }
+      if (SymbolName == StringRef()) {
+        *E = malformedError("for BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED "
+             "missing preceding BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM for "
+             "opcode at: 0x" + utohexstr(OpcodeStart - Opcodes.begin()));
+        moveToEnd();
+        return;
+      }
+      if (!LibraryOrdinalSet && TableKind != Kind::Weak) {
+        *E = malformedError("for BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED "
+             "missing preceding BIND_OPCODE_SET_DYLIB_ORDINAL_* for opcode "
+             "at: 0x" + utohexstr(OpcodeStart - Opcodes.begin()));
+        moveToEnd();
+        return;
+      }
       AdvanceAmount = ImmValue * PointerSize + PointerSize;
       RemainingLoopCount = 0;
+      error = O->BindEntryCheckSegAndOffset(SegmentIndex, SegmentOffset +
+                                            AdvanceAmount, false);
+      if (error) {
+        *E = malformedError("for BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED "
+             " (after adding immediate times the pointer size) " +
+             Twine(error) + " for opcode at: 0x" +
+             utohexstr(OpcodeStart - Opcodes.begin()));
+        moveToEnd();
+        return;
+      }
       if (TableKind == Kind::Lazy)
         Malformed = true;
       DEBUG_WITH_TYPE("mach-o-bind",
@@ -3104,8 +3299,58 @@ void MachOBindEntry::moveNext() {
                                              SegmentOffset) << "\n");
       return;
     case MachO::BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB:
-      RemainingLoopCount = readULEB128() - 1;
-      AdvanceAmount = readULEB128() + PointerSize;
+      Count = readULEB128(&error);
+      if (Count != 0)
+        RemainingLoopCount = Count - 1;
+      else
+        RemainingLoopCount = 0;
+      if (error) {
+        *E = malformedError("for BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB "
+                            " (count value) " + Twine(error) + " for opcode at"
+                            ": 0x" + utohexstr(OpcodeStart - Opcodes.begin()));
+        moveToEnd();
+        return;
+      }
+      Skip = readULEB128(&error);
+      AdvanceAmount = Skip + PointerSize;
+      if (error) {
+        *E = malformedError("for BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB "
+                            " (skip value) " + Twine(error) + " for opcode at"
+                            ": 0x" + utohexstr(OpcodeStart - Opcodes.begin()));
+        moveToEnd();
+        return;
+      }
+      error = O->BindEntryCheckSegAndOffset(SegmentIndex, SegmentOffset, true);
+      if (error) {
+        *E = malformedError("for BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB "
+             + Twine(error) + " for opcode at: 0x" +
+             utohexstr(OpcodeStart - Opcodes.begin()));
+        moveToEnd();
+        return;
+      }
+      if (SymbolName == StringRef()) {
+        *E = malformedError("for BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB "
+             "missing preceding BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM for "
+             "opcode at: 0x" + utohexstr(OpcodeStart - Opcodes.begin()));
+        moveToEnd();
+        return;
+      }
+      if (!LibraryOrdinalSet && TableKind != Kind::Weak) {
+        *E = malformedError("for BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB "
+             "missing preceding BIND_OPCODE_SET_DYLIB_ORDINAL_* for opcode "
+             "at: 0x" + utohexstr(OpcodeStart - Opcodes.begin()));
+        moveToEnd();
+        return;
+      }
+      error = O->BindEntryCheckCountAndSkip(Count, Skip, PointerSize,
+                                            SegmentIndex, SegmentOffset);
+      if (error) {
+        *E = malformedError("for BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB "
+             + Twine(error) + " for opcode at: 0x" +
+             utohexstr(OpcodeStart - Opcodes.begin()));
+        moveToEnd();
+	return;
+      }
       if (TableKind == Kind::Lazy)
         Malformed = true;
       DEBUG_WITH_TYPE(
@@ -3118,13 +3363,18 @@ void MachOBindEntry::moveNext() {
       return;
     default:
       Malformed = true;
+      *E = malformedError("bad bind info (bad opcode value 0x" +
+           utohexstr(Opcode) + " for opcode at: 0x" +
+           utohexstr(OpcodeStart - Opcodes.begin()));
+      moveToEnd();
+      return;
     }
   }
 }
 
-uint64_t MachOBindEntry::readULEB128() {
+uint64_t MachOBindEntry::readULEB128(const char **error) {
   unsigned Count;
-  uint64_t Result = decodeULEB128(Ptr, &Count);
+  uint64_t Result = decodeULEB128(Ptr, &Count, Opcodes.end(), error);
   Ptr += Count;
   if (Ptr > Opcodes.end()) {
     Ptr = Opcodes.end();
@@ -3133,9 +3383,9 @@ uint64_t MachOBindEntry::readULEB128() {
   return Result;
 }
 
-int64_t MachOBindEntry::readSLEB128() {
+int64_t MachOBindEntry::readSLEB128(const char **error) {
   unsigned Count;
-  int64_t Result = decodeSLEB128(Ptr, &Count);
+  int64_t Result = decodeSLEB128(Ptr, &Count, Opcodes.end(), error);
   Ptr += Count;
   if (Ptr > Opcodes.end()) {
     Ptr = Opcodes.end();
@@ -3144,7 +3394,7 @@ int64_t MachOBindEntry::readSLEB128() {
   return Result;
 }
 
-uint32_t MachOBindEntry::segmentIndex() const { return SegmentIndex; }
+int32_t MachOBindEntry::segmentIndex() const { return SegmentIndex; }
 
 uint64_t MachOBindEntry::segmentOffset() const { return SegmentOffset; }
 
@@ -3168,6 +3418,24 @@ uint32_t MachOBindEntry::flags() const {
 
 int MachOBindEntry::ordinal() const { return Ordinal; }
 
+// For use with the SegIndex of a checked Mach-O Bind entry
+// to get the segment name.
+StringRef MachOBindEntry::segmentName() const {
+  return O->BindRebaseSegmentName(SegmentIndex);
+}
+
+// For use with a SegIndex,SegOffset pair from a checked Mach-O Bind entry
+// to get the section name.
+StringRef MachOBindEntry::sectionName() const {
+  return O->BindRebaseSectionName(SegmentIndex, SegmentOffset);
+}
+
+// For use with a SegIndex,SegOffset pair from a checked Mach-O Bind entry
+// to get the address.
+uint64_t MachOBindEntry::address() const {
+  return O->BindRebaseAddress(SegmentIndex, SegmentOffset);
+}
+
 bool MachOBindEntry::operator==(const MachOBindEntry &Other) const {
 #ifdef EXPENSIVE_CHECKS
   assert(Opcodes == Other.Opcodes && "compare iterators of different files");
@@ -3179,10 +3447,119 @@ bool MachOBindEntry::operator==(const Ma
          (Done == Other.Done);
 }
 
+// Build table of sections so SegIndex/SegOffset pairs can be translated.
+BindRebaseSegInfo::BindRebaseSegInfo(const object::MachOObjectFile *Obj) {
+  uint32_t CurSegIndex = Obj->hasPageZeroSegment() ? 1 : 0;
+  StringRef CurSegName;
+  uint64_t CurSegAddress;
+  for (const SectionRef &Section : Obj->sections()) {
+    SectionInfo Info;
+    Section.getName(Info.SectionName);
+    Info.Address = Section.getAddress();
+    Info.Size = Section.getSize();
+    Info.SegmentName =
+        Obj->getSectionFinalSegmentName(Section.getRawDataRefImpl());
+    if (!Info.SegmentName.equals(CurSegName)) {
+      ++CurSegIndex;
+      CurSegName = Info.SegmentName;
+      CurSegAddress = Info.Address;
+    }
+    Info.SegmentIndex = CurSegIndex - 1;
+    Info.OffsetInSegment = Info.Address - CurSegAddress;
+    Info.SegmentStartAddress = CurSegAddress;
+    Sections.push_back(Info);
+  }
+  MaxSegIndex = CurSegIndex;
+}
+
+// For use with a SegIndex,SegOffset pair in MachOBindEntry::moveNext() to
+// validate a MachOBindEntry.
+const char * BindRebaseSegInfo::checkSegAndOffset(int32_t SegIndex,
+                                                  uint64_t SegOffset,
+                                                  bool endInvalid) {
+  if (SegIndex == -1)
+    return "missing preceding BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB";
+  if (SegIndex >= MaxSegIndex)
+    return "bad segIndex (too large)";
+  for (const SectionInfo &SI : Sections) {
+    if (SI.SegmentIndex != SegIndex)
+      continue;
+    if (SI.OffsetInSegment > SegOffset)
+      continue;
+    if (SegOffset > (SI.OffsetInSegment + SI.Size))
+      continue;
+    if (endInvalid && SegOffset >= (SI.OffsetInSegment + SI.Size))
+      continue;
+    return nullptr;
+  }
+  return "bad segOffset, too large";
+}
+
+// For use in MachOBindEntry::moveNext() to validate a MachOBindEntry for
+// the BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB opcode.  The SegIndex
+// and SegOffset must have been already checked.
+const char * BindRebaseSegInfo::checkCountAndSkip(uint32_t Count, uint32_t Skip,
+                                                  uint8_t PointerSize,
+                                                 int32_t SegIndex,
+                                                 uint64_t SegOffset) {
+  const SectionInfo &SI = findSection(SegIndex, SegOffset);
+  uint64_t addr = SI.SegmentStartAddress + SegOffset;
+  if (addr >= SI.Address + SI.Size)
+    return "bad segOffset, too large";
+  uint64_t i = 0;
+  if (Count > 1)
+    i = (Skip + PointerSize) * (Count - 1);
+  if (addr + i >= SI.Address + SI.Size)
+    return "bad count and skip, too large";
+  return nullptr;
+}
+
+// For use with the SegIndex of a checked Mach-O Bind or Rebase entry
+// to get the segment name.
+StringRef BindRebaseSegInfo::segmentName(int32_t SegIndex) {
+  for (const SectionInfo &SI : Sections) {
+    if (SI.SegmentIndex == SegIndex)
+      return SI.SegmentName;
+  }
+  llvm_unreachable("invalid SegIndex");
+}
+
+// For use with a SegIndex,SegOffset pair from a checked Mach-O Bind or Rebase
+// to get the SectionInfo.
+const BindRebaseSegInfo::SectionInfo &BindRebaseSegInfo::findSection(
+                                     int32_t SegIndex, uint64_t SegOffset) {
+  for (const SectionInfo &SI : Sections) {
+    if (SI.SegmentIndex != SegIndex)
+      continue;
+    if (SI.OffsetInSegment > SegOffset)
+      continue;
+    if (SegOffset >= (SI.OffsetInSegment + SI.Size))
+      continue;
+    return SI;
+  }
+  llvm_unreachable("SegIndex and SegOffset not in any section");
+}
+
+// For use with a SegIndex,SegOffset pair from a checked Mach-O Bind or Rebase
+// entry to get the section name.
+StringRef BindRebaseSegInfo::sectionName(int32_t SegIndex,
+                                         uint64_t SegOffset) {
+  return findSection(SegIndex, SegOffset).SectionName;
+}
+
+// For use with a SegIndex,SegOffset pair from a checked Mach-O Bind or Rebase
+// entry to get the address.
+uint64_t BindRebaseSegInfo::address(uint32_t SegIndex, uint64_t OffsetInSeg) {
+  const SectionInfo &SI = findSection(SegIndex, OffsetInSeg);
+  return SI.SegmentStartAddress + OffsetInSeg;
+}
+
 iterator_range<bind_iterator>
-MachOObjectFile::bindTable(Error &Err, const MachOObjectFile *O,
+MachOObjectFile::bindTable(Error &Err, MachOObjectFile *O,
                            ArrayRef<uint8_t> Opcodes, bool is64,
                            MachOBindEntry::Kind BKind) {
+  if (O->BindRebaseSectionTable == nullptr)
+    O->BindRebaseSectionTable = llvm::make_unique<BindRebaseSegInfo>(O);
   MachOBindEntry Start(&Err, O, Opcodes, is64, BKind);
   Start.moveToFirst();
 
@@ -3192,17 +3569,17 @@ MachOObjectFile::bindTable(Error &Err, c
   return make_range(bind_iterator(Start), bind_iterator(Finish));
 }
 
-iterator_range<bind_iterator> MachOObjectFile::bindTable(Error &Err) const {
+iterator_range<bind_iterator> MachOObjectFile::bindTable(Error &Err) {
   return bindTable(Err, this, getDyldInfoBindOpcodes(), is64Bit(),
                    MachOBindEntry::Kind::Regular);
 }
 
-iterator_range<bind_iterator> MachOObjectFile::lazyBindTable(Error &Err) const {
+iterator_range<bind_iterator> MachOObjectFile::lazyBindTable(Error &Err) {
   return bindTable(Err, this, getDyldInfoLazyBindOpcodes(), is64Bit(),
                    MachOBindEntry::Kind::Lazy);
 }
 
-iterator_range<bind_iterator> MachOObjectFile::weakBindTable(Error &Err) const {
+iterator_range<bind_iterator> MachOObjectFile::weakBindTable(Error &Err) {
   return bindTable(Err, this, getDyldInfoWeakBindOpcodes(), is64Bit(),
                    MachOBindEntry::Kind::Weak);
 }

Added: llvm/trunk/test/tools/llvm-objdump/Inputs/macho-bind-add-addr-imm-scaled
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-objdump/Inputs/macho-bind-add-addr-imm-scaled?rev=298292&view=auto
==============================================================================
Binary file - no diff available.

Propchange: llvm/trunk/test/tools/llvm-objdump/Inputs/macho-bind-add-addr-imm-scaled
------------------------------------------------------------------------------
    svn:executable = *

Propchange: llvm/trunk/test/tools/llvm-objdump/Inputs/macho-bind-add-addr-imm-scaled
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: llvm/trunk/test/tools/llvm-objdump/Inputs/macho-bind-add_addr_uleb
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-objdump/Inputs/macho-bind-add_addr_uleb?rev=298292&view=auto
==============================================================================
Binary file - no diff available.

Propchange: llvm/trunk/test/tools/llvm-objdump/Inputs/macho-bind-add_addr_uleb
------------------------------------------------------------------------------
    svn:executable = *

Propchange: llvm/trunk/test/tools/llvm-objdump/Inputs/macho-bind-add_addr_uleb
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: llvm/trunk/test/tools/llvm-objdump/Inputs/macho-bind-bad-opcode-value
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-objdump/Inputs/macho-bind-bad-opcode-value?rev=298292&view=auto
==============================================================================
Binary file - no diff available.

Propchange: llvm/trunk/test/tools/llvm-objdump/Inputs/macho-bind-bad-opcode-value
------------------------------------------------------------------------------
    svn:executable = *

Propchange: llvm/trunk/test/tools/llvm-objdump/Inputs/macho-bind-bad-opcode-value
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: llvm/trunk/test/tools/llvm-objdump/Inputs/macho-bind-bind-add-addr-uleb
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-objdump/Inputs/macho-bind-bind-add-addr-uleb?rev=298292&view=auto
==============================================================================
Binary file - no diff available.

Propchange: llvm/trunk/test/tools/llvm-objdump/Inputs/macho-bind-bind-add-addr-uleb
------------------------------------------------------------------------------
    svn:executable = *

Propchange: llvm/trunk/test/tools/llvm-objdump/Inputs/macho-bind-bind-add-addr-uleb
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: llvm/trunk/test/tools/llvm-objdump/Inputs/macho-bind-do-bind-no-segIndex
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-objdump/Inputs/macho-bind-do-bind-no-segIndex?rev=298292&view=auto
==============================================================================
Binary file - no diff available.

Propchange: llvm/trunk/test/tools/llvm-objdump/Inputs/macho-bind-do-bind-no-segIndex
------------------------------------------------------------------------------
    svn:executable = *

Propchange: llvm/trunk/test/tools/llvm-objdump/Inputs/macho-bind-do-bind-no-segIndex
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: llvm/trunk/test/tools/llvm-objdump/Inputs/macho-bind-dylib-ordinal-uleb
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-objdump/Inputs/macho-bind-dylib-ordinal-uleb?rev=298292&view=auto
==============================================================================
Binary file - no diff available.

Propchange: llvm/trunk/test/tools/llvm-objdump/Inputs/macho-bind-dylib-ordinal-uleb
------------------------------------------------------------------------------
    svn:executable = *

Propchange: llvm/trunk/test/tools/llvm-objdump/Inputs/macho-bind-dylib-ordinal-uleb
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: llvm/trunk/test/tools/llvm-objdump/Inputs/macho-bind-dylib-ordinal-uleb-malformed-uleb128
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-objdump/Inputs/macho-bind-dylib-ordinal-uleb-malformed-uleb128?rev=298292&view=auto
==============================================================================
Binary file - no diff available.

Propchange: llvm/trunk/test/tools/llvm-objdump/Inputs/macho-bind-dylib-ordinal-uleb-malformed-uleb128
------------------------------------------------------------------------------
    svn:executable = *

Propchange: llvm/trunk/test/tools/llvm-objdump/Inputs/macho-bind-dylib-ordinal-uleb-malformed-uleb128
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: llvm/trunk/test/tools/llvm-objdump/Inputs/macho-bind-dylib-ordinal-uleb-too-big
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-objdump/Inputs/macho-bind-dylib-ordinal-uleb-too-big?rev=298292&view=auto
==============================================================================
Binary file - no diff available.

Propchange: llvm/trunk/test/tools/llvm-objdump/Inputs/macho-bind-dylib-ordinal-uleb-too-big
------------------------------------------------------------------------------
    svn:executable = *

Propchange: llvm/trunk/test/tools/llvm-objdump/Inputs/macho-bind-dylib-ordinal-uleb-too-big
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: llvm/trunk/test/tools/llvm-objdump/Inputs/macho-bind-dylib-special-imm
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-objdump/Inputs/macho-bind-dylib-special-imm?rev=298292&view=auto
==============================================================================
Binary file - no diff available.

Propchange: llvm/trunk/test/tools/llvm-objdump/Inputs/macho-bind-dylib-special-imm
------------------------------------------------------------------------------
    svn:executable = *

Propchange: llvm/trunk/test/tools/llvm-objdump/Inputs/macho-bind-dylib-special-imm
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: llvm/trunk/test/tools/llvm-objdump/Inputs/macho-bind-seg-too-big
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-objdump/Inputs/macho-bind-seg-too-big?rev=298292&view=auto
==============================================================================
Binary file - no diff available.

Propchange: llvm/trunk/test/tools/llvm-objdump/Inputs/macho-bind-seg-too-big
------------------------------------------------------------------------------
    svn:executable = *

Propchange: llvm/trunk/test/tools/llvm-objdump/Inputs/macho-bind-seg-too-big
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: llvm/trunk/test/tools/llvm-objdump/Inputs/macho-bind-segoff-too-big
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-objdump/Inputs/macho-bind-segoff-too-big?rev=298292&view=auto
==============================================================================
Binary file - no diff available.

Propchange: llvm/trunk/test/tools/llvm-objdump/Inputs/macho-bind-segoff-too-big
------------------------------------------------------------------------------
    svn:executable = *

Propchange: llvm/trunk/test/tools/llvm-objdump/Inputs/macho-bind-segoff-too-big
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: llvm/trunk/test/tools/llvm-objdump/Inputs/macho-bind-set-addend-sleb
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-objdump/Inputs/macho-bind-set-addend-sleb?rev=298292&view=auto
==============================================================================
Binary file - no diff available.

Propchange: llvm/trunk/test/tools/llvm-objdump/Inputs/macho-bind-set-addend-sleb
------------------------------------------------------------------------------
    svn:executable = *

Propchange: llvm/trunk/test/tools/llvm-objdump/Inputs/macho-bind-set-addend-sleb
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: llvm/trunk/test/tools/llvm-objdump/Inputs/macho-bind-set-symbol
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-objdump/Inputs/macho-bind-set-symbol?rev=298292&view=auto
==============================================================================
Binary file - no diff available.

Propchange: llvm/trunk/test/tools/llvm-objdump/Inputs/macho-bind-set-symbol
------------------------------------------------------------------------------
    svn:executable = *

Propchange: llvm/trunk/test/tools/llvm-objdump/Inputs/macho-bind-set-symbol
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: llvm/trunk/test/tools/llvm-objdump/Inputs/macho-bind-set-type-imm
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-objdump/Inputs/macho-bind-set-type-imm?rev=298292&view=auto
==============================================================================
Binary file - no diff available.

Propchange: llvm/trunk/test/tools/llvm-objdump/Inputs/macho-bind-set-type-imm
------------------------------------------------------------------------------
    svn:executable = *

Propchange: llvm/trunk/test/tools/llvm-objdump/Inputs/macho-bind-set-type-imm
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: llvm/trunk/test/tools/llvm-objdump/Inputs/macho-bind-uleb-times-skipping-uleb
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-objdump/Inputs/macho-bind-uleb-times-skipping-uleb?rev=298292&view=auto
==============================================================================
Binary file - no diff available.

Propchange: llvm/trunk/test/tools/llvm-objdump/Inputs/macho-bind-uleb-times-skipping-uleb
------------------------------------------------------------------------------
    svn:executable = *

Propchange: llvm/trunk/test/tools/llvm-objdump/Inputs/macho-bind-uleb-times-skipping-uleb
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: llvm/trunk/test/tools/llvm-objdump/Inputs/macho-do-bind-no-dylib-ordinal
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-objdump/Inputs/macho-do-bind-no-dylib-ordinal?rev=298292&view=auto
==============================================================================
Binary file - no diff available.

Propchange: llvm/trunk/test/tools/llvm-objdump/Inputs/macho-do-bind-no-dylib-ordinal
------------------------------------------------------------------------------
    svn:executable = *

Propchange: llvm/trunk/test/tools/llvm-objdump/Inputs/macho-do-bind-no-dylib-ordinal
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: llvm/trunk/test/tools/llvm-objdump/Inputs/macho-do-bind-no-symbol
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-objdump/Inputs/macho-do-bind-no-symbol?rev=298292&view=auto
==============================================================================
Binary file - no diff available.

Propchange: llvm/trunk/test/tools/llvm-objdump/Inputs/macho-do-bind-no-symbol
------------------------------------------------------------------------------
    svn:executable = *

Propchange: llvm/trunk/test/tools/llvm-objdump/Inputs/macho-do-bind-no-symbol
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Modified: llvm/trunk/test/tools/llvm-objdump/X86/malformed-machos.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-objdump/X86/malformed-machos.test?rev=298292&r1=298291&r2=298292&view=diff
==============================================================================
--- llvm/trunk/test/tools/llvm-objdump/X86/malformed-machos.test (original)
+++ llvm/trunk/test/tools/llvm-objdump/X86/malformed-machos.test Mon Mar 20 14:46:55 2017
@@ -64,5 +64,5 @@ INVALID-SYMBOL-STRX-UNIVERSAL: macho-inv
 RUN: not llvm-objdump -macho -disassemble %p/Inputs/macho-invalid-symbol-lib_ordinal 2>&1 | FileCheck -check-prefix INVALID-SYMBOL-LIB_ORDINAL %s
 INVALID-SYMBOL-LIB_ORDINAL: macho-invalid-symbol-lib_ordinal': truncated or malformed object (bad library ordinal: 7 for symbol at index 2)
 
-RUN: llvm-objdump -macho -objc-meta-data %p/Inputs/macho-invalid-bind-entry | FileCheck -check-prefix INVALID-BIND-ENTRY %s
-INVALID-BIND-ENTRY: 0000000100020c90 0x2d0409887202e473
+RUN: not llvm-objdump -macho -objc-meta-data %p/Inputs/macho-invalid-bind-entry 2>&1 | FileCheck -check-prefix INVALID-BIND-ENTRY %s
+INVALID-BIND-ENTRY: macho-invalid-bind-entry': truncated or malformed object (for BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB bad library ordinal: 83 (max 0) for opcode at: 0x0)

Added: llvm/trunk/test/tools/llvm-objdump/macho-bad-bind.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-objdump/macho-bad-bind.test?rev=298292&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-objdump/macho-bad-bind.test (added)
+++ llvm/trunk/test/tools/llvm-objdump/macho-bad-bind.test Mon Mar 20 14:46:55 2017
@@ -0,0 +1,50 @@
+RUN: not llvm-objdump -macho -bind %p/Inputs/macho-bind-dylib-ordinal-uleb 2>&1 | FileCheck -check-prefix DYLIB-ORDINAL-ULEB %s 
+DYLIB-ORDINAL-ULEB: macho-bind-dylib-ordinal-uleb': truncated or malformed object (for BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB bad library ordinal: 355 (max 1) for opcode at: 0x0)
+
+RUN: not llvm-objdump -macho -bind %p/Inputs/macho-bind-dylib-ordinal-uleb-malformed-uleb128 2>&1 | FileCheck -check-prefix DYLIB-ORDINAL-ULEB-MALFORMED-ULEB128 %s 
+DYLIB-ORDINAL-ULEB-MALFORMED-ULEB128: macho-bind-dylib-ordinal-uleb-malformed-uleb128': truncated or malformed object (for BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB malformed uleb128, extends past end for opcode at: 0x0)
+
+RUN: not llvm-objdump -macho -bind %p/Inputs/macho-bind-dylib-ordinal-uleb-too-big 2>&1 | FileCheck -check-prefix DYLIB-ORDINAL-ULEB-TOO-BIG %s 
+DYLIB-ORDINAL-ULEB-TOO-BIG: macho-bind-dylib-ordinal-uleb-too-big': truncated or malformed object (for BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB uleb128 too big for uint64 for opcode at: 0x0)
+
+RUN: not llvm-objdump -macho -bind %p/Inputs/macho-bind-dylib-special-imm 2>&1 | FileCheck -check-prefix DYLIB-SPECIAL-IMM %s 
+DYLIB-SPECIAL-IMM: macho-bind-dylib-special-imm': truncated or malformed object (for BIND_OPCODE_SET_DYLIB_SPECIAL_IMM unknown special ordinal: -5 for opcode at: 0x0)
+
+RUN: not llvm-objdump -macho -bind %p/Inputs/macho-bind-set-symbol 2>&1 | FileCheck -check-prefix BIND-SET-SYMBOL %s 
+BIND-SET-SYMBOL: macho-bind-set-symbol': truncated or malformed object (for BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM symbol name extends past opcodes for opcode at: 0x2)
+
+RUN: not llvm-objdump -macho -bind %p/Inputs/macho-bind-set-type-imm 2>&1 | FileCheck -check-prefix SET-TYPE-IMM %s 
+SET-TYPE-IMM: macho-bind-set-type-imm': truncated or malformed object (for BIND_OPCODE_SET_TYPE_IMM bad bind type: 5 for opcode at: 0x14)
+
+RUN: not llvm-objdump -macho -bind %p/Inputs/macho-bind-set-addend-sleb 2>&1 | FileCheck -check-prefix SET-ADDEND-SLEB %s 
+SET-ADDEND-SLEB: macho-bind-set-addend-sleb': truncated or malformed object (for BIND_OPCODE_SET_ADDEND_SLEB malformed sleb128, extends past end for opcode at: 0x14)
+
+RUN: not llvm-objdump -macho -bind %p/Inputs/macho-bind-seg-too-big 2>&1 | FileCheck -check-prefix SEG-TOO-BIG %s 
+SEG-TOO-BIG: macho-bind-seg-too-big': truncated or malformed object (for BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB bad segIndex (too large) for opcode at: 0x15)
+
+RUN: not llvm-objdump -macho -bind %p/Inputs/macho-bind-segoff-too-big 2>&1 | FileCheck -check-prefix SEGOFF-TOO-BIG %s 
+SEGOFF-TOO-BIG: macho-bind-segoff-too-big': truncated or malformed object (for BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB bad segOffset, too large for opcode at: 0x15)
+
+RUN: not llvm-objdump -macho -bind %p/Inputs/macho-bind-add_addr_uleb 2>&1 | FileCheck -check-prefix ADD_ADDR_ULEB %s 
+ADD_ADDR_ULEB: macho-bind-add_addr_uleb': truncated or malformed object (for BIND_OPCODE_ADD_ADDR_ULEB bad segOffset, too large for opcode at: 0x17)
+
+RUN: not llvm-objdump -macho -bind %p/Inputs/macho-bind-do-bind-no-segIndex 2>&1 | FileCheck -check-prefix BIND-NO-SEGINDEX %s 
+BIND-NO-SEGINDEX: macho-bind-do-bind-no-segIndex': truncated or malformed object (for BIND_OPCODE_DO_BIND missing preceding BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB for opcode at: 0x15)
+
+RUN: not llvm-objdump -macho -bind %p/Inputs/macho-bind-bind-add-addr-uleb 2>&1 | FileCheck -check-prefix ADD-ADDR-ULEB %s 
+ADD-ADDR-ULEB: macho-bind-bind-add-addr-uleb': truncated or malformed object (for BIND_OPCODE_ADD_ADDR_ULEB (after adding ULEB) bad segOffset, too large for opcode at: 0x18)
+
+RUN: not llvm-objdump -macho -bind %p/Inputs/macho-bind-add-addr-imm-scaled 2>&1 | FileCheck -check-prefix ADD-ADDR-IMM-SCALED %s 
+ADD-ADDR-IMM-SCALED: macho-bind-add-addr-imm-scaled': truncated or malformed object (for BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED  (after adding immediate times the pointer size) bad segOffset, too large for opcode at: 0x17)
+
+RUN: not llvm-objdump -macho -bind %p/Inputs/macho-bind-uleb-times-skipping-uleb 2>&1 | FileCheck -check-prefix ULEB-TIMES-SKIPPING-ULEB %s 
+ULEB-TIMES-SKIPPING-ULEB: macho-bind-uleb-times-skipping-uleb': truncated or malformed object (for BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB bad count and skip, too large for opcode at: 0x17)
+
+RUN: not llvm-objdump -macho -bind %p/Inputs/macho-do-bind-no-symbol 2>&1 | FileCheck -check-prefix DO-BIND-NO-SYMBOL %s 
+DO-BIND-NO-SYMBOL: macho-do-bind-no-symbol': truncated or malformed object (for BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB missing preceding BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM for opcode at: 0x5)
+
+RUN: not llvm-objdump -macho -bind %p/Inputs/macho-do-bind-no-dylib-ordinal 2>&1 | FileCheck -check-prefix DO-BIND-NO-DYLIB-ORDINAL %s 
+DO-BIND-NO-DYLIB-ORDINAL: macho-do-bind-no-dylib-ordinal': truncated or malformed object (for BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB missing preceding BIND_OPCODE_SET_DYLIB_ORDINAL_* for opcode at: 0x15)
+
+RUN: not llvm-objdump -macho -bind %p/Inputs/macho-bind-bad-opcode-value 2>&1 | FileCheck -check-prefix BAD-OPCODE-VALUE %s 
+BAD-OPCODE-VALUE: macho-bind-bad-opcode-value': truncated or malformed object (bad bind info (bad opcode value 0xD0 for opcode at: 0x18)

Modified: llvm/trunk/tools/llvm-objdump/MachODump.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-objdump/MachODump.cpp?rev=298292&r1=298291&r2=298292&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-objdump/MachODump.cpp (original)
+++ llvm/trunk/tools/llvm-objdump/MachODump.cpp Mon Mar 20 14:46:55 2017
@@ -9391,117 +9391,21 @@ void llvm::printMachOExportsTrie(const o
 // rebase table dumping
 //===----------------------------------------------------------------------===//
 
-namespace {
-class SegInfo {
-public:
-  SegInfo(const object::MachOObjectFile *Obj);
-
-  StringRef segmentName(uint32_t SegIndex);
-  StringRef sectionName(uint32_t SegIndex, uint64_t SegOffset);
-  uint64_t address(uint32_t SegIndex, uint64_t SegOffset);
-  bool isValidSegIndexAndOffset(uint32_t SegIndex, uint64_t SegOffset);
-
-private:
-  struct SectionInfo {
-    uint64_t Address;
-    uint64_t Size;
-    StringRef SectionName;
-    StringRef SegmentName;
-    uint64_t OffsetInSegment;
-    uint64_t SegmentStartAddress;
-    uint32_t SegmentIndex;
-  };
-  const SectionInfo &findSection(uint32_t SegIndex, uint64_t SegOffset);
-  SmallVector<SectionInfo, 32> Sections;
-};
-}
-
-SegInfo::SegInfo(const object::MachOObjectFile *Obj) {
-  // Build table of sections so segIndex/offset pairs can be translated.
-  uint32_t CurSegIndex = Obj->hasPageZeroSegment() ? 1 : 0;
-  StringRef CurSegName;
-  uint64_t CurSegAddress;
-  for (const SectionRef &Section : Obj->sections()) {
-    SectionInfo Info;
-    error(Section.getName(Info.SectionName));
-    Info.Address = Section.getAddress();
-    Info.Size = Section.getSize();
-    Info.SegmentName =
-        Obj->getSectionFinalSegmentName(Section.getRawDataRefImpl());
-    if (!Info.SegmentName.equals(CurSegName)) {
-      ++CurSegIndex;
-      CurSegName = Info.SegmentName;
-      CurSegAddress = Info.Address;
-    }
-    Info.SegmentIndex = CurSegIndex - 1;
-    Info.OffsetInSegment = Info.Address - CurSegAddress;
-    Info.SegmentStartAddress = CurSegAddress;
-    Sections.push_back(Info);
-  }
-}
-
-StringRef SegInfo::segmentName(uint32_t SegIndex) {
-  for (const SectionInfo &SI : Sections) {
-    if (SI.SegmentIndex == SegIndex)
-      return SI.SegmentName;
-  }
-  llvm_unreachable("invalid segIndex");
-}
-
-bool SegInfo::isValidSegIndexAndOffset(uint32_t SegIndex,
-                                       uint64_t OffsetInSeg) {
-  for (const SectionInfo &SI : Sections) {
-    if (SI.SegmentIndex != SegIndex)
-      continue;
-    if (SI.OffsetInSegment > OffsetInSeg)
-      continue;
-    if (OffsetInSeg >= (SI.OffsetInSegment + SI.Size))
-      continue;
-    return true;
-  }
-  return false;
-}
-
-const SegInfo::SectionInfo &SegInfo::findSection(uint32_t SegIndex,
-                                                 uint64_t OffsetInSeg) {
-  for (const SectionInfo &SI : Sections) {
-    if (SI.SegmentIndex != SegIndex)
-      continue;
-    if (SI.OffsetInSegment > OffsetInSeg)
-      continue;
-    if (OffsetInSeg >= (SI.OffsetInSegment + SI.Size))
-      continue;
-    return SI;
-  }
-  llvm_unreachable("segIndex and offset not in any section");
-}
-
-StringRef SegInfo::sectionName(uint32_t SegIndex, uint64_t OffsetInSeg) {
-  return findSection(SegIndex, OffsetInSeg).SectionName;
-}
-
-uint64_t SegInfo::address(uint32_t SegIndex, uint64_t OffsetInSeg) {
-  const SectionInfo &SI = findSection(SegIndex, OffsetInSeg);
-  return SI.SegmentStartAddress + OffsetInSeg;
-}
-
-void llvm::printMachORebaseTable(const object::MachOObjectFile *Obj) {
-  // Build table of sections so names can used in final output.
-  SegInfo sectionTable(Obj);
-
+void llvm::printMachORebaseTable(object::MachOObjectFile *Obj) {
   outs() << "segment  section            address     type\n";
-  for (const llvm::object::MachORebaseEntry &Entry : Obj->rebaseTable()) {
-    uint32_t SegIndex = Entry.segmentIndex();
-    uint64_t OffsetInSeg = Entry.segmentOffset();
-    StringRef SegmentName = sectionTable.segmentName(SegIndex);
-    StringRef SectionName = sectionTable.sectionName(SegIndex, OffsetInSeg);
-    uint64_t Address = sectionTable.address(SegIndex, OffsetInSeg);
+  Error Err = Error::success();
+  for (const llvm::object::MachORebaseEntry &Entry : Obj->rebaseTable(Err)) {
+    StringRef SegmentName = Entry.segmentName();
+    StringRef SectionName = Entry.sectionName();
+    uint64_t Address = Entry.address();
 
     // Table lines look like: __DATA  __nl_symbol_ptr  0x0000F00C  pointer
     outs() << format("%-8s %-18s 0x%08" PRIX64 "  %s\n",
                      SegmentName.str().c_str(), SectionName.str().c_str(),
                      Address, Entry.typeName().str().c_str());
   }
+  if (Err)
+    report_error(Obj->getFileName(), std::move(Err));
 }
 
 static StringRef ordinalName(const object::MachOObjectFile *Obj, int Ordinal) {
@@ -9529,19 +9433,15 @@ static StringRef ordinalName(const objec
 // bind table dumping
 //===----------------------------------------------------------------------===//
 
-void llvm::printMachOBindTable(const object::MachOObjectFile *Obj) {
+void llvm::printMachOBindTable(object::MachOObjectFile *Obj) {
   // Build table of sections so names can used in final output.
-  SegInfo sectionTable(Obj);
-
   outs() << "segment  section            address    type       "
             "addend dylib            symbol\n";
   Error Err = Error::success();
   for (const llvm::object::MachOBindEntry &Entry : Obj->bindTable(Err)) {
-    uint32_t SegIndex = Entry.segmentIndex();
-    uint64_t OffsetInSeg = Entry.segmentOffset();
-    StringRef SegmentName = sectionTable.segmentName(SegIndex);
-    StringRef SectionName = sectionTable.sectionName(SegIndex, OffsetInSeg);
-    uint64_t Address = sectionTable.address(SegIndex, OffsetInSeg);
+    StringRef SegmentName = Entry.segmentName();
+    StringRef SectionName = Entry.sectionName();
+    uint64_t Address = Entry.address();
 
     // Table lines look like:
     //  __DATA  __got  0x00012010    pointer   0 libSystem ___stack_chk_guard
@@ -9564,19 +9464,14 @@ void llvm::printMachOBindTable(const obj
 // lazy bind table dumping
 //===----------------------------------------------------------------------===//
 
-void llvm::printMachOLazyBindTable(const object::MachOObjectFile *Obj) {
-  // Build table of sections so names can used in final output.
-  SegInfo sectionTable(Obj);
-
+void llvm::printMachOLazyBindTable(object::MachOObjectFile *Obj) {
   outs() << "segment  section            address     "
             "dylib            symbol\n";
   Error Err = Error::success();
   for (const llvm::object::MachOBindEntry &Entry : Obj->lazyBindTable(Err)) {
-    uint32_t SegIndex = Entry.segmentIndex();
-    uint64_t OffsetInSeg = Entry.segmentOffset();
-    StringRef SegmentName = sectionTable.segmentName(SegIndex);
-    StringRef SectionName = sectionTable.sectionName(SegIndex, OffsetInSeg);
-    uint64_t Address = sectionTable.address(SegIndex, OffsetInSeg);
+    StringRef SegmentName = Entry.segmentName();
+    StringRef SectionName = Entry.sectionName();
+    uint64_t Address = Entry.address();
 
     // Table lines look like:
     //  __DATA  __got  0x00012010 libSystem ___stack_chk_guard
@@ -9594,10 +9489,7 @@ void llvm::printMachOLazyBindTable(const
 // weak bind table dumping
 //===----------------------------------------------------------------------===//
 
-void llvm::printMachOWeakBindTable(const object::MachOObjectFile *Obj) {
-  // Build table of sections so names can used in final output.
-  SegInfo sectionTable(Obj);
-
+void llvm::printMachOWeakBindTable(object::MachOObjectFile *Obj) {
   outs() << "segment  section            address     "
             "type       addend   symbol\n";
   Error Err = Error::success();
@@ -9608,11 +9500,9 @@ void llvm::printMachOWeakBindTable(const
              << Entry.symbolName() << "\n";
       continue;
     }
-    uint32_t SegIndex = Entry.segmentIndex();
-    uint64_t OffsetInSeg = Entry.segmentOffset();
-    StringRef SegmentName = sectionTable.segmentName(SegIndex);
-    StringRef SectionName = sectionTable.sectionName(SegIndex, OffsetInSeg);
-    uint64_t Address = sectionTable.address(SegIndex, OffsetInSeg);
+    StringRef SegmentName = Entry.segmentName();
+    StringRef SectionName = Entry.sectionName();
+    uint64_t Address = Entry.address();
 
     // Table lines look like:
     // __DATA  __data  0x00001000  pointer    0   _foo
@@ -9635,17 +9525,9 @@ static const char *get_dyld_bind_info_sy
                                                  struct DisassembleInfo *info) {
   if (info->bindtable == nullptr) {
     info->bindtable = llvm::make_unique<SymbolAddressMap>();
-    SegInfo sectionTable(info->O);
     Error Err = Error::success();
     for (const llvm::object::MachOBindEntry &Entry : info->O->bindTable(Err)) {
-      uint32_t SegIndex = Entry.segmentIndex();
-      uint64_t OffsetInSeg = Entry.segmentOffset();
-      if (!sectionTable.isValidSegIndexAndOffset(SegIndex, OffsetInSeg)) {
-        if (Err)
-          report_error(info->O->getFileName(), std::move(Err));
-        return nullptr;
-      }
-      uint64_t Address = sectionTable.address(SegIndex, OffsetInSeg);
+      uint64_t Address = Entry.address();
       StringRef name = Entry.symbolName();
       if (!name.empty())
         (*info->bindtable)[Address] = name;

Modified: llvm/trunk/tools/llvm-objdump/llvm-objdump.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-objdump/llvm-objdump.cpp?rev=298292&r1=298291&r2=298292&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-objdump/llvm-objdump.cpp (original)
+++ llvm/trunk/tools/llvm-objdump/llvm-objdump.cpp Mon Mar 20 14:46:55 2017
@@ -1885,9 +1885,9 @@ void llvm::printExportsTrie(const Object
   }
 }
 
-void llvm::printRebaseTable(const ObjectFile *o) {
+void llvm::printRebaseTable(ObjectFile *o) {
   outs() << "Rebase table:\n";
-  if (const MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(o))
+  if (MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(o))
     printMachORebaseTable(MachO);
   else {
     errs() << "This operation is only currently supported "
@@ -1896,9 +1896,9 @@ void llvm::printRebaseTable(const Object
   }
 }
 
-void llvm::printBindTable(const ObjectFile *o) {
+void llvm::printBindTable(ObjectFile *o) {
   outs() << "Bind table:\n";
-  if (const MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(o))
+  if (MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(o))
     printMachOBindTable(MachO);
   else {
     errs() << "This operation is only currently supported "
@@ -1907,9 +1907,9 @@ void llvm::printBindTable(const ObjectFi
   }
 }
 
-void llvm::printLazyBindTable(const ObjectFile *o) {
+void llvm::printLazyBindTable(ObjectFile *o) {
   outs() << "Lazy bind table:\n";
-  if (const MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(o))
+  if (MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(o))
     printMachOLazyBindTable(MachO);
   else {
     errs() << "This operation is only currently supported "
@@ -1918,9 +1918,9 @@ void llvm::printLazyBindTable(const Obje
   }
 }
 
-void llvm::printWeakBindTable(const ObjectFile *o) {
+void llvm::printWeakBindTable(ObjectFile *o) {
   outs() << "Weak bind table:\n";
-  if (const MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(o))
+  if (MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(o))
     printMachOWeakBindTable(MachO);
   else {
     errs() << "This operation is only currently supported "
@@ -2018,7 +2018,7 @@ static void printPrivateFileHeaders(cons
   report_error(o->getFileName(), "Invalid/Unsupported object file format");
 }
 
-static void DumpObject(const ObjectFile *o, const Archive *a = nullptr) {
+static void DumpObject(ObjectFile *o, const Archive *a = nullptr) {
   StringRef ArchiveName = a != nullptr ? a->getFileName() : "";
   // Avoid other output when using a raw option.
   if (!RawClangAST) {

Modified: llvm/trunk/tools/llvm-objdump/llvm-objdump.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-objdump/llvm-objdump.h?rev=298292&r1=298291&r2=298292&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-objdump/llvm-objdump.h (original)
+++ llvm/trunk/tools/llvm-objdump/llvm-objdump.h Mon Mar 20 14:46:55 2017
@@ -70,10 +70,10 @@ void ParseInputMachO(StringRef Filename)
 void printCOFFUnwindInfo(const object::COFFObjectFile* o);
 void printMachOUnwindInfo(const object::MachOObjectFile* o);
 void printMachOExportsTrie(const object::MachOObjectFile* o);
-void printMachORebaseTable(const object::MachOObjectFile* o);
-void printMachOBindTable(const object::MachOObjectFile* o);
-void printMachOLazyBindTable(const object::MachOObjectFile* o);
-void printMachOWeakBindTable(const object::MachOObjectFile* o);
+void printMachORebaseTable(object::MachOObjectFile* o);
+void printMachOBindTable(object::MachOObjectFile* o);
+void printMachOLazyBindTable(object::MachOObjectFile* o);
+void printMachOWeakBindTable(object::MachOObjectFile* o);
 void printELFFileHeader(const object::ObjectFile *o);
 void printCOFFFileHeader(const object::ObjectFile *o);
 void printCOFFSymbolTable(const object::COFFImportFile *i);
@@ -82,10 +82,10 @@ void printMachOFileHeader(const object::
 void printMachOLoadCommands(const object::ObjectFile *o);
 void printWasmFileHeader(const object::ObjectFile *o);
 void printExportsTrie(const object::ObjectFile *o);
-void printRebaseTable(const object::ObjectFile *o);
-void printBindTable(const object::ObjectFile *o);
-void printLazyBindTable(const object::ObjectFile *o);
-void printWeakBindTable(const object::ObjectFile *o);
+void printRebaseTable(object::ObjectFile *o);
+void printBindTable(object::ObjectFile *o);
+void printLazyBindTable(object::ObjectFile *o);
+void printWeakBindTable(object::ObjectFile *o);
 void printRawClangAST(const object::ObjectFile *o);
 void PrintRelocations(const object::ObjectFile *o);
 void PrintSectionHeaders(const object::ObjectFile *o);




More information about the llvm-commits mailing list