// Copyright (c) 2010 Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

// Original author: Jim Blandy <jimb@mozilla.com> <jimb@red-bean.com>

// macho_reader_unittest.cc: Unit tests for google_breakpad::Mach_O::FatReader
// and google_breakpad::Mach_O::Reader.

#include <map>
#include <string>
#include <vector>

#include "breakpad_googletest_includes.h"
#include "common/mac/macho_reader.h"
#include "common/test_assembler.h"

namespace mach_o = google_breakpad::mach_o;
namespace test_assembler = google_breakpad::test_assembler;

using mach_o::FatReader;
using mach_o::FileFlags;
using mach_o::FileType;
using mach_o::LoadCommandType;
using mach_o::Reader;
using mach_o::Section;
using mach_o::SectionMap;
using mach_o::Segment;
using test_assembler::Endianness;
using test_assembler::Label;
using test_assembler::kBigEndian;
using test_assembler::kLittleEndian;
using test_assembler::kUnsetEndian;
using google_breakpad::ByteBuffer;
using std::map;
using std::string;
using std::vector;
using testing::AllOf;
using testing::DoAll;
using testing::Field;
using testing::InSequence;
using testing::Matcher;
using testing::Return;
using testing::SaveArg;
using testing::Test;
using testing::_;


// Mock classes for the reader's various reporters and handlers.

class MockFatReaderReporter: public FatReader::Reporter {
 public:
  MockFatReaderReporter(const string &filename)
      : FatReader::Reporter(filename) { }
  MOCK_METHOD0(BadHeader, void());
  MOCK_METHOD0(MisplacedObjectFile, void());
  MOCK_METHOD0(TooShort, void());
};

class MockReaderReporter: public Reader::Reporter {
 public:
  MockReaderReporter(const string &filename) : Reader::Reporter(filename) { }
  MOCK_METHOD0(BadHeader, void());
  MOCK_METHOD4(CPUTypeMismatch, void(cpu_type_t cpu_type,
                                     cpu_subtype_t cpu_subtype,
                                     cpu_type_t expected_cpu_type,
                                     cpu_subtype_t expected_cpu_subtype));
  MOCK_METHOD0(HeaderTruncated, void());
  MOCK_METHOD0(LoadCommandRegionTruncated, void());
  MOCK_METHOD3(LoadCommandsOverrun, void(size_t claimed, size_t i,
                                         LoadCommandType type));
  MOCK_METHOD2(LoadCommandTooShort, void(size_t i, LoadCommandType type));
  MOCK_METHOD1(SectionsMissing, void(const string &name));
  MOCK_METHOD1(MisplacedSegmentData, void(const string &name));
  MOCK_METHOD2(MisplacedSectionData, void(const string &section,
                                          const string &segment));
  MOCK_METHOD0(MisplacedSymbolTable, void());
  MOCK_METHOD1(UnsupportedCPUType, void(cpu_type_t cpu_type));
};

class MockLoadCommandHandler: public Reader::LoadCommandHandler {
 public:
  MOCK_METHOD2(UnknownCommand, bool(LoadCommandType, const ByteBuffer &));
  MOCK_METHOD1(SegmentCommand, bool(const Segment &));
  MOCK_METHOD2(SymtabCommand,  bool(const ByteBuffer &, const ByteBuffer &));
};

class MockSectionHandler: public Reader::SectionHandler {
 public:
  MOCK_METHOD1(HandleSection, bool(const Section &section));
};


// Tests for mach_o::FatReader.

// Since the effect of these functions is to write to stderr, the
// results of these tests must be inspected by hand.
TEST(FatReaderReporter, BadHeader) {
  FatReader::Reporter reporter("filename");
  reporter.BadHeader();
}

TEST(FatReaderReporter, MisplacedObjectFile) {
  FatReader::Reporter reporter("filename");
  reporter.MisplacedObjectFile();
}

TEST(FatReaderReporter, TooShort) {
  FatReader::Reporter reporter("filename");
  reporter.TooShort();
}

TEST(MachOReaderReporter, BadHeader) {
  Reader::Reporter reporter("filename");
  reporter.BadHeader();
}

TEST(MachOReaderReporter, CPUTypeMismatch) {
  Reader::Reporter reporter("filename");
  reporter.CPUTypeMismatch(CPU_TYPE_I386, CPU_SUBTYPE_X86_ALL,
                           CPU_TYPE_POWERPC, CPU_SUBTYPE_POWERPC_ALL);
}

TEST(MachOReaderReporter, HeaderTruncated) {
  Reader::Reporter reporter("filename");
  reporter.HeaderTruncated();
}

TEST(MachOReaderReporter, LoadCommandRegionTruncated) {
  Reader::Reporter reporter("filename");
  reporter.LoadCommandRegionTruncated();
}

TEST(MachOReaderReporter, LoadCommandsOverrun) {
  Reader::Reporter reporter("filename");
  reporter.LoadCommandsOverrun(10, 9, LC_DYSYMTAB);
  reporter.LoadCommandsOverrun(10, 9, 0);
}

TEST(MachOReaderReporter, LoadCommandTooShort) {
  Reader::Reporter reporter("filename");
  reporter.LoadCommandTooShort(11, LC_SYMTAB);
}

TEST(MachOReaderReporter, SectionsMissing) {
  Reader::Reporter reporter("filename");
  reporter.SectionsMissing("segment name");
}

TEST(MachOReaderReporter, MisplacedSegmentData) {
  Reader::Reporter reporter("filename");
  reporter.MisplacedSegmentData("segment name");
}

TEST(MachOReaderReporter, MisplacedSectionData) {
  Reader::Reporter reporter("filename");
  reporter.MisplacedSectionData("section name", "segment name");
}

TEST(MachOReaderReporter, MisplacedSymbolTable) {
  Reader::Reporter reporter("filename");
  reporter.MisplacedSymbolTable();
}

TEST(MachOReaderReporter, UnsupportedCPUType) {
  Reader::Reporter reporter("filename");
  reporter.UnsupportedCPUType(CPU_TYPE_HPPA);
}

struct FatReaderFixture {
  FatReaderFixture()
      : fat(kBigEndian),
        reporter("reporter filename"),
        reader(&reporter), object_files() {
    EXPECT_CALL(reporter, BadHeader()).Times(0);
    EXPECT_CALL(reporter, TooShort()).Times(0);

    // here, start, and Mark are file offsets in 'fat'.
    fat.start() = 0;
  }
  // Append a 'fat_arch' entry to 'fat', with the given field values.
  void AppendFatArch(cpu_type_t type, cpu_subtype_t subtype,
                     Label offset, Label size, uint32_t align) {
    fat
        .B32(type)
        .B32(subtype)
        .B32(offset)
        .B32(size)
        .B32(align);
  }
  // Append |n| dummy 'fat_arch' entries to 'fat'. The cpu type and
  // subtype have unrealistic values.
  void AppendDummyArchEntries(int n) {
    for (int i = 0; i < n; i++)
      AppendFatArch(0xb68ad617, 0x715a0840, 0, 0, 1);
  }
  void ReadFat(bool expect_parse_success = true) {
    ASSERT_TRUE(fat.GetContents(&contents));
    fat_bytes = reinterpret_cast<const uint8_t *>(contents.data());
    if (expect_parse_success) {
      EXPECT_TRUE(reader.Read(fat_bytes, contents.size()));
      size_t fat_files_count;
      const SuperFatArch* fat_files = reader.object_files(&fat_files_count);
      object_files.resize(fat_files_count);
      for (size_t i = 0; i < fat_files_count; ++i) {
        EXPECT_TRUE(fat_files[i].ConvertToFatArch(&object_files[i]));
      }
    }
    else
      EXPECT_FALSE(reader.Read(fat_bytes, contents.size()));
  }
  test_assembler::Section fat;
  MockFatReaderReporter reporter;
  FatReader reader;
  string contents;
  const uint8_t *fat_bytes;
  vector<struct fat_arch> object_files;
};

class FatReaderTest: public FatReaderFixture, public Test { };

TEST_F(FatReaderTest, BadMagic) {
  EXPECT_CALL(reporter, BadHeader()).Times(1);
  fat
      .B32(0xcafed00d)           // magic number (incorrect)
      .B32(10);                  // number of architectures
  AppendDummyArchEntries(10);
  ReadFat(false);
}

TEST_F(FatReaderTest, HeaderTooShort) {
  EXPECT_CALL(reporter, TooShort()).Times(1);
  fat
      .B32(0xcafebabe);             // magic number
  ReadFat(false);
}

TEST_F(FatReaderTest, ObjectListTooShort) {
  EXPECT_CALL(reporter, TooShort()).Times(1);
  fat
      .B32(0xcafebabe)              // magic number
      .B32(10);                     // number of architectures
  AppendDummyArchEntries(9);        // nine dummy architecture entries...
  fat                               // and a tenth, missing a byte at the end
      .B32(0x3d46c8fc)              // cpu type
      .B32(0x8a7bfb01)              // cpu subtype
      .B32(0)                       // offset
      .B32(0)                       // size
      .Append(3, '*');              // one byte short of a four-byte alignment
  ReadFat(false);
}

TEST_F(FatReaderTest, DataTooShort) {
  EXPECT_CALL(reporter, MisplacedObjectFile()).Times(1);
  Label arch_data;
  fat
      .B32(0xcafebabe)              // magic number
      .B32(1);                      // number of architectures
  AppendFatArch(0xb4d4a366, 0x4ba4f525, arch_data, 40, 0);
  fat
      .Mark(&arch_data)             // file data begins here
      .Append(30, '*');             // only 30 bytes, not 40 as header claims
  ReadFat(false);
}

TEST_F(FatReaderTest, NoObjectFiles) {
  fat
      .B32(0xcafebabe)              // magic number
      .B32(0);                      // number of architectures
  ReadFat();
  EXPECT_EQ(0U, object_files.size());
}

TEST_F(FatReaderTest, OneObjectFile) {
  Label obj1_offset;
  fat
      .B32(0xcafebabe)              // magic number
      .B32(1);                      // number of architectures
  // First object file list entry
  AppendFatArch(0x5e3a6e91, 0x52ccd852, obj1_offset, 0x42, 0x355b15b2);
  // First object file data
  fat
      .Mark(&obj1_offset)           
      .Append(0x42, '*');           // dummy contents
  ReadFat();
  ASSERT_EQ(1U, object_files.size());
  EXPECT_EQ(0x5e3a6e91, object_files[0].cputype);
  EXPECT_EQ(0x52ccd852, object_files[0].cpusubtype);
  EXPECT_EQ(obj1_offset.Value(), object_files[0].offset);
  EXPECT_EQ(0x42U, object_files[0].size);
  EXPECT_EQ(0x355b15b2U, object_files[0].align);
}

TEST_F(FatReaderTest, ThreeObjectFiles) {
  Label obj1, obj2, obj3;
  fat
      .B32(0xcafebabe)              // magic number
      .B32(3);                      // number of architectures
  // Three object file list entries.
  AppendFatArch(0x0cb92c30, 0x6a159a71, obj1, 0xfb4, 0x2615dbe8);
  AppendFatArch(0x0f3f1cbb, 0x6c55e90f, obj2, 0xc31, 0x83af6ffd);
  AppendFatArch(0x3717276d, 0x10ecdc84, obj3, 0x4b3, 0x035267d7);
  fat
      // First object file data
      .Mark(&obj1)           
      .Append(0xfb4, '*')           // dummy contents
      // Second object file data
      .Mark(&obj2)           
      .Append(0xc31, '%')           // dummy contents
      // Third object file data
      .Mark(&obj3)           
      .Append(0x4b3, '^');          // dummy contents
  
  ReadFat();

  ASSERT_EQ(3U, object_files.size());

  // First object file.
  EXPECT_EQ(0x0cb92c30, object_files[0].cputype);
  EXPECT_EQ(0x6a159a71, object_files[0].cpusubtype);
  EXPECT_EQ(obj1.Value(), object_files[0].offset);
  EXPECT_EQ(0xfb4U, object_files[0].size);
  EXPECT_EQ(0x2615dbe8U, object_files[0].align);

  // Second object file.
  EXPECT_EQ(0x0f3f1cbb, object_files[1].cputype);
  EXPECT_EQ(0x6c55e90f, object_files[1].cpusubtype);
  EXPECT_EQ(obj2.Value(), object_files[1].offset);
  EXPECT_EQ(0xc31U, object_files[1].size);
  EXPECT_EQ(0x83af6ffdU, object_files[1].align);

  // Third object file.
  EXPECT_EQ(0x3717276d, object_files[2].cputype);
  EXPECT_EQ(0x10ecdc84, object_files[2].cpusubtype);
  EXPECT_EQ(obj3.Value(), object_files[2].offset);
  EXPECT_EQ(0x4b3U, object_files[2].size);
  EXPECT_EQ(0x035267d7U, object_files[2].align);
}

TEST_F(FatReaderTest, BigEndianMachO32) {
  fat.set_endianness(kBigEndian);
  fat
      .D32(0xfeedface)                  // Mach-O file magic number
      .D32(0x1a9d0518)                  // cpu type
      .D32(0x1b779357)                  // cpu subtype
      .D32(0x009df67e)                  // file type
      .D32(0)                           // no load commands
      .D32(0)                           // the load commands occupy no bytes
      .D32(0x21987a99);                 // flags

  ReadFat();

  // FatReader should treat a Mach-O file as if it were a fat binary file
  // containing one object file --- the whole thing.
  ASSERT_EQ(1U, object_files.size());
  EXPECT_EQ(0x1a9d0518, object_files[0].cputype);
  EXPECT_EQ(0x1b779357, object_files[0].cpusubtype);
  EXPECT_EQ(0U, object_files[0].offset);
  EXPECT_EQ(contents.size(), object_files[0].size);
}

TEST_F(FatReaderTest, BigEndianMachO64) {
  fat.set_endianness(kBigEndian);
  fat
      .D32(0xfeedfacf)                  // Mach-O 64-bit file magic number
      .D32(0x5aff8487)                  // cpu type
      .D32(0x4c6a57f7)                  // cpu subtype
      .D32(0x4392d2c8)                  // file type
      .D32(0)                           // no load commands
      .D32(0)                           // the load commands occupy no bytes
      .D32(0x1b033eea);                 // flags

  ReadFat();

  // FatReader should treat a Mach-O file as if it were a fat binary file
  // containing one object file --- the whole thing.
  ASSERT_EQ(1U, object_files.size());
  EXPECT_EQ(0x5aff8487, object_files[0].cputype);
  EXPECT_EQ(0x4c6a57f7, object_files[0].cpusubtype);
  EXPECT_EQ(0U, object_files[0].offset);
  EXPECT_EQ(contents.size(), object_files[0].size);
}

TEST_F(FatReaderTest, LittleEndianMachO32) {
  fat.set_endianness(kLittleEndian);
  fat
      .D32(0xfeedface)                  // Mach-O file magic number
      .D32(0x1a9d0518)                  // cpu type
      .D32(0x1b779357)                  // cpu subtype
      .D32(0x009df67e)                  // file type
      .D32(0)                           // no load commands
      .D32(0)                           // the load commands occupy no bytes
      .D32(0x21987a99);                 // flags

  ReadFat();

  // FatReader should treat a Mach-O file as if it were a fat binary file
  // containing one object file --- the whole thing.
  ASSERT_EQ(1U, object_files.size());
  EXPECT_EQ(0x1a9d0518, object_files[0].cputype);
  EXPECT_EQ(0x1b779357, object_files[0].cpusubtype);
  EXPECT_EQ(0U, object_files[0].offset);
  EXPECT_EQ(contents.size(), object_files[0].size);
}

TEST_F(FatReaderTest, LittleEndianMachO64) {
  fat.set_endianness(kLittleEndian);
  fat
      .D32(0xfeedfacf)                  // Mach-O 64-bit file magic number
      .D32(0x5aff8487)                  // cpu type
      .D32(0x4c6a57f7)                  // cpu subtype
      .D32(0x4392d2c8)                  // file type
      .D32(0)                           // no load commands
      .D32(0)                           // the load commands occupy no bytes
      .D32(0x1b033eea);                 // flags

  ReadFat();

  // FatReader should treat a Mach-O file as if it were a fat binary file
  // containing one object file --- the whole thing.
  ASSERT_EQ(1U, object_files.size());
  EXPECT_EQ(0x5aff8487, object_files[0].cputype);
  EXPECT_EQ(0x4c6a57f7, object_files[0].cpusubtype);
  EXPECT_EQ(0U, object_files[0].offset);
  EXPECT_EQ(contents.size(), object_files[0].size);
}

TEST_F(FatReaderTest, IncompleteMach) {
  fat.set_endianness(kLittleEndian);
  fat
      .D32(0xfeedfacf)                  // Mach-O 64-bit file magic number
      .D32(0x5aff8487);                 // cpu type
      // Truncated!

  EXPECT_CALL(reporter, TooShort()).WillOnce(Return());

  ReadFat(false);
}


// General mach_o::Reader tests.

// Dynamically scoped configuration data.
class WithConfiguration {
 public:
  // Establish the given parameters as the default for SizedSections
  // created within the dynamic scope of this instance.
  WithConfiguration(Endianness endianness, size_t word_size)
      : endianness_(endianness), word_size_(word_size), saved_(current_) {
    current_ = this;
  }
  ~WithConfiguration() { current_ = saved_; }
  static Endianness endianness() { 
    assert(current_);
    return current_->endianness_;
  }
  static size_t word_size() { 
    assert(current_);
    return current_->word_size_;
  }

 private:
  // The innermost WithConfiguration in whose dynamic scope we are
  // currently executing.
  static WithConfiguration *current_;

  // The innermost WithConfiguration whose dynamic scope encloses this
  // WithConfiguration.
  Endianness endianness_;
  size_t word_size_;
  WithConfiguration *saved_;
};

WithConfiguration *WithConfiguration::current_ = NULL;

// A test_assembler::Section with a size that we can cite. The start(),
// Here() and Mark() member functions of a SizedSection always represent
// offsets within the overall file.
class SizedSection: public test_assembler::Section {
 public:
  // Construct a section of the given endianness and word size.
  explicit SizedSection(Endianness endianness, size_t word_size)
      : test_assembler::Section(endianness), word_size_(word_size) {
    assert(word_size_ == 32 || word_size_ == 64);
  }
  SizedSection()
      : test_assembler::Section(WithConfiguration::endianness()),
        word_size_(WithConfiguration::word_size()) {
    assert(word_size_ == 32 || word_size_ == 64);
  }

  // Access/set this section's word size.
  size_t word_size() const { return word_size_; }
  void set_word_size(size_t word_size) { 
    assert(word_size_ == 32 || word_size_ == 64);
    word_size_ = word_size;
  }

  // Return a label representing the size this section will have when it
  // is Placed in some containing section.
  Label final_size() const { return final_size_; }

  // Append SECTION to the end of this section, and call its Finish member.
  // Return a reference to this section.
  SizedSection &Place(SizedSection *section) {
    assert(section->endianness() == endianness());
    section->Finish();
    section->start() = Here();
    test_assembler::Section::Append(*section);
    return *this;
  }

 protected:
  // Mark this section's contents as complete. For plain SizedSections, we
  // set SECTION's start to its position in this section, and its final_size
  // label to its current size. Derived classes can extend this as needed
  // for their additional semantics.
  virtual void Finish() {
    final_size_ = Size();
  }

  // The word size for this data: either 32 or 64.
  size_t word_size_;

 private:
  // This section's final size, set when we are placed in some other
  // SizedSection.
  Label final_size_;
};

// A SizedSection that is loaded into memory at a particular address.
class LoadedSection: public SizedSection {
 public:
  explicit LoadedSection(Label address = Label()) : address_(address) { }

  // Return a label representing this section's address.
  Label address() const { return address_; }

  // Placing a loaded section within a loaded section sets the relationship
  // between their addresses.
  LoadedSection &Place(LoadedSection *section) {
    section->address() = address() + Size();
    SizedSection::Place(section);
    return *this;
  }

 protected:
  // The address at which this section's contents will be loaded.
  Label address_;
};
  
// A SizedSection representing a segment load command.
class SegmentLoadCommand: public SizedSection {
 public:
  SegmentLoadCommand() : section_count_(0) { }

  // Append a segment load command header with the given characteristics.
  // The load command will refer to CONTENTS, which must be Placed in the
  // file separately, at the desired position. Return a reference to this
  // section.
  SegmentLoadCommand &Header(const string &name, const LoadedSection &contents,
                             uint32_t maxprot, uint32_t initprot,
                             uint32_t flags) {
    assert(contents.word_size() == word_size());
    D32(word_size() == 32 ? LC_SEGMENT : LC_SEGMENT_64);
    D32(final_size());
    AppendCString(name, 16);
    Append(endianness(), word_size() / 8, contents.address());
    Append(endianness(), word_size() / 8, vmsize_);
    Append(endianness(), word_size() / 8, contents.start());
    Append(endianness(), word_size() / 8, contents.final_size());
    D32(maxprot);
    D32(initprot);
    D32(final_section_count_);
    D32(flags);

    content_final_size_ = contents.final_size();

    return *this;
  }

  // Return a label representing the size of this segment when loaded into
  // memory. If this label is still undefined by the time we place this
  // segment, it defaults to the final size of the segment's in-file
  // contents. Return a reference to this load command.
  Label &vmsize() { return vmsize_; }

  // Add a section entry with the given characteristics to this segment
  // load command. Return a reference to this. The section entry will refer
  // to CONTENTS, which must be Placed in the segment's contents
  // separately, at the desired position.
  SegmentLoadCommand &AppendSectionEntry(const string &section_name,
                                         const string &segment_name,
                                         uint32_t alignment, uint32_t flags,
                                         const LoadedSection &contents) {
    AppendCString(section_name, 16);
    AppendCString(segment_name, 16);
    Append(endianness(), word_size() / 8, contents.address());
    Append(endianness(), word_size() / 8, contents.final_size());
    D32(contents.start());
    D32(alignment);
    D32(0);                  // relocations start
    D32(0);                  // relocations size
    D32(flags);
    D32(0x93656b95);         // reserved1
    D32(0xc35a2473);         // reserved2
    if (word_size() == 64)
      D32(0x70284b95);       // reserved3

    section_count_++;

    return *this;
  }

 protected:
  void Finish() {
    final_section_count_ = section_count_;
    if (!vmsize_.IsKnownConstant())
      vmsize_ = content_final_size_;
    SizedSection::Finish();
  }

 private:
  // The number of sections that have been added to this segment so far.
  size_t section_count_;

  // A label representing the final number of sections this segment will hold.
  Label final_section_count_;

  // The size of the contents for this segment present in the file.
  Label content_final_size_;

  // A label representing the size of this segment when loaded; this can be
  // larger than the size of its file contents, the difference being
  // zero-filled. If not set explicitly by calling set_vmsize, this is set
  // equal to the size of the contents.
  Label vmsize_;
};

// A SizedSection holding a list of Mach-O load commands.
class LoadCommands: public SizedSection {
 public:
  LoadCommands() : command_count_(0) { }

  // Return a label representing the final load command count.
  Label final_command_count() const { return final_command_count_; }

  // Increment the command count; return a reference to this section.
  LoadCommands &CountCommand() {
    command_count_++;
    return *this;
  }

  // Place COMMAND, containing a load command, at the end of this section.
  // Return a reference to this section.
  LoadCommands &Place(SizedSection *section) {
    SizedSection::Place(section);
    CountCommand();
    return *this;
  }

 protected:
  // Mark this load command list as complete.
  void Finish() {
    SizedSection::Finish();
    final_command_count_ = command_count_;
  }

 private:
  // The number of load commands we have added to this file so far.
  size_t command_count_;

  // A label representing the final command count.
  Label final_command_count_;
};

// A SizedSection holding the contents of a Mach-O file. Within a
// MachOFile, the start, Here, and Mark members refer to file offsets.
class MachOFile: public SizedSection {
 public:
  MachOFile() { 
    start() = 0;
  }

  // Create a Mach-O file header using the given characteristics and load
  // command list. This Places COMMANDS immediately after the header.
  // Return a reference to this section.
  MachOFile &Header(LoadCommands *commands,
                    cpu_type_t cpu_type = CPU_TYPE_X86,
                    cpu_subtype_t cpu_subtype = CPU_SUBTYPE_I386_ALL,
                    FileType file_type = MH_EXECUTE,
                    uint32_t file_flags = (MH_TWOLEVEL |
                                           MH_DYLDLINK |
                                           MH_NOUNDEFS)) {
    D32(word_size() == 32 ? 0xfeedface : 0xfeedfacf);  // magic number
    D32(cpu_type);                              // cpu type
    D32(cpu_subtype);                           // cpu subtype
    D32(file_type);                             // file type
    D32(commands->final_command_count());       // number of load commands
    D32(commands->final_size());                // their size in bytes
    D32(file_flags);                            // flags
    if (word_size() == 64)
      D32(0x55638b90);                          // reserved
    Place(commands);
    return *this;
  }
};


struct ReaderFixture {
  ReaderFixture()
      : reporter("reporter filename"),
        reader(&reporter) { 
    EXPECT_CALL(reporter, BadHeader()).Times(0);
    EXPECT_CALL(reporter, CPUTypeMismatch(_, _, _, _)).Times(0);
    EXPECT_CALL(reporter, HeaderTruncated()).Times(0);
    EXPECT_CALL(reporter, LoadCommandRegionTruncated()).Times(0);
    EXPECT_CALL(reporter, LoadCommandsOverrun(_, _, _)).Times(0);
    EXPECT_CALL(reporter, LoadCommandTooShort(_, _)).Times(0);
    EXPECT_CALL(reporter, SectionsMissing(_)).Times(0);
    EXPECT_CALL(reporter, MisplacedSegmentData(_)).Times(0);
    EXPECT_CALL(reporter, MisplacedSectionData(_, _)).Times(0);
    EXPECT_CALL(reporter, MisplacedSymbolTable()).Times(0);
    EXPECT_CALL(reporter, UnsupportedCPUType(_)).Times(0);

    EXPECT_CALL(load_command_handler, UnknownCommand(_, _)).Times(0);
    EXPECT_CALL(load_command_handler, SegmentCommand(_)).Times(0);
  }

  void ReadFile(MachOFile *file,
                bool expect_parse_success,
                cpu_type_t expected_cpu_type,
                cpu_subtype_t expected_cpu_subtype) {
    ASSERT_TRUE(file->GetContents(&file_contents));
    file_bytes = reinterpret_cast<const uint8_t *>(file_contents.data());
    if (expect_parse_success) {
      EXPECT_TRUE(reader.Read(file_bytes,
                              file_contents.size(),
                              expected_cpu_type,
                              expected_cpu_subtype));
    } else {
      EXPECT_FALSE(reader.Read(file_bytes,
                               file_contents.size(),
                               expected_cpu_type,
                               expected_cpu_subtype));
    }
  }

  string file_contents;
  const uint8_t *file_bytes;
  MockReaderReporter reporter;
  Reader reader;
  MockLoadCommandHandler load_command_handler;
  MockSectionHandler section_handler;
};

class ReaderTest: public ReaderFixture, public Test { };

TEST_F(ReaderTest, BadMagic) {
  WithConfiguration config(kLittleEndian, 32);
  const cpu_type_t kCPUType = 0x46b760df;
  const cpu_subtype_t kCPUSubType = 0x76a0e7f7;
  MachOFile file;
  file
      .D32(0x67bdebe1)                  // Not a proper magic number.
      .D32(kCPUType)                    // cpu type
      .D32(kCPUSubType)                 // cpu subtype
      .D32(0x149fc717)                  // file type
      .D32(0)                           // no load commands
      .D32(0)                           // they occupy no bytes
      .D32(0x80e71d64)                  // flags
      .D32(0);                          // reserved
  EXPECT_CALL(reporter, BadHeader()).WillOnce(Return());
  ReadFile(&file, false, CPU_TYPE_ANY, kCPUSubType);
}

TEST_F(ReaderTest, MismatchedMagic) {
  WithConfiguration config(kLittleEndian, 32);
  const cpu_type_t kCPUType = CPU_TYPE_I386;
  const cpu_subtype_t kCPUSubType = CPU_SUBTYPE_X86_ALL;
  MachOFile file;
  file
      .D32(MH_CIGAM)                    // Right magic, but winds up wrong
                                        // due to bitswapping
      .D32(kCPUType)                    // cpu type
      .D32(kCPUSubType)                 // cpu subtype
      .D32(0x149fc717)                  // file type
      .D32(0)                           // no load commands
      .D32(0)                           // they occupy no bytes
      .D32(0x80e71d64)                  // flags
      .D32(0);                          // reserved
  EXPECT_CALL(reporter, BadHeader()).WillOnce(Return());
  ReadFile(&file, false, kCPUType, kCPUSubType);
}

TEST_F(ReaderTest, ShortMagic) {
  WithConfiguration config(kBigEndian, 32);
  MachOFile file;
  file
      .D16(0xfeed);                     // magic number
                                        // truncated!
  EXPECT_CALL(reporter, HeaderTruncated()).WillOnce(Return());
  ReadFile(&file, false, CPU_TYPE_ANY, 0);
}

TEST_F(ReaderTest, ShortHeader) {
  WithConfiguration config(kBigEndian, 32);
  const cpu_type_t kCPUType = CPU_TYPE_ANY;
  const cpu_subtype_t kCPUSubType = 0x76a0e7f7;
  MachOFile file;
  file
      .D32(0xfeedface)                  // magic number
      .D32(kCPUType)                    // cpu type
      .D32(kCPUSubType)                 // cpu subtype
      .D32(0x149fc717)                  // file type
      .D32(0)                           // no load commands
      .D32(0);                          // they occupy no bytes
  EXPECT_CALL(reporter, HeaderTruncated()).WillOnce(Return());
  ReadFile(&file, false, CPU_TYPE_ANY, kCPUSubType);
}

TEST_F(ReaderTest, MismatchedCPU) {
  WithConfiguration config(kBigEndian, 32);
  const cpu_type_t kCPUType = CPU_TYPE_I386;
  const cpu_subtype_t kCPUSubType = CPU_SUBTYPE_X86_ALL;
  MachOFile file;
  file
      .D32(MH_MAGIC)                    // Right magic for PPC (once bitswapped)
      .D32(kCPUType)                    // cpu type
      .D32(kCPUSubType)                 // cpu subtype
      .D32(0x149fc717)                  // file type
      .D32(0)                           // no load commands
      .D32(0)                           // they occupy no bytes
      .D32(0x80e71d64)                  // flags
      .D32(0);                          // reserved
  EXPECT_CALL(reporter,
              CPUTypeMismatch(CPU_TYPE_I386, CPU_SUBTYPE_X86_ALL,
                              CPU_TYPE_POWERPC, CPU_SUBTYPE_POWERPC_ALL))
    .WillOnce(Return());
  ReadFile(&file, false, CPU_TYPE_POWERPC, CPU_SUBTYPE_POWERPC_ALL);
}

TEST_F(ReaderTest, LittleEndian32Bit) {
  WithConfiguration config(kLittleEndian, 32);
  const cpu_type_t kCPUType = 0x46b760df;
  const cpu_subtype_t kCPUSubType = 0x76a0e7f7;
  MachOFile file;
  file
      .D32(0xfeedface)                  // magic number
      .D32(kCPUType)                    // cpu type
      .D32(kCPUSubType)                 // cpu subtype
      .D32(0x149fc717)                  // file type
      .D32(0)                           // no load commands
      .D32(0)                           // they occupy no bytes
      .D32(0x80e71d64)                  // flags
      .D32(0);                          // reserved
           ReadFile(&file, true, CPU_TYPE_ANY, kCPUSubType);
  EXPECT_FALSE(reader.bits_64());
  EXPECT_FALSE(reader.big_endian());
  EXPECT_EQ(kCPUType,               reader.cpu_type());
  EXPECT_EQ(kCPUSubType,            reader.cpu_subtype());
  EXPECT_EQ(FileType(0x149fc717),   reader.file_type());
  EXPECT_EQ(FileFlags(0x80e71d64),  reader.flags());
}

TEST_F(ReaderTest, LittleEndian64Bit) {
  WithConfiguration config(kLittleEndian, 64);
  const cpu_type_t kCPUType = 0x46b760df;
  const cpu_subtype_t kCPUSubType = 0x76a0e7f7;
  MachOFile file;
  file
      .D32(0xfeedfacf)                  // magic number
      .D32(kCPUType)                    // cpu type
      .D32(kCPUSubType)                 // cpu subtype
      .D32(0x149fc717)                  // file type
      .D32(0)                           // no load commands
      .D32(0)                           // they occupy no bytes
      .D32(0x80e71d64)                  // flags
      .D32(0);                          // reserved
  ReadFile(&file, true, CPU_TYPE_ANY, kCPUSubType);
  EXPECT_TRUE(reader.bits_64());
  EXPECT_FALSE(reader.big_endian());
  EXPECT_EQ(kCPUType,               reader.cpu_type());
  EXPECT_EQ(kCPUSubType,            reader.cpu_subtype());
  EXPECT_EQ(FileType(0x149fc717),   reader.file_type());
  EXPECT_EQ(FileFlags(0x80e71d64),  reader.flags());
}

TEST_F(ReaderTest, BigEndian32Bit) {
  WithConfiguration config(kBigEndian, 32);
  const cpu_type_t kCPUType = 0x46b760df;
  const cpu_subtype_t kCPUSubType = 0x76a0e7f7;
  MachOFile file;
  file
      .D32(0xfeedface)                  // magic number
      .D32(kCPUType)                    // cpu type
      .D32(kCPUSubType)                 // cpu subtype
      .D32(0x149fc717)                  // file type
      .D32(0)                           // no load commands
      .D32(0)                           // they occupy no bytes
      .D32(0x80e71d64)                  // flags
      .D32(0);                          // reserved
  ReadFile(&file, true, CPU_TYPE_ANY, kCPUSubType);
  EXPECT_FALSE(reader.bits_64());
  EXPECT_TRUE(reader.big_endian());
  EXPECT_EQ(kCPUType,               reader.cpu_type());
  EXPECT_EQ(kCPUSubType,            reader.cpu_subtype());
  EXPECT_EQ(FileType(0x149fc717),   reader.file_type());
  EXPECT_EQ(FileFlags(0x80e71d64),  reader.flags());
}

TEST_F(ReaderTest, BigEndian64Bit) {
  WithConfiguration config(kBigEndian, 64);
  const cpu_type_t kCPUType = 0x46b760df;
  const cpu_subtype_t kCPUSubType = 0x76a0e7f7;
  MachOFile file;
  file
      .D32(0xfeedfacf)                  // magic number
      .D32(kCPUType)                    // cpu type
      .D32(kCPUSubType)                 // cpu subtype
      .D32(0x149fc717)                  // file type
      .D32(0)                           // no load commands
      .D32(0)                           // they occupy no bytes
      .D32(0x80e71d64)                  // flags
      .D32(0);                          // reserved
  ReadFile(&file, true, CPU_TYPE_ANY, kCPUSubType);
  EXPECT_TRUE(reader.bits_64());
  EXPECT_TRUE(reader.big_endian());
  EXPECT_EQ(kCPUType,               reader.cpu_type());
  EXPECT_EQ(kCPUSubType,            reader.cpu_subtype());
  EXPECT_EQ(FileType(0x149fc717),   reader.file_type());
  EXPECT_EQ(FileFlags(0x80e71d64),  reader.flags());
}


// Load command tests.

class LoadCommand: public ReaderFixture, public Test { };

TEST_F(LoadCommand, RegionTruncated) {
  WithConfiguration config(kBigEndian, 64);
  const cpu_type_t kCPUType = 0x46b760df;
  const cpu_subtype_t kCPUSubType = 0x76a0e7f7;
  MachOFile file;
  file
      .D32(0xfeedfacf)                  // magic number
      .D32(kCPUType)                    // cpu type
      .D32(kCPUSubType)                 // cpu subtype
      .D32(0x149fc717)                  // file type
      .D32(1)                           // one load command
      .D32(40)                          // occupying 40 bytes
      .D32(0x80e71d64)                  // flags
      .D32(0)                           // reserved
      .Append(20, 0);                   // load command region, not as long as
                                        // Mach-O header promised

  EXPECT_CALL(reporter, LoadCommandRegionTruncated()).WillOnce(Return());

  ReadFile(&file, false, CPU_TYPE_ANY, kCPUSubType);
}

TEST_F(LoadCommand, None) {
  WithConfiguration config(kLittleEndian, 32);
  LoadCommands load_commands;
  MachOFile file;
  file.Header(&load_commands);

  ReadFile(&file, true, CPU_TYPE_X86, CPU_SUBTYPE_I386_ALL);

  EXPECT_FALSE(reader.bits_64());
  EXPECT_FALSE(reader.big_endian());
  EXPECT_EQ(CPU_TYPE_X86,         reader.cpu_type());
  EXPECT_EQ(CPU_SUBTYPE_I386_ALL, reader.cpu_subtype());
  EXPECT_EQ(static_cast<uint32_t>(MH_EXECUTE), reader.file_type());
  EXPECT_EQ(FileFlags(MH_TWOLEVEL |
                      MH_DYLDLINK |
                      MH_NOUNDEFS),
            FileFlags(reader.flags()));
  
  EXPECT_TRUE(reader.WalkLoadCommands(&load_command_handler));
}

TEST_F(LoadCommand, Unknown) {
  WithConfiguration config(kBigEndian, 32);
  LoadCommands load_commands;
  load_commands
      .CountCommand()
      .D32(0x33293d4a)                  // unknown load command
      .D32(40)                          // total size in bytes
      .Append(32, '*');                 // dummy data
  MachOFile file;
  file.Header(&load_commands);

  ReadFile(&file, true, CPU_TYPE_ANY, 0);

  EXPECT_FALSE(reader.bits_64());
  EXPECT_TRUE(reader.big_endian());
  EXPECT_EQ(CPU_TYPE_X86,         reader.cpu_type());
  EXPECT_EQ(CPU_SUBTYPE_I386_ALL, reader.cpu_subtype());
  EXPECT_EQ(static_cast<uint32_t>(MH_EXECUTE), reader.file_type());
  EXPECT_EQ(FileFlags(MH_TWOLEVEL |
                      MH_DYLDLINK |
                      MH_NOUNDEFS),
            reader.flags());

  ByteBuffer expected;
  expected.start = file_bytes + load_commands.start().Value();
  expected.end = expected.start + load_commands.final_size().Value();
  EXPECT_CALL(load_command_handler, UnknownCommand(0x33293d4a,
                                                   expected))
      .WillOnce(Return(true));

  EXPECT_TRUE(reader.WalkLoadCommands(&load_command_handler));
}

TEST_F(LoadCommand, TypeIncomplete) {
  WithConfiguration config(kLittleEndian, 32);
  LoadCommands load_commands;
  load_commands
      .CountCommand()
      .Append(3, 0);                    // load command type, incomplete

  MachOFile file;
  file.Header(&load_commands);

  ReadFile(&file, true, CPU_TYPE_ANY, 0);

  EXPECT_CALL(reporter, LoadCommandsOverrun(1, 0, 0))
      .WillOnce(Return());
  EXPECT_FALSE(reader.WalkLoadCommands(&load_command_handler));
}

TEST_F(LoadCommand, LengthIncomplete) {
  WithConfiguration config(kBigEndian, 64);
  LoadCommands load_commands;
  load_commands
      .CountCommand()
      .D32(LC_SEGMENT);                 // load command
                                                // no length
  MachOFile file;
  file.Header(&load_commands);

  ReadFile(&file, true, CPU_TYPE_ANY, 0);

  EXPECT_CALL(reporter, LoadCommandsOverrun(1, 0, LC_SEGMENT))
      .WillOnce(Return());
  EXPECT_FALSE(reader.WalkLoadCommands(&load_command_handler));
}

TEST_F(LoadCommand, ContentIncomplete) {
  WithConfiguration config(kLittleEndian, 64);
  LoadCommands load_commands;
  load_commands
      .CountCommand()
      .D32(LC_SEGMENT)          // load command
      .D32(40)                          // total size in bytes
      .Append(28, '*');                 // not enough dummy data
  MachOFile file;
  file.Header(&load_commands);

  ReadFile(&file, true, CPU_TYPE_ANY, 0);

  EXPECT_CALL(reporter, LoadCommandsOverrun(1, 0, LC_SEGMENT))
      .WillOnce(Return());
  EXPECT_FALSE(reader.WalkLoadCommands(&load_command_handler));
}

TEST_F(LoadCommand, SegmentBE32) {
  WithConfiguration config(kBigEndian, 32);
  LoadedSection segment;
  segment.address() = 0x1891139c;
  segment.Append(42, '*');              // segment contents
  SegmentLoadCommand segment_command;
  segment_command
      .Header("froon", segment, 0x94d6dd22, 0x8bdbc319, 0x990a16dd);
  segment_command.vmsize() = 0xcb76584fU;
  LoadCommands load_commands;
  load_commands.Place(&segment_command);
  MachOFile file;
  file
      .Header(&load_commands)
      .Place(&segment);

  ReadFile(&file, true, CPU_TYPE_ANY, 0);

  Segment actual_segment;
  EXPECT_CALL(load_command_handler, SegmentCommand(_))
    .WillOnce(DoAll(SaveArg<0>(&actual_segment),
                    Return(true)));
  EXPECT_TRUE(reader.WalkLoadCommands(&load_command_handler));

  EXPECT_FALSE(actual_segment.bits_64);
  EXPECT_EQ("froon",                      actual_segment.name);
  EXPECT_EQ(0x1891139cU,                  actual_segment.vmaddr);
  EXPECT_EQ(0xcb76584fU,                  actual_segment.vmsize);
  EXPECT_EQ(0x94d6dd22U,                  actual_segment.maxprot);
  EXPECT_EQ(0x8bdbc319U,                  actual_segment.initprot);
  EXPECT_EQ(0x990a16ddU,                  actual_segment.flags);
  EXPECT_EQ(0U,                           actual_segment.nsects);
  EXPECT_EQ(0U,                           actual_segment.section_list.Size());
  EXPECT_EQ(segment.final_size().Value(), actual_segment.contents.Size());
}

TEST_F(LoadCommand, SegmentLE32) {
  WithConfiguration config(kLittleEndian, 32);
  LoadedSection segment;
  segment.address() = 0x4b877866;
  segment.Append(42, '*');              // segment contents
  SegmentLoadCommand segment_command;
  segment_command
      .Header("sixteenprecisely", segment,
              0x350759ed, 0x6cf5a62e, 0x990a16dd);
  segment_command.vmsize() = 0xcb76584fU;
  LoadCommands load_commands;
  load_commands.Place(&segment_command);
  MachOFile file;
  file
      .Header(&load_commands)
      .Place(&segment);

  ReadFile(&file, true, CPU_TYPE_ANY, 0);

  Segment actual_segment;
  EXPECT_CALL(load_command_handler, SegmentCommand(_))
    .WillOnce(DoAll(SaveArg<0>(&actual_segment),
                    Return(true)));
  EXPECT_TRUE(reader.WalkLoadCommands(&load_command_handler));

  EXPECT_FALSE(actual_segment.bits_64);
  EXPECT_EQ("sixteenprecisely",           actual_segment.name);
  EXPECT_EQ(0x4b877866U,                  actual_segment.vmaddr);
  EXPECT_EQ(0xcb76584fU,                  actual_segment.vmsize);
  EXPECT_EQ(0x350759edU,                  actual_segment.maxprot);
  EXPECT_EQ(0x6cf5a62eU,                  actual_segment.initprot);
  EXPECT_EQ(0x990a16ddU,                  actual_segment.flags);
  EXPECT_EQ(0U,                           actual_segment.nsects);
  EXPECT_EQ(0U,                           actual_segment.section_list.Size());
  EXPECT_EQ(segment.final_size().Value(), actual_segment.contents.Size());
}

TEST_F(LoadCommand, SegmentBE64) {
  WithConfiguration config(kBigEndian, 64);
  LoadedSection segment;
  segment.address() = 0x79f484f77009e511ULL;
  segment.Append(42, '*');              // segment contents
  SegmentLoadCommand segment_command;
  segment_command
      .Header("froon", segment, 0x42b45da5, 0x8bdbc319, 0xb2335220);
  segment_command.vmsize() = 0x8d92397ce6248abaULL;
  LoadCommands load_commands;
  load_commands.Place(&segment_command);
  MachOFile file;
  file
      .Header(&load_commands)
      .Place(&segment);

  ReadFile(&file, true, CPU_TYPE_ANY, 0);

  Segment actual_segment;
  EXPECT_CALL(load_command_handler, SegmentCommand(_))
    .WillOnce(DoAll(SaveArg<0>(&actual_segment),
                    Return(true)));
  EXPECT_TRUE(reader.WalkLoadCommands(&load_command_handler));

  EXPECT_EQ(true,                         actual_segment.bits_64);
  EXPECT_EQ("froon",                      actual_segment.name);
  EXPECT_EQ(0x79f484f77009e511ULL,        actual_segment.vmaddr);
  EXPECT_EQ(0x8d92397ce6248abaULL,        actual_segment.vmsize);
  EXPECT_EQ(0x42b45da5U,                  actual_segment.maxprot);
  EXPECT_EQ(0x8bdbc319U,                  actual_segment.initprot);
  EXPECT_EQ(0xb2335220U,                  actual_segment.flags);
  EXPECT_EQ(0U,                           actual_segment.nsects);
  EXPECT_EQ(0U,                           actual_segment.section_list.Size());
  EXPECT_EQ(segment.final_size().Value(), actual_segment.contents.Size());
}

TEST_F(LoadCommand, SegmentLE64) {
  WithConfiguration config(kLittleEndian, 64);
  LoadedSection segment;
  segment.address() = 0x50c0501dc5922d35ULL;
  segment.Append(42, '*');              // segment contents
  SegmentLoadCommand segment_command;
  segment_command
      .Header("sixteenprecisely", segment,
              0x917c339d, 0xdbc446fa, 0xb650b563);
  segment_command.vmsize() = 0x84ae73e7c75469bfULL;
  LoadCommands load_commands;
  load_commands.Place(&segment_command);
  MachOFile file;
  file
      .Header(&load_commands)
      .Place(&segment);

  ReadFile(&file, true, CPU_TYPE_ANY, 0);

  Segment actual_segment;
  EXPECT_CALL(load_command_handler, SegmentCommand(_))
    .WillOnce(DoAll(SaveArg<0>(&actual_segment),
                    Return(true)));
  EXPECT_TRUE(reader.WalkLoadCommands(&load_command_handler));

  EXPECT_EQ(true,                         actual_segment.bits_64);
  EXPECT_EQ("sixteenprecisely",           actual_segment.name);
  EXPECT_EQ(0x50c0501dc5922d35ULL,        actual_segment.vmaddr);
  EXPECT_EQ(0x84ae73e7c75469bfULL,        actual_segment.vmsize);
  EXPECT_EQ(0x917c339dU,                  actual_segment.maxprot);
  EXPECT_EQ(0xdbc446faU,                  actual_segment.initprot);
  EXPECT_EQ(0xb650b563U,                  actual_segment.flags);
  EXPECT_EQ(0U,                           actual_segment.nsects);
  EXPECT_EQ(0U,                           actual_segment.section_list.Size());
  EXPECT_EQ(segment.final_size().Value(), actual_segment.contents.Size());
}

TEST_F(LoadCommand, SegmentCommandTruncated) {
  WithConfiguration config(kBigEndian, 32);
  LoadedSection segment_contents;
  segment_contents.Append(20, '*');     	// lah di dah
  SizedSection command;
  command
      .D32(LC_SEGMENT)          	// command type
      .D32(command.final_size())                // command size
      .AppendCString("too-short", 16)           // segment name
      .D32(0x9c759211)                          // vmaddr
      .D32(segment_contents.final_size())       // vmsize
      .D32(segment_contents.start())            // file offset
      .D32(segment_contents.final_size())       // file size
      .D32(0x56f28446)                          // max protection
      .D32(0xe7910dcb)                          // initial protection
      .D32(0)                                   // no sections
      .Append(3, 0);                            // flags (one byte short!)
  LoadCommands load_commands;
  load_commands.Place(&command);
  MachOFile file;
  file
      .Header(&load_commands)
      .Place(&segment_contents);
  
  ReadFile(&file, true, CPU_TYPE_ANY, 0);

  EXPECT_CALL(reporter, LoadCommandTooShort(0, LC_SEGMENT))
      .WillOnce(Return());

  EXPECT_FALSE(reader.WalkLoadCommands(&load_command_handler));
}

TEST_F(LoadCommand, SegmentBadContentOffset) {
  WithConfiguration config(kLittleEndian, 32);
  // Instead of letting a Place call set the segment's file offset and size,
  // set them ourselves, to check that the parser catches invalid offsets
  // instead of handing us bogus pointers.
  LoadedSection segment;
  segment.address() = 0x4db5489c;
  segment.start() = 0x7e189e76;         // beyond end of file
  segment.final_size() = 0x98b9c3ab;
  SegmentLoadCommand segment_command;
  segment_command
      .Header("notmerelyfifteen", segment, 0xcbab25ee, 0x359a20db, 0x68a3933f);
  LoadCommands load_commands;
  load_commands.Place(&segment_command);
  MachOFile file;
  file.Header(&load_commands);

  ReadFile(&file, true, CPU_TYPE_ANY, 0);

  EXPECT_CALL(reporter, MisplacedSegmentData("notmerelyfifteen"))
      .WillOnce(Return());

  EXPECT_FALSE(reader.WalkLoadCommands(&load_command_handler));
}

TEST_F(LoadCommand, ThreeLoadCommands) {
  WithConfiguration config(kBigEndian, 32);
  LoadedSection seg1, seg2, seg3;
  SegmentLoadCommand cmd1, cmd2, cmd3;

  seg1.Append(128, '@');
  seg1.address() = 0xa7f61ef6;
  cmd1.Header("head", seg1, 0x88bf1cc7, 0x889a26a4, 0xe9b80d87);
  // Include some dummy data at the end of the load command. Since we
  // didn't claim to have any sections, the reader should ignore this. But
  // making sure the commands have different lengths ensures that we're
  // using the right command's length to advance the LoadCommandIterator.
  cmd1.Append(128, '!');

  seg2.Append(42, '*');
  seg2.address() = 0xc70fc909;
  cmd2.Header("thorax", seg2, 0xde7327f4, 0xfdaf771d, 0x65e74b30);
  // More dummy data at the end of the load command. 
  cmd2.Append(32, '^');

  seg3.Append(42, '%');
  seg3.address() = 0x46b3ab05;
  cmd3.Header("abdomen", seg3, 0x7098b70d, 0x8d8d7728, 0x5131419b);
  // More dummy data at the end of the load command. 
  cmd3.Append(64, '&');

  LoadCommands load_commands;
  load_commands.Place(&cmd1).Place(&cmd2).Place(&cmd3);

  MachOFile file;
  file.Header(&load_commands).Place(&seg1).Place(&seg2).Place(&seg3);

  ReadFile(&file, true, CPU_TYPE_ANY, 0);

  {
    InSequence s;
    EXPECT_CALL(load_command_handler,
                SegmentCommand(Field(&Segment::name, "head")))
      .WillOnce(Return(true));
    EXPECT_CALL(load_command_handler,
                SegmentCommand(Field(&Segment::name, "thorax")))
      .WillOnce(Return(true));
    EXPECT_CALL(load_command_handler,
                SegmentCommand(Field(&Segment::name, "abdomen")))
      .WillOnce(Return(true));
  }

  EXPECT_TRUE(reader.WalkLoadCommands(&load_command_handler));
}

static inline Matcher<const Section &> MatchSection(
    Matcher<bool> bits_64,
    Matcher<const string &> section_name,
    Matcher<const string &> segment_name,
    Matcher<uint64_t> address,
    Matcher<uint32_t> alignment,
    Matcher<uint32_t> flags,
    Matcher<const ByteBuffer &> contents) {
  return AllOf(AllOf(Field(&Section::bits_64, bits_64),
                     Field(&Section::section_name, section_name),
                     Field(&Section::segment_name, segment_name),
                     Field(&Section::address, address)),
               AllOf(Field(&Section::align, alignment),
                     Field(&Section::flags, flags),
                     Field(&Section::contents, contents)));
}

static inline Matcher<const Section &> MatchSection(
    Matcher<bool> bits_64,
    Matcher<const string &> section_name,
    Matcher<const string &> segment_name,
    Matcher<uint64_t> address) {
  return AllOf(Field(&Section::bits_64, bits_64),
               Field(&Section::section_name, section_name),
               Field(&Section::segment_name, segment_name),
               Field(&Section::address, address));
}

TEST_F(LoadCommand, OneSegmentTwoSections) {
  WithConfiguration config(kBigEndian, 64);

  // Create some sections with some data.
  LoadedSection section1, section2;
  section1.Append("buddha's hand");
  section2.Append("kumquat");

  // Create a segment to hold them.
  LoadedSection segment;
  segment.address() = 0xe1d0eeec;
  segment.Place(&section2).Place(&section1);

  SegmentLoadCommand segment_command;
  segment_command
      .Header("head", segment, 0x92c9568c, 0xa89f2627, 0x4dc7a1e2)
      .AppendSectionEntry("mandarin", "kishu", 12, 0x8cd4604bU, section1)
      .AppendSectionEntry("bergamot", "cara cara", 12, 0x98746efaU, section2);

  LoadCommands commands;
  commands.Place(&segment_command);

  MachOFile file;
  file.Header(&commands).Place(&segment);

  ReadFile(&file, true, CPU_TYPE_ANY, 0);
  
  Segment actual_segment;
  EXPECT_CALL(load_command_handler, SegmentCommand(_))
      .WillOnce(DoAll(SaveArg<0>(&actual_segment),
                      Return(true)));
  EXPECT_TRUE(reader.WalkLoadCommands(&load_command_handler));

  {
    InSequence s;
    ByteBuffer contents1;
    contents1.start = file_bytes + section1.start().Value();
    contents1.end = contents1.start + section1.final_size().Value();
    EXPECT_EQ("buddha's hand",
              string(reinterpret_cast<const char *>(contents1.start),
                     contents1.Size()));
    EXPECT_CALL(section_handler,
                HandleSection(MatchSection(true, "mandarin", "kishu",
                                           section1.address().Value(), 12,
                                           0x8cd4604bU, contents1)))
      .WillOnce(Return(true));
    
    ByteBuffer contents2;
    contents2.start = file_bytes + section2.start().Value();
    contents2.end = contents2.start + section2.final_size().Value();
    EXPECT_EQ("kumquat",
              string(reinterpret_cast<const char *>(contents2.start),
                     contents2.Size()));
    EXPECT_CALL(section_handler,
                HandleSection(MatchSection(true, "bergamot", "cara cara",
                                           section2.address().Value(), 12,
                                           0x98746efaU, contents2)))
      .WillOnce(Return(true));
  }

  EXPECT_TRUE(reader.WalkSegmentSections(actual_segment, &section_handler));
}

TEST_F(LoadCommand, MisplacedSectionBefore) {
  WithConfiguration config(kLittleEndian, 64);

  // The segment.
  LoadedSection segment;
  segment.address() = 0x696d83cc;
  segment.Append(10, '0');

  // The contents of the following sections don't matter, because
  // we're not really going to Place them in segment; we're just going
  // to set all their labels by hand to get the (impossible)
  // configurations we want.

  // A section whose starting offset is before that of its section.
  LoadedSection before;
  before.Append(10, '1');
  before.start()   = segment.start() - 1;
  before.address() = segment.address() - 1;
  before.final_size() = before.Size();
  
  SegmentLoadCommand command;
  command
    .Header("segment", segment, 0x173baa29, 0x8407275d, 0xed8f7057)
    .AppendSectionEntry("before",     "segment", 0, 0x686c6921, before);

  LoadCommands commands;
  commands.Place(&command);

  MachOFile file;
  file.Header(&commands).Place(&segment);

  ReadFile(&file, true, CPU_TYPE_ANY, 0);

  Segment actual_segment;
  EXPECT_TRUE(reader.FindSegment("segment", &actual_segment));

  EXPECT_CALL(reporter, MisplacedSectionData("before", "segment"))
    .WillOnce(Return());
  EXPECT_FALSE(reader.WalkSegmentSections(actual_segment, &section_handler));
}

TEST_F(LoadCommand, MisplacedSectionAfter) {
  WithConfiguration config(kLittleEndian, 64);

  // The segment.
  LoadedSection segment;
  segment.address() = 0x696d83cc;
  segment.Append(10, '0');

  // The contents of the following sections don't matter, because
  // we're not really going to Place them in segment; we're just going
  // to set all their labels by hand to get the (impossible)
  // configurations we want.

  // A section whose starting offset is after the end of its section.
  LoadedSection after;
  after.Append(10, '2');
  after.start()    = segment.start() + 11;
  after.address()   = segment.address() + 11;
  after.final_size() = after.Size();

  SegmentLoadCommand command;
  command
    .Header("segment", segment, 0x173baa29, 0x8407275d, 0xed8f7057)
    .AppendSectionEntry("after",      "segment", 0, 0x2ee50124, after);

  LoadCommands commands;
  commands.Place(&command);

  MachOFile file;
  file.Header(&commands).Place(&segment);

  ReadFile(&file, true, CPU_TYPE_ANY, 0);

  Segment actual_segment;
  EXPECT_TRUE(reader.FindSegment("segment", &actual_segment));

  EXPECT_CALL(reporter, MisplacedSectionData("after", "segment"))
    .WillOnce(Return());
  EXPECT_FALSE(reader.WalkSegmentSections(actual_segment, &section_handler));
}

TEST_F(LoadCommand, MisplacedSectionTooBig) {
  WithConfiguration config(kLittleEndian, 64);

  // The segment.
  LoadedSection segment;
  segment.address() = 0x696d83cc;
  segment.Append(10, '0');

  // The contents of the following sections don't matter, because
  // we're not really going to Place them in segment; we're just going
  // to set all their labels by hand to get the (impossible)
  // configurations we want.

  // A section that extends beyond the end of its section.
  LoadedSection too_big;
  too_big.Append(10, '3');
  too_big.start()   = segment.start() + 1;
  too_big.address() = segment.address() + 1;
  too_big.final_size() = too_big.Size();

  SegmentLoadCommand command;
  command
    .Header("segment", segment, 0x173baa29, 0x8407275d, 0xed8f7057)
    .AppendSectionEntry("too big",    "segment", 0, 0x8b53ae5c, too_big);

  LoadCommands commands;
  commands.Place(&command);

  MachOFile file;
  file.Header(&commands).Place(&segment);

  ReadFile(&file, true, CPU_TYPE_ANY, 0);

  Segment actual_segment;
  EXPECT_TRUE(reader.FindSegment("segment", &actual_segment));

  EXPECT_CALL(reporter, MisplacedSectionData("too big", "segment"))
    .WillOnce(Return());
  EXPECT_FALSE(reader.WalkSegmentSections(actual_segment, &section_handler));
}


// The segments in a .dSYM bundle's Mach-O file have their file offset
// and size set to zero, but the sections don't.  The reader shouldn't
// report an error in this case.
TEST_F(LoadCommand, ZappedSegment) {
  WithConfiguration config(kBigEndian, 32);

  // The segment.
  LoadedSection segment;
  segment.address() = 0x696d83cc;
  segment.start() = 0;
  segment.final_size() = 0;

  // The section.
  LoadedSection section;
  section.address() = segment.address();
  section.start() = 0;
  section.final_size() = 1000;          // extends beyond its segment
  
  SegmentLoadCommand command;
  command
    .Header("zapped", segment, 0x0861a5cb, 0x68ccff67, 0x0b66255c)
    .AppendSectionEntry("twitching", "zapped", 0, 0x93b3bd42, section);

  LoadCommands commands;
  commands.Place(&command);

  MachOFile file;
  file.Header(&commands);

  ReadFile(&file, true, CPU_TYPE_ANY, 0);

  Segment actual_segment;
  EXPECT_TRUE(reader.FindSegment("zapped", &actual_segment));

  ByteBuffer zapped_extent(NULL, 0);
  EXPECT_CALL(section_handler,
              HandleSection(MatchSection(false, "twitching", "zapped",
                                         0x696d83cc, 0, 0x93b3bd42,
                                         zapped_extent)))
    .WillOnce(Return(true));

  EXPECT_TRUE(reader.WalkSegmentSections(actual_segment, &section_handler));
}

TEST_F(LoadCommand, MapSegmentSections) {
  WithConfiguration config(kLittleEndian, 32);

  // Create some sections with some data.
  LoadedSection section1, section2, section3, section4;
  section1.Append("buddha's hand");
  section2.start() = 0;                 // Section 2 is an S_ZEROFILL section.
  section2.final_size() = 0;
  section3.Append("shasta gold");
  section4.Append("satsuma");

  // Create two segments to hold them.
  LoadedSection segment1, segment2;
  segment1.address() = 0x13e6c8a9;
  segment1.Place(&section3).Place(&section1);
  segment2.set_word_size(64);
  segment2.address() = 0x04d462e2;
  segment2.Place(&section4);
  section2.address() = segment2.address() + segment2.Size();

  SegmentLoadCommand segment_command1, segment_command2;
  segment_command1
      .Header("head", segment1, 0x67d955a6, 0x7a61c13e, 0xe3e50c64)
      .AppendSectionEntry("mandarin", "head", 12, 0x5bb565d7, section1)
      .AppendSectionEntry("bergamot", "head", 12, 0x8620de73, section3);
  segment_command2.set_word_size(64);
  segment_command2
      .Header("thorax", segment2, 0x7aab2419, 0xe908007f, 0x17961d33)
      .AppendSectionEntry("sixteenprecisely", "thorax",
                          12, S_ZEROFILL, section2)
      .AppendSectionEntry("cara cara", "thorax", 12, 0xb6c5dd8a, section4);

  LoadCommands commands;
  commands.Place(&segment_command1).Place(&segment_command2);

  MachOFile file;
  file.Header(&commands).Place(&segment1).Place(&segment2);

  ReadFile(&file, true, CPU_TYPE_ANY, 0);

  Segment segment;
  SectionMap section_map;

  EXPECT_FALSE(reader.FindSegment("smoot", &segment));

  ASSERT_TRUE(reader.FindSegment("thorax", &segment));
  ASSERT_TRUE(reader.MapSegmentSections(segment, &section_map));

  EXPECT_FALSE(section_map.find("sixteenpreciselyandthensome")
               != section_map.end());
  EXPECT_FALSE(section_map.find("mandarin") != section_map.end());
  ASSERT_TRUE(section_map.find("cara cara") != section_map.end());
  EXPECT_THAT(section_map["cara cara"],
              MatchSection(true, "cara cara", "thorax", 0x04d462e2));
  ASSERT_TRUE(section_map.find("sixteenprecisely")
              != section_map.end());
  ByteBuffer sixteenprecisely_contents(NULL, 0);
  EXPECT_THAT(section_map["sixteenprecisely"],
              MatchSection(true, "sixteenprecisely", "thorax",
                           0x04d462e2 + 7, 12, S_ZEROFILL,
                           sixteenprecisely_contents));

  ASSERT_TRUE(reader.FindSegment("head", &segment));
  ASSERT_TRUE(reader.MapSegmentSections(segment, &section_map));

  ASSERT_TRUE(section_map.find("mandarin") != section_map.end());
  EXPECT_THAT(section_map["mandarin"],
              MatchSection(false, "mandarin", "head", 0x13e6c8a9 + 11));
  ASSERT_TRUE(section_map.find("bergamot") != section_map.end());
  EXPECT_THAT(section_map["bergamot"],
              MatchSection(false, "bergamot", "head", 0x13e6c8a9));
}

TEST_F(LoadCommand, FindSegment) {
  WithConfiguration config(kBigEndian, 32);

  LoadedSection segment1, segment2, segment3;
  segment1.address() = 0xb8ae5752;
  segment1.Append("Some contents!");
  segment2.address() = 0xd6b0ce83;
  segment2.Append("Different stuff.");
  segment3.address() = 0x7374fd2a;
  segment3.Append("Further materials.");

  SegmentLoadCommand cmd1, cmd2, cmd3;
  cmd1.Header("first",  segment1, 0xfadb6932, 0x175bf529, 0x0de790ad);
  cmd2.Header("second", segment2, 0xeef716e0, 0xe103a9d7, 0x7d38a8ef);
  cmd3.Header("third",  segment3, 0xe172b39e, 0x86012f07, 0x080ac94d);

  LoadCommands commands;
  commands.Place(&cmd1).Place(&cmd2).Place(&cmd3);

  MachOFile file;
  file.Header(&commands).Place(&segment1).Place(&segment2).Place(&segment3);

  ReadFile(&file, true, CPU_TYPE_ANY, 0);

  Segment actual_segment;

  EXPECT_FALSE(reader.FindSegment("murphy", &actual_segment));

  EXPECT_TRUE(reader.FindSegment("second", &actual_segment));
  EXPECT_EQ(0xd6b0ce83, actual_segment.vmaddr);
}


// Symtab tests.

// A StringAssembler is a class for generating .stabstr sections to present
// as input to the STABS parser.
class StringAssembler: public SizedSection {
 public:
  // Add the string S to this StringAssembler, and return the string's
  // offset within this compilation unit's strings.
  size_t Add(const string &s) {
    size_t offset = Size();
    AppendCString(s);
    return offset;
  }
};

// A SymbolAssembler is a class for generating .stab sections to present as
// test input for the STABS parser.
class SymbolAssembler: public SizedSection {
 public:
  // Create a SymbolAssembler that uses StringAssembler for its strings.
  explicit SymbolAssembler(StringAssembler *string_assembler) 
      : string_assembler_(string_assembler),
        entry_count_(0) { }

  // Append a STAB entry to the end of this section with the given
  // characteristics. NAME is the offset of this entry's name string within
  // its compilation unit's portion of the .stabstr section; this can be a
  // value generated by a StringAssembler. Return a reference to this
  // SymbolAssembler.
  SymbolAssembler &Symbol(uint8_t type, uint8_t other, Label descriptor,
                          Label value, Label name) {
    D32(name);
    D8(type);
    D8(other);
    D16(descriptor);
    Append(endianness(), word_size_ / 8, value);
    entry_count_++;
    return *this;
  }

  // As above, but automatically add NAME to our StringAssembler.
  SymbolAssembler &Symbol(uint8_t type, uint8_t other, Label descriptor,
                       Label value, const string &name) {
    return Symbol(type, other, descriptor, value, string_assembler_->Add(name));
  }

 private:
  // The strings for our STABS entries.
  StringAssembler *string_assembler_;

  // The number of entries in this compilation unit so far.
  size_t entry_count_;
};

class Symtab: public ReaderFixture, public Test { };

TEST_F(Symtab, Symtab32) {
  WithConfiguration config(kLittleEndian, 32);

  StringAssembler strings;
  SymbolAssembler symbols(&strings);
  symbols
      .Symbol(0x52, 0x7c, 0x3470, 0x9bb02e7c, "hrududu")
      .Symbol(0x50, 0x90, 0x7520, 0x1122525d, "Frith");

  SizedSection symtab_command;
  symtab_command
      .D32(LC_SYMTAB)                    // command
      .D32(symtab_command.final_size())  // size
      .D32(symbols.start())              // file offset of symbols
      .D32(2)                            // symbol count
      .D32(strings.start())              // file offset of strings
      .D32(strings.final_size());        // strings size

  LoadCommands load_commands;
  load_commands.Place(&symtab_command);

  MachOFile file;
  file.Header(&load_commands).Place(&symbols).Place(&strings);

  ReadFile(&file, true, CPU_TYPE_ANY, 0);

  ByteBuffer symbols_found, strings_found;
  EXPECT_CALL(load_command_handler, SymtabCommand(_, _))
      .WillOnce(DoAll(SaveArg<0>(&symbols_found),
                      SaveArg<1>(&strings_found),
                      Return(true)));
  EXPECT_TRUE(reader.WalkLoadCommands(&load_command_handler));

  EXPECT_EQ(24U, symbols_found.Size());
  EXPECT_EQ(14U, strings_found.Size());
}

TEST_F(Symtab, Symtab64) {
  WithConfiguration config(kBigEndian, 64);

  StringAssembler strings;
  SymbolAssembler symbols(&strings);
  symbols
      .Symbol(0xa7, 0xaf, 0x03af, 0x42f3072c74335181ULL, "foo")
      .Symbol(0xb0, 0x9a, 0x2aa7, 0x2e2d349b3d5744a0ULL, "bar");

  SizedSection symtab_command;
  symtab_command
      .D32(LC_SYMTAB)                    // command
      .D32(symtab_command.final_size())  // size
      .D32(symbols.start())              // file offset of symbols
      .D32(2)                            // symbol count
      .D32(strings.start())              // file offset of strings
      .D32(strings.final_size());        // strings size

  LoadCommands load_commands;
  load_commands.Place(&symtab_command);

  MachOFile file;
  file.Header(&load_commands).Place(&symbols).Place(&strings);

  ReadFile(&file, true, CPU_TYPE_ANY, 0);

  ByteBuffer symbols_found, strings_found;
  EXPECT_CALL(load_command_handler, SymtabCommand(_, _))
      .WillOnce(DoAll(SaveArg<0>(&symbols_found),
                      SaveArg<1>(&strings_found),
                      Return(true)));
  EXPECT_TRUE(reader.WalkLoadCommands(&load_command_handler));

  EXPECT_EQ(32U, symbols_found.Size());
  EXPECT_EQ(8U,  strings_found.Size());
}

TEST_F(Symtab, SymtabMisplacedSymbols) {
  WithConfiguration config(kBigEndian, 32);

  StringAssembler strings;
  SymbolAssembler symbols(&strings);
  symbols
      .Symbol(0xa7, 0xaf, 0x03af, 0x42f3072c74335181ULL, "foo")
      .Symbol(0xb0, 0x9a, 0x2aa7, 0x2e2d349b3d5744a0ULL, "bar");

  SizedSection symtab_command;
  symtab_command
      .D32(LC_SYMTAB)                    // command
      .D32(symtab_command.final_size())  // size
      .D32(symbols.start())              // file offset of symbols
      .D32(3)                            // symbol count (too many)
      .D32(strings.start())              // file offset of strings
      .D32(strings.final_size());        // strings size

  LoadCommands load_commands;
  load_commands.Place(&symtab_command);

  MachOFile file;
  // Put symbols at end, so the excessive length will be noticed.
  file.Header(&load_commands).Place(&strings).Place(&symbols);

  ReadFile(&file, true, CPU_TYPE_ANY, 0);

  EXPECT_CALL(reporter, MisplacedSymbolTable()).Times(1);
  EXPECT_FALSE(reader.WalkLoadCommands(&load_command_handler));
}

TEST_F(Symtab, SymtabMisplacedStrings) {
  WithConfiguration config(kLittleEndian, 32);

  StringAssembler strings;
  SymbolAssembler symbols(&strings);
  symbols
      .Symbol(0xa7, 0xaf, 0x03af, 0x42f3072c74335181ULL, "foo")
      .Symbol(0xb0, 0x9a, 0x2aa7, 0x2e2d349b3d5744a0ULL, "bar");

  SizedSection symtab_command;
  symtab_command
      .D32(LC_SYMTAB)                    // command
      .D32(symtab_command.final_size())  // size
      .D32(symbols.start())              // file offset of symbols
      .D32(2)                            // symbol count
      .D32(strings.start())              // file offset of strings
      .D32(strings.final_size() + 1);    // strings size (too long)

  LoadCommands load_commands;
  load_commands.Place(&symtab_command);

  MachOFile file;
  // Put strings at end, so the excessive length will be noticed.
  file.Header(&load_commands).Place(&symbols).Place(&strings);

  ReadFile(&file, true, CPU_TYPE_ANY, 0);

  EXPECT_CALL(reporter, MisplacedSymbolTable()).Times(1);
  EXPECT_FALSE(reader.WalkLoadCommands(&load_command_handler));
}

