// Copyright (c) 2006, 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.

// macho_walker.cc: Iterate over the load commands in a mach-o file
//
// See macho_walker.h for documentation
//
// Author: Dan Waylonis

#include <assert.h>
#include <fcntl.h>
#include <mach-o/arch.h>
#include <mach-o/fat.h>
#include <mach-o/loader.h>
#include <string.h>
#include <unistd.h>

#include "common/mac/byteswap.h"
#include "common/mac/macho_walker.h"
#include "common/mac/macho_utilities.h"

namespace MacFileUtilities {

MachoWalker::MachoWalker(const char* path, LoadCommandCallback callback,
                         void* context)
    : file_(-1),
      memory_(NULL),
      memory_size_(0),
      callback_(callback),
      callback_context_(context),
      current_header_(NULL),
      current_header_size_(0),
      current_header_offset_(0) {
  file_ = open(path, O_RDONLY);
}

MachoWalker::MachoWalker(void* memory, size_t size,
                         LoadCommandCallback callback, void* context)
    : file_(-1),
      memory_(memory),
      memory_size_(size),
      callback_(callback),
      callback_context_(context),
      current_header_(NULL),
      current_header_size_(0),
      current_header_offset_(0) {
}

MachoWalker::~MachoWalker() {
  if (file_ != -1)
    close(file_);
}

bool MachoWalker::WalkHeader(cpu_type_t cpu_type, cpu_subtype_t cpu_subtype) {
  cpu_type_t valid_cpu_type = cpu_type;
  cpu_subtype_t valid_cpu_subtype = cpu_subtype;
  // if |cpu_type| is 0, use the native cpu type.
  if (cpu_type == 0) {
    const NXArchInfo* arch = NXGetLocalArchInfo();
    assert(arch);
    valid_cpu_type = arch->cputype;
    valid_cpu_subtype = CPU_SUBTYPE_MULTIPLE;
  }
  off_t offset;
  if (FindHeader(valid_cpu_type, valid_cpu_subtype, offset)) {
    if (cpu_type & CPU_ARCH_ABI64)
      return WalkHeader64AtOffset(offset);

    return WalkHeaderAtOffset(offset);
  }

  return false;
}

bool MachoWalker::ReadBytes(void* buffer, size_t size, off_t offset) {
  if (memory_) {
    if (offset < 0)
      return false;
    bool result = true;
    if (offset + size > memory_size_) {
      if (static_cast<size_t>(offset) >= memory_size_)
        return false;
      size = memory_size_ - static_cast<size_t>(offset);
      result = false;
    }
    memcpy(buffer, static_cast<char*>(memory_) + offset, size);
    return result;
  } else {
    return pread(file_, buffer, size, offset) == (ssize_t)size;
  }
}

bool MachoWalker::CurrentHeader(struct mach_header_64* header, off_t* offset) {
  if (current_header_) {
    memcpy(header, current_header_, sizeof(mach_header_64));
    *offset = current_header_offset_;
    return true;
  }

  return false;
}

bool MachoWalker::FindHeader(cpu_type_t cpu_type,
                             cpu_subtype_t cpu_subtype,
                             off_t& offset) {
  // Read the magic bytes that's common amongst all mach-o files
  uint32_t magic;
  if (!ReadBytes(&magic, sizeof(magic), 0))
    return false;

  offset = sizeof(magic);

  // Figure out what type of file we've got
  bool is_fat = false;
  if (magic == FAT_MAGIC || magic == FAT_CIGAM) {
    is_fat = true;
  }
  else if (magic != MH_MAGIC && magic != MH_CIGAM && magic != MH_MAGIC_64 &&
           magic != MH_CIGAM_64) {
    return false;
  }

  if (!is_fat) {
    // If we don't have a fat header, check if the cpu type matches the single
    // header
    struct mach_header header;
    if (!ReadBytes(&header, sizeof(header), 0))
      return false;

    if (magic == MH_CIGAM || magic == MH_CIGAM_64)
      breakpad_swap_mach_header(&header);

    if (cpu_type != header.cputype ||
        (cpu_subtype != CPU_SUBTYPE_MULTIPLE &&
         cpu_subtype != header.cpusubtype)) {
      return false;
    }

    offset = 0;
    return true;
  } else {
    // Read the fat header and find an appropriate architecture
    offset = 0;
    struct fat_header fat;
    if (!ReadBytes(&fat, sizeof(fat), offset))
      return false;

    if (NXHostByteOrder() != NX_BigEndian)
      breakpad_swap_fat_header(&fat);

    offset += sizeof(fat);

    // Search each architecture for the desired one
    struct fat_arch arch;
    for (uint32_t i = 0; i < fat.nfat_arch; ++i) {
      if (!ReadBytes(&arch, sizeof(arch), offset))
        return false;

      if (NXHostByteOrder() != NX_BigEndian)
        breakpad_swap_fat_arch(&arch, 1);

      if (arch.cputype == cpu_type &&
          (cpu_subtype == CPU_SUBTYPE_MULTIPLE ||
           arch.cpusubtype == cpu_subtype)) {
        offset = arch.offset;
        return true;
      }

      offset += sizeof(arch);
    }
  }

  return false;
}

bool MachoWalker::WalkHeaderAtOffset(off_t offset) {
  struct mach_header header;
  if (!ReadBytes(&header, sizeof(header), offset))
    return false;

  bool swap = (header.magic == MH_CIGAM);
  if (swap)
    breakpad_swap_mach_header(&header);

  // Copy the data into the mach_header_64 structure.  Since the 32-bit and
  // 64-bit only differ in the last field (reserved), this is safe to do.
  struct mach_header_64 header64;
  memcpy((void*)&header64, (const void*)&header, sizeof(header));
  header64.reserved = 0;

  current_header_ = &header64;
  current_header_size_ = sizeof(header); // 32-bit, not 64-bit
  current_header_offset_ = offset;
  offset += current_header_size_;
  bool result = WalkHeaderCore(offset, header.ncmds, swap);
  current_header_ = NULL;
  current_header_size_ = 0;
  current_header_offset_ = 0;
  return result;
}

bool MachoWalker::WalkHeader64AtOffset(off_t offset) {
  struct mach_header_64 header;
  if (!ReadBytes(&header, sizeof(header), offset))
    return false;

  bool swap = (header.magic == MH_CIGAM_64);
  if (swap)
    breakpad_swap_mach_header_64(&header);

  current_header_ = &header;
  current_header_size_ = sizeof(header);
  current_header_offset_ = offset;
  offset += current_header_size_;
  bool result = WalkHeaderCore(offset, header.ncmds, swap);
  current_header_ = NULL;
  current_header_size_ = 0;
  current_header_offset_ = 0;
  return result;
}

bool MachoWalker::WalkHeaderCore(off_t offset, uint32_t number_of_commands,
                                 bool swap) {
  for (uint32_t i = 0; i < number_of_commands; ++i) {
    struct load_command cmd;
    if (!ReadBytes(&cmd, sizeof(cmd), offset))
      return false;

    if (swap)
      breakpad_swap_load_command(&cmd);

    // Call the user callback
    if (callback_ && !callback_(this, &cmd, offset, swap, callback_context_))
      break;

    offset += cmd.cmdsize;
  }

  return true;
}

}  // namespace MacFileUtilities
