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

// Author: Alfred Peng

#include <fcntl.h>
#include <sys/frame.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/utsname.h>
#include <sys/wait.h>
#include <unistd.h>

#include <cstdlib>
#include <ctime>

#include "client/solaris/handler/minidump_generator.h"
#include "client/minidump_file_writer-inl.h"
#include "common/solaris/file_id.h"

namespace {

using namespace google_breakpad;

// Argument for the writer function.
struct WriterArgument {
  MinidumpFileWriter* minidump_writer;

  // Pid of the lwp who called WriteMinidumpToFile
  int requester_pid;

  // The stack bottom of the lwp which caused the dump.
  // Mainly used to find the lwp id of the crashed lwp since signal
  // handler may not be called in the lwp who caused it.
  uintptr_t crashed_stack_bottom;

  // Id of the crashing lwp.
  int crashed_lwpid;

  // Signal number when crash happened. Can be 0 if this is a requested dump.
  int signo;

  // The ebp of the signal handler frame on x86.  Can be 0 if this is a
  // requested dump.
  uintptr_t sighandler_ebp;

  // User context when crash happens. Can be NULL if this is a requested dump.
  // This is actually an out parameter, but it will be filled in at the start
  // of the writer LWP.
  ucontext_t* sig_ctx;

  // Used to get information about the lwps.
  SolarisLwp* lwp_lister;
};

// Holding context information for the callback of finding the crashing lwp.
struct FindCrashLwpContext {
  const SolarisLwp* lwp_lister;
  uintptr_t crashing_stack_bottom;
  int crashing_lwpid;

  FindCrashLwpContext() :
    lwp_lister(NULL),
    crashing_stack_bottom(0UL),
    crashing_lwpid(-1) {
  }
};

// Callback for list lwps.
// It will compare the stack bottom of the provided lwp with the stack
// bottom of the crashed lwp, it they are eqaul, this lwp is the one
// who crashed.
bool IsLwpCrashedCallback(lwpstatus_t* lsp, void* context) {
  FindCrashLwpContext* crashing_context =
    static_cast<FindCrashLwpContext*>(context);
  const SolarisLwp* lwp_lister = crashing_context->lwp_lister;
  const prgregset_t* gregs = &(lsp->pr_reg);
#if TARGET_CPU_SPARC
  uintptr_t last_ebp = (*gregs)[R_FP];
#elif TARGET_CPU_X86
  uintptr_t last_ebp = (*gregs)[EBP];
#endif
  uintptr_t stack_bottom = lwp_lister->GetLwpStackBottom(last_ebp);
  if (stack_bottom > last_ebp &&
      stack_bottom == crashing_context->crashing_stack_bottom) {
    // Got it. Stop iteration.
    crashing_context->crashing_lwpid = lsp->pr_lwpid;
    return false;
  }

  return true;
}

// Find the crashing lwpid.
// This is done based on stack bottom comparing.
int FindCrashingLwp(uintptr_t crashing_stack_bottom,
                    int requester_pid,
                    const SolarisLwp* lwp_lister) {
  FindCrashLwpContext context;
  context.lwp_lister = lwp_lister;
  context.crashing_stack_bottom = crashing_stack_bottom;
  CallbackParam<LwpCallback> callback_param(IsLwpCrashedCallback,
                                            &context);
  lwp_lister->Lwp_iter_all(lwp_lister->getpid(), &callback_param);
  return context.crashing_lwpid;
}

bool WriteLwpStack(const SolarisLwp* lwp_lister,
                   uintptr_t last_esp,
                   UntypedMDRVA* memory,
                   MDMemoryDescriptor* loc) {
  uintptr_t stack_bottom = lwp_lister->GetLwpStackBottom(last_esp);
  if (stack_bottom >= last_esp) {
    int size = stack_bottom - last_esp;
    if (size > 0) {
      if (!memory->Allocate(size))
        return false;
      memory->Copy(reinterpret_cast<void*>(last_esp), size);
      loc->start_of_memory_range = last_esp;
      loc->memory = memory->location();
    }
    return true;
  }
  return false;
}

#if TARGET_CPU_SPARC
bool WriteContext(MDRawContextSPARC* context, ucontext_t* sig_ctx) {
  assert(sig_ctx != NULL);
  int* regs = sig_ctx->uc_mcontext.gregs;
  context->context_flags = MD_CONTEXT_SPARC_FULL;

  context->ccr = (unsigned int)(regs[0]);
  context->pc = (unsigned int)(regs[REG_PC]);
  context->npc = (unsigned int)(regs[REG_nPC]);
  context->y = (unsigned int)(regs[REG_Y]);
  context->asi = (unsigned int)(regs[19]);
  context->fprs = (unsigned int)(regs[20]);

  for ( int i = 0 ; i < 32; ++i ) {
    context->g_r[i] = 0;
  }

  for ( int i = 1 ; i < 16; ++i ) {
    context->g_r[i] = (uintptr_t)(sig_ctx->uc_mcontext.gregs[i + 3]);
  }
  context->g_r[30] = (uintptr_t)(((struct frame*)context->g_r[14])->fr_savfp);

  return true;
}

bool WriteContext(MDRawContextSPARC* context, prgregset_t regs,
                  prfpregset_t* fp_regs) {
  if (!context || !regs)
    return false;

  context->context_flags = MD_CONTEXT_SPARC_FULL;

  context->ccr = (uintptr_t)(regs[32]);
  context->pc = (uintptr_t)(regs[R_PC]);
  context->npc = (uintptr_t)(regs[R_nPC]);
  context->y = (uintptr_t)(regs[R_Y]);
  context->asi = (uintptr_t)(regs[36]);
  context->fprs = (uintptr_t)(regs[37]);
  for ( int i = 0 ; i < 32 ; ++i ){
    context->g_r[i] = (uintptr_t)(regs[i]);
  }

  return true;
}
#elif TARGET_CPU_X86
bool WriteContext(MDRawContextX86* context, prgregset_t regs,
                  prfpregset_t* fp_regs) {
  if (!context || !regs)
    return false;

  context->context_flags = MD_CONTEXT_X86_FULL;

  context->cs = regs[CS];
  context->ds = regs[DS];
  context->es = regs[ES];
  context->fs = regs[FS];
  context->gs = regs[GS];
  context->ss = regs[SS];
  context->edi = regs[EDI];
  context->esi = regs[ESI];
  context->ebx = regs[EBX];
  context->edx = regs[EDX];
  context->ecx = regs[ECX];
  context->eax = regs[EAX];
  context->ebp = regs[EBP];
  context->eip = regs[EIP];
  context->esp = regs[UESP];
  context->eflags = regs[EFL];

  return true;
}
#endif /* TARGET_CPU_XXX */

// Write information about a crashed Lwp.
// When a lwp crash, kernel will write something on the stack for processing
// signal. This makes the current stack not reliable, and our stack walker
// won't figure out the whole call stack for this. So we write the stack at the
// time of the crash into the minidump file, not the current stack.
bool WriteCrashedLwpStream(MinidumpFileWriter* minidump_writer,
                           const WriterArgument* writer_args,
                           const lwpstatus_t* lsp,
                           MDRawThread* lwp) {
  assert(writer_args->sig_ctx != NULL);

  lwp->thread_id = lsp->pr_lwpid;

#if TARGET_CPU_SPARC
  UntypedMDRVA memory(minidump_writer);
  if (!WriteLwpStack(writer_args->lwp_lister,
                     writer_args->sig_ctx->uc_mcontext.gregs[REG_O6],
                     &memory,
                     &lwp->stack))
    return false;

  TypedMDRVA<MDRawContextSPARC> context(minidump_writer);
  if (!context.Allocate())
    return false;
  lwp->thread_context = context.location();
  memset(context.get(), 0, sizeof(MDRawContextSPARC));
  return WriteContext(context.get(), writer_args->sig_ctx);
#elif TARGET_CPU_X86
  UntypedMDRVA memory(minidump_writer);
  if (!WriteLwpStack(writer_args->lwp_lister,
                     writer_args->sig_ctx->uc_mcontext.gregs[UESP],
                     &memory,
                     &lwp->stack))
    return false;

  TypedMDRVA<MDRawContextX86> context(minidump_writer);
  if (!context.Allocate())
    return false;
  lwp->thread_context = context.location();
  memset(context.get(), 0, sizeof(MDRawContextX86));
  return WriteContext(context.get(),
                      (int*)&writer_args->sig_ctx->uc_mcontext.gregs,
                      &writer_args->sig_ctx->uc_mcontext.fpregs);
#endif
}

bool WriteLwpStream(MinidumpFileWriter* minidump_writer,
                    const SolarisLwp* lwp_lister,
                    const lwpstatus_t* lsp, MDRawThread* lwp) {
  prfpregset_t fp_regs = lsp->pr_fpreg;
  const prgregset_t* gregs = &(lsp->pr_reg);
  UntypedMDRVA memory(minidump_writer);
#if TARGET_CPU_SPARC
  if (!WriteLwpStack(lwp_lister,
                     (*gregs)[R_SP],
                     &memory,
                     &lwp->stack))
    return false;

  // Write context
  TypedMDRVA<MDRawContextSPARC> context(minidump_writer);
  if (!context.Allocate())
    return false;
  // should be the thread_id
  lwp->thread_id = lsp->pr_lwpid;
  lwp->thread_context = context.location();
  memset(context.get(), 0, sizeof(MDRawContextSPARC));
#elif TARGET_CPU_X86
  if (!WriteLwpStack(lwp_lister,
                     (*gregs)[UESP],
                     &memory,
                     &lwp->stack))
  return false;

  // Write context
  TypedMDRVA<MDRawContextX86> context(minidump_writer);
  if (!context.Allocate())
    return false;
  // should be the thread_id
  lwp->thread_id = lsp->pr_lwpid;
  lwp->thread_context = context.location();
  memset(context.get(), 0, sizeof(MDRawContextX86));
#endif /* TARGET_CPU_XXX */
  return WriteContext(context.get(), (int*)gregs, &fp_regs);
}

bool WriteCPUInformation(MDRawSystemInfo* sys_info) {
  struct utsname uts;
  char *major, *minor, *build;

  sys_info->number_of_processors = sysconf(_SC_NPROCESSORS_CONF);
  sys_info->processor_architecture = MD_CPU_ARCHITECTURE_UNKNOWN;
  if (uname(&uts) != -1) {
    // Match "i86pc" as X86 architecture.
    if (strcmp(uts.machine, "i86pc") == 0)
      sys_info->processor_architecture = MD_CPU_ARCHITECTURE_X86;
    else if (strcmp(uts.machine, "sun4u") == 0)
      sys_info->processor_architecture = MD_CPU_ARCHITECTURE_SPARC;
  }

  major = uts.release;
  minor = strchr(major, '.');
  *minor = '\0';
  ++minor;
  sys_info->major_version = atoi(major);
  sys_info->minor_version = atoi(minor);

  build = strchr(uts.version, '_');
  ++build;
  sys_info->build_number = atoi(build);
  
  return true;
}

bool WriteOSInformation(MinidumpFileWriter* minidump_writer,
                        MDRawSystemInfo* sys_info) {
  sys_info->platform_id = MD_OS_SOLARIS;

  struct utsname uts;
  if (uname(&uts) != -1) {
    char os_version[512];
    size_t space_left = sizeof(os_version);
    memset(os_version, 0, space_left);
    const char* os_info_table[] = {
      uts.sysname,
      uts.release,
      uts.version,
      uts.machine,
      "OpenSolaris",
      NULL
    };
    for (const char** cur_os_info = os_info_table;
         *cur_os_info != NULL;
         ++cur_os_info) {
      if (cur_os_info != os_info_table && space_left > 1) {
        strcat(os_version, " ");
        --space_left;
      }
      if (space_left > strlen(*cur_os_info)) {
        strcat(os_version, *cur_os_info);
        space_left -= strlen(*cur_os_info);
      } else {
        break;
      }
    }

    MDLocationDescriptor location;
    if (!minidump_writer->WriteString(os_version, 0, &location))
      return false;
    sys_info->csd_version_rva = location.rva;
  }
  return true;
}

// Callback context for get writting lwp information.
struct LwpInfoCallbackCtx {
  MinidumpFileWriter* minidump_writer;
  const WriterArgument* writer_args;
  TypedMDRVA<MDRawThreadList>* list;
  int lwp_index;
};

bool LwpInformationCallback(lwpstatus_t* lsp, void* context) {
  bool success = true;
  LwpInfoCallbackCtx* callback_context =
    static_cast<LwpInfoCallbackCtx*>(context);

  // The current lwp is the one to handle the crash. Ignore it.
  if (lsp->pr_lwpid != pthread_self()) {
    LwpInfoCallbackCtx* callback_context =
      static_cast<LwpInfoCallbackCtx*>(context);
    MDRawThread lwp;
    memset(&lwp, 0, sizeof(MDRawThread));

    if (lsp->pr_lwpid != callback_context->writer_args->crashed_lwpid ||
        callback_context->writer_args->sig_ctx == NULL) {
      success = WriteLwpStream(callback_context->minidump_writer,
                               callback_context->writer_args->lwp_lister,
                               lsp, &lwp);
    } else {
      success = WriteCrashedLwpStream(callback_context->minidump_writer,
                                      callback_context->writer_args,
                                      lsp, &lwp);
    }
    if (success) {
      callback_context->list->CopyIndexAfterObject(
          callback_context->lwp_index++,
          &lwp, sizeof(MDRawThread));
    }
  }

  return success;
}

bool WriteLwpListStream(MinidumpFileWriter* minidump_writer,
                        const WriterArgument* writer_args,
                        MDRawDirectory* dir) {
  // Get the lwp information.
  const SolarisLwp* lwp_lister = writer_args->lwp_lister;
  int lwp_count = lwp_lister->GetLwpCount();
  if (lwp_count < 0)
    return false;
  TypedMDRVA<MDRawThreadList> list(minidump_writer);
  if (!list.AllocateObjectAndArray(lwp_count - 1, sizeof(MDRawThread)))
    return false;
  dir->stream_type = MD_THREAD_LIST_STREAM;
  dir->location = list.location();
  list.get()->number_of_threads = lwp_count - 1;

  LwpInfoCallbackCtx context;
  context.minidump_writer = minidump_writer;
  context.writer_args = writer_args;
  context.list = &list;
  context.lwp_index = 0;
  CallbackParam<LwpCallback> callback_param(LwpInformationCallback,
                                            &context);
  int written =
    lwp_lister->Lwp_iter_all(lwp_lister->getpid(), &callback_param);
  return written == lwp_count;
}

bool WriteCVRecord(MinidumpFileWriter* minidump_writer,
                   MDRawModule* module,
                   const char* module_path,
                   char* realname) {
  TypedMDRVA<MDCVInfoPDB70> cv(minidump_writer);

  char path[PATH_MAX];
  const char* module_name = module_path ? module_path : "<Unknown>";
  snprintf(path, sizeof(path), "/proc/self/object/%s", module_name);

  size_t module_name_length = strlen(realname);
  if (!cv.AllocateObjectAndArray(module_name_length + 1, sizeof(uint8_t)))
    return false;
  if (!cv.CopyIndexAfterObject(0, realname, module_name_length))
    return false;

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

  // Get the module identifier
  FileID file_id(path);
  unsigned char identifier[16];

  if (file_id.ElfFileIdentifier(identifier)) {
    cv_ptr->signature.data1 = (uint32_t)identifier[0] << 24 |
      (uint32_t)identifier[1] << 16 | (uint32_t)identifier[2] << 8 |
      (uint32_t)identifier[3];
    cv_ptr->signature.data2 = (uint32_t)identifier[4] << 8 | identifier[5];
    cv_ptr->signature.data3 = (uint32_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;
}

struct ModuleInfoCallbackCtx {
  MinidumpFileWriter* minidump_writer;
  const WriterArgument* writer_args;
  TypedMDRVA<MDRawModuleList>* list;
  int module_index;
};

bool ModuleInfoCallback(const ModuleInfo& module_info, void* context) {
  ModuleInfoCallbackCtx* callback_context =
    static_cast<ModuleInfoCallbackCtx*>(context);
  // Skip those modules without name, or those that are not modules.
  if (strlen(module_info.name) == 0)
    return true;

  MDRawModule module;
  memset(&module, 0, sizeof(module));
  MDLocationDescriptor loc;
  char path[PATH_MAX];
  char buf[PATH_MAX];
  char* realname;
  int count;

  snprintf(path, sizeof (path), "/proc/self/path/%s", module_info.name);
  if ((count = readlink(path, buf, PATH_MAX)) < 0)
    return false;
  buf[count] = '\0';

  if ((realname = strrchr(buf, '/')) == NULL)
    return false;
  realname++;

  if (!callback_context->minidump_writer->WriteString(realname, 0, &loc))
    return false;

  module.base_of_image = (uint64_t)module_info.start_addr;
  module.size_of_image = module_info.size;
  module.module_name_rva = loc.rva;

  if (!WriteCVRecord(callback_context->minidump_writer, &module,
                     module_info.name, realname))
    return false;

  callback_context->list->CopyIndexAfterObject(
      callback_context->module_index++, &module, MD_MODULE_SIZE);
  return true;
}

bool WriteModuleListStream(MinidumpFileWriter* minidump_writer,
                           const WriterArgument* writer_args,
                           MDRawDirectory* dir) {
  TypedMDRVA<MDRawModuleList> list(minidump_writer);
  int module_count = writer_args->lwp_lister->GetModuleCount();

  if (module_count <= 0 ||
      !list.AllocateObjectAndArray(module_count, MD_MODULE_SIZE)) {
    return false;
  }

  dir->stream_type = MD_MODULE_LIST_STREAM;
  dir->location = list.location();
  list.get()->number_of_modules = module_count;
  ModuleInfoCallbackCtx context;
  context.minidump_writer = minidump_writer;
  context.writer_args = writer_args;
  context.list = &list;
  context.module_index = 0;
  CallbackParam<ModuleCallback> callback(ModuleInfoCallback, &context);
  return writer_args->lwp_lister->ListModules(&callback) == module_count;
}

bool WriteSystemInfoStream(MinidumpFileWriter* minidump_writer,
                           const WriterArgument* writer_args,
                           MDRawDirectory* dir) {
  TypedMDRVA<MDRawSystemInfo> sys_info(minidump_writer);

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

  dir->stream_type = MD_SYSTEM_INFO_STREAM;
  dir->location = sys_info.location();

  return WriteCPUInformation(sys_info.get()) &&
         WriteOSInformation(minidump_writer, sys_info.get());
}

bool WriteExceptionStream(MinidumpFileWriter* minidump_writer,
                          const WriterArgument* writer_args,
                          MDRawDirectory* dir) {
  // This happenes when this is not a crash, but a requested dump.
  if (writer_args->sig_ctx == NULL)
    return false;

  TypedMDRVA<MDRawExceptionStream> exception(minidump_writer);
  if (!exception.Allocate())
    return false;

  dir->stream_type = MD_EXCEPTION_STREAM;
  dir->location = exception.location();
  exception.get()->thread_id = writer_args->crashed_lwpid;
  exception.get()->exception_record.exception_code = writer_args->signo;
  exception.get()->exception_record.exception_flags = 0;

#if TARGET_CPU_SPARC
  if (writer_args->sig_ctx != NULL) {
    exception.get()->exception_record.exception_address = 
      writer_args->sig_ctx->uc_mcontext.gregs[REG_PC];
  } else {
    return true;
  }

  // Write context of the exception.
  TypedMDRVA<MDRawContextSPARC> context(minidump_writer);
  if (!context.Allocate())
    return false;
  exception.get()->thread_context = context.location();
  memset(context.get(), 0, sizeof(MDRawContextSPARC));
  return WriteContext(context.get(), writer_args->sig_ctx);
#elif TARGET_CPU_X86
  if (writer_args->sig_ctx != NULL) {
    exception.get()->exception_record.exception_address =
      writer_args->sig_ctx->uc_mcontext.gregs[EIP];
  } else {
    return true;
  }

  // Write context of the exception.
  TypedMDRVA<MDRawContextX86> context(minidump_writer);
  if (!context.Allocate())
    return false;
  exception.get()->thread_context = context.location();
  memset(context.get(), 0, sizeof(MDRawContextX86));
  return WriteContext(context.get(),
                      (int*)&writer_args->sig_ctx->uc_mcontext.gregs,
                      NULL);
#endif
}

bool WriteMiscInfoStream(MinidumpFileWriter* minidump_writer,
                         const WriterArgument* writer_args,
                         MDRawDirectory* dir) {
  TypedMDRVA<MDRawMiscInfo> info(minidump_writer);

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

  dir->stream_type = MD_MISC_INFO_STREAM;
  dir->location = info.location();
  info.get()->size_of_info = sizeof(MDRawMiscInfo);
  info.get()->flags1 = MD_MISCINFO_FLAGS1_PROCESS_ID;
  info.get()->process_id = writer_args->requester_pid;

  return true;
}

bool WriteBreakpadInfoStream(MinidumpFileWriter* minidump_writer,
                             const WriterArgument* writer_args,
                             MDRawDirectory* dir) {
  TypedMDRVA<MDRawBreakpadInfo> info(minidump_writer);

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

  dir->stream_type = MD_BREAKPAD_INFO_STREAM;
  dir->location = info.location();

  info.get()->validity = MD_BREAKPAD_INFO_VALID_DUMP_THREAD_ID |
                         MD_BREAKPAD_INFO_VALID_REQUESTING_THREAD_ID;
  info.get()->dump_thread_id = getpid();
  info.get()->requesting_thread_id = writer_args->requester_pid;
  return true;
}

class AutoLwpResumer {
 public:
  AutoLwpResumer(SolarisLwp* lwp) : lwp_(lwp) {}
  ~AutoLwpResumer() { lwp_->ControlAllLwps(false); }
 private:
  SolarisLwp* lwp_;
};

// Prototype of writer functions.
typedef bool (*WriteStreamFN)(MinidumpFileWriter*,
                              const WriterArgument*,
                              MDRawDirectory*);

// Function table to writer a full minidump.
const WriteStreamFN writers[] = {
  WriteLwpListStream,
  WriteModuleListStream,
  WriteSystemInfoStream,
  WriteExceptionStream,
  WriteMiscInfoStream,
  WriteBreakpadInfoStream,
};

// Will call each writer function in the writers table.
//void* MinidumpGenerator::Write(void* argument) {
void* Write(void* argument) {
  WriterArgument* writer_args = static_cast<WriterArgument*>(argument);

  if (!writer_args->lwp_lister->ControlAllLwps(true))
    return NULL;

  AutoLwpResumer lwpResumer(writer_args->lwp_lister);

  if (writer_args->sighandler_ebp != 0 &&
      writer_args->lwp_lister->FindSigContext(writer_args->sighandler_ebp,
                                              &writer_args->sig_ctx)) {
    writer_args->crashed_stack_bottom = 
      writer_args->lwp_lister->GetLwpStackBottom(
#if TARGET_CPU_SPARC
          writer_args->sig_ctx->uc_mcontext.gregs[REG_O6]
#elif TARGET_CPU_X86
          writer_args->sig_ctx->uc_mcontext.gregs[UESP]
#endif
      );

    int crashed_lwpid = FindCrashingLwp(writer_args->crashed_stack_bottom,
                                        writer_args->requester_pid,
                                        writer_args->lwp_lister);
    if (crashed_lwpid > 0)
      writer_args->crashed_lwpid = crashed_lwpid;
  }

  MinidumpFileWriter* minidump_writer = writer_args->minidump_writer;
  TypedMDRVA<MDRawHeader> header(minidump_writer);
  TypedMDRVA<MDRawDirectory> dir(minidump_writer);
  if (!header.Allocate())
    return 0;

  int writer_count = sizeof(writers) / sizeof(writers[0]);
  // Need directory space for all writers.
  if (!dir.AllocateArray(writer_count))
    return 0;
  header.get()->signature = MD_HEADER_SIGNATURE;
  header.get()->version = MD_HEADER_VERSION;
  header.get()->time_date_stamp = time(NULL);
  header.get()->stream_count = writer_count;
  header.get()->stream_directory_rva = dir.position();

  int dir_index = 0;
  MDRawDirectory local_dir;
  for (int i = 0; i < writer_count; ++i) {
    if ((*writers[i])(minidump_writer, writer_args, &local_dir))
      dir.CopyIndex(dir_index++, &local_dir);
  }

  return 0;
}

}  // namespace

namespace google_breakpad {

MinidumpGenerator::MinidumpGenerator() {
}

MinidumpGenerator::~MinidumpGenerator() {
}

// Write minidump into file.
// It runs in a different thread from the crashing thread.
bool MinidumpGenerator::WriteMinidumpToFile(const char* file_pathname,
                                            int signo,
                                            uintptr_t sighandler_ebp,
                                            ucontext_t** sig_ctx) const {
  // The exception handler thread.
  pthread_t handler_thread;

  assert(file_pathname != NULL);

  if (file_pathname == NULL)
    return false;

  MinidumpFileWriter minidump_writer;
  if (minidump_writer.Open(file_pathname)) {
    WriterArgument argument;
    memset(&argument, 0, sizeof(argument));
    SolarisLwp lwp_lister(getpid());
    argument.lwp_lister = &lwp_lister;
    argument.minidump_writer = &minidump_writer;
    argument.requester_pid = getpid();
    argument.crashed_lwpid = pthread_self();
    argument.signo = signo;
    argument.sighandler_ebp = sighandler_ebp;
    argument.sig_ctx = NULL;

    pthread_create(&handler_thread, NULL, Write, (void*)&argument);
    pthread_join(handler_thread, NULL);
    return true;
  }

  return false;
}

}  // namespace google_breakpad
