summaryrefslogtreecommitdiffstats
path: root/toolkit/crashreporter/google-breakpad/src/tools/linux
diff options
context:
space:
mode:
Diffstat (limited to 'toolkit/crashreporter/google-breakpad/src/tools/linux')
-rw-r--r--toolkit/crashreporter/google-breakpad/src/tools/linux/core2md/core2md.cc72
-rw-r--r--toolkit/crashreporter/google-breakpad/src/tools/linux/dump_syms/dump_syms.cc113
-rw-r--r--toolkit/crashreporter/google-breakpad/src/tools/linux/dump_syms/moz.build33
-rw-r--r--toolkit/crashreporter/google-breakpad/src/tools/linux/md2core/minidump-2-core.cc1276
-rw-r--r--toolkit/crashreporter/google-breakpad/src/tools/linux/md2core/minidump_memory_range.h89
-rw-r--r--toolkit/crashreporter/google-breakpad/src/tools/linux/md2core/minidump_memory_range_unittest.cc258
-rw-r--r--toolkit/crashreporter/google-breakpad/src/tools/linux/symupload/minidump_upload.cc153
-rw-r--r--toolkit/crashreporter/google-breakpad/src/tools/linux/symupload/sym_upload.cc112
-rw-r--r--toolkit/crashreporter/google-breakpad/src/tools/linux/tools_linux.gypi83
9 files changed, 0 insertions, 2189 deletions
diff --git a/toolkit/crashreporter/google-breakpad/src/tools/linux/core2md/core2md.cc b/toolkit/crashreporter/google-breakpad/src/tools/linux/core2md/core2md.cc
deleted file mode 100644
index a0e8f8ba2..000000000
--- a/toolkit/crashreporter/google-breakpad/src/tools/linux/core2md/core2md.cc
+++ /dev/null
@@ -1,72 +0,0 @@
-// Copyright (c) 2012, 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.
-
-// core2md.cc: A utility to convert an ELF core file to a minidump file.
-
-#include <stdio.h>
-
-#include "client/linux/minidump_writer/minidump_writer.h"
-#include "client/linux/minidump_writer/linux_core_dumper.h"
-
-using google_breakpad::AppMemoryList;
-using google_breakpad::MappingList;
-using google_breakpad::LinuxCoreDumper;
-
-static int ShowUsage(const char* argv0) {
- fprintf(stderr, "Usage: %s <core file> <procfs dir> <output>\n", argv0);
- return 1;
-}
-
-bool WriteMinidumpFromCore(const char* filename,
- const char* core_path,
- const char* procfs_override) {
- MappingList mappings;
- AppMemoryList memory_list;
- LinuxCoreDumper dumper(0, core_path, procfs_override);
- return google_breakpad::WriteMinidump(filename, mappings, memory_list,
- &dumper);
-}
-
-int main(int argc, char *argv[]) {
- if (argc != 4) {
- return ShowUsage(argv[0]);
- }
-
- const char* core_file = argv[1];
- const char* procfs_dir = argv[2];
- const char* minidump_file = argv[3];
- if (!WriteMinidumpFromCore(minidump_file,
- core_file,
- procfs_dir)) {
- fprintf(stderr, "Unable to generate minidump.\n");
- return 1;
- }
-
- return 0;
-}
diff --git a/toolkit/crashreporter/google-breakpad/src/tools/linux/dump_syms/dump_syms.cc b/toolkit/crashreporter/google-breakpad/src/tools/linux/dump_syms/dump_syms.cc
deleted file mode 100644
index 84953172e..000000000
--- a/toolkit/crashreporter/google-breakpad/src/tools/linux/dump_syms/dump_syms.cc
+++ /dev/null
@@ -1,113 +0,0 @@
-// Copyright (c) 2011, 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 <paths.h>
-#include <stdio.h>
-#include <unistd.h>
-
-#include <cstring>
-#include <iostream>
-#include <string>
-#include <vector>
-
-#include "common/linux/dump_symbols.h"
-
-using google_breakpad::WriteSymbolFile;
-using google_breakpad::WriteSymbolFileHeader;
-
-int usage(const char* self) {
- fprintf(stderr, "Usage: %s [OPTION] <binary-with-debugging-info> "
- "[directories-for-debug-file]\n\n", self);
- fprintf(stderr, "Options:\n");
- fprintf(stderr, " -i: Output module header information only.\n");
- fprintf(stderr, " -c Do not generate CFI section\n");
- fprintf(stderr, " -r Do not handle inter-compilation unit references\n");
- fprintf(stderr, " -v Print all warnings to stderr\n");
- return 1;
-}
-
-int main(int argc, char **argv) {
- if (argc < 2)
- return usage(argv[0]);
- bool header_only = false;
- bool cfi = true;
- bool handle_inter_cu_refs = true;
- bool log_to_stderr = false;
- int arg_index = 1;
- while (arg_index < argc && strlen(argv[arg_index]) > 0 &&
- argv[arg_index][0] == '-') {
- if (strcmp("-i", argv[arg_index]) == 0) {
- header_only = true;
- } else if (strcmp("-c", argv[arg_index]) == 0) {
- cfi = false;
- } else if (strcmp("-r", argv[arg_index]) == 0) {
- handle_inter_cu_refs = false;
- } else if (strcmp("-v", argv[arg_index]) == 0) {
- log_to_stderr = true;
- } else {
- printf("2.4 %s\n", argv[arg_index]);
- return usage(argv[0]);
- }
- ++arg_index;
- }
- if (arg_index == argc)
- return usage(argv[0]);
- // Save stderr so it can be used below.
- FILE* saved_stderr = fdopen(dup(fileno(stderr)), "w");
- if (!log_to_stderr) {
- if (freopen(_PATH_DEVNULL, "w", stderr)) {
- // If it fails, not a lot we can (or should) do.
- // Add this brace section to silence gcc warnings.
- }
- }
- const char* binary;
- std::vector<string> debug_dirs;
- binary = argv[arg_index];
- for (int debug_dir_index = arg_index + 1;
- debug_dir_index < argc;
- ++debug_dir_index) {
- debug_dirs.push_back(argv[debug_dir_index]);
- }
-
- if (header_only) {
- if (!WriteSymbolFileHeader(binary, std::cout)) {
- fprintf(saved_stderr, "Failed to process file.\n");
- return 1;
- }
- } else {
- SymbolData symbol_data = cfi ? ALL_SYMBOL_DATA : NO_CFI;
- google_breakpad::DumpOptions options(symbol_data, handle_inter_cu_refs);
- if (!WriteSymbolFile(binary, debug_dirs, options, std::cout)) {
- fprintf(saved_stderr, "Failed to write symbol file.\n");
- return 1;
- }
- }
-
- return 0;
-}
diff --git a/toolkit/crashreporter/google-breakpad/src/tools/linux/dump_syms/moz.build b/toolkit/crashreporter/google-breakpad/src/tools/linux/dump_syms/moz.build
deleted file mode 100644
index 643020e84..000000000
--- a/toolkit/crashreporter/google-breakpad/src/tools/linux/dump_syms/moz.build
+++ /dev/null
@@ -1,33 +0,0 @@
-# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
-# vim: set filetype=python:
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-HOST_SOURCES += [
- 'dump_syms.cc',
-]
-
-HOST_CXXFLAGS += [
- '-O2',
- '-g',
-]
-
-# host_breakpad_linux_common_s needs to come first
-HOST_USE_LIBS += [
- 'host_breakpad_linux_common_s',
-]
-HOST_USE_LIBS += [
- 'host_breakpad_common_s',
- 'host_breakpad_dwarf_s',
-]
-
-# The HostProgram template may append 'host_stdc++compat' to
-# HOST_USE_LIBS, which needs to appear after the entries above.
-HostProgram('dump_syms')
-
-LOCAL_INCLUDES += [
- '../../../common/linux',
-]
-
-include('/toolkit/crashreporter/crashreporter.mozbuild')
diff --git a/toolkit/crashreporter/google-breakpad/src/tools/linux/md2core/minidump-2-core.cc b/toolkit/crashreporter/google-breakpad/src/tools/linux/md2core/minidump-2-core.cc
deleted file mode 100644
index 6f637845e..000000000
--- a/toolkit/crashreporter/google-breakpad/src/tools/linux/md2core/minidump-2-core.cc
+++ /dev/null
@@ -1,1276 +0,0 @@
-// 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/
-//
-// Usage: minidump-2-core [-v] 1234.dmp > core
-
-#include <elf.h>
-#include <errno.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/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 __WORDSIZE == 64
- #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);
-static bool verbose;
-static string g_custom_so_basedir;
-
-static int usage(const char* argv0) {
- fprintf(stderr, "Usage: %s [-v] <minidump file>\n", argv0);
- return 1;
-}
-
-// 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;
- 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;
-
- std::map<uintptr_t, string> 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) {
- const MDRawContextARM64* rawregs = range.GetData<MDRawContextARM64>(0);
-
- 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;
-}
-#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(CrashedProcess* crashinfo, const MinidumpMemoryRange& range,
- const MinidumpMemoryRange& full_file) {
- const uint32_t num_threads = *range.GetData<uint32_t>(0);
- if (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(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) {
- 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 (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(CrashedProcess* crashinfo, const MinidumpMemoryRange& range) {
- if (verbose) {
- fputs("MD_LINUX_CPU_INFO:\n", stderr);
- fwrite(range.data(), range.length(), 1, stderr);
- fputs("\n\n\n", stderr);
- }
-}
-
-static void
-ParseProcessStatus(CrashedProcess* crashinfo,
- const MinidumpMemoryRange& range) {
- if (verbose) {
- fputs("MD_LINUX_PROC_STATUS:\n", stderr);
- fwrite(range.data(), range.length(), 1, stderr);
- fputs("\n\n", stderr);
- }
-}
-
-static void
-ParseLSBRelease(CrashedProcess* crashinfo, const MinidumpMemoryRange& range) {
- if (verbose) {
- fputs("MD_LINUX_LSB_RELEASE:\n", stderr);
- fwrite(range.data(), range.length(), 1, stderr);
- fputs("\n\n", stderr);
- }
-}
-
-static void
-ParseMaps(CrashedProcess* crashinfo, const MinidumpMemoryRange& range) {
- if (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 (verbose) {
- fputs("\n\n\n", stderr);
- }
-}
-
-static void
-ParseEnvironment(CrashedProcess* crashinfo, const MinidumpMemoryRange& range) {
- if (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(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(crashinfo, range);
- return;
- }
- }
-
- crashinfo->auxv = range.data();
- crashinfo->auxv_length = range.length();
-}
-
-static void
-ParseCmdLine(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 (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(CrashedProcess* crashinfo, const MinidumpMemoryRange& range,
- const MinidumpMemoryRange& full_file) {
- const MDRawDebug* debug = range.GetData<MDRawDebug>(0);
- if (!debug) {
- return;
- }
- if (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 (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 (verbose) {
- fputs("\n\n", stderr);
- }
-}
-
-static void
-ParseExceptionStream(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 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(1, &nhdr, sizeof(nhdr)) ||
- !writea(1, "CORE\0\0\0\0", 8) ||
- !writea(1, &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(1, &nhdr, sizeof(nhdr)) ||
- !writea(1, "CORE\0\0\0\0", 8) ||
- !writea(1, &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(1, &nhdr, sizeof(nhdr)) ||
- !writea(1, "LINUX\0\0\0", 8) ||
- !writea(1, &thread.fpxregs, sizeof(user_fpxregs_struct))) {
- return false;
- }
-#endif
-
- return true;
-}
-
-static void
-ParseModuleStream(CrashedProcess* crashinfo, const MinidumpMemoryRange& range,
- const MinidumpMemoryRange& full_file) {
- if (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);
- size_t slash = filename.find_last_of('/');
- string basename = slash == string::npos ?
- filename : filename.substr(slash + 1);
- if (strcmp(guid, "00000000-0000-0000-0000-000000000000")) {
- string prefix;
- if (!g_custom_so_basedir.empty())
- prefix = g_custom_so_basedir;
- else
- prefix = string("/var/lib/breakpad/") + guid + "-" + basename;
-
- crashinfo->signatures[rawmodule->base_of_image] = prefix + basename;
- }
-
- if (verbose) {
- fprintf(stderr, "0x%08llX-0x%08llX, ChkSum: 0x%08X, GUID: %s, \"%s\"\n",
- (unsigned long long)rawmodule->base_of_image,
- (unsigned long long)rawmodule->base_of_image +
- rawmodule->size_of_image,
- rawmodule->checksum, guid, filename.c_str());
- }
- }
- if (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(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, string>::const_iterator guid =
- crashinfo->signatures.find((uintptr_t)iter->addr);
- if (guid != crashinfo->signatures.end()) {
- filename = guid->second;
- }
-
- 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 (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, char** argv) {
- int argi = 1;
- while (argi < argc && argv[argi][0] == '-') {
- if (!strcmp(argv[argi], "-v")) {
- verbose = true;
- } else if (!strcmp(argv[argi], "--sobasedir")) {
- argi++;
- if (argi >= argc) {
- fprintf(stderr, "--sobasedir expects an argument.");
- return usage(argv[0]);
- }
-
- g_custom_so_basedir = argv[argi];
- } else {
- return usage(argv[0]);
- }
- argi++;
- }
-
- if (argc != argi + 1)
- return usage(argv[0]);
-
- MemoryMappedFile mapped_file(argv[argi], 0);
- if (!mapped_file.data()) {
- fprintf(stderr, "Failed to mmap dump file\n");
- 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(&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(&crashinfo, dump.Subrange(dirent->location), dump);
- break;
- case MD_LINUX_CPU_INFO:
- ParseCPUInfo(&crashinfo, dump.Subrange(dirent->location));
- break;
- case MD_LINUX_PROC_STATUS:
- ParseProcessStatus(&crashinfo, dump.Subrange(dirent->location));
- break;
- case MD_LINUX_LSB_RELEASE:
- ParseLSBRelease(&crashinfo, dump.Subrange(dirent->location));
- break;
- case MD_LINUX_ENVIRON:
- ParseEnvironment(&crashinfo, dump.Subrange(dirent->location));
- break;
- case MD_LINUX_MAPS:
- ParseMaps(&crashinfo, dump.Subrange(dirent->location));
- break;
- case MD_LINUX_AUXV:
- ParseAuxVector(&crashinfo, dump.Subrange(dirent->location));
- break;
- case MD_LINUX_CMD_LINE:
- ParseCmdLine(&crashinfo, dump.Subrange(dirent->location));
- break;
- case MD_LINUX_DSO_DEBUG:
- ParseDSODebugInfo(&crashinfo, dump.Subrange(dirent->location), dump);
- break;
- case MD_EXCEPTION_STREAM:
- ParseExceptionStream(&crashinfo, dump.Subrange(dirent->location));
- break;
- case MD_MODULE_LIST_STREAM:
- ParseModuleStream(&crashinfo, dump.Subrange(dirent->location), dump);
- break;
- default:
- if (verbose)
- fprintf(stderr, "Skipping %x\n", dirent->stream_type);
- }
- }
-
- AugmentMappings(&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(1, &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(1, &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(1, &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(1, &nhdr, sizeof(nhdr)) ||
- !writea(1, "CORE\0\0\0\0", 8) ||
- !writea(1, &crashinfo.prps, sizeof(prpsinfo))) {
- return 1;
- }
-
- nhdr.n_descsz = crashinfo.auxv_length;
- nhdr.n_type = NT_AUXV;
- if (!writea(1, &nhdr, sizeof(nhdr)) ||
- !writea(1, "CORE\0\0\0\0", 8) ||
- !writea(1, 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(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(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(1, 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(1, mapping.data.c_str(), mapping.data.size()))
- return 1;
- }
- }
-
- return 0;
-}
diff --git a/toolkit/crashreporter/google-breakpad/src/tools/linux/md2core/minidump_memory_range.h b/toolkit/crashreporter/google-breakpad/src/tools/linux/md2core/minidump_memory_range.h
deleted file mode 100644
index a793e2cfb..000000000
--- a/toolkit/crashreporter/google-breakpad/src/tools/linux/md2core/minidump_memory_range.h
+++ /dev/null
@@ -1,89 +0,0 @@
-// Copyright (c) 2011, 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.
-
-// minidump_memory_range.h: Define the google_breakpad::MinidumpMemoryRange
-// class, which adds methods for handling minidump specific data structures
-// on top of google_breakpad::MemoryRange. See common/memory_range.h for
-// more details on MemoryRange.
-
-#ifndef TOOLS_LINUX_MD2CORE_MINIDUMP_MEMORY_RANGE_H_
-#define TOOLS_LINUX_MD2CORE_MINIDUMP_MEMORY_RANGE_H_
-
-#include <string>
-
-#include "common/memory_range.h"
-#include "google_breakpad/common/minidump_format.h"
-
-namespace google_breakpad {
-
-// A derived class of MemoryRange with added methods for handling minidump
-// specific data structures. To avoid virtual functions, it is not designed
-// to be used polymorphically.
-class MinidumpMemoryRange : public MemoryRange {
- public:
- MinidumpMemoryRange() {}
-
- MinidumpMemoryRange(const void* data, size_t length)
- : MemoryRange(data, length) {}
-
- // Returns a subrange of |length| bytes at |offset| bytes of this memory
- // range, or an empty range if the subrange is out of bounds.
- // This methods overrides the base implemementation in order to return
- // an instance of MinidumpMemoryRange instead of MemoryRange.
- MinidumpMemoryRange Subrange(size_t sub_offset, size_t sub_length) const {
- if (Covers(sub_offset, sub_length))
- return MinidumpMemoryRange(data() + sub_offset, sub_length);
- return MinidumpMemoryRange();
- }
-
- // Returns a subrange that covers the offset and length specified by
- // |location|, or an empty range if the subrange is out of bounds.
- MinidumpMemoryRange Subrange(const MDLocationDescriptor& location) const {
- return MinidumpMemoryRange::Subrange(location.rva, location.data_size);
- }
-
- // Gets a STL string from a MDString at |sub_offset| bytes of this memory
- // range. This method only works correctly for ASCII characters and does
- // not convert between UTF-16 and UTF-8.
- const std::string GetAsciiMDString(size_t sub_offset) const {
- std::string str;
- const MDString* md_str = GetData<MDString>(sub_offset);
- if (md_str) {
- const uint16_t* buffer = &md_str->buffer[0];
- for (uint32_t i = 0; i < md_str->length && buffer[i]; ++i) {
- str.push_back(buffer[i]);
- }
- }
- return str;
- }
-};
-
-} // namespace google_breakpad
-
-#endif // TOOLS_LINUX_MD2CORE_MINIDUMP_MEMORY_RANGE_H_
diff --git a/toolkit/crashreporter/google-breakpad/src/tools/linux/md2core/minidump_memory_range_unittest.cc b/toolkit/crashreporter/google-breakpad/src/tools/linux/md2core/minidump_memory_range_unittest.cc
deleted file mode 100644
index fe4ded83d..000000000
--- a/toolkit/crashreporter/google-breakpad/src/tools/linux/md2core/minidump_memory_range_unittest.cc
+++ /dev/null
@@ -1,258 +0,0 @@
-// Copyright (c) 2011, 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.
-
-// minidump_memory_range_unittest.cc:
-// Unit tests for google_breakpad::MinidumpMemoryRange.
-
-#include "breakpad_googletest_includes.h"
-#include "tools/linux/md2core/minidump_memory_range.h"
-
-using google_breakpad::MinidumpMemoryRange;
-using testing::Message;
-
-namespace {
-
-const uint32_t kBuffer[10] = { 0 };
-const size_t kBufferSize = sizeof(kBuffer);
-const uint8_t* kBufferPointer = reinterpret_cast<const uint8_t*>(kBuffer);
-
-// Test vectors for verifying Covers, GetData, and Subrange.
-const struct {
- bool valid;
- size_t offset;
- size_t length;
-} kSubranges[] = {
- { true, 0, 0 },
- { true, 0, 2 },
- { true, 0, kBufferSize },
- { true, 2, 0 },
- { true, 2, 4 },
- { true, 2, kBufferSize - 2 },
- { true, kBufferSize - 1, 1 },
- { false, kBufferSize, 0 },
- { false, kBufferSize, static_cast<size_t>(-1) },
- { false, kBufferSize + 1, 0 },
- { false, static_cast<size_t>(-1), 2 },
- { false, 1, kBufferSize },
- { false, kBufferSize - 1, 2 },
- { false, 0, static_cast<size_t>(-1) },
- { false, 1, static_cast<size_t>(-1) },
-};
-const size_t kNumSubranges = sizeof(kSubranges) / sizeof(kSubranges[0]);
-
-// Test vectors for verifying GetArrayElement.
-const struct {
- size_t offset;
- size_t size;
- size_t index;
- const void* const pointer;
-} kElements[] = {
- // Valid array elemenets
- { 0, 1, 0, kBufferPointer },
- { 0, 1, 1, kBufferPointer + 1 },
- { 0, 1, kBufferSize - 1, kBufferPointer + kBufferSize - 1 },
- { 0, 2, 1, kBufferPointer + 2 },
- { 0, 4, 2, kBufferPointer + 8 },
- { 0, 4, 9, kBufferPointer + 36 },
- { kBufferSize - 1, 1, 0, kBufferPointer + kBufferSize - 1 },
- // Invalid array elemenets
- { 0, 1, kBufferSize, NULL },
- { 0, 4, 10, NULL },
- { kBufferSize - 1, 1, 1, NULL },
- { kBufferSize - 1, 2, 0, NULL },
- { kBufferSize, 1, 0, NULL },
-};
-const size_t kNumElements = sizeof(kElements) / sizeof(kElements[0]);
-
-} // namespace
-
-TEST(MinidumpMemoryRangeTest, DefaultConstructor) {
- MinidumpMemoryRange range;
- EXPECT_EQ(NULL, range.data());
- EXPECT_EQ(0U, range.length());
-}
-
-TEST(MinidumpMemoryRangeTest, ConstructorWithDataAndLength) {
- MinidumpMemoryRange range(kBuffer, kBufferSize);
- EXPECT_EQ(kBufferPointer, range.data());
- EXPECT_EQ(kBufferSize, range.length());
-}
-
-TEST(MinidumpMemoryRangeTest, Reset) {
- MinidumpMemoryRange range;
- range.Reset();
- EXPECT_EQ(NULL, range.data());
- EXPECT_EQ(0U, range.length());
-
- range.Set(kBuffer, kBufferSize);
- EXPECT_EQ(kBufferPointer, range.data());
- EXPECT_EQ(kBufferSize, range.length());
-
- range.Reset();
- EXPECT_EQ(NULL, range.data());
- EXPECT_EQ(0U, range.length());
-}
-
-TEST(MinidumpMemoryRangeTest, Set) {
- MinidumpMemoryRange range;
- range.Set(kBuffer, kBufferSize);
- EXPECT_EQ(kBufferPointer, range.data());
- EXPECT_EQ(kBufferSize, range.length());
-
- range.Set(NULL, 0);
- EXPECT_EQ(NULL, range.data());
- EXPECT_EQ(0U, range.length());
-}
-
-TEST(MinidumpMemoryRangeTest, SubrangeOfEmptyMemoryRange) {
- MinidumpMemoryRange range;
- MinidumpMemoryRange subrange = range.Subrange(0, 10);
- EXPECT_EQ(NULL, subrange.data());
- EXPECT_EQ(0U, subrange.length());
-}
-
-TEST(MinidumpMemoryRangeTest, SubrangeAndGetData) {
- MinidumpMemoryRange range(kBuffer, kBufferSize);
- for (size_t i = 0; i < kNumSubranges; ++i) {
- bool valid = kSubranges[i].valid;
- size_t sub_offset = kSubranges[i].offset;
- size_t sub_length = kSubranges[i].length;
- SCOPED_TRACE(Message() << "offset=" << sub_offset
- << ", length=" << sub_length);
-
- MinidumpMemoryRange subrange = range.Subrange(sub_offset, sub_length);
- if (valid) {
- EXPECT_TRUE(range.Covers(sub_offset, sub_length));
- EXPECT_EQ(kBufferPointer + sub_offset,
- range.GetData(sub_offset, sub_length));
- EXPECT_EQ(kBufferPointer + sub_offset, subrange.data());
- EXPECT_EQ(sub_length, subrange.length());
- } else {
- EXPECT_FALSE(range.Covers(sub_offset, sub_length));
- EXPECT_EQ(NULL, range.GetData(sub_offset, sub_length));
- EXPECT_EQ(NULL, subrange.data());
- EXPECT_EQ(0U, subrange.length());
- }
- }
-}
-
-TEST(MinidumpMemoryRangeTest, SubrangeWithMDLocationDescriptor) {
- MinidumpMemoryRange range(kBuffer, kBufferSize);
- for (size_t i = 0; i < kNumSubranges; ++i) {
- bool valid = kSubranges[i].valid;
- size_t sub_offset = kSubranges[i].offset;
- size_t sub_length = kSubranges[i].length;
- SCOPED_TRACE(Message() << "offset=" << sub_offset
- << ", length=" << sub_length);
-
- MDLocationDescriptor location;
- location.rva = sub_offset;
- location.data_size = sub_length;
- MinidumpMemoryRange subrange = range.Subrange(location);
- if (valid) {
- EXPECT_TRUE(range.Covers(sub_offset, sub_length));
- EXPECT_EQ(kBufferPointer + sub_offset,
- range.GetData(sub_offset, sub_length));
- EXPECT_EQ(kBufferPointer + sub_offset, subrange.data());
- EXPECT_EQ(sub_length, subrange.length());
- } else {
- EXPECT_FALSE(range.Covers(sub_offset, sub_length));
- EXPECT_EQ(NULL, range.GetData(sub_offset, sub_length));
- EXPECT_EQ(NULL, subrange.data());
- EXPECT_EQ(0U, subrange.length());
- }
- }
-}
-
-TEST(MinidumpMemoryRangeTest, GetDataWithTemplateType) {
- MinidumpMemoryRange range(kBuffer, kBufferSize);
- const char* char_pointer = range.GetData<char>(0);
- EXPECT_EQ(reinterpret_cast<const char*>(kBufferPointer), char_pointer);
- const int* int_pointer = range.GetData<int>(0);
- EXPECT_EQ(reinterpret_cast<const int*>(kBufferPointer), int_pointer);
-}
-
-TEST(MinidumpMemoryRangeTest, GetArrayElement) {
- MinidumpMemoryRange range(kBuffer, kBufferSize);
- for (size_t i = 0; i < kNumElements; ++i) {
- size_t element_offset = kElements[i].offset;
- size_t element_size = kElements[i].size;
- unsigned element_index = kElements[i].index;
- const void* const element_pointer = kElements[i].pointer;
- SCOPED_TRACE(Message() << "offset=" << element_offset
- << ", size=" << element_size
- << ", index=" << element_index);
- EXPECT_EQ(element_pointer, range.GetArrayElement(
- element_offset, element_size, element_index));
- }
-}
-
-TEST(MinidumpMemoryRangeTest, GetArrayElmentWithTemplateType) {
- MinidumpMemoryRange range(kBuffer, kBufferSize);
- const char* char_pointer = range.GetArrayElement<char>(0, 0);
- EXPECT_EQ(reinterpret_cast<const char*>(kBufferPointer), char_pointer);
- const int* int_pointer = range.GetArrayElement<int>(0, 0);
- EXPECT_EQ(reinterpret_cast<const int*>(kBufferPointer), int_pointer);
-}
-
-TEST(MinidumpMemoryRangeTest, GetAsciiMDString) {
- uint8_t buffer[100] = { 0 };
-
- MDString* md_str = reinterpret_cast<MDString*>(buffer);
- md_str->length = 4;
- md_str->buffer[0] = 'T';
- md_str->buffer[1] = 'e';
- md_str->buffer[2] = 's';
- md_str->buffer[3] = 't';
- md_str->buffer[4] = '\0';
-
- size_t str2_offset =
- sizeof(MDString) + (md_str->length + 1) * sizeof(uint16_t);
-
- md_str = reinterpret_cast<MDString*>(buffer + str2_offset);
- md_str->length = 9; // Test length larger than actual string
- md_str->buffer[0] = 'S';
- md_str->buffer[1] = 't';
- md_str->buffer[2] = 'r';
- md_str->buffer[3] = 'i';
- md_str->buffer[4] = 'n';
- md_str->buffer[5] = 'g';
- md_str->buffer[6] = '\0';
- md_str->buffer[7] = '1';
- md_str->buffer[8] = '2';
-
- MinidumpMemoryRange range(buffer, sizeof(buffer));
- EXPECT_EQ("Test", range.GetAsciiMDString(0));
- EXPECT_EQ("String", range.GetAsciiMDString(str2_offset));
-
- // Test out-of-bounds cases.
- EXPECT_EQ("", range.GetAsciiMDString(
- sizeof(buffer) - sizeof(MDString) + 1));
- EXPECT_EQ("", range.GetAsciiMDString(sizeof(buffer)));
-}
diff --git a/toolkit/crashreporter/google-breakpad/src/tools/linux/symupload/minidump_upload.cc b/toolkit/crashreporter/google-breakpad/src/tools/linux/symupload/minidump_upload.cc
deleted file mode 100644
index 19f17450a..000000000
--- a/toolkit/crashreporter/google-breakpad/src/tools/linux/symupload/minidump_upload.cc
+++ /dev/null
@@ -1,153 +0,0 @@
-// 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.
-
-// minidump_upload.cc: Upload a minidump to a HTTP server.
-// The upload is sent as a multipart/form-data POST request with
-// the following parameters:
-// prod: the product name
-// ver: the product version
-// symbol_file: the breakpad format symbol file
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-
-#include <string>
-
-#include "common/linux/http_upload.h"
-#include "common/using_std_string.h"
-
-using google_breakpad::HTTPUpload;
-
-struct Options {
- string minidumpPath;
- string uploadURLStr;
- string product;
- string version;
- string proxy;
- string proxy_user_pwd;
- bool success;
-};
-
-//=============================================================================
-static void Start(Options *options) {
- std::map<string, string> parameters;
- // Add parameters
- parameters["prod"] = options->product;
- parameters["ver"] = options->version;
-
- std::map<string, string> files;
- files["upload_file_minidump"] = options->minidumpPath;
-
- // Send it
- string response, error;
- bool success = HTTPUpload::SendRequest(options->uploadURLStr,
- parameters,
- files,
- options->proxy,
- options->proxy_user_pwd,
- "",
- &response,
- NULL,
- &error);
-
- if (success) {
- printf("Successfully sent the minidump file.\n");
- } else {
- printf("Failed to send minidump: %s\n", error.c_str());
- }
- printf("Response:\n");
- printf("%s\n", response.c_str());
- options->success = success;
-}
-
-//=============================================================================
-static void
-Usage(int argc, const char *argv[]) {
- fprintf(stderr, "Submit minidump information.\n");
- fprintf(stderr, "Usage: %s [options...] -p <product> -v <version> <minidump> "
- "<upload-URL>\n", argv[0]);
- fprintf(stderr, "Options:\n");
- fprintf(stderr, "<minidump> should be a minidump.\n");
- fprintf(stderr, "<upload-URL> is the destination for the upload\n");
-
- fprintf(stderr, "-p:\t <product> Product name\n");
- fprintf(stderr, "-v:\t <version> Product version\n");
- fprintf(stderr, "-x:\t <host[:port]> Use HTTP proxy on given port\n");
- fprintf(stderr, "-u:\t <user[:password]> Set proxy user and password\n");
- fprintf(stderr, "-h:\t Usage\n");
- fprintf(stderr, "-?:\t Usage\n");
-}
-
-//=============================================================================
-static void
-SetupOptions(int argc, const char *argv[], Options *options) {
- extern int optind;
- int ch;
-
- while ((ch = getopt(argc, (char * const *)argv, "p:u:v:x:h?")) != -1) {
- switch (ch) {
- case 'p':
- options->product = optarg;
- break;
- case 'u':
- options->proxy_user_pwd = optarg;
- break;
- case 'v':
- options->version = optarg;
- break;
- case 'x':
- options->proxy = optarg;
- break;
-
- default:
- fprintf(stderr, "Invalid option '%c'\n", ch);
- Usage(argc, argv);
- exit(1);
- break;
- }
- }
-
- if ((argc - optind) != 2) {
- fprintf(stderr, "%s: Missing symbols file and/or upload-URL\n", argv[0]);
- Usage(argc, argv);
- exit(1);
- }
-
- options->minidumpPath = argv[optind];
- options->uploadURLStr = argv[optind + 1];
-}
-
-//=============================================================================
-int main(int argc, const char* argv[]) {
- Options options;
- SetupOptions(argc, argv, &options);
- Start(&options);
- return options.success ? 0 : 1;
-}
diff --git a/toolkit/crashreporter/google-breakpad/src/tools/linux/symupload/sym_upload.cc b/toolkit/crashreporter/google-breakpad/src/tools/linux/symupload/sym_upload.cc
deleted file mode 100644
index 9eeb2d447..000000000
--- a/toolkit/crashreporter/google-breakpad/src/tools/linux/symupload/sym_upload.cc
+++ /dev/null
@@ -1,112 +0,0 @@
-// 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.
-
-// symupload.cc: Upload a symbol file to a HTTP server. The upload is sent as
-// a multipart/form-data POST request with the following parameters:
-// code_file: the basename of the module, e.g. "app"
-// debug_file: the basename of the debugging file, e.g. "app"
-// debug_identifier: the debug file's identifier, usually consisting of
-// the guid and age embedded in the pdb, e.g.
-// "11111111BBBB3333DDDD555555555555F"
-// version: the file version of the module, e.g. "1.2.3.4"
-// os: the operating system that the module was built for
-// cpu: the CPU that the module was built for
-// symbol_file: the contents of the breakpad-format symbol file
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-
-#include "common/linux/symbol_upload.h"
-
-using google_breakpad::sym_upload::Options;
-
-//=============================================================================
-static void
-Usage(int argc, const char *argv[]) {
- fprintf(stderr, "Submit symbol information.\n");
- fprintf(stderr, "Usage: %s [options...] <symbols> <upload-URL>\n", argv[0]);
- fprintf(stderr, "Options:\n");
- fprintf(stderr, "<symbols> should be created by using the dump_syms tool.\n");
- fprintf(stderr, "<upload-URL> is the destination for the upload\n");
- fprintf(stderr, "-v:\t Version information (e.g., 1.2.3.4)\n");
- fprintf(stderr, "-x:\t <host[:port]> Use HTTP proxy on given port\n");
- fprintf(stderr, "-u:\t <user[:password]> Set proxy user and password\n");
- fprintf(stderr, "-h:\t Usage\n");
- fprintf(stderr, "-?:\t Usage\n");
-}
-
-//=============================================================================
-static void
-SetupOptions(int argc, const char *argv[], Options *options) {
- extern int optind;
- int ch;
-
- while ((ch = getopt(argc, (char * const *)argv, "u:v:x:h?")) != -1) {
- switch (ch) {
- case 'h':
- case '?':
- Usage(argc, argv);
- exit(0);
- break;
- case 'u':
- options->proxy_user_pwd = optarg;
- break;
- case 'v':
- options->version = optarg;
- break;
- case 'x':
- options->proxy = optarg;
- break;
-
- default:
- fprintf(stderr, "Invalid option '%c'\n", ch);
- Usage(argc, argv);
- exit(1);
- break;
- }
- }
-
- if ((argc - optind) != 2) {
- fprintf(stderr, "%s: Missing symbols file and/or upload-URL\n", argv[0]);
- Usage(argc, argv);
- exit(1);
- }
-
- options->symbolsPath = argv[optind];
- options->uploadURLStr = argv[optind + 1];
-}
-
-//=============================================================================
-int main(int argc, const char* argv[]) {
- Options options;
- SetupOptions(argc, argv, &options);
- google_breakpad::sym_upload::Start(&options);
- return options.success ? 0 : 1;
-}
diff --git a/toolkit/crashreporter/google-breakpad/src/tools/linux/tools_linux.gypi b/toolkit/crashreporter/google-breakpad/src/tools/linux/tools_linux.gypi
deleted file mode 100644
index 1c15992e1..000000000
--- a/toolkit/crashreporter/google-breakpad/src/tools/linux/tools_linux.gypi
+++ /dev/null
@@ -1,83 +0,0 @@
-# Copyright 2014 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.
-
-{
- 'target_defaults': {
- 'include_dirs': [
- '../..',
- ],
- },
- 'targets': [
- {
- 'target_name': 'dump_syms',
- 'type': 'executable',
- 'sources': [
- 'dump_syms/dump_syms.cc',
- ],
- 'dependencies': [
- '../common/common.gyp:common',
- ],
- },
- {
- 'target_name': 'md2core',
- 'type': 'executable',
- 'sources': [
- 'md2core/minidump-2-core.cc',
- 'md2core/minidump_memory_range.h',
- ],
- 'dependencies': [
- '../common/common.gyp:common',
- ],
- },
- {
- 'target_name': 'minidump_upload',
- 'type': 'executable',
- 'sources': [
- 'symupload/minidump_upload.m',
- ],
- 'dependencies': [
- '../common/common.gyp:common',
- ],
- },
- {
- 'target_name': 'symupload',
- 'type': 'executable',
- 'sources': [
- 'symupload/sym_upload.cc',
- ],
- 'link_settings': {
- 'libraries': [
- '-ldl',
- ],
- },
- 'dependencies': [
- '../common/common.gyp:common',
- ],
- },
- ],
-}