// 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_dump.cc: Dump the contents of a Mach-O file. This is mostly
// a test program for the Mach_O::FatReader and Mach_O::Reader classes.

#include <errno.h>
#include <fcntl.h>
#include <mach-o/arch.h>
#include <sys/mman.h>
#include <stdint.h>
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>

#include <sstream>
#include <string>
#include <vector>

#include "common/byte_cursor.h"
#include "common/mac/arch_utilities.h"
#include "common/mac/macho_reader.h"
#include "common/path_helper.h"

using google_breakpad::ByteBuffer;
using std::ostringstream;
using std::string;
using std::vector;

namespace {
namespace mach_o = google_breakpad::mach_o;

string program_name;

int check_syscall(int result, const char* operation, const char* filename) {
  if (result < 0) {
    fprintf(stderr, "%s: %s '%s': %s\n",
            program_name.c_str(), operation,
            filename, strerror(errno));
    exit(1);
  }
  return result;
}

class DumpSection: public mach_o::Reader::SectionHandler {
 public:
  DumpSection() : index_(0) { }
  bool HandleSection(const mach_o::Section& section) {
    printf("        section %d '%s' in segment '%s'\n"
           "          address: 0x%llx\n"
           "          alignment: 1 << %d B\n"
           "          flags: %d\n"
           "          size: %ld\n",
           index_++, section.section_name.c_str(), section.segment_name.c_str(),
           section.address, section.align,
           mach_o::SectionFlags(section.flags),
           section.contents.Size());
    return true;
  }

 private:
  int index_;
};

class DumpCommand: public mach_o::Reader::LoadCommandHandler {
 public:
  DumpCommand(mach_o::Reader* reader) : reader_(reader), index_(0) { }
  bool UnknownCommand(mach_o::LoadCommandType type,
                      const ByteBuffer& contents) {
    printf("      load command %d: %d", index_++, type);
    return true;
  }
  bool SegmentCommand(const mach_o::Segment& segment) {
    printf("      load command %d: %s-bit segment '%s'\n"
           "        address: 0x%llx\n"
           "        memory size: 0x%llx\n"
           "        maximum protection: 0x%x\n"
           "        initial protection: 0x%x\n"
           "        flags: %d\n"
           "        section_list size: %ld B\n",
           index_++, (segment.bits_64 ? "64" : "32"), segment.name.c_str(),
           segment.vmaddr, segment.vmsize, segment.maxprot,
           segment.initprot, mach_o::SegmentFlags(segment.flags),
           segment.section_list.Size());
           
    DumpSection dump_section;
    return reader_->WalkSegmentSections(segment, &dump_section);
  }
 private:
  mach_o::Reader* reader_;
  int index_;
};

void DumpFile(const char* filename) {
  int fd = check_syscall(open(filename, O_RDONLY), "opening", filename);
  struct stat attributes;
  check_syscall(fstat(fd, &attributes),
                "getting file attributes for", filename);
  void* mapping = mmap(NULL, attributes.st_size, PROT_READ,
                       MAP_PRIVATE, fd, 0);
  close(fd);
  check_syscall(mapping == (void*)-1 ? -1 : 0,
                "mapping contents of", filename);

  mach_o::FatReader::Reporter fat_reporter(filename);
  mach_o::FatReader fat_reader(&fat_reporter);
  if (!fat_reader.Read(reinterpret_cast<uint8_t*>(mapping),
                       attributes.st_size)) {
    exit(1);
  }
  printf("filename: %s\n", filename);
  size_t object_files_size;
  const SuperFatArch* super_fat_object_files =
      fat_reader.object_files(&object_files_size);
  struct fat_arch* object_files;
  if (!super_fat_object_files->ConvertToFatArch(object_files)) {
    exit(1);
  }
  printf("  object file count: %ld\n", object_files_size);
  for (size_t i = 0; i < object_files_size; i++) {
    const struct fat_arch& file = object_files[i];
    const NXArchInfo* fat_arch_info =
        google_breakpad::BreakpadGetArchInfoFromCpuType(
            file.cputype, file.cpusubtype);
    printf("\n  object file %ld:\n"
           "    fat header:\n:"
           "      CPU type: %s (%s)\n"
           "      size: %d B\n"
           "      alignment: 1<<%d B\n",
           i, fat_arch_info->name, fat_arch_info->description,
           file.size, file.align);

    ostringstream name;
    name << filename;
    if (object_files_size > 1)
      name << ", object file #" << i;
    ByteBuffer file_contents(reinterpret_cast<uint8_t*>(mapping)
                             + file.offset, file.size);
    mach_o::Reader::Reporter reporter(name.str());
    mach_o::Reader reader(&reporter);
    if (!reader.Read(file_contents, file.cputype, file.cpusubtype)) {
      exit(1);
    }

    const NXArchInfo* macho_arch_info =
      NXGetArchInfoFromCpuType(reader.cpu_type(),
                               reader.cpu_subtype());
    printf("    Mach-O header:\n"
           "      word size: %s\n" 
           "      CPU type: %s (%s)\n"
           "      File type: %d\n"
           "      flags: %x\n",
           (reader.bits_64() ? "64 bits" : "32 bits"),
           macho_arch_info->name, macho_arch_info->description,
           reader.file_type(), reader.flags());

    DumpCommand dump_command(&reader);
    reader.WalkLoadCommands(&dump_command);
  }
  munmap(mapping, attributes.st_size);
}

}  // namespace

int main(int argc, char** argv) {
  program_name = google_breakpad::BaseName(argv[0]);
  if (argc == 1) {
    fprintf(stderr, "Usage: %s FILE ...\n"
            "Dump the contents of the Mach-O or fat binary files "
            "'FILE ...'.\n", program_name.c_str());
  }
  for (int i = 1; i < argc; i++) {
    DumpFile(argv[i]);
  }
}
