summaryrefslogtreecommitdiffstats
path: root/toolkit/crashreporter/google-breakpad/src/tools
diff options
context:
space:
mode:
authorMatt A. Tobin <mattatobin@localhost.localdomain>2018-02-02 04:16:08 -0500
committerMatt A. Tobin <mattatobin@localhost.localdomain>2018-02-02 04:16:08 -0500
commit5f8de423f190bbb79a62f804151bc24824fa32d8 (patch)
tree10027f336435511475e392454359edea8e25895d /toolkit/crashreporter/google-breakpad/src/tools
parent49ee0794b5d912db1f95dce6eb52d781dc210db5 (diff)
downloadUXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.gz
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.lz
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.xz
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.zip
Add m-esr52 at 52.6.0
Diffstat (limited to 'toolkit/crashreporter/google-breakpad/src/tools')
-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
-rw-r--r--toolkit/crashreporter/google-breakpad/src/tools/mac/crash_report/crash_report.mm408
-rw-r--r--toolkit/crashreporter/google-breakpad/src/tools/mac/crash_report/crash_report.xcodeproj/project.pbxproj587
-rw-r--r--toolkit/crashreporter/google-breakpad/src/tools/mac/crash_report/on_demand_symbol_supplier.h111
-rw-r--r--toolkit/crashreporter/google-breakpad/src/tools/mac/crash_report/on_demand_symbol_supplier.mm316
-rw-r--r--toolkit/crashreporter/google-breakpad/src/tools/mac/dump_syms/dump_syms.xcodeproj/project.pbxproj1839
-rw-r--r--toolkit/crashreporter/google-breakpad/src/tools/mac/dump_syms/dump_syms_tool.cc264
-rw-r--r--toolkit/crashreporter/google-breakpad/src/tools/mac/dump_syms/macho_dump.cc203
-rw-r--r--toolkit/crashreporter/google-breakpad/src/tools/mac/dump_syms/moz.build40
-rw-r--r--toolkit/crashreporter/google-breakpad/src/tools/mac/symupload/minidump_upload.m135
-rw-r--r--toolkit/crashreporter/google-breakpad/src/tools/mac/symupload/symupload.m204
-rw-r--r--toolkit/crashreporter/google-breakpad/src/tools/mac/symupload/symupload.xcodeproj/project.pbxproj254
-rw-r--r--toolkit/crashreporter/google-breakpad/src/tools/mac/tools_mac.gypi116
-rw-r--r--toolkit/crashreporter/google-breakpad/src/tools/mac/upload_system_symbols/arch_constants.h61
-rw-r--r--toolkit/crashreporter/google-breakpad/src/tools/mac/upload_system_symbols/arch_reader.go65
-rw-r--r--toolkit/crashreporter/google-breakpad/src/tools/mac/upload_system_symbols/upload_system_symbols.go420
-rw-r--r--toolkit/crashreporter/google-breakpad/src/tools/python/filter_syms.py204
-rw-r--r--toolkit/crashreporter/google-breakpad/src/tools/python/tests/filter_syms_unittest.py138
-rw-r--r--toolkit/crashreporter/google-breakpad/src/tools/solaris/dump_syms/Makefile64
-rw-r--r--toolkit/crashreporter/google-breakpad/src/tools/solaris/dump_syms/Makefile.in5
-rw-r--r--toolkit/crashreporter/google-breakpad/src/tools/solaris/dump_syms/dump_syms.cc54
-rw-r--r--toolkit/crashreporter/google-breakpad/src/tools/solaris/dump_syms/moz.build29
-rw-r--r--toolkit/crashreporter/google-breakpad/src/tools/solaris/dump_syms/run_regtest.sh51
-rw-r--r--toolkit/crashreporter/google-breakpad/src/tools/solaris/dump_syms/testdata/dump_syms_regtest.cc64
-rw-r--r--toolkit/crashreporter/google-breakpad/src/tools/solaris/dump_syms/testdata/dump_syms_regtest.stabs129
-rw-r--r--toolkit/crashreporter/google-breakpad/src/tools/solaris/dump_syms/testdata/dump_syms_regtest.sym33
-rw-r--r--toolkit/crashreporter/google-breakpad/src/tools/tools.gyp38
-rw-r--r--toolkit/crashreporter/google-breakpad/src/tools/windows/binaries/dump_syms.exebin0 -> 130048 bytes
-rw-r--r--toolkit/crashreporter/google-breakpad/src/tools/windows/binaries/symupload.exebin0 -> 195072 bytes
-rw-r--r--toolkit/crashreporter/google-breakpad/src/tools/windows/converter/ms_symbol_server_converter.cc576
-rw-r--r--toolkit/crashreporter/google-breakpad/src/tools/windows/converter/ms_symbol_server_converter.gyp46
-rw-r--r--toolkit/crashreporter/google-breakpad/src/tools/windows/converter/ms_symbol_server_converter.h219
-rw-r--r--toolkit/crashreporter/google-breakpad/src/tools/windows/dump_syms/dump_syms.cc61
-rw-r--r--toolkit/crashreporter/google-breakpad/src/tools/windows/dump_syms/dump_syms.gyp64
-rw-r--r--toolkit/crashreporter/google-breakpad/src/tools/windows/dump_syms/dump_syms_unittest.cc204
-rw-r--r--toolkit/crashreporter/google-breakpad/src/tools/windows/dump_syms/moz.build31
-rwxr-xr-xtoolkit/crashreporter/google-breakpad/src/tools/windows/dump_syms/run_regtest.sh53
-rw-r--r--toolkit/crashreporter/google-breakpad/src/tools/windows/refresh_binaries.bat27
-rw-r--r--toolkit/crashreporter/google-breakpad/src/tools/windows/symupload/symupload.cc259
-rw-r--r--toolkit/crashreporter/google-breakpad/src/tools/windows/symupload/symupload.gyp45
48 files changed, 9606 insertions, 0 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
new file mode 100644
index 000000000..a0e8f8ba2
--- /dev/null
+++ b/toolkit/crashreporter/google-breakpad/src/tools/linux/core2md/core2md.cc
@@ -0,0 +1,72 @@
+// 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
new file mode 100644
index 000000000..84953172e
--- /dev/null
+++ b/toolkit/crashreporter/google-breakpad/src/tools/linux/dump_syms/dump_syms.cc
@@ -0,0 +1,113 @@
+// 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
new file mode 100644
index 000000000..643020e84
--- /dev/null
+++ b/toolkit/crashreporter/google-breakpad/src/tools/linux/dump_syms/moz.build
@@ -0,0 +1,33 @@
+# -*- 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
new file mode 100644
index 000000000..6f637845e
--- /dev/null
+++ b/toolkit/crashreporter/google-breakpad/src/tools/linux/md2core/minidump-2-core.cc
@@ -0,0 +1,1276 @@
+// 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
new file mode 100644
index 000000000..a793e2cfb
--- /dev/null
+++ b/toolkit/crashreporter/google-breakpad/src/tools/linux/md2core/minidump_memory_range.h
@@ -0,0 +1,89 @@
+// 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
new file mode 100644
index 000000000..fe4ded83d
--- /dev/null
+++ b/toolkit/crashreporter/google-breakpad/src/tools/linux/md2core/minidump_memory_range_unittest.cc
@@ -0,0 +1,258 @@
+// 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
new file mode 100644
index 000000000..19f17450a
--- /dev/null
+++ b/toolkit/crashreporter/google-breakpad/src/tools/linux/symupload/minidump_upload.cc
@@ -0,0 +1,153 @@
+// 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
new file mode 100644
index 000000000..9eeb2d447
--- /dev/null
+++ b/toolkit/crashreporter/google-breakpad/src/tools/linux/symupload/sym_upload.cc
@@ -0,0 +1,112 @@
+// 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
new file mode 100644
index 000000000..1c15992e1
--- /dev/null
+++ b/toolkit/crashreporter/google-breakpad/src/tools/linux/tools_linux.gypi
@@ -0,0 +1,83 @@
+# 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',
+ ],
+ },
+ ],
+}
diff --git a/toolkit/crashreporter/google-breakpad/src/tools/mac/crash_report/crash_report.mm b/toolkit/crashreporter/google-breakpad/src/tools/mac/crash_report/crash_report.mm
new file mode 100644
index 000000000..f68200c7c
--- /dev/null
+++ b/toolkit/crashreporter/google-breakpad/src/tools/mac/crash_report/crash_report.mm
@@ -0,0 +1,408 @@
+// Copyright (c) 2010 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.
+
+// crash_report.mm: Convert the contents of a minidump into a format that
+// looks more like Apple's CrashReporter format
+
+#include <unistd.h>
+
+#include <mach/machine.h>
+#include <mach-o/arch.h>
+
+#include <string>
+
+#include <Foundation/Foundation.h>
+
+#include "common/scoped_ptr.h"
+#include "google_breakpad/processor/basic_source_line_resolver.h"
+#include "google_breakpad/processor/call_stack.h"
+#include "google_breakpad/processor/code_module.h"
+#include "google_breakpad/processor/minidump.h"
+#include "google_breakpad/processor/minidump_processor.h"
+#include "google_breakpad/processor/process_state.h"
+#include "google_breakpad/processor/stack_frame_cpu.h"
+#include "google_breakpad/processor/system_info.h"
+#include "processor/pathname_stripper.h"
+#include "processor/simple_symbol_supplier.h"
+
+#include "on_demand_symbol_supplier.h"
+
+using std::string;
+
+using google_breakpad::BasicSourceLineResolver;
+using google_breakpad::CallStack;
+using google_breakpad::CodeModule;
+using google_breakpad::CodeModules;
+using google_breakpad::Minidump;
+using google_breakpad::MinidumpProcessor;
+using google_breakpad::OnDemandSymbolSupplier;
+using google_breakpad::PathnameStripper;
+using google_breakpad::ProcessState;
+using google_breakpad::scoped_ptr;
+using google_breakpad::StackFrame;
+using google_breakpad::StackFramePPC;
+using google_breakpad::StackFrameX86;
+using google_breakpad::SystemInfo;
+
+typedef struct {
+ NSString *minidumpPath;
+ NSString *searchDir;
+ NSString *symbolSearchDir;
+ BOOL printThreadMemory;
+} Options;
+
+//=============================================================================
+static int PrintRegister(const char *name, u_int32_t value, int sequence) {
+ if (sequence % 4 == 0) {
+ printf("\n");
+ }
+ printf("%6s = 0x%08x ", name, value);
+ return ++sequence;
+}
+
+//=============================================================================
+static void PrintStack(const CallStack *stack, const string &cpu) {
+ size_t frame_count = stack->frames()->size();
+ char buffer[1024];
+ for (size_t frame_index = 0; frame_index < frame_count; ++frame_index) {
+ const StackFrame *frame = stack->frames()->at(frame_index);
+ const CodeModule *module = frame->module;
+ printf("%2zu ", frame_index);
+
+ if (module) {
+ // Module name (20 chars max)
+ strcpy(buffer, PathnameStripper::File(module->code_file()).c_str());
+ int maxStr = 20;
+ buffer[maxStr] = 0;
+ printf("%-*s", maxStr, buffer);
+
+ strcpy(buffer, module->version().c_str());
+ buffer[maxStr] = 0;
+
+ printf("%-*s",maxStr, buffer);
+
+ u_int64_t instruction = frame->instruction;
+
+ // PPC only: Adjust the instruction to match that of Crash reporter. The
+ // instruction listed is actually the return address. See the detailed
+ // comments in stackwalker_ppc.cc for more information.
+ if (cpu == "ppc" && frame_index)
+ instruction += 4;
+
+ printf(" 0x%08llx ", instruction);
+
+ // Function name
+ if (!frame->function_name.empty()) {
+ printf("%s", frame->function_name.c_str());
+ if (!frame->source_file_name.empty()) {
+ string source_file = PathnameStripper::File(frame->source_file_name);
+ printf(" + 0x%llx (%s:%d)",
+ instruction - frame->source_line_base,
+ source_file.c_str(), frame->source_line);
+ } else {
+ printf(" + 0x%llx", instruction - frame->function_base);
+ }
+ }
+ }
+ printf("\n");
+ }
+}
+
+//=============================================================================
+static void PrintRegisters(const CallStack *stack, const string &cpu) {
+ int sequence = 0;
+ const StackFrame *frame = stack->frames()->at(0);
+ if (cpu == "x86") {
+ const StackFrameX86 *frame_x86 =
+ reinterpret_cast<const StackFrameX86*>(frame);
+
+ if (frame_x86->context_validity & StackFrameX86::CONTEXT_VALID_EIP)
+ sequence = PrintRegister("eip", frame_x86->context.eip, sequence);
+ if (frame_x86->context_validity & StackFrameX86::CONTEXT_VALID_ESP)
+ sequence = PrintRegister("esp", frame_x86->context.esp, sequence);
+ if (frame_x86->context_validity & StackFrameX86::CONTEXT_VALID_EBP)
+ sequence = PrintRegister("ebp", frame_x86->context.ebp, sequence);
+ if (frame_x86->context_validity & StackFrameX86::CONTEXT_VALID_EBX)
+ sequence = PrintRegister("ebx", frame_x86->context.ebx, sequence);
+ if (frame_x86->context_validity & StackFrameX86::CONTEXT_VALID_ESI)
+ sequence = PrintRegister("esi", frame_x86->context.esi, sequence);
+ if (frame_x86->context_validity & StackFrameX86::CONTEXT_VALID_EDI)
+ sequence = PrintRegister("edi", frame_x86->context.edi, sequence);
+ if (frame_x86->context_validity == StackFrameX86::CONTEXT_VALID_ALL) {
+ sequence = PrintRegister("eax", frame_x86->context.eax, sequence);
+ sequence = PrintRegister("ecx", frame_x86->context.ecx, sequence);
+ sequence = PrintRegister("edx", frame_x86->context.edx, sequence);
+ sequence = PrintRegister("efl", frame_x86->context.eflags, sequence);
+ }
+ } else if (cpu == "ppc") {
+ const StackFramePPC *frame_ppc =
+ reinterpret_cast<const StackFramePPC*>(frame);
+
+ if ((frame_ppc->context_validity & StackFramePPC::CONTEXT_VALID_ALL) ==
+ StackFramePPC::CONTEXT_VALID_ALL) {
+ sequence = PrintRegister("srr0", frame_ppc->context.srr0, sequence);
+ sequence = PrintRegister("srr1", frame_ppc->context.srr1, sequence);
+ sequence = PrintRegister("cr", frame_ppc->context.cr, sequence);
+ sequence = PrintRegister("xer", frame_ppc->context.xer, sequence);
+ sequence = PrintRegister("lr", frame_ppc->context.lr, sequence);
+ sequence = PrintRegister("ctr", frame_ppc->context.ctr, sequence);
+ sequence = PrintRegister("mq", frame_ppc->context.mq, sequence);
+ sequence = PrintRegister("vrsave", frame_ppc->context.vrsave, sequence);
+
+ sequence = 0;
+ char buffer[5];
+ for (int i = 0; i < MD_CONTEXT_PPC_GPR_COUNT; ++i) {
+ sprintf(buffer, "r%d", i);
+ sequence = PrintRegister(buffer, frame_ppc->context.gpr[i], sequence);
+ }
+ } else {
+ if (frame_ppc->context_validity & StackFramePPC::CONTEXT_VALID_SRR0)
+ sequence = PrintRegister("srr0", frame_ppc->context.srr0, sequence);
+ if (frame_ppc->context_validity & StackFramePPC::CONTEXT_VALID_GPR1)
+ sequence = PrintRegister("r1", frame_ppc->context.gpr[1], sequence);
+ }
+ }
+
+ printf("\n");
+}
+
+static void PrintModules(const CodeModules *modules) {
+ if (!modules)
+ return;
+
+ printf("\n");
+ printf("Loaded modules:\n");
+
+ u_int64_t main_address = 0;
+ const CodeModule *main_module = modules->GetMainModule();
+ if (main_module) {
+ main_address = main_module->base_address();
+ }
+
+ unsigned int module_count = modules->module_count();
+ for (unsigned int module_sequence = 0;
+ module_sequence < module_count;
+ ++module_sequence) {
+ const CodeModule *module = modules->GetModuleAtSequence(module_sequence);
+ assert(module);
+ u_int64_t base_address = module->base_address();
+ printf("0x%08llx - 0x%08llx %s %s%s %s\n",
+ base_address, base_address + module->size() - 1,
+ PathnameStripper::File(module->code_file()).c_str(),
+ module->version().empty() ? "???" : module->version().c_str(),
+ main_module != NULL && base_address == main_address ?
+ " (main)" : "",
+ module->code_file().c_str());
+ }
+}
+
+static void ProcessSingleReport(Options *options, NSString *file_path) {
+ string minidump_file([file_path fileSystemRepresentation]);
+ BasicSourceLineResolver resolver;
+ string search_dir = options->searchDir ?
+ [options->searchDir fileSystemRepresentation] : "";
+ string symbol_search_dir = options->symbolSearchDir ?
+ [options->symbolSearchDir fileSystemRepresentation] : "";
+ scoped_ptr<OnDemandSymbolSupplier> symbol_supplier(
+ new OnDemandSymbolSupplier(search_dir, symbol_search_dir));
+ scoped_ptr<MinidumpProcessor>
+ minidump_processor(new MinidumpProcessor(symbol_supplier.get(), &resolver));
+ ProcessState process_state;
+ scoped_ptr<Minidump> dump(new google_breakpad::Minidump(minidump_file));
+
+ if (!dump->Read()) {
+ fprintf(stderr, "Minidump %s could not be read\n", dump->path().c_str());
+ return;
+ }
+ if (minidump_processor->Process(dump.get(), &process_state) !=
+ google_breakpad::PROCESS_OK) {
+ fprintf(stderr, "MinidumpProcessor::Process failed\n");
+ return;
+ }
+
+ const SystemInfo *system_info = process_state.system_info();
+ string cpu = system_info->cpu;
+
+ // Convert the time to a string
+ u_int32_t time_date_stamp = process_state.time_date_stamp();
+ struct tm timestruct;
+ gmtime_r(reinterpret_cast<time_t*>(&time_date_stamp), &timestruct);
+ char timestr[20];
+ strftime(timestr, 20, "%Y-%m-%d %H:%M:%S", &timestruct);
+ printf("Date: %s GMT\n", timestr);
+
+ printf("Operating system: %s (%s)\n", system_info->os.c_str(),
+ system_info->os_version.c_str());
+ printf("Architecture: %s\n", cpu.c_str());
+
+ if (process_state.crashed()) {
+ printf("Crash reason: %s\n", process_state.crash_reason().c_str());
+ printf("Crash address: 0x%llx\n", process_state.crash_address());
+ } else {
+ printf("No crash\n");
+ }
+
+ int requesting_thread = process_state.requesting_thread();
+ if (requesting_thread != -1) {
+ printf("\n");
+ printf("Thread %d (%s)\n",
+ requesting_thread,
+ process_state.crashed() ? "crashed" :
+ "requested dump, did not crash");
+ PrintStack(process_state.threads()->at(requesting_thread), cpu);
+ }
+
+ // Print all of the threads in the dump.
+ int thread_count = static_cast<int>(process_state.threads()->size());
+ const std::vector<google_breakpad::MemoryRegion*>
+ *thread_memory_regions = process_state.thread_memory_regions();
+
+ for (int thread_index = 0; thread_index < thread_count; ++thread_index) {
+ if (thread_index != requesting_thread) {
+ // Don't print the crash thread again, it was already printed.
+ printf("\n");
+ printf("Thread %d\n", thread_index);
+ PrintStack(process_state.threads()->at(thread_index), cpu);
+ google_breakpad::MemoryRegion *thread_stack_bytes =
+ thread_memory_regions->at(thread_index);
+ if (options->printThreadMemory) {
+ thread_stack_bytes->Print();
+ }
+ }
+ }
+
+ // Print the crashed registers
+ if (requesting_thread != -1) {
+ printf("\nThread %d:", requesting_thread);
+ PrintRegisters(process_state.threads()->at(requesting_thread), cpu);
+ }
+
+ // Print information about modules
+ PrintModules(process_state.modules());
+}
+
+//=============================================================================
+static void Start(Options *options) {
+ NSFileManager *manager = [NSFileManager defaultManager];
+ NSString *minidump_path = options->minidumpPath;
+ BOOL is_dir = NO;
+ BOOL file_exists = [manager fileExistsAtPath:minidump_path
+ isDirectory:&is_dir];
+ if (file_exists && is_dir) {
+ NSDirectoryEnumerator *enumerator =
+ [manager enumeratorAtPath:minidump_path];
+ NSString *current_file = nil;
+ while ((current_file = [enumerator nextObject])) {
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+ if ([[current_file pathExtension] isEqualTo:@"dmp"]) {
+ printf("Attempting to process report: %s\n",
+ [current_file cStringUsingEncoding:NSASCIIStringEncoding]);
+ NSString *full_path =
+ [minidump_path stringByAppendingPathComponent:current_file];
+ ProcessSingleReport(options, full_path);
+ }
+ [pool release];
+ }
+ } else if (file_exists) {
+ ProcessSingleReport(options, minidump_path);
+ }
+}
+
+//=============================================================================
+static void Usage(int argc, const char *argv[]) {
+ fprintf(stderr, "Convert a minidump to a crash report. Breakpad symbol "
+ "files will be used (or created if missing) in /tmp.\n"
+ "If a symbol-file-search-dir is specified, any symbol "
+ "files in it will be used instead of being loaded from "
+ "modules on disk.\n"
+ "If modules cannot be found at the paths stored in the "
+ "minidump file, they will be searched for at "
+ "<module-search-dir>/<path-in-minidump-file>.\n");
+ fprintf(stderr, "Usage: %s [-s module-search-dir] [-S symbol-file-search-dir] "
+ "minidump-file\n", argv[0]);
+ fprintf(stderr, "\t-s: Specify a search directory to use for missing modules\n"
+ "\t-S: Specify a search directory to use for symbol files\n"
+ "\t-t: Print thread stack memory in hex\n"
+ "\t-h: Usage\n"
+ "\t-?: Usage\n");
+}
+
+//=============================================================================
+static void SetupOptions(int argc, const char *argv[], Options *options) {
+ extern int optind;
+ char ch;
+
+ while ((ch = getopt(argc, (char * const *)argv, "S:s:ht?")) != -1) {
+ switch (ch) {
+ case 's':
+ options->searchDir = [[NSFileManager defaultManager]
+ stringWithFileSystemRepresentation:optarg
+ length:strlen(optarg)];
+ break;
+
+ case 'S':
+ options->symbolSearchDir = [[NSFileManager defaultManager]
+ stringWithFileSystemRepresentation:optarg
+ length:strlen(optarg)];
+ break;
+
+ case 't':
+ options->printThreadMemory = YES;
+ break;
+ case 'h':
+ case '?':
+ Usage(argc, argv);
+ exit(1);
+ break;
+ }
+ }
+
+ if ((argc - optind) != 1) {
+ fprintf(stderr, "%s: Missing minidump file\n", argv[0]);
+ Usage(argc, argv);
+ exit(1);
+ }
+
+ options->minidumpPath = [[NSFileManager defaultManager]
+ stringWithFileSystemRepresentation:argv[optind]
+ length:strlen(argv[optind])];
+}
+
+//=============================================================================
+int main (int argc, const char * argv[]) {
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+ Options options;
+
+ bzero(&options, sizeof(Options));
+ SetupOptions(argc, argv, &options);
+ Start(&options);
+ [pool release];
+
+ return 0;
+}
diff --git a/toolkit/crashreporter/google-breakpad/src/tools/mac/crash_report/crash_report.xcodeproj/project.pbxproj b/toolkit/crashreporter/google-breakpad/src/tools/mac/crash_report/crash_report.xcodeproj/project.pbxproj
new file mode 100644
index 000000000..d32837cbd
--- /dev/null
+++ b/toolkit/crashreporter/google-breakpad/src/tools/mac/crash_report/crash_report.xcodeproj/project.pbxproj
@@ -0,0 +1,587 @@
+// !$*UTF8*$!
+{
+ archiveVersion = 1;
+ classes = {
+ };
+ objectVersion = 45;
+ objects = {
+
+/* Begin PBXBuildFile section */
+ 162F64FE161C5ECB00CD68D5 /* arch_utilities.cc in Sources */ = {isa = PBXBuildFile; fileRef = 162F64FC161C5ECB00CD68D5 /* arch_utilities.cc */; };
+ 4D2C721B126F9ACC00B43EAF /* source_line_resolver_base.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4D2C721A126F9ACC00B43EAF /* source_line_resolver_base.cc */; };
+ 4D2C721F126F9ADE00B43EAF /* exploitability.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4D2C721E126F9ADE00B43EAF /* exploitability.cc */; };
+ 4D2C7223126F9AF900B43EAF /* exploitability_win.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4D2C7222126F9AF900B43EAF /* exploitability_win.cc */; };
+ 4D2C7227126F9B0F00B43EAF /* disassembler_x86.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4D2C7226126F9B0F00B43EAF /* disassembler_x86.cc */; };
+ 4D2C722B126F9B5A00B43EAF /* x86_disasm.c in Sources */ = {isa = PBXBuildFile; fileRef = 4D2C722A126F9B5A00B43EAF /* x86_disasm.c */; };
+ 4D2C722D126F9B6E00B43EAF /* x86_misc.c in Sources */ = {isa = PBXBuildFile; fileRef = 4D2C722C126F9B6E00B43EAF /* x86_misc.c */; };
+ 4D2C722F126F9B8300B43EAF /* x86_operand_list.c in Sources */ = {isa = PBXBuildFile; fileRef = 4D2C722E126F9B8300B43EAF /* x86_operand_list.c */; };
+ 4D2C7233126F9BB000B43EAF /* ia32_invariant.c in Sources */ = {isa = PBXBuildFile; fileRef = 4D2C7232126F9BB000B43EAF /* ia32_invariant.c */; settings = {COMPILER_FLAGS = "-Wno-error"; }; };
+ 4D2C7235126F9BC200B43EAF /* ia32_settings.c in Sources */ = {isa = PBXBuildFile; fileRef = 4D2C7234126F9BC200B43EAF /* ia32_settings.c */; };
+ 4D2C7246126F9C0B00B43EAF /* ia32_insn.c in Sources */ = {isa = PBXBuildFile; fileRef = 4D2C7245126F9C0B00B43EAF /* ia32_insn.c */; };
+ 4D2C724A126F9C2300B43EAF /* ia32_opcode_tables.c in Sources */ = {isa = PBXBuildFile; fileRef = 4D2C7249126F9C2300B43EAF /* ia32_opcode_tables.c */; settings = {COMPILER_FLAGS = "-Wno-error"; }; };
+ 4D2C724C126F9C3800B43EAF /* ia32_implicit.c in Sources */ = {isa = PBXBuildFile; fileRef = 4D2C724B126F9C3800B43EAF /* ia32_implicit.c */; settings = {COMPILER_FLAGS = "-Wno-error"; }; };
+ 4D2C724E126F9C4D00B43EAF /* ia32_reg.c in Sources */ = {isa = PBXBuildFile; fileRef = 4D2C724D126F9C4D00B43EAF /* ia32_reg.c */; settings = {COMPILER_FLAGS = "-Wno-error"; }; };
+ 4D2C725B126F9C8000B43EAF /* ia32_operand.c in Sources */ = {isa = PBXBuildFile; fileRef = 4D2C725A126F9C8000B43EAF /* ia32_operand.c */; };
+ 4D2C725D126F9C9200B43EAF /* x86_insn.c in Sources */ = {isa = PBXBuildFile; fileRef = 4D2C725C126F9C9200B43EAF /* x86_insn.c */; };
+ 4D2C7264126F9CBB00B43EAF /* ia32_modrm.c in Sources */ = {isa = PBXBuildFile; fileRef = 4D2C7261126F9CBB00B43EAF /* ia32_modrm.c */; };
+ 4D2C726D126F9CDC00B43EAF /* x86_imm.c in Sources */ = {isa = PBXBuildFile; fileRef = 4D2C7263126F9CBB00B43EAF /* x86_imm.c */; };
+ 4D72CA5713DFBA84006CABE3 /* md5.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4D72CA5613DFBA84006CABE3 /* md5.cc */; };
+ 557800400BE1F28500EC23E0 /* macho_utilities.cc in Sources */ = {isa = PBXBuildFile; fileRef = 5578003E0BE1F28500EC23E0 /* macho_utilities.cc */; };
+ 8B31FF2A11F0C62700FCF3E4 /* dwarf_cfi_to_module.cc in Sources */ = {isa = PBXBuildFile; fileRef = 8B31FF2411F0C62700FCF3E4 /* dwarf_cfi_to_module.cc */; };
+ 8B31FF2B11F0C62700FCF3E4 /* dwarf_cu_to_module.cc in Sources */ = {isa = PBXBuildFile; fileRef = 8B31FF2611F0C62700FCF3E4 /* dwarf_cu_to_module.cc */; };
+ 8B31FF2C11F0C62700FCF3E4 /* dwarf_line_to_module.cc in Sources */ = {isa = PBXBuildFile; fileRef = 8B31FF2811F0C62700FCF3E4 /* dwarf_line_to_module.cc */; };
+ 8B31FF4111F0C64400FCF3E4 /* stabs_reader.cc in Sources */ = {isa = PBXBuildFile; fileRef = 8B31FF3D11F0C64400FCF3E4 /* stabs_reader.cc */; };
+ 8B31FF4211F0C64400FCF3E4 /* stabs_to_module.cc in Sources */ = {isa = PBXBuildFile; fileRef = 8B31FF3F11F0C64400FCF3E4 /* stabs_to_module.cc */; };
+ 8B31FF7411F0C6E000FCF3E4 /* macho_reader.cc in Sources */ = {isa = PBXBuildFile; fileRef = 8B31FF7211F0C6E000FCF3E4 /* macho_reader.cc */; };
+ 8B31FF8811F0C6FB00FCF3E4 /* language.cc in Sources */ = {isa = PBXBuildFile; fileRef = 8B31FF8411F0C6FB00FCF3E4 /* language.cc */; };
+ 8B31FF8911F0C6FB00FCF3E4 /* module.cc in Sources */ = {isa = PBXBuildFile; fileRef = 8B31FF8611F0C6FB00FCF3E4 /* module.cc */; };
+ 8B31FFC511F0C8AB00FCF3E4 /* dwarf2diehandler.cc in Sources */ = {isa = PBXBuildFile; fileRef = 8B31FFC311F0C8AB00FCF3E4 /* dwarf2diehandler.cc */; };
+ 8B40BDC00C0638E4009535AF /* logging.cc in Sources */ = {isa = PBXBuildFile; fileRef = 8B40BDBF0C0638E4009535AF /* logging.cc */; };
+ 8DD76F9A0486AA7600D96B5E /* crash_report.mm in Sources */ = {isa = PBXBuildFile; fileRef = 08FB7796FE84155DC02AAC07 /* crash_report.mm */; settings = {ATTRIBUTES = (); }; };
+ 8DD76F9C0486AA7600D96B5E /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 08FB779EFE84155DC02AAC07 /* Foundation.framework */; };
+ 9B35FEEA0B26761C008DE8C7 /* basic_code_modules.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9B35FEE70B26761C008DE8C7 /* basic_code_modules.cc */; };
+ 9B3904990B2E52FD0059FABE /* basic_source_line_resolver.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9B3904980B2E52FD0059FABE /* basic_source_line_resolver.cc */; };
+ 9BDF172C0B1B8B2400F8391B /* call_stack.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9BDF172A0B1B8B2400F8391B /* call_stack.cc */; };
+ 9BDF172D0B1B8B2400F8391B /* minidump_processor.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9BDF172B0B1B8B2400F8391B /* minidump_processor.cc */; };
+ 9BDF17410B1B8B9A00F8391B /* minidump.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9BDF173F0B1B8B9A00F8391B /* minidump.cc */; };
+ 9BDF17540B1B8BF900F8391B /* stackwalker_ppc.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9BDF17510B1B8BF900F8391B /* stackwalker_ppc.cc */; };
+ 9BDF17550B1B8BF900F8391B /* stackwalker_x86.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9BDF17520B1B8BF900F8391B /* stackwalker_x86.cc */; };
+ 9BDF17560B1B8BF900F8391B /* stackwalker.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9BDF17530B1B8BF900F8391B /* stackwalker.cc */; };
+ 9BDF175D0B1B8C1B00F8391B /* process_state.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9BDF175B0B1B8C1B00F8391B /* process_state.cc */; };
+ 9BDF176E0B1B8CB100F8391B /* on_demand_symbol_supplier.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9BDF176C0B1B8CB100F8391B /* on_demand_symbol_supplier.mm */; };
+ 9BDF1A280B1BD58200F8391B /* pathname_stripper.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9BDF1A270B1BD58200F8391B /* pathname_stripper.cc */; };
+ 9BDF21A70B1E825400F8391B /* dump_syms.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9BDF192E0B1BC15D00F8391B /* dump_syms.mm */; };
+ 9BE650B20B52FE3000611104 /* file_id.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9BE650AC0B52FE3000611104 /* file_id.cc */; };
+ 9BE650B40B52FE3000611104 /* macho_id.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9BE650AE0B52FE3000611104 /* macho_id.cc */; };
+ 9BE650B60B52FE3000611104 /* macho_walker.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9BE650B00B52FE3000611104 /* macho_walker.cc */; };
+ D2A5DD4D1188651100081F03 /* cfi_frame_info.cc in Sources */ = {isa = PBXBuildFile; fileRef = D2A5DD4C1188651100081F03 /* cfi_frame_info.cc */; };
+ D2A5DD631188658B00081F03 /* tokenize.cc in Sources */ = {isa = PBXBuildFile; fileRef = D2A5DD621188658B00081F03 /* tokenize.cc */; };
+ F407DC48185773C10064622B /* exploitability_linux.cc in Sources */ = {isa = PBXBuildFile; fileRef = F407DC40185773C10064622B /* exploitability_linux.cc */; };
+ F407DC49185773C10064622B /* stack_frame_symbolizer.cc in Sources */ = {isa = PBXBuildFile; fileRef = F407DC41185773C10064622B /* stack_frame_symbolizer.cc */; };
+ F407DC4A185773C10064622B /* stackwalker_arm64.cc in Sources */ = {isa = PBXBuildFile; fileRef = F407DC42185773C10064622B /* stackwalker_arm64.cc */; };
+ F407DC4B185773C10064622B /* stackwalker_mips.cc in Sources */ = {isa = PBXBuildFile; fileRef = F407DC44185773C10064622B /* stackwalker_mips.cc */; };
+ F407DC4C185773C10064622B /* stackwalker_ppc64.cc in Sources */ = {isa = PBXBuildFile; fileRef = F407DC46185773C10064622B /* stackwalker_ppc64.cc */; };
+ F44DDD8719C85CD50047280E /* dump_context.cc in Sources */ = {isa = PBXBuildFile; fileRef = F44DDD8419C85CD50047280E /* dump_context.cc */; };
+ F44DDD8819C85CD50047280E /* dump_object.cc in Sources */ = {isa = PBXBuildFile; fileRef = F44DDD8519C85CD50047280E /* dump_object.cc */; };
+ F44DDD8919C85CD50047280E /* microdump_processor.cc in Sources */ = {isa = PBXBuildFile; fileRef = F44DDD8619C85CD50047280E /* microdump_processor.cc */; };
+ F4D43B2F1A38490700C290B2 /* microdump.cc in Sources */ = {isa = PBXBuildFile; fileRef = F4D43B2E1A38490700C290B2 /* microdump.cc */; };
+ F9C7ECE50E8ABCA600E953AD /* bytereader.cc in Sources */ = {isa = PBXBuildFile; fileRef = F9C7ECE20E8ABCA600E953AD /* bytereader.cc */; };
+ F9C7ECE60E8ABCA600E953AD /* dwarf2reader.cc in Sources */ = {isa = PBXBuildFile; fileRef = F9C7ECE30E8ABCA600E953AD /* dwarf2reader.cc */; };
+ F9C7ECE70E8ABCA600E953AD /* functioninfo.cc in Sources */ = {isa = PBXBuildFile; fileRef = F9C7ECE40E8ABCA600E953AD /* functioninfo.cc */; };
+ F9F0706710FBC02D0037B88B /* stackwalker_arm.cc in Sources */ = {isa = PBXBuildFile; fileRef = F9F0706510FBC02D0037B88B /* stackwalker_arm.cc */; };
+ FD6625CD0CF4D45C004AC844 /* stackwalker_amd64.cc in Sources */ = {isa = PBXBuildFile; fileRef = FD6625C40CF4D438004AC844 /* stackwalker_amd64.cc */; };
+ FD8EDEAE0CADDAD400A5EDF1 /* stackwalker_sparc.cc in Sources */ = {isa = PBXBuildFile; fileRef = FD8EDEAC0CADDAD400A5EDF1 /* stackwalker_sparc.cc */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXFileReference section */
+ 08FB7796FE84155DC02AAC07 /* crash_report.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = crash_report.mm; sourceTree = "<group>"; };
+ 08FB779EFE84155DC02AAC07 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
+ 162F64FC161C5ECB00CD68D5 /* arch_utilities.cc */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = arch_utilities.cc; path = ../../../common/mac/arch_utilities.cc; sourceTree = "<group>"; };
+ 162F64FD161C5ECB00CD68D5 /* arch_utilities.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = arch_utilities.h; path = ../../../common/mac/arch_utilities.h; sourceTree = "<group>"; };
+ 4D2C721A126F9ACC00B43EAF /* source_line_resolver_base.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = source_line_resolver_base.cc; path = ../../../processor/source_line_resolver_base.cc; sourceTree = SOURCE_ROOT; };
+ 4D2C721E126F9ADE00B43EAF /* exploitability.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = exploitability.cc; path = ../../../processor/exploitability.cc; sourceTree = SOURCE_ROOT; };
+ 4D2C7222126F9AF900B43EAF /* exploitability_win.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = exploitability_win.cc; path = ../../../processor/exploitability_win.cc; sourceTree = SOURCE_ROOT; };
+ 4D2C7226126F9B0F00B43EAF /* disassembler_x86.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = disassembler_x86.cc; path = ../../../processor/disassembler_x86.cc; sourceTree = SOURCE_ROOT; };
+ 4D2C722A126F9B5A00B43EAF /* x86_disasm.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = x86_disasm.c; path = ../../../third_party/libdisasm/x86_disasm.c; sourceTree = SOURCE_ROOT; };
+ 4D2C722C126F9B6E00B43EAF /* x86_misc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = x86_misc.c; path = ../../../third_party/libdisasm/x86_misc.c; sourceTree = SOURCE_ROOT; };
+ 4D2C722E126F9B8300B43EAF /* x86_operand_list.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = x86_operand_list.c; path = ../../../third_party/libdisasm/x86_operand_list.c; sourceTree = SOURCE_ROOT; };
+ 4D2C7232126F9BB000B43EAF /* ia32_invariant.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = ia32_invariant.c; path = ../../../third_party/libdisasm/ia32_invariant.c; sourceTree = SOURCE_ROOT; };
+ 4D2C7234126F9BC200B43EAF /* ia32_settings.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = ia32_settings.c; path = ../../../third_party/libdisasm/ia32_settings.c; sourceTree = SOURCE_ROOT; };
+ 4D2C7245126F9C0B00B43EAF /* ia32_insn.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = ia32_insn.c; path = ../../../third_party/libdisasm/ia32_insn.c; sourceTree = SOURCE_ROOT; };
+ 4D2C7249126F9C2300B43EAF /* ia32_opcode_tables.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = ia32_opcode_tables.c; path = ../../../third_party/libdisasm/ia32_opcode_tables.c; sourceTree = SOURCE_ROOT; };
+ 4D2C724B126F9C3800B43EAF /* ia32_implicit.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = ia32_implicit.c; path = ../../../third_party/libdisasm/ia32_implicit.c; sourceTree = SOURCE_ROOT; };
+ 4D2C724D126F9C4D00B43EAF /* ia32_reg.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = ia32_reg.c; path = ../../../third_party/libdisasm/ia32_reg.c; sourceTree = SOURCE_ROOT; };
+ 4D2C725A126F9C8000B43EAF /* ia32_operand.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = ia32_operand.c; path = ../../../third_party/libdisasm/ia32_operand.c; sourceTree = SOURCE_ROOT; };
+ 4D2C725C126F9C9200B43EAF /* x86_insn.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = x86_insn.c; path = ../../../third_party/libdisasm/x86_insn.c; sourceTree = SOURCE_ROOT; };
+ 4D2C7261126F9CBB00B43EAF /* ia32_modrm.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = ia32_modrm.c; path = ../../../third_party/libdisasm/ia32_modrm.c; sourceTree = SOURCE_ROOT; };
+ 4D2C7263126F9CBB00B43EAF /* x86_imm.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = x86_imm.c; path = ../../../third_party/libdisasm/x86_imm.c; sourceTree = SOURCE_ROOT; };
+ 4D72CA5613DFBA84006CABE3 /* md5.cc */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = md5.cc; path = ../../../common/md5.cc; sourceTree = SOURCE_ROOT; };
+ 5578003E0BE1F28500EC23E0 /* macho_utilities.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = macho_utilities.cc; path = ../../../common/mac/macho_utilities.cc; sourceTree = SOURCE_ROOT; };
+ 5578003F0BE1F28500EC23E0 /* macho_utilities.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = macho_utilities.h; path = ../../../common/mac/macho_utilities.h; sourceTree = SOURCE_ROOT; };
+ 8B31025311F0D2D400FCF3E4 /* Breakpad.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Breakpad.xcconfig; path = ../../../common/mac/Breakpad.xcconfig; sourceTree = SOURCE_ROOT; };
+ 8B3102DA11F0D65600FCF3E4 /* BreakpadDebug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = BreakpadDebug.xcconfig; path = ../../../common/mac/BreakpadDebug.xcconfig; sourceTree = SOURCE_ROOT; };
+ 8B3102DB11F0D65600FCF3E4 /* BreakpadRelease.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = BreakpadRelease.xcconfig; path = ../../../common/mac/BreakpadRelease.xcconfig; sourceTree = SOURCE_ROOT; };
+ 8B31FF2411F0C62700FCF3E4 /* dwarf_cfi_to_module.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = dwarf_cfi_to_module.cc; path = ../../../common/dwarf_cfi_to_module.cc; sourceTree = SOURCE_ROOT; };
+ 8B31FF2511F0C62700FCF3E4 /* dwarf_cfi_to_module.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = dwarf_cfi_to_module.h; path = ../../../common/dwarf_cfi_to_module.h; sourceTree = SOURCE_ROOT; };
+ 8B31FF2611F0C62700FCF3E4 /* dwarf_cu_to_module.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = dwarf_cu_to_module.cc; path = ../../../common/dwarf_cu_to_module.cc; sourceTree = SOURCE_ROOT; };
+ 8B31FF2711F0C62700FCF3E4 /* dwarf_cu_to_module.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = dwarf_cu_to_module.h; path = ../../../common/dwarf_cu_to_module.h; sourceTree = SOURCE_ROOT; };
+ 8B31FF2811F0C62700FCF3E4 /* dwarf_line_to_module.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = dwarf_line_to_module.cc; path = ../../../common/dwarf_line_to_module.cc; sourceTree = SOURCE_ROOT; };
+ 8B31FF2911F0C62700FCF3E4 /* dwarf_line_to_module.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = dwarf_line_to_module.h; path = ../../../common/dwarf_line_to_module.h; sourceTree = SOURCE_ROOT; };
+ 8B31FF3D11F0C64400FCF3E4 /* stabs_reader.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = stabs_reader.cc; path = ../../../common/stabs_reader.cc; sourceTree = SOURCE_ROOT; };
+ 8B31FF3E11F0C64400FCF3E4 /* stabs_reader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = stabs_reader.h; path = ../../../common/stabs_reader.h; sourceTree = SOURCE_ROOT; };
+ 8B31FF3F11F0C64400FCF3E4 /* stabs_to_module.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = stabs_to_module.cc; path = ../../../common/stabs_to_module.cc; sourceTree = SOURCE_ROOT; };
+ 8B31FF4011F0C64400FCF3E4 /* stabs_to_module.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = stabs_to_module.h; path = ../../../common/stabs_to_module.h; sourceTree = SOURCE_ROOT; };
+ 8B31FF7211F0C6E000FCF3E4 /* macho_reader.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = macho_reader.cc; path = ../../../common/mac/macho_reader.cc; sourceTree = SOURCE_ROOT; };
+ 8B31FF7311F0C6E000FCF3E4 /* macho_reader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = macho_reader.h; path = ../../../common/mac/macho_reader.h; sourceTree = SOURCE_ROOT; };
+ 8B31FF8411F0C6FB00FCF3E4 /* language.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = language.cc; path = ../../../common/language.cc; sourceTree = SOURCE_ROOT; };
+ 8B31FF8511F0C6FB00FCF3E4 /* language.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = language.h; path = ../../../common/language.h; sourceTree = SOURCE_ROOT; };
+ 8B31FF8611F0C6FB00FCF3E4 /* module.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = module.cc; path = ../../../common/module.cc; sourceTree = SOURCE_ROOT; };
+ 8B31FF8711F0C6FB00FCF3E4 /* module.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = module.h; path = ../../../common/module.h; sourceTree = SOURCE_ROOT; };
+ 8B31FFC311F0C8AB00FCF3E4 /* dwarf2diehandler.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = dwarf2diehandler.cc; path = ../../../common/dwarf/dwarf2diehandler.cc; sourceTree = SOURCE_ROOT; };
+ 8B31FFC411F0C8AB00FCF3E4 /* dwarf2diehandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = dwarf2diehandler.h; path = ../../../common/dwarf/dwarf2diehandler.h; sourceTree = SOURCE_ROOT; };
+ 8B40BDBF0C0638E4009535AF /* logging.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = logging.cc; path = ../../../processor/logging.cc; sourceTree = SOURCE_ROOT; };
+ 8DD76FA10486AA7600D96B5E /* crash_report */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = crash_report; sourceTree = BUILT_PRODUCTS_DIR; };
+ 9B35FEE20B2675F9008DE8C7 /* code_module.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = code_module.h; path = ../../../google_breakpad/processor/code_module.h; sourceTree = SOURCE_ROOT; };
+ 9B35FEE30B2675F9008DE8C7 /* code_modules.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = code_modules.h; path = ../../../google_breakpad/processor/code_modules.h; sourceTree = SOURCE_ROOT; };
+ 9B35FEE60B26761C008DE8C7 /* basic_code_module.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = basic_code_module.h; path = ../../../processor/basic_code_module.h; sourceTree = SOURCE_ROOT; };
+ 9B35FEE70B26761C008DE8C7 /* basic_code_modules.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = basic_code_modules.cc; path = ../../../processor/basic_code_modules.cc; sourceTree = SOURCE_ROOT; };
+ 9B35FEE80B26761C008DE8C7 /* basic_code_modules.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = basic_code_modules.h; path = ../../../processor/basic_code_modules.h; sourceTree = SOURCE_ROOT; };
+ 9B3904940B2E52D90059FABE /* basic_source_line_resolver.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = basic_source_line_resolver.h; sourceTree = "<group>"; };
+ 9B3904950B2E52D90059FABE /* source_line_resolver_interface.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = source_line_resolver_interface.h; sourceTree = "<group>"; };
+ 9B3904980B2E52FD0059FABE /* basic_source_line_resolver.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = basic_source_line_resolver.cc; path = ../../../processor/basic_source_line_resolver.cc; sourceTree = SOURCE_ROOT; };
+ 9B44619D0B66C66B00BBB817 /* system_info.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = system_info.h; sourceTree = "<group>"; };
+ 9BDF16F90B1B8ACD00F8391B /* breakpad_types.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = breakpad_types.h; sourceTree = "<group>"; };
+ 9BDF16FA0B1B8ACD00F8391B /* minidump_format.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = minidump_format.h; sourceTree = "<group>"; };
+ 9BDF16FC0B1B8ACD00F8391B /* call_stack.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = call_stack.h; sourceTree = "<group>"; };
+ 9BDF16FD0B1B8ACD00F8391B /* memory_region.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = memory_region.h; sourceTree = "<group>"; };
+ 9BDF16FE0B1B8ACD00F8391B /* minidump.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = minidump.h; sourceTree = "<group>"; };
+ 9BDF16FF0B1B8ACD00F8391B /* minidump_processor.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = minidump_processor.h; sourceTree = "<group>"; };
+ 9BDF17000B1B8ACD00F8391B /* process_state.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = process_state.h; sourceTree = "<group>"; };
+ 9BDF17010B1B8ACD00F8391B /* stack_frame.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = stack_frame.h; sourceTree = "<group>"; };
+ 9BDF17020B1B8ACD00F8391B /* stack_frame_cpu.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = stack_frame_cpu.h; sourceTree = "<group>"; };
+ 9BDF17030B1B8ACD00F8391B /* stackwalker.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = stackwalker.h; sourceTree = "<group>"; };
+ 9BDF17040B1B8ACD00F8391B /* symbol_supplier.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = symbol_supplier.h; sourceTree = "<group>"; };
+ 9BDF172A0B1B8B2400F8391B /* call_stack.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = call_stack.cc; path = ../../../processor/call_stack.cc; sourceTree = SOURCE_ROOT; };
+ 9BDF172B0B1B8B2400F8391B /* minidump_processor.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = minidump_processor.cc; path = ../../../processor/minidump_processor.cc; sourceTree = SOURCE_ROOT; };
+ 9BDF173F0B1B8B9A00F8391B /* minidump.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = minidump.cc; path = ../../../processor/minidump.cc; sourceTree = SOURCE_ROOT; };
+ 9BDF17510B1B8BF900F8391B /* stackwalker_ppc.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = stackwalker_ppc.cc; path = ../../../processor/stackwalker_ppc.cc; sourceTree = SOURCE_ROOT; };
+ 9BDF17520B1B8BF900F8391B /* stackwalker_x86.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = stackwalker_x86.cc; path = ../../../processor/stackwalker_x86.cc; sourceTree = SOURCE_ROOT; };
+ 9BDF17530B1B8BF900F8391B /* stackwalker.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = stackwalker.cc; path = ../../../processor/stackwalker.cc; sourceTree = SOURCE_ROOT; };
+ 9BDF175B0B1B8C1B00F8391B /* process_state.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = process_state.cc; path = ../../../processor/process_state.cc; sourceTree = SOURCE_ROOT; };
+ 9BDF176B0B1B8CB100F8391B /* on_demand_symbol_supplier.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = on_demand_symbol_supplier.h; sourceTree = "<group>"; };
+ 9BDF176C0B1B8CB100F8391B /* on_demand_symbol_supplier.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = on_demand_symbol_supplier.mm; sourceTree = "<group>"; };
+ 9BDF192D0B1BC15D00F8391B /* dump_syms.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = dump_syms.h; path = ../../../common/mac/dump_syms.h; sourceTree = SOURCE_ROOT; };
+ 9BDF192E0B1BC15D00F8391B /* dump_syms.mm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.objcpp; name = dump_syms.mm; path = ../../../common/mac/dump_syms.mm; sourceTree = SOURCE_ROOT; };
+ 9BDF1A270B1BD58200F8391B /* pathname_stripper.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = pathname_stripper.cc; path = ../../../processor/pathname_stripper.cc; sourceTree = SOURCE_ROOT; };
+ 9BDF1A7A0B1BE30100F8391B /* range_map-inl.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = "range_map-inl.h"; path = "../../../processor/range_map-inl.h"; sourceTree = SOURCE_ROOT; };
+ 9BDF1A7B0B1BE30100F8391B /* range_map.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = range_map.h; path = ../../../processor/range_map.h; sourceTree = SOURCE_ROOT; };
+ 9BDF1AFA0B1BEB6300F8391B /* address_map-inl.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = "address_map-inl.h"; path = "../../../processor/address_map-inl.h"; sourceTree = SOURCE_ROOT; };
+ 9BDF1AFB0B1BEB6300F8391B /* address_map.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = address_map.h; path = ../../../processor/address_map.h; sourceTree = SOURCE_ROOT; };
+ 9BE650AC0B52FE3000611104 /* file_id.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = file_id.cc; path = ../../../common/mac/file_id.cc; sourceTree = SOURCE_ROOT; };
+ 9BE650AD0B52FE3000611104 /* file_id.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = file_id.h; path = ../../../common/mac/file_id.h; sourceTree = SOURCE_ROOT; };
+ 9BE650AE0B52FE3000611104 /* macho_id.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = macho_id.cc; path = ../../../common/mac/macho_id.cc; sourceTree = SOURCE_ROOT; };
+ 9BE650AF0B52FE3000611104 /* macho_id.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = macho_id.h; path = ../../../common/mac/macho_id.h; sourceTree = SOURCE_ROOT; };
+ 9BE650B00B52FE3000611104 /* macho_walker.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = macho_walker.cc; path = ../../../common/mac/macho_walker.cc; sourceTree = SOURCE_ROOT; };
+ 9BE650B10B52FE3000611104 /* macho_walker.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = macho_walker.h; path = ../../../common/mac/macho_walker.h; sourceTree = SOURCE_ROOT; };
+ D2A5DD4C1188651100081F03 /* cfi_frame_info.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = cfi_frame_info.cc; path = ../../../processor/cfi_frame_info.cc; sourceTree = SOURCE_ROOT; };
+ D2A5DD621188658B00081F03 /* tokenize.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = tokenize.cc; path = ../../../processor/tokenize.cc; sourceTree = SOURCE_ROOT; };
+ F407DC40185773C10064622B /* exploitability_linux.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = exploitability_linux.cc; path = ../../../processor/exploitability_linux.cc; sourceTree = "<group>"; };
+ F407DC41185773C10064622B /* stack_frame_symbolizer.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = stack_frame_symbolizer.cc; path = ../../../processor/stack_frame_symbolizer.cc; sourceTree = "<group>"; };
+ F407DC42185773C10064622B /* stackwalker_arm64.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = stackwalker_arm64.cc; path = ../../../processor/stackwalker_arm64.cc; sourceTree = "<group>"; };
+ F407DC43185773C10064622B /* stackwalker_arm64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = stackwalker_arm64.h; path = ../../../processor/stackwalker_arm64.h; sourceTree = "<group>"; };
+ F407DC44185773C10064622B /* stackwalker_mips.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = stackwalker_mips.cc; path = ../../../processor/stackwalker_mips.cc; sourceTree = "<group>"; };
+ F407DC45185773C10064622B /* stackwalker_mips.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = stackwalker_mips.h; path = ../../../processor/stackwalker_mips.h; sourceTree = "<group>"; };
+ F407DC46185773C10064622B /* stackwalker_ppc64.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = stackwalker_ppc64.cc; path = ../../../processor/stackwalker_ppc64.cc; sourceTree = "<group>"; };
+ F407DC47185773C10064622B /* stackwalker_ppc64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = stackwalker_ppc64.h; path = ../../../processor/stackwalker_ppc64.h; sourceTree = "<group>"; };
+ F44DDD8419C85CD50047280E /* dump_context.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = dump_context.cc; path = ../../../processor/dump_context.cc; sourceTree = "<group>"; };
+ F44DDD8519C85CD50047280E /* dump_object.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = dump_object.cc; path = ../../../processor/dump_object.cc; sourceTree = "<group>"; };
+ F44DDD8619C85CD50047280E /* microdump_processor.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = microdump_processor.cc; path = ../../../processor/microdump_processor.cc; sourceTree = "<group>"; };
+ F44DDD8A19C85CFB0047280E /* dump_context.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = dump_context.h; path = ../../../google_breakpad/processor/dump_context.h; sourceTree = "<group>"; };
+ F44DDD8B19C85CFB0047280E /* dump_object.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = dump_object.h; path = ../../../google_breakpad/processor/dump_object.h; sourceTree = "<group>"; };
+ F44DDD8C19C85CFC0047280E /* microdump_processor.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = microdump_processor.h; path = ../../../google_breakpad/processor/microdump_processor.h; sourceTree = "<group>"; };
+ F44DDD8D19C85CFC0047280E /* process_result.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = process_result.h; path = ../../../google_breakpad/processor/process_result.h; sourceTree = "<group>"; };
+ F4D43B2E1A38490700C290B2 /* microdump.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = microdump.cc; path = ../../../processor/microdump.cc; sourceTree = "<group>"; };
+ F4D43B301A38492000C290B2 /* microdump.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = microdump.h; path = ../../../google_breakpad/processor/microdump.h; sourceTree = "<group>"; };
+ F9C7ECE20E8ABCA600E953AD /* bytereader.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = bytereader.cc; path = ../../../common/dwarf/bytereader.cc; sourceTree = SOURCE_ROOT; };
+ F9C7ECE30E8ABCA600E953AD /* dwarf2reader.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = dwarf2reader.cc; path = ../../../common/dwarf/dwarf2reader.cc; sourceTree = SOURCE_ROOT; };
+ F9C7ECE40E8ABCA600E953AD /* functioninfo.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = functioninfo.cc; path = ../../../common/dwarf/functioninfo.cc; sourceTree = SOURCE_ROOT; };
+ F9F0706510FBC02D0037B88B /* stackwalker_arm.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = stackwalker_arm.cc; path = ../../../processor/stackwalker_arm.cc; sourceTree = SOURCE_ROOT; };
+ F9F0706610FBC02D0037B88B /* stackwalker_arm.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = stackwalker_arm.h; path = ../../../processor/stackwalker_arm.h; sourceTree = SOURCE_ROOT; };
+ FD6625C40CF4D438004AC844 /* stackwalker_amd64.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = stackwalker_amd64.cc; path = ../../../processor/stackwalker_amd64.cc; sourceTree = SOURCE_ROOT; };
+ FD6625C50CF4D438004AC844 /* stackwalker_amd64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = stackwalker_amd64.h; path = ../../../processor/stackwalker_amd64.h; sourceTree = SOURCE_ROOT; };
+ FD8EDEAC0CADDAD400A5EDF1 /* stackwalker_sparc.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = stackwalker_sparc.cc; path = ../../../processor/stackwalker_sparc.cc; sourceTree = SOURCE_ROOT; };
+ FD8EDEAD0CADDAD400A5EDF1 /* stackwalker_sparc.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = stackwalker_sparc.h; path = ../../../processor/stackwalker_sparc.h; sourceTree = SOURCE_ROOT; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+ 8DD76F9B0486AA7600D96B5E /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 8DD76F9C0486AA7600D96B5E /* Foundation.framework in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+ 08FB7794FE84155DC02AAC07 /* crash_report */ = {
+ isa = PBXGroup;
+ children = (
+ 8B31025311F0D2D400FCF3E4 /* Breakpad.xcconfig */,
+ 8B3102DA11F0D65600FCF3E4 /* BreakpadDebug.xcconfig */,
+ 8B3102DB11F0D65600FCF3E4 /* BreakpadRelease.xcconfig */,
+ F9C7ECE10E8ABC7F00E953AD /* DWARF */,
+ 162F64FC161C5ECB00CD68D5 /* arch_utilities.cc */,
+ 162F64FD161C5ECB00CD68D5 /* arch_utilities.h */,
+ 5578003E0BE1F28500EC23E0 /* macho_utilities.cc */,
+ 5578003F0BE1F28500EC23E0 /* macho_utilities.h */,
+ 8B31FF7211F0C6E000FCF3E4 /* macho_reader.cc */,
+ 8B31FF7311F0C6E000FCF3E4 /* macho_reader.h */,
+ 9BDF192D0B1BC15D00F8391B /* dump_syms.h */,
+ 9BDF192E0B1BC15D00F8391B /* dump_syms.mm */,
+ 08FB7796FE84155DC02AAC07 /* crash_report.mm */,
+ F44DDD8D19C85CFC0047280E /* process_result.h */,
+ 9BDF176B0B1B8CB100F8391B /* on_demand_symbol_supplier.h */,
+ F44DDD8419C85CD50047280E /* dump_context.cc */,
+ F44DDD8A19C85CFB0047280E /* dump_context.h */,
+ F44DDD8519C85CD50047280E /* dump_object.cc */,
+ F44DDD8B19C85CFB0047280E /* dump_object.h */,
+ F4D43B2E1A38490700C290B2 /* microdump.cc */,
+ F4D43B301A38492000C290B2 /* microdump.h */,
+ F44DDD8619C85CD50047280E /* microdump_processor.cc */,
+ F44DDD8C19C85CFC0047280E /* microdump_processor.h */,
+ 9BDF176C0B1B8CB100F8391B /* on_demand_symbol_supplier.mm */,
+ 8B31FF2411F0C62700FCF3E4 /* dwarf_cfi_to_module.cc */,
+ 8B31FF2511F0C62700FCF3E4 /* dwarf_cfi_to_module.h */,
+ 8B31FF2611F0C62700FCF3E4 /* dwarf_cu_to_module.cc */,
+ 8B31FF2711F0C62700FCF3E4 /* dwarf_cu_to_module.h */,
+ 8B31FF2811F0C62700FCF3E4 /* dwarf_line_to_module.cc */,
+ 8B31FF2911F0C62700FCF3E4 /* dwarf_line_to_module.h */,
+ 8B31FF3D11F0C64400FCF3E4 /* stabs_reader.cc */,
+ 8B31FF3E11F0C64400FCF3E4 /* stabs_reader.h */,
+ 8B31FF3F11F0C64400FCF3E4 /* stabs_to_module.cc */,
+ 8B31FF4011F0C64400FCF3E4 /* stabs_to_module.h */,
+ 8B31FF8411F0C6FB00FCF3E4 /* language.cc */,
+ 8B31FF8511F0C6FB00FCF3E4 /* language.h */,
+ 4D72CA5613DFBA84006CABE3 /* md5.cc */,
+ 8B31FF8611F0C6FB00FCF3E4 /* module.cc */,
+ 8B31FF8711F0C6FB00FCF3E4 /* module.h */,
+ 08FB7795FE84155DC02AAC07 /* breakpad */,
+ 4D2C726E126F9CE200B43EAF /* libdisasm */,
+ 08FB779DFE84155DC02AAC07 /* External Frameworks and Libraries */,
+ 1AB674ADFE9D54B511CA2CBB /* Products */,
+ );
+ name = crash_report;
+ sourceTree = "<group>";
+ };
+ 08FB7795FE84155DC02AAC07 /* breakpad */ = {
+ isa = PBXGroup;
+ children = (
+ 9BE650AB0B52FE1A00611104 /* common */,
+ 9BDF17280B1B8B0200F8391B /* processor */,
+ 9BDF16F70B1B8ACD00F8391B /* google_breakpad */,
+ );
+ name = breakpad;
+ sourceTree = "<group>";
+ };
+ 08FB779DFE84155DC02AAC07 /* External Frameworks and Libraries */ = {
+ isa = PBXGroup;
+ children = (
+ 08FB779EFE84155DC02AAC07 /* Foundation.framework */,
+ );
+ name = "External Frameworks and Libraries";
+ sourceTree = "<group>";
+ };
+ 1AB674ADFE9D54B511CA2CBB /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ 8DD76FA10486AA7600D96B5E /* crash_report */,
+ );
+ name = Products;
+ sourceTree = "<group>";
+ };
+ 4D2C726E126F9CE200B43EAF /* libdisasm */ = {
+ isa = PBXGroup;
+ children = (
+ 4D2C7226126F9B0F00B43EAF /* disassembler_x86.cc */,
+ 4D2C724B126F9C3800B43EAF /* ia32_implicit.c */,
+ 4D2C7245126F9C0B00B43EAF /* ia32_insn.c */,
+ 4D2C7232126F9BB000B43EAF /* ia32_invariant.c */,
+ 4D2C7261126F9CBB00B43EAF /* ia32_modrm.c */,
+ 4D2C7249126F9C2300B43EAF /* ia32_opcode_tables.c */,
+ 4D2C725A126F9C8000B43EAF /* ia32_operand.c */,
+ 4D2C724D126F9C4D00B43EAF /* ia32_reg.c */,
+ 4D2C7234126F9BC200B43EAF /* ia32_settings.c */,
+ 4D2C722A126F9B5A00B43EAF /* x86_disasm.c */,
+ 4D2C7263126F9CBB00B43EAF /* x86_imm.c */,
+ 4D2C725C126F9C9200B43EAF /* x86_insn.c */,
+ 4D2C722C126F9B6E00B43EAF /* x86_misc.c */,
+ 4D2C722E126F9B8300B43EAF /* x86_operand_list.c */,
+ );
+ name = libdisasm;
+ sourceTree = "<group>";
+ };
+ 9BDF16F70B1B8ACD00F8391B /* google_breakpad */ = {
+ isa = PBXGroup;
+ children = (
+ 9BDF16F80B1B8ACD00F8391B /* common */,
+ 9BDF16FB0B1B8ACD00F8391B /* processor */,
+ );
+ name = google_breakpad;
+ path = ../../../google_breakpad;
+ sourceTree = SOURCE_ROOT;
+ };
+ 9BDF16F80B1B8ACD00F8391B /* common */ = {
+ isa = PBXGroup;
+ children = (
+ 9BDF16F90B1B8ACD00F8391B /* breakpad_types.h */,
+ 9BDF16FA0B1B8ACD00F8391B /* minidump_format.h */,
+ );
+ path = common;
+ sourceTree = "<group>";
+ };
+ 9BDF16FB0B1B8ACD00F8391B /* processor */ = {
+ isa = PBXGroup;
+ children = (
+ 9B3904940B2E52D90059FABE /* basic_source_line_resolver.h */,
+ 9BDF16FC0B1B8ACD00F8391B /* call_stack.h */,
+ 9B35FEE20B2675F9008DE8C7 /* code_module.h */,
+ 9B35FEE30B2675F9008DE8C7 /* code_modules.h */,
+ 9BDF16FD0B1B8ACD00F8391B /* memory_region.h */,
+ 9BDF16FE0B1B8ACD00F8391B /* minidump.h */,
+ 9BDF16FF0B1B8ACD00F8391B /* minidump_processor.h */,
+ 9BDF17000B1B8ACD00F8391B /* process_state.h */,
+ 9B3904950B2E52D90059FABE /* source_line_resolver_interface.h */,
+ 9BDF17010B1B8ACD00F8391B /* stack_frame.h */,
+ 9BDF17020B1B8ACD00F8391B /* stack_frame_cpu.h */,
+ 9BDF17030B1B8ACD00F8391B /* stackwalker.h */,
+ 9BDF17040B1B8ACD00F8391B /* symbol_supplier.h */,
+ 9B44619D0B66C66B00BBB817 /* system_info.h */,
+ );
+ path = processor;
+ sourceTree = "<group>";
+ };
+ 9BDF17280B1B8B0200F8391B /* processor */ = {
+ isa = PBXGroup;
+ children = (
+ 4D2C7222126F9AF900B43EAF /* exploitability_win.cc */,
+ F407DC40185773C10064622B /* exploitability_linux.cc */,
+ F407DC41185773C10064622B /* stack_frame_symbolizer.cc */,
+ F407DC42185773C10064622B /* stackwalker_arm64.cc */,
+ F407DC43185773C10064622B /* stackwalker_arm64.h */,
+ F407DC44185773C10064622B /* stackwalker_mips.cc */,
+ F407DC45185773C10064622B /* stackwalker_mips.h */,
+ F407DC46185773C10064622B /* stackwalker_ppc64.cc */,
+ F407DC47185773C10064622B /* stackwalker_ppc64.h */,
+ 4D2C721E126F9ADE00B43EAF /* exploitability.cc */,
+ 4D2C721A126F9ACC00B43EAF /* source_line_resolver_base.cc */,
+ D2A5DD621188658B00081F03 /* tokenize.cc */,
+ D2A5DD4C1188651100081F03 /* cfi_frame_info.cc */,
+ F9F0706510FBC02D0037B88B /* stackwalker_arm.cc */,
+ F9F0706610FBC02D0037B88B /* stackwalker_arm.h */,
+ 9B3904980B2E52FD0059FABE /* basic_source_line_resolver.cc */,
+ 9BDF1AFA0B1BEB6300F8391B /* address_map-inl.h */,
+ 9BDF1AFB0B1BEB6300F8391B /* address_map.h */,
+ 9B35FEE60B26761C008DE8C7 /* basic_code_module.h */,
+ 9B35FEE70B26761C008DE8C7 /* basic_code_modules.cc */,
+ 9B35FEE80B26761C008DE8C7 /* basic_code_modules.h */,
+ 9BDF172A0B1B8B2400F8391B /* call_stack.cc */,
+ 8B40BDBF0C0638E4009535AF /* logging.cc */,
+ 9BDF173F0B1B8B9A00F8391B /* minidump.cc */,
+ 9BDF172B0B1B8B2400F8391B /* minidump_processor.cc */,
+ 9BDF1A270B1BD58200F8391B /* pathname_stripper.cc */,
+ 9BDF175B0B1B8C1B00F8391B /* process_state.cc */,
+ 9BDF1A7A0B1BE30100F8391B /* range_map-inl.h */,
+ 9BDF1A7B0B1BE30100F8391B /* range_map.h */,
+ 9BDF17530B1B8BF900F8391B /* stackwalker.cc */,
+ 9BDF17510B1B8BF900F8391B /* stackwalker_ppc.cc */,
+ 9BDF17520B1B8BF900F8391B /* stackwalker_x86.cc */,
+ FD8EDEAC0CADDAD400A5EDF1 /* stackwalker_sparc.cc */,
+ FD8EDEAD0CADDAD400A5EDF1 /* stackwalker_sparc.h */,
+ FD6625C40CF4D438004AC844 /* stackwalker_amd64.cc */,
+ FD6625C50CF4D438004AC844 /* stackwalker_amd64.h */,
+ );
+ name = processor;
+ sourceTree = "<group>";
+ };
+ 9BE650AB0B52FE1A00611104 /* common */ = {
+ isa = PBXGroup;
+ children = (
+ 9BE650AC0B52FE3000611104 /* file_id.cc */,
+ 9BE650AD0B52FE3000611104 /* file_id.h */,
+ 9BE650AE0B52FE3000611104 /* macho_id.cc */,
+ 9BE650AF0B52FE3000611104 /* macho_id.h */,
+ 9BE650B00B52FE3000611104 /* macho_walker.cc */,
+ 9BE650B10B52FE3000611104 /* macho_walker.h */,
+ );
+ name = common;
+ sourceTree = "<group>";
+ };
+ F9C7ECE10E8ABC7F00E953AD /* DWARF */ = {
+ isa = PBXGroup;
+ children = (
+ F9C7ECE20E8ABCA600E953AD /* bytereader.cc */,
+ F9C7ECE30E8ABCA600E953AD /* dwarf2reader.cc */,
+ 8B31FFC311F0C8AB00FCF3E4 /* dwarf2diehandler.cc */,
+ 8B31FFC411F0C8AB00FCF3E4 /* dwarf2diehandler.h */,
+ F9C7ECE40E8ABCA600E953AD /* functioninfo.cc */,
+ );
+ name = DWARF;
+ sourceTree = "<group>";
+ };
+/* End PBXGroup section */
+
+/* Begin PBXNativeTarget section */
+ 8DD76F960486AA7600D96B5E /* crash_report */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 1DEB927408733DD40010E9CD /* Build configuration list for PBXNativeTarget "crash_report" */;
+ buildPhases = (
+ 8DD76F990486AA7600D96B5E /* Sources */,
+ 8DD76F9B0486AA7600D96B5E /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = crash_report;
+ productInstallPath = "$(HOME)/bin";
+ productName = crash_report;
+ productReference = 8DD76FA10486AA7600D96B5E /* crash_report */;
+ productType = "com.apple.product-type.tool";
+ };
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+ 08FB7793FE84155DC02AAC07 /* Project object */ = {
+ isa = PBXProject;
+ buildConfigurationList = 1DEB927808733DD40010E9CD /* Build configuration list for PBXProject "crash_report" */;
+ compatibilityVersion = "Xcode 3.1";
+ hasScannedForEncodings = 1;
+ knownRegions = (
+ English,
+ Japanese,
+ French,
+ German,
+ );
+ mainGroup = 08FB7794FE84155DC02AAC07 /* crash_report */;
+ projectDirPath = "";
+ projectRoot = "";
+ targets = (
+ 8DD76F960486AA7600D96B5E /* crash_report */,
+ );
+ };
+/* End PBXProject section */
+
+/* Begin PBXSourcesBuildPhase section */
+ 8DD76F990486AA7600D96B5E /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 162F64FE161C5ECB00CD68D5 /* arch_utilities.cc in Sources */,
+ 8DD76F9A0486AA7600D96B5E /* crash_report.mm in Sources */,
+ 9BDF172C0B1B8B2400F8391B /* call_stack.cc in Sources */,
+ 9BDF172D0B1B8B2400F8391B /* minidump_processor.cc in Sources */,
+ 9BDF17410B1B8B9A00F8391B /* minidump.cc in Sources */,
+ F44DDD8719C85CD50047280E /* dump_context.cc in Sources */,
+ 9BDF17540B1B8BF900F8391B /* stackwalker_ppc.cc in Sources */,
+ 9BDF17550B1B8BF900F8391B /* stackwalker_x86.cc in Sources */,
+ 9BDF17560B1B8BF900F8391B /* stackwalker.cc in Sources */,
+ 9BDF175D0B1B8C1B00F8391B /* process_state.cc in Sources */,
+ 9BDF176E0B1B8CB100F8391B /* on_demand_symbol_supplier.mm in Sources */,
+ 9BDF1A280B1BD58200F8391B /* pathname_stripper.cc in Sources */,
+ 9BDF21A70B1E825400F8391B /* dump_syms.mm in Sources */,
+ 9B35FEEA0B26761C008DE8C7 /* basic_code_modules.cc in Sources */,
+ 9B3904990B2E52FD0059FABE /* basic_source_line_resolver.cc in Sources */,
+ 9BE650B20B52FE3000611104 /* file_id.cc in Sources */,
+ 9BE650B40B52FE3000611104 /* macho_id.cc in Sources */,
+ 9BE650B60B52FE3000611104 /* macho_walker.cc in Sources */,
+ 557800400BE1F28500EC23E0 /* macho_utilities.cc in Sources */,
+ 8B40BDC00C0638E4009535AF /* logging.cc in Sources */,
+ FD8EDEAE0CADDAD400A5EDF1 /* stackwalker_sparc.cc in Sources */,
+ FD6625CD0CF4D45C004AC844 /* stackwalker_amd64.cc in Sources */,
+ F9C7ECE50E8ABCA600E953AD /* bytereader.cc in Sources */,
+ F9C7ECE60E8ABCA600E953AD /* dwarf2reader.cc in Sources */,
+ F9C7ECE70E8ABCA600E953AD /* functioninfo.cc in Sources */,
+ F9F0706710FBC02D0037B88B /* stackwalker_arm.cc in Sources */,
+ D2A5DD4D1188651100081F03 /* cfi_frame_info.cc in Sources */,
+ D2A5DD631188658B00081F03 /* tokenize.cc in Sources */,
+ 8B31FF2A11F0C62700FCF3E4 /* dwarf_cfi_to_module.cc in Sources */,
+ F4D43B2F1A38490700C290B2 /* microdump.cc in Sources */,
+ 8B31FF2B11F0C62700FCF3E4 /* dwarf_cu_to_module.cc in Sources */,
+ F44DDD8819C85CD50047280E /* dump_object.cc in Sources */,
+ 8B31FF2C11F0C62700FCF3E4 /* dwarf_line_to_module.cc in Sources */,
+ 8B31FF4111F0C64400FCF3E4 /* stabs_reader.cc in Sources */,
+ 8B31FF4211F0C64400FCF3E4 /* stabs_to_module.cc in Sources */,
+ 8B31FF7411F0C6E000FCF3E4 /* macho_reader.cc in Sources */,
+ 8B31FF8811F0C6FB00FCF3E4 /* language.cc in Sources */,
+ 8B31FF8911F0C6FB00FCF3E4 /* module.cc in Sources */,
+ 8B31FFC511F0C8AB00FCF3E4 /* dwarf2diehandler.cc in Sources */,
+ F407DC49185773C10064622B /* stack_frame_symbolizer.cc in Sources */,
+ 4D2C721B126F9ACC00B43EAF /* source_line_resolver_base.cc in Sources */,
+ 4D2C721F126F9ADE00B43EAF /* exploitability.cc in Sources */,
+ 4D2C7223126F9AF900B43EAF /* exploitability_win.cc in Sources */,
+ 4D2C7227126F9B0F00B43EAF /* disassembler_x86.cc in Sources */,
+ F407DC48185773C10064622B /* exploitability_linux.cc in Sources */,
+ 4D2C722B126F9B5A00B43EAF /* x86_disasm.c in Sources */,
+ 4D2C722D126F9B6E00B43EAF /* x86_misc.c in Sources */,
+ 4D2C722F126F9B8300B43EAF /* x86_operand_list.c in Sources */,
+ F407DC4A185773C10064622B /* stackwalker_arm64.cc in Sources */,
+ 4D2C7233126F9BB000B43EAF /* ia32_invariant.c in Sources */,
+ 4D2C7235126F9BC200B43EAF /* ia32_settings.c in Sources */,
+ 4D2C7246126F9C0B00B43EAF /* ia32_insn.c in Sources */,
+ 4D2C724A126F9C2300B43EAF /* ia32_opcode_tables.c in Sources */,
+ 4D2C724C126F9C3800B43EAF /* ia32_implicit.c in Sources */,
+ F44DDD8919C85CD50047280E /* microdump_processor.cc in Sources */,
+ 4D2C724E126F9C4D00B43EAF /* ia32_reg.c in Sources */,
+ 4D2C725B126F9C8000B43EAF /* ia32_operand.c in Sources */,
+ F407DC4C185773C10064622B /* stackwalker_ppc64.cc in Sources */,
+ 4D2C725D126F9C9200B43EAF /* x86_insn.c in Sources */,
+ 4D2C7264126F9CBB00B43EAF /* ia32_modrm.c in Sources */,
+ F407DC4B185773C10064622B /* stackwalker_mips.cc in Sources */,
+ 4D2C726D126F9CDC00B43EAF /* x86_imm.c in Sources */,
+ 4D72CA5713DFBA84006CABE3 /* md5.cc in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXSourcesBuildPhase section */
+
+/* Begin XCBuildConfiguration section */
+ 1DEB927508733DD40010E9CD /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ HEADER_SEARCH_PATHS = ../../../../src;
+ PRODUCT_NAME = crash_report;
+ };
+ name = Debug;
+ };
+ 1DEB927608733DD40010E9CD /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ HEADER_SEARCH_PATHS = ../../../../src;
+ PRODUCT_NAME = crash_report;
+ };
+ name = Release;
+ };
+ 1DEB927908733DD40010E9CD /* Debug */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 8B3102DA11F0D65600FCF3E4 /* BreakpadDebug.xcconfig */;
+ buildSettings = {
+ GCC_PREPROCESSOR_DEFINITIONS = HAVE_MACH_O_NLIST_H;
+ GCC_TREAT_WARNINGS_AS_ERRORS = NO;
+ };
+ name = Debug;
+ };
+ 1DEB927A08733DD40010E9CD /* Release */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 8B3102DB11F0D65600FCF3E4 /* BreakpadRelease.xcconfig */;
+ buildSettings = {
+ GCC_PREPROCESSOR_DEFINITIONS = HAVE_MACH_O_NLIST_H;
+ };
+ name = Release;
+ };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+ 1DEB927408733DD40010E9CD /* Build configuration list for PBXNativeTarget "crash_report" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 1DEB927508733DD40010E9CD /* Debug */,
+ 1DEB927608733DD40010E9CD /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ 1DEB927808733DD40010E9CD /* Build configuration list for PBXProject "crash_report" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 1DEB927908733DD40010E9CD /* Debug */,
+ 1DEB927A08733DD40010E9CD /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+/* End XCConfigurationList section */
+ };
+ rootObject = 08FB7793FE84155DC02AAC07 /* Project object */;
+}
diff --git a/toolkit/crashreporter/google-breakpad/src/tools/mac/crash_report/on_demand_symbol_supplier.h b/toolkit/crashreporter/google-breakpad/src/tools/mac/crash_report/on_demand_symbol_supplier.h
new file mode 100644
index 000000000..3fbe108eb
--- /dev/null
+++ b/toolkit/crashreporter/google-breakpad/src/tools/mac/crash_report/on_demand_symbol_supplier.h
@@ -0,0 +1,111 @@
+// 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.
+
+// on_demand_symbol_supplier.h: Provides a Symbol Supplier that will create
+// a breakpad symbol file on demand.
+
+#ifndef TOOLS_MAC_CRASH_REPORT_ON_DEMAND_SYMBOL_SUPPLIER_H__
+#define TOOLS_MAC_CRASH_REPORT_ON_DEMAND_SYMBOL_SUPPLIER_H__
+
+#include <map>
+#include <string>
+#include "google_breakpad/processor/symbol_supplier.h"
+
+namespace google_breakpad {
+
+using std::map;
+using std::string;
+class MinidumpModule;
+
+class OnDemandSymbolSupplier : public SymbolSupplier {
+ public:
+ // |search_dir| is the directory to search for alternative symbols with
+ // the same name as the module in the minidump
+ OnDemandSymbolSupplier(const string &search_dir,
+ const string &symbol_search_dir);
+ virtual ~OnDemandSymbolSupplier() {}
+
+ // Returns the path to the symbol file for the given module.
+ virtual SymbolResult GetSymbolFile(const CodeModule *module,
+ const SystemInfo *system_info,
+ string *symbol_file);
+
+ // Returns the path to the symbol file for the given module.
+ virtual SymbolResult GetSymbolFile(const CodeModule *module,
+ const SystemInfo *system_info,
+ string *symbol_file,
+ string *symbol_data);
+ // Allocates data buffer on heap, and takes the ownership of
+ // the data buffer.
+ virtual SymbolResult GetCStringSymbolData(const CodeModule *module,
+ const SystemInfo *system_info,
+ string *symbol_file,
+ char **symbol_data,
+ size_t *symbol_data_size);
+
+ // Delete the data buffer allocated for module in GetCStringSymbolData().
+ virtual void FreeSymbolData(const CodeModule *module);
+
+ protected:
+ // Search directory
+ string search_dir_;
+ string symbol_search_dir_;
+
+ // When we create a symbol file for a module, save the name of the module
+ // and the path to that module's symbol file.
+ map<string, string> module_file_map_;
+
+ // Map of allocated data buffers, keyed by module->code_file().
+ map<string, char *> memory_buffers_;
+
+ // Return the name for |module| This will be the value used as the key
+ // to the |module_file_map_|.
+ string GetNameForModule(const CodeModule *module);
+
+ // Find the module on local system. If the module resides in a different
+ // location than the full path in the minidump, this will be the location
+ // used.
+ string GetLocalModulePath(const CodeModule *module);
+
+ // Return the full path for |module|.
+ string GetModulePath(const CodeModule *module);
+
+ // Return the path to the symbol file for |module|. If an empty string is
+ // returned, then |module| doesn't have a symbol file.
+ string GetModuleSymbolFile(const CodeModule *module);
+
+ // Generate the breakpad symbol file for |module|. Return true if successful.
+ // File is generated in /tmp.
+ bool GenerateSymbolFile(const CodeModule *module,
+ const SystemInfo *system_info);
+};
+
+} // namespace google_breakpad
+
+#endif // TOOLS_MAC_CRASH_REPORT_ON_DEMAND_SYMBOL_SUPPLIER_H__
diff --git a/toolkit/crashreporter/google-breakpad/src/tools/mac/crash_report/on_demand_symbol_supplier.mm b/toolkit/crashreporter/google-breakpad/src/tools/mac/crash_report/on_demand_symbol_supplier.mm
new file mode 100644
index 000000000..ebbca87a0
--- /dev/null
+++ b/toolkit/crashreporter/google-breakpad/src/tools/mac/crash_report/on_demand_symbol_supplier.mm
@@ -0,0 +1,316 @@
+// Copyright (c) 2006, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include <sys/stat.h>
+#include <map>
+#include <string>
+#include <iostream>
+#include <fstream>
+#include <utility>
+
+#include "google_breakpad/processor/basic_source_line_resolver.h"
+#include "google_breakpad/processor/minidump.h"
+#include "google_breakpad/processor/system_info.h"
+#include "processor/pathname_stripper.h"
+
+#include "on_demand_symbol_supplier.h"
+#include "common/mac/dump_syms.h"
+
+using std::map;
+using std::string;
+
+using google_breakpad::OnDemandSymbolSupplier;
+using google_breakpad::PathnameStripper;
+using google_breakpad::SymbolSupplier;
+using google_breakpad::SystemInfo;
+
+OnDemandSymbolSupplier::OnDemandSymbolSupplier(const string &search_dir,
+ const string &symbol_search_dir)
+ : search_dir_(search_dir) {
+ NSFileManager *mgr = [NSFileManager defaultManager];
+ size_t length = symbol_search_dir.length();
+ if (length) {
+ // Load all sym files in symbol_search_dir into our module_file_map
+ // A symbol file always starts with a line like this:
+ // MODULE mac x86 BBF0A8F9BEADDD2048E6464001CA193F0 GoogleDesktopDaemon
+ // or
+ // MODULE mac ppc BBF0A8F9BEADDD2048E6464001CA193F0 GoogleDesktopDaemon
+ const char *symbolSearchStr = symbol_search_dir.c_str();
+ NSString *symbolSearchPath =
+ [mgr stringWithFileSystemRepresentation:symbolSearchStr
+ length:strlen(symbolSearchStr)];
+ NSDirectoryEnumerator *dirEnum = [mgr enumeratorAtPath:symbolSearchPath];
+ NSString *fileName;
+ NSCharacterSet *hexSet =
+ [NSCharacterSet characterSetWithCharactersInString:@"0123456789ABCDEF"];
+ NSCharacterSet *newlineSet =
+ [NSCharacterSet characterSetWithCharactersInString:@"\r\n"];
+ while ((fileName = [dirEnum nextObject])) {
+ // Check to see what type of file we have
+ NSDictionary *attrib = [dirEnum fileAttributes];
+ NSString *fileType = [attrib objectForKey:NSFileType];
+ if ([fileType isEqualToString:NSFileTypeDirectory]) {
+ // Skip subdirectories
+ [dirEnum skipDescendents];
+ } else {
+ NSString *filePath = [symbolSearchPath stringByAppendingPathComponent:fileName];
+ NSString *dataStr = [NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:NULL];
+ if (dataStr) {
+ // Check file to see if it is of appropriate type, and grab module
+ // name.
+ NSScanner *scanner = [NSScanner scannerWithString:dataStr];
+ BOOL goodScan = [scanner scanString:@"MODULE mac " intoString:nil];
+ if (goodScan) {
+ goodScan = ([scanner scanString:@"x86 " intoString:nil] ||
+ [scanner scanString:@"x86_64 " intoString:nil] ||
+ [scanner scanString:@"ppc " intoString:nil]);
+ if (goodScan) {
+ NSString *moduleID;
+ goodScan = [scanner scanCharactersFromSet:hexSet
+ intoString:&moduleID];
+ if (goodScan) {
+ // Module IDs are always 33 chars long
+ goodScan = [moduleID length] == 33;
+ if (goodScan) {
+ NSString *moduleName;
+ goodScan = [scanner scanUpToCharactersFromSet:newlineSet
+ intoString:&moduleName];
+ if (goodScan) {
+ goodScan = [moduleName length] > 0;
+ if (goodScan) {
+ const char *moduleNameStr = [moduleName UTF8String];
+ const char *filePathStr = [filePath fileSystemRepresentation];
+ // Map our file
+ module_file_map_[moduleNameStr] = filePathStr;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+SymbolSupplier::SymbolResult
+OnDemandSymbolSupplier::GetSymbolFile(const CodeModule *module,
+ const SystemInfo *system_info,
+ string *symbol_file) {
+ string path(GetModuleSymbolFile(module));
+
+ if (path.empty()) {
+ if (!GenerateSymbolFile(module, system_info))
+ return NOT_FOUND;
+
+ path = GetModuleSymbolFile(module);
+ }
+
+ if (path.empty())
+ return NOT_FOUND;
+
+ *symbol_file = path;
+ return FOUND;
+}
+
+SymbolSupplier::SymbolResult
+OnDemandSymbolSupplier::GetSymbolFile(const CodeModule *module,
+ const SystemInfo *system_info,
+ string *symbol_file,
+ string *symbol_data) {
+ SymbolSupplier::SymbolResult s = GetSymbolFile(module,
+ system_info,
+ symbol_file);
+
+
+ if (s == FOUND) {
+ std::ifstream in(symbol_file->c_str());
+ getline(in, *symbol_data, std::string::traits_type::to_char_type(
+ std::string::traits_type::eof()));
+ in.close();
+ }
+
+ return s;
+}
+
+SymbolSupplier::SymbolResult
+OnDemandSymbolSupplier::GetCStringSymbolData(const CodeModule *module,
+ const SystemInfo *system_info,
+ string *symbol_file,
+ char **symbol_data,
+ size_t *symbol_data_size) {
+ std::string symbol_data_string;
+ SymbolSupplier::SymbolResult result = GetSymbolFile(module,
+ system_info,
+ symbol_file,
+ &symbol_data_string);
+ if (result == FOUND) {
+ *symbol_data_size = symbol_data_string.size() + 1;
+ *symbol_data = new char[*symbol_data_size];
+ if (*symbol_data == NULL) {
+ // Should return INTERRUPT on memory allocation failure.
+ return INTERRUPT;
+ }
+ memcpy(*symbol_data, symbol_data_string.c_str(), symbol_data_string.size());
+ (*symbol_data)[symbol_data_string.size()] = '\0';
+ memory_buffers_.insert(make_pair(module->code_file(), *symbol_data));
+ }
+ return result;
+}
+
+void OnDemandSymbolSupplier::FreeSymbolData(const CodeModule *module) {
+ map<string, char *>::iterator it = memory_buffers_.find(module->code_file());
+ if (it != memory_buffers_.end()) {
+ delete [] it->second;
+ memory_buffers_.erase(it);
+ }
+}
+
+string OnDemandSymbolSupplier::GetLocalModulePath(const CodeModule *module) {
+ NSFileManager *mgr = [NSFileManager defaultManager];
+ const char *moduleStr = module->code_file().c_str();
+ NSString *modulePath =
+ [mgr stringWithFileSystemRepresentation:moduleStr length:strlen(moduleStr)];
+ const char *searchStr = search_dir_.c_str();
+ NSString *searchDir =
+ [mgr stringWithFileSystemRepresentation:searchStr length:strlen(searchStr)];
+
+ if ([mgr fileExistsAtPath:modulePath])
+ return module->code_file();
+
+ // If the module is not found, try to start appending the components to the
+ // search string and stop if a file (not dir) is found or all components
+ // have been appended
+ NSArray *pathComponents = [modulePath componentsSeparatedByString:@"/"];
+ size_t count = [pathComponents count];
+ NSMutableString *path = [NSMutableString string];
+
+ for (size_t i = 0; i < count; ++i) {
+ [path setString:searchDir];
+
+ for (size_t j = 0; j < i + 1; ++j) {
+ size_t idx = count - 1 - i + j;
+ [path appendFormat:@"/%@", [pathComponents objectAtIndex:idx]];
+ }
+
+ BOOL isDir;
+ if ([mgr fileExistsAtPath:path isDirectory:&isDir] && (!isDir)) {
+ return [path fileSystemRepresentation];
+ }
+ }
+
+ return "";
+}
+
+string OnDemandSymbolSupplier::GetModulePath(const CodeModule *module) {
+ return module->code_file();
+}
+
+string OnDemandSymbolSupplier::GetNameForModule(const CodeModule *module) {
+ return PathnameStripper::File(module->code_file());
+}
+
+string OnDemandSymbolSupplier::GetModuleSymbolFile(const CodeModule *module) {
+ string name(GetNameForModule(module));
+ map<string, string>::iterator result = module_file_map_.find(name);
+
+ return (result == module_file_map_.end()) ? "" : (*result).second;
+}
+
+static float GetFileModificationTime(const char *path) {
+ float result = 0;
+ struct stat file_stat;
+ if (stat(path, &file_stat) == 0)
+ result = (float)file_stat.st_mtimespec.tv_sec +
+ (float)file_stat.st_mtimespec.tv_nsec / 1.0e9f;
+
+ return result;
+}
+
+bool OnDemandSymbolSupplier::GenerateSymbolFile(const CodeModule *module,
+ const SystemInfo *system_info) {
+ bool result = true;
+ string name = GetNameForModule(module);
+ string module_path = GetLocalModulePath(module);
+ NSString *symbol_path = [NSString stringWithFormat:@"/tmp/%s.%s.sym",
+ name.c_str(), system_info->cpu.c_str()];
+
+ if (module_path.empty())
+ return false;
+
+ // Check if there's already a symbol file cached. Ensure that the file is
+ // newer than the module. Otherwise, generate a new one.
+ BOOL generate_file = YES;
+ if ([[NSFileManager defaultManager] fileExistsAtPath:symbol_path]) {
+ // Check if the module file is newer than the saved symbols
+ float cache_time =
+ GetFileModificationTime([symbol_path fileSystemRepresentation]);
+ float module_time =
+ GetFileModificationTime(module_path.c_str());
+
+ if (cache_time > module_time)
+ generate_file = NO;
+ }
+
+ if (generate_file) {
+ NSString *module_str = [[NSFileManager defaultManager]
+ stringWithFileSystemRepresentation:module_path.c_str()
+ length:module_path.length()];
+ DumpSymbols dump(ALL_SYMBOL_DATA, false);
+ if (dump.Read(module_str)) {
+ // What Breakpad calls "x86" should be given to the system as "i386".
+ std::string architecture;
+ if (system_info->cpu.compare("x86") == 0) {
+ architecture = "i386";
+ } else {
+ architecture = system_info->cpu;
+ }
+
+ if (dump.SetArchitecture(architecture)) {
+ std::fstream file([symbol_path fileSystemRepresentation],
+ std::ios_base::out | std::ios_base::trunc);
+ dump.WriteSymbolFile(file);
+ } else {
+ printf("Architecture %s not available for %s\n",
+ system_info->cpu.c_str(), name.c_str());
+ result = false;
+ }
+ } else {
+ printf("Unable to open %s\n", [module_str UTF8String]);
+ result = false;
+ }
+ }
+
+ // Add the mapping
+ if (result)
+ module_file_map_[name] = [symbol_path fileSystemRepresentation];
+
+ return result;
+}
diff --git a/toolkit/crashreporter/google-breakpad/src/tools/mac/dump_syms/dump_syms.xcodeproj/project.pbxproj b/toolkit/crashreporter/google-breakpad/src/tools/mac/dump_syms/dump_syms.xcodeproj/project.pbxproj
new file mode 100644
index 000000000..2e6bd9e10
--- /dev/null
+++ b/toolkit/crashreporter/google-breakpad/src/tools/mac/dump_syms/dump_syms.xcodeproj/project.pbxproj
@@ -0,0 +1,1839 @@
+// !$*UTF8*$!
+{
+ archiveVersion = 1;
+ classes = {
+ };
+ objectVersion = 45;
+ objects = {
+
+/* Begin PBXAggregateTarget section */
+ B88FAFC9116BDCAD00407530 /* all_unittests */ = {
+ isa = PBXAggregateTarget;
+ buildConfigurationList = B88FAFCC116BDCCC00407530 /* Build configuration list for PBXAggregateTarget "all_unittests" */;
+ buildPhases = (
+ B88FB094116CE73E00407530 /* ShellScript */,
+ );
+ dependencies = (
+ B88FB15B116CF53E00407530 /* PBXTargetDependency */,
+ B88FAFCF116BDD7000407530 /* PBXTargetDependency */,
+ B88FB01D116BDF9800407530 /* PBXTargetDependency */,
+ B88FB167116CF54B00407530 /* PBXTargetDependency */,
+ B88FAFD1116BDD7000407530 /* PBXTargetDependency */,
+ B88FB165116CF54B00407530 /* PBXTargetDependency */,
+ B88FB161116CF54B00407530 /* PBXTargetDependency */,
+ B88FB15F116CF54B00407530 /* PBXTargetDependency */,
+ B88FB15D116CF54B00407530 /* PBXTargetDependency */,
+ B84A9201116CF7D2006C210E /* PBXTargetDependency */,
+ B88FB0C8116CEB4A00407530 /* PBXTargetDependency */,
+ 8B31051511F100CF00FCF3E4 /* PBXTargetDependency */,
+ );
+ name = all_unittests;
+ productName = all_unittests;
+ };
+/* End PBXAggregateTarget section */
+
+/* Begin PBXBuildFile section */
+ 162F64FA161C591500CD68D5 /* arch_utilities.cc in Sources */ = {isa = PBXBuildFile; fileRef = 162F64F8161C591500CD68D5 /* arch_utilities.cc */; };
+ 162F6500161C5F2200CD68D5 /* arch_utilities.cc in Sources */ = {isa = PBXBuildFile; fileRef = 162F64F8161C591500CD68D5 /* arch_utilities.cc */; };
+ 4D72CAF513DFBAC2006CABE3 /* md5.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4D72CAF413DFBAC2006CABE3 /* md5.cc */; };
+ 8BCAAA4C1CE3A7980046090B /* elf_reader.cc in Sources */ = {isa = PBXBuildFile; fileRef = 8BCAAA4A1CE3A7980046090B /* elf_reader.cc */; };
+ 8BCAAA4D1CE3B1260046090B /* elf_reader.cc in Sources */ = {isa = PBXBuildFile; fileRef = 8BCAAA4A1CE3A7980046090B /* elf_reader.cc */; };
+ B84A91F8116CF78F006C210E /* libgtestmockall.a in Frameworks */ = {isa = PBXBuildFile; fileRef = B88FB024116BDFFF00407530 /* libgtestmockall.a */; };
+ B84A91FB116CF7AF006C210E /* module.cc in Sources */ = {isa = PBXBuildFile; fileRef = B88FAE241166603300407530 /* module.cc */; };
+ B84A91FC116CF7AF006C210E /* stabs_to_module.cc in Sources */ = {isa = PBXBuildFile; fileRef = B88FAE3C11666C8900407530 /* stabs_to_module.cc */; };
+ B84A91FD116CF7AF006C210E /* stabs_to_module_unittest.cc in Sources */ = {isa = PBXBuildFile; fileRef = B88FB0D8116CEC0600407530 /* stabs_to_module_unittest.cc */; };
+ B88FAE1911665FE400407530 /* dwarf2diehandler.cc in Sources */ = {isa = PBXBuildFile; fileRef = B88FAE1711665FE400407530 /* dwarf2diehandler.cc */; };
+ B88FAE261166603300407530 /* dwarf_cu_to_module.cc in Sources */ = {isa = PBXBuildFile; fileRef = B88FAE1E1166603300407530 /* dwarf_cu_to_module.cc */; };
+ B88FAE271166603300407530 /* dwarf_line_to_module.cc in Sources */ = {isa = PBXBuildFile; fileRef = B88FAE201166603300407530 /* dwarf_line_to_module.cc */; };
+ B88FAE281166603300407530 /* language.cc in Sources */ = {isa = PBXBuildFile; fileRef = B88FAE221166603300407530 /* language.cc */; };
+ B88FAE291166603300407530 /* module.cc in Sources */ = {isa = PBXBuildFile; fileRef = B88FAE241166603300407530 /* module.cc */; };
+ B88FAE2C1166606200407530 /* macho_reader.cc in Sources */ = {isa = PBXBuildFile; fileRef = B89E0E6E1166571D00DD08C9 /* macho_reader.cc */; };
+ B88FAE351166673E00407530 /* dwarf_cfi_to_module.cc in Sources */ = {isa = PBXBuildFile; fileRef = B88FAE331166673E00407530 /* dwarf_cfi_to_module.cc */; };
+ B88FAE3B11666C6F00407530 /* stabs_reader.cc in Sources */ = {isa = PBXBuildFile; fileRef = B88FAE3911666C6F00407530 /* stabs_reader.cc */; };
+ B88FAE3E11666C8900407530 /* stabs_to_module.cc in Sources */ = {isa = PBXBuildFile; fileRef = B88FAE3C11666C8900407530 /* stabs_to_module.cc */; };
+ B88FAF37116A595400407530 /* cfi_assembler.cc in Sources */ = {isa = PBXBuildFile; fileRef = B88FAF34116A595400407530 /* cfi_assembler.cc */; };
+ B88FAF38116A595400407530 /* dwarf2reader_cfi_unittest.cc in Sources */ = {isa = PBXBuildFile; fileRef = B88FAF36116A595400407530 /* dwarf2reader_cfi_unittest.cc */; };
+ B88FAF3F116A5A2E00407530 /* dwarf2reader.cc in Sources */ = {isa = PBXBuildFile; fileRef = F95B422F0E0E22D100DBDE83 /* dwarf2reader.cc */; };
+ B88FAF40116A5A2E00407530 /* bytereader.cc in Sources */ = {isa = PBXBuildFile; fileRef = F95B422C0E0E22D100DBDE83 /* bytereader.cc */; };
+ B88FB00F116BDEA700407530 /* stabs_reader_unittest.cc in Sources */ = {isa = PBXBuildFile; fileRef = B88FB003116BDE7200407530 /* stabs_reader_unittest.cc */; };
+ B88FB010116BDEA700407530 /* stabs_reader.cc in Sources */ = {isa = PBXBuildFile; fileRef = B88FAE3911666C6F00407530 /* stabs_reader.cc */; };
+ B88FB028116BE03100407530 /* test_assembler.cc in Sources */ = {isa = PBXBuildFile; fileRef = B88FAE0911665B5700407530 /* test_assembler.cc */; };
+ B88FB029116BE03100407530 /* gmock-all.cc in Sources */ = {isa = PBXBuildFile; fileRef = B89E0EA311665AEA00DD08C9 /* gmock-all.cc */; };
+ B88FB02A116BE03100407530 /* gtest_main.cc in Sources */ = {isa = PBXBuildFile; fileRef = B89E0E9F11665AC300DD08C9 /* gtest_main.cc */; };
+ B88FB02B116BE03100407530 /* gtest-all.cc in Sources */ = {isa = PBXBuildFile; fileRef = B89E0EA011665AC300DD08C9 /* gtest-all.cc */; };
+ B88FB03F116BE24200407530 /* libgtestmockall.a in Frameworks */ = {isa = PBXBuildFile; fileRef = B88FB024116BDFFF00407530 /* libgtestmockall.a */; };
+ B88FB042116BE3C400407530 /* libgtestmockall.a in Frameworks */ = {isa = PBXBuildFile; fileRef = B88FB024116BDFFF00407530 /* libgtestmockall.a */; };
+ B88FB057116C0CDE00407530 /* libgtestmockall.a in Frameworks */ = {isa = PBXBuildFile; fileRef = B88FB024116BDFFF00407530 /* libgtestmockall.a */; };
+ B88FB0BD116CEAE000407530 /* module_unittest.cc in Sources */ = {isa = PBXBuildFile; fileRef = B88FB0B5116CEA8A00407530 /* module_unittest.cc */; };
+ B88FB0C1116CEB0600407530 /* libgtestmockall.a in Frameworks */ = {isa = PBXBuildFile; fileRef = B88FB024116BDFFF00407530 /* libgtestmockall.a */; };
+ B88FB0C4116CEB4100407530 /* module.cc in Sources */ = {isa = PBXBuildFile; fileRef = B88FAE241166603300407530 /* module.cc */; };
+ B88FB0E3116CEEB000407530 /* libgtestmockall.a in Frameworks */ = {isa = PBXBuildFile; fileRef = B88FB024116BDFFF00407530 /* libgtestmockall.a */; };
+ B88FB0E5116CEED300407530 /* dwarf2diehandler.cc in Sources */ = {isa = PBXBuildFile; fileRef = B88FAE1711665FE400407530 /* dwarf2diehandler.cc */; };
+ B88FB0E6116CEED300407530 /* dwarf2diehandler_unittest.cc in Sources */ = {isa = PBXBuildFile; fileRef = B88FB0DB116CEC5800407530 /* dwarf2diehandler_unittest.cc */; };
+ B88FB0F6116CEF2000407530 /* libgtestmockall.a in Frameworks */ = {isa = PBXBuildFile; fileRef = B88FB024116BDFFF00407530 /* libgtestmockall.a */; };
+ B88FB0FA116CF00E00407530 /* dwarf_line_to_module.cc in Sources */ = {isa = PBXBuildFile; fileRef = B88FAE201166603300407530 /* dwarf_line_to_module.cc */; };
+ B88FB0FB116CF00E00407530 /* dwarf_line_to_module_unittest.cc in Sources */ = {isa = PBXBuildFile; fileRef = B88FB0D7116CEC0600407530 /* dwarf_line_to_module_unittest.cc */; };
+ B88FB0FE116CF02400407530 /* module.cc in Sources */ = {isa = PBXBuildFile; fileRef = B88FAE241166603300407530 /* module.cc */; };
+ B88FB10E116CF08100407530 /* libgtestmockall.a in Frameworks */ = {isa = PBXBuildFile; fileRef = B88FB024116BDFFF00407530 /* libgtestmockall.a */; };
+ B88FB112116CF1F000407530 /* dwarf_cu_to_module.cc in Sources */ = {isa = PBXBuildFile; fileRef = B88FAE1E1166603300407530 /* dwarf_cu_to_module.cc */; };
+ B88FB113116CF1F000407530 /* dwarf_cu_to_module_unittest.cc in Sources */ = {isa = PBXBuildFile; fileRef = B88FB0D6116CEC0600407530 /* dwarf_cu_to_module_unittest.cc */; };
+ B88FB114116CF1F000407530 /* language.cc in Sources */ = {isa = PBXBuildFile; fileRef = B88FAE221166603300407530 /* language.cc */; };
+ B88FB115116CF1F000407530 /* module.cc in Sources */ = {isa = PBXBuildFile; fileRef = B88FAE241166603300407530 /* module.cc */; };
+ B88FB123116CF28500407530 /* libgtestmockall.a in Frameworks */ = {isa = PBXBuildFile; fileRef = B88FB024116BDFFF00407530 /* libgtestmockall.a */; };
+ B88FB129116CF2DD00407530 /* module.cc in Sources */ = {isa = PBXBuildFile; fileRef = B88FAE241166603300407530 /* module.cc */; };
+ B88FB12A116CF2DD00407530 /* dwarf_cfi_to_module.cc in Sources */ = {isa = PBXBuildFile; fileRef = B88FAE331166673E00407530 /* dwarf_cfi_to_module.cc */; };
+ B88FB12B116CF2DD00407530 /* dwarf_cfi_to_module_unittest.cc in Sources */ = {isa = PBXBuildFile; fileRef = B88FB0D5116CEC0600407530 /* dwarf_cfi_to_module_unittest.cc */; };
+ B88FB139116CF31600407530 /* libgtestmockall.a in Frameworks */ = {isa = PBXBuildFile; fileRef = B88FB024116BDFFF00407530 /* libgtestmockall.a */; };
+ B88FB13D116CF38300407530 /* cfi_assembler.cc in Sources */ = {isa = PBXBuildFile; fileRef = B88FAF34116A595400407530 /* cfi_assembler.cc */; };
+ B88FB13E116CF38300407530 /* bytereader.cc in Sources */ = {isa = PBXBuildFile; fileRef = F95B422C0E0E22D100DBDE83 /* bytereader.cc */; };
+ B88FB13F116CF38300407530 /* bytereader_unittest.cc in Sources */ = {isa = PBXBuildFile; fileRef = B88FB0DA116CEC5800407530 /* bytereader_unittest.cc */; };
+ B88FB14F116CF4AE00407530 /* libgtestmockall.a in Frameworks */ = {isa = PBXBuildFile; fileRef = B88FB024116BDFFF00407530 /* libgtestmockall.a */; };
+ B88FB152116CF4D300407530 /* byte_cursor_unittest.cc in Sources */ = {isa = PBXBuildFile; fileRef = B88FB0D4116CEC0600407530 /* byte_cursor_unittest.cc */; };
+ B89E0E781166576C00DD08C9 /* macho_reader.cc in Sources */ = {isa = PBXBuildFile; fileRef = B89E0E6E1166571D00DD08C9 /* macho_reader.cc */; };
+ B89E0E7A1166576C00DD08C9 /* macho_dump.cc in Sources */ = {isa = PBXBuildFile; fileRef = B89E0E701166573700DD08C9 /* macho_dump.cc */; };
+ B89E0E9911665A7200DD08C9 /* macho_reader_unittest.cc in Sources */ = {isa = PBXBuildFile; fileRef = B89E0E6D1166571D00DD08C9 /* macho_reader_unittest.cc */; };
+ B89E0E9A11665A7200DD08C9 /* macho_reader.cc in Sources */ = {isa = PBXBuildFile; fileRef = B89E0E6E1166571D00DD08C9 /* macho_reader.cc */; };
+ B8C5B5171166534700D34F4E /* dwarf2reader.cc in Sources */ = {isa = PBXBuildFile; fileRef = F95B422F0E0E22D100DBDE83 /* dwarf2reader.cc */; };
+ B8C5B5181166534700D34F4E /* bytereader.cc in Sources */ = {isa = PBXBuildFile; fileRef = F95B422C0E0E22D100DBDE83 /* bytereader.cc */; };
+ B8C5B5191166534700D34F4E /* macho_utilities.cc in Sources */ = {isa = PBXBuildFile; fileRef = 557800890BE1F3AB00EC23E0 /* macho_utilities.cc */; };
+ B8C5B51A1166534700D34F4E /* file_id.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9BE650410B52F6D800611104 /* file_id.cc */; };
+ B8C5B51B1166534700D34F4E /* macho_id.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9BE650430B52F6D800611104 /* macho_id.cc */; };
+ B8C5B51C1166534700D34F4E /* macho_walker.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9BE650450B52F6D800611104 /* macho_walker.cc */; };
+ B8C5B51D1166534700D34F4E /* dump_syms.cc in Sources */ = {isa = PBXBuildFile; fileRef = 08FB7796FE84155DC02AAC07 /* dump_syms.cc */; };
+ B8C5B51E1166534700D34F4E /* dump_syms_tool.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9BDF186E0B1BB43700F8391B /* dump_syms_tool.cc */; };
+ B8C5B523116653BA00D34F4E /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 08FB779EFE84155DC02AAC07 /* Foundation.framework */; };
+ D21F97D711CBA12300239E38 /* test_assembler_unittest.cc in Sources */ = {isa = PBXBuildFile; fileRef = B88FB0D9116CEC0600407530 /* test_assembler_unittest.cc */; };
+ D21F97D811CBA13D00239E38 /* libgtestmockall.a in Frameworks */ = {isa = PBXBuildFile; fileRef = B88FB024116BDFFF00407530 /* libgtestmockall.a */; };
+ D21F97E911CBA1FF00239E38 /* test_assembler.cc in Sources */ = {isa = PBXBuildFile; fileRef = B88FAE0911665B5700407530 /* test_assembler.cc */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXContainerItemProxy section */
+ 8B31051411F100CF00FCF3E4 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = D21F97D111CBA0F200239E38;
+ remoteInfo = test_assembler_unittest;
+ };
+ B84A91F9116CF796006C210E /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = B88FB023116BDFFF00407530;
+ remoteInfo = gtestmockall;
+ };
+ B84A9200116CF7D2006C210E /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = B84A91F3116CF784006C210E;
+ remoteInfo = stabs_to_module_unittest;
+ };
+ B88FAFCE116BDD7000407530 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = B89E0E9411665A6400DD08C9;
+ remoteInfo = macho_reader_unittest;
+ };
+ B88FAFD0116BDD7000407530 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = B88FAF2E116A591D00407530;
+ remoteInfo = dwarf2reader_cfi_unittest;
+ };
+ B88FB01C116BDF9800407530 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = B88FB006116BDE8300407530;
+ remoteInfo = stabs_reader_unittest;
+ };
+ B88FB039116BE17E00407530 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = B88FB023116BDFFF00407530;
+ remoteInfo = gtestmockall;
+ };
+ B88FB087116CE6D800407530 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = B88FB023116BDFFF00407530;
+ remoteInfo = gtestmockall;
+ };
+ B88FB08F116CE71000407530 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = B88FB023116BDFFF00407530;
+ remoteInfo = gtestmockall;
+ };
+ B88FB0BF116CEAFE00407530 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = B88FB023116BDFFF00407530;
+ remoteInfo = gtestmockall;
+ };
+ B88FB0C7116CEB4A00407530 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = B88FB0B8116CEABF00407530;
+ remoteInfo = module_unittest;
+ };
+ B88FB0E7116CEEDA00407530 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = B88FB023116BDFFF00407530;
+ remoteInfo = gtestmockall;
+ };
+ B88FB0F7116CEF2E00407530 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = B88FB023116BDFFF00407530;
+ remoteInfo = gtestmockall;
+ };
+ B88FB10F116CF08A00407530 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = B88FB023116BDFFF00407530;
+ remoteInfo = gtestmockall;
+ };
+ B88FB124116CF29E00407530 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = B88FB023116BDFFF00407530;
+ remoteInfo = gtestmockall;
+ };
+ B88FB13B116CF35C00407530 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = B88FB023116BDFFF00407530;
+ remoteInfo = gtestmockall;
+ };
+ B88FB150116CF4C100407530 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = B88FB023116BDFFF00407530;
+ remoteInfo = gtestmockall;
+ };
+ B88FB15A116CF53E00407530 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = B88FB14A116CF4A700407530;
+ remoteInfo = byte_cursor_unittest;
+ };
+ B88FB15C116CF54B00407530 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = B88FB11E116CF27F00407530;
+ remoteInfo = dwarf_cfi_to_module_unittest;
+ };
+ B88FB15E116CF54B00407530 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = B88FB0F1116CEF1900407530;
+ remoteInfo = dwarf_line_to_module_unittest;
+ };
+ B88FB160116CF54B00407530 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = B88FB109116CF07900407530;
+ remoteInfo = dwarf_cu_to_module_unittest;
+ };
+ B88FB164116CF54B00407530 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = B88FB0DE116CEEA800407530;
+ remoteInfo = dwarf2diehandler_unittest;
+ };
+ B88FB166116CF54B00407530 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = B88FB134116CF30F00407530;
+ remoteInfo = bytereader_unittest;
+ };
+/* End PBXContainerItemProxy section */
+
+/* Begin PBXFileReference section */
+ 08FB7796FE84155DC02AAC07 /* dump_syms.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = dump_syms.cc; path = ../../../common/mac/dump_syms.cc; sourceTree = "<group>"; };
+ 08FB779EFE84155DC02AAC07 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
+ 162F64F8161C591500CD68D5 /* arch_utilities.cc */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = arch_utilities.cc; path = ../../../common/mac/arch_utilities.cc; sourceTree = "<group>"; };
+ 162F64F9161C591500CD68D5 /* arch_utilities.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = arch_utilities.h; path = ../../../common/mac/arch_utilities.h; sourceTree = "<group>"; };
+ 4D72CAF413DFBAC2006CABE3 /* md5.cc */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = md5.cc; path = ../../../common/md5.cc; sourceTree = SOURCE_ROOT; };
+ 557800890BE1F3AB00EC23E0 /* macho_utilities.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = macho_utilities.cc; path = ../../../common/mac/macho_utilities.cc; sourceTree = SOURCE_ROOT; };
+ 5578008A0BE1F3AB00EC23E0 /* macho_utilities.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = macho_utilities.h; path = ../../../common/mac/macho_utilities.h; sourceTree = SOURCE_ROOT; };
+ 8B31023E11F0CF1C00FCF3E4 /* Breakpad.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Breakpad.xcconfig; path = ../../../common/mac/Breakpad.xcconfig; sourceTree = SOURCE_ROOT; };
+ 8B3102D411F0D60300FCF3E4 /* BreakpadDebug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = BreakpadDebug.xcconfig; path = ../../../common/mac/BreakpadDebug.xcconfig; sourceTree = SOURCE_ROOT; };
+ 8B3102D511F0D60300FCF3E4 /* BreakpadRelease.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = BreakpadRelease.xcconfig; path = ../../../common/mac/BreakpadRelease.xcconfig; sourceTree = SOURCE_ROOT; };
+ 8BCAAA4A1CE3A7980046090B /* elf_reader.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = elf_reader.cc; path = ../../../common/dwarf/elf_reader.cc; sourceTree = "<group>"; };
+ 8BCAAA4B1CE3A7980046090B /* elf_reader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = elf_reader.h; path = ../../../common/dwarf/elf_reader.h; sourceTree = "<group>"; };
+ 9BDF186D0B1BB43700F8391B /* dump_syms.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = dump_syms.h; path = ../../../common/mac/dump_syms.h; sourceTree = "<group>"; };
+ 9BDF186E0B1BB43700F8391B /* dump_syms_tool.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = dump_syms_tool.cc; sourceTree = "<group>"; };
+ 9BE650410B52F6D800611104 /* file_id.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = file_id.cc; path = ../../../common/mac/file_id.cc; sourceTree = SOURCE_ROOT; };
+ 9BE650420B52F6D800611104 /* file_id.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = file_id.h; path = ../../../common/mac/file_id.h; sourceTree = SOURCE_ROOT; };
+ 9BE650430B52F6D800611104 /* macho_id.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = macho_id.cc; path = ../../../common/mac/macho_id.cc; sourceTree = SOURCE_ROOT; };
+ 9BE650440B52F6D800611104 /* macho_id.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = macho_id.h; path = ../../../common/mac/macho_id.h; sourceTree = SOURCE_ROOT; };
+ 9BE650450B52F6D800611104 /* macho_walker.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = macho_walker.cc; path = ../../../common/mac/macho_walker.cc; sourceTree = SOURCE_ROOT; };
+ 9BE650460B52F6D800611104 /* macho_walker.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = macho_walker.h; path = ../../../common/mac/macho_walker.h; sourceTree = SOURCE_ROOT; };
+ B84A91F4116CF784006C210E /* stabs_to_module_unittest */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = stabs_to_module_unittest; sourceTree = BUILT_PRODUCTS_DIR; };
+ B88FAE0911665B5700407530 /* test_assembler.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = test_assembler.cc; path = ../../../common/test_assembler.cc; sourceTree = SOURCE_ROOT; };
+ B88FAE0A11665B5700407530 /* test_assembler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = test_assembler.h; path = ../../../common/test_assembler.h; sourceTree = SOURCE_ROOT; };
+ B88FAE1711665FE400407530 /* dwarf2diehandler.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = dwarf2diehandler.cc; path = ../../../common/dwarf/dwarf2diehandler.cc; sourceTree = SOURCE_ROOT; };
+ B88FAE1811665FE400407530 /* dwarf2diehandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = dwarf2diehandler.h; path = ../../../common/dwarf/dwarf2diehandler.h; sourceTree = SOURCE_ROOT; };
+ B88FAE1D1166603300407530 /* byte_cursor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = byte_cursor.h; path = ../../../common/byte_cursor.h; sourceTree = SOURCE_ROOT; };
+ B88FAE1E1166603300407530 /* dwarf_cu_to_module.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = dwarf_cu_to_module.cc; path = ../../../common/dwarf_cu_to_module.cc; sourceTree = SOURCE_ROOT; };
+ B88FAE1F1166603300407530 /* dwarf_cu_to_module.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = dwarf_cu_to_module.h; path = ../../../common/dwarf_cu_to_module.h; sourceTree = SOURCE_ROOT; };
+ B88FAE201166603300407530 /* dwarf_line_to_module.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = dwarf_line_to_module.cc; path = ../../../common/dwarf_line_to_module.cc; sourceTree = SOURCE_ROOT; };
+ B88FAE211166603300407530 /* dwarf_line_to_module.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = dwarf_line_to_module.h; path = ../../../common/dwarf_line_to_module.h; sourceTree = SOURCE_ROOT; };
+ B88FAE221166603300407530 /* language.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = language.cc; path = ../../../common/language.cc; sourceTree = SOURCE_ROOT; };
+ B88FAE231166603300407530 /* language.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = language.h; path = ../../../common/language.h; sourceTree = SOURCE_ROOT; };
+ B88FAE241166603300407530 /* module.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = module.cc; path = ../../../common/module.cc; sourceTree = SOURCE_ROOT; };
+ B88FAE251166603300407530 /* module.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = module.h; path = ../../../common/module.h; sourceTree = SOURCE_ROOT; };
+ B88FAE331166673E00407530 /* dwarf_cfi_to_module.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = dwarf_cfi_to_module.cc; path = ../../../common/dwarf_cfi_to_module.cc; sourceTree = SOURCE_ROOT; };
+ B88FAE341166673E00407530 /* dwarf_cfi_to_module.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = dwarf_cfi_to_module.h; path = ../../../common/dwarf_cfi_to_module.h; sourceTree = SOURCE_ROOT; };
+ B88FAE3911666C6F00407530 /* stabs_reader.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = stabs_reader.cc; path = ../../../common/stabs_reader.cc; sourceTree = SOURCE_ROOT; };
+ B88FAE3A11666C6F00407530 /* stabs_reader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = stabs_reader.h; path = ../../../common/stabs_reader.h; sourceTree = SOURCE_ROOT; };
+ B88FAE3C11666C8900407530 /* stabs_to_module.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = stabs_to_module.cc; path = ../../../common/stabs_to_module.cc; sourceTree = SOURCE_ROOT; };
+ B88FAE3D11666C8900407530 /* stabs_to_module.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = stabs_to_module.h; path = ../../../common/stabs_to_module.h; sourceTree = SOURCE_ROOT; };
+ B88FAF2F116A591E00407530 /* dwarf2reader_cfi_unittest */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = dwarf2reader_cfi_unittest; sourceTree = BUILT_PRODUCTS_DIR; };
+ B88FAF34116A595400407530 /* cfi_assembler.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = cfi_assembler.cc; path = ../../../common/dwarf/cfi_assembler.cc; sourceTree = SOURCE_ROOT; };
+ B88FAF35116A595400407530 /* cfi_assembler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = cfi_assembler.h; path = ../../../common/dwarf/cfi_assembler.h; sourceTree = SOURCE_ROOT; };
+ B88FAF36116A595400407530 /* dwarf2reader_cfi_unittest.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = dwarf2reader_cfi_unittest.cc; path = ../../../common/dwarf/dwarf2reader_cfi_unittest.cc; sourceTree = SOURCE_ROOT; };
+ B88FB003116BDE7200407530 /* stabs_reader_unittest.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = stabs_reader_unittest.cc; path = ../../../common/stabs_reader_unittest.cc; sourceTree = SOURCE_ROOT; };
+ B88FB007116BDE8300407530 /* stabs_reader_unittest */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = stabs_reader_unittest; sourceTree = BUILT_PRODUCTS_DIR; };
+ B88FB024116BDFFF00407530 /* libgtestmockall.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libgtestmockall.a; sourceTree = BUILT_PRODUCTS_DIR; };
+ B88FB0B5116CEA8A00407530 /* module_unittest.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = module_unittest.cc; path = ../../../common/module_unittest.cc; sourceTree = SOURCE_ROOT; };
+ B88FB0B9116CEABF00407530 /* module_unittest */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = module_unittest; sourceTree = BUILT_PRODUCTS_DIR; };
+ B88FB0D4116CEC0600407530 /* byte_cursor_unittest.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = byte_cursor_unittest.cc; path = ../../../common/byte_cursor_unittest.cc; sourceTree = SOURCE_ROOT; };
+ B88FB0D5116CEC0600407530 /* dwarf_cfi_to_module_unittest.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = dwarf_cfi_to_module_unittest.cc; path = ../../../common/dwarf_cfi_to_module_unittest.cc; sourceTree = SOURCE_ROOT; };
+ B88FB0D6116CEC0600407530 /* dwarf_cu_to_module_unittest.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = dwarf_cu_to_module_unittest.cc; path = ../../../common/dwarf_cu_to_module_unittest.cc; sourceTree = SOURCE_ROOT; };
+ B88FB0D7116CEC0600407530 /* dwarf_line_to_module_unittest.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = dwarf_line_to_module_unittest.cc; path = ../../../common/dwarf_line_to_module_unittest.cc; sourceTree = SOURCE_ROOT; };
+ B88FB0D8116CEC0600407530 /* stabs_to_module_unittest.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = stabs_to_module_unittest.cc; path = ../../../common/stabs_to_module_unittest.cc; sourceTree = SOURCE_ROOT; };
+ B88FB0D9116CEC0600407530 /* test_assembler_unittest.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = test_assembler_unittest.cc; path = ../../../common/test_assembler_unittest.cc; sourceTree = SOURCE_ROOT; };
+ B88FB0DA116CEC5800407530 /* bytereader_unittest.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = bytereader_unittest.cc; path = ../../../common/dwarf/bytereader_unittest.cc; sourceTree = SOURCE_ROOT; };
+ B88FB0DB116CEC5800407530 /* dwarf2diehandler_unittest.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = dwarf2diehandler_unittest.cc; path = ../../../common/dwarf/dwarf2diehandler_unittest.cc; sourceTree = SOURCE_ROOT; };
+ B88FB0DF116CEEA800407530 /* dwarf2diehandler_unittest */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = dwarf2diehandler_unittest; sourceTree = BUILT_PRODUCTS_DIR; };
+ B88FB0F2116CEF1900407530 /* dwarf_line_to_module_unittest */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = dwarf_line_to_module_unittest; sourceTree = BUILT_PRODUCTS_DIR; };
+ B88FB10A116CF07900407530 /* dwarf_cu_to_module_unittest */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = dwarf_cu_to_module_unittest; sourceTree = BUILT_PRODUCTS_DIR; };
+ B88FB11F116CF27F00407530 /* dwarf_cfi_to_module_unittest */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = dwarf_cfi_to_module_unittest; sourceTree = BUILT_PRODUCTS_DIR; };
+ B88FB135116CF30F00407530 /* bytereader_unittest */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = bytereader_unittest; sourceTree = BUILT_PRODUCTS_DIR; };
+ B88FB14B116CF4A700407530 /* byte_cursor_unittest */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = byte_cursor_unittest; sourceTree = BUILT_PRODUCTS_DIR; };
+ B89E0E6D1166571D00DD08C9 /* macho_reader_unittest.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = macho_reader_unittest.cc; path = ../../../common/mac/macho_reader_unittest.cc; sourceTree = SOURCE_ROOT; };
+ B89E0E6E1166571D00DD08C9 /* macho_reader.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = macho_reader.cc; path = ../../../common/mac/macho_reader.cc; sourceTree = SOURCE_ROOT; };
+ B89E0E6F1166571D00DD08C9 /* macho_reader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = macho_reader.h; path = ../../../common/mac/macho_reader.h; sourceTree = SOURCE_ROOT; };
+ B89E0E701166573700DD08C9 /* macho_dump.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = macho_dump.cc; sourceTree = "<group>"; };
+ B89E0E741166575200DD08C9 /* macho_dump */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = macho_dump; sourceTree = BUILT_PRODUCTS_DIR; };
+ B89E0E9511665A6400DD08C9 /* macho_reader_unittest */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = macho_reader_unittest; sourceTree = BUILT_PRODUCTS_DIR; };
+ B89E0E9F11665AC300DD08C9 /* gtest_main.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = gtest_main.cc; path = ../../../testing/gtest/src/gtest_main.cc; sourceTree = SOURCE_ROOT; };
+ B89E0EA011665AC300DD08C9 /* gtest-all.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "gtest-all.cc"; path = "../../../testing/gtest/src/gtest-all.cc"; sourceTree = SOURCE_ROOT; };
+ B89E0EA311665AEA00DD08C9 /* gmock-all.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "gmock-all.cc"; path = "../../../testing/src/gmock-all.cc"; sourceTree = SOURCE_ROOT; };
+ B8C5B5111166531A00D34F4E /* dump_syms */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = dump_syms; sourceTree = BUILT_PRODUCTS_DIR; };
+ B8E8CA0C1156C854009E61B2 /* byteswap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = byteswap.h; path = ../../../common/mac/byteswap.h; sourceTree = SOURCE_ROOT; };
+ D21F97D211CBA0F200239E38 /* test_assembler_unittest */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = test_assembler_unittest; sourceTree = BUILT_PRODUCTS_DIR; };
+ F95B422B0E0E22D100DBDE83 /* bytereader-inl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "bytereader-inl.h"; path = "../../../common/dwarf/bytereader-inl.h"; sourceTree = SOURCE_ROOT; };
+ F95B422C0E0E22D100DBDE83 /* bytereader.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = bytereader.cc; path = ../../../common/dwarf/bytereader.cc; sourceTree = SOURCE_ROOT; };
+ F95B422D0E0E22D100DBDE83 /* bytereader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = bytereader.h; path = ../../../common/dwarf/bytereader.h; sourceTree = SOURCE_ROOT; };
+ F95B422E0E0E22D100DBDE83 /* dwarf2enums.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = dwarf2enums.h; path = ../../../common/dwarf/dwarf2enums.h; sourceTree = SOURCE_ROOT; };
+ F95B422F0E0E22D100DBDE83 /* dwarf2reader.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = dwarf2reader.cc; path = ../../../common/dwarf/dwarf2reader.cc; sourceTree = SOURCE_ROOT; };
+ F95B42300E0E22D100DBDE83 /* dwarf2reader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = dwarf2reader.h; path = ../../../common/dwarf/dwarf2reader.h; sourceTree = SOURCE_ROOT; };
+ F95B42310E0E22D100DBDE83 /* line_state_machine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = line_state_machine.h; path = ../../../common/dwarf/line_state_machine.h; sourceTree = SOURCE_ROOT; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+ B84A91F2116CF784006C210E /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ B84A91F8116CF78F006C210E /* libgtestmockall.a in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ B88FAF2D116A591D00407530 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ B88FB042116BE3C400407530 /* libgtestmockall.a in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ B88FB005116BDE8300407530 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ B88FB03F116BE24200407530 /* libgtestmockall.a in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ B88FB022116BDFFF00407530 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ B88FB0B7116CEABF00407530 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ B88FB0C1116CEB0600407530 /* libgtestmockall.a in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ B88FB0DD116CEEA800407530 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ B88FB0E3116CEEB000407530 /* libgtestmockall.a in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ B88FB0F0116CEF1900407530 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ B88FB0F6116CEF2000407530 /* libgtestmockall.a in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ B88FB108116CF07900407530 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ B88FB10E116CF08100407530 /* libgtestmockall.a in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ B88FB11D116CF27F00407530 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ B88FB123116CF28500407530 /* libgtestmockall.a in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ B88FB133116CF30F00407530 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ B88FB139116CF31600407530 /* libgtestmockall.a in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ B88FB149116CF4A700407530 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ B88FB14F116CF4AE00407530 /* libgtestmockall.a in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ B89E0E721166575200DD08C9 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ B89E0E9311665A6400DD08C9 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ B88FB057116C0CDE00407530 /* libgtestmockall.a in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ B8C5B50F1166531A00D34F4E /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ B8C5B523116653BA00D34F4E /* Foundation.framework in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ D21F97D011CBA0F200239E38 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ D21F97D811CBA13D00239E38 /* libgtestmockall.a in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+ 08FB7794FE84155DC02AAC07 /* dump_syms */ = {
+ isa = PBXGroup;
+ children = (
+ 8B31023E11F0CF1C00FCF3E4 /* Breakpad.xcconfig */,
+ 8B3102D411F0D60300FCF3E4 /* BreakpadDebug.xcconfig */,
+ 8B3102D511F0D60300FCF3E4 /* BreakpadRelease.xcconfig */,
+ B89E0E9D11665A9500DD08C9 /* TESTING */,
+ F9F5344B0E7C8FFC0012363F /* DWARF */,
+ B89E0E6C1166569700DD08C9 /* MACHO */,
+ B88FAE3811666A1700407530 /* STABS */,
+ B88FAE1C11665FFD00407530 /* MODULE */,
+ 162F64F8161C591500CD68D5 /* arch_utilities.cc */,
+ 162F64F9161C591500CD68D5 /* arch_utilities.h */,
+ B88FAE1D1166603300407530 /* byte_cursor.h */,
+ B88FB0D4116CEC0600407530 /* byte_cursor_unittest.cc */,
+ B8E8CA0C1156C854009E61B2 /* byteswap.h */,
+ 9BE650410B52F6D800611104 /* file_id.cc */,
+ 9BE650420B52F6D800611104 /* file_id.h */,
+ 9BDF186D0B1BB43700F8391B /* dump_syms.h */,
+ 08FB7796FE84155DC02AAC07 /* dump_syms.cc */,
+ 9BDF186E0B1BB43700F8391B /* dump_syms_tool.cc */,
+ B89E0E701166573700DD08C9 /* macho_dump.cc */,
+ 4D72CAF413DFBAC2006CABE3 /* md5.cc */,
+ 08FB779DFE84155DC02AAC07 /* External Frameworks and Libraries */,
+ 1AB674ADFE9D54B511CA2CBB /* Products */,
+ );
+ name = dump_syms;
+ sourceTree = "<group>";
+ };
+ 08FB779DFE84155DC02AAC07 /* External Frameworks and Libraries */ = {
+ isa = PBXGroup;
+ children = (
+ 08FB779EFE84155DC02AAC07 /* Foundation.framework */,
+ );
+ name = "External Frameworks and Libraries";
+ sourceTree = "<group>";
+ };
+ 1AB674ADFE9D54B511CA2CBB /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ B8C5B5111166531A00D34F4E /* dump_syms */,
+ B89E0E741166575200DD08C9 /* macho_dump */,
+ B89E0E9511665A6400DD08C9 /* macho_reader_unittest */,
+ B88FAF2F116A591E00407530 /* dwarf2reader_cfi_unittest */,
+ B88FB007116BDE8300407530 /* stabs_reader_unittest */,
+ B88FB024116BDFFF00407530 /* libgtestmockall.a */,
+ B88FB0B9116CEABF00407530 /* module_unittest */,
+ B88FB0DF116CEEA800407530 /* dwarf2diehandler_unittest */,
+ B88FB0F2116CEF1900407530 /* dwarf_line_to_module_unittest */,
+ B88FB10A116CF07900407530 /* dwarf_cu_to_module_unittest */,
+ B88FB11F116CF27F00407530 /* dwarf_cfi_to_module_unittest */,
+ B88FB135116CF30F00407530 /* bytereader_unittest */,
+ B88FB14B116CF4A700407530 /* byte_cursor_unittest */,
+ B84A91F4116CF784006C210E /* stabs_to_module_unittest */,
+ D21F97D211CBA0F200239E38 /* test_assembler_unittest */,
+ );
+ name = Products;
+ sourceTree = "<group>";
+ };
+ B88FAE1C11665FFD00407530 /* MODULE */ = {
+ isa = PBXGroup;
+ children = (
+ B88FAE1E1166603300407530 /* dwarf_cu_to_module.cc */,
+ B88FAE1F1166603300407530 /* dwarf_cu_to_module.h */,
+ B88FB0D6116CEC0600407530 /* dwarf_cu_to_module_unittest.cc */,
+ B88FAE201166603300407530 /* dwarf_line_to_module.cc */,
+ B88FAE211166603300407530 /* dwarf_line_to_module.h */,
+ B88FB0D7116CEC0600407530 /* dwarf_line_to_module_unittest.cc */,
+ B88FAE221166603300407530 /* language.cc */,
+ B88FAE231166603300407530 /* language.h */,
+ B88FAE241166603300407530 /* module.cc */,
+ B88FAE251166603300407530 /* module.h */,
+ B88FB0B5116CEA8A00407530 /* module_unittest.cc */,
+ B88FAE331166673E00407530 /* dwarf_cfi_to_module.cc */,
+ B88FAE341166673E00407530 /* dwarf_cfi_to_module.h */,
+ B88FB0D5116CEC0600407530 /* dwarf_cfi_to_module_unittest.cc */,
+ B88FAE3C11666C8900407530 /* stabs_to_module.cc */,
+ B88FAE3D11666C8900407530 /* stabs_to_module.h */,
+ B88FB0D8116CEC0600407530 /* stabs_to_module_unittest.cc */,
+ );
+ name = MODULE;
+ sourceTree = "<group>";
+ };
+ B88FAE3811666A1700407530 /* STABS */ = {
+ isa = PBXGroup;
+ children = (
+ B88FB003116BDE7200407530 /* stabs_reader_unittest.cc */,
+ B88FAE3911666C6F00407530 /* stabs_reader.cc */,
+ B88FAE3A11666C6F00407530 /* stabs_reader.h */,
+ );
+ name = STABS;
+ sourceTree = "<group>";
+ };
+ B89E0E6C1166569700DD08C9 /* MACHO */ = {
+ isa = PBXGroup;
+ children = (
+ B89E0E6D1166571D00DD08C9 /* macho_reader_unittest.cc */,
+ B89E0E6E1166571D00DD08C9 /* macho_reader.cc */,
+ B89E0E6F1166571D00DD08C9 /* macho_reader.h */,
+ 557800890BE1F3AB00EC23E0 /* macho_utilities.cc */,
+ 5578008A0BE1F3AB00EC23E0 /* macho_utilities.h */,
+ 9BE650430B52F6D800611104 /* macho_id.cc */,
+ 9BE650440B52F6D800611104 /* macho_id.h */,
+ 9BE650450B52F6D800611104 /* macho_walker.cc */,
+ 9BE650460B52F6D800611104 /* macho_walker.h */,
+ );
+ name = MACHO;
+ sourceTree = "<group>";
+ };
+ B89E0E9D11665A9500DD08C9 /* TESTING */ = {
+ isa = PBXGroup;
+ children = (
+ B88FAE0911665B5700407530 /* test_assembler.cc */,
+ B88FAE0A11665B5700407530 /* test_assembler.h */,
+ B88FB0D9116CEC0600407530 /* test_assembler_unittest.cc */,
+ B89E0EA311665AEA00DD08C9 /* gmock-all.cc */,
+ B89E0E9F11665AC300DD08C9 /* gtest_main.cc */,
+ B89E0EA011665AC300DD08C9 /* gtest-all.cc */,
+ );
+ name = TESTING;
+ sourceTree = "<group>";
+ };
+ F9F5344B0E7C8FFC0012363F /* DWARF */ = {
+ isa = PBXGroup;
+ children = (
+ B88FAF34116A595400407530 /* cfi_assembler.cc */,
+ B88FAF35116A595400407530 /* cfi_assembler.h */,
+ F95B422E0E0E22D100DBDE83 /* dwarf2enums.h */,
+ F95B422F0E0E22D100DBDE83 /* dwarf2reader.cc */,
+ F95B42300E0E22D100DBDE83 /* dwarf2reader.h */,
+ B88FAF36116A595400407530 /* dwarf2reader_cfi_unittest.cc */,
+ F95B422D0E0E22D100DBDE83 /* bytereader.h */,
+ F95B422B0E0E22D100DBDE83 /* bytereader-inl.h */,
+ F95B422C0E0E22D100DBDE83 /* bytereader.cc */,
+ B88FB0DA116CEC5800407530 /* bytereader_unittest.cc */,
+ F95B42310E0E22D100DBDE83 /* line_state_machine.h */,
+ B88FAE1711665FE400407530 /* dwarf2diehandler.cc */,
+ B88FAE1811665FE400407530 /* dwarf2diehandler.h */,
+ B88FB0DB116CEC5800407530 /* dwarf2diehandler_unittest.cc */,
+ 8BCAAA4A1CE3A7980046090B /* elf_reader.cc */,
+ 8BCAAA4B1CE3A7980046090B /* elf_reader.h */,
+ );
+ name = DWARF;
+ sourceTree = "<group>";
+ };
+/* End PBXGroup section */
+
+/* Begin PBXHeadersBuildPhase section */
+ B88FB020116BDFFF00407530 /* Headers */ = {
+ isa = PBXHeadersBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXHeadersBuildPhase section */
+
+/* Begin PBXNativeTarget section */
+ B84A91F3116CF784006C210E /* stabs_to_module_unittest */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = B84A9202116CF7F0006C210E /* Build configuration list for PBXNativeTarget "stabs_to_module_unittest" */;
+ buildPhases = (
+ B84A91F1116CF784006C210E /* Sources */,
+ B84A91F2116CF784006C210E /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ B84A91FA116CF796006C210E /* PBXTargetDependency */,
+ );
+ name = stabs_to_module_unittest;
+ productName = stabs_to_module_unittest;
+ productReference = B84A91F4116CF784006C210E /* stabs_to_module_unittest */;
+ productType = "com.apple.product-type.tool";
+ };
+ B88FAF2E116A591D00407530 /* dwarf2reader_cfi_unittest */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = B88FAF33116A594800407530 /* Build configuration list for PBXNativeTarget "dwarf2reader_cfi_unittest" */;
+ buildPhases = (
+ B88FAF2C116A591D00407530 /* Sources */,
+ B88FAF2D116A591D00407530 /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ B88FB03A116BE17E00407530 /* PBXTargetDependency */,
+ );
+ name = dwarf2reader_cfi_unittest;
+ productName = dwarf2reader_cfi_unittest;
+ productReference = B88FAF2F116A591E00407530 /* dwarf2reader_cfi_unittest */;
+ productType = "com.apple.product-type.tool";
+ };
+ B88FB006116BDE8300407530 /* stabs_reader_unittest */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = B88FB013116BDEC800407530 /* Build configuration list for PBXNativeTarget "stabs_reader_unittest" */;
+ buildPhases = (
+ B88FB004116BDE8300407530 /* Sources */,
+ B88FB005116BDE8300407530 /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ B88FB088116CE6D800407530 /* PBXTargetDependency */,
+ );
+ name = stabs_reader_unittest;
+ productName = stabs_reader_unittest;
+ productReference = B88FB007116BDE8300407530 /* stabs_reader_unittest */;
+ productType = "com.apple.product-type.tool";
+ };
+ B88FB023116BDFFF00407530 /* gtestmockall */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = B88FB027116BE02900407530 /* Build configuration list for PBXNativeTarget "gtestmockall" */;
+ buildPhases = (
+ B88FB020116BDFFF00407530 /* Headers */,
+ B88FB021116BDFFF00407530 /* Sources */,
+ B88FB022116BDFFF00407530 /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = gtestmockall;
+ productName = gtestmockall;
+ productReference = B88FB024116BDFFF00407530 /* libgtestmockall.a */;
+ productType = "com.apple.product-type.library.static";
+ };
+ B88FB0B8116CEABF00407530 /* module_unittest */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = B88FB0BE116CEAFE00407530 /* Build configuration list for PBXNativeTarget "module_unittest" */;
+ buildPhases = (
+ B88FB0B6116CEABF00407530 /* Sources */,
+ B88FB0B7116CEABF00407530 /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ B88FB0C0116CEAFE00407530 /* PBXTargetDependency */,
+ );
+ name = module_unittest;
+ productName = module_unittest;
+ productReference = B88FB0B9116CEABF00407530 /* module_unittest */;
+ productType = "com.apple.product-type.tool";
+ };
+ B88FB0DE116CEEA800407530 /* dwarf2diehandler_unittest */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = B88FB0E4116CEECE00407530 /* Build configuration list for PBXNativeTarget "dwarf2diehandler_unittest" */;
+ buildPhases = (
+ B88FB0DC116CEEA800407530 /* Sources */,
+ B88FB0DD116CEEA800407530 /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ B88FB0E8116CEEDA00407530 /* PBXTargetDependency */,
+ );
+ name = dwarf2diehandler_unittest;
+ productName = dwarf2diehandler_unittest;
+ productReference = B88FB0DF116CEEA800407530 /* dwarf2diehandler_unittest */;
+ productType = "com.apple.product-type.tool";
+ };
+ B88FB0F1116CEF1900407530 /* dwarf_line_to_module_unittest */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = B88FB0F9116CEF9800407530 /* Build configuration list for PBXNativeTarget "dwarf_line_to_module_unittest" */;
+ buildPhases = (
+ B88FB0EF116CEF1900407530 /* Sources */,
+ B88FB0F0116CEF1900407530 /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ B88FB0F8116CEF2E00407530 /* PBXTargetDependency */,
+ );
+ name = dwarf_line_to_module_unittest;
+ productName = dwarf_line_to_module_unittest;
+ productReference = B88FB0F2116CEF1900407530 /* dwarf_line_to_module_unittest */;
+ productType = "com.apple.product-type.tool";
+ };
+ B88FB109116CF07900407530 /* dwarf_cu_to_module_unittest */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = B88FB111116CF0A800407530 /* Build configuration list for PBXNativeTarget "dwarf_cu_to_module_unittest" */;
+ buildPhases = (
+ B88FB107116CF07900407530 /* Sources */,
+ B88FB108116CF07900407530 /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ B88FB110116CF08A00407530 /* PBXTargetDependency */,
+ );
+ name = dwarf_cu_to_module_unittest;
+ productName = dwarf_cu_to_module_unittest;
+ productReference = B88FB10A116CF07900407530 /* dwarf_cu_to_module_unittest */;
+ productType = "com.apple.product-type.tool";
+ };
+ B88FB11E116CF27F00407530 /* dwarf_cfi_to_module_unittest */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = B88FB128116CF2C800407530 /* Build configuration list for PBXNativeTarget "dwarf_cfi_to_module_unittest" */;
+ buildPhases = (
+ B88FB11C116CF27F00407530 /* Sources */,
+ B88FB11D116CF27F00407530 /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ B88FB125116CF29E00407530 /* PBXTargetDependency */,
+ );
+ name = dwarf_cfi_to_module_unittest;
+ productName = dwarf_cfi_to_module_unittest;
+ productReference = B88FB11F116CF27F00407530 /* dwarf_cfi_to_module_unittest */;
+ productType = "com.apple.product-type.tool";
+ };
+ B88FB134116CF30F00407530 /* bytereader_unittest */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = B88FB13A116CF33400407530 /* Build configuration list for PBXNativeTarget "bytereader_unittest" */;
+ buildPhases = (
+ B88FB132116CF30F00407530 /* Sources */,
+ B88FB133116CF30F00407530 /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ B88FB13C116CF35C00407530 /* PBXTargetDependency */,
+ );
+ name = bytereader_unittest;
+ productName = bytereader_unittest;
+ productReference = B88FB135116CF30F00407530 /* bytereader_unittest */;
+ productType = "com.apple.product-type.tool";
+ };
+ B88FB14A116CF4A700407530 /* byte_cursor_unittest */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = B88FB159116CF4F900407530 /* Build configuration list for PBXNativeTarget "byte_cursor_unittest" */;
+ buildPhases = (
+ B88FB148116CF4A700407530 /* Sources */,
+ B88FB149116CF4A700407530 /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ B88FB151116CF4C100407530 /* PBXTargetDependency */,
+ );
+ name = byte_cursor_unittest;
+ productName = byte_cursor_unittest;
+ productReference = B88FB14B116CF4A700407530 /* byte_cursor_unittest */;
+ productType = "com.apple.product-type.tool";
+ };
+ B89E0E731166575200DD08C9 /* macho_dump */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = B89E0E7F116657A100DD08C9 /* Build configuration list for PBXNativeTarget "macho_dump" */;
+ buildPhases = (
+ B89E0E711166575200DD08C9 /* Sources */,
+ B89E0E721166575200DD08C9 /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = macho_dump;
+ productName = macho_dump;
+ productReference = B89E0E741166575200DD08C9 /* macho_dump */;
+ productType = "com.apple.product-type.tool";
+ };
+ B89E0E9411665A6400DD08C9 /* macho_reader_unittest */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = B89E0E9E11665A9600DD08C9 /* Build configuration list for PBXNativeTarget "macho_reader_unittest" */;
+ buildPhases = (
+ B89E0E9211665A6400DD08C9 /* Sources */,
+ B89E0E9311665A6400DD08C9 /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ B88FB090116CE71000407530 /* PBXTargetDependency */,
+ );
+ name = macho_reader_unittest;
+ productName = macho_reader_unittest;
+ productReference = B89E0E9511665A6400DD08C9 /* macho_reader_unittest */;
+ productType = "com.apple.product-type.tool";
+ };
+ B8C5B5101166531A00D34F4E /* dump_syms */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = B8C5B5151166533900D34F4E /* Build configuration list for PBXNativeTarget "dump_syms" */;
+ buildPhases = (
+ B8C5B50E1166531A00D34F4E /* Sources */,
+ B8C5B50F1166531A00D34F4E /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = dump_syms;
+ productName = dump_syms;
+ productReference = B8C5B5111166531A00D34F4E /* dump_syms */;
+ productType = "com.apple.product-type.tool";
+ };
+ D21F97D111CBA0F200239E38 /* test_assembler_unittest */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = D21F97D611CBA11000239E38 /* Build configuration list for PBXNativeTarget "test_assembler_unittest" */;
+ buildPhases = (
+ D21F97CF11CBA0F200239E38 /* Sources */,
+ D21F97D011CBA0F200239E38 /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = test_assembler_unittest;
+ productName = test_assembler_unittest;
+ productReference = D21F97D211CBA0F200239E38 /* test_assembler_unittest */;
+ productType = "com.apple.product-type.tool";
+ };
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+ 08FB7793FE84155DC02AAC07 /* Project object */ = {
+ isa = PBXProject;
+ attributes = {
+ };
+ buildConfigurationList = 1DEB927808733DD40010E9CD /* Build configuration list for PBXProject "dump_syms" */;
+ compatibilityVersion = "Xcode 3.1";
+ developmentRegion = English;
+ hasScannedForEncodings = 1;
+ knownRegions = (
+ English,
+ Japanese,
+ French,
+ German,
+ );
+ mainGroup = 08FB7794FE84155DC02AAC07 /* dump_syms */;
+ projectDirPath = "";
+ projectRoot = "";
+ targets = (
+ B8C5B5101166531A00D34F4E /* dump_syms */,
+ B89E0E731166575200DD08C9 /* macho_dump */,
+ B88FB023116BDFFF00407530 /* gtestmockall */,
+ B88FB14A116CF4A700407530 /* byte_cursor_unittest */,
+ B89E0E9411665A6400DD08C9 /* macho_reader_unittest */,
+ B88FB006116BDE8300407530 /* stabs_reader_unittest */,
+ B88FB134116CF30F00407530 /* bytereader_unittest */,
+ B88FAF2E116A591D00407530 /* dwarf2reader_cfi_unittest */,
+ B88FB0DE116CEEA800407530 /* dwarf2diehandler_unittest */,
+ B88FB109116CF07900407530 /* dwarf_cu_to_module_unittest */,
+ B88FB0F1116CEF1900407530 /* dwarf_line_to_module_unittest */,
+ B88FB11E116CF27F00407530 /* dwarf_cfi_to_module_unittest */,
+ B84A91F3116CF784006C210E /* stabs_to_module_unittest */,
+ B88FB0B8116CEABF00407530 /* module_unittest */,
+ B88FAFC9116BDCAD00407530 /* all_unittests */,
+ D21F97D111CBA0F200239E38 /* test_assembler_unittest */,
+ );
+ };
+/* End PBXProject section */
+
+/* Begin PBXShellScriptBuildPhase section */
+ B88FB094116CE73E00407530 /* ShellScript */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ );
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "set -eu\n\ncd $BUILT_PRODUCTS_DIR\npwd\n\n./byte_cursor_unittest\n./macho_reader_unittest\n./stabs_reader_unittest\n./bytereader_unittest\n./dwarf2reader_cfi_unittest\n./dwarf2diehandler_unittest\n./dwarf_cu_to_module_unittest\n./dwarf_line_to_module_unittest\n./dwarf_cfi_to_module_unittest\n./stabs_to_module_unittest\n./module_unittest\n./test_assembler_unittest\n\necho \"Expect two warnings from the following tests:\"\necho \" Errors.BadFileNumber\"\necho \" Errors.BadDirectoryNumber\"\necho \"The proper behavior of these tests is to print text that XCode confuses with compiler warnings.\"\n";
+ };
+/* End PBXShellScriptBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+ B84A91F1116CF784006C210E /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ B84A91FB116CF7AF006C210E /* module.cc in Sources */,
+ B84A91FC116CF7AF006C210E /* stabs_to_module.cc in Sources */,
+ B84A91FD116CF7AF006C210E /* stabs_to_module_unittest.cc in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ B88FAF2C116A591D00407530 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ B88FAF38116A595400407530 /* dwarf2reader_cfi_unittest.cc in Sources */,
+ B88FAF3F116A5A2E00407530 /* dwarf2reader.cc in Sources */,
+ 8BCAAA4D1CE3B1260046090B /* elf_reader.cc in Sources */,
+ B88FAF40116A5A2E00407530 /* bytereader.cc in Sources */,
+ B88FAF37116A595400407530 /* cfi_assembler.cc in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ B88FB004116BDE8300407530 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ B88FB00F116BDEA700407530 /* stabs_reader_unittest.cc in Sources */,
+ B88FB010116BDEA700407530 /* stabs_reader.cc in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ B88FB021116BDFFF00407530 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ B88FB028116BE03100407530 /* test_assembler.cc in Sources */,
+ B88FB029116BE03100407530 /* gmock-all.cc in Sources */,
+ B88FB02A116BE03100407530 /* gtest_main.cc in Sources */,
+ B88FB02B116BE03100407530 /* gtest-all.cc in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ B88FB0B6116CEABF00407530 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ B88FB0BD116CEAE000407530 /* module_unittest.cc in Sources */,
+ B88FB0C4116CEB4100407530 /* module.cc in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ B88FB0DC116CEEA800407530 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ B88FB0E5116CEED300407530 /* dwarf2diehandler.cc in Sources */,
+ B88FB0E6116CEED300407530 /* dwarf2diehandler_unittest.cc in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ B88FB0EF116CEF1900407530 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ B88FB0FA116CF00E00407530 /* dwarf_line_to_module.cc in Sources */,
+ B88FB0FE116CF02400407530 /* module.cc in Sources */,
+ B88FB0FB116CF00E00407530 /* dwarf_line_to_module_unittest.cc in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ B88FB107116CF07900407530 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ B88FB112116CF1F000407530 /* dwarf_cu_to_module.cc in Sources */,
+ B88FB113116CF1F000407530 /* dwarf_cu_to_module_unittest.cc in Sources */,
+ B88FB114116CF1F000407530 /* language.cc in Sources */,
+ B88FB115116CF1F000407530 /* module.cc in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ B88FB11C116CF27F00407530 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ B88FB129116CF2DD00407530 /* module.cc in Sources */,
+ B88FB12A116CF2DD00407530 /* dwarf_cfi_to_module.cc in Sources */,
+ B88FB12B116CF2DD00407530 /* dwarf_cfi_to_module_unittest.cc in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ B88FB132116CF30F00407530 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ B88FB13D116CF38300407530 /* cfi_assembler.cc in Sources */,
+ B88FB13E116CF38300407530 /* bytereader.cc in Sources */,
+ B88FB13F116CF38300407530 /* bytereader_unittest.cc in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ B88FB148116CF4A700407530 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ B88FB152116CF4D300407530 /* byte_cursor_unittest.cc in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ B89E0E711166575200DD08C9 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 162F6500161C5F2200CD68D5 /* arch_utilities.cc in Sources */,
+ B89E0E781166576C00DD08C9 /* macho_reader.cc in Sources */,
+ B89E0E7A1166576C00DD08C9 /* macho_dump.cc in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ B89E0E9211665A6400DD08C9 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ B89E0E9911665A7200DD08C9 /* macho_reader_unittest.cc in Sources */,
+ B89E0E9A11665A7200DD08C9 /* macho_reader.cc in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ B8C5B50E1166531A00D34F4E /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 162F64FA161C591500CD68D5 /* arch_utilities.cc in Sources */,
+ B88FAE2C1166606200407530 /* macho_reader.cc in Sources */,
+ 8BCAAA4C1CE3A7980046090B /* elf_reader.cc in Sources */,
+ B8C5B5171166534700D34F4E /* dwarf2reader.cc in Sources */,
+ B8C5B5181166534700D34F4E /* bytereader.cc in Sources */,
+ B8C5B5191166534700D34F4E /* macho_utilities.cc in Sources */,
+ B8C5B51A1166534700D34F4E /* file_id.cc in Sources */,
+ B8C5B51B1166534700D34F4E /* macho_id.cc in Sources */,
+ B8C5B51C1166534700D34F4E /* macho_walker.cc in Sources */,
+ B8C5B51D1166534700D34F4E /* dump_syms.cc in Sources */,
+ B8C5B51E1166534700D34F4E /* dump_syms_tool.cc in Sources */,
+ B88FAE1911665FE400407530 /* dwarf2diehandler.cc in Sources */,
+ B88FAE261166603300407530 /* dwarf_cu_to_module.cc in Sources */,
+ B88FAE271166603300407530 /* dwarf_line_to_module.cc in Sources */,
+ B88FAE281166603300407530 /* language.cc in Sources */,
+ B88FAE291166603300407530 /* module.cc in Sources */,
+ B88FAE351166673E00407530 /* dwarf_cfi_to_module.cc in Sources */,
+ B88FAE3B11666C6F00407530 /* stabs_reader.cc in Sources */,
+ B88FAE3E11666C8900407530 /* stabs_to_module.cc in Sources */,
+ 4D72CAF513DFBAC2006CABE3 /* md5.cc in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ D21F97CF11CBA0F200239E38 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ D21F97E911CBA1FF00239E38 /* test_assembler.cc in Sources */,
+ D21F97D711CBA12300239E38 /* test_assembler_unittest.cc in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXSourcesBuildPhase section */
+
+/* Begin PBXTargetDependency section */
+ 8B31051511F100CF00FCF3E4 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = D21F97D111CBA0F200239E38 /* test_assembler_unittest */;
+ targetProxy = 8B31051411F100CF00FCF3E4 /* PBXContainerItemProxy */;
+ };
+ B84A91FA116CF796006C210E /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = B88FB023116BDFFF00407530 /* gtestmockall */;
+ targetProxy = B84A91F9116CF796006C210E /* PBXContainerItemProxy */;
+ };
+ B84A9201116CF7D2006C210E /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = B84A91F3116CF784006C210E /* stabs_to_module_unittest */;
+ targetProxy = B84A9200116CF7D2006C210E /* PBXContainerItemProxy */;
+ };
+ B88FAFCF116BDD7000407530 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = B89E0E9411665A6400DD08C9 /* macho_reader_unittest */;
+ targetProxy = B88FAFCE116BDD7000407530 /* PBXContainerItemProxy */;
+ };
+ B88FAFD1116BDD7000407530 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = B88FAF2E116A591D00407530 /* dwarf2reader_cfi_unittest */;
+ targetProxy = B88FAFD0116BDD7000407530 /* PBXContainerItemProxy */;
+ };
+ B88FB01D116BDF9800407530 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = B88FB006116BDE8300407530 /* stabs_reader_unittest */;
+ targetProxy = B88FB01C116BDF9800407530 /* PBXContainerItemProxy */;
+ };
+ B88FB03A116BE17E00407530 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = B88FB023116BDFFF00407530 /* gtestmockall */;
+ targetProxy = B88FB039116BE17E00407530 /* PBXContainerItemProxy */;
+ };
+ B88FB088116CE6D800407530 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = B88FB023116BDFFF00407530 /* gtestmockall */;
+ targetProxy = B88FB087116CE6D800407530 /* PBXContainerItemProxy */;
+ };
+ B88FB090116CE71000407530 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = B88FB023116BDFFF00407530 /* gtestmockall */;
+ targetProxy = B88FB08F116CE71000407530 /* PBXContainerItemProxy */;
+ };
+ B88FB0C0116CEAFE00407530 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = B88FB023116BDFFF00407530 /* gtestmockall */;
+ targetProxy = B88FB0BF116CEAFE00407530 /* PBXContainerItemProxy */;
+ };
+ B88FB0C8116CEB4A00407530 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = B88FB0B8116CEABF00407530 /* module_unittest */;
+ targetProxy = B88FB0C7116CEB4A00407530 /* PBXContainerItemProxy */;
+ };
+ B88FB0E8116CEEDA00407530 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = B88FB023116BDFFF00407530 /* gtestmockall */;
+ targetProxy = B88FB0E7116CEEDA00407530 /* PBXContainerItemProxy */;
+ };
+ B88FB0F8116CEF2E00407530 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = B88FB023116BDFFF00407530 /* gtestmockall */;
+ targetProxy = B88FB0F7116CEF2E00407530 /* PBXContainerItemProxy */;
+ };
+ B88FB110116CF08A00407530 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = B88FB023116BDFFF00407530 /* gtestmockall */;
+ targetProxy = B88FB10F116CF08A00407530 /* PBXContainerItemProxy */;
+ };
+ B88FB125116CF29E00407530 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = B88FB023116BDFFF00407530 /* gtestmockall */;
+ targetProxy = B88FB124116CF29E00407530 /* PBXContainerItemProxy */;
+ };
+ B88FB13C116CF35C00407530 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = B88FB023116BDFFF00407530 /* gtestmockall */;
+ targetProxy = B88FB13B116CF35C00407530 /* PBXContainerItemProxy */;
+ };
+ B88FB151116CF4C100407530 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = B88FB023116BDFFF00407530 /* gtestmockall */;
+ targetProxy = B88FB150116CF4C100407530 /* PBXContainerItemProxy */;
+ };
+ B88FB15B116CF53E00407530 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = B88FB14A116CF4A700407530 /* byte_cursor_unittest */;
+ targetProxy = B88FB15A116CF53E00407530 /* PBXContainerItemProxy */;
+ };
+ B88FB15D116CF54B00407530 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = B88FB11E116CF27F00407530 /* dwarf_cfi_to_module_unittest */;
+ targetProxy = B88FB15C116CF54B00407530 /* PBXContainerItemProxy */;
+ };
+ B88FB15F116CF54B00407530 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = B88FB0F1116CEF1900407530 /* dwarf_line_to_module_unittest */;
+ targetProxy = B88FB15E116CF54B00407530 /* PBXContainerItemProxy */;
+ };
+ B88FB161116CF54B00407530 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = B88FB109116CF07900407530 /* dwarf_cu_to_module_unittest */;
+ targetProxy = B88FB160116CF54B00407530 /* PBXContainerItemProxy */;
+ };
+ B88FB165116CF54B00407530 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = B88FB0DE116CEEA800407530 /* dwarf2diehandler_unittest */;
+ targetProxy = B88FB164116CF54B00407530 /* PBXContainerItemProxy */;
+ };
+ B88FB167116CF54B00407530 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = B88FB134116CF30F00407530 /* bytereader_unittest */;
+ targetProxy = B88FB166116CF54B00407530 /* PBXContainerItemProxy */;
+ };
+/* End PBXTargetDependency section */
+
+/* Begin XCBuildConfiguration section */
+ 1DEB927908733DD40010E9CD /* Debug */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 8B3102D411F0D60300FCF3E4 /* BreakpadDebug.xcconfig */;
+ buildSettings = {
+ HEADER_SEARCH_PATHS = (
+ ../../..,
+ ../../../common/mac/include/,
+ ../../../third_party/musl/include/,
+ );
+ };
+ name = Debug;
+ };
+ 1DEB927A08733DD40010E9CD /* Release */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 8B3102D511F0D60300FCF3E4 /* BreakpadRelease.xcconfig */;
+ buildSettings = {
+ HEADER_SEARCH_PATHS = (
+ ../../..,
+ ../../../common/mac/include/,
+ ../../../third_party/musl/include/,
+ );
+ };
+ name = Release;
+ };
+ B84A91F6116CF784006C210E /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ HEADER_SEARCH_PATHS = (
+ $inherited,
+ ../../../testing,
+ ../../../testing/include,
+ ../../../testing/gtest,
+ ../../../testing/gtest/include,
+ );
+ PRODUCT_NAME = stabs_to_module_unittest;
+ };
+ name = Debug;
+ };
+ B84A91F7116CF784006C210E /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ HEADER_SEARCH_PATHS = (
+ $inherited,
+ ../../../testing,
+ ../../../testing/include,
+ ../../../testing/gtest,
+ ../../../testing/gtest/include,
+ );
+ PRODUCT_NAME = stabs_to_module_unittest;
+ };
+ name = Release;
+ };
+ B88FAF31116A591F00407530 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ HEADER_SEARCH_PATHS = (
+ $inherited,
+ ../../../testing,
+ ../../../testing/include,
+ ../../../testing/gtest,
+ ../../../testing/gtest/include,
+ );
+ LIBRARY_SEARCH_PATHS = (
+ "$(inherited)",
+ "$(LIBRARY_SEARCH_PATHS_QUOTED_FOR_TARGET_1)",
+ );
+ LIBRARY_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/build/Debug\"";
+ PRODUCT_NAME = dwarf2reader_cfi_unittest;
+ };
+ name = Debug;
+ };
+ B88FAF32116A591F00407530 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ HEADER_SEARCH_PATHS = (
+ $inherited,
+ ../../../testing,
+ ../../../testing/include,
+ ../../../testing/gtest,
+ ../../../testing/gtest/include,
+ );
+ LIBRARY_SEARCH_PATHS = (
+ "$(inherited)",
+ "$(LIBRARY_SEARCH_PATHS_QUOTED_FOR_TARGET_1)",
+ );
+ LIBRARY_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/build/Debug\"";
+ PRODUCT_NAME = dwarf2reader_cfi_unittest;
+ };
+ name = Release;
+ };
+ B88FAFCA116BDCAD00407530 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ PRODUCT_NAME = all_unittests;
+ };
+ name = Debug;
+ };
+ B88FAFCB116BDCAD00407530 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ PRODUCT_NAME = all_unittests;
+ };
+ name = Release;
+ };
+ B88FB009116BDE8400407530 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ GCC_PREPROCESSOR_DEFINITIONS = HAVE_MACH_O_NLIST_H;
+ HEADER_SEARCH_PATHS = (
+ $inherited,
+ ../../../testing,
+ ../../../testing/include,
+ ../../../testing/gtest,
+ ../../../testing/gtest/include,
+ );
+ PRODUCT_NAME = stabs_reader_unittest;
+ };
+ name = Debug;
+ };
+ B88FB00A116BDE8400407530 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ GCC_PREPROCESSOR_DEFINITIONS = HAVE_MACH_O_NLIST_H;
+ HEADER_SEARCH_PATHS = (
+ $inherited,
+ ../../../testing,
+ ../../../testing/include,
+ ../../../testing/gtest,
+ ../../../testing/gtest/include,
+ );
+ PRODUCT_NAME = stabs_reader_unittest;
+ };
+ name = Release;
+ };
+ B88FB025116BE00100407530 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ HEADER_SEARCH_PATHS = (
+ $inherited,
+ ../../../testing,
+ ../../../testing/include,
+ ../../../testing/gtest,
+ ../../../testing/gtest/include,
+ );
+ PRODUCT_NAME = gtestmockall;
+ };
+ name = Debug;
+ };
+ B88FB026116BE00100407530 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ HEADER_SEARCH_PATHS = (
+ $inherited,
+ ../../../testing,
+ ../../../testing/include,
+ ../../../testing/gtest,
+ ../../../testing/gtest/include,
+ );
+ PRODUCT_NAME = gtestmockall;
+ };
+ name = Release;
+ };
+ B88FB0BB116CEAC000407530 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ HEADER_SEARCH_PATHS = (
+ $inherited,
+ ../../../testing,
+ ../../../testing/include,
+ ../../../testing/gtest,
+ ../../../testing/gtest/include,
+ );
+ PRODUCT_NAME = module_unittest;
+ };
+ name = Debug;
+ };
+ B88FB0BC116CEAC000407530 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ HEADER_SEARCH_PATHS = (
+ $inherited,
+ ../../../testing,
+ ../../../testing/include,
+ ../../../testing/gtest,
+ ../../../testing/gtest/include,
+ );
+ PRODUCT_NAME = module_unittest;
+ };
+ name = Release;
+ };
+ B88FB0E1116CEEA800407530 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ HEADER_SEARCH_PATHS = (
+ $inherited,
+ ../../../testing,
+ ../../../testing/include,
+ ../../../testing/gtest,
+ ../../../testing/gtest/include,
+ );
+ PRODUCT_NAME = dwarf2diehandler_unittest;
+ };
+ name = Debug;
+ };
+ B88FB0E2116CEEA800407530 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ HEADER_SEARCH_PATHS = (
+ $inherited,
+ ../../../testing,
+ ../../../testing/include,
+ ../../../testing/gtest,
+ ../../../testing/gtest/include,
+ );
+ PRODUCT_NAME = dwarf2diehandler_unittest;
+ };
+ name = Release;
+ };
+ B88FB0F4116CEF1900407530 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ HEADER_SEARCH_PATHS = (
+ $inherited,
+ ../../../testing,
+ ../../../testing/include,
+ ../../../testing/gtest,
+ ../../../testing/gtest/include,
+ );
+ PRODUCT_NAME = dwarf_line_to_module_unittest;
+ };
+ name = Debug;
+ };
+ B88FB0F5116CEF1900407530 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ HEADER_SEARCH_PATHS = (
+ $inherited,
+ ../../../testing,
+ ../../../testing/include,
+ ../../../testing/gtest,
+ ../../../testing/gtest/include,
+ );
+ PRODUCT_NAME = dwarf_line_to_module_unittest;
+ };
+ name = Release;
+ };
+ B88FB10C116CF07A00407530 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ HEADER_SEARCH_PATHS = (
+ $inherited,
+ ../../../testing,
+ ../../../testing/include,
+ ../../../testing/gtest,
+ ../../../testing/gtest/include,
+ );
+ PRODUCT_NAME = dwarf_cu_to_module_unittest;
+ };
+ name = Debug;
+ };
+ B88FB10D116CF07A00407530 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ HEADER_SEARCH_PATHS = (
+ $inherited,
+ ../../../testing,
+ ../../../testing/include,
+ ../../../testing/gtest,
+ ../../../testing/gtest/include,
+ );
+ PRODUCT_NAME = dwarf_cu_to_module_unittest;
+ };
+ name = Release;
+ };
+ B88FB121116CF28000407530 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ HEADER_SEARCH_PATHS = (
+ $inherited,
+ ../../../testing,
+ ../../../testing/include,
+ ../../../testing/gtest,
+ ../../../testing/gtest/include,
+ );
+ PRODUCT_NAME = dwarf_cfi_to_module_unittest;
+ };
+ name = Debug;
+ };
+ B88FB122116CF28000407530 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ HEADER_SEARCH_PATHS = (
+ $inherited,
+ ../../../testing,
+ ../../../testing/include,
+ ../../../testing/gtest,
+ ../../../testing/gtest/include,
+ );
+ PRODUCT_NAME = dwarf_cfi_to_module_unittest;
+ };
+ name = Release;
+ };
+ B88FB137116CF30F00407530 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ HEADER_SEARCH_PATHS = (
+ $inherited,
+ ../../../testing,
+ ../../../testing/include,
+ ../../../testing/gtest,
+ ../../../testing/gtest/include,
+ );
+ PRODUCT_NAME = bytereader_unittest;
+ };
+ name = Debug;
+ };
+ B88FB138116CF30F00407530 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ HEADER_SEARCH_PATHS = (
+ $inherited,
+ ../../../testing,
+ ../../../testing/include,
+ ../../../testing/gtest,
+ ../../../testing/gtest/include,
+ );
+ PRODUCT_NAME = bytereader_unittest;
+ };
+ name = Release;
+ };
+ B88FB14D116CF4A800407530 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ HEADER_SEARCH_PATHS = (
+ $inherited,
+ ../../../testing,
+ ../../../testing/include,
+ ../../../testing/gtest,
+ ../../../testing/gtest/include,
+ );
+ PRODUCT_NAME = byte_cursor_unittest;
+ };
+ name = Debug;
+ };
+ B88FB14E116CF4A800407530 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ HEADER_SEARCH_PATHS = (
+ $inherited,
+ ../../../testing,
+ ../../../testing/include,
+ ../../../testing/gtest,
+ ../../../testing/gtest/include,
+ );
+ PRODUCT_NAME = byte_cursor_unittest;
+ };
+ name = Release;
+ };
+ B89E0E761166575300DD08C9 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ PRODUCT_NAME = macho_dump;
+ };
+ name = Debug;
+ };
+ B89E0E771166575300DD08C9 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ PRODUCT_NAME = macho_dump;
+ };
+ name = Release;
+ };
+ B89E0E9711665A6400DD08C9 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ HEADER_SEARCH_PATHS = (
+ $inherited,
+ ../../../testing,
+ ../../../testing/include,
+ ../../../testing/gtest,
+ ../../../testing/gtest/include,
+ );
+ PRODUCT_NAME = macho_reader_unittest;
+ };
+ name = Debug;
+ };
+ B89E0E9811665A6400DD08C9 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ HEADER_SEARCH_PATHS = (
+ $inherited,
+ ../../../testing,
+ ../../../testing/include,
+ ../../../testing/gtest,
+ ../../../testing/gtest/include,
+ );
+ PRODUCT_NAME = macho_reader_unittest;
+ };
+ name = Release;
+ };
+ B8C5B5131166531B00D34F4E /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ GCC_PREPROCESSOR_DEFINITIONS = HAVE_MACH_O_NLIST_H;
+ GCC_VERSION = "";
+ PRODUCT_NAME = dump_syms;
+ };
+ name = Debug;
+ };
+ B8C5B5141166531B00D34F4E /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ GCC_PREPROCESSOR_DEFINITIONS = HAVE_MACH_O_NLIST_H;
+ GCC_VERSION = "";
+ PRODUCT_NAME = dump_syms;
+ };
+ name = Release;
+ };
+ D21F97D411CBA0F200239E38 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ HEADER_SEARCH_PATHS = (
+ $inherited,
+ ../../../testing,
+ ../../../testing/include,
+ ../../../testing/gtest,
+ ../../../testing/gtest/include,
+ );
+ PRODUCT_NAME = test_assembler_unittest;
+ };
+ name = Debug;
+ };
+ D21F97D511CBA0F200239E38 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ HEADER_SEARCH_PATHS = (
+ $inherited,
+ ../../../testing,
+ ../../../testing/include,
+ ../../../testing/gtest,
+ ../../../testing/gtest/include,
+ );
+ PRODUCT_NAME = test_assembler_unittest;
+ };
+ name = Release;
+ };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+ 1DEB927808733DD40010E9CD /* Build configuration list for PBXProject "dump_syms" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 1DEB927908733DD40010E9CD /* Debug */,
+ 1DEB927A08733DD40010E9CD /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ B84A9202116CF7F0006C210E /* Build configuration list for PBXNativeTarget "stabs_to_module_unittest" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ B84A91F6116CF784006C210E /* Debug */,
+ B84A91F7116CF784006C210E /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ B88FAF33116A594800407530 /* Build configuration list for PBXNativeTarget "dwarf2reader_cfi_unittest" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ B88FAF31116A591F00407530 /* Debug */,
+ B88FAF32116A591F00407530 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ B88FAFCC116BDCCC00407530 /* Build configuration list for PBXAggregateTarget "all_unittests" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ B88FAFCA116BDCAD00407530 /* Debug */,
+ B88FAFCB116BDCAD00407530 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ B88FB013116BDEC800407530 /* Build configuration list for PBXNativeTarget "stabs_reader_unittest" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ B88FB009116BDE8400407530 /* Debug */,
+ B88FB00A116BDE8400407530 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ B88FB027116BE02900407530 /* Build configuration list for PBXNativeTarget "gtestmockall" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ B88FB025116BE00100407530 /* Debug */,
+ B88FB026116BE00100407530 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ B88FB0BE116CEAFE00407530 /* Build configuration list for PBXNativeTarget "module_unittest" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ B88FB0BB116CEAC000407530 /* Debug */,
+ B88FB0BC116CEAC000407530 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ B88FB0E4116CEECE00407530 /* Build configuration list for PBXNativeTarget "dwarf2diehandler_unittest" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ B88FB0E1116CEEA800407530 /* Debug */,
+ B88FB0E2116CEEA800407530 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ B88FB0F9116CEF9800407530 /* Build configuration list for PBXNativeTarget "dwarf_line_to_module_unittest" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ B88FB0F4116CEF1900407530 /* Debug */,
+ B88FB0F5116CEF1900407530 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ B88FB111116CF0A800407530 /* Build configuration list for PBXNativeTarget "dwarf_cu_to_module_unittest" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ B88FB10C116CF07A00407530 /* Debug */,
+ B88FB10D116CF07A00407530 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ B88FB128116CF2C800407530 /* Build configuration list for PBXNativeTarget "dwarf_cfi_to_module_unittest" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ B88FB121116CF28000407530 /* Debug */,
+ B88FB122116CF28000407530 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ B88FB13A116CF33400407530 /* Build configuration list for PBXNativeTarget "bytereader_unittest" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ B88FB137116CF30F00407530 /* Debug */,
+ B88FB138116CF30F00407530 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ B88FB159116CF4F900407530 /* Build configuration list for PBXNativeTarget "byte_cursor_unittest" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ B88FB14D116CF4A800407530 /* Debug */,
+ B88FB14E116CF4A800407530 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ B89E0E7F116657A100DD08C9 /* Build configuration list for PBXNativeTarget "macho_dump" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ B89E0E761166575300DD08C9 /* Debug */,
+ B89E0E771166575300DD08C9 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ B89E0E9E11665A9600DD08C9 /* Build configuration list for PBXNativeTarget "macho_reader_unittest" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ B89E0E9711665A6400DD08C9 /* Debug */,
+ B89E0E9811665A6400DD08C9 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ B8C5B5151166533900D34F4E /* Build configuration list for PBXNativeTarget "dump_syms" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ B8C5B5131166531B00D34F4E /* Debug */,
+ B8C5B5141166531B00D34F4E /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ D21F97D611CBA11000239E38 /* Build configuration list for PBXNativeTarget "test_assembler_unittest" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ D21F97D411CBA0F200239E38 /* Debug */,
+ D21F97D511CBA0F200239E38 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+/* End XCConfigurationList section */
+ };
+ rootObject = 08FB7793FE84155DC02AAC07 /* Project object */;
+}
diff --git a/toolkit/crashreporter/google-breakpad/src/tools/mac/dump_syms/dump_syms_tool.cc b/toolkit/crashreporter/google-breakpad/src/tools/mac/dump_syms/dump_syms_tool.cc
new file mode 100644
index 000000000..6f68457b4
--- /dev/null
+++ b/toolkit/crashreporter/google-breakpad/src/tools/mac/dump_syms/dump_syms_tool.cc
@@ -0,0 +1,264 @@
+// -*- mode: c++ -*-
+
+// 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.
+
+// dump_syms_tool.cc: Command line tool that uses the DumpSymbols class.
+// TODO(waylonis): accept stdin
+
+#include <mach-o/arch.h>
+#include <unistd.h>
+
+#include <algorithm>
+#include <iostream>
+#include <vector>
+
+#include "common/mac/dump_syms.h"
+#include "common/mac/arch_utilities.h"
+#include "common/mac/macho_utilities.h"
+#include "common/scoped_ptr.h"
+
+using google_breakpad::DumpSymbols;
+using google_breakpad::Module;
+using google_breakpad::scoped_ptr;
+using std::vector;
+
+struct Options {
+ Options()
+ : srcPath(), dsymPath(), arch(), header_only(false),
+ cfi(true), handle_inter_cu_refs(true) {}
+
+ string srcPath;
+ string dsymPath;
+ const NXArchInfo *arch;
+ bool header_only;
+ bool cfi;
+ bool handle_inter_cu_refs;
+};
+
+static bool StackFrameEntryComparator(const Module::StackFrameEntry* a,
+ const Module::StackFrameEntry* b) {
+ return a->address < b->address;
+}
+
+// Copy the CFI data from |from_module| into |to_module|, for any non-
+// overlapping ranges.
+static void CopyCFIDataBetweenModules(Module* to_module,
+ const Module* from_module) {
+ typedef vector<Module::StackFrameEntry*>::const_iterator Iterator;
+
+ // Get the CFI data from both the source and destination modules and ensure
+ // it is sorted by start address.
+ vector<Module::StackFrameEntry*> from_data;
+ from_module->GetStackFrameEntries(&from_data);
+ std::sort(from_data.begin(), from_data.end(), &StackFrameEntryComparator);
+
+ vector<Module::StackFrameEntry*> to_data;
+ to_module->GetStackFrameEntries(&to_data);
+ std::sort(to_data.begin(), to_data.end(), &StackFrameEntryComparator);
+
+ Iterator to_it = to_data.begin();
+
+ for (Iterator it = from_data.begin(); it != from_data.end(); ++it) {
+ Module::StackFrameEntry* from_entry = *it;
+ Module::Address from_entry_end = from_entry->address + from_entry->size;
+
+ // Find the first CFI record in the |to_module| that does not have an
+ // address less than the entry to be copied.
+ while (to_it != to_data.end()) {
+ if (from_entry->address > (*to_it)->address)
+ ++to_it;
+ else
+ break;
+ }
+
+ // If the entry does not overlap, then it is safe to copy to |to_module|.
+ if (to_it == to_data.end() || (from_entry->address < (*to_it)->address &&
+ from_entry_end < (*to_it)->address)) {
+ to_module->AddStackFrameEntry(new Module::StackFrameEntry(*from_entry));
+ }
+ }
+}
+
+static bool Start(const Options &options) {
+ SymbolData symbol_data = options.cfi ? ALL_SYMBOL_DATA : NO_CFI;
+ DumpSymbols dump_symbols(symbol_data, options.handle_inter_cu_refs);
+
+ // For x86_64 binaries, the CFI data is in the __TEXT,__eh_frame of the
+ // Mach-O file, which is not copied into the dSYM. Whereas in i386, the CFI
+ // data is in the __DWARF,__debug_frame section, which is moved into the
+ // dSYM. Therefore, to get x86_64 CFI data, dump_syms needs to look at both
+ // the dSYM and the Mach-O file. If both paths are present and CFI was
+ // requested, then consider the Module as "split" and dump all the debug data
+ // from the primary debug info file, the dSYM, and then dump additional CFI
+ // data from the source Mach-O file.
+ bool split_module =
+ !options.dsymPath.empty() && !options.srcPath.empty() && options.cfi;
+ const string& primary_file =
+ split_module ? options.dsymPath : options.srcPath;
+
+ if (!dump_symbols.Read(primary_file))
+ return false;
+
+ if (options.arch) {
+ if (!dump_symbols.SetArchitecture(options.arch->cputype,
+ options.arch->cpusubtype)) {
+ fprintf(stderr, "%s: no architecture '%s' is present in file.\n",
+ primary_file.c_str(), options.arch->name);
+ size_t available_size;
+ const SuperFatArch *available =
+ dump_symbols.AvailableArchitectures(&available_size);
+ if (available_size == 1)
+ fprintf(stderr, "the file's architecture is: ");
+ else
+ fprintf(stderr, "architectures present in the file are:\n");
+ for (size_t i = 0; i < available_size; i++) {
+ const SuperFatArch *arch = &available[i];
+ const NXArchInfo *arch_info =
+ google_breakpad::BreakpadGetArchInfoFromCpuType(
+ arch->cputype, arch->cpusubtype);
+ if (arch_info)
+ fprintf(stderr, "%s (%s)\n", arch_info->name, arch_info->description);
+ else
+ fprintf(stderr, "unrecognized cpu type 0x%x, subtype 0x%x\n",
+ arch->cputype, arch->cpusubtype);
+ }
+ return false;
+ }
+ }
+
+ if (options.header_only)
+ return dump_symbols.WriteSymbolFileHeader(std::cout);
+
+ // Read the primary file into a Breakpad Module.
+ Module* module = NULL;
+ if (!dump_symbols.ReadSymbolData(&module))
+ return false;
+ scoped_ptr<Module> scoped_module(module);
+
+ // If this is a split module, read the secondary Mach-O file, from which the
+ // CFI data will be extracted.
+ if (split_module && primary_file == options.dsymPath) {
+ if (!dump_symbols.Read(options.srcPath))
+ return false;
+
+ Module* cfi_module = NULL;
+ if (!dump_symbols.ReadSymbolData(&cfi_module))
+ return false;
+ scoped_ptr<Module> scoped_cfi_module(cfi_module);
+
+ // Ensure that the modules are for the same debug code file.
+ if (cfi_module->name() != module->name() ||
+ cfi_module->os() != module->os() ||
+ cfi_module->architecture() != module->architecture() ||
+ cfi_module->identifier() != module->identifier()) {
+ fprintf(stderr, "Cannot generate a symbol file from split sources that do"
+ " not match.\n");
+ return false;
+ }
+
+ CopyCFIDataBetweenModules(module, cfi_module);
+ }
+
+ return module->Write(std::cout, symbol_data);
+}
+
+//=============================================================================
+static void Usage(int argc, const char *argv[]) {
+ fprintf(stderr, "Output a Breakpad symbol file from a Mach-o file.\n");
+ fprintf(stderr, "Usage: %s [-a ARCHITECTURE] [-c] [-g dSYM path] "
+ "<Mach-o file>\n", argv[0]);
+ fprintf(stderr, "\t-i: Output module header information only.\n");
+ fprintf(stderr, "\t-a: Architecture type [default: native, or whatever is\n");
+ fprintf(stderr, "\t in the file, if it contains only one architecture]\n");
+ fprintf(stderr, "\t-g: Debug symbol file (dSYM) to dump in addition to the "
+ "Mach-o file\n");
+ fprintf(stderr, "\t-c: Do not generate CFI section\n");
+ fprintf(stderr, "\t-r: Do not handle inter-compilation unit references\n");
+ fprintf(stderr, "\t-h: Usage\n");
+ fprintf(stderr, "\t-?: Usage\n");
+}
+
+//=============================================================================
+static void SetupOptions(int argc, const char *argv[], Options *options) {
+ extern int optind;
+ signed char ch;
+
+ while ((ch = getopt(argc, (char * const *)argv, "ia:g:chr?")) != -1) {
+ switch (ch) {
+ case 'i':
+ options->header_only = true;
+ break;
+ case 'a': {
+ const NXArchInfo *arch_info =
+ google_breakpad::BreakpadGetArchInfoFromName(optarg);
+ if (!arch_info) {
+ fprintf(stderr, "%s: Invalid architecture: %s\n", argv[0], optarg);
+ Usage(argc, argv);
+ exit(1);
+ }
+ options->arch = arch_info;
+ break;
+ }
+ case 'g':
+ options->dsymPath = optarg;
+ break;
+ case 'c':
+ options->cfi = false;
+ break;
+ case 'r':
+ options->handle_inter_cu_refs = false;
+ break;
+ case '?':
+ case 'h':
+ Usage(argc, argv);
+ exit(0);
+ break;
+ }
+ }
+
+ if ((argc - optind) != 1) {
+ fprintf(stderr, "Must specify Mach-o file\n");
+ Usage(argc, argv);
+ exit(1);
+ }
+
+ options->srcPath = argv[optind];
+}
+
+//=============================================================================
+int main (int argc, const char * argv[]) {
+ Options options;
+ bool result;
+
+ SetupOptions(argc, argv, &options);
+ result = Start(options);
+
+ return !result;
+}
diff --git a/toolkit/crashreporter/google-breakpad/src/tools/mac/dump_syms/macho_dump.cc b/toolkit/crashreporter/google-breakpad/src/tools/mac/dump_syms/macho_dump.cc
new file mode 100644
index 000000000..d882bbe88
--- /dev/null
+++ b/toolkit/crashreporter/google-breakpad/src/tools/mac/dump_syms/macho_dump.cc
@@ -0,0 +1,203 @@
+// Copyright (c) 2010, 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.
+
+// Original author: Jim Blandy <jimb@mozilla.com> <jimb@red-bean.com>
+
+// macho_dump.cc: Dump the contents of a Mach-O file. This is mostly
+// a test program for the Mach_O::FatReader and Mach_O::Reader classes.
+
+#include <errno.h>
+#include <fcntl.h>
+#include <libgen.h>
+#include <mach-o/arch.h>
+#include <sys/mman.h>
+#include <stdint.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include <sstream>
+#include <string>
+#include <vector>
+
+#include "common/byte_cursor.h"
+#include "common/mac/arch_utilities.h"
+#include "common/mac/macho_reader.h"
+
+using google_breakpad::ByteBuffer;
+using std::ostringstream;
+using std::string;
+using std::vector;
+
+namespace {
+namespace mach_o = google_breakpad::mach_o;
+
+string program_name;
+
+int check_syscall(int result, const char *operation, const char *filename) {
+ if (result < 0) {
+ fprintf(stderr, "%s: %s '%s': %s\n",
+ program_name.c_str(), operation,
+ filename, strerror(errno));
+ exit(1);
+ }
+ return result;
+}
+
+class DumpSection: public mach_o::Reader::SectionHandler {
+ public:
+ DumpSection() : index_(0) { }
+ bool HandleSection(const mach_o::Section &section) {
+ printf(" section %d '%s' in segment '%s'\n"
+ " address: 0x%llx\n"
+ " alignment: 1 << %d B\n"
+ " flags: %d\n"
+ " size: %ld\n",
+ index_++, section.section_name.c_str(), section.segment_name.c_str(),
+ section.address, section.align,
+ mach_o::SectionFlags(section.flags),
+ section.contents.Size());
+ return true;
+ }
+
+ private:
+ int index_;
+};
+
+class DumpCommand: public mach_o::Reader::LoadCommandHandler {
+ public:
+ DumpCommand(mach_o::Reader *reader) : reader_(reader), index_(0) { }
+ bool UnknownCommand(mach_o::LoadCommandType type,
+ const ByteBuffer &contents) {
+ printf(" load command %d: %d", index_++, type);
+ return true;
+ }
+ bool SegmentCommand(const mach_o::Segment &segment) {
+ printf(" load command %d: %s-bit segment '%s'\n"
+ " address: 0x%llx\n"
+ " memory size: 0x%llx\n"
+ " maximum protection: 0x%x\n"
+ " initial protection: 0x%x\n"
+ " flags: %d\n"
+ " section_list size: %ld B\n",
+ index_++, (segment.bits_64 ? "64" : "32"), segment.name.c_str(),
+ segment.vmaddr, segment.vmsize, segment.maxprot,
+ segment.initprot, mach_o::SegmentFlags(segment.flags),
+ segment.section_list.Size());
+
+ DumpSection dump_section;
+ return reader_->WalkSegmentSections(segment, &dump_section);
+ }
+ private:
+ mach_o::Reader *reader_;
+ int index_;
+};
+
+void DumpFile(const char *filename) {
+ int fd = check_syscall(open(filename, O_RDONLY), "opening", filename);
+ struct stat attributes;
+ check_syscall(fstat(fd, &attributes),
+ "getting file attributes for", filename);
+ void *mapping = mmap(NULL, attributes.st_size, PROT_READ,
+ MAP_PRIVATE, fd, 0);
+ close(fd);
+ check_syscall(mapping == (void *)-1 ? -1 : 0,
+ "mapping contents of", filename);
+
+ mach_o::FatReader::Reporter fat_reporter(filename);
+ mach_o::FatReader fat_reader(&fat_reporter);
+ if (!fat_reader.Read(reinterpret_cast<uint8_t *>(mapping),
+ attributes.st_size)) {
+ exit(1);
+ }
+ printf("filename: %s\n", filename);
+ size_t object_files_size;
+ const SuperFatArch* super_fat_object_files =
+ fat_reader.object_files(&object_files_size);
+ struct fat_arch *object_files;
+ if (!super_fat_object_files->ConvertToFatArch(object_files)) {
+ exit(1);
+ }
+ printf(" object file count: %ld\n", object_files_size);
+ for (size_t i = 0; i < object_files_size; i++) {
+ const struct fat_arch &file = object_files[i];
+ const NXArchInfo *fat_arch_info =
+ google_breakpad::BreakpadGetArchInfoFromCpuType(
+ file.cputype, file.cpusubtype);
+ printf("\n object file %ld:\n"
+ " fat header:\n:"
+ " CPU type: %s (%s)\n"
+ " size: %d B\n"
+ " alignment: 1<<%d B\n",
+ i, fat_arch_info->name, fat_arch_info->description,
+ file.size, file.align);
+
+ ostringstream name;
+ name << filename;
+ if (object_files_size > 1)
+ name << ", object file #" << i;
+ ByteBuffer file_contents(reinterpret_cast<uint8_t *>(mapping)
+ + file.offset, file.size);
+ mach_o::Reader::Reporter reporter(name.str());
+ mach_o::Reader reader(&reporter);
+ if (!reader.Read(file_contents, file.cputype, file.cpusubtype)) {
+ exit(1);
+ }
+
+ const NXArchInfo *macho_arch_info =
+ NXGetArchInfoFromCpuType(reader.cpu_type(),
+ reader.cpu_subtype());
+ printf(" Mach-O header:\n"
+ " word size: %s\n"
+ " CPU type: %s (%s)\n"
+ " File type: %d\n"
+ " flags: %x\n",
+ (reader.bits_64() ? "64 bits" : "32 bits"),
+ macho_arch_info->name, macho_arch_info->description,
+ reader.file_type(), reader.flags());
+
+ DumpCommand dump_command(&reader);
+ reader.WalkLoadCommands(&dump_command);
+ }
+ munmap(mapping, attributes.st_size);
+}
+
+} // namespace
+
+int main(int argc, char **argv) {
+ program_name = basename(argv[0]);
+ if (argc == 1) {
+ fprintf(stderr, "Usage: %s FILE ...\n"
+ "Dump the contents of the Mach-O or fat binary files "
+ "'FILE ...'.\n", program_name.c_str());
+ }
+ for (int i = 1; i < argc; i++) {
+ DumpFile(argv[i]);
+ }
+}
diff --git a/toolkit/crashreporter/google-breakpad/src/tools/mac/dump_syms/moz.build b/toolkit/crashreporter/google-breakpad/src/tools/mac/dump_syms/moz.build
new file mode 100644
index 000000000..99ae82aa7
--- /dev/null
+++ b/toolkit/crashreporter/google-breakpad/src/tools/mac/dump_syms/moz.build
@@ -0,0 +1,40 @@
+# -*- 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_tool.cc',
+]
+
+HOST_CXXFLAGS += [
+ '-O2',
+ '-g',
+ '-pthread',
+ '-stdlib=libc++',
+]
+
+# Order matters here, but HOST_USE_LIBS must be sorted.
+HOST_USE_LIBS += [
+ 'host_breakpad_mac_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/mac',
+]
+
+if CONFIG['HOST_OS_ARCH'] != 'Darwin':
+ HOST_CXXFLAGS += [
+ '-I%s/toolkit/crashreporter/google-breakpad/src/third_party/mac_headers/' % TOPSRCDIR,
+ ]
+
+include('/toolkit/crashreporter/crashreporter.mozbuild')
diff --git a/toolkit/crashreporter/google-breakpad/src/tools/mac/symupload/minidump_upload.m b/toolkit/crashreporter/google-breakpad/src/tools/mac/symupload/minidump_upload.m
new file mode 100644
index 000000000..741ad765e
--- /dev/null
+++ b/toolkit/crashreporter/google-breakpad/src/tools/mac/symupload/minidump_upload.m
@@ -0,0 +1,135 @@
+// 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.m: 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
+
+#import <unistd.h>
+
+#import <Foundation/Foundation.h>
+
+#import "common/mac/HTTPMultipartUpload.h"
+
+typedef struct {
+ NSString *minidumpPath;
+ NSString *uploadURLStr;
+ NSString *product;
+ NSString *version;
+ BOOL success;
+} Options;
+
+//=============================================================================
+static void Start(Options *options) {
+ NSURL *url = [NSURL URLWithString:options->uploadURLStr];
+ HTTPMultipartUpload *ul = [[HTTPMultipartUpload alloc] initWithURL:url];
+ NSMutableDictionary *parameters = [NSMutableDictionary dictionary];
+
+ // Add parameters
+ [parameters setObject:options->product forKey:@"prod"];
+ [parameters setObject:options->version forKey:@"ver"];
+ [ul setParameters:parameters];
+
+ // Add file
+ [ul addFileAtPath:options->minidumpPath name:@"upload_file_minidump"];
+
+ // Send it
+ NSError *error = nil;
+ NSData *data = [ul send:&error];
+ NSString *result = [[NSString alloc] initWithData:data
+ encoding:NSUTF8StringEncoding];
+
+ NSLog(@"Send: %@", error ? [error description] : @"No Error");
+ NSLog(@"Response: %ld", (long)[[ul response] statusCode]);
+ NSLog(@"Result: %lu bytes\n%@", (unsigned long)[data length], result);
+
+ [result release];
+ [ul release];
+ options->success = !error;
+}
+
+//=============================================================================
+static void
+Usage(int argc, const char *argv[]) {
+ fprintf(stderr, "Submit minidump information.\n");
+ fprintf(stderr, "Usage: %s -p <product> -v <version> <minidump> "
+ "<upload-URL>\n", argv[0]);
+ fprintf(stderr, "<minidump> should be a minidump.\n");
+ fprintf(stderr, "<upload-URL> is the destination for the upload\n");
+
+ fprintf(stderr, "\t-h: Usage\n");
+ fprintf(stderr, "\t-?: Usage\n");
+}
+
+//=============================================================================
+static void
+SetupOptions(int argc, const char *argv[], Options *options) {
+ extern int optind;
+ char ch;
+
+ while ((ch = getopt(argc, (char * const *)argv, "p:v:h?")) != -1) {
+ switch (ch) {
+ case 'p':
+ options->product = [NSString stringWithUTF8String:optarg];
+ break;
+ case 'v':
+ options->version = [NSString stringWithUTF8String:optarg];
+ break;
+
+ default:
+ Usage(argc, argv);
+ exit(0);
+ 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 = [NSString stringWithUTF8String:argv[optind]];
+ options->uploadURLStr = [NSString stringWithUTF8String:argv[optind + 1]];
+}
+
+//=============================================================================
+int main (int argc, const char * argv[]) {
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+ Options options;
+
+ bzero(&options, sizeof(Options));
+ SetupOptions(argc, argv, &options);
+ Start(&options);
+
+ [pool release];
+ return options.success ? 0 : 1;
+}
diff --git a/toolkit/crashreporter/google-breakpad/src/tools/mac/symupload/symupload.m b/toolkit/crashreporter/google-breakpad/src/tools/mac/symupload/symupload.m
new file mode 100644
index 000000000..a7cce7b00
--- /dev/null
+++ b/toolkit/crashreporter/google-breakpad/src/tools/mac/symupload/symupload.m
@@ -0,0 +1,204 @@
+// 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.m: 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"
+// os: the operating system that the module was built for
+// cpu: the CPU that the module was built for (x86 or ppc)
+// symbol_file: the contents of the breakpad-format symbol file
+
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include <Foundation/Foundation.h>
+#include "HTTPMultipartUpload.h"
+
+typedef struct {
+ NSString *symbolsPath;
+ NSString *uploadURLStr;
+ BOOL success;
+} Options;
+
+//=============================================================================
+static NSArray *ModuleDataForSymbolFile(NSString *file) {
+ NSFileHandle *fh = [NSFileHandle fileHandleForReadingAtPath:file];
+ NSData *data = [fh readDataOfLength:1024];
+ NSString *str = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
+ NSScanner *scanner = [NSScanner scannerWithString:str];
+ NSString *line;
+ NSMutableArray *parts = nil;
+ const int MODULE_ID_INDEX = 3;
+
+ if ([scanner scanUpToString:@"\n" intoString:&line]) {
+ parts = [[NSMutableArray alloc] init];
+ NSScanner *moduleInfoScanner = [NSScanner scannerWithString:line];
+ NSString *moduleInfo;
+ // Get everything BEFORE the module name. None of these properties
+ // can have spaces.
+ for (int i = 0; i <= MODULE_ID_INDEX; i++) {
+ [moduleInfoScanner scanUpToString:@" " intoString:&moduleInfo];
+ [parts addObject:moduleInfo];
+ }
+
+ // Now get the module name. This can have a space so we scan to
+ // the end of the line.
+ [moduleInfoScanner scanUpToString:@"\n" intoString:&moduleInfo];
+ [parts addObject:moduleInfo];
+ }
+
+ [str release];
+
+ return parts;
+}
+
+//=============================================================================
+static void Start(Options *options) {
+ NSURL *url = [NSURL URLWithString:options->uploadURLStr];
+ HTTPMultipartUpload *ul = [[HTTPMultipartUpload alloc] initWithURL:url];
+ NSMutableDictionary *parameters = [NSMutableDictionary dictionary];
+ NSArray *moduleParts = ModuleDataForSymbolFile(options->symbolsPath);
+ NSMutableString *compactedID =
+ [NSMutableString stringWithString:[moduleParts objectAtIndex:3]];
+ [compactedID replaceOccurrencesOfString:@"-" withString:@"" options:0
+ range:NSMakeRange(0, [compactedID length])];
+
+ // Add parameters
+ [parameters setObject:compactedID forKey:@"debug_identifier"];
+
+ // MODULE <os> <cpu> <uuid> <module-name>
+ // 0 1 2 3 4
+ [parameters setObject:[moduleParts objectAtIndex:1] forKey:@"os"];
+ [parameters setObject:[moduleParts objectAtIndex:2] forKey:@"cpu"];
+ [parameters setObject:[moduleParts objectAtIndex:4] forKey:@"debug_file"];
+ [parameters setObject:[moduleParts objectAtIndex:4] forKey:@"code_file"];
+ [ul setParameters:parameters];
+
+ NSArray *keys = [parameters allKeys];
+ int count = [keys count];
+ for (int i = 0; i < count; ++i) {
+ NSString *key = [keys objectAtIndex:i];
+ NSString *value = [parameters objectForKey:key];
+ fprintf(stdout, "'%s' = '%s'\n", [key UTF8String],
+ [value UTF8String]);
+ }
+
+ // Add file
+ [ul addFileAtPath:options->symbolsPath name:@"symbol_file"];
+
+ // Send it
+ NSError *error = nil;
+ NSData *data = [ul send:&error];
+ NSString *result = [[NSString alloc] initWithData:data
+ encoding:NSUTF8StringEncoding];
+ int status = [[ul response] statusCode];
+
+ fprintf(stdout, "Send: %s\n", error ? [[error description] UTF8String] :
+ "No Error");
+ fprintf(stdout, "Response: %d\n", status);
+ fprintf(stdout, "Result: %lu bytes\n%s\n",
+ (unsigned long)[data length], [result UTF8String]);
+
+ [result release];
+ [ul release];
+ options->success = !error && status==200;
+}
+
+//=============================================================================
+static void
+Usage(int argc, const char *argv[]) {
+ fprintf(stderr, "Submit symbol information.\n");
+ fprintf(stderr, "Usage: %s <symbols> <upload-URL>\n", argv[0]);
+ 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, "\t-h: Usage\n");
+ fprintf(stderr, "\t-?: Usage\n");
+}
+
+//=============================================================================
+static void
+SetupOptions(int argc, const char *argv[], Options *options) {
+ extern int optind;
+ char ch;
+
+ while ((ch = getopt(argc, (char * const *)argv, "h?")) != -1) {
+ switch (ch) {
+ default:
+ Usage(argc, argv);
+ exit(0);
+ break;
+ }
+ }
+
+ if ((argc - optind) != 2) {
+ fprintf(stderr, "%s: Missing symbols file and/or upload-URL\n", argv[0]);
+ Usage(argc, argv);
+ exit(1);
+ }
+
+ int fd = open(argv[optind], O_RDONLY);
+ if (fd < 0) {
+ fprintf(stderr, "%s: %s: %s\n", argv[0], argv[optind], strerror(errno));
+ exit(1);
+ }
+
+ struct stat statbuf;
+ if (fstat(fd, &statbuf) < 0) {
+ fprintf(stderr, "%s: %s: %s\n", argv[0], argv[optind], strerror(errno));
+ close(fd);
+ exit(1);
+ }
+ close(fd);
+
+ if (!S_ISREG(statbuf.st_mode)) {
+ fprintf(stderr, "%s: %s: not a regular file\n", argv[0], argv[optind]);
+ exit(1);
+ }
+
+ options->symbolsPath = [NSString stringWithUTF8String:argv[optind]];
+ options->uploadURLStr = [NSString stringWithUTF8String:argv[optind + 1]];
+}
+
+//=============================================================================
+int main (int argc, const char * argv[]) {
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+ Options options;
+
+ bzero(&options, sizeof(Options));
+ SetupOptions(argc, argv, &options);
+ Start(&options);
+
+ [pool release];
+ return options.success ? 0 : 1;
+}
diff --git a/toolkit/crashreporter/google-breakpad/src/tools/mac/symupload/symupload.xcodeproj/project.pbxproj b/toolkit/crashreporter/google-breakpad/src/tools/mac/symupload/symupload.xcodeproj/project.pbxproj
new file mode 100644
index 000000000..a6a78dc5f
--- /dev/null
+++ b/toolkit/crashreporter/google-breakpad/src/tools/mac/symupload/symupload.xcodeproj/project.pbxproj
@@ -0,0 +1,254 @@
+// !$*UTF8*$!
+{
+ archiveVersion = 1;
+ classes = {
+ };
+ objectVersion = 45;
+ objects = {
+
+/* Begin PBXBuildFile section */
+ 8B31022C11F0CEBD00FCF3E4 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 08FB779EFE84155DC02AAC07 /* Foundation.framework */; };
+ 8DD76F9A0486AA7600D96B5E /* symupload.m in Sources */ = {isa = PBXBuildFile; fileRef = 08FB7796FE84155DC02AAC07 /* symupload.m */; settings = {ATTRIBUTES = (); }; };
+ 8DD76F9C0486AA7600D96B5E /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 08FB779EFE84155DC02AAC07 /* Foundation.framework */; };
+ 9BC1D49E0B37427A00F2A2B4 /* minidump_upload.m in Sources */ = {isa = PBXBuildFile; fileRef = 9BD836000B0544BA0055103E /* minidump_upload.m */; };
+ 9BD8336A0B03E4080055103E /* HTTPMultipartUpload.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 9BD833680B03E4080055103E /* HTTPMultipartUpload.h */; };
+ 9BD8336B0B03E4080055103E /* HTTPMultipartUpload.m in Sources */ = {isa = PBXBuildFile; fileRef = 9BD833690B03E4080055103E /* HTTPMultipartUpload.m */; };
+ 9BD836180B0549F70055103E /* HTTPMultipartUpload.m in Sources */ = {isa = PBXBuildFile; fileRef = 9BD833690B03E4080055103E /* HTTPMultipartUpload.m */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXCopyFilesBuildPhase section */
+ 8DD76F9E0486AA7600D96B5E /* CopyFiles */ = {
+ isa = PBXCopyFilesBuildPhase;
+ buildActionMask = 8;
+ dstPath = /usr/share/man/man1/;
+ dstSubfolderSpec = 0;
+ files = (
+ 9BD8336A0B03E4080055103E /* HTTPMultipartUpload.h in CopyFiles */,
+ );
+ runOnlyForDeploymentPostprocessing = 1;
+ };
+/* End PBXCopyFilesBuildPhase section */
+
+/* Begin PBXFileReference section */
+ 08FB7796FE84155DC02AAC07 /* symupload.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = symupload.m; sourceTree = "<group>"; };
+ 08FB779EFE84155DC02AAC07 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
+ 8B31022B11F0CE6900FCF3E4 /* Breakpad.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Breakpad.xcconfig; path = ../../../common/mac/Breakpad.xcconfig; sourceTree = SOURCE_ROOT; };
+ 8B3102B611F0D5CE00FCF3E4 /* BreakpadDebug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = BreakpadDebug.xcconfig; path = ../../../common/mac/BreakpadDebug.xcconfig; sourceTree = SOURCE_ROOT; };
+ 8B3102B711F0D5CE00FCF3E4 /* BreakpadRelease.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = BreakpadRelease.xcconfig; path = ../../../common/mac/BreakpadRelease.xcconfig; sourceTree = SOURCE_ROOT; };
+ 8DD76FA10486AA7600D96B5E /* symupload */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = symupload; sourceTree = BUILT_PRODUCTS_DIR; };
+ 9BD833680B03E4080055103E /* HTTPMultipartUpload.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = HTTPMultipartUpload.h; path = ../../../common/mac/HTTPMultipartUpload.h; sourceTree = "<group>"; };
+ 9BD833690B03E4080055103E /* HTTPMultipartUpload.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = HTTPMultipartUpload.m; path = ../../../common/mac/HTTPMultipartUpload.m; sourceTree = "<group>"; };
+ 9BD835FB0B0544950055103E /* minidump_upload */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = minidump_upload; sourceTree = BUILT_PRODUCTS_DIR; };
+ 9BD836000B0544BA0055103E /* minidump_upload.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = minidump_upload.m; sourceTree = "<group>"; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+ 8DD76F9B0486AA7600D96B5E /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 8DD76F9C0486AA7600D96B5E /* Foundation.framework in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ 9BD835F90B0544950055103E /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 8B31022C11F0CEBD00FCF3E4 /* Foundation.framework in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+ 08FB7794FE84155DC02AAC07 /* symupload */ = {
+ isa = PBXGroup;
+ children = (
+ 8B31022B11F0CE6900FCF3E4 /* Breakpad.xcconfig */,
+ 8B3102B611F0D5CE00FCF3E4 /* BreakpadDebug.xcconfig */,
+ 8B3102B711F0D5CE00FCF3E4 /* BreakpadRelease.xcconfig */,
+ 08FB7796FE84155DC02AAC07 /* symupload.m */,
+ 9BD836000B0544BA0055103E /* minidump_upload.m */,
+ 9BD833680B03E4080055103E /* HTTPMultipartUpload.h */,
+ 9BD833690B03E4080055103E /* HTTPMultipartUpload.m */,
+ 08FB779DFE84155DC02AAC07 /* External Frameworks and Libraries */,
+ 1AB674ADFE9D54B511CA2CBB /* Products */,
+ );
+ name = symupload;
+ sourceTree = "<group>";
+ };
+ 08FB779DFE84155DC02AAC07 /* External Frameworks and Libraries */ = {
+ isa = PBXGroup;
+ children = (
+ 08FB779EFE84155DC02AAC07 /* Foundation.framework */,
+ );
+ name = "External Frameworks and Libraries";
+ sourceTree = "<group>";
+ };
+ 1AB674ADFE9D54B511CA2CBB /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ 8DD76FA10486AA7600D96B5E /* symupload */,
+ 9BD835FB0B0544950055103E /* minidump_upload */,
+ );
+ name = Products;
+ sourceTree = "<group>";
+ };
+/* End PBXGroup section */
+
+/* Begin PBXNativeTarget section */
+ 8DD76F960486AA7600D96B5E /* symupload */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 1DEB927408733DD40010E9CD /* Build configuration list for PBXNativeTarget "symupload" */;
+ buildPhases = (
+ 8DD76F990486AA7600D96B5E /* Sources */,
+ 8DD76F9B0486AA7600D96B5E /* Frameworks */,
+ 8DD76F9E0486AA7600D96B5E /* CopyFiles */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = symupload;
+ productInstallPath = "$(HOME)/bin";
+ productName = symupload;
+ productReference = 8DD76FA10486AA7600D96B5E /* symupload */;
+ productType = "com.apple.product-type.tool";
+ };
+ 9BD835FA0B0544950055103E /* minidump_upload */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 9BD836020B0544BB0055103E /* Build configuration list for PBXNativeTarget "minidump_upload" */;
+ buildPhases = (
+ 9BD835F80B0544950055103E /* Sources */,
+ 9BD835F90B0544950055103E /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = minidump_upload;
+ productName = minidump_upload;
+ productReference = 9BD835FB0B0544950055103E /* minidump_upload */;
+ productType = "com.apple.product-type.tool";
+ };
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+ 08FB7793FE84155DC02AAC07 /* Project object */ = {
+ isa = PBXProject;
+ buildConfigurationList = 1DEB927808733DD40010E9CD /* Build configuration list for PBXProject "symupload" */;
+ compatibilityVersion = "Xcode 3.1";
+ hasScannedForEncodings = 1;
+ mainGroup = 08FB7794FE84155DC02AAC07 /* symupload */;
+ projectDirPath = "";
+ projectRoot = "";
+ targets = (
+ 8DD76F960486AA7600D96B5E /* symupload */,
+ 9BD835FA0B0544950055103E /* minidump_upload */,
+ );
+ };
+/* End PBXProject section */
+
+/* Begin PBXSourcesBuildPhase section */
+ 8DD76F990486AA7600D96B5E /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 8DD76F9A0486AA7600D96B5E /* symupload.m in Sources */,
+ 9BD8336B0B03E4080055103E /* HTTPMultipartUpload.m in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ 9BD835F80B0544950055103E /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 9BD836180B0549F70055103E /* HTTPMultipartUpload.m in Sources */,
+ 9BC1D49E0B37427A00F2A2B4 /* minidump_upload.m in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXSourcesBuildPhase section */
+
+/* Begin XCBuildConfiguration section */
+ 1DEB927508733DD40010E9CD /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ HEADER_SEARCH_PATHS = ../../..;
+ PRODUCT_NAME = symupload;
+ };
+ name = Debug;
+ };
+ 1DEB927608733DD40010E9CD /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ HEADER_SEARCH_PATHS = ../../..;
+ PRODUCT_NAME = symupload;
+ };
+ name = Release;
+ };
+ 1DEB927908733DD40010E9CD /* Debug */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 8B3102B611F0D5CE00FCF3E4 /* BreakpadDebug.xcconfig */;
+ buildSettings = {
+ };
+ name = Debug;
+ };
+ 1DEB927A08733DD40010E9CD /* Release */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 8B3102B711F0D5CE00FCF3E4 /* BreakpadRelease.xcconfig */;
+ buildSettings = {
+ };
+ name = Release;
+ };
+ 9BD836030B0544BB0055103E /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ HEADER_SEARCH_PATHS = ../../..;
+ PRODUCT_NAME = minidump_upload;
+ };
+ name = Debug;
+ };
+ 9BD836040B0544BB0055103E /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ HEADER_SEARCH_PATHS = ../../..;
+ PRODUCT_NAME = minidump_upload;
+ };
+ name = Release;
+ };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+ 1DEB927408733DD40010E9CD /* Build configuration list for PBXNativeTarget "symupload" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 1DEB927508733DD40010E9CD /* Debug */,
+ 1DEB927608733DD40010E9CD /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ 1DEB927808733DD40010E9CD /* Build configuration list for PBXProject "symupload" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 1DEB927908733DD40010E9CD /* Debug */,
+ 1DEB927A08733DD40010E9CD /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ 9BD836020B0544BB0055103E /* Build configuration list for PBXNativeTarget "minidump_upload" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 9BD836030B0544BB0055103E /* Debug */,
+ 9BD836040B0544BB0055103E /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+/* End XCConfigurationList section */
+ };
+ rootObject = 08FB7793FE84155DC02AAC07 /* Project object */;
+}
diff --git a/toolkit/crashreporter/google-breakpad/src/tools/mac/tools_mac.gypi b/toolkit/crashreporter/google-breakpad/src/tools/mac/tools_mac.gypi
new file mode 100644
index 000000000..7457573b4
--- /dev/null
+++ b/toolkit/crashreporter/google-breakpad/src/tools/mac/tools_mac.gypi
@@ -0,0 +1,116 @@
+# 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': 'crash_report',
+ 'type': 'executable',
+ 'sources': [
+ 'crash_report/crash_report.mm',
+ 'crash_report/on_demand_symbol_supplier.h',
+ 'crash_report/on_demand_symbol_supplier.mm',
+ ],
+ 'link_settings': {
+ 'libraries': [
+ '$(SDKROOT)/System/Library/Frameworks/Foundation.framework',
+ ],
+ },
+ 'dependencies': [
+ '../common/common.gyp:common',
+ '../processor/processor.gyp:processor',
+ ],
+ },
+ {
+ 'target_name': 'dump_syms',
+ 'type': 'executable',
+ 'sources': [
+ 'dump_syms/dump_syms_tool.cc',
+ ],
+ 'link_settings': {
+ 'libraries': [
+ '$(SDKROOT)/System/Library/Frameworks/Foundation.framework',
+ ],
+ },
+ 'dependencies': [
+ '../common/common.gyp:common',
+ ],
+ },
+ {
+ 'target_name': 'macho_dump',
+ 'type': 'executable',
+ 'sources': [
+ 'dump_syms/macho_dump.cc',
+ ],
+ 'dependencies': [
+ '../common/common.gyp:common',
+ ],
+ },
+ {
+ 'target_name': 'minidump_upload',
+ 'type': 'executable',
+ 'sources': [
+ 'symupload/minidump_upload.m',
+ ],
+ 'include_dirs': [
+ '../../common/mac',
+ ],
+ 'link_settings': {
+ 'libraries': [
+ '$(SDKROOT)/System/Library/Frameworks/Foundation.framework',
+ ],
+ },
+ 'dependencies': [
+ '../common/common.gyp:common',
+ ],
+ },
+ {
+ 'target_name': 'symupload',
+ 'type': 'executable',
+ 'sources': [
+ 'symupload/symupload.m',
+ ],
+ 'include_dirs': [
+ '../../common/mac',
+ ],
+ 'link_settings': {
+ 'libraries': [
+ '$(SDKROOT)/System/Library/Frameworks/Foundation.framework',
+ ],
+ },
+ 'dependencies': [
+ '../common/common.gyp:common',
+ ],
+ },
+ ],
+}
diff --git a/toolkit/crashreporter/google-breakpad/src/tools/mac/upload_system_symbols/arch_constants.h b/toolkit/crashreporter/google-breakpad/src/tools/mac/upload_system_symbols/arch_constants.h
new file mode 100644
index 000000000..2115e54e6
--- /dev/null
+++ b/toolkit/crashreporter/google-breakpad/src/tools/mac/upload_system_symbols/arch_constants.h
@@ -0,0 +1,61 @@
+/* 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.
+*/
+
+#include <mach-o/arch.h>
+#include <mach-o/loader.h>
+#include <mach/machine.h>
+
+// Go/Cgo does not support #define constants, so turn them into symbols
+// that are reachable from Go.
+
+#ifndef CPU_TYPE_ARM64
+#define CPU_TYPE_ARM64 (CPU_TYPE_ARM | CPU_ARCH_ABI64)
+#endif
+
+#ifndef CPU_SUBTYPE_ARM64_ALL
+#define CPU_SUBTYPE_ARM64_ALL 0
+#endif
+
+const cpu_type_t kCPU_TYPE_ARM = CPU_TYPE_ARM;
+const cpu_type_t kCPU_TYPE_ARM64 = CPU_TYPE_ARM64;
+
+const cpu_subtype_t kCPU_SUBTYPE_ARM64_ALL = CPU_SUBTYPE_ARM64_ALL;
+const cpu_subtype_t kCPU_SUBTYPE_ARM_V7S = CPU_SUBTYPE_ARM_V7S;
+
+const char* GetNXArchInfoName(cpu_type_t cpu_type, cpu_subtype_t cpu_subtype) {
+ const NXArchInfo* arch_info = NXGetArchInfoFromCpuType(cpu_type, cpu_subtype);
+ if (!arch_info)
+ return 0;
+ return arch_info->name;
+}
+
+const uint32_t kMachHeaderFtypeDylib = MH_DYLIB;
+const uint32_t kMachHeaderFtypeBundle = MH_BUNDLE;
+const uint32_t kMachHeaderFtypeExe = MH_EXECUTE;
diff --git a/toolkit/crashreporter/google-breakpad/src/tools/mac/upload_system_symbols/arch_reader.go b/toolkit/crashreporter/google-breakpad/src/tools/mac/upload_system_symbols/arch_reader.go
new file mode 100644
index 000000000..f60648230
--- /dev/null
+++ b/toolkit/crashreporter/google-breakpad/src/tools/mac/upload_system_symbols/arch_reader.go
@@ -0,0 +1,65 @@
+/* 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.
+*/
+
+package main
+
+import (
+ "debug/macho"
+)
+
+/*
+#include "arch_constants.h"
+*/
+import "C"
+
+// getArchStringFromHeader takes a MachO FileHeader and returns a string that
+// represents the CPU type and subtype.
+// This function is a Go version of src/common/mac/arch_utilities.cc:BreakpadGetArchInfoFromCpuType().
+func getArchStringFromHeader(header macho.FileHeader) string {
+ // TODO(rsesek): As of 10.9.4, OS X doesn't list these in /usr/include/mach/machine.h.
+ if header.Cpu == C.kCPU_TYPE_ARM64 && header.SubCpu == C.kCPU_SUBTYPE_ARM64_ALL {
+ return "arm64"
+ }
+ if header.Cpu == C.kCPU_TYPE_ARM && header.SubCpu == C.kCPU_SUBTYPE_ARM_V7S {
+ return "armv7s"
+ }
+
+ cstr := C.GetNXArchInfoName(C.cpu_type_t(header.Cpu), C.cpu_subtype_t(header.SubCpu))
+ if cstr == nil {
+ return ""
+ }
+ return C.GoString(cstr)
+}
+
+const (
+ MachODylib macho.Type = C.kMachHeaderFtypeDylib
+ MachOBundle = C.kMachHeaderFtypeBundle
+ MachOExe = C.kMachHeaderFtypeExe
+)
diff --git a/toolkit/crashreporter/google-breakpad/src/tools/mac/upload_system_symbols/upload_system_symbols.go b/toolkit/crashreporter/google-breakpad/src/tools/mac/upload_system_symbols/upload_system_symbols.go
new file mode 100644
index 000000000..355612086
--- /dev/null
+++ b/toolkit/crashreporter/google-breakpad/src/tools/mac/upload_system_symbols/upload_system_symbols.go
@@ -0,0 +1,420 @@
+/* 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.
+*/
+
+/*
+Tool upload_system_symbols generates and uploads Breakpad symbol files for OS X system libraries.
+
+This tool shells out to the dump_syms and symupload Breakpad tools. In its default mode, this
+will find all dynamic libraries on the system, run dump_syms to create the Breakpad symbol files,
+and then upload them to Google's crash infrastructure.
+
+The tool can also be used to only dump libraries or upload from a directory. See -help for more
+information.
+
+Both i386 and x86_64 architectures will be dumped and uploaded.
+*/
+package main
+
+import (
+ "debug/macho"
+ "flag"
+ "fmt"
+ "io"
+ "io/ioutil"
+ "log"
+ "os"
+ "os/exec"
+ "path"
+ "regexp"
+ "strings"
+ "sync"
+ "time"
+)
+
+var (
+ breakpadTools = flag.String("breakpad-tools", "out/Release/", "Path to the Breakpad tools directory, containing dump_syms and symupload.")
+ uploadOnlyPath = flag.String("upload-from", "", "Upload a directory of symbol files that has been dumped independently.")
+ dumpOnlyPath = flag.String("dump-to", "", "Dump the symbols to the specified directory, but do not upload them.")
+ systemRoot = flag.String("system-root", "", "Path to the root of the Mac OS X system whose symbols will be dumped.")
+ dumpArchitecture = flag.String("arch", "", "The CPU architecture for which symbols should be dumped. If not specified, dumps all architectures.")
+)
+
+var (
+ // pathsToScan are the subpaths in the systemRoot that should be scanned for shared libraries.
+ pathsToScan = []string{
+ "/Library/QuickTime",
+ "/System/Library/Components",
+ "/System/Library/Frameworks",
+ "/System/Library/PrivateFrameworks",
+ "/usr/lib",
+ }
+
+ // uploadServers are the list of servers to which symbols should be uploaded.
+ uploadServers = []string{
+ "https://clients2.google.com/cr/symbol",
+ "https://clients2.google.com/cr/staging_symbol",
+ }
+
+ // blacklistRegexps match paths that should be excluded from dumping.
+ blacklistRegexps = []*regexp.Regexp{
+ regexp.MustCompile(`/System/Library/Frameworks/Python\.framework/`),
+ regexp.MustCompile(`/System/Library/Frameworks/Ruby\.framework/`),
+ regexp.MustCompile(`_profile\.dylib$`),
+ regexp.MustCompile(`_debug\.dylib$`),
+ regexp.MustCompile(`\.a$`),
+ regexp.MustCompile(`\.dat$`),
+ }
+)
+
+func main() {
+ flag.Parse()
+ log.SetFlags(0)
+
+ var uq *UploadQueue
+
+ if *uploadOnlyPath != "" {
+ // -upload-from specified, so handle that case early.
+ uq = StartUploadQueue()
+ uploadFromDirectory(*uploadOnlyPath, uq)
+ uq.Wait()
+ return
+ }
+
+ if *systemRoot == "" {
+ log.Fatal("Need a -system-root to dump symbols for")
+ }
+
+ if *dumpOnlyPath != "" {
+ // -dump-to specified, so make sure that the path is a directory.
+ if fi, err := os.Stat(*dumpOnlyPath); err != nil {
+ log.Fatal("-dump-to location: %v", err)
+ } else if !fi.IsDir() {
+ log.Fatal("-dump-to location is not a directory")
+ }
+ }
+
+ dumpPath := *dumpOnlyPath
+ if *dumpOnlyPath == "" {
+ // If -dump-to was not specified, then run the upload pipeline and create
+ // a temporary dump output directory.
+ uq = StartUploadQueue()
+
+ if p, err := ioutil.TempDir("", "upload_system_symbols"); err != nil {
+ log.Fatal("Failed to create temporary directory: %v", err)
+ } else {
+ dumpPath = p
+ defer os.RemoveAll(p)
+ }
+ }
+
+ dq := StartDumpQueue(*systemRoot, dumpPath, uq)
+ dq.Wait()
+ if uq != nil {
+ uq.Wait()
+ }
+}
+
+type WorkerPool struct {
+ wg sync.WaitGroup
+}
+
+// StartWorkerPool will launch numWorkers goroutines all running workerFunc.
+// When workerFunc exits, the goroutine will terminate.
+func StartWorkerPool(numWorkers int, workerFunc func()) *WorkerPool {
+ p := new(WorkerPool)
+ for i := 0; i < numWorkers; i++ {
+ p.wg.Add(1)
+ go func() {
+ workerFunc()
+ p.wg.Done()
+ }()
+ }
+ return p
+}
+
+// Wait for all the workers in the pool to complete the workerFunc.
+func (p *WorkerPool) Wait() {
+ p.wg.Wait()
+}
+
+type UploadQueue struct {
+ *WorkerPool
+ queue chan string
+}
+
+// StartUploadQueue creates a new worker pool and queue, to which paths to
+// Breakpad symbol files may be sent for uploading.
+func StartUploadQueue() *UploadQueue {
+ uq := &UploadQueue{
+ queue: make(chan string, 10),
+ }
+ uq.WorkerPool = StartWorkerPool(5, uq.worker)
+ return uq
+}
+
+// Upload enqueues the contents of filepath to be uploaded.
+func (uq *UploadQueue) Upload(filepath string) {
+ uq.queue <- filepath
+}
+
+// Done tells the queue that no more files need to be uploaded. This must be
+// called before WorkerPool.Wait.
+func (uq *UploadQueue) Done() {
+ close(uq.queue)
+}
+
+func (uq *UploadQueue) worker() {
+ symUpload := path.Join(*breakpadTools, "symupload")
+
+ for symfile := range uq.queue {
+ for _, server := range uploadServers {
+ for i := 0; i < 3; i++ { // Give each upload 3 attempts to succeed.
+ cmd := exec.Command(symUpload, symfile, server)
+ if output, err := cmd.Output(); err == nil {
+ // Success. No retry needed.
+ fmt.Printf("Uploaded %s to %s\n", symfile, server)
+ break
+ } else {
+ log.Printf("Error running symupload(%s, %s), attempt %d: %v: %s\n", symfile, server, i, err, output)
+ time.Sleep(1 * time.Second)
+ }
+ }
+ }
+ }
+}
+
+type DumpQueue struct {
+ *WorkerPool
+ dumpPath string
+ queue chan dumpRequest
+ uq *UploadQueue
+}
+
+type dumpRequest struct {
+ path string
+ arch string
+}
+
+// StartDumpQueue creates a new worker pool to find all the Mach-O libraries in
+// root and dump their symbols to dumpPath. If an UploadQueue is passed, the
+// path to the symbol file will be enqueued there, too.
+func StartDumpQueue(root, dumpPath string, uq *UploadQueue) *DumpQueue {
+ dq := &DumpQueue{
+ dumpPath: dumpPath,
+ queue: make(chan dumpRequest),
+ uq: uq,
+ }
+ dq.WorkerPool = StartWorkerPool(12, dq.worker)
+
+ findLibsInRoot(root, dq)
+
+ return dq
+}
+
+// DumpSymbols enqueues the filepath to have its symbols dumped in the specified
+// architecture.
+func (dq *DumpQueue) DumpSymbols(filepath string, arch string) {
+ dq.queue <- dumpRequest{
+ path: filepath,
+ arch: arch,
+ }
+}
+
+func (dq *DumpQueue) Wait() {
+ dq.WorkerPool.Wait()
+ if dq.uq != nil {
+ dq.uq.Done()
+ }
+}
+
+func (dq *DumpQueue) done() {
+ close(dq.queue)
+}
+
+func (dq *DumpQueue) worker() {
+ dumpSyms := path.Join(*breakpadTools, "dump_syms")
+
+ for req := range dq.queue {
+ filebase := path.Join(dq.dumpPath, strings.Replace(req.path, "/", "_", -1))
+ symfile := fmt.Sprintf("%s_%s.sym", filebase, req.arch)
+ f, err := os.Create(symfile)
+ if err != nil {
+ log.Fatal("Error creating symbol file:", err)
+ }
+
+ cmd := exec.Command(dumpSyms, "-a", req.arch, req.path)
+ cmd.Stdout = f
+ err = cmd.Run()
+ f.Close()
+
+ if err != nil {
+ os.Remove(symfile)
+ log.Printf("Error running dump_syms(%s, %s): %v\n", req.arch, req.path, err)
+ } else if dq.uq != nil {
+ dq.uq.Upload(symfile)
+ }
+ }
+}
+
+// uploadFromDirectory handles the upload-only case and merely uploads all files in
+// a directory.
+func uploadFromDirectory(directory string, uq *UploadQueue) {
+ d, err := os.Open(directory)
+ if err != nil {
+ log.Fatal("Could not open directory to upload: %v", err)
+ }
+ defer d.Close()
+
+ entries, err := d.Readdirnames(0)
+ if err != nil {
+ log.Fatal("Could not read directory: %v", err)
+ }
+
+ for _, entry := range entries {
+ uq.Upload(path.Join(directory, entry))
+ }
+
+ uq.Done()
+}
+
+// findQueue is an implementation detail of the DumpQueue that finds all the
+// Mach-O files and their architectures.
+type findQueue struct {
+ *WorkerPool
+ queue chan string
+ dq *DumpQueue
+}
+
+// findLibsInRoot looks in all the pathsToScan in the root and manages the
+// interaction between findQueue and DumpQueue.
+func findLibsInRoot(root string, dq *DumpQueue) {
+ fq := &findQueue{
+ queue: make(chan string, 10),
+ dq: dq,
+ }
+ fq.WorkerPool = StartWorkerPool(12, fq.worker)
+
+ for _, p := range pathsToScan {
+ fq.findLibsInPath(path.Join(root, p))
+ }
+
+ close(fq.queue)
+ fq.Wait()
+ dq.done()
+}
+
+// findLibsInPath recursively walks the directory tree, sending file paths to
+// test for being Mach-O to the findQueue.
+func (fq *findQueue) findLibsInPath(loc string) {
+ d, err := os.Open(loc)
+ if err != nil {
+ log.Fatal("Could not open %s: %v", loc, err)
+ }
+ defer d.Close()
+
+ for {
+ fis, err := d.Readdir(100)
+ if err != nil && err != io.EOF {
+ log.Fatal("Error reading directory %s: %v", loc, err)
+ }
+
+ for _, fi := range fis {
+ fp := path.Join(loc, fi.Name())
+ if fi.IsDir() {
+ fq.findLibsInPath(fp)
+ continue
+ } else if fi.Mode()&os.ModeSymlink != 0 {
+ continue
+ }
+
+ // Test the blacklist in the worker to not slow down this main loop.
+
+ fq.queue <- fp
+ }
+
+ if err == io.EOF {
+ break
+ }
+ }
+}
+
+func (fq *findQueue) worker() {
+ for fp := range fq.queue {
+ blacklisted := false
+ for _, re := range blacklistRegexps {
+ blacklisted = blacklisted || re.MatchString(fp)
+ }
+ if blacklisted {
+ continue
+ }
+
+ f, err := os.Open(fp)
+ if err != nil {
+ log.Printf("%s: %v", fp, err)
+ continue
+ }
+
+ fatFile, err := macho.NewFatFile(f)
+ if err == nil {
+ // The file is fat, so dump its architectures.
+ for _, fatArch := range fatFile.Arches {
+ fq.dumpMachOFile(fp, fatArch.File)
+ }
+ fatFile.Close()
+ } else if err == macho.ErrNotFat {
+ // The file isn't fat but may still be MachO.
+ thinFile, err := macho.NewFile(f)
+ if err != nil {
+ log.Printf("%s: %v", fp, err)
+ continue
+ }
+ fq.dumpMachOFile(fp, thinFile)
+ thinFile.Close()
+ } else {
+ f.Close()
+ }
+ }
+}
+
+func (fq *findQueue) dumpMachOFile(fp string, image *macho.File) {
+ if image.Type != MachODylib && image.Type != MachOBundle {
+ return
+ }
+
+ arch := getArchStringFromHeader(image.FileHeader)
+ if arch == "" {
+ // Don't know about this architecture type.
+ return
+ }
+
+ if (*dumpArchitecture != "" && *dumpArchitecture == arch) || *dumpArchitecture == "" {
+ fq.dq.DumpSymbols(fp, arch)
+ }
+}
diff --git a/toolkit/crashreporter/google-breakpad/src/tools/python/filter_syms.py b/toolkit/crashreporter/google-breakpad/src/tools/python/filter_syms.py
new file mode 100644
index 000000000..abddf7893
--- /dev/null
+++ b/toolkit/crashreporter/google-breakpad/src/tools/python/filter_syms.py
@@ -0,0 +1,204 @@
+#!/usr/bin/env python
+# 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.
+
+"""Normalizes and de-duplicates paths within Breakpad symbol files.
+
+When using DWARF for storing debug symbols, some file information will be
+stored relative to the current working directory of the current compilation
+unit, and may be further relativized based upon how the file was #included.
+
+This helper can be used to parse the Breakpad symbol file generated from such
+DWARF files and normalize and de-duplicate the FILE records found within,
+updating any references to the FILE records in the other record types.
+"""
+
+import macpath
+import ntpath
+import optparse
+import os
+import posixpath
+import sys
+
+class BreakpadParseError(Exception):
+ """Unsupported Breakpad symbol record exception class."""
+ pass
+
+class SymbolFileParser(object):
+ """Parser for Breakpad symbol files.
+
+ The format of these files is documented at
+ https://chromium.googlesource.com/breakpad/breakpad/+/master/docs/symbol_files.md
+ """
+
+ def __init__(self, input_stream, output_stream, ignored_prefixes=None,
+ path_handler=os.path):
+ """Inits a SymbolFileParser to read symbol records from |input_stream| and
+ write the processed output to |output_stream|.
+
+ |ignored_prefixes| contains a list of optional path prefixes that
+ should be stripped from the final, normalized path outputs.
+
+ For example, if the Breakpad symbol file had all paths starting with a
+ common prefix, such as:
+ FILE 1 /b/build/src/foo.cc
+ FILE 2 /b/build/src/bar.cc
+ Then adding "/b/build/src" as an ignored prefix would result in an output
+ file that contained:
+ FILE 1 foo.cc
+ FILE 2 bar.cc
+
+ Note that |ignored_prefixes| does not necessarily contain file system
+ paths, as the contents of the DWARF DW_AT_comp_dir attribute is dependent
+ upon the host system and compiler, and may contain additional information
+ such as hostname or compiler version.
+ """
+
+ self.unique_files = {}
+ self.duplicate_files = {}
+ self.input_stream = input_stream
+ self.output_stream = output_stream
+ self.ignored_prefixes = ignored_prefixes or []
+ self.path_handler = path_handler
+
+ def Process(self):
+ """Processes the Breakpad symbol file."""
+ for line in self.input_stream:
+ parsed = self._ParseRecord(line.rstrip())
+ if parsed:
+ self.output_stream.write(parsed + '\n')
+
+ def _ParseRecord(self, record):
+ """Parses a single Breakpad symbol record - a single line from the symbol
+ file.
+
+ Returns:
+ The modified string to write to the output file, or None if no line
+ should be written.
+ """
+ record_type = record.partition(' ')[0]
+ if record_type == 'FILE':
+ return self._ParseFileRecord(record)
+ elif self._IsLineRecord(record_type):
+ return self._ParseLineRecord(record)
+ else:
+ # Simply pass the record through unaltered.
+ return record
+
+ def _NormalizePath(self, path):
+ """Normalizes a file path to its canonical form.
+
+ As this may not execute on the machine or file system originally
+ responsible for compilation, it may be necessary to further correct paths
+ for symlinks, junctions, or other such file system indirections.
+
+ Returns:
+ A unique, canonical representation for the the file path.
+ """
+ return self.path_handler.normpath(path)
+
+ def _AdjustPath(self, path):
+ """Adjusts the supplied path after performing path de-duplication.
+
+ This may be used to perform secondary adjustments, such as removing a
+ common prefix, such as "/D/build", or replacing the file system path with
+ information from the version control system.
+
+ Returns:
+ The actual path to use when writing the FILE record.
+ """
+ return path[len(filter(path.startswith,
+ self.ignored_prefixes + [''])[0]):]
+
+ def _ParseFileRecord(self, file_record):
+ """Parses and corrects a FILE record."""
+ file_info = file_record[5:].split(' ', 3)
+ if len(file_info) > 2:
+ raise BreakpadParseError('Unsupported FILE record: ' + file_record)
+ file_index = int(file_info[0])
+ file_name = self._NormalizePath(file_info[1])
+ existing_file_index = self.unique_files.get(file_name)
+ if existing_file_index is None:
+ self.unique_files[file_name] = file_index
+ file_info[1] = self._AdjustPath(file_name)
+ return 'FILE ' + ' '.join(file_info)
+ else:
+ self.duplicate_files[file_index] = existing_file_index
+ return None
+
+ def _IsLineRecord(self, record_type):
+ """Determines if the current record type is a Line record"""
+ try:
+ line = int(record_type, 16)
+ except (ValueError, TypeError):
+ return False
+ return True
+
+ def _ParseLineRecord(self, line_record):
+ """Parses and corrects a Line record."""
+ line_info = line_record.split(' ', 5)
+ if len(line_info) > 4:
+ raise BreakpadParseError('Unsupported Line record: ' + line_record)
+ file_index = int(line_info[3])
+ line_info[3] = str(self.duplicate_files.get(file_index, file_index))
+ return ' '.join(line_info)
+
+def main():
+ option_parser = optparse.OptionParser()
+ option_parser.add_option("-p", "--prefix",
+ action="append", dest="prefixes", type="string",
+ default=[],
+ help="A path prefix that should be removed from "
+ "all FILE lines. May be repeated to specify "
+ "multiple prefixes.")
+ option_parser.add_option("-t", "--path_type",
+ action="store", type="choice", dest="path_handler",
+ choices=['win32', 'posix'],
+ help="Indicates how file paths should be "
+ "interpreted. The default is to treat paths "
+ "the same as the OS running Python (eg: "
+ "os.path)")
+ options, args = option_parser.parse_args()
+ if args:
+ option_parser.error('Unknown argument: %s' % args)
+
+ path_handler = { 'win32': ntpath,
+ 'posix': posixpath }.get(options.path_handler, os.path)
+ try:
+ symbol_parser = SymbolFileParser(sys.stdin, sys.stdout, options.prefixes,
+ path_handler)
+ symbol_parser.Process()
+ except BreakpadParseError, e:
+ print >> sys.stderr, 'Got an error while processing symbol file'
+ print >> sys.stderr, str(e)
+ return 1
+ return 0
+
+if __name__ == '__main__':
+ sys.exit(main())
diff --git a/toolkit/crashreporter/google-breakpad/src/tools/python/tests/filter_syms_unittest.py b/toolkit/crashreporter/google-breakpad/src/tools/python/tests/filter_syms_unittest.py
new file mode 100644
index 000000000..b111f3498
--- /dev/null
+++ b/toolkit/crashreporter/google-breakpad/src/tools/python/tests/filter_syms_unittest.py
@@ -0,0 +1,138 @@
+#!/usr/bin/env python
+# 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.
+
+"""Unit tests for filter_syms.py"""
+
+import cStringIO
+import ntpath
+import os
+import StringIO
+import sys
+import unittest
+
+ROOT_DIR = os.path.dirname(os.path.abspath(__file__))
+sys.path.insert(0, os.path.join(ROOT_DIR, '..'))
+
+# In root
+import filter_syms
+
+class FilterSysmsTest(unittest.TestCase):
+ def assertParsed(self, input_data, ignored_prefixes, expected):
+ input_io = cStringIO.StringIO(input_data)
+ output_io = cStringIO.StringIO()
+ parser = filter_syms.SymbolFileParser(input_io, output_io,
+ ignored_prefixes, ntpath)
+ parser.Process()
+ self.assertEqual(output_io.getvalue(), expected)
+
+ def testDuplicateFiles(self):
+ """Tests that duplicate files in FILE records are correctly removed and
+ that Line records are updated."""
+
+ INPUT = \
+"""MODULE windows x86 111111111111111111111111111111111 module1.pdb
+INFO CODE_ID FFFFFFFF module1.exe
+FILE 1 foo/../file1_1.cc
+FILE 2 bar/../file1_1.cc
+FILE 3 baz/../file1_1.cc
+FUNC 1000 c 0 Function1_1
+1000 8 45 2
+1008 4 46 3
+100c 4 44 1
+"""
+ EXPECTED_OUTPUT = \
+"""MODULE windows x86 111111111111111111111111111111111 module1.pdb
+INFO CODE_ID FFFFFFFF module1.exe
+FILE 1 file1_1.cc
+FUNC 1000 c 0 Function1_1
+1000 8 45 1
+1008 4 46 1
+100c 4 44 1
+"""
+ self.assertParsed(INPUT, [], EXPECTED_OUTPUT)
+
+ def testIgnoredPrefix(self):
+ """Tests that prefixes in FILE records are correctly removed."""
+
+ INPUT = \
+"""MODULE windows x86 111111111111111111111111111111111 module1.pdb
+INFO CODE_ID FFFFFFFF module1.exe
+FILE 1 /src/build/foo/../file1_1.cc
+FILE 2 /src/build/bar/../file1_2.cc
+FILE 3 /src/build/baz/../file1_2.cc
+FUNC 1000 c 0 Function1_1
+1000 8 45 2
+1008 4 46 3
+100c 4 44 1
+"""
+ EXPECTED_OUTPUT = \
+"""MODULE windows x86 111111111111111111111111111111111 module1.pdb
+INFO CODE_ID FFFFFFFF module1.exe
+FILE 1 file1_1.cc
+FILE 2 file1_2.cc
+FUNC 1000 c 0 Function1_1
+1000 8 45 2
+1008 4 46 2
+100c 4 44 1
+"""
+ IGNORED_PREFIXES = ['\\src\\build\\']
+ self.assertParsed(INPUT, IGNORED_PREFIXES, EXPECTED_OUTPUT)
+
+ def testIgnoredPrefixesDuplicateFiles(self):
+ """Tests that de-duplication of FILE records happens BEFORE prefixes
+ are removed."""
+
+ INPUT = \
+"""MODULE windows x86 111111111111111111111111111111111 module1.pdb
+INFO CODE_ID FFFFFFFF module1.exe
+FILE 1 /src/build/foo/../file1_1.cc
+FILE 2 /src/build/bar/../file1_2.cc
+FILE 3 D:/src/build2/baz/../file1_2.cc
+FUNC 1000 c 0 Function1_1
+1000 8 45 2
+1008 4 46 3
+100c 4 44 1
+"""
+ EXPECTED_OUTPUT = \
+"""MODULE windows x86 111111111111111111111111111111111 module1.pdb
+INFO CODE_ID FFFFFFFF module1.exe
+FILE 1 file1_1.cc
+FILE 2 file1_2.cc
+FILE 3 file1_2.cc
+FUNC 1000 c 0 Function1_1
+1000 8 45 2
+1008 4 46 3
+100c 4 44 1
+"""
+ IGNORED_PREFIXES = ['\\src\\build\\', 'D:\\src\\build2\\']
+ self.assertParsed(INPUT, IGNORED_PREFIXES, EXPECTED_OUTPUT)
+
+if __name__ == '__main__':
+ unittest.main() \ No newline at end of file
diff --git a/toolkit/crashreporter/google-breakpad/src/tools/solaris/dump_syms/Makefile b/toolkit/crashreporter/google-breakpad/src/tools/solaris/dump_syms/Makefile
new file mode 100644
index 000000000..ff77105c6
--- /dev/null
+++ b/toolkit/crashreporter/google-breakpad/src/tools/solaris/dump_syms/Makefile
@@ -0,0 +1,64 @@
+# Copyright (c) 2007, Google Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+# Author: Alfred Peng
+
+CXX=CC
+CC=cc
+
+CXXFLAGS=-g -xs -xdebugformat=stabs -I../../.. -I../../../common/solaris -lelf -ldemangle -D_REENTRANT
+
+.PHONY:all clean
+
+BIN=dump_syms
+
+all:$(BIN)
+
+DUMP_OBJ=dump_symbols.o guid_creator.o dump_syms.o file_id.o md5.o
+
+dump_syms:$(DUMP_OBJ)
+ $(CXX) $(CXXFLAGS) -o $@ $^
+
+dump_symbols.o:../../../common/solaris/dump_symbols.cc
+ $(CXX) $(CXXFLAGS) -c $^
+
+guid_creator.o:../../../common/solaris/guid_creator.cc
+ $(CXX) $(CXXFLAGS) -c $^
+
+file_id.o:../../../common/solaris/file_id.cc
+ $(CXX) $(CXXFLAGS) -c $^
+
+md5.o:../../../common/md5.cc
+ $(CXX) $(CXXFLAGS) -c $^
+
+test:all
+ ./run_regtest.sh
+
+clean:
+ rm -f $(BIN) $(DUMP_OBJ)
diff --git a/toolkit/crashreporter/google-breakpad/src/tools/solaris/dump_syms/Makefile.in b/toolkit/crashreporter/google-breakpad/src/tools/solaris/dump_syms/Makefile.in
new file mode 100644
index 000000000..7bef51e07
--- /dev/null
+++ b/toolkit/crashreporter/google-breakpad/src/tools/solaris/dump_syms/Makefile.in
@@ -0,0 +1,5 @@
+# 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_LDFLAGS += -lelf -ldemangle
diff --git a/toolkit/crashreporter/google-breakpad/src/tools/solaris/dump_syms/dump_syms.cc b/toolkit/crashreporter/google-breakpad/src/tools/solaris/dump_syms/dump_syms.cc
new file mode 100644
index 000000000..54cea57e7
--- /dev/null
+++ b/toolkit/crashreporter/google-breakpad/src/tools/solaris/dump_syms/dump_syms.cc
@@ -0,0 +1,54 @@
+// Copyright (c) 2007, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: Alfred Peng
+
+#include <string>
+#include <cstdio>
+
+#include "common/solaris/dump_symbols.h"
+
+using namespace google_breakpad;
+
+int main(int argc, char **argv) {
+ if (argc != 2) {
+ fprintf(stderr, "Usage: %s <binary-with-stab-symbol>\n", argv[0]);
+ return 1;
+ }
+
+ const char *binary = argv[1];
+
+ DumpSymbols dumper;
+ if (!dumper.WriteSymbolFile(binary, fileno(stdout))) {
+ fprintf(stderr, "Failed to write symbol file.\n");
+ return 1;
+ }
+
+ return 0;
+}
diff --git a/toolkit/crashreporter/google-breakpad/src/tools/solaris/dump_syms/moz.build b/toolkit/crashreporter/google-breakpad/src/tools/solaris/dump_syms/moz.build
new file mode 100644
index 000000000..3efeac039
--- /dev/null
+++ b/toolkit/crashreporter/google-breakpad/src/tools/solaris/dump_syms/moz.build
@@ -0,0 +1,29 @@
+# -*- 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_USE_LIBS += [
+ 'host_breakpad_common_s',
+ 'host_breakpad_solaris_common_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/solaris',
+]
+
+include('/toolkit/crashreporter/crashreporter.mozbuild')
diff --git a/toolkit/crashreporter/google-breakpad/src/tools/solaris/dump_syms/run_regtest.sh b/toolkit/crashreporter/google-breakpad/src/tools/solaris/dump_syms/run_regtest.sh
new file mode 100644
index 000000000..ffb343306
--- /dev/null
+++ b/toolkit/crashreporter/google-breakpad/src/tools/solaris/dump_syms/run_regtest.sh
@@ -0,0 +1,51 @@
+#!/bin/sh
+
+# Copyright (c) 2007, Google Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+./dump_syms testdata/dump_syms_regtest.o > testdata/dump_syms_regtest.new
+status=$?
+
+if [ $status -ne 0 ] ; then
+ echo "FAIL, dump_syms failed"
+ exit $status
+fi
+
+diff -u testdata/dump_syms_regtest.new testdata/dump_syms_regtest.sym > \
+ testdata/dump_syms_regtest.diff
+status=$?
+
+if [ $status -eq 0 ] ; then
+ rm testdata/dump_syms_regtest.diff testdata/dump_syms_regtest.new
+ echo "PASS"
+else
+ echo "FAIL, see testdata/dump_syms_regtest.[new|diff]"
+fi
+
+exit $status
diff --git a/toolkit/crashreporter/google-breakpad/src/tools/solaris/dump_syms/testdata/dump_syms_regtest.cc b/toolkit/crashreporter/google-breakpad/src/tools/solaris/dump_syms/testdata/dump_syms_regtest.cc
new file mode 100644
index 000000000..e617a23b8
--- /dev/null
+++ b/toolkit/crashreporter/google-breakpad/src/tools/solaris/dump_syms/testdata/dump_syms_regtest.cc
@@ -0,0 +1,64 @@
+// Copyright (c) 2007, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// ./dump_syms dump_syms_regtest.pdb > dump_syms_regtest.sym
+
+namespace google_breakpad {
+
+class C {
+ public:
+ C() : member_(1) {}
+ virtual ~C() {}
+
+ void set_member(int value) { member_ = value; }
+ int member() const { return member_; }
+
+ void f() { member_ = g(); }
+ virtual int g() { return 2; }
+ static char* h(const C &that) { return 0; }
+
+ private:
+ int member_;
+};
+
+static int i() {
+ return 3;
+}
+
+} // namespace google_breakpad
+
+int main(int argc, char **argv) {
+ google_breakpad::C object;
+ object.set_member(google_breakpad::i());
+ object.f();
+ int value = object.g();
+ char *nothing = object.h(object);
+
+ return 0;
+}
diff --git a/toolkit/crashreporter/google-breakpad/src/tools/solaris/dump_syms/testdata/dump_syms_regtest.stabs b/toolkit/crashreporter/google-breakpad/src/tools/solaris/dump_syms/testdata/dump_syms_regtest.stabs
new file mode 100644
index 000000000..c5f93ef78
--- /dev/null
+++ b/toolkit/crashreporter/google-breakpad/src/tools/solaris/dump_syms/testdata/dump_syms_regtest.stabs
@@ -0,0 +1,129 @@
+
+
+Debugging Stab table -- 104 entries
+
+ 0: .stabs "dump_syms_regtest.cc",N_UNDF,0x0,0x67,0x71c
+ 1: .stabs "/export/home/alfred/cvs/breakpad/google-breakpad20070927/src/tools/solaris/dump_syms/testdata/",N_SO,0x0,0x0,0x0
+ 2: .stabs "dump_syms_regtest.cc",N_SO,0x0,0x4,0x0
+ 3: .stabs "",N_OBJ,0x0,0x0,0x0
+ 4: .stabs "",N_OBJ,0x0,0x0,0x0
+ 5: .stabs "V=9.0;DBG_GEN=5.0.8;dm;cd;backend;ptf;ptx;ptk;s;g;R=5.8<<Sun C++ 5.8 Patch 121018-07 2006/11/01 (ccfe)>>;G=.XAB6Z2hOiL$Gl1b.;A=2",N_OPT,0x0,0x0,0x46fcb88e
+ 6: .stabs "dump_syms_regtest.cc",N_SOL,0x0,0x0,0x0
+ 7: .stabs "char:t(0,1)=bsc1;0;8",N_ISYM,0x0,0x0,0x0
+ 8: .stabs "short:t(0,2)=bs2;0;16",N_ISYM,0x0,0x0,0x0
+ 9: .stabs "int:t(0,3)=bs4;0;32",N_ISYM,0x0,0x0,0x0
+ 10: .stabs "long:t(0,4)=bs4;0;32",N_ISYM,0x0,0x0,0x0
+ 11: .stabs "long long:t(0,5)=bs8;0;64",N_ISYM,0x0,0x0,0x0
+ 12: .stabs "unsigned char:t(0,6)=buc1;0;8",N_ISYM,0x0,0x0,0x0
+ 13: .stabs "unsigned short:t(0,7)=bu2;0;16",N_ISYM,0x0,0x0,0x0
+ 14: .stabs "unsigned:t(0,8)=bu4;0;32",N_ISYM,0x0,0x0,0x0
+ 15: .stabs "unsigned long:t(0,9)=bu4;0;32",N_ISYM,0x0,0x0,0x0
+ 16: .stabs "unsigned long long:t(0,10)=bu8;0;64",N_ISYM,0x0,0x0,0x0
+ 17: .stabs "signed char:t(0,11)=bsc1;0;8",N_ISYM,0x0,0x0,0x0
+ 18: .stabs "wchar_t:t(0,12)=buc4;0;32",N_ISYM,0x0,0x0,0x0
+ 19: .stabs "void:t(0,13)=bs0;0;0",N_ISYM,0x0,0x0,0x0
+ 20: .stabs "float:t(0,14)=R1;4",N_ISYM,0x0,0x0,0x0
+ 21: .stabs "double:t(0,15)=R2;8",N_ISYM,0x0,0x0,0x0
+ 22: .stabs "long double:t(0,16)=R6;12",N_ISYM,0x0,0x0,0x0
+ 23: .stabs "...:t(0,17)=buv4;0;32",N_ISYM,0x0,0x0,0x0
+ 24: .stabs "bool:t(0,18)=bub1;0;8",N_ISYM,0x0,0x0,0x0
+ 25: .stabs "__1nPgoogle_breakpad_:T(0,19)=Yn0google_breakpad;",N_ISYM,0x0,0x0,0x0
+ 26: .stabs "nBC(0,19):U(0,20)",N_ESYM,0x0,0x0,0x0
+ 27: .stabs "nBC(0,19):T(0,20)=Yc8C;;AcHmember_:(0,3),32,32;;Cc2t6M_v K2c2T6M_v CcKset_member6Mi_v CcGmember6kM_i CcBf6M_v K3cBg6M_i GcBh6Frk1_pc;;;2 0;;;;110;",N_ESYM,0x0,0x8,0x0
+ 28: .stabs "main:F(0,3);(0,3);(0,21)=*(0,22)=*(0,1)",N_FUN,0x0,0x38,0x0
+ 29: .stabs "main",N_MAIN,0x0,0x0,0x0
+ 30: .stabs "argc:p(0,3)",N_PSYM,0x0,0x4,0x8
+ 31: .stabs "argv:p(0,21)",N_PSYM,0x0,0x4,0xc
+ 32: .stabn N_LBRAC,0x0,0x1,0x12
+ 33: .stabs "object:(0,20)",N_LSYM,0x0,0x8,0xfffffff4
+ 34: .stabs "value:(0,3)",N_LSYM,0x0,0x4,0xfffffff0
+ 35: .stabs "nothing:(0,22)",N_LSYM,0x0,0x4,0xffffffec
+ 36: .stabn N_SLINE,0x0,0x39,0x12
+ 37: .stabs "object:2",N_CONSTRUCT,0x0,0xc,0x12
+ 38: .stabn N_SLINE,0x2,0x3a,0x1e
+ 39: .stabn N_SLINE,0x0,0x3b,0x36
+ 40: .stabn N_SLINE,0x0,0x3c,0x42
+ 41: .stabn N_SLINE,0x0,0x3d,0x57
+ 42: .stabn N_SLINE,0x0,0x3f,0x6c
+ 43: .stabs "2:0",N_DESTRUCT,0x0,0xc,0x73
+ 44: .stabn N_SLINE,0xfffffffe,0x40,0x9c
+ 45: .stabn N_RBRAC,0x0,0x1,0x9c
+ 46: .stabs "__1cPgoogle_breakpadBi6F_i_:f(0,3)",N_FUN,0x0,0x32,0x0
+ 47: .stabn N_LBRAC,0x0,0x1,0x6
+ 48: .stabn N_SLINE,0x0,0x33,0x6
+ 49: .stabn N_SLINE,0x0,0x34,0x10
+ 50: .stabn N_RBRAC,0x0,0x1,0x10
+ 51: .stabs "__1cPgoogle_breakpadBC2t6M_v_:F(0,13);(0,23)=*(0,20)",N_FUN,0x0,0x24,0x0
+ 52: .stabs "this:p(0,23)",N_PSYM,0x0,0x4,0x8
+ 53: .stabn N_LBRAC,0x0,0x1,0x3
+ 54: .stabn N_SLINE,0x0,0x24,0x25
+ 55: .stabn N_RBRAC,0x0,0x1,0x25
+ 56: .stabs "__1cPgoogle_breakpadBC2T6M_v_:F(0,13);(0,23)",N_FUN,0x0,0x25,0x0
+ 57: .stabs "this:p(0,23)",N_PSYM,0x0,0x4,0x8
+ 58: .stabn N_LBRAC,0x0,0x1,0x3
+ 59: .stabn N_SLINE,0x0,0x25,0x3
+ 60: .stabn N_RBRAC,0x0,0x1,0x3
+ 61: .stabs "__1cPgoogle_breakpadBCKset_member6Mi_v_:F(0,13);(0,23);(0,3)",N_FUN,0x0,0x27,0x0
+ 62: .stabs "this:p(0,23)",N_PSYM,0x0,0x4,0x8
+ 63: .stabs "value:p(0,3)",N_PSYM,0x0,0x4,0xc
+ 64: .stabn N_LBRAC,0x0,0x1,0x3
+ 65: .stabn N_SLINE,0x0,0x27,0x3
+ 66: .stabn N_SLINE,0x0,0x27,0xc
+ 67: .stabn N_RBRAC,0x0,0x1,0xc
+ 68: .stabs "__1cPgoogle_breakpadBCBf6M_v_:F(0,13);(0,23)",N_FUN,0x0,0x2a,0x0
+ 69: .stabs "this:p(0,23)",N_PSYM,0x0,0x4,0x8
+ 70: .stabn N_LBRAC,0x0,0x1,0x3
+ 71: .stabn N_SLINE,0x0,0x2a,0x3
+ 72: .stabn N_SLINE,0x0,0x2a,0x1d
+ 73: .stabn N_RBRAC,0x0,0x1,0x1d
+ 74: .stabs "__1cPgoogle_breakpadBCBg6M_i_:F(0,3);(0,23)",N_FUN,0x0,0x2b,0x0
+ 75: .stabs "this:p(0,23)",N_PSYM,0x0,0x4,0x8
+ 76: .stabn N_LBRAC,0x0,0x1,0x6
+ 77: .stabn N_SLINE,0x0,0x2b,0x6
+ 78: .stabn N_SLINE,0x0,0x2b,0x10
+ 79: .stabn N_RBRAC,0x0,0x1,0x10
+ 80: .stabs "__1cPgoogle_breakpadBCBh6Frk1_pc_:F(0,22);(0,24)=&(0,25)=k(0,20)",N_FUN,0x0,0x2c,0x0
+ 81: .stabs "that:p(0,24)",N_PSYM,0x0,0x4,0x8
+ 82: .stabn N_LBRAC,0x0,0x1,0x6
+ 83: .stabn N_SLINE,0x0,0x2c,0x6
+ 84: .stabn N_SLINE,0x0,0x2c,0x10
+ 85: .stabn N_RBRAC,0x0,0x1,0x10
+ 86: .stabs "__1cPgoogle_breakpadBC2T5B6M_v_:F(0,13);(0,23)",N_FUN,0x0,0x25,0x0
+ 87: .stabs "this:p(0,23)",N_PSYM,0x0,0x4,0x8
+ 88: .stabn N_LBRAC,0x0,0x1,0x3
+ 89: .stabn N_SLINE,0x0,0x25,0xf
+ 90: .stabn N_RBRAC,0x0,0x1,0xf
+ 91: .stabs "__SLIP.DELETER__A:f(0,13);(0,23);(0,3)",N_FUN,0x0,0x25,0x0
+ 92: .stabs "this:p(0,23)",N_PSYM,0x0,0x4,0x8
+ 93: .stabs "delete:p(0,3)",N_PSYM,0x0,0x4,0xc
+ 94: .stabn N_LBRAC,0x0,0x1,0x3
+ 95: .stabn N_LBRAC,0x0,0x2,0x3
+ 96: .stabn N_RBRAC,0x0,0x2,0x28
+ 97: .stabn N_RBRAC,0x0,0x1,0x28
+ 98: .stabs "true:l(0,18);1",N_LSYM,0x0,0x4,0x0
+ 99: .stabs "false:l(0,18);0",N_LSYM,0x0,0x4,0x0
+ 100: .stabs "__1c2k6Fpv_v_:P(0,13);(0,26)=*(0,13)",N_FUN,0x0,0x0,0x0
+ 101: .stabs "__1cPgoogle_breakpadBC2t5B6M_v_:F__1cPgoogle_breakpadBC2t6M_v_",N_ALIAS,0x0,0x0,0x0
+ 102: .stabs "cbD__RTTI__1nPgoogle_breakpadBC_(0,19):YR(0,20)",N_LSYM,0x0,0x0,0x0
+ 103: .stabn N_ENDM,0x0,0x0,0x0
+
+
+Index Stab table -- 17 entries
+
+ 0: .stabs "dump_syms_regtest.cc",N_UNDF,0x0,0x10,0x3b1
+ 1: .stabs "/export/home/alfred/cvs/breakpad/google-breakpad20070927/src/tools/solaris/dump_syms/testdata/",N_SO,0x0,0x0,0x0
+ 2: .stabs "dump_syms_regtest.cc",N_SO,0x0,0x4,0x0
+ 3: .stabs "/export/home/alfred/cvs/breakpad/google-breakpad20070927/src/tools/solaris/dump_syms/testdata",N_OBJ,0x0,0x0,0x0
+ 4: .stabs "dump_syms_regtest.o",N_OBJ,0x0,0x0,0x0
+ 5: .stabs "V=9.0;DBG_GEN=5.0.8;dm;cd;backend;ptf;ptx;ptk;s;g;R=5.8<<Sun C++ 5.8 Patch 121018-07 2006/11/01 (ccfe)>>;G=.XAB6Z2hOiL$Gl1b.;A=2",N_OPT,0x0,0x0,0x46fcb88e
+ 6: .stabs "/export/home/alfred/cvs/breakpad/google-breakpad20070927/src/tools/solaris/dump_syms/testdata/; /ws/on10-tools-prc/SUNWspro/SS11/prod/bin/CC -g -xs -xdebugformat=stabs -I../../.. -I../../../common/solaris -D_REENTRANT -xs dump_syms_regtest.cc -Qoption ccfe -prefix -Qoption ccfe .XAB6Z2hOiL\$Gl1b.",N_CMDLINE,0x0,0x0,0x0
+ 7: .stabs "__1nPgoogle_breakpadBC_:U",N_ESYM,0x0,0x0,0x0
+ 8: .stabs "main",N_MAIN,0x0,0x0,0x0
+ 9: .stabs "main",N_FUN,0x0,0x0,0x0
+ 10: .stabs "__1cPgoogle_breakpadBC2t6M_v_",N_FUN,0x0,0x0,0x0
+ 11: .stabs "__1cPgoogle_breakpadBC2T6M_v_",N_FUN,0x0,0x0,0x0
+ 12: .stabs "__1cPgoogle_breakpadBCKset_member6Mi_v_",N_FUN,0x0,0x0,0x0
+ 13: .stabs "__1cPgoogle_breakpadBCBf6M_v_",N_FUN,0x0,0x0,0x0
+ 14: .stabs "__1cPgoogle_breakpadBCBg6M_i_",N_FUN,0x0,0x0,0x0
+ 15: .stabs "__1cPgoogle_breakpadBCBh6Frk1_pc_",N_FUN,0x0,0x0,0x0
+ 16: .stabs "__1cPgoogle_breakpadBC2T5B6M_v_",N_FUN,0x0,0x0,0x0
diff --git a/toolkit/crashreporter/google-breakpad/src/tools/solaris/dump_syms/testdata/dump_syms_regtest.sym b/toolkit/crashreporter/google-breakpad/src/tools/solaris/dump_syms/testdata/dump_syms_regtest.sym
new file mode 100644
index 000000000..44d3c5391
--- /dev/null
+++ b/toolkit/crashreporter/google-breakpad/src/tools/solaris/dump_syms/testdata/dump_syms_regtest.sym
@@ -0,0 +1,33 @@
+MODULE solaris x86 3DC8191474338D8587339B5FB3E2C62A0 dump_syms_regtest.o
+FILE 0 dump_syms_regtest.cc
+FUNC 0 156 0 main
+12 18 57 0
+1e 12 58 0
+36 24 59 0
+42 12 60 0
+57 21 61 0
+6c 21 63 0
+9c 48 64 0
+FUNC 0 16 0 int google_breakpad::i()
+6 6 51 0
+10 10 52 0
+FUNC 0 37 0 google_breakpad::C::C()
+25 37 36 0
+FUNC 0 3 0 google_breakpad::C::~C()
+3 3 37 0
+FUNC 0 12 0 void google_breakpad::C::set_member(int)
+3 3 39 0
+c 9 39 0
+FUNC 0 29 0 void google_breakpad::C::f()
+3 3 42 0
+1d 26 42 0
+FUNC 0 16 0 int google_breakpad::C::g()
+6 6 43 0
+10 10 43 0
+FUNC 0 16 0 char*google_breakpad::C::h(const google_breakpad::C&)
+6 6 44 0
+10 10 44 0
+FUNC 0 15 0 google_breakpad::C::~C #Nvariant 1()
+f 15 37 0
+FUNC 0 0 0 __SLIP.DELETER__A
+FUNC 0 0 0 void operator delete(void*)
diff --git a/toolkit/crashreporter/google-breakpad/src/tools/tools.gyp b/toolkit/crashreporter/google-breakpad/src/tools/tools.gyp
new file mode 100644
index 000000000..e6a4210fe
--- /dev/null
+++ b/toolkit/crashreporter/google-breakpad/src/tools/tools.gyp
@@ -0,0 +1,38 @@
+# 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.
+
+{
+ 'conditions': [
+ ['OS=="mac"', {
+ 'includes': ['mac/tools_mac.gypi'],
+ }],
+ ['OS=="linux"', {
+ 'includes': ['linux/tools_linux.gypi'],
+ }],
+ ],
+}
diff --git a/toolkit/crashreporter/google-breakpad/src/tools/windows/binaries/dump_syms.exe b/toolkit/crashreporter/google-breakpad/src/tools/windows/binaries/dump_syms.exe
new file mode 100644
index 000000000..ca4676f50
--- /dev/null
+++ b/toolkit/crashreporter/google-breakpad/src/tools/windows/binaries/dump_syms.exe
Binary files differ
diff --git a/toolkit/crashreporter/google-breakpad/src/tools/windows/binaries/symupload.exe b/toolkit/crashreporter/google-breakpad/src/tools/windows/binaries/symupload.exe
new file mode 100644
index 000000000..ba319b269
--- /dev/null
+++ b/toolkit/crashreporter/google-breakpad/src/tools/windows/binaries/symupload.exe
Binary files differ
diff --git a/toolkit/crashreporter/google-breakpad/src/tools/windows/converter/ms_symbol_server_converter.cc b/toolkit/crashreporter/google-breakpad/src/tools/windows/converter/ms_symbol_server_converter.cc
new file mode 100644
index 000000000..dd3f770f5
--- /dev/null
+++ b/toolkit/crashreporter/google-breakpad/src/tools/windows/converter/ms_symbol_server_converter.cc
@@ -0,0 +1,576 @@
+// Copyright (c) 2007, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// ms_symbol_server_converter.cc: Obtain symbol files from a Microsoft
+// symbol server, and convert them to Breakpad's dumped format.
+//
+// See ms_symbol_server_converter.h for documentation.
+//
+// Author: Mark Mentovai
+
+#include <windows.h>
+#include <dbghelp.h>
+
+#include <cassert>
+#include <cstdio>
+
+#include "tools/windows/converter/ms_symbol_server_converter.h"
+#include "common/windows/pdb_source_line_writer.h"
+#include "common/windows/string_utils-inl.h"
+
+// SYMOPT_NO_PROMPTS is not defined in earlier platform SDKs. Define it
+// in that case, in the event that this code is used with a newer version
+// of DbgHelp at runtime that recognizes the option. The presence of this
+// bit in the symbol options should not harm earlier versions of DbgHelp.
+#ifndef SYMOPT_NO_PROMPTS
+#define SYMOPT_NO_PROMPTS 0x00080000
+#endif // SYMOPT_NO_PROMPTS
+
+namespace google_breakpad {
+
+// Use sscanf_s if it is available, to quench the warning about scanf being
+// deprecated. Use scanf where sscanf_is not available. Note that the
+// parameters passed to sscanf and sscanf_s are only compatible as long as
+// fields of type c, C, s, S, and [ are not used.
+#if _MSC_VER >= 1400 // MSVC 2005/8
+#define SSCANF sscanf_s
+#else // _MSC_VER >= 1400
+#define SSCANF sscanf
+#endif // _MSC_VER >= 1400
+
+bool GUIDOrSignatureIdentifier::InitializeFromString(
+ const string &identifier) {
+ type_ = TYPE_NONE;
+
+ size_t length = identifier.length();
+
+ if (length > 32 && length <= 40) {
+ // GUID
+ if (SSCANF(identifier.c_str(),
+ "%08X%04X%04X%02X%02X%02X%02X%02X%02X%02X%02X%X",
+ &guid_.Data1, &guid_.Data2, &guid_.Data3,
+ &guid_.Data4[0], &guid_.Data4[1],
+ &guid_.Data4[2], &guid_.Data4[3],
+ &guid_.Data4[4], &guid_.Data4[5],
+ &guid_.Data4[6], &guid_.Data4[7],
+ &age_) != 12) {
+ return false;
+ }
+
+ type_ = TYPE_GUID;
+ } else if (length > 8 && length <= 15) {
+ // Signature
+ if (SSCANF(identifier.c_str(), "%08X%x", &signature_, &age_) != 2) {
+ return false;
+ }
+
+ type_ = TYPE_SIGNATURE;
+ } else {
+ return false;
+ }
+
+ return true;
+}
+
+#undef SSCANF
+
+MSSymbolServerConverter::MSSymbolServerConverter(
+ const string &local_cache, const vector<string> &symbol_servers)
+ : symbol_path_(),
+ fail_dns_(false),
+ fail_timeout_(false),
+ fail_not_found_(false) {
+ // Setting local_cache can be done without verifying that it exists because
+ // SymSrv will create it if it is missing - any creation failures will occur
+ // at that time, so there's nothing to check here, making it safe to
+ // assign this in the constructor.
+
+ assert(symbol_servers.size() > 0);
+
+#if !defined(NDEBUG)
+ // These are characters that are interpreted as having special meanings in
+ // symbol_path_.
+ const char kInvalidCharacters[] = "*;";
+ assert(local_cache.find_first_of(kInvalidCharacters) == string::npos);
+#endif // !defined(NDEBUG)
+
+ for (vector<string>::const_iterator symbol_server = symbol_servers.begin();
+ symbol_server != symbol_servers.end();
+ ++symbol_server) {
+ // The symbol path format is explained by
+ // http://msdn.microsoft.com/library/en-us/debug/base/using_symsrv.asp .
+ // "srv*" is the same as "symsrv*symsrv.dll*", which means that
+ // symsrv.dll is to be responsible for locating symbols. symsrv.dll
+ // interprets the rest of the string as a series of symbol stores separated
+ // by '*'. "srv*local_cache*symbol_server" means to check local_cache
+ // first for the symbol file, and if it is not found there, to check
+ // symbol_server. Symbol files found on the symbol server will be placed
+ // in the local cache, decompressed.
+ //
+ // Multiple specifications in this format may be presented, separated by
+ // semicolons.
+
+ assert((*symbol_server).find_first_of(kInvalidCharacters) == string::npos);
+ symbol_path_ += "srv*" + local_cache + "*" + *symbol_server + ";";
+ }
+
+ // Strip the trailing semicolon.
+ symbol_path_.erase(symbol_path_.length() - 1);
+}
+
+// A stack-based class that manages SymInitialize and SymCleanup calls.
+class AutoSymSrv {
+ public:
+ AutoSymSrv() : initialized_(false) {}
+
+ ~AutoSymSrv() {
+ if (!Cleanup()) {
+ // Print the error message here, because destructors have no return
+ // value.
+ fprintf(stderr, "~AutoSymSrv: SymCleanup: error %d\n", GetLastError());
+ }
+ }
+
+ bool Initialize(HANDLE process, char *path, bool invade_process) {
+ process_ = process;
+ initialized_ = SymInitialize(process, path, invade_process) == TRUE;
+ return initialized_;
+ }
+
+ bool Cleanup() {
+ if (initialized_) {
+ if (SymCleanup(process_)) {
+ initialized_ = false;
+ return true;
+ }
+ return false;
+ }
+
+ return true;
+ }
+
+ private:
+ HANDLE process_;
+ bool initialized_;
+};
+
+// A stack-based class that "owns" a pathname and deletes it when destroyed,
+// unless told not to by having its Release() method called. Early deletions
+// are supported by calling Delete().
+class AutoDeleter {
+ public:
+ explicit AutoDeleter(const string &path) : path_(path) {}
+
+ ~AutoDeleter() {
+ int error;
+ if ((error = Delete()) != 0) {
+ // Print the error message here, because destructors have no return
+ // value.
+ fprintf(stderr, "~AutoDeleter: Delete: error %d for %s\n",
+ error, path_.c_str());
+ }
+ }
+
+ int Delete() {
+ if (path_.empty())
+ return 0;
+
+ int error = remove(path_.c_str());
+ Release();
+ return error;
+ }
+
+ void Release() {
+ path_.clear();
+ }
+
+ private:
+ string path_;
+};
+
+MSSymbolServerConverter::LocateResult
+MSSymbolServerConverter::LocateFile(const string &debug_or_code_file,
+ const string &debug_or_code_id,
+ const string &version,
+ string *file_name) {
+ assert(file_name);
+ file_name->clear();
+
+ GUIDOrSignatureIdentifier identifier;
+ if (!identifier.InitializeFromString(debug_or_code_id)) {
+ fprintf(stderr,
+ "LocateFile: Unparseable identifier for %s %s %s\n",
+ debug_or_code_file.c_str(),
+ debug_or_code_id.c_str(),
+ version.c_str());
+ return LOCATE_FAILURE;
+ }
+
+ HANDLE process = GetCurrentProcess(); // CloseHandle is not needed.
+ AutoSymSrv symsrv;
+ if (!symsrv.Initialize(process,
+ const_cast<char *>(symbol_path_.c_str()),
+ false)) {
+ fprintf(stderr, "LocateFile: SymInitialize: error %d for %s %s %s\n",
+ GetLastError(),
+ debug_or_code_file.c_str(),
+ debug_or_code_id.c_str(),
+ version.c_str());
+ return LOCATE_FAILURE;
+ }
+
+ if (!SymRegisterCallback64(process, SymCallback,
+ reinterpret_cast<ULONG64>(this))) {
+ fprintf(stderr,
+ "LocateFile: SymRegisterCallback64: error %d for %s %s %s\n",
+ GetLastError(),
+ debug_or_code_file.c_str(),
+ debug_or_code_id.c_str(),
+ version.c_str());
+ return LOCATE_FAILURE;
+ }
+
+ // SYMOPT_DEBUG arranges for SymCallback to be called with additional
+ // debugging information. This is used to determine the nature of failures.
+ DWORD options = SymGetOptions() | SYMOPT_DEBUG | SYMOPT_NO_PROMPTS |
+ SYMOPT_FAIL_CRITICAL_ERRORS | SYMOPT_SECURE;
+ SymSetOptions(options);
+
+ // SymCallback will set these as needed inisde the SymFindFileInPath call.
+ fail_dns_ = false;
+ fail_timeout_ = false;
+ fail_not_found_ = false;
+
+ // Do the lookup.
+ char path[MAX_PATH];
+ if (!SymFindFileInPath(
+ process, NULL,
+ const_cast<char *>(debug_or_code_file.c_str()),
+ const_cast<void *>(identifier.guid_or_signature_pointer()),
+ identifier.age(), 0,
+ identifier.type() == GUIDOrSignatureIdentifier::TYPE_GUID ?
+ SSRVOPT_GUIDPTR : SSRVOPT_DWORDPTR,
+ path, SymFindFileInPathCallback, this)) {
+ DWORD error = GetLastError();
+ if (error == ERROR_FILE_NOT_FOUND) {
+ // This can be returned for a number of reasons. Use the crumbs
+ // collected by SymCallback to determine which one is relevant.
+
+ // These errors are possibly transient.
+ if (fail_dns_ || fail_timeout_) {
+ return LOCATE_RETRY;
+ }
+
+ // This is an authoritiative file-not-found message.
+ if (fail_not_found_) {
+ fprintf(stderr,
+ "LocateFile: SymFindFileInPath: LOCATE_NOT_FOUND error "
+ "for %s %s %s\n",
+ debug_or_code_file.c_str(),
+ debug_or_code_id.c_str(),
+ version.c_str());
+ return LOCATE_NOT_FOUND;
+ }
+
+ // If the error is FILE_NOT_FOUND but none of the known error
+ // conditions are matched, fall through to LOCATE_FAILURE.
+ }
+
+ fprintf(stderr,
+ "LocateFile: SymFindFileInPath: error %d for %s %s %s\n",
+ error,
+ debug_or_code_file.c_str(),
+ debug_or_code_id.c_str(),
+ version.c_str());
+ return LOCATE_FAILURE;
+ }
+
+ // Making sure path is null-terminated.
+ path[MAX_PATH - 1] = '\0';
+
+ // The AutoDeleter ensures that the file is only kept when returning
+ // LOCATE_SUCCESS.
+ AutoDeleter deleter(path);
+
+ // Do the cleanup here even though it will happen when symsrv goes out of
+ // scope, to allow it to influence the return value.
+ if (!symsrv.Cleanup()) {
+ fprintf(stderr, "LocateFile: SymCleanup: error %d for %s %s %s\n",
+ GetLastError(),
+ debug_or_code_file.c_str(),
+ debug_or_code_id.c_str(),
+ version.c_str());
+ return LOCATE_FAILURE;
+ }
+
+ deleter.Release();
+
+ printf("Downloaded: %s\n", path);
+ *file_name = path;
+ return LOCATE_SUCCESS;
+}
+
+
+MSSymbolServerConverter::LocateResult
+MSSymbolServerConverter::LocatePEFile(const MissingSymbolInfo &missing,
+ string *pe_file) {
+ return LocateFile(missing.code_file, missing.code_identifier,
+ missing.version, pe_file);
+}
+
+MSSymbolServerConverter::LocateResult
+MSSymbolServerConverter::LocateSymbolFile(const MissingSymbolInfo &missing,
+ string *symbol_file) {
+ return LocateFile(missing.debug_file, missing.debug_identifier,
+ missing.version, symbol_file);
+}
+
+
+// static
+BOOL CALLBACK MSSymbolServerConverter::SymCallback(HANDLE process,
+ ULONG action,
+ ULONG64 data,
+ ULONG64 context) {
+ MSSymbolServerConverter *self =
+ reinterpret_cast<MSSymbolServerConverter *>(context);
+
+ switch (action) {
+ case CBA_EVENT: {
+ IMAGEHLP_CBA_EVENT *cba_event =
+ reinterpret_cast<IMAGEHLP_CBA_EVENT *>(data);
+
+ // Put the string into a string object to be able to use string::find
+ // for substring matching. This is important because the not-found
+ // message does not use the entire string but is appended to the URL
+ // that SymSrv attempted to retrieve.
+ string desc(cba_event->desc);
+
+ // desc_action maps strings (in desc) to boolean pointers that are to
+ // be set to true if the string matches.
+ struct desc_action {
+ const char *desc; // The substring to match.
+ bool *action; // On match, this pointer will be set to true.
+ };
+
+ static const desc_action desc_actions[] = {
+ // When a DNS error occurs, it could be indiciative of network
+ // problems.
+ { "SYMSRV: The server name or address could not be resolved\n",
+ &self->fail_dns_ },
+
+ // This message is produced if no connection is opened.
+ { "SYMSRV: A connection with the server could not be established\n",
+ &self->fail_timeout_ },
+
+ // This message is produced if a connection is established but the
+ // server fails to respond to the HTTP request.
+ { "SYMSRV: The operation timed out\n",
+ &self->fail_timeout_ },
+
+ // This message is produced when the requested file is not found,
+ // even if one or more of the above messages are also produced.
+ // It's trapped to distinguish between not-found and unknown-failure
+ // conditions. Note that this message will not be produced if a
+ // connection is established and the server begins to respond to the
+ // HTTP request but does not finish transmitting the file.
+ { " not found\n",
+ &self->fail_not_found_ }
+ };
+
+ for (int desc_action_index = 0;
+ desc_action_index < sizeof(desc_actions) / sizeof(desc_action);
+ ++desc_action_index) {
+ if (desc.find(desc_actions[desc_action_index].desc) != string::npos) {
+ *(desc_actions[desc_action_index].action) = true;
+ break;
+ }
+ }
+
+ break;
+ }
+ }
+
+ // This function is a mere fly on the wall. Treat everything as unhandled.
+ return FALSE;
+}
+
+// static
+BOOL CALLBACK MSSymbolServerConverter::SymFindFileInPathCallback(
+ const char *filename, void *context) {
+ // FALSE ends the search, indicating that the located symbol file is
+ // satisfactory.
+ return FALSE;
+}
+
+MSSymbolServerConverter::LocateResult
+MSSymbolServerConverter::LocateAndConvertSymbolFile(
+ const MissingSymbolInfo &missing,
+ bool keep_symbol_file,
+ bool keep_pe_file,
+ string *converted_symbol_file,
+ string *symbol_file,
+ string *out_pe_file) {
+ assert(converted_symbol_file);
+ converted_symbol_file->clear();
+ if (symbol_file) {
+ symbol_file->clear();
+ }
+
+ string pdb_file;
+ LocateResult result = LocateSymbolFile(missing, &pdb_file);
+ if (result != LOCATE_SUCCESS) {
+ return result;
+ }
+
+ if (symbol_file && keep_symbol_file) {
+ *symbol_file = pdb_file;
+ }
+
+ // The conversion of a symbol file for a Windows 64-bit module requires
+ // loading of the executable file. If there is no executable file, convert
+ // using only the PDB file. Without an executable file, the conversion will
+ // fail for 64-bit modules but it should succeed for 32-bit modules.
+ string pe_file;
+ result = LocatePEFile(missing, &pe_file);
+ if (result != LOCATE_SUCCESS) {
+ fprintf(stderr, "WARNING: Could not download: %s\n", pe_file.c_str());
+ }
+
+ if (out_pe_file && keep_pe_file) {
+ *out_pe_file = pe_file;
+ }
+
+ // Conversion may fail because the file is corrupt. If a broken file is
+ // kept in the local cache, LocateSymbolFile will not hit the network again
+ // to attempt to locate it. To guard against problems like this, the
+ // symbol file in the local cache will be removed if conversion fails.
+ AutoDeleter pdb_deleter(pdb_file);
+ AutoDeleter pe_deleter(pe_file);
+
+ // Be sure that it's a .pdb file, since we'll be replacing .pdb with .sym
+ // for the converted file's name.
+ string pdb_extension = pdb_file.substr(pdb_file.length() - 4);
+ // strcasecmp is called _stricmp here.
+ if (_stricmp(pdb_extension.c_str(), ".pdb") != 0) {
+ fprintf(stderr, "LocateAndConvertSymbolFile: "
+ "no .pdb extension for %s %s %s %s\n",
+ missing.debug_file.c_str(),
+ missing.debug_identifier.c_str(),
+ missing.version.c_str(),
+ pdb_file.c_str());
+ return LOCATE_FAILURE;
+ }
+
+ PDBSourceLineWriter writer;
+ wstring pe_file_w;
+ if (!WindowsStringUtils::safe_mbstowcs(pe_file, &pe_file_w)) {
+ fprintf(stderr,
+ "LocateAndConvertSymbolFile: "
+ "WindowsStringUtils::safe_mbstowcs failed for %s\n",
+ pe_file.c_str());
+ return LOCATE_FAILURE;
+ }
+ wstring pdb_file_w;
+ if (!WindowsStringUtils::safe_mbstowcs(pdb_file, &pdb_file_w)) {
+ fprintf(stderr,
+ "LocateAndConvertSymbolFile: "
+ "WindowsStringUtils::safe_mbstowcs failed for %s\n",
+ pdb_file_w.c_str());
+ return LOCATE_FAILURE;
+ }
+ if (!writer.Open(pdb_file_w, PDBSourceLineWriter::PDB_FILE)) {
+ fprintf(stderr,
+ "ERROR: PDBSourceLineWriter::Open failed for %s %s %s %ws\n",
+ missing.debug_file.c_str(), missing.debug_identifier.c_str(),
+ missing.version.c_str(), pdb_file_w.c_str());
+ return LOCATE_FAILURE;
+ }
+ if (!writer.SetCodeFile(pe_file_w)) {
+ fprintf(stderr,
+ "ERROR: PDBSourceLineWriter::SetCodeFile failed for %s %s %s %ws\n",
+ missing.debug_file.c_str(), missing.debug_identifier.c_str(),
+ missing.version.c_str(), pe_file_w.c_str());
+ return LOCATE_FAILURE;
+ }
+
+ *converted_symbol_file = pdb_file.substr(0, pdb_file.length() - 4) + ".sym";
+
+ FILE *converted_output = NULL;
+#if _MSC_VER >= 1400 // MSVC 2005/8
+ errno_t err;
+ if ((err = fopen_s(&converted_output, converted_symbol_file->c_str(), "w"))
+ != 0) {
+#else // _MSC_VER >= 1400
+ // fopen_s and errno_t were introduced in MSVC8. Use fopen for earlier
+ // environments. Don't use fopen with MSVC8 and later, because it's
+ // deprecated. fopen does not provide reliable error codes, so just use
+ // -1 in the event of a failure.
+ int err;
+ if (!(converted_output = fopen(converted_symbol_file->c_str(), "w"))) {
+ err = -1;
+#endif // _MSC_VER >= 1400
+ fprintf(stderr, "LocateAndConvertSymbolFile: "
+ "fopen_s: error %d for %s %s %s %s\n",
+ err,
+ missing.debug_file.c_str(),
+ missing.debug_identifier.c_str(),
+ missing.version.c_str(),
+ converted_symbol_file->c_str());
+ return LOCATE_FAILURE;
+ }
+
+ AutoDeleter sym_deleter(*converted_symbol_file);
+
+ bool success = writer.WriteMap(converted_output);
+ fclose(converted_output);
+
+ if (!success) {
+ fprintf(stderr, "LocateAndConvertSymbolFile: "
+ "PDBSourceLineWriter::WriteMap failed for %s %s %s %s\n",
+ missing.debug_file.c_str(),
+ missing.debug_identifier.c_str(),
+ missing.version.c_str(),
+ pdb_file.c_str());
+ return LOCATE_FAILURE;
+ }
+
+ if (keep_symbol_file) {
+ pdb_deleter.Release();
+ }
+
+ if (keep_pe_file) {
+ pe_deleter.Release();
+ }
+
+ sym_deleter.Release();
+
+ return LOCATE_SUCCESS;
+}
+
+} // namespace google_breakpad
diff --git a/toolkit/crashreporter/google-breakpad/src/tools/windows/converter/ms_symbol_server_converter.gyp b/toolkit/crashreporter/google-breakpad/src/tools/windows/converter/ms_symbol_server_converter.gyp
new file mode 100644
index 000000000..57ec79068
--- /dev/null
+++ b/toolkit/crashreporter/google-breakpad/src/tools/windows/converter/ms_symbol_server_converter.gyp
@@ -0,0 +1,46 @@
+# Copyright 2013 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.
+
+{
+ 'includes': [
+ '../../../build/common.gypi',
+ ],
+ 'targets': [
+ {
+ 'target_name': 'ms_symbol_server_converter',
+ 'type': 'static_library',
+ 'msvs_guid': '1463C4CD-23FC-4DE9-BFDE-283338200157',
+ 'sources': [
+ 'ms_symbol_server_converter.cc',
+ ],
+ 'dependencies': [
+ '../../../common/windows/common_windows.gyp:common_windows_lib',
+ ],
+ },
+ ],
+}
diff --git a/toolkit/crashreporter/google-breakpad/src/tools/windows/converter/ms_symbol_server_converter.h b/toolkit/crashreporter/google-breakpad/src/tools/windows/converter/ms_symbol_server_converter.h
new file mode 100644
index 000000000..d601b4333
--- /dev/null
+++ b/toolkit/crashreporter/google-breakpad/src/tools/windows/converter/ms_symbol_server_converter.h
@@ -0,0 +1,219 @@
+// Copyright (c) 2007, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// ms_symbol_server_converter.h: Obtain symbol files from a Microsoft
+// symbol server, and convert them to Breakpad's dumped format.
+//
+// At runtime, MSSymbolServerConverter and code that it calls depend on being
+// able to locate suitable versions of dbghelp.dll and symsrv.dll. For best
+// results, place these files in the same directory as the executable.
+// dbghelp.dll and symsrv.dll as supplied with Debugging Tools for Windows are
+// both redistributable, as indicated by the package's redist.txt file.
+//
+// When connecting to Microsoft's symbol server at
+// http://msdl.microsoft.com/download/symbols/, which provides access to
+// symbols for the operating system itself, symsrv.dll requires agreement to
+// Microsoft's "Terms of Use for Microsoft Symbols and Binaries." Because this
+// library places the symbol engine into a promptless mode, the dialog with the
+// terms will not appear, and use of Microsoft's symbol server will not be
+// possible. To indicate agreement to the terms, create a file called
+// symsrv.yes in the same directory as symsrv.dll. (Note that symsrv.dll will
+// also recognize a symsrv.no file as indicating that you do not accept the
+// terms; the .yes file takes priority over the .no file.) The terms of use
+// are contained within symsrv.dll; they were formerly available online at
+// http://www.microsoft.com/whdc/devtools/debugging/symsrvTOU2.mspx , but
+// do not appear to be available online any longer as of January, 2007. It is
+// possible to view the terms from within WinDbg (Debugging Tools for Windows)
+// by removing any symsrv.yes and symsrv.no files from WinDbg's directory,
+// setting the symbol path to include Microsoft's symbol server (.sympath), and
+// attempting to load symbols from their server (.reload).
+//
+// This code has been tested with dbghelp.dll 6.5.3.7 and symsrv.dll 6.5.3.8,
+// included with Microsoft Visual Studio 8 in Common7/IDE. This has also been
+// tested with dbghelp.dll and symsrv.dll versions 6.6.7.5 and 6.12.2.633,
+// included with the same versions of Debugging Tools for Windows, available at
+// http://www.microsoft.com/whdc/devtools/debugging/ .
+//
+// Author: Mark Mentovai
+
+#ifndef TOOLS_WINDOWS_MS_SYMBOL_SERVER_CONVERTER_H_
+#define TOOLS_WINDOWS_MS_SYMBOL_SERVER_CONVERTER_H_
+
+#include <windows.h>
+
+#include <string>
+#include <vector>
+
+namespace google_breakpad {
+
+using std::string;
+using std::vector;
+
+// MissingSymbolInfo contains the subset of the information in the processor's
+// CodeModule structure relevant to obtaining a missing symbol file. Only
+// debug_file and debug_identifier are relevant in actually obtaining the
+// missing file; the other fields are for convenience.
+struct MissingSymbolInfo {
+ string code_file;
+ string code_identifier;
+ string debug_file;
+ string debug_identifier;
+ string version;
+};
+
+class GUIDOrSignatureIdentifier {
+ public:
+ enum GUIDOrSignatureType {
+ TYPE_NONE = 0,
+ TYPE_GUID,
+ TYPE_SIGNATURE
+ };
+
+ GUIDOrSignatureIdentifier() : type_(TYPE_NONE) {}
+
+ // Converts |identifier|, a debug_identifier-formatted string, into its
+ // component fields: either a GUID and age, or signature and age. If
+ // successful, sets the relevant fields in the object, including the type
+ // field, and returns true. On error, returns false.
+ bool InitializeFromString(const string &identifier);
+
+ GUIDOrSignatureType type() const { return type_; }
+ GUID guid() const { return guid_; }
+ DWORD signature() const { return signature_; }
+ int age() const { return age_; }
+ const void *guid_or_signature_pointer() const { return &guid_; }
+
+ private:
+ GUIDOrSignatureType type_;
+
+ // An identifier contains either a 128-bit uuid or a 32-bit signature.
+ union {
+ GUID guid_;
+ DWORD signature_;
+ };
+
+ // All identifiers used here have age fields, which indicate a specific
+ // revision given a uuid or signature.
+ int age_;
+};
+
+class MSSymbolServerConverter {
+ public:
+ enum LocateResult {
+ LOCATE_FAILURE = 0,
+ LOCATE_NOT_FOUND, // Authoritative: the file is not present.
+ LOCATE_RETRY, // Transient (network?) error, try again later.
+ LOCATE_SUCCESS
+ };
+
+ // Create a new object. local_cache is the location (pathname) of a local
+ // symbol store used to hold downloaded and converted symbol files. This
+ // directory will be created by LocateSymbolFile when it successfully
+ // retrieves a symbol file. symbol_servers contains a list of locations (URLs
+ // or pathnames) of the upstream symbol server stores, given in order of
+ // preference, with the first string in the vector identifying the first
+ // store to try. The vector must contain at least one string. None of the
+ // strings passed to this constructor may contain asterisk ('*') or semicolon
+ // (';') characters, as the symbol engine uses these characters as separators.
+ MSSymbolServerConverter(const string &local_cache,
+ const vector<string> &symbol_servers);
+
+ // Locates the PE file (DLL or EXE) specified by the identifying information
+ // in |missing|, by checking the symbol stores identified when the object
+ // was created. When returning LOCATE_SUCCESS, pe_file is set to
+ // the pathname of the decompressed PE file as it is stored in the
+ // local cache.
+ LocateResult LocatePEFile(const MissingSymbolInfo &missing, string *pe_file);
+
+ // Locates the symbol file specified by the identifying information in
+ // |missing|, by checking the symbol stores identified when the object
+ // was created. When returning LOCATE_SUCCESS, symbol_file is set to
+ // the pathname of the decompressed symbol file as it is stored in the
+ // local cache.
+ LocateResult LocateSymbolFile(const MissingSymbolInfo &missing,
+ string *symbol_file);
+
+ // Calls LocateSymbolFile and converts the returned symbol file to the
+ // dumped-symbol format, storing it adjacent to the symbol file. The
+ // only conversion supported is from pdb files. Returns the return
+ // value of LocateSymbolFile, or if LocateSymbolFile succeeds but
+ // conversion fails, returns LOCATE_FAILURE. The pathname to the
+ // pdb file and to the converted symbol file are returned in
+ // |converted_symbol_file|, |symbol_file|, and |pe_file|. |symbol_file| and
+ // |pe_file| are optional and may be NULL. If only the converted symbol file
+ // is desired, set |keep_symbol_file| and |keep_pe_file| to false to indicate
+ // that the original symbol file (pdb) and executable file (exe, dll) should
+ // be deleted after conversion.
+ LocateResult LocateAndConvertSymbolFile(const MissingSymbolInfo &missing,
+ bool keep_symbol_file,
+ bool keep_pe_file,
+ string *converted_symbol_file,
+ string *symbol_file,
+ string *pe_file);
+
+ private:
+ // Locates the PDB or PE file (DLL or EXE) specified by the identifying
+ // information in |debug_or_code_file| and |debug_or_code_id|, by checking
+ // the symbol stores identified when the object was created. When
+ // returning LOCATE_SUCCESS, file_name is set to the pathname of the
+ // decompressed PDB or PE file file as it is stored in the local cache.
+ LocateResult LocateFile(const string &debug_or_code_file,
+ const string &debug_or_code_id,
+ const string &version, string *file_name);
+
+ // Called by various SymSrv functions to report status as progress is made
+ // and to allow the callback to influence processing. Messages sent to this
+ // callback can be used to distinguish between the various failure modes
+ // that SymFindFileInPath might encounter.
+ static BOOL CALLBACK SymCallback(HANDLE process, ULONG action, ULONG64 data,
+ ULONG64 context);
+
+ // Called by SymFindFileInPath (in LocateSymbolFile) after a candidate
+ // symbol file is located, when it's present in the local cache.
+ // SymFindFileInPath actually seems to accept NULL for a callback function
+ // and behave properly for our needs in that case, but the documentation
+ // doesn't mention it, so this little callback is provided.
+ static BOOL CALLBACK SymFindFileInPathCallback(const char *filename,
+ void *context);
+
+ // The search path used by SymSrv, built based on the arguments to the
+ // constructor.
+ string symbol_path_;
+
+ // SymCallback will set at least one of these failure variables if
+ // SymFindFileInPath fails for an expected reason.
+ bool fail_dns_; // DNS failures (fail_not_found_ will also be set).
+ bool fail_timeout_; // Timeouts (fail_not_found_ will also be set).
+ bool fail_not_found_; // The file could not be found. If this is the only
+ // fail_* member set, then it is authoritative.
+};
+
+} // namespace google_breakpad
+
+#endif // TOOLS_WINDOWS_MS_SYMBOL_SERVER_CONVERTER_H_
diff --git a/toolkit/crashreporter/google-breakpad/src/tools/windows/dump_syms/dump_syms.cc b/toolkit/crashreporter/google-breakpad/src/tools/windows/dump_syms/dump_syms.cc
new file mode 100644
index 000000000..3e8827b61
--- /dev/null
+++ b/toolkit/crashreporter/google-breakpad/src/tools/windows/dump_syms/dump_syms.cc
@@ -0,0 +1,61 @@
+// 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.
+
+// Windows utility to dump the line number data from a pdb file to
+// a text-based format that we can use from the minidump processor.
+
+#include <stdio.h>
+
+#include <string>
+
+#include "common/windows/pdb_source_line_writer.h"
+
+using std::wstring;
+using google_breakpad::PDBSourceLineWriter;
+
+int wmain(int argc, wchar_t **argv) {
+ if (argc < 2) {
+ fprintf(stderr, "Usage: %ws <file.[pdb|exe|dll]>\n", argv[0]);
+ return 1;
+ }
+
+ PDBSourceLineWriter writer;
+ if (!writer.Open(wstring(argv[1]), PDBSourceLineWriter::ANY_FILE)) {
+ fprintf(stderr, "Open failed\n");
+ return 1;
+ }
+
+ if (!writer.WriteMap(stdout)) {
+ fprintf(stderr, "WriteMap failed\n");
+ return 1;
+ }
+
+ writer.Close();
+ return 0;
+}
diff --git a/toolkit/crashreporter/google-breakpad/src/tools/windows/dump_syms/dump_syms.gyp b/toolkit/crashreporter/google-breakpad/src/tools/windows/dump_syms/dump_syms.gyp
new file mode 100644
index 000000000..b815574b2
--- /dev/null
+++ b/toolkit/crashreporter/google-breakpad/src/tools/windows/dump_syms/dump_syms.gyp
@@ -0,0 +1,64 @@
+# Copyright 2013 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.
+
+{
+ 'includes': [
+ '../../../build/common.gypi',
+ ],
+ 'targets': [
+ {
+ 'target_name': 'dump_syms',
+ 'type': 'executable',
+ 'sources': [
+ 'dump_syms.cc',
+ ],
+ 'dependencies': [
+ '../../../common/windows/common_windows.gyp:common_windows_lib',
+ ],
+ },
+ {
+ 'target_name': 'dump_syms_unittest',
+ 'type': 'executable',
+ 'sources': [
+ 'dump_syms_unittest.cc',
+ ],
+ 'dependencies': [
+ '<(DEPTH)/client/windows/unittests/testing.gyp:gmock',
+ '<(DEPTH)/client/windows/unittests/testing.gyp:gtest',
+ 'dump_syms',
+ ],
+ 'msvs_settings': {
+ 'VCLinkerTool': {
+ 'AdditionalDependencies': [
+ 'shell32.lib',
+ ],
+ },
+ },
+ },
+ ],
+}
diff --git a/toolkit/crashreporter/google-breakpad/src/tools/windows/dump_syms/dump_syms_unittest.cc b/toolkit/crashreporter/google-breakpad/src/tools/windows/dump_syms/dump_syms_unittest.cc
new file mode 100644
index 000000000..61f84431e
--- /dev/null
+++ b/toolkit/crashreporter/google-breakpad/src/tools/windows/dump_syms/dump_syms_unittest.cc
@@ -0,0 +1,204 @@
+// Copyright 2003 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 <Windows.h>
+#include <shellapi.h>
+
+#include <string>
+#include <utility>
+
+#include "gmock/gmock.h"
+#include "gtest/gtest.h"
+
+namespace tools {
+namespace windows {
+namespace dump_syms {
+
+namespace {
+
+// Root names of PDB and dumped symbol files to be regression tested. These are
+// specified in complexity of the resulting dumped symbol files.
+const wchar_t* kRootNames[] = {
+ // A PDB file with no OMAP data.
+ L"dump_syms_regtest",
+ // A PDB file with OMAP data for an image that has been function-level
+ // reordered.
+ L"omap_reorder_funcs",
+ // A PDB file with OMAP data for an image that had new content injected, all
+ // of it with source data.
+ L"omap_stretched_filled",
+ // A PDB file with OMAP data for an image that had new content injected, but
+ // without source data.
+ L"omap_stretched",
+ // A PDB file with OMAP data for an image that has been basic block reordered.
+ L"omap_reorder_bbs",
+ // A 64bit PDB file with no OMAP data.
+ L"dump_syms_regtest64",
+};
+
+void TrimLastComponent(const std::wstring& path,
+ std::wstring* trimmed,
+ std::wstring* component) {
+ size_t len = path.size();
+ while (len > 0 && path[len - 1] != '\\')
+ --len;
+
+ if (component != NULL)
+ component->assign(path.c_str() + len, path.c_str() + path.size());
+
+ while (len > 0 && path[len - 1] == '\\')
+ --len;
+
+ if (trimmed != NULL)
+ trimmed->assign(path.c_str(), len);
+}
+
+// Get the directory of the current executable.
+bool GetSelfDirectory(std::wstring* self_dir) {
+ std::wstring command_line = GetCommandLineW();
+
+ int num_args = 0;
+ wchar_t** args = NULL;
+ args = ::CommandLineToArgvW(command_line.c_str(), &num_args);
+ if (args == NULL)
+ return false;
+
+ *self_dir = args[0];
+ TrimLastComponent(*self_dir, self_dir, NULL);
+
+ return true;
+}
+
+void RunCommand(const std::wstring& command_line,
+ std::string* stdout_string) {
+ // Create a PIPE for the child process stdout.
+ HANDLE child_stdout_read = 0;
+ HANDLE child_stdout_write = 0;
+ SECURITY_ATTRIBUTES sec_attr_stdout = {};
+ sec_attr_stdout.nLength = sizeof(sec_attr_stdout);
+ sec_attr_stdout.bInheritHandle = TRUE;
+ ASSERT_TRUE(::CreatePipe(&child_stdout_read, &child_stdout_write,
+ &sec_attr_stdout, 0));
+ ASSERT_TRUE(::SetHandleInformation(child_stdout_read, HANDLE_FLAG_INHERIT,
+ 0));
+
+ // Create a PIPE for the child process stdin.
+ HANDLE child_stdin_read = 0;
+ HANDLE child_stdin_write = 0;
+ SECURITY_ATTRIBUTES sec_attr_stdin = {};
+ sec_attr_stdin.nLength = sizeof(sec_attr_stdin);
+ sec_attr_stdin.bInheritHandle = TRUE;
+ ASSERT_TRUE(::CreatePipe(&child_stdin_read, &child_stdin_write,
+ &sec_attr_stdin, 0));
+ ASSERT_TRUE(::SetHandleInformation(child_stdin_write, HANDLE_FLAG_INHERIT,
+ 0));
+
+ // Startup the child.
+ STARTUPINFO startup_info = {};
+ PROCESS_INFORMATION process_info = {};
+ startup_info.cb = sizeof(STARTUPINFO);
+ startup_info.hStdError = child_stdout_write;
+ startup_info.hStdInput = child_stdin_read;
+ startup_info.hStdOutput = child_stdout_write;
+ startup_info.dwFlags = STARTF_USESTDHANDLES;
+ ASSERT_TRUE(::CreateProcessW(NULL, (LPWSTR)command_line.c_str(), NULL, NULL,
+ TRUE, 0, NULL, NULL,
+ &startup_info, &process_info));
+
+ // Collect the output.
+ ASSERT_TRUE(::CloseHandle(child_stdout_write));
+ char buffer[4096] = {};
+ DWORD bytes_read = 0;
+ while (::ReadFile(child_stdout_read, buffer, sizeof(buffer), &bytes_read,
+ NULL) && bytes_read > 0) {
+ stdout_string->append(buffer, bytes_read);
+ }
+
+ // Wait for the process to finish.
+ ::WaitForSingleObject(process_info.hProcess, INFINITE);
+
+ // Shut down all of our handles.
+ ASSERT_TRUE(::CloseHandle(process_info.hThread));
+ ASSERT_TRUE(::CloseHandle(process_info.hProcess));
+ ASSERT_TRUE(::CloseHandle(child_stdin_write));
+ ASSERT_TRUE(::CloseHandle(child_stdin_read));
+ ASSERT_TRUE(::CloseHandle(child_stdout_read));
+}
+
+void GetFileContents(const std::wstring& path, std::string* content) {
+ FILE* f = ::_wfopen(path.c_str(), L"rb");
+ ASSERT_TRUE(f != NULL);
+
+ char buffer[4096] = {};
+ while (true) {
+ size_t bytes_read = ::fread(buffer, 1, sizeof(buffer), f);
+ if (bytes_read == 0)
+ break;
+ content->append(buffer, bytes_read);
+ }
+}
+
+class DumpSymsRegressionTest : public testing::Test {
+ public:
+ virtual void SetUp() {
+ std::wstring self_dir;
+ ASSERT_TRUE(GetSelfDirectory(&self_dir));
+ dump_syms_exe = self_dir + L"\\dump_syms.exe";
+
+ TrimLastComponent(self_dir, &testdata_dir, NULL);
+ testdata_dir += L"\\testdata";
+ }
+
+ std::wstring dump_syms_exe;
+ std::wstring testdata_dir;
+};
+
+} //namespace
+
+TEST_F(DumpSymsRegressionTest, EnsureDumpedSymbolsMatch) {
+ for (size_t i = 0; i < sizeof(kRootNames) / sizeof(kRootNames[0]); ++i) {
+ const wchar_t* root_name = kRootNames[i];
+ std::wstring root_path = testdata_dir + L"\\" + root_name;
+
+ std::wstring sym_path = root_path + L".sym";
+ std::string expected_symbols;
+ ASSERT_NO_FATAL_FAILURE(GetFileContents(sym_path, &expected_symbols));
+
+ std::wstring pdb_path = root_path + L".pdb";
+ std::wstring command_line = L"\"" + dump_syms_exe + L"\" \"" +
+ pdb_path + L"\"";
+ std::string symbols;
+ ASSERT_NO_FATAL_FAILURE(RunCommand(command_line, &symbols));
+
+ EXPECT_EQ(expected_symbols, symbols);
+ }
+}
+
+} // namespace dump_syms
+} // namespace windows
+} // namespace tools \ No newline at end of file
diff --git a/toolkit/crashreporter/google-breakpad/src/tools/windows/dump_syms/moz.build b/toolkit/crashreporter/google-breakpad/src/tools/windows/dump_syms/moz.build
new file mode 100644
index 000000000..2a286da53
--- /dev/null
+++ b/toolkit/crashreporter/google-breakpad/src/tools/windows/dump_syms/moz.build
@@ -0,0 +1,31 @@
+# -*- 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/.
+
+HostProgram('dump_syms')
+
+HOST_SOURCES += [
+ '../../../common/windows/dia_util.cc',
+ '../../../common/windows/guid_string.cc',
+ '../../../common/windows/omap.cc',
+ '../../../common/windows/pdb_source_line_writer.cc',
+ '../../../common/windows/string_utils.cc',
+ 'dump_syms.cc',
+]
+
+HOST_CXXFLAGS += [
+ '-O2',
+ '-EHsc',
+ '-MD'
+]
+
+HOST_OS_LIBS += [
+ 'diaguids',
+ 'imagehlp'
+]
+
+LOCAL_INCLUDES += [
+ '../../..'
+]
diff --git a/toolkit/crashreporter/google-breakpad/src/tools/windows/dump_syms/run_regtest.sh b/toolkit/crashreporter/google-breakpad/src/tools/windows/dump_syms/run_regtest.sh
new file mode 100755
index 000000000..1f20f64fd
--- /dev/null
+++ b/toolkit/crashreporter/google-breakpad/src/tools/windows/dump_syms/run_regtest.sh
@@ -0,0 +1,53 @@
+#!/bin/sh
+
+# 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.
+
+Release/dump_syms.exe testdata/dump_syms_regtest.pdb | \
+ tr -d '\015' > \
+ testdata/dump_syms_regtest.new
+status=$?
+
+if [ $status -ne 0 ] ; then
+ echo "FAIL, dump_syms.exe failed"
+ exit $status
+fi
+
+diff -u testdata/dump_syms_regtest.new testdata/dump_syms_regtest.sym > \
+ testdata/dump_syms_regtest.diff
+status=$?
+
+if [ $status -eq 0 ] ; then
+ rm testdata/dump_syms_regtest.diff testdata/dump_syms_regtest.new
+ echo "PASS"
+else
+ echo "FAIL, see testdata/dump_syms_regtest.[new|diff]"
+fi
+
+exit $status
diff --git a/toolkit/crashreporter/google-breakpad/src/tools/windows/refresh_binaries.bat b/toolkit/crashreporter/google-breakpad/src/tools/windows/refresh_binaries.bat
new file mode 100644
index 000000000..d881ae64b
--- /dev/null
+++ b/toolkit/crashreporter/google-breakpad/src/tools/windows/refresh_binaries.bat
@@ -0,0 +1,27 @@
+REM This batch file is meant to facilitate regenerating prebuilt binaries for
+REM the Windows tools.
+REM You MUST run it from a Visual Studio xxxx Command Prompt. To do this,
+REM navigate to:
+REM
+REM Start->Programs->Microsoft Visual Studio XXXX->Tools->
+REM Visual Studio Command Prompt
+REM
+REM Then run this batch file. It performs an SVN update, edits the
+REM README.binaries file to contain
+REM the revision number, and builds the tools. You must run 'svn commit' to
+REM commit the pending edits to the repository.
+
+pushd %~dp0\..\..\
+call svn update --accept postpone
+cd tools\windows
+devenv symupload\symupload.vcproj /rebuild Release
+copy symupload\Release\symupload.exe binaries\
+REM switch back to top level so that 'svn info' displays useful information.
+cd ..\..\
+echo This checkin of the binaries was created by refresh_binaries.bat. > %TEMP%\checkin.txt
+echo Date: %DATE% %TIME% >> %TEMP%\checkin.txt
+echo Repository information (output of 'svn info') follows: >> %TEMP%\checkin.txt
+call svn info >> %TEMP%\checkin.txt
+echo Done!
+echo type 'svn commit -F %%TEMP%%\checkin.txt' to commit.
+popd
diff --git a/toolkit/crashreporter/google-breakpad/src/tools/windows/symupload/symupload.cc b/toolkit/crashreporter/google-breakpad/src/tools/windows/symupload/symupload.cc
new file mode 100644
index 000000000..fa5294ded
--- /dev/null
+++ b/toolkit/crashreporter/google-breakpad/src/tools/windows/symupload/symupload.cc
@@ -0,0 +1,259 @@
+// 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.
+
+// Tool to upload an exe/dll and its associated symbols to an HTTP server.
+// The PDB file is located automatically, using the path embedded in the
+// executable. 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.exe"
+// debug_file: the basename of the debugging file, e.g. "app.pdb"
+// debug_identifier: the debug file's identifier, usually consisting of
+// the guid and age embedded in the pdb, e.g.
+// "11111111BBBB3333DDDD555555555555F"
+// product: the HTTP-friendly product name, e.g. "MyApp"
+// version: the file version of the module, e.g. "1.2.3.4"
+// os: the operating system that the module was built for, always
+// "windows" in this implementation.
+// cpu: the CPU that the module was built for, typically "x86".
+// symbol_file: the contents of the breakpad-format symbol file
+
+#include <windows.h>
+#include <dbghelp.h>
+#include <wininet.h>
+
+#include <cstdio>
+#include <map>
+#include <string>
+#include <vector>
+
+#include "common/windows/string_utils-inl.h"
+
+#include "common/windows/http_upload.h"
+#include "common/windows/pdb_source_line_writer.h"
+
+using std::string;
+using std::wstring;
+using std::vector;
+using std::map;
+using google_breakpad::HTTPUpload;
+using google_breakpad::PDBModuleInfo;
+using google_breakpad::PDBSourceLineWriter;
+using google_breakpad::WindowsStringUtils;
+
+// Extracts the file version information for the given filename,
+// as a string, for example, "1.2.3.4". Returns true on success.
+static bool GetFileVersionString(const wchar_t *filename, wstring *version) {
+ DWORD handle;
+ DWORD version_size = GetFileVersionInfoSize(filename, &handle);
+ if (version_size < sizeof(VS_FIXEDFILEINFO)) {
+ return false;
+ }
+
+ vector<char> version_info(version_size);
+ if (!GetFileVersionInfo(filename, handle, version_size, &version_info[0])) {
+ return false;
+ }
+
+ void *file_info_buffer = NULL;
+ unsigned int file_info_length;
+ if (!VerQueryValue(&version_info[0], L"\\",
+ &file_info_buffer, &file_info_length)) {
+ return false;
+ }
+
+ // The maximum value of each version component is 65535 (0xffff),
+ // so the max length is 24, including the terminating null.
+ wchar_t ver_string[24];
+ VS_FIXEDFILEINFO *file_info =
+ reinterpret_cast<VS_FIXEDFILEINFO*>(file_info_buffer);
+ swprintf(ver_string, sizeof(ver_string) / sizeof(ver_string[0]),
+ L"%d.%d.%d.%d",
+ file_info->dwFileVersionMS >> 16,
+ file_info->dwFileVersionMS & 0xffff,
+ file_info->dwFileVersionLS >> 16,
+ file_info->dwFileVersionLS & 0xffff);
+
+ // remove when VC++7.1 is no longer supported
+ ver_string[sizeof(ver_string) / sizeof(ver_string[0]) - 1] = L'\0';
+
+ *version = ver_string;
+ return true;
+}
+
+// Creates a new temporary file and writes the symbol data from the given
+// exe/dll file to it. Returns the path to the temp file in temp_file_path
+// and information about the pdb in pdb_info.
+static bool DumpSymbolsToTempFile(const wchar_t *file,
+ wstring *temp_file_path,
+ PDBModuleInfo *pdb_info) {
+ google_breakpad::PDBSourceLineWriter writer;
+ // Use EXE_FILE to get information out of the exe/dll in addition to the
+ // pdb. The name and version number of the exe/dll are of value, and
+ // there's no way to locate an exe/dll given a pdb.
+ if (!writer.Open(file, PDBSourceLineWriter::EXE_FILE)) {
+ return false;
+ }
+
+ wchar_t temp_path[_MAX_PATH];
+ if (GetTempPath(_MAX_PATH, temp_path) == 0) {
+ return false;
+ }
+
+ wchar_t temp_filename[_MAX_PATH];
+ if (GetTempFileName(temp_path, L"sym", 0, temp_filename) == 0) {
+ return false;
+ }
+
+ FILE *temp_file = NULL;
+#if _MSC_VER >= 1400 // MSVC 2005/8
+ if (_wfopen_s(&temp_file, temp_filename, L"w") != 0)
+#else // _MSC_VER >= 1400
+ // _wfopen_s was introduced in MSVC8. Use _wfopen for earlier environments.
+ // Don't use it with MSVC8 and later, because it's deprecated.
+ if (!(temp_file = _wfopen(temp_filename, L"w")))
+#endif // _MSC_VER >= 1400
+ {
+ return false;
+ }
+
+ bool success = writer.WriteMap(temp_file);
+ fclose(temp_file);
+ if (!success) {
+ _wunlink(temp_filename);
+ return false;
+ }
+
+ *temp_file_path = temp_filename;
+
+ return writer.GetModuleInfo(pdb_info);
+}
+
+__declspec(noreturn) void printUsageAndExit() {
+ wprintf(L"Usage:\n\n"
+ L" symupload [--timeout NN] [--product product_name] ^\n"
+ L" <file.exe|file.dll> <symbol upload URL> ^\n"
+ L" [...<symbol upload URLs>]\n\n");
+ wprintf(L" - Timeout is in milliseconds, or can be 0 to be unlimited.\n");
+ wprintf(L" - product_name is an HTTP-friendly product name. It must only\n"
+ L" contain an ascii subset: alphanumeric and punctuation.\n"
+ L" This string is case-sensitive.\n\n");
+ wprintf(L"Example:\n\n"
+ L" symupload.exe --timeout 0 --product Chrome ^\n"
+ L" chrome.dll http://no.free.symbol.server.for.you\n");
+ exit(0);
+}
+int wmain(int argc, wchar_t *argv[]) {
+ const wchar_t *module;
+ const wchar_t *product = nullptr;
+ int timeout = -1;
+ int currentarg = 1;
+ while (argc > currentarg + 1) {
+ if (!wcscmp(L"--timeout", argv[currentarg])) {
+ timeout = _wtoi(argv[currentarg + 1]);
+ currentarg += 2;
+ continue;
+ }
+ if (!wcscmp(L"--product", argv[currentarg])) {
+ product = argv[currentarg + 1];
+ currentarg += 2;
+ continue;
+ }
+ break;
+ }
+
+ if (argc >= currentarg + 2)
+ module = argv[currentarg++];
+ else
+ printUsageAndExit();
+
+ wstring symbol_file;
+ PDBModuleInfo pdb_info;
+ if (!DumpSymbolsToTempFile(module, &symbol_file, &pdb_info)) {
+ fwprintf(stderr, L"Could not get symbol data from %s\n", module);
+ return 1;
+ }
+
+ wstring code_file = WindowsStringUtils::GetBaseName(wstring(module));
+
+ map<wstring, wstring> parameters;
+ parameters[L"code_file"] = code_file;
+ parameters[L"debug_file"] = pdb_info.debug_file;
+ parameters[L"debug_identifier"] = pdb_info.debug_identifier;
+ parameters[L"os"] = L"windows"; // This version of symupload is Windows-only
+ parameters[L"cpu"] = pdb_info.cpu;
+
+ // Don't make a missing product name a hard error. Issue a warning and let
+ // the server decide whether to reject files without product name.
+ if (product) {
+ parameters[L"product"] = product;
+ } else {
+ fwprintf(
+ stderr,
+ L"Warning: No product name (flag --product) was specified for %s\n",
+ module);
+ }
+
+ // Don't make a missing version a hard error. Issue a warning, and let the
+ // server decide whether to reject files without versions.
+ wstring file_version;
+ if (GetFileVersionString(module, &file_version)) {
+ parameters[L"version"] = file_version;
+ } else {
+ fwprintf(stderr, L"Warning: Could not get file version for %s\n", module);
+ }
+
+ map<wstring, wstring> files;
+ files[L"symbol_file"] = symbol_file;
+
+ bool success = true;
+
+ while (currentarg < argc) {
+ int response_code;
+ if (!HTTPUpload::SendRequest(argv[currentarg], parameters, files,
+ timeout == -1 ? NULL : &timeout,
+ nullptr, &response_code)) {
+ success = false;
+ fwprintf(stderr,
+ L"Symbol file upload to %s failed. Response code = %ld\n",
+ argv[currentarg], response_code);
+ }
+ currentarg++;
+ }
+
+ _wunlink(symbol_file.c_str());
+
+ if (success) {
+ wprintf(L"Uploaded symbols for windows-%s/%s/%s (%s %s)\n",
+ pdb_info.cpu.c_str(), pdb_info.debug_file.c_str(),
+ pdb_info.debug_identifier.c_str(), code_file.c_str(),
+ file_version.c_str());
+ }
+
+ return success ? 0 : 1;
+}
diff --git a/toolkit/crashreporter/google-breakpad/src/tools/windows/symupload/symupload.gyp b/toolkit/crashreporter/google-breakpad/src/tools/windows/symupload/symupload.gyp
new file mode 100644
index 000000000..d7e5fb7b9
--- /dev/null
+++ b/toolkit/crashreporter/google-breakpad/src/tools/windows/symupload/symupload.gyp
@@ -0,0 +1,45 @@
+# Copyright 2013 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.
+
+{
+ 'includes': [
+ '../../../build/common.gypi',
+ ],
+ 'targets': [
+ {
+ 'target_name': 'symupload',
+ 'type': 'executable',
+ 'sources': [
+ 'symupload.cc',
+ ],
+ 'dependencies': [
+ '../../../common/windows/common_windows.gyp:common_windows_lib',
+ ],
+ },
+ ],
+}