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

// Converts a minidump file to a core file which gdb can read.
// Large parts lifted from the userspace core dumper:
//   http://code.google.com/p/google-coredumper/

#include <elf.h>
#include <errno.h>
#include <limits.h>
#include <link.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/user.h>
#include <unistd.h>

#include <map>
#include <string>
#include <vector>

#include "common/linux/memory_mapped_file.h"
#include "common/minidump_type_helper.h"
#include "common/path_helper.h"
#include "common/scoped_ptr.h"
#include "common/using_std_string.h"
#include "google_breakpad/common/breakpad_types.h"
#include "google_breakpad/common/minidump_format.h"
#include "third_party/lss/linux_syscall_support.h"
#include "tools/linux/md2core/minidump_memory_range.h"

#if ULONG_MAX == 0xffffffffffffffff
  #define ELF_CLASS ELFCLASS64
#else
  #define ELF_CLASS ELFCLASS32
#endif
#define Ehdr   ElfW(Ehdr)
#define Phdr   ElfW(Phdr)
#define Shdr   ElfW(Shdr)
#define Nhdr   ElfW(Nhdr)
#define auxv_t ElfW(auxv_t)


#if defined(__x86_64__)
  #define ELF_ARCH  EM_X86_64
#elif defined(__i386__)
  #define ELF_ARCH  EM_386
#elif defined(__arm__)
  #define ELF_ARCH  EM_ARM
#elif defined(__mips__)
  #define ELF_ARCH  EM_MIPS
#elif defined(__aarch64__)
  #define ELF_ARCH  EM_AARCH64
#endif

#if defined(__arm__)
// GLibc/ARM and Android/ARM both use 'user_regs' for the structure type
// containing core registers, while they use 'user_regs_struct' on other
// architectures. This file-local typedef simplifies the source code.
typedef user_regs user_regs_struct;
#elif defined (__mips__)
// This file-local typedef simplifies the source code.
typedef gregset_t user_regs_struct;
#endif

using google_breakpad::MDTypeHelper;
using google_breakpad::MemoryMappedFile;
using google_breakpad::MinidumpMemoryRange;

typedef MDTypeHelper<sizeof(ElfW(Addr))>::MDRawDebug MDRawDebug;
typedef MDTypeHelper<sizeof(ElfW(Addr))>::MDRawLinkMap MDRawLinkMap;

static const MDRVA kInvalidMDRVA = static_cast<MDRVA>(-1);

struct Options {
  string minidump_path;
  bool verbose;
  int out_fd;
  bool use_filename;
  bool inc_guid;
  string so_basedir;
};

static void
Usage(int argc, const char* argv[]) {
  fprintf(stderr,
          "Usage: %s [options] <minidump file>\n"
          "\n"
          "Convert a minidump file into a core file (often for use by gdb).\n"
          "\n"
          "The shared library list will by default have filenames as the runtime expects.\n"
          "There are many flags to control the output names though to make it easier to\n"
          "integrate with your debug environment (e.g. gdb).\n"
          " Default:    /lib64/libpthread.so.0\n"
          " -f:         /lib64/libpthread-2.19.so\n"
          " -i:         /lib64/<module id>-libpthread.so.0\n"
          " -f -i:      /lib64/<module id>-libpthread-2.19.so\n"
          " -S /foo/:   /foo/libpthread.so.0\n"
          "\n"
          "Options:\n"
          "  -v         Enable verbose output\n"
          "  -o <file>  Write coredump to specified file (otherwise use stdout).\n"
          "  -f         Use the filename rather than the soname in the sharedlib list.\n"
          "             The soname is what the runtime system uses, but the filename is\n"
          "             how it's stored on disk.\n"
          "  -i         Prefix sharedlib names with ID (when available).  This makes it\n"
          "             easier to have a single directory full of symbols.\n"
          "  -S <dir>   Set soname base directory.  This will force all debug/symbol\n"
          "             lookups to be done in this directory rather than the filesystem\n"
          "             layout as it exists in the crashing image.  This path should end\n"
          "             with a slash if it's a directory.  e.g. /var/lib/breakpad/\n"
          "", google_breakpad::BaseName(argv[0]).c_str());
}

static void
SetupOptions(int argc, const char* argv[], Options* options) {
  extern int optind;
  int ch;
  const char* output_file = NULL;

  // Initialize the options struct as needed.
  options->verbose = false;
  options->use_filename = false;
  options->inc_guid = false;

  while ((ch = getopt(argc, (char * const *)argv, "fhio:S:v")) != -1) {
    switch (ch) {
      case 'h':
        Usage(argc, argv);
        exit(0);
        break;
      case '?':
        Usage(argc, argv);
        exit(1);
        break;

      case 'f':
        options->use_filename = true;
        break;
      case 'i':
        options->inc_guid = true;
        break;
      case 'o':
        output_file = optarg;
        break;
      case 'S':
        options->so_basedir = optarg;
        break;
      case 'v':
        options->verbose = true;
        break;
    }
  }

  if ((argc - optind) != 1) {
    fprintf(stderr, "%s: Missing minidump file\n", argv[0]);
    Usage(argc, argv);
    exit(1);
  }

  if (output_file == NULL || !strcmp(output_file, "-")) {
    options->out_fd = STDOUT_FILENO;
  } else {
    options->out_fd = open(output_file, O_WRONLY|O_CREAT|O_TRUNC, 0664);
    if (options->out_fd == -1) {
      fprintf(stderr, "%s: could not open output %s: %s\n", argv[0],
              output_file, strerror(errno));
      exit(1);
    }
  }

  options->minidump_path = argv[optind];
}

// Write all of the given buffer, handling short writes and EINTR. Return true
// iff successful.
static bool
writea(int fd, const void* idata, size_t length) {
  const uint8_t* data = (const uint8_t*) idata;

  size_t done = 0;
  while (done < length) {
    ssize_t r;
    do {
      r = write(fd, data + done, length - done);
    } while (r == -1 && errno == EINTR);

    if (r < 1)
      return false;
    done += r;
  }

  return true;
}

/* Dynamically determines the byte sex of the system. Returns non-zero
 * for big-endian machines.
 */
static inline int sex() {
  int probe = 1;
  return !*(char *)&probe;
}

typedef struct elf_timeval {    /* Time value with microsecond resolution    */
  long tv_sec;                  /* Seconds                                   */
  long tv_usec;                 /* Microseconds                              */
} elf_timeval;

typedef struct _elf_siginfo {   /* Information about signal (unused)         */
  int32_t si_signo;             /* Signal number                             */
  int32_t si_code;              /* Extra code                                */
  int32_t si_errno;             /* Errno                                     */
} _elf_siginfo;

typedef struct prstatus {       /* Information about thread; includes CPU reg*/
  _elf_siginfo   pr_info;       /* Info associated with signal               */
  uint16_t       pr_cursig;     /* Current signal                            */
  unsigned long  pr_sigpend;    /* Set of pending signals                    */
  unsigned long  pr_sighold;    /* Set of held signals                       */
  pid_t          pr_pid;        /* Process ID                                */
  pid_t          pr_ppid;       /* Parent's process ID                       */
  pid_t          pr_pgrp;       /* Group ID                                  */
  pid_t          pr_sid;        /* Session ID                                */
  elf_timeval    pr_utime;      /* User time                                 */
  elf_timeval    pr_stime;      /* System time                               */
  elf_timeval    pr_cutime;     /* Cumulative user time                      */
  elf_timeval    pr_cstime;     /* Cumulative system time                    */
  user_regs_struct pr_reg;      /* CPU registers                             */
  uint32_t       pr_fpvalid;    /* True if math co-processor being used      */
} prstatus;

typedef struct prpsinfo {       /* Information about process                 */
  unsigned char  pr_state;      /* Numeric process state                     */
  char           pr_sname;      /* Char for pr_state                         */
  unsigned char  pr_zomb;       /* Zombie                                    */
  signed char    pr_nice;       /* Nice val                                  */
  unsigned long  pr_flag;       /* Flags                                     */
#if defined(__x86_64__) || defined(__mips__)
  uint32_t       pr_uid;        /* User ID                                   */
  uint32_t       pr_gid;        /* Group ID                                  */
#else
  uint16_t       pr_uid;        /* User ID                                   */
  uint16_t       pr_gid;        /* Group ID                                  */
#endif
  pid_t          pr_pid;        /* Process ID                                */
  pid_t          pr_ppid;       /* Parent's process ID                       */
  pid_t          pr_pgrp;       /* Group ID                                  */
  pid_t          pr_sid;        /* Session ID                                */
  char           pr_fname[16];  /* Filename of executable                    */
  char           pr_psargs[80]; /* Initial part of arg list                  */
} prpsinfo;

// We parse the minidump file and keep the parsed information in this structure
struct CrashedProcess {
  CrashedProcess()
      : crashing_tid(-1),
        auxv(NULL),
        auxv_length(0) {
    memset(&prps, 0, sizeof(prps));
    prps.pr_sname = 'R';
    memset(&debug, 0, sizeof(debug));
  }

  struct Mapping {
    Mapping()
      : permissions(0xFFFFFFFF),
        start_address(0),
        end_address(0),
        offset(0) {
    }

    uint32_t permissions;
    uint64_t start_address, end_address, offset;
    // The name we write out to the core.
    string filename;
    string data;
  };
  std::map<uint64_t, Mapping> mappings;

  pid_t crashing_tid;
  int fatal_signal;

  struct Thread {
    pid_t tid;
#if defined(__mips__)
    mcontext_t mcontext;
#else
    user_regs_struct regs;
#endif
#if defined(__i386__) || defined(__x86_64__)
    user_fpregs_struct fpregs;
#endif
#if defined(__i386__)
    user_fpxregs_struct fpxregs;
#endif
#if defined(__aarch64__)
    user_fpsimd_struct fpregs;
#endif
    uintptr_t stack_addr;
    const uint8_t* stack;
    size_t stack_length;
  };
  std::vector<Thread> threads;

  const uint8_t* auxv;
  size_t auxv_length;

  prpsinfo prps;

  // The GUID/filename from MD_MODULE_LIST_STREAM entries.
  // We gather them for merging later on into the list of maps.
  struct Signature {
    char guid[40];
    string filename;
  };
  std::map<uintptr_t, Signature> signatures;

  string dynamic_data;
  MDRawDebug debug;
  std::vector<MDRawLinkMap> link_map;
};

#if defined(__i386__)
static uint32_t
U32(const uint8_t* data) {
  uint32_t v;
  memcpy(&v, data, sizeof(v));
  return v;
}

static uint16_t
U16(const uint8_t* data) {
  uint16_t v;
  memcpy(&v, data, sizeof(v));
  return v;
}

static void
ParseThreadRegisters(CrashedProcess::Thread* thread,
                     const MinidumpMemoryRange& range) {
  const MDRawContextX86* rawregs = range.GetData<MDRawContextX86>(0);

  thread->regs.ebx = rawregs->ebx;
  thread->regs.ecx = rawregs->ecx;
  thread->regs.edx = rawregs->edx;
  thread->regs.esi = rawregs->esi;
  thread->regs.edi = rawregs->edi;
  thread->regs.ebp = rawregs->ebp;
  thread->regs.eax = rawregs->eax;
  thread->regs.xds = rawregs->ds;
  thread->regs.xes = rawregs->es;
  thread->regs.xfs = rawregs->fs;
  thread->regs.xgs = rawregs->gs;
  thread->regs.orig_eax = rawregs->eax;
  thread->regs.eip = rawregs->eip;
  thread->regs.xcs = rawregs->cs;
  thread->regs.eflags = rawregs->eflags;
  thread->regs.esp = rawregs->esp;
  thread->regs.xss = rawregs->ss;

  thread->fpregs.cwd = rawregs->float_save.control_word;
  thread->fpregs.swd = rawregs->float_save.status_word;
  thread->fpregs.twd = rawregs->float_save.tag_word;
  thread->fpregs.fip = rawregs->float_save.error_offset;
  thread->fpregs.fcs = rawregs->float_save.error_selector;
  thread->fpregs.foo = rawregs->float_save.data_offset;
  thread->fpregs.fos = rawregs->float_save.data_selector;
  memcpy(thread->fpregs.st_space, rawregs->float_save.register_area,
         10 * 8);

  thread->fpxregs.cwd = rawregs->float_save.control_word;
  thread->fpxregs.swd = rawregs->float_save.status_word;
  thread->fpxregs.twd = rawregs->float_save.tag_word;
  thread->fpxregs.fop = U16(rawregs->extended_registers + 6);
  thread->fpxregs.fip = U16(rawregs->extended_registers + 8);
  thread->fpxregs.fcs = U16(rawregs->extended_registers + 12);
  thread->fpxregs.foo = U16(rawregs->extended_registers + 16);
  thread->fpxregs.fos = U16(rawregs->extended_registers + 20);
  thread->fpxregs.mxcsr = U32(rawregs->extended_registers + 24);
  memcpy(thread->fpxregs.st_space, rawregs->extended_registers + 32, 128);
  memcpy(thread->fpxregs.xmm_space, rawregs->extended_registers + 160, 128);
}
#elif defined(__x86_64__)
static void
ParseThreadRegisters(CrashedProcess::Thread* thread,
                     const MinidumpMemoryRange& range) {
  const MDRawContextAMD64* rawregs = range.GetData<MDRawContextAMD64>(0);

  thread->regs.r15 = rawregs->r15;
  thread->regs.r14 = rawregs->r14;
  thread->regs.r13 = rawregs->r13;
  thread->regs.r12 = rawregs->r12;
  thread->regs.rbp = rawregs->rbp;
  thread->regs.rbx = rawregs->rbx;
  thread->regs.r11 = rawregs->r11;
  thread->regs.r10 = rawregs->r10;
  thread->regs.r9 = rawregs->r9;
  thread->regs.r8 = rawregs->r8;
  thread->regs.rax = rawregs->rax;
  thread->regs.rcx = rawregs->rcx;
  thread->regs.rdx = rawregs->rdx;
  thread->regs.rsi = rawregs->rsi;
  thread->regs.rdi = rawregs->rdi;
  thread->regs.orig_rax = rawregs->rax;
  thread->regs.rip = rawregs->rip;
  thread->regs.cs  = rawregs->cs;
  thread->regs.eflags = rawregs->eflags;
  thread->regs.rsp = rawregs->rsp;
  thread->regs.ss = rawregs->ss;
  thread->regs.fs_base = 0;
  thread->regs.gs_base = 0;
  thread->regs.ds = rawregs->ds;
  thread->regs.es = rawregs->es;
  thread->regs.fs = rawregs->fs;
  thread->regs.gs = rawregs->gs;

  thread->fpregs.cwd = rawregs->flt_save.control_word;
  thread->fpregs.swd = rawregs->flt_save.status_word;
  thread->fpregs.ftw = rawregs->flt_save.tag_word;
  thread->fpregs.fop = rawregs->flt_save.error_opcode;
  thread->fpregs.rip = rawregs->flt_save.error_offset;
  thread->fpregs.rdp = rawregs->flt_save.data_offset;
  thread->fpregs.mxcsr = rawregs->flt_save.mx_csr;
  thread->fpregs.mxcr_mask = rawregs->flt_save.mx_csr_mask;
  memcpy(thread->fpregs.st_space, rawregs->flt_save.float_registers, 8 * 16);
  memcpy(thread->fpregs.xmm_space, rawregs->flt_save.xmm_registers, 16 * 16);
}
#elif defined(__arm__)
static void
ParseThreadRegisters(CrashedProcess::Thread* thread,
                     const MinidumpMemoryRange& range) {
  const MDRawContextARM* rawregs = range.GetData<MDRawContextARM>(0);

  thread->regs.uregs[0] = rawregs->iregs[0];
  thread->regs.uregs[1] = rawregs->iregs[1];
  thread->regs.uregs[2] = rawregs->iregs[2];
  thread->regs.uregs[3] = rawregs->iregs[3];
  thread->regs.uregs[4] = rawregs->iregs[4];
  thread->regs.uregs[5] = rawregs->iregs[5];
  thread->regs.uregs[6] = rawregs->iregs[6];
  thread->regs.uregs[7] = rawregs->iregs[7];
  thread->regs.uregs[8] = rawregs->iregs[8];
  thread->regs.uregs[9] = rawregs->iregs[9];
  thread->regs.uregs[10] = rawregs->iregs[10];
  thread->regs.uregs[11] = rawregs->iregs[11];
  thread->regs.uregs[12] = rawregs->iregs[12];
  thread->regs.uregs[13] = rawregs->iregs[13];
  thread->regs.uregs[14] = rawregs->iregs[14];
  thread->regs.uregs[15] = rawregs->iregs[15];

  thread->regs.uregs[16] = rawregs->cpsr;
  thread->regs.uregs[17] = 0;  // what is ORIG_r0 exactly?
}
#elif defined(__aarch64__)
static void
ParseThreadRegisters(CrashedProcess::Thread* thread,
                     const MinidumpMemoryRange& range) {
#define COPY_REGS(rawregs)                                          \
  do {                                                              \
    for (int i = 0; i < 31; ++i)                                    \
      thread->regs.regs[i] = rawregs->iregs[i];                     \
    thread->regs.sp = rawregs->iregs[MD_CONTEXT_ARM64_REG_SP];      \
    thread->regs.pc = rawregs->iregs[MD_CONTEXT_ARM64_REG_PC];      \
    thread->regs.pstate = rawregs->cpsr;                            \
                                                                    \
    memcpy(thread->fpregs.vregs, rawregs->float_save.regs, 8 * 32); \
    thread->fpregs.fpsr = rawregs->float_save.fpsr;                 \
    thread->fpregs.fpcr = rawregs->float_save.fpcr;                 \
  } while (false)

  if (range.length() == sizeof(MDRawContextARM64_Old)) {
    const MDRawContextARM64_Old* rawregs =
        range.GetData<MDRawContextARM64_Old>(0);
    COPY_REGS(rawregs);
  } else {
    const MDRawContextARM64* rawregs = range.GetData<MDRawContextARM64>(0);
    COPY_REGS(rawregs);
  }
#undef COPY_REGS
}
#elif defined(__mips__)
static void
ParseThreadRegisters(CrashedProcess::Thread* thread,
                     const MinidumpMemoryRange& range) {
  const MDRawContextMIPS* rawregs = range.GetData<MDRawContextMIPS>(0);

  for (int i = 0; i < MD_CONTEXT_MIPS_GPR_COUNT; ++i)
    thread->mcontext.gregs[i] = rawregs->iregs[i];

  thread->mcontext.pc = rawregs->epc;

  thread->mcontext.mdlo = rawregs->mdlo;
  thread->mcontext.mdhi = rawregs->mdhi;

  thread->mcontext.hi1 = rawregs->hi[0];
  thread->mcontext.lo1 = rawregs->lo[0];
  thread->mcontext.hi2 = rawregs->hi[1];
  thread->mcontext.lo2 = rawregs->lo[1];
  thread->mcontext.hi3 = rawregs->hi[2];
  thread->mcontext.lo3 = rawregs->lo[2];

  for (int i = 0; i < MD_FLOATINGSAVEAREA_MIPS_FPR_COUNT; ++i) {
    thread->mcontext.fpregs.fp_r.fp_fregs[i]._fp_fregs =
        rawregs->float_save.regs[i];
  }

  thread->mcontext.fpc_csr = rawregs->float_save.fpcsr;
#if _MIPS_SIM == _ABIO32
  thread->mcontext.fpc_eir = rawregs->float_save.fir;
#endif
}
#else
#error "This code has not been ported to your platform yet"
#endif

static void
ParseThreadList(const Options& options, CrashedProcess* crashinfo,
                const MinidumpMemoryRange& range,
                const MinidumpMemoryRange& full_file) {
  const uint32_t num_threads = *range.GetData<uint32_t>(0);
  if (options.verbose) {
    fprintf(stderr,
            "MD_THREAD_LIST_STREAM:\n"
            "Found %d threads\n"
            "\n\n",
            num_threads);
  }
  for (unsigned i = 0; i < num_threads; ++i) {
    CrashedProcess::Thread thread;
    memset(&thread, 0, sizeof(thread));
    const MDRawThread* rawthread =
        range.GetArrayElement<MDRawThread>(sizeof(uint32_t), i);
    thread.tid = rawthread->thread_id;
    thread.stack_addr = rawthread->stack.start_of_memory_range;
    MinidumpMemoryRange stack_range =
        full_file.Subrange(rawthread->stack.memory);
    thread.stack = stack_range.data();
    thread.stack_length = rawthread->stack.memory.data_size;

    ParseThreadRegisters(&thread,
                         full_file.Subrange(rawthread->thread_context));

    crashinfo->threads.push_back(thread);
  }
}

static void
ParseSystemInfo(const Options& options, CrashedProcess* crashinfo,
                const MinidumpMemoryRange& range,
                const MinidumpMemoryRange& full_file) {
  const MDRawSystemInfo* sysinfo = range.GetData<MDRawSystemInfo>(0);
  if (!sysinfo) {
    fprintf(stderr, "Failed to access MD_SYSTEM_INFO_STREAM\n");
    exit(1);
  }
#if defined(__i386__)
  if (sysinfo->processor_architecture != MD_CPU_ARCHITECTURE_X86) {
    fprintf(stderr,
            "This version of minidump-2-core only supports x86 (32bit)%s.\n",
            sysinfo->processor_architecture == MD_CPU_ARCHITECTURE_AMD64 ?
            ",\nbut the minidump file is from a 64bit machine" : "");
    exit(1);
  }
#elif defined(__x86_64__)
  if (sysinfo->processor_architecture != MD_CPU_ARCHITECTURE_AMD64) {
    fprintf(stderr,
            "This version of minidump-2-core only supports x86 (64bit)%s.\n",
            sysinfo->processor_architecture == MD_CPU_ARCHITECTURE_X86 ?
            ",\nbut the minidump file is from a 32bit machine" : "");
    exit(1);
  }
#elif defined(__arm__)
  if (sysinfo->processor_architecture != MD_CPU_ARCHITECTURE_ARM) {
    fprintf(stderr,
            "This version of minidump-2-core only supports ARM (32bit).\n");
    exit(1);
  }
#elif defined(__aarch64__)
  if (sysinfo->processor_architecture != MD_CPU_ARCHITECTURE_ARM64_OLD) {
    fprintf(stderr,
            "This version of minidump-2-core only supports ARM (64bit).\n");
    exit(1);
  }
#elif defined(__mips__)
# if _MIPS_SIM == _ABIO32
  if (sysinfo->processor_architecture != MD_CPU_ARCHITECTURE_MIPS) {
    fprintf(stderr,
            "This version of minidump-2-core only supports mips o32 (32bit).\n");
    exit(1);
  }
# elif _MIPS_SIM == _ABI64
  if (sysinfo->processor_architecture != MD_CPU_ARCHITECTURE_MIPS64) {
    fprintf(stderr,
            "This version of minidump-2-core only supports mips n64 (64bit).\n");
    exit(1);
  }
# else
#  error "This mips ABI is currently not supported (n32)"
# endif
#else
#error "This code has not been ported to your platform yet"
#endif
  if (!strstr(full_file.GetAsciiMDString(sysinfo->csd_version_rva).c_str(),
              "Linux") &&
      sysinfo->platform_id != MD_OS_NACL) {
    fprintf(stderr, "This minidump was not generated by Linux or NaCl.\n");
    exit(1);
  }

  if (options.verbose) {
    fprintf(stderr,
            "MD_SYSTEM_INFO_STREAM:\n"
            "Architecture: %s\n"
            "Number of processors: %d\n"
            "Processor level: %d\n"
            "Processor model: %d\n"
            "Processor stepping: %d\n",
            sysinfo->processor_architecture == MD_CPU_ARCHITECTURE_X86
            ? "i386"
            : sysinfo->processor_architecture == MD_CPU_ARCHITECTURE_AMD64
            ? "x86-64"
            : sysinfo->processor_architecture == MD_CPU_ARCHITECTURE_ARM
            ? "ARM"
            : sysinfo->processor_architecture == MD_CPU_ARCHITECTURE_MIPS
            ? "MIPS"
            : sysinfo->processor_architecture == MD_CPU_ARCHITECTURE_MIPS64
            ? "MIPS64"
            : "???",
            sysinfo->number_of_processors,
            sysinfo->processor_level,
            sysinfo->processor_revision >> 8,
            sysinfo->processor_revision & 0xFF);
    if (sysinfo->processor_architecture == MD_CPU_ARCHITECTURE_X86 ||
        sysinfo->processor_architecture == MD_CPU_ARCHITECTURE_AMD64) {
      fputs("Vendor id: ", stderr);
      const char *nul =
        (const char *)memchr(sysinfo->cpu.x86_cpu_info.vendor_id, 0,
                             sizeof(sysinfo->cpu.x86_cpu_info.vendor_id));
      fwrite(sysinfo->cpu.x86_cpu_info.vendor_id,
             nul ? nul - (const char *)&sysinfo->cpu.x86_cpu_info.vendor_id[0]
             : sizeof(sysinfo->cpu.x86_cpu_info.vendor_id), 1, stderr);
      fputs("\n", stderr);
    }
    fprintf(stderr, "OS: %s\n",
            full_file.GetAsciiMDString(sysinfo->csd_version_rva).c_str());
    fputs("\n\n", stderr);
  }
}

static void
ParseCPUInfo(const Options& options, CrashedProcess* crashinfo,
             const MinidumpMemoryRange& range) {
  if (options.verbose) {
    fputs("MD_LINUX_CPU_INFO:\n", stderr);
    fwrite(range.data(), range.length(), 1, stderr);
    fputs("\n\n\n", stderr);
  }
}

static void
ParseProcessStatus(const Options& options, CrashedProcess* crashinfo,
                   const MinidumpMemoryRange& range) {
  if (options.verbose) {
    fputs("MD_LINUX_PROC_STATUS:\n", stderr);
    fwrite(range.data(), range.length(), 1, stderr);
    fputs("\n\n", stderr);
  }
}

static void
ParseLSBRelease(const Options& options, CrashedProcess* crashinfo,
                const MinidumpMemoryRange& range) {
  if (options.verbose) {
    fputs("MD_LINUX_LSB_RELEASE:\n", stderr);
    fwrite(range.data(), range.length(), 1, stderr);
    fputs("\n\n", stderr);
  }
}

static void
ParseMaps(const Options& options, CrashedProcess* crashinfo,
          const MinidumpMemoryRange& range) {
  if (options.verbose) {
    fputs("MD_LINUX_MAPS:\n", stderr);
    fwrite(range.data(), range.length(), 1, stderr);
  }
  for (const uint8_t* ptr = range.data();
       ptr < range.data() + range.length();) {
    const uint8_t* eol = (uint8_t*)memchr(ptr, '\n',
                                       range.data() + range.length() - ptr);
    string line((const char*)ptr,
                eol ? eol - ptr : range.data() + range.length() - ptr);
    ptr = eol ? eol + 1 : range.data() + range.length();
    unsigned long long start, stop, offset;
    char* permissions = NULL;
    char* filename = NULL;
    sscanf(line.c_str(), "%llx-%llx %m[-rwxp] %llx %*[:0-9a-f] %*d %ms",
           &start, &stop, &permissions, &offset, &filename);
    if (filename && *filename == '/') {
      CrashedProcess::Mapping mapping;
      mapping.permissions = 0;
      if (strchr(permissions, 'r')) {
        mapping.permissions |= PF_R;
      }
      if (strchr(permissions, 'w')) {
        mapping.permissions |= PF_W;
      }
      if (strchr(permissions, 'x')) {
        mapping.permissions |= PF_X;
      }
      mapping.start_address = start;
      mapping.end_address = stop;
      mapping.offset = offset;
      if (filename) {
        mapping.filename = filename;
      }
      crashinfo->mappings[mapping.start_address] = mapping;
    }
    free(permissions);
    free(filename);
  }
  if (options.verbose) {
    fputs("\n\n\n", stderr);
  }
}

static void
ParseEnvironment(const Options& options, CrashedProcess* crashinfo,
                 const MinidumpMemoryRange& range) {
  if (options.verbose) {
    fputs("MD_LINUX_ENVIRON:\n", stderr);
    char* env = new char[range.length()];
    memcpy(env, range.data(), range.length());
    int nul_count = 0;
    for (char *ptr = env;;) {
      ptr = (char *)memchr(ptr, '\000', range.length() - (ptr - env));
      if (!ptr) {
        break;
      }
      if (ptr > env && ptr[-1] == '\n') {
        if (++nul_count > 5) {
          // Some versions of Chrome try to rewrite the process' command line
          // in a way that causes the environment to be corrupted. Afterwards,
          // part of the environment will contain the trailing bit of the
          // command line. The rest of the environment will be filled with
          // NUL bytes.
          // We detect this corruption by counting the number of consecutive
          // NUL bytes. Normally, we would not expect any consecutive NUL
          // bytes. But we are conservative and only suppress printing of
          // the environment if we see at least five consecutive NULs.
          fputs("Environment has been corrupted; no data available", stderr);
          goto env_corrupted;
        }
      } else {
        nul_count = 0;
      }
      *ptr = '\n';
    }
    fwrite(env, range.length(), 1, stderr);
  env_corrupted:
    delete[] env;
    fputs("\n\n\n", stderr);
  }
}

static void
ParseAuxVector(const Options& options, CrashedProcess* crashinfo,
               const MinidumpMemoryRange& range) {
  // Some versions of Chrome erroneously used the MD_LINUX_AUXV stream value
  // when dumping /proc/$x/maps
  if (range.length() > 17) {
    // The AUXV vector contains binary data, whereas the maps always begin
    // with an 8+ digit hex address followed by a hyphen and another 8+ digit
    // address.
    char addresses[18];
    memcpy(addresses, range.data(), 17);
    addresses[17] = '\000';
    if (strspn(addresses, "0123456789abcdef-") == 17) {
      ParseMaps(options, crashinfo, range);
      return;
    }
  }

  crashinfo->auxv = range.data();
  crashinfo->auxv_length = range.length();
}

static void
ParseCmdLine(const Options& options, CrashedProcess* crashinfo,
             const MinidumpMemoryRange& range) {
  // The command line is supposed to use NUL bytes to separate arguments.
  // As Chrome rewrites its own command line and (incorrectly) substitutes
  // spaces, this is often not the case in our minidump files.
  const char* cmdline = (const char*) range.data();
  if (options.verbose) {
    fputs("MD_LINUX_CMD_LINE:\n", stderr);
    unsigned i = 0;
    for (; i < range.length() && cmdline[i] && cmdline[i] != ' '; ++i) { }
    fputs("argv[0] = \"", stderr);
    fwrite(cmdline, i, 1, stderr);
    fputs("\"\n", stderr);
    for (unsigned j = ++i, argc = 1; j < range.length(); ++j) {
      if (!cmdline[j] || cmdline[j] == ' ') {
        fprintf(stderr, "argv[%d] = \"", argc++);
        fwrite(cmdline + i, j - i, 1, stderr);
        fputs("\"\n", stderr);
        i = j + 1;
      }
    }
    fputs("\n\n", stderr);
  }

  const char *binary_name = cmdline;
  for (size_t i = 0; i < range.length(); ++i) {
    if (cmdline[i] == '/') {
      binary_name = cmdline + i + 1;
    } else if (cmdline[i] == 0 || cmdline[i] == ' ') {
      static const size_t fname_len = sizeof(crashinfo->prps.pr_fname) - 1;
      static const size_t args_len = sizeof(crashinfo->prps.pr_psargs) - 1;
      memset(crashinfo->prps.pr_fname, 0, fname_len + 1);
      memset(crashinfo->prps.pr_psargs, 0, args_len + 1);
      unsigned len = cmdline + i - binary_name;
      memcpy(crashinfo->prps.pr_fname, binary_name,
               len > fname_len ? fname_len : len);

      len = range.length() > args_len ? args_len : range.length();
      memcpy(crashinfo->prps.pr_psargs, cmdline, len);
      for (unsigned j = 0; j < len; ++j) {
        if (crashinfo->prps.pr_psargs[j] == 0)
          crashinfo->prps.pr_psargs[j] = ' ';
      }
      break;
    }
  }
}

static void
ParseDSODebugInfo(const Options& options, CrashedProcess* crashinfo,
                  const MinidumpMemoryRange& range,
                  const MinidumpMemoryRange& full_file) {
  const MDRawDebug* debug = range.GetData<MDRawDebug>(0);
  if (!debug) {
    return;
  }
  if (options.verbose) {
    fprintf(stderr,
            "MD_LINUX_DSO_DEBUG:\n"
            "Version: %d\n"
            "Number of DSOs: %d\n"
            "Brk handler: 0x%" PRIx64 "\n"
            "Dynamic loader at: 0x%" PRIx64 "\n"
            "_DYNAMIC: 0x%" PRIx64 "\n",
            debug->version,
            debug->dso_count,
            static_cast<uint64_t>(debug->brk),
            static_cast<uint64_t>(debug->ldbase),
            static_cast<uint64_t>(debug->dynamic));
  }
  crashinfo->debug = *debug;
  if (range.length() > sizeof(MDRawDebug)) {
    char* dynamic_data = (char*)range.data() + sizeof(MDRawDebug);
    crashinfo->dynamic_data.assign(dynamic_data,
                                   range.length() - sizeof(MDRawDebug));
  }
  if (debug->map != kInvalidMDRVA) {
    for (unsigned int i = 0; i < debug->dso_count; ++i) {
      const MDRawLinkMap* link_map =
          full_file.GetArrayElement<MDRawLinkMap>(debug->map, i);
      if (link_map) {
        if (options.verbose) {
          fprintf(stderr,
                  "#%03d: %" PRIx64 ", %" PRIx64 ", \"%s\"\n",
                  i, static_cast<uint64_t>(link_map->addr),
                  static_cast<uint64_t>(link_map->ld),
                  full_file.GetAsciiMDString(link_map->name).c_str());
        }
        crashinfo->link_map.push_back(*link_map);
      }
    }
  }
  if (options.verbose) {
    fputs("\n\n", stderr);
  }
}

static void
ParseExceptionStream(const Options& options, CrashedProcess* crashinfo,
                     const MinidumpMemoryRange& range) {
  const MDRawExceptionStream* exp = range.GetData<MDRawExceptionStream>(0);
  crashinfo->crashing_tid = exp->thread_id;
  crashinfo->fatal_signal = (int) exp->exception_record.exception_code;
}

static bool
WriteThread(const Options& options, const CrashedProcess::Thread& thread,
            int fatal_signal) {
  struct prstatus pr;
  memset(&pr, 0, sizeof(pr));

  pr.pr_info.si_signo = fatal_signal;
  pr.pr_cursig = fatal_signal;
  pr.pr_pid = thread.tid;
#if defined(__mips__)
  memcpy(&pr.pr_reg, &thread.mcontext.gregs, sizeof(user_regs_struct));
#else
  memcpy(&pr.pr_reg, &thread.regs, sizeof(user_regs_struct));
#endif

  Nhdr nhdr;
  memset(&nhdr, 0, sizeof(nhdr));
  nhdr.n_namesz = 5;
  nhdr.n_descsz = sizeof(struct prstatus);
  nhdr.n_type = NT_PRSTATUS;
  if (!writea(options.out_fd, &nhdr, sizeof(nhdr)) ||
      !writea(options.out_fd, "CORE\0\0\0\0", 8) ||
      !writea(options.out_fd, &pr, sizeof(struct prstatus))) {
    return false;
  }

#if defined(__i386__) || defined(__x86_64__)
  nhdr.n_descsz = sizeof(user_fpregs_struct);
  nhdr.n_type = NT_FPREGSET;
  if (!writea(options.out_fd, &nhdr, sizeof(nhdr)) ||
      !writea(options.out_fd, "CORE\0\0\0\0", 8) ||
      !writea(options.out_fd, &thread.fpregs, sizeof(user_fpregs_struct))) {
    return false;
  }
#endif

#if defined(__i386__)
  nhdr.n_descsz = sizeof(user_fpxregs_struct);
  nhdr.n_type = NT_PRXFPREG;
  if (!writea(options.out_fd, &nhdr, sizeof(nhdr)) ||
      !writea(options.out_fd, "LINUX\0\0\0", 8) ||
      !writea(options.out_fd, &thread.fpxregs, sizeof(user_fpxregs_struct))) {
    return false;
  }
#endif

  return true;
}

static void
ParseModuleStream(const Options& options, CrashedProcess* crashinfo,
                  const MinidumpMemoryRange& range,
                  const MinidumpMemoryRange& full_file) {
  if (options.verbose) {
    fputs("MD_MODULE_LIST_STREAM:\n", stderr);
  }
  const uint32_t num_mappings = *range.GetData<uint32_t>(0);
  for (unsigned i = 0; i < num_mappings; ++i) {
    CrashedProcess::Mapping mapping;
    const MDRawModule* rawmodule = reinterpret_cast<const MDRawModule*>(
        range.GetArrayElement(sizeof(uint32_t), MD_MODULE_SIZE, i));
    mapping.start_address = rawmodule->base_of_image;
    mapping.end_address = rawmodule->size_of_image + rawmodule->base_of_image;

    if (crashinfo->mappings.find(mapping.start_address) ==
        crashinfo->mappings.end()) {
      // We prefer data from MD_LINUX_MAPS over MD_MODULE_LIST_STREAM, as
      // the former is a strict superset of the latter.
      crashinfo->mappings[mapping.start_address] = mapping;
    }

    const MDCVInfoPDB70* record = reinterpret_cast<const MDCVInfoPDB70*>(
        full_file.GetData(rawmodule->cv_record.rva, MDCVInfoPDB70_minsize));
    char guid[40];
    sprintf(guid, "%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X",
            record->signature.data1, record->signature.data2,
            record->signature.data3,
            record->signature.data4[0], record->signature.data4[1],
            record->signature.data4[2], record->signature.data4[3],
            record->signature.data4[4], record->signature.data4[5],
            record->signature.data4[6], record->signature.data4[7]);

    string filename = full_file.GetAsciiMDString(rawmodule->module_name_rva);

    CrashedProcess::Signature signature;
    strcpy(signature.guid, guid);
    signature.filename = filename;
    crashinfo->signatures[rawmodule->base_of_image] = signature;

    if (options.verbose) {
      fprintf(stderr, "0x%" PRIx64 "-0x%" PRIx64 ", ChkSum: 0x%08X, GUID: %s, "
              " \"%s\"\n",
              rawmodule->base_of_image,
              rawmodule->base_of_image + rawmodule->size_of_image,
              rawmodule->checksum, guid, filename.c_str());
    }
  }
  if (options.verbose) {
    fputs("\n\n", stderr);
  }
}

static void
AddDataToMapping(CrashedProcess* crashinfo, const string& data,
                 uintptr_t addr) {
  for (std::map<uint64_t, CrashedProcess::Mapping>::iterator
         iter = crashinfo->mappings.begin();
       iter != crashinfo->mappings.end();
       ++iter) {
    if (addr >= iter->second.start_address &&
        addr < iter->second.end_address) {
      CrashedProcess::Mapping mapping = iter->second;
      if ((addr & ~4095) != iter->second.start_address) {
        // If there are memory pages in the mapping prior to where the
        // data starts, truncate the existing mapping so that it ends with
        // the page immediately preceding the data region.
        iter->second.end_address = addr & ~4095;
        if (!mapping.filename.empty()) {
          // "mapping" is a copy of "iter->second". We are splitting the
          // existing mapping into two separate ones when we write the data
          // to the core file. The first one does not have any associated
          // data in the core file, the second one is backed by data that is
          // included with the core file.
          // If this mapping wasn't supposed to be anonymous, then we also
          // have to update the file offset upon splitting the mapping.
          mapping.offset += iter->second.end_address -
            iter->second.start_address;
        }
      }
      // Create a new mapping that contains the data contents. We often
      // limit the amount of data that is actually written to the core
      // file. But it is OK if the mapping itself extends past the end of
      // the data.
      mapping.start_address = addr & ~4095;
      mapping.data.assign(addr & 4095, 0).append(data);
      mapping.data.append(-mapping.data.size() & 4095, 0);
      crashinfo->mappings[mapping.start_address] = mapping;
      return;
    }
  }
  // Didn't find a suitable existing mapping for the data. Create a new one.
  CrashedProcess::Mapping mapping;
  mapping.permissions = PF_R | PF_W;
  mapping.start_address = addr & ~4095;
  mapping.end_address =
    (addr + data.size() + 4095) & ~4095;
  mapping.data.assign(addr & 4095, 0).append(data);
  mapping.data.append(-mapping.data.size() & 4095, 0);
  crashinfo->mappings[mapping.start_address] = mapping;
}

static void
AugmentMappings(const Options& options, CrashedProcess* crashinfo,
                const MinidumpMemoryRange& full_file) {
  // For each thread, find the memory mapping that matches the thread's stack.
  // Then adjust the mapping to include the stack dump.
  for (unsigned i = 0; i < crashinfo->threads.size(); ++i) {
    const CrashedProcess::Thread& thread = crashinfo->threads[i];
    AddDataToMapping(crashinfo,
                     string((char *)thread.stack, thread.stack_length),
                     thread.stack_addr);
  }

  // Create a new link map with information about DSOs. We move this map to
  // the beginning of the address space, as this area should always be
  // available.
  static const uintptr_t start_addr = 4096;
  string data;
  struct r_debug debug = { 0 };
  debug.r_version = crashinfo->debug.version;
  debug.r_brk = (ElfW(Addr))crashinfo->debug.brk;
  debug.r_state = r_debug::RT_CONSISTENT;
  debug.r_ldbase = (ElfW(Addr))crashinfo->debug.ldbase;
  debug.r_map = crashinfo->debug.dso_count > 0 ?
    (struct link_map*)(start_addr + sizeof(debug)) : 0;
  data.append((char*)&debug, sizeof(debug));

  struct link_map* prev = 0;
  for (std::vector<MDRawLinkMap>::iterator iter = crashinfo->link_map.begin();
       iter != crashinfo->link_map.end();
       ++iter) {
    struct link_map link_map = { 0 };
    link_map.l_addr = (ElfW(Addr))iter->addr;
    link_map.l_name = (char*)(start_addr + data.size() + sizeof(link_map));
    link_map.l_ld = (ElfW(Dyn)*)iter->ld;
    link_map.l_prev = prev;
    prev = (struct link_map*)(start_addr + data.size());
    string filename = full_file.GetAsciiMDString(iter->name);

    // Look up signature for this filename. If available, change filename
    // to point to GUID, instead.
    std::map<uintptr_t, CrashedProcess::Signature>::const_iterator sig =
      crashinfo->signatures.find((uintptr_t)iter->addr);
    if (sig != crashinfo->signatures.end()) {
      // At this point, we have:
      // old_filename: The path as found via SONAME (e.g. /lib/libpthread.so.0).
      // sig_filename: The path on disk (e.g. /lib/libpthread-2.19.so).
      const char* guid = sig->second.guid;
      string sig_filename = sig->second.filename;
      string old_filename = filename.empty() ? sig_filename : filename;
      string new_filename;

      // First set up the leading path.  We assume dirname always ends with a
      // trailing slash (as needed), so we won't be appending one manually.
      if (options.so_basedir.empty()) {
        string dirname;
        if (options.use_filename) {
          dirname = sig_filename;
        } else {
          dirname = old_filename;
        }
        size_t slash = dirname.find_last_of('/');
        if (slash != string::npos) {
          new_filename = dirname.substr(0, slash + 1);
        }
      } else {
        new_filename = options.so_basedir;
      }

      // Insert the module ID if requested.
      if (options.inc_guid &&
          strcmp(guid, "00000000-0000-0000-0000-000000000000") != 0) {
        new_filename += guid;
        new_filename += "-";
      }

      // Decide whether we use the filename or the SONAME (where the SONAME tends
      // to be a symlink to the actual file).
      new_filename += google_breakpad::BaseName(
          options.use_filename ? sig_filename : old_filename);

      if (filename != new_filename) {
        if (options.verbose) {
          fprintf(stderr, "0x%" PRIx64": rewriting mapping \"%s\" to \"%s\"\n",
                  static_cast<uint64_t>(link_map.l_addr),
                  filename.c_str(), new_filename.c_str());
        }
        filename = new_filename;
      }
    }

    if (std::distance(iter, crashinfo->link_map.end()) == 1) {
      link_map.l_next = 0;
    } else {
      link_map.l_next = (struct link_map*)(start_addr + data.size() +
                                           sizeof(link_map) +
                                           ((filename.size() + 8) & ~7));
    }
    data.append((char*)&link_map, sizeof(link_map));
    data.append(filename);
    data.append(8 - (filename.size() & 7), 0);
  }
  AddDataToMapping(crashinfo, data, start_addr);

  // Map the page containing the _DYNAMIC array
  if (!crashinfo->dynamic_data.empty()) {
    // Make _DYNAMIC DT_DEBUG entry point to our link map
    for (int i = 0;; ++i) {
      ElfW(Dyn) dyn;
      if ((i+1)*sizeof(dyn) > crashinfo->dynamic_data.length()) {
      no_dt_debug:
        if (options.verbose) {
          fprintf(stderr, "No DT_DEBUG entry found\n");
        }
        return;
      }
      memcpy(&dyn, crashinfo->dynamic_data.c_str() + i*sizeof(dyn),
             sizeof(dyn));
      if (dyn.d_tag == DT_DEBUG) {
        crashinfo->dynamic_data.replace(i*sizeof(dyn) +
                                       offsetof(ElfW(Dyn), d_un.d_ptr),
                                       sizeof(start_addr),
                                       (char*)&start_addr, sizeof(start_addr));
        break;
      } else if (dyn.d_tag == DT_NULL) {
        goto no_dt_debug;
      }
    }
    AddDataToMapping(crashinfo, crashinfo->dynamic_data,
                     (uintptr_t)crashinfo->debug.dynamic);
  }
}

int
main(int argc, const char* argv[]) {
  Options options;
  SetupOptions(argc, argv, &options);

  MemoryMappedFile mapped_file(options.minidump_path.c_str(), 0);
  if (!mapped_file.data()) {
    fprintf(stderr, "Failed to mmap dump file: %s: %s\n",
            options.minidump_path.c_str(), strerror(errno));
    return 1;
  }

  MinidumpMemoryRange dump(mapped_file.data(), mapped_file.size());

  const MDRawHeader* header = dump.GetData<MDRawHeader>(0);

  CrashedProcess crashinfo;

  // Always check the system info first, as that allows us to tell whether
  // this is a minidump file that is compatible with our converter.
  bool ok = false;
  for (unsigned i = 0; i < header->stream_count; ++i) {
    const MDRawDirectory* dirent =
        dump.GetArrayElement<MDRawDirectory>(header->stream_directory_rva, i);
    switch (dirent->stream_type) {
      case MD_SYSTEM_INFO_STREAM:
        ParseSystemInfo(options, &crashinfo, dump.Subrange(dirent->location),
                        dump);
        ok = true;
        break;
      default:
        break;
    }
  }
  if (!ok) {
    fprintf(stderr, "Cannot determine input file format.\n");
    exit(1);
  }

  for (unsigned i = 0; i < header->stream_count; ++i) {
    const MDRawDirectory* dirent =
        dump.GetArrayElement<MDRawDirectory>(header->stream_directory_rva, i);
    switch (dirent->stream_type) {
      case MD_THREAD_LIST_STREAM:
        ParseThreadList(options, &crashinfo, dump.Subrange(dirent->location),
                        dump);
        break;
      case MD_LINUX_CPU_INFO:
        ParseCPUInfo(options, &crashinfo, dump.Subrange(dirent->location));
        break;
      case MD_LINUX_PROC_STATUS:
        ParseProcessStatus(options, &crashinfo,
                           dump.Subrange(dirent->location));
        break;
      case MD_LINUX_LSB_RELEASE:
        ParseLSBRelease(options, &crashinfo, dump.Subrange(dirent->location));
        break;
      case MD_LINUX_ENVIRON:
        ParseEnvironment(options, &crashinfo, dump.Subrange(dirent->location));
        break;
      case MD_LINUX_MAPS:
        ParseMaps(options, &crashinfo, dump.Subrange(dirent->location));
        break;
      case MD_LINUX_AUXV:
        ParseAuxVector(options, &crashinfo, dump.Subrange(dirent->location));
        break;
      case MD_LINUX_CMD_LINE:
        ParseCmdLine(options, &crashinfo, dump.Subrange(dirent->location));
        break;
      case MD_LINUX_DSO_DEBUG:
        ParseDSODebugInfo(options, &crashinfo, dump.Subrange(dirent->location),
                          dump);
        break;
      case MD_EXCEPTION_STREAM:
        ParseExceptionStream(options, &crashinfo,
                             dump.Subrange(dirent->location));
        break;
      case MD_MODULE_LIST_STREAM:
        ParseModuleStream(options, &crashinfo, dump.Subrange(dirent->location),
                          dump);
        break;
      default:
        if (options.verbose)
          fprintf(stderr, "Skipping %x\n", dirent->stream_type);
    }
  }

  AugmentMappings(options, &crashinfo, dump);

  // Write the ELF header. The file will look like:
  //   ELF header
  //   Phdr for the PT_NOTE
  //   Phdr for each of the thread stacks
  //   PT_NOTE
  //   each of the thread stacks
  Ehdr ehdr;
  memset(&ehdr, 0, sizeof(Ehdr));
  ehdr.e_ident[0] = ELFMAG0;
  ehdr.e_ident[1] = ELFMAG1;
  ehdr.e_ident[2] = ELFMAG2;
  ehdr.e_ident[3] = ELFMAG3;
  ehdr.e_ident[4] = ELF_CLASS;
  ehdr.e_ident[5] = sex() ? ELFDATA2MSB : ELFDATA2LSB;
  ehdr.e_ident[6] = EV_CURRENT;
  ehdr.e_type     = ET_CORE;
  ehdr.e_machine  = ELF_ARCH;
  ehdr.e_version  = EV_CURRENT;
  ehdr.e_phoff    = sizeof(Ehdr);
  ehdr.e_ehsize   = sizeof(Ehdr);
  ehdr.e_phentsize= sizeof(Phdr);
  ehdr.e_phnum    = 1 +                         // PT_NOTE
                    crashinfo.mappings.size();  // memory mappings
  ehdr.e_shentsize= sizeof(Shdr);
  if (!writea(options.out_fd, &ehdr, sizeof(Ehdr)))
    return 1;

  size_t offset = sizeof(Ehdr) + ehdr.e_phnum * sizeof(Phdr);
  size_t filesz = sizeof(Nhdr) + 8 + sizeof(prpsinfo) +
                  // sizeof(Nhdr) + 8 + sizeof(user) +
                  sizeof(Nhdr) + 8 + crashinfo.auxv_length +
                  crashinfo.threads.size() * (
                    (sizeof(Nhdr) + 8 + sizeof(prstatus))
#if defined(__i386__) || defined(__x86_64__)
                   + sizeof(Nhdr) + 8 + sizeof(user_fpregs_struct)
#endif
#if defined(__i386__)
                   + sizeof(Nhdr) + 8 + sizeof(user_fpxregs_struct)
#endif
                    );

  Phdr phdr;
  memset(&phdr, 0, sizeof(Phdr));
  phdr.p_type = PT_NOTE;
  phdr.p_offset = offset;
  phdr.p_filesz = filesz;
  if (!writea(options.out_fd, &phdr, sizeof(phdr)))
    return 1;

  phdr.p_type = PT_LOAD;
  phdr.p_align = 4096;
  size_t note_align = phdr.p_align - ((offset+filesz) % phdr.p_align);
  if (note_align == phdr.p_align)
    note_align = 0;
  offset += note_align;

  for (std::map<uint64_t, CrashedProcess::Mapping>::const_iterator iter =
         crashinfo.mappings.begin();
       iter != crashinfo.mappings.end(); ++iter) {
    const CrashedProcess::Mapping& mapping = iter->second;
    if (mapping.permissions == 0xFFFFFFFF) {
      // This is a map that we found in MD_MODULE_LIST_STREAM (as opposed to
      // MD_LINUX_MAPS). It lacks some of the information that we would like
      // to include.
      phdr.p_flags = PF_R;
    } else {
      phdr.p_flags = mapping.permissions;
    }
    phdr.p_vaddr = mapping.start_address;
    phdr.p_memsz = mapping.end_address - mapping.start_address;
    if (mapping.data.size()) {
      offset += filesz;
      filesz = mapping.data.size();
      phdr.p_filesz = mapping.data.size();
      phdr.p_offset = offset;
    } else {
      phdr.p_filesz = 0;
      phdr.p_offset = 0;
    }
    if (!writea(options.out_fd, &phdr, sizeof(phdr)))
      return 1;
  }

  Nhdr nhdr;
  memset(&nhdr, 0, sizeof(nhdr));
  nhdr.n_namesz = 5;
  nhdr.n_descsz = sizeof(prpsinfo);
  nhdr.n_type = NT_PRPSINFO;
  if (!writea(options.out_fd, &nhdr, sizeof(nhdr)) ||
      !writea(options.out_fd, "CORE\0\0\0\0", 8) ||
      !writea(options.out_fd, &crashinfo.prps, sizeof(prpsinfo))) {
    return 1;
  }

  nhdr.n_descsz = crashinfo.auxv_length;
  nhdr.n_type = NT_AUXV;
  if (!writea(options.out_fd, &nhdr, sizeof(nhdr)) ||
      !writea(options.out_fd, "CORE\0\0\0\0", 8) ||
      !writea(options.out_fd, crashinfo.auxv, crashinfo.auxv_length)) {
    return 1;
  }

  for (unsigned i = 0; i < crashinfo.threads.size(); ++i) {
    if (crashinfo.threads[i].tid == crashinfo.crashing_tid) {
      WriteThread(options, crashinfo.threads[i], crashinfo.fatal_signal);
      break;
    }
  }

  for (unsigned i = 0; i < crashinfo.threads.size(); ++i) {
    if (crashinfo.threads[i].tid != crashinfo.crashing_tid)
      WriteThread(options, crashinfo.threads[i], 0);
  }

  if (note_align) {
    google_breakpad::scoped_array<char> scratch(new char[note_align]);
    memset(scratch.get(), 0, note_align);
    if (!writea(options.out_fd, scratch.get(), note_align))
      return 1;
  }

  for (std::map<uint64_t, CrashedProcess::Mapping>::const_iterator iter =
         crashinfo.mappings.begin();
       iter != crashinfo.mappings.end(); ++iter) {
    const CrashedProcess::Mapping& mapping = iter->second;
    if (mapping.data.size()) {
      if (!writea(options.out_fd, mapping.data.c_str(), mapping.data.size()))
        return 1;
    }
  }

  if (options.out_fd != STDOUT_FILENO) {
    close(options.out_fd);
  }

  return 0;
}
