// 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.

#include <algorithm>
#include <cstdio>

#include <mach/host_info.h>
#include <mach/machine.h>
#include <mach/vm_statistics.h>
#include <mach-o/dyld.h>
#include <mach-o/loader.h>
#include <sys/sysctl.h>
#include <sys/resource.h>

#include <CoreFoundation/CoreFoundation.h>

#include "client/mac/handler/minidump_generator.h"

#if defined(HAS_ARM_SUPPORT) || defined(HAS_ARM64_SUPPORT)
#include <mach/arm/thread_status.h>
#endif
#ifdef HAS_PPC_SUPPORT
#include <mach/ppc/thread_status.h>
#endif
#ifdef HAS_X86_SUPPORT
#include <mach/i386/thread_status.h>
#endif

#include "client/minidump_file_writer-inl.h"
#include "common/mac/file_id.h"
#include "common/mac/macho_id.h"
#include "common/mac/string_utilities.h"

using MacStringUtils::ConvertToString;
using MacStringUtils::IntegerValueAtIndex;

namespace google_breakpad {

#if defined(__LP64__) && __LP64__
#define LC_SEGMENT_ARCH LC_SEGMENT_64
#else
#define LC_SEGMENT_ARCH LC_SEGMENT
#endif

// constructor when generating from within the crashed process
MinidumpGenerator::MinidumpGenerator()
    : writer_(),
      exception_type_(0),
      exception_code_(0),
      exception_subcode_(0),
      exception_thread_(0),
      crashing_task_(mach_task_self()),
      handler_thread_(mach_thread_self()),
      cpu_type_(DynamicImages::GetNativeCPUType()),
      task_context_(NULL),
      dynamic_images_(NULL),
      memory_blocks_(&allocator_) {
  GatherSystemInformation();
}

// constructor when generating from a different process than the
// crashed process
MinidumpGenerator::MinidumpGenerator(mach_port_t crashing_task,
                                     mach_port_t handler_thread)
    : writer_(),
      exception_type_(0),
      exception_code_(0),
      exception_subcode_(0),
      exception_thread_(0),
      crashing_task_(crashing_task),
      handler_thread_(handler_thread),
      cpu_type_(DynamicImages::GetNativeCPUType()),
      task_context_(NULL),
      dynamic_images_(NULL),
      memory_blocks_(&allocator_) {
  if (crashing_task != mach_task_self()) {
    dynamic_images_ = new DynamicImages(crashing_task_);
    cpu_type_ = dynamic_images_->GetCPUType();
  } else {
    dynamic_images_ = NULL;
    cpu_type_ = DynamicImages::GetNativeCPUType();
  }

  GatherSystemInformation();
}

MinidumpGenerator::~MinidumpGenerator() {
  delete dynamic_images_;
}

char MinidumpGenerator::build_string_[16];
int MinidumpGenerator::os_major_version_ = 0;
int MinidumpGenerator::os_minor_version_ = 0;
int MinidumpGenerator::os_build_number_ = 0;

// static
void MinidumpGenerator::GatherSystemInformation() {
  // If this is non-zero, then we've already gathered the information
  if (os_major_version_)
    return;

  // This code extracts the version and build information from the OS
  CFStringRef vers_path =
    CFSTR("/System/Library/CoreServices/SystemVersion.plist");
  CFURLRef sys_vers =
    CFURLCreateWithFileSystemPath(NULL,
                                  vers_path,
                                  kCFURLPOSIXPathStyle,
                                  false);
  CFReadStreamRef read_stream = CFReadStreamCreateWithFile(NULL, sys_vers);
  CFRelease(sys_vers);
  if (!read_stream) {
    return;
  }
  if (!CFReadStreamOpen(read_stream)) {
    CFRelease(read_stream);
    return;
  }
  CFMutableDataRef data = NULL;
  while (true) {
    // Actual data file tests: Mac at 480 bytes and iOS at 413 bytes.
    const CFIndex kMaxBufferLength = 1024;
    UInt8 data_bytes[kMaxBufferLength];
    CFIndex num_bytes_read =
      CFReadStreamRead(read_stream, data_bytes, kMaxBufferLength);
    if (num_bytes_read < 0) {
      if (data) {
        CFRelease(data);
        data = NULL;
      }
      break;
    } else if (num_bytes_read == 0) {
      break;
    } else if (!data) {
      data = CFDataCreateMutable(NULL, 0);
    }
    CFDataAppendBytes(data, data_bytes, num_bytes_read);
  }
  CFReadStreamClose(read_stream);
  CFRelease(read_stream);
  if (!data) {
    return;
  }
  CFDictionaryRef list =
      static_cast<CFDictionaryRef>(CFPropertyListCreateWithData(
          NULL, data, kCFPropertyListImmutable, NULL, NULL));
  CFRelease(data);
  if (!list) {
    return;
  }
  CFStringRef build_version = static_cast<CFStringRef>
    (CFDictionaryGetValue(list, CFSTR("ProductBuildVersion")));
  CFStringRef product_version = static_cast<CFStringRef>
    (CFDictionaryGetValue(list, CFSTR("ProductVersion")));
  string build_str = ConvertToString(build_version);
  string product_str = ConvertToString(product_version);

  CFRelease(list);

  strlcpy(build_string_, build_str.c_str(), sizeof(build_string_));

  // Parse the string that looks like "10.4.8"
  os_major_version_ = IntegerValueAtIndex(product_str, 0);
  os_minor_version_ = IntegerValueAtIndex(product_str, 1);
  os_build_number_ = IntegerValueAtIndex(product_str, 2);
}

void MinidumpGenerator::SetTaskContext(breakpad_ucontext_t *task_context) {
  task_context_ = task_context;
}

string MinidumpGenerator::UniqueNameInDirectory(const string &dir,
                                                string *unique_name) {
  CFUUIDRef uuid = CFUUIDCreate(NULL);
  CFStringRef uuid_cfstr = CFUUIDCreateString(NULL, uuid);
  CFRelease(uuid);
  string file_name(ConvertToString(uuid_cfstr));
  CFRelease(uuid_cfstr);
  string path(dir);

  // Ensure that the directory (if non-empty) has a trailing slash so that
  // we can append the file name and have a valid pathname.
  if (!dir.empty()) {
    if (dir.at(dir.size() - 1) != '/')
      path.append(1, '/');
  }

  path.append(file_name);
  path.append(".dmp");

  if (unique_name)
    *unique_name = file_name;

  return path;
}

bool MinidumpGenerator::Write(const char *path) {
  WriteStreamFN writers[] = {
    &MinidumpGenerator::WriteThreadListStream,
    &MinidumpGenerator::WriteMemoryListStream,
    &MinidumpGenerator::WriteSystemInfoStream,
    &MinidumpGenerator::WriteModuleListStream,
    &MinidumpGenerator::WriteMiscInfoStream,
    &MinidumpGenerator::WriteBreakpadInfoStream,
    // Exception stream needs to be the last entry in this array as it may
    // be omitted in the case where the minidump is written without an
    // exception.
    &MinidumpGenerator::WriteExceptionStream,
  };
  bool result = false;

  // If opening was successful, create the header, directory, and call each
  // writer.  The destructor for the TypedMDRVAs will cause the data to be
  // flushed.  The destructor for the MinidumpFileWriter will close the file.
  if (writer_.Open(path)) {
    TypedMDRVA<MDRawHeader> header(&writer_);
    TypedMDRVA<MDRawDirectory> dir(&writer_);

    if (!header.Allocate())
      return false;

    int writer_count = static_cast<int>(sizeof(writers) / sizeof(writers[0]));

    // If we don't have exception information, don't write out the
    // exception stream
    if (!exception_thread_ && !exception_type_)
      --writer_count;

    // Add space for all writers
    if (!dir.AllocateArray(writer_count))
      return false;

    MDRawHeader *header_ptr = header.get();
    header_ptr->signature = MD_HEADER_SIGNATURE;
    header_ptr->version = MD_HEADER_VERSION;
    time(reinterpret_cast<time_t *>(&(header_ptr->time_date_stamp)));
    header_ptr->stream_count = writer_count;
    header_ptr->stream_directory_rva = dir.position();

    MDRawDirectory local_dir;
    result = true;
    for (int i = 0; (result) && (i < writer_count); ++i) {
      result = (this->*writers[i])(&local_dir);

      if (result)
        dir.CopyIndex(i, &local_dir);
    }
  }
  return result;
}

size_t MinidumpGenerator::CalculateStackSize(mach_vm_address_t start_addr) {
  mach_vm_address_t stack_region_base = start_addr;
  mach_vm_size_t stack_region_size;
  natural_t nesting_level = 0;
  vm_region_submap_info_64 submap_info;
  mach_msg_type_number_t info_count = VM_REGION_SUBMAP_INFO_COUNT_64;

  vm_region_recurse_info_t region_info;
  region_info = reinterpret_cast<vm_region_recurse_info_t>(&submap_info);

  if (start_addr == 0) {
    return 0;
  }

  kern_return_t result =
    mach_vm_region_recurse(crashing_task_, &stack_region_base,
                           &stack_region_size, &nesting_level,
                           region_info, &info_count);

  if (result != KERN_SUCCESS || start_addr < stack_region_base) {
    // Failure or stack corruption, since mach_vm_region had to go
    // higher in the process address space to find a valid region.
    return 0;
  }

  unsigned int tag = submap_info.user_tag;

  // If the user tag is VM_MEMORY_STACK, look for more readable regions with
  // the same tag placed immediately above the computed stack region. Under
  // some circumstances, the stack for thread 0 winds up broken up into
  // multiple distinct abutting regions. This can happen for several reasons,
  // including user code that calls setrlimit(RLIMIT_STACK, ...) or changes
  // the access on stack pages by calling mprotect.
  if (tag == VM_MEMORY_STACK) {
    while (true) {
      mach_vm_address_t next_region_base = stack_region_base +
                                           stack_region_size;
      mach_vm_address_t proposed_next_region_base = next_region_base;
      mach_vm_size_t next_region_size;
      nesting_level = 0;
      info_count = VM_REGION_SUBMAP_INFO_COUNT_64;
      result = mach_vm_region_recurse(crashing_task_, &next_region_base,
                                      &next_region_size, &nesting_level,
                                      region_info, &info_count);
      if (result != KERN_SUCCESS ||
          next_region_base != proposed_next_region_base ||
          submap_info.user_tag != tag ||
          (submap_info.protection & VM_PROT_READ) == 0) {
        break;
      }

      stack_region_size += next_region_size;
    }
  }

  return stack_region_base + stack_region_size - start_addr;
}

bool MinidumpGenerator::WriteStackFromStartAddress(
    mach_vm_address_t start_addr,
    MDMemoryDescriptor *stack_location) {
  UntypedMDRVA memory(&writer_);

  bool result = false;
  size_t size = CalculateStackSize(start_addr);

  if (size == 0) {
      // In some situations the stack address for the thread can come back 0.
      // In these cases we skip over the threads in question and stuff the
      // stack with a clearly borked value.
      start_addr = 0xDEADBEEF;
      size = 16;
      if (!memory.Allocate(size))
        return false;

      unsigned long long dummy_stack[2];  // Fill dummy stack with 16 bytes of
                                          // junk.
      dummy_stack[0] = 0xDEADBEEF;
      dummy_stack[1] = 0xDEADBEEF;

      result = memory.Copy(dummy_stack, size);
  } else {

    if (!memory.Allocate(size))
      return false;

    if (dynamic_images_) {
      vector<uint8_t> stack_memory;
      if (ReadTaskMemory(crashing_task_,
                         start_addr,
                         size,
                         stack_memory) != KERN_SUCCESS) {
        return false;
      }

      result = memory.Copy(&stack_memory[0], size);
    } else {
      result = memory.Copy(reinterpret_cast<const void *>(start_addr), size);
    }
  }

  stack_location->start_of_memory_range = start_addr;
  stack_location->memory = memory.location();

  return result;
}

bool MinidumpGenerator::WriteStack(breakpad_thread_state_data_t state,
                                   MDMemoryDescriptor *stack_location) {
  switch (cpu_type_) {
#ifdef HAS_ARM_SUPPORT
    case CPU_TYPE_ARM:
      return WriteStackARM(state, stack_location);
#endif
#ifdef HAS_ARM64_SUPPORT
    case CPU_TYPE_ARM64:
      return WriteStackARM64(state, stack_location);
#endif
#ifdef HAS_PPC_SUPPORT
    case CPU_TYPE_POWERPC:
      return WriteStackPPC(state, stack_location);
    case CPU_TYPE_POWERPC64:
      return WriteStackPPC64(state, stack_location);
#endif
#ifdef HAS_X86_SUPPORT
    case CPU_TYPE_I386:
      return WriteStackX86(state, stack_location);
    case CPU_TYPE_X86_64:
      return WriteStackX86_64(state, stack_location);
#endif
    default:
      return false;
  }
}

bool MinidumpGenerator::WriteContext(breakpad_thread_state_data_t state,
                                     MDLocationDescriptor *register_location) {
  switch (cpu_type_) {
#ifdef HAS_ARM_SUPPORT
    case CPU_TYPE_ARM:
      return WriteContextARM(state, register_location);
#endif
#ifdef HAS_ARM64_SUPPORT
    case CPU_TYPE_ARM64:
      return WriteContextARM64(state, register_location);
#endif
#ifdef HAS_PPC_SUPPORT
    case CPU_TYPE_POWERPC:
      return WriteContextPPC(state, register_location);
    case CPU_TYPE_POWERPC64:
      return WriteContextPPC64(state, register_location);
#endif
#ifdef HAS_X86_SUPPORT
    case CPU_TYPE_I386:
      return WriteContextX86(state, register_location);
    case CPU_TYPE_X86_64:
      return WriteContextX86_64(state, register_location);
#endif
    default:
      return false;
  }
}

uint64_t MinidumpGenerator::CurrentPCForStack(
    breakpad_thread_state_data_t state) {
  switch (cpu_type_) {
#ifdef HAS_ARM_SUPPORT
    case CPU_TYPE_ARM:
      return CurrentPCForStackARM(state);
#endif
#ifdef HAS_ARM64_SUPPORT
    case CPU_TYPE_ARM64:
      return CurrentPCForStackARM64(state);
#endif
#ifdef HAS_PPC_SUPPORT
    case CPU_TYPE_POWERPC:
      return CurrentPCForStackPPC(state);
    case CPU_TYPE_POWERPC64:
      return CurrentPCForStackPPC64(state);
#endif
#ifdef HAS_X86_SUPPORT
    case CPU_TYPE_I386:
      return CurrentPCForStackX86(state);
    case CPU_TYPE_X86_64:
      return CurrentPCForStackX86_64(state);
#endif
    default:
      assert(0 && "Unknown CPU type!");
      return 0;
  }
}

#ifdef HAS_ARM_SUPPORT
bool MinidumpGenerator::WriteStackARM(breakpad_thread_state_data_t state,
                                      MDMemoryDescriptor *stack_location) {
  arm_thread_state_t *machine_state =
      reinterpret_cast<arm_thread_state_t *>(state);
  mach_vm_address_t start_addr = REGISTER_FROM_THREADSTATE(machine_state, sp);
  return WriteStackFromStartAddress(start_addr, stack_location);
}

uint64_t
MinidumpGenerator::CurrentPCForStackARM(breakpad_thread_state_data_t state) {
  arm_thread_state_t *machine_state =
      reinterpret_cast<arm_thread_state_t *>(state);

  return REGISTER_FROM_THREADSTATE(machine_state, pc);
}

bool MinidumpGenerator::WriteContextARM(breakpad_thread_state_data_t state,
                                        MDLocationDescriptor *register_location)
{
  TypedMDRVA<MDRawContextARM> context(&writer_);
  arm_thread_state_t *machine_state =
      reinterpret_cast<arm_thread_state_t *>(state);

  if (!context.Allocate())
    return false;

  *register_location = context.location();
  MDRawContextARM *context_ptr = context.get();
  context_ptr->context_flags = MD_CONTEXT_ARM_FULL;

#define AddGPR(a) context_ptr->iregs[a] = REGISTER_FROM_THREADSTATE(machine_state, r[a])

  context_ptr->iregs[13] = REGISTER_FROM_THREADSTATE(machine_state, sp);
  context_ptr->iregs[14] = REGISTER_FROM_THREADSTATE(machine_state, lr);
  context_ptr->iregs[15] = REGISTER_FROM_THREADSTATE(machine_state, pc);
  context_ptr->cpsr = REGISTER_FROM_THREADSTATE(machine_state, cpsr);

  AddGPR(0);
  AddGPR(1);
  AddGPR(2);
  AddGPR(3);
  AddGPR(4);
  AddGPR(5);
  AddGPR(6);
  AddGPR(7);
  AddGPR(8);
  AddGPR(9);
  AddGPR(10);
  AddGPR(11);
  AddGPR(12);
#undef AddGPR

  return true;
}
#endif

#ifdef HAS_ARM64_SUPPORT
bool MinidumpGenerator::WriteStackARM64(breakpad_thread_state_data_t state,
                                        MDMemoryDescriptor *stack_location) {
  arm_thread_state64_t *machine_state =
      reinterpret_cast<arm_thread_state64_t *>(state);
  mach_vm_address_t start_addr = REGISTER_FROM_THREADSTATE(machine_state, sp);
  return WriteStackFromStartAddress(start_addr, stack_location);
}

uint64_t
MinidumpGenerator::CurrentPCForStackARM64(breakpad_thread_state_data_t state) {
  arm_thread_state64_t *machine_state =
      reinterpret_cast<arm_thread_state64_t *>(state);

  return REGISTER_FROM_THREADSTATE(machine_state, pc);
}

bool
MinidumpGenerator::WriteContextARM64(breakpad_thread_state_data_t state,
                                     MDLocationDescriptor *register_location)
{
  TypedMDRVA<MDRawContextARM64> context(&writer_);
  arm_thread_state64_t *machine_state =
      reinterpret_cast<arm_thread_state64_t *>(state);

  if (!context.Allocate())
    return false;

  *register_location = context.location();
  MDRawContextARM64 *context_ptr = context.get();
  context_ptr->context_flags = MD_CONTEXT_ARM64_FULL;

#define AddGPR(a) context_ptr->iregs[a] = \
    REGISTER_FROM_THREADSTATE(machine_state, x[a])

  context_ptr->iregs[29] = REGISTER_FROM_THREADSTATE(machine_state, fp);
  context_ptr->iregs[30] = REGISTER_FROM_THREADSTATE(machine_state, lr);
  context_ptr->iregs[31] = REGISTER_FROM_THREADSTATE(machine_state, sp);
  context_ptr->iregs[32] = REGISTER_FROM_THREADSTATE(machine_state, pc);
  context_ptr->cpsr = REGISTER_FROM_THREADSTATE(machine_state, cpsr);

  AddGPR(0);
  AddGPR(1);
  AddGPR(2);
  AddGPR(3);
  AddGPR(4);
  AddGPR(5);
  AddGPR(6);
  AddGPR(7);
  AddGPR(8);
  AddGPR(9);
  AddGPR(10);
  AddGPR(11);
  AddGPR(12);
  AddGPR(13);
  AddGPR(14);
  AddGPR(15);
  AddGPR(16);
  AddGPR(17);
  AddGPR(18);
  AddGPR(19);
  AddGPR(20);
  AddGPR(21);
  AddGPR(22);
  AddGPR(23);
  AddGPR(24);
  AddGPR(25);
  AddGPR(26);
  AddGPR(27);
  AddGPR(28);
#undef AddGPR

  return true;
}
#endif

#ifdef HAS_PCC_SUPPORT
bool MinidumpGenerator::WriteStackPPC(breakpad_thread_state_data_t state,
                                      MDMemoryDescriptor *stack_location) {
  ppc_thread_state_t *machine_state =
      reinterpret_cast<ppc_thread_state_t *>(state);
  mach_vm_address_t start_addr = REGISTER_FROM_THREADSTATE(machine_state, r1);
  return WriteStackFromStartAddress(start_addr, stack_location);
}

bool MinidumpGenerator::WriteStackPPC64(breakpad_thread_state_data_t state,
                                        MDMemoryDescriptor *stack_location) {
  ppc_thread_state64_t *machine_state =
      reinterpret_cast<ppc_thread_state64_t *>(state);
  mach_vm_address_t start_addr = REGISTER_FROM_THREADSTATE(machine_state, r1);
  return WriteStackFromStartAddress(start_addr, stack_location);
}

uint64_t
MinidumpGenerator::CurrentPCForStackPPC(breakpad_thread_state_data_t state) {
  ppc_thread_state_t *machine_state =
      reinterpret_cast<ppc_thread_state_t *>(state);

  return REGISTER_FROM_THREADSTATE(machine_state, srr0);
}

uint64_t
MinidumpGenerator::CurrentPCForStackPPC64(breakpad_thread_state_data_t state) {
  ppc_thread_state64_t *machine_state =
      reinterpret_cast<ppc_thread_state64_t *>(state);

  return REGISTER_FROM_THREADSTATE(machine_state, srr0);
}

bool MinidumpGenerator::WriteContextPPC(breakpad_thread_state_data_t state,
                                        MDLocationDescriptor *register_location)
{
  TypedMDRVA<MDRawContextPPC> context(&writer_);
  ppc_thread_state_t *machine_state =
      reinterpret_cast<ppc_thread_state_t *>(state);

  if (!context.Allocate())
    return false;

  *register_location = context.location();
  MDRawContextPPC *context_ptr = context.get();
  context_ptr->context_flags = MD_CONTEXT_PPC_BASE;

#define AddReg(a) context_ptr->a = static_cast<__typeof__(context_ptr->a)>( \
    REGISTER_FROM_THREADSTATE(machine_state, a))
#define AddGPR(a) context_ptr->gpr[a] = \
    static_cast<__typeof__(context_ptr->a)>( \
    REGISTER_FROM_THREADSTATE(machine_state, r ## a)

  AddReg(srr0);
  AddReg(cr);
  AddReg(xer);
  AddReg(ctr);
  AddReg(lr);
  AddReg(vrsave);

  AddGPR(0);
  AddGPR(1);
  AddGPR(2);
  AddGPR(3);
  AddGPR(4);
  AddGPR(5);
  AddGPR(6);
  AddGPR(7);
  AddGPR(8);
  AddGPR(9);
  AddGPR(10);
  AddGPR(11);
  AddGPR(12);
  AddGPR(13);
  AddGPR(14);
  AddGPR(15);
  AddGPR(16);
  AddGPR(17);
  AddGPR(18);
  AddGPR(19);
  AddGPR(20);
  AddGPR(21);
  AddGPR(22);
  AddGPR(23);
  AddGPR(24);
  AddGPR(25);
  AddGPR(26);
  AddGPR(27);
  AddGPR(28);
  AddGPR(29);
  AddGPR(30);
  AddGPR(31);
  AddReg(mq);
#undef AddReg
#undef AddGPR

  return true;
}

bool MinidumpGenerator::WriteContextPPC64(
    breakpad_thread_state_data_t state,
    MDLocationDescriptor *register_location) {
  TypedMDRVA<MDRawContextPPC64> context(&writer_);
  ppc_thread_state64_t *machine_state =
      reinterpret_cast<ppc_thread_state64_t *>(state);

  if (!context.Allocate())
    return false;

  *register_location = context.location();
  MDRawContextPPC64 *context_ptr = context.get();
  context_ptr->context_flags = MD_CONTEXT_PPC_BASE;

#define AddReg(a) context_ptr->a = static_cast<__typeof__(context_ptr->a)>( \
    REGISTER_FROM_THREADSTATE(machine_state, a))
#define AddGPR(a) context_ptr->gpr[a] = \
    static_cast<__typeof__(context_ptr->a)>( \
    REGISTER_FROM_THREADSTATE(machine_state, r ## a)

  AddReg(srr0);
  AddReg(cr);
  AddReg(xer);
  AddReg(ctr);
  AddReg(lr);
  AddReg(vrsave);

  AddGPR(0);
  AddGPR(1);
  AddGPR(2);
  AddGPR(3);
  AddGPR(4);
  AddGPR(5);
  AddGPR(6);
  AddGPR(7);
  AddGPR(8);
  AddGPR(9);
  AddGPR(10);
  AddGPR(11);
  AddGPR(12);
  AddGPR(13);
  AddGPR(14);
  AddGPR(15);
  AddGPR(16);
  AddGPR(17);
  AddGPR(18);
  AddGPR(19);
  AddGPR(20);
  AddGPR(21);
  AddGPR(22);
  AddGPR(23);
  AddGPR(24);
  AddGPR(25);
  AddGPR(26);
  AddGPR(27);
  AddGPR(28);
  AddGPR(29);
  AddGPR(30);
  AddGPR(31);
#undef AddReg
#undef AddGPR

  return true;
}

#endif

#ifdef HAS_X86_SUPPORT
bool MinidumpGenerator::WriteStackX86(breakpad_thread_state_data_t state,
                                   MDMemoryDescriptor *stack_location) {
  i386_thread_state_t *machine_state =
      reinterpret_cast<i386_thread_state_t *>(state);

  mach_vm_address_t start_addr = REGISTER_FROM_THREADSTATE(machine_state, esp);
  return WriteStackFromStartAddress(start_addr, stack_location);
}

bool MinidumpGenerator::WriteStackX86_64(breakpad_thread_state_data_t state,
                                         MDMemoryDescriptor *stack_location) {
  x86_thread_state64_t *machine_state =
      reinterpret_cast<x86_thread_state64_t *>(state);

  mach_vm_address_t start_addr = static_cast<mach_vm_address_t>(
      REGISTER_FROM_THREADSTATE(machine_state, rsp));
  return WriteStackFromStartAddress(start_addr, stack_location);
}

uint64_t
MinidumpGenerator::CurrentPCForStackX86(breakpad_thread_state_data_t state) {
  i386_thread_state_t *machine_state =
      reinterpret_cast<i386_thread_state_t *>(state);

  return REGISTER_FROM_THREADSTATE(machine_state, eip);
}

uint64_t
MinidumpGenerator::CurrentPCForStackX86_64(breakpad_thread_state_data_t state) {
  x86_thread_state64_t *machine_state =
      reinterpret_cast<x86_thread_state64_t *>(state);

  return REGISTER_FROM_THREADSTATE(machine_state, rip);
}

bool MinidumpGenerator::WriteContextX86(breakpad_thread_state_data_t state,
                                        MDLocationDescriptor *register_location)
{
  TypedMDRVA<MDRawContextX86> context(&writer_);
  i386_thread_state_t *machine_state =
      reinterpret_cast<i386_thread_state_t *>(state);

  if (!context.Allocate())
    return false;

  *register_location = context.location();
  MDRawContextX86 *context_ptr = context.get();

#define AddReg(a) context_ptr->a = static_cast<__typeof__(context_ptr->a)>( \
    REGISTER_FROM_THREADSTATE(machine_state, a))

  context_ptr->context_flags = MD_CONTEXT_X86;
  AddReg(eax);
  AddReg(ebx);
  AddReg(ecx);
  AddReg(edx);
  AddReg(esi);
  AddReg(edi);
  AddReg(ebp);
  AddReg(esp);

  AddReg(cs);
  AddReg(ds);
  AddReg(ss);
  AddReg(es);
  AddReg(fs);
  AddReg(gs);
  AddReg(eflags);

  AddReg(eip);
#undef AddReg

  return true;
}

bool MinidumpGenerator::WriteContextX86_64(
    breakpad_thread_state_data_t state,
    MDLocationDescriptor *register_location) {
  TypedMDRVA<MDRawContextAMD64> context(&writer_);
  x86_thread_state64_t *machine_state =
      reinterpret_cast<x86_thread_state64_t *>(state);

  if (!context.Allocate())
    return false;

  *register_location = context.location();
  MDRawContextAMD64 *context_ptr = context.get();

#define AddReg(a) context_ptr->a = static_cast<__typeof__(context_ptr->a)>( \
    REGISTER_FROM_THREADSTATE(machine_state, a))

  context_ptr->context_flags = MD_CONTEXT_AMD64;
  AddReg(rax);
  AddReg(rbx);
  AddReg(rcx);
  AddReg(rdx);
  AddReg(rdi);
  AddReg(rsi);
  AddReg(rbp);
  AddReg(rsp);
  AddReg(r8);
  AddReg(r9);
  AddReg(r10);
  AddReg(r11);
  AddReg(r12);
  AddReg(r13);
  AddReg(r14);
  AddReg(r15);
  AddReg(rip);
  // according to AMD's software developer guide, bits above 18 are
  // not used in the flags register.  Since the minidump format
  // specifies 32 bits for the flags register, we can truncate safely
  // with no loss.
  context_ptr->eflags = static_cast<uint32_t>(REGISTER_FROM_THREADSTATE(machine_state, rflags));
  AddReg(cs);
  AddReg(fs);
  AddReg(gs);
#undef AddReg

  return true;
}
#endif

bool MinidumpGenerator::GetThreadState(thread_act_t target_thread,
                                       thread_state_t state,
                                       mach_msg_type_number_t *count) {
  if (task_context_ && target_thread == mach_thread_self()) {
    switch (cpu_type_) {
#ifdef HAS_ARM_SUPPORT
      case CPU_TYPE_ARM:
        size_t final_size =
            std::min(static_cast<size_t>(*count), sizeof(arm_thread_state_t));
        memcpy(state, &task_context_->breakpad_uc_mcontext->__ss, final_size);
        *count = static_cast<mach_msg_type_number_t>(final_size);
        return true;
#endif
#ifdef HAS_ARM64_SUPPORT
      case CPU_TYPE_ARM64: {
        size_t final_size =
            std::min(static_cast<size_t>(*count), sizeof(arm_thread_state64_t));
        memcpy(state, &task_context_->breakpad_uc_mcontext->__ss, final_size);
        *count = static_cast<mach_msg_type_number_t>(final_size);
        return true;
      }
#endif
#ifdef HAS_X86_SUPPORT
    case CPU_TYPE_I386:
    case CPU_TYPE_X86_64: {
        size_t state_size = cpu_type_ == CPU_TYPE_I386 ?
            sizeof(i386_thread_state_t) : sizeof(x86_thread_state64_t);
        size_t final_size =
            std::min(static_cast<size_t>(*count), state_size);
        memcpy(state, &task_context_->breakpad_uc_mcontext->__ss, final_size);
        *count = static_cast<mach_msg_type_number_t>(final_size);
        return true;
      }
#endif
    }
  }

  thread_state_flavor_t flavor;
  switch (cpu_type_) {
#ifdef HAS_ARM_SUPPORT
    case CPU_TYPE_ARM:
      flavor = ARM_THREAD_STATE;
      break;
#endif
#ifdef HAS_ARM64_SUPPORT
    case CPU_TYPE_ARM64:
      flavor = ARM_THREAD_STATE64;
      break;
#endif
#ifdef HAS_PPC_SUPPORT
    case CPU_TYPE_POWERPC:
      flavor = PPC_THREAD_STATE;
      break;
    case CPU_TYPE_POWERPC64:
      flavor = PPC_THREAD_STATE64;
      break;
#endif
#ifdef HAS_X86_SUPPORT
    case CPU_TYPE_I386:
      flavor = i386_THREAD_STATE;
      break;
    case CPU_TYPE_X86_64:
      flavor = x86_THREAD_STATE64;
      break;
#endif
    default:
      return false;
  }
  return thread_get_state(target_thread, flavor,
                          state, count) == KERN_SUCCESS;
}

bool MinidumpGenerator::WriteThreadStream(mach_port_t thread_id,
                                          MDRawThread *thread) {
  breakpad_thread_state_data_t state;
  mach_msg_type_number_t state_count
      = static_cast<mach_msg_type_number_t>(sizeof(state));

  if (GetThreadState(thread_id, state, &state_count)) {
    if (!WriteStack(state, &thread->stack))
      return false;

    memory_blocks_.push_back(thread->stack);

    if (!WriteContext(state, &thread->thread_context))
      return false;

    thread->thread_id = thread_id;
  } else {
    return false;
  }

  return true;
}

bool MinidumpGenerator::WriteThreadListStream(
    MDRawDirectory *thread_list_stream) {
  TypedMDRVA<MDRawThreadList> list(&writer_);
  thread_act_port_array_t threads_for_task;
  mach_msg_type_number_t thread_count;
  int non_generator_thread_count;

  if (task_threads(crashing_task_, &threads_for_task, &thread_count))
    return false;

  // Don't include the generator thread
  if (handler_thread_ != MACH_PORT_NULL)
    non_generator_thread_count = thread_count - 1;
  else
    non_generator_thread_count = thread_count;
  if (!list.AllocateObjectAndArray(non_generator_thread_count,
                                   sizeof(MDRawThread)))
    return false;

  thread_list_stream->stream_type = MD_THREAD_LIST_STREAM;
  thread_list_stream->location = list.location();

  list.get()->number_of_threads = non_generator_thread_count;

  MDRawThread thread;
  int thread_idx = 0;

  for (unsigned int i = 0; i < thread_count; ++i) {
    memset(&thread, 0, sizeof(MDRawThread));

    if (threads_for_task[i] != handler_thread_) {
      if (!WriteThreadStream(threads_for_task[i], &thread))
        return false;

      list.CopyIndexAfterObject(thread_idx++, &thread, sizeof(MDRawThread));
    }
  }

  return true;
}

bool MinidumpGenerator::WriteMemoryListStream(
    MDRawDirectory *memory_list_stream) {
  TypedMDRVA<MDRawMemoryList> list(&writer_);

  // If the dump has an exception, include some memory around the
  // instruction pointer.
  const size_t kIPMemorySize = 256;  // bytes
  bool have_ip_memory = false;
  MDMemoryDescriptor ip_memory_d;
  if (exception_thread_ && exception_type_) {
    breakpad_thread_state_data_t state;
    mach_msg_type_number_t stateCount
      = static_cast<mach_msg_type_number_t>(sizeof(state));

    if (GetThreadState(exception_thread_, state, &stateCount)) {
      uint64_t ip = CurrentPCForStack(state);
      // Bound it to the upper and lower bounds of the region
      // it's contained within. If it's not in a known memory region,
      // don't bother trying to write it.
      mach_vm_address_t addr = static_cast<vm_address_t>(ip);
      mach_vm_size_t size;
      natural_t nesting_level = 0;
      vm_region_submap_info_64 info;
      mach_msg_type_number_t info_count = VM_REGION_SUBMAP_INFO_COUNT_64;
      vm_region_recurse_info_t recurse_info;
      recurse_info = reinterpret_cast<vm_region_recurse_info_t>(&info);

      kern_return_t ret =
        mach_vm_region_recurse(crashing_task_,
                               &addr,
                               &size,
                               &nesting_level,
                               recurse_info,
                               &info_count);
      if (ret == KERN_SUCCESS && ip >= addr && ip < (addr + size)) {
        // Try to get 128 bytes before and after the IP, but
        // settle for whatever's available.
        ip_memory_d.start_of_memory_range =
          std::max(uintptr_t(addr),
                   uintptr_t(ip - (kIPMemorySize / 2)));
        uintptr_t end_of_range = 
          std::min(uintptr_t(ip + (kIPMemorySize / 2)),
                   uintptr_t(addr + size));
        uintptr_t range_diff = end_of_range -
            static_cast<uintptr_t>(ip_memory_d.start_of_memory_range);
        ip_memory_d.memory.data_size = static_cast<uint32_t>(range_diff);
        have_ip_memory = true;
        // This needs to get appended to the list even though
        // the memory bytes aren't filled in yet so the entire
        // list can be written first. The memory bytes will get filled
        // in after the memory list is written.
        memory_blocks_.push_back(ip_memory_d);
      }
    }
  }

  // Now fill in the memory list and write it.
  size_t memory_count = memory_blocks_.size();
  if (!list.AllocateObjectAndArray(memory_count,
                                   sizeof(MDMemoryDescriptor)))
    return false;

  memory_list_stream->stream_type = MD_MEMORY_LIST_STREAM;
  memory_list_stream->location = list.location();

  list.get()->number_of_memory_ranges = static_cast<uint32_t>(memory_count);

  unsigned int i;
  for (i = 0; i < memory_count; ++i) {
    list.CopyIndexAfterObject(i, &memory_blocks_[i],
                              sizeof(MDMemoryDescriptor));
  }

  if (have_ip_memory) {
    // Now read the memory around the instruction pointer.
    UntypedMDRVA ip_memory(&writer_);
    if (!ip_memory.Allocate(ip_memory_d.memory.data_size))
      return false;

    if (dynamic_images_) {
      // Out-of-process.
      vector<uint8_t> memory;
      if (ReadTaskMemory(crashing_task_,
                         ip_memory_d.start_of_memory_range,
                         ip_memory_d.memory.data_size,
                         memory) != KERN_SUCCESS) {
        return false;
      }

      ip_memory.Copy(&memory[0], ip_memory_d.memory.data_size);
    } else {
      // In-process, just copy from local memory.
      ip_memory.Copy(
        reinterpret_cast<const void *>(ip_memory_d.start_of_memory_range),
        ip_memory_d.memory.data_size);
    }

    ip_memory_d.memory = ip_memory.location();
    // Write this again now that the data location is filled in.
    list.CopyIndexAfterObject(i - 1, &ip_memory_d,
                              sizeof(MDMemoryDescriptor));
  }

  return true;
}

bool
MinidumpGenerator::WriteExceptionStream(MDRawDirectory *exception_stream) {
  TypedMDRVA<MDRawExceptionStream> exception(&writer_);

  if (!exception.Allocate())
    return false;

  exception_stream->stream_type = MD_EXCEPTION_STREAM;
  exception_stream->location = exception.location();
  MDRawExceptionStream *exception_ptr = exception.get();
  exception_ptr->thread_id = exception_thread_;

  // This naming is confusing, but it is the proper translation from
  // mach naming to minidump naming.
  exception_ptr->exception_record.exception_code = exception_type_;
  exception_ptr->exception_record.exception_flags = exception_code_;

  breakpad_thread_state_data_t state;
  mach_msg_type_number_t state_count
      = static_cast<mach_msg_type_number_t>(sizeof(state));

  if (!GetThreadState(exception_thread_, state, &state_count))
    return false;

  if (!WriteContext(state, &exception_ptr->thread_context))
    return false;

  if (exception_type_ == EXC_BAD_ACCESS)
    exception_ptr->exception_record.exception_address = exception_subcode_;
  else
    exception_ptr->exception_record.exception_address = CurrentPCForStack(state);

  return true;
}

bool MinidumpGenerator::WriteSystemInfoStream(
    MDRawDirectory *system_info_stream) {
  TypedMDRVA<MDRawSystemInfo> info(&writer_);

  if (!info.Allocate())
    return false;

  system_info_stream->stream_type = MD_SYSTEM_INFO_STREAM;
  system_info_stream->location = info.location();

  // CPU Information
  uint32_t number_of_processors;
  size_t len = sizeof(number_of_processors);
  sysctlbyname("hw.ncpu", &number_of_processors, &len, NULL, 0);
  MDRawSystemInfo *info_ptr = info.get();

  switch (cpu_type_) {
#ifdef HAS_ARM_SUPPORT
    case CPU_TYPE_ARM:
      info_ptr->processor_architecture = MD_CPU_ARCHITECTURE_ARM;
      break;
#endif
#ifdef HAS_ARM64_SUPPORT
    case CPU_TYPE_ARM64:
      info_ptr->processor_architecture = MD_CPU_ARCHITECTURE_ARM64;
      break;
#endif
#ifdef HAS_PPC_SUPPORT
    case CPU_TYPE_POWERPC:
    case CPU_TYPE_POWERPC64:
      info_ptr->processor_architecture = MD_CPU_ARCHITECTURE_PPC;
      break;
#endif
#ifdef HAS_X86_SUPPORT
    case CPU_TYPE_I386:
    case CPU_TYPE_X86_64:
      if (cpu_type_ == CPU_TYPE_I386)
        info_ptr->processor_architecture = MD_CPU_ARCHITECTURE_X86;
      else
        info_ptr->processor_architecture = MD_CPU_ARCHITECTURE_AMD64;
#ifdef __i386__
      // ebx is used for PIC code, so we need
      // to preserve it.
#define cpuid(op,eax,ebx,ecx,edx)      \
  asm ("pushl %%ebx   \n\t"            \
       "cpuid         \n\t"            \
       "movl %%ebx,%1 \n\t"            \
       "popl %%ebx"                    \
       : "=a" (eax),                   \
         "=g" (ebx),                   \
         "=c" (ecx),                   \
         "=d" (edx)                    \
       : "0" (op))
#elif defined(__x86_64__)

#define cpuid(op,eax,ebx,ecx,edx)      \
  asm ("cpuid         \n\t"            \
       : "=a" (eax),                   \
         "=b" (ebx),                   \
         "=c" (ecx),                   \
         "=d" (edx)                    \
       : "0" (op))
#endif

#if defined(__i386__) || defined(__x86_64__)
      int unused, unused2;
      // get vendor id
      cpuid(0, unused, info_ptr->cpu.x86_cpu_info.vendor_id[0],
            info_ptr->cpu.x86_cpu_info.vendor_id[2],
            info_ptr->cpu.x86_cpu_info.vendor_id[1]);
      // get version and feature info
      cpuid(1, info_ptr->cpu.x86_cpu_info.version_information, unused, unused2,
            info_ptr->cpu.x86_cpu_info.feature_information);

      // family
      info_ptr->processor_level =
        (info_ptr->cpu.x86_cpu_info.version_information & 0xF00) >> 8;
      // 0xMMSS (Model, Stepping)
      info_ptr->processor_revision = static_cast<uint16_t>(
          (info_ptr->cpu.x86_cpu_info.version_information & 0xF) |
          ((info_ptr->cpu.x86_cpu_info.version_information & 0xF0) << 4));

      // decode extended model info
      if (info_ptr->processor_level == 0xF ||
          info_ptr->processor_level == 0x6) {
        info_ptr->processor_revision |=
          ((info_ptr->cpu.x86_cpu_info.version_information & 0xF0000) >> 4);
      }

      // decode extended family info
      if (info_ptr->processor_level == 0xF) {
        info_ptr->processor_level +=
          ((info_ptr->cpu.x86_cpu_info.version_information & 0xFF00000) >> 20);
      }

#endif  // __i386__ || __x86_64_
      break;
#endif  // HAS_X86_SUPPORT
    default:
      info_ptr->processor_architecture = MD_CPU_ARCHITECTURE_UNKNOWN;
      break;
  }

  info_ptr->number_of_processors = static_cast<uint8_t>(number_of_processors);
#if TARGET_OS_IPHONE
  info_ptr->platform_id = MD_OS_IOS;
#else
  info_ptr->platform_id = MD_OS_MAC_OS_X;
#endif  // TARGET_OS_IPHONE

  MDLocationDescriptor build_string_loc;

  if (!writer_.WriteString(build_string_, 0,
                           &build_string_loc))
    return false;

  info_ptr->csd_version_rva = build_string_loc.rva;
  info_ptr->major_version = os_major_version_;
  info_ptr->minor_version = os_minor_version_;
  info_ptr->build_number = os_build_number_;

  return true;
}

bool MinidumpGenerator::WriteModuleStream(unsigned int index,
                                          MDRawModule *module) {
  if (dynamic_images_) {
    // we're in a different process than the crashed process
    DynamicImage *image = dynamic_images_->GetImage(index);

    if (!image)
      return false;

    memset(module, 0, sizeof(MDRawModule));

    MDLocationDescriptor string_location;

    string name = image->GetFilePath();
    if (!writer_.WriteString(name.c_str(), 0, &string_location))
      return false;

    module->base_of_image = image->GetVMAddr() + image->GetVMAddrSlide();
    module->size_of_image = static_cast<uint32_t>(image->GetVMSize());
    module->module_name_rva = string_location.rva;

    // We'll skip the executable module, because they don't have
    // LC_ID_DYLIB load commands, and the crash processing server gets
    // version information from the Plist file, anyway.
    if (index != static_cast<uint32_t>(FindExecutableModule())) {
      module->version_info.signature = MD_VSFIXEDFILEINFO_SIGNATURE;
      module->version_info.struct_version |= MD_VSFIXEDFILEINFO_VERSION;
      // Convert MAC dylib version format, which is a 32 bit number, to the
      // format used by minidump.  The mac format is <16 bits>.<8 bits>.<8 bits>
      // so it fits nicely into the windows version with some massaging
      // The mapping is:
      //    1) upper 16 bits of MAC version go to lower 16 bits of product HI
      //    2) Next most significant 8 bits go to upper 16 bits of product LO
      //    3) Least significant 8 bits go to lower 16 bits of product LO
      uint32_t modVersion = image->GetVersion();
      module->version_info.file_version_hi = 0;
      module->version_info.file_version_hi = modVersion >> 16;
      module->version_info.file_version_lo |= (modVersion & 0xff00)  << 8;
      module->version_info.file_version_lo |= (modVersion & 0xff);
    }

    if (!WriteCVRecord(module, image->GetCPUType(), name.c_str(), false)) {
      return false;
    }
  } else {
    // Getting module info in the crashed process
    const breakpad_mach_header *header;
    header = (breakpad_mach_header*)_dyld_get_image_header(index);
    if (!header)
      return false;

#ifdef __LP64__
    assert(header->magic == MH_MAGIC_64);

    if(header->magic != MH_MAGIC_64)
      return false;
#else
    assert(header->magic == MH_MAGIC);

    if(header->magic != MH_MAGIC)
      return false;
#endif

    int cpu_type = header->cputype;
    unsigned long slide = _dyld_get_image_vmaddr_slide(index);
    const char* name = _dyld_get_image_name(index);
    const struct load_command *cmd =
        reinterpret_cast<const struct load_command *>(header + 1);

    memset(module, 0, sizeof(MDRawModule));

    for (unsigned int i = 0; cmd && (i < header->ncmds); i++) {
      if (cmd->cmd == LC_SEGMENT_ARCH) {

        const breakpad_mach_segment_command *seg =
            reinterpret_cast<const breakpad_mach_segment_command *>(cmd);

        if (!strcmp(seg->segname, "__TEXT")) {
          MDLocationDescriptor string_location;

          if (!writer_.WriteString(name, 0, &string_location))
            return false;

          module->base_of_image = seg->vmaddr + slide;
          module->size_of_image = static_cast<uint32_t>(seg->vmsize);
          module->module_name_rva = string_location.rva;

          bool in_memory = false;
#if TARGET_OS_IPHONE
          in_memory = true;
#endif
          if (!WriteCVRecord(module, cpu_type, name, in_memory))
            return false;

          return true;
        }
      }

      cmd = reinterpret_cast<struct load_command*>((char *)cmd + cmd->cmdsize);
    }
  }

  return true;
}

int MinidumpGenerator::FindExecutableModule() {
  if (dynamic_images_) {
    int index = dynamic_images_->GetExecutableImageIndex();

    if (index >= 0) {
      return index;
    }
  } else {
    int image_count = _dyld_image_count();
    const struct mach_header *header;

    for (int index = 0; index < image_count; ++index) {
      header = _dyld_get_image_header(index);

      if (header->filetype == MH_EXECUTE)
        return index;
    }
  }

  // failed - just use the first image
  return 0;
}

bool MinidumpGenerator::WriteCVRecord(MDRawModule *module, int cpu_type,
                                      const char *module_path, bool in_memory) {
  TypedMDRVA<MDCVInfoPDB70> cv(&writer_);

  // Only return the last path component of the full module path
  const char *module_name = strrchr(module_path, '/');

  // Increment past the slash
  if (module_name)
    ++module_name;
  else
    module_name = "<Unknown>";

  size_t module_name_length = strlen(module_name);

  if (!cv.AllocateObjectAndArray(module_name_length + 1, sizeof(uint8_t)))
    return false;

  if (!cv.CopyIndexAfterObject(0, module_name, module_name_length))
    return false;

  module->cv_record = cv.location();
  MDCVInfoPDB70 *cv_ptr = cv.get();
  cv_ptr->cv_signature = MD_CVINFOPDB70_SIGNATURE;
  cv_ptr->age = 0;

  // Get the module identifier
  unsigned char identifier[16];
  bool result = false;
  if (in_memory) {
    MacFileUtilities::MachoID macho(module_path,
        reinterpret_cast<void *>(module->base_of_image),
        static_cast<size_t>(module->size_of_image));
    result = macho.UUIDCommand(cpu_type, CPU_SUBTYPE_MULTIPLE, identifier);
    if (!result)
      result = macho.MD5(cpu_type, CPU_SUBTYPE_MULTIPLE, identifier);
  }

  if (!result) {
     FileID file_id(module_path);
     result = file_id.MachoIdentifier(cpu_type, CPU_SUBTYPE_MULTIPLE,
                                      identifier);
  }

  if (result) {
    cv_ptr->signature.data1 =
        static_cast<uint32_t>(identifier[0]) << 24 |
        static_cast<uint32_t>(identifier[1]) << 16 |
        static_cast<uint32_t>(identifier[2]) << 8 |
        static_cast<uint32_t>(identifier[3]);
    cv_ptr->signature.data2 =
        static_cast<uint16_t>(identifier[4] << 8) | identifier[5];
    cv_ptr->signature.data3 =
        static_cast<uint16_t>(identifier[6] << 8) | identifier[7];
    cv_ptr->signature.data4[0] = identifier[8];
    cv_ptr->signature.data4[1] = identifier[9];
    cv_ptr->signature.data4[2] = identifier[10];
    cv_ptr->signature.data4[3] = identifier[11];
    cv_ptr->signature.data4[4] = identifier[12];
    cv_ptr->signature.data4[5] = identifier[13];
    cv_ptr->signature.data4[6] = identifier[14];
    cv_ptr->signature.data4[7] = identifier[15];
  }

  return true;
}

bool MinidumpGenerator::WriteModuleListStream(
    MDRawDirectory *module_list_stream) {
  TypedMDRVA<MDRawModuleList> list(&writer_);

  uint32_t image_count = dynamic_images_ ?
      dynamic_images_->GetImageCount() :
      _dyld_image_count();

  if (!list.AllocateObjectAndArray(image_count, MD_MODULE_SIZE))
    return false;

  module_list_stream->stream_type = MD_MODULE_LIST_STREAM;
  module_list_stream->location = list.location();
  list.get()->number_of_modules = static_cast<uint32_t>(image_count);

  // Write out the executable module as the first one
  MDRawModule module;
  uint32_t executableIndex = FindExecutableModule();

  if (!WriteModuleStream(static_cast<unsigned>(executableIndex), &module)) {
    return false;
  }

  list.CopyIndexAfterObject(0, &module, MD_MODULE_SIZE);
  int destinationIndex = 1;  // Write all other modules after this one

  for (uint32_t i = 0; i < image_count; ++i) {
    if (i != executableIndex) {
      if (!WriteModuleStream(static_cast<unsigned>(i), &module)) {
        return false;
      }

      list.CopyIndexAfterObject(destinationIndex++, &module, MD_MODULE_SIZE);
    }
  }

  return true;
}

bool MinidumpGenerator::WriteMiscInfoStream(MDRawDirectory *misc_info_stream) {
  TypedMDRVA<MDRawMiscInfo> info(&writer_);

  if (!info.Allocate())
    return false;

  misc_info_stream->stream_type = MD_MISC_INFO_STREAM;
  misc_info_stream->location = info.location();

  MDRawMiscInfo *info_ptr = info.get();
  info_ptr->size_of_info = static_cast<uint32_t>(sizeof(MDRawMiscInfo));
  info_ptr->flags1 = MD_MISCINFO_FLAGS1_PROCESS_ID |
    MD_MISCINFO_FLAGS1_PROCESS_TIMES |
    MD_MISCINFO_FLAGS1_PROCESSOR_POWER_INFO;

  // Process ID
  info_ptr->process_id = getpid();

  // Times
  struct rusage usage;
  if (getrusage(RUSAGE_SELF, &usage) != -1) {
    // Omit the fractional time since the MDRawMiscInfo only wants seconds
    info_ptr->process_user_time =
        static_cast<uint32_t>(usage.ru_utime.tv_sec);
    info_ptr->process_kernel_time =
        static_cast<uint32_t>(usage.ru_stime.tv_sec);
  }
  int mib[4] = { CTL_KERN, KERN_PROC, KERN_PROC_PID,
                 static_cast<int>(info_ptr->process_id) };
  uint mibsize = static_cast<uint>(sizeof(mib) / sizeof(mib[0]));
  struct kinfo_proc proc;
  size_t size = sizeof(proc);
  if (sysctl(mib, mibsize, &proc, &size, NULL, 0) == 0) {
    info_ptr->process_create_time =
        static_cast<uint32_t>(proc.kp_proc.p_starttime.tv_sec);
  }

  // Speed
  uint64_t speed;
  const uint64_t kOneMillion = 1000 * 1000;
  size = sizeof(speed);
  sysctlbyname("hw.cpufrequency_max", &speed, &size, NULL, 0);
  info_ptr->processor_max_mhz = static_cast<uint32_t>(speed / kOneMillion);
  info_ptr->processor_mhz_limit = static_cast<uint32_t>(speed / kOneMillion);
  size = sizeof(speed);
  sysctlbyname("hw.cpufrequency", &speed, &size, NULL, 0);
  info_ptr->processor_current_mhz = static_cast<uint32_t>(speed / kOneMillion);

  return true;
}

bool MinidumpGenerator::WriteBreakpadInfoStream(
    MDRawDirectory *breakpad_info_stream) {
  TypedMDRVA<MDRawBreakpadInfo> info(&writer_);

  if (!info.Allocate())
    return false;

  breakpad_info_stream->stream_type = MD_BREAKPAD_INFO_STREAM;
  breakpad_info_stream->location = info.location();
  MDRawBreakpadInfo *info_ptr = info.get();

  if (exception_thread_ && exception_type_) {
    info_ptr->validity = MD_BREAKPAD_INFO_VALID_DUMP_THREAD_ID |
                         MD_BREAKPAD_INFO_VALID_REQUESTING_THREAD_ID;
    info_ptr->dump_thread_id = handler_thread_;
    info_ptr->requesting_thread_id = exception_thread_;
  } else {
    info_ptr->validity = MD_BREAKPAD_INFO_VALID_DUMP_THREAD_ID;
    info_ptr->dump_thread_id = handler_thread_;
    info_ptr->requesting_thread_id = 0;
  }

  return true;
}

}  // namespace google_breakpad
