// 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_id.cc: Functions to gather identifying information from a macho file
//
// See macho_id.h for documentation
//
// Author: Dan Waylonis

extern "C" {  // necessary for Leopard
  #include <fcntl.h>
  #include <mach-o/loader.h>
  #include <mach-o/swap.h>
  #include <stdio.h>
  #include <stdlib.h>
  #include <string.h>
  #include <sys/time.h>
  #include <sys/types.h>
  #include <unistd.h>
}

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

namespace MacFileUtilities {

using google_breakpad::MD5Init;
using google_breakpad::MD5Update;
using google_breakpad::MD5Final;

MachoID::MachoID(const char *path)
   : memory_(0),
     memory_size_(0),
     crc_(0), 
     md5_context_(), 
     update_function_(NULL) {
  strlcpy(path_, path, sizeof(path_));
}

MachoID::MachoID(const char *path, void *memory, size_t size)
   : memory_(memory),
     memory_size_(size),
     crc_(0), 
     md5_context_(), 
     update_function_(NULL) {
  strlcpy(path_, path, sizeof(path_));
}

MachoID::~MachoID() {
}

// The CRC info is from http://en.wikipedia.org/wiki/Adler-32
// With optimizations from http://www.zlib.net/

// The largest prime smaller than 65536
#define MOD_ADLER 65521
// MAX_BLOCK is the largest n such that 255n(n+1)/2 + (n+1)(MAX_BLOCK-1) <= 2^32-1
#define MAX_BLOCK 5552

void MachoID::UpdateCRC(unsigned char *bytes, size_t size) {
// Unrolled loops for summing
#define DO1(buf,i)  {sum1 += (buf)[i]; sum2 += sum1;}
#define DO2(buf,i)  DO1(buf,i); DO1(buf,i+1);
#define DO4(buf,i)  DO2(buf,i); DO2(buf,i+2);
#define DO8(buf,i)  DO4(buf,i); DO4(buf,i+4);
#define DO16(buf)   DO8(buf,0); DO8(buf,8);
  // Split up the crc
  uint32_t sum1 = crc_ & 0xFFFF;
  uint32_t sum2 = (crc_ >> 16) & 0xFFFF;

  // Do large blocks
  while (size >= MAX_BLOCK) {
    size -= MAX_BLOCK;
    int block_count = MAX_BLOCK / 16;
    do {
      DO16(bytes);
      bytes += 16;
    } while (--block_count);
    sum1 %= MOD_ADLER;
    sum2 %= MOD_ADLER;
  }

  // Do remaining bytes
  if (size) {
    while (size >= 16) {
      size -= 16;
      DO16(bytes);
      bytes += 16;
    }
    while (size--) {
      sum1 += *bytes++;
      sum2 += sum1;
    }
    sum1 %= MOD_ADLER;
    sum2 %= MOD_ADLER;
    crc_ = (sum2 << 16) | sum1;
  }
}

void MachoID::UpdateMD5(unsigned char *bytes, size_t size) {
  MD5Update(&md5_context_, bytes, static_cast<unsigned>(size));
}

void MachoID::Update(MachoWalker *walker, off_t offset, size_t size) {
  if (!update_function_ || !size)
    return;

  // Read up to 4k bytes at a time
  unsigned char buffer[4096];
  size_t buffer_size;
  off_t file_offset = offset;
  while (size > 0) {
    if (size > sizeof(buffer)) {
      buffer_size = sizeof(buffer);
      size -= buffer_size;
    } else {
      buffer_size = size;
      size = 0;
    }

    if (!walker->ReadBytes(buffer, buffer_size, file_offset))
      return;

    (this->*update_function_)(buffer, buffer_size);
    file_offset += buffer_size;
  }
}

bool MachoID::UUIDCommand(cpu_type_t cpu_type,
                          cpu_subtype_t cpu_subtype,
                          unsigned char bytes[16]) {
  struct breakpad_uuid_command uuid_cmd;
  uuid_cmd.cmd = 0;
  if (!WalkHeader(cpu_type, cpu_subtype, UUIDWalkerCB, &uuid_cmd))
    return false;

  // If we found the command, we'll have initialized the uuid_command
  // structure
  if (uuid_cmd.cmd == LC_UUID) {
    memcpy(bytes, uuid_cmd.uuid, sizeof(uuid_cmd.uuid));
    return true;
  }

  return false;
}

bool MachoID::IDCommand(cpu_type_t cpu_type,
                        cpu_subtype_t cpu_subtype,
                        unsigned char identifier[16]) {
  struct dylib_command dylib_cmd;
  dylib_cmd.cmd = 0;
  if (!WalkHeader(cpu_type, cpu_subtype, IDWalkerCB, &dylib_cmd))
    return false;

  // If we found the command, we'll have initialized the dylib_command
  // structure
  if (dylib_cmd.cmd == LC_ID_DYLIB) {
    // Take the hashed filename, version, and compatability version bytes
    // to form the first 12 bytes, pad the rest with zeros

    // create a crude hash of the filename to generate the first 4 bytes
    identifier[0] = 0;
    identifier[1] = 0;
    identifier[2] = 0;
    identifier[3] = 0;

    for (int j = 0, i = (int)strlen(path_)-1; i>=0 && path_[i]!='/'; ++j, --i) {
      identifier[j%4] += path_[i];
    }

    identifier[4] = (dylib_cmd.dylib.current_version >> 24) & 0xFF;
    identifier[5] = (dylib_cmd.dylib.current_version >> 16) & 0xFF;
    identifier[6] = (dylib_cmd.dylib.current_version >> 8) & 0xFF;
    identifier[7] = dylib_cmd.dylib.current_version & 0xFF;
    identifier[8] = (dylib_cmd.dylib.compatibility_version >> 24) & 0xFF;
    identifier[9] = (dylib_cmd.dylib.compatibility_version >> 16) & 0xFF;
    identifier[10] = (dylib_cmd.dylib.compatibility_version >> 8) & 0xFF;
    identifier[11] = dylib_cmd.dylib.compatibility_version & 0xFF;
    identifier[12] = (cpu_type >> 24) & 0xFF;
    identifier[13] = (cpu_type >> 16) & 0xFF;
    identifier[14] = (cpu_type >> 8) & 0xFF;
    identifier[15] = cpu_type & 0xFF;

    return true;
  }

  return false;
}

uint32_t MachoID::Adler32(cpu_type_t cpu_type, cpu_subtype_t cpu_subtype) {
  update_function_ = &MachoID::UpdateCRC;
  crc_ = 0;

  if (!WalkHeader(cpu_type, cpu_subtype, WalkerCB, this))
    return 0;

  return crc_;
}

bool MachoID::MD5(cpu_type_t cpu_type, cpu_subtype_t cpu_subtype, unsigned char identifier[16]) {
  update_function_ = &MachoID::UpdateMD5;

  MD5Init(&md5_context_);

  if (!WalkHeader(cpu_type, cpu_subtype, WalkerCB, this))
    return false;

  MD5Final(identifier, &md5_context_);
  return true;
}

bool MachoID::WalkHeader(cpu_type_t cpu_type,
                         cpu_subtype_t cpu_subtype,
                         MachoWalker::LoadCommandCallback callback,
                         void *context) {
  if (memory_) {
    MachoWalker walker(memory_, memory_size_, callback, context);
    return walker.WalkHeader(cpu_type, cpu_subtype);
  } else {
    MachoWalker walker(path_, callback, context);
    return walker.WalkHeader(cpu_type, cpu_subtype);
  }
}

// static
bool MachoID::WalkerCB(MachoWalker *walker, load_command *cmd, off_t offset,
                       bool swap, void *context) {
  MachoID *macho_id = (MachoID *)context;

  if (cmd->cmd == LC_SEGMENT) {
    struct segment_command seg;

    if (!walker->ReadBytes(&seg, sizeof(seg), offset))
      return false;

    if (swap)
      swap_segment_command(&seg, NXHostByteOrder());

    struct mach_header_64 header;
    off_t header_offset;
    
    if (!walker->CurrentHeader(&header, &header_offset))
      return false;
        
    // Process segments that have sections:
    // (e.g., __TEXT, __DATA, __IMPORT, __OBJC)
    offset += sizeof(struct segment_command);
    struct section sec;
    for (unsigned long i = 0; i < seg.nsects; ++i) {
      if (!walker->ReadBytes(&sec, sizeof(sec), offset))
        return false;

      if (swap)
        swap_section(&sec, 1, NXHostByteOrder());

      // sections of type S_ZEROFILL are "virtual" and contain no data
      // in the file itself
      if ((sec.flags & SECTION_TYPE) != S_ZEROFILL && sec.offset != 0)
        macho_id->Update(walker, header_offset + sec.offset, sec.size);

      offset += sizeof(struct section);
    }
  } else if (cmd->cmd == LC_SEGMENT_64) {
    struct segment_command_64 seg64;

    if (!walker->ReadBytes(&seg64, sizeof(seg64), offset))
      return false;

    if (swap)
      breakpad_swap_segment_command_64(&seg64, NXHostByteOrder());

    struct mach_header_64 header;
    off_t header_offset;
    
    if (!walker->CurrentHeader(&header, &header_offset))
      return false;
    
    // Process segments that have sections:
    // (e.g., __TEXT, __DATA, __IMPORT, __OBJC)
    offset += sizeof(struct segment_command_64);
    struct section_64 sec64;
    for (unsigned long i = 0; i < seg64.nsects; ++i) {
      if (!walker->ReadBytes(&sec64, sizeof(sec64), offset))
        return false;

      if (swap)
        breakpad_swap_section_64(&sec64, 1, NXHostByteOrder());

      // sections of type S_ZEROFILL are "virtual" and contain no data
      // in the file itself
      if ((sec64.flags & SECTION_TYPE) != S_ZEROFILL && sec64.offset != 0)
        macho_id->Update(walker, 
                         header_offset + sec64.offset, 
                         (size_t)sec64.size);

      offset += sizeof(struct section_64);
    }
  }

  // Continue processing
  return true;
}

// static
bool MachoID::UUIDWalkerCB(MachoWalker *walker, load_command *cmd, off_t offset,
                           bool swap, void *context) {
  if (cmd->cmd == LC_UUID) {
    struct breakpad_uuid_command *uuid_cmd =
      (struct breakpad_uuid_command *)context;

    if (!walker->ReadBytes(uuid_cmd, sizeof(struct breakpad_uuid_command),
                           offset))
      return false;

    if (swap)
      breakpad_swap_uuid_command(uuid_cmd, NXHostByteOrder());

    return false;
  }

  // Continue processing
  return true;
}

// static
bool MachoID::IDWalkerCB(MachoWalker *walker, load_command *cmd, off_t offset,
                         bool swap, void *context) {
  if (cmd->cmd == LC_ID_DYLIB) {
    struct dylib_command *dylib_cmd = (struct dylib_command *)context;

    if (!walker->ReadBytes(dylib_cmd, sizeof(struct dylib_command), offset))
      return false;

    if (swap)
      swap_dylib_command(dylib_cmd, NXHostByteOrder());

    return false;
  }

  // Continue processing
  return true;
}

}  // namespace MacFileUtilities
