From 4397df6b409ca84f63838fa635fc2abe8af80b71 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Remko=20Tron=C3=A7on?= <git@el-tramo.be>
Date: Fri, 17 Aug 2012 23:07:13 +0200
Subject: Added Breakpad support for Windows.


diff --git a/.gitignore b/.gitignore
index c70de7b..748acd5 100644
--- a/.gitignore
+++ b/.gitignore
@@ -15,6 +15,7 @@
 *.swp
 *.nib
 *.exe
+*.syms
 *.dll
 *.lib
 *.exp
diff --git a/3rdParty/Breakpad/.gitignore b/3rdParty/Breakpad/.gitignore
new file mode 100644
index 0000000..77270bf
--- /dev/null
+++ b/3rdParty/Breakpad/.gitignore
@@ -0,0 +1 @@
+dump_syms
diff --git a/3rdParty/Breakpad/SConscript b/3rdParty/Breakpad/SConscript
new file mode 100644
index 0000000..142634b
--- /dev/null
+++ b/3rdParty/Breakpad/SConscript
@@ -0,0 +1,97 @@
+Import("env")
+
+# Currently disabling breakpad for all platforms except windows
+if env["PLATFORM"] == "win32" :
+
+################################################################################
+# Module flags
+################################################################################
+
+	if env["SCONS_STAGE"] == "flags" :
+		env["HAVE_BREAKPAD"] = True
+		env["BREAKPAD_FLAGS"] = {
+				"CPPPATH": [env.Dir("src")],
+				"CPPFLAGS": [],
+				"LIBPATH": [env.Dir(".")],
+				"LIBS": ["Swift_BreakPad"]
+			}
+
+################################################################################
+# Build
+################################################################################
+
+	if env["SCONS_STAGE"] == "build" :
+		myenv = env.Clone()
+		myenv.Replace(CXXFLAGS = [flag for flag in env["CXXFLAGS"] if not flag.startswith("-W")])
+		myenv.Append(CPPPATH = ["src"])
+
+		lib_sources = []
+		dumpsyms_sources = []
+		common_sources = []
+		if myenv["PLATFORM"] == "win32" :
+			myenv.Append(CPPDEFINES = ["UNICODE"])
+			lib_sources += [
+				"src/client/windows/handler/exception_handler.cc",
+				"src/client/windows/crash_generation/crash_generation_client.cc",
+				"src/common/windows/guid_string.cc",
+			]
+
+		if myenv["PLATFORM"] == "darwin" or myenv["PLATFORM"] == "linux" :
+			lib_sources += [
+			]
+			common_sources += [
+				"src/common/md5.cc",
+			]
+		
+		if myenv["PLATFORM"] == "darwin" :
+			myenv.Append(CPPDEFINES = ["HAVE_MACH_O_NLIST_H"])
+			lib_sources += [
+				"src/client/mac/handler/exception_handler.cc",
+				"src/client/mac/handler/minidump_generator.cc",
+				"src/client/mac/handler/dynamic_images.cc",
+				"src/client/mac/handler/breakpad_nlist_64.cc",
+				"src/client/mac/crash_generation/crash_generation_client.cc",
+				"src/common/mac/MachIPC.mm",
+				"src/common/mac/string_utilities.cc",
+				"src/common/mac/bootstrap_compat.cc",
+				"src/client/minidump_file_writer.cc",
+				"src/common/string_conversion.cc",
+				"src/common/convert_UTF.c",
+			]
+			common_sources += [
+				"src/common/mac/macho_id.cc",
+				"src/common/mac/macho_walker.cc",
+				"src/common/mac/file_id.cc",
+				"src/common/mac/macho_utilities.cc",
+			]
+			dumpsyms_sources += [
+				"src/tools/mac/dump_syms/dump_syms_tool.mm",
+				"src/common/mac/dump_syms.mm",
+				"src/common/mac/macho_reader.cc",
+				"src/common/dwarf/bytereader.cc",
+				"src/common/dwarf/dwarf2reader.cc",
+				"src/common/dwarf/dwarf2diehandler.cc",
+				"src/common/dwarf_line_to_module.cc",
+				"src/common/dwarf_cfi_to_module.cc",
+				"src/common/dwarf_cu_to_module.cc",
+				"src/common/stabs_to_module.cc",
+				"src/common/stabs_reader.cc",
+				"src/common/module.cc",
+				"src/common/language.cc",
+			]
+
+		if myenv["PLATFORM"] == "linux" :
+			dumpsyms_sources += ["src/tools/linux/dump_syms/dump_syms.cc"]
+
+		common_objects = myenv.StaticObject(common_sources)
+
+		myenv.StaticLibrary("Swift_BreakPad", lib_sources + common_objects)
+
+		#if myenv["PLATFORM"] == "darwin" or myenv["PLATFORM"] == "linux" :
+		#	myenv.Program("dump_syms", dumpsyms_sources + common_objects)
+
+else :
+
+	if env["SCONS_STAGE"] == "flags" :
+		env["HAVE_BREAKPAD"] = False
+		env["BREAKPAD_FLAGS"] = {}
diff --git a/3rdParty/Breakpad/src/COPYING b/3rdParty/Breakpad/src/COPYING
new file mode 100644
index 0000000..d15b0c2
--- /dev/null
+++ b/3rdParty/Breakpad/src/COPYING
@@ -0,0 +1,28 @@
+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.
diff --git a/3rdParty/Breakpad/src/client/mac/crash_generation/crash_generation_client.cc b/3rdParty/Breakpad/src/client/mac/crash_generation/crash_generation_client.cc
new file mode 100644
index 0000000..ceeb3b3
--- /dev/null
+++ b/3rdParty/Breakpad/src/client/mac/crash_generation/crash_generation_client.cc
@@ -0,0 +1,72 @@
+// 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.
+
+#include "client/mac/crash_generation/crash_generation_client.h"
+
+#include "client/mac/crash_generation/crash_generation_server.h"
+#include "common/mac/MachIPC.h"
+
+namespace google_breakpad {
+
+bool CrashGenerationClient::RequestDumpForException(
+    int exception_type,
+    int exception_code,
+    int exception_subcode,
+    mach_port_t crashing_thread) {
+  // The server will send a message to this port indicating that it
+  // has finished its work.
+  ReceivePort acknowledge_port;
+
+  MachSendMessage message(kDumpRequestMessage);
+  message.AddDescriptor(mach_task_self());            // this task
+  message.AddDescriptor(crashing_thread);             // crashing thread
+  message.AddDescriptor(mach_thread_self());          // handler thread
+  message.AddDescriptor(acknowledge_port.GetPort());  // message receive port
+
+  ExceptionInfo info;
+  info.exception_type = exception_type;
+  info.exception_code = exception_code;
+  info.exception_subcode = exception_subcode;
+  message.SetData(&info, sizeof(info));
+
+  const mach_msg_timeout_t kSendTimeoutMs = 2 * 1000;
+  kern_return_t result = sender_.SendMessage(message, kSendTimeoutMs);
+  if (result != KERN_SUCCESS)
+    return false;
+
+  // Give the server slightly longer to reply since it has to
+  // inspect this task and write the minidump.
+  const mach_msg_timeout_t kReceiveTimeoutMs = 5 * 1000;
+  MachReceiveMessage acknowledge_message;
+  result = acknowledge_port.WaitForMessage(&acknowledge_message,
+					   kReceiveTimeoutMs);
+  return result == KERN_SUCCESS;
+}
+
+}  // namespace google_breakpad
diff --git a/3rdParty/Breakpad/src/client/mac/crash_generation/crash_generation_client.h b/3rdParty/Breakpad/src/client/mac/crash_generation/crash_generation_client.h
new file mode 100644
index 0000000..527f577
--- /dev/null
+++ b/3rdParty/Breakpad/src/client/mac/crash_generation/crash_generation_client.h
@@ -0,0 +1,65 @@
+// 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.
+
+#ifndef GOOGLE_BREAKPAD_CLIENT_MAC_CRASH_GENERATION_CRASH_GENERATION_CLIENT_H_
+#define GOOGLE_BREAKPAD_CLIENT_MAC_CRASH_GENERATION_CRASH_GENERATION_CLIENT_H_
+
+#include "common/mac/MachIPC.h"
+
+namespace google_breakpad {
+
+class CrashGenerationClient {
+ public:
+  explicit CrashGenerationClient(const char* mach_port_name)
+    : sender_(mach_port_name) {
+  }
+
+  // Request the crash server to generate a dump.
+  //
+  // Return true if the dump was successful; false otherwise.
+  bool RequestDumpForException(int exception_type,
+			       int exception_code,
+			       int exception_subcode,
+			       mach_port_t crashing_thread);
+
+  bool RequestDump() {
+    return RequestDumpForException(0, 0, 0, MACH_PORT_NULL);
+  }
+
+ private:
+  MachPortSender sender_;
+
+  // Prevent copy construction and assignment.
+  CrashGenerationClient(const CrashGenerationClient&);
+  CrashGenerationClient& operator=(const CrashGenerationClient&);
+};
+
+}  // namespace google_breakpad
+
+#endif  // GOOGLE_BREAKPAD_CLIENT_MAC_CRASH_GENERATION_CRASH_GENERATION_CLIENT_H_
diff --git a/3rdParty/Breakpad/src/client/mac/crash_generation/crash_generation_server.h b/3rdParty/Breakpad/src/client/mac/crash_generation/crash_generation_server.h
new file mode 100644
index 0000000..85bd5b5
--- /dev/null
+++ b/3rdParty/Breakpad/src/client/mac/crash_generation/crash_generation_server.h
@@ -0,0 +1,150 @@
+// 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.
+
+#ifndef GOOGLE_BREAKPAD_CLIENT_MAC_CRASH_GENERATION_CRASH_GENERATION_SERVER_H_
+#define GOOGLE_BREAKPAD_CLIENT_MAC_CRASH_GENERATION_CRASH_GENERATION_SERVER_H_
+
+#include <stdint.h>
+
+#include <string>
+
+#include "common/mac/MachIPC.h"
+
+namespace google_breakpad {
+
+class ClientInfo;
+
+// Messages the server can read via its mach port
+enum {
+  kDumpRequestMessage     = 1,
+  kAcknowledgementMessage = 2,
+  kQuitMessage            = 3
+};
+
+// Exception details sent by the client when requesting a dump.
+struct ExceptionInfo {
+  int32_t exception_type;
+  int32_t exception_code;
+  int32_t exception_subcode;
+};
+
+class CrashGenerationServer {
+ public:
+  // WARNING: callbacks may be invoked on a different thread
+  // than that which creates the CrashGenerationServer.  They must
+  // be thread safe.
+  typedef void (*OnClientDumpRequestCallback)(void *context,
+                                              const ClientInfo &client_info,
+                                              const std::string &file_path);
+
+  typedef void (*OnClientExitingCallback)(void *context,
+                                          const ClientInfo &client_info);
+  // If a FilterCallback returns false, the dump will not be written.
+  typedef bool (*FilterCallback)(void *context);
+
+  // Create an instance with the given parameters.
+  //
+  // mach_port_name: Named server port to listen on.
+  // filter: Callback for a client to cancel writing a dump.
+  // filter_context: Context for the filter callback.
+  // dump_callback: Callback for a client crash dump request.
+  // dump_context: Context for client crash dump request callback.
+  // exit_callback: Callback for client process exit.
+  // exit_context: Context for client exit callback.
+  // generate_dumps: Whether to automatically generate dumps.
+  //     Client code of this class might want to generate dumps explicitly
+  //     in the crash dump request callback. In that case, false can be
+  //     passed for this parameter.
+  // dump_path: Path for generating dumps; required only if true is
+  //     passed for generateDumps parameter; NULL can be passed otherwise.
+  CrashGenerationServer(const char *mach_port_name,
+                        FilterCallback filter,
+                        void *filter_context,
+                        OnClientDumpRequestCallback dump_callback,
+                        void *dump_context,
+                        OnClientExitingCallback exit_callback,
+                        void *exit_context,
+                        bool generate_dumps,
+                        const std::string &dump_path);
+
+  ~CrashGenerationServer();
+
+  // Perform initialization steps needed to start listening to clients.
+  //
+  // Return true if initialization is successful; false otherwise.
+  bool Start();
+
+  // Stop the server.
+  bool Stop();
+
+ private:
+  // Return a unique filename at which a minidump can be written.
+  bool MakeMinidumpFilename(std::string &outFilename);
+
+  // Loop reading client messages and responding to them until
+  // a quit message is received.
+  static void *WaitForMessages(void *server);
+
+  // Wait for a single client message and respond to it. Returns false
+  // if a quit message was received or if an error occurred.
+  bool WaitForOneMessage();
+
+  FilterCallback filter_;
+  void *filter_context_;
+
+  OnClientDumpRequestCallback dump_callback_;
+  void *dump_context_;
+
+  OnClientExitingCallback exit_callback_;
+  void *exit_context_;
+
+  bool generate_dumps_;
+
+  std::string dump_dir_;
+
+  bool started_;
+
+  // The mach port that receives requests to dump from child processes.
+  ReceivePort receive_port_;
+
+  // The name of the mach port. Stored so the Stop method can message
+  // the background thread to shut it down.
+  std::string mach_port_name_;
+
+  // The thread that waits on the receive port.
+  pthread_t server_thread_;
+
+  // Disable copy constructor and operator=.
+  CrashGenerationServer(const CrashGenerationServer&);
+  CrashGenerationServer& operator=(const CrashGenerationServer&);
+};
+
+}  // namespace google_breakpad
+
+#endif  // GOOGLE_BREAKPAD_CLIENT_MAC_CRASH_GENERATION_CRASH_GENERATION_SERVER_H_
diff --git a/3rdParty/Breakpad/src/client/mac/handler/breakpad_nlist_64.cc b/3rdParty/Breakpad/src/client/mac/handler/breakpad_nlist_64.cc
new file mode 100644
index 0000000..b50aa03
--- /dev/null
+++ b/3rdParty/Breakpad/src/client/mac/handler/breakpad_nlist_64.cc
@@ -0,0 +1,413 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1989, 1993
+ * The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed by the University of
+ *      California, Berkeley and its contributors.
+ * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
+ */
+
+
+/*
+ * This file was copied from libc/gen/nlist.c from Darwin's source code       
+ * The version of nlist used as a base is from 10.5.2, libc-498               
+ * http://www.opensource.apple.com/darwinsource/10.5.2/Libc-498/gen/nlist.c   
+ *                                                                            
+ * The full tarball is at:                                                    
+ * http://www.opensource.apple.com/darwinsource/tarballs/apsl/Libc-498.tar.gz 
+ *                                                                            
+ * I've modified it to be compatible with 64-bit images.
+*/
+
+#include "breakpad_nlist_64.h"
+
+#include <CoreFoundation/CoreFoundation.h>
+#include <fcntl.h>
+#include <mach-o/nlist.h>
+#include <mach-o/loader.h>
+#include <mach-o/fat.h>
+#include <mach/mach.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/uio.h>
+#include <TargetConditionals.h>
+#include <unistd.h>
+
+/* Stuff lifted from <a.out.h> and <sys/exec.h> since they are gone */
+/*
+ * Header prepended to each a.out file.
+ */
+struct exec {
+  unsigned short  a_machtype;     /* machine type */
+  unsigned short  a_magic;        /* magic number */
+  unsigned long a_text;         /* size of text segment */
+  unsigned long a_data;         /* size of initialized data */
+  unsigned long a_bss;          /* size of uninitialized data */
+  unsigned long a_syms;         /* size of symbol table */
+  unsigned long a_entry;        /* entry point */
+  unsigned long a_trsize;       /* size of text relocation */
+  unsigned long a_drsize;       /* size of data relocation */
+};
+
+#define OMAGIC  0407            /* old impure format */
+#define NMAGIC  0410            /* read-only text */
+#define ZMAGIC  0413            /* demand load format */
+
+#define N_BADMAG(x)                                                     \
+  (((x).a_magic)!=OMAGIC && ((x).a_magic)!=NMAGIC && ((x).a_magic)!=ZMAGIC)
+#define N_TXTOFF(x)                                     \
+  ((x).a_magic==ZMAGIC ? 0 : sizeof (struct exec))
+#define N_SYMOFF(x)                                                     \
+  (N_TXTOFF(x) + (x).a_text+(x).a_data + (x).a_trsize+(x).a_drsize)
+
+// Traits structs for specializing function templates to handle
+// 32-bit/64-bit Mach-O files.
+template<typename T>
+struct MachBits {};
+
+typedef struct nlist nlist32;
+typedef struct nlist_64 nlist64;
+
+template<>
+struct MachBits<nlist32> {
+  typedef mach_header mach_header_type;
+  typedef uint32_t word_type;
+  static const uint32_t magic = MH_MAGIC;
+};
+
+template<>
+struct MachBits<nlist64> {
+  typedef mach_header_64 mach_header_type;
+  typedef uint64_t word_type;
+  static const uint32_t magic = MH_MAGIC_64;
+};
+
+template<typename nlist_type>
+int
+__breakpad_fdnlist(int fd, nlist_type *list, const char **symbolNames,
+                   cpu_type_t cpu_type);
+
+/*
+ * nlist - retreive attributes from name list (string table version)
+ */
+
+template <typename nlist_type>
+int breakpad_nlist_common(const char *name,
+                          nlist_type *list,
+                          const char **symbolNames,
+                          cpu_type_t cpu_type) {
+  int fd = open(name, O_RDONLY, 0);
+  if (fd < 0)
+    return -1;
+  int n = __breakpad_fdnlist(fd, list, symbolNames, cpu_type);
+  close(fd);
+  return n;
+}
+
+int breakpad_nlist(const char *name,
+                   struct nlist *list,
+                   const char **symbolNames,
+                   cpu_type_t cpu_type) {
+  return breakpad_nlist_common(name, list, symbolNames, cpu_type);
+}
+
+int breakpad_nlist(const char *name,
+                   struct nlist_64 *list,
+                   const char **symbolNames,
+                   cpu_type_t cpu_type) {
+  return breakpad_nlist_common(name, list, symbolNames, cpu_type);
+}
+
+/* Note: __fdnlist() is called from kvm_nlist in libkvm's kvm.c */
+
+template<typename nlist_type>
+int __breakpad_fdnlist(int fd, nlist_type *list, const char **symbolNames,
+                       cpu_type_t cpu_type) {
+  typedef typename MachBits<nlist_type>::mach_header_type mach_header_type;
+  typedef typename MachBits<nlist_type>::word_type word_type;
+
+  const uint32_t magic = MachBits<nlist_type>::magic;
+
+  int maxlen = 500;
+  int nreq = 0;
+  for (nlist_type* q = list;
+       symbolNames[q-list] && symbolNames[q-list][0];
+       q++, nreq++) {
+
+    q->n_type = 0;
+    q->n_value = 0;
+    q->n_desc = 0;
+    q->n_sect = 0;
+    q->n_un.n_strx = 0;
+  }
+
+  struct exec buf;
+  if (read(fd, (char *)&buf, sizeof(buf)) != sizeof(buf) ||
+      (N_BADMAG(buf) && *((uint32_t *)&buf) != magic &&
+        CFSwapInt32BigToHost(*((uint32_t *)&buf)) != FAT_MAGIC &&
+       /* The following is the big-endian ppc64 check */
+       (*((uint32_t*)&buf)) != FAT_MAGIC)) {
+    return -1;
+  }
+
+  /* Deal with fat file if necessary */
+  unsigned arch_offset = 0;
+  if (CFSwapInt32BigToHost(*((uint32_t *)&buf)) == FAT_MAGIC ||
+      /* The following is the big-endian ppc64 check */
+      *((unsigned int *)&buf) == FAT_MAGIC) {
+    /* Get host info */
+    host_t host = mach_host_self();
+    unsigned i = HOST_BASIC_INFO_COUNT;
+    struct host_basic_info hbi;
+    kern_return_t kr;
+    if ((kr = host_info(host, HOST_BASIC_INFO,
+                        (host_info_t)(&hbi), &i)) != KERN_SUCCESS) {
+      return -1;
+    }
+    mach_port_deallocate(mach_task_self(), host);
+
+    /* Read in the fat header */
+    struct fat_header fh;
+    if (lseek(fd, 0, SEEK_SET) == -1) {
+      return -1;
+    }
+    if (read(fd, (char *)&fh, sizeof(fh)) != sizeof(fh)) {
+      return -1;
+    }
+
+    /* Convert fat_narchs to host byte order */
+    fh.nfat_arch = CFSwapInt32BigToHost(fh.nfat_arch);
+
+    /* Read in the fat archs */
+    struct fat_arch *fat_archs =
+        (struct fat_arch *)malloc(fh.nfat_arch * sizeof(struct fat_arch));
+    if (fat_archs == NULL) {
+      return -1;
+    }
+    if (read(fd, (char *)fat_archs,
+             sizeof(struct fat_arch) * fh.nfat_arch) !=
+        (ssize_t)(sizeof(struct fat_arch) * fh.nfat_arch)) {
+      free(fat_archs);
+      return -1;
+    }
+
+    /*
+     * Convert archs to host byte ordering (a constraint of
+     * cpusubtype_getbestarch()
+     */
+    for (unsigned i = 0; i < fh.nfat_arch; i++) {
+      fat_archs[i].cputype =
+        CFSwapInt32BigToHost(fat_archs[i].cputype);
+      fat_archs[i].cpusubtype =
+        CFSwapInt32BigToHost(fat_archs[i].cpusubtype);
+      fat_archs[i].offset =
+        CFSwapInt32BigToHost(fat_archs[i].offset);
+      fat_archs[i].size =
+        CFSwapInt32BigToHost(fat_archs[i].size);
+      fat_archs[i].align =
+        CFSwapInt32BigToHost(fat_archs[i].align);
+    }
+
+    struct fat_arch *fap = NULL;
+    for (unsigned i = 0; i < fh.nfat_arch; i++) {
+      if (fat_archs[i].cputype == cpu_type) {
+        fap = &fat_archs[i];
+        break;
+      }
+    }
+
+    if (!fap) {
+      free(fat_archs);
+      return -1;
+    }
+    arch_offset = fap->offset;
+    free(fat_archs);
+
+    /* Read in the beginning of the architecture-specific file */
+    if (lseek(fd, arch_offset, SEEK_SET) == -1) {
+      return -1;
+    }
+    if (read(fd, (char *)&buf, sizeof(buf)) != sizeof(buf)) {
+      return -1;
+    }
+  }
+
+  off_t sa;  /* symbol address */
+  off_t ss;  /* start of strings */
+  register register_t n;
+  if (*((unsigned int *)&buf) == magic) {
+    if (lseek(fd, arch_offset, SEEK_SET) == -1) {
+      return -1;
+    }
+    mach_header_type mh;
+    if (read(fd, (char *)&mh, sizeof(mh)) != sizeof(mh)) {
+      return -1;
+    }
+
+    struct load_command *load_commands =
+        (struct load_command *)malloc(mh.sizeofcmds);
+    if (load_commands == NULL) {
+      return -1;
+    }
+    if (read(fd, (char *)load_commands, mh.sizeofcmds) !=
+        (ssize_t)mh.sizeofcmds) {
+      free(load_commands);
+      return -1;
+    }
+    struct symtab_command *stp = NULL;
+    struct load_command *lcp = load_commands;
+    // iterate through all load commands, looking for
+    // LC_SYMTAB load command
+    for (uint32_t i = 0; i < mh.ncmds; i++) {
+      if (lcp->cmdsize % sizeof(word_type) != 0 ||
+          lcp->cmdsize <= 0 ||
+          (char *)lcp + lcp->cmdsize >
+          (char *)load_commands + mh.sizeofcmds) {
+        free(load_commands);
+        return -1;
+      }
+      if (lcp->cmd == LC_SYMTAB) {
+        if (lcp->cmdsize !=
+            sizeof(struct symtab_command)) {
+          free(load_commands);
+          return -1;
+        }
+        stp = (struct symtab_command *)lcp;
+        break;
+      }
+      lcp = (struct load_command *)
+        ((char *)lcp + lcp->cmdsize);
+    }
+    if (stp == NULL) {
+      free(load_commands);
+      return -1;
+    }
+    // sa points to the beginning of the symbol table
+    sa = stp->symoff + arch_offset;
+    // ss points to the beginning of the string table
+    ss = stp->stroff + arch_offset;
+    // n is the number of bytes in the symbol table
+    // each symbol table entry is an nlist structure
+    n = stp->nsyms * sizeof(nlist_type);
+    free(load_commands);
+  } else {
+    sa = N_SYMOFF(buf) + arch_offset;
+    ss = sa + buf.a_syms + arch_offset;
+    n = buf.a_syms;
+  }
+
+  if (lseek(fd, sa, SEEK_SET) == -1) {
+    return -1;
+  }
+
+  // the algorithm here is to read the nlist entries in m-sized
+  // chunks into q.  q is then iterated over. for each entry in q,
+  // use the string table index(q->n_un.n_strx) to read the symbol 
+  // name, then scan the nlist entries passed in by the user(via p),
+  // and look for a match
+  while (n) {
+    nlist_type space[BUFSIZ/sizeof (nlist_type)];
+    register register_t m = sizeof (space);
+
+    if (n < m)
+      m = n;
+    if (read(fd, (char *)space, m) != m)
+      break;
+    n -= m;
+    long savpos = lseek(fd, 0, SEEK_CUR);
+    if (savpos == -1) {
+      return -1;
+    }
+    for (nlist_type* q = space; (m -= sizeof(nlist_type)) >= 0; q++) {
+      char nambuf[BUFSIZ];
+
+      if (q->n_un.n_strx == 0 || q->n_type & N_STAB)
+        continue;
+
+      // seek to the location in the binary where the symbol
+      // name is stored & read it into memory
+      if (lseek(fd, ss+q->n_un.n_strx, SEEK_SET) == -1) {
+        return -1;
+      }
+      if (read(fd, nambuf, maxlen+1) == -1) {
+        return -1;
+      }
+      const char *s2 = nambuf;
+      for (nlist_type *p = list; 
+           symbolNames[p-list] && symbolNames[p-list][0];
+           p++) {
+        // get the symbol name the user has passed in that 
+        // corresponds to the nlist entry that we're looking at
+        const char *s1 = symbolNames[p - list];
+        while (*s1) {
+          if (*s1++ != *s2++)
+            goto cont;
+        }
+        if (*s2)
+          goto cont;
+
+        p->n_value = q->n_value;
+        p->n_type = q->n_type;
+        p->n_desc = q->n_desc;
+        p->n_sect = q->n_sect;
+        p->n_un.n_strx = q->n_un.n_strx;
+        if (--nreq == 0)
+          return nreq;
+
+        break;
+      cont:           ;
+      }
+    }
+    if (lseek(fd, savpos, SEEK_SET) == -1) {
+      return -1;
+    }
+  }
+  return nreq;
+}
diff --git a/3rdParty/Breakpad/src/client/mac/handler/breakpad_nlist_64.h b/3rdParty/Breakpad/src/client/mac/handler/breakpad_nlist_64.h
new file mode 100644
index 0000000..1d2c639
--- /dev/null
+++ b/3rdParty/Breakpad/src/client/mac/handler/breakpad_nlist_64.h
@@ -0,0 +1,47 @@
+// Copyright (c) 2008, 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.
+
+// breakpad_nlist.h
+//
+// This file is meant to provide a header for clients of the modified
+// nlist function implemented to work on 64-bit.
+
+#ifndef CLIENT_MAC_HANDLER_BREAKPAD_NLIST_H__
+
+#include <mach/machine.h>
+
+int breakpad_nlist(const char *name,
+                   struct nlist *list,
+                   const char **symbolNames,
+                   cpu_type_t cpu_type);
+int breakpad_nlist(const char *name,
+                   struct nlist_64 *list,
+                   const char **symbolNames,
+                   cpu_type_t cpu_type);
+
+#endif  /* CLIENT_MAC_HANDLER_BREAKPAD_NLIST_H__ */
diff --git a/3rdParty/Breakpad/src/client/mac/handler/dynamic_images.cc b/3rdParty/Breakpad/src/client/mac/handler/dynamic_images.cc
new file mode 100644
index 0000000..ef5743c
--- /dev/null
+++ b/3rdParty/Breakpad/src/client/mac/handler/dynamic_images.cc
@@ -0,0 +1,578 @@
+// 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.
+
+#include "client/mac/handler/dynamic_images.h"
+
+extern "C" { // needed to compile on Leopard
+  #include <mach-o/nlist.h>
+  #include <stdlib.h>
+  #include <stdio.h>
+}
+
+#include <assert.h>
+#include <AvailabilityMacros.h>
+#include <dlfcn.h>
+#include <mach/task_info.h>
+#include <sys/sysctl.h>
+#include <TargetConditionals.h>
+
+#include <algorithm>
+#include <string>
+#include <vector>
+
+#include "breakpad_nlist_64.h"
+
+#if !TARGET_OS_IPHONE
+#include <CoreServices/CoreServices.h>
+
+#ifndef MAC_OS_X_VERSION_10_6
+#define MAC_OS_X_VERSION_10_6 1060
+#endif
+
+#if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_6
+
+// Fallback declarations for TASK_DYLD_INFO and friends, introduced in
+// <mach/task_info.h> in the Mac OS X 10.6 SDK.
+#define TASK_DYLD_INFO 17
+struct task_dyld_info {
+  mach_vm_address_t all_image_info_addr;
+  mach_vm_size_t all_image_info_size;
+};
+typedef struct task_dyld_info task_dyld_info_data_t;
+typedef struct task_dyld_info *task_dyld_info_t;
+#define TASK_DYLD_INFO_COUNT (sizeof(task_dyld_info_data_t) / sizeof(natural_t))
+
+#endif
+
+#endif  // !TARGET_OS_IPHONE
+
+namespace google_breakpad {
+
+using std::string;
+using std::vector;
+
+//==============================================================================
+// Returns the size of the memory region containing |address| and the
+// number of bytes from |address| to the end of the region.
+// We potentially, will extend the size of the original
+// region by the size of the following region if it's contiguous with the
+// first in order to handle cases when we're reading strings and they
+// straddle two vm regions.
+//
+static mach_vm_size_t GetMemoryRegionSize(task_port_t target_task,
+                                          const uint64_t address,
+                                          mach_vm_size_t *size_to_end) {
+  mach_vm_address_t region_base = (mach_vm_address_t)address;
+  mach_vm_size_t region_size;
+  natural_t nesting_level = 0;
+  vm_region_submap_info_64 submap_info;
+  mach_msg_type_number_t info_count = VM_REGION_SUBMAP_INFO_COUNT_64;
+
+  // Get information about the vm region containing |address|
+  vm_region_recurse_info_t region_info;
+  region_info = reinterpret_cast<vm_region_recurse_info_t>(&submap_info);
+
+  kern_return_t result =
+    mach_vm_region_recurse(target_task,
+                           &region_base,
+                           &region_size,
+                           &nesting_level,
+                           region_info,
+                           &info_count);
+
+  if (result == KERN_SUCCESS) {
+    // Get distance from |address| to the end of this region
+    *size_to_end = region_base + region_size -(mach_vm_address_t)address;
+
+    // If we want to handle strings as long as 4096 characters we may need
+    // to check if there's a vm region immediately following the first one.
+    // If so, we need to extend |*size_to_end| to go all the way to the end
+    // of the second region.
+    if (*size_to_end < 4096) {
+      // Second region starts where the first one ends
+      mach_vm_address_t region_base2 =
+        (mach_vm_address_t)(region_base + region_size);
+      mach_vm_size_t region_size2;
+
+      // Get information about the following vm region
+      result =
+        mach_vm_region_recurse(target_task,
+                               &region_base2,
+                               &region_size2,
+                               &nesting_level,
+                               region_info,
+                               &info_count);
+
+      // Extend region_size to go all the way to the end of the 2nd region
+      if (result == KERN_SUCCESS
+          && region_base2 == region_base + region_size) {
+        region_size += region_size2;
+      }
+    }
+
+    *size_to_end = region_base + region_size -(mach_vm_address_t)address;
+  } else {
+    region_size = 0;
+    *size_to_end = 0;
+  }
+
+  return region_size;
+}
+
+#define kMaxStringLength 8192
+//==============================================================================
+// Reads a NULL-terminated string from another task.
+//
+// Warning!  This will not read any strings longer than kMaxStringLength-1
+//
+static string ReadTaskString(task_port_t target_task,
+                             const uint64_t address) {
+  // The problem is we don't know how much to read until we know how long
+  // the string is. And we don't know how long the string is, until we've read
+  // the memory!  So, we'll try to read kMaxStringLength bytes
+  // (or as many bytes as we can until we reach the end of the vm region).
+  mach_vm_size_t size_to_end;
+  GetMemoryRegionSize(target_task, address, &size_to_end);
+
+  if (size_to_end > 0) {
+    mach_vm_size_t size_to_read =
+      size_to_end > kMaxStringLength ? kMaxStringLength : size_to_end;
+
+    vector<uint8_t> bytes;
+    if (ReadTaskMemory(target_task, address, (size_t)size_to_read, bytes) !=
+        KERN_SUCCESS)
+      return string();
+
+    return string(reinterpret_cast<const char*>(&bytes[0]));
+  }
+
+  return string();
+}
+
+//==============================================================================
+// Reads an address range from another task. The bytes read will be returned
+// in bytes, which will be resized as necessary.
+kern_return_t ReadTaskMemory(task_port_t target_task,
+                             const uint64_t address,
+                             size_t length,
+                             vector<uint8_t> &bytes) {
+  int systemPageSize = getpagesize();
+
+  // use the negative of the page size for the mask to find the page address
+  mach_vm_address_t page_address = address & (-systemPageSize);
+
+  mach_vm_address_t last_page_address =
+      (address + length + (systemPageSize - 1)) & (-systemPageSize);
+
+  mach_vm_size_t page_size = last_page_address - page_address;
+  uint8_t* local_start;
+  uint32_t local_length;
+
+  kern_return_t r = mach_vm_read(target_task,
+                                 page_address,
+                                 page_size,
+                                 reinterpret_cast<vm_offset_t*>(&local_start),
+                                 &local_length);
+
+  if (r != KERN_SUCCESS)
+    return r;
+
+  bytes.resize(length);
+  memcpy(&bytes[0],
+         &local_start[(mach_vm_address_t)address - page_address],
+         length);
+  mach_vm_deallocate(mach_task_self(), (uintptr_t)local_start, local_length);
+  return KERN_SUCCESS;
+}
+
+#pragma mark -
+
+//==============================================================================
+// Traits structs for specializing function templates to handle
+// 32-bit/64-bit Mach-O files.
+struct MachO32 {
+  typedef mach_header mach_header_type;
+  typedef segment_command mach_segment_command_type;
+  typedef dyld_image_info32 dyld_image_info;
+  typedef dyld_all_image_infos32 dyld_all_image_infos;
+  typedef struct nlist nlist_type;
+  static const uint32_t magic = MH_MAGIC;
+  static const uint32_t segment_load_command = LC_SEGMENT;
+};
+
+struct MachO64 {
+  typedef mach_header_64 mach_header_type;
+  typedef segment_command_64 mach_segment_command_type;
+  typedef dyld_image_info64 dyld_image_info;
+  typedef dyld_all_image_infos64 dyld_all_image_infos;
+  typedef struct nlist_64 nlist_type;
+  static const uint32_t magic = MH_MAGIC_64;
+  static const uint32_t segment_load_command = LC_SEGMENT_64;
+};
+
+template<typename MachBits>
+bool FindTextSection(DynamicImage& image) {
+  typedef typename MachBits::mach_header_type mach_header_type;
+  typedef typename MachBits::mach_segment_command_type
+      mach_segment_command_type;
+  
+  const mach_header_type* header =
+      reinterpret_cast<const mach_header_type*>(&image.header_[0]);
+
+  if(header->magic != MachBits::magic) {
+    return false;
+  }
+
+  const struct load_command *cmd =
+      reinterpret_cast<const struct load_command *>(header + 1);
+
+  bool found_text_section = false;
+  bool found_dylib_id_command = false;
+  for (unsigned int i = 0; cmd && (i < header->ncmds); ++i) {
+    if (!found_text_section) {
+      if (cmd->cmd == MachBits::segment_load_command) {
+        const mach_segment_command_type *seg =
+            reinterpret_cast<const mach_segment_command_type *>(cmd);
+
+        if (!strcmp(seg->segname, "__TEXT")) {
+          image.vmaddr_ = seg->vmaddr;
+          image.vmsize_ = seg->vmsize;
+          image.slide_ = 0;
+
+          if (seg->fileoff == 0 && seg->filesize != 0) {
+            image.slide_ =
+                (uintptr_t)image.GetLoadAddress() - (uintptr_t)seg->vmaddr;
+          }
+          found_text_section = true;
+        }
+      }
+    }
+
+    if (!found_dylib_id_command) {
+      if (cmd->cmd == LC_ID_DYLIB) {
+        const struct dylib_command *dc =
+            reinterpret_cast<const struct dylib_command *>(cmd);
+
+        image.version_ = dc->dylib.current_version;
+        found_dylib_id_command = true;
+      }
+    }
+
+    if (found_dylib_id_command && found_text_section) {
+      return true;
+    }
+
+    cmd = reinterpret_cast<const struct load_command *>
+        (reinterpret_cast<const char *>(cmd) + cmd->cmdsize);
+  }
+
+  return false;
+}
+
+//==============================================================================
+// Initializes vmaddr_, vmsize_, and slide_
+void DynamicImage::CalculateMemoryAndVersionInfo() {
+  // unless we can process the header, ensure that calls to
+  // IsValid() will return false
+  vmaddr_ = 0;
+  vmsize_ = 0;
+  slide_ = 0;
+  version_ = 0;
+
+  // The function template above does all the real work.
+  if (Is64Bit())
+    FindTextSection<MachO64>(*this);
+  else
+    FindTextSection<MachO32>(*this);
+}
+
+//==============================================================================
+// The helper function template abstracts the 32/64-bit differences.
+template<typename MachBits>
+uint32_t GetFileTypeFromHeader(DynamicImage& image) {
+  typedef typename MachBits::mach_header_type mach_header_type;
+
+  const mach_header_type* header =
+      reinterpret_cast<const mach_header_type*>(&image.header_[0]);
+  return header->filetype;
+}
+
+uint32_t DynamicImage::GetFileType() {
+  if (Is64Bit())
+    return GetFileTypeFromHeader<MachO64>(*this);
+
+  return GetFileTypeFromHeader<MachO32>(*this);
+}
+
+#pragma mark -
+
+//==============================================================================
+// Loads information about dynamically loaded code in the given task.
+DynamicImages::DynamicImages(mach_port_t task)
+    : task_(task),
+      cpu_type_(DetermineTaskCPUType(task)),
+      image_list_() {
+  ReadImageInfoForTask();
+}
+
+template<typename MachBits>
+static uint64_t LookupSymbol(const char* symbol_name,
+                             const char* filename,
+                             cpu_type_t cpu_type) {
+  typedef typename MachBits::nlist_type nlist_type;
+
+  nlist_type symbol_info[8] = {};
+  const char *symbolNames[2] = { symbol_name, "\0" };
+  nlist_type &list = symbol_info[0];
+  int invalidEntriesCount = breakpad_nlist(filename,
+                                           &list,
+                                           symbolNames,
+                                           cpu_type);
+
+  if(invalidEntriesCount != 0) {
+    return 0;
+  }
+
+  assert(list.n_value);
+  return list.n_value;
+}
+
+#if TARGET_OS_IPHONE
+static bool HasTaskDyldInfo() {
+  return true;
+}
+#else
+static SInt32 GetOSVersionInternal() {
+  SInt32 os_version = 0;
+  Gestalt(gestaltSystemVersion, &os_version);
+  return os_version;
+}
+
+static SInt32 GetOSVersion() {
+  static SInt32 os_version = GetOSVersionInternal();
+  return os_version;
+}
+
+static bool HasTaskDyldInfo() {
+#if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_6
+  return true;
+#else
+  return GetOSVersion() >= 0x1060;
+#endif
+}
+#endif  // TARGET_OS_IPHONE
+
+uint64_t DynamicImages::GetDyldAllImageInfosPointer() {
+  if (HasTaskDyldInfo()) {
+    task_dyld_info_data_t task_dyld_info;
+    mach_msg_type_number_t count = TASK_DYLD_INFO_COUNT;
+    if (task_info(task_, TASK_DYLD_INFO, (task_info_t)&task_dyld_info,
+                  &count) != KERN_SUCCESS) {
+      return 0;
+    }
+
+    return (uint64_t)task_dyld_info.all_image_info_addr;
+  } else {
+    const char *imageSymbolName = "_dyld_all_image_infos";
+    const char *dyldPath = "/usr/lib/dyld";
+
+    if (Is64Bit())
+      return LookupSymbol<MachO64>(imageSymbolName, dyldPath, cpu_type_);
+    return LookupSymbol<MachO32>(imageSymbolName, dyldPath, cpu_type_);
+  }
+}
+
+//==============================================================================
+// This code was written using dyld_debug.c (from Darwin) as a guide.
+
+template<typename MachBits>
+void ReadImageInfo(DynamicImages& images,
+                   uint64_t image_list_address) {
+  typedef typename MachBits::dyld_image_info dyld_image_info;
+  typedef typename MachBits::dyld_all_image_infos dyld_all_image_infos;
+  typedef typename MachBits::mach_header_type mach_header_type;
+
+  // Read the structure inside of dyld that contains information about
+  // loaded images.  We're reading from the desired task's address space.
+
+  // Here we make the assumption that dyld loaded at the same address in
+  // the crashed process vs. this one.  This is an assumption made in
+  // "dyld_debug.c" and is said to be nearly always valid.
+  vector<uint8_t> dyld_all_info_bytes;
+  if (ReadTaskMemory(images.task_,
+                     image_list_address,
+                     sizeof(dyld_all_image_infos),
+                     dyld_all_info_bytes) != KERN_SUCCESS)
+    return;
+
+  dyld_all_image_infos *dyldInfo =
+    reinterpret_cast<dyld_all_image_infos*>(&dyld_all_info_bytes[0]);
+
+  // number of loaded images
+  int count = dyldInfo->infoArrayCount;
+
+  // Read an array of dyld_image_info structures each containing
+  // information about a loaded image.
+  vector<uint8_t> dyld_info_array_bytes;
+    if (ReadTaskMemory(images.task_,
+                       dyldInfo->infoArray,
+                       count * sizeof(dyld_image_info),
+                       dyld_info_array_bytes) != KERN_SUCCESS)
+      return;
+
+    dyld_image_info *infoArray =
+        reinterpret_cast<dyld_image_info*>(&dyld_info_array_bytes[0]);
+    images.image_list_.reserve(count);
+
+    for (int i = 0; i < count; ++i) {
+      dyld_image_info &info = infoArray[i];
+
+      // First read just the mach_header from the image in the task.
+      vector<uint8_t> mach_header_bytes;
+      if (ReadTaskMemory(images.task_,
+                         info.load_address_,
+                         sizeof(mach_header_type),
+                         mach_header_bytes) != KERN_SUCCESS)
+        continue;  // bail on this dynamic image
+
+      mach_header_type *header =
+          reinterpret_cast<mach_header_type*>(&mach_header_bytes[0]);
+
+      // Now determine the total amount necessary to read the header
+      // plus all of the load commands.
+      size_t header_size =
+          sizeof(mach_header_type) + header->sizeofcmds;
+
+      if (ReadTaskMemory(images.task_,
+                         info.load_address_,
+                         header_size,
+                         mach_header_bytes) != KERN_SUCCESS)
+        continue;
+
+      header = reinterpret_cast<mach_header_type*>(&mach_header_bytes[0]);
+
+      // Read the file name from the task's memory space.
+      string file_path;
+      if (info.file_path_) {
+        // Although we're reading kMaxStringLength bytes, it's copied in the
+        // the DynamicImage constructor below with the correct string length,
+        // so it's not really wasting memory.
+        file_path = ReadTaskString(images.task_, info.file_path_);
+      }
+
+      // Create an object representing this image and add it to our list.
+      DynamicImage *new_image;
+      new_image = new DynamicImage(&mach_header_bytes[0],
+                                   header_size,
+                                   info.load_address_,
+                                   file_path,
+                                   info.file_mod_date_,
+                                   images.task_,
+                                   images.cpu_type_);
+
+      if (new_image->IsValid()) {
+        images.image_list_.push_back(DynamicImageRef(new_image));
+      } else {
+        delete new_image;
+      }
+    }
+
+    // sorts based on loading address
+    sort(images.image_list_.begin(), images.image_list_.end());
+    // remove duplicates - this happens in certain strange cases
+    // You can see it in DashboardClient when Google Gadgets plugin
+    // is installed.  Apple's crash reporter log and gdb "info shared"
+    // both show the same library multiple times at the same address
+
+    vector<DynamicImageRef>::iterator it = unique(images.image_list_.begin(),
+                                                  images.image_list_.end());
+    images.image_list_.erase(it, images.image_list_.end());
+}
+
+void DynamicImages::ReadImageInfoForTask() {
+  uint64_t imageList = GetDyldAllImageInfosPointer();
+
+  if (imageList) {
+    if (Is64Bit())
+      ReadImageInfo<MachO64>(*this, imageList);
+    else
+      ReadImageInfo<MachO32>(*this, imageList);
+  }
+}
+
+//==============================================================================
+DynamicImage  *DynamicImages::GetExecutableImage() {
+  int executable_index = GetExecutableImageIndex();
+
+  if (executable_index >= 0) {
+    return GetImage(executable_index);
+  }
+
+  return NULL;
+}
+
+//==============================================================================
+// returns -1 if failure to find executable
+int DynamicImages::GetExecutableImageIndex() {
+  int image_count = GetImageCount();
+
+  for (int i = 0; i < image_count; ++i) {
+    DynamicImage  *image = GetImage(i);
+    if (image->GetFileType() == MH_EXECUTE) {
+      return i;
+    }
+  }
+
+  return -1;
+}
+
+//==============================================================================
+// static
+cpu_type_t DynamicImages::DetermineTaskCPUType(task_t task) {
+  if (task == mach_task_self())
+    return GetNativeCPUType();
+
+  int mib[CTL_MAXNAME];
+  size_t mibLen = CTL_MAXNAME;
+  int err = sysctlnametomib("sysctl.proc_cputype", mib, &mibLen);
+  if (err == 0) {
+    assert(mibLen < CTL_MAXNAME);
+    pid_for_task(task, &mib[mibLen]);
+    mibLen += 1;
+
+    cpu_type_t cpu_type;
+    size_t cpuTypeSize = sizeof(cpu_type);
+    sysctl(mib, mibLen, &cpu_type, &cpuTypeSize, 0, 0);
+    return cpu_type;
+  }
+
+  return GetNativeCPUType();
+}
+
+}  // namespace google_breakpad
diff --git a/3rdParty/Breakpad/src/client/mac/handler/dynamic_images.h b/3rdParty/Breakpad/src/client/mac/handler/dynamic_images.h
new file mode 100644
index 0000000..d039eda
--- /dev/null
+++ b/3rdParty/Breakpad/src/client/mac/handler/dynamic_images.h
@@ -0,0 +1,317 @@
+// 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.
+
+//  dynamic_images.h
+//
+//    Implements most of the function of the dyld API, but allowing an
+//    arbitrary task to be introspected, unlike the dyld API which
+//    only allows operation on the current task.  The current implementation
+//    is limited to use by 32-bit tasks.
+
+#ifndef CLIENT_MAC_HANDLER_DYNAMIC_IMAGES_H__
+#define CLIENT_MAC_HANDLER_DYNAMIC_IMAGES_H__
+
+#include <mach/mach.h>
+#include <mach-o/dyld.h>
+#include <mach-o/loader.h>
+#include <sys/types.h>
+
+#include <string>
+#include <vector>
+
+#include "mach_vm_compat.h"
+
+namespace google_breakpad {
+
+using std::string;
+using std::vector;
+
+//==============================================================================
+// The memory layout of this struct matches the dyld_image_info struct
+// defined in "dyld_gdb.h" in the darwin source.
+typedef struct dyld_image_info32 {
+  uint32_t                   load_address_;  // struct mach_header*
+  uint32_t                   file_path_;     // char*
+  uint32_t                   file_mod_date_;
+} dyld_image_info32;
+
+typedef struct dyld_image_info64 {
+  uint64_t                   load_address_;  // struct mach_header*
+  uint64_t                   file_path_;     // char*
+  uint64_t                   file_mod_date_;
+} dyld_image_info64;
+
+//==============================================================================
+// This is as defined in "dyld_gdb.h" in the darwin source.
+// _dyld_all_image_infos (in dyld) is a structure of this type
+// which will be used to determine which dynamic code has been loaded.
+typedef struct dyld_all_image_infos32 {
+  uint32_t                      version;  // == 1 in Mac OS X 10.4
+  uint32_t                      infoArrayCount;
+  uint32_t                      infoArray;  // const struct dyld_image_info*
+  uint32_t                      notification;
+  bool                          processDetachedFromSharedRegion;
+} dyld_all_image_infos32;
+
+typedef struct dyld_all_image_infos64 {
+  uint32_t                      version;  // == 1 in Mac OS X 10.4
+  uint32_t                      infoArrayCount;
+  uint64_t                      infoArray;  // const struct dyld_image_info*
+  uint64_t                      notification;
+  bool                          processDetachedFromSharedRegion;
+} dyld_all_image_infos64;
+
+// some typedefs to isolate 64/32 bit differences
+#ifdef __LP64__
+typedef mach_header_64 breakpad_mach_header;
+typedef segment_command_64 breakpad_mach_segment_command;
+#else
+typedef mach_header breakpad_mach_header;
+typedef segment_command breakpad_mach_segment_command;
+#endif
+
+// Helper functions to deal with 32-bit/64-bit Mach-O differences.
+class DynamicImage;
+template<typename MachBits>
+bool FindTextSection(DynamicImage& image);
+
+template<typename MachBits>
+uint32_t GetFileTypeFromHeader(DynamicImage& image);
+
+//==============================================================================
+// Represents a single dynamically loaded mach-o image
+class DynamicImage {
+ public:
+  DynamicImage(uint8_t *header,     // data is copied
+               size_t header_size,  // includes load commands
+               uint64_t load_address,
+               string file_path,
+               uintptr_t image_mod_date,
+               mach_port_t task,
+               cpu_type_t cpu_type)
+    : header_(header, header + header_size),
+      header_size_(header_size),
+      load_address_(load_address),
+      vmaddr_(0),
+      vmsize_(0),
+      slide_(0),
+      version_(0),
+      file_path_(file_path),
+      file_mod_date_(image_mod_date),
+      task_(task),
+      cpu_type_(cpu_type) {
+    CalculateMemoryAndVersionInfo();
+  }
+
+  // Size of mach_header plus load commands
+  size_t GetHeaderSize() const {return header_.size();}
+
+  // Full path to mach-o binary
+  string GetFilePath() {return file_path_;}
+
+  uint64_t GetModDate() const {return file_mod_date_;}
+
+  // Actual address where the image was loaded
+  uint64_t GetLoadAddress() const {return load_address_;}
+
+  // Address where the image should be loaded
+  mach_vm_address_t GetVMAddr() const {return vmaddr_;}
+
+  // Difference between GetLoadAddress() and GetVMAddr()
+  ptrdiff_t GetVMAddrSlide() const {return slide_;}
+
+  // Size of the image
+  mach_vm_size_t GetVMSize() const {return vmsize_;}
+
+  // Task owning this loaded image
+  mach_port_t GetTask() {return task_;}
+
+  // CPU type of the task
+  cpu_type_t GetCPUType() {return cpu_type_;}
+
+  // filetype from the Mach-O header.
+  uint32_t GetFileType();
+
+  // Return true if the task is a 64-bit architecture.
+  bool Is64Bit() { return (GetCPUType() & CPU_ARCH_ABI64) == CPU_ARCH_ABI64; }
+
+  uint32_t GetVersion() {return version_;}
+  // For sorting
+  bool operator<(const DynamicImage &inInfo) {
+    return GetLoadAddress() < inInfo.GetLoadAddress();
+  }
+
+  // Sanity checking
+  bool IsValid() {return GetVMSize() != 0;}
+
+ private:
+  DynamicImage(const DynamicImage &);
+  DynamicImage &operator=(const DynamicImage &);
+
+  friend class DynamicImages;
+  template<typename MachBits>
+  friend bool FindTextSection(DynamicImage& image);
+  template<typename MachBits>
+  friend uint32_t GetFileTypeFromHeader(DynamicImage& image);
+
+  // Initializes vmaddr_, vmsize_, and slide_
+  void CalculateMemoryAndVersionInfo();
+
+  const vector<uint8_t>   header_;        // our local copy of the header
+  size_t                  header_size_;    // mach_header plus load commands
+  uint64_t                load_address_;   // base address image is mapped into
+  mach_vm_address_t       vmaddr_;
+  mach_vm_size_t          vmsize_;
+  ptrdiff_t               slide_;
+  uint32_t                version_;        // Dylib version
+  string                  file_path_;     // path dyld used to load the image
+  uintptr_t               file_mod_date_;  // time_t of image file
+
+  mach_port_t             task_;
+  cpu_type_t              cpu_type_;        // CPU type of task_
+};
+
+//==============================================================================
+// DynamicImageRef is just a simple wrapper for a pointer to
+// DynamicImage.  The reason we use it instead of a simple typedef is so
+// that we can use stl::sort() on a vector of DynamicImageRefs
+// and simple class pointers can't implement operator<().
+//
+class DynamicImageRef {
+ public:
+  explicit DynamicImageRef(DynamicImage *inP) : p(inP) {}
+  // The copy constructor is required by STL
+  DynamicImageRef(const DynamicImageRef &inRef) : p(inRef.p) {}
+
+  bool operator<(const DynamicImageRef &inRef) const {
+    return (*const_cast<DynamicImageRef*>(this)->p)
+      < (*const_cast<DynamicImageRef&>(inRef).p);
+  }
+
+  bool operator==(const DynamicImageRef &inInfo) const {
+    return (*const_cast<DynamicImageRef*>(this)->p).GetLoadAddress() ==
+        (*const_cast<DynamicImageRef&>(inInfo)).GetLoadAddress();
+  }
+
+  // Be just like DynamicImage*
+  DynamicImage  *operator->() {return p;}
+  operator DynamicImage*() {return p;}
+
+ private:
+  DynamicImage  *p;
+};
+
+// Helper function to deal with 32-bit/64-bit Mach-O differences.
+class DynamicImages;
+template<typename MachBits>
+void ReadImageInfo(DynamicImages& images, uint64_t image_list_address);
+
+//==============================================================================
+// An object of type DynamicImages may be created to allow introspection of
+// an arbitrary task's dynamically loaded mach-o binaries.  This makes the
+// assumption that the current task has send rights to the target task.
+class DynamicImages {
+ public:
+  explicit DynamicImages(mach_port_t task);
+
+  ~DynamicImages() {
+    for (int i = 0; i < GetImageCount(); ++i) {
+      delete image_list_[i];
+    }
+  }
+
+  // Returns the number of dynamically loaded mach-o images.
+  int GetImageCount() const {return static_cast<int>(image_list_.size());}
+
+  // Returns an individual image.
+  DynamicImage *GetImage(int i) {
+    if (i < (int)image_list_.size()) {
+      return image_list_[i];
+    }
+    return NULL;
+  }
+
+  // Returns the image corresponding to the main executable.
+  DynamicImage *GetExecutableImage();
+  int GetExecutableImageIndex();
+
+  // Returns the task which we're looking at.
+  mach_port_t GetTask() const {return task_;}
+
+  // CPU type of the task
+  cpu_type_t GetCPUType() {return cpu_type_;}
+
+  // Return true if the task is a 64-bit architecture.
+  bool Is64Bit() { return (GetCPUType() & CPU_ARCH_ABI64) == CPU_ARCH_ABI64; }
+
+  // Determine the CPU type of the task being dumped.
+  static cpu_type_t DetermineTaskCPUType(task_t task);
+
+  // Get the native CPU type of this task.
+  static cpu_type_t GetNativeCPUType() {
+#if defined(__i386__)
+    return CPU_TYPE_I386;
+#elif defined(__x86_64__)
+    return CPU_TYPE_X86_64;
+#elif defined(__ppc__)
+    return CPU_TYPE_POWERPC;
+#elif defined(__ppc64__)
+    return CPU_TYPE_POWERPC64;
+#elif defined(__arm__)
+    return CPU_TYPE_ARM;
+#else
+#error "GetNativeCPUType not implemented for this architecture"
+#endif
+  }
+
+ private:
+  template<typename MachBits>
+  friend void ReadImageInfo(DynamicImages& images, uint64_t image_list_address);
+
+  bool IsOurTask() {return task_ == mach_task_self();}
+
+  // Initialization
+  void ReadImageInfoForTask();
+  uint64_t GetDyldAllImageInfosPointer();
+
+  mach_port_t              task_;
+  cpu_type_t               cpu_type_;  // CPU type of task_
+  vector<DynamicImageRef>  image_list_;
+};
+
+// Fill bytes with the contents of memory at a particular
+// location in another task.
+kern_return_t ReadTaskMemory(task_port_t target_task,
+                             const uint64_t address,
+                             size_t length,
+                             vector<uint8_t> &bytes);
+
+}   // namespace google_breakpad
+
+#endif // CLIENT_MAC_HANDLER_DYNAMIC_IMAGES_H__
diff --git a/3rdParty/Breakpad/src/client/mac/handler/exception_handler.cc b/3rdParty/Breakpad/src/client/mac/handler/exception_handler.cc
new file mode 100644
index 0000000..4043019
--- /dev/null
+++ b/3rdParty/Breakpad/src/client/mac/handler/exception_handler.cc
@@ -0,0 +1,830 @@
+// 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 <map>
+#include <mach/exc.h>
+#include <mach/mig.h>
+#include <pthread.h>
+#include <signal.h>
+#include <TargetConditionals.h>
+
+#include "client/mac/handler/exception_handler.h"
+#include "client/mac/handler/minidump_generator.h"
+#include "common/mac/macho_utilities.h"
+#include "common/mac/scoped_task_suspend-inl.h"
+#include "google_breakpad/common/minidump_exception_mac.h"
+
+#ifndef USE_PROTECTED_ALLOCATIONS
+#if TARGET_OS_IPHONE
+#define USE_PROTECTED_ALLOCATIONS 1
+#else
+#define USE_PROTECTED_ALLOCATIONS 0
+#endif
+#endif
+
+// If USE_PROTECTED_ALLOCATIONS is activated then the
+// gBreakpadAllocator needs to be setup in other code
+// ahead of time.  Please see ProtectedMemoryAllocator.h
+// for more details.
+#if USE_PROTECTED_ALLOCATIONS
+  #include "protected_memory_allocator.h"
+  extern ProtectedMemoryAllocator *gBreakpadAllocator;
+#endif
+
+namespace google_breakpad {
+
+static union {
+#if USE_PROTECTED_ALLOCATIONS
+  char protected_buffer[PAGE_SIZE] __attribute__((aligned(PAGE_SIZE)));
+#endif
+  google_breakpad::ExceptionHandler *handler;
+} gProtectedData;
+
+using std::map;
+
+// These structures and techniques are illustrated in
+// Mac OS X Internals, Amit Singh, ch 9.7
+struct ExceptionMessage {
+  mach_msg_header_t           header;
+  mach_msg_body_t             body;
+  mach_msg_port_descriptor_t  thread;
+  mach_msg_port_descriptor_t  task;
+  NDR_record_t                ndr;
+  exception_type_t            exception;
+  mach_msg_type_number_t      code_count;
+  integer_t                   code[EXCEPTION_CODE_MAX];
+  char                        padding[512];
+};
+
+struct ExceptionParameters {
+  ExceptionParameters() : count(0) {}
+  mach_msg_type_number_t count;
+  exception_mask_t masks[EXC_TYPES_COUNT];
+  mach_port_t ports[EXC_TYPES_COUNT];
+  exception_behavior_t behaviors[EXC_TYPES_COUNT];
+  thread_state_flavor_t flavors[EXC_TYPES_COUNT];
+};
+
+struct ExceptionReplyMessage {
+  mach_msg_header_t  header;
+  NDR_record_t       ndr;
+  kern_return_t      return_code;
+};
+
+// Only catch these three exceptions.  The other ones are nebulously defined
+// and may result in treating a non-fatal exception as fatal.
+exception_mask_t s_exception_mask = EXC_MASK_BAD_ACCESS |
+EXC_MASK_BAD_INSTRUCTION | EXC_MASK_ARITHMETIC | EXC_MASK_BREAKPOINT;
+
+#if !TARGET_OS_IPHONE
+extern "C"
+{
+  // Forward declarations for functions that need "C" style compilation
+  boolean_t exc_server(mach_msg_header_t *request,
+                       mach_msg_header_t *reply);
+
+  // This symbol must be visible to dlsym() - see
+  // http://code.google.com/p/google-breakpad/issues/detail?id=345 for details.
+  kern_return_t catch_exception_raise(mach_port_t target_port,
+                                      mach_port_t failed_thread,
+                                      mach_port_t task,
+                                      exception_type_t exception,
+                                      exception_data_t code,
+                                      mach_msg_type_number_t code_count)
+      __attribute__((visibility("default")));
+}
+#endif
+
+kern_return_t ForwardException(mach_port_t task,
+                               mach_port_t failed_thread,
+                               exception_type_t exception,
+                               exception_data_t code,
+                               mach_msg_type_number_t code_count);
+
+#if TARGET_OS_IPHONE
+// Implementation is based on the implementation generated by mig.
+boolean_t breakpad_exc_server(mach_msg_header_t *InHeadP,
+                              mach_msg_header_t *OutHeadP) {
+   OutHeadP->msgh_bits =
+       MACH_MSGH_BITS(MACH_MSGH_BITS_REMOTE(InHeadP->msgh_bits), 0);
+   OutHeadP->msgh_remote_port = InHeadP->msgh_remote_port;
+   /* Minimal size: routine() will update it if different */
+   OutHeadP->msgh_size = (mach_msg_size_t)sizeof(mig_reply_error_t);
+   OutHeadP->msgh_local_port = MACH_PORT_NULL;
+   OutHeadP->msgh_id = InHeadP->msgh_id + 100;
+
+  if (InHeadP->msgh_id != 2401) {
+    ((mig_reply_error_t *)OutHeadP)->NDR = NDR_record;
+    ((mig_reply_error_t *)OutHeadP)->RetCode = MIG_BAD_ID;
+    return FALSE;
+  }
+
+#ifdef  __MigPackStructs
+#pragma pack(4)
+#endif
+  typedef struct {
+    mach_msg_header_t Head;
+    /* start of the kernel processed data */
+    mach_msg_body_t msgh_body;
+    mach_msg_port_descriptor_t thread;
+    mach_msg_port_descriptor_t task;
+    /* end of the kernel processed data */
+    NDR_record_t NDR;
+    exception_type_t exception;
+    mach_msg_type_number_t codeCnt;
+    integer_t code[2];
+    mach_msg_trailer_t trailer;
+  } Request;
+
+  typedef struct {
+    mach_msg_header_t Head;
+    NDR_record_t NDR;
+    kern_return_t RetCode;
+  } Reply;
+#ifdef  __MigPackStructs
+#pragma pack()
+#endif
+
+  Request *In0P = (Request *)InHeadP;
+  Reply *OutP = (Reply *)OutHeadP;
+
+  if (In0P->task.name != mach_task_self()) {
+    return FALSE;
+  }
+  OutP->RetCode = ForwardException(In0P->task.name,
+                                   In0P->thread.name,
+                                   In0P->exception,
+                                   In0P->code,
+                                   In0P->codeCnt);
+  OutP->NDR = NDR_record;
+  return TRUE;
+}
+#else
+boolean_t breakpad_exc_server(mach_msg_header_t *request,
+                              mach_msg_header_t *reply) {
+  return exc_server(request, reply);
+}
+
+// Callback from exc_server()
+kern_return_t catch_exception_raise(mach_port_t port, mach_port_t failed_thread,
+                                    mach_port_t task,
+                                    exception_type_t exception,
+                                    exception_data_t code,
+                                    mach_msg_type_number_t code_count) {
+  if (task != mach_task_self()) {
+    return KERN_FAILURE;
+  }
+  return ForwardException(task, failed_thread, exception, code, code_count);
+}
+#endif
+
+ExceptionHandler::ExceptionHandler(const string &dump_path,
+                                   FilterCallback filter,
+                                   MinidumpCallback callback,
+                                   void *callback_context,
+                                   bool install_handler,
+                                   const char *port_name)
+    : dump_path_(),
+      filter_(filter),
+      callback_(callback),
+      callback_context_(callback_context),
+      directCallback_(NULL),
+      handler_thread_(NULL),
+      handler_port_(MACH_PORT_NULL),
+      previous_(NULL),
+      installed_exception_handler_(false),
+      is_in_teardown_(false),
+      last_minidump_write_result_(false),
+      use_minidump_write_mutex_(false) {
+  // This will update to the ID and C-string pointers
+  set_dump_path(dump_path);
+  MinidumpGenerator::GatherSystemInformation();
+#if !TARGET_OS_IPHONE
+  if (port_name)
+    crash_generation_client_.reset(new CrashGenerationClient(port_name));
+#endif
+  Setup(install_handler);
+}
+
+// special constructor if we want to bypass minidump writing and
+// simply get a callback with the exception information
+ExceptionHandler::ExceptionHandler(DirectCallback callback,
+                                   void *callback_context,
+                                   bool install_handler)
+    : dump_path_(),
+      filter_(NULL),
+      callback_(NULL),
+      callback_context_(callback_context),
+      directCallback_(callback),
+      handler_thread_(NULL),
+      handler_port_(MACH_PORT_NULL),
+      previous_(NULL),
+      installed_exception_handler_(false),
+      is_in_teardown_(false),
+      last_minidump_write_result_(false),
+      use_minidump_write_mutex_(false) {
+  MinidumpGenerator::GatherSystemInformation();
+  Setup(install_handler);
+}
+
+ExceptionHandler::~ExceptionHandler() {
+  Teardown();
+}
+
+bool ExceptionHandler::WriteMinidump(bool write_exception_stream) {
+  // If we're currently writing, just return
+  if (use_minidump_write_mutex_)
+    return false;
+
+  use_minidump_write_mutex_ = true;
+  last_minidump_write_result_ = false;
+
+  // Lock the mutex.  Since we just created it, this will return immediately.
+  if (pthread_mutex_lock(&minidump_write_mutex_) == 0) {
+    // Send an empty message to the handle port so that a minidump will
+    // be written
+    SendMessageToHandlerThread(write_exception_stream ?
+                                   kWriteDumpWithExceptionMessage :
+                                   kWriteDumpMessage);
+
+    // Wait for the minidump writer to complete its writing.  It will unlock
+    // the mutex when completed
+    pthread_mutex_lock(&minidump_write_mutex_);
+  }
+
+  use_minidump_write_mutex_ = false;
+  UpdateNextID();
+  return last_minidump_write_result_;
+}
+
+// static
+bool ExceptionHandler::WriteMinidump(const string &dump_path,
+                                     bool write_exception_stream,
+                                     MinidumpCallback callback,
+                                     void *callback_context) {
+  ExceptionHandler handler(dump_path, NULL, callback, callback_context, false,
+			   NULL);
+  return handler.WriteMinidump(write_exception_stream);
+}
+
+// static
+bool ExceptionHandler::WriteMinidumpForChild(mach_port_t child,
+					     mach_port_t child_blamed_thread,
+					     const string &dump_path,
+					     MinidumpCallback callback,
+					     void *callback_context) {
+  ScopedTaskSuspend suspend(child);
+
+  MinidumpGenerator generator(child, MACH_PORT_NULL);
+  string dump_id;
+  string dump_filename = generator.UniqueNameInDirectory(dump_path, &dump_id);
+
+  generator.SetExceptionInformation(EXC_BREAKPOINT,
+#if defined (__i386__) || defined(__x86_64__)
+				    EXC_I386_BPT,
+#elif defined (__ppc__) || defined (__ppc64__)
+				    EXC_PPC_BREAKPOINT,
+#elif defined (__arm__)
+				    EXC_ARM_BREAKPOINT,
+#else
+#error architecture not supported
+#endif
+				    0,
+				    child_blamed_thread);
+  bool result = generator.Write(dump_filename.c_str());
+
+  if (callback) {
+    return callback(dump_path.c_str(), dump_id.c_str(),
+		    callback_context, result);
+  }
+  return result;
+}
+
+bool ExceptionHandler::WriteMinidumpWithException(int exception_type,
+                                                  int exception_code,
+                                                  int exception_subcode,
+                                                  mach_port_t thread_name,
+                                                  bool exit_after_write,
+                                                  bool report_current_thread) {
+  bool result = false;
+
+  if (directCallback_) {
+    if (directCallback_(callback_context_,
+                        exception_type,
+                        exception_code,
+                        exception_subcode,
+                        thread_name) ) {
+      if (exit_after_write)
+        _exit(exception_type);
+    }
+#if !TARGET_OS_IPHONE
+  } else if (IsOutOfProcess()) {
+    if (exception_type && exception_code) {
+      // If this is a real exception, give the filter (if any) a chance to
+      // decide if this should be sent.
+      if (filter_ && !filter_(callback_context_))
+	return false;
+      return crash_generation_client_->RequestDumpForException(
+	         exception_type,
+		 exception_code,
+		 exception_subcode,
+		 thread_name);
+    }
+#endif
+  } else {
+    string minidump_id;
+
+    // Putting the MinidumpGenerator in its own context will ensure that the
+    // destructor is executed, closing the newly created minidump file.
+    if (!dump_path_.empty()) {
+      MinidumpGenerator md(mach_task_self(),
+                           report_current_thread ? MACH_PORT_NULL :
+                                                   mach_thread_self());
+      if (exception_type && exception_code) {
+        // If this is a real exception, give the filter (if any) a chance to
+        // decide if this should be sent.
+        if (filter_ && !filter_(callback_context_))
+          return false;
+
+        md.SetExceptionInformation(exception_type, exception_code,
+                                   exception_subcode, thread_name);
+      }
+
+      result = md.Write(next_minidump_path_c_);
+    }
+
+    // Call user specified callback (if any)
+    if (callback_) {
+      // If the user callback returned true and we're handling an exception
+      // (rather than just writing out the file), then we should exit without
+      // forwarding the exception to the next handler.
+      if (callback_(dump_path_c_, next_minidump_id_c_, callback_context_,
+                    result)) {
+        if (exit_after_write)
+          _exit(exception_type);
+      }
+    }
+  }
+
+  return result;
+}
+
+kern_return_t ForwardException(mach_port_t task, mach_port_t failed_thread,
+                               exception_type_t exception,
+                               exception_data_t code,
+                               mach_msg_type_number_t code_count) {
+  // At this time, we should have called Uninstall() on the exception handler
+  // so that the current exception ports are the ones that we should be
+  // forwarding to.
+  ExceptionParameters current;
+
+  current.count = EXC_TYPES_COUNT;
+  mach_port_t current_task = mach_task_self();
+  task_get_exception_ports(current_task,
+                           s_exception_mask,
+                           current.masks,
+                           &current.count,
+                           current.ports,
+                           current.behaviors,
+                           current.flavors);
+
+  // Find the first exception handler that matches the exception
+  unsigned int found;
+  for (found = 0; found < current.count; ++found) {
+    if (current.masks[found] & (1 << exception)) {
+      break;
+    }
+  }
+
+  // Nothing to forward
+  if (found == current.count) {
+    fprintf(stderr, "** No previous ports for forwarding!! \n");
+    exit(KERN_FAILURE);
+  }
+
+  mach_port_t target_port = current.ports[found];
+  exception_behavior_t target_behavior = current.behaviors[found];
+
+  kern_return_t result;
+  switch (target_behavior) {
+    case EXCEPTION_DEFAULT:
+      result = exception_raise(target_port, failed_thread, task, exception,
+                               code, code_count);
+      break;
+
+    default:
+      fprintf(stderr, "** Unknown exception behavior: %d\n", target_behavior);
+      result = KERN_FAILURE;
+      break;
+  }
+
+  return result;
+}
+
+// static
+void *ExceptionHandler::WaitForMessage(void *exception_handler_class) {
+  ExceptionHandler *self =
+    reinterpret_cast<ExceptionHandler *>(exception_handler_class);
+  ExceptionMessage receive;
+
+  // Wait for the exception info
+  while (1) {
+    receive.header.msgh_local_port = self->handler_port_;
+    receive.header.msgh_size = static_cast<mach_msg_size_t>(sizeof(receive));
+    kern_return_t result = mach_msg(&(receive.header),
+                                    MACH_RCV_MSG | MACH_RCV_LARGE, 0,
+                                    receive.header.msgh_size,
+                                    self->handler_port_,
+                                    MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
+
+
+    if (result == KERN_SUCCESS) {
+      // Uninstall our handler so that we don't get in a loop if the process of
+      // writing out a minidump causes an exception.  However, if the exception
+      // was caused by a fork'd process, don't uninstall things
+
+      // If the actual exception code is zero, then we're calling this handler
+      // in a way that indicates that we want to either exit this thread or
+      // generate a minidump
+      //
+      // While reporting, all threads (except this one) must be suspended
+      // to avoid misleading stacks.  If appropriate they will be resumed
+      // afterwards.
+      if (!receive.exception) {
+        // Don't touch self, since this message could have been sent
+        // from its destructor.
+        if (receive.header.msgh_id == kShutdownMessage)
+          return NULL;
+
+        self->SuspendThreads();
+
+#if USE_PROTECTED_ALLOCATIONS
+        if (gBreakpadAllocator)
+          gBreakpadAllocator->Unprotect();
+#endif
+
+        mach_port_t thread = MACH_PORT_NULL;
+        int exception_type = 0;
+        int exception_code = 0;
+        if (receive.header.msgh_id == kWriteDumpWithExceptionMessage) {
+          thread = receive.thread.name;
+          exception_type = EXC_BREAKPOINT;
+#if defined (__i386__) || defined(__x86_64__)
+          exception_code = EXC_I386_BPT;
+#elif defined (__ppc__) || defined (__ppc64__)
+          exception_code = EXC_PPC_BREAKPOINT;
+#elif defined (__arm__)
+          exception_code = EXC_ARM_BREAKPOINT;
+#else
+#error architecture not supported
+#endif
+        }
+
+        // Write out the dump and save the result for later retrieval
+        self->last_minidump_write_result_ =
+          self->WriteMinidumpWithException(exception_type, exception_code,
+                                           0, thread,
+                                           false, false);
+
+#if USE_PROTECTED_ALLOCATIONS
+        if (gBreakpadAllocator)
+          gBreakpadAllocator->Protect();
+#endif
+
+        self->ResumeThreads();
+
+        if (self->use_minidump_write_mutex_)
+          pthread_mutex_unlock(&self->minidump_write_mutex_);
+      } else {
+        // When forking a child process with the exception handler installed,
+        // if the child crashes, it will send the exception back to the parent
+        // process.  The check for task == self_task() ensures that only
+        // exceptions that occur in the parent process are caught and
+        // processed.  If the exception was not caused by this task, we
+        // still need to call into the exception server and have it return
+        // KERN_FAILURE (see catch_exception_raise) in order for the kernel
+        // to move onto the host exception handler for the child task
+        if (receive.task.name == mach_task_self()) {
+          self->SuspendThreads();
+
+#if USE_PROTECTED_ALLOCATIONS
+        if (gBreakpadAllocator)
+          gBreakpadAllocator->Unprotect();
+#endif
+
+        int subcode = 0;
+        if (receive.exception == EXC_BAD_ACCESS && receive.code_count > 1)
+          subcode = receive.code[1];
+
+        // Generate the minidump with the exception data.
+        self->WriteMinidumpWithException(receive.exception, receive.code[0],
+                                         subcode, receive.thread.name, true,
+                                         false);
+
+#if USE_PROTECTED_ALLOCATIONS
+        // This may have become protected again within
+        // WriteMinidumpWithException, but it needs to be unprotected for
+        // UninstallHandler.
+        if (gBreakpadAllocator)
+          gBreakpadAllocator->Unprotect();
+#endif
+
+        self->UninstallHandler(true);
+
+#if USE_PROTECTED_ALLOCATIONS
+        if (gBreakpadAllocator)
+          gBreakpadAllocator->Protect();
+#endif
+        }
+        // Pass along the exception to the server, which will setup the
+        // message and call catch_exception_raise() and put the return
+        // code into the reply.
+        ExceptionReplyMessage reply;
+        if (!breakpad_exc_server(&receive.header, &reply.header))
+          exit(1);
+
+        // Send a reply and exit
+        mach_msg(&(reply.header), MACH_SEND_MSG,
+                 reply.header.msgh_size, 0, MACH_PORT_NULL,
+                 MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
+      }
+    }
+  }
+
+  return NULL;
+}
+
+//static
+void ExceptionHandler::SignalHandler(int sig, siginfo_t* info, void* uc) {
+#if USE_PROTECTED_ALLOCATIONS
+  if (gBreakpadAllocator)
+    gBreakpadAllocator->Unprotect();
+#endif
+  gProtectedData.handler->WriteMinidumpWithException(
+      EXC_SOFTWARE,
+      MD_EXCEPTION_CODE_MAC_ABORT,
+      0,
+      mach_thread_self(),
+      true,
+      true);
+#if USE_PROTECTED_ALLOCATIONS
+  if (gBreakpadAllocator)
+    gBreakpadAllocator->Protect();
+#endif
+}
+
+bool ExceptionHandler::InstallHandler() {
+  // If a handler is already installed, something is really wrong.
+  if (gProtectedData.handler != NULL) {
+    return false;
+  }
+#if TARGET_OS_IPHONE
+  if (!IsOutOfProcess()) {
+    struct sigaction sa;
+    memset(&sa, 0, sizeof(sa));
+    sigemptyset(&sa.sa_mask);
+    sigaddset(&sa.sa_mask, SIGABRT);
+    sa.sa_sigaction = ExceptionHandler::SignalHandler;
+    sa.sa_flags = SA_SIGINFO;
+
+    scoped_ptr<struct sigaction> old(new struct sigaction);
+    if (sigaction(SIGABRT, &sa, old.get()) == -1) {
+      return false;
+    }
+    old_handler_.swap(old);
+    gProtectedData.handler = this;
+#if USE_PROTECTED_ALLOCATIONS
+    assert(((size_t)(gProtectedData.protected_buffer) & PAGE_MASK) == 0);
+    mprotect(gProtectedData.protected_buffer, PAGE_SIZE, PROT_READ);
+#endif
+  }
+#endif
+
+  try {
+#if USE_PROTECTED_ALLOCATIONS
+    previous_ = new (gBreakpadAllocator->Allocate(sizeof(ExceptionParameters)) )
+      ExceptionParameters();
+#else
+    previous_ = new ExceptionParameters();
+#endif
+
+  }
+  catch (std::bad_alloc) {
+    return false;
+  }
+
+  // Save the current exception ports so that we can forward to them
+  previous_->count = EXC_TYPES_COUNT;
+  mach_port_t current_task = mach_task_self();
+  kern_return_t result = task_get_exception_ports(current_task,
+                                                  s_exception_mask,
+                                                  previous_->masks,
+                                                  &previous_->count,
+                                                  previous_->ports,
+                                                  previous_->behaviors,
+                                                  previous_->flavors);
+
+  // Setup the exception ports on this task
+  if (result == KERN_SUCCESS)
+    result = task_set_exception_ports(current_task, s_exception_mask,
+                                      handler_port_, EXCEPTION_DEFAULT,
+                                      THREAD_STATE_NONE);
+
+  installed_exception_handler_ = (result == KERN_SUCCESS);
+
+  return installed_exception_handler_;
+}
+
+bool ExceptionHandler::UninstallHandler(bool in_exception) {
+  kern_return_t result = KERN_SUCCESS;
+
+  if (old_handler_.get()) {
+    sigaction(SIGABRT, old_handler_.get(), NULL);
+#if USE_PROTECTED_ALLOCATIONS
+    mprotect(gProtectedData.protected_buffer, PAGE_SIZE,
+        PROT_READ | PROT_WRITE);
+#endif
+    old_handler_.reset();
+    gProtectedData.handler = NULL;
+  }
+
+  if (installed_exception_handler_) {
+    mach_port_t current_task = mach_task_self();
+
+    // Restore the previous ports
+    for (unsigned int i = 0; i < previous_->count; ++i) {
+       result = task_set_exception_ports(current_task, previous_->masks[i],
+                                        previous_->ports[i],
+                                        previous_->behaviors[i],
+                                        previous_->flavors[i]);
+      if (result != KERN_SUCCESS)
+        return false;
+    }
+
+    // this delete should NOT happen if an exception just occurred!
+    if (!in_exception) {
+#if USE_PROTECTED_ALLOCATIONS
+      previous_->~ExceptionParameters();
+#else
+      delete previous_;
+#endif
+    }
+
+    previous_ = NULL;
+    installed_exception_handler_ = false;
+  }
+
+  return result == KERN_SUCCESS;
+}
+
+bool ExceptionHandler::Setup(bool install_handler) {
+  if (pthread_mutex_init(&minidump_write_mutex_, NULL))
+    return false;
+
+  // Create a receive right
+  mach_port_t current_task = mach_task_self();
+  kern_return_t result = mach_port_allocate(current_task,
+                                            MACH_PORT_RIGHT_RECEIVE,
+                                            &handler_port_);
+  // Add send right
+  if (result == KERN_SUCCESS)
+    result = mach_port_insert_right(current_task, handler_port_, handler_port_,
+                                    MACH_MSG_TYPE_MAKE_SEND);
+
+  if (install_handler && result == KERN_SUCCESS)
+    if (!InstallHandler())
+      return false;
+
+  if (result == KERN_SUCCESS) {
+    // Install the handler in its own thread, detached as we won't be joining.
+    pthread_attr_t attr;
+    pthread_attr_init(&attr);
+    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+    int thread_create_result = pthread_create(&handler_thread_, &attr,
+                                              &WaitForMessage, this);
+    pthread_attr_destroy(&attr);
+    result = thread_create_result ? KERN_FAILURE : KERN_SUCCESS;
+  }
+
+  return result == KERN_SUCCESS ? true : false;
+}
+
+bool ExceptionHandler::Teardown() {
+  kern_return_t result = KERN_SUCCESS;
+  is_in_teardown_ = true;
+
+  if (!UninstallHandler(false))
+    return false;
+
+  // Send an empty message so that the handler_thread exits
+  if (SendMessageToHandlerThread(kShutdownMessage)) {
+    mach_port_t current_task = mach_task_self();
+    result = mach_port_deallocate(current_task, handler_port_);
+    if (result != KERN_SUCCESS)
+      return false;
+  } else {
+    return false;
+  }
+
+  handler_thread_ = NULL;
+  handler_port_ = MACH_PORT_NULL;
+  pthread_mutex_destroy(&minidump_write_mutex_);
+
+  return result == KERN_SUCCESS;
+}
+
+bool ExceptionHandler::SendMessageToHandlerThread(
+    HandlerThreadMessage message_id) {
+  ExceptionMessage msg;
+  memset(&msg, 0, sizeof(msg));
+  msg.header.msgh_id = message_id;
+  if (message_id == kWriteDumpMessage ||
+      message_id == kWriteDumpWithExceptionMessage) {
+    // Include this thread's port.
+    msg.thread.name = mach_thread_self();
+    msg.thread.disposition = MACH_MSG_TYPE_PORT_SEND;
+    msg.thread.type = MACH_MSG_PORT_DESCRIPTOR;
+  }
+  msg.header.msgh_size = sizeof(msg) - sizeof(msg.padding);
+  msg.header.msgh_remote_port = handler_port_;
+  msg.header.msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND,
+                                          MACH_MSG_TYPE_MAKE_SEND_ONCE);
+  kern_return_t result = mach_msg(&(msg.header),
+                                  MACH_SEND_MSG | MACH_SEND_TIMEOUT,
+                                  msg.header.msgh_size, 0, 0,
+                                  MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
+
+  return result == KERN_SUCCESS;
+}
+
+void ExceptionHandler::UpdateNextID() {
+  next_minidump_path_ =
+    (MinidumpGenerator::UniqueNameInDirectory(dump_path_, &next_minidump_id_));
+
+  next_minidump_path_c_ = next_minidump_path_.c_str();
+  next_minidump_id_c_ = next_minidump_id_.c_str();
+}
+
+bool ExceptionHandler::SuspendThreads() {
+  thread_act_port_array_t   threads_for_task;
+  mach_msg_type_number_t    thread_count;
+
+  if (task_threads(mach_task_self(), &threads_for_task, &thread_count))
+    return false;
+
+  // suspend all of the threads except for this one
+  for (unsigned int i = 0; i < thread_count; ++i) {
+    if (threads_for_task[i] != mach_thread_self()) {
+      if (thread_suspend(threads_for_task[i]))
+        return false;
+    }
+  }
+
+  return true;
+}
+
+bool ExceptionHandler::ResumeThreads() {
+  thread_act_port_array_t   threads_for_task;
+  mach_msg_type_number_t    thread_count;
+
+  if (task_threads(mach_task_self(), &threads_for_task, &thread_count))
+    return false;
+
+  // resume all of the threads except for this one
+  for (unsigned int i = 0; i < thread_count; ++i) {
+    if (threads_for_task[i] != mach_thread_self()) {
+      if (thread_resume(threads_for_task[i]))
+        return false;
+    }
+  }
+
+  return true;
+}
+
+}  // namespace google_breakpad
diff --git a/3rdParty/Breakpad/src/client/mac/handler/exception_handler.h b/3rdParty/Breakpad/src/client/mac/handler/exception_handler.h
new file mode 100644
index 0000000..ec09134
--- /dev/null
+++ b/3rdParty/Breakpad/src/client/mac/handler/exception_handler.h
@@ -0,0 +1,277 @@
+// 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.
+
+// exception_handler.h:  MacOS exception handler
+// This class can install a Mach exception port handler to trap most common
+// programming errors.  If an exception occurs, a minidump file will be
+// generated which contains detailed information about the process and the
+// exception.
+
+#ifndef CLIENT_MAC_HANDLER_EXCEPTION_HANDLER_H__
+#define CLIENT_MAC_HANDLER_EXCEPTION_HANDLER_H__
+
+#include <mach/mach.h>
+#include <TargetConditionals.h>
+
+#include <string>
+
+#include "processor/scoped_ptr.h"
+
+#if !TARGET_OS_IPHONE
+#include "client/mac/crash_generation/crash_generation_client.h"
+#endif
+
+namespace google_breakpad {
+
+using std::string;
+
+struct ExceptionParameters;
+
+enum HandlerThreadMessage {
+  // Message ID telling the handler thread to write a dump.
+  kWriteDumpMessage = 0,
+  // Message ID telling the handler thread to write a dump and include
+  // an exception stream.
+  kWriteDumpWithExceptionMessage = 1,
+  // Message ID telling the handler thread to quit.
+  kShutdownMessage = 2
+};
+
+class ExceptionHandler {
+ public:
+  // A callback function to run before Breakpad performs any substantial
+  // processing of an exception.  A FilterCallback is called before writing
+  // a minidump.  context is the parameter supplied by the user as
+  // callback_context when the handler was created.
+  //
+  // If a FilterCallback returns true, Breakpad will continue processing,
+  // attempting to write a minidump.  If a FilterCallback returns false, Breakpad
+  // will immediately report the exception as unhandled without writing a
+  // minidump, allowing another handler the opportunity to handle it.
+  typedef bool (*FilterCallback)(void *context);
+
+  // A callback function to run after the minidump has been written.
+  // |minidump_id| is a unique id for the dump, so the minidump
+  // file is <dump_dir>/<minidump_id>.dmp.
+  // |context| is the value passed into the constructor.
+  // |succeeded| indicates whether a minidump file was successfully written.
+  // Return true if the exception was fully handled and breakpad should exit.
+  // Return false to allow any other exception handlers to process the
+  // exception.
+  typedef bool (*MinidumpCallback)(const char *dump_dir,
+                                   const char *minidump_id,
+                                   void *context, bool succeeded);
+
+  // A callback function which will be called directly if an exception occurs.
+  // This bypasses the minidump file writing and simply gives the client
+  // the exception information.
+  typedef bool (*DirectCallback)( void *context,
+                                  int exception_type,
+                                  int exception_code,
+                                  int exception_subcode,
+                                  mach_port_t thread_name);
+
+  // Creates a new ExceptionHandler instance to handle writing minidumps.
+  // Minidump files will be written to dump_path, and the optional callback
+  // is called after writing the dump file, as described above.
+  // If install_handler is true, then a minidump will be written whenever
+  // an unhandled exception occurs.  If it is false, minidumps will only
+  // be written when WriteMinidump is called.
+  // If port_name is non-NULL, attempt to perform out-of-process dump generation
+  // If port_name is NULL, in-process dump generation will be used.
+  ExceptionHandler(const string &dump_path,
+                   FilterCallback filter, MinidumpCallback callback,
+                   void *callback_context, bool install_handler,
+		   const char *port_name);
+
+  // A special constructor if we want to bypass minidump writing and
+  // simply get a callback with the exception information.
+  ExceptionHandler(DirectCallback callback,
+                   void *callback_context,
+                   bool install_handler);
+
+  ~ExceptionHandler();
+
+  // Get and set the minidump path.
+  string dump_path() const { return dump_path_; }
+  void set_dump_path(const string &dump_path) {
+    dump_path_ = dump_path;
+    dump_path_c_ = dump_path_.c_str();
+    UpdateNextID();  // Necessary to put dump_path_ in next_minidump_path_.
+  }
+
+  // Writes a minidump immediately.  This can be used to capture the
+  // execution state independently of a crash.  Returns true on success.
+  bool WriteMinidump() {
+    return WriteMinidump(false);
+  }
+
+  bool WriteMinidump(bool write_exception_stream);
+
+  // Convenience form of WriteMinidump which does not require an
+  // ExceptionHandler instance.
+  static bool WriteMinidump(const string &dump_path, MinidumpCallback callback,
+                            void *callback_context) {
+    return WriteMinidump(dump_path, false, callback, callback_context);
+  }
+
+  static bool WriteMinidump(const string &dump_path,
+                            bool write_exception_stream,
+                            MinidumpCallback callback,
+                            void *callback_context);
+
+  // Write a minidump of child immediately. This can be used to capture
+  // the execution state of a child process independently of a crash.
+  static bool WriteMinidumpForChild(mach_port_t child,
+				    mach_port_t child_blamed_thread,
+				    const std::string &dump_path,
+				    MinidumpCallback callback,
+				    void *callback_context);
+
+  // Returns whether out-of-process dump generation is used or not.
+  bool IsOutOfProcess() const {
+#if TARGET_OS_IPHONE
+    return false;
+#else
+    return crash_generation_client_.get() != NULL;
+#endif
+  }
+
+ private:
+  // Install the mach exception handler
+  bool InstallHandler();
+
+  // Uninstall the mach exception handler (if any)
+  bool UninstallHandler(bool in_exception);
+
+  // Setup the handler thread, and if |install_handler| is true, install the
+  // mach exception port handler
+  bool Setup(bool install_handler);
+
+  // Uninstall the mach exception handler (if any) and terminate the helper
+  // thread
+  bool Teardown();
+
+  // Send a mach message to the exception handler.  Return true on
+  // success, false otherwise.
+  bool SendMessageToHandlerThread(HandlerThreadMessage message_id);
+
+  // All minidump writing goes through this one routine
+  bool WriteMinidumpWithException(int exception_type,
+                                  int exception_code,
+                                  int exception_subcode,
+                                  mach_port_t thread_name,
+                                  bool exit_after_write,
+                                  bool report_current_thread);
+
+  // When installed, this static function will be call from a newly created
+  // pthread with |this| as the argument
+  static void *WaitForMessage(void *exception_handler_class);
+
+  // Signal handler for SIGABRT.
+  static void SignalHandler(int sig, siginfo_t* info, void* uc);
+
+  // disallow copy ctor and operator=
+  explicit ExceptionHandler(const ExceptionHandler &);
+  void operator=(const ExceptionHandler &);
+
+  // Generates a new ID and stores it in next_minidump_id_, and stores the
+  // path of the next minidump to be written in next_minidump_path_.
+  void UpdateNextID();
+
+  // These functions will suspend/resume all threads except for the
+  // reporting thread
+  bool SuspendThreads();
+  bool ResumeThreads();
+
+  // The destination directory for the minidump
+  string dump_path_;
+
+  // The basename of the next minidump w/o extension
+  string next_minidump_id_;
+
+  // The full path to the next minidump to be written, including extension
+  string next_minidump_path_;
+
+  // Pointers to the UTF-8 versions of above
+  const char *dump_path_c_;
+  const char *next_minidump_id_c_;
+  const char *next_minidump_path_c_;
+
+  // The callback function and pointer to be passed back after the minidump
+  // has been written
+  FilterCallback filter_;
+  MinidumpCallback callback_;
+  void *callback_context_;
+
+  // The callback function to be passed back when we don't want a minidump
+  // file to be written
+  DirectCallback directCallback_;
+
+  // The thread that is created for the handler
+  pthread_t handler_thread_;
+
+  // The port that is waiting on an exception message to be sent, if the
+  // handler is installed
+  mach_port_t handler_port_;
+
+  // These variables save the previous exception handler's data so that it
+  // can be re-installed when this handler is uninstalled
+  ExceptionParameters *previous_;
+
+  // True, if we've installed the exception handler
+  bool installed_exception_handler_;
+
+  // True, if we're in the process of uninstalling the exception handler and
+  // the thread.
+  bool is_in_teardown_;
+
+  // Save the last result of the last minidump
+  bool last_minidump_write_result_;
+
+  // A mutex for use when writing out a minidump that was requested on a
+  // thread other than the exception handler.
+  pthread_mutex_t minidump_write_mutex_;
+
+  // True, if we're using the mutext to indicate when mindump writing occurs
+  bool use_minidump_write_mutex_;
+
+  // Old signal handler for SIGABRT. Used to be able to restore it when
+  // uninstalling.
+  scoped_ptr<struct sigaction> old_handler_;
+
+#if !TARGET_OS_IPHONE
+  // Client for out-of-process dump generation.
+  scoped_ptr<CrashGenerationClient> crash_generation_client_;
+#endif
+};
+
+}  // namespace google_breakpad
+
+#endif  // CLIENT_MAC_HANDLER_EXCEPTION_HANDLER_H__
diff --git a/3rdParty/Breakpad/src/client/mac/handler/mach_vm_compat.h b/3rdParty/Breakpad/src/client/mac/handler/mach_vm_compat.h
new file mode 100644
index 0000000..e0459be
--- /dev/null
+++ b/3rdParty/Breakpad/src/client/mac/handler/mach_vm_compat.h
@@ -0,0 +1,49 @@
+// 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.
+
+#ifndef CLIENT_MAC_GENERATOR_MACH_VM_COMPAT_H_
+#define CLIENT_MAC_GENERATOR_MACH_VM_COMPAT_H_
+
+#include <TargetConditionals.h>
+
+// On iOS 5, mach/mach_vm.h is not supported anymore. As the architecture is 32
+// bits, we can use the simple vm_ functions instead of the mach_vm_ ones.
+#if TARGET_OS_IPHONE
+#include <mach/vm_map.h>
+#define mach_vm_address_t vm_address_t
+#define mach_vm_deallocate vm_deallocate
+#define mach_vm_read vm_read
+#define mach_vm_region vm_region
+#define mach_vm_region_recurse vm_region_recurse
+#define mach_vm_size_t vm_size_t
+#else
+#include <mach/mach_vm.h>
+#endif  // TARGET_OS_IPHONE
+
+#endif  // CLIENT_MAC_GENERATOR_MACH_VM_COMPAT_H_
diff --git a/3rdParty/Breakpad/src/client/mac/handler/minidump_generator.cc b/3rdParty/Breakpad/src/client/mac/handler/minidump_generator.cc
new file mode 100644
index 0000000..b1d429c
--- /dev/null
+++ b/3rdParty/Breakpad/src/client/mac/handler/minidump_generator.cc
@@ -0,0 +1,1432 @@
+// Copyright (c) 2006, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include <algorithm>
+#include <cstdio>
+
+#include <mach/host_info.h>
+#include <mach/vm_statistics.h>
+#include <mach-o/dyld.h>
+#include <mach-o/loader.h>
+#include <sys/sysctl.h>
+#include <sys/resource.h>
+
+#include <CoreFoundation/CoreFoundation.h>
+
+#include "client/mac/handler/minidump_generator.h"
+
+#ifdef HAS_ARM_SUPPORT
+#include <mach/arm/thread_status.h>
+#endif
+#ifdef HAS_PPC_SUPPORT
+#include <mach/ppc/thread_status.h>
+#endif
+#ifdef HAS_X86_SUPPORT
+#include <mach/i386/thread_status.h>
+#endif
+
+#include "client/minidump_file_writer-inl.h"
+#include "common/mac/file_id.h"
+#include "common/mac/macho_id.h"
+#include "common/mac/string_utilities.h"
+
+using MacStringUtils::ConvertToString;
+using MacStringUtils::IntegerValueAtIndex;
+
+namespace google_breakpad {
+
+#if __LP64__
+#define LC_SEGMENT_ARCH LC_SEGMENT_64
+#else
+#define LC_SEGMENT_ARCH LC_SEGMENT
+#endif
+
+// constructor when generating from within the crashed process
+MinidumpGenerator::MinidumpGenerator()
+    : writer_(),
+      exception_type_(0),
+      exception_code_(0),
+      exception_subcode_(0),
+      exception_thread_(0),
+      crashing_task_(mach_task_self()),
+      handler_thread_(mach_thread_self()),
+      cpu_type_(DynamicImages::GetNativeCPUType()),
+      dynamic_images_(NULL),
+      memory_blocks_(&allocator_) {
+  GatherSystemInformation();
+}
+
+// constructor when generating from a different process than the
+// crashed process
+MinidumpGenerator::MinidumpGenerator(mach_port_t crashing_task,
+                                     mach_port_t handler_thread)
+    : writer_(),
+      exception_type_(0),
+      exception_code_(0),
+      exception_subcode_(0),
+      exception_thread_(0),
+      crashing_task_(crashing_task),
+      handler_thread_(handler_thread),
+      cpu_type_(DynamicImages::GetNativeCPUType()),
+      dynamic_images_(NULL),
+      memory_blocks_(&allocator_) {
+  if (crashing_task != mach_task_self()) {
+    dynamic_images_ = new DynamicImages(crashing_task_);
+    cpu_type_ = dynamic_images_->GetCPUType();
+  } else {
+    dynamic_images_ = NULL;
+    cpu_type_ = DynamicImages::GetNativeCPUType();
+  }
+
+  GatherSystemInformation();
+}
+
+MinidumpGenerator::~MinidumpGenerator() {
+  delete dynamic_images_;
+}
+
+char MinidumpGenerator::build_string_[16];
+int MinidumpGenerator::os_major_version_ = 0;
+int MinidumpGenerator::os_minor_version_ = 0;
+int MinidumpGenerator::os_build_number_ = 0;
+
+// static
+void MinidumpGenerator::GatherSystemInformation() {
+  // If this is non-zero, then we've already gathered the information
+  if (os_major_version_)
+    return;
+
+  // This code extracts the version and build information from the OS
+  CFStringRef vers_path =
+    CFSTR("/System/Library/CoreServices/SystemVersion.plist");
+  CFURLRef sys_vers =
+    CFURLCreateWithFileSystemPath(NULL,
+                                  vers_path,
+                                  kCFURLPOSIXPathStyle,
+                                  false);
+  CFDataRef data;
+  SInt32 error;
+  CFURLCreateDataAndPropertiesFromResource(NULL, sys_vers, &data, NULL, NULL,
+                                           &error);
+
+  if (!data) {
+    CFRelease(sys_vers);
+    return;
+  }
+
+  CFDictionaryRef list = static_cast<CFDictionaryRef>
+    (CFPropertyListCreateFromXMLData(NULL, data, kCFPropertyListImmutable,
+                                     NULL));
+  if (!list) {
+    CFRelease(sys_vers);
+    CFRelease(data);
+    return;
+  }
+
+  CFStringRef build_version = static_cast<CFStringRef>
+    (CFDictionaryGetValue(list, CFSTR("ProductBuildVersion")));
+  CFStringRef product_version = static_cast<CFStringRef>
+    (CFDictionaryGetValue(list, CFSTR("ProductVersion")));
+  string build_str = ConvertToString(build_version);
+  string product_str = ConvertToString(product_version);
+
+  CFRelease(list);
+  CFRelease(sys_vers);
+  CFRelease(data);
+
+  strlcpy(build_string_, build_str.c_str(), sizeof(build_string_));
+
+  // Parse the string that looks like "10.4.8"
+  os_major_version_ = IntegerValueAtIndex(product_str, 0);
+  os_minor_version_ = IntegerValueAtIndex(product_str, 1);
+  os_build_number_ = IntegerValueAtIndex(product_str, 2);
+}
+
+string MinidumpGenerator::UniqueNameInDirectory(const string &dir,
+                                                string *unique_name) {
+  CFUUIDRef uuid = CFUUIDCreate(NULL);
+  CFStringRef uuid_cfstr = CFUUIDCreateString(NULL, uuid);
+  CFRelease(uuid);
+  string file_name(ConvertToString(uuid_cfstr));
+  CFRelease(uuid_cfstr);
+  string path(dir);
+
+  // Ensure that the directory (if non-empty) has a trailing slash so that
+  // we can append the file name and have a valid pathname.
+  if (!dir.empty()) {
+    if (dir.at(dir.size() - 1) != '/')
+      path.append(1, '/');
+  }
+
+  path.append(file_name);
+  path.append(".dmp");
+
+  if (unique_name)
+    *unique_name = file_name;
+
+  return path;
+}
+
+bool MinidumpGenerator::Write(const char *path) {
+  WriteStreamFN writers[] = {
+    &MinidumpGenerator::WriteThreadListStream,
+    &MinidumpGenerator::WriteMemoryListStream,
+    &MinidumpGenerator::WriteSystemInfoStream,
+    &MinidumpGenerator::WriteModuleListStream,
+    &MinidumpGenerator::WriteMiscInfoStream,
+    &MinidumpGenerator::WriteBreakpadInfoStream,
+    // Exception stream needs to be the last entry in this array as it may
+    // be omitted in the case where the minidump is written without an
+    // exception.
+    &MinidumpGenerator::WriteExceptionStream,
+  };
+  bool result = false;
+
+  // If opening was successful, create the header, directory, and call each
+  // writer.  The destructor for the TypedMDRVAs will cause the data to be
+  // flushed.  The destructor for the MinidumpFileWriter will close the file.
+  if (writer_.Open(path)) {
+    TypedMDRVA<MDRawHeader> header(&writer_);
+    TypedMDRVA<MDRawDirectory> dir(&writer_);
+
+    if (!header.Allocate())
+      return false;
+
+    int writer_count = static_cast<int>(sizeof(writers) / sizeof(writers[0]));
+
+    // If we don't have exception information, don't write out the
+    // exception stream
+    if (!exception_thread_ && !exception_type_)
+      --writer_count;
+
+    // Add space for all writers
+    if (!dir.AllocateArray(writer_count))
+      return false;
+
+    MDRawHeader *header_ptr = header.get();
+    header_ptr->signature = MD_HEADER_SIGNATURE;
+    header_ptr->version = MD_HEADER_VERSION;
+    time(reinterpret_cast<time_t *>(&(header_ptr->time_date_stamp)));
+    header_ptr->stream_count = writer_count;
+    header_ptr->stream_directory_rva = dir.position();
+
+    MDRawDirectory local_dir;
+    result = true;
+    for (int i = 0; (result) && (i < writer_count); ++i) {
+      result = (this->*writers[i])(&local_dir);
+
+      if (result)
+        dir.CopyIndex(i, &local_dir);
+    }
+  }
+  return result;
+}
+
+size_t MinidumpGenerator::CalculateStackSize(mach_vm_address_t start_addr) {
+  mach_vm_address_t stack_region_base = start_addr;
+  mach_vm_size_t stack_region_size;
+  natural_t nesting_level = 0;
+  vm_region_submap_info_64 submap_info;
+  mach_msg_type_number_t info_count = VM_REGION_SUBMAP_INFO_COUNT_64;
+
+  vm_region_recurse_info_t region_info;
+  region_info = reinterpret_cast<vm_region_recurse_info_t>(&submap_info);
+
+  if (start_addr == 0) {
+    return 0;
+  }
+
+  kern_return_t result =
+    mach_vm_region_recurse(crashing_task_, &stack_region_base,
+                           &stack_region_size, &nesting_level,
+                           region_info, &info_count);
+
+  if (result != KERN_SUCCESS || start_addr < stack_region_base) {
+    // Failure or stack corruption, since mach_vm_region had to go
+    // higher in the process address space to find a valid region.
+    return 0;
+  }
+
+  unsigned int tag = submap_info.user_tag;
+
+  // If the user tag is VM_MEMORY_STACK, look for more readable regions with
+  // the same tag placed immediately above the computed stack region. Under
+  // some circumstances, the stack for thread 0 winds up broken up into
+  // multiple distinct abutting regions. This can happen for several reasons,
+  // including user code that calls setrlimit(RLIMIT_STACK, ...) or changes
+  // the access on stack pages by calling mprotect.
+  if (tag == VM_MEMORY_STACK) {
+    while (true) {
+      mach_vm_address_t next_region_base = stack_region_base +
+                                           stack_region_size;
+      mach_vm_address_t proposed_next_region_base = next_region_base;
+      mach_vm_size_t next_region_size;
+      nesting_level = 0;
+      mach_msg_type_number_t info_count = VM_REGION_SUBMAP_INFO_COUNT_64;
+      result = mach_vm_region_recurse(crashing_task_, &next_region_base,
+                                      &next_region_size, &nesting_level,
+                                      region_info, &info_count);
+      if (result != KERN_SUCCESS ||
+          next_region_base != proposed_next_region_base ||
+          submap_info.user_tag != tag ||
+          (submap_info.protection & VM_PROT_READ) == 0) {
+        break;
+      }
+
+      stack_region_size += next_region_size;
+    }
+  }
+
+  return stack_region_base + stack_region_size - start_addr;
+}
+
+bool MinidumpGenerator::WriteStackFromStartAddress(
+    mach_vm_address_t start_addr,
+    MDMemoryDescriptor *stack_location) {
+  UntypedMDRVA memory(&writer_);
+
+  bool result = false;
+  size_t size = CalculateStackSize(start_addr);
+
+  if (size == 0) {
+      // In some situations the stack address for the thread can come back 0.
+      // In these cases we skip over the threads in question and stuff the
+      // stack with a clearly borked value.
+      start_addr = 0xDEADBEEF;
+      size = 16;
+      if (!memory.Allocate(size))
+        return false;
+
+      unsigned long long dummy_stack[2];  // Fill dummy stack with 16 bytes of
+                                          // junk.
+      dummy_stack[0] = 0xDEADBEEF;
+      dummy_stack[1] = 0xDEADBEEF;
+
+      result = memory.Copy(dummy_stack, size);
+  } else {
+
+    if (!memory.Allocate(size))
+      return false;
+
+    if (dynamic_images_) {
+      vector<uint8_t> stack_memory;
+      if (ReadTaskMemory(crashing_task_,
+                         start_addr,
+                         size,
+                         stack_memory) != KERN_SUCCESS) {
+        return false;
+      }
+
+      result = memory.Copy(&stack_memory[0], size);
+    } else {
+      result = memory.Copy(reinterpret_cast<const void *>(start_addr), size);
+    }
+  }
+
+  stack_location->start_of_memory_range = start_addr;
+  stack_location->memory = memory.location();
+
+  return result;
+}
+
+bool MinidumpGenerator::WriteStack(breakpad_thread_state_data_t state,
+                                   MDMemoryDescriptor *stack_location) {
+  switch (cpu_type_) {
+#ifdef HAS_ARM_SUPPORT
+    case CPU_TYPE_ARM:
+      return WriteStackARM(state, stack_location);
+#endif
+#ifdef HAS_PPC_SUPPORT
+    case CPU_TYPE_POWERPC:
+      return WriteStackPPC(state, stack_location);
+    case CPU_TYPE_POWERPC64:
+      return WriteStackPPC64(state, stack_location);
+#endif
+#ifdef HAS_X86_SUPPORT
+    case CPU_TYPE_I386:
+      return WriteStackX86(state, stack_location);
+    case CPU_TYPE_X86_64:
+      return WriteStackX86_64(state, stack_location);
+#endif
+    default:
+      return false;
+  }
+}
+
+bool MinidumpGenerator::WriteContext(breakpad_thread_state_data_t state,
+                                     MDLocationDescriptor *register_location) {
+  switch (cpu_type_) {
+#ifdef HAS_ARM_SUPPORT
+    case CPU_TYPE_ARM:
+      return WriteContextARM(state, register_location);
+#endif
+#ifdef HAS_PPC_SUPPORT
+    case CPU_TYPE_POWERPC:
+      return WriteContextPPC(state, register_location);
+    case CPU_TYPE_POWERPC64:
+      return WriteContextPPC64(state, register_location);
+#endif
+#ifdef HAS_X86_SUPPORT
+    case CPU_TYPE_I386:
+      return WriteContextX86(state, register_location);
+    case CPU_TYPE_X86_64:
+      return WriteContextX86_64(state, register_location);
+#endif
+    default:
+      return false;
+  }
+}
+
+u_int64_t MinidumpGenerator::CurrentPCForStack(
+    breakpad_thread_state_data_t state) {
+  switch (cpu_type_) {
+#ifdef HAS_ARM_SUPPORT
+    case CPU_TYPE_ARM:
+      return CurrentPCForStackARM(state);
+#endif
+#ifdef HAS_PPC_SUPPORT
+    case CPU_TYPE_POWERPC:
+      return CurrentPCForStackPPC(state);
+    case CPU_TYPE_POWERPC64:
+      return CurrentPCForStackPPC64(state);
+#endif
+#ifdef HAS_X86_SUPPORT
+    case CPU_TYPE_I386:
+      return CurrentPCForStackX86(state);
+    case CPU_TYPE_X86_64:
+      return CurrentPCForStackX86_64(state);
+#endif
+    default:
+      assert("Unknown CPU type!");
+      return 0;
+  }
+}
+
+#ifdef HAS_ARM_SUPPORT
+bool MinidumpGenerator::WriteStackARM(breakpad_thread_state_data_t state,
+                                      MDMemoryDescriptor *stack_location) {
+  arm_thread_state_t *machine_state =
+      reinterpret_cast<arm_thread_state_t *>(state);
+  mach_vm_address_t start_addr = REGISTER_FROM_THREADSTATE(machine_state, sp);
+  return WriteStackFromStartAddress(start_addr, stack_location);
+}
+
+u_int64_t
+MinidumpGenerator::CurrentPCForStackARM(breakpad_thread_state_data_t state) {
+  arm_thread_state_t *machine_state =
+      reinterpret_cast<arm_thread_state_t *>(state);
+
+  return REGISTER_FROM_THREADSTATE(machine_state, pc);
+}
+
+bool MinidumpGenerator::WriteContextARM(breakpad_thread_state_data_t state,
+                                        MDLocationDescriptor *register_location)
+{
+  TypedMDRVA<MDRawContextARM> context(&writer_);
+  arm_thread_state_t *machine_state =
+      reinterpret_cast<arm_thread_state_t *>(state);
+
+  if (!context.Allocate())
+    return false;
+
+  *register_location = context.location();
+  MDRawContextARM *context_ptr = context.get();
+  context_ptr->context_flags = MD_CONTEXT_ARM_FULL;
+
+#define AddGPR(a) context_ptr->iregs[a] = REGISTER_FROM_THREADSTATE(machine_state, r[a])
+
+  context_ptr->iregs[13] = REGISTER_FROM_THREADSTATE(machine_state, sp);
+  context_ptr->iregs[14] = REGISTER_FROM_THREADSTATE(machine_state, lr);
+  context_ptr->iregs[15] = REGISTER_FROM_THREADSTATE(machine_state, pc);
+  context_ptr->cpsr = REGISTER_FROM_THREADSTATE(machine_state, cpsr);
+
+  AddGPR(0);
+  AddGPR(1);
+  AddGPR(2);
+  AddGPR(3);
+  AddGPR(4);
+  AddGPR(5);
+  AddGPR(6);
+  AddGPR(7);
+  AddGPR(8);
+  AddGPR(9);
+  AddGPR(10);
+  AddGPR(11);
+  AddGPR(12);
+#undef AddReg
+#undef AddGPR
+
+  return true;
+}
+#endif
+
+#ifdef HAS_PCC_SUPPORT
+bool MinidumpGenerator::WriteStackPPC(breakpad_thread_state_data_t state,
+                                      MDMemoryDescriptor *stack_location) {
+  ppc_thread_state_t *machine_state =
+      reinterpret_cast<ppc_thread_state_t *>(state);
+  mach_vm_address_t start_addr = REGISTER_FROM_THREADSTATE(machine_state, r1);
+  return WriteStackFromStartAddress(start_addr, stack_location);
+}
+
+bool MinidumpGenerator::WriteStackPPC64(breakpad_thread_state_data_t state,
+                                        MDMemoryDescriptor *stack_location) {
+  ppc_thread_state64_t *machine_state =
+      reinterpret_cast<ppc_thread_state64_t *>(state);
+  mach_vm_address_t start_addr = REGISTER_FROM_THREADSTATE(machine_state, r1);
+  return WriteStackFromStartAddress(start_addr, stack_location);
+}
+
+u_int64_t
+MinidumpGenerator::CurrentPCForStackPPC(breakpad_thread_state_data_t state) {
+  ppc_thread_state_t *machine_state =
+      reinterpret_cast<ppc_thread_state_t *>(state);
+
+  return REGISTER_FROM_THREADSTATE(machine_state, srr0);
+}
+
+u_int64_t
+MinidumpGenerator::CurrentPCForStackPPC64(breakpad_thread_state_data_t state) {
+  ppc_thread_state64_t *machine_state =
+      reinterpret_cast<ppc_thread_state64_t *>(state);
+
+  return REGISTER_FROM_THREADSTATE(machine_state, srr0);
+}
+
+bool MinidumpGenerator::WriteContextPPC(breakpad_thread_state_data_t state,
+                                        MDLocationDescriptor *register_location)
+{
+  TypedMDRVA<MDRawContextPPC> context(&writer_);
+  ppc_thread_state_t *machine_state =
+      reinterpret_cast<ppc_thread_state_t *>(state);
+
+  if (!context.Allocate())
+    return false;
+
+  *register_location = context.location();
+  MDRawContextPPC *context_ptr = context.get();
+  context_ptr->context_flags = MD_CONTEXT_PPC_BASE;
+
+#define AddReg(a) context_ptr->a = REGISTER_FROM_THREADSTATE(machine_state, a)
+#define AddGPR(a) context_ptr->gpr[a] = REGISTER_FROM_THREADSTATE(machine_state, r ## a)
+
+  AddReg(srr0);
+  AddReg(cr);
+  AddReg(xer);
+  AddReg(ctr);
+  AddReg(lr);
+  AddReg(vrsave);
+
+  AddGPR(0);
+  AddGPR(1);
+  AddGPR(2);
+  AddGPR(3);
+  AddGPR(4);
+  AddGPR(5);
+  AddGPR(6);
+  AddGPR(7);
+  AddGPR(8);
+  AddGPR(9);
+  AddGPR(10);
+  AddGPR(11);
+  AddGPR(12);
+  AddGPR(13);
+  AddGPR(14);
+  AddGPR(15);
+  AddGPR(16);
+  AddGPR(17);
+  AddGPR(18);
+  AddGPR(19);
+  AddGPR(20);
+  AddGPR(21);
+  AddGPR(22);
+  AddGPR(23);
+  AddGPR(24);
+  AddGPR(25);
+  AddGPR(26);
+  AddGPR(27);
+  AddGPR(28);
+  AddGPR(29);
+  AddGPR(30);
+  AddGPR(31);
+  AddReg(mq);
+#undef AddReg
+#undef AddGPR
+
+  return true;
+}
+
+bool MinidumpGenerator::WriteContextPPC64(
+    breakpad_thread_state_data_t state,
+    MDLocationDescriptor *register_location) {
+  TypedMDRVA<MDRawContextPPC64> context(&writer_);
+  ppc_thread_state64_t *machine_state =
+      reinterpret_cast<ppc_thread_state64_t *>(state);
+
+  if (!context.Allocate())
+    return false;
+
+  *register_location = context.location();
+  MDRawContextPPC64 *context_ptr = context.get();
+  context_ptr->context_flags = MD_CONTEXT_PPC_BASE;
+
+#define AddReg(a) context_ptr->a = REGISTER_FROM_THREADSTATE(machine_state, a)
+#define AddGPR(a) context_ptr->gpr[a] = REGISTER_FROM_THREADSTATE(machine_state, r ## a)
+
+  AddReg(srr0);
+  AddReg(cr);
+  AddReg(xer);
+  AddReg(ctr);
+  AddReg(lr);
+  AddReg(vrsave);
+
+  AddGPR(0);
+  AddGPR(1);
+  AddGPR(2);
+  AddGPR(3);
+  AddGPR(4);
+  AddGPR(5);
+  AddGPR(6);
+  AddGPR(7);
+  AddGPR(8);
+  AddGPR(9);
+  AddGPR(10);
+  AddGPR(11);
+  AddGPR(12);
+  AddGPR(13);
+  AddGPR(14);
+  AddGPR(15);
+  AddGPR(16);
+  AddGPR(17);
+  AddGPR(18);
+  AddGPR(19);
+  AddGPR(20);
+  AddGPR(21);
+  AddGPR(22);
+  AddGPR(23);
+  AddGPR(24);
+  AddGPR(25);
+  AddGPR(26);
+  AddGPR(27);
+  AddGPR(28);
+  AddGPR(29);
+  AddGPR(30);
+  AddGPR(31);
+#undef AddReg
+#undef AddGPR
+
+  return true;
+}
+
+#endif
+
+#ifdef HAS_X86_SUPPORT
+bool MinidumpGenerator::WriteStackX86(breakpad_thread_state_data_t state,
+                                   MDMemoryDescriptor *stack_location) {
+  i386_thread_state_t *machine_state =
+      reinterpret_cast<i386_thread_state_t *>(state);
+
+  mach_vm_address_t start_addr = REGISTER_FROM_THREADSTATE(machine_state, esp);
+  return WriteStackFromStartAddress(start_addr, stack_location);
+}
+
+bool MinidumpGenerator::WriteStackX86_64(breakpad_thread_state_data_t state,
+                                         MDMemoryDescriptor *stack_location) {
+  x86_thread_state64_t *machine_state =
+      reinterpret_cast<x86_thread_state64_t *>(state);
+
+  mach_vm_address_t start_addr = REGISTER_FROM_THREADSTATE(machine_state, rsp);
+  return WriteStackFromStartAddress(start_addr, stack_location);
+}
+
+u_int64_t
+MinidumpGenerator::CurrentPCForStackX86(breakpad_thread_state_data_t state) {
+  i386_thread_state_t *machine_state =
+      reinterpret_cast<i386_thread_state_t *>(state);
+
+  return REGISTER_FROM_THREADSTATE(machine_state, eip);
+}
+
+u_int64_t
+MinidumpGenerator::CurrentPCForStackX86_64(breakpad_thread_state_data_t state) {
+  x86_thread_state64_t *machine_state =
+      reinterpret_cast<x86_thread_state64_t *>(state);
+
+  return REGISTER_FROM_THREADSTATE(machine_state, rip);
+}
+
+bool MinidumpGenerator::WriteContextX86(breakpad_thread_state_data_t state,
+                                        MDLocationDescriptor *register_location)
+{
+  TypedMDRVA<MDRawContextX86> context(&writer_);
+  i386_thread_state_t *machine_state =
+      reinterpret_cast<i386_thread_state_t *>(state);
+
+  if (!context.Allocate())
+    return false;
+
+  *register_location = context.location();
+  MDRawContextX86 *context_ptr = context.get();
+
+#define AddReg(a) context_ptr->a = REGISTER_FROM_THREADSTATE(machine_state, a)
+
+  context_ptr->context_flags = MD_CONTEXT_X86;
+  AddReg(eax);
+  AddReg(ebx);
+  AddReg(ecx);
+  AddReg(edx);
+  AddReg(esi);
+  AddReg(edi);
+  AddReg(ebp);
+  AddReg(esp);
+
+  AddReg(cs);
+  AddReg(ds);
+  AddReg(ss);
+  AddReg(es);
+  AddReg(fs);
+  AddReg(gs);
+  AddReg(eflags);
+
+  AddReg(eip);
+#undef AddReg
+
+  return true;
+}
+
+bool MinidumpGenerator::WriteContextX86_64(
+    breakpad_thread_state_data_t state,
+    MDLocationDescriptor *register_location) {
+  TypedMDRVA<MDRawContextAMD64> context(&writer_);
+  x86_thread_state64_t *machine_state =
+      reinterpret_cast<x86_thread_state64_t *>(state);
+
+  if (!context.Allocate())
+    return false;
+
+  *register_location = context.location();
+  MDRawContextAMD64 *context_ptr = context.get();
+
+#define AddReg(a) context_ptr->a = REGISTER_FROM_THREADSTATE(machine_state, a)
+
+  context_ptr->context_flags = MD_CONTEXT_AMD64;
+  AddReg(rax);
+  AddReg(rbx);
+  AddReg(rcx);
+  AddReg(rdx);
+  AddReg(rdi);
+  AddReg(rsi);
+  AddReg(rbp);
+  AddReg(rsp);
+  AddReg(r8);
+  AddReg(r9);
+  AddReg(r10);
+  AddReg(r11);
+  AddReg(r12);
+  AddReg(r13);
+  AddReg(r14);
+  AddReg(r15);
+  AddReg(rip);
+  // according to AMD's software developer guide, bits above 18 are
+  // not used in the flags register.  Since the minidump format
+  // specifies 32 bits for the flags register, we can truncate safely
+  // with no loss.
+  context_ptr->eflags = static_cast<u_int32_t>(REGISTER_FROM_THREADSTATE(machine_state, rflags));
+  AddReg(cs);
+  AddReg(fs);
+  AddReg(gs);
+#undef AddReg
+
+  return true;
+}
+#endif
+
+bool MinidumpGenerator::GetThreadState(thread_act_t target_thread,
+                                       thread_state_t state,
+                                       mach_msg_type_number_t *count) {
+  thread_state_flavor_t flavor;
+  switch (cpu_type_) {
+#ifdef HAS_ARM_SUPPORT
+    case CPU_TYPE_ARM:
+      flavor = ARM_THREAD_STATE;
+      break;
+#endif
+#ifdef HAS_PPC_SUPPORT
+    case CPU_TYPE_POWERPC:
+      flavor = PPC_THREAD_STATE;
+      break;
+    case CPU_TYPE_POWERPC64:
+      flavor = PPC_THREAD_STATE64;
+      break;
+#endif
+#ifdef HAS_X86_SUPPORT
+    case CPU_TYPE_I386:
+      flavor = i386_THREAD_STATE;
+      break;
+    case CPU_TYPE_X86_64:
+      flavor = x86_THREAD_STATE64;
+      break;
+#endif
+    default:
+      return false;
+  }
+  return thread_get_state(target_thread, flavor,
+                          state, count) == KERN_SUCCESS;
+}
+
+bool MinidumpGenerator::WriteThreadStream(mach_port_t thread_id,
+                                          MDRawThread *thread) {
+  breakpad_thread_state_data_t state;
+  mach_msg_type_number_t state_count
+      = static_cast<mach_msg_type_number_t>(sizeof(state));
+
+  if (GetThreadState(thread_id, state, &state_count)) {
+    if (!WriteStack(state, &thread->stack))
+      return false;
+
+    memory_blocks_.push_back(thread->stack);
+
+    if (!WriteContext(state, &thread->thread_context))
+      return false;
+
+    thread->thread_id = thread_id;
+  } else {
+    return false;
+  }
+
+  return true;
+}
+
+bool MinidumpGenerator::WriteThreadListStream(
+    MDRawDirectory *thread_list_stream) {
+  TypedMDRVA<MDRawThreadList> list(&writer_);
+  thread_act_port_array_t threads_for_task;
+  mach_msg_type_number_t thread_count;
+  int non_generator_thread_count;
+
+  if (task_threads(crashing_task_, &threads_for_task, &thread_count))
+    return false;
+
+  // Don't include the generator thread
+  if (handler_thread_ != MACH_PORT_NULL)
+    non_generator_thread_count = thread_count - 1;
+  else
+    non_generator_thread_count = thread_count;
+  if (!list.AllocateObjectAndArray(non_generator_thread_count,
+                                   sizeof(MDRawThread)))
+    return false;
+
+  thread_list_stream->stream_type = MD_THREAD_LIST_STREAM;
+  thread_list_stream->location = list.location();
+
+  list.get()->number_of_threads = non_generator_thread_count;
+
+  MDRawThread thread;
+  int thread_idx = 0;
+
+  for (unsigned int i = 0; i < thread_count; ++i) {
+    memset(&thread, 0, sizeof(MDRawThread));
+
+    if (threads_for_task[i] != handler_thread_) {
+      if (!WriteThreadStream(threads_for_task[i], &thread))
+        return false;
+
+      list.CopyIndexAfterObject(thread_idx++, &thread, sizeof(MDRawThread));
+    }
+  }
+
+  return true;
+}
+
+bool MinidumpGenerator::WriteMemoryListStream(
+    MDRawDirectory *memory_list_stream) {
+  TypedMDRVA<MDRawMemoryList> list(&writer_);
+
+  // If the dump has an exception, include some memory around the
+  // instruction pointer.
+  const size_t kIPMemorySize = 256;  // bytes
+  bool have_ip_memory = false;
+  MDMemoryDescriptor ip_memory_d;
+  if (exception_thread_ && exception_type_) {
+    breakpad_thread_state_data_t state;
+    mach_msg_type_number_t stateCount
+      = static_cast<mach_msg_type_number_t>(sizeof(state));
+
+    if (thread_get_state(exception_thread_,
+                         BREAKPAD_MACHINE_THREAD_STATE,
+                         state,
+                         &stateCount) == KERN_SUCCESS) {
+      u_int64_t ip = CurrentPCForStack(state);
+      // Bound it to the upper and lower bounds of the region
+      // it's contained within. If it's not in a known memory region,
+      // don't bother trying to write it.
+      mach_vm_address_t addr = ip;
+      mach_vm_size_t size;
+      natural_t nesting_level = 0;
+      vm_region_submap_info_64 info;
+      mach_msg_type_number_t info_count = VM_REGION_SUBMAP_INFO_COUNT_64;
+
+      kern_return_t ret =
+        mach_vm_region_recurse(crashing_task_,
+                               &addr,
+                               &size,
+                               &nesting_level,
+                               (vm_region_recurse_info_t)&info,
+                               &info_count);
+      if (ret == KERN_SUCCESS && ip >= addr && ip < (addr + size)) {
+        // Try to get 128 bytes before and after the IP, but
+        // settle for whatever's available.
+        ip_memory_d.start_of_memory_range =
+          std::max(uintptr_t(addr),
+                   uintptr_t(ip - (kIPMemorySize / 2)));
+        uintptr_t end_of_range = 
+          std::min(uintptr_t(ip + (kIPMemorySize / 2)),
+                   uintptr_t(addr + size));
+        ip_memory_d.memory.data_size =
+          end_of_range - ip_memory_d.start_of_memory_range;
+        have_ip_memory = true;
+        // This needs to get appended to the list even though
+        // the memory bytes aren't filled in yet so the entire
+        // list can be written first. The memory bytes will get filled
+        // in after the memory list is written.
+        memory_blocks_.push_back(ip_memory_d);
+      }
+    }
+  }
+
+  // Now fill in the memory list and write it.
+  unsigned memory_count = memory_blocks_.size();
+  if (!list.AllocateObjectAndArray(memory_count,
+                                   sizeof(MDMemoryDescriptor)))
+    return false;
+
+  memory_list_stream->stream_type = MD_MEMORY_LIST_STREAM;
+  memory_list_stream->location = list.location();
+
+  list.get()->number_of_memory_ranges = memory_count;
+
+  unsigned int i;
+  for (i = 0; i < memory_count; ++i) {
+    list.CopyIndexAfterObject(i, &memory_blocks_[i],
+                              sizeof(MDMemoryDescriptor));
+  }
+
+  if (have_ip_memory) {
+    // Now read the memory around the instruction pointer.
+    UntypedMDRVA ip_memory(&writer_);
+    if (!ip_memory.Allocate(ip_memory_d.memory.data_size))
+      return false;
+
+    if (dynamic_images_) {
+      // Out-of-process.
+      vector<uint8_t> memory;
+      if (ReadTaskMemory(crashing_task_,
+                         ip_memory_d.start_of_memory_range,
+                         ip_memory_d.memory.data_size,
+                         memory) != KERN_SUCCESS) {
+        return false;
+      }
+
+      ip_memory.Copy(&memory[0], ip_memory_d.memory.data_size);
+    } else {
+      // In-process, just copy from local memory.
+      ip_memory.Copy(
+        reinterpret_cast<const void *>(ip_memory_d.start_of_memory_range),
+        ip_memory_d.memory.data_size);
+    }
+
+    ip_memory_d.memory = ip_memory.location();
+    // Write this again now that the data location is filled in.
+    list.CopyIndexAfterObject(i - 1, &ip_memory_d,
+                              sizeof(MDMemoryDescriptor));
+  }
+
+  return true;
+}
+
+bool
+MinidumpGenerator::WriteExceptionStream(MDRawDirectory *exception_stream) {
+  TypedMDRVA<MDRawExceptionStream> exception(&writer_);
+
+  if (!exception.Allocate())
+    return false;
+
+  exception_stream->stream_type = MD_EXCEPTION_STREAM;
+  exception_stream->location = exception.location();
+  MDRawExceptionStream *exception_ptr = exception.get();
+  exception_ptr->thread_id = exception_thread_;
+
+  // This naming is confusing, but it is the proper translation from
+  // mach naming to minidump naming.
+  exception_ptr->exception_record.exception_code = exception_type_;
+  exception_ptr->exception_record.exception_flags = exception_code_;
+
+  breakpad_thread_state_data_t state;
+  mach_msg_type_number_t state_count
+      = static_cast<mach_msg_type_number_t>(sizeof(state));
+
+  if (!GetThreadState(exception_thread_, state, &state_count))
+    return false;
+
+  if (!WriteContext(state, &exception_ptr->thread_context))
+    return false;
+
+  if (exception_type_ == EXC_BAD_ACCESS)
+    exception_ptr->exception_record.exception_address = exception_subcode_;
+  else
+    exception_ptr->exception_record.exception_address = CurrentPCForStack(state);
+
+  return true;
+}
+
+bool MinidumpGenerator::WriteSystemInfoStream(
+    MDRawDirectory *system_info_stream) {
+  TypedMDRVA<MDRawSystemInfo> info(&writer_);
+
+  if (!info.Allocate())
+    return false;
+
+  system_info_stream->stream_type = MD_SYSTEM_INFO_STREAM;
+  system_info_stream->location = info.location();
+
+  // CPU Information
+  uint32_t number_of_processors;
+  size_t len = sizeof(number_of_processors);
+  sysctlbyname("hw.ncpu", &number_of_processors, &len, NULL, 0);
+  MDRawSystemInfo *info_ptr = info.get();
+
+  switch (cpu_type_) {
+#ifdef HAS_ARM_SUPPORT
+    case CPU_TYPE_ARM:
+      info_ptr->processor_architecture = MD_CPU_ARCHITECTURE_ARM;
+      break;
+#endif
+#ifdef HAS_PPC_SUPPORT
+    case CPU_TYPE_POWERPC:
+    case CPU_TYPE_POWERPC64:
+      info_ptr->processor_architecture = MD_CPU_ARCHITECTURE_PPC;
+      break;
+#endif
+#ifdef HAS_X86_SUPPORT
+    case CPU_TYPE_I386:
+    case CPU_TYPE_X86_64:
+      if (cpu_type_ == CPU_TYPE_I386)
+        info_ptr->processor_architecture = MD_CPU_ARCHITECTURE_X86;
+      else
+        info_ptr->processor_architecture = MD_CPU_ARCHITECTURE_AMD64;
+#ifdef __i386__
+      // ebx is used for PIC code, so we need
+      // to preserve it.
+#define cpuid(op,eax,ebx,ecx,edx)      \
+  asm ("pushl %%ebx   \n\t"            \
+       "cpuid         \n\t"            \
+       "movl %%ebx,%1 \n\t"            \
+       "popl %%ebx"                    \
+       : "=a" (eax),                   \
+         "=g" (ebx),                   \
+         "=c" (ecx),                   \
+         "=d" (edx)                    \
+       : "0" (op))
+#elif defined(__x86_64__)
+
+#define cpuid(op,eax,ebx,ecx,edx)      \
+  asm ("cpuid         \n\t"            \
+       : "=a" (eax),                   \
+         "=b" (ebx),                   \
+         "=c" (ecx),                   \
+         "=d" (edx)                    \
+       : "0" (op))
+#endif
+
+#if defined(__i386__) || defined(__x86_64__)
+      int unused, unused2;
+      // get vendor id
+      cpuid(0, unused, info_ptr->cpu.x86_cpu_info.vendor_id[0],
+            info_ptr->cpu.x86_cpu_info.vendor_id[2],
+            info_ptr->cpu.x86_cpu_info.vendor_id[1]);
+      // get version and feature info
+      cpuid(1, info_ptr->cpu.x86_cpu_info.version_information, unused, unused2,
+            info_ptr->cpu.x86_cpu_info.feature_information);
+
+      // family
+      info_ptr->processor_level =
+        (info_ptr->cpu.x86_cpu_info.version_information & 0xF00) >> 8;
+      // 0xMMSS (Model, Stepping)
+      info_ptr->processor_revision =
+        (info_ptr->cpu.x86_cpu_info.version_information & 0xF) |
+        ((info_ptr->cpu.x86_cpu_info.version_information & 0xF0) << 4);
+
+      // decode extended model info
+      if (info_ptr->processor_level == 0xF ||
+          info_ptr->processor_level == 0x6) {
+        info_ptr->processor_revision |=
+          ((info_ptr->cpu.x86_cpu_info.version_information & 0xF0000) >> 4);
+      }
+
+      // decode extended family info
+      if (info_ptr->processor_level == 0xF) {
+        info_ptr->processor_level +=
+          ((info_ptr->cpu.x86_cpu_info.version_information & 0xFF00000) >> 20);
+      }
+
+#endif  // __i386__ || __x86_64_
+      break;
+#endif  // HAS_X86_SUPPORT
+    default:
+      info_ptr->processor_architecture = MD_CPU_ARCHITECTURE_UNKNOWN;
+      break;
+  }
+
+  info_ptr->number_of_processors = number_of_processors;
+#if TARGET_OS_IPHONE
+  info_ptr->platform_id = MD_OS_IOS;
+#else
+  info_ptr->platform_id = MD_OS_MAC_OS_X;
+#endif  // TARGET_OS_IPHONE
+
+  MDLocationDescriptor build_string_loc;
+
+  if (!writer_.WriteString(build_string_, 0,
+                           &build_string_loc))
+    return false;
+
+  info_ptr->csd_version_rva = build_string_loc.rva;
+  info_ptr->major_version = os_major_version_;
+  info_ptr->minor_version = os_minor_version_;
+  info_ptr->build_number = os_build_number_;
+
+  return true;
+}
+
+bool MinidumpGenerator::WriteModuleStream(unsigned int index,
+                                          MDRawModule *module) {
+  if (dynamic_images_) {
+    // we're in a different process than the crashed process
+    DynamicImage *image = dynamic_images_->GetImage(index);
+
+    if (!image)
+      return false;
+
+    memset(module, 0, sizeof(MDRawModule));
+
+    MDLocationDescriptor string_location;
+
+    string name = image->GetFilePath();
+    if (!writer_.WriteString(name.c_str(), 0, &string_location))
+      return false;
+
+    module->base_of_image = image->GetVMAddr() + image->GetVMAddrSlide();
+    module->size_of_image = static_cast<u_int32_t>(image->GetVMSize());
+    module->module_name_rva = string_location.rva;
+
+    // We'll skip the executable module, because they don't have
+    // LC_ID_DYLIB load commands, and the crash processing server gets
+    // version information from the Plist file, anyway.
+    if (index != (uint32_t)FindExecutableModule()) {
+      module->version_info.signature = MD_VSFIXEDFILEINFO_SIGNATURE;
+      module->version_info.struct_version |= MD_VSFIXEDFILEINFO_VERSION;
+      // Convert MAC dylib version format, which is a 32 bit number, to the
+      // format used by minidump.  The mac format is <16 bits>.<8 bits>.<8 bits>
+      // so it fits nicely into the windows version with some massaging
+      // The mapping is:
+      //    1) upper 16 bits of MAC version go to lower 16 bits of product HI
+      //    2) Next most significant 8 bits go to upper 16 bits of product LO
+      //    3) Least significant 8 bits go to lower 16 bits of product LO
+      uint32_t modVersion = image->GetVersion();
+      module->version_info.file_version_hi = 0;
+      module->version_info.file_version_hi = modVersion >> 16;
+      module->version_info.file_version_lo |= (modVersion & 0xff00)  << 8;
+      module->version_info.file_version_lo |= (modVersion & 0xff);
+    }
+
+    if (!WriteCVRecord(module, image->GetCPUType(), name.c_str(), false)) {
+      return false;
+    }
+  } else {
+    // Getting module info in the crashed process
+    const breakpad_mach_header *header;
+    header = (breakpad_mach_header*)_dyld_get_image_header(index);
+    if (!header)
+      return false;
+
+#ifdef __LP64__
+    assert(header->magic == MH_MAGIC_64);
+
+    if(header->magic != MH_MAGIC_64)
+      return false;
+#else
+    assert(header->magic == MH_MAGIC);
+
+    if(header->magic != MH_MAGIC)
+      return false;
+#endif
+
+    int cpu_type = header->cputype;
+    unsigned long slide = _dyld_get_image_vmaddr_slide(index);
+    const char* name = _dyld_get_image_name(index);
+    const struct load_command *cmd =
+        reinterpret_cast<const struct load_command *>(header + 1);
+
+    memset(module, 0, sizeof(MDRawModule));
+
+    for (unsigned int i = 0; cmd && (i < header->ncmds); i++) {
+      if (cmd->cmd == LC_SEGMENT_ARCH) {
+
+        const breakpad_mach_segment_command *seg =
+            reinterpret_cast<const breakpad_mach_segment_command *>(cmd);
+
+        if (!strcmp(seg->segname, "__TEXT")) {
+          MDLocationDescriptor string_location;
+
+          if (!writer_.WriteString(name, 0, &string_location))
+            return false;
+
+          module->base_of_image = seg->vmaddr + slide;
+          module->size_of_image = static_cast<u_int32_t>(seg->vmsize);
+          module->module_name_rva = string_location.rva;
+
+          bool in_memory = false;
+#if TARGET_OS_IPHONE
+          in_memory = true;
+#endif
+          if (!WriteCVRecord(module, cpu_type, name, in_memory))
+            return false;
+
+          return true;
+        }
+      }
+
+      cmd = reinterpret_cast<struct load_command*>((char *)cmd + cmd->cmdsize);
+    }
+  }
+
+  return true;
+}
+
+int MinidumpGenerator::FindExecutableModule() {
+  if (dynamic_images_) {
+    int index = dynamic_images_->GetExecutableImageIndex();
+
+    if (index >= 0) {
+      return index;
+    }
+  } else {
+    int image_count = _dyld_image_count();
+    const struct mach_header *header;
+
+    for (int index = 0; index < image_count; ++index) {
+      header = _dyld_get_image_header(index);
+
+      if (header->filetype == MH_EXECUTE)
+        return index;
+    }
+  }
+
+  // failed - just use the first image
+  return 0;
+}
+
+bool MinidumpGenerator::WriteCVRecord(MDRawModule *module, int cpu_type,
+                                      const char *module_path, bool in_memory) {
+  TypedMDRVA<MDCVInfoPDB70> cv(&writer_);
+
+  // Only return the last path component of the full module path
+  const char *module_name = strrchr(module_path, '/');
+
+  // Increment past the slash
+  if (module_name)
+    ++module_name;
+  else
+    module_name = "<Unknown>";
+
+  size_t module_name_length = strlen(module_name);
+
+  if (!cv.AllocateObjectAndArray(module_name_length + 1, sizeof(u_int8_t)))
+    return false;
+
+  if (!cv.CopyIndexAfterObject(0, module_name, module_name_length))
+    return false;
+
+  module->cv_record = cv.location();
+  MDCVInfoPDB70 *cv_ptr = cv.get();
+  cv_ptr->cv_signature = MD_CVINFOPDB70_SIGNATURE;
+  cv_ptr->age = 0;
+
+  // Get the module identifier
+  unsigned char identifier[16];
+  bool result = false;
+  if (in_memory) {
+    MacFileUtilities::MachoID macho(module_path,
+        reinterpret_cast<void *>(module->base_of_image),
+        static_cast<size_t>(module->size_of_image));
+    result = macho.UUIDCommand(cpu_type, identifier);
+    if (!result)
+      result = macho.MD5(cpu_type, identifier);
+  }
+
+  if (!result) {
+     FileID file_id(module_path);
+     result = file_id.MachoIdentifier(cpu_type, identifier);
+  }
+
+  if (result) {
+    cv_ptr->signature.data1 = (uint32_t)identifier[0] << 24 |
+      (uint32_t)identifier[1] << 16 | (uint32_t)identifier[2] << 8 |
+      (uint32_t)identifier[3];
+    cv_ptr->signature.data2 = (uint32_t)identifier[4] << 8 | identifier[5];
+    cv_ptr->signature.data3 = (uint32_t)identifier[6] << 8 | identifier[7];
+    cv_ptr->signature.data4[0] = identifier[8];
+    cv_ptr->signature.data4[1] = identifier[9];
+    cv_ptr->signature.data4[2] = identifier[10];
+    cv_ptr->signature.data4[3] = identifier[11];
+    cv_ptr->signature.data4[4] = identifier[12];
+    cv_ptr->signature.data4[5] = identifier[13];
+    cv_ptr->signature.data4[6] = identifier[14];
+    cv_ptr->signature.data4[7] = identifier[15];
+  }
+
+  return true;
+}
+
+bool MinidumpGenerator::WriteModuleListStream(
+    MDRawDirectory *module_list_stream) {
+  TypedMDRVA<MDRawModuleList> list(&writer_);
+
+  size_t image_count = dynamic_images_ ?
+      static_cast<size_t>(dynamic_images_->GetImageCount()) :
+      _dyld_image_count();
+
+  if (!list.AllocateObjectAndArray(image_count, MD_MODULE_SIZE))
+    return false;
+
+  module_list_stream->stream_type = MD_MODULE_LIST_STREAM;
+  module_list_stream->location = list.location();
+  list.get()->number_of_modules = image_count;
+
+  // Write out the executable module as the first one
+  MDRawModule module;
+  size_t executableIndex = FindExecutableModule();
+
+  if (!WriteModuleStream(executableIndex, &module)) {
+    return false;
+  }
+
+  list.CopyIndexAfterObject(0, &module, MD_MODULE_SIZE);
+  int destinationIndex = 1;  // Write all other modules after this one
+
+  for (size_t i = 0; i < image_count; ++i) {
+    if (i != executableIndex) {
+      if (!WriteModuleStream(i, &module)) {
+        return false;
+      }
+
+      list.CopyIndexAfterObject(destinationIndex++, &module, MD_MODULE_SIZE);
+    }
+  }
+
+  return true;
+}
+
+bool MinidumpGenerator::WriteMiscInfoStream(MDRawDirectory *misc_info_stream) {
+  TypedMDRVA<MDRawMiscInfo> info(&writer_);
+
+  if (!info.Allocate())
+    return false;
+
+  misc_info_stream->stream_type = MD_MISC_INFO_STREAM;
+  misc_info_stream->location = info.location();
+
+  MDRawMiscInfo *info_ptr = info.get();
+  info_ptr->size_of_info = static_cast<u_int32_t>(sizeof(MDRawMiscInfo));
+  info_ptr->flags1 = MD_MISCINFO_FLAGS1_PROCESS_ID |
+    MD_MISCINFO_FLAGS1_PROCESS_TIMES |
+    MD_MISCINFO_FLAGS1_PROCESSOR_POWER_INFO;
+
+  // Process ID
+  info_ptr->process_id = getpid();
+
+  // Times
+  struct rusage usage;
+  if (getrusage(RUSAGE_SELF, &usage) != -1) {
+    // Omit the fractional time since the MDRawMiscInfo only wants seconds
+    info_ptr->process_user_time =
+        static_cast<u_int32_t>(usage.ru_utime.tv_sec);
+    info_ptr->process_kernel_time =
+        static_cast<u_int32_t>(usage.ru_stime.tv_sec);
+  }
+  int mib[4] = { CTL_KERN, KERN_PROC, KERN_PROC_PID,
+                 static_cast<int>(info_ptr->process_id) };
+  u_int mibsize = static_cast<u_int>(sizeof(mib) / sizeof(mib[0]));
+  struct kinfo_proc proc;
+  size_t size = sizeof(proc);
+  if (sysctl(mib, mibsize, &proc, &size, NULL, 0) == 0) {
+    info_ptr->process_create_time =
+        static_cast<u_int32_t>(proc.kp_proc.p_starttime.tv_sec);
+  }
+
+  // Speed
+  uint64_t speed;
+  const uint64_t kOneMillion = 1000 * 1000;
+  size = sizeof(speed);
+  sysctlbyname("hw.cpufrequency_max", &speed, &size, NULL, 0);
+  info_ptr->processor_max_mhz = static_cast<u_int32_t>(speed / kOneMillion);
+  info_ptr->processor_mhz_limit = static_cast<u_int32_t>(speed / kOneMillion);
+  size = sizeof(speed);
+  sysctlbyname("hw.cpufrequency", &speed, &size, NULL, 0);
+  info_ptr->processor_current_mhz = static_cast<u_int32_t>(speed / kOneMillion);
+
+  return true;
+}
+
+bool MinidumpGenerator::WriteBreakpadInfoStream(
+    MDRawDirectory *breakpad_info_stream) {
+  TypedMDRVA<MDRawBreakpadInfo> info(&writer_);
+
+  if (!info.Allocate())
+    return false;
+
+  breakpad_info_stream->stream_type = MD_BREAKPAD_INFO_STREAM;
+  breakpad_info_stream->location = info.location();
+  MDRawBreakpadInfo *info_ptr = info.get();
+
+  if (exception_thread_ && exception_type_) {
+    info_ptr->validity = MD_BREAKPAD_INFO_VALID_DUMP_THREAD_ID |
+                         MD_BREAKPAD_INFO_VALID_REQUESTING_THREAD_ID;
+    info_ptr->dump_thread_id = handler_thread_;
+    info_ptr->requesting_thread_id = exception_thread_;
+  } else {
+    info_ptr->validity = MD_BREAKPAD_INFO_VALID_DUMP_THREAD_ID;
+    info_ptr->dump_thread_id = handler_thread_;
+    info_ptr->requesting_thread_id = 0;
+  }
+
+  return true;
+}
+
+}  // namespace google_breakpad
diff --git a/3rdParty/Breakpad/src/client/mac/handler/minidump_generator.h b/3rdParty/Breakpad/src/client/mac/handler/minidump_generator.h
new file mode 100644
index 0000000..8394ce6
--- /dev/null
+++ b/3rdParty/Breakpad/src/client/mac/handler/minidump_generator.h
@@ -0,0 +1,218 @@
+// 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_generator.h:  Create a minidump of the current MacOS process.
+
+#ifndef CLIENT_MAC_GENERATOR_MINIDUMP_GENERATOR_H__
+#define CLIENT_MAC_GENERATOR_MINIDUMP_GENERATOR_H__
+
+#include <mach/mach.h>
+#include <TargetConditionals.h>
+
+#include <string>
+
+#include "client/minidump_file_writer.h"
+#include "common/memory.h"
+#include "common/mac/macho_utilities.h"
+#include "google_breakpad/common/minidump_format.h"
+
+#include "dynamic_images.h"
+#include "mach_vm_compat.h"
+
+#if !TARGET_OS_IPHONE && (MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_7)
+  #define HAS_PPC_SUPPORT
+#endif
+#if defined(__arm__)
+  #define HAS_ARM_SUPPORT
+#elif defined(__i386__) || defined(__x86_64__)
+  #define HAS_X86_SUPPORT
+#endif
+
+namespace google_breakpad {
+
+using std::string;
+
+// Use the REGISTER_FROM_THREADSTATE to access a register name from the
+// breakpad_thread_state_t structure.
+#if __DARWIN_UNIX03 || TARGET_CPU_X86_64 || TARGET_CPU_PPC64 || TARGET_CPU_ARM
+// In The 10.5 SDK Headers Apple prepended __ to the variable names in the
+// i386_thread_state_t structure.  There's no good way to tell what version of
+// the SDK we're compiling against so we just toggle on the same preprocessor
+// symbol Apple's headers use.
+#define REGISTER_FROM_THREADSTATE(a, b) ((a)->__ ## b)
+#else
+#define REGISTER_FROM_THREADSTATE(a, b) (a->b)
+#endif
+
+// Creates a minidump file of the current process.  If there is exception data,
+// use SetExceptionInformation() to add this to the minidump.  The minidump
+// file is generated by the Write() function.
+// Usage:
+// MinidumpGenerator minidump();
+// minidump.Write("/tmp/minidump");
+//
+class MinidumpGenerator {
+ public:
+  MinidumpGenerator();
+  MinidumpGenerator(mach_port_t crashing_task, mach_port_t handler_thread);
+
+  virtual ~MinidumpGenerator();
+
+  // Return <dir>/<unique_name>.dmp
+  // Sets |unique_name| (if requested) to the unique name for the minidump
+  static string UniqueNameInDirectory(const string &dir, string *unique_name);
+
+  // Write out the minidump into |path|
+  // All of the components of |path| must exist and be writable
+  // Return true if successful, false otherwise
+  bool Write(const char *path);
+
+  // Specify some exception information, if applicable
+  void SetExceptionInformation(int type, int code, int subcode,
+                               mach_port_t thread_name) {
+    exception_type_ = type;
+    exception_code_ = code;
+    exception_subcode_ = subcode;
+    exception_thread_ = thread_name;
+  }
+
+  // Gather system information.  This should be call at least once before using
+  // the MinidumpGenerator class.
+  static void GatherSystemInformation();
+
+ protected:
+  // Overridable Stream writers
+  virtual bool WriteExceptionStream(MDRawDirectory *exception_stream);
+
+  // Overridable Helper
+  virtual bool WriteThreadStream(mach_port_t thread_id, MDRawThread *thread);
+
+ private:
+  typedef bool (MinidumpGenerator::*WriteStreamFN)(MDRawDirectory *);
+
+  // Stream writers
+  bool WriteThreadListStream(MDRawDirectory *thread_list_stream);
+  bool WriteMemoryListStream(MDRawDirectory *memory_list_stream);
+  bool WriteSystemInfoStream(MDRawDirectory *system_info_stream);
+  bool WriteModuleListStream(MDRawDirectory *module_list_stream);
+  bool WriteMiscInfoStream(MDRawDirectory *misc_info_stream);
+  bool WriteBreakpadInfoStream(MDRawDirectory *breakpad_info_stream);
+
+  // Helpers
+  u_int64_t CurrentPCForStack(breakpad_thread_state_data_t state);
+  bool GetThreadState(thread_act_t target_thread, thread_state_t state,
+                      mach_msg_type_number_t *count);
+  bool WriteStackFromStartAddress(mach_vm_address_t start_addr,
+                                  MDMemoryDescriptor *stack_location);
+  bool WriteStack(breakpad_thread_state_data_t state,
+                  MDMemoryDescriptor *stack_location);
+  bool WriteContext(breakpad_thread_state_data_t state,
+                    MDLocationDescriptor *register_location);
+  bool WriteCVRecord(MDRawModule *module, int cpu_type,
+                     const char *module_path, bool in_memory);
+  bool WriteModuleStream(unsigned int index, MDRawModule *module);
+  size_t CalculateStackSize(mach_vm_address_t start_addr);
+  int  FindExecutableModule();
+
+  // Per-CPU implementations of these methods
+#ifdef HAS_ARM_SUPPORT
+  bool WriteStackARM(breakpad_thread_state_data_t state,
+                     MDMemoryDescriptor *stack_location);
+  bool WriteContextARM(breakpad_thread_state_data_t state,
+                       MDLocationDescriptor *register_location);
+  u_int64_t CurrentPCForStackARM(breakpad_thread_state_data_t state);
+#endif
+#ifdef HAS_PPC_SUPPORT
+  bool WriteStackPPC(breakpad_thread_state_data_t state,
+                     MDMemoryDescriptor *stack_location);
+  bool WriteContextPPC(breakpad_thread_state_data_t state,
+                       MDLocationDescriptor *register_location);
+  u_int64_t CurrentPCForStackPPC(breakpad_thread_state_data_t state);
+  bool WriteStackPPC64(breakpad_thread_state_data_t state,
+                       MDMemoryDescriptor *stack_location);
+  bool WriteContextPPC64(breakpad_thread_state_data_t state,
+                       MDLocationDescriptor *register_location);
+  u_int64_t CurrentPCForStackPPC64(breakpad_thread_state_data_t state);
+#endif
+#ifdef HAS_X86_SUPPORT
+  bool WriteStackX86(breakpad_thread_state_data_t state,
+                       MDMemoryDescriptor *stack_location);
+  bool WriteContextX86(breakpad_thread_state_data_t state,
+                       MDLocationDescriptor *register_location);
+  u_int64_t CurrentPCForStackX86(breakpad_thread_state_data_t state);
+  bool WriteStackX86_64(breakpad_thread_state_data_t state,
+                        MDMemoryDescriptor *stack_location);
+  bool WriteContextX86_64(breakpad_thread_state_data_t state,
+                          MDLocationDescriptor *register_location);
+  u_int64_t CurrentPCForStackX86_64(breakpad_thread_state_data_t state);
+#endif
+
+  // disallow copy ctor and operator=
+  explicit MinidumpGenerator(const MinidumpGenerator &);
+  void operator=(const MinidumpGenerator &);
+
+ protected:
+  // Use this writer to put the data to disk
+  MinidumpFileWriter writer_;
+
+ private:
+  // Exception information
+  int exception_type_;
+  int exception_code_;
+  int exception_subcode_;
+  mach_port_t exception_thread_;
+  mach_port_t crashing_task_;
+  mach_port_t handler_thread_;
+
+  // CPU type of the task being dumped.
+  cpu_type_t cpu_type_;
+  
+  // System information
+  static char build_string_[16];
+  static int os_major_version_;
+  static int os_minor_version_;
+  static int os_build_number_;
+  
+  // Information about dynamically loaded code
+  DynamicImages *dynamic_images_;
+
+  // PageAllocator makes it possible to allocate memory
+  // directly from the system, even while handling an exception.
+  mutable PageAllocator allocator_;
+
+ protected:
+  // Blocks of memory written to the dump. These are all currently
+  // written while writing the thread list stream, but saved here
+  // so a memory list stream can be written afterwards.
+  wasteful_vector<MDMemoryDescriptor> memory_blocks_;
+};
+
+}  // namespace google_breakpad
+
+#endif  // CLIENT_MAC_GENERATOR_MINIDUMP_GENERATOR_H__
diff --git a/3rdParty/Breakpad/src/client/minidump_file_writer-inl.h b/3rdParty/Breakpad/src/client/minidump_file_writer-inl.h
new file mode 100644
index 0000000..0e12e00
--- /dev/null
+++ b/3rdParty/Breakpad/src/client/minidump_file_writer-inl.h
@@ -0,0 +1,97 @@
+// 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_file_writer-inl.h: Minidump file writer implementation.
+//
+// See minidump_file_writer.h for documentation.
+
+#ifndef CLIENT_MINIDUMP_FILE_WRITER_INL_H__
+#define CLIENT_MINIDUMP_FILE_WRITER_INL_H__
+
+#include <assert.h>
+
+#include "client/minidump_file_writer.h"
+#include "google_breakpad/common/minidump_size.h"
+
+namespace google_breakpad {
+
+template<typename MDType>
+inline bool TypedMDRVA<MDType>::Allocate() {
+  allocation_state_ = SINGLE_OBJECT;
+  return UntypedMDRVA::Allocate(minidump_size<MDType>::size());
+}
+
+template<typename MDType>
+inline bool TypedMDRVA<MDType>::Allocate(size_t additional) {
+  allocation_state_ = SINGLE_OBJECT;
+  return UntypedMDRVA::Allocate(minidump_size<MDType>::size() + additional);
+}
+
+template<typename MDType>
+inline bool TypedMDRVA<MDType>::AllocateArray(size_t count) {
+  assert(count);
+  allocation_state_ = ARRAY;
+  return UntypedMDRVA::Allocate(minidump_size<MDType>::size() * count);
+}
+
+template<typename MDType>
+inline bool TypedMDRVA<MDType>::AllocateObjectAndArray(size_t count,
+                                                       size_t length) {
+  assert(count && length);
+  allocation_state_ = SINGLE_OBJECT_WITH_ARRAY;
+  return UntypedMDRVA::Allocate(minidump_size<MDType>::size() + count * length);
+}
+
+template<typename MDType>
+inline bool TypedMDRVA<MDType>::CopyIndex(unsigned int index, MDType *item) {
+  assert(allocation_state_ == ARRAY);
+  return writer_->Copy(
+      static_cast<MDRVA>(position_ + index * minidump_size<MDType>::size()), 
+      item, minidump_size<MDType>::size());
+}
+
+template<typename MDType>
+inline bool TypedMDRVA<MDType>::CopyIndexAfterObject(unsigned int index,
+                                                     const void *src, 
+                                                     size_t length) {
+  assert(allocation_state_ == SINGLE_OBJECT_WITH_ARRAY);
+  return writer_->Copy(
+      static_cast<MDRVA>(position_ + minidump_size<MDType>::size() 
+                         + index * length),
+      src, length);
+}
+
+template<typename MDType>
+inline bool TypedMDRVA<MDType>::Flush() {
+  return writer_->Copy(position_, &data_, minidump_size<MDType>::size());
+}
+
+}  // namespace google_breakpad
+
+#endif  // CLIENT_MINIDUMP_FILE_WRITER_INL_H__
diff --git a/3rdParty/Breakpad/src/client/minidump_file_writer.cc b/3rdParty/Breakpad/src/client/minidump_file_writer.cc
new file mode 100644
index 0000000..c267410
--- /dev/null
+++ b/3rdParty/Breakpad/src/client/minidump_file_writer.cc
@@ -0,0 +1,284 @@
+// 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_file_writer.cc: Minidump file writer implementation.
+//
+// See minidump_file_writer.h for documentation.
+
+#include <fcntl.h>
+#include <limits.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "client/minidump_file_writer-inl.h"
+#include "common/linux/linux_libc_support.h"
+#include "common/string_conversion.h"
+#if __linux__
+#include "third_party/lss/linux_syscall_support.h"
+#endif
+
+namespace google_breakpad {
+
+const MDRVA MinidumpFileWriter::kInvalidMDRVA = static_cast<MDRVA>(-1);
+
+MinidumpFileWriter::MinidumpFileWriter()
+    : file_(-1),
+      close_file_when_destroyed_(true),
+      position_(0),
+      size_(0) {
+}
+
+MinidumpFileWriter::~MinidumpFileWriter() {
+  if (close_file_when_destroyed_)
+    Close();
+}
+
+bool MinidumpFileWriter::Open(const char *path) {
+  assert(file_ == -1);
+#if __linux__
+  file_ = sys_open(path, O_WRONLY | O_CREAT | O_EXCL, 0600);
+#else
+  file_ = open(path, O_WRONLY | O_CREAT | O_EXCL, 0600);
+#endif
+
+  return file_ != -1;
+}
+
+void MinidumpFileWriter::SetFile(const int file) {
+  assert(file_ == -1);
+  file_ = file;
+  close_file_when_destroyed_ = false;
+}
+
+bool MinidumpFileWriter::Close() {
+  bool result = true;
+
+  if (file_ != -1) {
+    if (-1 == ftruncate(file_, position_)) {
+       return false;
+    }
+#if __linux__
+    result = (sys_close(file_) == 0);
+#else
+    result = (close(file_) == 0);
+#endif
+    file_ = -1;
+  }
+
+  return result;
+}
+
+bool MinidumpFileWriter::CopyStringToMDString(const wchar_t *str,
+                                              unsigned int length,
+                                              TypedMDRVA<MDString> *mdstring) {
+  bool result = true;
+  if (sizeof(wchar_t) == sizeof(u_int16_t)) {
+    // Shortcut if wchar_t is the same size as MDString's buffer
+    result = mdstring->Copy(str, mdstring->get()->length);
+  } else {
+    u_int16_t out[2];
+    int out_idx = 0;
+
+    // Copy the string character by character
+    while (length && result) {
+      UTF32ToUTF16Char(*str, out);
+      if (!out[0])
+        return false;
+
+      // Process one character at a time
+      --length;
+      ++str;
+
+      // Append the one or two UTF-16 characters.  The first one will be non-
+      // zero, but the second one may be zero, depending on the conversion from
+      // UTF-32.
+      int out_count = out[1] ? 2 : 1;
+      size_t out_size = sizeof(u_int16_t) * out_count;
+      result = mdstring->CopyIndexAfterObject(out_idx, out, out_size);
+      out_idx += out_count;
+    }
+  }
+  return result;
+}
+
+bool MinidumpFileWriter::CopyStringToMDString(const char *str,
+                                              unsigned int length,
+                                              TypedMDRVA<MDString> *mdstring) {
+  bool result = true;
+  u_int16_t out[2];
+  int out_idx = 0;
+
+  // Copy the string character by character
+  while (length && result) {
+    int conversion_count = UTF8ToUTF16Char(str, length, out);
+    if (!conversion_count)
+      return false;
+
+    // Move the pointer along based on the nubmer of converted characters
+    length -= conversion_count;
+    str += conversion_count;
+
+    // Append the one or two UTF-16 characters
+    int out_count = out[1] ? 2 : 1;
+    size_t out_size = sizeof(u_int16_t) * out_count;
+    result = mdstring->CopyIndexAfterObject(out_idx, out, out_size);
+    out_idx += out_count;
+  }
+  return result;
+}
+
+template <typename CharType>
+bool MinidumpFileWriter::WriteStringCore(const CharType *str,
+                                         unsigned int length,
+                                         MDLocationDescriptor *location) {
+  assert(str);
+  assert(location);
+  // Calculate the mdstring length by either limiting to |length| as passed in
+  // or by finding the location of the NULL character.
+  unsigned int mdstring_length = 0;
+  if (!length)
+    length = INT_MAX;
+  for (; mdstring_length < length && str[mdstring_length]; ++mdstring_length)
+    ;
+
+  // Allocate the string buffer
+  TypedMDRVA<MDString> mdstring(this);
+  if (!mdstring.AllocateObjectAndArray(mdstring_length + 1, sizeof(u_int16_t)))
+    return false;
+
+  // Set length excluding the NULL and copy the string
+  mdstring.get()->length =
+      static_cast<u_int32_t>(mdstring_length * sizeof(u_int16_t));
+  bool result = CopyStringToMDString(str, mdstring_length, &mdstring);
+
+  // NULL terminate
+  if (result) {
+    u_int16_t ch = 0;
+    result = mdstring.CopyIndexAfterObject(mdstring_length, &ch, sizeof(ch));
+
+    if (result)
+      *location = mdstring.location();
+  }
+
+  return result;
+}
+
+bool MinidumpFileWriter::WriteString(const wchar_t *str, unsigned int length,
+                 MDLocationDescriptor *location) {
+  return WriteStringCore(str, length, location);
+}
+
+bool MinidumpFileWriter::WriteString(const char *str, unsigned int length,
+                 MDLocationDescriptor *location) {
+  return WriteStringCore(str, length, location);
+}
+
+bool MinidumpFileWriter::WriteMemory(const void *src, size_t size,
+                                     MDMemoryDescriptor *output) {
+  assert(src);
+  assert(output);
+  UntypedMDRVA mem(this);
+
+  if (!mem.Allocate(size))
+    return false;
+  if (!mem.Copy(src, mem.size()))
+    return false;
+
+  output->start_of_memory_range = reinterpret_cast<u_int64_t>(src);
+  output->memory = mem.location();
+
+  return true;
+}
+
+MDRVA MinidumpFileWriter::Allocate(size_t size) {
+  assert(size);
+  assert(file_ != -1);
+  size_t aligned_size = (size + 7) & ~7;  // 64-bit alignment
+
+  if (position_ + aligned_size > size_) {
+    size_t growth = aligned_size;
+    size_t minimal_growth = getpagesize();
+
+    // Ensure that the file grows by at least the size of a memory page
+    if (growth < minimal_growth)
+      growth = minimal_growth;
+
+    size_t new_size = size_ + growth;
+    if (ftruncate(file_, new_size) != 0)
+      return kInvalidMDRVA;
+
+    size_ = new_size;
+  }
+
+  MDRVA current_position = position_;
+  position_ += static_cast<MDRVA>(aligned_size);
+
+  return current_position;
+}
+
+bool MinidumpFileWriter::Copy(MDRVA position, const void *src, ssize_t size) {
+  assert(src);
+  assert(size);
+  assert(file_ != -1);
+
+  // Ensure that the data will fit in the allocated space
+  if (static_cast<size_t>(size + position) > size_)
+    return false;
+
+  // Seek and write the data
+#if __linux__
+  if (sys_lseek(file_, position, SEEK_SET) == static_cast<off_t>(position)) {
+    if (sys_write(file_, src, size) == size) {
+#else
+  if (lseek(file_, position, SEEK_SET) == static_cast<off_t>(position)) {
+    if (write(file_, src, size) == size) {
+#endif
+      return true;
+    }
+  }
+
+  return false;
+}
+
+bool UntypedMDRVA::Allocate(size_t size) {
+  assert(size_ == 0);
+  size_ = size;
+  position_ = writer_->Allocate(size_);
+  return position_ != MinidumpFileWriter::kInvalidMDRVA;
+}
+
+bool UntypedMDRVA::Copy(MDRVA pos, const void *src, size_t size) {
+  assert(src);
+  assert(size);
+  assert(pos + size <= position_ + size_);
+  return writer_->Copy(pos, src, size);
+}
+
+}  // namespace google_breakpad
diff --git a/3rdParty/Breakpad/src/client/minidump_file_writer.h b/3rdParty/Breakpad/src/client/minidump_file_writer.h
new file mode 100644
index 0000000..313b250
--- /dev/null
+++ b/3rdParty/Breakpad/src/client/minidump_file_writer.h
@@ -0,0 +1,272 @@
+// 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_file_writer.h:  Implements file-based minidump generation.  It's
+// intended to be used with the Google Breakpad open source crash handling
+// project.
+
+#ifndef CLIENT_MINIDUMP_FILE_WRITER_H__
+#define CLIENT_MINIDUMP_FILE_WRITER_H__
+
+#include <string>
+
+#include "google_breakpad/common/minidump_format.h"
+
+namespace google_breakpad {
+
+class UntypedMDRVA;
+template<typename MDType> class TypedMDRVA;
+
+// The user of this class can Open() a file and add minidump streams, data, and
+// strings using the definitions in minidump_format.h.  Since this class is
+// expected to be used in a situation where the current process may be
+// damaged, it will not allocate heap memory.
+// Sample usage:
+// MinidumpFileWriter writer;
+// writer.Open("/tmp/minidump.dmp");
+// TypedMDRVA<MDRawHeader> header(&writer_);
+// header.Allocate();
+// header->get()->signature = MD_HEADER_SIGNATURE;
+//  :
+// writer.Close();
+//
+// An alternative is to use SetFile and provide a file descriptor:
+// MinidumpFileWriter writer;
+// writer.SetFile(minidump_fd);
+// TypedMDRVA<MDRawHeader> header(&writer_);
+// header.Allocate();
+// header->get()->signature = MD_HEADER_SIGNATURE;
+//  :
+// writer.Close();
+
+class MinidumpFileWriter {
+public:
+  // Invalid MDRVA (Minidump Relative Virtual Address)
+  // returned on failed allocation
+  static const MDRVA kInvalidMDRVA;
+
+  MinidumpFileWriter();
+  ~MinidumpFileWriter();
+
+  // Open |path| as the destination of the minidump data.  Any existing file
+  // will be overwritten.
+  // Return true on success, or false on failure.
+  bool Open(const char *path);
+
+  // Sets the file descriptor |file| as the destination of the minidump data.
+  // Can be used as an alternative to Open() when a file descriptor is
+  // available.
+  // Note that |fd| is not closed when the instance of MinidumpFileWriter is
+  // destroyed.
+  void SetFile(const int file);
+
+  // Close the current file (that was either created when Open was called, or
+  // specified with SetFile).
+  // Return true on success, or false on failure.
+  bool Close();
+
+  // Copy the contents of |str| to a MDString and write it to the file.
+  // |str| is expected to be either UTF-16 or UTF-32 depending on the size
+  // of wchar_t.
+  // Maximum |length| of characters to copy from |str|, or specify 0 to use the
+  // entire NULL terminated string.  Copying will stop at the first NULL.
+  // |location| the allocated location
+  // Return true on success, or false on failure
+  bool WriteString(const wchar_t *str, unsigned int length,
+                   MDLocationDescriptor *location);
+
+  // Same as above, except with |str| as a UTF-8 string
+  bool WriteString(const char *str, unsigned int length,
+                   MDLocationDescriptor *location);
+
+  // Write |size| bytes starting at |src| into the current position.
+  // Return true on success and set |output| to position, or false on failure
+  bool WriteMemory(const void *src, size_t size, MDMemoryDescriptor *output);
+
+  // Copies |size| bytes from |src| to |position|
+  // Return true on success, or false on failure
+  bool Copy(MDRVA position, const void *src, ssize_t size);
+
+  // Return the current position for writing to the minidump
+  inline MDRVA position() const { return position_; }
+
+ private:
+  friend class UntypedMDRVA;
+
+  // Allocates an area of |size| bytes.
+  // Returns the position of the allocation, or kInvalidMDRVA if it was
+  // unable to allocate the bytes.
+  MDRVA Allocate(size_t size);
+
+  // The file descriptor for the output file.
+  int file_;
+
+  // Whether |file_| should be closed when the instance is destroyed.
+  bool close_file_when_destroyed_;
+
+  // Current position in buffer
+  MDRVA position_;
+
+  // Current allocated size
+  size_t size_;
+
+  // Copy |length| characters from |str| to |mdstring|.  These are distinct
+  // because the underlying MDString is a UTF-16 based string.  The wchar_t
+  // variant may need to create a MDString that has more characters than the
+  // source |str|, whereas the UTF-8 variant may coalesce characters to form
+  // a single UTF-16 character.
+  bool CopyStringToMDString(const wchar_t *str, unsigned int length,
+                            TypedMDRVA<MDString> *mdstring);
+  bool CopyStringToMDString(const char *str, unsigned int length,
+                            TypedMDRVA<MDString> *mdstring);
+
+  // The common templated code for writing a string
+  template <typename CharType>
+  bool WriteStringCore(const CharType *str, unsigned int length,
+                       MDLocationDescriptor *location);
+};
+
+// Represents an untyped allocated chunk
+class UntypedMDRVA {
+ public:
+  explicit UntypedMDRVA(MinidumpFileWriter *writer)
+      : writer_(writer),
+        position_(writer->position()),
+        size_(0) {}
+
+  // Allocates |size| bytes.  Must not call more than once.
+  // Return true on success, or false on failure
+  bool Allocate(size_t size);
+
+  // Returns the current position or kInvalidMDRVA if allocation failed
+  inline MDRVA position() const { return position_; }
+
+  // Number of bytes allocated
+  inline size_t size() const { return size_; }
+
+  // Return size and position
+  inline MDLocationDescriptor location() const {
+    MDLocationDescriptor location = { static_cast<u_int32_t>(size_),
+                                      position_ };
+    return location;
+  }
+
+  // Copy |size| bytes starting at |src| into the minidump at |position|
+  // Return true on success, or false on failure
+  bool Copy(MDRVA position, const void *src, size_t size);
+
+  // Copy |size| bytes from |src| to the current position
+  inline bool Copy(const void *src, size_t size) {
+    return Copy(position_, src, size);
+  }
+
+ protected:
+  // Writer we associate with
+  MinidumpFileWriter *writer_;
+
+  // Position of the start of the data
+  MDRVA position_;
+
+  // Allocated size
+  size_t size_;
+};
+
+// Represents a Minidump object chunk.  Additional memory can be allocated at
+// the end of the object as a:
+// - single allocation
+// - Array of MDType objects
+// - A MDType object followed by an array
+template<typename MDType>
+class TypedMDRVA : public UntypedMDRVA {
+ public:
+  // Constructs an unallocated MDRVA
+  explicit TypedMDRVA(MinidumpFileWriter *writer)
+      : UntypedMDRVA(writer),
+        data_(),
+        allocation_state_(UNALLOCATED) {}
+
+  inline ~TypedMDRVA() {
+    // Ensure that the data_ object is written out
+    if (allocation_state_ != ARRAY)
+      Flush();
+  }
+
+  // Address of object data_ of MDType.  This is not declared const as the
+  // typical usage will be to access the underlying |data_| object as to
+  // alter its contents.
+  MDType *get() { return &data_; }
+
+  // Allocates minidump_size<MDType>::size() bytes.
+  // Must not call more than once.
+  // Return true on success, or false on failure
+  bool Allocate();
+
+  // Allocates minidump_size<MDType>::size() + |additional| bytes.
+  // Must not call more than once.
+  // Return true on success, or false on failure
+  bool Allocate(size_t additional);
+
+  // Allocate an array of |count| elements of MDType.
+  // Must not call more than once.
+  // Return true on success, or false on failure
+  bool AllocateArray(size_t count);
+
+  // Allocate an array of |count| elements of |size| after object of MDType
+  // Must not call more than once.
+  // Return true on success, or false on failure
+  bool AllocateObjectAndArray(size_t count, size_t size);
+
+  // Copy |item| to |index|
+  // Must have been allocated using AllocateArray().
+  // Return true on success, or false on failure
+  bool CopyIndex(unsigned int index, MDType *item);
+
+  // Copy |size| bytes starting at |str| to |index|
+  // Must have been allocated using AllocateObjectAndArray().
+  // Return true on success, or false on failure
+  bool CopyIndexAfterObject(unsigned int index, const void *src, size_t size);
+
+  // Write data_
+  bool Flush();
+
+ private:
+  enum AllocationState {
+    UNALLOCATED = 0,
+    SINGLE_OBJECT,
+    ARRAY,
+    SINGLE_OBJECT_WITH_ARRAY
+  };
+
+  MDType data_;
+  AllocationState allocation_state_;
+};
+
+}  // namespace google_breakpad
+
+#endif  // CLIENT_MINIDUMP_FILE_WRITER_H__
diff --git a/3rdParty/Breakpad/src/client/windows/common/ipc_protocol.h b/3rdParty/Breakpad/src/client/windows/common/ipc_protocol.h
new file mode 100644
index 0000000..b03c032
--- /dev/null
+++ b/3rdParty/Breakpad/src/client/windows/common/ipc_protocol.h
@@ -0,0 +1,181 @@
+// Copyright (c) 2008, 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.
+
+#ifndef CLIENT_WINDOWS_COMMON_IPC_PROTOCOL_H__
+#define CLIENT_WINDOWS_COMMON_IPC_PROTOCOL_H__
+
+#include <Windows.h>
+#include <DbgHelp.h>
+#include <string>
+#include <utility>
+#include "common/windows/string_utils-inl.h"
+#include "google_breakpad/common/minidump_format.h"
+
+namespace google_breakpad {
+
+// Name/value pair for custom client information.
+struct CustomInfoEntry {
+  // Maximum length for name and value for client custom info.
+  static const int kNameMaxLength = 64;
+  static const int kValueMaxLength = 64;
+
+  CustomInfoEntry() {
+    // Putting name and value in initializer list makes VC++ show warning 4351.
+    set_name(NULL);
+    set_value(NULL);
+  }
+
+  CustomInfoEntry(const wchar_t* name_arg, const wchar_t* value_arg) {
+    set_name(name_arg);
+    set_value(value_arg);
+  }
+
+  void set_name(const wchar_t* name_arg) {
+    if (!name_arg) {
+      name[0] = L'\0';
+      return;
+    }
+    WindowsStringUtils::safe_wcscpy(name, kNameMaxLength, name_arg);
+  }
+
+  void set_value(const wchar_t* value_arg) {
+    if (!value_arg) {
+      value[0] = L'\0';
+      return;
+    }
+
+    WindowsStringUtils::safe_wcscpy(value, kValueMaxLength, value_arg);
+  }
+
+  void set(const wchar_t* name_arg, const wchar_t* value_arg) {
+    set_name(name_arg);
+    set_value(value_arg);
+  }
+
+  wchar_t name[kNameMaxLength];
+  wchar_t value[kValueMaxLength];
+};
+
+// Constants for the protocol between client and the server.
+
+// Tags sent with each message indicating the purpose of
+// the message.
+enum MessageTag {
+  MESSAGE_TAG_NONE = 0,
+  MESSAGE_TAG_REGISTRATION_REQUEST = 1,
+  MESSAGE_TAG_REGISTRATION_RESPONSE = 2,
+  MESSAGE_TAG_REGISTRATION_ACK = 3,
+  MESSAGE_TAG_UPLOAD_REQUEST = 4
+};
+
+struct CustomClientInfo {
+  const CustomInfoEntry* entries;
+  size_t count;
+};
+
+// Message structure for IPC between crash client and crash server.
+struct ProtocolMessage {
+  ProtocolMessage()
+      : tag(MESSAGE_TAG_NONE),
+        id(0),
+        dump_type(MiniDumpNormal),
+        thread_id(0),
+        exception_pointers(NULL),
+        assert_info(NULL),
+        custom_client_info(),
+        dump_request_handle(NULL),
+        dump_generated_handle(NULL),
+        server_alive_handle(NULL) {
+  }
+
+  // Creates an instance with the given parameters.
+  ProtocolMessage(MessageTag arg_tag,
+                  DWORD arg_id,
+                  MINIDUMP_TYPE arg_dump_type,
+                  DWORD* arg_thread_id,
+                  EXCEPTION_POINTERS** arg_exception_pointers,
+                  MDRawAssertionInfo* arg_assert_info,
+                  const CustomClientInfo& custom_info,
+                  HANDLE arg_dump_request_handle,
+                  HANDLE arg_dump_generated_handle,
+                  HANDLE arg_server_alive)
+    : tag(arg_tag),
+      id(arg_id),
+      dump_type(arg_dump_type),
+      thread_id(arg_thread_id),
+      exception_pointers(arg_exception_pointers),
+      assert_info(arg_assert_info),
+      custom_client_info(custom_info),
+      dump_request_handle(arg_dump_request_handle),
+      dump_generated_handle(arg_dump_generated_handle),
+      server_alive_handle(arg_server_alive) {
+  }
+
+  // Tag in the message.
+  MessageTag tag;
+
+  // The id for this message. This may be either a process id or a crash id
+  // depending on the type of message.
+  DWORD id;
+
+  // Dump type requested.
+  MINIDUMP_TYPE dump_type;
+
+  // Client thread id pointer.
+  DWORD* thread_id;
+
+  // Exception information.
+  EXCEPTION_POINTERS** exception_pointers;
+
+  // Assert information in case of an invalid parameter or
+  // pure call failure.
+  MDRawAssertionInfo* assert_info;
+
+  // Custom client information.
+  CustomClientInfo custom_client_info;
+
+  // Handle to signal the crash event.
+  HANDLE dump_request_handle;
+
+  // Handle to check if server is done generating crash.
+  HANDLE dump_generated_handle;
+
+  // Handle to a mutex that becomes signaled (WAIT_ABANDONED)
+  // if server process goes down.
+  HANDLE server_alive_handle;
+
+ private:
+  // Disable copy ctor and operator=.
+  ProtocolMessage(const ProtocolMessage& msg);
+  ProtocolMessage& operator=(const ProtocolMessage& msg);
+};
+
+}  // namespace google_breakpad
+
+#endif  // CLIENT_WINDOWS_COMMON_IPC_PROTOCOL_H__
diff --git a/3rdParty/Breakpad/src/client/windows/crash_generation/crash_generation_client.cc b/3rdParty/Breakpad/src/client/windows/crash_generation/crash_generation_client.cc
new file mode 100644
index 0000000..b0d3d04
--- /dev/null
+++ b/3rdParty/Breakpad/src/client/windows/crash_generation/crash_generation_client.cc
@@ -0,0 +1,401 @@
+// Copyright (c) 2008, 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 "client/windows/crash_generation/crash_generation_client.h"
+#include <cassert>
+#include <utility>
+#include "client/windows/common/ipc_protocol.h"
+
+namespace google_breakpad {
+
+const int kPipeBusyWaitTimeoutMs = 2000;
+
+#ifdef _DEBUG
+const DWORD kWaitForServerTimeoutMs = INFINITE;
+#else
+const DWORD kWaitForServerTimeoutMs = 15000;
+#endif
+
+const int kPipeConnectMaxAttempts = 2;
+
+const DWORD kPipeDesiredAccess = FILE_READ_DATA |
+                                 FILE_WRITE_DATA |
+                                 FILE_WRITE_ATTRIBUTES;
+
+const DWORD kPipeFlagsAndAttributes = SECURITY_IDENTIFICATION |
+                                      SECURITY_SQOS_PRESENT;
+
+const DWORD kPipeMode = PIPE_READMODE_MESSAGE;
+
+const size_t kWaitEventCount = 2;
+
+// This function is orphan for production code. It can be used
+// for debugging to help repro some scenarios like the client
+// is slow in writing to the pipe after connecting, the client
+// is slow in reading from the pipe after writing, etc. The parameter
+// overlapped below is not used and it is present to match the signature
+// of this function to TransactNamedPipe Win32 API. Uncomment if needed
+// for debugging.
+/**
+static bool TransactNamedPipeDebugHelper(HANDLE pipe,
+                                         const void* in_buffer,
+                                         DWORD in_size,
+                                         void* out_buffer,
+                                         DWORD out_size,
+                                         DWORD* bytes_count,
+                                         LPOVERLAPPED) {
+  // Uncomment the next sleep to create a gap before writing
+  // to pipe.
+  // Sleep(5000);
+
+  if (!WriteFile(pipe,
+                 in_buffer,
+                 in_size,
+                 bytes_count,
+                 NULL)) {
+    return false;
+  }
+
+  // Uncomment the next sleep to create a gap between write
+  // and read.
+  // Sleep(5000);
+
+  return ReadFile(pipe, out_buffer, out_size, bytes_count, NULL) != FALSE;
+}
+**/
+
+CrashGenerationClient::CrashGenerationClient(
+    const wchar_t* pipe_name,
+    MINIDUMP_TYPE dump_type,
+    const CustomClientInfo* custom_info)
+        : pipe_name_(pipe_name),
+          pipe_handle_(NULL),
+          dump_type_(dump_type),
+          thread_id_(0),
+          server_process_id_(0),
+          crash_event_(NULL),
+          crash_generated_(NULL),
+          server_alive_(NULL),
+          exception_pointers_(NULL),
+          custom_info_() {
+  memset(&assert_info_, 0, sizeof(assert_info_));
+  if (custom_info) {
+    custom_info_ = *custom_info;
+  }
+}
+
+CrashGenerationClient::CrashGenerationClient(
+    HANDLE pipe_handle,
+    MINIDUMP_TYPE dump_type,
+    const CustomClientInfo* custom_info)
+        : pipe_name_(),
+          pipe_handle_(pipe_handle),
+          dump_type_(dump_type),
+          thread_id_(0),
+          server_process_id_(0),
+          crash_event_(NULL),
+          crash_generated_(NULL),
+          server_alive_(NULL),
+          exception_pointers_(NULL),
+          custom_info_() {
+  memset(&assert_info_, 0, sizeof(assert_info_));
+  if (custom_info) {
+    custom_info_ = *custom_info;
+  }
+}
+
+CrashGenerationClient::~CrashGenerationClient() {
+  if (crash_event_) {
+    CloseHandle(crash_event_);
+  }
+
+  if (crash_generated_) {
+    CloseHandle(crash_generated_);
+  }
+
+  if (server_alive_) {
+    CloseHandle(server_alive_);
+  }
+}
+
+// Performs the registration step with the server process.
+// The registration step involves communicating with the server
+// via a named pipe. The client sends the following pieces of
+// data to the server:
+//
+// * Message tag indicating the client is requesting registration.
+// * Process id of the client process.
+// * Address of a DWORD variable in the client address space
+//   that will contain the thread id of the client thread that
+//   caused the crash.
+// * Address of a EXCEPTION_POINTERS* variable in the client
+//   address space that will point to an instance of EXCEPTION_POINTERS
+//   when the crash happens.
+// * Address of an instance of MDRawAssertionInfo that will contain
+//   relevant information in case of non-exception crashes like assertion
+//   failures and pure calls.
+//
+// In return the client expects the following information from the server:
+//
+// * Message tag indicating successful registration.
+// * Server process id.
+// * Handle to an object that client can signal to request dump
+//   generation from the server.
+// * Handle to an object that client can wait on after requesting
+//   dump generation for the server to finish dump generation.
+// * Handle to a mutex object that client can wait on to make sure
+//   server is still alive.
+//
+// If any step of the expected behavior mentioned above fails, the
+// registration step is not considered successful and hence out-of-process
+// dump generation service is not available.
+//
+// Returns true if the registration is successful; false otherwise.
+bool CrashGenerationClient::Register() {
+  HANDLE pipe = ConnectToServer();
+  if (!pipe) {
+    return false;
+  }
+
+  bool success = RegisterClient(pipe);
+  CloseHandle(pipe);
+  return success;
+}
+
+bool CrashGenerationClient::RequestUpload(DWORD crash_id) {
+  HANDLE pipe = ConnectToServer();
+  if (!pipe) {
+    return false;
+  }
+
+  CustomClientInfo custom_info = {NULL, 0};
+  ProtocolMessage msg(MESSAGE_TAG_UPLOAD_REQUEST, crash_id,
+                      static_cast<MINIDUMP_TYPE>(NULL), NULL, NULL, NULL,
+                      custom_info, NULL, NULL, NULL);
+  DWORD bytes_count = 0;
+  bool success = WriteFile(pipe, &msg, sizeof(msg), &bytes_count, NULL) != 0;
+
+  CloseHandle(pipe);
+  return success;
+}
+
+HANDLE CrashGenerationClient::ConnectToServer() {
+  HANDLE pipe = ConnectToPipe(pipe_name_.c_str(),
+                              kPipeDesiredAccess,
+                              kPipeFlagsAndAttributes);
+  if (!pipe) {
+    return NULL;
+  }
+
+  DWORD mode = kPipeMode;
+  if (!SetNamedPipeHandleState(pipe, &mode, NULL, NULL)) {
+    CloseHandle(pipe);
+    pipe = NULL;
+  }
+
+  return pipe;
+}
+
+bool CrashGenerationClient::RegisterClient(HANDLE pipe) {
+  ProtocolMessage msg(MESSAGE_TAG_REGISTRATION_REQUEST,
+                      GetCurrentProcessId(),
+                      dump_type_,
+                      &thread_id_,
+                      &exception_pointers_,
+                      &assert_info_,
+                      custom_info_,
+                      NULL,
+                      NULL,
+                      NULL);
+  ProtocolMessage reply;
+  DWORD bytes_count = 0;
+  // The call to TransactNamedPipe below can be changed to a call
+  // to TransactNamedPipeDebugHelper to help repro some scenarios.
+  // For details see comments for TransactNamedPipeDebugHelper.
+  if (!TransactNamedPipe(pipe,
+                         &msg,
+                         sizeof(msg),
+                         &reply,
+                         sizeof(ProtocolMessage),
+                         &bytes_count,
+                         NULL)) {
+    return false;
+  }
+
+  if (!ValidateResponse(reply)) {
+    return false;
+  }
+
+  ProtocolMessage ack_msg;
+  ack_msg.tag = MESSAGE_TAG_REGISTRATION_ACK;
+
+  if (!WriteFile(pipe, &ack_msg, sizeof(ack_msg), &bytes_count, NULL)) {
+    return false;
+  }
+  crash_event_ = reply.dump_request_handle;
+  crash_generated_ = reply.dump_generated_handle;
+  server_alive_ = reply.server_alive_handle;
+  server_process_id_ = reply.id;
+
+  return true;
+}
+
+HANDLE CrashGenerationClient::ConnectToPipe(const wchar_t* pipe_name,
+                                            DWORD pipe_access,
+                                            DWORD flags_attrs) {
+  if (pipe_handle_) {
+    HANDLE t = pipe_handle_;
+    pipe_handle_ = NULL;
+    return t;
+  }
+
+  for (int i = 0; i < kPipeConnectMaxAttempts; ++i) {
+    HANDLE pipe = CreateFile(pipe_name,
+                             pipe_access,
+                             0,
+                             NULL,
+                             OPEN_EXISTING,
+                             flags_attrs,
+                             NULL);
+    if (pipe != INVALID_HANDLE_VALUE) {
+      return pipe;
+    }
+
+    // Cannot continue retrying if error is something other than
+    // ERROR_PIPE_BUSY.
+    if (GetLastError() != ERROR_PIPE_BUSY) {
+      break;
+    }
+
+    // Cannot continue retrying if wait on pipe fails.
+    if (!WaitNamedPipe(pipe_name, kPipeBusyWaitTimeoutMs)) {
+      break;
+    }
+  }
+
+  return NULL;
+}
+
+bool CrashGenerationClient::ValidateResponse(
+    const ProtocolMessage& msg) const {
+  return (msg.tag == MESSAGE_TAG_REGISTRATION_RESPONSE) &&
+         (msg.id != 0) &&
+         (msg.dump_request_handle != NULL) &&
+         (msg.dump_generated_handle != NULL) &&
+         (msg.server_alive_handle != NULL);
+}
+
+bool CrashGenerationClient::IsRegistered() const {
+  return crash_event_ != NULL;
+}
+
+bool CrashGenerationClient::RequestDump(EXCEPTION_POINTERS* ex_info,
+                                        MDRawAssertionInfo* assert_info) {
+  if (!IsRegistered()) {
+    return false;
+  }
+
+  exception_pointers_ = ex_info;
+  thread_id_ = GetCurrentThreadId();
+
+  if (assert_info) {
+    memcpy(&assert_info_, assert_info, sizeof(assert_info_));
+  } else {
+    memset(&assert_info_, 0, sizeof(assert_info_));
+  }
+
+  return SignalCrashEventAndWait();
+}
+
+bool CrashGenerationClient::RequestDump(EXCEPTION_POINTERS* ex_info) {
+  return RequestDump(ex_info, NULL);
+}
+
+bool CrashGenerationClient::RequestDump(MDRawAssertionInfo* assert_info) {
+  return RequestDump(NULL, assert_info);
+}
+
+bool CrashGenerationClient::SignalCrashEventAndWait() {
+  assert(crash_event_);
+  assert(crash_generated_);
+  assert(server_alive_);
+
+  // Reset the dump generated event before signaling the crash
+  // event so that the server can set the dump generated event
+  // once it is done generating the event.
+  if (!ResetEvent(crash_generated_)) {
+    return false;
+  }
+
+  if (!SetEvent(crash_event_)) {
+    return false;
+  }
+
+  HANDLE wait_handles[kWaitEventCount] = {crash_generated_, server_alive_};
+
+  DWORD result = WaitForMultipleObjects(kWaitEventCount,
+                                        wait_handles,
+                                        FALSE,
+                                        kWaitForServerTimeoutMs);
+
+  // Crash dump was successfully generated only if the server
+  // signaled the crash generated event.
+  return result == WAIT_OBJECT_0;
+}
+
+HANDLE CrashGenerationClient::DuplicatePipeToClientProcess(const wchar_t* pipe_name,
+                                                           HANDLE hProcess) {
+  for (int i = 0; i < kPipeConnectMaxAttempts; ++i) {
+    HANDLE local_pipe = CreateFile(pipe_name, kPipeDesiredAccess,
+                                   0, NULL, OPEN_EXISTING,
+                                   kPipeFlagsAndAttributes, NULL);
+    if (local_pipe != INVALID_HANDLE_VALUE) {
+      HANDLE remotePipe = INVALID_HANDLE_VALUE;
+      if (DuplicateHandle(GetCurrentProcess(), local_pipe,
+                          hProcess, &remotePipe, 0, FALSE,
+                          DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS)) {
+        return remotePipe;
+      } else {
+        return INVALID_HANDLE_VALUE;
+      }
+    }
+
+    // Cannot continue retrying if the error wasn't a busy pipe.
+    if (GetLastError() != ERROR_PIPE_BUSY) {
+      return INVALID_HANDLE_VALUE;
+    }
+
+    if (!WaitNamedPipe(pipe_name, kPipeBusyWaitTimeoutMs)) {
+      return INVALID_HANDLE_VALUE;
+    }
+  }
+  return INVALID_HANDLE_VALUE;
+}
+
+}  // namespace google_breakpad
diff --git a/3rdParty/Breakpad/src/client/windows/crash_generation/crash_generation_client.h b/3rdParty/Breakpad/src/client/windows/crash_generation/crash_generation_client.h
new file mode 100644
index 0000000..2ce14dd
--- /dev/null
+++ b/3rdParty/Breakpad/src/client/windows/crash_generation/crash_generation_client.h
@@ -0,0 +1,182 @@
+// Copyright (c) 2008, 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.
+
+#ifndef CLIENT_WINDOWS_CRASH_GENERATION_CRASH_GENERATION_CLIENT_H_
+#define CLIENT_WINDOWS_CRASH_GENERATION_CRASH_GENERATION_CLIENT_H_
+
+#include <windows.h>
+#include <dbghelp.h>
+#include <string>
+#include <utility>
+#include "client/windows/common/ipc_protocol.h"
+#include "processor/scoped_ptr.h"
+
+namespace google_breakpad {
+
+struct CustomClientInfo;
+
+// Abstraction of client-side implementation of out of process
+// crash generation.
+//
+// The process that desires to have out-of-process crash dump
+// generation service can use this class in the following way:
+//
+// * Create an instance.
+// * Call Register method so that the client tries to register
+//   with the server process and check the return value. If
+//   registration is not successful, out-of-process crash dump
+//   generation will not be available
+// * Request dump generation by calling either of the two
+//   overloaded RequestDump methods - one in case of exceptions
+//   and the other in case of assertion failures
+//
+// Note that it is the responsibility of the client code of
+// this class to set the unhandled exception filter with the
+// system by calling the SetUnhandledExceptionFilter function
+// and the client code should explicitly request dump generation.
+class CrashGenerationClient {
+ public:
+  CrashGenerationClient(const wchar_t* pipe_name,
+                        MINIDUMP_TYPE dump_type,
+                        const CustomClientInfo* custom_info);
+
+  CrashGenerationClient(HANDLE pipe_handle,
+                        MINIDUMP_TYPE dump_type,
+                        const CustomClientInfo* custom_info);
+
+  ~CrashGenerationClient();
+
+  // Registers the client process with the crash server.
+  //
+  // Returns true if the registration is successful; false otherwise.
+  bool Register();
+
+  // Requests the crash server to upload a previous dump with the
+  // given crash id.
+  bool RequestUpload(DWORD crash_id);
+
+  bool RequestDump(EXCEPTION_POINTERS* ex_info,
+                   MDRawAssertionInfo* assert_info);
+
+  // Requests the crash server to generate a dump with the given
+  // exception information.
+  //
+  // Returns true if the dump was successful; false otherwise. Note that
+  // if the registration step was not performed or it was not successful,
+  // false will be returned.
+  bool RequestDump(EXCEPTION_POINTERS* ex_info);
+
+  // Requests the crash server to generate a dump with the given
+  // assertion information.
+  //
+  // Returns true if the dump was successful; false otherwise. Note that
+  // if the registration step was not performed or it was not successful,
+  // false will be returned.
+  bool RequestDump(MDRawAssertionInfo* assert_info);
+
+  // If the crash generation client is running in a sandbox that prevents it
+  // from opening the named pipe directly, the server process may open the
+  // handle and duplicate it into the client process with this helper method.
+  // Returns INVALID_HANDLE_VALUE on failure. The process must have been opened
+  // with the PROCESS_DUP_HANDLE access right.
+  static HANDLE DuplicatePipeToClientProcess(const wchar_t* pipe_name,
+                                             HANDLE hProcess);
+
+ private:
+  // Connects to the appropriate pipe and sets the pipe handle state.
+  //
+  // Returns the pipe handle if everything goes well; otherwise Returns NULL.
+  HANDLE ConnectToServer();
+
+  // Performs a handshake with the server over the given pipe which should be
+  // already connected to the server.
+  //
+  // Returns true if handshake with the server was successful; false otherwise.
+  bool RegisterClient(HANDLE pipe);
+
+  // Validates the given server response.
+  bool ValidateResponse(const ProtocolMessage& msg) const;
+
+  // Returns true if the registration step succeeded; false otherwise.
+  bool IsRegistered() const;
+
+  // Connects to the given named pipe with given parameters.
+  //
+  // Returns true if the connection is successful; false otherwise.
+  HANDLE ConnectToPipe(const wchar_t* pipe_name,
+                       DWORD pipe_access,
+                       DWORD flags_attrs);
+
+  // Signals the crash event and wait for the server to generate crash.
+  bool SignalCrashEventAndWait();
+
+  // Pipe name to use to talk to server.
+  std::wstring pipe_name_;
+
+  // Pipe handle duplicated from server process. Only valid before
+  // Register is called.
+  HANDLE pipe_handle_;
+
+  // Custom client information
+  CustomClientInfo custom_info_;
+
+  // Type of dump to generate.
+  MINIDUMP_TYPE dump_type_;
+
+  // Event to signal in case of a crash.
+  HANDLE crash_event_;
+
+  // Handle to wait on after signaling a crash for the server
+  // to finish generating crash dump.
+  HANDLE crash_generated_;
+
+  // Handle to a mutex that will become signaled with WAIT_ABANDONED
+  // if the server process goes down.
+  HANDLE server_alive_;
+
+  // Server process id.
+  DWORD server_process_id_;
+
+  // Id of the thread that caused the crash.
+  DWORD thread_id_;
+
+  // Exception pointers for an exception crash.
+  EXCEPTION_POINTERS* exception_pointers_;
+
+  // Assertion info for an invalid parameter or pure call crash.
+  MDRawAssertionInfo assert_info_;
+
+  // Disable copy ctor and operator=.
+  CrashGenerationClient(const CrashGenerationClient& crash_client);
+  CrashGenerationClient& operator=(const CrashGenerationClient& crash_client);
+};
+
+}  // namespace google_breakpad
+
+#endif  // CLIENT_WINDOWS_CRASH_GENERATION_CRASH_GENERATION_CLIENT_H_
diff --git a/3rdParty/Breakpad/src/client/windows/handler/exception_handler.cc b/3rdParty/Breakpad/src/client/windows/handler/exception_handler.cc
new file mode 100644
index 0000000..6e5b724
--- /dev/null
+++ b/3rdParty/Breakpad/src/client/windows/handler/exception_handler.cc
@@ -0,0 +1,927 @@
+// 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 <ObjBase.h>
+
+#include <algorithm>
+#include <cassert>
+#include <cstdio>
+
+#include "common/windows/string_utils-inl.h"
+
+#include "client/windows/common/ipc_protocol.h"
+#include "client/windows/handler/exception_handler.h"
+#include "common/windows/guid_string.h"
+
+namespace google_breakpad {
+
+static const int kWaitForHandlerThreadMs = 60000;
+static const int kExceptionHandlerThreadInitialStackSize = 64 * 1024;
+
+// This is passed as the context to the MinidumpWriteDump callback.
+typedef struct {
+  ULONG64 memory_base;
+  ULONG memory_size;
+  bool finished;
+} MinidumpCallbackContext;
+
+vector<ExceptionHandler*>* ExceptionHandler::handler_stack_ = NULL;
+LONG ExceptionHandler::handler_stack_index_ = 0;
+CRITICAL_SECTION ExceptionHandler::handler_stack_critical_section_;
+volatile LONG ExceptionHandler::instance_count_ = 0;
+
+ExceptionHandler::ExceptionHandler(const wstring& dump_path,
+                                   FilterCallback filter,
+                                   MinidumpCallback callback,
+                                   void* callback_context,
+                                   int handler_types,
+                                   MINIDUMP_TYPE dump_type,
+                                   const wchar_t* pipe_name,
+                                   const CustomClientInfo* custom_info) {
+  Initialize(dump_path,
+             filter,
+             callback,
+             callback_context,
+             handler_types,
+             dump_type,
+             pipe_name,
+             NULL,
+             custom_info);
+}
+
+ExceptionHandler::ExceptionHandler(const wstring& dump_path,
+                                   FilterCallback filter,
+                                   MinidumpCallback callback,
+                                   void* callback_context,
+                                   int handler_types,
+                                   MINIDUMP_TYPE dump_type,
+                                   HANDLE pipe_handle,
+                                   const CustomClientInfo* custom_info) {
+  Initialize(dump_path,
+             filter,
+             callback,
+             callback_context,
+             handler_types,
+             dump_type,
+             NULL,
+             pipe_handle,
+             custom_info);
+}  
+
+ExceptionHandler::ExceptionHandler(const wstring &dump_path,
+                                   FilterCallback filter,
+                                   MinidumpCallback callback,
+                                   void* callback_context,
+                                   int handler_types) {
+  Initialize(dump_path,
+             filter,
+             callback,
+             callback_context,
+             handler_types,
+             MiniDumpNormal,
+             NULL,
+             NULL,
+             NULL);
+}
+
+void ExceptionHandler::Initialize(const wstring& dump_path,
+                                  FilterCallback filter,
+                                  MinidumpCallback callback,
+                                  void* callback_context,
+                                  int handler_types,
+                                  MINIDUMP_TYPE dump_type,
+                                  const wchar_t* pipe_name,
+                                  HANDLE pipe_handle,
+                                  const CustomClientInfo* custom_info) {
+  LONG instance_count = InterlockedIncrement(&instance_count_);
+  filter_ = filter;
+  callback_ = callback;
+  callback_context_ = callback_context;
+  dump_path_c_ = NULL;
+  next_minidump_id_c_ = NULL;
+  next_minidump_path_c_ = NULL;
+  dbghelp_module_ = NULL;
+  minidump_write_dump_ = NULL;
+  dump_type_ = dump_type;
+  rpcrt4_module_ = NULL;
+  uuid_create_ = NULL;
+  handler_types_ = handler_types;
+  previous_filter_ = NULL;
+#if _MSC_VER >= 1400  // MSVC 2005/8
+  previous_iph_ = NULL;
+#endif  // _MSC_VER >= 1400
+  previous_pch_ = NULL;
+  handler_thread_ = NULL;
+  is_shutdown_ = false;
+  handler_start_semaphore_ = NULL;
+  handler_finish_semaphore_ = NULL;
+  requesting_thread_id_ = 0;
+  exception_info_ = NULL;
+  assertion_ = NULL;
+  handler_return_value_ = false;
+  handle_debug_exceptions_ = false;
+
+  // Attempt to use out-of-process if user has specified a pipe.
+  if (pipe_name != NULL || pipe_handle != NULL) {
+    assert(!(pipe_name && pipe_handle));
+
+    scoped_ptr<CrashGenerationClient> client;
+    if (pipe_name) {
+      client.reset(
+        new CrashGenerationClient(pipe_name,
+                                  dump_type_,
+                                  custom_info));
+    } else {
+      client.reset(
+        new CrashGenerationClient(pipe_handle,
+                                  dump_type_,
+                                  custom_info));
+    }
+
+    // If successful in registering with the monitoring process,
+    // there is no need to setup in-process crash generation.
+    if (client->Register()) {
+      crash_generation_client_.reset(client.release());
+    }
+  }
+
+  if (!IsOutOfProcess()) {
+    // Either client did not ask for out-of-process crash generation
+    // or registration with the server process failed. In either case,
+    // setup to do in-process crash generation.
+
+    // Set synchronization primitives and the handler thread.  Each
+    // ExceptionHandler object gets its own handler thread because that's the
+    // only way to reliably guarantee sufficient stack space in an exception,
+    // and it allows an easy way to get a snapshot of the requesting thread's
+    // context outside of an exception.
+    InitializeCriticalSection(&handler_critical_section_);
+    handler_start_semaphore_ = CreateSemaphore(NULL, 0, 1, NULL);
+    assert(handler_start_semaphore_ != NULL);
+
+    handler_finish_semaphore_ = CreateSemaphore(NULL, 0, 1, NULL);
+    assert(handler_finish_semaphore_ != NULL);
+
+    // Don't attempt to create the thread if we could not create the semaphores.
+    if (handler_finish_semaphore_ != NULL && handler_start_semaphore_ != NULL) {
+      DWORD thread_id;
+      handler_thread_ = CreateThread(NULL,         // lpThreadAttributes
+                                     kExceptionHandlerThreadInitialStackSize,
+                                     ExceptionHandlerThreadMain,
+                                     this,         // lpParameter
+                                     0,            // dwCreationFlags
+                                     &thread_id);
+      assert(handler_thread_ != NULL);
+    }
+
+    dbghelp_module_ = LoadLibrary(L"dbghelp.dll");
+    if (dbghelp_module_) {
+      minidump_write_dump_ = reinterpret_cast<MiniDumpWriteDump_type>(
+          GetProcAddress(dbghelp_module_, "MiniDumpWriteDump"));
+    }
+
+    // Load this library dynamically to not affect existing projects.  Most
+    // projects don't link against this directly, it's usually dynamically
+    // loaded by dependent code.
+    rpcrt4_module_ = LoadLibrary(L"rpcrt4.dll");
+    if (rpcrt4_module_) {
+      uuid_create_ = reinterpret_cast<UuidCreate_type>(
+          GetProcAddress(rpcrt4_module_, "UuidCreate"));
+    }
+
+    // set_dump_path calls UpdateNextID.  This sets up all of the path and id
+    // strings, and their equivalent c_str pointers.
+    set_dump_path(dump_path);
+  }
+
+  // There is a race condition here. If the first instance has not yet
+  // initialized the critical section, the second (and later) instances may
+  // try to use uninitialized critical section object. The feature of multiple
+  // instances in one module is not used much, so leave it as is for now.
+  // One way to solve this in the current design (that is, keeping the static
+  // handler stack) is to use spin locks with volatile bools to synchronize
+  // the handler stack. This works only if the compiler guarantees to generate
+  // cache coherent code for volatile.
+  // TODO(munjal): Fix this in a better way by changing the design if possible.
+
+  // Lazy initialization of the handler_stack_critical_section_
+  if (instance_count == 1) {
+    InitializeCriticalSection(&handler_stack_critical_section_);
+  }
+
+  if (handler_types != HANDLER_NONE) {
+    EnterCriticalSection(&handler_stack_critical_section_);
+
+    // The first time an ExceptionHandler that installs a handler is
+    // created, set up the handler stack.
+    if (!handler_stack_) {
+      handler_stack_ = new vector<ExceptionHandler*>();
+    }
+    handler_stack_->push_back(this);
+
+    if (handler_types & HANDLER_EXCEPTION)
+      previous_filter_ = SetUnhandledExceptionFilter(HandleException);
+
+#if _MSC_VER >= 1400  // MSVC 2005/8
+    if (handler_types & HANDLER_INVALID_PARAMETER)
+      previous_iph_ = _set_invalid_parameter_handler(HandleInvalidParameter);
+#endif  // _MSC_VER >= 1400
+
+    if (handler_types & HANDLER_PURECALL)
+      previous_pch_ = _set_purecall_handler(HandlePureVirtualCall);
+
+    LeaveCriticalSection(&handler_stack_critical_section_);
+  }
+}
+
+ExceptionHandler::~ExceptionHandler() {
+  if (dbghelp_module_) {
+    FreeLibrary(dbghelp_module_);
+  }
+
+  if (rpcrt4_module_) {
+    FreeLibrary(rpcrt4_module_);
+  }
+
+  if (handler_types_ != HANDLER_NONE) {
+    EnterCriticalSection(&handler_stack_critical_section_);
+
+    if (handler_types_ & HANDLER_EXCEPTION)
+      SetUnhandledExceptionFilter(previous_filter_);
+
+#if _MSC_VER >= 1400  // MSVC 2005/8
+    if (handler_types_ & HANDLER_INVALID_PARAMETER)
+      _set_invalid_parameter_handler(previous_iph_);
+#endif  // _MSC_VER >= 1400
+
+    if (handler_types_ & HANDLER_PURECALL)
+      _set_purecall_handler(previous_pch_);
+
+    if (handler_stack_->back() == this) {
+      handler_stack_->pop_back();
+    } else {
+      // TODO(mmentovai): use advapi32!ReportEvent to log the warning to the
+      // system's application event log.
+      fprintf(stderr, "warning: removing Breakpad handler out of order\n");
+      vector<ExceptionHandler*>::iterator iterator = handler_stack_->begin();
+      while (iterator != handler_stack_->end()) {
+        if (*iterator == this) {
+          iterator = handler_stack_->erase(iterator);
+        } else {
+          ++iterator;
+        }
+      }
+    }
+
+    if (handler_stack_->empty()) {
+      // When destroying the last ExceptionHandler that installed a handler,
+      // clean up the handler stack.
+      delete handler_stack_;
+      handler_stack_ = NULL;
+    }
+
+    LeaveCriticalSection(&handler_stack_critical_section_);
+  }
+
+  // Some of the objects were only initialized if out of process
+  // registration was not done.
+  if (!IsOutOfProcess()) {
+#ifdef BREAKPAD_NO_TERMINATE_THREAD
+    // Clean up the handler thread and synchronization primitives. The handler
+    // thread is either waiting on the semaphore to handle a crash or it is
+    // handling a crash. Coming out of the wait is fast but wait more in the
+    // eventuality a crash is handled.  This compilation option results in a
+    // deadlock if the exception handler is destroyed while executing code
+    // inside DllMain.
+    is_shutdown_ = true;
+    ReleaseSemaphore(handler_start_semaphore_, 1, NULL);
+    WaitForSingleObject(handler_thread_, kWaitForHandlerThreadMs);
+#else
+    TerminateThread(handler_thread_, 1);
+#endif  // BREAKPAD_NO_TERMINATE_THREAD
+
+    CloseHandle(handler_thread_);
+    handler_thread_ = NULL;
+    DeleteCriticalSection(&handler_critical_section_);
+    CloseHandle(handler_start_semaphore_);
+    CloseHandle(handler_finish_semaphore_);
+  }
+
+  // There is a race condition in the code below: if this instance is
+  // deleting the static critical section and a new instance of the class
+  // is created, then there is a possibility that the critical section be
+  // initialized while the same critical section is being deleted. Given the
+  // usage pattern for the code, this race condition is unlikely to hit, but it
+  // is a race condition nonetheless.
+  if (InterlockedDecrement(&instance_count_) == 0) {
+    DeleteCriticalSection(&handler_stack_critical_section_);
+  }
+}
+
+bool ExceptionHandler::RequestUpload(DWORD crash_id) {
+  return crash_generation_client_->RequestUpload(crash_id);
+}
+
+// static
+DWORD ExceptionHandler::ExceptionHandlerThreadMain(void* lpParameter) {
+  ExceptionHandler* self = reinterpret_cast<ExceptionHandler *>(lpParameter);
+  assert(self);
+  assert(self->handler_start_semaphore_ != NULL);
+  assert(self->handler_finish_semaphore_ != NULL);
+
+  while (true) {
+    if (WaitForSingleObject(self->handler_start_semaphore_, INFINITE) ==
+        WAIT_OBJECT_0) {
+      // Perform the requested action.
+      if (self->is_shutdown_) {
+        // The instance of the exception handler is being destroyed.
+        break;
+      } else {
+        self->handler_return_value_ =
+            self->WriteMinidumpWithException(self->requesting_thread_id_,
+                                             self->exception_info_,
+                                             self->assertion_);
+      }
+
+      // Allow the requesting thread to proceed.
+      ReleaseSemaphore(self->handler_finish_semaphore_, 1, NULL);
+    }
+  }
+
+  // This statement is not reached when the thread is unconditionally
+  // terminated by the ExceptionHandler destructor.
+  return 0;
+}
+
+// HandleException and HandleInvalidParameter must create an
+// AutoExceptionHandler object to maintain static state and to determine which
+// ExceptionHandler instance to use.  The constructor locates the correct
+// instance, and makes it available through get_handler().  The destructor
+// restores the state in effect prior to allocating the AutoExceptionHandler.
+class AutoExceptionHandler {
+ public:
+  AutoExceptionHandler() {
+    // Increment handler_stack_index_ so that if another Breakpad handler is
+    // registered using this same HandleException function, and it needs to be
+    // called while this handler is running (either because this handler
+    // declines to handle the exception, or an exception occurs during
+    // handling), HandleException will find the appropriate ExceptionHandler
+    // object in handler_stack_ to deliver the exception to.
+    //
+    // Because handler_stack_ is addressed in reverse (as |size - index|),
+    // preincrementing handler_stack_index_ avoids needing to subtract 1 from
+    // the argument to |at|.
+    //
+    // The index is maintained instead of popping elements off of the handler
+    // stack and pushing them at the end of this method.  This avoids ruining
+    // the order of elements in the stack in the event that some other thread
+    // decides to manipulate the handler stack (such as creating a new
+    // ExceptionHandler object) while an exception is being handled.
+    EnterCriticalSection(&ExceptionHandler::handler_stack_critical_section_);
+    handler_ = ExceptionHandler::handler_stack_->at(
+        ExceptionHandler::handler_stack_->size() -
+        ++ExceptionHandler::handler_stack_index_);
+
+    // In case another exception occurs while this handler is doing its thing,
+    // it should be delivered to the previous filter.
+    SetUnhandledExceptionFilter(handler_->previous_filter_);
+#if _MSC_VER >= 1400  // MSVC 2005/8
+    _set_invalid_parameter_handler(handler_->previous_iph_);
+#endif  // _MSC_VER >= 1400
+    _set_purecall_handler(handler_->previous_pch_);
+  }
+
+  ~AutoExceptionHandler() {
+    // Put things back the way they were before entering this handler.
+    SetUnhandledExceptionFilter(ExceptionHandler::HandleException);
+#if _MSC_VER >= 1400  // MSVC 2005/8
+    _set_invalid_parameter_handler(ExceptionHandler::HandleInvalidParameter);
+#endif  // _MSC_VER >= 1400
+    _set_purecall_handler(ExceptionHandler::HandlePureVirtualCall);
+
+    --ExceptionHandler::handler_stack_index_;
+    LeaveCriticalSection(&ExceptionHandler::handler_stack_critical_section_);
+  }
+
+  ExceptionHandler* get_handler() const { return handler_; }
+
+ private:
+  ExceptionHandler* handler_;
+};
+
+// static
+LONG ExceptionHandler::HandleException(EXCEPTION_POINTERS* exinfo) {
+  AutoExceptionHandler auto_exception_handler;
+  ExceptionHandler* current_handler = auto_exception_handler.get_handler();
+
+  // Ignore EXCEPTION_BREAKPOINT and EXCEPTION_SINGLE_STEP exceptions.  This
+  // logic will short-circuit before calling WriteMinidumpOnHandlerThread,
+  // allowing something else to handle the breakpoint without incurring the
+  // overhead transitioning to and from the handler thread.  This behavior
+  // can be overridden by calling ExceptionHandler::set_handle_debug_exceptions.
+  DWORD code = exinfo->ExceptionRecord->ExceptionCode;
+  LONG action;
+  bool is_debug_exception = (code == EXCEPTION_BREAKPOINT) ||
+                            (code == EXCEPTION_SINGLE_STEP);
+
+  bool success = false;
+
+  if (!is_debug_exception ||
+      current_handler->get_handle_debug_exceptions()) {
+    // If out-of-proc crash handler client is available, we have to use that
+    // to generate dump and we cannot fall back on in-proc dump generation
+    // because we never prepared for an in-proc dump generation
+
+    // In case of out-of-process dump generation, directly call
+    // WriteMinidumpWithException since there is no separate thread running.
+    if (current_handler->IsOutOfProcess()) {
+      success = current_handler->WriteMinidumpWithException(
+          GetCurrentThreadId(),
+          exinfo,
+          NULL);
+    } else {
+      success = current_handler->WriteMinidumpOnHandlerThread(exinfo, NULL);
+    }
+  }
+
+  // The handler fully handled the exception.  Returning
+  // EXCEPTION_EXECUTE_HANDLER indicates this to the system, and usually
+  // results in the application being terminated.
+  //
+  // Note: If the application was launched from within the Cygwin
+  // environment, returning EXCEPTION_EXECUTE_HANDLER seems to cause the
+  // application to be restarted.
+  if (success) {
+    action = EXCEPTION_EXECUTE_HANDLER;
+  } else {
+    // There was an exception, it was a breakpoint or something else ignored
+    // above, or it was passed to the handler, which decided not to handle it.
+    // This could be because the filter callback didn't want it, because
+    // minidump writing failed for some reason, or because the post-minidump
+    // callback function indicated failure.  Give the previous handler a
+    // chance to do something with the exception.  If there is no previous
+    // handler, return EXCEPTION_CONTINUE_SEARCH, which will allow a debugger
+    // or native "crashed" dialog to handle the exception.
+    if (current_handler->previous_filter_) {
+      action = current_handler->previous_filter_(exinfo);
+    } else {
+      action = EXCEPTION_CONTINUE_SEARCH;
+    }
+  }
+
+  return action;
+}
+
+#if _MSC_VER >= 1400  // MSVC 2005/8
+// static
+void ExceptionHandler::HandleInvalidParameter(const wchar_t* expression,
+                                              const wchar_t* function,
+                                              const wchar_t* file,
+                                              unsigned int line,
+                                              uintptr_t reserved) {
+  // This is an invalid parameter, not an exception.  It's safe to play with
+  // sprintf here.
+  AutoExceptionHandler auto_exception_handler;
+  ExceptionHandler* current_handler = auto_exception_handler.get_handler();
+
+  MDRawAssertionInfo assertion;
+  memset(&assertion, 0, sizeof(assertion));
+  _snwprintf_s(reinterpret_cast<wchar_t*>(assertion.expression),
+               sizeof(assertion.expression) / sizeof(assertion.expression[0]),
+               _TRUNCATE, L"%s", expression);
+  _snwprintf_s(reinterpret_cast<wchar_t*>(assertion.function),
+               sizeof(assertion.function) / sizeof(assertion.function[0]),
+               _TRUNCATE, L"%s", function);
+  _snwprintf_s(reinterpret_cast<wchar_t*>(assertion.file),
+               sizeof(assertion.file) / sizeof(assertion.file[0]),
+               _TRUNCATE, L"%s", file);
+  assertion.line = line;
+  assertion.type = MD_ASSERTION_INFO_TYPE_INVALID_PARAMETER;
+
+  // Make up an exception record for the current thread and CPU context
+  // to make it possible for the crash processor to classify these
+  // as do regular crashes, and to make it humane for developers to
+  // analyze them.
+  EXCEPTION_RECORD exception_record = {};
+  CONTEXT exception_context = {};
+  EXCEPTION_POINTERS exception_ptrs = { &exception_record, &exception_context };
+
+  ::RtlCaptureContext(&exception_context);
+
+  exception_record.ExceptionCode = STATUS_INVALID_PARAMETER;
+
+  // We store pointers to the the expression and function strings,
+  // and the line as exception parameters to make them easy to
+  // access by the developer on the far side.
+  exception_record.NumberParameters = 3;
+  exception_record.ExceptionInformation[0] =
+      reinterpret_cast<ULONG_PTR>(&assertion.expression);
+  exception_record.ExceptionInformation[1] =
+      reinterpret_cast<ULONG_PTR>(&assertion.file);
+  exception_record.ExceptionInformation[2] = assertion.line;
+
+  bool success = false;
+  // In case of out-of-process dump generation, directly call
+  // WriteMinidumpWithException since there is no separate thread running.
+  if (current_handler->IsOutOfProcess()) {
+    success = current_handler->WriteMinidumpWithException(
+        GetCurrentThreadId(),
+        &exception_ptrs,
+        &assertion);
+  } else {
+    success = current_handler->WriteMinidumpOnHandlerThread(&exception_ptrs,
+                                                            &assertion);
+  }
+
+  if (!success) {
+    if (current_handler->previous_iph_) {
+      // The handler didn't fully handle the exception.  Give it to the
+      // previous invalid parameter handler.
+      current_handler->previous_iph_(expression,
+                                     function,
+                                     file,
+                                     line,
+                                     reserved);
+    } else {
+      // If there's no previous handler, pass the exception back in to the
+      // invalid parameter handler's core.  That's the routine that called this
+      // function, but now, since this function is no longer registered (and in
+      // fact, no function at all is registered), this will result in the
+      // default code path being taken: _CRT_DEBUGGER_HOOK and _invoke_watson.
+      // Use _invalid_parameter where it exists (in _DEBUG builds) as it passes
+      // more information through.  In non-debug builds, it is not available,
+      // so fall back to using _invalid_parameter_noinfo.  See invarg.c in the
+      // CRT source.
+#ifdef _DEBUG
+      _invalid_parameter(expression, function, file, line, reserved);
+#else  // _DEBUG
+      _invalid_parameter_noinfo();
+#endif  // _DEBUG
+    }
+  }
+
+  // The handler either took care of the invalid parameter problem itself,
+  // or passed it on to another handler.  "Swallow" it by exiting, paralleling
+  // the behavior of "swallowing" exceptions.
+  exit(0);
+}
+#endif  // _MSC_VER >= 1400
+
+// static
+void ExceptionHandler::HandlePureVirtualCall() {
+  // This is an pure virtual function call, not an exception.  It's safe to
+  // play with sprintf here.
+  AutoExceptionHandler auto_exception_handler;
+  ExceptionHandler* current_handler = auto_exception_handler.get_handler();
+
+  MDRawAssertionInfo assertion;
+  memset(&assertion, 0, sizeof(assertion));
+  assertion.type = MD_ASSERTION_INFO_TYPE_PURE_VIRTUAL_CALL;
+
+  // Make up an exception record for the current thread and CPU context
+  // to make it possible for the crash processor to classify these
+  // as do regular crashes, and to make it humane for developers to
+  // analyze them.
+  EXCEPTION_RECORD exception_record = {};
+  CONTEXT exception_context = {};
+  EXCEPTION_POINTERS exception_ptrs = { &exception_record, &exception_context };
+
+  ::RtlCaptureContext(&exception_context);
+
+  exception_record.ExceptionCode = STATUS_NONCONTINUABLE_EXCEPTION;
+
+  // We store pointers to the the expression and function strings,
+  // and the line as exception parameters to make them easy to
+  // access by the developer on the far side.
+  exception_record.NumberParameters = 3;
+  exception_record.ExceptionInformation[0] =
+      reinterpret_cast<ULONG_PTR>(&assertion.expression);
+  exception_record.ExceptionInformation[1] =
+      reinterpret_cast<ULONG_PTR>(&assertion.file);
+  exception_record.ExceptionInformation[2] = assertion.line;
+
+  bool success = false;
+  // In case of out-of-process dump generation, directly call
+  // WriteMinidumpWithException since there is no separate thread running.
+
+  if (current_handler->IsOutOfProcess()) {
+    success = current_handler->WriteMinidumpWithException(
+        GetCurrentThreadId(),
+        &exception_ptrs,
+        &assertion);
+  } else {
+    success = current_handler->WriteMinidumpOnHandlerThread(&exception_ptrs,
+                                                            &assertion);
+  }
+
+  if (!success) {
+    if (current_handler->previous_pch_) {
+      // The handler didn't fully handle the exception.  Give it to the
+      // previous purecall handler.
+      current_handler->previous_pch_();
+    } else {
+      // If there's no previous handler, return and let _purecall handle it.
+      // This will just put up an assertion dialog.
+      return;
+    }
+  }
+
+  // The handler either took care of the invalid parameter problem itself,
+  // or passed it on to another handler.  "Swallow" it by exiting, paralleling
+  // the behavior of "swallowing" exceptions.
+  exit(0);
+}
+
+bool ExceptionHandler::WriteMinidumpOnHandlerThread(
+    EXCEPTION_POINTERS* exinfo, MDRawAssertionInfo* assertion) {
+  EnterCriticalSection(&handler_critical_section_);
+
+  // There isn't much we can do if the handler thread
+  // was not successfully created.
+  if (handler_thread_ == NULL) {
+    LeaveCriticalSection(&handler_critical_section_);
+    return false;
+  }
+
+  // The handler thread should only be created when the semaphores are valid.
+  assert(handler_start_semaphore_ != NULL);
+  assert(handler_finish_semaphore_ != NULL);
+
+  // Set up data to be passed in to the handler thread.
+  requesting_thread_id_ = GetCurrentThreadId();
+  exception_info_ = exinfo;
+  assertion_ = assertion;
+
+  // This causes the handler thread to call WriteMinidumpWithException.
+  ReleaseSemaphore(handler_start_semaphore_, 1, NULL);
+
+  // Wait until WriteMinidumpWithException is done and collect its return value.
+  WaitForSingleObject(handler_finish_semaphore_, INFINITE);
+  bool status = handler_return_value_;
+
+  // Clean up.
+  requesting_thread_id_ = 0;
+  exception_info_ = NULL;
+  assertion_ = NULL;
+
+  LeaveCriticalSection(&handler_critical_section_);
+
+  return status;
+}
+
+bool ExceptionHandler::WriteMinidump() {
+  // Make up an exception record for the current thread and CPU context
+  // to make it possible for the crash processor to classify these
+  // as do regular crashes, and to make it humane for developers to
+  // analyze them.
+  EXCEPTION_RECORD exception_record = {};
+  CONTEXT exception_context = {};
+  EXCEPTION_POINTERS exception_ptrs = { &exception_record, &exception_context };
+
+  ::RtlCaptureContext(&exception_context);
+  exception_record.ExceptionCode = STATUS_NONCONTINUABLE_EXCEPTION;
+
+  return WriteMinidumpForException(&exception_ptrs);
+}
+
+bool ExceptionHandler::WriteMinidumpForException(EXCEPTION_POINTERS* exinfo) {
+  // In case of out-of-process dump generation, directly call
+  // WriteMinidumpWithException since there is no separate thread running.
+  if (IsOutOfProcess()) {
+    return WriteMinidumpWithException(GetCurrentThreadId(),
+                                      exinfo,
+                                      NULL);
+  }
+
+  bool success = WriteMinidumpOnHandlerThread(exinfo, NULL);
+  UpdateNextID();
+  return success;
+}
+
+// static
+bool ExceptionHandler::WriteMinidump(const wstring &dump_path,
+                                     MinidumpCallback callback,
+                                     void* callback_context) {
+  ExceptionHandler handler(dump_path, NULL, callback, callback_context,
+                           HANDLER_NONE);
+  return handler.WriteMinidump();
+}
+
+bool ExceptionHandler::WriteMinidumpWithException(
+    DWORD requesting_thread_id,
+    EXCEPTION_POINTERS* exinfo,
+    MDRawAssertionInfo* assertion) {
+  // Give user code a chance to approve or prevent writing a minidump.  If the
+  // filter returns false, don't handle the exception at all.  If this method
+  // was called as a result of an exception, returning false will cause
+  // HandleException to call any previous handler or return
+  // EXCEPTION_CONTINUE_SEARCH on the exception thread, allowing it to appear
+  // as though this handler were not present at all.
+  if (filter_ && !filter_(callback_context_, exinfo, assertion)) {
+    return false;
+  }
+
+  bool success = false;
+  if (IsOutOfProcess()) {
+    success = crash_generation_client_->RequestDump(exinfo, assertion);
+  } else {
+    if (minidump_write_dump_) {
+      HANDLE dump_file = CreateFile(next_minidump_path_c_,
+                                    GENERIC_WRITE,
+                                    0,  // no sharing
+                                    NULL,
+                                    CREATE_NEW,  // fail if exists
+                                    FILE_ATTRIBUTE_NORMAL,
+                                    NULL);
+      if (dump_file != INVALID_HANDLE_VALUE) {
+        MINIDUMP_EXCEPTION_INFORMATION except_info;
+        except_info.ThreadId = requesting_thread_id;
+        except_info.ExceptionPointers = exinfo;
+        except_info.ClientPointers = FALSE;
+
+        // Add an MDRawBreakpadInfo stream to the minidump, to provide
+        // additional information about the exception handler to the Breakpad
+        // processor. The information will help the processor determine which
+        // threads are relevant.  The Breakpad processor does not require this
+        // information but can function better with Breakpad-generated dumps
+        // when it is present. The native debugger is not harmed by the
+        // presence of this information.
+        MDRawBreakpadInfo breakpad_info;
+        breakpad_info.validity = MD_BREAKPAD_INFO_VALID_DUMP_THREAD_ID |
+                               MD_BREAKPAD_INFO_VALID_REQUESTING_THREAD_ID;
+        breakpad_info.dump_thread_id = GetCurrentThreadId();
+        breakpad_info.requesting_thread_id = requesting_thread_id;
+
+        // Leave room in user_stream_array for a possible assertion info stream.
+        MINIDUMP_USER_STREAM user_stream_array[2];
+        user_stream_array[0].Type = MD_BREAKPAD_INFO_STREAM;
+        user_stream_array[0].BufferSize = sizeof(breakpad_info);
+        user_stream_array[0].Buffer = &breakpad_info;
+
+        MINIDUMP_USER_STREAM_INFORMATION user_streams;
+        user_streams.UserStreamCount = 1;
+        user_streams.UserStreamArray = user_stream_array;
+
+        if (assertion) {
+          user_stream_array[1].Type = MD_ASSERTION_INFO_STREAM;
+          user_stream_array[1].BufferSize = sizeof(MDRawAssertionInfo);
+          user_stream_array[1].Buffer = assertion;
+          ++user_streams.UserStreamCount;
+        }
+
+        MINIDUMP_CALLBACK_INFORMATION callback;
+        MinidumpCallbackContext context;
+        MINIDUMP_CALLBACK_INFORMATION* callback_pointer = NULL;
+        // Older versions of DbgHelp.dll don't correctly put the memory around
+        // the faulting instruction pointer into the minidump. This
+        // callback will ensure that it gets included.
+        if (exinfo) {
+          // Find a memory region of 256 bytes centered on the
+          // faulting instruction pointer.
+          const ULONG64 instruction_pointer = 
+#if defined(_M_IX86)
+            exinfo->ContextRecord->Eip;
+#elif defined(_M_AMD64)
+            exinfo->ContextRecord->Rip;
+#else
+#error Unsupported platform
+#endif
+
+          MEMORY_BASIC_INFORMATION info;
+          if (VirtualQuery(reinterpret_cast<LPCVOID>(instruction_pointer),
+                           &info,
+                           sizeof(MEMORY_BASIC_INFORMATION)) != 0 &&
+              info.State == MEM_COMMIT) {
+            // Attempt to get 128 bytes before and after the instruction
+            // pointer, but settle for whatever's available up to the
+            // boundaries of the memory region.
+            const ULONG64 kIPMemorySize = 256;
+            context.memory_base =
+              (std::max)(reinterpret_cast<ULONG64>(info.BaseAddress),
+                       instruction_pointer - (kIPMemorySize / 2));
+            ULONG64 end_of_range =
+              (std::min)(instruction_pointer + (kIPMemorySize / 2),
+                       reinterpret_cast<ULONG64>(info.BaseAddress)
+                       + info.RegionSize);
+            context.memory_size =
+                static_cast<ULONG>(end_of_range - context.memory_base);
+
+            context.finished = false;
+            callback.CallbackRoutine = MinidumpWriteDumpCallback;
+            callback.CallbackParam = reinterpret_cast<void*>(&context);
+            callback_pointer = &callback;
+          }
+        }
+
+        // The explicit comparison to TRUE avoids a warning (C4800).
+        success = (minidump_write_dump_(GetCurrentProcess(),
+                                        GetCurrentProcessId(),
+                                        dump_file,
+                                        dump_type_,
+                                        exinfo ? &except_info : NULL,
+                                        &user_streams,
+                                        callback_pointer) == TRUE);
+
+        CloseHandle(dump_file);
+      }
+    }
+  }
+
+  if (callback_) {
+    // TODO(munjal): In case of out-of-process dump generation, both
+    // dump_path_c_ and next_minidump_id_ will be NULL. For out-of-process
+    // scenario, the server process ends up creating the dump path and dump
+    // id so they are not known to the client.
+    success = callback_(dump_path_c_, next_minidump_id_c_, callback_context_,
+                        exinfo, assertion, success);
+  }
+
+  return success;
+}
+
+// static
+BOOL CALLBACK ExceptionHandler::MinidumpWriteDumpCallback(
+    PVOID context,
+    const PMINIDUMP_CALLBACK_INPUT callback_input,
+    PMINIDUMP_CALLBACK_OUTPUT callback_output) {
+  switch (callback_input->CallbackType) {
+  case MemoryCallback: {
+    MinidumpCallbackContext* callback_context =
+        reinterpret_cast<MinidumpCallbackContext*>(context);
+    if (callback_context->finished)
+      return FALSE;
+
+    // Include the specified memory region.
+    callback_output->MemoryBase = callback_context->memory_base;
+    callback_output->MemorySize = callback_context->memory_size;
+    callback_context->finished = true;
+    return TRUE;
+  }
+    
+    // Include all modules.
+  case IncludeModuleCallback:
+  case ModuleCallback:
+    return TRUE;
+
+    // Include all threads.
+  case IncludeThreadCallback:
+  case ThreadCallback:
+    return TRUE;
+
+    // Stop receiving cancel callbacks.
+  case CancelCallback:
+    callback_output->CheckCancel = FALSE;
+    callback_output->Cancel = FALSE;
+    return TRUE;
+  }
+  // Ignore other callback types.
+  return FALSE;
+}
+
+void ExceptionHandler::UpdateNextID() {
+  assert(uuid_create_);
+  UUID id = {0};
+  if (uuid_create_) {
+    uuid_create_(&id);
+  }
+  next_minidump_id_ = GUIDString::GUIDToWString(&id);
+  next_minidump_id_c_ = next_minidump_id_.c_str();
+
+  wchar_t minidump_path[MAX_PATH];
+  swprintf(minidump_path, MAX_PATH, L"%s\\%s.dmp",
+           dump_path_c_, next_minidump_id_c_);
+
+  // remove when VC++7.1 is no longer supported
+  minidump_path[MAX_PATH - 1] = L'\0';
+
+  next_minidump_path_ = minidump_path;
+  next_minidump_path_c_ = next_minidump_path_.c_str();
+}
+
+}  // namespace google_breakpad
diff --git a/3rdParty/Breakpad/src/client/windows/handler/exception_handler.h b/3rdParty/Breakpad/src/client/windows/handler/exception_handler.h
new file mode 100644
index 0000000..09f5177
--- /dev/null
+++ b/3rdParty/Breakpad/src/client/windows/handler/exception_handler.h
@@ -0,0 +1,437 @@
+// 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.
+
+// ExceptionHandler can write a minidump file when an exception occurs,
+// or when WriteMinidump() is called explicitly by your program.
+//
+// To have the exception handler write minidumps when an uncaught exception
+// (crash) occurs, you should create an instance early in the execution
+// of your program, and keep it around for the entire time you want to
+// have crash handling active (typically, until shutdown).
+//
+// If you want to write minidumps without installing the exception handler,
+// you can create an ExceptionHandler with install_handler set to false,
+// then call WriteMinidump.  You can also use this technique if you want to
+// use different minidump callbacks for different call sites.
+//
+// In either case, a callback function is called when a minidump is written,
+// which receives the unqiue id of the minidump.  The caller can use this
+// id to collect and write additional application state, and to launch an
+// external crash-reporting application.
+//
+// It is important that creation and destruction of ExceptionHandler objects
+// be nested cleanly, when using install_handler = true.
+// Avoid the following pattern:
+//   ExceptionHandler *e = new ExceptionHandler(...);
+//   ExceptionHandler *f = new ExceptionHandler(...);
+//   delete e;
+// This will put the exception filter stack into an inconsistent state.
+
+#ifndef CLIENT_WINDOWS_HANDLER_EXCEPTION_HANDLER_H__
+#define CLIENT_WINDOWS_HANDLER_EXCEPTION_HANDLER_H__
+
+#include <stdlib.h>
+#include <Windows.h>
+#include <DbgHelp.h>
+#include <rpc.h>
+
+#pragma warning( push )
+// Disable exception handler warnings.
+#pragma warning( disable : 4530 )
+
+#include <string>
+#include <vector>
+
+#include "client/windows/common/ipc_protocol.h"
+#include "client/windows/crash_generation/crash_generation_client.h"
+#include "google_breakpad/common/minidump_format.h"
+#include "processor/scoped_ptr.h"
+
+namespace google_breakpad {
+
+using std::vector;
+using std::wstring;
+
+class ExceptionHandler {
+ public:
+  // A callback function to run before Breakpad performs any substantial
+  // processing of an exception.  A FilterCallback is called before writing
+  // a minidump.  context is the parameter supplied by the user as
+  // callback_context when the handler was created.  exinfo points to the
+  // exception record, if any; assertion points to assertion information,
+  // if any.
+  //
+  // If a FilterCallback returns true, Breakpad will continue processing,
+  // attempting to write a minidump.  If a FilterCallback returns false,
+  // Breakpad will immediately report the exception as unhandled without
+  // writing a minidump, allowing another handler the opportunity to handle it.
+  typedef bool (*FilterCallback)(void* context, EXCEPTION_POINTERS* exinfo,
+                                 MDRawAssertionInfo* assertion);
+
+  // A callback function to run after the minidump has been written.
+  // minidump_id is a unique id for the dump, so the minidump
+  // file is <dump_path>\<minidump_id>.dmp.  context is the parameter supplied
+  // by the user as callback_context when the handler was created.  exinfo
+  // points to the exception record, or NULL if no exception occurred.
+  // succeeded indicates whether a minidump file was successfully written.
+  // assertion points to information about an assertion if the handler was
+  // invoked by an assertion.
+  //
+  // If an exception occurred and the callback returns true, Breakpad will treat
+  // the exception as fully-handled, suppressing any other handlers from being
+  // notified of the exception.  If the callback returns false, Breakpad will
+  // treat the exception as unhandled, and allow another handler to handle it.
+  // If there are no other handlers, Breakpad will report the exception to the
+  // system as unhandled, allowing a debugger or native crash dialog the
+  // opportunity to handle the exception.  Most callback implementations
+  // should normally return the value of |succeeded|, or when they wish to
+  // not report an exception of handled, false.  Callbacks will rarely want to
+  // return true directly (unless |succeeded| is true).
+  //
+  // For out-of-process dump generation, dump path and minidump ID will always
+  // be NULL. In case of out-of-process dump generation, the dump path and
+  // minidump id are controlled by the server process and are not communicated
+  // back to the crashing process.
+  typedef bool (*MinidumpCallback)(const wchar_t* dump_path,
+                                   const wchar_t* minidump_id,
+                                   void* context,
+                                   EXCEPTION_POINTERS* exinfo,
+                                   MDRawAssertionInfo* assertion,
+                                   bool succeeded);
+
+  // HandlerType specifies which types of handlers should be installed, if
+  // any.  Use HANDLER_NONE for an ExceptionHandler that remains idle,
+  // without catching any failures on its own.  This type of handler may
+  // still be triggered by calling WriteMinidump.  Otherwise, use a
+  // combination of the other HANDLER_ values, or HANDLER_ALL to install
+  // all handlers.
+  enum HandlerType {
+    HANDLER_NONE = 0,
+    HANDLER_EXCEPTION = 1 << 0,          // SetUnhandledExceptionFilter
+    HANDLER_INVALID_PARAMETER = 1 << 1,  // _set_invalid_parameter_handler
+    HANDLER_PURECALL = 1 << 2,           // _set_purecall_handler
+    HANDLER_ALL = HANDLER_EXCEPTION |
+                  HANDLER_INVALID_PARAMETER |
+                  HANDLER_PURECALL
+  };
+
+  // Creates a new ExceptionHandler instance to handle writing minidumps.
+  // Before writing a minidump, the optional filter callback will be called.
+  // Its return value determines whether or not Breakpad should write a
+  // minidump.  Minidump files will be written to dump_path, and the optional
+  // callback is called after writing the dump file, as described above.
+  // handler_types specifies the types of handlers that should be installed.
+  ExceptionHandler(const wstring& dump_path,
+                   FilterCallback filter,
+                   MinidumpCallback callback,
+                   void* callback_context,
+                   int handler_types);
+
+  // Creates a new ExceptionHandler instance that can attempt to perform
+  // out-of-process dump generation if pipe_name is not NULL. If pipe_name is
+  // NULL, or if out-of-process dump generation registration step fails,
+  // in-process dump generation will be used. This also allows specifying
+  // the dump type to generate.
+  ExceptionHandler(const wstring& dump_path,
+                   FilterCallback filter,
+                   MinidumpCallback callback,
+                   void* callback_context,
+                   int handler_types,
+                   MINIDUMP_TYPE dump_type,
+                   const wchar_t* pipe_name,
+                   const CustomClientInfo* custom_info);
+
+  // As above, creates a new ExceptionHandler instance to perform
+  // out-of-process dump generation if the given pipe_handle is not NULL.
+  ExceptionHandler(const wstring& dump_path,
+                   FilterCallback filter,
+                   MinidumpCallback callback,
+                   void* callback_context,
+                   int handler_types,
+                   MINIDUMP_TYPE dump_type,
+                   HANDLE pipe_handle,
+                   const CustomClientInfo* custom_info);
+
+  ~ExceptionHandler();
+
+  // Get and set the minidump path.
+  wstring dump_path() const { return dump_path_; }
+  void set_dump_path(const wstring &dump_path) {
+    dump_path_ = dump_path;
+    dump_path_c_ = dump_path_.c_str();
+    UpdateNextID();  // Necessary to put dump_path_ in next_minidump_path_.
+  }
+
+  // Requests that a previously reported crash be uploaded.
+  bool RequestUpload(DWORD crash_id);
+
+  // Writes a minidump immediately.  This can be used to capture the
+  // execution state independently of a crash.  Returns true on success.
+  bool WriteMinidump();
+
+  // Writes a minidump immediately, with the user-supplied exception
+  // information.
+  bool WriteMinidumpForException(EXCEPTION_POINTERS* exinfo);
+
+  // Convenience form of WriteMinidump which does not require an
+  // ExceptionHandler instance.
+  static bool WriteMinidump(const wstring &dump_path,
+                            MinidumpCallback callback, void* callback_context);
+
+  // Get the thread ID of the thread requesting the dump (either the exception
+  // thread or any other thread that called WriteMinidump directly).  This
+  // may be useful if you want to include additional thread state in your
+  // dumps.
+  DWORD get_requesting_thread_id() const { return requesting_thread_id_; }
+
+  // Controls behavior of EXCEPTION_BREAKPOINT and EXCEPTION_SINGLE_STEP.
+  bool get_handle_debug_exceptions() const { return handle_debug_exceptions_; }
+  void set_handle_debug_exceptions(bool handle_debug_exceptions) {
+    handle_debug_exceptions_ = handle_debug_exceptions;
+  }
+
+  // Returns whether out-of-process dump generation is used or not.
+  bool IsOutOfProcess() const { return crash_generation_client_.get() != NULL; }
+
+ private:
+  friend class AutoExceptionHandler;
+
+  // Initializes the instance with given values.
+  void Initialize(const wstring& dump_path,
+                  FilterCallback filter,
+                  MinidumpCallback callback,
+                  void* callback_context,
+                  int handler_types,
+                  MINIDUMP_TYPE dump_type,
+                  const wchar_t* pipe_name,
+                  HANDLE pipe_handle,
+                  const CustomClientInfo* custom_info);
+
+  // Function pointer type for MiniDumpWriteDump, which is looked up
+  // dynamically.
+  typedef BOOL (WINAPI *MiniDumpWriteDump_type)(
+      HANDLE hProcess,
+      DWORD dwPid,
+      HANDLE hFile,
+      MINIDUMP_TYPE DumpType,
+      CONST PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam,
+      CONST PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam,
+      CONST PMINIDUMP_CALLBACK_INFORMATION CallbackParam);
+
+  // Function pointer type for UuidCreate, which is looked up dynamically.
+  typedef RPC_STATUS (RPC_ENTRY *UuidCreate_type)(UUID* Uuid);
+
+  // Runs the main loop for the exception handler thread.
+  static DWORD WINAPI ExceptionHandlerThreadMain(void* lpParameter);
+
+  // Called on the exception thread when an unhandled exception occurs.
+  // Signals the exception handler thread to handle the exception.
+  static LONG WINAPI HandleException(EXCEPTION_POINTERS* exinfo);
+
+#if _MSC_VER >= 1400  // MSVC 2005/8
+  // This function will be called by some CRT functions when they detect
+  // that they were passed an invalid parameter.  Note that in _DEBUG builds,
+  // the CRT may display an assertion dialog before calling this function,
+  // and the function will not be called unless the assertion dialog is
+  // dismissed by clicking "Ignore."
+  static void HandleInvalidParameter(const wchar_t* expression,
+                                     const wchar_t* function,
+                                     const wchar_t* file,
+                                     unsigned int line,
+                                     uintptr_t reserved);
+#endif  // _MSC_VER >= 1400
+
+  // This function will be called by the CRT when a pure virtual
+  // function is called.
+  static void HandlePureVirtualCall();
+
+  // This is called on the exception thread or on another thread that
+  // the user wishes to produce a dump from.  It calls
+  // WriteMinidumpWithException on the handler thread, avoiding stack
+  // overflows and inconsistent dumps due to writing the dump from
+  // the exception thread.  If the dump is requested as a result of an
+  // exception, exinfo contains exception information, otherwise, it
+  // is NULL.  If the dump is requested as a result of an assertion
+  // (such as an invalid parameter being passed to a CRT function),
+  // assertion contains data about the assertion, otherwise, it is NULL.
+  bool WriteMinidumpOnHandlerThread(EXCEPTION_POINTERS* exinfo,
+                                    MDRawAssertionInfo* assertion);
+
+  // This function does the actual writing of a minidump.  It is called
+  // on the handler thread.  requesting_thread_id is the ID of the thread
+  // that requested the dump.  If the dump is requested as a result of
+  // an exception, exinfo contains exception information, otherwise,
+  // it is NULL.
+  bool WriteMinidumpWithException(DWORD requesting_thread_id,
+                                  EXCEPTION_POINTERS* exinfo,
+                                  MDRawAssertionInfo* assertion);
+
+  // This function is used as a callback when calling MinidumpWriteDump,
+  // in order to add additional memory regions to the dump.
+  static BOOL CALLBACK MinidumpWriteDumpCallback(
+      PVOID context,
+      const PMINIDUMP_CALLBACK_INPUT callback_input,
+      PMINIDUMP_CALLBACK_OUTPUT callback_output);
+
+  // Generates a new ID and stores it in next_minidump_id_, and stores the
+  // path of the next minidump to be written in next_minidump_path_.
+  void UpdateNextID();
+
+  FilterCallback filter_;
+  MinidumpCallback callback_;
+  void* callback_context_;
+
+  scoped_ptr<CrashGenerationClient> crash_generation_client_;
+
+  // The directory in which a minidump will be written, set by the dump_path
+  // argument to the constructor, or set_dump_path.
+  wstring dump_path_;
+
+  // The basename of the next minidump to be written, without the extension.
+  wstring next_minidump_id_;
+
+  // The full pathname of the next minidump to be written, including the file
+  // extension.
+  wstring next_minidump_path_;
+
+  // Pointers to C-string representations of the above.  These are set when
+  // the above wstring versions are set in order to avoid calling c_str during
+  // an exception, as c_str may attempt to allocate heap memory.  These
+  // pointers are not owned by the ExceptionHandler object, but their lifetimes
+  // should be equivalent to the lifetimes of the associated wstring, provided
+  // that the wstrings are not altered.
+  const wchar_t* dump_path_c_;
+  const wchar_t* next_minidump_id_c_;
+  const wchar_t* next_minidump_path_c_;
+
+  HMODULE dbghelp_module_;
+  MiniDumpWriteDump_type minidump_write_dump_;
+  MINIDUMP_TYPE dump_type_;
+
+  HMODULE rpcrt4_module_;
+  UuidCreate_type uuid_create_;
+
+  // Tracks the handler types that were installed according to the
+  // handler_types constructor argument.
+  int handler_types_;
+
+  // When installed_handler_ is true, previous_filter_ is the unhandled
+  // exception filter that was set prior to installing ExceptionHandler as
+  // the unhandled exception filter and pointing it to |this|.  NULL indicates
+  // that there is no previous unhandled exception filter.
+  LPTOP_LEVEL_EXCEPTION_FILTER previous_filter_;
+
+#if _MSC_VER >= 1400  // MSVC 2005/8
+  // Beginning in VC 8, the CRT provides an invalid parameter handler that will
+  // be called when some CRT functions are passed invalid parameters.  In
+  // earlier CRTs, the same conditions would cause unexpected behavior or
+  // crashes.
+  _invalid_parameter_handler previous_iph_;
+#endif  // _MSC_VER >= 1400
+
+  // The CRT allows you to override the default handler for pure
+  // virtual function calls.
+  _purecall_handler previous_pch_;
+
+  // The exception handler thread.
+  HANDLE handler_thread_;
+
+  // True if the exception handler is being destroyed.
+  // Starting with MSVC 2005, Visual C has stronger guarantees on volatile vars.
+  // It has release semantics on write and acquire semantics on reads.
+  // See the msdn documentation.
+  volatile bool is_shutdown_;
+
+  // The critical section enforcing the requirement that only one exception be
+  // handled by a handler at a time.
+  CRITICAL_SECTION handler_critical_section_;
+
+  // Semaphores used to move exception handling between the exception thread
+  // and the handler thread.  handler_start_semaphore_ is signalled by the
+  // exception thread to wake up the handler thread when an exception occurs.
+  // handler_finish_semaphore_ is signalled by the handler thread to wake up
+  // the exception thread when handling is complete.
+  HANDLE handler_start_semaphore_;
+  HANDLE handler_finish_semaphore_;
+
+  // The next 2 fields contain data passed from the requesting thread to
+  // the handler thread.
+
+  // The thread ID of the thread requesting the dump (either the exception
+  // thread or any other thread that called WriteMinidump directly).
+  DWORD requesting_thread_id_;
+
+  // The exception info passed to the exception handler on the exception
+  // thread, if an exception occurred.  NULL for user-requested dumps.
+  EXCEPTION_POINTERS* exception_info_;
+
+  // If the handler is invoked due to an assertion, this will contain a
+  // pointer to the assertion information.  It is NULL at other times.
+  MDRawAssertionInfo* assertion_;
+
+  // The return value of the handler, passed from the handler thread back to
+  // the requesting thread.
+  bool handler_return_value_;
+
+  // If true, the handler will intercept EXCEPTION_BREAKPOINT and
+  // EXCEPTION_SINGLE_STEP exceptions.  Leave this false (the default)
+  // to not interfere with debuggers.
+  bool handle_debug_exceptions_;
+
+  // A stack of ExceptionHandler objects that have installed unhandled
+  // exception filters.  This vector is used by HandleException to determine
+  // which ExceptionHandler object to route an exception to.  When an
+  // ExceptionHandler is created with install_handler true, it will append
+  // itself to this list.
+  static vector<ExceptionHandler*>* handler_stack_;
+
+  // The index of the ExceptionHandler in handler_stack_ that will handle the
+  // next exception.  Note that 0 means the last entry in handler_stack_, 1
+  // means the next-to-last entry, and so on.  This is used by HandleException
+  // to support multiple stacked Breakpad handlers.
+  static LONG handler_stack_index_;
+
+  // handler_stack_critical_section_ guards operations on handler_stack_ and
+  // handler_stack_index_. The critical section is initialized by the
+  // first instance of the class and destroyed by the last instance of it.
+  static CRITICAL_SECTION handler_stack_critical_section_;
+
+  // The number of instances of this class.
+  volatile static LONG instance_count_;
+
+  // disallow copy ctor and operator=
+  explicit ExceptionHandler(const ExceptionHandler &);
+  void operator=(const ExceptionHandler &);
+};
+
+}  // namespace google_breakpad
+
+#pragma warning( pop )
+
+#endif  // CLIENT_WINDOWS_HANDLER_EXCEPTION_HANDLER_H__
diff --git a/3rdParty/Breakpad/src/common/byte_cursor.h b/3rdParty/Breakpad/src/common/byte_cursor.h
new file mode 100644
index 0000000..accd54e
--- /dev/null
+++ b/3rdParty/Breakpad/src/common/byte_cursor.h
@@ -0,0 +1,265 @@
+// -*- mode: c++ -*-
+
+// 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>
+
+// byte_cursor.h: Classes for parsing values from a buffer of bytes.
+// The ByteCursor class provides a convenient interface for reading
+// fixed-size integers of arbitrary endianness, being thorough about
+// checking for buffer overruns.
+
+#ifndef COMMON_BYTE_CURSOR_H_
+#define COMMON_BYTE_CURSOR_H_
+
+#include <assert.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <string>
+
+#include "common/using_std_string.h"
+
+namespace google_breakpad {
+
+// A buffer holding a series of bytes.
+struct ByteBuffer {
+  ByteBuffer() : start(0), end(0) { }
+  ByteBuffer(const uint8_t *set_start, size_t set_size)
+      : start(set_start), end(set_start + set_size) { }
+  ~ByteBuffer() { };
+
+  // Equality operators. Useful in unit tests, and when we're using
+  // ByteBuffers to refer to regions of a larger buffer.
+  bool operator==(const ByteBuffer &that) const {
+    return start == that.start && end == that.end;
+  }
+  bool operator!=(const ByteBuffer &that) const {
+    return start != that.start || end != that.end;
+  }
+
+  // Not C++ style guide compliant, but this definitely belongs here.
+  size_t Size() const {
+    assert(start <= end);
+    return end - start;
+  }
+
+  const uint8_t *start, *end;
+};
+
+// A cursor pointing into a ByteBuffer that can parse numbers of various
+// widths and representations, strings, and data blocks, advancing through
+// the buffer as it goes. All ByteCursor operations check that accesses
+// haven't gone beyond the end of the enclosing ByteBuffer.
+class ByteCursor {
+ public:
+  // Create a cursor reading bytes from the start of BUFFER. By default, the
+  // cursor reads multi-byte values in little-endian form.
+  ByteCursor(const ByteBuffer *buffer, bool big_endian = false)
+      : buffer_(buffer), here_(buffer->start), 
+        big_endian_(big_endian), complete_(true) { }
+
+  // Accessor and setter for this cursor's endianness flag.
+  bool big_endian() const { return big_endian_; }
+  void set_big_endian(bool big_endian) { big_endian_ = big_endian; }
+
+  // Accessor and setter for this cursor's current position. The setter
+  // returns a reference to this cursor.
+  const uint8_t *here() const { return here_; }
+  ByteCursor &set_here(const uint8_t *here) {
+    assert(buffer_->start <= here && here <= buffer_->end);
+    here_ = here;
+    return *this;
+  }
+
+  // Return the number of bytes available to read at the cursor.
+  size_t Available() const { return size_t(buffer_->end - here_); }
+
+  // Return true if this cursor is at the end of its buffer.
+  bool AtEnd() const { return Available() == 0; }
+
+  // When used as a boolean value this cursor converts to true if all
+  // prior reads have been completed, or false if we ran off the end
+  // of the buffer.
+  operator bool() const { return complete_; }
+
+  // Read a SIZE-byte integer at this cursor, signed if IS_SIGNED is true,
+  // unsigned otherwise, using the cursor's established endianness, and set
+  // *RESULT to the number. If we read off the end of our buffer, clear
+  // this cursor's complete_ flag, and store a dummy value in *RESULT.
+  // Return a reference to this cursor.
+  template<typename T>
+  ByteCursor &Read(size_t size, bool is_signed, T *result) {
+    if (CheckAvailable(size)) {
+      T v = 0;
+      if (big_endian_) {
+        for (size_t i = 0; i < size; i++)
+          v = (v << 8) + here_[i];
+      } else {
+        // This loop condition looks weird, but size_t is unsigned, so
+        // decrementing i after it is zero yields the largest size_t value.
+        for (size_t i = size - 1; i < size; i--)
+          v = (v << 8) + here_[i];
+      }
+      if (is_signed && size < sizeof(T)) {
+        size_t sign_bit = (T)1 << (size * 8 - 1);
+        v = (v ^ sign_bit) - sign_bit;
+      }
+      here_ += size;
+      *result = v;
+    } else {
+      *result = (T) 0xdeadbeef;
+    }
+    return *this;
+  }
+
+  // Read an integer, using the cursor's established endianness and
+  // *RESULT's size and signedness, and set *RESULT to the number. If we
+  // read off the end of our buffer, clear this cursor's complete_ flag.
+  // Return a reference to this cursor.
+  template<typename T>
+  ByteCursor &operator>>(T &result) {
+    bool T_is_signed = (T)-1 < 0;
+    return Read(sizeof(T), T_is_signed, &result); 
+  }
+
+  // Copy the SIZE bytes at the cursor to BUFFER, and advance this
+  // cursor to the end of them. If we read off the end of our buffer,
+  // clear this cursor's complete_ flag, and set *POINTER to NULL.
+  // Return a reference to this cursor.
+  ByteCursor &Read(uint8_t *buffer, size_t size) {
+    if (CheckAvailable(size)) {
+      memcpy(buffer, here_, size);
+      here_ += size;
+    }
+    return *this;
+  }
+
+  // Set STR to a copy of the '\0'-terminated string at the cursor. If the
+  // byte buffer does not contain a terminating zero, clear this cursor's
+  // complete_ flag, and set STR to the empty string. Return a reference to
+  // this cursor.
+  ByteCursor &CString(string *str) {
+    const uint8_t *end
+      = static_cast<const uint8_t *>(memchr(here_, '\0', Available()));
+    if (end) {
+      str->assign(reinterpret_cast<const char *>(here_), end - here_);
+      here_ = end + 1;
+    } else {
+      str->clear();
+      here_ = buffer_->end;
+      complete_ = false;
+    }
+    return *this;
+  }
+
+  // Like CString(STR), but extract the string from a fixed-width buffer
+  // LIMIT bytes long, which may or may not contain a terminating '\0'
+  // byte. Specifically:
+  //
+  // - If there are not LIMIT bytes available at the cursor, clear the
+  //   cursor's complete_ flag and set STR to the empty string.
+  //
+  // - Otherwise, if the LIMIT bytes at the cursor contain any '\0'
+  //   characters, set *STR to a copy of the bytes before the first '\0',
+  //   and advance the cursor by LIMIT bytes.
+  //   
+  // - Otherwise, set *STR to a copy of those LIMIT bytes, and advance the
+  //   cursor by LIMIT bytes.
+  ByteCursor &CString(string *str, size_t limit) {
+    if (CheckAvailable(limit)) {
+      const uint8_t *end
+        = static_cast<const uint8_t *>(memchr(here_, '\0', limit));
+      if (end)
+        str->assign(reinterpret_cast<const char *>(here_), end - here_);
+      else
+        str->assign(reinterpret_cast<const char *>(here_), limit);
+      here_ += limit;
+    } else {
+      str->clear();
+    }
+    return *this;
+  }
+
+  // Set *POINTER to point to the SIZE bytes at the cursor, and advance
+  // this cursor to the end of them. If SIZE is omitted, don't move the
+  // cursor. If we read off the end of our buffer, clear this cursor's
+  // complete_ flag, and set *POINTER to NULL. Return a reference to this
+  // cursor.
+  ByteCursor &PointTo(const uint8_t **pointer, size_t size = 0) {
+    if (CheckAvailable(size)) {
+      *pointer = here_;
+      here_ += size;
+    } else {
+      *pointer = NULL;
+    }
+    return *this;
+  }
+
+  // Skip SIZE bytes at the cursor. If doing so would advance us off
+  // the end of our buffer, clear this cursor's complete_ flag, and
+  // set *POINTER to NULL. Return a reference to this cursor.
+  ByteCursor &Skip(size_t size) {
+    if (CheckAvailable(size))
+      here_ += size;
+    return *this;
+  }
+
+ private:
+  // If there are at least SIZE bytes available to read from the buffer,
+  // return true. Otherwise, set here_ to the end of the buffer, set
+  // complete_ to false, and return false.
+  bool CheckAvailable(size_t size) {
+    if (Available() >= size) {
+      return true;
+    } else {
+      here_ = buffer_->end;
+      complete_ = false;
+      return false;
+    }
+  }
+
+  // The buffer we're reading bytes from.
+  const ByteBuffer *buffer_;
+
+  // The next byte within buffer_ that we'll read.
+  const uint8_t *here_;
+
+  // True if we should read numbers in big-endian form; false if we
+  // should read in little-endian form.
+  bool big_endian_;
+
+  // True if we've been able to read all we've been asked to.
+  bool complete_;
+};
+
+}  // namespace google_breakpad
+
+#endif  // COMMON_BYTE_CURSOR_H_
diff --git a/3rdParty/Breakpad/src/common/convert_UTF.c b/3rdParty/Breakpad/src/common/convert_UTF.c
new file mode 100644
index 0000000..80178d3
--- /dev/null
+++ b/3rdParty/Breakpad/src/common/convert_UTF.c
@@ -0,0 +1,533 @@
+/*
+ * Copyright 2001-2004 Unicode, Inc.
+ *
+ * Disclaimer
+ *
+ * This source code is provided as is by Unicode, Inc. No claims are
+ * made as to fitness for any particular purpose. No warranties of any
+ * kind are expressed or implied. The recipient agrees to determine
+ * applicability of information provided. If this file has been
+ * purchased on magnetic or optical media from Unicode, Inc., the
+ * sole remedy for any claim will be exchange of defective media
+ * within 90 days of receipt.
+ *
+ * Limitations on Rights to Redistribute This Code
+ *
+ * Unicode, Inc. hereby grants the right to freely use the information
+ * supplied in this file in the creation of products supporting the
+ * Unicode Standard, and to make copies of this file in any form
+ * for internal or external distribution as long as this notice
+ * remains attached.
+ */
+
+/* ---------------------------------------------------------------------
+
+Conversions between UTF32, UTF-16, and UTF-8. Source code file.
+Author: Mark E. Davis, 1994.
+Rev History: Rick McGowan, fixes & updates May 2001.
+Sept 2001: fixed const & error conditions per
+mods suggested by S. Parent & A. Lillich.
+June 2002: Tim Dodd added detection and handling of incomplete
+source sequences, enhanced error detection, added casts
+to eliminate compiler warnings.
+July 2003: slight mods to back out aggressive FFFE detection.
+Jan 2004: updated switches in from-UTF8 conversions.
+Oct 2004: updated to use UNI_MAX_LEGAL_UTF32 in UTF-32 conversions.
+
+See the header file "ConvertUTF.h" for complete documentation.
+
+------------------------------------------------------------------------ */
+
+
+#include "convert_UTF.h"
+#ifdef CVTUTF_DEBUG
+#include <stdio.h>
+#endif
+
+static const int halfShift  = 10; /* used for shifting by 10 bits */
+
+static const UTF32 halfBase = 0x0010000UL;
+static const UTF32 halfMask = 0x3FFUL;
+
+#define UNI_SUR_HIGH_START  (UTF32)0xD800
+#define UNI_SUR_HIGH_END    (UTF32)0xDBFF
+#define UNI_SUR_LOW_START   (UTF32)0xDC00
+#define UNI_SUR_LOW_END     (UTF32)0xDFFF
+#define false	   0
+#define true	    1
+
+/* --------------------------------------------------------------------- */
+
+ConversionResult ConvertUTF32toUTF16 (const UTF32** sourceStart, const UTF32* sourceEnd,
+                                      UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags) {
+  ConversionResult result = conversionOK;
+  const UTF32* source = *sourceStart;
+  UTF16* target = *targetStart;
+  while (source < sourceEnd) {
+    UTF32 ch;
+    if (target >= targetEnd) {
+	    result = targetExhausted; break;
+    }
+    ch = *source++;
+    if (ch <= UNI_MAX_BMP) { /* Target is a character <= 0xFFFF */
+	    /* UTF-16 surrogate values are illegal in UTF-32; 0xffff or 0xfffe are both reserved values */
+	    if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) {
+        if (flags == strictConversion) {
+          --source; /* return to the illegal value itself */
+          result = sourceIllegal;
+          break;
+        } else {
+          *target++ = UNI_REPLACEMENT_CHAR;
+        }
+	    } else {
+        *target++ = (UTF16)ch; /* normal case */
+	    }
+    } else if (ch > UNI_MAX_LEGAL_UTF32) {
+	    if (flags == strictConversion) {
+        result = sourceIllegal;
+	    } else {
+        *target++ = UNI_REPLACEMENT_CHAR;
+	    }
+    } else {
+	    /* target is a character in range 0xFFFF - 0x10FFFF. */
+	    if (target + 1 >= targetEnd) {
+        --source; /* Back up source pointer! */
+        result = targetExhausted; break;
+	    }
+	    ch -= halfBase;
+	    *target++ = (UTF16)((ch >> halfShift) + UNI_SUR_HIGH_START);
+	    *target++ = (UTF16)((ch & halfMask) + UNI_SUR_LOW_START);
+    }
+  }
+*sourceStart = source;
+*targetStart = target;
+return result;
+}
+
+/* --------------------------------------------------------------------- */
+
+ConversionResult ConvertUTF16toUTF32 (const UTF16** sourceStart, const UTF16* sourceEnd,
+                                      UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags) {
+  ConversionResult result = conversionOK;
+  const UTF16* source = *sourceStart;
+  UTF32* target = *targetStart;
+  UTF32 ch, ch2;
+  while (source < sourceEnd) {
+    const UTF16* oldSource = source; /*  In case we have to back up because of target overflow. */
+    ch = *source++;
+    /* If we have a surrogate pair, convert to UTF32 first. */
+    if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_HIGH_END) {
+	    /* If the 16 bits following the high surrogate are in the source buffer... */
+	    if (source < sourceEnd) {
+        ch2 = *source;
+        /* If it's a low surrogate, convert to UTF32. */
+        if (ch2 >= UNI_SUR_LOW_START && ch2 <= UNI_SUR_LOW_END) {
+          ch = ((ch - UNI_SUR_HIGH_START) << halfShift)
+          + (ch2 - UNI_SUR_LOW_START) + halfBase;
+          ++source;
+        } else if (flags == strictConversion) { /* it's an unpaired high surrogate */
+          --source; /* return to the illegal value itself */
+          result = sourceIllegal;
+          break;
+        }
+	    } else { /* We don't have the 16 bits following the high surrogate. */
+        --source; /* return to the high surrogate */
+        result = sourceExhausted;
+        break;
+	    }
+    } else if (flags == strictConversion) {
+	    /* UTF-16 surrogate values are illegal in UTF-32 */
+	    if (ch >= UNI_SUR_LOW_START && ch <= UNI_SUR_LOW_END) {
+        --source; /* return to the illegal value itself */
+        result = sourceIllegal;
+        break;
+	    }
+    }
+    if (target >= targetEnd) {
+	    source = oldSource; /* Back up source pointer! */
+	    result = targetExhausted; break;
+    }
+    *target++ = ch;
+  }
+  *sourceStart = source;
+  *targetStart = target;
+#ifdef CVTUTF_DEBUG
+  if (result == sourceIllegal) {
+    fprintf(stderr, "ConvertUTF16toUTF32 illegal seq 0x%04x,%04x\n", ch, ch2);
+    fflush(stderr);
+  }
+#endif
+  return result;
+}
+
+/* --------------------------------------------------------------------- */
+
+/*
+ * Index into the table below with the first byte of a UTF-8 sequence to
+ * get the number of trailing bytes that are supposed to follow it.
+ * Note that *legal* UTF-8 values can't have 4 or 5-bytes. The table is
+ * left as-is for anyone who may want to do such conversion, which was
+ * allowed in earlier algorithms.
+ */
+static const char trailingBytesForUTF8[256] = {
+  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+  1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+  2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5
+};
+
+/*
+ * Magic values subtracted from a buffer value during UTF8 conversion.
+ * This table contains as many values as there might be trailing bytes
+ * in a UTF-8 sequence.
+ */
+static const UTF32 offsetsFromUTF8[6] = { 0x00000000UL, 0x00003080UL, 0x000E2080UL,
+  0x03C82080UL, 0xFA082080UL, 0x82082080UL };
+
+/*
+ * Once the bits are split out into bytes of UTF-8, this is a mask OR-ed
+ * into the first byte, depending on how many bytes follow.  There are
+ * as many entries in this table as there are UTF-8 sequence types.
+ * (I.e., one byte sequence, two byte... etc.). Remember that sequencs
+ * for *legal* UTF-8 will be 4 or fewer bytes total.
+ */
+static const UTF8 firstByteMark[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
+
+/* --------------------------------------------------------------------- */
+
+/* The interface converts a whole buffer to avoid function-call overhead.
+* Constants have been gathered. Loops & conditionals have been removed as
+* much as possible for efficiency, in favor of drop-through switches.
+* (See "Note A" at the bottom of the file for equivalent code.)
+* If your compiler supports it, the "isLegalUTF8" call can be turned
+* into an inline function.
+*/
+
+/* --------------------------------------------------------------------- */
+
+ConversionResult ConvertUTF16toUTF8 (const UTF16** sourceStart, const UTF16* sourceEnd,
+                                     UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags) {
+  ConversionResult result = conversionOK;
+  const UTF16* source = *sourceStart;
+  UTF8* target = *targetStart;
+  while (source < sourceEnd) {
+    UTF32 ch;
+    unsigned short bytesToWrite = 0;
+    const UTF32 byteMask = 0xBF;
+    const UTF32 byteMark = 0x80;
+    const UTF16* oldSource = source; /* In case we have to back up because of target overflow. */
+    ch = *source++;
+    /* If we have a surrogate pair, convert to UTF32 first. */
+    if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_HIGH_END) {
+	    /* If the 16 bits following the high surrogate are in the source buffer... */
+	    if (source < sourceEnd) {
+        UTF32 ch2 = *source;
+        /* If it's a low surrogate, convert to UTF32. */
+        if (ch2 >= UNI_SUR_LOW_START && ch2 <= UNI_SUR_LOW_END) {
+          ch = ((ch - UNI_SUR_HIGH_START) << halfShift)
+          + (ch2 - UNI_SUR_LOW_START) + halfBase;
+          ++source;
+        } else if (flags == strictConversion) { /* it's an unpaired high surrogate */
+          --source; /* return to the illegal value itself */
+          result = sourceIllegal;
+          break;
+        }
+	    } else { /* We don't have the 16 bits following the high surrogate. */
+        --source; /* return to the high surrogate */
+        result = sourceExhausted;
+        break;
+	    }
+    } else if (flags == strictConversion) {
+	    /* UTF-16 surrogate values are illegal in UTF-32 */
+	    if (ch >= UNI_SUR_LOW_START && ch <= UNI_SUR_LOW_END) {
+        --source; /* return to the illegal value itself */
+        result = sourceIllegal;
+        break;
+	    }
+    }
+    /* Figure out how many bytes the result will require */
+    if (ch < (UTF32)0x80) {	     bytesToWrite = 1;
+    } else if (ch < (UTF32)0x800) {     bytesToWrite = 2;
+    } else if (ch < (UTF32)0x10000) {   bytesToWrite = 3;
+    } else if (ch < (UTF32)0x110000) {  bytesToWrite = 4;
+    } else {			    bytesToWrite = 3;
+      ch = UNI_REPLACEMENT_CHAR;
+    }
+
+    target += bytesToWrite;
+    if (target > targetEnd) {
+	    source = oldSource; /* Back up source pointer! */
+	    target -= bytesToWrite; result = targetExhausted; break;
+    }
+    switch (bytesToWrite) { /* note: everything falls through. */
+	    case 4: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6;
+	    case 3: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6;
+	    case 2: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6;
+	    case 1: *--target =  (UTF8)(ch | firstByteMark[bytesToWrite]);
+    }
+    target += bytesToWrite;
+  }
+*sourceStart = source;
+*targetStart = target;
+return result;
+}
+
+/* --------------------------------------------------------------------- */
+
+/*
+ * Utility routine to tell whether a sequence of bytes is legal UTF-8.
+ * This must be called with the length pre-determined by the first byte.
+ * If not calling this from ConvertUTF8to*, then the length can be set by:
+ *  length = trailingBytesForUTF8[*source]+1;
+ * and the sequence is illegal right away if there aren't that many bytes
+ * available.
+ * If presented with a length > 4, this returns false.  The Unicode
+ * definition of UTF-8 goes up to 4-byte sequences.
+ */
+
+static Boolean isLegalUTF8(const UTF8 *source, int length) {
+  UTF8 a;
+  const UTF8 *srcptr = source+length;
+  switch (length) {
+    default: return false;
+      /* Everything else falls through when "true"... */
+    case 4: if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return false;
+    case 3: if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return false;
+    case 2: if ((a = (*--srcptr)) > 0xBF) return false;
+
+      switch (*source) {
+        /* no fall-through in this inner switch */
+        case 0xE0: if (a < 0xA0) return false; break;
+        case 0xED: if (a > 0x9F) return false; break;
+        case 0xF0: if (a < 0x90) return false; break;
+        case 0xF4: if (a > 0x8F) return false; break;
+        default:   if (a < 0x80) return false;
+      }
+
+      case 1: if (*source >= 0x80 && *source < 0xC2) return false;
+  }
+  if (*source > 0xF4) return false;
+  return true;
+}
+
+/* --------------------------------------------------------------------- */
+
+/*
+ * Exported function to return whether a UTF-8 sequence is legal or not.
+ * This is not used here; it's just exported.
+ */
+Boolean isLegalUTF8Sequence(const UTF8 *source, const UTF8 *sourceEnd) {
+  int length = trailingBytesForUTF8[*source]+1;
+  if (source+length > sourceEnd) {
+    return false;
+  }
+  return isLegalUTF8(source, length);
+}
+
+/* --------------------------------------------------------------------- */
+
+ConversionResult ConvertUTF8toUTF16 (const UTF8** sourceStart, const UTF8* sourceEnd,
+                                     UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags) {
+  ConversionResult result = conversionOK;
+  const UTF8* source = *sourceStart;
+  UTF16* target = *targetStart;
+  while (source < sourceEnd) {
+    UTF32 ch = 0;
+    unsigned short extraBytesToRead = trailingBytesForUTF8[*source];
+    if (source + extraBytesToRead >= sourceEnd) {
+	    result = sourceExhausted; break;
+    }
+    /* Do this check whether lenient or strict */
+    if (! isLegalUTF8(source, extraBytesToRead+1)) {
+	    result = sourceIllegal;
+	    break;
+    }
+    /*
+     * The cases all fall through. See "Note A" below.
+     */
+    switch (extraBytesToRead) {
+	    case 5: ch += *source++; ch <<= 6; /* remember, illegal UTF-8 */
+	    case 4: ch += *source++; ch <<= 6; /* remember, illegal UTF-8 */
+	    case 3: ch += *source++; ch <<= 6;
+	    case 2: ch += *source++; ch <<= 6;
+	    case 1: ch += *source++; ch <<= 6;
+	    case 0: ch += *source++;
+    }
+    ch -= offsetsFromUTF8[extraBytesToRead];
+
+    if (target >= targetEnd) {
+	    source -= (extraBytesToRead+1); /* Back up source pointer! */
+	    result = targetExhausted; break;
+    }
+    if (ch <= UNI_MAX_BMP) { /* Target is a character <= 0xFFFF */
+	    /* UTF-16 surrogate values are illegal in UTF-32 */
+	    if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) {
+        if (flags == strictConversion) {
+          source -= (extraBytesToRead+1); /* return to the illegal value itself */
+          result = sourceIllegal;
+          break;
+        } else {
+          *target++ = UNI_REPLACEMENT_CHAR;
+        }
+	    } else {
+        *target++ = (UTF16)ch; /* normal case */
+	    }
+    } else if (ch > UNI_MAX_UTF16) {
+	    if (flags == strictConversion) {
+        result = sourceIllegal;
+        source -= (extraBytesToRead+1); /* return to the start */
+        break; /* Bail out; shouldn't continue */
+	    } else {
+        *target++ = UNI_REPLACEMENT_CHAR;
+	    }
+    } else {
+	    /* target is a character in range 0xFFFF - 0x10FFFF. */
+	    if (target + 1 >= targetEnd) {
+        source -= (extraBytesToRead+1); /* Back up source pointer! */
+        result = targetExhausted; break;
+	    }
+	    ch -= halfBase;
+	    *target++ = (UTF16)((ch >> halfShift) + UNI_SUR_HIGH_START);
+	    *target++ = (UTF16)((ch & halfMask) + UNI_SUR_LOW_START);
+    }
+  }
+*sourceStart = source;
+*targetStart = target;
+return result;
+}
+
+/* --------------------------------------------------------------------- */
+
+ConversionResult ConvertUTF32toUTF8 (const UTF32** sourceStart, const UTF32* sourceEnd,
+                                     UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags) {
+  ConversionResult result = conversionOK;
+  const UTF32* source = *sourceStart;
+  UTF8* target = *targetStart;
+  while (source < sourceEnd) {
+    UTF32 ch;
+    unsigned short bytesToWrite = 0;
+    const UTF32 byteMask = 0xBF;
+    const UTF32 byteMark = 0x80;
+    ch = *source++;
+    if (flags == strictConversion ) {
+	    /* UTF-16 surrogate values are illegal in UTF-32 */
+	    if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) {
+        --source; /* return to the illegal value itself */
+        result = sourceIllegal;
+        break;
+	    }
+    }
+    /*
+     * Figure out how many bytes the result will require. Turn any
+     * illegally large UTF32 things (> Plane 17) into replacement chars.
+     */
+    if (ch < (UTF32)0x80) {	     bytesToWrite = 1;
+    } else if (ch < (UTF32)0x800) {     bytesToWrite = 2;
+    } else if (ch < (UTF32)0x10000) {   bytesToWrite = 3;
+    } else if (ch <= UNI_MAX_LEGAL_UTF32) {  bytesToWrite = 4;
+    } else {			    bytesToWrite = 3;
+      ch = UNI_REPLACEMENT_CHAR;
+      result = sourceIllegal;
+    }
+
+    target += bytesToWrite;
+    if (target > targetEnd) {
+	    --source; /* Back up source pointer! */
+	    target -= bytesToWrite; result = targetExhausted; break;
+    }
+    switch (bytesToWrite) { /* note: everything falls through. */
+	    case 4: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6;
+	    case 3: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6;
+	    case 2: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6;
+	    case 1: *--target = (UTF8) (ch | firstByteMark[bytesToWrite]);
+    }
+    target += bytesToWrite;
+  }
+*sourceStart = source;
+*targetStart = target;
+return result;
+}
+
+/* --------------------------------------------------------------------- */
+
+ConversionResult ConvertUTF8toUTF32 (const UTF8** sourceStart, const UTF8* sourceEnd,
+                                     UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags) {
+  ConversionResult result = conversionOK;
+  const UTF8* source = *sourceStart;
+  UTF32* target = *targetStart;
+  while (source < sourceEnd) {
+    UTF32 ch = 0;
+    unsigned short extraBytesToRead = trailingBytesForUTF8[*source];
+    if (source + extraBytesToRead >= sourceEnd) {
+	    result = sourceExhausted; break;
+    }
+    /* Do this check whether lenient or strict */
+    if (! isLegalUTF8(source, extraBytesToRead+1)) {
+	    result = sourceIllegal;
+	    break;
+    }
+    /*
+     * The cases all fall through. See "Note A" below.
+     */
+    switch (extraBytesToRead) {
+	    case 5: ch += *source++; ch <<= 6;
+	    case 4: ch += *source++; ch <<= 6;
+	    case 3: ch += *source++; ch <<= 6;
+	    case 2: ch += *source++; ch <<= 6;
+	    case 1: ch += *source++; ch <<= 6;
+	    case 0: ch += *source++;
+    }
+    ch -= offsetsFromUTF8[extraBytesToRead];
+
+    if (target >= targetEnd) {
+	    source -= (extraBytesToRead+1); /* Back up the source pointer! */
+	    result = targetExhausted; break;
+    }
+    if (ch <= UNI_MAX_LEGAL_UTF32) {
+	    /*
+	     * UTF-16 surrogate values are illegal in UTF-32, and anything
+	     * over Plane 17 (> 0x10FFFF) is illegal.
+	     */
+	    if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) {
+        if (flags == strictConversion) {
+          source -= (extraBytesToRead+1); /* return to the illegal value itself */
+          result = sourceIllegal;
+          break;
+        } else {
+          *target++ = UNI_REPLACEMENT_CHAR;
+        }
+	    } else {
+        *target++ = ch;
+	    }
+    } else { /* i.e., ch > UNI_MAX_LEGAL_UTF32 */
+	    result = sourceIllegal;
+	    *target++ = UNI_REPLACEMENT_CHAR;
+    }
+  }
+  *sourceStart = source;
+  *targetStart = target;
+  return result;
+}
+
+/* ---------------------------------------------------------------------
+
+Note A.
+The fall-through switches in UTF-8 reading code save a
+temp variable, some decrements & conditionals.  The switches
+are equivalent to the following loop:
+{
+  int tmpBytesToRead = extraBytesToRead+1;
+  do {
+		ch += *source++;
+		--tmpBytesToRead;
+		if (tmpBytesToRead) ch <<= 6;
+  } while (tmpBytesToRead > 0);
+}
+In UTF-8 writing code, the switches on "bytesToWrite" are
+similarly unrolled loops.
+
+--------------------------------------------------------------------- */
diff --git a/3rdParty/Breakpad/src/common/convert_UTF.h b/3rdParty/Breakpad/src/common/convert_UTF.h
new file mode 100644
index 0000000..b1556de
--- /dev/null
+++ b/3rdParty/Breakpad/src/common/convert_UTF.h
@@ -0,0 +1,143 @@
+/*
+ * Copyright 2001-2004 Unicode, Inc.
+ *
+ * Disclaimer
+ *
+ * This source code is provided as is by Unicode, Inc. No claims are
+ * made as to fitness for any particular purpose. No warranties of any
+ * kind are expressed or implied. The recipient agrees to determine
+ * applicability of information provided. If this file has been
+ * purchased on magnetic or optical media from Unicode, Inc., the
+ * sole remedy for any claim will be exchange of defective media
+ * within 90 days of receipt.
+ *
+ * Limitations on Rights to Redistribute This Code
+ *
+ * Unicode, Inc. hereby grants the right to freely use the information
+ * supplied in this file in the creation of products supporting the
+ * Unicode Standard, and to make copies of this file in any form
+ * for internal or external distribution as long as this notice
+ * remains attached.
+ */
+
+/* ---------------------------------------------------------------------
+
+Conversions between UTF32, UTF-16, and UTF-8.  Header file.
+
+Several funtions are included here, forming a complete set of
+conversions between the three formats.  UTF-7 is not included
+here, but is handled in a separate source file.
+
+Each of these routines takes pointers to input buffers and output
+buffers.  The input buffers are const.
+
+Each routine converts the text between *sourceStart and sourceEnd,
+putting the result into the buffer between *targetStart and
+targetEnd. Note: the end pointers are *after* the last item: e.g.
+*(sourceEnd - 1) is the last item.
+
+The return result indicates whether the conversion was successful,
+and if not, whether the problem was in the source or target buffers.
+(Only the first encountered problem is indicated.)
+
+After the conversion, *sourceStart and *targetStart are both
+updated to point to the end of last text successfully converted in
+the respective buffers.
+
+Input parameters:
+sourceStart - pointer to a pointer to the source buffer.
+The contents of this are modified on return so that
+it points at the next thing to be converted.
+targetStart - similarly, pointer to pointer to the target buffer.
+sourceEnd, targetEnd - respectively pointers to the ends of the
+two buffers, for overflow checking only.
+
+These conversion functions take a ConversionFlags argument. When this
+flag is set to strict, both irregular sequences and isolated surrogates
+will cause an error.  When the flag is set to lenient, both irregular
+sequences and isolated surrogates are converted.
+
+Whether the flag is strict or lenient, all illegal sequences will cause
+an error return. This includes sequences such as: <F4 90 80 80>, <C0 80>,
+or <A0> in UTF-8, and values above 0x10FFFF in UTF-32. Conformant code
+must check for illegal sequences.
+
+When the flag is set to lenient, characters over 0x10FFFF are converted
+to the replacement character; otherwise (when the flag is set to strict)
+they constitute an error.
+
+Output parameters:
+The value "sourceIllegal" is returned from some routines if the input
+sequence is malformed.  When "sourceIllegal" is returned, the source
+value will point to the illegal value that caused the problem. E.g.,
+in UTF-8 when a sequence is malformed, it points to the start of the
+malformed sequence.
+
+Author: Mark E. Davis, 1994.
+Rev History: Rick McGowan, fixes & updates May 2001.
+Fixes & updates, Sept 2001.
+
+------------------------------------------------------------------------ */
+
+/* ---------------------------------------------------------------------
+The following 4 definitions are compiler-specific.
+The C standard does not guarantee that wchar_t has at least
+16 bits, so wchar_t is no less portable than unsigned short!
+All should be unsigned values to avoid sign extension during
+bit mask & shift operations.
+------------------------------------------------------------------------ */
+
+typedef unsigned long	UTF32;	/* at least 32 bits */
+typedef unsigned short	UTF16;	/* at least 16 bits */
+typedef unsigned char	UTF8;	/* typically 8 bits */
+typedef unsigned char	Boolean; /* 0 or 1 */
+
+/* Some fundamental constants */
+#define UNI_REPLACEMENT_CHAR (UTF32)0x0000FFFD
+#define UNI_MAX_BMP (UTF32)0x0000FFFF
+#define UNI_MAX_UTF16 (UTF32)0x0010FFFF
+#define UNI_MAX_UTF32 (UTF32)0x7FFFFFFF
+#define UNI_MAX_LEGAL_UTF32 (UTF32)0x0010FFFF
+
+typedef enum {
+	conversionOK, 		/* conversion successful */
+	sourceExhausted,	/* partial character in source, but hit end */
+	targetExhausted,	/* insuff. room in target for conversion */
+	sourceIllegal		/* source sequence is illegal/malformed */
+} ConversionResult;
+
+typedef enum {
+	strictConversion = 0,
+	lenientConversion
+} ConversionFlags;
+
+/* This is for C++ and does no harm in C */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ConversionResult ConvertUTF8toUTF16 (const UTF8** sourceStart, const UTF8* sourceEnd,
+                                     UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags);
+
+ConversionResult ConvertUTF16toUTF8 (const UTF16** sourceStart, const UTF16* sourceEnd,
+                                     UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags);
+
+ConversionResult ConvertUTF8toUTF32 (const UTF8** sourceStart, const UTF8* sourceEnd,
+                                     UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags);
+
+ConversionResult ConvertUTF32toUTF8 (const UTF32** sourceStart, const UTF32* sourceEnd,
+                                     UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags);
+
+ConversionResult ConvertUTF16toUTF32 (const UTF16** sourceStart, const UTF16* sourceEnd,
+                                      UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags);
+
+ConversionResult ConvertUTF32toUTF16 (const UTF32** sourceStart, const UTF32* sourceEnd,
+                                      UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags);
+
+Boolean isLegalUTF8Sequence(const UTF8 *source, const UTF8 *sourceEnd);
+
+#ifdef __cplusplus
+}
+#endif
+
+/* --------------------------------------------------------------------- */
diff --git a/3rdParty/Breakpad/src/common/dwarf/bytereader-inl.h b/3rdParty/Breakpad/src/common/dwarf/bytereader-inl.h
new file mode 100644
index 0000000..3c16708
--- /dev/null
+++ b/3rdParty/Breakpad/src/common/dwarf/bytereader-inl.h
@@ -0,0 +1,175 @@
+// Copyright 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.
+
+#ifndef UTIL_DEBUGINFO_BYTEREADER_INL_H__
+#define UTIL_DEBUGINFO_BYTEREADER_INL_H__
+
+#include "common/dwarf/bytereader.h"
+
+#include <assert.h>
+
+namespace dwarf2reader {
+
+inline uint8 ByteReader::ReadOneByte(const char* buffer) const {
+  return buffer[0];
+}
+
+inline uint16 ByteReader::ReadTwoBytes(const char* signed_buffer) const {
+  const unsigned char *buffer
+    = reinterpret_cast<const unsigned char *>(signed_buffer);
+  const uint16 buffer0 = buffer[0];
+  const uint16 buffer1 = buffer[1];
+  if (endian_ == ENDIANNESS_LITTLE) {
+    return buffer0 | buffer1 << 8;
+  } else {
+    return buffer1 | buffer0 << 8;
+  }
+}
+
+inline uint64 ByteReader::ReadFourBytes(const char* signed_buffer) const {
+  const unsigned char *buffer
+    = reinterpret_cast<const unsigned char *>(signed_buffer);
+  const uint32 buffer0 = buffer[0];
+  const uint32 buffer1 = buffer[1];
+  const uint32 buffer2 = buffer[2];
+  const uint32 buffer3 = buffer[3];
+  if (endian_ == ENDIANNESS_LITTLE) {
+    return buffer0 | buffer1 << 8 | buffer2 << 16 | buffer3 << 24;
+  } else {
+    return buffer3 | buffer2 << 8 | buffer1 << 16 | buffer0 << 24;
+  }
+}
+
+inline uint64 ByteReader::ReadEightBytes(const char* signed_buffer) const {
+  const unsigned char *buffer
+    = reinterpret_cast<const unsigned char *>(signed_buffer);
+  const uint64 buffer0 = buffer[0];
+  const uint64 buffer1 = buffer[1];
+  const uint64 buffer2 = buffer[2];
+  const uint64 buffer3 = buffer[3];
+  const uint64 buffer4 = buffer[4];
+  const uint64 buffer5 = buffer[5];
+  const uint64 buffer6 = buffer[6];
+  const uint64 buffer7 = buffer[7];
+  if (endian_ == ENDIANNESS_LITTLE) {
+    return buffer0 | buffer1 << 8 | buffer2 << 16 | buffer3 << 24 |
+      buffer4 << 32 | buffer5 << 40 | buffer6 << 48 | buffer7 << 56;
+  } else {
+    return buffer7 | buffer6 << 8 | buffer5 << 16 | buffer4 << 24 |
+      buffer3 << 32 | buffer2 << 40 | buffer1 << 48 | buffer0 << 56;
+  }
+}
+
+// Read an unsigned LEB128 number.  Each byte contains 7 bits of
+// information, plus one bit saying whether the number continues or
+// not.
+
+inline uint64 ByteReader::ReadUnsignedLEB128(const char* buffer,
+                                             size_t* len) const {
+  uint64 result = 0;
+  size_t num_read = 0;
+  unsigned int shift = 0;
+  unsigned char byte;
+
+  do {
+    byte = *buffer++;
+    num_read++;
+
+    result |= (static_cast<uint64>(byte & 0x7f)) << shift;
+
+    shift += 7;
+
+  } while (byte & 0x80);
+
+  *len = num_read;
+
+  return result;
+}
+
+// Read a signed LEB128 number.  These are like regular LEB128
+// numbers, except the last byte may have a sign bit set.
+
+inline int64 ByteReader::ReadSignedLEB128(const char* buffer,
+                                          size_t* len) const {
+  int64 result = 0;
+  unsigned int shift = 0;
+  size_t num_read = 0;
+  unsigned char byte;
+
+  do {
+      byte = *buffer++;
+      num_read++;
+      result |= (static_cast<uint64>(byte & 0x7f) << shift);
+      shift += 7;
+  } while (byte & 0x80);
+
+  if ((shift < 8 * sizeof (result)) && (byte & 0x40))
+    result |= -((static_cast<int64>(1)) << shift);
+  *len = num_read;
+  return result;
+}
+
+inline uint64 ByteReader::ReadOffset(const char* buffer) const {
+  assert(this->offset_reader_);
+  return (this->*offset_reader_)(buffer);
+}
+
+inline uint64 ByteReader::ReadAddress(const char* buffer) const {
+  assert(this->address_reader_);
+  return (this->*address_reader_)(buffer);
+}
+
+inline void ByteReader::SetCFIDataBase(uint64 section_base,
+                                       const char *buffer_base) {
+  section_base_ = section_base;
+  buffer_base_ = buffer_base;
+  have_section_base_ = true;
+}
+
+inline void ByteReader::SetTextBase(uint64 text_base) {
+  text_base_ = text_base;
+  have_text_base_ = true;
+}
+
+inline void ByteReader::SetDataBase(uint64 data_base) {
+  data_base_ = data_base;
+  have_data_base_ = true;
+}
+
+inline void ByteReader::SetFunctionBase(uint64 function_base) {
+  function_base_ = function_base;
+  have_function_base_ = true;
+}
+
+inline void ByteReader::ClearFunctionBase() {
+  have_function_base_ = false;
+}
+
+}  // namespace dwarf2reader
+
+#endif  // UTIL_DEBUGINFO_BYTEREADER_INL_H__
diff --git a/3rdParty/Breakpad/src/common/dwarf/bytereader.cc b/3rdParty/Breakpad/src/common/dwarf/bytereader.cc
new file mode 100644
index 0000000..6802026
--- /dev/null
+++ b/3rdParty/Breakpad/src/common/dwarf/bytereader.cc
@@ -0,0 +1,245 @@
+// 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.
+
+#include <assert.h>
+#include <stdlib.h>
+
+#include "common/dwarf/bytereader-inl.h"
+#include "common/dwarf/bytereader.h"
+
+namespace dwarf2reader {
+
+ByteReader::ByteReader(enum Endianness endian)
+    :offset_reader_(NULL), address_reader_(NULL), endian_(endian),
+     address_size_(0), offset_size_(0),
+     have_section_base_(), have_text_base_(), have_data_base_(),
+     have_function_base_() { }
+
+ByteReader::~ByteReader() { }
+
+void ByteReader::SetOffsetSize(uint8 size) {
+  offset_size_ = size;
+  assert(size == 4 || size == 8);
+  if (size == 4) {
+    this->offset_reader_ = &ByteReader::ReadFourBytes;
+  } else {
+    this->offset_reader_ = &ByteReader::ReadEightBytes;
+  }
+}
+
+void ByteReader::SetAddressSize(uint8 size) {
+  address_size_ = size;
+  assert(size == 4 || size == 8);
+  if (size == 4) {
+    this->address_reader_ = &ByteReader::ReadFourBytes;
+  } else {
+    this->address_reader_ = &ByteReader::ReadEightBytes;
+  }
+}
+
+uint64 ByteReader::ReadInitialLength(const char* start, size_t* len) {
+  const uint64 initial_length = ReadFourBytes(start);
+  start += 4;
+
+  // In DWARF2/3, if the initial length is all 1 bits, then the offset
+  // size is 8 and we need to read the next 8 bytes for the real length.
+  if (initial_length == 0xffffffff) {
+    SetOffsetSize(8);
+    *len = 12;
+    return ReadOffset(start);
+  } else {
+    SetOffsetSize(4);
+    *len = 4;
+  }
+  return initial_length;
+}
+
+bool ByteReader::ValidEncoding(DwarfPointerEncoding encoding) const {
+  if (encoding == DW_EH_PE_omit) return true;
+  if (encoding == DW_EH_PE_aligned) return true;
+  if ((encoding & 0x7) > DW_EH_PE_udata8)
+    return false;
+  if ((encoding & 0x70) > DW_EH_PE_funcrel)
+    return false;
+  return true;
+}
+
+bool ByteReader::UsableEncoding(DwarfPointerEncoding encoding) const {
+  switch (encoding & 0x70) {
+    case DW_EH_PE_absptr:  return true;
+    case DW_EH_PE_pcrel:   return have_section_base_;
+    case DW_EH_PE_textrel: return have_text_base_;
+    case DW_EH_PE_datarel: return have_data_base_;
+    case DW_EH_PE_funcrel: return have_function_base_;
+    default:               return false;
+  }
+}
+
+uint64 ByteReader::ReadEncodedPointer(const char *buffer,
+                                      DwarfPointerEncoding encoding,
+                                      size_t *len) const {
+  // UsableEncoding doesn't approve of DW_EH_PE_omit, so we shouldn't
+  // see it here.
+  assert(encoding != DW_EH_PE_omit);
+
+  // The Linux Standards Base 4.0 does not make this clear, but the
+  // GNU tools (gcc/unwind-pe.h; readelf/dwarf.c; gdb/dwarf2-frame.c)
+  // agree that aligned pointers are always absolute, machine-sized,
+  // machine-signed pointers.
+  if (encoding == DW_EH_PE_aligned) {
+    assert(have_section_base_);
+
+    // We don't need to align BUFFER in *our* address space. Rather, we
+    // need to find the next position in our buffer that would be aligned
+    // when the .eh_frame section the buffer contains is loaded into the
+    // program's memory. So align assuming that buffer_base_ gets loaded at
+    // address section_base_, where section_base_ itself may or may not be
+    // aligned.
+
+    // First, find the offset to START from the closest prior aligned
+    // address.
+    uint64 skew = section_base_ & (AddressSize() - 1);
+    // Now find the offset from that aligned address to buffer.
+    uint64 offset = skew + (buffer - buffer_base_);
+    // Round up to the next boundary.
+    uint64 aligned = (offset + AddressSize() - 1) & -AddressSize();
+    // Convert back to a pointer.
+    const char *aligned_buffer = buffer_base_ + (aligned - skew);
+    // Finally, store the length and actually fetch the pointer.
+    *len = aligned_buffer - buffer + AddressSize();
+    return ReadAddress(aligned_buffer);
+  }
+
+  // Extract the value first, ignoring whether it's a pointer or an
+  // offset relative to some base.
+  uint64 offset;
+  switch (encoding & 0x0f) {
+    case DW_EH_PE_absptr:
+      // DW_EH_PE_absptr is weird, as it is used as a meaningful value for
+      // both the high and low nybble of encoding bytes. When it appears in
+      // the high nybble, it means that the pointer is absolute, not an
+      // offset from some base address. When it appears in the low nybble,
+      // as here, it means that the pointer is stored as a normal
+      // machine-sized and machine-signed address. A low nybble of
+      // DW_EH_PE_absptr does not imply that the pointer is absolute; it is
+      // correct for us to treat the value as an offset from a base address
+      // if the upper nybble is not DW_EH_PE_absptr.
+      offset = ReadAddress(buffer);
+      *len = AddressSize();
+      break;
+
+    case DW_EH_PE_uleb128:
+      offset = ReadUnsignedLEB128(buffer, len);
+      break;
+
+    case DW_EH_PE_udata2:
+      offset = ReadTwoBytes(buffer);
+      *len = 2;
+      break;
+
+    case DW_EH_PE_udata4:
+      offset = ReadFourBytes(buffer);
+      *len = 4;
+      break;
+
+    case DW_EH_PE_udata8:
+      offset = ReadEightBytes(buffer);
+      *len = 8;
+      break;
+
+    case DW_EH_PE_sleb128:
+      offset = ReadSignedLEB128(buffer, len);
+      break;
+
+    case DW_EH_PE_sdata2:
+      offset = ReadTwoBytes(buffer);
+      // Sign-extend from 16 bits.
+      offset = (offset ^ 0x8000) - 0x8000;
+      *len = 2;
+      break;
+
+    case DW_EH_PE_sdata4:
+      offset = ReadFourBytes(buffer);
+      // Sign-extend from 32 bits.
+      offset = (offset ^ 0x80000000ULL) - 0x80000000ULL;
+      *len = 4;
+      break;
+
+    case DW_EH_PE_sdata8:
+      // No need to sign-extend; this is the full width of our type.
+      offset = ReadEightBytes(buffer);
+      *len = 8;
+      break;
+
+    default:
+      abort();
+  }
+
+  // Find the appropriate base address.
+  uint64 base;
+  switch (encoding & 0x70) {
+    case DW_EH_PE_absptr:
+      base = 0;
+      break;
+
+    case DW_EH_PE_pcrel:
+      assert(have_section_base_);
+      base = section_base_ + (buffer - buffer_base_);
+      break;
+
+    case DW_EH_PE_textrel:
+      assert(have_text_base_);
+      base = text_base_;
+      break;
+
+    case DW_EH_PE_datarel:
+      assert(have_data_base_);
+      base = data_base_;
+      break;
+
+    case DW_EH_PE_funcrel:
+      assert(have_function_base_);
+      base = function_base_;
+      break;
+
+    default:
+      abort();
+  }
+
+  uint64 pointer = base + offset;
+
+  // Remove inappropriate upper bits.
+  if (AddressSize() == 4)
+    pointer = pointer & 0xffffffff;
+  else
+    assert(AddressSize() == sizeof(uint64));
+
+  return pointer;
+}
+
+}  // namespace dwarf2reader
diff --git a/3rdParty/Breakpad/src/common/dwarf/bytereader.h b/3rdParty/Breakpad/src/common/dwarf/bytereader.h
new file mode 100644
index 0000000..e389427
--- /dev/null
+++ b/3rdParty/Breakpad/src/common/dwarf/bytereader.h
@@ -0,0 +1,310 @@
+// -*- mode: C++ -*-
+
+// 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.
+
+#ifndef COMMON_DWARF_BYTEREADER_H__
+#define COMMON_DWARF_BYTEREADER_H__
+
+#include <string>
+#include "common/dwarf/types.h"
+#include "common/dwarf/dwarf2enums.h"
+
+namespace dwarf2reader {
+
+// We can't use the obvious name of LITTLE_ENDIAN and BIG_ENDIAN
+// because it conflicts with a macro
+enum Endianness {
+  ENDIANNESS_BIG,
+  ENDIANNESS_LITTLE
+};
+
+// A ByteReader knows how to read single- and multi-byte values of
+// various endiannesses, sizes, and encodings, as used in DWARF
+// debugging information and Linux C++ exception handling data.
+class ByteReader {
+ public:
+  // Construct a ByteReader capable of reading one-, two-, four-, and
+  // eight-byte values according to ENDIANNESS, absolute machine-sized
+  // addresses, DWARF-style "initial length" values, signed and
+  // unsigned LEB128 numbers, and Linux C++ exception handling data's
+  // encoded pointers.
+  explicit ByteReader(enum Endianness endianness);
+  virtual ~ByteReader();
+
+  // Read a single byte from BUFFER and return it as an unsigned 8 bit
+  // number.
+  uint8 ReadOneByte(const char* buffer) const;
+
+  // Read two bytes from BUFFER and return them as an unsigned 16 bit
+  // number, using this ByteReader's endianness.
+  uint16 ReadTwoBytes(const char* buffer) const;
+
+  // Read four bytes from BUFFER and return them as an unsigned 32 bit
+  // number, using this ByteReader's endianness. This function returns
+  // a uint64 so that it is compatible with ReadAddress and
+  // ReadOffset. The number it returns will never be outside the range
+  // of an unsigned 32 bit integer.
+  uint64 ReadFourBytes(const char* buffer) const;
+
+  // Read eight bytes from BUFFER and return them as an unsigned 64
+  // bit number, using this ByteReader's endianness.
+  uint64 ReadEightBytes(const char* buffer) const;
+
+  // Read an unsigned LEB128 (Little Endian Base 128) number from
+  // BUFFER and return it as an unsigned 64 bit integer. Set LEN to
+  // the number of bytes read.
+  //
+  // The unsigned LEB128 representation of an integer N is a variable
+  // number of bytes:
+  //
+  // - If N is between 0 and 0x7f, then its unsigned LEB128
+  //   representation is a single byte whose value is N.
+  //
+  // - Otherwise, its unsigned LEB128 representation is (N & 0x7f) |
+  //   0x80, followed by the unsigned LEB128 representation of N /
+  //   128, rounded towards negative infinity.
+  //
+  // In other words, we break VALUE into groups of seven bits, put
+  // them in little-endian order, and then write them as eight-bit
+  // bytes with the high bit on all but the last.
+  uint64 ReadUnsignedLEB128(const char* buffer, size_t* len) const;
+
+  // Read a signed LEB128 number from BUFFER and return it as an
+  // signed 64 bit integer. Set LEN to the number of bytes read.
+  //
+  // The signed LEB128 representation of an integer N is a variable
+  // number of bytes:
+  //
+  // - If N is between -0x40 and 0x3f, then its signed LEB128
+  //   representation is a single byte whose value is N in two's
+  //   complement.
+  //
+  // - Otherwise, its signed LEB128 representation is (N & 0x7f) |
+  //   0x80, followed by the signed LEB128 representation of N / 128,
+  //   rounded towards negative infinity.
+  //
+  // In other words, we break VALUE into groups of seven bits, put
+  // them in little-endian order, and then write them as eight-bit
+  // bytes with the high bit on all but the last.
+  int64 ReadSignedLEB128(const char* buffer, size_t* len) const;
+
+  // Indicate that addresses on this architecture are SIZE bytes long. SIZE
+  // must be either 4 or 8. (DWARF allows addresses to be any number of
+  // bytes in length from 1 to 255, but we only support 32- and 64-bit
+  // addresses at the moment.) You must call this before using the
+  // ReadAddress member function.
+  //
+  // For data in a .debug_info section, or something that .debug_info
+  // refers to like line number or macro data, the compilation unit
+  // header's address_size field indicates the address size to use. Call
+  // frame information doesn't indicate its address size (a shortcoming of
+  // the spec); you must supply the appropriate size based on the
+  // architecture of the target machine.
+  void SetAddressSize(uint8 size);
+
+  // Return the current address size, in bytes. This is either 4,
+  // indicating 32-bit addresses, or 8, indicating 64-bit addresses.
+  uint8 AddressSize() const { return address_size_; }
+
+  // Read an address from BUFFER and return it as an unsigned 64 bit
+  // integer, respecting this ByteReader's endianness and address size. You
+  // must call SetAddressSize before calling this function.
+  uint64 ReadAddress(const char* buffer) const;
+
+  // DWARF actually defines two slightly different formats: 32-bit DWARF
+  // and 64-bit DWARF. This is *not* related to the size of registers or
+  // addresses on the target machine; it refers only to the size of section
+  // offsets and data lengths appearing in the DWARF data. One only needs
+  // 64-bit DWARF when the debugging data itself is larger than 4GiB.
+  // 32-bit DWARF can handle x86_64 or PPC64 code just fine, unless the
+  // debugging data itself is very large.
+  //
+  // DWARF information identifies itself as 32-bit or 64-bit DWARF: each
+  // compilation unit and call frame information entry begins with an
+  // "initial length" field, which, in addition to giving the length of the
+  // data, also indicates the size of section offsets and lengths appearing
+  // in that data. The ReadInitialLength member function, below, reads an
+  // initial length and sets the ByteReader's offset size as a side effect.
+  // Thus, in the normal process of reading DWARF data, the appropriate
+  // offset size is set automatically. So, you should only need to call
+  // SetOffsetSize if you are using the same ByteReader to jump from the
+  // midst of one block of DWARF data into another.
+
+  // Read a DWARF "initial length" field from START, and return it as
+  // an unsigned 64 bit integer, respecting this ByteReader's
+  // endianness. Set *LEN to the length of the initial length in
+  // bytes, either four or twelve. As a side effect, set this
+  // ByteReader's offset size to either 4 (if we see a 32-bit DWARF
+  // initial length) or 8 (if we see a 64-bit DWARF initial length).
+  //
+  // A DWARF initial length is either:
+  //
+  // - a byte count stored as an unsigned 32-bit value less than
+  //   0xffffff00, indicating that the data whose length is being
+  //   measured uses the 32-bit DWARF format, or
+  //
+  // - The 32-bit value 0xffffffff, followed by a 64-bit byte count,
+  //   indicating that the data whose length is being measured uses
+  //   the 64-bit DWARF format.
+  uint64 ReadInitialLength(const char* start, size_t* len);
+
+  // Read an offset from BUFFER and return it as an unsigned 64 bit
+  // integer, respecting the ByteReader's endianness. In 32-bit DWARF, the
+  // offset is 4 bytes long; in 64-bit DWARF, the offset is eight bytes
+  // long. You must call ReadInitialLength or SetOffsetSize before calling
+  // this function; see the comments above for details.
+  uint64 ReadOffset(const char* buffer) const;
+
+  // Return the current offset size, in bytes.
+  // A return value of 4 indicates that we are reading 32-bit DWARF.
+  // A return value of 8 indicates that we are reading 64-bit DWARF.
+  uint8 OffsetSize() const { return offset_size_; }
+
+  // Indicate that section offsets and lengths are SIZE bytes long. SIZE
+  // must be either 4 (meaning 32-bit DWARF) or 8 (meaning 64-bit DWARF).
+  // Usually, you should not call this function yourself; instead, let a
+  // call to ReadInitialLength establish the data's offset size
+  // automatically.
+  void SetOffsetSize(uint8 size);
+
+  // The Linux C++ ABI uses a variant of DWARF call frame information
+  // for exception handling. This data is included in the program's
+  // address space as the ".eh_frame" section, and intepreted at
+  // runtime to walk the stack, find exception handlers, and run
+  // cleanup code. The format is mostly the same as DWARF CFI, with
+  // some adjustments made to provide the additional
+  // exception-handling data, and to make the data easier to work with
+  // in memory --- for example, to allow it to be placed in read-only
+  // memory even when describing position-independent code.
+  //
+  // In particular, exception handling data can select a number of
+  // different encodings for pointers that appear in the data, as
+  // described by the DwarfPointerEncoding enum. There are actually
+  // four axes(!) to the encoding:
+  //
+  // - The pointer size: pointers can be 2, 4, or 8 bytes long, or use
+  //   the DWARF LEB128 encoding.
+  //
+  // - The pointer's signedness: pointers can be signed or unsigned.
+  //
+  // - The pointer's base address: the data stored in the exception
+  //   handling data can be the actual address (that is, an absolute
+  //   pointer), or relative to one of a number of different base
+  //   addreses --- including that of the encoded pointer itself, for
+  //   a form of "pc-relative" addressing.
+  //
+  // - The pointer may be indirect: it may be the address where the
+  //   true pointer is stored. (This is used to refer to things via
+  //   global offset table entries, program linkage table entries, or
+  //   other tricks used in position-independent code.)
+  //
+  // There are also two options that fall outside that matrix
+  // altogether: the pointer may be omitted, or it may have padding to
+  // align it on an appropriate address boundary. (That last option
+  // may seem like it should be just another axis, but it is not.)
+
+  // Indicate that the exception handling data is loaded starting at
+  // SECTION_BASE, and that the start of its buffer in our own memory
+  // is BUFFER_BASE. This allows us to find the address that a given
+  // byte in our buffer would have when loaded into the program the
+  // data describes. We need this to resolve DW_EH_PE_pcrel pointers.
+  void SetCFIDataBase(uint64 section_base, const char *buffer_base);
+
+  // Indicate that the base address of the program's ".text" section
+  // is TEXT_BASE. We need this to resolve DW_EH_PE_textrel pointers.
+  void SetTextBase(uint64 text_base);
+
+  // Indicate that the base address for DW_EH_PE_datarel pointers is
+  // DATA_BASE. The proper value depends on the ABI; it is usually the
+  // address of the global offset table, held in a designated register in
+  // position-independent code. You will need to look at the startup code
+  // for the target system to be sure. I tried; my eyes bled.
+  void SetDataBase(uint64 data_base);
+
+  // Indicate that the base address for the FDE we are processing is
+  // FUNCTION_BASE. This is the start address of DW_EH_PE_funcrel
+  // pointers. (This encoding does not seem to be used by the GNU
+  // toolchain.)
+  void SetFunctionBase(uint64 function_base);
+
+  // Indicate that we are no longer processing any FDE, so any use of
+  // a DW_EH_PE_funcrel encoding is an error.
+  void ClearFunctionBase();
+
+  // Return true if ENCODING is a valid pointer encoding.
+  bool ValidEncoding(DwarfPointerEncoding encoding) const;
+
+  // Return true if we have all the information we need to read a
+  // pointer that uses ENCODING. This checks that the appropriate
+  // SetFooBase function for ENCODING has been called.
+  bool UsableEncoding(DwarfPointerEncoding encoding) const;
+
+  // Read an encoded pointer from BUFFER using ENCODING; return the
+  // absolute address it represents, and set *LEN to the pointer's
+  // length in bytes, including any padding for aligned pointers.
+  //
+  // This function calls 'abort' if ENCODING is invalid or refers to a
+  // base address this reader hasn't been given, so you should check
+  // with ValidEncoding and UsableEncoding first if you would rather
+  // die in a more helpful way.
+  uint64 ReadEncodedPointer(const char *buffer, DwarfPointerEncoding encoding,
+                            size_t *len) const;
+
+ private:
+
+  // Function pointer type for our address and offset readers.
+  typedef uint64 (ByteReader::*AddressReader)(const char*) const;
+
+  // Read an offset from BUFFER and return it as an unsigned 64 bit
+  // integer.  DWARF2/3 define offsets as either 4 or 8 bytes,
+  // generally depending on the amount of DWARF2/3 info present.
+  // This function pointer gets set by SetOffsetSize.
+  AddressReader offset_reader_;
+
+  // Read an address from BUFFER and return it as an unsigned 64 bit
+  // integer.  DWARF2/3 allow addresses to be any size from 0-255
+  // bytes currently.  Internally we support 4 and 8 byte addresses,
+  // and will CHECK on anything else.
+  // This function pointer gets set by SetAddressSize.
+  AddressReader address_reader_;
+
+  Endianness endian_;
+  uint8 address_size_;
+  uint8 offset_size_;
+
+  // Base addresses for Linux C++ exception handling data's encoded pointers.
+  bool have_section_base_, have_text_base_, have_data_base_;
+  bool have_function_base_;
+  uint64 section_base_, text_base_, data_base_, function_base_;
+  const char *buffer_base_;
+};
+
+}  // namespace dwarf2reader
+
+#endif  // COMMON_DWARF_BYTEREADER_H__
diff --git a/3rdParty/Breakpad/src/common/dwarf/dwarf2diehandler.cc b/3rdParty/Breakpad/src/common/dwarf/dwarf2diehandler.cc
new file mode 100644
index 0000000..c741d69
--- /dev/null
+++ b/3rdParty/Breakpad/src/common/dwarf/dwarf2diehandler.cc
@@ -0,0 +1,199 @@
+// 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>
+
+// dwarf2diehandler.cc: Implement the dwarf2reader::DieDispatcher class.
+// See dwarf2diehandler.h for details.
+
+#include <assert.h>
+
+#include <string>
+
+#include "common/dwarf/dwarf2diehandler.h"
+#include "common/using_std_string.h"
+
+namespace dwarf2reader {
+
+DIEDispatcher::~DIEDispatcher() {
+  while (!die_handlers_.empty()) {
+    HandlerStack &entry = die_handlers_.top();
+    if (entry.handler_ != root_handler_)
+      delete entry.handler_;
+    die_handlers_.pop();
+  }
+}
+
+bool DIEDispatcher::StartCompilationUnit(uint64 offset, uint8 address_size,
+                                         uint8 offset_size, uint64 cu_length,
+                                         uint8 dwarf_version) {
+  return root_handler_->StartCompilationUnit(offset, address_size,
+                                             offset_size, cu_length,
+                                             dwarf_version);
+}
+
+bool DIEDispatcher::StartDIE(uint64 offset, enum DwarfTag tag,
+                             const AttributeList& attrs) {
+  // The stack entry for the parent of this DIE, if there is one.
+  HandlerStack *parent = die_handlers_.empty() ? NULL : &die_handlers_.top();
+
+  // Does this call indicate that we're done receiving the parent's
+  // attributes' values?  If so, call its EndAttributes member function.
+  if (parent && parent->handler_ && !parent->reported_attributes_end_) {
+    parent->reported_attributes_end_ = true;
+    if (!parent->handler_->EndAttributes()) {
+      // Finish off this handler now. and edit *PARENT to indicate that
+      // we don't want to visit any of the children.
+      parent->handler_->Finish();
+      if (parent->handler_ != root_handler_)
+        delete parent->handler_;
+      parent->handler_ = NULL;
+      return false;
+    }
+  }
+
+  // Find a handler for this DIE.
+  DIEHandler *handler;
+  if (parent) {
+    if (parent->handler_)
+      // Ask the parent to find a handler.
+      handler = parent->handler_->FindChildHandler(offset, tag, attrs);
+    else
+      // No parent handler means we're not interested in any of our
+      // children.
+      handler = NULL;
+  } else {
+    // This is the root DIE.  For a non-root DIE, the parent's handler
+    // decides whether to visit it, but the root DIE has no parent
+    // handler, so we have a special method on the root DIE handler
+    // itself to decide.
+    if (root_handler_->StartRootDIE(offset, tag, attrs))
+      handler = root_handler_;
+    else
+      handler = NULL;
+  }
+
+  // Push a handler stack entry for this new handler. As an
+  // optimization, we don't push NULL-handler entries on top of other
+  // NULL-handler entries; we just let the oldest such entry stand for
+  // the whole subtree.
+  if (handler || !parent || parent->handler_) {
+    HandlerStack entry;
+    entry.offset_ = offset;
+    entry.handler_ = handler;
+    entry.reported_attributes_end_ = false;
+    die_handlers_.push(entry);
+  }
+
+  return handler != NULL;
+}
+
+void DIEDispatcher::EndDIE(uint64 offset) {
+  assert(!die_handlers_.empty());
+  HandlerStack *entry = &die_handlers_.top();
+  if (entry->handler_) {
+    // This entry had better be the handler for this DIE.
+    assert(entry->offset_ == offset);
+    // If a DIE has no children, this EndDIE call indicates that we're
+    // done receiving its attributes' values.
+    if (!entry->reported_attributes_end_)
+      entry->handler_->EndAttributes(); // Ignore return value: no children.
+    entry->handler_->Finish();
+    if (entry->handler_ != root_handler_)
+      delete entry->handler_;
+  } else {
+    // If this DIE is within a tree we're ignoring, then don't pop the
+    // handler stack: that entry stands for the whole tree.
+    if (entry->offset_ != offset)
+      return;
+  }
+  die_handlers_.pop();
+}
+
+void DIEDispatcher::ProcessAttributeUnsigned(uint64 offset,
+                                             enum DwarfAttribute attr,
+                                             enum DwarfForm form,
+                                             uint64 data) {
+  HandlerStack &current = die_handlers_.top();
+  // This had better be an attribute of the DIE we were meant to handle.
+  assert(offset == current.offset_);
+  current.handler_->ProcessAttributeUnsigned(attr, form, data);
+}
+
+void DIEDispatcher::ProcessAttributeSigned(uint64 offset,
+                                           enum DwarfAttribute attr,
+                                           enum DwarfForm form,
+                                           int64 data) {
+  HandlerStack &current = die_handlers_.top();
+  // This had better be an attribute of the DIE we were meant to handle.
+  assert(offset == current.offset_);
+  current.handler_->ProcessAttributeSigned(attr, form, data);
+}
+
+void DIEDispatcher::ProcessAttributeReference(uint64 offset,
+                                              enum DwarfAttribute attr,
+                                              enum DwarfForm form,
+                                              uint64 data) {
+  HandlerStack &current = die_handlers_.top();
+  // This had better be an attribute of the DIE we were meant to handle.
+  assert(offset == current.offset_);
+  current.handler_->ProcessAttributeReference(attr, form, data);
+}
+
+void DIEDispatcher::ProcessAttributeBuffer(uint64 offset,
+                                           enum DwarfAttribute attr,
+                                           enum DwarfForm form,
+                                           const char* data,
+                                           uint64 len) {
+  HandlerStack &current = die_handlers_.top();
+  // This had better be an attribute of the DIE we were meant to handle.
+  assert(offset == current.offset_);
+  current.handler_->ProcessAttributeBuffer(attr, form, data, len);
+}
+
+void DIEDispatcher::ProcessAttributeString(uint64 offset,
+                                           enum DwarfAttribute attr,
+                                           enum DwarfForm form,
+                                           const string& data) {
+  HandlerStack &current = die_handlers_.top();
+  // This had better be an attribute of the DIE we were meant to handle.
+  assert(offset == current.offset_);
+  current.handler_->ProcessAttributeString(attr, form, data);
+}
+
+void DIEDispatcher::ProcessAttributeSignature(uint64 offset,
+                                              enum DwarfAttribute attr,
+                                              enum DwarfForm form,
+                                              uint64 signature) {
+  HandlerStack &current = die_handlers_.top();
+  // This had better be an attribute of the DIE we were meant to handle.
+  assert(offset == current.offset_);
+  current.handler_->ProcessAttributeSignature(attr, form, signature);
+}
+
+} // namespace dwarf2reader
diff --git a/3rdParty/Breakpad/src/common/dwarf/dwarf2diehandler.h b/3rdParty/Breakpad/src/common/dwarf/dwarf2diehandler.h
new file mode 100644
index 0000000..12b8d3a
--- /dev/null
+++ b/3rdParty/Breakpad/src/common/dwarf/dwarf2diehandler.h
@@ -0,0 +1,367 @@
+// -*- mode: c++ -*-
+
+// 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>
+
+// dwarf2reader::CompilationUnit is a simple and direct parser for
+// DWARF data, but its handler interface is not convenient to use.  In
+// particular:
+//
+// - CompilationUnit calls Dwarf2Handler's member functions to report
+//   every attribute's value, regardless of what sort of DIE it is.
+//   As a result, the ProcessAttributeX functions end up looking like
+//   this:
+//
+//     switch (parent_die_tag) {
+//       case DW_TAG_x:
+//         switch (attribute_name) {
+//           case DW_AT_y:
+//             handle attribute y of DIE type x
+//           ...
+//         } break;
+//       ...
+//     } 
+//
+//   In C++ it's much nicer to use virtual function dispatch to find
+//   the right code for a given case than to switch on the DIE tag
+//   like this.
+//
+// - Processing different kinds of DIEs requires different sets of
+//   data: lexical block DIEs have start and end addresses, but struct
+//   type DIEs don't.  It would be nice to be able to have separate
+//   handler classes for separate kinds of DIEs, each with the members
+//   appropriate to its role, instead of having one handler class that
+//   needs to hold data for every DIE type.
+//
+// - There should be a separate instance of the appropriate handler
+//   class for each DIE, instead of a single object with tables
+//   tracking all the dies in the compilation unit.
+//
+// - It's not convenient to take some action after all a DIE's
+//   attributes have been seen, but before visiting any of its
+//   children.  The only indication you have that a DIE's attribute
+//   list is complete is that you get either a StartDIE or an EndDIE
+//   call.
+//
+// - It's not convenient to make use of the tree structure of the
+//   DIEs.  Skipping all the children of a given die requires
+//   maintaining state and returning false from StartDIE until we get
+//   an EndDIE call with the appropriate offset.
+//
+// This interface tries to take care of all that.  (You're shocked, I'm sure.)
+//
+// Using the classes here, you provide an initial handler for the root
+// DIE of the compilation unit.  Each handler receives its DIE's
+// attributes, and provides fresh handler objects for children of
+// interest, if any.  The three classes are:
+//
+// - DIEHandler: the base class for your DIE-type-specific handler
+//   classes.
+//
+// - RootDIEHandler: derived from DIEHandler, the base class for your
+//   root DIE handler class.
+//
+// - DIEDispatcher: derived from Dwarf2Handler, an instance of this
+//   invokes your DIE-type-specific handler objects.
+//
+// In detail:
+//
+// - Define handler classes specialized for the DIE types you're
+//   interested in.  These handler classes must inherit from
+//   DIEHandler.  Thus:
+//
+//     class My_DW_TAG_X_Handler: public DIEHandler { ... };
+//     class My_DW_TAG_Y_Handler: public DIEHandler { ... };
+//
+//   DIEHandler subclasses needn't correspond exactly to single DIE
+//   types, as shown here; the point is that you can have several
+//   different classes appropriate to different kinds of DIEs.
+//
+// - In particular, define a handler class for the compilation
+//   unit's root DIE, that inherits from RootDIEHandler:
+//
+//     class My_DW_TAG_compile_unit_Handler: public RootDIEHandler { ... };
+//
+//   RootDIEHandler inherits from DIEHandler, adding a few additional
+//   member functions for examining the compilation unit as a whole,
+//   and other quirks of rootness.
+//
+// - Then, create a DIEDispatcher instance, passing it an instance of
+//   your root DIE handler class, and use that DIEDispatcher as the
+//   dwarf2reader::CompilationUnit's handler:
+//
+//     My_DW_TAG_compile_unit_Handler root_die_handler(...);
+//     DIEDispatcher die_dispatcher(&root_die_handler);
+//     CompilationUnit reader(sections, offset, bytereader, &die_dispatcher);
+//
+//   Here, 'die_dispatcher' acts as a shim between 'reader' and the
+//   various DIE-specific handlers you have defined.
+//
+// - When you call reader.Start(), die_dispatcher behaves as follows,
+//   starting with your root die handler and the compilation unit's
+//   root DIE:
+//
+//   - It calls the handler's ProcessAttributeX member functions for
+//     each of the DIE's attributes.
+//
+//   - It calls the handler's EndAttributes member function.  This
+//     should return true if any of the DIE's children should be
+//     visited, in which case:
+//
+//     - For each of the DIE's children, die_dispatcher calls the
+//       DIE's handler's FindChildHandler member function.  If that
+//       returns a pointer to a DIEHandler instance, then
+//       die_dispatcher uses that handler to process the child, using
+//       this procedure recursively.  Alternatively, if
+//       FindChildHandler returns NULL, die_dispatcher ignores that
+//       child and its descendants.
+// 
+//   - When die_dispatcher has finished processing all the DIE's
+//     children, it invokes the handler's Finish() member function,
+//     and destroys the handler.  (As a special case, it doesn't
+//     destroy the root DIE handler.)
+// 
+// This allows the code for handling a particular kind of DIE to be
+// gathered together in a single class, makes it easy to skip all the
+// children or individual children of a particular DIE, and provides
+// appropriate parental context for each die.
+
+#ifndef COMMON_DWARF_DWARF2DIEHANDLER_H__
+#define COMMON_DWARF_DWARF2DIEHANDLER_H__
+
+#include <stack>
+#include <string>
+
+#include "common/dwarf/types.h"
+#include "common/dwarf/dwarf2enums.h"
+#include "common/dwarf/dwarf2reader.h"
+#include "common/using_std_string.h"
+
+namespace dwarf2reader {
+
+// A base class for handlers for specific DIE types.  The series of
+// calls made on a DIE handler is as follows:
+//
+// - for each attribute of the DIE:
+//   - ProcessAttributeX()
+// - EndAttributes()
+// - if that returned true, then for each child:
+//   - FindChildHandler()
+//   - if that returns a non-NULL pointer to a new handler:
+//     - recurse, with the new handler and the child die
+// - Finish()
+// - destruction
+class DIEHandler {
+ public:
+  DIEHandler() { }
+  virtual ~DIEHandler() { }
+
+  // When we visit a DIE, we first use these member functions to
+  // report the DIE's attributes and their values.  These have the
+  // same restrictions as the corresponding member functions of
+  // dwarf2reader::Dwarf2Handler.
+  //
+  // Since DWARF does not specify in what order attributes must
+  // appear, avoid making decisions in these functions that would be
+  // affected by the presence of other attributes. The EndAttributes
+  // function is a more appropriate place for such work, as all the
+  // DIE's attributes have been seen at that point.
+  //
+  // The default definitions ignore the values they are passed.
+  virtual void ProcessAttributeUnsigned(enum DwarfAttribute attr,
+                                        enum DwarfForm form,
+                                        uint64 data) { }
+  virtual void ProcessAttributeSigned(enum DwarfAttribute attr,
+                                      enum DwarfForm form,
+                                      int64 data) { }
+  virtual void ProcessAttributeReference(enum DwarfAttribute attr,
+                                         enum DwarfForm form,
+                                         uint64 data) { }
+  virtual void ProcessAttributeBuffer(enum DwarfAttribute attr,
+                                      enum DwarfForm form,
+                                      const char* data,
+                                      uint64 len) { }
+  virtual void ProcessAttributeString(enum DwarfAttribute attr,
+                                      enum DwarfForm form,
+                                      const string& data) { }
+  virtual void ProcessAttributeSignature(enum DwarfAttribute attr,
+                                         enum DwarfForm form,
+                                         uint64 signture) { }
+
+  // Once we have reported all the DIE's attributes' values, we call
+  // this member function.  If it returns false, we skip all the DIE's
+  // children.  If it returns true, we call FindChildHandler on each
+  // child.  If that returns a handler object, we use that to visit
+  // the child; otherwise, we skip the child.
+  //
+  // This is a good place to make decisions that depend on more than
+  // one attribute. DWARF does not specify in what order attributes
+  // must appear, so only when the EndAttributes function is called
+  // does the handler have a complete picture of the DIE's attributes.
+  //
+  // The default definition elects to ignore the DIE's children.
+  // You'll need to override this if you override FindChildHandler,
+  // but at least the default behavior isn't to pass the children to
+  // FindChildHandler, which then ignores them all.
+  virtual bool EndAttributes() { return false; }
+
+  // If EndAttributes returns true to indicate that some of the DIE's
+  // children might be of interest, then we apply this function to
+  // each of the DIE's children.  If it returns a handler object, then
+  // we use that to visit the child DIE.  If it returns NULL, we skip
+  // that child DIE (and all its descendants).
+  //
+  // OFFSET is the offset of the child; TAG indicates what kind of DIE
+  // it is; and ATTRS is the list of attributes the DIE will have, and
+  // their forms (their values are not provided).
+  //
+  // The default definition skips all children.
+  virtual DIEHandler *FindChildHandler(uint64 offset, enum DwarfTag tag,
+                                       const AttributeList &attrs) {
+    return NULL;
+  }
+
+  // When we are done processing a DIE, we call this member function.
+  // This happens after the EndAttributes call, all FindChildHandler
+  // calls (if any), and all operations on the children themselves (if
+  // any). We call Finish on every handler --- even if EndAttributes
+  // returns false.
+  virtual void Finish() { };
+};
+
+// A subclass of DIEHandler, with additional kludges for handling the
+// compilation unit's root die.
+class RootDIEHandler: public DIEHandler {
+ public:
+  RootDIEHandler() { }
+  virtual ~RootDIEHandler() { }
+
+  // We pass the values reported via Dwarf2Handler::StartCompilationUnit
+  // to this member function, and skip the entire compilation unit if it
+  // returns false.  So the root DIE handler is actually also
+  // responsible for handling the compilation unit metadata.
+  // The default definition always visits the compilation unit.
+  virtual bool StartCompilationUnit(uint64 offset, uint8 address_size,
+                                    uint8 offset_size, uint64 cu_length,
+                                    uint8 dwarf_version) { return true; }
+
+  // For the root DIE handler only, we pass the offset, tag and
+  // attributes of the compilation unit's root DIE.  This is the only
+  // way the root DIE handler can find the root DIE's tag.  If this
+  // function returns true, we will visit the root DIE using the usual
+  // DIEHandler methods; otherwise, we skip the entire compilation
+  // unit.
+  //
+  // The default definition elects to visit the root DIE.
+  virtual bool StartRootDIE(uint64 offset, enum DwarfTag tag,
+                            const AttributeList& attrs) { return true; }
+};
+
+class DIEDispatcher: public Dwarf2Handler {
+ public:
+  // Create a Dwarf2Handler which uses ROOT_HANDLER as the handler for
+  // the compilation unit's root die, as described for the DIEHandler
+  // class.
+  DIEDispatcher(RootDIEHandler *root_handler) : root_handler_(root_handler) { }
+  // Destroying a DIEDispatcher destroys all active handler objects
+  // except the root handler.
+  ~DIEDispatcher();
+  bool StartCompilationUnit(uint64 offset, uint8 address_size,
+                            uint8 offset_size, uint64 cu_length,
+                            uint8 dwarf_version);
+  bool StartDIE(uint64 offset, enum DwarfTag tag,
+                const AttributeList &attrs);
+  void ProcessAttributeUnsigned(uint64 offset,
+                                enum DwarfAttribute attr,
+                                enum DwarfForm form,
+                                uint64 data);
+  void ProcessAttributeSigned(uint64 offset,
+                              enum DwarfAttribute attr,
+                              enum DwarfForm form,
+                              int64 data);
+  void ProcessAttributeReference(uint64 offset,
+                                 enum DwarfAttribute attr,
+                                 enum DwarfForm form,
+                                 uint64 data);
+  void ProcessAttributeBuffer(uint64 offset,
+                              enum DwarfAttribute attr,
+                              enum DwarfForm form,
+                              const char* data,
+                              uint64 len);
+  void ProcessAttributeString(uint64 offset,
+                              enum DwarfAttribute attr,
+                              enum DwarfForm form,
+                              const string &data);
+  void ProcessAttributeSignature(uint64 offset,
+                                 enum DwarfAttribute attr,
+                                 enum DwarfForm form,
+                                 uint64 signature);
+  void EndDIE(uint64 offset);
+
+ private:
+
+  // The type of a handler stack entry.  This includes some fields
+  // which don't really need to be on the stack --- they could just be
+  // single data members of DIEDispatcher --- but putting them here
+  // makes it easier to see that the code is correct.
+  struct HandlerStack {
+    // The offset of the DIE for this handler stack entry.
+    uint64 offset_;
+
+    // The handler object interested in this DIE's attributes and
+    // children.  If NULL, we're not interested in either.
+    DIEHandler *handler_;
+
+    // Have we reported the end of this DIE's attributes to the handler?
+    bool reported_attributes_end_;
+  };
+
+  // Stack of DIE attribute handlers.  At StartDIE(D), the top of the
+  // stack is the handler of D's parent, whom we may ask for a handler
+  // for D itself.  At EndDIE(D), the top of the stack is D's handler.
+  // Special cases:
+  //
+  // - Before we've seen the compilation unit's root DIE, the stack is
+  //   empty; we'll call root_handler_'s special member functions, and
+  //   perhaps push root_handler_ on the stack to look at the root's
+  //   immediate children.
+  //
+  // - When we decide to ignore a subtree, we only push an entry on
+  //   the stack for the root of the tree being ignored, rather than
+  //   pushing lots of stack entries with handler_ set to NULL.
+  std::stack<HandlerStack> die_handlers_;
+
+  // The root handler.  We don't push it on die_handlers_ until we
+  // actually get the StartDIE call for the root.
+  RootDIEHandler *root_handler_;
+};
+
+} // namespace dwarf2reader
+#endif  // COMMON_DWARF_DWARF2DIEHANDLER_H__
diff --git a/3rdParty/Breakpad/src/common/dwarf/dwarf2enums.h b/3rdParty/Breakpad/src/common/dwarf/dwarf2enums.h
new file mode 100644
index 0000000..5565d66
--- /dev/null
+++ b/3rdParty/Breakpad/src/common/dwarf/dwarf2enums.h
@@ -0,0 +1,650 @@
+// -*- mode: c++ -*-
+
+// 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.
+
+#ifndef COMMON_DWARF_DWARF2ENUMS_H__
+#define COMMON_DWARF_DWARF2ENUMS_H__
+
+namespace dwarf2reader {
+
+// These enums do not follow the google3 style only because they are
+// known universally (specs, other implementations) by the names in
+// exactly this capitalization.
+// Tag names and codes.
+enum DwarfTag {
+  DW_TAG_padding = 0x00,
+  DW_TAG_array_type = 0x01,
+  DW_TAG_class_type = 0x02,
+  DW_TAG_entry_point = 0x03,
+  DW_TAG_enumeration_type = 0x04,
+  DW_TAG_formal_parameter = 0x05,
+  DW_TAG_imported_declaration = 0x08,
+  DW_TAG_label = 0x0a,
+  DW_TAG_lexical_block = 0x0b,
+  DW_TAG_member = 0x0d,
+  DW_TAG_pointer_type = 0x0f,
+  DW_TAG_reference_type = 0x10,
+  DW_TAG_compile_unit = 0x11,
+  DW_TAG_string_type = 0x12,
+  DW_TAG_structure_type = 0x13,
+  DW_TAG_subroutine_type = 0x15,
+  DW_TAG_typedef = 0x16,
+  DW_TAG_union_type = 0x17,
+  DW_TAG_unspecified_parameters = 0x18,
+  DW_TAG_variant = 0x19,
+  DW_TAG_common_block = 0x1a,
+  DW_TAG_common_inclusion = 0x1b,
+  DW_TAG_inheritance = 0x1c,
+  DW_TAG_inlined_subroutine = 0x1d,
+  DW_TAG_module = 0x1e,
+  DW_TAG_ptr_to_member_type = 0x1f,
+  DW_TAG_set_type = 0x20,
+  DW_TAG_subrange_type = 0x21,
+  DW_TAG_with_stmt = 0x22,
+  DW_TAG_access_declaration = 0x23,
+  DW_TAG_base_type = 0x24,
+  DW_TAG_catch_block = 0x25,
+  DW_TAG_const_type = 0x26,
+  DW_TAG_constant = 0x27,
+  DW_TAG_enumerator = 0x28,
+  DW_TAG_file_type = 0x29,
+  DW_TAG_friend = 0x2a,
+  DW_TAG_namelist = 0x2b,
+  DW_TAG_namelist_item = 0x2c,
+  DW_TAG_packed_type = 0x2d,
+  DW_TAG_subprogram = 0x2e,
+  DW_TAG_template_type_param = 0x2f,
+  DW_TAG_template_value_param = 0x30,
+  DW_TAG_thrown_type = 0x31,
+  DW_TAG_try_block = 0x32,
+  DW_TAG_variant_part = 0x33,
+  DW_TAG_variable = 0x34,
+  DW_TAG_volatile_type = 0x35,
+  // DWARF 3.
+  DW_TAG_dwarf_procedure = 0x36,
+  DW_TAG_restrict_type = 0x37,
+  DW_TAG_interface_type = 0x38,
+  DW_TAG_namespace = 0x39,
+  DW_TAG_imported_module = 0x3a,
+  DW_TAG_unspecified_type = 0x3b,
+  DW_TAG_partial_unit = 0x3c,
+  DW_TAG_imported_unit = 0x3d,
+  // SGI/MIPS Extensions.
+  DW_TAG_MIPS_loop = 0x4081,
+  // HP extensions.  See:
+  // ftp://ftp.hp.com/pub/lang/tools/WDB/wdb-4.0.tar.gz
+  DW_TAG_HP_array_descriptor = 0x4090,
+  // GNU extensions.
+  DW_TAG_format_label = 0x4101,  // For FORTRAN 77 and Fortran 90.
+  DW_TAG_function_template = 0x4102,  // For C++.
+  DW_TAG_class_template = 0x4103,  // For C++.
+  DW_TAG_GNU_BINCL = 0x4104,
+  DW_TAG_GNU_EINCL = 0x4105,
+  // Extensions for UPC.  See: http://upc.gwu.edu/~upc.
+  DW_TAG_upc_shared_type = 0x8765,
+  DW_TAG_upc_strict_type = 0x8766,
+  DW_TAG_upc_relaxed_type = 0x8767,
+  // PGI (STMicroelectronics) extensions.  No documentation available.
+  DW_TAG_PGI_kanji_type      = 0xA000,
+  DW_TAG_PGI_interface_block = 0xA020
+};
+
+
+enum DwarfHasChild {
+  DW_children_no = 0,
+  DW_children_yes = 1
+};
+
+// Form names and codes.
+enum DwarfForm {
+  DW_FORM_addr = 0x01,
+  DW_FORM_block2 = 0x03,
+  DW_FORM_block4 = 0x04,
+  DW_FORM_data2 = 0x05,
+  DW_FORM_data4 = 0x06,
+  DW_FORM_data8 = 0x07,
+  DW_FORM_string = 0x08,
+  DW_FORM_block = 0x09,
+  DW_FORM_block1 = 0x0a,
+  DW_FORM_data1 = 0x0b,
+  DW_FORM_flag = 0x0c,
+  DW_FORM_sdata = 0x0d,
+  DW_FORM_strp = 0x0e,
+  DW_FORM_udata = 0x0f,
+  DW_FORM_ref_addr = 0x10,
+  DW_FORM_ref1 = 0x11,
+  DW_FORM_ref2 = 0x12,
+  DW_FORM_ref4 = 0x13,
+  DW_FORM_ref8 = 0x14,
+  DW_FORM_ref_udata = 0x15,
+  DW_FORM_indirect = 0x16,
+
+  // Added in DWARF 4:
+  DW_FORM_sec_offset = 0x17,
+  DW_FORM_exprloc = 0x18,
+  DW_FORM_flag_present = 0x19,
+  DW_FORM_ref_sig8 = 0x20
+};
+
+// Attribute names and codes
+enum DwarfAttribute {
+  DW_AT_sibling = 0x01,
+  DW_AT_location = 0x02,
+  DW_AT_name = 0x03,
+  DW_AT_ordering = 0x09,
+  DW_AT_subscr_data = 0x0a,
+  DW_AT_byte_size = 0x0b,
+  DW_AT_bit_offset = 0x0c,
+  DW_AT_bit_size = 0x0d,
+  DW_AT_element_list = 0x0f,
+  DW_AT_stmt_list = 0x10,
+  DW_AT_low_pc = 0x11,
+  DW_AT_high_pc = 0x12,
+  DW_AT_language = 0x13,
+  DW_AT_member = 0x14,
+  DW_AT_discr = 0x15,
+  DW_AT_discr_value = 0x16,
+  DW_AT_visibility = 0x17,
+  DW_AT_import = 0x18,
+  DW_AT_string_length = 0x19,
+  DW_AT_common_reference = 0x1a,
+  DW_AT_comp_dir = 0x1b,
+  DW_AT_const_value = 0x1c,
+  DW_AT_containing_type = 0x1d,
+  DW_AT_default_value = 0x1e,
+  DW_AT_inline = 0x20,
+  DW_AT_is_optional = 0x21,
+  DW_AT_lower_bound = 0x22,
+  DW_AT_producer = 0x25,
+  DW_AT_prototyped = 0x27,
+  DW_AT_return_addr = 0x2a,
+  DW_AT_start_scope = 0x2c,
+  DW_AT_stride_size = 0x2e,
+  DW_AT_upper_bound = 0x2f,
+  DW_AT_abstract_origin = 0x31,
+  DW_AT_accessibility = 0x32,
+  DW_AT_address_class = 0x33,
+  DW_AT_artificial = 0x34,
+  DW_AT_base_types = 0x35,
+  DW_AT_calling_convention = 0x36,
+  DW_AT_count = 0x37,
+  DW_AT_data_member_location = 0x38,
+  DW_AT_decl_column = 0x39,
+  DW_AT_decl_file = 0x3a,
+  DW_AT_decl_line = 0x3b,
+  DW_AT_declaration = 0x3c,
+  DW_AT_discr_list = 0x3d,
+  DW_AT_encoding = 0x3e,
+  DW_AT_external = 0x3f,
+  DW_AT_frame_base = 0x40,
+  DW_AT_friend = 0x41,
+  DW_AT_identifier_case = 0x42,
+  DW_AT_macro_info = 0x43,
+  DW_AT_namelist_items = 0x44,
+  DW_AT_priority = 0x45,
+  DW_AT_segment = 0x46,
+  DW_AT_specification = 0x47,
+  DW_AT_static_link = 0x48,
+  DW_AT_type = 0x49,
+  DW_AT_use_location = 0x4a,
+  DW_AT_variable_parameter = 0x4b,
+  DW_AT_virtuality = 0x4c,
+  DW_AT_vtable_elem_location = 0x4d,
+  // DWARF 3 values.
+  DW_AT_allocated     = 0x4e,
+  DW_AT_associated    = 0x4f,
+  DW_AT_data_location = 0x50,
+  DW_AT_stride        = 0x51,
+  DW_AT_entry_pc      = 0x52,
+  DW_AT_use_UTF8      = 0x53,
+  DW_AT_extension     = 0x54,
+  DW_AT_ranges        = 0x55,
+  DW_AT_trampoline    = 0x56,
+  DW_AT_call_column   = 0x57,
+  DW_AT_call_file     = 0x58,
+  DW_AT_call_line     = 0x59,
+  // SGI/MIPS extensions.
+  DW_AT_MIPS_fde = 0x2001,
+  DW_AT_MIPS_loop_begin = 0x2002,
+  DW_AT_MIPS_tail_loop_begin = 0x2003,
+  DW_AT_MIPS_epilog_begin = 0x2004,
+  DW_AT_MIPS_loop_unroll_factor = 0x2005,
+  DW_AT_MIPS_software_pipeline_depth = 0x2006,
+  DW_AT_MIPS_linkage_name = 0x2007,
+  DW_AT_MIPS_stride = 0x2008,
+  DW_AT_MIPS_abstract_name = 0x2009,
+  DW_AT_MIPS_clone_origin = 0x200a,
+  DW_AT_MIPS_has_inlines = 0x200b,
+  // HP extensions.
+  DW_AT_HP_block_index         = 0x2000,
+  DW_AT_HP_unmodifiable        = 0x2001,  // Same as DW_AT_MIPS_fde.
+  DW_AT_HP_actuals_stmt_list   = 0x2010,
+  DW_AT_HP_proc_per_section    = 0x2011,
+  DW_AT_HP_raw_data_ptr        = 0x2012,
+  DW_AT_HP_pass_by_reference   = 0x2013,
+  DW_AT_HP_opt_level           = 0x2014,
+  DW_AT_HP_prof_version_id     = 0x2015,
+  DW_AT_HP_opt_flags           = 0x2016,
+  DW_AT_HP_cold_region_low_pc  = 0x2017,
+  DW_AT_HP_cold_region_high_pc = 0x2018,
+  DW_AT_HP_all_variables_modifiable = 0x2019,
+  DW_AT_HP_linkage_name        = 0x201a,
+  DW_AT_HP_prof_flags          = 0x201b,  // In comp unit of procs_info for -g.
+  // GNU extensions.
+  DW_AT_sf_names   = 0x2101,
+  DW_AT_src_info   = 0x2102,
+  DW_AT_mac_info   = 0x2103,
+  DW_AT_src_coords = 0x2104,
+  DW_AT_body_begin = 0x2105,
+  DW_AT_body_end   = 0x2106,
+  DW_AT_GNU_vector = 0x2107,
+  // VMS extensions.
+  DW_AT_VMS_rtnbeg_pd_address = 0x2201,
+  // UPC extension.
+  DW_AT_upc_threads_scaled = 0x3210,
+  // PGI (STMicroelectronics) extensions.
+  DW_AT_PGI_lbase    = 0x3a00,
+  DW_AT_PGI_soffset  = 0x3a01,
+  DW_AT_PGI_lstride  = 0x3a02
+};
+
+
+// Line number opcodes.
+enum DwarfLineNumberOps {
+  DW_LNS_extended_op = 0,
+  DW_LNS_copy = 1,
+  DW_LNS_advance_pc = 2,
+  DW_LNS_advance_line = 3,
+  DW_LNS_set_file = 4,
+  DW_LNS_set_column = 5,
+  DW_LNS_negate_stmt = 6,
+  DW_LNS_set_basic_block = 7,
+  DW_LNS_const_add_pc = 8,
+  DW_LNS_fixed_advance_pc = 9,
+  // DWARF 3.
+  DW_LNS_set_prologue_end = 10,
+  DW_LNS_set_epilogue_begin = 11,
+  DW_LNS_set_isa = 12
+};
+
+// Line number extended opcodes.
+enum DwarfLineNumberExtendedOps {
+  DW_LNE_end_sequence = 1,
+  DW_LNE_set_address = 2,
+  DW_LNE_define_file = 3,
+  // HP extensions.
+  DW_LNE_HP_negate_is_UV_update      = 0x11,
+  DW_LNE_HP_push_context             = 0x12,
+  DW_LNE_HP_pop_context              = 0x13,
+  DW_LNE_HP_set_file_line_column     = 0x14,
+  DW_LNE_HP_set_routine_name         = 0x15,
+  DW_LNE_HP_set_sequence             = 0x16,
+  DW_LNE_HP_negate_post_semantics    = 0x17,
+  DW_LNE_HP_negate_function_exit     = 0x18,
+  DW_LNE_HP_negate_front_end_logical = 0x19,
+  DW_LNE_HP_define_proc              = 0x20
+};
+
+// Type encoding names and codes
+enum DwarfEncoding {
+  DW_ATE_address                     =0x1,
+  DW_ATE_boolean                     =0x2,
+  DW_ATE_complex_float               =0x3,
+  DW_ATE_float                       =0x4,
+  DW_ATE_signed                      =0x5,
+  DW_ATE_signed_char                 =0x6,
+  DW_ATE_unsigned                    =0x7,
+  DW_ATE_unsigned_char               =0x8,
+  // DWARF3/DWARF3f
+  DW_ATE_imaginary_float             =0x9,
+  DW_ATE_packed_decimal              =0xa,
+  DW_ATE_numeric_string              =0xb,
+  DW_ATE_edited                      =0xc,
+  DW_ATE_signed_fixed                =0xd,
+  DW_ATE_unsigned_fixed              =0xe,
+  DW_ATE_decimal_float               =0xf,
+  DW_ATE_lo_user                     =0x80,
+  DW_ATE_hi_user                     =0xff
+};
+
+// Location virtual machine opcodes
+enum DwarfOpcode {
+  DW_OP_addr                         =0x03,
+  DW_OP_deref                        =0x06,
+  DW_OP_const1u                      =0x08,
+  DW_OP_const1s                      =0x09,
+  DW_OP_const2u                      =0x0a,
+  DW_OP_const2s                      =0x0b,
+  DW_OP_const4u                      =0x0c,
+  DW_OP_const4s                      =0x0d,
+  DW_OP_const8u                      =0x0e,
+  DW_OP_const8s                      =0x0f,
+  DW_OP_constu                       =0x10,
+  DW_OP_consts                       =0x11,
+  DW_OP_dup                          =0x12,
+  DW_OP_drop                         =0x13,
+  DW_OP_over                         =0x14,
+  DW_OP_pick                         =0x15,
+  DW_OP_swap                         =0x16,
+  DW_OP_rot                          =0x17,
+  DW_OP_xderef                       =0x18,
+  DW_OP_abs                          =0x19,
+  DW_OP_and                          =0x1a,
+  DW_OP_div                          =0x1b,
+  DW_OP_minus                        =0x1c,
+  DW_OP_mod                          =0x1d,
+  DW_OP_mul                          =0x1e,
+  DW_OP_neg                          =0x1f,
+  DW_OP_not                          =0x20,
+  DW_OP_or                           =0x21,
+  DW_OP_plus                         =0x22,
+  DW_OP_plus_uconst                  =0x23,
+  DW_OP_shl                          =0x24,
+  DW_OP_shr                          =0x25,
+  DW_OP_shra                         =0x26,
+  DW_OP_xor                          =0x27,
+  DW_OP_bra                          =0x28,
+  DW_OP_eq                           =0x29,
+  DW_OP_ge                           =0x2a,
+  DW_OP_gt                           =0x2b,
+  DW_OP_le                           =0x2c,
+  DW_OP_lt                           =0x2d,
+  DW_OP_ne                           =0x2e,
+  DW_OP_skip                         =0x2f,
+  DW_OP_lit0                         =0x30,
+  DW_OP_lit1                         =0x31,
+  DW_OP_lit2                         =0x32,
+  DW_OP_lit3                         =0x33,
+  DW_OP_lit4                         =0x34,
+  DW_OP_lit5                         =0x35,
+  DW_OP_lit6                         =0x36,
+  DW_OP_lit7                         =0x37,
+  DW_OP_lit8                         =0x38,
+  DW_OP_lit9                         =0x39,
+  DW_OP_lit10                        =0x3a,
+  DW_OP_lit11                        =0x3b,
+  DW_OP_lit12                        =0x3c,
+  DW_OP_lit13                        =0x3d,
+  DW_OP_lit14                        =0x3e,
+  DW_OP_lit15                        =0x3f,
+  DW_OP_lit16                        =0x40,
+  DW_OP_lit17                        =0x41,
+  DW_OP_lit18                        =0x42,
+  DW_OP_lit19                        =0x43,
+  DW_OP_lit20                        =0x44,
+  DW_OP_lit21                        =0x45,
+  DW_OP_lit22                        =0x46,
+  DW_OP_lit23                        =0x47,
+  DW_OP_lit24                        =0x48,
+  DW_OP_lit25                        =0x49,
+  DW_OP_lit26                        =0x4a,
+  DW_OP_lit27                        =0x4b,
+  DW_OP_lit28                        =0x4c,
+  DW_OP_lit29                        =0x4d,
+  DW_OP_lit30                        =0x4e,
+  DW_OP_lit31                        =0x4f,
+  DW_OP_reg0                         =0x50,
+  DW_OP_reg1                         =0x51,
+  DW_OP_reg2                         =0x52,
+  DW_OP_reg3                         =0x53,
+  DW_OP_reg4                         =0x54,
+  DW_OP_reg5                         =0x55,
+  DW_OP_reg6                         =0x56,
+  DW_OP_reg7                         =0x57,
+  DW_OP_reg8                         =0x58,
+  DW_OP_reg9                         =0x59,
+  DW_OP_reg10                        =0x5a,
+  DW_OP_reg11                        =0x5b,
+  DW_OP_reg12                        =0x5c,
+  DW_OP_reg13                        =0x5d,
+  DW_OP_reg14                        =0x5e,
+  DW_OP_reg15                        =0x5f,
+  DW_OP_reg16                        =0x60,
+  DW_OP_reg17                        =0x61,
+  DW_OP_reg18                        =0x62,
+  DW_OP_reg19                        =0x63,
+  DW_OP_reg20                        =0x64,
+  DW_OP_reg21                        =0x65,
+  DW_OP_reg22                        =0x66,
+  DW_OP_reg23                        =0x67,
+  DW_OP_reg24                        =0x68,
+  DW_OP_reg25                        =0x69,
+  DW_OP_reg26                        =0x6a,
+  DW_OP_reg27                        =0x6b,
+  DW_OP_reg28                        =0x6c,
+  DW_OP_reg29                        =0x6d,
+  DW_OP_reg30                        =0x6e,
+  DW_OP_reg31                        =0x6f,
+  DW_OP_breg0                        =0x70,
+  DW_OP_breg1                        =0x71,
+  DW_OP_breg2                        =0x72,
+  DW_OP_breg3                        =0x73,
+  DW_OP_breg4                        =0x74,
+  DW_OP_breg5                        =0x75,
+  DW_OP_breg6                        =0x76,
+  DW_OP_breg7                        =0x77,
+  DW_OP_breg8                        =0x78,
+  DW_OP_breg9                        =0x79,
+  DW_OP_breg10                       =0x7a,
+  DW_OP_breg11                       =0x7b,
+  DW_OP_breg12                       =0x7c,
+  DW_OP_breg13                       =0x7d,
+  DW_OP_breg14                       =0x7e,
+  DW_OP_breg15                       =0x7f,
+  DW_OP_breg16                       =0x80,
+  DW_OP_breg17                       =0x81,
+  DW_OP_breg18                       =0x82,
+  DW_OP_breg19                       =0x83,
+  DW_OP_breg20                       =0x84,
+  DW_OP_breg21                       =0x85,
+  DW_OP_breg22                       =0x86,
+  DW_OP_breg23                       =0x87,
+  DW_OP_breg24                       =0x88,
+  DW_OP_breg25                       =0x89,
+  DW_OP_breg26                       =0x8a,
+  DW_OP_breg27                       =0x8b,
+  DW_OP_breg28                       =0x8c,
+  DW_OP_breg29                       =0x8d,
+  DW_OP_breg30                       =0x8e,
+  DW_OP_breg31                       =0x8f,
+  DW_OP_regX                         =0x90,
+  DW_OP_fbreg                        =0x91,
+  DW_OP_bregX                        =0x92,
+  DW_OP_piece                        =0x93,
+  DW_OP_deref_size                   =0x94,
+  DW_OP_xderef_size                  =0x95,
+  DW_OP_nop                          =0x96,
+  // DWARF3/DWARF3f
+  DW_OP_push_object_address          =0x97,
+  DW_OP_call2                        =0x98,
+  DW_OP_call4                        =0x99,
+  DW_OP_call_ref                     =0x9a,
+  DW_OP_form_tls_address             =0x9b,
+  DW_OP_call_frame_cfa               =0x9c,
+  DW_OP_bit_piece                    =0x9d,
+  DW_OP_lo_user                      =0xe0,
+  DW_OP_hi_user                      =0xff,  
+  // GNU extensions
+  DW_OP_GNU_push_tls_address         =0xe0
+};
+
+// Source languages.  These are values for DW_AT_language.
+enum DwarfLanguage
+  {
+    DW_LANG_none                     =0x0000,
+    DW_LANG_C89                      =0x0001,
+    DW_LANG_C                        =0x0002,
+    DW_LANG_Ada83                    =0x0003,
+    DW_LANG_C_plus_plus              =0x0004,
+    DW_LANG_Cobol74                  =0x0005,
+    DW_LANG_Cobol85                  =0x0006,
+    DW_LANG_Fortran77                =0x0007,
+    DW_LANG_Fortran90                =0x0008,
+    DW_LANG_Pascal83                 =0x0009,
+    DW_LANG_Modula2                  =0x000a,
+    DW_LANG_Java                     =0x000b,
+    DW_LANG_C99                      =0x000c,
+    DW_LANG_Ada95                    =0x000d,
+    DW_LANG_Fortran95                =0x000e,
+    DW_LANG_PLI                      =0x000f,
+    DW_LANG_ObjC                     =0x0010,
+    DW_LANG_ObjC_plus_plus           =0x0011,
+    DW_LANG_UPC                      =0x0012,
+    DW_LANG_D                        =0x0013,
+    // Implementation-defined language code range.
+    DW_LANG_lo_user = 0x8000,
+    DW_LANG_hi_user = 0xffff,
+
+    // Extensions.
+
+    // MIPS assembly language.  The GNU toolchain uses this for all
+    // assembly languages, since there's no generic DW_LANG_ value for that.
+    // See include/dwarf2.h in the binutils, gdb, or gcc source trees.
+    DW_LANG_Mips_Assembler           =0x8001,
+    DW_LANG_Upc                      =0x8765 // Unified Parallel C
+  };
+
+// Inline codes.  These are values for DW_AT_inline.
+enum DwarfInline {
+  DW_INL_not_inlined                 =0x0,
+  DW_INL_inlined                     =0x1,
+  DW_INL_declared_not_inlined        =0x2,
+  DW_INL_declared_inlined            =0x3
+};
+
+// Call Frame Info instructions.
+enum DwarfCFI
+  {
+    DW_CFA_advance_loc        = 0x40,
+    DW_CFA_offset             = 0x80,
+    DW_CFA_restore            = 0xc0,
+    DW_CFA_nop                = 0x00,
+    DW_CFA_set_loc            = 0x01,
+    DW_CFA_advance_loc1       = 0x02,
+    DW_CFA_advance_loc2       = 0x03,
+    DW_CFA_advance_loc4       = 0x04,
+    DW_CFA_offset_extended    = 0x05,
+    DW_CFA_restore_extended   = 0x06,
+    DW_CFA_undefined          = 0x07,
+    DW_CFA_same_value         = 0x08,
+    DW_CFA_register           = 0x09,
+    DW_CFA_remember_state     = 0x0a,
+    DW_CFA_restore_state      = 0x0b,
+    DW_CFA_def_cfa            = 0x0c,
+    DW_CFA_def_cfa_register   = 0x0d,
+    DW_CFA_def_cfa_offset     = 0x0e,
+    DW_CFA_def_cfa_expression = 0x0f,
+    DW_CFA_expression         = 0x10,
+    DW_CFA_offset_extended_sf = 0x11,
+    DW_CFA_def_cfa_sf         = 0x12,
+    DW_CFA_def_cfa_offset_sf  = 0x13,
+    DW_CFA_val_offset         = 0x14,
+    DW_CFA_val_offset_sf      = 0x15,
+    DW_CFA_val_expression     = 0x16,
+
+    // Opcodes in this range are reserved for user extensions.
+    DW_CFA_lo_user = 0x1c,
+    DW_CFA_hi_user = 0x3f,
+
+    // SGI/MIPS specific.
+    DW_CFA_MIPS_advance_loc8 = 0x1d,
+
+    // GNU extensions.
+    DW_CFA_GNU_window_save = 0x2d,
+    DW_CFA_GNU_args_size = 0x2e,
+    DW_CFA_GNU_negative_offset_extended = 0x2f
+  };
+
+// Exception handling 'z' augmentation letters.
+enum DwarfZAugmentationCodes {
+  // If the CFI augmentation string begins with 'z', then the CIE and FDE
+  // have an augmentation data area just before the instructions, whose
+  // contents are determined by the subsequent augmentation letters.
+  DW_Z_augmentation_start = 'z',
+
+  // If this letter is present in a 'z' augmentation string, the CIE
+  // augmentation data includes a pointer encoding, and the FDE
+  // augmentation data includes a language-specific data area pointer,
+  // represented using that encoding.
+  DW_Z_has_LSDA = 'L',
+
+  // If this letter is present in a 'z' augmentation string, the CIE
+  // augmentation data includes a pointer encoding, followed by a pointer
+  // to a personality routine, represented using that encoding.
+  DW_Z_has_personality_routine = 'P',
+
+  // If this letter is present in a 'z' augmentation string, the CIE
+  // augmentation data includes a pointer encoding describing how the FDE's
+  // initial location, address range, and DW_CFA_set_loc operands are
+  // encoded.
+  DW_Z_has_FDE_address_encoding = 'R',
+
+  // If this letter is present in a 'z' augmentation string, then code
+  // addresses covered by FDEs that cite this CIE are signal delivery
+  // trampolines. Return addresses of frames in trampolines should not be
+  // adjusted as described in section 6.4.4 of the DWARF 3 spec.
+  DW_Z_is_signal_trampoline = 'S'
+};
+
+// Exception handling frame description pointer formats, as described
+// by the Linux Standard Base Core Specification 4.0, section 11.5,
+// DWARF Extensions.
+enum DwarfPointerEncoding
+  {
+    DW_EH_PE_absptr	= 0x00,
+    DW_EH_PE_omit	= 0xff,
+    DW_EH_PE_uleb128    = 0x01,
+    DW_EH_PE_udata2	= 0x02,
+    DW_EH_PE_udata4	= 0x03,
+    DW_EH_PE_udata8	= 0x04,
+    DW_EH_PE_sleb128    = 0x09,
+    DW_EH_PE_sdata2	= 0x0A,
+    DW_EH_PE_sdata4	= 0x0B,
+    DW_EH_PE_sdata8	= 0x0C,
+    DW_EH_PE_pcrel	= 0x10,
+    DW_EH_PE_textrel	= 0x20,
+    DW_EH_PE_datarel	= 0x30,
+    DW_EH_PE_funcrel	= 0x40,
+    DW_EH_PE_aligned	= 0x50,
+
+    // The GNU toolchain sources define this enum value as well,
+    // simply to help classify the lower nybble values into signed and
+    // unsigned groups.
+    DW_EH_PE_signed	= 0x08,
+
+    // This is not documented in LSB 4.0, but it is used in both the
+    // Linux and OS X toolchains. It can be added to any other
+    // encoding (except DW_EH_PE_aligned), and indicates that the
+    // encoded value represents the address at which the true address
+    // is stored, not the true address itself.
+    DW_EH_PE_indirect	= 0x80  
+  };
+
+}  // namespace dwarf2reader
+#endif  // COMMON_DWARF_DWARF2ENUMS_H__
diff --git a/3rdParty/Breakpad/src/common/dwarf/dwarf2reader.cc b/3rdParty/Breakpad/src/common/dwarf/dwarf2reader.cc
new file mode 100644
index 0000000..7c1a29d
--- /dev/null
+++ b/3rdParty/Breakpad/src/common/dwarf/dwarf2reader.cc
@@ -0,0 +1,2340 @@
+// 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.
+
+// CFI reader author: Jim Blandy <jimb@mozilla.com> <jimb@red-bean.com>
+
+// Implementation of dwarf2reader::LineInfo, dwarf2reader::CompilationUnit,
+// and dwarf2reader::CallFrameInfo. See dwarf2reader.h for details.
+
+#include "common/dwarf/dwarf2reader.h"
+
+#include <assert.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <map>
+#include <memory>
+#include <stack>
+#include <string>
+#include <utility>
+
+#include "common/dwarf/bytereader-inl.h"
+#include "common/dwarf/bytereader.h"
+#include "common/dwarf/line_state_machine.h"
+#include "common/using_std_string.h"
+
+namespace dwarf2reader {
+
+CompilationUnit::CompilationUnit(const SectionMap& sections, uint64 offset,
+                                 ByteReader* reader, Dwarf2Handler* handler)
+    : offset_from_section_start_(offset), reader_(reader),
+      sections_(sections), handler_(handler), abbrevs_(NULL),
+      string_buffer_(NULL), string_buffer_length_(0) {}
+
+// Read a DWARF2/3 abbreviation section.
+// Each abbrev consists of a abbreviation number, a tag, a byte
+// specifying whether the tag has children, and a list of
+// attribute/form pairs.
+// The list of forms is terminated by a 0 for the attribute, and a
+// zero for the form.  The entire abbreviation section is terminated
+// by a zero for the code.
+
+void CompilationUnit::ReadAbbrevs() {
+  if (abbrevs_)
+    return;
+
+  // First get the debug_abbrev section.  ".debug_abbrev" is the name
+  // recommended in the DWARF spec, and used on Linux;
+  // "__debug_abbrev" is the name used in Mac OS X Mach-O files.
+  SectionMap::const_iterator iter = sections_.find(".debug_abbrev");
+  if (iter == sections_.end())
+    iter = sections_.find("__debug_abbrev");
+  assert(iter != sections_.end());
+
+  abbrevs_ = new std::vector<Abbrev>;
+  abbrevs_->resize(1);
+
+  // The only way to check whether we are reading over the end of the
+  // buffer would be to first compute the size of the leb128 data by
+  // reading it, then go back and read it again.
+  const char* abbrev_start = iter->second.first +
+                                      header_.abbrev_offset;
+  const char* abbrevptr = abbrev_start;
+#ifndef NDEBUG
+  const uint64 abbrev_length = iter->second.second - header_.abbrev_offset;
+#endif
+
+  while (1) {
+    CompilationUnit::Abbrev abbrev;
+    size_t len;
+    const uint64 number = reader_->ReadUnsignedLEB128(abbrevptr, &len);
+
+    if (number == 0)
+      break;
+    abbrev.number = number;
+    abbrevptr += len;
+
+    assert(abbrevptr < abbrev_start + abbrev_length);
+    const uint64 tag = reader_->ReadUnsignedLEB128(abbrevptr, &len);
+    abbrevptr += len;
+    abbrev.tag = static_cast<enum DwarfTag>(tag);
+
+    assert(abbrevptr < abbrev_start + abbrev_length);
+    abbrev.has_children = reader_->ReadOneByte(abbrevptr);
+    abbrevptr += 1;
+
+    assert(abbrevptr < abbrev_start + abbrev_length);
+
+    while (1) {
+      const uint64 nametemp = reader_->ReadUnsignedLEB128(abbrevptr, &len);
+      abbrevptr += len;
+
+      assert(abbrevptr < abbrev_start + abbrev_length);
+      const uint64 formtemp = reader_->ReadUnsignedLEB128(abbrevptr, &len);
+      abbrevptr += len;
+      if (nametemp == 0 && formtemp == 0)
+        break;
+
+      const enum DwarfAttribute name =
+        static_cast<enum DwarfAttribute>(nametemp);
+      const enum DwarfForm form = static_cast<enum DwarfForm>(formtemp);
+      abbrev.attributes.push_back(std::make_pair(name, form));
+    }
+    assert(abbrev.number == abbrevs_->size());
+    abbrevs_->push_back(abbrev);
+  }
+}
+
+// Skips a single DIE's attributes.
+const char* CompilationUnit::SkipDIE(const char* start,
+                                              const Abbrev& abbrev) {
+  for (AttributeList::const_iterator i = abbrev.attributes.begin();
+       i != abbrev.attributes.end();
+       i++)  {
+    start = SkipAttribute(start, i->second);
+  }
+  return start;
+}
+
+// Skips a single attribute form's data.
+const char* CompilationUnit::SkipAttribute(const char* start,
+                                                    enum DwarfForm form) {
+  size_t len;
+
+  switch (form) {
+    case DW_FORM_indirect:
+      form = static_cast<enum DwarfForm>(reader_->ReadUnsignedLEB128(start,
+                                                                     &len));
+      start += len;
+      return SkipAttribute(start, form);
+
+    case DW_FORM_flag_present:
+      return start;
+    case DW_FORM_data1:
+    case DW_FORM_flag:
+    case DW_FORM_ref1:
+      return start + 1;
+    case DW_FORM_ref2:
+    case DW_FORM_data2:
+      return start + 2;
+    case DW_FORM_ref4:
+    case DW_FORM_data4:
+      return start + 4;
+    case DW_FORM_ref8:
+    case DW_FORM_data8:
+    case DW_FORM_ref_sig8:
+      return start + 8;
+    case DW_FORM_string:
+      return start + strlen(start) + 1;
+    case DW_FORM_udata:
+    case DW_FORM_ref_udata:
+      reader_->ReadUnsignedLEB128(start, &len);
+      return start + len;
+
+    case DW_FORM_sdata:
+      reader_->ReadSignedLEB128(start, &len);
+      return start + len;
+    case DW_FORM_addr:
+      return start + reader_->AddressSize();
+    case DW_FORM_ref_addr:
+      // DWARF2 and 3 differ on whether ref_addr is address size or
+      // offset size.
+      assert(header_.version == 2 || header_.version == 3);
+      if (header_.version == 2) {
+        return start + reader_->AddressSize();
+      } else if (header_.version == 3) {
+        return start + reader_->OffsetSize();
+      }
+
+    case DW_FORM_block1:
+      return start + 1 + reader_->ReadOneByte(start);
+    case DW_FORM_block2:
+      return start + 2 + reader_->ReadTwoBytes(start);
+    case DW_FORM_block4:
+      return start + 4 + reader_->ReadFourBytes(start);
+    case DW_FORM_block:
+    case DW_FORM_exprloc: {
+      uint64 size = reader_->ReadUnsignedLEB128(start, &len);
+      return start + size + len;
+    }
+    case DW_FORM_strp:
+    case DW_FORM_sec_offset:
+      return start + reader_->OffsetSize();
+  }
+  fprintf(stderr,"Unhandled form type");
+  return NULL;
+}
+
+// Read a DWARF2/3 header.
+// The header is variable length in DWARF3 (and DWARF2 as extended by
+// most compilers), and consists of an length field, a version number,
+// the offset in the .debug_abbrev section for our abbrevs, and an
+// address size.
+void CompilationUnit::ReadHeader() {
+  const char* headerptr = buffer_;
+  size_t initial_length_size;
+
+  assert(headerptr + 4 < buffer_ + buffer_length_);
+  const uint64 initial_length
+    = reader_->ReadInitialLength(headerptr, &initial_length_size);
+  headerptr += initial_length_size;
+  header_.length = initial_length;
+
+  assert(headerptr + 2 < buffer_ + buffer_length_);
+  header_.version = reader_->ReadTwoBytes(headerptr);
+  headerptr += 2;
+
+  assert(headerptr + reader_->OffsetSize() < buffer_ + buffer_length_);
+  header_.abbrev_offset = reader_->ReadOffset(headerptr);
+  headerptr += reader_->OffsetSize();
+
+  assert(headerptr + 1 < buffer_ + buffer_length_);
+  header_.address_size = reader_->ReadOneByte(headerptr);
+  reader_->SetAddressSize(header_.address_size);
+  headerptr += 1;
+
+  after_header_ = headerptr;
+
+  // This check ensures that we don't have to do checking during the
+  // reading of DIEs. header_.length does not include the size of the
+  // initial length.
+  assert(buffer_ + initial_length_size + header_.length <=
+        buffer_ + buffer_length_);
+}
+
+uint64 CompilationUnit::Start() {
+  // First get the debug_info section.  ".debug_info" is the name
+  // recommended in the DWARF spec, and used on Linux; "__debug_info"
+  // is the name used in Mac OS X Mach-O files.
+  SectionMap::const_iterator iter = sections_.find(".debug_info");
+  if (iter == sections_.end())
+    iter = sections_.find("__debug_info");
+  assert(iter != sections_.end());
+
+  // Set up our buffer
+  buffer_ = iter->second.first + offset_from_section_start_;
+  buffer_length_ = iter->second.second - offset_from_section_start_;
+
+  // Read the header
+  ReadHeader();
+
+  // Figure out the real length from the end of the initial length to
+  // the end of the compilation unit, since that is the value we
+  // return.
+  uint64 ourlength = header_.length;
+  if (reader_->OffsetSize() == 8)
+    ourlength += 12;
+  else
+    ourlength += 4;
+
+  // See if the user wants this compilation unit, and if not, just return.
+  if (!handler_->StartCompilationUnit(offset_from_section_start_,
+                                      reader_->AddressSize(),
+                                      reader_->OffsetSize(),
+                                      header_.length,
+                                      header_.version))
+    return ourlength;
+
+  // Otherwise, continue by reading our abbreviation entries.
+  ReadAbbrevs();
+
+  // Set the string section if we have one.  ".debug_str" is the name
+  // recommended in the DWARF spec, and used on Linux; "__debug_str"
+  // is the name used in Mac OS X Mach-O files.
+  iter = sections_.find(".debug_str");
+  if (iter == sections_.end())
+    iter = sections_.find("__debug_str");
+  if (iter != sections_.end()) {
+    string_buffer_ = iter->second.first;
+    string_buffer_length_ = iter->second.second;
+  }
+
+  // Now that we have our abbreviations, start processing DIE's.
+  ProcessDIEs();
+
+  return ourlength;
+}
+
+// If one really wanted, you could merge SkipAttribute and
+// ProcessAttribute
+// This is all boring data manipulation and calling of the handler.
+const char* CompilationUnit::ProcessAttribute(
+    uint64 dieoffset, const char* start, enum DwarfAttribute attr,
+    enum DwarfForm form) {
+  size_t len;
+
+  switch (form) {
+    // DW_FORM_indirect is never used because it is such a space
+    // waster.
+    case DW_FORM_indirect:
+      form = static_cast<enum DwarfForm>(reader_->ReadUnsignedLEB128(start,
+                                                                     &len));
+      start += len;
+      return ProcessAttribute(dieoffset, start, attr, form);
+
+    case DW_FORM_flag_present:
+      handler_->ProcessAttributeUnsigned(dieoffset, attr, form, 1);
+      return start;
+    case DW_FORM_data1:
+    case DW_FORM_flag:
+      handler_->ProcessAttributeUnsigned(dieoffset, attr, form,
+                                         reader_->ReadOneByte(start));
+      return start + 1;
+    case DW_FORM_data2:
+      handler_->ProcessAttributeUnsigned(dieoffset, attr, form,
+                                         reader_->ReadTwoBytes(start));
+      return start + 2;
+    case DW_FORM_data4:
+      handler_->ProcessAttributeUnsigned(dieoffset, attr, form,
+                                         reader_->ReadFourBytes(start));
+      return start + 4;
+    case DW_FORM_data8:
+      handler_->ProcessAttributeUnsigned(dieoffset, attr, form,
+                                         reader_->ReadEightBytes(start));
+      return start + 8;
+    case DW_FORM_string: {
+      const char* str = start;
+      handler_->ProcessAttributeString(dieoffset, attr, form,
+                                       str);
+      return start + strlen(str) + 1;
+    }
+    case DW_FORM_udata:
+      handler_->ProcessAttributeUnsigned(dieoffset, attr, form,
+                                         reader_->ReadUnsignedLEB128(start,
+                                                                     &len));
+      return start + len;
+
+    case DW_FORM_sdata:
+      handler_->ProcessAttributeSigned(dieoffset, attr, form,
+                                      reader_->ReadSignedLEB128(start, &len));
+      return start + len;
+    case DW_FORM_addr:
+      handler_->ProcessAttributeUnsigned(dieoffset, attr, form,
+                                         reader_->ReadAddress(start));
+      return start + reader_->AddressSize();
+    case DW_FORM_sec_offset:
+      handler_->ProcessAttributeUnsigned(dieoffset, attr, form,
+                                         reader_->ReadOffset(start));
+      return start + reader_->OffsetSize();
+
+    case DW_FORM_ref1:
+      handler_->ProcessAttributeReference(dieoffset, attr, form,
+                                          reader_->ReadOneByte(start)
+                                          + offset_from_section_start_);
+      return start + 1;
+    case DW_FORM_ref2:
+      handler_->ProcessAttributeReference(dieoffset, attr, form,
+                                          reader_->ReadTwoBytes(start)
+                                          + offset_from_section_start_);
+      return start + 2;
+    case DW_FORM_ref4:
+      handler_->ProcessAttributeReference(dieoffset, attr, form,
+                                          reader_->ReadFourBytes(start)
+                                          + offset_from_section_start_);
+      return start + 4;
+    case DW_FORM_ref8:
+      handler_->ProcessAttributeReference(dieoffset, attr, form,
+                                          reader_->ReadEightBytes(start)
+                                          + offset_from_section_start_);
+      return start + 8;
+    case DW_FORM_ref_udata:
+      handler_->ProcessAttributeReference(dieoffset, attr, form,
+                                          reader_->ReadUnsignedLEB128(start,
+                                                                      &len)
+                                          + offset_from_section_start_);
+      return start + len;
+    case DW_FORM_ref_addr:
+      // DWARF2 and 3 differ on whether ref_addr is address size or
+      // offset size.
+      assert(header_.version == 2 || header_.version == 3);
+      if (header_.version == 2) {
+        handler_->ProcessAttributeReference(dieoffset, attr, form,
+                                            reader_->ReadAddress(start));
+        return start + reader_->AddressSize();
+      } else if (header_.version == 3) {
+        handler_->ProcessAttributeReference(dieoffset, attr, form,
+                                            reader_->ReadOffset(start));
+        return start + reader_->OffsetSize();
+      }
+      break;
+    case DW_FORM_ref_sig8:
+      handler_->ProcessAttributeSignature(dieoffset, attr, form,
+                                          reader_->ReadEightBytes(start));
+      return start + 8;
+
+    case DW_FORM_block1: {
+      uint64 datalen = reader_->ReadOneByte(start);
+      handler_->ProcessAttributeBuffer(dieoffset, attr, form, start + 1,
+                                       datalen);
+      return start + 1 + datalen;
+    }
+    case DW_FORM_block2: {
+      uint64 datalen = reader_->ReadTwoBytes(start);
+      handler_->ProcessAttributeBuffer(dieoffset, attr, form, start + 2,
+                                       datalen);
+      return start + 2 + datalen;
+    }
+    case DW_FORM_block4: {
+      uint64 datalen = reader_->ReadFourBytes(start);
+      handler_->ProcessAttributeBuffer(dieoffset, attr, form, start + 4,
+                                       datalen);
+      return start + 4 + datalen;
+    }
+    case DW_FORM_block:
+    case DW_FORM_exprloc: {
+      uint64 datalen = reader_->ReadUnsignedLEB128(start, &len);
+      handler_->ProcessAttributeBuffer(dieoffset, attr, form, start + len,
+                                       datalen);
+      return start + datalen + len;
+    }
+    case DW_FORM_strp: {
+      assert(string_buffer_ != NULL);
+
+      const uint64 offset = reader_->ReadOffset(start);
+      assert(string_buffer_ + offset < string_buffer_ + string_buffer_length_);
+
+      const char* str = string_buffer_ + offset;
+      handler_->ProcessAttributeString(dieoffset, attr, form,
+                                       str);
+      return start + reader_->OffsetSize();
+    }
+  }
+  fprintf(stderr, "Unhandled form type\n");
+  return NULL;
+}
+
+const char* CompilationUnit::ProcessDIE(uint64 dieoffset,
+                                                 const char* start,
+                                                 const Abbrev& abbrev) {
+  for (AttributeList::const_iterator i = abbrev.attributes.begin();
+       i != abbrev.attributes.end();
+       i++)  {
+    start = ProcessAttribute(dieoffset, start, i->first, i->second);
+  }
+  return start;
+}
+
+void CompilationUnit::ProcessDIEs() {
+  const char* dieptr = after_header_;
+  size_t len;
+
+  // lengthstart is the place the length field is based on.
+  // It is the point in the header after the initial length field
+  const char* lengthstart = buffer_;
+
+  // In 64 bit dwarf, the initial length is 12 bytes, because of the
+  // 0xffffffff at the start.
+  if (reader_->OffsetSize() == 8)
+    lengthstart += 12;
+  else
+    lengthstart += 4;
+
+  std::stack<uint64> die_stack;
+  
+  while (dieptr < (lengthstart + header_.length)) {
+    // We give the user the absolute offset from the beginning of
+    // debug_info, since they need it to deal with ref_addr forms.
+    uint64 absolute_offset = (dieptr - buffer_) + offset_from_section_start_;
+
+    uint64 abbrev_num = reader_->ReadUnsignedLEB128(dieptr, &len);
+
+    dieptr += len;
+
+    // Abbrev == 0 represents the end of a list of children, or padding
+    // at the end of the compilation unit.
+    if (abbrev_num == 0) {
+      if (die_stack.size() == 0)
+        // If it is padding, then we are done with the compilation unit's DIEs.
+        return;
+      const uint64 offset = die_stack.top();
+      die_stack.pop();
+      handler_->EndDIE(offset);
+      continue;
+    }
+
+    const Abbrev& abbrev = abbrevs_->at(static_cast<size_t>(abbrev_num));
+    const enum DwarfTag tag = abbrev.tag;
+    if (!handler_->StartDIE(absolute_offset, tag, abbrev.attributes)) {
+      dieptr = SkipDIE(dieptr, abbrev);
+    } else {
+      dieptr = ProcessDIE(absolute_offset, dieptr, abbrev);
+    }
+
+    if (abbrev.has_children) {
+      die_stack.push(absolute_offset);
+    } else {
+      handler_->EndDIE(absolute_offset);
+    }
+  }
+}
+
+LineInfo::LineInfo(const char* buffer, uint64 buffer_length,
+                   ByteReader* reader, LineInfoHandler* handler):
+    handler_(handler), reader_(reader), buffer_(buffer),
+    buffer_length_(buffer_length) {
+  header_.std_opcode_lengths = NULL;
+}
+
+uint64 LineInfo::Start() {
+  ReadHeader();
+  ReadLines();
+  return after_header_ - buffer_;
+}
+
+// The header for a debug_line section is mildly complicated, because
+// the line info is very tightly encoded.
+void LineInfo::ReadHeader() {
+  const char* lineptr = buffer_;
+  size_t initial_length_size;
+
+  const uint64 initial_length
+    = reader_->ReadInitialLength(lineptr, &initial_length_size);
+
+  lineptr += initial_length_size;
+  header_.total_length = initial_length;
+  assert(buffer_ + initial_length_size + header_.total_length <=
+        buffer_ + buffer_length_);
+
+  // Address size *must* be set by CU ahead of time.
+  assert(reader_->AddressSize() != 0);
+
+  header_.version = reader_->ReadTwoBytes(lineptr);
+  lineptr += 2;
+
+  header_.prologue_length = reader_->ReadOffset(lineptr);
+  lineptr += reader_->OffsetSize();
+
+  header_.min_insn_length = reader_->ReadOneByte(lineptr);
+  lineptr += 1;
+
+  header_.default_is_stmt = reader_->ReadOneByte(lineptr);
+  lineptr += 1;
+
+  header_.line_base = *reinterpret_cast<const int8*>(lineptr);
+  lineptr += 1;
+
+  header_.line_range = reader_->ReadOneByte(lineptr);
+  lineptr += 1;
+
+  header_.opcode_base = reader_->ReadOneByte(lineptr);
+  lineptr += 1;
+
+  header_.std_opcode_lengths = new std::vector<unsigned char>;
+  header_.std_opcode_lengths->resize(header_.opcode_base + 1);
+  (*header_.std_opcode_lengths)[0] = 0;
+  for (int i = 1; i < header_.opcode_base; i++) {
+    (*header_.std_opcode_lengths)[i] = reader_->ReadOneByte(lineptr);
+    lineptr += 1;
+  }
+
+  // It is legal for the directory entry table to be empty.
+  if (*lineptr) {
+    uint32 dirindex = 1;
+    while (*lineptr) {
+      const char* dirname = lineptr;
+      handler_->DefineDir(dirname, dirindex);
+      lineptr += strlen(dirname) + 1;
+      dirindex++;
+    }
+  }
+  lineptr++;
+
+  // It is also legal for the file entry table to be empty.
+  if (*lineptr) {
+    uint32 fileindex = 1;
+    size_t len;
+    while (*lineptr) {
+      const char* filename = lineptr;
+      lineptr += strlen(filename) + 1;
+
+      uint64 dirindex = reader_->ReadUnsignedLEB128(lineptr, &len);
+      lineptr += len;
+
+      uint64 mod_time = reader_->ReadUnsignedLEB128(lineptr, &len);
+      lineptr += len;
+
+      uint64 filelength = reader_->ReadUnsignedLEB128(lineptr, &len);
+      lineptr += len;
+      handler_->DefineFile(filename, fileindex, static_cast<uint32>(dirindex), 
+                           mod_time, filelength);
+      fileindex++;
+    }
+  }
+  lineptr++;
+
+  after_header_ = lineptr;
+}
+
+/* static */
+bool LineInfo::ProcessOneOpcode(ByteReader* reader,
+                                LineInfoHandler* handler,
+                                const struct LineInfoHeader &header,
+                                const char* start,
+                                struct LineStateMachine* lsm,
+                                size_t* len,
+                                uintptr pc,
+                                bool *lsm_passes_pc) {
+  size_t oplen = 0;
+  size_t templen;
+  uint8 opcode = reader->ReadOneByte(start);
+  oplen++;
+  start++;
+
+  // If the opcode is great than the opcode_base, it is a special
+  // opcode. Most line programs consist mainly of special opcodes.
+  if (opcode >= header.opcode_base) {
+    opcode -= header.opcode_base;
+    const int64 advance_address = (opcode / header.line_range)
+                                  * header.min_insn_length;
+    const int32 advance_line = (opcode % header.line_range)
+                               + header.line_base;
+
+    // Check if the lsm passes "pc". If so, mark it as passed.
+    if (lsm_passes_pc &&
+        lsm->address <= pc && pc < lsm->address + advance_address) {
+      *lsm_passes_pc = true;
+    }
+
+    lsm->address += advance_address;
+    lsm->line_num += advance_line;
+    lsm->basic_block = true;
+    *len = oplen;
+    return true;
+  }
+
+  // Otherwise, we have the regular opcodes
+  switch (opcode) {
+    case DW_LNS_copy: {
+      lsm->basic_block = false;
+      *len = oplen;
+      return true;
+    }
+
+    case DW_LNS_advance_pc: {
+      uint64 advance_address = reader->ReadUnsignedLEB128(start, &templen);
+      oplen += templen;
+
+      // Check if the lsm passes "pc". If so, mark it as passed.
+      if (lsm_passes_pc && lsm->address <= pc &&
+          pc < lsm->address + header.min_insn_length * advance_address) {
+        *lsm_passes_pc = true;
+      }
+
+      lsm->address += header.min_insn_length * advance_address;
+    }
+      break;
+    case DW_LNS_advance_line: {
+      const int64 advance_line = reader->ReadSignedLEB128(start, &templen);
+      oplen += templen;
+      lsm->line_num += static_cast<int32>(advance_line);
+
+      // With gcc 4.2.1, we can get the line_no here for the first time
+      // since DW_LNS_advance_line is called after DW_LNE_set_address is
+      // called. So we check if the lsm passes "pc" here, not in
+      // DW_LNE_set_address.
+      if (lsm_passes_pc && lsm->address == pc) {
+        *lsm_passes_pc = true;
+      }
+    }
+      break;
+    case DW_LNS_set_file: {
+      const uint64 fileno = reader->ReadUnsignedLEB128(start, &templen);
+      oplen += templen;
+      lsm->file_num = static_cast<uint32>(fileno);
+    }
+      break;
+    case DW_LNS_set_column: {
+      const uint64 colno = reader->ReadUnsignedLEB128(start, &templen);
+      oplen += templen;
+      lsm->column_num = static_cast<uint32>(colno);
+    }
+      break;
+    case DW_LNS_negate_stmt: {
+      lsm->is_stmt = !lsm->is_stmt;
+    }
+      break;
+    case DW_LNS_set_basic_block: {
+      lsm->basic_block = true;
+    }
+      break;
+    case DW_LNS_fixed_advance_pc: {
+      const uint16 advance_address = reader->ReadTwoBytes(start);
+      oplen += 2;
+
+      // Check if the lsm passes "pc". If so, mark it as passed.
+      if (lsm_passes_pc &&
+          lsm->address <= pc && pc < lsm->address + advance_address) {
+        *lsm_passes_pc = true;
+      }
+
+      lsm->address += advance_address;
+    }
+      break;
+    case DW_LNS_const_add_pc: {
+      const int64 advance_address = header.min_insn_length
+                                    * ((255 - header.opcode_base)
+                                       / header.line_range);
+
+      // Check if the lsm passes "pc". If so, mark it as passed.
+      if (lsm_passes_pc &&
+          lsm->address <= pc && pc < lsm->address + advance_address) {
+        *lsm_passes_pc = true;
+      }
+
+      lsm->address += advance_address;
+    }
+      break;
+    case DW_LNS_extended_op: {
+      const uint64 extended_op_len = reader->ReadUnsignedLEB128(start,
+                                                                &templen);
+      start += templen;
+      oplen += templen + extended_op_len;
+
+      const uint64 extended_op = reader->ReadOneByte(start);
+      start++;
+
+      switch (extended_op) {
+        case DW_LNE_end_sequence: {
+          lsm->end_sequence = true;
+          *len = oplen;
+          return true;
+        }
+          break;
+        case DW_LNE_set_address: {
+          // With gcc 4.2.1, we cannot tell the line_no here since
+          // DW_LNE_set_address is called before DW_LNS_advance_line is
+          // called.  So we do not check if the lsm passes "pc" here.  See
+          // also the comment in DW_LNS_advance_line.
+          uint64 address = reader->ReadAddress(start);
+          lsm->address = address;
+        }
+          break;
+        case DW_LNE_define_file: {
+          const char* filename  = start;
+
+          templen = strlen(filename) + 1;
+          start += templen;
+
+          uint64 dirindex = reader->ReadUnsignedLEB128(start, &templen);
+          oplen += templen;
+
+          const uint64 mod_time = reader->ReadUnsignedLEB128(start,
+                                                             &templen);
+          oplen += templen;
+
+          const uint64 filelength = reader->ReadUnsignedLEB128(start,
+                                                               &templen);
+          oplen += templen;
+
+          if (handler) {
+            handler->DefineFile(filename, -1, static_cast<uint32>(dirindex), 
+                                mod_time, filelength);
+          }
+        }
+          break;
+      }
+    }
+      break;
+
+    default: {
+      // Ignore unknown opcode  silently
+      if (header.std_opcode_lengths) {
+        for (int i = 0; i < (*header.std_opcode_lengths)[opcode]; i++) {
+          reader->ReadUnsignedLEB128(start, &templen);
+          start += templen;
+          oplen += templen;
+        }
+      }
+    }
+      break;
+  }
+  *len = oplen;
+  return false;
+}
+
+void LineInfo::ReadLines() {
+  struct LineStateMachine lsm;
+
+  // lengthstart is the place the length field is based on.
+  // It is the point in the header after the initial length field
+  const char* lengthstart = buffer_;
+
+  // In 64 bit dwarf, the initial length is 12 bytes, because of the
+  // 0xffffffff at the start.
+  if (reader_->OffsetSize() == 8)
+    lengthstart += 12;
+  else
+    lengthstart += 4;
+
+  const char* lineptr = after_header_;
+  lsm.Reset(header_.default_is_stmt);
+
+  // The LineInfoHandler interface expects each line's length along
+  // with its address, but DWARF only provides addresses (sans
+  // length), and an end-of-sequence address; one infers the length
+  // from the next address. So we report a line only when we get the
+  // next line's address, or the end-of-sequence address.
+  bool have_pending_line = false;
+  uint64 pending_address = 0;
+  uint32 pending_file_num = 0, pending_line_num = 0, pending_column_num = 0;
+
+  while (lineptr < lengthstart + header_.total_length) {
+    size_t oplength;
+    bool add_row = ProcessOneOpcode(reader_, handler_, header_,
+                                    lineptr, &lsm, &oplength, (uintptr)-1,
+                                    NULL);
+    if (add_row) {
+      if (have_pending_line)
+        handler_->AddLine(pending_address, lsm.address - pending_address,
+                          pending_file_num, pending_line_num,
+                          pending_column_num);
+      if (lsm.end_sequence) {
+        lsm.Reset(header_.default_is_stmt);      
+        have_pending_line = false;
+      } else {
+        pending_address = lsm.address;
+        pending_file_num = lsm.file_num;
+        pending_line_num = lsm.line_num;
+        pending_column_num = lsm.column_num;
+        have_pending_line = true;
+      }
+    }
+    lineptr += oplength;
+  }
+
+  after_header_ = lengthstart + header_.total_length;
+}
+
+// A DWARF rule for recovering the address or value of a register, or
+// computing the canonical frame address. There is one subclass of this for
+// each '*Rule' member function in CallFrameInfo::Handler.
+//
+// It's annoying that we have to handle Rules using pointers (because
+// the concrete instances can have an arbitrary size). They're small,
+// so it would be much nicer if we could just handle them by value
+// instead of fretting about ownership and destruction.
+//
+// It seems like all these could simply be instances of std::tr1::bind,
+// except that we need instances to be EqualityComparable, too.
+//
+// This could logically be nested within State, but then the qualified names
+// get horrendous.
+class CallFrameInfo::Rule {
+ public:
+  virtual ~Rule() { }
+
+  // Tell HANDLER that, at ADDRESS in the program, REGISTER can be
+  // recovered using this rule. If REGISTER is kCFARegister, then this rule
+  // describes how to compute the canonical frame address. Return what the
+  // HANDLER member function returned.
+  virtual bool Handle(Handler *handler,
+                      uint64 address, int register) const = 0;
+
+  // Equality on rules. We use these to decide which rules we need
+  // to report after a DW_CFA_restore_state instruction.
+  virtual bool operator==(const Rule &rhs) const = 0;
+
+  bool operator!=(const Rule &rhs) const { return ! (*this == rhs); }
+
+  // Return a pointer to a copy of this rule.
+  virtual Rule *Copy() const = 0;
+
+  // If this is a base+offset rule, change its base register to REG.
+  // Otherwise, do nothing. (Ugly, but required for DW_CFA_def_cfa_register.)
+  virtual void SetBaseRegister(unsigned reg) { }
+
+  // If this is a base+offset rule, change its offset to OFFSET. Otherwise,
+  // do nothing. (Ugly, but required for DW_CFA_def_cfa_offset.)
+  virtual void SetOffset(long long offset) { }
+};
+
+// Rule: the value the register had in the caller cannot be recovered.
+class CallFrameInfo::UndefinedRule: public CallFrameInfo::Rule {
+ public:
+  UndefinedRule() { }
+  ~UndefinedRule() { }
+  bool Handle(Handler *handler, uint64 address, int reg) const {
+    return handler->UndefinedRule(address, reg);
+  }
+  bool operator==(const Rule &rhs) const {
+    // dynamic_cast is allowed by the Google C++ Style Guide, if the use has
+    // been carefully considered; cheap RTTI-like workarounds are forbidden.
+    const UndefinedRule *our_rhs = dynamic_cast<const UndefinedRule *>(&rhs);
+    return (our_rhs != NULL);
+  }
+  Rule *Copy() const { return new UndefinedRule(*this); }
+};
+
+// Rule: the register's value is the same as that it had in the caller.
+class CallFrameInfo::SameValueRule: public CallFrameInfo::Rule {
+ public:
+  SameValueRule() { }
+  ~SameValueRule() { }
+  bool Handle(Handler *handler, uint64 address, int reg) const {
+    return handler->SameValueRule(address, reg);
+  }
+  bool operator==(const Rule &rhs) const {
+    // dynamic_cast is allowed by the Google C++ Style Guide, if the use has
+    // been carefully considered; cheap RTTI-like workarounds are forbidden.
+    const SameValueRule *our_rhs = dynamic_cast<const SameValueRule *>(&rhs);
+    return (our_rhs != NULL);
+  }
+  Rule *Copy() const { return new SameValueRule(*this); }
+};
+
+// Rule: the register is saved at OFFSET from BASE_REGISTER.  BASE_REGISTER
+// may be CallFrameInfo::Handler::kCFARegister.
+class CallFrameInfo::OffsetRule: public CallFrameInfo::Rule {
+ public:
+  OffsetRule(int base_register, long offset)
+      : base_register_(base_register), offset_(offset) { }
+  ~OffsetRule() { }
+  bool Handle(Handler *handler, uint64 address, int reg) const {
+    return handler->OffsetRule(address, reg, base_register_, offset_);
+  }
+  bool operator==(const Rule &rhs) const {
+    // dynamic_cast is allowed by the Google C++ Style Guide, if the use has
+    // been carefully considered; cheap RTTI-like workarounds are forbidden.
+    const OffsetRule *our_rhs = dynamic_cast<const OffsetRule *>(&rhs);
+    return (our_rhs &&
+            base_register_ == our_rhs->base_register_ &&
+            offset_ == our_rhs->offset_);
+  }
+  Rule *Copy() const { return new OffsetRule(*this); }
+  // We don't actually need SetBaseRegister or SetOffset here, since they
+  // are only ever applied to CFA rules, for DW_CFA_def_cfa_offset, and it
+  // doesn't make sense to use OffsetRule for computing the CFA: it
+  // computes the address at which a register is saved, not a value.
+ private:
+  int base_register_;
+  long offset_;
+};
+
+// Rule: the value the register had in the caller is the value of
+// BASE_REGISTER plus offset. BASE_REGISTER may be
+// CallFrameInfo::Handler::kCFARegister.
+class CallFrameInfo::ValOffsetRule: public CallFrameInfo::Rule {
+ public:
+  ValOffsetRule(int base_register, long offset)
+      : base_register_(base_register), offset_(offset) { }
+  ~ValOffsetRule() { }
+  bool Handle(Handler *handler, uint64 address, int reg) const {
+    return handler->ValOffsetRule(address, reg, base_register_, offset_);
+  }
+  bool operator==(const Rule &rhs) const {
+    // dynamic_cast is allowed by the Google C++ Style Guide, if the use has
+    // been carefully considered; cheap RTTI-like workarounds are forbidden.
+    const ValOffsetRule *our_rhs = dynamic_cast<const ValOffsetRule *>(&rhs);
+    return (our_rhs &&
+            base_register_ == our_rhs->base_register_ &&
+            offset_ == our_rhs->offset_);
+  }
+  Rule *Copy() const { return new ValOffsetRule(*this); }
+  void SetBaseRegister(unsigned reg) { base_register_ = reg; }
+  void SetOffset(long long offset) { offset_ = offset; }
+ private:
+  int base_register_;
+  long offset_;
+};
+
+// Rule: the register has been saved in another register REGISTER_NUMBER_.
+class CallFrameInfo::RegisterRule: public CallFrameInfo::Rule {
+ public:
+  explicit RegisterRule(int register_number)
+      : register_number_(register_number) { }
+  ~RegisterRule() { }
+  bool Handle(Handler *handler, uint64 address, int reg) const {
+    return handler->RegisterRule(address, reg, register_number_);
+  }
+  bool operator==(const Rule &rhs) const {
+    // dynamic_cast is allowed by the Google C++ Style Guide, if the use has
+    // been carefully considered; cheap RTTI-like workarounds are forbidden.
+    const RegisterRule *our_rhs = dynamic_cast<const RegisterRule *>(&rhs);
+    return (our_rhs && register_number_ == our_rhs->register_number_);
+  }
+  Rule *Copy() const { return new RegisterRule(*this); }
+ private:
+  int register_number_;
+};
+
+// Rule: EXPRESSION evaluates to the address at which the register is saved.
+class CallFrameInfo::ExpressionRule: public CallFrameInfo::Rule {
+ public:
+  explicit ExpressionRule(const string &expression)
+      : expression_(expression) { }
+  ~ExpressionRule() { }
+  bool Handle(Handler *handler, uint64 address, int reg) const {
+    return handler->ExpressionRule(address, reg, expression_);
+  }
+  bool operator==(const Rule &rhs) const {
+    // dynamic_cast is allowed by the Google C++ Style Guide, if the use has
+    // been carefully considered; cheap RTTI-like workarounds are forbidden.
+    const ExpressionRule *our_rhs = dynamic_cast<const ExpressionRule *>(&rhs);
+    return (our_rhs && expression_ == our_rhs->expression_);
+  }
+  Rule *Copy() const { return new ExpressionRule(*this); }
+ private:
+  string expression_;
+};
+
+// Rule: EXPRESSION evaluates to the address at which the register is saved.
+class CallFrameInfo::ValExpressionRule: public CallFrameInfo::Rule {
+ public:
+  explicit ValExpressionRule(const string &expression)
+      : expression_(expression) { }
+  ~ValExpressionRule() { }
+  bool Handle(Handler *handler, uint64 address, int reg) const {
+    return handler->ValExpressionRule(address, reg, expression_);
+  }
+  bool operator==(const Rule &rhs) const {
+    // dynamic_cast is allowed by the Google C++ Style Guide, if the use has
+    // been carefully considered; cheap RTTI-like workarounds are forbidden.
+    const ValExpressionRule *our_rhs =
+        dynamic_cast<const ValExpressionRule *>(&rhs);
+    return (our_rhs && expression_ == our_rhs->expression_);
+  }
+  Rule *Copy() const { return new ValExpressionRule(*this); }
+ private:
+  string expression_;
+};
+
+// A map from register numbers to rules.
+class CallFrameInfo::RuleMap {
+ public:
+  RuleMap() : cfa_rule_(NULL) { }
+  RuleMap(const RuleMap &rhs) : cfa_rule_(NULL) { *this = rhs; }
+  ~RuleMap() { Clear(); }
+
+  RuleMap &operator=(const RuleMap &rhs);
+
+  // Set the rule for computing the CFA to RULE. Take ownership of RULE.
+  void SetCFARule(Rule *rule) { delete cfa_rule_; cfa_rule_ = rule; }
+
+  // Return the current CFA rule. Unlike RegisterRule, this RuleMap retains
+  // ownership of the rule. We use this for DW_CFA_def_cfa_offset and
+  // DW_CFA_def_cfa_register, and for detecting references to the CFA before
+  // a rule for it has been established.
+  Rule *CFARule() const { return cfa_rule_; }
+
+  // Return the rule for REG, or NULL if there is none. The caller takes
+  // ownership of the result.
+  Rule *RegisterRule(int reg) const;
+
+  // Set the rule for computing REG to RULE. Take ownership of RULE.
+  void SetRegisterRule(int reg, Rule *rule);
+
+  // Make all the appropriate calls to HANDLER as if we were changing from
+  // this RuleMap to NEW_RULES at ADDRESS. We use this to implement
+  // DW_CFA_restore_state, where lots of rules can change simultaneously.
+  // Return true if all handlers returned true; otherwise, return false.
+  bool HandleTransitionTo(Handler *handler, uint64 address,
+                          const RuleMap &new_rules) const;
+
+ private:
+  // A map from register numbers to Rules.
+  typedef std::map<int, Rule *> RuleByNumber;
+
+  // Remove all register rules and clear cfa_rule_.
+  void Clear();
+
+  // The rule for computing the canonical frame address. This RuleMap owns
+  // this rule.
+  Rule *cfa_rule_;
+
+  // A map from register numbers to postfix expressions to recover
+  // their values. This RuleMap owns the Rules the map refers to.
+  RuleByNumber registers_;
+};
+
+CallFrameInfo::RuleMap &CallFrameInfo::RuleMap::operator=(const RuleMap &rhs) {
+  Clear();
+  // Since each map owns the rules it refers to, assignment must copy them.
+  if (rhs.cfa_rule_) cfa_rule_ = rhs.cfa_rule_->Copy();
+  for (RuleByNumber::const_iterator it = rhs.registers_.begin();
+       it != rhs.registers_.end(); it++)
+    registers_[it->first] = it->second->Copy();
+  return *this;
+}
+
+CallFrameInfo::Rule *CallFrameInfo::RuleMap::RegisterRule(int reg) const {
+  assert(reg != Handler::kCFARegister);
+  RuleByNumber::const_iterator it = registers_.find(reg);
+  if (it != registers_.end())
+    return it->second->Copy();
+  else
+    return NULL;
+}
+
+void CallFrameInfo::RuleMap::SetRegisterRule(int reg, Rule *rule) {
+  assert(reg != Handler::kCFARegister);
+  assert(rule);
+  Rule **slot = &registers_[reg];
+  delete *slot;
+  *slot = rule;
+}
+
+bool CallFrameInfo::RuleMap::HandleTransitionTo(
+    Handler *handler,
+    uint64 address,
+    const RuleMap &new_rules) const {
+  // Transition from cfa_rule_ to new_rules.cfa_rule_.
+  if (cfa_rule_ && new_rules.cfa_rule_) {
+    if (*cfa_rule_ != *new_rules.cfa_rule_ &&
+        !new_rules.cfa_rule_->Handle(handler, address,
+                                     Handler::kCFARegister))
+      return false;
+  } else if (cfa_rule_) {
+    // this RuleMap has a CFA rule but new_rules doesn't.
+    // CallFrameInfo::Handler has no way to handle this --- and shouldn't;
+    // it's garbage input. The instruction interpreter should have
+    // detected this and warned, so take no action here.
+  } else if (new_rules.cfa_rule_) {
+    // This shouldn't be possible: NEW_RULES is some prior state, and
+    // there's no way to remove entries.
+    assert(0);
+  } else {
+    // Both CFA rules are empty.  No action needed.
+  }
+
+  // Traverse the two maps in order by register number, and report
+  // whatever differences we find.
+  RuleByNumber::const_iterator old_it = registers_.begin();
+  RuleByNumber::const_iterator new_it = new_rules.registers_.begin();
+  while (old_it != registers_.end() && new_it != new_rules.registers_.end()) {
+    if (old_it->first < new_it->first) {
+      // This RuleMap has an entry for old_it->first, but NEW_RULES
+      // doesn't.
+      //
+      // This isn't really the right thing to do, but since CFI generally
+      // only mentions callee-saves registers, and GCC's convention for
+      // callee-saves registers is that they are unchanged, it's a good
+      // approximation.
+      if (!handler->SameValueRule(address, old_it->first))
+        return false;
+      old_it++;
+    } else if (old_it->first > new_it->first) {
+      // NEW_RULES has entry for new_it->first, but this RuleMap
+      // doesn't. This shouldn't be possible: NEW_RULES is some prior
+      // state, and there's no way to remove entries.
+      assert(0);
+    } else {
+      // Both maps have an entry for this register. Report the new
+      // rule if it is different.
+      if (*old_it->second != *new_it->second &&
+          !new_it->second->Handle(handler, address, new_it->first))
+        return false;
+      new_it++, old_it++;
+    }
+  }
+  // Finish off entries from this RuleMap with no counterparts in new_rules.
+  while (old_it != registers_.end()) {
+    if (!handler->SameValueRule(address, old_it->first))
+      return false;
+    old_it++;
+  }
+  // Since we only make transitions from a rule set to some previously
+  // saved rule set, and we can only add rules to the map, NEW_RULES
+  // must have fewer rules than *this.
+  assert(new_it == new_rules.registers_.end());
+
+  return true;
+}
+
+// Remove all register rules and clear cfa_rule_.
+void CallFrameInfo::RuleMap::Clear() {
+  delete cfa_rule_;
+  cfa_rule_ = NULL;
+  for (RuleByNumber::iterator it = registers_.begin();
+       it != registers_.end(); it++)
+    delete it->second;
+  registers_.clear();
+}
+
+// The state of the call frame information interpreter as it processes
+// instructions from a CIE and FDE.
+class CallFrameInfo::State {
+ public:
+  // Create a call frame information interpreter state with the given
+  // reporter, reader, handler, and initial call frame info address.
+  State(ByteReader *reader, Handler *handler, Reporter *reporter,
+        uint64 address)
+      : reader_(reader), handler_(handler), reporter_(reporter),
+        address_(address), entry_(NULL), cursor_(NULL) { }
+
+  // Interpret instructions from CIE, save the resulting rule set for
+  // DW_CFA_restore instructions, and return true. On error, report
+  // the problem to reporter_ and return false.
+  bool InterpretCIE(const CIE &cie);
+
+  // Interpret instructions from FDE, and return true. On error,
+  // report the problem to reporter_ and return false.
+  bool InterpretFDE(const FDE &fde);
+
+ private:  
+  // The operands of a CFI instruction, for ParseOperands.
+  struct Operands {
+    unsigned register_number;  // A register number.
+    uint64 offset;             // An offset or address.
+    long signed_offset;        // A signed offset.
+    string expression;         // A DWARF expression.
+  };
+
+  // Parse CFI instruction operands from STATE's instruction stream as
+  // described by FORMAT. On success, populate OPERANDS with the
+  // results, and return true. On failure, report the problem and
+  // return false.
+  //
+  // Each character of FORMAT should be one of the following:
+  //
+  //   'r'  unsigned LEB128 register number (OPERANDS->register_number)
+  //   'o'  unsigned LEB128 offset          (OPERANDS->offset)
+  //   's'  signed LEB128 offset            (OPERANDS->signed_offset)
+  //   'a'  machine-size address            (OPERANDS->offset)
+  //        (If the CIE has a 'z' augmentation string, 'a' uses the
+  //        encoding specified by the 'R' argument.)
+  //   '1'  a one-byte offset               (OPERANDS->offset)
+  //   '2'  a two-byte offset               (OPERANDS->offset)
+  //   '4'  a four-byte offset              (OPERANDS->offset)
+  //   '8'  an eight-byte offset            (OPERANDS->offset)
+  //   'e'  a DW_FORM_block holding a       (OPERANDS->expression)
+  //        DWARF expression
+  bool ParseOperands(const char *format, Operands *operands);
+
+  // Interpret one CFI instruction from STATE's instruction stream, update
+  // STATE, report any rule changes to handler_, and return true. On
+  // failure, report the problem and return false.
+  bool DoInstruction();
+
+  // The following Do* member functions are subroutines of DoInstruction,
+  // factoring out the actual work of operations that have several
+  // different encodings.
+
+  // Set the CFA rule to be the value of BASE_REGISTER plus OFFSET, and
+  // return true. On failure, report and return false. (Used for
+  // DW_CFA_def_cfa and DW_CFA_def_cfa_sf.)
+  bool DoDefCFA(unsigned base_register, long offset);
+
+  // Change the offset of the CFA rule to OFFSET, and return true. On
+  // failure, report and return false. (Subroutine for
+  // DW_CFA_def_cfa_offset and DW_CFA_def_cfa_offset_sf.)
+  bool DoDefCFAOffset(long offset);
+
+  // Specify that REG can be recovered using RULE, and return true. On
+  // failure, report and return false.
+  bool DoRule(unsigned reg, Rule *rule);
+
+  // Specify that REG can be found at OFFSET from the CFA, and return true.
+  // On failure, report and return false. (Subroutine for DW_CFA_offset,
+  // DW_CFA_offset_extended, and DW_CFA_offset_extended_sf.)
+  bool DoOffset(unsigned reg, long offset);
+
+  // Specify that the caller's value for REG is the CFA plus OFFSET,
+  // and return true. On failure, report and return false. (Subroutine
+  // for DW_CFA_val_offset and DW_CFA_val_offset_sf.)
+  bool DoValOffset(unsigned reg, long offset);
+
+  // Restore REG to the rule established in the CIE, and return true. On
+  // failure, report and return false. (Subroutine for DW_CFA_restore and
+  // DW_CFA_restore_extended.)
+  bool DoRestore(unsigned reg);
+
+  // Return the section offset of the instruction at cursor. For use
+  // in error messages.
+  uint64 CursorOffset() { return entry_->offset + (cursor_ - entry_->start); }
+
+  // Report that entry_ is incomplete, and return false. For brevity.
+  bool ReportIncomplete() {
+    reporter_->Incomplete(entry_->offset, entry_->kind);
+    return false;
+  }
+
+  // For reading multi-byte values with the appropriate endianness.
+  ByteReader *reader_;
+
+  // The handler to which we should report the data we find.
+  Handler *handler_;
+
+  // For reporting problems in the info we're parsing.
+  Reporter *reporter_;
+
+  // The code address to which the next instruction in the stream applies.
+  uint64 address_;
+
+  // The entry whose instructions we are currently processing. This is
+  // first a CIE, and then an FDE.
+  const Entry *entry_;
+
+  // The next instruction to process.
+  const char *cursor_;
+
+  // The current set of rules.
+  RuleMap rules_;
+
+  // The set of rules established by the CIE, used by DW_CFA_restore
+  // and DW_CFA_restore_extended. We set this after interpreting the
+  // CIE's instructions.
+  RuleMap cie_rules_;
+
+  // A stack of saved states, for DW_CFA_remember_state and
+  // DW_CFA_restore_state.
+  std::stack<RuleMap> saved_rules_;
+};
+
+bool CallFrameInfo::State::InterpretCIE(const CIE &cie) {
+  entry_ = &cie;
+  cursor_ = entry_->instructions;
+  while (cursor_ < entry_->end)
+    if (!DoInstruction())
+      return false;
+  // Note the rules established by the CIE, for use by DW_CFA_restore
+  // and DW_CFA_restore_extended.
+  cie_rules_ = rules_;
+  return true;
+}
+
+bool CallFrameInfo::State::InterpretFDE(const FDE &fde) {
+  entry_ = &fde;
+  cursor_ = entry_->instructions;
+  while (cursor_ < entry_->end)
+    if (!DoInstruction())
+      return false;
+  return true;
+}
+
+bool CallFrameInfo::State::ParseOperands(const char *format,
+                                         Operands *operands) {
+  size_t len;
+  const char *operand;
+
+  for (operand = format; *operand; operand++) {
+    size_t bytes_left = entry_->end - cursor_;
+    switch (*operand) {
+      case 'r':
+        operands->register_number = reader_->ReadUnsignedLEB128(cursor_, &len);
+        if (len > bytes_left) return ReportIncomplete();
+        cursor_ += len;
+        break;
+
+      case 'o':
+        operands->offset = reader_->ReadUnsignedLEB128(cursor_, &len);
+        if (len > bytes_left) return ReportIncomplete();
+        cursor_ += len;
+        break;
+
+      case 's':
+        operands->signed_offset = reader_->ReadSignedLEB128(cursor_, &len);
+        if (len > bytes_left) return ReportIncomplete();
+        cursor_ += len;
+        break;
+
+      case 'a':
+        operands->offset =
+          reader_->ReadEncodedPointer(cursor_, entry_->cie->pointer_encoding,
+                                      &len);
+        if (len > bytes_left) return ReportIncomplete();
+        cursor_ += len;
+        break;
+
+      case '1':
+        if (1 > bytes_left) return ReportIncomplete();
+        operands->offset = static_cast<unsigned char>(*cursor_++);
+        break;
+
+      case '2':
+        if (2 > bytes_left) return ReportIncomplete();
+        operands->offset = reader_->ReadTwoBytes(cursor_);
+        cursor_ += 2;
+        break;
+
+      case '4':
+        if (4 > bytes_left) return ReportIncomplete();
+        operands->offset = reader_->ReadFourBytes(cursor_);
+        cursor_ += 4;
+        break;
+
+      case '8':
+        if (8 > bytes_left) return ReportIncomplete();
+        operands->offset = reader_->ReadEightBytes(cursor_);
+        cursor_ += 8;
+        break;
+
+      case 'e': {
+        size_t expression_length = reader_->ReadUnsignedLEB128(cursor_, &len);
+        if (len > bytes_left || expression_length > bytes_left - len)
+          return ReportIncomplete();
+        cursor_ += len;
+        operands->expression = string(cursor_, expression_length);
+        cursor_ += expression_length;
+        break;
+      }
+
+      default:
+          assert(0);
+    }
+  }
+
+  return true;
+}
+
+bool CallFrameInfo::State::DoInstruction() {
+  CIE *cie = entry_->cie;
+  Operands ops;
+
+  // Our entry's kind should have been set by now.
+  assert(entry_->kind != kUnknown);
+
+  // We shouldn't have been invoked unless there were more
+  // instructions to parse.
+  assert(cursor_ < entry_->end);
+
+  unsigned opcode = *cursor_++;
+  if ((opcode & 0xc0) != 0) {
+    switch (opcode & 0xc0) {
+      // Advance the address.
+      case DW_CFA_advance_loc: {
+        size_t code_offset = opcode & 0x3f;
+        address_ += code_offset * cie->code_alignment_factor;
+        break;
+      }
+
+      // Find a register at an offset from the CFA.
+      case DW_CFA_offset:
+        if (!ParseOperands("o", &ops) ||
+            !DoOffset(opcode & 0x3f, ops.offset * cie->data_alignment_factor))
+          return false;
+        break;
+
+      // Restore the rule established for a register by the CIE.
+      case DW_CFA_restore:
+        if (!DoRestore(opcode & 0x3f)) return false;
+        break;
+
+      // The 'if' above should have excluded this possibility.
+      default:
+        assert(0);
+    }
+
+    // Return here, so the big switch below won't be indented.
+    return true;
+  }
+
+  switch (opcode) {
+    // Set the address.
+    case DW_CFA_set_loc:
+      if (!ParseOperands("a", &ops)) return false;
+      address_ = ops.offset;
+      break;
+
+    // Advance the address.
+    case DW_CFA_advance_loc1:
+      if (!ParseOperands("1", &ops)) return false;
+      address_ += ops.offset * cie->code_alignment_factor;
+      break;
+      
+    // Advance the address.
+    case DW_CFA_advance_loc2:
+      if (!ParseOperands("2", &ops)) return false;
+      address_ += ops.offset * cie->code_alignment_factor;
+      break;
+      
+    // Advance the address.
+    case DW_CFA_advance_loc4:
+      if (!ParseOperands("4", &ops)) return false;
+      address_ += ops.offset * cie->code_alignment_factor;
+      break;
+      
+    // Advance the address.
+    case DW_CFA_MIPS_advance_loc8:
+      if (!ParseOperands("8", &ops)) return false;
+      address_ += ops.offset * cie->code_alignment_factor;
+      break;
+
+    // Compute the CFA by adding an offset to a register.
+    case DW_CFA_def_cfa:
+      if (!ParseOperands("ro", &ops) ||
+          !DoDefCFA(ops.register_number, ops.offset))
+        return false;
+      break;
+
+    // Compute the CFA by adding an offset to a register.
+    case DW_CFA_def_cfa_sf:
+      if (!ParseOperands("rs", &ops) ||
+          !DoDefCFA(ops.register_number,
+                    ops.signed_offset * cie->data_alignment_factor))
+        return false;
+      break;
+
+    // Change the base register used to compute the CFA.
+    case DW_CFA_def_cfa_register: {
+      Rule *cfa_rule = rules_.CFARule();
+      if (!cfa_rule) {
+        reporter_->NoCFARule(entry_->offset, entry_->kind, CursorOffset());
+        return false;
+      }
+      if (!ParseOperands("r", &ops)) return false;
+      cfa_rule->SetBaseRegister(ops.register_number);
+      if (!cfa_rule->Handle(handler_, address_,
+                            Handler::kCFARegister))
+        return false;
+      break;
+    }
+
+    // Change the offset used to compute the CFA.
+    case DW_CFA_def_cfa_offset:
+      if (!ParseOperands("o", &ops) ||
+          !DoDefCFAOffset(ops.offset))
+        return false;
+      break;
+
+    // Change the offset used to compute the CFA.
+    case DW_CFA_def_cfa_offset_sf:
+      if (!ParseOperands("s", &ops) ||
+          !DoDefCFAOffset(ops.signed_offset * cie->data_alignment_factor))
+        return false;
+      break;
+
+    // Specify an expression whose value is the CFA.
+    case DW_CFA_def_cfa_expression: {
+      if (!ParseOperands("e", &ops))
+        return false;
+      Rule *rule = new ValExpressionRule(ops.expression);
+      rules_.SetCFARule(rule);
+      if (!rule->Handle(handler_, address_,
+                        Handler::kCFARegister))
+        return false;
+      break;
+    }
+
+    // The register's value cannot be recovered.
+    case DW_CFA_undefined: {
+      if (!ParseOperands("r", &ops) ||
+          !DoRule(ops.register_number, new UndefinedRule()))
+        return false;
+      break;
+    }
+
+    // The register's value is unchanged from its value in the caller.
+    case DW_CFA_same_value: {
+      if (!ParseOperands("r", &ops) ||
+          !DoRule(ops.register_number, new SameValueRule()))
+        return false;
+      break;
+    }
+
+    // Find a register at an offset from the CFA.
+    case DW_CFA_offset_extended:
+      if (!ParseOperands("ro", &ops) ||
+          !DoOffset(ops.register_number,
+                    ops.offset * cie->data_alignment_factor))
+        return false;
+      break;
+
+    // The register is saved at an offset from the CFA.
+    case DW_CFA_offset_extended_sf:
+      if (!ParseOperands("rs", &ops) ||
+          !DoOffset(ops.register_number,
+                    ops.signed_offset * cie->data_alignment_factor))
+        return false;
+      break;
+
+    // The register is saved at an offset from the CFA.
+    case DW_CFA_GNU_negative_offset_extended:
+      if (!ParseOperands("ro", &ops) ||
+          !DoOffset(ops.register_number,
+                    -ops.offset * cie->data_alignment_factor))
+        return false;
+      break;
+
+    // The register's value is the sum of the CFA plus an offset.
+    case DW_CFA_val_offset:
+      if (!ParseOperands("ro", &ops) ||
+          !DoValOffset(ops.register_number,
+                       ops.offset * cie->data_alignment_factor))
+        return false;
+      break;
+
+    // The register's value is the sum of the CFA plus an offset.
+    case DW_CFA_val_offset_sf:
+      if (!ParseOperands("rs", &ops) ||
+          !DoValOffset(ops.register_number,
+                       ops.signed_offset * cie->data_alignment_factor))
+        return false;
+      break;
+
+    // The register has been saved in another register.
+    case DW_CFA_register: {
+      if (!ParseOperands("ro", &ops) ||
+          !DoRule(ops.register_number, new RegisterRule(ops.offset)))
+        return false;
+      break;
+    }
+
+    // An expression yields the address at which the register is saved.
+    case DW_CFA_expression: {
+      if (!ParseOperands("re", &ops) ||
+          !DoRule(ops.register_number, new ExpressionRule(ops.expression)))
+        return false;
+      break;
+    }
+
+    // An expression yields the caller's value for the register.
+    case DW_CFA_val_expression: {
+      if (!ParseOperands("re", &ops) ||
+          !DoRule(ops.register_number, new ValExpressionRule(ops.expression)))
+        return false;
+      break;
+    }
+
+    // Restore the rule established for a register by the CIE.
+    case DW_CFA_restore_extended:
+      if (!ParseOperands("r", &ops) ||
+          !DoRestore( ops.register_number))
+        return false;
+      break;
+
+    // Save the current set of rules on a stack.
+    case DW_CFA_remember_state:
+      saved_rules_.push(rules_);
+      break;
+
+    // Pop the current set of rules off the stack.
+    case DW_CFA_restore_state: {
+      if (saved_rules_.empty()) {
+        reporter_->EmptyStateStack(entry_->offset, entry_->kind,
+                                   CursorOffset());
+        return false;
+      }
+      const RuleMap &new_rules = saved_rules_.top();
+      if (rules_.CFARule() && !new_rules.CFARule()) {
+        reporter_->ClearingCFARule(entry_->offset, entry_->kind,
+                                   CursorOffset());
+        return false;
+      }
+      rules_.HandleTransitionTo(handler_, address_, new_rules);
+      rules_ = new_rules;
+      saved_rules_.pop();
+      break;
+    }
+
+    // No operation.  (Padding instruction.)
+    case DW_CFA_nop:
+      break;
+
+    // A SPARC register window save: Registers 8 through 15 (%o0-%o7)
+    // are saved in registers 24 through 31 (%i0-%i7), and registers
+    // 16 through 31 (%l0-%l7 and %i0-%i7) are saved at CFA offsets
+    // (0-15 * the register size). The register numbers must be
+    // hard-coded. A GNU extension, and not a pretty one.
+    case DW_CFA_GNU_window_save: {
+      // Save %o0-%o7 in %i0-%i7.
+      for (int i = 8; i < 16; i++)
+        if (!DoRule(i, new RegisterRule(i + 16)))
+          return false;
+      // Save %l0-%l7 and %i0-%i7 at the CFA.
+      for (int i = 16; i < 32; i++)
+        // Assume that the byte reader's address size is the same as
+        // the architecture's register size. !@#%*^ hilarious.
+        if (!DoRule(i, new OffsetRule(Handler::kCFARegister,
+                                      (i - 16) * reader_->AddressSize())))
+          return false;
+      break;
+    }
+
+    // I'm not sure what this is. GDB doesn't use it for unwinding.
+    case DW_CFA_GNU_args_size:
+      if (!ParseOperands("o", &ops)) return false;
+      break;
+
+    // An opcode we don't recognize.
+    default: {
+      reporter_->BadInstruction(entry_->offset, entry_->kind, CursorOffset());
+      return false;
+    }
+  }
+
+  return true;
+}
+
+bool CallFrameInfo::State::DoDefCFA(unsigned base_register, long offset) {
+  Rule *rule = new ValOffsetRule(base_register, offset);
+  rules_.SetCFARule(rule);
+  return rule->Handle(handler_, address_,
+                      Handler::kCFARegister);
+}
+
+bool CallFrameInfo::State::DoDefCFAOffset(long offset) {
+  Rule *cfa_rule = rules_.CFARule();
+  if (!cfa_rule) {
+    reporter_->NoCFARule(entry_->offset, entry_->kind, CursorOffset());
+    return false;
+  }
+  cfa_rule->SetOffset(offset);
+  return cfa_rule->Handle(handler_, address_,
+                          Handler::kCFARegister);
+}
+
+bool CallFrameInfo::State::DoRule(unsigned reg, Rule *rule) {
+  rules_.SetRegisterRule(reg, rule);
+  return rule->Handle(handler_, address_, reg);
+}
+
+bool CallFrameInfo::State::DoOffset(unsigned reg, long offset) {
+  if (!rules_.CFARule()) {
+    reporter_->NoCFARule(entry_->offset, entry_->kind, CursorOffset());
+    return false;
+  }
+  return DoRule(reg,
+                new OffsetRule(Handler::kCFARegister, offset));
+}
+
+bool CallFrameInfo::State::DoValOffset(unsigned reg, long offset) {
+  if (!rules_.CFARule()) {
+    reporter_->NoCFARule(entry_->offset, entry_->kind, CursorOffset());
+    return false;
+  }
+  return DoRule(reg,
+                new ValOffsetRule(Handler::kCFARegister, offset));
+}
+
+bool CallFrameInfo::State::DoRestore(unsigned reg) {
+  // DW_CFA_restore and DW_CFA_restore_extended don't make sense in a CIE.
+  if (entry_->kind == kCIE) {
+    reporter_->RestoreInCIE(entry_->offset, CursorOffset());
+    return false;
+  }
+  Rule *rule = cie_rules_.RegisterRule(reg);
+  if (!rule) {
+    // This isn't really the right thing to do, but since CFI generally
+    // only mentions callee-saves registers, and GCC's convention for
+    // callee-saves registers is that they are unchanged, it's a good
+    // approximation.
+    rule = new SameValueRule();
+  }
+  return DoRule(reg, rule);
+}
+
+bool CallFrameInfo::ReadEntryPrologue(const char *cursor, Entry *entry) {
+  const char *buffer_end = buffer_ + buffer_length_;
+
+  // Initialize enough of ENTRY for use in error reporting.
+  entry->offset = cursor - buffer_;
+  entry->start = cursor;
+  entry->kind = kUnknown;
+  entry->end = NULL;
+
+  // Read the initial length. This sets reader_'s offset size.
+  size_t length_size;
+  uint64 length = reader_->ReadInitialLength(cursor, &length_size);
+  if (length_size > size_t(buffer_end - cursor))
+    return ReportIncomplete(entry);
+  cursor += length_size;
+
+  // In a .eh_frame section, a length of zero marks the end of the series
+  // of entries.
+  if (length == 0 && eh_frame_) {
+    entry->kind = kTerminator;
+    entry->end = cursor;
+    return true;
+  }
+
+  // Validate the length.
+  if (length > size_t(buffer_end - cursor))
+    return ReportIncomplete(entry);
+ 
+  // The length is the number of bytes after the initial length field;
+  // we have that position handy at this point, so compute the end
+  // now. (If we're parsing 64-bit-offset DWARF on a 32-bit machine,
+  // and the length didn't fit in a size_t, we would have rejected it
+  // above.)
+  entry->end = cursor + length;
+
+  // Parse the next field: either the offset of a CIE or a CIE id.
+  size_t offset_size = reader_->OffsetSize();
+  if (offset_size > size_t(entry->end - cursor)) return ReportIncomplete(entry);
+  entry->id = reader_->ReadOffset(cursor);
+
+  // Don't advance cursor past id field yet; in .eh_frame data we need
+  // the id's position to compute the section offset of an FDE's CIE.
+
+  // Now we can decide what kind of entry this is.
+  if (eh_frame_) {
+    // In .eh_frame data, an ID of zero marks the entry as a CIE, and
+    // anything else is an offset from the id field of the FDE to the start
+    // of the CIE.
+    if (entry->id == 0) {
+      entry->kind = kCIE;
+    } else {
+      entry->kind = kFDE;
+      // Turn the offset from the id into an offset from the buffer's start.
+      entry->id = (cursor - buffer_) - entry->id;
+    }
+  } else {
+    // In DWARF CFI data, an ID of ~0 (of the appropriate width, given the
+    // offset size for the entry) marks the entry as a CIE, and anything
+    // else is the offset of the CIE from the beginning of the section.
+    if (offset_size == 4)
+      entry->kind = (entry->id == 0xffffffff) ? kCIE : kFDE;
+    else {
+      assert(offset_size == 8);
+      entry->kind = (entry->id == 0xffffffffffffffffULL) ? kCIE : kFDE;
+    }
+  }
+
+  // Now advance cursor past the id.
+   cursor += offset_size;
+ 
+  // The fields specific to this kind of entry start here.
+  entry->fields = cursor;
+
+  entry->cie = NULL;
+
+  return true;
+}
+
+bool CallFrameInfo::ReadCIEFields(CIE *cie) {
+  const char *cursor = cie->fields;
+  size_t len;
+
+  assert(cie->kind == kCIE);
+
+  // Prepare for early exit.
+  cie->version = 0;
+  cie->augmentation.clear();
+  cie->code_alignment_factor = 0;
+  cie->data_alignment_factor = 0;
+  cie->return_address_register = 0;
+  cie->has_z_augmentation = false;
+  cie->pointer_encoding = DW_EH_PE_absptr;
+  cie->instructions = 0;
+
+  // Parse the version number.
+  if (cie->end - cursor < 1)
+    return ReportIncomplete(cie);
+  cie->version = reader_->ReadOneByte(cursor);
+  cursor++;
+
+  // If we don't recognize the version, we can't parse any more fields of the
+  // CIE. For DWARF CFI, we handle versions 1 through 3 (there was never a
+  // version 2 of CFI data). For .eh_frame, we handle versions 1 and 3 as well;
+  // the difference between those versions seems to be the same as for
+  // .debug_frame.
+  if (cie->version < 1 || cie->version > 3) {
+    reporter_->UnrecognizedVersion(cie->offset, cie->version);
+    return false;
+  }
+
+  const char *augmentation_start = cursor;
+  const void *augmentation_end =
+      memchr(augmentation_start, '\0', cie->end - augmentation_start);
+  if (! augmentation_end) return ReportIncomplete(cie);
+  cursor = static_cast<const char *>(augmentation_end);
+  cie->augmentation = string(augmentation_start,
+                                  cursor - augmentation_start);
+  // Skip the terminating '\0'.
+  cursor++;
+
+  // Is this CFI augmented?
+  if (!cie->augmentation.empty()) {
+    // Is it an augmentation we recognize?
+    if (cie->augmentation[0] == DW_Z_augmentation_start) {
+      // Linux C++ ABI 'z' augmentation, used for exception handling data.
+      cie->has_z_augmentation = true;
+    } else {
+      // Not an augmentation we recognize. Augmentations can have arbitrary
+      // effects on the form of rest of the content, so we have to give up.
+      reporter_->UnrecognizedAugmentation(cie->offset, cie->augmentation);
+      return false;
+    }
+  }
+
+  // Parse the code alignment factor.
+  cie->code_alignment_factor = reader_->ReadUnsignedLEB128(cursor, &len);
+  if (size_t(cie->end - cursor) < len) return ReportIncomplete(cie);
+  cursor += len;
+  
+  // Parse the data alignment factor.
+  cie->data_alignment_factor = reader_->ReadSignedLEB128(cursor, &len);
+  if (size_t(cie->end - cursor) < len) return ReportIncomplete(cie);
+  cursor += len;
+  
+  // Parse the return address register. This is a ubyte in version 1, and
+  // a ULEB128 in version 3.
+  if (cie->version == 1) {
+    if (cursor >= cie->end) return ReportIncomplete(cie);
+    cie->return_address_register = uint8(*cursor++);
+  } else {
+    cie->return_address_register = reader_->ReadUnsignedLEB128(cursor, &len);
+    if (size_t(cie->end - cursor) < len) return ReportIncomplete(cie);
+    cursor += len;
+  }
+
+  // If we have a 'z' augmentation string, find the augmentation data and
+  // use the augmentation string to parse it.
+  if (cie->has_z_augmentation) {
+    uint64_t data_size = reader_->ReadUnsignedLEB128(cursor, &len);
+    if (size_t(cie->end - cursor) < len + data_size)
+      return ReportIncomplete(cie);
+    cursor += len;
+    const char *data = cursor;
+    cursor += data_size;
+    const char *data_end = cursor;
+
+    cie->has_z_lsda = false;
+    cie->has_z_personality = false;
+    cie->has_z_signal_frame = false;
+
+    // Walk the augmentation string, and extract values from the
+    // augmentation data as the string directs.
+    for (size_t i = 1; i < cie->augmentation.size(); i++) {
+      switch (cie->augmentation[i]) {
+        case DW_Z_has_LSDA:
+          // The CIE's augmentation data holds the language-specific data
+          // area pointer's encoding, and the FDE's augmentation data holds
+          // the pointer itself.
+          cie->has_z_lsda = true;
+          // Fetch the LSDA encoding from the augmentation data.
+          if (data >= data_end) return ReportIncomplete(cie);
+          cie->lsda_encoding = DwarfPointerEncoding(*data++);
+          if (!reader_->ValidEncoding(cie->lsda_encoding)) {
+            reporter_->InvalidPointerEncoding(cie->offset, cie->lsda_encoding);
+            return false;
+          }
+          // Don't check if the encoding is usable here --- we haven't
+          // read the FDE's fields yet, so we're not prepared for
+          // DW_EH_PE_funcrel, although that's a fine encoding for the
+          // LSDA to use, since it appears in the FDE.
+          break;
+
+        case DW_Z_has_personality_routine:
+          // The CIE's augmentation data holds the personality routine
+          // pointer's encoding, followed by the pointer itself.
+          cie->has_z_personality = true;
+          // Fetch the personality routine pointer's encoding from the
+          // augmentation data.
+          if (data >= data_end) return ReportIncomplete(cie);
+          cie->personality_encoding = DwarfPointerEncoding(*data++);
+          if (!reader_->ValidEncoding(cie->personality_encoding)) {
+            reporter_->InvalidPointerEncoding(cie->offset,
+                                              cie->personality_encoding);
+            return false;
+          }
+          if (!reader_->UsableEncoding(cie->personality_encoding)) {
+            reporter_->UnusablePointerEncoding(cie->offset,
+                                               cie->personality_encoding);
+            return false;
+          }
+          // Fetch the personality routine's pointer itself from the data.
+          cie->personality_address =
+            reader_->ReadEncodedPointer(data, cie->personality_encoding,
+                                        &len);
+          if (len > size_t(data_end - data))
+            return ReportIncomplete(cie);
+          data += len;
+          break;
+
+        case DW_Z_has_FDE_address_encoding:
+          // The CIE's augmentation data holds the pointer encoding to use
+          // for addresses in the FDE.
+          if (data >= data_end) return ReportIncomplete(cie);
+          cie->pointer_encoding = DwarfPointerEncoding(*data++);
+          if (!reader_->ValidEncoding(cie->pointer_encoding)) {
+            reporter_->InvalidPointerEncoding(cie->offset,
+                                              cie->pointer_encoding);
+            return false;
+          }
+          if (!reader_->UsableEncoding(cie->pointer_encoding)) {
+            reporter_->UnusablePointerEncoding(cie->offset,
+                                               cie->pointer_encoding);
+            return false;
+          }
+          break;
+
+        case DW_Z_is_signal_trampoline:
+          // Frames using this CIE are signal delivery frames.
+          cie->has_z_signal_frame = true;
+          break;
+
+        default:
+          // An augmentation we don't recognize.
+          reporter_->UnrecognizedAugmentation(cie->offset, cie->augmentation);
+          return false;
+      }
+    }
+  }
+
+  // The CIE's instructions start here.
+  cie->instructions = cursor;
+
+  return true;
+}
+  
+bool CallFrameInfo::ReadFDEFields(FDE *fde) {
+  const char *cursor = fde->fields;
+  size_t size;
+
+  fde->address = reader_->ReadEncodedPointer(cursor, fde->cie->pointer_encoding,
+                                             &size);
+  if (size > size_t(fde->end - cursor))
+    return ReportIncomplete(fde);
+  cursor += size;
+  reader_->SetFunctionBase(fde->address);
+
+  // For the length, we strip off the upper nybble of the encoding used for
+  // the starting address.
+  DwarfPointerEncoding length_encoding =
+    DwarfPointerEncoding(fde->cie->pointer_encoding & 0x0f);
+  fde->size = reader_->ReadEncodedPointer(cursor, length_encoding, &size);
+  if (size > size_t(fde->end - cursor))
+    return ReportIncomplete(fde);
+  cursor += size;
+
+  // If the CIE has a 'z' augmentation string, then augmentation data
+  // appears here.
+  if (fde->cie->has_z_augmentation) {
+    uint64_t data_size = reader_->ReadUnsignedLEB128(cursor, &size);
+    if (size_t(fde->end - cursor) < size + data_size)
+      return ReportIncomplete(fde);
+    cursor += size;
+    
+    // In the abstract, we should walk the augmentation string, and extract
+    // items from the FDE's augmentation data as we encounter augmentation
+    // string characters that specify their presence: the ordering of items
+    // in the augmentation string determines the arrangement of values in
+    // the augmentation data.
+    //
+    // In practice, there's only ever one value in FDE augmentation data
+    // that we support --- the LSDA pointer --- and we have to bail if we
+    // see any unrecognized augmentation string characters. So if there is
+    // anything here at all, we know what it is, and where it starts.
+    if (fde->cie->has_z_lsda) {
+      // Check whether the LSDA's pointer encoding is usable now: only once
+      // we've parsed the FDE's starting address do we call reader_->
+      // SetFunctionBase, so that the DW_EH_PE_funcrel encoding becomes
+      // usable.
+      if (!reader_->UsableEncoding(fde->cie->lsda_encoding)) {
+        reporter_->UnusablePointerEncoding(fde->cie->offset,
+                                           fde->cie->lsda_encoding);
+        return false;
+      }
+
+      fde->lsda_address =
+        reader_->ReadEncodedPointer(cursor, fde->cie->lsda_encoding, &size);
+      if (size > data_size)
+        return ReportIncomplete(fde);
+      // Ideally, we would also complain here if there were unconsumed
+      // augmentation data.
+    }
+
+    cursor += data_size;
+  }
+
+  // The FDE's instructions start after those.
+  fde->instructions = cursor;
+
+  return true;
+}
+  
+bool CallFrameInfo::Start() {
+  const char *buffer_end = buffer_ + buffer_length_;
+  const char *cursor;
+  bool all_ok = true;
+  const char *entry_end;
+  bool ok;
+
+  // Traverse all the entries in buffer_, skipping CIEs and offering
+  // FDEs to the handler.
+  for (cursor = buffer_; cursor < buffer_end;
+       cursor = entry_end, all_ok = all_ok && ok) {
+    FDE fde;
+
+    // Make it easy to skip this entry with 'continue': assume that
+    // things are not okay until we've checked all the data, and
+    // prepare the address of the next entry.
+    ok = false;
+
+    // Read the entry's prologue.
+    if (!ReadEntryPrologue(cursor, &fde)) {
+      if (!fde.end) {
+        // If we couldn't even figure out this entry's extent, then we
+        // must stop processing entries altogether.
+        all_ok = false;
+        break;
+      }
+      entry_end = fde.end;
+      continue;
+    }
+
+    // The next iteration picks up after this entry.
+    entry_end = fde.end;
+
+    // Did we see an .eh_frame terminating mark?
+    if (fde.kind == kTerminator) {
+      // If there appears to be more data left in the section after the
+      // terminating mark, warn the user. But this is just a warning;
+      // we leave all_ok true.
+      if (fde.end < buffer_end) reporter_->EarlyEHTerminator(fde.offset);
+      break;
+    }
+
+    // In this loop, we skip CIEs. We only parse them fully when we
+    // parse an FDE that refers to them. This limits our memory
+    // consumption (beyond the buffer itself) to that needed to
+    // process the largest single entry.
+    if (fde.kind != kFDE) {
+      ok = true;
+      continue;
+    }
+
+    // Validate the CIE pointer.
+    if (fde.id > buffer_length_) {
+      reporter_->CIEPointerOutOfRange(fde.offset, fde.id);
+      continue;
+    }
+      
+    CIE cie;
+
+    // Parse this FDE's CIE header.
+    if (!ReadEntryPrologue(buffer_ + fde.id, &cie))
+      continue;
+    // This had better be an actual CIE.
+    if (cie.kind != kCIE) {
+      reporter_->BadCIEId(fde.offset, fde.id);
+      continue;
+    }
+    if (!ReadCIEFields(&cie))
+      continue;
+
+    // We now have the values that govern both the CIE and the FDE.
+    cie.cie = &cie;
+    fde.cie = &cie;
+
+    // Parse the FDE's header.
+    if (!ReadFDEFields(&fde))
+      continue;
+
+    // Call Entry to ask the consumer if they're interested.
+    if (!handler_->Entry(fde.offset, fde.address, fde.size,
+                         cie.version, cie.augmentation,
+                         cie.return_address_register)) {
+      // The handler isn't interested in this entry. That's not an error.
+      ok = true;
+      continue;
+    }
+                         
+    if (cie.has_z_augmentation) {
+      // Report the personality routine address, if we have one.
+      if (cie.has_z_personality) {
+        if (!handler_
+            ->PersonalityRoutine(cie.personality_address,
+                                 IsIndirectEncoding(cie.personality_encoding)))
+          continue;
+      }
+
+      // Report the language-specific data area address, if we have one.
+      if (cie.has_z_lsda) {
+        if (!handler_
+            ->LanguageSpecificDataArea(fde.lsda_address,
+                                       IsIndirectEncoding(cie.lsda_encoding)))
+          continue;
+      }
+
+      // If this is a signal-handling frame, report that.
+      if (cie.has_z_signal_frame) {
+        if (!handler_->SignalHandler())
+          continue;
+      }
+    }
+
+    // Interpret the CIE's instructions, and then the FDE's instructions.
+    State state(reader_, handler_, reporter_, fde.address);
+    ok = state.InterpretCIE(cie) && state.InterpretFDE(fde);
+
+    // Tell the ByteReader that the function start address from the
+    // FDE header is no longer valid.
+    reader_->ClearFunctionBase();
+
+    // Report the end of the entry.
+    handler_->End();
+  }
+
+  return all_ok;
+}
+
+const char *CallFrameInfo::KindName(EntryKind kind) {
+  if (kind == CallFrameInfo::kUnknown)
+    return "entry";
+  else if (kind == CallFrameInfo::kCIE)
+    return "common information entry";
+  else if (kind == CallFrameInfo::kFDE)
+    return "frame description entry";
+  else {
+    assert (kind == CallFrameInfo::kTerminator);
+    return ".eh_frame sequence terminator";
+  }
+}
+
+bool CallFrameInfo::ReportIncomplete(Entry *entry) {
+  reporter_->Incomplete(entry->offset, entry->kind);
+  return false;
+}
+
+void CallFrameInfo::Reporter::Incomplete(uint64 offset,
+                                         CallFrameInfo::EntryKind kind) {
+  fprintf(stderr,
+          "%s: CFI %s at offset 0x%llx in '%s': entry ends early\n",
+          filename_.c_str(), CallFrameInfo::KindName(kind), offset,
+          section_.c_str());
+}
+
+void CallFrameInfo::Reporter::EarlyEHTerminator(uint64 offset) {
+  fprintf(stderr,
+          "%s: CFI at offset 0x%llx in '%s': saw end-of-data marker"
+          " before end of section contents\n",
+          filename_.c_str(), offset, section_.c_str());
+}
+
+void CallFrameInfo::Reporter::CIEPointerOutOfRange(uint64 offset,
+                                                   uint64 cie_offset) {
+  fprintf(stderr,
+          "%s: CFI frame description entry at offset 0x%llx in '%s':"
+          " CIE pointer is out of range: 0x%llx\n",
+          filename_.c_str(), offset, section_.c_str(), cie_offset);
+}
+
+void CallFrameInfo::Reporter::BadCIEId(uint64 offset, uint64 cie_offset) {
+  fprintf(stderr,
+          "%s: CFI frame description entry at offset 0x%llx in '%s':"
+          " CIE pointer does not point to a CIE: 0x%llx\n",
+          filename_.c_str(), offset, section_.c_str(), cie_offset);
+}
+
+void CallFrameInfo::Reporter::UnrecognizedVersion(uint64 offset, int version) {
+  fprintf(stderr,
+          "%s: CFI frame description entry at offset 0x%llx in '%s':"
+          " CIE specifies unrecognized version: %d\n",
+          filename_.c_str(), offset, section_.c_str(), version);
+}
+
+void CallFrameInfo::Reporter::UnrecognizedAugmentation(uint64 offset,
+                                                       const string &aug) {
+  fprintf(stderr,
+          "%s: CFI frame description entry at offset 0x%llx in '%s':"
+          " CIE specifies unrecognized augmentation: '%s'\n",
+          filename_.c_str(), offset, section_.c_str(), aug.c_str());
+}
+
+void CallFrameInfo::Reporter::InvalidPointerEncoding(uint64 offset,
+                                                     uint8 encoding) {
+  fprintf(stderr,
+          "%s: CFI common information entry at offset 0x%llx in '%s':"
+          " 'z' augmentation specifies invalid pointer encoding: 0x%02x\n",
+          filename_.c_str(), offset, section_.c_str(), encoding);
+}
+
+void CallFrameInfo::Reporter::UnusablePointerEncoding(uint64 offset,
+                                                      uint8 encoding) {
+  fprintf(stderr,
+          "%s: CFI common information entry at offset 0x%llx in '%s':"
+          " 'z' augmentation specifies a pointer encoding for which"
+          " we have no base address: 0x%02x\n",
+          filename_.c_str(), offset, section_.c_str(), encoding);
+}
+
+void CallFrameInfo::Reporter::RestoreInCIE(uint64 offset, uint64 insn_offset) {
+  fprintf(stderr,
+          "%s: CFI common information entry at offset 0x%llx in '%s':"
+          " the DW_CFA_restore instruction at offset 0x%llx"
+          " cannot be used in a common information entry\n",
+          filename_.c_str(), offset, section_.c_str(), insn_offset);
+}
+
+void CallFrameInfo::Reporter::BadInstruction(uint64 offset,
+                                             CallFrameInfo::EntryKind kind,
+                                             uint64 insn_offset) {
+  fprintf(stderr,
+          "%s: CFI %s at offset 0x%llx in section '%s':"
+          " the instruction at offset 0x%llx is unrecognized\n",
+          filename_.c_str(), CallFrameInfo::KindName(kind),
+          offset, section_.c_str(), insn_offset);
+}
+
+void CallFrameInfo::Reporter::NoCFARule(uint64 offset,
+                                        CallFrameInfo::EntryKind kind,
+                                        uint64 insn_offset) {
+  fprintf(stderr,
+          "%s: CFI %s at offset 0x%llx in section '%s':"
+          " the instruction at offset 0x%llx assumes that a CFA rule has"
+          " been set, but none has been set\n",
+          filename_.c_str(), CallFrameInfo::KindName(kind), offset,
+          section_.c_str(), insn_offset);
+}
+
+void CallFrameInfo::Reporter::EmptyStateStack(uint64 offset,
+                                              CallFrameInfo::EntryKind kind,
+                                              uint64 insn_offset) {
+  fprintf(stderr,
+          "%s: CFI %s at offset 0x%llx in section '%s':"
+          " the DW_CFA_restore_state instruction at offset 0x%llx"
+          " should pop a saved state from the stack, but the stack is empty\n",
+          filename_.c_str(), CallFrameInfo::KindName(kind), offset,
+          section_.c_str(), insn_offset);
+}
+
+void CallFrameInfo::Reporter::ClearingCFARule(uint64 offset,
+                                              CallFrameInfo::EntryKind kind,
+                                              uint64 insn_offset) {
+  fprintf(stderr,
+          "%s: CFI %s at offset 0x%llx in section '%s':"
+          " the DW_CFA_restore_state instruction at offset 0x%llx"
+          " would clear the CFA rule in effect\n",
+          filename_.c_str(), CallFrameInfo::KindName(kind), offset,
+          section_.c_str(), insn_offset);
+}
+
+}  // namespace dwarf2reader
diff --git a/3rdParty/Breakpad/src/common/dwarf/dwarf2reader.h b/3rdParty/Breakpad/src/common/dwarf/dwarf2reader.h
new file mode 100644
index 0000000..ecf4eb2
--- /dev/null
+++ b/3rdParty/Breakpad/src/common/dwarf/dwarf2reader.h
@@ -0,0 +1,1051 @@
+// -*- mode: C++ -*-
+
+// 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.
+
+// CFI reader author: Jim Blandy <jimb@mozilla.com> <jimb@red-bean.com>
+
+// This file contains definitions related to the DWARF2/3 reader and
+// it's handler interfaces.
+// The DWARF2/3 specification can be found at
+// http://dwarf.freestandards.org and should be considered required
+// reading if you wish to modify the implementation.
+// Only a cursory attempt is made to explain terminology that is
+// used here, as it is much better explained in the standard documents
+#ifndef COMMON_DWARF_DWARF2READER_H__
+#define COMMON_DWARF_DWARF2READER_H__
+
+#include <list>
+#include <map>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "common/dwarf/bytereader.h"
+#include "common/dwarf/dwarf2enums.h"
+#include "common/dwarf/types.h"
+#include "common/using_std_string.h"
+
+namespace dwarf2reader {
+struct LineStateMachine;
+class Dwarf2Handler;
+class LineInfoHandler;
+
+// This maps from a string naming a section to a pair containing a
+// the data for the section, and the size of the section.
+typedef std::map<string, std::pair<const char*, uint64> > SectionMap;
+typedef std::list<std::pair<enum DwarfAttribute, enum DwarfForm> >
+    AttributeList;
+typedef AttributeList::iterator AttributeIterator;
+typedef AttributeList::const_iterator ConstAttributeIterator;
+
+struct LineInfoHeader {
+  uint64 total_length;
+  uint16 version;
+  uint64 prologue_length;
+  uint8 min_insn_length; // insn stands for instructin
+  bool default_is_stmt; // stmt stands for statement
+  int8 line_base;
+  uint8 line_range;
+  uint8 opcode_base;
+  // Use a pointer so that signalsafe_addr2line is able to use this structure
+  // without heap allocation problem.
+  std::vector<unsigned char> *std_opcode_lengths;
+};
+
+class LineInfo {
+ public:
+
+  // Initializes a .debug_line reader. Buffer and buffer length point
+  // to the beginning and length of the line information to read.
+  // Reader is a ByteReader class that has the endianness set
+  // properly.
+  LineInfo(const char* buffer_, uint64 buffer_length,
+           ByteReader* reader, LineInfoHandler* handler);
+
+  virtual ~LineInfo() {
+    if (header_.std_opcode_lengths) {
+      delete header_.std_opcode_lengths;
+    }
+  }
+
+  // Start processing line info, and calling callbacks in the handler.
+  // Consumes the line number information for a single compilation unit.
+  // Returns the number of bytes processed.
+  uint64 Start();
+
+  // Process a single line info opcode at START using the state
+  // machine at LSM.  Return true if we should define a line using the
+  // current state of the line state machine.  Place the length of the
+  // opcode in LEN.
+  // If LSM_PASSES_PC is non-NULL, this function also checks if the lsm
+  // passes the address of PC. In other words, LSM_PASSES_PC will be
+  // set to true, if the following condition is met.
+  //
+  // lsm's old address < PC <= lsm's new address
+  static bool ProcessOneOpcode(ByteReader* reader,
+                               LineInfoHandler* handler,
+                               const struct LineInfoHeader &header,
+                               const char* start,
+                               struct LineStateMachine* lsm,
+                               size_t* len,
+                               uintptr pc,
+                               bool *lsm_passes_pc);
+
+ private:
+  // Reads the DWARF2/3 header for this line info.
+  void ReadHeader();
+
+  // Reads the DWARF2/3 line information
+  void ReadLines();
+
+  // The associated handler to call processing functions in
+  LineInfoHandler* handler_;
+
+  // The associated ByteReader that handles endianness issues for us
+  ByteReader* reader_;
+
+  // A DWARF2/3 line info header.  This is not the same size as
+  // in the actual file, as the one in the file may have a 32 bit or
+  // 64 bit lengths
+
+  struct LineInfoHeader header_;
+
+  // buffer is the buffer for our line info, starting at exactly where
+  // the line info to read is.  after_header is the place right after
+  // the end of the line information header.
+  const char* buffer_;
+  uint64 buffer_length_;
+  const char* after_header_;
+};
+
+// This class is the main interface between the line info reader and
+// the client.  The virtual functions inside this get called for
+// interesting events that happen during line info reading.  The
+// default implementation does nothing
+
+class LineInfoHandler {
+ public:
+  LineInfoHandler() { }
+
+  virtual ~LineInfoHandler() { }
+
+  // Called when we define a directory.  NAME is the directory name,
+  // DIR_NUM is the directory number
+  virtual void DefineDir(const string& name, uint32 dir_num) { }
+
+  // Called when we define a filename. NAME is the filename, FILE_NUM
+  // is the file number which is -1 if the file index is the next
+  // index after the last numbered index (this happens when files are
+  // dynamically defined by the line program), DIR_NUM is the
+  // directory index for the directory name of this file, MOD_TIME is
+  // the modification time of the file, and LENGTH is the length of
+  // the file
+  virtual void DefineFile(const string& name, int32 file_num,
+                          uint32 dir_num, uint64 mod_time,
+                          uint64 length) { }
+
+  // Called when the line info reader has a new line, address pair
+  // ready for us. ADDRESS is the address of the code, LENGTH is the
+  // length of its machine code in bytes, FILE_NUM is the file number
+  // containing the code, LINE_NUM is the line number in that file for
+  // the code, and COLUMN_NUM is the column number the code starts at,
+  // if we know it (0 otherwise).
+  virtual void AddLine(uint64 address, uint64 length,
+                       uint32 file_num, uint32 line_num, uint32 column_num) { }
+};
+
+// The base of DWARF2/3 debug info is a DIE (Debugging Information
+// Entry.
+// DWARF groups DIE's into a tree and calls the root of this tree a
+// "compilation unit".  Most of the time, there is one compilation
+// unit in the .debug_info section for each file that had debug info
+// generated.
+// Each DIE consists of
+
+// 1. a tag specifying a thing that is being described (ie
+// DW_TAG_subprogram for functions, DW_TAG_variable for variables, etc
+// 2. attributes (such as DW_AT_location for location in memory,
+// DW_AT_name for name), and data for each attribute.
+// 3. A flag saying whether the DIE has children or not
+
+// In order to gain some amount of compression, the format of
+// each DIE (tag name, attributes and data forms for the attributes)
+// are stored in a separate table called the "abbreviation table".
+// This is done because a large number of DIEs have the exact same tag
+// and list of attributes, but different data for those attributes.
+// As a result, the .debug_info section is just a stream of data, and
+// requires reading of the .debug_abbrev section to say what the data
+// means.
+
+// As a warning to the user, it should be noted that the reason for
+// using absolute offsets from the beginning of .debug_info is that
+// DWARF2/3 supports referencing DIE's from other DIE's by their offset
+// from either the current compilation unit start, *or* the beginning
+// of the .debug_info section.  This means it is possible to reference
+// a DIE in one compilation unit from a DIE in another compilation
+// unit.  This style of reference is usually used to eliminate
+// duplicated information that occurs across compilation
+// units, such as base types, etc.  GCC 3.4+ support this with
+// -feliminate-dwarf2-dups.  Other toolchains will sometimes do
+// duplicate elimination in the linker.
+
+class CompilationUnit {
+ public:
+
+  // Initialize a compilation unit.  This requires a map of sections,
+  // the offset of this compilation unit in the .debug_info section, a
+  // ByteReader, and a Dwarf2Handler class to call callbacks in.
+  CompilationUnit(const SectionMap& sections, uint64 offset,
+                  ByteReader* reader, Dwarf2Handler* handler);
+  virtual ~CompilationUnit() {
+    if (abbrevs_) delete abbrevs_;
+  }
+
+  // Begin reading a Dwarf2 compilation unit, and calling the
+  // callbacks in the Dwarf2Handler
+
+  // Return the full length of the compilation unit, including
+  // headers. This plus the starting offset passed to the constructor
+  // is the offset of the end of the compilation unit --- and the
+  // start of the next compilation unit, if there is one.
+  uint64 Start();
+
+ private:
+
+  // This struct represents a single DWARF2/3 abbreviation
+  // The abbreviation tells how to read a DWARF2/3 DIE, and consist of a
+  // tag and a list of attributes, as well as the data form of each attribute.
+  struct Abbrev {
+    uint64 number;
+    enum DwarfTag tag;
+    bool has_children;
+    AttributeList attributes;
+  };
+
+  // A DWARF2/3 compilation unit header.  This is not the same size as
+  // in the actual file, as the one in the file may have a 32 bit or
+  // 64 bit length.
+  struct CompilationUnitHeader {
+    uint64 length;
+    uint16 version;
+    uint64 abbrev_offset;
+    uint8 address_size;
+  } header_;
+
+  // Reads the DWARF2/3 header for this compilation unit.
+  void ReadHeader();
+
+  // Reads the DWARF2/3 abbreviations for this compilation unit
+  void ReadAbbrevs();
+
+  // Processes a single DIE for this compilation unit and return a new
+  // pointer just past the end of it
+  const char* ProcessDIE(uint64 dieoffset,
+                                  const char* start,
+                                  const Abbrev& abbrev);
+
+  // Processes a single attribute and return a new pointer just past the
+  // end of it
+  const char* ProcessAttribute(uint64 dieoffset,
+                                        const char* start,
+                                        enum DwarfAttribute attr,
+                                        enum DwarfForm form);
+
+  // Processes all DIEs for this compilation unit
+  void ProcessDIEs();
+
+  // Skips the die with attributes specified in ABBREV starting at
+  // START, and return the new place to position the stream to.
+  const char* SkipDIE(const char* start,
+                               const Abbrev& abbrev);
+
+  // Skips the attribute starting at START, with FORM, and return the
+  // new place to position the stream to.
+  const char* SkipAttribute(const char* start,
+                                     enum DwarfForm form);
+
+  // Offset from section start is the offset of this compilation unit
+  // from the beginning of the .debug_info section.
+  uint64 offset_from_section_start_;
+
+  // buffer is the buffer for our CU, starting at .debug_info + offset
+  // passed in from constructor.
+  // after_header points to right after the compilation unit header.
+  const char* buffer_;
+  uint64 buffer_length_;
+  const char* after_header_;
+
+  // The associated ByteReader that handles endianness issues for us
+  ByteReader* reader_;
+
+  // The map of sections in our file to buffers containing their data
+  const SectionMap& sections_;
+
+  // The associated handler to call processing functions in
+  Dwarf2Handler* handler_;
+
+  // Set of DWARF2/3 abbreviations for this compilation unit.  Indexed
+  // by abbreviation number, which means that abbrevs_[0] is not
+  // valid.
+  std::vector<Abbrev>* abbrevs_;
+
+  // String section buffer and length, if we have a string section.
+  // This is here to avoid doing a section lookup for strings in
+  // ProcessAttribute, which is in the hot path for DWARF2 reading.
+  const char* string_buffer_;
+  uint64 string_buffer_length_;
+};
+
+// This class is the main interface between the reader and the
+// client.  The virtual functions inside this get called for
+// interesting events that happen during DWARF2 reading.
+// The default implementation skips everything.
+
+class Dwarf2Handler {
+ public:
+  Dwarf2Handler() { }
+
+  virtual ~Dwarf2Handler() { }
+
+  // Start to process a compilation unit at OFFSET from the beginning of the
+  // .debug_info section. Return false if you would like to skip this
+  // compilation unit.
+  virtual bool StartCompilationUnit(uint64 offset, uint8 address_size,
+                                    uint8 offset_size, uint64 cu_length,
+                                    uint8 dwarf_version) { return false; }
+
+  // Start to process a DIE at OFFSET from the beginning of the .debug_info
+  // section. Return false if you would like to skip this DIE.
+  virtual bool StartDIE(uint64 offset, enum DwarfTag tag,
+                        const AttributeList& attrs) { return false; }
+
+  // Called when we have an attribute with unsigned data to give to our
+  // handler. The attribute is for the DIE at OFFSET from the beginning of the
+  // .debug_info section. Its name is ATTR, its form is FORM, and its value is
+  // DATA.
+  virtual void ProcessAttributeUnsigned(uint64 offset,
+                                        enum DwarfAttribute attr,
+                                        enum DwarfForm form,
+                                        uint64 data) { }
+
+  // Called when we have an attribute with signed data to give to our handler.
+  // The attribute is for the DIE at OFFSET from the beginning of the
+  // .debug_info section. Its name is ATTR, its form is FORM, and its value is
+  // DATA.
+  virtual void ProcessAttributeSigned(uint64 offset,
+                                      enum DwarfAttribute attr,
+                                      enum DwarfForm form,
+                                      int64 data) { }
+
+  // Called when we have an attribute whose value is a reference to
+  // another DIE. The attribute belongs to the DIE at OFFSET from the
+  // beginning of the .debug_info section. Its name is ATTR, its form
+  // is FORM, and the offset of the DIE being referred to from the
+  // beginning of the .debug_info section is DATA.
+  virtual void ProcessAttributeReference(uint64 offset,
+                                         enum DwarfAttribute attr,
+                                         enum DwarfForm form,
+                                         uint64 data) { }
+
+  // Called when we have an attribute with a buffer of data to give to our
+  // handler. The attribute is for the DIE at OFFSET from the beginning of the
+  // .debug_info section. Its name is ATTR, its form is FORM, DATA points to
+  // the buffer's contents, and its length in bytes is LENGTH. The buffer is
+  // owned by the caller, not the callee, and may not persist for very long.
+  // If you want the data to be available later, it needs to be copied.
+  virtual void ProcessAttributeBuffer(uint64 offset,
+                                      enum DwarfAttribute attr,
+                                      enum DwarfForm form,
+                                      const char* data,
+                                      uint64 len) { }
+
+  // Called when we have an attribute with string data to give to our handler.
+  // The attribute is for the DIE at OFFSET from the beginning of the
+  // .debug_info section. Its name is ATTR, its form is FORM, and its value is
+  // DATA.
+  virtual void ProcessAttributeString(uint64 offset,
+                                      enum DwarfAttribute attr,
+                                      enum DwarfForm form,
+                                      const string& data) { }
+
+  // Called when we have an attribute whose value is the 64-bit signature
+  // of a type unit in the .debug_types section. OFFSET is the offset of
+  // the DIE whose attribute we're reporting. ATTR and FORM are the
+  // attribute's name and form. SIGNATURE is the type unit's signature.
+  virtual void ProcessAttributeSignature(uint64 offset,
+                                         enum DwarfAttribute attr,
+                                         enum DwarfForm form,
+                                         uint64 signature) { }
+
+  // Called when finished processing the DIE at OFFSET.
+  // Because DWARF2/3 specifies a tree of DIEs, you may get starts
+  // before ends of the previous DIE, as we process children before
+  // ending the parent.
+  virtual void EndDIE(uint64 offset) { }
+
+};
+
+// This class is a reader for DWARF's Call Frame Information.  CFI
+// describes how to unwind stack frames --- even for functions that do
+// not follow fixed conventions for saving registers, whose frame size
+// varies as they execute, etc.
+//
+// CFI describes, at each machine instruction, how to compute the
+// stack frame's base address, how to find the return address, and
+// where to find the saved values of the caller's registers (if the
+// callee has stashed them somewhere to free up the registers for its
+// own use).
+//
+// For example, suppose we have a function whose machine code looks
+// like this (imagine an assembly language that looks like C, for a
+// machine with 32-bit registers, and a stack that grows towards lower
+// addresses):
+//
+// func:                                ; entry point; return address at sp
+// func+0:      sp = sp - 16            ; allocate space for stack frame
+// func+1:      sp[12] = r0             ; save r0 at sp+12
+// ...                                  ; other code, not frame-related
+// func+10:     sp -= 4; *sp = x        ; push some x on the stack
+// ...                                  ; other code, not frame-related
+// func+20:     r0 = sp[16]             ; restore saved r0
+// func+21:     sp += 20                ; pop whole stack frame
+// func+22:     pc = *sp; sp += 4       ; pop return address and jump to it
+//
+// DWARF CFI is (a very compressed representation of) a table with a
+// row for each machine instruction address and a column for each
+// register showing how to restore it, if possible.
+//
+// A special column named "CFA", for "Canonical Frame Address", tells how
+// to compute the base address of the frame; registers' entries may
+// refer to the CFA in describing where the registers are saved.
+//
+// Another special column, named "RA", represents the return address.
+//
+// For example, here is a complete (uncompressed) table describing the
+// function above:
+// 
+//     insn      cfa    r0      r1 ...  ra
+//     =======================================
+//     func+0:   sp                     cfa[0]
+//     func+1:   sp+16                  cfa[0] 
+//     func+2:   sp+16  cfa[-4]         cfa[0]
+//     func+11:  sp+20  cfa[-4]         cfa[0]
+//     func+21:  sp+20                  cfa[0]
+//     func+22:  sp                     cfa[0]
+//
+// Some things to note here:
+//
+// - Each row describes the state of affairs *before* executing the
+//   instruction at the given address.  Thus, the row for func+0
+//   describes the state before we allocate the stack frame.  In the
+//   next row, the formula for computing the CFA has changed,
+//   reflecting that allocation.
+//
+// - The other entries are written in terms of the CFA; this allows
+//   them to remain unchanged as the stack pointer gets bumped around.
+//   For example, the rule for recovering the return address (the "ra"
+//   column) remains unchanged throughout the function, even as the
+//   stack pointer takes on three different offsets from the return
+//   address.
+//
+// - Although we haven't shown it, most calling conventions designate
+//   "callee-saves" and "caller-saves" registers. The callee must
+//   preserve the values of callee-saves registers; if it uses them,
+//   it must save their original values somewhere, and restore them
+//   before it returns. In contrast, the callee is free to trash
+//   caller-saves registers; if the callee uses these, it will
+//   probably not bother to save them anywhere, and the CFI will
+//   probably mark their values as "unrecoverable".
+//
+//   (However, since the caller cannot assume the callee was going to
+//   save them, caller-saves registers are probably dead in the caller
+//   anyway, so compilers usually don't generate CFA for caller-saves
+//   registers.)
+// 
+// - Exactly where the CFA points is a matter of convention that
+//   depends on the architecture and ABI in use. In the example, the
+//   CFA is the value the stack pointer had upon entry to the
+//   function, pointing at the saved return address. But on the x86,
+//   the call frame information generated by GCC follows the
+//   convention that the CFA is the address *after* the saved return
+//   address.
+//
+//   But by definition, the CFA remains constant throughout the
+//   lifetime of the frame. This makes it a useful value for other
+//   columns to refer to. It is also gives debuggers a useful handle
+//   for identifying a frame.
+//
+// If you look at the table above, you'll notice that a given entry is
+// often the same as the one immediately above it: most instructions
+// change only one or two aspects of the stack frame, if they affect
+// it at all. The DWARF format takes advantage of this fact, and
+// reduces the size of the data by mentioning only the addresses and
+// columns at which changes take place. So for the above, DWARF CFI
+// data would only actually mention the following:
+// 
+//     insn      cfa    r0      r1 ...  ra
+//     =======================================
+//     func+0:   sp                     cfa[0]
+//     func+1:   sp+16
+//     func+2:          cfa[-4]
+//     func+11:  sp+20
+//     func+21:         r0
+//     func+22:  sp            
+//
+// In fact, this is the way the parser reports CFI to the consumer: as
+// a series of statements of the form, "At address X, column Y changed
+// to Z," and related conventions for describing the initial state.
+//
+// Naturally, it would be impractical to have to scan the entire
+// program's CFI, noting changes as we go, just to recover the
+// unwinding rules in effect at one particular instruction. To avoid
+// this, CFI data is grouped into "entries", each of which covers a
+// specified range of addresses and begins with a complete statement
+// of the rules for all recoverable registers at that starting
+// address. Each entry typically covers a single function.
+//
+// Thus, to compute the contents of a given row of the table --- that
+// is, rules for recovering the CFA, RA, and registers at a given
+// instruction --- the consumer should find the entry that covers that
+// instruction's address, start with the initial state supplied at the
+// beginning of the entry, and work forward until it has processed all
+// the changes up to and including those for the present instruction.
+//
+// There are seven kinds of rules that can appear in an entry of the
+// table:
+//
+// - "undefined": The given register is not preserved by the callee;
+//   its value cannot be recovered.
+//
+// - "same value": This register has the same value it did in the callee.
+//
+// - offset(N): The register is saved at offset N from the CFA.
+//
+// - val_offset(N): The value the register had in the caller is the
+//   CFA plus offset N. (This is usually only useful for describing
+//   the stack pointer.)
+//
+// - register(R): The register's value was saved in another register R.
+//
+// - expression(E): Evaluating the DWARF expression E using the
+//   current frame's registers' values yields the address at which the
+//   register was saved.
+//
+// - val_expression(E): Evaluating the DWARF expression E using the
+//   current frame's registers' values yields the value the register
+//   had in the caller.
+
+class CallFrameInfo {
+ public:
+  // The different kinds of entries one finds in CFI. Used internally,
+  // and for error reporting.
+  enum EntryKind { kUnknown, kCIE, kFDE, kTerminator };
+
+  // The handler class to which the parser hands the parsed call frame
+  // information.  Defined below.
+  class Handler;
+
+  // A reporter class, which CallFrameInfo uses to report errors
+  // encountered while parsing call frame information.  Defined below.
+  class Reporter;
+
+  // Create a DWARF CFI parser. BUFFER points to the contents of the
+  // .debug_frame section to parse; BUFFER_LENGTH is its length in bytes.
+  // REPORTER is an error reporter the parser should use to report
+  // problems. READER is a ByteReader instance that has the endianness and
+  // address size set properly. Report the data we find to HANDLER.
+  //
+  // This class can also parse Linux C++ exception handling data, as found
+  // in '.eh_frame' sections. This data is a variant of DWARF CFI that is
+  // placed in loadable segments so that it is present in the program's
+  // address space, and is interpreted by the C++ runtime to search the
+  // call stack for a handler interested in the exception being thrown,
+  // actually pop the frames, and find cleanup code to run.
+  //
+  // There are two differences between the call frame information described
+  // in the DWARF standard and the exception handling data Linux places in
+  // the .eh_frame section:
+  //
+  // - Exception handling data uses uses a different format for call frame
+  //   information entry headers. The distinguished CIE id, the way FDEs
+  //   refer to their CIEs, and the way the end of the series of entries is
+  //   determined are all slightly different.
+  //
+  //   If the constructor's EH_FRAME argument is true, then the
+  //   CallFrameInfo parses the entry headers as Linux C++ exception
+  //   handling data. If EH_FRAME is false or omitted, the CallFrameInfo
+  //   parses standard DWARF call frame information.
+  //
+  // - Linux C++ exception handling data uses CIE augmentation strings
+  //   beginning with 'z' to specify the presence of additional data after
+  //   the CIE and FDE headers and special encodings used for addresses in
+  //   frame description entries.
+  //
+  //   CallFrameInfo can handle 'z' augmentations in either DWARF CFI or
+  //   exception handling data if you have supplied READER with the base
+  //   addresses needed to interpret the pointer encodings that 'z'
+  //   augmentations can specify. See the ByteReader interface for details
+  //   about the base addresses. See the CallFrameInfo::Handler interface
+  //   for details about the additional information one might find in
+  //   'z'-augmented data.
+  //
+  // Thus:
+  //
+  // - If you are parsing standard DWARF CFI, as found in a .debug_frame
+  //   section, you should pass false for the EH_FRAME argument, or omit
+  //   it, and you need not worry about providing READER with the
+  //   additional base addresses.
+  //
+  // - If you want to parse Linux C++ exception handling data from a
+  //   .eh_frame section, you should pass EH_FRAME as true, and call
+  //   READER's Set*Base member functions before calling our Start method.
+  //
+  // - If you want to parse DWARF CFI that uses the 'z' augmentations
+  //   (although I don't think any toolchain ever emits such data), you
+  //   could pass false for EH_FRAME, but call READER's Set*Base members.
+  //
+  // The extensions the Linux C++ ABI makes to DWARF for exception
+  // handling are described here, rather poorly:
+  // http://refspecs.linux-foundation.org/LSB_4.0.0/LSB-Core-generic/LSB-Core-generic/dwarfext.html
+  // http://refspecs.linux-foundation.org/LSB_4.0.0/LSB-Core-generic/LSB-Core-generic/ehframechpt.html
+  // 
+  // The mechanics of C++ exception handling, personality routines,
+  // and language-specific data areas are described here, rather nicely:
+  // http://www.codesourcery.com/public/cxx-abi/abi-eh.html
+  CallFrameInfo(const char *buffer, size_t buffer_length,
+                ByteReader *reader, Handler *handler, Reporter *reporter,
+                bool eh_frame = false)
+      : buffer_(buffer), buffer_length_(buffer_length),
+        reader_(reader), handler_(handler), reporter_(reporter),
+        eh_frame_(eh_frame) { }
+
+  ~CallFrameInfo() { }
+
+  // Parse the entries in BUFFER, reporting what we find to HANDLER.
+  // Return true if we reach the end of the section successfully, or
+  // false if we encounter an error.
+  bool Start();
+
+  // Return the textual name of KIND. For error reporting.
+  static const char *KindName(EntryKind kind);
+
+ private:
+
+  struct CIE;
+
+  // A CFI entry, either an FDE or a CIE.
+  struct Entry {
+    // The starting offset of the entry in the section, for error
+    // reporting.
+    size_t offset;
+
+    // The start of this entry in the buffer.
+    const char *start;
+    
+    // Which kind of entry this is.
+    //
+    // We want to be able to use this for error reporting even while we're
+    // in the midst of parsing. Error reporting code may assume that kind,
+    // offset, and start fields are valid, although kind may be kUnknown.
+    EntryKind kind;
+
+    // The end of this entry's common prologue (initial length and id), and
+    // the start of this entry's kind-specific fields.
+    const char *fields;
+
+    // The start of this entry's instructions.
+    const char *instructions;
+
+    // The address past the entry's last byte in the buffer. (Note that
+    // since offset points to the entry's initial length field, and the
+    // length field is the number of bytes after that field, this is not
+    // simply buffer_ + offset + length.)
+    const char *end;
+
+    // For both DWARF CFI and .eh_frame sections, this is the CIE id in a
+    // CIE, and the offset of the associated CIE in an FDE.
+    uint64 id;
+
+    // The CIE that applies to this entry, if we've parsed it. If this is a
+    // CIE, then this field points to this structure.
+    CIE *cie;
+  };
+
+  // A common information entry (CIE).
+  struct CIE: public Entry {
+    uint8 version;                      // CFI data version number
+    string augmentation;                // vendor format extension markers
+    uint64 code_alignment_factor;       // scale for code address adjustments 
+    int data_alignment_factor;          // scale for stack pointer adjustments
+    unsigned return_address_register;   // which register holds the return addr
+
+    // True if this CIE includes Linux C++ ABI 'z' augmentation data.
+    bool has_z_augmentation;
+ 
+    // Parsed 'z' augmentation data. These are meaningful only if
+    // has_z_augmentation is true.
+    bool has_z_lsda;                    // The 'z' augmentation included 'L'.
+    bool has_z_personality;             // The 'z' augmentation included 'P'.
+    bool has_z_signal_frame;            // The 'z' augmentation included 'S'.
+
+    // If has_z_lsda is true, this is the encoding to be used for language-
+    // specific data area pointers in FDEs.
+    DwarfPointerEncoding lsda_encoding;
+
+    // If has_z_personality is true, this is the encoding used for the
+    // personality routine pointer in the augmentation data.
+    DwarfPointerEncoding personality_encoding;
+
+    // If has_z_personality is true, this is the address of the personality
+    // routine --- or, if personality_encoding & DW_EH_PE_indirect, the
+    // address where the personality routine's address is stored.
+    uint64 personality_address;
+
+    // This is the encoding used for addresses in the FDE header and
+    // in DW_CFA_set_loc instructions. This is always valid, whether
+    // or not we saw a 'z' augmentation string; its default value is
+    // DW_EH_PE_absptr, which is what normal DWARF CFI uses.
+    DwarfPointerEncoding pointer_encoding;
+  };
+
+  // A frame description entry (FDE).
+  struct FDE: public Entry {
+    uint64 address;                     // start address of described code
+    uint64 size;                        // size of described code, in bytes
+
+    // If cie->has_z_lsda is true, then this is the language-specific data
+    // area's address --- or its address's address, if cie->lsda_encoding
+    // has the DW_EH_PE_indirect bit set.
+    uint64 lsda_address;
+  };
+
+  // Internal use.
+  class Rule;
+  class UndefinedRule;
+  class SameValueRule;
+  class OffsetRule;
+  class ValOffsetRule;
+  class RegisterRule;
+  class ExpressionRule;
+  class ValExpressionRule;
+  class RuleMap;
+  class State;
+  
+  // Parse the initial length and id of a CFI entry, either a CIE, an FDE,
+  // or a .eh_frame end-of-data mark. CURSOR points to the beginning of the
+  // data to parse. On success, populate ENTRY as appropriate, and return
+  // true. On failure, report the problem, and return false. Even if we
+  // return false, set ENTRY->end to the first byte after the entry if we
+  // were able to figure that out, or NULL if we weren't.
+  bool ReadEntryPrologue(const char *cursor, Entry *entry);
+
+  // Parse the fields of a CIE after the entry prologue, including any 'z'
+  // augmentation data. Assume that the 'Entry' fields of CIE are
+  // populated; use CIE->fields and CIE->end as the start and limit for
+  // parsing. On success, populate the rest of *CIE, and return true; on
+  // failure, report the problem and return false.
+  bool ReadCIEFields(CIE *cie);
+
+  // Parse the fields of an FDE after the entry prologue, including any 'z'
+  // augmentation data. Assume that the 'Entry' fields of *FDE are
+  // initialized; use FDE->fields and FDE->end as the start and limit for
+  // parsing. Assume that FDE->cie is fully initialized. On success,
+  // populate the rest of *FDE, and return true; on failure, report the
+  // problem and return false.
+  bool ReadFDEFields(FDE *fde);
+
+  // Report that ENTRY is incomplete, and return false. This is just a
+  // trivial wrapper for invoking reporter_->Incomplete; it provides a
+  // little brevity.
+  bool ReportIncomplete(Entry *entry);
+
+  // Return true if ENCODING has the DW_EH_PE_indirect bit set.
+  static bool IsIndirectEncoding(DwarfPointerEncoding encoding) {
+    return encoding & DW_EH_PE_indirect;
+  }
+
+  // The contents of the DWARF .debug_info section we're parsing.
+  const char *buffer_;
+  size_t buffer_length_;
+
+  // For reading multi-byte values with the appropriate endianness.
+  ByteReader *reader_;
+
+  // The handler to which we should report the data we find.
+  Handler *handler_;
+
+  // For reporting problems in the info we're parsing.
+  Reporter *reporter_;
+
+  // True if we are processing .eh_frame-format data.
+  bool eh_frame_;
+};
+
+// The handler class for CallFrameInfo.  The a CFI parser calls the
+// member functions of a handler object to report the data it finds.
+class CallFrameInfo::Handler {
+ public:
+  // The pseudo-register number for the canonical frame address.
+  enum { kCFARegister = -1 };
+
+  Handler() { }
+  virtual ~Handler() { }
+
+  // The parser has found CFI for the machine code at ADDRESS,
+  // extending for LENGTH bytes. OFFSET is the offset of the frame
+  // description entry in the section, for use in error messages.
+  // VERSION is the version number of the CFI format. AUGMENTATION is
+  // a string describing any producer-specific extensions present in
+  // the data. RETURN_ADDRESS is the number of the register that holds
+  // the address to which the function should return.
+  //
+  // Entry should return true to process this CFI, or false to skip to
+  // the next entry.
+  //
+  // The parser invokes Entry for each Frame Description Entry (FDE)
+  // it finds.  The parser doesn't report Common Information Entries
+  // to the handler explicitly; instead, if the handler elects to
+  // process a given FDE, the parser reiterates the appropriate CIE's
+  // contents at the beginning of the FDE's rules.
+  virtual bool Entry(size_t offset, uint64 address, uint64 length,
+                     uint8 version, const string &augmentation,
+                     unsigned return_address) = 0;
+
+  // When the Entry function returns true, the parser calls these
+  // handler functions repeatedly to describe the rules for recovering
+  // registers at each instruction in the given range of machine code.
+  // Immediately after a call to Entry, the handler should assume that
+  // the rule for each callee-saves register is "unchanged" --- that
+  // is, that the register still has the value it had in the caller.
+  // 
+  // If a *Rule function returns true, we continue processing this entry's
+  // instructions. If a *Rule function returns false, we stop evaluating
+  // instructions, and skip to the next entry. Either way, we call End
+  // before going on to the next entry.
+  //
+  // In all of these functions, if the REG parameter is kCFARegister, then
+  // the rule describes how to find the canonical frame address.
+  // kCFARegister may be passed as a BASE_REGISTER argument, meaning that
+  // the canonical frame address should be used as the base address for the
+  // computation. All other REG values will be positive.
+
+  // At ADDRESS, register REG's value is not recoverable.
+  virtual bool UndefinedRule(uint64 address, int reg) = 0;
+
+  // At ADDRESS, register REG's value is the same as that it had in
+  // the caller.
+  virtual bool SameValueRule(uint64 address, int reg) = 0;
+
+  // At ADDRESS, register REG has been saved at offset OFFSET from
+  // BASE_REGISTER.
+  virtual bool OffsetRule(uint64 address, int reg,
+                          int base_register, long offset) = 0;
+
+  // At ADDRESS, the caller's value of register REG is the current
+  // value of BASE_REGISTER plus OFFSET. (This rule doesn't provide an
+  // address at which the register's value is saved.)
+  virtual bool ValOffsetRule(uint64 address, int reg,
+                             int base_register, long offset) = 0;
+
+  // At ADDRESS, register REG has been saved in BASE_REGISTER. This differs
+  // from ValOffsetRule(ADDRESS, REG, BASE_REGISTER, 0), in that
+  // BASE_REGISTER is the "home" for REG's saved value: if you want to
+  // assign to a variable whose home is REG in the calling frame, you
+  // should put the value in BASE_REGISTER.
+  virtual bool RegisterRule(uint64 address, int reg, int base_register) = 0;
+
+  // At ADDRESS, the DWARF expression EXPRESSION yields the address at
+  // which REG was saved.
+  virtual bool ExpressionRule(uint64 address, int reg,
+                              const string &expression) = 0;
+
+  // At ADDRESS, the DWARF expression EXPRESSION yields the caller's
+  // value for REG. (This rule doesn't provide an address at which the
+  // register's value is saved.)
+  virtual bool ValExpressionRule(uint64 address, int reg,
+                                 const string &expression) = 0;
+
+  // Indicate that the rules for the address range reported by the
+  // last call to Entry are complete.  End should return true if
+  // everything is okay, or false if an error has occurred and parsing
+  // should stop.
+  virtual bool End() = 0;
+
+  // Handler functions for Linux C++ exception handling data. These are
+  // only called if the data includes 'z' augmentation strings.
+
+  // The Linux C++ ABI uses an extension of the DWARF CFI format to
+  // walk the stack to propagate exceptions from the throw to the
+  // appropriate catch, and do the appropriate cleanups along the way.
+  // CFI entries used for exception handling have two additional data
+  // associated with them:
+  //
+  // - The "language-specific data area" describes which exception
+  //   types the function has 'catch' clauses for, and indicates how
+  //   to go about re-entering the function at the appropriate catch
+  //   clause. If the exception is not caught, it describes the
+  //   destructors that must run before the frame is popped.
+  //
+  // - The "personality routine" is responsible for interpreting the
+  //   language-specific data area's contents, and deciding whether
+  //   the exception should continue to propagate down the stack,
+  //   perhaps after doing some cleanup for this frame, or whether the
+  //   exception will be caught here.
+  //
+  // In principle, the language-specific data area is opaque to
+  // everybody but the personality routine. In practice, these values
+  // may be useful or interesting to readers with extra context, and
+  // we have to at least skip them anyway, so we might as well report
+  // them to the handler.
+
+  // This entry's exception handling personality routine's address is
+  // ADDRESS. If INDIRECT is true, then ADDRESS is the address at
+  // which the routine's address is stored. The default definition for
+  // this handler function simply returns true, allowing parsing of
+  // the entry to continue.
+  virtual bool PersonalityRoutine(uint64 address, bool indirect) {
+    return true;
+  }
+
+  // This entry's language-specific data area (LSDA) is located at
+  // ADDRESS. If INDIRECT is true, then ADDRESS is the address at
+  // which the area's address is stored. The default definition for
+  // this handler function simply returns true, allowing parsing of
+  // the entry to continue.
+  virtual bool LanguageSpecificDataArea(uint64 address, bool indirect) {
+    return true;
+  }
+
+  // This entry describes a signal trampoline --- this frame is the
+  // caller of a signal handler. The default definition for this
+  // handler function simply returns true, allowing parsing of the
+  // entry to continue.
+  //
+  // The best description of the rationale for and meaning of signal
+  // trampoline CFI entries seems to be in the GCC bug database:
+  // http://gcc.gnu.org/bugzilla/show_bug.cgi?id=26208
+  virtual bool SignalHandler() { return true; }
+};
+
+// The CallFrameInfo class makes calls on an instance of this class to
+// report errors or warn about problems in the data it is parsing. The
+// default definitions of these methods print a message to stderr, but
+// you can make a derived class that overrides them.
+class CallFrameInfo::Reporter {
+ public:
+  // Create an error reporter which attributes troubles to the section
+  // named SECTION in FILENAME.
+  //
+  // Normally SECTION would be .debug_frame, but the Mac puts CFI data
+  // in a Mach-O section named __debug_frame. If we support
+  // Linux-style exception handling data, we could be reading an
+  // .eh_frame section.
+  Reporter(const string &filename,
+           const string &section = ".debug_frame")
+      : filename_(filename), section_(section) { }
+  virtual ~Reporter() { }
+
+  // The CFI entry at OFFSET ends too early to be well-formed. KIND
+  // indicates what kind of entry it is; KIND can be kUnknown if we
+  // haven't parsed enough of the entry to tell yet.
+  virtual void Incomplete(uint64 offset, CallFrameInfo::EntryKind kind);
+
+  // The .eh_frame data has a four-byte zero at OFFSET where the next
+  // entry's length would be; this is a terminator. However, the buffer
+  // length as given to the CallFrameInfo constructor says there should be
+  // more data.
+  virtual void EarlyEHTerminator(uint64 offset);
+
+  // The FDE at OFFSET refers to the CIE at CIE_OFFSET, but the
+  // section is not that large.
+  virtual void CIEPointerOutOfRange(uint64 offset, uint64 cie_offset);
+
+  // The FDE at OFFSET refers to the CIE at CIE_OFFSET, but the entry
+  // there is not a CIE.
+  virtual void BadCIEId(uint64 offset, uint64 cie_offset);
+
+  // The FDE at OFFSET refers to a CIE with version number VERSION,
+  // which we don't recognize. We cannot parse DWARF CFI if it uses
+  // a version number we don't recognize.
+  virtual void UnrecognizedVersion(uint64 offset, int version);
+
+  // The FDE at OFFSET refers to a CIE with augmentation AUGMENTATION,
+  // which we don't recognize. We cannot parse DWARF CFI if it uses
+  // augmentations we don't recognize.
+  virtual void UnrecognizedAugmentation(uint64 offset,
+                                        const string &augmentation);
+
+  // The pointer encoding ENCODING, specified by the CIE at OFFSET, is not
+  // a valid encoding.
+  virtual void InvalidPointerEncoding(uint64 offset, uint8 encoding);
+
+  // The pointer encoding ENCODING, specified by the CIE at OFFSET, depends
+  // on a base address which has not been supplied.
+  virtual void UnusablePointerEncoding(uint64 offset, uint8 encoding);
+
+  // The CIE at OFFSET contains a DW_CFA_restore instruction at
+  // INSN_OFFSET, which may not appear in a CIE.
+  virtual void RestoreInCIE(uint64 offset, uint64 insn_offset);
+
+  // The entry at OFFSET, of kind KIND, has an unrecognized
+  // instruction at INSN_OFFSET.
+  virtual void BadInstruction(uint64 offset, CallFrameInfo::EntryKind kind,
+                              uint64 insn_offset);
+
+  // The instruction at INSN_OFFSET in the entry at OFFSET, of kind
+  // KIND, establishes a rule that cites the CFA, but we have not
+  // established a CFA rule yet.
+  virtual void NoCFARule(uint64 offset, CallFrameInfo::EntryKind kind, 
+                         uint64 insn_offset);
+
+  // The instruction at INSN_OFFSET in the entry at OFFSET, of kind
+  // KIND, is a DW_CFA_restore_state instruction, but the stack of
+  // saved states is empty.
+  virtual void EmptyStateStack(uint64 offset, CallFrameInfo::EntryKind kind, 
+                               uint64 insn_offset);
+
+  // The DW_CFA_remember_state instruction at INSN_OFFSET in the entry
+  // at OFFSET, of kind KIND, would restore a state that has no CFA
+  // rule, whereas the current state does have a CFA rule. This is
+  // bogus input, which the CallFrameInfo::Handler interface doesn't
+  // (and shouldn't) have any way to report.
+  virtual void ClearingCFARule(uint64 offset, CallFrameInfo::EntryKind kind, 
+                               uint64 insn_offset);
+
+ protected:
+  // The name of the file whose CFI we're reading.
+  string filename_;
+
+  // The name of the CFI section in that file.
+  string section_;
+};
+
+}  // namespace dwarf2reader
+
+#endif  // UTIL_DEBUGINFO_DWARF2READER_H__
diff --git a/3rdParty/Breakpad/src/common/dwarf/line_state_machine.h b/3rdParty/Breakpad/src/common/dwarf/line_state_machine.h
new file mode 100644
index 0000000..0ff72ab
--- /dev/null
+++ b/3rdParty/Breakpad/src/common/dwarf/line_state_machine.h
@@ -0,0 +1,61 @@
+// Copyright 2008 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.
+
+
+#ifndef COMMON_DWARF_LINE_STATE_MACHINE_H__
+#define COMMON_DWARF_LINE_STATE_MACHINE_H__
+
+namespace dwarf2reader {
+
+// This is the format of a DWARF2/3 line state machine that we process
+// opcodes using.  There is no need for anything outside the lineinfo
+// processor to know how this works.
+struct LineStateMachine {
+  void Reset(bool default_is_stmt) {
+    file_num = 1;
+    address = 0;
+    line_num = 1;
+    column_num = 0;
+    is_stmt = default_is_stmt;
+    basic_block = false;
+    end_sequence = false;
+  }
+
+  uint32 file_num;
+  uint64 address;
+  uint32 line_num;
+  uint32 column_num;
+  bool is_stmt;  // stmt means statement.
+  bool basic_block;
+  bool end_sequence;
+};
+
+}  // namespace dwarf2reader
+
+
+#endif  // COMMON_DWARF_LINE_STATE_MACHINE_H__
diff --git a/3rdParty/Breakpad/src/common/dwarf/types.h b/3rdParty/Breakpad/src/common/dwarf/types.h
new file mode 100644
index 0000000..61ca457
--- /dev/null
+++ b/3rdParty/Breakpad/src/common/dwarf/types.h
@@ -0,0 +1,55 @@
+// Copyright 2008 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.
+
+
+// This file contains some typedefs for basic types
+
+
+#ifndef _COMMON_DWARF_TYPES_H__
+#define _COMMON_DWARF_TYPES_H__
+
+#include <stdint.h>
+
+typedef signed char         int8;
+typedef short               int16;
+typedef int                 int32;
+typedef long long           int64;
+
+typedef unsigned char      uint8;
+typedef unsigned short     uint16;
+typedef unsigned int       uint32;
+typedef unsigned long long uint64;
+
+#ifdef __PTRDIFF_TYPE__
+typedef          __PTRDIFF_TYPE__ intptr;
+typedef unsigned __PTRDIFF_TYPE__ uintptr;
+#else
+#error "Can't find pointer-sized integral types."
+#endif
+
+#endif // _COMMON_DWARF_TYPES_H__
diff --git a/3rdParty/Breakpad/src/common/dwarf_cfi_to_module.cc b/3rdParty/Breakpad/src/common/dwarf_cfi_to_module.cc
new file mode 100644
index 0000000..15904d7
--- /dev/null
+++ b/3rdParty/Breakpad/src/common/dwarf_cfi_to_module.cc
@@ -0,0 +1,258 @@
+// -*- mode: c++ -*-
+
+// 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>
+
+// Implementation of google_breakpad::DwarfCFIToModule.
+// See dwarf_cfi_to_module.h for details.
+
+#include <sstream>
+
+#include "common/dwarf_cfi_to_module.h"
+
+namespace google_breakpad {
+
+using std::ostringstream;
+
+vector<string> DwarfCFIToModule::RegisterNames::MakeVector(
+    const char * const *strings,
+    size_t size) {
+  vector<string> names(strings, strings + size);
+  return names;
+}
+
+vector<string> DwarfCFIToModule::RegisterNames::I386() {
+  static const char *const names[] = {
+    "$eax", "$ecx", "$edx", "$ebx", "$esp", "$ebp", "$esi", "$edi",
+    "$eip", "$eflags", "$unused1",
+    "$st0", "$st1", "$st2", "$st3", "$st4", "$st5", "$st6", "$st7",
+    "$unused2", "$unused3",
+    "$xmm0", "$xmm1", "$xmm2", "$xmm3", "$xmm4", "$xmm5", "$xmm6", "$xmm7",
+    "$mm0", "$mm1", "$mm2", "$mm3", "$mm4", "$mm5", "$mm6", "$mm7",
+    "$fcw", "$fsw", "$mxcsr",
+    "$es", "$cs", "$ss", "$ds", "$fs", "$gs", "$unused4", "$unused5",
+    "$tr", "$ldtr"
+  };
+
+  return MakeVector(names, sizeof(names) / sizeof(names[0]));
+}
+
+vector<string> DwarfCFIToModule::RegisterNames::X86_64() {
+  static const char *const names[] = {
+    "$rax", "$rdx", "$rcx", "$rbx", "$rsi", "$rdi", "$rbp", "$rsp",
+    "$r8",  "$r9",  "$r10", "$r11", "$r12", "$r13", "$r14", "$r15",
+    "$rip",
+    "$xmm0","$xmm1","$xmm2", "$xmm3", "$xmm4", "$xmm5", "$xmm6", "$xmm7",
+    "$xmm8","$xmm9","$xmm10","$xmm11","$xmm12","$xmm13","$xmm14","$xmm15",
+    "$st0", "$st1", "$st2", "$st3", "$st4", "$st5", "$st6", "$st7",
+    "$mm0", "$mm1", "$mm2", "$mm3", "$mm4", "$mm5", "$mm6", "$mm7",
+    "$rflags",
+    "$es", "$cs", "$ss", "$ds", "$fs", "$gs", "$unused1", "$unused2",
+    "$fs.base", "$gs.base", "$unused3", "$unused4",
+    "$tr", "$ldtr",
+    "$mxcsr", "$fcw", "$fsw"
+  };
+
+  return MakeVector(names, sizeof(names) / sizeof(names[0]));
+}
+
+// Per ARM IHI 0040A, section 3.1
+vector<string> DwarfCFIToModule::RegisterNames::ARM() {
+  static const char *const names[] = {
+    "r0",  "r1",  "r2",  "r3",  "r4",  "r5",  "r6",  "r7",
+    "r8",  "r9",  "r10", "r11", "r12", "sp",  "lr",  "pc",
+    "f0",  "f1",  "f2",  "f3",  "f4",  "f5",  "f6",  "f7",
+    "fps", "cpsr", "",   "",    "",    "",    "",    "",
+    "",    "",    "",    "",    "",    "",    "",    "",
+    "",    "",    "",    "",    "",    "",    "",    "",
+    "",    "",    "",    "",    "",    "",    "",    "",
+    "",    "",    "",    "",    "",    "",    "",    "",
+    "s0",  "s1",  "s2",  "s3",  "s4",  "s5",  "s6",  "s7",
+    "s8",  "s9",  "s10", "s11", "s12", "s13", "s14", "s15",
+    "s16", "s17", "s18", "s19", "s20", "s21", "s22", "s23",
+    "s24", "s25", "s26", "s27", "s28", "s29", "s30", "s31",
+    "f0",  "f1",  "f2",  "f3",  "f4",  "f5",  "f6",  "f7"
+  };
+
+  return MakeVector(names, sizeof(names) / sizeof(names[0]));
+}
+
+bool DwarfCFIToModule::Entry(size_t offset, uint64 address, uint64 length,
+                             uint8 version, const string &augmentation,
+                             unsigned return_address) {
+  assert(!entry_);
+
+  // If dwarf2reader::CallFrameInfo can handle this version and
+  // augmentation, then we should be okay with that, so there's no
+  // need to check them here.
+
+  // Get ready to collect entries.
+  entry_ = new Module::StackFrameEntry;
+  entry_->address = address;
+  entry_->size = length;
+  entry_offset_ = offset;
+  return_address_ = return_address;
+
+  // Breakpad STACK CFI records must provide a .ra rule, but DWARF CFI
+  // may not establish any rule for .ra if the return address column
+  // is an ordinary register, and that register holds the return
+  // address on entry to the function. So establish an initial .ra
+  // rule citing the return address register.
+  if (return_address_ < register_names_.size())
+    entry_->initial_rules[ra_name_] = register_names_[return_address_];
+
+  return true;
+}
+
+string DwarfCFIToModule::RegisterName(int i) {
+  assert(entry_);
+  if (i < 0) {
+    assert(i == kCFARegister);
+    return cfa_name_;
+  }
+  unsigned reg = i;
+  if (reg == return_address_)
+    return ra_name_;
+
+  // Ensure that a non-empty name exists for this register value.
+  if (reg < register_names_.size() && !register_names_[reg].empty())
+    return register_names_[reg];
+
+  reporter_->UnnamedRegister(entry_offset_, reg);
+  char buf[30];
+  sprintf(buf, "unnamed_register%u", reg);
+  return buf;
+}
+
+void DwarfCFIToModule::Record(Module::Address address, int reg,
+                              const string &rule) {
+  assert(entry_);
+
+  // Place the name in our global set of strings, and then use the string
+  // from the set. Even though the assignment looks like a copy, all the
+  // major std::string implementations use reference counting internally,
+  // so the effect is to have all our data structures share copies of rules
+  // whenever possible. Since register names are drawn from a
+  // vector<string>, register names are already shared.
+  string shared_rule = *common_strings_.insert(rule).first;
+
+  // Is this one of this entry's initial rules?
+  if (address == entry_->address)
+    entry_->initial_rules[RegisterName(reg)] = shared_rule;
+  // File it under the appropriate address.
+  else
+    entry_->rule_changes[address][RegisterName(reg)] = shared_rule;
+}
+
+bool DwarfCFIToModule::UndefinedRule(uint64 address, int reg) {
+  reporter_->UndefinedNotSupported(entry_offset_, RegisterName(reg));
+  // Treat this as a non-fatal error.
+  return true;
+}
+
+bool DwarfCFIToModule::SameValueRule(uint64 address, int reg) {
+  ostringstream s;
+  s << RegisterName(reg);
+  Record(address, reg, s.str());
+  return true;
+}
+
+bool DwarfCFIToModule::OffsetRule(uint64 address, int reg,
+                                  int base_register, long offset) {
+  ostringstream s;
+  s << RegisterName(base_register) << " " << offset << " + ^";
+  Record(address, reg, s.str());
+  return true;
+}
+
+bool DwarfCFIToModule::ValOffsetRule(uint64 address, int reg,
+                                     int base_register, long offset) {
+  ostringstream s;
+  s << RegisterName(base_register) << " " << offset << " +";
+  Record(address, reg, s.str());
+  return true;
+}
+
+bool DwarfCFIToModule::RegisterRule(uint64 address, int reg,
+                                    int base_register) {
+  ostringstream s;
+  s << RegisterName(base_register);
+  Record(address, reg, s.str());
+  return true;
+}
+
+bool DwarfCFIToModule::ExpressionRule(uint64 address, int reg,
+                                      const string &expression) {
+  reporter_->ExpressionsNotSupported(entry_offset_, RegisterName(reg));
+  // Treat this as a non-fatal error.
+  return true;
+}
+
+bool DwarfCFIToModule::ValExpressionRule(uint64 address, int reg,
+                                         const string &expression) {
+  reporter_->ExpressionsNotSupported(entry_offset_, RegisterName(reg));
+  // Treat this as a non-fatal error.
+  return true;
+}
+
+bool DwarfCFIToModule::End() {
+  module_->AddStackFrameEntry(entry_);
+  entry_ = NULL;
+  return true;
+}
+
+void DwarfCFIToModule::Reporter::UnnamedRegister(size_t offset, int reg) {
+  fprintf(stderr, "%s, section '%s': "
+          "the call frame entry at offset 0x%zx refers to register %d,"
+          " whose name we don't know\n",
+          file_.c_str(), section_.c_str(), offset, reg);
+}
+
+void DwarfCFIToModule::Reporter::UndefinedNotSupported(size_t offset,
+                                                       const string &reg) {
+  fprintf(stderr, "%s, section '%s': "
+          "the call frame entry at offset 0x%zx sets the rule for "
+          "register '%s' to 'undefined', but the Breakpad symbol file format"
+          " cannot express this\n",
+          file_.c_str(), section_.c_str(), offset, reg.c_str());
+}
+
+void DwarfCFIToModule::Reporter::ExpressionsNotSupported(size_t offset,
+                                                         const string &reg) {
+  fprintf(stderr, "%s, section '%s': "
+          "the call frame entry at offset 0x%zx uses a DWARF expression to"
+          " describe how to recover register '%s', "
+          " but this translator cannot yet translate DWARF expressions to"
+          " Breakpad postfix expressions\n",
+          file_.c_str(), section_.c_str(), offset, reg.c_str());
+}
+
+} // namespace google_breakpad
diff --git a/3rdParty/Breakpad/src/common/dwarf_cfi_to_module.h b/3rdParty/Breakpad/src/common/dwarf_cfi_to_module.h
new file mode 100644
index 0000000..7db552a
--- /dev/null
+++ b/3rdParty/Breakpad/src/common/dwarf_cfi_to_module.h
@@ -0,0 +1,196 @@
+// -*- mode: c++ -*-
+
+// 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>
+
+// dwarf_cfi_to_module.h: Define the DwarfCFIToModule class, which
+// accepts parsed DWARF call frame info and adds it to a
+// google_breakpad::Module object, which can write that information to
+// a Breakpad symbol file.
+
+#ifndef COMMON_LINUX_DWARF_CFI_TO_MODULE_H
+#define COMMON_LINUX_DWARF_CFI_TO_MODULE_H
+
+#include <assert.h>
+#include <stdio.h>
+
+#include <set>
+#include <string>
+#include <vector>
+
+#include "common/module.h"
+#include "common/dwarf/dwarf2reader.h"
+#include "common/using_std_string.h"
+
+namespace google_breakpad {
+
+using dwarf2reader::CallFrameInfo;
+using google_breakpad::Module;
+using std::set;
+using std::vector;
+
+// A class that accepts parsed call frame information from the DWARF
+// CFI parser and populates a google_breakpad::Module object with the
+// contents.
+class DwarfCFIToModule: public CallFrameInfo::Handler {
+ public:
+
+  // DwarfCFIToModule uses an instance of this class to report errors
+  // detected while converting DWARF CFI to Breakpad STACK CFI records.
+  class Reporter {
+   public:
+    // Create a reporter that writes messages to the standard error
+    // stream. FILE is the name of the file we're processing, and
+    // SECTION is the name of the section within that file that we're
+    // looking at (.debug_frame, .eh_frame, etc.).
+    Reporter(const string &file, const string &section)
+      : file_(file), section_(section) { }
+    virtual ~Reporter() { }
+
+    // The DWARF CFI entry at OFFSET cites register REG, but REG is not
+    // covered by the vector of register names passed to the
+    // DwarfCFIToModule constructor, nor does it match the return
+    // address column number for this entry.
+    virtual void UnnamedRegister(size_t offset, int reg);
+
+    // The DWARF CFI entry at OFFSET says that REG is undefined, but the
+    // Breakpad symbol file format cannot express this.
+    virtual void UndefinedNotSupported(size_t offset, const string &reg);
+
+    // The DWARF CFI entry at OFFSET says that REG uses a DWARF
+    // expression to find its value, but DwarfCFIToModule is not
+    // capable of translating DWARF expressions to Breakpad postfix
+    // expressions.
+    virtual void ExpressionsNotSupported(size_t offset, const string &reg);
+
+  protected:
+    string file_, section_;
+  };
+
+  // Register name tables. If TABLE is a vector returned by one of these
+  // functions, then TABLE[R] is the name of the register numbered R in
+  // DWARF call frame information.
+  class RegisterNames {
+   public:
+    // Intel's "x86" or IA-32.
+    static vector<string> I386();
+
+    // AMD x86_64, AMD64, Intel EM64T, or Intel 64
+    static vector<string> X86_64();
+
+    // ARM.
+    static vector<string> ARM();
+
+   private:
+    // Given STRINGS, an array of C strings with SIZE elements, return an
+    // equivalent vector<string>.
+    static vector<string> MakeVector(const char * const *strings, size_t size);
+  };
+
+  // Create a handler for the dwarf2reader::CallFrameInfo parser that
+  // records the stack unwinding information it receives in MODULE.
+  //
+  // Use REGISTER_NAMES[I] as the name of register number I; *this
+  // keeps a reference to the vector, so the vector should remain
+  // alive for as long as the DwarfCFIToModule does.
+  //
+  // Use REPORTER for reporting problems encountered in the conversion
+  // process.
+  DwarfCFIToModule(Module *module, const vector<string> &register_names,
+                   Reporter *reporter)
+      : module_(module), register_names_(register_names), reporter_(reporter),
+        entry_(NULL), return_address_(-1), cfa_name_(".cfa"), ra_name_(".ra") {
+  }
+  virtual ~DwarfCFIToModule() { delete entry_; }
+
+  virtual bool Entry(size_t offset, uint64 address, uint64 length,
+                     uint8 version, const string &augmentation,
+                     unsigned return_address);
+  virtual bool UndefinedRule(uint64 address, int reg);
+  virtual bool SameValueRule(uint64 address, int reg);
+  virtual bool OffsetRule(uint64 address, int reg,
+                          int base_register, long offset);
+  virtual bool ValOffsetRule(uint64 address, int reg,
+                             int base_register, long offset);
+  virtual bool RegisterRule(uint64 address, int reg, int base_register);
+  virtual bool ExpressionRule(uint64 address, int reg,
+                              const string &expression);
+  virtual bool ValExpressionRule(uint64 address, int reg,
+                                 const string &expression);
+  virtual bool End();
+
+ private:
+  // Return the name to use for register REG.
+  string RegisterName(int i);
+
+  // Record RULE for register REG at ADDRESS.
+  void Record(Module::Address address, int reg, const string &rule);
+
+  // The module to which we should add entries.
+  Module *module_;
+
+  // Map from register numbers to register names.
+  const vector<string> &register_names_;
+
+  // The reporter to use to report problems.
+  Reporter *reporter_;
+
+  // The current entry we're constructing.
+  Module::StackFrameEntry *entry_;
+
+  // The section offset of the current frame description entry, for
+  // use in error messages.
+  size_t entry_offset_;
+
+  // The return address column for that entry.
+  unsigned return_address_;
+
+  // The names of the return address and canonical frame address. Putting
+  // these here instead of using string literals allows us to share their
+  // texts in reference-counted std::string implementations (all the
+  // popular ones). Many, many rules cite these strings.
+  string cfa_name_, ra_name_;
+
+  // A set of strings used by this CFI. Before storing a string in one of
+  // our data structures, insert it into this set, and then use the string
+  // from the set.
+  // 
+  // Because std::string uses reference counting internally, simply using
+  // strings from this set, even if passed by value, assigned, or held
+  // directly in structures and containers (map<string, ...>, for example),
+  // causes those strings to share a single instance of each distinct piece
+  // of text.
+  set<string> common_strings_;
+};
+
+} // namespace google_breakpad
+
+#endif // COMMON_LINUX_DWARF_CFI_TO_MODULE_H
diff --git a/3rdParty/Breakpad/src/common/dwarf_cu_to_module.cc b/3rdParty/Breakpad/src/common/dwarf_cu_to_module.cc
new file mode 100644
index 0000000..ded5f83
--- /dev/null
+++ b/3rdParty/Breakpad/src/common/dwarf_cu_to_module.cc
@@ -0,0 +1,936 @@
+// 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>
+
+// Implement the DwarfCUToModule class; see dwarf_cu_to_module.h.
+
+// For <inttypes.h> PRI* macros, before anything else might #include it.
+#ifndef __STDC_FORMAT_MACROS
+#define __STDC_FORMAT_MACROS
+#endif  /* __STDC_FORMAT_MACROS */
+
+#include "common/dwarf_cu_to_module.h"
+
+#include <assert.h>
+#include <inttypes.h>
+#include <stdio.h>
+
+#include <algorithm>
+#include <set>
+#include <utility>
+
+#include "common/dwarf_line_to_module.h"
+
+namespace google_breakpad {
+
+using std::map;
+using std::pair;
+using std::set;
+using std::vector;
+
+// Data provided by a DWARF specification DIE.
+// 
+// In DWARF, the DIE for a definition may contain a DW_AT_specification
+// attribute giving the offset of the corresponding declaration DIE, and
+// the definition DIE may omit information given in the declaration. For
+// example, it's common for a function's address range to appear only in
+// its definition DIE, but its name to appear only in its declaration
+// DIE.
+//
+// The dumper needs to be able to follow DW_AT_specification links to
+// bring all this information together in a FUNC record. Conveniently,
+// DIEs that are the target of such links have a DW_AT_declaration flag
+// set, so we can identify them when we first see them, and record their
+// contents for later reference.
+//
+// A Specification holds information gathered from a declaration DIE that
+// we may need if we find a DW_AT_specification link pointing to it.
+struct DwarfCUToModule::Specification {
+  // The name of the enclosing scope, or the empty string if there is none.
+  string enclosing_name;
+
+  // The name for the specification DIE itself, without any enclosing
+  // name components.
+  string unqualified_name;
+};
+
+// An abstract origin -- base definition of an inline function.
+struct AbstractOrigin {
+  AbstractOrigin() : name() {}
+  AbstractOrigin(const string& name) : name(name) {}
+
+  string name;
+};
+
+typedef map<uint64, AbstractOrigin> AbstractOriginByOffset;
+
+// Data global to the DWARF-bearing file that is private to the
+// DWARF-to-Module process.
+struct DwarfCUToModule::FilePrivate {
+  // A set of strings used in this CU. Before storing a string in one of
+  // our data structures, insert it into this set, and then use the string
+  // from the set.
+  // 
+  // Because std::string uses reference counting internally, simply using
+  // strings from this set, even if passed by value, assigned, or held
+  // directly in structures and containers (map<string, ...>, for example),
+  // causes those strings to share a single instance of each distinct piece
+  // of text.
+  set<string> common_strings;
+
+  // A map from offsets of DIEs within the .debug_info section to
+  // Specifications describing those DIEs. Specification references can
+  // cross compilation unit boundaries.
+  SpecificationByOffset specifications;
+
+  AbstractOriginByOffset origins;
+};
+
+DwarfCUToModule::FileContext::FileContext(const string &filename_arg,
+                                          Module *module_arg)
+    : filename(filename_arg), module(module_arg) {
+  file_private = new FilePrivate();
+}
+
+DwarfCUToModule::FileContext::~FileContext() {
+  delete file_private;
+}
+
+// Information global to the particular compilation unit we're
+// parsing. This is for data shared across the CU's entire DIE tree,
+// and parameters from the code invoking the CU parser.
+struct DwarfCUToModule::CUContext {
+  CUContext(FileContext *file_context_arg, WarningReporter *reporter_arg)
+      : file_context(file_context_arg),
+        reporter(reporter_arg),
+        language(Language::CPlusPlus) { }
+  ~CUContext() {
+    for (vector<Module::Function *>::iterator it = functions.begin();
+         it != functions.end(); it++)
+      delete *it;
+  };
+
+  // The DWARF-bearing file into which this CU was incorporated.
+  FileContext *file_context;
+
+  // For printing error messages.
+  WarningReporter *reporter;
+
+  // The source language of this compilation unit.
+  const Language *language;
+
+  // The functions defined in this compilation unit. We accumulate
+  // them here during parsing. Then, in DwarfCUToModule::Finish, we
+  // assign them lines and add them to file_context->module.
+  //
+  // Destroying this destroys all the functions this vector points to.
+  vector<Module::Function *> functions;
+};
+
+// Information about the context of a particular DIE. This is for
+// information that changes as we descend the tree towards the leaves:
+// the containing classes/namespaces, etc.
+struct DwarfCUToModule::DIEContext {
+  // The fully-qualified name of the context. For example, for a
+  // tree like:
+  //
+  // DW_TAG_namespace Foo
+  //   DW_TAG_class Bar
+  //     DW_TAG_subprogram Baz
+  //
+  // in a C++ compilation unit, the DIEContext's name for the
+  // DW_TAG_subprogram DIE would be "Foo::Bar". The DIEContext's
+  // name for the DW_TAG_namespace DIE would be "".
+  string name;
+};
+
+// An abstract base class for all the dumper's DIE handlers.
+class DwarfCUToModule::GenericDIEHandler: public dwarf2reader::DIEHandler {
+ public:
+  // Create a handler for the DIE at OFFSET whose compilation unit is
+  // described by CU_CONTEXT, and whose immediate context is described
+  // by PARENT_CONTEXT.
+  GenericDIEHandler(CUContext *cu_context, DIEContext *parent_context,
+                    uint64 offset)
+      : cu_context_(cu_context),
+        parent_context_(parent_context),
+        offset_(offset),
+        declaration_(false),
+        specification_(NULL) { }
+
+  // Derived classes' ProcessAttributeUnsigned can defer to this to
+  // handle DW_AT_declaration, or simply not override it.
+  void ProcessAttributeUnsigned(enum DwarfAttribute attr,
+                                enum DwarfForm form,
+                                uint64 data);
+
+  // Derived classes' ProcessAttributeReference can defer to this to
+  // handle DW_AT_specification, or simply not override it.
+  void ProcessAttributeReference(enum DwarfAttribute attr,
+                                 enum DwarfForm form,
+                                 uint64 data);
+
+  // Derived classes' ProcessAttributeReference can defer to this to
+  // handle DW_AT_specification, or simply not override it.
+  void ProcessAttributeString(enum DwarfAttribute attr,
+                              enum DwarfForm form,
+                              const string &data);
+
+ protected:
+  // Compute and return the fully-qualified name of the DIE. If this
+  // DIE is a declaration DIE, to be cited by other DIEs'
+  // DW_AT_specification attributes, record its enclosing name and
+  // unqualified name in the specification table.
+  //
+  // Use this from EndAttributes member functions, not ProcessAttribute*
+  // functions; only the former can be sure that all the DIE's attributes
+  // have been seen.
+  string ComputeQualifiedName();
+
+  CUContext *cu_context_;
+  DIEContext *parent_context_;
+  uint64 offset_;
+
+  // If this DIE has a DW_AT_declaration attribute, this is its value.
+  // It is false on DIEs with no DW_AT_declaration attribute.
+  bool declaration_;
+
+  // If this DIE has a DW_AT_specification attribute, this is the
+  // Specification structure for the DIE the attribute refers to.
+  // Otherwise, this is NULL.
+  Specification *specification_;
+
+  // The value of the DW_AT_name attribute, or the empty string if the
+  // DIE has no such attribute.
+  string name_attribute_;
+};
+
+void DwarfCUToModule::GenericDIEHandler::ProcessAttributeUnsigned(
+    enum DwarfAttribute attr,
+    enum DwarfForm form,
+    uint64 data) {
+  switch (attr) {
+    case dwarf2reader::DW_AT_declaration: declaration_ = (data != 0); break;
+    default: break;
+  }
+}
+
+void DwarfCUToModule::GenericDIEHandler::ProcessAttributeReference(
+    enum DwarfAttribute attr,
+    enum DwarfForm form,
+    uint64 data) {
+  switch (attr) {
+    case dwarf2reader::DW_AT_specification: {
+      // Find the Specification to which this attribute refers, and
+      // set specification_ appropriately. We could do more processing
+      // here, but it's better to leave the real work to our
+      // EndAttribute member function, at which point we know we have
+      // seen all the DIE's attributes.
+      FileContext *file_context = cu_context_->file_context;
+      SpecificationByOffset *specifications
+          = &file_context->file_private->specifications;
+      SpecificationByOffset::iterator spec = specifications->find(data);
+      if (spec != specifications->end()) {
+        specification_ = &spec->second;
+      } else {
+        // Technically, there's no reason a DW_AT_specification
+        // couldn't be a forward reference, but supporting that would
+        // be a lot of work (changing to a two-pass structure), and I
+        // don't think any producers we care about ever emit such
+        // things.
+        cu_context_->reporter->UnknownSpecification(offset_, data);
+      }
+      break;
+    }
+    default: break;
+  }
+}
+
+void DwarfCUToModule::GenericDIEHandler::ProcessAttributeString(
+    enum DwarfAttribute attr,
+    enum DwarfForm form,
+    const string &data) {
+  switch (attr) {
+    case dwarf2reader::DW_AT_name: {
+      // Place the name in our global set of strings, and then use the
+      // string from the set. Even though the assignment looks like a copy,
+      // all the major std::string implementations use reference counting
+      // internally, so the effect is to have all our data structures share
+      // copies of strings whenever possible.
+      pair<set<string>::iterator, bool> result =
+          cu_context_->file_context->file_private->common_strings.insert(data);
+      name_attribute_ = *result.first; 
+      break;
+    }
+    default: break;
+  }
+}
+
+string DwarfCUToModule::GenericDIEHandler::ComputeQualifiedName() {
+  // Find our unqualified name. If the DIE has its own DW_AT_name
+  // attribute, then use that; otherwise, check our specification.
+  const string *unqualified_name;
+  if (name_attribute_.empty() && specification_)
+    unqualified_name = &specification_->unqualified_name;
+  else
+    unqualified_name = &name_attribute_;
+
+  // Find the name of our enclosing context. If we have a
+  // specification, it's the specification's enclosing context that
+  // counts; otherwise, use this DIE's context.
+  const string *enclosing_name;
+  if (specification_)
+    enclosing_name = &specification_->enclosing_name;
+  else
+    enclosing_name = &parent_context_->name;
+
+  // If this DIE was marked as a declaration, record its names in the
+  // specification table.
+  if (declaration_) {
+    FileContext *file_context = cu_context_->file_context;
+    Specification spec;
+    spec.enclosing_name = *enclosing_name;
+    spec.unqualified_name = *unqualified_name;
+    file_context->file_private->specifications[offset_] = spec;
+  }
+
+  // Combine the enclosing name and unqualified name to produce our
+  // own fully-qualified name.
+  return cu_context_->language->MakeQualifiedName(*enclosing_name,
+                                                  *unqualified_name);
+}
+
+// A handler class for DW_TAG_subprogram DIEs.
+class DwarfCUToModule::FuncHandler: public GenericDIEHandler {
+ public:
+  FuncHandler(CUContext *cu_context, DIEContext *parent_context,
+              uint64 offset)
+      : GenericDIEHandler(cu_context, parent_context, offset),
+        low_pc_(0), high_pc_(0), abstract_origin_(NULL), inline_(false) { }
+  void ProcessAttributeUnsigned(enum DwarfAttribute attr,
+                                enum DwarfForm form,
+                                uint64 data);
+  void ProcessAttributeSigned(enum DwarfAttribute attr,
+                              enum DwarfForm form,
+                              int64 data);
+  void ProcessAttributeReference(enum DwarfAttribute attr,
+                                 enum DwarfForm form,
+                                 uint64 data);
+
+  bool EndAttributes();
+  void Finish();
+
+ private:
+  // The fully-qualified name, as derived from name_attribute_,
+  // specification_, parent_context_.  Computed in EndAttributes.
+  string name_;
+  uint64 low_pc_, high_pc_; // DW_AT_low_pc, DW_AT_high_pc
+  const AbstractOrigin* abstract_origin_;
+  bool inline_;
+};
+
+void DwarfCUToModule::FuncHandler::ProcessAttributeUnsigned(
+    enum DwarfAttribute attr,
+    enum DwarfForm form,
+    uint64 data) {
+  switch (attr) {
+    // If this attribute is present at all --- even if its value is
+    // DW_INL_not_inlined --- then GCC may cite it as someone else's
+    // DW_AT_abstract_origin attribute.
+    case dwarf2reader::DW_AT_inline:      inline_  = true; break;
+
+    case dwarf2reader::DW_AT_low_pc:      low_pc_  = data; break;
+    case dwarf2reader::DW_AT_high_pc:     high_pc_ = data; break;
+    default:
+      GenericDIEHandler::ProcessAttributeUnsigned(attr, form, data);
+      break;
+  }
+}
+
+void DwarfCUToModule::FuncHandler::ProcessAttributeSigned(
+    enum DwarfAttribute attr,
+    enum DwarfForm form,
+    int64 data) {
+  switch (attr) {
+    // If this attribute is present at all --- even if its value is
+    // DW_INL_not_inlined --- then GCC may cite it as someone else's
+    // DW_AT_abstract_origin attribute.
+    case dwarf2reader::DW_AT_inline:      inline_  = true; break;
+
+    default:
+      break;
+  }
+}
+
+void DwarfCUToModule::FuncHandler::ProcessAttributeReference(
+    enum DwarfAttribute attr,
+    enum DwarfForm form,
+    uint64 data) {
+  switch(attr) {
+    case dwarf2reader::DW_AT_abstract_origin: {
+      const AbstractOriginByOffset& origins =
+          cu_context_->file_context->file_private->origins;
+      AbstractOriginByOffset::const_iterator origin = origins.find(data);
+      if (origin != origins.end()) {
+        abstract_origin_ = &(origin->second);
+      } else {
+        cu_context_->reporter->UnknownAbstractOrigin(offset_, data);
+      }
+      break;
+    }
+    default:
+      GenericDIEHandler::ProcessAttributeReference(attr, form, data);
+      break;
+  }
+}
+
+bool DwarfCUToModule::FuncHandler::EndAttributes() {
+  // Compute our name, and record a specification, if appropriate.
+  name_ = ComputeQualifiedName();
+  if (name_.empty() && abstract_origin_) {
+    name_ = abstract_origin_->name;
+  }
+  return true;
+}
+
+void DwarfCUToModule::FuncHandler::Finish() {
+  // Did we collect the information we need?  Not all DWARF function
+  // entries have low and high addresses (for example, inlined
+  // functions that were never used), but all the ones we're
+  // interested in cover a non-empty range of bytes.
+  if (low_pc_ < high_pc_) {
+    // Create a Module::Function based on the data we've gathered, and
+    // add it to the functions_ list.
+    Module::Function *func = new Module::Function;
+    // Malformed DWARF may omit the name, but all Module::Functions must
+    // have names.
+    if (!name_.empty()) {
+      func->name = name_;
+    } else {
+      cu_context_->reporter->UnnamedFunction(offset_);
+      func->name = "<name omitted>";
+    }
+    func->address = low_pc_;
+    func->size = high_pc_ - low_pc_;
+    func->parameter_size = 0;
+    if (func->address) {
+       // If the function address is zero this is a sign that this function
+       // description is just empty debug data and should just be discarded.
+       cu_context_->functions.push_back(func);
+     }
+  } else if (inline_) {
+    AbstractOrigin origin(name_);
+    cu_context_->file_context->file_private->origins[offset_] = origin;
+  }
+}
+
+// A handler for DIEs that contain functions and contribute a
+// component to their names: namespaces, classes, etc.
+class DwarfCUToModule::NamedScopeHandler: public GenericDIEHandler {
+ public:
+  NamedScopeHandler(CUContext *cu_context, DIEContext *parent_context,
+                    uint64 offset)
+      : GenericDIEHandler(cu_context, parent_context, offset) { }
+  bool EndAttributes();
+  DIEHandler *FindChildHandler(uint64 offset, enum DwarfTag tag,
+                               const AttributeList &attrs);
+
+ private:
+  DIEContext child_context_; // A context for our children.
+};
+
+bool DwarfCUToModule::NamedScopeHandler::EndAttributes() {
+  child_context_.name = ComputeQualifiedName();
+  return true;
+}
+
+dwarf2reader::DIEHandler *DwarfCUToModule::NamedScopeHandler::FindChildHandler(
+    uint64 offset,
+    enum DwarfTag tag,
+    const AttributeList &attrs) {
+  switch (tag) {
+    case dwarf2reader::DW_TAG_subprogram:
+      return new FuncHandler(cu_context_, &child_context_, offset);
+    case dwarf2reader::DW_TAG_namespace:
+    case dwarf2reader::DW_TAG_class_type:
+    case dwarf2reader::DW_TAG_structure_type:
+    case dwarf2reader::DW_TAG_union_type:
+      return new NamedScopeHandler(cu_context_, &child_context_, offset);
+    default:
+      return NULL;
+  }
+}
+
+void DwarfCUToModule::WarningReporter::CUHeading() {
+  if (printed_cu_header_)
+    return;
+  fprintf(stderr, "%s: in compilation unit '%s' (offset 0x%llx):\n",
+          filename_.c_str(), cu_name_.c_str(), cu_offset_);
+  printed_cu_header_ = true;
+}
+
+void DwarfCUToModule::WarningReporter::UnknownSpecification(uint64 offset,
+                                                            uint64 target) {
+  CUHeading();
+  fprintf(stderr, "%s: the DIE at offset 0x%llx has a DW_AT_specification"
+          " attribute referring to the die at offset 0x%llx, which either"
+          " was not marked as a declaration, or comes later in the file\n",
+          filename_.c_str(), offset, target);
+}
+
+void DwarfCUToModule::WarningReporter::UnknownAbstractOrigin(uint64 offset,
+                                                             uint64 target) {
+  CUHeading();
+  fprintf(stderr, "%s: the DIE at offset 0x%llx has a DW_AT_abstract_origin"
+          " attribute referring to the die at offset 0x%llx, which either"
+          " was not marked as an inline, or comes later in the file\n",
+          filename_.c_str(), offset, target);
+}
+
+void DwarfCUToModule::WarningReporter::MissingSection(const string &name) {
+  CUHeading();
+  fprintf(stderr, "%s: warning: couldn't find DWARF '%s' section\n",
+          filename_.c_str(), name.c_str());
+}
+
+void DwarfCUToModule::WarningReporter::BadLineInfoOffset(uint64 offset) {
+  CUHeading();
+  fprintf(stderr, "%s: warning: line number data offset beyond end"
+          " of '.debug_line' section\n",
+          filename_.c_str());
+}
+
+void DwarfCUToModule::WarningReporter::UncoveredHeading() {
+  if (printed_unpaired_header_)
+    return;
+  CUHeading();
+  fprintf(stderr, "%s: warning: skipping unpaired lines/functions:\n",
+          filename_.c_str());
+  printed_unpaired_header_ = true;
+}
+
+void DwarfCUToModule::WarningReporter::UncoveredFunction(
+    const Module::Function &function) {
+  if (!uncovered_warnings_enabled_)
+    return;
+  UncoveredHeading();
+  fprintf(stderr, "    function%s: %s\n",
+          function.size == 0 ? " (zero-length)" : "",
+          function.name.c_str());
+}
+
+void DwarfCUToModule::WarningReporter::UncoveredLine(const Module::Line &line) {
+  if (!uncovered_warnings_enabled_)
+    return;
+  UncoveredHeading();
+  fprintf(stderr, "    line%s: %s:%d at 0x%" PRIx64 "\n",
+          (line.size == 0 ? " (zero-length)" : ""),
+          line.file->name.c_str(), line.number, line.address);
+}
+
+void DwarfCUToModule::WarningReporter::UnnamedFunction(uint64 offset) {
+  CUHeading();
+  fprintf(stderr, "%s: warning: function at offset 0x%llx has no name\n",
+          filename_.c_str(), offset);
+}
+
+DwarfCUToModule::DwarfCUToModule(FileContext *file_context,
+                                 LineToModuleFunctor *line_reader,
+                                 WarningReporter *reporter)
+    : line_reader_(line_reader), has_source_line_info_(false) { 
+  cu_context_ = new CUContext(file_context, reporter);
+  child_context_ = new DIEContext();
+}
+
+DwarfCUToModule::~DwarfCUToModule() {
+  delete cu_context_;
+  delete child_context_;
+}
+
+void DwarfCUToModule::ProcessAttributeSigned(enum DwarfAttribute attr,
+                                             enum DwarfForm form,
+                                             int64 data) {
+  switch (attr) {
+    case dwarf2reader::DW_AT_language: // source language of this CU
+      SetLanguage(static_cast<DwarfLanguage>(data));
+      break;
+    default:
+      break;
+  }
+}
+
+void DwarfCUToModule::ProcessAttributeUnsigned(enum DwarfAttribute attr,
+                                               enum DwarfForm form,
+                                               uint64 data) {
+  switch (attr) {
+    case dwarf2reader::DW_AT_stmt_list: // Line number information.
+      has_source_line_info_ = true;
+      source_line_offset_ = data;
+      break;
+    case dwarf2reader::DW_AT_language: // source language of this CU
+      SetLanguage(static_cast<DwarfLanguage>(data));
+      break;
+    default:
+      break;
+  }
+}
+
+void DwarfCUToModule::ProcessAttributeString(enum DwarfAttribute attr,
+                                             enum DwarfForm form,
+                                             const string &data) {
+  if (attr == dwarf2reader::DW_AT_name)
+    cu_context_->reporter->SetCUName(data);
+}
+
+bool DwarfCUToModule::EndAttributes() {
+  return true;
+}
+
+dwarf2reader::DIEHandler *DwarfCUToModule::FindChildHandler(
+    uint64 offset,
+    enum DwarfTag tag,
+    const AttributeList &attrs) {
+  switch (tag) {
+    case dwarf2reader::DW_TAG_subprogram:
+      return new FuncHandler(cu_context_, child_context_, offset);
+    case dwarf2reader::DW_TAG_namespace:
+    case dwarf2reader::DW_TAG_class_type:
+    case dwarf2reader::DW_TAG_structure_type:
+    case dwarf2reader::DW_TAG_union_type:
+      return new NamedScopeHandler(cu_context_, child_context_, offset);
+    default:
+      return NULL;
+  }
+}
+
+void DwarfCUToModule::SetLanguage(DwarfLanguage language) {
+  switch (language) {
+    case dwarf2reader::DW_LANG_Java:
+      cu_context_->language = Language::Java;
+      break;
+
+    // DWARF has no generic language code for assembly language; this is
+    // what the GNU toolchain uses.
+    case dwarf2reader::DW_LANG_Mips_Assembler:
+      cu_context_->language = Language::Assembler;
+      break;
+
+    // C++ covers so many cases that it probably has some way to cope
+    // with whatever the other languages throw at us. So make it the
+    // default.
+    //
+    // Objective C and Objective C++ seem to create entries for
+    // methods whose DW_AT_name values are already fully-qualified:
+    // "-[Classname method:]".  These appear at the top level.
+    // 
+    // DWARF data for C should never include namespaces or functions
+    // nested in struct types, but if it ever does, then C++'s
+    // notation is probably not a bad choice for that.
+    default:
+    case dwarf2reader::DW_LANG_ObjC:
+    case dwarf2reader::DW_LANG_ObjC_plus_plus:
+    case dwarf2reader::DW_LANG_C:
+    case dwarf2reader::DW_LANG_C89:
+    case dwarf2reader::DW_LANG_C99:
+    case dwarf2reader::DW_LANG_C_plus_plus:
+      cu_context_->language = Language::CPlusPlus;
+      break;
+  }
+}
+
+void DwarfCUToModule::ReadSourceLines(uint64 offset) {
+  const dwarf2reader::SectionMap &section_map
+      = cu_context_->file_context->section_map;
+  dwarf2reader::SectionMap::const_iterator map_entry
+      = section_map.find(".debug_line");
+  // Mac OS X puts DWARF data in sections whose names begin with "__"
+  // instead of ".".
+  if (map_entry == section_map.end())
+    map_entry = section_map.find("__debug_line");
+  if (map_entry == section_map.end()) {
+    cu_context_->reporter->MissingSection(".debug_line");
+    return;
+  }
+  const char *section_start = map_entry->second.first;
+  uint64 section_length = map_entry->second.second;
+  if (offset >= section_length) {
+    cu_context_->reporter->BadLineInfoOffset(offset);
+    return;
+  }
+  (*line_reader_)(section_start + offset, section_length - offset,
+                  cu_context_->file_context->module, &lines_);
+}
+
+namespace {
+// Return true if ADDRESS falls within the range of ITEM.
+template <class T>
+inline bool within(const T &item, Module::Address address) {
+  // Because Module::Address is unsigned, and unsigned arithmetic
+  // wraps around, this will be false if ADDRESS falls before the
+  // start of ITEM, or if it falls after ITEM's end.
+  return address - item.address < item.size;
+}
+}
+
+void DwarfCUToModule::AssignLinesToFunctions() {
+  vector<Module::Function *> *functions = &cu_context_->functions;
+  WarningReporter *reporter = cu_context_->reporter;
+
+  // This would be simpler if we assumed that source line entries
+  // don't cross function boundaries.  However, there's no real reason
+  // to assume that (say) a series of function definitions on the same
+  // line wouldn't get coalesced into one line number entry.  The
+  // DWARF spec certainly makes no such promises.
+  //
+  // So treat the functions and lines as peers, and take the trouble
+  // to compute their ranges' intersections precisely.  In any case,
+  // the hair here is a constant factor for performance; the
+  // complexity from here on out is linear.
+
+  // Put both our functions and lines in order by address.
+  sort(functions->begin(), functions->end(),
+       Module::Function::CompareByAddress);
+  sort(lines_.begin(), lines_.end(), Module::Line::CompareByAddress);
+
+  // The last line that we used any piece of.  We use this only for
+  // generating warnings.
+  const Module::Line *last_line_used = NULL;
+
+  // The last function and line we warned about --- so we can avoid
+  // doing so more than once.
+  const Module::Function *last_function_cited = NULL;
+  const Module::Line *last_line_cited = NULL;
+
+  // Make a single pass through both vectors from lower to higher
+  // addresses, populating each Function's lines vector with lines
+  // from our lines_ vector that fall within the function's address
+  // range.
+  vector<Module::Function *>::iterator func_it = functions->begin();
+  vector<Module::Line>::const_iterator line_it = lines_.begin();
+
+  Module::Address current;
+
+  // Pointers to the referents of func_it and line_it, or NULL if the
+  // iterator is at the end of the sequence.
+  Module::Function *func;
+  const Module::Line *line;
+
+  // Start current at the beginning of the first line or function,
+  // whichever is earlier.
+  if (func_it != functions->end() && line_it != lines_.end()) {
+    func = *func_it;
+    line = &*line_it;
+    current = std::min(func->address, line->address);
+  } else if (line_it != lines_.end()) {
+    func = NULL;
+    line = &*line_it;
+    current = line->address;
+  } else if (func_it != functions->end()) {
+    func = *func_it;
+    line = NULL;
+    current = (*func_it)->address;
+  } else {
+    return;
+  }
+
+  while (func || line) {
+    // This loop has two invariants that hold at the top.
+    //
+    // First, at least one of the iterators is not at the end of its
+    // sequence, and those that are not refer to the earliest
+    // function or line that contains or starts after CURRENT.
+    //
+    // Note that every byte is in one of four states: it is covered
+    // or not covered by a function, and, independently, it is
+    // covered or not covered by a line.
+    //
+    // The second invariant is that CURRENT refers to a byte whose
+    // state is different from its predecessor, or it refers to the
+    // first byte in the address space. In other words, CURRENT is
+    // always the address of a transition.
+    //
+    // Note that, although each iteration advances CURRENT from one
+    // transition address to the next in each iteration, it might
+    // not advance the iterators. Suppose we have a function that
+    // starts with a line, has a gap, and then a second line, and
+    // suppose that we enter an iteration with CURRENT at the end of
+    // the first line. The next transition address is the start of
+    // the second line, after the gap, so the iteration should
+    // advance CURRENT to that point. At the head of that iteration,
+    // the invariants require that the line iterator be pointing at
+    // the second line. But this is also true at the head of the
+    // next. And clearly, the iteration must not change the function
+    // iterator. So neither iterator moves.
+
+    // Assert the first invariant (see above).
+    assert(!func || current < func->address || within(*func, current));
+    assert(!line || current < line->address || within(*line, current));
+
+    // The next transition after CURRENT.
+    Module::Address next_transition;
+
+    // Figure out which state we're in, add lines or warn, and compute
+    // the next transition address.
+    if (func && current >= func->address) {
+      if (line && current >= line->address) {
+        // Covered by both a line and a function.
+        Module::Address func_left = func->size - (current - func->address);
+        Module::Address line_left = line->size - (current - line->address);
+        // This may overflow, but things work out.
+        next_transition = current + std::min(func_left, line_left);
+        Module::Line l = *line;
+        l.address = current;
+        l.size = next_transition - current;
+        func->lines.push_back(l);
+        last_line_used = line;
+      } else {
+        // Covered by a function, but no line.
+        if (func != last_function_cited) {
+          reporter->UncoveredFunction(*func);
+          last_function_cited = func;
+        }
+        if (line && within(*func, line->address))
+          next_transition = line->address;
+        else
+          // If this overflows, we'll catch it below.
+          next_transition = func->address + func->size;
+      }
+    } else {
+      if (line && current >= line->address) {
+        // Covered by a line, but no function.
+        //
+        // If GCC emits padding after one function to align the start
+        // of the next, then it will attribute the padding
+        // instructions to the last source line of function (to reduce
+        // the size of the line number info), but omit it from the
+        // DW_AT_{low,high}_pc range given in .debug_info (since it
+        // costs nothing to be precise there). If we did use at least
+        // some of the line we're about to skip, and it ends at the
+        // start of the next function, then assume this is what
+        // happened, and don't warn.
+        if (line != last_line_cited
+            && !(func
+                 && line == last_line_used
+                 && func->address - line->address == line->size)) {
+          reporter->UncoveredLine(*line);
+          last_line_cited = line;
+        }
+        if (func && within(*line, func->address))
+          next_transition = func->address;
+        else
+          // If this overflows, we'll catch it below.
+          next_transition = line->address + line->size;
+      } else {
+        // Covered by neither a function nor a line. By the invariant,
+        // both func and line begin after CURRENT. The next transition
+        // is the start of the next function or next line, whichever
+        // is earliest.
+        assert (func || line);
+        if (func && line)
+          next_transition = std::min(func->address, line->address);
+        else if (func)
+          next_transition = func->address;
+        else
+          next_transition = line->address;
+      }
+    }
+
+    // If a function or line abuts the end of the address space, then
+    // next_transition may end up being zero, in which case we've completed
+    // our pass. Handle that here, instead of trying to deal with it in
+    // each place we compute next_transition.
+    if (!next_transition)
+      break;
+
+    // Advance iterators as needed. If lines overlap or functions overlap,
+    // then we could go around more than once. We don't worry too much
+    // about what result we produce in that case, just as long as we don't
+    // hang or crash.
+    while (func_it != functions->end()
+           && next_transition >= (*func_it)->address
+           && !within(**func_it, next_transition))
+      func_it++;
+    func = (func_it != functions->end()) ? *func_it : NULL;
+    while (line_it != lines_.end()
+           && next_transition >= line_it->address
+           && !within(*line_it, next_transition))
+      line_it++;
+    line = (line_it != lines_.end()) ? &*line_it : NULL;
+
+    // We must make progress.
+    assert(next_transition > current);
+    current = next_transition;
+  }
+}
+
+void DwarfCUToModule::Finish() {
+  // Assembly language files have no function data, and that gives us
+  // no place to store our line numbers (even though the GNU toolchain
+  // will happily produce source line info for assembly language
+  // files).  To avoid spurious warnings about lines we can't assign
+  // to functions, skip CUs in languages that lack functions.
+  if (!cu_context_->language->HasFunctions())
+    return;
+
+  // Read source line info, if we have any.
+  if (has_source_line_info_)
+    ReadSourceLines(source_line_offset_);
+
+  vector<Module::Function *> *functions = &cu_context_->functions;
+
+  // Dole out lines to the appropriate functions.
+  AssignLinesToFunctions();
+
+  // Add our functions, which now have source lines assigned to them,
+  // to module_.
+  cu_context_->file_context->module->AddFunctions(functions->begin(),
+                                                  functions->end());
+
+  // Ownership of the function objects has shifted from cu_context to
+  // the Module.
+  functions->clear();
+}
+
+bool DwarfCUToModule::StartCompilationUnit(uint64 offset,
+                                           uint8 address_size,
+                                           uint8 offset_size,
+                                           uint64 cu_length,
+                                           uint8 dwarf_version) {
+  return dwarf_version >= 2;
+}
+
+bool DwarfCUToModule::StartRootDIE(uint64 offset, enum DwarfTag tag,
+                                   const AttributeList& attrs) {
+  // We don't deal with partial compilation units (the only other tag
+  // likely to be used for root DIE).
+  return tag == dwarf2reader::DW_TAG_compile_unit;
+}
+
+} // namespace google_breakpad
diff --git a/3rdParty/Breakpad/src/common/dwarf_cu_to_module.h b/3rdParty/Breakpad/src/common/dwarf_cu_to_module.h
new file mode 100644
index 0000000..ac62846
--- /dev/null
+++ b/3rdParty/Breakpad/src/common/dwarf_cu_to_module.h
@@ -0,0 +1,277 @@
+// -*- mode: c++ -*-
+
+// 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>
+
+// Add DWARF debugging information to a Breakpad symbol file. This
+// file defines the DwarfCUToModule class, which accepts parsed DWARF
+// data and populates a google_breakpad::Module with the results; the
+// Module can then write its contents as a Breakpad symbol file.
+
+#ifndef COMMON_LINUX_DWARF_CU_TO_MODULE_H__
+#define COMMON_LINUX_DWARF_CU_TO_MODULE_H__
+
+#include <string>
+
+#include "common/language.h"
+#include "common/module.h"
+#include "common/dwarf/bytereader.h"
+#include "common/dwarf/dwarf2diehandler.h"
+#include "common/dwarf/dwarf2reader.h"
+#include "common/using_std_string.h"
+
+namespace google_breakpad {
+
+using dwarf2reader::AttributeList;
+using dwarf2reader::DwarfAttribute;
+using dwarf2reader::DwarfForm;
+using dwarf2reader::DwarfLanguage;
+using dwarf2reader::DwarfTag;
+
+// Populate a google_breakpad::Module with DWARF debugging information.
+//
+// An instance of this class can be provided as a handler to a
+// dwarf2reader::DIEDispatcher, which can in turn be a handler for a
+// dwarf2reader::CompilationUnit DWARF parser. The handler uses the results
+// of parsing to populate a google_breakpad::Module with source file,
+// function, and source line information.
+class DwarfCUToModule: public dwarf2reader::RootDIEHandler {
+  struct FilePrivate;
+ public:
+
+  // Information global to the DWARF-bearing file we are processing,
+  // for use by DwarfCUToModule. Each DwarfCUToModule instance deals
+  // with a single compilation unit within the file, but information
+  // global to the whole file is held here. The client is responsible
+  // for filling it in appropriately (except for the 'file_private'
+  // field, which the constructor and destructor take care of), and
+  // then providing it to the DwarfCUToModule instance for each
+  // compilation unit we process in that file.
+  struct FileContext {
+    FileContext(const string &filename_arg, Module *module_arg);
+    ~FileContext();
+
+    // The name of this file, for use in error messages.
+    string filename;
+
+    // A map of this file's sections, used for finding other DWARF
+    // sections that the .debug_info section may refer to.
+    dwarf2reader::SectionMap section_map;
+
+    // The Module to which we're contributing definitions.
+    Module *module;
+
+    // Inter-compilation unit data used internally by the handlers.
+    FilePrivate *file_private;
+  };
+
+  // An abstract base class for functors that handle DWARF line data
+  // for DwarfCUToModule. DwarfCUToModule could certainly just use
+  // dwarf2reader::LineInfo itself directly, but decoupling things
+  // this way makes unit testing a little easier.
+  class LineToModuleFunctor {
+   public:
+    LineToModuleFunctor() { }
+    virtual ~LineToModuleFunctor() { }
+
+    // Populate MODULE and LINES with source file names and code/line
+    // mappings, given a pointer to some DWARF line number data
+    // PROGRAM, and an overestimate of its size. Add no zero-length
+    // lines to LINES.
+    virtual void operator()(const char *program, uint64 length,
+                            Module *module, vector<Module::Line> *lines) = 0;
+  };
+
+  // The interface DwarfCUToModule uses to report warnings. The member
+  // function definitions for this class write messages to stderr, but
+  // you can override them if you'd like to detect or report these
+  // conditions yourself.
+  class WarningReporter {
+   public:
+    // Warn about problems in the DWARF file FILENAME, in the
+    // compilation unit at OFFSET.
+    WarningReporter(const string &filename, uint64 cu_offset)
+        : filename_(filename), cu_offset_(cu_offset), printed_cu_header_(false),
+          printed_unpaired_header_(false),
+          uncovered_warnings_enabled_(false) { }
+    virtual ~WarningReporter() { }
+
+    // Set the name of the compilation unit we're processing to NAME.
+    virtual void SetCUName(const string &name) { cu_name_ = name; }
+
+    // Accessor and setter for uncovered_warnings_enabled_.
+    // UncoveredFunction and UncoveredLine only report a problem if that is
+    // true. By default, these warnings are disabled, because those
+    // conditions occur occasionally in healthy code.
+    virtual bool uncovered_warnings_enabled() const {
+      return uncovered_warnings_enabled_;
+    }
+    virtual void set_uncovered_warnings_enabled(bool value) {
+      uncovered_warnings_enabled_ = value;
+    }
+
+    // A DW_AT_specification in the DIE at OFFSET refers to a DIE we
+    // haven't processed yet, or that wasn't marked as a declaration,
+    // at TARGET.
+    virtual void UnknownSpecification(uint64 offset, uint64 target);
+
+    // A DW_AT_abstract_origin in the DIE at OFFSET refers to a DIE we
+    // haven't processed yet, or that wasn't marked as inline, at TARGET.
+    virtual void UnknownAbstractOrigin(uint64 offset, uint64 target);
+
+    // We were unable to find the DWARF section named SECTION_NAME.
+    virtual void MissingSection(const string &section_name);
+
+    // The CU's DW_AT_stmt_list offset OFFSET is bogus.
+    virtual void BadLineInfoOffset(uint64 offset);
+
+    // FUNCTION includes code covered by no line number data.
+    virtual void UncoveredFunction(const Module::Function &function);
+
+    // Line number NUMBER in LINE_FILE, of length LENGTH, includes code
+    // covered by no function.
+    virtual void UncoveredLine(const Module::Line &line);
+
+    // The DW_TAG_subprogram DIE at OFFSET has no name specified directly
+    // in the DIE, nor via a DW_AT_specification or DW_AT_abstract_origin
+    // link.
+    virtual void UnnamedFunction(uint64 offset);
+
+   protected:
+    string filename_;
+    uint64 cu_offset_;
+    string cu_name_;
+    bool printed_cu_header_;
+    bool printed_unpaired_header_;
+    bool uncovered_warnings_enabled_;
+
+   private:
+    // Print a per-CU heading, once.
+    void CUHeading();
+    // Print an unpaired function/line heading, once.
+    void UncoveredHeading();
+  };
+
+  // Create a DWARF debugging info handler for a compilation unit
+  // within FILE_CONTEXT. This uses information received from the
+  // dwarf2reader::CompilationUnit DWARF parser to populate
+  // FILE_CONTEXT->module. Use LINE_READER to handle the compilation
+  // unit's line number data. Use REPORTER to report problems with the
+  // data we find.
+  DwarfCUToModule(FileContext *file_context,
+                  LineToModuleFunctor *line_reader,
+                  WarningReporter *reporter);
+  ~DwarfCUToModule();
+
+  void ProcessAttributeSigned(enum DwarfAttribute attr,
+                              enum DwarfForm form,
+                              int64 data);
+  void ProcessAttributeUnsigned(enum DwarfAttribute attr,
+                                enum DwarfForm form,
+                                uint64 data);
+  void ProcessAttributeString(enum DwarfAttribute attr,
+                              enum DwarfForm form,
+                              const string &data);
+  bool EndAttributes();
+  DIEHandler *FindChildHandler(uint64 offset, enum DwarfTag tag,
+                               const AttributeList &attrs);
+
+  // Assign all our source Lines to the Functions that cover their
+  // addresses, and then add them to module_.
+  void Finish();
+
+  bool StartCompilationUnit(uint64 offset, uint8 address_size,
+                            uint8 offset_size, uint64 cu_length,
+                            uint8 dwarf_version);
+  bool StartRootDIE(uint64 offset, enum DwarfTag tag,
+                    const AttributeList& attrs);
+
+ private:
+
+  // Used internally by the handler. Full definitions are in
+  // dwarf_cu_to_module.cc.
+  struct FilePrivate;
+  struct Specification;
+  struct CUContext;
+  struct DIEContext;
+  class GenericDIEHandler;
+  class FuncHandler;
+  class NamedScopeHandler;
+
+  // A map from section offsets to specifications.
+  typedef map<uint64, Specification> SpecificationByOffset;
+
+  // Set this compilation unit's source language to LANGUAGE.
+  void SetLanguage(DwarfLanguage language);
+  
+  // Read source line information at OFFSET in the .debug_line
+  // section.  Record source files in module_, but record source lines
+  // in lines_; we apportion them to functions in
+  // AssignLinesToFunctions.
+  void ReadSourceLines(uint64 offset);
+
+  // Assign the lines in lines_ to the individual line lists of the
+  // functions in functions_.  (DWARF line information maps an entire
+  // compilation unit at a time, and gives no indication of which
+  // lines belong to which functions, beyond their addresses.)
+  void AssignLinesToFunctions();
+
+  // The only reason cu_context_ and child_context_ are pointers is
+  // that we want to keep their definitions private to
+  // dwarf_cu_to_module.cc, instead of listing them all here. They are
+  // owned by this DwarfCUToModule: the constructor sets them, and the
+  // destructor deletes them.
+
+  // The functor to use to handle line number data.
+  LineToModuleFunctor *line_reader_;
+
+  // This compilation unit's context.
+  CUContext *cu_context_;
+
+  // A context for our children.
+  DIEContext *child_context_;
+
+  // True if this compilation unit has source line information.
+  bool has_source_line_info_;
+
+  // The offset of this compilation unit's line number information in
+  // the .debug_line section.
+  uint64 source_line_offset_;
+
+  // The line numbers we have seen thus far.  We accumulate these here
+  // during parsing.  Then, in Finish, we call AssignLinesToFunctions
+  // to dole them out to the appropriate functions.
+  vector<Module::Line> lines_;
+};
+
+} // namespace google_breakpad
+
+#endif  // COMMON_LINUX_DWARF_CU_TO_MODULE_H__
diff --git a/3rdParty/Breakpad/src/common/dwarf_line_to_module.cc b/3rdParty/Breakpad/src/common/dwarf_line_to_module.cc
new file mode 100644
index 0000000..962848d
--- /dev/null
+++ b/3rdParty/Breakpad/src/common/dwarf_line_to_module.cc
@@ -0,0 +1,138 @@
+// 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>
+
+// dwarf_line_to_module.cc: Implementation of DwarfLineToModule class.
+// See dwarf_line_to_module.h for details. 
+
+#include <stdio.h>
+
+#include <string>
+
+#include "common/dwarf_line_to_module.h"
+#include "common/using_std_string.h"
+
+// Trying to support Windows paths in a reasonable way adds a lot of
+// variations to test; it would be better to just put off dealing with
+// it until we actually have to deal with DWARF on Windows.
+
+// Return true if PATH is an absolute path, false if it is relative.
+static bool PathIsAbsolute(const string &path) {
+  return (path.size() >= 1 && path[0] == '/');
+}
+
+// If PATH is an absolute path, return PATH.  If PATH is a relative path,
+// treat it as relative to BASE and return the combined path.
+static string ExpandPath(const string &path,
+                         const string &base) {
+  if (PathIsAbsolute(path))
+    return path;
+  return base + "/" + path;
+}
+
+namespace google_breakpad {
+
+void DwarfLineToModule::DefineDir(const string &name, uint32 dir_num) {
+  // Directory number zero is reserved to mean the compilation
+  // directory. Silently ignore attempts to redefine it.
+  if (dir_num != 0)
+    directories_[dir_num] = name;
+}
+
+void DwarfLineToModule::DefineFile(const string &name, int32 file_num,
+                                   uint32 dir_num, uint64 mod_time,
+                                   uint64 length) {
+  if (file_num == -1)
+    file_num = ++highest_file_number_;
+  else if (file_num > highest_file_number_)
+    highest_file_number_ = file_num;
+
+  string full_name;
+  if (dir_num != 0) {
+    DirectoryTable::const_iterator directory_it = directories_.find(dir_num);
+    if (directory_it != directories_.end()) {
+      full_name = ExpandPath(name, directory_it->second);
+    } else {
+      if (!warned_bad_directory_number_) {
+        fprintf(stderr, "warning: DWARF line number data refers to undefined"
+                " directory numbers\n");
+        warned_bad_directory_number_ = true;
+      }
+      full_name = name; // just treat name as relative
+    }
+  } else {
+    // Directory number zero is the compilation directory; we just report
+    // relative paths in that case.
+    full_name = name;
+  }
+
+  // Find a Module::File object of the given name, and add it to the
+  // file table.
+  files_[file_num] = module_->FindFile(full_name);
+}
+
+void DwarfLineToModule::AddLine(uint64 address, uint64 length,
+                                uint32 file_num, uint32 line_num,
+                                uint32 column_num) {
+  if (length == 0)
+    return;
+
+  // Clip lines not to extend beyond the end of the address space.
+  if (address + length < address)
+    length = -address;
+
+  // Should we omit this line? (See the comments for omitted_line_end_.)
+  if (address == 0 || address == omitted_line_end_) {
+    omitted_line_end_ = address + length;
+    return;
+  } else {
+    omitted_line_end_ = 0;
+  }
+
+  // Find the source file being referred to.
+  Module::File *file = files_[file_num];
+  if (!file) {
+    if (!warned_bad_file_number_) {
+      fprintf(stderr, "warning: DWARF line number data refers to "
+              "undefined file numbers\n");
+      warned_bad_file_number_ = true;
+    }
+    return;
+  }
+  Module::Line line;
+  line.address = address;
+  // We set the size when we get the next line or the EndSequence call.
+  line.size = length;
+  line.file = file;
+  line.number = line_num;
+  lines_->push_back(line);
+}
+
+} // namespace google_breakpad
diff --git a/3rdParty/Breakpad/src/common/dwarf_line_to_module.h b/3rdParty/Breakpad/src/common/dwarf_line_to_module.h
new file mode 100644
index 0000000..9382e40
--- /dev/null
+++ b/3rdParty/Breakpad/src/common/dwarf_line_to_module.h
@@ -0,0 +1,182 @@
+// -*- mode: c++ -*-
+
+// 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>
+
+// The DwarfLineToModule class accepts line number information from a
+// DWARF parser and adds it to a google_breakpad::Module. The Module
+// can write that data out as a Breakpad symbol file.
+
+#ifndef COMMON_LINUX_DWARF_LINE_TO_MODULE_H
+#define COMMON_LINUX_DWARF_LINE_TO_MODULE_H
+
+#include <string>
+
+#include "common/module.h"
+#include "common/dwarf/dwarf2reader.h"
+#include "common/using_std_string.h"
+
+namespace google_breakpad {
+
+// A class for producing a vector of google_breakpad::Module::Line
+// instances from parsed DWARF line number data.  
+//
+// An instance of this class can be provided as a handler to a
+// dwarf2reader::LineInfo DWARF line number information parser. The
+// handler accepts source location information from the parser and
+// uses it to produce a vector of google_breakpad::Module::Line
+// objects, referring to google_breakpad::Module::File objects added
+// to a particular google_breakpad::Module.
+//
+// GNU toolchain omitted sections support:
+// ======================================
+//
+// Given the right options, the GNU toolchain will omit unreferenced
+// functions from the final executable. Unfortunately, when it does so, it
+// does not remove the associated portions of the DWARF line number
+// program; instead, it gives the DW_LNE_set_address instructions referring
+// to the now-deleted code addresses of zero. Given this input, the DWARF
+// line parser will call AddLine with a series of lines starting at address
+// zero. For example, here is the output from 'readelf -wl' for a program
+// with four functions, the first three of which have been omitted:
+//
+//   Line Number Statements:
+//    Extended opcode 2: set Address to 0x0
+//    Advance Line by 14 to 15
+//    Copy
+//    Special opcode 48: advance Address by 3 to 0x3 and Line by 1 to 16
+//    Special opcode 119: advance Address by 8 to 0xb and Line by 2 to 18
+//    Advance PC by 2 to 0xd
+//    Extended opcode 1: End of Sequence
+// 
+//    Extended opcode 2: set Address to 0x0
+//    Advance Line by 14 to 15
+//    Copy
+//    Special opcode 48: advance Address by 3 to 0x3 and Line by 1 to 16
+//    Special opcode 119: advance Address by 8 to 0xb and Line by 2 to 18
+//    Advance PC by 2 to 0xd
+//    Extended opcode 1: End of Sequence
+// 
+//    Extended opcode 2: set Address to 0x0
+//    Advance Line by 19 to 20
+//    Copy
+//    Special opcode 48: advance Address by 3 to 0x3 and Line by 1 to 21
+//    Special opcode 76: advance Address by 5 to 0x8 and Line by 1 to 22
+//    Advance PC by 2 to 0xa
+//    Extended opcode 1: End of Sequence
+// 
+//    Extended opcode 2: set Address to 0x80483a4
+//    Advance Line by 23 to 24
+//    Copy
+//    Special opcode 202: advance Address by 14 to 0x80483b2 and Line by 1 to 25
+//    Special opcode 76: advance Address by 5 to 0x80483b7 and Line by 1 to 26
+//    Advance PC by 6 to 0x80483bd
+//    Extended opcode 1: End of Sequence
+//
+// Instead of collecting runs of lines describing code that is not there,
+// we try to recognize and drop them. Since the linker doesn't explicitly
+// distinguish references to dropped sections from genuine references to
+// code at address zero, we must use a heuristic. We have chosen:
+//
+// - If a line starts at address zero, omit it. (On the platforms
+//   breakpad targets, it is extremely unlikely that there will be code
+//   at address zero.)
+//
+// - If a line starts immediately after an omitted line, omit it too.
+class DwarfLineToModule: public dwarf2reader::LineInfoHandler {
+ public:
+  // As the DWARF line info parser passes us line records, add source
+  // files to MODULE, and add all lines to the end of LINES. LINES
+  // need not be empty. If the parser hands us a zero-length line, we
+  // omit it. If the parser hands us a line that extends beyond the
+  // end of the address space, we clip it. It's up to our client to
+  // sort out which lines belong to which functions; we don't add them
+  // to any particular function in MODULE ourselves.
+  DwarfLineToModule(Module *module, vector<Module::Line> *lines)
+      : module_(module),
+        lines_(lines),
+        highest_file_number_(-1),
+        omitted_line_end_(0),
+        warned_bad_file_number_(false),
+        warned_bad_directory_number_(false) { }
+  
+  ~DwarfLineToModule() { }
+
+  void DefineDir(const string &name, uint32 dir_num);
+  void DefineFile(const string &name, int32 file_num,
+                  uint32 dir_num, uint64 mod_time,
+                  uint64 length);
+  void AddLine(uint64 address, uint64 length,
+               uint32 file_num, uint32 line_num, uint32 column_num);
+
+ private:
+
+  typedef std::map<uint32, string> DirectoryTable;
+  typedef std::map<uint32, Module::File *> FileTable;
+
+  // The module we're contributing debugging info to. Owned by our
+  // client.
+  Module *module_;
+
+  // The vector of lines we're accumulating. Owned by our client.
+  //
+  // In a Module, as in a breakpad symbol file, lines belong to
+  // specific functions, but DWARF simply assigns lines to addresses;
+  // one must infer the line/function relationship using the
+  // functions' beginning and ending addresses. So we can't add these
+  // to the appropriate function from module_ until we've read the
+  // function info as well. Instead, we accumulate lines here, and let
+  // whoever constructed this sort it all out.
+  vector<Module::Line> *lines_;
+
+  // A table mapping directory numbers to paths.
+  DirectoryTable directories_;
+
+  // A table mapping file numbers to Module::File pointers.
+  FileTable files_;
+
+  // The highest file number we've seen so far, or -1 if we've seen
+  // none.  Used for dynamically defined file numbers.
+  int32 highest_file_number_;
+  
+  // This is the ending address of the last line we omitted, or zero if we
+  // didn't omit the previous line. It is zero before we have received any
+  // AddLine calls.
+  uint64 omitted_line_end_;
+
+  // True if we've warned about:
+  bool warned_bad_file_number_; // bad file numbers
+  bool warned_bad_directory_number_; // bad directory numbers
+};
+
+} // namespace google_breakpad
+
+#endif // COMMON_LINUX_DWARF_LINE_TO_MODULE_H
diff --git a/3rdParty/Breakpad/src/common/language.cc b/3rdParty/Breakpad/src/common/language.cc
new file mode 100644
index 0000000..c2fd81f
--- /dev/null
+++ b/3rdParty/Breakpad/src/common/language.cc
@@ -0,0 +1,83 @@
+// 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>
+
+// language.cc: Subclasses and singletons for google_breakpad::Language.
+// See language.h for details.
+
+#include "common/language.h"
+
+namespace google_breakpad {
+
+// C++ language-specific operations.
+class CPPLanguage: public Language {
+ public:
+  CPPLanguage() {}
+  string MakeQualifiedName(const string &parent_name,
+                           const string &name) const {
+    if (parent_name.empty())
+      return name;
+    else
+      return parent_name + "::" + name;
+  }
+};
+
+CPPLanguage CPPLanguageSingleton;
+
+// Java language-specific operations.
+class JavaLanguage: public Language {
+ public:
+  string MakeQualifiedName(const string &parent_name,
+                           const string &name) const {
+    if (parent_name.empty())
+      return name;
+    else
+      return parent_name + "." + name;
+  }
+};
+
+JavaLanguage JavaLanguageSingleton;
+
+// Assembler language-specific operations.
+class AssemblerLanguage: public Language {
+  bool HasFunctions() const { return false; }
+  string MakeQualifiedName(const string &parent_name,
+                           const string &name) const {
+    return name;
+  }
+};
+
+AssemblerLanguage AssemblerLanguageSingleton;
+
+const Language * const Language::CPlusPlus = &CPPLanguageSingleton;
+const Language * const Language::Java = &JavaLanguageSingleton;
+const Language * const Language::Assembler = &AssemblerLanguageSingleton;
+
+} // namespace google_breakpad
diff --git a/3rdParty/Breakpad/src/common/language.h b/3rdParty/Breakpad/src/common/language.h
new file mode 100644
index 0000000..bbe3033
--- /dev/null
+++ b/3rdParty/Breakpad/src/common/language.h
@@ -0,0 +1,88 @@
+// -*- mode: c++ -*-
+
+// 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>
+
+// language.h: Define google_breakpad::Language. Instances of
+// subclasses of this class provide language-appropriate operations
+// for the Breakpad symbol dumper.
+
+#ifndef COMMON_LINUX_LANGUAGE_H__
+#define COMMON_LINUX_LANGUAGE_H__
+
+#include <string>
+
+#include "common/using_std_string.h"
+
+namespace google_breakpad {
+
+// An abstract base class for language-specific operations. We choose
+// an instance of a subclass of this when we find the CU's language.
+// This class's definitions are appropriate for CUs with no specified
+// language.
+class Language {
+ public:
+  // A base class destructor should be either public and virtual,
+  // or protected and nonvirtual.
+  virtual ~Language() {}
+
+  // Return true if this language has functions to which we can assign
+  // line numbers. (Debugging info for assembly language, for example,
+  // can have source location information, but does not have functions
+  // recorded using DW_TAG_subprogram DIEs.)
+  virtual bool HasFunctions() const { return true; }
+
+  // Construct a fully-qualified, language-appropriate form of NAME,
+  // given that PARENT_NAME is the name of the construct enclosing
+  // NAME. If PARENT_NAME is the empty string, then NAME is a
+  // top-level name.
+  //
+  // This API sort of assumes that a fully-qualified name is always
+  // some simple textual composition of the unqualified name and its
+  // parent's name, and that we don't need to know anything else about
+  // the parent or the child (say, their DIEs' tags) to do the job.
+  // This is true for the languages we support at the moment, and
+  // keeps things concrete. Perhaps a more refined operation would
+  // take into account the parent and child DIE types, allow languages
+  // to use their own data type for complex parent names, etc. But if
+  // C++ doesn't need all that, who would?
+  virtual string MakeQualifiedName (const string &parent_name,
+                                    const string &name) const = 0;
+
+  // Instances for specific languages.
+  static const Language * const CPlusPlus,
+                        * const Java,
+                        * const Assembler;
+};
+
+} // namespace google_breakpad
+
+#endif  // COMMON_LINUX_LANGUAGE_H__
diff --git a/3rdParty/Breakpad/src/common/linux/linux_libc_support.h b/3rdParty/Breakpad/src/common/linux/linux_libc_support.h
new file mode 100644
index 0000000..b2f47af
--- /dev/null
+++ b/3rdParty/Breakpad/src/common/linux/linux_libc_support.h
@@ -0,0 +1,95 @@
+// 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.
+
+// This header provides replacements for libc functions that we need. We if
+// call the libc functions directly we risk crashing in the dynamic linker as
+// it tries to resolve uncached PLT entries.
+
+#ifndef CLIENT_LINUX_LINUX_LIBC_SUPPORT_H_
+#define CLIENT_LINUX_LINUX_LIBC_SUPPORT_H_
+
+#include <stdint.h>
+#include <limits.h>
+#include <sys/types.h>
+
+extern "C" {
+
+extern size_t my_strlen(const char* s);
+
+extern int my_strcmp(const char* a, const char* b);
+
+extern int my_strncmp(const char* a, const char* b, size_t len);
+
+// Parse a non-negative integer.
+//   result: (output) the resulting non-negative integer
+//   s: a NUL terminated string
+// Return true iff successful.
+extern bool my_strtoui(int* result, const char* s);
+
+// Return the length of the given, non-negative integer when expressed in base
+// 10.
+extern unsigned my_int_len(intmax_t i);
+
+// Convert a non-negative integer to a string
+//   output: (output) the resulting string is written here. This buffer must be
+//     large enough to hold the resulting string. Call |my_int_len| to get the
+//     required length.
+//   i: the non-negative integer to serialise.
+//   i_len: the length of the integer in base 10 (see |my_int_len|).
+extern void my_itos(char* output, intmax_t i, unsigned i_len);
+
+extern const char* my_strchr(const char* haystack, char needle);
+
+extern const char* my_strrchr(const char* haystack, char needle);
+
+// Read a hex value
+//   result: (output) the resulting value
+//   s: a string
+// Returns a pointer to the first invalid charactor.
+extern const char* my_read_hex_ptr(uintptr_t* result, const char* s);
+
+extern const char* my_read_decimal_ptr(uintptr_t* result, const char* s);
+
+extern void my_memset(void* ip, char c, size_t len);
+
+// The following are considered safe to use in a compromised environment.
+// Besides, this gives the compiler an opportunity to optimize their calls.
+#define my_memcpy  memcpy
+#define my_memmove memmove
+#define my_memcmp  memcmp
+
+extern size_t my_strlcpy(char* s1, const char* s2, size_t len);
+
+extern size_t my_strlcat(char* s1, const char* s2, size_t len);
+
+extern int my_isspace(int ch);
+
+}  // extern "C"
+
+#endif  // CLIENT_LINUX_LINUX_LIBC_SUPPORT_H_
diff --git a/3rdParty/Breakpad/src/common/mac/MachIPC.h b/3rdParty/Breakpad/src/common/mac/MachIPC.h
new file mode 100644
index 0000000..52bed59
--- /dev/null
+++ b/3rdParty/Breakpad/src/common/mac/MachIPC.h
@@ -0,0 +1,301 @@
+// 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.
+//
+//  MachIPC.h
+//
+//  Some helpful wrappers for using Mach IPC calls
+
+#ifndef MACH_IPC_H__
+#define MACH_IPC_H__
+
+#import <mach/mach.h>
+#import <mach/message.h>
+#import <servers/bootstrap.h>
+#import <sys/types.h>
+
+#import <CoreServices/CoreServices.h>
+
+//==============================================================================
+// DISCUSSION:
+//
+// The three main classes of interest are
+//
+//  MachMessage:    a wrapper for a mach message of the following form
+//   mach_msg_header_t
+//   mach_msg_body_t
+//   optional descriptors
+//   optional extra message data
+//
+//  MachReceiveMessage and MachSendMessage subclass MachMessage
+//    and are used instead of MachMessage which is an abstract base class
+//
+//  ReceivePort:
+//    Represents a mach port for which we have receive rights
+//
+//  MachPortSender:
+//    Represents a mach port for which we have send rights
+//
+// Here's an example to receive a message on a server port:
+//
+//        // This creates our named server port
+//        ReceivePort receivePort("com.Google.MyService");
+//
+//        MachReceiveMessage message;
+//        kern_return_t result = receivePort.WaitForMessage(&message, 0);
+//
+//        if (result == KERN_SUCCESS && message.GetMessageID() == 57) {
+//          mach_port_t task = message.GetTranslatedPort(0);
+//          mach_port_t thread = message.GetTranslatedPort(1);
+//
+//          char *messageString = message.GetData();
+//
+//          printf("message string = %s\n", messageString);
+//        }
+//
+// Here is an example of using these classes to send a message to this port:
+//
+//    // send to already named port
+//    MachPortSender sender("com.Google.MyService");
+//    MachSendMessage message(57);      // our message ID is 57
+//
+//    // add some ports to be translated for us
+//    message.AddDescriptor(mach_task_self());     // our task
+//    message.AddDescriptor(mach_thread_self());   // this thread
+//
+//    char messageString[] = "Hello server!\n";
+//    message.SetData(messageString, strlen(messageString)+1);
+//
+//    kern_return_t result = sender.SendMessage(message, 1000); // timeout 1000ms
+//
+
+namespace google_breakpad {
+#define PRINT_MACH_RESULT(result_, message_) \
+  printf(message_" %s (%d)\n", mach_error_string(result_), result_ );
+
+//==============================================================================
+// A wrapper class for mach_msg_port_descriptor_t (with same memory layout)
+// with convenient constructors and accessors
+class MachMsgPortDescriptor : public mach_msg_port_descriptor_t {
+ public:
+  // General-purpose constructor
+  MachMsgPortDescriptor(mach_port_t in_name,
+                        mach_msg_type_name_t in_disposition) {
+    name = in_name;
+    pad1 = 0;
+    pad2 = 0;
+    disposition = in_disposition;
+    type = MACH_MSG_PORT_DESCRIPTOR;
+  }
+
+  // For passing send rights to a port
+  MachMsgPortDescriptor(mach_port_t in_name) {
+    name = in_name;
+    pad1 = 0;
+    pad2 = 0;
+    disposition = MACH_MSG_TYPE_COPY_SEND;
+    type = MACH_MSG_PORT_DESCRIPTOR;
+  }
+
+  // Copy constructor
+  MachMsgPortDescriptor(const MachMsgPortDescriptor& desc) {
+    name = desc.name;
+    pad1 = desc.pad1;
+    pad2 = desc.pad2;
+    disposition = desc.disposition;
+    type = desc.type;
+  }
+
+  mach_port_t GetMachPort() const {
+    return name;
+  }
+
+  mach_msg_type_name_t GetDisposition() const {
+    return disposition;
+  }
+
+  // For convenience
+  operator mach_port_t() const {
+    return GetMachPort();
+  }
+};
+
+//==============================================================================
+// MachMessage: a wrapper for a mach message
+//  (mach_msg_header_t, mach_msg_body_t, extra data)
+//
+//  This considerably simplifies the construction of a message for sending
+//  and the getting at relevant data and descriptors for the receiver.
+//
+//  Currently the combined size of the descriptors plus data must be
+//  less than 1024.  But as a benefit no memory allocation is necessary.
+//
+// TODO: could consider adding malloc() support for very large messages
+//
+//  A MachMessage object is used by ReceivePort::WaitForMessage
+//  and MachPortSender::SendMessage
+//
+class MachMessage {
+ public:
+
+  // The receiver of the message can retrieve the raw data this way
+  u_int8_t *GetData() {
+    return GetDataLength() > 0 ? GetDataPacket()->data : NULL;
+  }
+
+  u_int32_t GetDataLength() {
+    return EndianU32_LtoN(GetDataPacket()->data_length);
+  }
+
+  // The message ID may be used as a code identifying the type of message
+  void SetMessageID(int32_t message_id) {
+    GetDataPacket()->id = EndianU32_NtoL(message_id);
+  }
+
+  int32_t GetMessageID() { return EndianU32_LtoN(GetDataPacket()->id); }
+
+  // Adds a descriptor (typically a mach port) to be translated
+  // returns true if successful, otherwise not enough space
+  bool AddDescriptor(const MachMsgPortDescriptor &desc);
+
+  int GetDescriptorCount() const { return body.msgh_descriptor_count; }
+  MachMsgPortDescriptor *GetDescriptor(int n);
+
+  // Convenience method which gets the mach port described by the descriptor
+  mach_port_t GetTranslatedPort(int n);
+
+  // A simple message is one with no descriptors
+  bool IsSimpleMessage() const { return GetDescriptorCount() == 0; }
+
+  // Sets raw data for the message (returns false if not enough space)
+  bool SetData(void *data, int32_t data_length);
+
+ protected:
+  // Consider this an abstract base class - must create an actual instance
+  // of MachReceiveMessage or MachSendMessage
+
+  MachMessage() {
+    memset(this, 0, sizeof(MachMessage));
+  }
+
+  friend class ReceivePort;
+  friend class MachPortSender;
+
+  // Represents raw data in our message
+  struct MessageDataPacket {
+    int32_t      id;          // little-endian
+    int32_t      data_length; // little-endian
+    u_int8_t     data[1];     // actual size limited by sizeof(MachMessage)
+  };
+
+  MessageDataPacket* GetDataPacket();
+
+  void SetDescriptorCount(int n);
+  void SetDescriptor(int n, const MachMsgPortDescriptor &desc);
+
+  // Returns total message size setting msgh_size in the header to this value
+  mach_msg_size_t CalculateSize();
+
+  mach_msg_header_t  head;
+  mach_msg_body_t    body;
+  u_int8_t           padding[1024]; // descriptors and data may be embedded here
+};
+
+//==============================================================================
+// MachReceiveMessage and MachSendMessage are useful to separate the idea
+// of a mach message being sent and being received, and adds increased type
+// safety:
+//  ReceivePort::WaitForMessage() only accepts a MachReceiveMessage
+//  MachPortSender::SendMessage() only accepts a MachSendMessage
+
+//==============================================================================
+class MachReceiveMessage : public MachMessage {
+ public:
+  MachReceiveMessage() : MachMessage() {};
+};
+
+//==============================================================================
+class MachSendMessage : public MachMessage {
+ public:
+  MachSendMessage(int32_t message_id);
+};
+
+//==============================================================================
+// Represents a mach port for which we have receive rights
+class ReceivePort {
+ public:
+  // Creates a new mach port for receiving messages and registers a name for it
+  explicit ReceivePort(const char *receive_port_name);
+
+  // Given an already existing mach port, use it.  We take ownership of the
+  // port and deallocate it in our destructor.
+  explicit ReceivePort(mach_port_t receive_port);
+
+  // Create a new mach port for receiving messages
+  ReceivePort();
+
+  ~ReceivePort();
+
+  // Waits on the mach port until message received or timeout
+  kern_return_t WaitForMessage(MachReceiveMessage *out_message,
+                               mach_msg_timeout_t timeout);
+
+  // The underlying mach port that we wrap
+  mach_port_t  GetPort() const { return port_; }
+
+ private:
+  ReceivePort(const ReceivePort&);  // disable copy c-tor
+
+  mach_port_t   port_;
+  kern_return_t init_result_;
+};
+
+//==============================================================================
+// Represents a mach port for which we have send rights
+class MachPortSender {
+ public:
+  // get a port with send rights corresponding to a named registered service
+  explicit MachPortSender(const char *receive_port_name);
+
+
+  // Given an already existing mach port, use it.
+  explicit MachPortSender(mach_port_t send_port);
+
+  kern_return_t SendMessage(MachSendMessage &message,
+                            mach_msg_timeout_t timeout);
+
+ private:
+  MachPortSender(const MachPortSender&);  // disable copy c-tor
+
+  mach_port_t   send_port_;
+  kern_return_t init_result_;
+};
+
+}  // namespace google_breakpad
+
+#endif // MACH_IPC_H__
diff --git a/3rdParty/Breakpad/src/common/mac/MachIPC.mm b/3rdParty/Breakpad/src/common/mac/MachIPC.mm
new file mode 100644
index 0000000..dc9773f
--- /dev/null
+++ b/3rdParty/Breakpad/src/common/mac/MachIPC.mm
@@ -0,0 +1,306 @@
+// 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.
+//
+//  MachIPC.mm
+//  Wrapper for mach IPC calls
+
+#import <stdio.h>
+#import "MachIPC.h"
+#include "common/mac/bootstrap_compat.h"
+
+namespace google_breakpad {
+//==============================================================================
+MachSendMessage::MachSendMessage(int32_t message_id) : MachMessage() {
+  head.msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND, 0);
+
+  // head.msgh_remote_port = ...; // filled out in MachPortSender::SendMessage()
+  head.msgh_local_port = MACH_PORT_NULL;
+  head.msgh_reserved = 0;
+  head.msgh_id = 0;
+
+  SetDescriptorCount(0);  // start out with no descriptors
+
+  SetMessageID(message_id);
+  SetData(NULL, 0);       // client may add data later
+}
+
+//==============================================================================
+// returns true if successful
+bool MachMessage::SetData(void *data,
+                          int32_t data_length) {
+  // first check to make sure we have enough space
+  size_t size = CalculateSize();
+  size_t new_size = size + data_length;
+  
+  if (new_size > sizeof(MachMessage)) {
+    return false;  // not enough space
+  }
+
+  GetDataPacket()->data_length = EndianU32_NtoL(data_length);
+  if (data) memcpy(GetDataPacket()->data, data, data_length);
+
+  CalculateSize();
+
+  return true;
+}
+
+//==============================================================================
+// calculates and returns the total size of the message
+// Currently, the entire message MUST fit inside of the MachMessage
+//    messsage size <= sizeof(MachMessage)
+mach_msg_size_t MachMessage::CalculateSize() {
+  size_t size = sizeof(mach_msg_header_t) + sizeof(mach_msg_body_t);
+  
+  // add space for MessageDataPacket
+  int32_t alignedDataLength = (GetDataLength() + 3) & ~0x3;
+  size += 2*sizeof(int32_t) + alignedDataLength;
+  
+  // add space for descriptors
+  size += GetDescriptorCount() * sizeof(MachMsgPortDescriptor);
+  
+  head.msgh_size = static_cast<mach_msg_size_t>(size);
+  
+  return head.msgh_size;
+}
+
+//==============================================================================
+MachMessage::MessageDataPacket *MachMessage::GetDataPacket() {
+  size_t desc_size = sizeof(MachMsgPortDescriptor)*GetDescriptorCount();
+  MessageDataPacket *packet =
+    reinterpret_cast<MessageDataPacket*>(padding + desc_size);
+
+  return packet;
+}
+
+//==============================================================================
+void MachMessage::SetDescriptor(int n,
+                                const MachMsgPortDescriptor &desc) {
+  MachMsgPortDescriptor *desc_array =
+    reinterpret_cast<MachMsgPortDescriptor*>(padding);
+  desc_array[n] = desc;
+}
+
+//==============================================================================
+// returns true if successful otherwise there was not enough space
+bool MachMessage::AddDescriptor(const MachMsgPortDescriptor &desc) {
+  // first check to make sure we have enough space
+  int size = CalculateSize();
+  size_t new_size = size + sizeof(MachMsgPortDescriptor);
+  
+  if (new_size > sizeof(MachMessage)) {
+    return false;  // not enough space
+  }
+
+  // unfortunately, we need to move the data to allow space for the
+  // new descriptor
+  u_int8_t *p = reinterpret_cast<u_int8_t*>(GetDataPacket());
+  bcopy(p, p+sizeof(MachMsgPortDescriptor), GetDataLength()+2*sizeof(int32_t));
+  
+  SetDescriptor(GetDescriptorCount(), desc);
+  SetDescriptorCount(GetDescriptorCount() + 1);
+
+  CalculateSize();
+  
+  return true;
+}
+
+//==============================================================================
+void MachMessage::SetDescriptorCount(int n) {
+  body.msgh_descriptor_count = n;
+
+  if (n > 0) {
+    head.msgh_bits |= MACH_MSGH_BITS_COMPLEX;
+  } else {
+    head.msgh_bits &= ~MACH_MSGH_BITS_COMPLEX;
+  }
+}
+
+//==============================================================================
+MachMsgPortDescriptor *MachMessage::GetDescriptor(int n) {
+  if (n < GetDescriptorCount()) {
+    MachMsgPortDescriptor *desc =
+      reinterpret_cast<MachMsgPortDescriptor*>(padding);
+    return desc + n;
+  }
+  
+  return nil;
+}
+
+//==============================================================================
+mach_port_t MachMessage::GetTranslatedPort(int n) {
+  if (n < GetDescriptorCount()) {
+    return GetDescriptor(n)->GetMachPort();
+  }
+  return MACH_PORT_NULL;
+}
+
+#pragma mark -
+
+//==============================================================================
+// create a new mach port for receiving messages and register a name for it
+ReceivePort::ReceivePort(const char *receive_port_name) {
+  mach_port_t current_task = mach_task_self();
+
+  init_result_ = mach_port_allocate(current_task,
+                                    MACH_PORT_RIGHT_RECEIVE,
+                                    &port_);
+
+  if (init_result_ != KERN_SUCCESS)
+    return;
+    
+  init_result_ = mach_port_insert_right(current_task,
+                                        port_,
+                                        port_,
+                                        MACH_MSG_TYPE_MAKE_SEND);
+
+  if (init_result_ != KERN_SUCCESS)
+    return;
+
+  mach_port_t task_bootstrap_port = 0;
+  init_result_ = task_get_bootstrap_port(current_task, &task_bootstrap_port);
+
+  if (init_result_ != KERN_SUCCESS)
+    return;
+
+  init_result_ = breakpad::BootstrapRegister(
+      bootstrap_port,
+      const_cast<char*>(receive_port_name),
+      port_);
+}
+
+//==============================================================================
+// create a new mach port for receiving messages
+ReceivePort::ReceivePort() {
+  mach_port_t current_task = mach_task_self();
+
+  init_result_ = mach_port_allocate(current_task,
+                                    MACH_PORT_RIGHT_RECEIVE,
+                                    &port_);
+
+  if (init_result_ != KERN_SUCCESS)
+    return;
+
+  init_result_ =   mach_port_insert_right(current_task,
+                                          port_,
+                                          port_,
+                                          MACH_MSG_TYPE_MAKE_SEND);
+}
+
+//==============================================================================
+// Given an already existing mach port, use it.  We take ownership of the
+// port and deallocate it in our destructor.
+ReceivePort::ReceivePort(mach_port_t receive_port)
+  : port_(receive_port),
+    init_result_(KERN_SUCCESS) {
+}
+
+//==============================================================================
+ReceivePort::~ReceivePort() {
+  if (init_result_ == KERN_SUCCESS)
+    mach_port_deallocate(mach_task_self(), port_);
+}
+
+//==============================================================================
+kern_return_t ReceivePort::WaitForMessage(MachReceiveMessage *out_message,
+                                          mach_msg_timeout_t timeout) {
+  if (!out_message) {
+    return KERN_INVALID_ARGUMENT;
+  }
+
+  // return any error condition encountered in constructor
+  if (init_result_ != KERN_SUCCESS)
+    return init_result_;
+  
+  out_message->head.msgh_bits = 0;
+  out_message->head.msgh_local_port = port_;
+  out_message->head.msgh_remote_port = MACH_PORT_NULL;
+  out_message->head.msgh_reserved = 0;
+  out_message->head.msgh_id = 0;
+
+  mach_msg_option_t options = MACH_RCV_MSG;
+  if (timeout != MACH_MSG_TIMEOUT_NONE)
+    options |= MACH_RCV_TIMEOUT;
+  kern_return_t result = mach_msg(&out_message->head,
+                                  options,
+                                  0,
+                                  sizeof(MachMessage),
+                                  port_,
+                                  timeout,              // timeout in ms
+                                  MACH_PORT_NULL);
+
+  return result;
+}
+
+#pragma mark -
+
+//==============================================================================
+// get a port with send rights corresponding to a named registered service
+MachPortSender::MachPortSender(const char *receive_port_name) {
+  mach_port_t task_bootstrap_port = 0;
+  init_result_ = task_get_bootstrap_port(mach_task_self(), 
+                                         &task_bootstrap_port);
+  
+  if (init_result_ != KERN_SUCCESS)
+    return;
+
+  init_result_ = bootstrap_look_up(task_bootstrap_port,
+                    const_cast<char*>(receive_port_name),
+                    &send_port_);
+}
+
+//==============================================================================
+MachPortSender::MachPortSender(mach_port_t send_port) 
+  : send_port_(send_port),
+    init_result_(KERN_SUCCESS) {
+}
+
+//==============================================================================
+kern_return_t MachPortSender::SendMessage(MachSendMessage &message,
+                                          mach_msg_timeout_t timeout) {
+  if (message.head.msgh_size == 0) {
+    return KERN_INVALID_VALUE;    // just for safety -- never should occur
+  };
+  
+  if (init_result_ != KERN_SUCCESS)
+    return init_result_;
+  
+  message.head.msgh_remote_port = send_port_;
+
+  kern_return_t result = mach_msg(&message.head,
+                                  MACH_SEND_MSG | MACH_SEND_TIMEOUT,
+                                  message.head.msgh_size,
+                                  0,
+                                  MACH_PORT_NULL,
+                                  timeout,              // timeout in ms
+                                  MACH_PORT_NULL);
+
+  return result;
+}
+
+}  // namespace google_breakpad
diff --git a/3rdParty/Breakpad/src/common/mac/bootstrap_compat.cc b/3rdParty/Breakpad/src/common/mac/bootstrap_compat.cc
new file mode 100644
index 0000000..d875d95
--- /dev/null
+++ b/3rdParty/Breakpad/src/common/mac/bootstrap_compat.cc
@@ -0,0 +1,42 @@
+// 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.
+
+#include "common/mac/bootstrap_compat.h"
+
+namespace breakpad {
+
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+kern_return_t BootstrapRegister(mach_port_t bp,
+                                name_t service_name,
+                                mach_port_t sp) {
+  return bootstrap_register(bp, service_name, sp);
+}
+#pragma GCC diagnostic warning "-Wdeprecated-declarations"
+
+}  // namesapce breakpad
diff --git a/3rdParty/Breakpad/src/common/mac/bootstrap_compat.h b/3rdParty/Breakpad/src/common/mac/bootstrap_compat.h
new file mode 100644
index 0000000..8ca7357
--- /dev/null
+++ b/3rdParty/Breakpad/src/common/mac/bootstrap_compat.h
@@ -0,0 +1,54 @@
+// 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.
+
+#ifndef COMMON_MAC_BOOTSTRAP_COMPAT_H_
+#define COMMON_MAC_BOOTSTRAP_COMPAT_H_
+
+#include <servers/bootstrap.h>
+
+namespace breakpad {
+
+// Wrapper for bootstrap_register to avoid deprecation warnings.
+//
+// In 10.6, it's possible to call bootstrap_check_in as the one-stop-shop for
+// handling what bootstrap_register is used for. In 10.5, bootstrap_check_in
+// can't check in a service whose name has not yet been registered, despite
+// bootstrap_register being marked as deprecated in that OS release. Breakpad
+// needs to register new service names, and in 10.5, calling
+// bootstrap_register is the only way to achieve that. Attempts to call
+// bootstrap_check_in for a new service name on 10.5 will result in
+// BOOTSTRAP_UNKNOWN_SERVICE being returned rather than registration of the
+// new service name.
+kern_return_t BootstrapRegister(mach_port_t bp,
+                                name_t service_name,
+                                mach_port_t sp);
+
+}  // namespace breakpad
+
+#endif  // COMMON_MAC_BOOTSTRAP_COMPAT_H_
diff --git a/3rdParty/Breakpad/src/common/mac/byteswap.h b/3rdParty/Breakpad/src/common/mac/byteswap.h
new file mode 100644
index 0000000..a5d745b
--- /dev/null
+++ b/3rdParty/Breakpad/src/common/mac/byteswap.h
@@ -0,0 +1,48 @@
+// -*- mode: c++ -*-
+
+// 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 <jim@mozilla.com> <jimb@red-bean.com>
+
+// byteswap.h: Overloaded functions for conveniently byteswapping values.
+
+#ifndef COMMON_MAC_BYTESWAP_H_
+#define COMMON_MAC_BYTESWAP_H_
+
+#include <libkern/OSByteOrder.h>
+
+static inline uint16_t ByteSwap(uint16_t v) { return OSSwapInt16(v); }
+static inline uint32_t ByteSwap(uint32_t v) { return OSSwapInt32(v); }
+static inline uint64_t ByteSwap(uint64_t v) { return OSSwapInt64(v); }
+static inline int16_t  ByteSwap(int16_t  v) { return OSSwapInt16(v); }
+static inline int32_t  ByteSwap(int32_t  v) { return OSSwapInt32(v); }
+static inline int64_t  ByteSwap(int64_t  v) { return OSSwapInt64(v); }
+
+#endif  // COMMON_MAC_BYTESWAP_H_
diff --git a/3rdParty/Breakpad/src/common/mac/dump_syms.h b/3rdParty/Breakpad/src/common/mac/dump_syms.h
new file mode 100644
index 0000000..0e2f464
--- /dev/null
+++ b/3rdParty/Breakpad/src/common/mac/dump_syms.h
@@ -0,0 +1,172 @@
+// -*- 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.
+
+// Author: Jim Blandy <jimb@mozilla.com> <jimb@red-bean.com>
+
+// dump_syms.h: Declaration of google_breakpad::DumpSymbols, a class for
+// reading debugging information from Mach-O files and writing it out as a
+// Breakpad symbol file.
+
+#include <Foundation/Foundation.h>
+#include <mach-o/loader.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <ostream>
+#include <string>
+#include <vector>
+
+#include "common/byte_cursor.h"
+#include "common/mac/macho_reader.h"
+#include "common/module.h"
+
+namespace google_breakpad {
+
+class DumpSymbols {
+ public:
+  DumpSymbols()
+      : input_pathname_(),
+        object_filename_(),
+        contents_(),
+        selected_object_file_(),
+        selected_object_name_() { }
+  ~DumpSymbols() {
+    [input_pathname_ release];
+    [object_filename_ release];
+    [contents_ release];
+  }
+
+  // Prepare to read debugging information from |filename|. |filename| may be
+  // the name of a universal binary, a Mach-O file, or a dSYM bundle
+  // containing either of the above. On success, return true; if there is a
+  // problem reading |filename|, report it and return false.
+  //
+  // (This class uses NSString for filenames and related values,
+  // because the Mac Foundation framework seems to support
+  // filename-related operations more fully on NSString values.)
+  bool Read(NSString *filename);
+
+  // If this dumper's file includes an object file for |cpu_type| and
+  // |cpu_subtype|, then select that object file for dumping, and return
+  // true. Otherwise, return false, and leave this dumper's selected
+  // architecture unchanged.
+  //
+  // By default, if this dumper's file contains only one object file, then
+  // the dumper will dump those symbols; and if it contains more than one
+  // object file, then the dumper will dump the object file whose
+  // architecture matches that of this dumper program.
+  bool SetArchitecture(cpu_type_t cpu_type, cpu_subtype_t cpu_subtype);
+
+  // If this dumper's file includes an object file for |arch_name|, then select
+  // that object file for dumping, and return true. Otherwise, return false,
+  // and leave this dumper's selected architecture unchanged.
+  //
+  // By default, if this dumper's file contains only one object file, then
+  // the dumper will dump those symbols; and if it contains more than one
+  // object file, then the dumper will dump the object file whose
+  // architecture matches that of this dumper program.
+  bool SetArchitecture(const std::string &arch_name);
+
+  // Return a pointer to an array of 'struct fat_arch' structures,
+  // describing the object files contained in this dumper's file. Set
+  // *|count| to the number of elements in the array. The returned array is
+  // owned by this DumpSymbols instance.
+  //
+  // If there are no available architectures, this function
+  // may return NULL.
+  const struct fat_arch *AvailableArchitectures(size_t *count) {
+    *count = object_files_.size();
+    if (object_files_.size() > 0)
+      return &object_files_[0];
+    return NULL;
+  }
+
+  // Read the selected object file's debugging information, and write it out to
+  // |stream|. Write the CFI section if |cfi| is true. Return true on success;
+  // if an error occurs, report it and return false.
+  bool WriteSymbolFile(std::ostream &stream, bool cfi);
+
+ private:
+  // Used internally.
+  class DumperLineToModule;
+  class LoadCommandDumper;
+
+  // Return an identifier string for the file this DumpSymbols is dumping.
+  std::string Identifier();
+
+  // Read debugging information from |dwarf_sections|, which was taken from
+  // |macho_reader|, and add it to |module|. On success, return true;
+  // on failure, report the problem and return false.
+  bool ReadDwarf(google_breakpad::Module *module,
+                 const mach_o::Reader &macho_reader,
+                 const mach_o::SectionMap &dwarf_sections) const;
+
+  // Read DWARF CFI or .eh_frame data from |section|, belonging to
+  // |macho_reader|, and record it in |module|.  If |eh_frame| is true,
+  // then the data is .eh_frame-format data; otherwise, it is standard DWARF
+  // .debug_frame data. On success, return true; on failure, report
+  // the problem and return false.
+  bool ReadCFI(google_breakpad::Module *module,
+               const mach_o::Reader &macho_reader,
+               const mach_o::Section &section,
+               bool eh_frame) const;
+
+  // The name of the file or bundle whose symbols this will dump.
+  // This is the path given to Read, for use in error messages.
+  NSString *input_pathname_;
+
+  // The name of the file this DumpSymbols will actually read debugging
+  // information from. Normally, this is the same as input_pathname_, but if
+  // filename refers to a dSYM bundle, then this is the resource file
+  // within that bundle.
+  NSString *object_filename_;
+
+  // The complete contents of object_filename_, mapped into memory.
+  NSData *contents_;
+
+  // A vector of fat_arch structures describing the object files
+  // object_filename_ contains. If object_filename_ refers to a fat binary,
+  // this may have more than one element; if it refers to a Mach-O file, this
+  // has exactly one element.
+  vector<struct fat_arch> object_files_;
+
+  // The object file in object_files_ selected to dump, or NULL if
+  // SetArchitecture hasn't been called yet.
+  const struct fat_arch *selected_object_file_;
+
+  // A string that identifies the selected object file, for use in error
+  // messages.  This is usually object_filename_, but if that refers to a
+  // fat binary, it includes an indication of the particular architecture
+  // within that binary.
+  string selected_object_name_;
+};
+
+}  // namespace google_breakpad
diff --git a/3rdParty/Breakpad/src/common/mac/dump_syms.mm b/3rdParty/Breakpad/src/common/mac/dump_syms.mm
new file mode 100644
index 0000000..9783514
--- /dev/null
+++ b/3rdParty/Breakpad/src/common/mac/dump_syms.mm
@@ -0,0 +1,496 @@
+// -*- 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.
+
+// Author: Jim Blandy <jimb@mozilla.com> <jimb@red-bean.com>
+
+// dump_syms.mm: Create a symbol file for use with minidumps
+
+#include "common/mac/dump_syms.h"
+
+#include <Foundation/Foundation.h>
+#include <mach-o/arch.h>
+#include <mach-o/fat.h>
+#include <stdio.h>
+
+#include <ostream>
+#include <string>
+#include <vector>
+
+#include "common/dwarf/bytereader-inl.h"
+#include "common/dwarf/dwarf2reader.h"
+#include "common/dwarf_cfi_to_module.h"
+#include "common/dwarf_cu_to_module.h"
+#include "common/dwarf_line_to_module.h"
+#include "common/mac/file_id.h"
+#include "common/mac/macho_reader.h"
+#include "common/module.h"
+#include "common/stabs_reader.h"
+#include "common/stabs_to_module.h"
+
+#ifndef CPU_TYPE_ARM
+#define CPU_TYPE_ARM (static_cast<cpu_type_t>(12))
+#endif //  CPU_TYPE_ARM
+
+using dwarf2reader::ByteReader;
+using google_breakpad::DwarfCUToModule;
+using google_breakpad::DwarfLineToModule;
+using google_breakpad::FileID;
+using google_breakpad::mach_o::FatReader;
+using google_breakpad::mach_o::Section;
+using google_breakpad::mach_o::Segment;
+using google_breakpad::Module;
+using google_breakpad::StabsReader;
+using google_breakpad::StabsToModule;
+using std::make_pair;
+using std::pair;
+using std::string;
+using std::vector;
+
+namespace google_breakpad {
+
+bool DumpSymbols::Read(NSString *filename) {
+  if (![[NSFileManager defaultManager] fileExistsAtPath:filename]) {
+    fprintf(stderr, "Object file does not exist: %s\n",
+            [filename fileSystemRepresentation]);
+    return false;
+  }
+
+  input_pathname_ = [filename retain];
+
+  // Does this filename refer to a dSYM bundle?
+  NSBundle *bundle = [NSBundle bundleWithPath:input_pathname_];
+
+  if (bundle) {
+    // Filenames referring to bundles usually have names of the form
+    // "<basename>.dSYM"; however, if the user has specified a wrapper
+    // suffix (the WRAPPER_SUFFIX and WRAPPER_EXTENSION build settings),
+    // then the name may have the form "<basename>.<extension>.dSYM". In
+    // either case, the resource name for the file containing the DWARF
+    // info within the bundle is <basename>.
+    //
+    // Since there's no way to tell how much to strip off, remove one
+    // extension at a time, and use the first one that
+    // pathForResource:ofType:inDirectory likes.
+    NSString *base_name = [input_pathname_ lastPathComponent];
+    NSString *dwarf_resource;
+
+    do {
+      NSString *new_base_name = [base_name stringByDeletingPathExtension];
+
+      // If stringByDeletingPathExtension returned the name unchanged, then
+      // there's nothing more for us to strip off --- lose.
+      if ([new_base_name isEqualToString:base_name]) {
+        fprintf(stderr, "Unable to find DWARF-bearing file in bundle: %s\n",
+                [input_pathname_ fileSystemRepresentation]);
+        return false;
+      }
+
+      // Take the shortened result as our new base_name.
+      base_name = new_base_name;
+
+      // Try to find a DWARF resource in the bundle under the new base_name.
+      dwarf_resource = [bundle pathForResource:base_name
+                        ofType:nil inDirectory:@"DWARF"];
+    } while (!dwarf_resource);
+
+    object_filename_ = [dwarf_resource retain];
+  } else {
+    object_filename_ = [input_pathname_ retain];
+  }
+
+  // Read the file's contents into memory.
+  //
+  // The documentation for dataWithContentsOfMappedFile says:
+  //
+  //     Because of file mapping restrictions, this method should only be
+  //     used if the file is guaranteed to exist for the duration of the
+  //     data object’s existence. It is generally safer to use the
+  //     dataWithContentsOfFile: method.
+  //
+  // I gather this means that OS X doesn't have (or at least, that method
+  // doesn't use) a form of mapping like Linux's MAP_PRIVATE, where the
+  // process appears to get its own copy of the data, and changes to the
+  // file don't affect memory and vice versa).
+  NSError *error;
+  contents_ = [NSData dataWithContentsOfFile:object_filename_
+                                     options:0
+                                       error:&error];
+  if (!contents_) {
+    fprintf(stderr, "Error reading object file: %s: %s\n",
+            [object_filename_ fileSystemRepresentation],
+            [[error localizedDescription] UTF8String]);
+    return false;
+  }
+  [contents_ retain];
+
+  // Get the list of object files present in the file.
+  FatReader::Reporter fat_reporter([object_filename_
+                                    fileSystemRepresentation]);
+  FatReader fat_reader(&fat_reporter);
+  if (!fat_reader.Read(reinterpret_cast<const uint8_t *>([contents_ bytes]),
+                       [contents_ length])) {
+    return false;
+  }
+
+  // Get our own copy of fat_reader's object file list.
+  size_t object_files_count;
+  const struct fat_arch *object_files =
+    fat_reader.object_files(&object_files_count);
+  if (object_files_count == 0) {
+    fprintf(stderr, "Fat binary file contains *no* architectures: %s\n",
+            [object_filename_ fileSystemRepresentation]);
+    return false;
+  }
+  object_files_.resize(object_files_count);
+  memcpy(&object_files_[0], object_files,
+         sizeof(struct fat_arch) * object_files_count);
+
+  return true;
+}
+
+bool DumpSymbols::SetArchitecture(cpu_type_t cpu_type,
+                                  cpu_subtype_t cpu_subtype) {
+  // Find the best match for the architecture the user requested.
+  const struct fat_arch *best_match
+    = NXFindBestFatArch(cpu_type, cpu_subtype, &object_files_[0],
+                        static_cast<uint32_t>(object_files_.size()));
+  if (!best_match) return false;
+
+  // Record the selected object file.
+  selected_object_file_ = best_match;
+  return true;
+}
+
+bool DumpSymbols::SetArchitecture(const std::string &arch_name) {
+  bool arch_set = false;
+  const NXArchInfo *arch_info = NXGetArchInfoFromName(arch_name.c_str());
+  if (arch_info) {
+    arch_set = SetArchitecture(arch_info->cputype, arch_info->cpusubtype);
+  }
+  return arch_set;
+}
+
+string DumpSymbols::Identifier() {
+  FileID file_id([object_filename_ fileSystemRepresentation]);
+  unsigned char identifier_bytes[16];
+  cpu_type_t cpu_type = selected_object_file_->cputype;
+  if (!file_id.MachoIdentifier(cpu_type, identifier_bytes)) {
+    fprintf(stderr, "Unable to calculate UUID of mach-o binary %s!\n",
+            [object_filename_ fileSystemRepresentation]);
+    return "";
+  }
+
+  char identifier_string[40];
+  FileID::ConvertIdentifierToString(identifier_bytes, identifier_string,
+                                    sizeof(identifier_string));
+
+  string compacted(identifier_string);
+  for(size_t i = compacted.find('-'); i != string::npos;
+      i = compacted.find('-', i))
+    compacted.erase(i, 1);
+
+  return compacted;
+}
+
+// A line-to-module loader that accepts line number info parsed by
+// dwarf2reader::LineInfo and populates a Module and a line vector
+// with the results.
+class DumpSymbols::DumperLineToModule:
+      public DwarfCUToModule::LineToModuleFunctor {
+ public:
+  // Create a line-to-module converter using BYTE_READER.
+  DumperLineToModule(dwarf2reader::ByteReader *byte_reader)
+      : byte_reader_(byte_reader) { }
+  void operator()(const char *program, uint64 length,
+                  Module *module, vector<Module::Line> *lines) {
+    DwarfLineToModule handler(module, lines);
+    dwarf2reader::LineInfo parser(program, length, byte_reader_, &handler);
+    parser.Start();
+  }
+ private:
+  dwarf2reader::ByteReader *byte_reader_;  // WEAK
+};
+
+bool DumpSymbols::ReadDwarf(google_breakpad::Module *module,
+                            const mach_o::Reader &macho_reader,
+                            const mach_o::SectionMap &dwarf_sections) const {
+  // Build a byte reader of the appropriate endianness.
+  ByteReader byte_reader(macho_reader.big_endian()
+                         ? dwarf2reader::ENDIANNESS_BIG
+                         : dwarf2reader::ENDIANNESS_LITTLE);
+
+  // Construct a context for this file.
+  DwarfCUToModule::FileContext file_context(selected_object_name_,
+                                            module);
+
+  // Build a dwarf2reader::SectionMap from our mach_o::SectionMap.
+  for (mach_o::SectionMap::const_iterator it = dwarf_sections.begin();
+       it != dwarf_sections.end(); it++) {
+    file_context.section_map[it->first] =
+      make_pair(reinterpret_cast<const char *>(it->second.contents.start),
+                it->second.contents.Size());
+  }
+
+  // Find the __debug_info section.
+  std::pair<const char *, uint64> debug_info_section
+      = file_context.section_map["__debug_info"];
+  // There had better be a __debug_info section!
+  if (!debug_info_section.first) {
+    fprintf(stderr, "%s: __DWARF segment of file has no __debug_info section\n",
+            selected_object_name_.c_str());
+    return false;
+  }
+
+  // Build a line-to-module loader for the root handler to use.
+  DumperLineToModule line_to_module(&byte_reader);
+
+  // Walk the __debug_info section, one compilation unit at a time.
+  uint64 debug_info_length = debug_info_section.second;
+  for (uint64 offset = 0; offset < debug_info_length;) {
+    // Make a handler for the root DIE that populates MODULE with the
+    // debug info.
+    DwarfCUToModule::WarningReporter reporter(selected_object_name_,
+                                              offset);
+    DwarfCUToModule root_handler(&file_context, &line_to_module, &reporter);
+    // Make a Dwarf2Handler that drives our DIEHandler.
+    dwarf2reader::DIEDispatcher die_dispatcher(&root_handler);
+    // Make a DWARF parser for the compilation unit at OFFSET.
+    dwarf2reader::CompilationUnit dwarf_reader(file_context.section_map,
+                                               offset,
+                                               &byte_reader,
+                                               &die_dispatcher);
+    // Process the entire compilation unit; get the offset of the next.
+    offset += dwarf_reader.Start();
+  }
+
+  return true;
+}
+
+bool DumpSymbols::ReadCFI(google_breakpad::Module *module,
+                          const mach_o::Reader &macho_reader,
+                          const mach_o::Section &section,
+                          bool eh_frame) const {
+  // Find the appropriate set of register names for this file's
+  // architecture.
+  vector<string> register_names;
+  switch (macho_reader.cpu_type()) {
+    case CPU_TYPE_X86:
+      register_names = DwarfCFIToModule::RegisterNames::I386();
+      break;
+    case CPU_TYPE_X86_64:
+      register_names = DwarfCFIToModule::RegisterNames::X86_64();
+      break;
+    case CPU_TYPE_ARM:
+      register_names = DwarfCFIToModule::RegisterNames::ARM();
+      break;
+    default: {
+      const NXArchInfo *arch =
+          NXGetArchInfoFromCpuType(macho_reader.cpu_type(),
+                                   macho_reader.cpu_subtype());
+      fprintf(stderr, "%s: cannot convert DWARF call frame information for ",
+              selected_object_name_.c_str());
+      if (arch)
+        fprintf(stderr, "architecture '%s'", arch->name);
+      else
+        fprintf(stderr, "architecture %d,%d",
+                macho_reader.cpu_type(), macho_reader.cpu_subtype());
+      fprintf(stderr, " to Breakpad symbol file: no register name table\n");
+      return false;
+    }
+  }
+
+  // Find the call frame information and its size.
+  const char *cfi = reinterpret_cast<const char *>(section.contents.start);
+  size_t cfi_size = section.contents.Size();
+
+  // Plug together the parser, handler, and their entourages.
+  DwarfCFIToModule::Reporter module_reporter(selected_object_name_,
+                                             section.section_name);
+  DwarfCFIToModule handler(module, register_names, &module_reporter);
+  dwarf2reader::ByteReader byte_reader(macho_reader.big_endian() ?
+                                       dwarf2reader::ENDIANNESS_BIG :
+                                       dwarf2reader::ENDIANNESS_LITTLE);
+  byte_reader.SetAddressSize(macho_reader.bits_64() ? 8 : 4);
+  // At the moment, according to folks at Apple and some cursory
+  // investigation, Mac OS X only uses DW_EH_PE_pcrel-based pointers, so
+  // this is the only base address the CFI parser will need.
+  byte_reader.SetCFIDataBase(section.address, cfi);
+
+  dwarf2reader::CallFrameInfo::Reporter dwarf_reporter(selected_object_name_,
+                                                       section.section_name);
+  dwarf2reader::CallFrameInfo parser(cfi, cfi_size,
+                                     &byte_reader, &handler, &dwarf_reporter,
+                                     eh_frame);
+  parser.Start();
+  return true;
+}
+
+// A LoadCommandHandler that loads whatever debugging data it finds into a
+// Module.
+class DumpSymbols::LoadCommandDumper:
+      public mach_o::Reader::LoadCommandHandler {
+ public:
+  // Create a load command dumper handling load commands from READER's
+  // file, and adding data to MODULE.
+  LoadCommandDumper(const DumpSymbols &dumper,
+                    google_breakpad::Module *module,
+                    const mach_o::Reader &reader)
+      : dumper_(dumper), module_(module), reader_(reader) { }
+
+  bool SegmentCommand(const mach_o::Segment &segment);
+  bool SymtabCommand(const ByteBuffer &entries, const ByteBuffer &strings);
+
+ private:
+  const DumpSymbols &dumper_;
+  google_breakpad::Module *module_;  // WEAK
+  const mach_o::Reader &reader_;
+};
+
+bool DumpSymbols::LoadCommandDumper::SegmentCommand(const Segment &segment) {
+  mach_o::SectionMap section_map;
+  if (!reader_.MapSegmentSections(segment, &section_map))
+    return false;
+
+  if (segment.name == "__TEXT") {
+    module_->SetLoadAddress(segment.vmaddr);
+    mach_o::SectionMap::const_iterator eh_frame =
+        section_map.find("__eh_frame");
+    if (eh_frame != section_map.end()) {
+      // If there is a problem reading this, don't treat it as a fatal error.
+      dumper_.ReadCFI(module_, reader_, eh_frame->second, true);
+    }
+    return true;
+  }
+
+  if (segment.name == "__DWARF") {
+    if (!dumper_.ReadDwarf(module_, reader_, section_map))
+      return false;
+    mach_o::SectionMap::const_iterator debug_frame
+        = section_map.find("__debug_frame");
+    if (debug_frame != section_map.end()) {
+      // If there is a problem reading this, don't treat it as a fatal error.
+      dumper_.ReadCFI(module_, reader_, debug_frame->second, false);
+    }
+  }
+
+  return true;
+}
+
+bool DumpSymbols::LoadCommandDumper::SymtabCommand(const ByteBuffer &entries,
+                                                   const ByteBuffer &strings) {
+  StabsToModule stabs_to_module(module_);
+  // Mac OS X STABS are never "unitized", and the size of the 'value' field
+  // matches the address size of the executable.
+  StabsReader stabs_reader(entries.start, entries.Size(),
+                           strings.start, strings.Size(),
+                           reader_.big_endian(),
+                           reader_.bits_64() ? 8 : 4,
+                           true,
+                           &stabs_to_module);
+  if (!stabs_reader.Process())
+    return false;
+  stabs_to_module.Finalize();
+  return true;
+}
+
+bool DumpSymbols::WriteSymbolFile(std::ostream &stream, bool cfi) {
+  // Select an object file, if SetArchitecture hasn't been called to set one
+  // explicitly.
+  if (!selected_object_file_) {
+    // If there's only one architecture, that's the one.
+    if (object_files_.size() == 1)
+      selected_object_file_ = &object_files_[0];
+    else {
+      // Look for an object file whose architecture matches our own.
+      const NXArchInfo *local_arch = NXGetLocalArchInfo();
+      if (!SetArchitecture(local_arch->cputype, local_arch->cpusubtype)) {
+        fprintf(stderr, "%s: object file contains more than one"
+                " architecture, none of which match the current"
+                " architecture; specify an architecture explicitly"
+                " with '-a ARCH' to resolve the ambiguity\n",
+                [object_filename_ fileSystemRepresentation]);
+        return false;
+      }
+    }
+  }
+
+  assert(selected_object_file_);
+
+  // Find the name of the selected file's architecture, to appear in
+  // the MODULE record and in error messages.
+  const NXArchInfo *selected_arch_info
+      = NXGetArchInfoFromCpuType(selected_object_file_->cputype,
+                                 selected_object_file_->cpusubtype);
+
+  const char *selected_arch_name = selected_arch_info->name;
+  if (strcmp(selected_arch_name, "i386") == 0)
+    selected_arch_name = "x86";
+
+  // Produce a name to use in error messages that includes the
+  // filename, and the architecture, if there is more than one.
+  selected_object_name_ = [object_filename_ UTF8String];
+  if (object_files_.size() > 1) {
+    selected_object_name_ += ", architecture ";
+    selected_object_name_ + selected_arch_name;
+  }
+
+  // Compute a module name, to appear in the MODULE record.
+  NSString *module_name = [object_filename_ lastPathComponent];
+
+  // Choose an identifier string, to appear in the MODULE record.
+  string identifier = Identifier();
+  if (identifier.empty())
+    return false;
+  identifier += "0";
+
+  // Create a module to hold the debugging information.
+  Module module([module_name UTF8String], "mac", selected_arch_name,
+                identifier);
+
+  // Parse the selected object file.
+  mach_o::Reader::Reporter reporter(selected_object_name_);
+  mach_o::Reader reader(&reporter);
+  if (!reader.Read(reinterpret_cast<const uint8_t *>([contents_ bytes])
+                   + selected_object_file_->offset,
+                   selected_object_file_->size,
+                   selected_object_file_->cputype,
+                   selected_object_file_->cpusubtype))
+    return false;
+
+  // Walk its load commands, and deal with whatever is there.
+  LoadCommandDumper load_command_dumper(*this, &module, reader);
+  if (!reader.WalkLoadCommands(&load_command_dumper))
+    return false;
+
+  return module.Write(stream, cfi);
+}
+
+}  // namespace google_breakpad
diff --git a/3rdParty/Breakpad/src/common/mac/file_id.cc b/3rdParty/Breakpad/src/common/mac/file_id.cc
new file mode 100644
index 0000000..50502e4
--- /dev/null
+++ b/3rdParty/Breakpad/src/common/mac/file_id.cc
@@ -0,0 +1,101 @@
+// 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.
+
+// file_id.cc: Return a unique identifier for a file
+//
+// See file_id.h for documentation
+//
+// Author: Dan Waylonis
+
+#include <fcntl.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "common/mac/file_id.h"
+#include "common/mac/macho_id.h"
+
+using MacFileUtilities::MachoID;
+
+namespace google_breakpad {
+
+FileID::FileID(const char *path) {
+  strlcpy(path_, path, sizeof(path_));
+}
+
+bool FileID::FileIdentifier(unsigned char identifier[16]) {
+  int fd = open(path_, O_RDONLY);
+  if (fd == -1)
+    return false;
+
+  MD5Context md5;
+  MD5Init(&md5);
+
+  // Read 4k x 2 bytes at a time.  This is faster than just 4k bytes, but
+  // doesn't seem to be an unreasonable size for the stack.
+  unsigned char buffer[4096 * 2];
+  size_t buffer_size = sizeof(buffer);
+  while ((buffer_size = read(fd, buffer, buffer_size) > 0)) {
+    MD5Update(&md5, buffer, buffer_size);
+  }
+
+  close(fd);
+  MD5Final(identifier, &md5);
+
+  return true;
+}
+
+bool FileID::MachoIdentifier(int cpu_type, unsigned char identifier[16]) {
+  MachoID macho(path_);
+
+  if (macho.UUIDCommand(cpu_type, identifier))
+    return true;
+
+  return macho.MD5(cpu_type, identifier);
+}
+
+// static
+void FileID::ConvertIdentifierToString(const unsigned char identifier[16],
+                                       char *buffer, int buffer_length) {
+  int buffer_idx = 0;
+  for (int idx = 0; (buffer_idx < buffer_length) && (idx < 16); ++idx) {
+    int hi = (identifier[idx] >> 4) & 0x0F;
+    int lo = (identifier[idx]) & 0x0F;
+
+    if (idx == 4 || idx == 6 || idx == 8 || idx == 10)
+      buffer[buffer_idx++] = '-';
+
+    buffer[buffer_idx++] = (hi >= 10) ? 'A' + hi - 10 : '0' + hi;
+    buffer[buffer_idx++] = (lo >= 10) ? 'A' + lo - 10 : '0' + lo;
+  }
+
+  // NULL terminate
+  buffer[(buffer_idx < buffer_length) ? buffer_idx : buffer_idx - 1] = 0;
+}
+
+}  // namespace google_breakpad
diff --git a/3rdParty/Breakpad/src/common/mac/file_id.h b/3rdParty/Breakpad/src/common/mac/file_id.h
new file mode 100644
index 0000000..eb06b0d
--- /dev/null
+++ b/3rdParty/Breakpad/src/common/mac/file_id.h
@@ -0,0 +1,78 @@
+// 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.
+
+// file_id.h: Return a unique identifier for a file
+//
+// Author: Dan Waylonis
+
+#ifndef COMMON_MAC_FILE_ID_H__
+#define COMMON_MAC_FILE_ID_H__
+
+#include <limits.h>
+
+namespace google_breakpad {
+
+class FileID {
+ public:
+  FileID(const char *path);
+  ~FileID() {};
+
+  // Load the identifier for the file path specified in the constructor into
+  // |identifier|.  Return false if the identifier could not be created for the
+  // file.
+  // The current implementation will return the MD5 hash of the file's bytes.
+  bool FileIdentifier(unsigned char identifier[16]);
+
+  // Treat the file as a mach-o file that will contain one or more archicture.
+  // Accepted values for |cpu_type| (e.g., CPU_TYPE_X86 or CPU_TYPE_POWERPC)
+  // are listed in /usr/include/mach/machine.h.
+  // If |cpu_type| is 0, then the native cpu type is used.
+  // Returns false if opening the file failed or if the |cpu_type| is not
+  // present in the file.
+  // Return the unique identifier in |identifier|.
+  // The current implementation will look for the (in order of priority):
+  // LC_UUID, LC_ID_DYLIB, or MD5 hash of the given |cpu_type|.
+  bool MachoIdentifier(int cpu_type, unsigned char identifier[16]);
+
+  // Convert the |identifier| data to a NULL terminated string.  The string will
+  // be formatted as a UUID (e.g., 22F065BB-FC9C-49F7-80FE-26A7CEBD7BCE).
+  // The |buffer| should be at least 37 bytes long to receive all of the data
+  // and termination.  Shorter buffers will contain truncated data.
+  static void ConvertIdentifierToString(const unsigned char identifier[16],
+                                        char *buffer, int buffer_length);
+
+ private:
+  // Storage for the path specified
+  char path_[PATH_MAX];
+};
+
+}  // namespace google_breakpad
+
+#endif  // COMMON_MAC_FILE_ID_H__
+
diff --git a/3rdParty/Breakpad/src/common/mac/macho_id.cc b/3rdParty/Breakpad/src/common/mac/macho_id.cc
new file mode 100644
index 0000000..abe1fab
--- /dev/null
+++ b/3rdParty/Breakpad/src/common/mac/macho_id.cc
@@ -0,0 +1,366 @@
+// 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.
+
+// macho_id.cc: Functions to gather identifying information from a macho file
+//
+// See macho_id.h for documentation
+//
+// Author: Dan Waylonis
+
+extern "C" {  // necessary for Leopard
+  #include <fcntl.h>
+  #include <mach-o/loader.h>
+  #include <mach-o/swap.h>
+  #include <stdio.h>
+  #include <stdlib.h>
+  #include <string.h>
+  #include <sys/time.h>
+  #include <sys/types.h>
+  #include <unistd.h>
+}
+
+#include "common/mac/macho_id.h"
+#include "common/mac/macho_walker.h"
+#include "common/mac/macho_utilities.h"
+
+namespace MacFileUtilities {
+
+using google_breakpad::MD5Init;
+using google_breakpad::MD5Update;
+using google_breakpad::MD5Final;
+
+MachoID::MachoID(const char *path)
+   : memory_(0),
+     memory_size_(0),
+     crc_(0), 
+     md5_context_(), 
+     update_function_(NULL) {
+  strlcpy(path_, path, sizeof(path_));
+}
+
+MachoID::MachoID(const char *path, void *memory, size_t size)
+   : memory_(memory),
+     memory_size_(size),
+     crc_(0), 
+     md5_context_(), 
+     update_function_(NULL) {
+  strlcpy(path_, path, sizeof(path_));
+}
+
+MachoID::~MachoID() {
+}
+
+// The CRC info is from http://en.wikipedia.org/wiki/Adler-32
+// With optimizations from http://www.zlib.net/
+
+// The largest prime smaller than 65536
+#define MOD_ADLER 65521
+// MAX_BLOCK is the largest n such that 255n(n+1)/2 + (n+1)(MAX_BLOCK-1) <= 2^32-1
+#define MAX_BLOCK 5552
+
+void MachoID::UpdateCRC(unsigned char *bytes, size_t size) {
+// Unrolled loops for summing
+#define DO1(buf,i)  {sum1 += (buf)[i]; sum2 += sum1;}
+#define DO2(buf,i)  DO1(buf,i); DO1(buf,i+1);
+#define DO4(buf,i)  DO2(buf,i); DO2(buf,i+2);
+#define DO8(buf,i)  DO4(buf,i); DO4(buf,i+4);
+#define DO16(buf)   DO8(buf,0); DO8(buf,8);
+  // Split up the crc
+  uint32_t sum1 = crc_ & 0xFFFF;
+  uint32_t sum2 = (crc_ >> 16) & 0xFFFF;
+
+  // Do large blocks
+  while (size >= MAX_BLOCK) {
+    size -= MAX_BLOCK;
+    int block_count = MAX_BLOCK / 16;
+    do {
+      DO16(bytes);
+      bytes += 16;
+    } while (--block_count);
+    sum1 %= MOD_ADLER;
+    sum2 %= MOD_ADLER;
+  }
+
+  // Do remaining bytes
+  if (size) {
+    while (size >= 16) {
+      size -= 16;
+      DO16(bytes);
+      bytes += 16;
+    }
+    while (size--) {
+      sum1 += *bytes++;
+      sum2 += sum1;
+    }
+    sum1 %= MOD_ADLER;
+    sum2 %= MOD_ADLER;
+    crc_ = (sum2 << 16) | sum1;
+  }
+}
+
+void MachoID::UpdateMD5(unsigned char *bytes, size_t size) {
+  MD5Update(&md5_context_, bytes, size);
+}
+
+void MachoID::Update(MachoWalker *walker, off_t offset, size_t size) {
+  if (!update_function_ || !size)
+    return;
+
+  // Read up to 4k bytes at a time
+  unsigned char buffer[4096];
+  size_t buffer_size;
+  off_t file_offset = offset;
+  while (size > 0) {
+    if (size > sizeof(buffer)) {
+      buffer_size = sizeof(buffer);
+      size -= buffer_size;
+    } else {
+      buffer_size = size;
+      size = 0;
+    }
+
+    if (!walker->ReadBytes(buffer, buffer_size, file_offset))
+      return;
+
+    (this->*update_function_)(buffer, buffer_size);
+    file_offset += buffer_size;
+  }
+}
+
+bool MachoID::UUIDCommand(int cpu_type, unsigned char bytes[16]) {
+  struct breakpad_uuid_command uuid_cmd;
+  uuid_cmd.cmd = 0;
+  if (!WalkHeader(cpu_type, UUIDWalkerCB, &uuid_cmd))
+    return false;
+
+  // If we found the command, we'll have initialized the uuid_command
+  // structure
+  if (uuid_cmd.cmd == LC_UUID) {
+    memcpy(bytes, uuid_cmd.uuid, sizeof(uuid_cmd.uuid));
+    return true;
+  }
+
+  return false;
+}
+
+bool MachoID::IDCommand(int cpu_type, unsigned char identifier[16]) {
+  struct dylib_command dylib_cmd;
+  dylib_cmd.cmd = 0;
+  if (!WalkHeader(cpu_type, IDWalkerCB, &dylib_cmd))
+    return false;
+
+  // If we found the command, we'll have initialized the dylib_command
+  // structure
+  if (dylib_cmd.cmd == LC_ID_DYLIB) {
+    // Take the hashed filename, version, and compatability version bytes
+    // to form the first 12 bytes, pad the rest with zeros
+
+    // create a crude hash of the filename to generate the first 4 bytes
+    identifier[0] = 0;
+    identifier[1] = 0;
+    identifier[2] = 0;
+    identifier[3] = 0;
+
+    for (int j = 0, i = (int)strlen(path_)-1; i>=0 && path_[i]!='/'; ++j, --i) {
+      identifier[j%4] += path_[i];
+    }
+
+    identifier[4] = (dylib_cmd.dylib.current_version >> 24) & 0xFF;
+    identifier[5] = (dylib_cmd.dylib.current_version >> 16) & 0xFF;
+    identifier[6] = (dylib_cmd.dylib.current_version >> 8) & 0xFF;
+    identifier[7] = dylib_cmd.dylib.current_version & 0xFF;
+    identifier[8] = (dylib_cmd.dylib.compatibility_version >> 24) & 0xFF;
+    identifier[9] = (dylib_cmd.dylib.compatibility_version >> 16) & 0xFF;
+    identifier[10] = (dylib_cmd.dylib.compatibility_version >> 8) & 0xFF;
+    identifier[11] = dylib_cmd.dylib.compatibility_version & 0xFF;
+    identifier[12] = (cpu_type >> 24) & 0xFF;
+    identifier[13] = (cpu_type >> 16) & 0xFF;
+    identifier[14] = (cpu_type >> 8) & 0xFF;
+    identifier[15] = cpu_type & 0xFF;
+
+    return true;
+  }
+
+  return false;
+}
+
+uint32_t MachoID::Adler32(int cpu_type) {
+  update_function_ = &MachoID::UpdateCRC;
+  crc_ = 0;
+
+  if (!WalkHeader(cpu_type, WalkerCB, this))
+    return 0;
+
+  return crc_;
+}
+
+bool MachoID::MD5(int cpu_type, unsigned char identifier[16]) {
+  update_function_ = &MachoID::UpdateMD5;
+
+  MD5Init(&md5_context_);
+
+  if (!WalkHeader(cpu_type, WalkerCB, this))
+    return false;
+
+  MD5Final(identifier, &md5_context_);
+  return true;
+}
+
+bool MachoID::WalkHeader(int cpu_type,
+                         MachoWalker::LoadCommandCallback callback,
+                         void *context) {
+  if (memory_) {
+    MachoWalker walker(memory_, memory_size_, callback, context);
+    return walker.WalkHeader(cpu_type);
+  } else {
+    MachoWalker walker(path_, callback, context);
+    return walker.WalkHeader(cpu_type);
+  }
+}
+
+// static
+bool MachoID::WalkerCB(MachoWalker *walker, load_command *cmd, off_t offset,
+                       bool swap, void *context) {
+  MachoID *macho_id = (MachoID *)context;
+
+  if (cmd->cmd == LC_SEGMENT) {
+    struct segment_command seg;
+
+    if (!walker->ReadBytes(&seg, sizeof(seg), offset))
+      return false;
+
+    if (swap)
+      swap_segment_command(&seg, NXHostByteOrder());
+
+    struct mach_header_64 header;
+    off_t header_offset;
+    
+    if (!walker->CurrentHeader(&header, &header_offset))
+      return false;
+        
+    // Process segments that have sections:
+    // (e.g., __TEXT, __DATA, __IMPORT, __OBJC)
+    offset += sizeof(struct segment_command);
+    struct section sec;
+    for (unsigned long i = 0; i < seg.nsects; ++i) {
+      if (!walker->ReadBytes(&sec, sizeof(sec), offset))
+        return false;
+
+      if (swap)
+        swap_section(&sec, 1, NXHostByteOrder());
+
+      // sections of type S_ZEROFILL are "virtual" and contain no data
+      // in the file itself
+      if ((sec.flags & SECTION_TYPE) != S_ZEROFILL && sec.offset != 0)
+        macho_id->Update(walker, header_offset + sec.offset, sec.size);
+
+      offset += sizeof(struct section);
+    }
+  } else if (cmd->cmd == LC_SEGMENT_64) {
+    struct segment_command_64 seg64;
+
+    if (!walker->ReadBytes(&seg64, sizeof(seg64), offset))
+      return false;
+
+    if (swap)
+      breakpad_swap_segment_command_64(&seg64, NXHostByteOrder());
+
+    struct mach_header_64 header;
+    off_t header_offset;
+    
+    if (!walker->CurrentHeader(&header, &header_offset))
+      return false;
+    
+    // Process segments that have sections:
+    // (e.g., __TEXT, __DATA, __IMPORT, __OBJC)
+    offset += sizeof(struct segment_command_64);
+    struct section_64 sec64;
+    for (unsigned long i = 0; i < seg64.nsects; ++i) {
+      if (!walker->ReadBytes(&sec64, sizeof(sec64), offset))
+        return false;
+
+      if (swap)
+        breakpad_swap_section_64(&sec64, 1, NXHostByteOrder());
+
+      // sections of type S_ZEROFILL are "virtual" and contain no data
+      // in the file itself
+      if ((sec64.flags & SECTION_TYPE) != S_ZEROFILL && sec64.offset != 0)
+        macho_id->Update(walker, 
+                         header_offset + sec64.offset, 
+                         (size_t)sec64.size);
+
+      offset += sizeof(struct section_64);
+    }
+  }
+
+  // Continue processing
+  return true;
+}
+
+// static
+bool MachoID::UUIDWalkerCB(MachoWalker *walker, load_command *cmd, off_t offset,
+                           bool swap, void *context) {
+  if (cmd->cmd == LC_UUID) {
+    struct breakpad_uuid_command *uuid_cmd =
+      (struct breakpad_uuid_command *)context;
+
+    if (!walker->ReadBytes(uuid_cmd, sizeof(struct breakpad_uuid_command),
+                           offset))
+      return false;
+
+    if (swap)
+      breakpad_swap_uuid_command(uuid_cmd, NXHostByteOrder());
+
+    return false;
+  }
+
+  // Continue processing
+  return true;
+}
+
+// static
+bool MachoID::IDWalkerCB(MachoWalker *walker, load_command *cmd, off_t offset,
+                         bool swap, void *context) {
+  if (cmd->cmd == LC_ID_DYLIB) {
+    struct dylib_command *dylib_cmd = (struct dylib_command *)context;
+
+    if (!walker->ReadBytes(dylib_cmd, sizeof(struct dylib_command), offset))
+      return false;
+
+    if (swap)
+      swap_dylib_command(dylib_cmd, NXHostByteOrder());
+
+    return false;
+  }
+
+  // Continue processing
+  return true;
+}
+
+}  // namespace MacFileUtilities
diff --git a/3rdParty/Breakpad/src/common/mac/macho_id.h b/3rdParty/Breakpad/src/common/mac/macho_id.h
new file mode 100644
index 0000000..ccb126d
--- /dev/null
+++ b/3rdParty/Breakpad/src/common/mac/macho_id.h
@@ -0,0 +1,120 @@
+// 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.
+
+// macho_id.h: Functions to gather identifying information from a macho file
+//
+// Author: Dan Waylonis
+
+#ifndef COMMON_MAC_MACHO_ID_H__
+#define COMMON_MAC_MACHO_ID_H__
+
+#include <limits.h>
+#include <mach-o/loader.h>
+
+#include "common/mac/macho_walker.h"
+#include "common/md5.h"
+
+namespace MacFileUtilities {
+
+class MachoID {
+ public:
+  MachoID(const char *path);
+  MachoID(const char *path, void *memory, size_t size);
+  ~MachoID();
+
+  // For the given |cpu_type|, return a UUID from the LC_UUID command.
+  // Return false if there isn't a LC_UUID command.
+  bool UUIDCommand(int cpu_type, unsigned char identifier[16]);
+
+  // For the given |cpu_type|, return a UUID from the LC_ID_DYLIB command.
+  // Return false if there isn't a LC_ID_DYLIB command.
+  bool IDCommand(int cpu_type, unsigned char identifier[16]);
+
+  // For the given |cpu_type|, return the Adler32 CRC for the mach-o data
+  // segment(s).
+  // Return 0 on error (e.g., if the file is not a mach-o file)
+  uint32_t Adler32(int cpu_type);
+
+  // For the given |cpu_type|, return the MD5 for the mach-o data segment(s).
+  // Return true on success, false otherwise
+  bool MD5(int cpu_type, unsigned char identifier[16]);
+
+ private:
+  // Signature of class member function to be called with data read from file
+  typedef void (MachoID::*UpdateFunction)(unsigned char *bytes, size_t size);
+
+  // Update the CRC value by examining |size| |bytes| and applying the algorithm
+  // to each byte.
+  void UpdateCRC(unsigned char *bytes, size_t size);
+
+  // Update the MD5 value by examining |size| |bytes| and applying the algorithm
+  // to each byte.
+  void UpdateMD5(unsigned char *bytes, size_t size);
+
+  // Bottleneck for update routines
+  void Update(MachoWalker *walker, off_t offset, size_t size);
+
+  // Factory for the MachoWalker
+  bool WalkHeader(int cpu_type, MachoWalker::LoadCommandCallback callback,
+                  void *context);
+
+  // The callback from the MachoWalker for CRC and MD5
+  static bool WalkerCB(MachoWalker *walker, load_command *cmd, off_t offset,
+                       bool swap, void *context);
+
+  // The callback from the MachoWalker for LC_UUID
+  static bool UUIDWalkerCB(MachoWalker *walker, load_command *cmd, off_t offset,
+                           bool swap, void *context);
+
+  // The callback from the MachoWalker for LC_ID_DYLIB
+  static bool IDWalkerCB(MachoWalker *walker, load_command *cmd, off_t offset,
+                         bool swap, void *context);
+
+  // File path
+  char path_[PATH_MAX];
+
+  // Memory region to read from
+  void *memory_;
+
+  // Size of the memory region
+  size_t memory_size_;
+
+  // The current crc value
+  uint32_t crc_;
+
+  // The MD5 context
+  google_breakpad::MD5Context md5_context_;
+
+  // The current update to call from the Update callback
+  UpdateFunction update_function_;
+};
+
+}  // namespace MacFileUtilities
+
+#endif  // COMMON_MAC_MACHO_ID_H__
diff --git a/3rdParty/Breakpad/src/common/mac/macho_reader.cc b/3rdParty/Breakpad/src/common/mac/macho_reader.cc
new file mode 100644
index 0000000..f1f0a17
--- /dev/null
+++ b/3rdParty/Breakpad/src/common/mac/macho_reader.cc
@@ -0,0 +1,530 @@
+// 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_reader.cc: Implementation of google_breakpad::Mach_O::FatReader and
+// google_breakpad::Mach_O::Reader. See macho_reader.h for details.
+
+#include "common/mac/macho_reader.h"
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+// Unfortunately, CPU_TYPE_ARM is not define for 10.4.
+#if !defined(CPU_TYPE_ARM)
+#define CPU_TYPE_ARM 12
+#endif
+
+namespace google_breakpad {
+namespace mach_o {
+
+// If NDEBUG is #defined, then the 'assert' macro doesn't evaluate its
+// arguments, so you can't place expressions that do necessary work in
+// the argument of an assert. Nor can you assign the result of the
+// expression to a variable and assert that the variable's value is
+// true: you'll get unused variable warnings when NDEBUG is #defined.
+//
+// ASSERT_ALWAYS_EVAL always evaluates its argument, and asserts that
+// the result is true if NDEBUG is not #defined.
+#if defined(NDEBUG)
+#define ASSERT_ALWAYS_EVAL(x) (x)
+#else
+#define ASSERT_ALWAYS_EVAL(x) assert(x)
+#endif
+
+void FatReader::Reporter::BadHeader() {
+  fprintf(stderr, "%s: file is neither a fat binary file"
+          " nor a Mach-O object file\n", filename_.c_str());
+}
+
+void FatReader::Reporter::TooShort() {
+  fprintf(stderr, "%s: file too short for the data it claims to contain\n",
+          filename_.c_str());
+}
+
+void FatReader::Reporter::MisplacedObjectFile() {
+  fprintf(stderr, "%s: file too short for the object files it claims"
+          " to contain\n", filename_.c_str());
+}
+
+bool FatReader::Read(const uint8_t *buffer, size_t size) {
+  buffer_.start = buffer;
+  buffer_.end = buffer + size;
+  ByteCursor cursor(&buffer_);
+
+  // Fat binaries always use big-endian, so read the magic number in
+  // that endianness. To recognize Mach-O magic numbers, which can use
+  // either endianness, check for both the proper and reversed forms
+  // of the magic numbers.
+  cursor.set_big_endian(true);
+  if (cursor >> magic_) {
+    if (magic_ == FAT_MAGIC) {
+      // How many object files does this fat binary contain?
+      uint32_t object_files_count;
+      if (!(cursor >> object_files_count)) {  // nfat_arch
+        reporter_->TooShort();
+        return false;
+      }
+
+      // Read the list of object files.
+      object_files_.resize(object_files_count);
+      for (size_t i = 0; i < object_files_count; i++) {
+        struct fat_arch *objfile = &object_files_[i];
+
+        // Read this object file entry, byte-swapping as appropriate.
+        cursor >> objfile->cputype
+               >> objfile->cpusubtype
+               >> objfile->offset
+               >> objfile->size
+               >> objfile->align;
+        if (!cursor) {
+          reporter_->TooShort();
+          return false;
+        }
+        // Does the file actually have the bytes this entry refers to?
+        size_t fat_size = buffer_.Size();
+        if (objfile->offset > fat_size ||
+            objfile->size > fat_size - objfile->offset) {
+          reporter_->MisplacedObjectFile();
+          return false;
+        }
+      }
+
+      return true;
+    } else if (magic_ == MH_MAGIC || magic_ == MH_MAGIC_64 ||
+               magic_ == MH_CIGAM || magic_ == MH_CIGAM_64) {
+      // If this is a little-endian Mach-O file, fix the cursor's endianness.
+      if (magic_ == MH_CIGAM || magic_ == MH_CIGAM_64)
+        cursor.set_big_endian(false);
+      // Record the entire file as a single entry in the object file list.
+      object_files_.resize(1);
+
+      // Get the cpu type and subtype from the Mach-O header.
+      if (!(cursor >> object_files_[0].cputype
+                   >> object_files_[0].cpusubtype)) {
+        reporter_->TooShort();
+        return false;
+      }
+
+      object_files_[0].offset = 0;
+      object_files_[0].size = static_cast<uint32_t>(buffer_.Size());
+      // This alignment is correct for 32 and 64-bit x86 and ppc.
+      // See get_align in the lipo source for other architectures:
+      // http://www.opensource.apple.com/source/cctools/cctools-773/misc/lipo.c
+      object_files_[0].align = 12;  // 2^12 == 4096
+      
+      return true;
+    }
+  }
+  
+  reporter_->BadHeader();
+  return false;
+}
+
+void Reader::Reporter::BadHeader() {
+  fprintf(stderr, "%s: file is not a Mach-O object file\n", filename_.c_str());
+}
+
+void Reader::Reporter::CPUTypeMismatch(cpu_type_t cpu_type,
+                                       cpu_subtype_t cpu_subtype,
+                                       cpu_type_t expected_cpu_type,
+                                       cpu_subtype_t expected_cpu_subtype) {
+  fprintf(stderr, "%s: CPU type %d, subtype %d does not match expected"
+          " type %d, subtype %d\n",
+          filename_.c_str(), cpu_type, cpu_subtype,
+          expected_cpu_type, expected_cpu_subtype);
+}
+
+void Reader::Reporter::HeaderTruncated() {
+  fprintf(stderr, "%s: file does not contain a complete Mach-O header\n",
+          filename_.c_str());
+}
+
+void Reader::Reporter::LoadCommandRegionTruncated() {
+  fprintf(stderr, "%s: file too short to hold load command region"
+          " given in Mach-O header\n", filename_.c_str());
+}
+
+void Reader::Reporter::LoadCommandsOverrun(size_t claimed, size_t i,
+                                           LoadCommandType type) {
+  fprintf(stderr, "%s: file's header claims there are %ld"
+          " load commands, but load command #%ld",
+          filename_.c_str(), claimed, i);
+  if (type) fprintf(stderr, ", of type %d,", type);
+  fprintf(stderr, " extends beyond the end of the load command region\n");
+}
+
+void Reader::Reporter::LoadCommandTooShort(size_t i, LoadCommandType type) {
+  fprintf(stderr, "%s: the contents of load command #%ld, of type %d,"
+          " extend beyond the size given in the load command's header\n",
+          filename_.c_str(), i, type);
+}
+
+void Reader::Reporter::SectionsMissing(const string &name) {
+  fprintf(stderr, "%s: the load command for segment '%s'"
+          " is too short to hold the section headers it claims to have\n",
+          filename_.c_str(), name.c_str());
+}
+
+void Reader::Reporter::MisplacedSegmentData(const string &name) {
+  fprintf(stderr, "%s: the segment '%s' claims its contents lie beyond"
+          " the end of the file\n", filename_.c_str(), name.c_str());
+}
+
+void Reader::Reporter::MisplacedSectionData(const string &section,
+                                            const string &segment) {
+  fprintf(stderr, "%s: the section '%s' in segment '%s'"
+          " claims its contents lie outside the segment's contents\n",
+          filename_.c_str(), section.c_str(), segment.c_str());
+}
+
+void Reader::Reporter::MisplacedSymbolTable() {
+  fprintf(stderr, "%s: the LC_SYMTAB load command claims that the symbol"
+          " table's contents are located beyond the end of the file\n",
+          filename_.c_str());
+}
+
+void Reader::Reporter::UnsupportedCPUType(cpu_type_t cpu_type) {
+  fprintf(stderr, "%s: CPU type %d is not supported\n",
+          filename_.c_str(), cpu_type);
+}
+
+bool Reader::Read(const uint8_t *buffer,
+                  size_t size,
+                  cpu_type_t expected_cpu_type,
+                  cpu_subtype_t expected_cpu_subtype) {
+  assert(!buffer_.start);
+  buffer_.start = buffer;
+  buffer_.end = buffer + size;
+  ByteCursor cursor(&buffer_, true);
+  uint32_t magic;
+  if (!(cursor >> magic)) {
+    reporter_->HeaderTruncated();
+    return false;
+  }
+
+  if (expected_cpu_type != CPU_TYPE_ANY) {
+    uint32_t expected_magic;
+    // validate that magic matches the expected cpu type
+    switch (expected_cpu_type) {
+      case CPU_TYPE_ARM:
+      case CPU_TYPE_I386:
+        expected_magic = MH_CIGAM;
+        break;
+      case CPU_TYPE_POWERPC:
+        expected_magic = MH_MAGIC;
+        break;
+      case CPU_TYPE_X86_64:
+        expected_magic = MH_CIGAM_64;
+        break;
+      case CPU_TYPE_POWERPC64:
+        expected_magic = MH_MAGIC_64;
+        break;
+      default:
+        reporter_->UnsupportedCPUType(expected_cpu_type);
+        return false;
+    }
+
+    if (expected_magic != magic) {
+      reporter_->BadHeader();
+      return false;
+    }
+  }
+
+  // Since the byte cursor is in big-endian mode, a reversed magic number
+  // always indicates a little-endian file, regardless of our own endianness.
+  switch (magic) {
+    case MH_MAGIC:    big_endian_ = true;  bits_64_ = false; break;
+    case MH_CIGAM:    big_endian_ = false; bits_64_ = false; break;
+    case MH_MAGIC_64: big_endian_ = true;  bits_64_ = true;  break;
+    case MH_CIGAM_64: big_endian_ = false; bits_64_ = true;  break;
+    default:
+      reporter_->BadHeader();
+      return false;
+  }
+  cursor.set_big_endian(big_endian_);
+  uint32_t commands_size, reserved;
+  cursor >> cpu_type_ >> cpu_subtype_ >> file_type_ >> load_command_count_
+         >> commands_size >> flags_;
+  if (bits_64_)
+    cursor >> reserved;
+  if (!cursor) {
+    reporter_->HeaderTruncated();
+    return false;
+  }
+
+  if (expected_cpu_type != CPU_TYPE_ANY &&
+      (expected_cpu_type != cpu_type_ ||
+       expected_cpu_subtype != cpu_subtype_)) {
+    reporter_->CPUTypeMismatch(cpu_type_, cpu_subtype_,
+                              expected_cpu_type, expected_cpu_subtype);
+    return false;
+  }
+
+  cursor
+      .PointTo(&load_commands_.start, commands_size)
+      .PointTo(&load_commands_.end, 0);
+  if (!cursor) {
+    reporter_->LoadCommandRegionTruncated();
+    return false;
+  }
+
+  return true;
+}
+
+bool Reader::WalkLoadCommands(Reader::LoadCommandHandler *handler) const {
+  ByteCursor list_cursor(&load_commands_, big_endian_);
+
+  for (size_t index = 0; index < load_command_count_; ++index) {
+    // command refers to this load command alone, so that cursor will
+    // refuse to read past the load command's end. But since we haven't
+    // read the size yet, let command initially refer to the entire
+    // remainder of the load command series.
+    ByteBuffer command(list_cursor.here(), list_cursor.Available());
+    ByteCursor cursor(&command, big_endian_);
+    
+    // Read the command type and size --- fields common to all commands.
+    uint32_t type, size;
+    if (!(cursor >> type)) {
+      reporter_->LoadCommandsOverrun(load_command_count_, index, 0);
+      return false;
+    }
+    if (!(cursor >> size) || size > command.Size()) {
+      reporter_->LoadCommandsOverrun(load_command_count_, index, type);
+      return false;
+    }
+
+    // Now that we've read the length, restrict command's range to this
+    // load command only.
+    command.end = command.start + size;
+
+    switch (type) {
+      case LC_SEGMENT:
+      case LC_SEGMENT_64: {
+        Segment segment;
+        segment.bits_64 = (type == LC_SEGMENT_64);
+        size_t word_size = segment.bits_64 ? 8 : 4;
+        cursor.CString(&segment.name, 16);
+        size_t file_offset, file_size;
+        cursor
+            .Read(word_size, false, &segment.vmaddr)
+            .Read(word_size, false, &segment.vmsize)
+            .Read(word_size, false, &file_offset)
+            .Read(word_size, false, &file_size);
+        cursor >> segment.maxprot
+               >> segment.initprot
+               >> segment.nsects
+               >> segment.flags;
+        if (!cursor) {
+          reporter_->LoadCommandTooShort(index, type);
+          return false;
+        }
+        if (file_offset > buffer_.Size() ||
+            file_size > buffer_.Size() - file_offset) {
+          reporter_->MisplacedSegmentData(segment.name);
+          return false;
+        }
+        // Mach-O files in .dSYM bundles have the contents of the loaded
+        // segments removed, and their file offsets and file sizes zeroed
+        // out. To help us handle this special case properly, give such
+        // segments' contents NULL starting and ending pointers.
+        if (file_offset == 0 && file_size == 0) {
+          segment.contents.start = segment.contents.end = NULL;
+        } else {
+          segment.contents.start = buffer_.start + file_offset;
+          segment.contents.end = segment.contents.start + file_size;
+        }
+        // The section list occupies the remainder of this load command's space.
+        segment.section_list.start = cursor.here();
+        segment.section_list.end = command.end;
+
+        if (!handler->SegmentCommand(segment))
+          return false;
+        break;
+      }
+
+      case LC_SYMTAB: {
+        uint32_t symoff, nsyms, stroff, strsize;
+        cursor >> symoff >> nsyms >> stroff >> strsize;
+        if (!cursor) {
+          reporter_->LoadCommandTooShort(index, type);
+          return false;
+        }
+        // How big are the entries in the symbol table?
+        // sizeof(struct nlist_64) : sizeof(struct nlist),
+        // but be paranoid about alignment vs. target architecture.
+        size_t symbol_size = bits_64_ ? 16 : 12;
+        // How big is the entire symbol array?
+        size_t symbols_size = nsyms * symbol_size;
+        if (symoff > buffer_.Size() || symbols_size > buffer_.Size() - symoff ||
+            stroff > buffer_.Size() || strsize > buffer_.Size() - stroff) {
+          reporter_->MisplacedSymbolTable();
+          return false;
+        }
+        ByteBuffer entries(buffer_.start + symoff, symbols_size);
+        ByteBuffer names(buffer_.start + stroff, strsize);
+        if (!handler->SymtabCommand(entries, names))
+          return false;
+        break;
+      }
+      
+      default: {
+        if (!handler->UnknownCommand(type, command))
+          return false;
+        break;
+      }
+    }
+
+    list_cursor.set_here(command.end);
+  }
+
+  return true;
+}
+
+// A load command handler that looks for a segment of a given name.
+class Reader::SegmentFinder : public LoadCommandHandler {
+ public:
+  // Create a load command handler that looks for a segment named NAME,
+  // and sets SEGMENT to describe it if found.
+  SegmentFinder(const string &name, Segment *segment) 
+      : name_(name), segment_(segment), found_() { }
+
+  // Return true if the traversal found the segment, false otherwise.
+  bool found() const { return found_; }
+
+  bool SegmentCommand(const Segment &segment) {
+    if (segment.name == name_) {
+      *segment_ = segment;
+      found_ = true;
+      return false;
+    }
+    return true;
+  }
+
+ private:
+  // The name of the segment our creator is looking for.
+  const string &name_;
+
+  // Where we should store the segment if found. (WEAK)
+  Segment *segment_;
+
+  // True if we found the segment.
+  bool found_;
+};
+
+bool Reader::FindSegment(const string &name, Segment *segment) const {
+  SegmentFinder finder(name, segment);
+  WalkLoadCommands(&finder);
+  return finder.found();
+}
+
+bool Reader::WalkSegmentSections(const Segment &segment,
+                                 SectionHandler *handler) const {
+  size_t word_size = segment.bits_64 ? 8 : 4;
+  ByteCursor cursor(&segment.section_list, big_endian_);
+
+  for (size_t i = 0; i < segment.nsects; i++) {
+    Section section;
+    section.bits_64 = segment.bits_64;
+    uint64_t size;
+    uint32_t offset, dummy32;
+    cursor
+        .CString(&section.section_name, 16)
+        .CString(&section.segment_name, 16)
+        .Read(word_size, false, &section.address)
+        .Read(word_size, false, &size)
+        >> offset
+        >> section.align
+        >> dummy32
+        >> dummy32
+        >> section.flags
+        >> dummy32
+        >> dummy32;
+    if (section.bits_64)
+      cursor >> dummy32;
+    if (!cursor) {
+      reporter_->SectionsMissing(segment.name);
+      return false;
+    }
+    if ((section.flags & SECTION_TYPE) == S_ZEROFILL) {
+      // Zero-fill sections have a size, but no contents.
+      section.contents.start = section.contents.end = NULL;
+    } else if (segment.contents.start == NULL && 
+               segment.contents.end == NULL) {
+      // Mach-O files in .dSYM bundles have the contents of the loaded
+      // segments removed, and their file offsets and file sizes zeroed
+      // out.  However, the sections within those segments still have
+      // non-zero sizes.  There's no reason to call MisplacedSectionData in
+      // this case; the caller may just need the section's load
+      // address. But do set the contents' limits to NULL, for safety.
+      section.contents.start = section.contents.end = NULL;
+    } else {
+      if (offset < size_t(segment.contents.start - buffer_.start) ||
+          offset > size_t(segment.contents.end - buffer_.start) ||
+          size > size_t(segment.contents.end - buffer_.start - offset)) {
+        reporter_->MisplacedSectionData(section.section_name,
+                                        section.segment_name);
+        return false;
+      }
+      section.contents.start = buffer_.start + offset;
+      section.contents.end = section.contents.start + size;
+    }
+    if (!handler->HandleSection(section))
+      return false;
+  }
+  return true;
+}
+
+// A SectionHandler that builds a SectionMap for the sections within a
+// given segment.
+class Reader::SectionMapper: public SectionHandler {
+ public:
+  // Create a SectionHandler that populates MAP with an entry for
+  // each section it is given.
+  SectionMapper(SectionMap *map) : map_(map) { }
+  bool HandleSection(const Section &section) {
+    (*map_)[section.section_name] = section;
+    return true;
+  }
+ private:
+  // The map under construction. (WEAK)
+  SectionMap *map_;
+};
+
+bool Reader::MapSegmentSections(const Segment &segment,
+                                SectionMap *section_map) const {
+  section_map->clear();
+  SectionMapper mapper(section_map);
+  return WalkSegmentSections(segment, &mapper);
+}
+
+}  // namespace mach_o
+}  // namespace google_breakpad
diff --git a/3rdParty/Breakpad/src/common/mac/macho_reader.h b/3rdParty/Breakpad/src/common/mac/macho_reader.h
new file mode 100644
index 0000000..7537648
--- /dev/null
+++ b/3rdParty/Breakpad/src/common/mac/macho_reader.h
@@ -0,0 +1,459 @@
+// -*- mode: C++ -*-
+
+// 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_reader.h: A class for parsing Mach-O files.
+
+#ifndef BREAKPAD_COMMON_MAC_MACHO_READER_H_
+#define BREAKPAD_COMMON_MAC_MACHO_READER_H_
+
+#include <mach-o/loader.h>
+#include <mach-o/fat.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <map>
+#include <string>
+#include <vector>
+
+#include "common/byte_cursor.h"
+
+namespace google_breakpad {
+namespace mach_o {
+
+using std::map;
+using std::string;
+using std::vector;
+
+// The Mac headers don't specify particular types for these groups of
+// constants, but defining them here provides some documentation
+// value.  We also give them the same width as the fields in which
+// they appear, which makes them a bit easier to use with ByteCursors.
+typedef uint32_t Magic;
+typedef uint32_t FileType;
+typedef uint32_t FileFlags;
+typedef uint32_t LoadCommandType;
+typedef uint32_t SegmentFlags;
+typedef uint32_t SectionFlags;
+
+// A parser for fat binary files, used to store universal binaries.
+// When applied to a (non-fat) Mach-O file, this behaves as if the
+// file were a fat file containing a single object file.
+class FatReader {
+ public:
+
+  // A class for reporting errors found while parsing fat binary files. The
+  // default definitions of these methods print messages to stderr.
+  class Reporter {
+   public:
+    // Create a reporter that attributes problems to |filename|.
+    explicit Reporter(const string &filename) : filename_(filename) { }
+
+    virtual ~Reporter() { }
+
+    // The data does not begin with a fat binary or Mach-O magic number.
+    // This is a fatal error.
+    virtual void BadHeader();
+
+    // The Mach-O fat binary file ends abruptly, without enough space
+    // to contain an object file it claims is present.
+    virtual void MisplacedObjectFile();
+
+    // The file ends abruptly: either it is not large enough to hold a
+    // complete header, or the header implies that contents are present
+    // beyond the actual end of the file.
+    virtual void TooShort();
+  
+   private:
+    // The filename to which the reader should attribute problems.
+    string filename_;
+  };
+
+  // Create a fat binary file reader that uses |reporter| to report problems.
+  explicit FatReader(Reporter *reporter) : reporter_(reporter) { }
+  
+  // Read the |size| bytes at |buffer| as a fat binary file. On success,
+  // return true; on failure, report the problem to reporter_ and return
+  // false.
+  //
+  // If the data is a plain Mach-O file, rather than a fat binary file,
+  // then the reader behaves as if it had found a fat binary file whose
+  // single object file is the Mach-O file.
+  bool Read(const uint8_t *buffer, size_t size);
+
+  // Return an array of 'struct fat_arch' structures describing the
+  // object files present in this fat binary file. Set |size| to the
+  // number of elements in the array.
+  //
+  // Assuming Read returned true, the entries are validated: it is
+  // safe to assume that the offsets and sizes in each 'struct
+  // fat_arch' refer to subranges of the bytes passed to Read.
+  //
+  // If there are no object files in this fat binary, then this
+  // function can return NULL.
+  //
+  // The array is owned by this FatReader instance; it will be freed when
+  // this FatReader is destroyed.
+  //
+  // This function returns a C-style array instead of a vector to make it
+  // possible to use the result with OS X functions like NXFindBestFatArch,
+  // so that the symbol dumper will behave consistently with other OS X
+  // utilities that work with fat binaries.
+  const struct fat_arch *object_files(size_t *count) const { 
+    *count = object_files_.size();
+    if (object_files_.size() > 0)
+      return &object_files_[0];
+    return NULL;
+  }
+
+ private:
+  // We use this to report problems parsing the file's contents. (WEAK)
+  Reporter *reporter_;
+
+  // The contents of the fat binary or Mach-O file we're parsing. We do not
+  // own the storage it refers to.
+  ByteBuffer buffer_;
+
+  // The magic number of this binary, in host byte order.
+  Magic magic_;
+
+  // The list of object files in this binary.
+  // object_files_.size() == fat_header.nfat_arch
+  vector<struct fat_arch> object_files_;
+};
+
+// A segment in a Mach-O file. All these fields have been byte-swapped as
+// appropriate for use by the executing architecture.
+struct Segment {
+  // The ByteBuffers below point into the bytes passed to the Reader that
+  // created this Segment.
+
+  ByteBuffer section_list;    // This segment's section list.
+  ByteBuffer contents;        // This segment's contents.
+
+  // This segment's name.
+  string name;
+
+  // The address at which this segment should be loaded in memory. If
+  // bits_64 is false, only the bottom 32 bits of this value are valid.
+  uint64_t vmaddr;
+
+  // The size of this segment when loaded into memory. This may be larger
+  // than contents.Size(), in which case the extra area will be
+  // initialized with zeros. If bits_64 is false, only the bottom 32 bits
+  // of this value are valid.
+  uint64_t vmsize;
+
+  // The maximum and initial VM protection of this segment's contents.
+  uint32_t maxprot;
+  uint32_t initprot;
+  
+  // The number of sections in section_list.
+  uint32_t nsects;
+
+  // Flags describing this segment, from SegmentFlags.
+  uint32_t flags;
+
+  // True if this is a 64-bit section; false if it is a 32-bit section.
+  bool bits_64;
+};
+
+// A section in a Mach-O file. All these fields have been byte-swapped as
+// appropriate for use by the executing architecture.
+struct Section {
+  // This section's contents. This points into the bytes passed to the
+  // Reader that created this Section.
+  ByteBuffer contents;
+
+  // This section's name.
+  string section_name;  // section[_64].sectname
+  // The name of the segment this section belongs to.
+  string segment_name;  // section[_64].segname
+
+  // The address at which this section's contents should be loaded in
+  // memory. If bits_64 is false, only the bottom 32 bits of this value
+  // are valid.
+  uint64_t address;
+
+  // The contents of this section should be loaded into memory at an
+  // address which is a multiple of (two raised to this power).
+  uint32_t align;
+
+  // Flags from SectionFlags describing the section's contents.
+  uint32_t flags;
+
+  // We don't support reading relocations yet.
+
+  // True if this is a 64-bit section; false if it is a 32-bit section.
+  bool bits_64;
+};
+
+// A map from section names to Sections.
+typedef map<string, Section> SectionMap;
+
+// A reader for a Mach-O file.
+//
+// This does not handle fat binaries; see FatReader above. FatReader
+// provides a friendly interface for parsing data that could be either a
+// fat binary or a Mach-O file.
+class Reader {
+ public:
+
+  // A class for reporting errors found while parsing Mach-O files. The
+  // default definitions of these member functions print messages to
+  // stderr.
+  class Reporter {
+   public:
+    // Create a reporter that attributes problems to |filename|.
+    explicit Reporter(const string &filename) : filename_(filename) { }
+    virtual ~Reporter() { }
+
+    // Reporter functions for fatal errors return void; the reader will
+    // definitely return an error to its caller after calling them
+
+    // The data does not begin with a Mach-O magic number, or the magic
+    // number does not match the expected value for the cpu architecture.
+    // This is a fatal error.
+    virtual void BadHeader();
+
+    // The data contained in a Mach-O fat binary (|cpu_type|, |cpu_subtype|)
+    // does not match the expected CPU architecture
+    // (|expected_cpu_type|, |expected_cpu_subtype|).
+    virtual void CPUTypeMismatch(cpu_type_t cpu_type,
+                                 cpu_subtype_t cpu_subtype,
+                                 cpu_type_t expected_cpu_type,
+                                 cpu_subtype_t expected_cpu_subtype);
+
+    // The file ends abruptly: either it is not large enough to hold a
+    // complete header, or the header implies that contents are present
+    // beyond the actual end of the file.
+    virtual void HeaderTruncated();
+
+    // The file's load command region, as given in the Mach-O header, is
+    // too large for the file.
+    virtual void LoadCommandRegionTruncated();
+
+    // The file's Mach-O header claims the file contains |claimed| load
+    // commands, but the I'th load command, of type |type|, extends beyond
+    // the end of the load command region, as given by the Mach-O header.
+    // If |type| is zero, the command's type was unreadable.
+    virtual void LoadCommandsOverrun(size_t claimed, size_t i,
+                                     LoadCommandType type);
+
+    // The contents of the |i|'th load command, of type |type|, extend beyond
+    // the size given in the load command's header.
+    virtual void LoadCommandTooShort(size_t i, LoadCommandType type);
+
+    // The LC_SEGMENT or LC_SEGMENT_64 load command for the segment named
+    // |name| is too short to hold the sections that its header says it does.
+    // (This more specific than LoadCommandTooShort.)
+    virtual void SectionsMissing(const string &name);
+
+    // The segment named |name| claims that its contents lie beyond the end
+    // of the file.
+    virtual void MisplacedSegmentData(const string &name);
+
+    // The section named |section| in the segment named |segment| claims that
+    // its contents do not lie entirely within the segment.
+    virtual void MisplacedSectionData(const string &section,
+                                      const string &segment);
+
+    // The LC_SYMTAB command claims that symbol table contents are located
+    // beyond the end of the file.
+    virtual void MisplacedSymbolTable();
+
+    // An attempt was made to read a Mach-O file of the unsupported
+    // CPU architecture |cpu_type|.
+    virtual void UnsupportedCPUType(cpu_type_t cpu_type);
+
+   private:
+    string filename_;
+  };
+
+  // A handler for sections parsed from a segment. The WalkSegmentSections
+  // member function accepts an instance of this class, and applies it to
+  // each section defined in a given segment.
+  class SectionHandler {
+   public:
+    virtual ~SectionHandler() { }
+
+    // Called to report that the segment's section list contains |section|.
+    // This should return true if the iteration should continue, or false
+    // if it should stop.
+    virtual bool HandleSection(const Section &section) = 0;
+  };
+
+  // A handler for the load commands in a Mach-O file.
+  class LoadCommandHandler {
+   public:
+    LoadCommandHandler() { }
+    virtual ~LoadCommandHandler() { }
+
+    // When called from WalkLoadCommands, the following handler functions
+    // should return true if they wish to continue iterating over the load
+    // command list, or false if they wish to stop iterating.
+    //
+    // When called from LoadCommandIterator::Handle or Reader::Handle,
+    // these functions' return values are simply passed through to Handle's
+    // caller.
+    //
+    // The definitions provided by this base class simply return true; the
+    // default is to silently ignore sections whose member functions the
+    // subclass doesn't override.
+
+    // COMMAND is load command we don't recognize. We provide only the
+    // command type and a ByteBuffer enclosing the command's data (If we
+    // cannot parse the command type or its size, we call
+    // reporter_->IncompleteLoadCommand instead.)
+    virtual bool UnknownCommand(LoadCommandType type,
+                                const ByteBuffer &contents) {
+      return true;
+    }
+
+    // The load command is LC_SEGMENT or LC_SEGMENT_64, defining a segment
+    // with the properties given in |segment|.
+    virtual bool SegmentCommand(const Segment &segment) {
+      return true;
+    }
+
+    // The load command is LC_SYMTAB. |entries| holds the array of nlist
+    // entries, and |names| holds the strings the entries refer to.
+    virtual bool SymtabCommand(const ByteBuffer &entries,
+                               const ByteBuffer &names) {
+      return true;
+    }
+
+    // Add handler functions for more load commands here as needed.
+  };
+
+  // Create a Mach-O file reader that reports problems to |reporter|.
+  explicit Reader(Reporter *reporter)
+      : reporter_(reporter) { }
+
+  // Read the given data as a Mach-O file. The reader retains pointers
+  // into the data passed, so the data should live as long as the reader
+  // does. On success, return true; on failure, return false.
+  //
+  // At most one of these functions should be invoked once on each Reader
+  // instance.
+  bool Read(const uint8_t *buffer,
+            size_t size,
+            cpu_type_t expected_cpu_type,
+            cpu_subtype_t expected_cpu_subtype);
+  bool Read(const ByteBuffer &buffer,
+            cpu_type_t expected_cpu_type,
+            cpu_subtype_t expected_cpu_subtype) {
+    return Read(buffer.start,
+                buffer.Size(),
+                expected_cpu_type,
+                expected_cpu_subtype); 
+  }
+
+  // Return this file's characteristics, as found in the Mach-O header.
+  cpu_type_t    cpu_type()    const { return cpu_type_; }
+  cpu_subtype_t cpu_subtype() const { return cpu_subtype_; }
+  FileType      file_type()   const { return file_type_; }
+  FileFlags     flags()       const { return flags_; }
+
+  // Return true if this is a 64-bit Mach-O file, false if it is a 32-bit
+  // Mach-O file.
+  bool bits_64() const { return bits_64_; }
+
+  // Return true if this is a big-endian Mach-O file, false if it is
+  // little-endian.
+  bool big_endian() const { return big_endian_; }
+
+  // Apply |handler| to each load command in this Mach-O file, stopping when
+  // a handler function returns false. If we encounter a malformed load
+  // command, report it via reporter_ and return false. Return true if all
+  // load commands were parseable and all handlers returned true.
+  bool WalkLoadCommands(LoadCommandHandler *handler) const;
+
+  // Set |segment| to describe the segment named |name|, if present. If
+  // found, |segment|'s byte buffers refer to a subregion of the bytes
+  // passed to Read. If we find the section, return true; otherwise,
+  // return false.
+  bool FindSegment(const string &name, Segment *segment) const;
+
+  // Apply |handler| to each section defined in |segment|. If |handler| returns
+  // false, stop iterating and return false. If all calls to |handler| return
+  // true and we reach the end of the section list, return true.
+  bool WalkSegmentSections(const Segment &segment, SectionHandler *handler)
+    const;
+
+  // Clear |section_map| and then populate it with a map of the sections
+  // in |segment|, from section names to Section structures.
+  // Each Section's contents refer to bytes in |segment|'s contents.
+  // On success, return true; if a problem occurs, report it and return false.
+  bool MapSegmentSections(const Segment &segment, SectionMap *section_map)
+    const;
+
+ private:
+  // Used internally.
+  class SegmentFinder;
+  class SectionMapper;
+
+  // We use this to report problems parsing the file's contents. (WEAK)
+  Reporter *reporter_;
+
+  // The contents of the Mach-O file we're parsing. We do not own the
+  // storage it refers to.
+  ByteBuffer buffer_;
+
+  // True if this file is big-endian.
+  bool big_endian_;
+
+  // True if this file is a 64-bit Mach-O file.
+  bool bits_64_;
+
+  // This file's cpu type and subtype.
+  cpu_type_t cpu_type_;        // mach_header[_64].cputype
+  cpu_subtype_t cpu_subtype_;  // mach_header[_64].cpusubtype
+
+  // This file's type.
+  FileType file_type_;         // mach_header[_64].filetype
+
+  // The region of buffer_ occupied by load commands.
+  ByteBuffer load_commands_;
+
+  // The number of load commands in load_commands_.
+  uint32_t load_command_count_;  // mach_header[_64].ncmds
+
+  // This file's header flags.
+  FileFlags flags_;
+};
+
+}  // namespace mach_o
+}  // namespace google_breakpad
+
+#endif  // BREAKPAD_COMMON_MAC_MACHO_READER_H_
diff --git a/3rdParty/Breakpad/src/common/mac/macho_utilities.cc b/3rdParty/Breakpad/src/common/mac/macho_utilities.cc
new file mode 100644
index 0000000..89f9e77
--- /dev/null
+++ b/3rdParty/Breakpad/src/common/mac/macho_utilities.cc
@@ -0,0 +1,90 @@
+// 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.
+
+// macho_utilties.cc: Utilities for dealing with mach-o files
+//
+// Author: Dave Camp
+
+#include "common/mac/byteswap.h"
+#include "common/mac/macho_utilities.h"
+
+void breakpad_swap_uuid_command(struct breakpad_uuid_command *uc,
+                                enum NXByteOrder target_byte_order)
+{
+  uc->cmd = ByteSwap(uc->cmd);
+  uc->cmdsize = ByteSwap(uc->cmdsize);
+}
+
+void breakpad_swap_segment_command_64(struct segment_command_64 *sg,
+                                      enum NXByteOrder target_byte_order)
+{
+  sg->cmd = ByteSwap(sg->cmd);
+  sg->cmdsize = ByteSwap(sg->cmdsize);
+
+  sg->vmaddr = ByteSwap(sg->vmaddr);
+  sg->vmsize = ByteSwap(sg->vmsize);
+  sg->fileoff = ByteSwap(sg->fileoff);
+  sg->filesize = ByteSwap(sg->filesize);
+
+  sg->maxprot = ByteSwap(sg->maxprot);
+  sg->initprot = ByteSwap(sg->initprot);
+  sg->nsects = ByteSwap(sg->nsects);
+  sg->flags = ByteSwap(sg->flags);
+}
+
+void breakpad_swap_mach_header_64(struct mach_header_64 *mh,
+                                  enum NXByteOrder target_byte_order)
+{
+  mh->magic = ByteSwap(mh->magic);
+  mh->cputype = ByteSwap(mh->cputype);
+  mh->cpusubtype = ByteSwap(mh->cpusubtype);
+  mh->filetype = ByteSwap(mh->filetype);
+  mh->ncmds = ByteSwap(mh->ncmds);
+  mh->sizeofcmds = ByteSwap(mh->sizeofcmds);
+  mh->flags = ByteSwap(mh->flags);
+  mh->reserved = ByteSwap(mh->reserved);
+}
+
+void breakpad_swap_section_64(struct section_64 *s,
+                              uint32_t nsects,
+                              enum NXByteOrder target_byte_order)
+{
+  for (uint32_t i = 0; i < nsects; i++) {
+    s[i].addr = ByteSwap(s[i].addr);
+    s[i].size = ByteSwap(s[i].size);
+
+    s[i].offset = ByteSwap(s[i].offset);
+    s[i].align = ByteSwap(s[i].align);
+    s[i].reloff = ByteSwap(s[i].reloff);
+    s[i].nreloc = ByteSwap(s[i].nreloc);
+    s[i].flags = ByteSwap(s[i].flags);
+    s[i].reserved1 = ByteSwap(s[i].reserved1);
+    s[i].reserved2 = ByteSwap(s[i].reserved2);
+  }
+}
diff --git a/3rdParty/Breakpad/src/common/mac/macho_utilities.h b/3rdParty/Breakpad/src/common/mac/macho_utilities.h
new file mode 100644
index 0000000..a07945f
--- /dev/null
+++ b/3rdParty/Breakpad/src/common/mac/macho_utilities.h
@@ -0,0 +1,92 @@
+// 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.
+
+// macho_utilities.h: Utilities for dealing with mach-o files
+//
+// Author: Dave Camp
+
+#ifndef COMMON_MAC_MACHO_UTILITIES_H__
+#define COMMON_MAC_MACHO_UTILITIES_H__
+
+#include <mach-o/loader.h>
+#include <mach/thread_status.h>
+
+/* Some #defines and structs that aren't defined in older SDKs */
+#ifndef CPU_ARCH_ABI64
+# define CPU_ARCH_ABI64    0x01000000
+#endif
+
+#ifndef CPU_TYPE_X86
+# define CPU_TYPE_X86 CPU_TYPE_I386
+#endif
+
+#ifndef CPU_TYPE_POWERPC64
+# define CPU_TYPE_POWERPC64 (CPU_TYPE_POWERPC | CPU_ARCH_ABI64)
+#endif
+
+#ifndef LC_UUID
+# define LC_UUID         0x1b    /* the uuid */
+#endif
+
+#if TARGET_CPU_X86
+# define BREAKPAD_MACHINE_THREAD_STATE i386_THREAD_STATE
+#elif TARGET_CPU_X86_64
+# define BREAKPAD_MACHINE_THREAD_STATE x86_THREAD_STATE64
+#else
+# define BREAKPAD_MACHINE_THREAD_STATE MACHINE_THREAD_STATE
+#endif
+
+// The uuid_command struct/swap routines were added during the 10.4 series.
+// Their presence isn't guaranteed.
+struct breakpad_uuid_command {
+  uint32_t    cmd;            /* LC_UUID */
+  uint32_t    cmdsize;        /* sizeof(struct uuid_command) */
+  uint8_t     uuid[16];       /* the 128-bit uuid */
+};
+
+void breakpad_swap_uuid_command(struct breakpad_uuid_command *uc,
+                                enum NXByteOrder target_byte_order);
+
+// Older SDKs defines thread_state_data_t as an int[] instead
+// of the natural_t[] it should be.
+typedef natural_t breakpad_thread_state_data_t[THREAD_STATE_MAX];
+
+// The 64-bit swap routines were added during the 10.4 series, their
+// presence isn't guaranteed.
+void breakpad_swap_segment_command_64(struct segment_command_64 *sg,
+                                      enum NXByteOrder target_byte_order);
+
+void breakpad_swap_mach_header_64(struct mach_header_64 *mh,
+                                  enum NXByteOrder target_byte_order);
+
+void breakpad_swap_section_64(struct section_64 *s,
+                              uint32_t nsects,
+                              enum NXByteOrder target_byte_order);
+
+#endif
diff --git a/3rdParty/Breakpad/src/common/mac/macho_walker.cc b/3rdParty/Breakpad/src/common/mac/macho_walker.cc
new file mode 100644
index 0000000..92da7b1
--- /dev/null
+++ b/3rdParty/Breakpad/src/common/mac/macho_walker.cc
@@ -0,0 +1,267 @@
+// 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.
+
+// macho_walker.cc: Iterate over the load commands in a mach-o file
+//
+// See macho_walker.h for documentation
+//
+// Author: Dan Waylonis
+
+extern "C" {  // necessary for Leopard
+  #include <assert.h>
+  #include <fcntl.h>
+  #include <mach-o/arch.h>
+  #include <mach-o/loader.h>
+  #include <mach-o/swap.h>
+  #include <string.h>
+  #include <unistd.h>
+}
+
+#include "common/mac/byteswap.h"
+#include "common/mac/macho_walker.h"
+#include "common/mac/macho_utilities.h"
+
+namespace MacFileUtilities {
+
+MachoWalker::MachoWalker(const char *path, LoadCommandCallback callback,
+                         void *context)
+    : file_(0),
+      memory_(NULL),
+      memory_size_(0),
+      callback_(callback),
+      callback_context_(context),
+      current_header_(NULL),
+      current_header_size_(0),
+      current_header_offset_(0) {
+  file_ = open(path, O_RDONLY);
+}
+
+MachoWalker::MachoWalker(void *memory, size_t size,
+                         LoadCommandCallback callback, void *context)
+    : file_(0),
+      memory_(memory),
+      memory_size_(size),
+      callback_(callback),
+      callback_context_(context),
+      current_header_(NULL),
+      current_header_size_(0),
+      current_header_offset_(0) {
+}
+
+MachoWalker::~MachoWalker() {
+  if (file_ != -1)
+    close(file_);
+}
+
+int MachoWalker::ValidateCPUType(int cpu_type) {
+  // If the user didn't specify, use the local architecture.
+  if (cpu_type == 0) {
+    const NXArchInfo *arch = NXGetLocalArchInfo();
+    assert(arch);
+    cpu_type = arch->cputype;
+  }
+
+  return cpu_type;
+}
+
+bool MachoWalker::WalkHeader(int cpu_type) {
+  int valid_cpu_type = ValidateCPUType(cpu_type);
+  off_t offset;
+  if (FindHeader(valid_cpu_type, offset)) {
+    if (cpu_type & CPU_ARCH_ABI64)
+      return WalkHeader64AtOffset(offset);
+
+    return WalkHeaderAtOffset(offset);
+  }
+
+  return false;
+}
+
+bool MachoWalker::ReadBytes(void *buffer, size_t size, off_t offset) {
+  if (memory_) {
+    if (offset < 0)
+      return false;
+    bool result = true;
+    if (offset + size > memory_size_) {
+      if (static_cast<size_t>(offset) >= memory_size_)
+        return false;
+      size = memory_size_ - offset;
+      result = false;
+    }
+    memcpy(buffer, static_cast<char *>(memory_) + offset, size);
+    return result;
+  } else {
+    return pread(file_, buffer, size, offset) == (ssize_t)size;
+  }
+}
+
+bool MachoWalker::CurrentHeader(struct mach_header_64 *header, off_t *offset) {
+  if (current_header_) {
+    memcpy(header, current_header_, sizeof(mach_header_64));
+    *offset = current_header_offset_;
+    return true;
+  }
+
+  return false;
+}
+
+bool MachoWalker::FindHeader(int cpu_type, off_t &offset) {
+  int valid_cpu_type = ValidateCPUType(cpu_type);
+  // Read the magic bytes that's common amongst all mach-o files
+  uint32_t magic;
+  if (!ReadBytes(&magic, sizeof(magic), 0))
+    return false;
+
+  offset = sizeof(magic);
+
+  // Figure out what type of file we've got
+  bool is_fat = false;
+  if (magic == FAT_MAGIC || magic == FAT_CIGAM) {
+    is_fat = true;
+  }
+  else if (magic != MH_MAGIC && magic != MH_CIGAM && magic != MH_MAGIC_64 &&
+           magic != MH_CIGAM_64) {
+    return false;
+  }
+
+  if (!is_fat) {
+    // If we don't have a fat header, check if the cpu type matches the single
+    // header
+    cpu_type_t header_cpu_type;
+    if (!ReadBytes(&header_cpu_type, sizeof(header_cpu_type), offset))
+      return false;
+
+    if (magic == MH_CIGAM || magic == MH_CIGAM_64)
+      header_cpu_type = ByteSwap(header_cpu_type);
+
+    if (valid_cpu_type != header_cpu_type)
+      return false;
+
+    offset = 0;
+    return true;
+  } else {
+    // Read the fat header and find an appropriate architecture
+    offset = 0;
+    struct fat_header fat;
+    if (!ReadBytes(&fat, sizeof(fat), offset))
+      return false;
+
+    if (NXHostByteOrder() != NX_BigEndian)
+      swap_fat_header(&fat, NXHostByteOrder());
+
+    offset += sizeof(fat);
+
+    // Search each architecture for the desired one
+    struct fat_arch arch;
+    for (uint32_t i = 0; i < fat.nfat_arch; ++i) {
+      if (!ReadBytes(&arch, sizeof(arch), offset))
+        return false;
+
+      if (NXHostByteOrder() != NX_BigEndian)
+        swap_fat_arch(&arch, 1, NXHostByteOrder());
+
+      if (arch.cputype == valid_cpu_type) {
+        offset = arch.offset;
+        return true;
+      }
+
+      offset += sizeof(arch);
+    }
+  }
+
+  return false;
+}
+
+bool MachoWalker::WalkHeaderAtOffset(off_t offset) {
+  struct mach_header header;
+  if (!ReadBytes(&header, sizeof(header), offset))
+    return false;
+
+  bool swap = (header.magic == MH_CIGAM);
+  if (swap)
+    swap_mach_header(&header, NXHostByteOrder());
+
+  // Copy the data into the mach_header_64 structure.  Since the 32-bit and
+  // 64-bit only differ in the last field (reserved), this is safe to do.
+  struct mach_header_64 header64;
+  memcpy((void *)&header64, (const void *)&header, sizeof(header));
+  header64.reserved = 0;
+
+  current_header_ = &header64;
+  current_header_size_ = sizeof(header); // 32-bit, not 64-bit
+  current_header_offset_ = offset;
+  offset += current_header_size_;
+  bool result = WalkHeaderCore(offset, header.ncmds, swap);
+  current_header_ = NULL;
+  current_header_size_ = 0;
+  current_header_offset_ = 0;
+  return result;
+}
+
+bool MachoWalker::WalkHeader64AtOffset(off_t offset) {
+  struct mach_header_64 header;
+  if (!ReadBytes(&header, sizeof(header), offset))
+    return false;
+
+  bool swap = (header.magic == MH_CIGAM_64);
+  if (swap)
+    breakpad_swap_mach_header_64(&header, NXHostByteOrder());
+
+  current_header_ = &header;
+  current_header_size_ = sizeof(header);
+  current_header_offset_ = offset;
+  offset += current_header_size_;
+  bool result = WalkHeaderCore(offset, header.ncmds, swap);
+  current_header_ = NULL;
+  current_header_size_ = 0;
+  current_header_offset_ = 0;
+  return result;
+}
+
+bool MachoWalker::WalkHeaderCore(off_t offset, uint32_t number_of_commands,
+                                 bool swap) {
+  for (uint32_t i = 0; i < number_of_commands; ++i) {
+    struct load_command cmd;
+    if (!ReadBytes(&cmd, sizeof(cmd), offset))
+      return false;
+
+    if (swap)
+      swap_load_command(&cmd, NXHostByteOrder());
+
+    // Call the user callback
+    if (callback_ && !callback_(this, &cmd, offset, swap, callback_context_))
+      break;
+
+    offset += cmd.cmdsize;
+  }
+
+  return true;
+}
+
+}  // namespace MacFileUtilities
diff --git a/3rdParty/Breakpad/src/common/mac/macho_walker.h b/3rdParty/Breakpad/src/common/mac/macho_walker.h
new file mode 100644
index 0000000..cee3eb8
--- /dev/null
+++ b/3rdParty/Breakpad/src/common/mac/macho_walker.h
@@ -0,0 +1,117 @@
+// 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.
+
+// macho_walker.h: Iterate over the load commands in a mach-o file
+//
+// Author: Dan Waylonis
+
+#ifndef COMMON_MAC_MACHO_WALKER_H__
+#define COMMON_MAC_MACHO_WALKER_H__
+
+#include <mach-o/loader.h>
+#include <sys/types.h>
+
+namespace MacFileUtilities {
+
+class MachoWalker {
+ public:
+  // A callback function executed when a new load command is read.  If no
+  // further processing of load commands is desired, return false.  Otherwise,
+  // return true.
+  // |cmd| is the current command, and |offset| is the location relative to the
+  // beginning of the file (not header) where the command was read.  If |swap|
+  // is set, then any command data (other than the returned load_command) should
+  // be swapped when read
+  typedef bool (*LoadCommandCallback)(MachoWalker *walker, load_command *cmd,
+                                      off_t offset, bool swap, void *context);
+
+  MachoWalker(const char *path, LoadCommandCallback callback, void *context);
+  MachoWalker(void *memory, size_t size, LoadCommandCallback callback,
+              void *context);
+  ~MachoWalker();
+
+  // Begin walking the header for |cpu_type|.  If |cpu_type| is 0, then the
+  // native cpu type is used.  Otherwise, accepted values are listed in
+  // /usr/include/mach/machine.h (e.g., CPU_TYPE_X86 or CPU_TYPE_POWERPC).
+  // Returns false if opening the file failed or if the |cpu_type| is not
+  // present in the file.
+  bool WalkHeader(int cpu_type);
+
+  // Locate (if any) the header offset for |cpu_type| and return in |offset|.
+  // Return true if found, false otherwise.
+  bool FindHeader(int cpu_type, off_t &offset);
+
+  // Read |size| bytes from the opened file at |offset| into |buffer|
+  bool ReadBytes(void *buffer, size_t size, off_t offset);
+
+  // Return the current header and header offset
+  bool CurrentHeader(struct mach_header_64 *header, off_t *offset);
+
+ private:
+  // Validate the |cpu_type|
+  int ValidateCPUType(int cpu_type);
+
+  // Process an individual header starting at |offset| from the start of the
+  // file.  Return true if successful, false otherwise.
+  bool WalkHeaderAtOffset(off_t offset);
+  bool WalkHeader64AtOffset(off_t offset);
+
+  // Bottleneck for walking the load commands
+  bool WalkHeaderCore(off_t offset, uint32_t number_of_commands, bool swap);
+
+  // File descriptor to the opened file
+  int file_;
+
+  // Memory location to read from.
+  void *memory_;
+
+  // Size of the memory segment we can read from.
+  size_t memory_size_;
+
+  // User specified callback & context
+  LoadCommandCallback callback_;
+  void *callback_context_;
+
+  // Current header, size, and offset.  The mach_header_64 is used for both
+  // 32-bit and 64-bit headers because they only differ in their last field
+  // (reserved).  By adding the |current_header_size_| and the
+  // |current_header_offset_|, you can determine the offset in the file just
+  // after the header.
+  struct mach_header_64 *current_header_;
+  unsigned long current_header_size_;
+  off_t current_header_offset_;
+
+ private:
+  MachoWalker(const MachoWalker &);
+  MachoWalker &operator=(const MachoWalker &);
+};
+
+}  // namespace MacFileUtilities
+
+#endif  // COMMON_MAC_MACHO_WALKER_H__
diff --git a/3rdParty/Breakpad/src/common/mac/scoped_task_suspend-inl.h b/3rdParty/Breakpad/src/common/mac/scoped_task_suspend-inl.h
new file mode 100644
index 0000000..d6d1bef
--- /dev/null
+++ b/3rdParty/Breakpad/src/common/mac/scoped_task_suspend-inl.h
@@ -0,0 +1,56 @@
+// 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.
+
+// Inline implementation of ScopedTaskSuspend, which suspends a Mach
+// task for the duration of its scope.
+
+#ifndef GOOGLE_BREAKPAD_COMMON_MAC_SCOPED_TASK_SUSPEND_H_
+#define GOOGLE_BREAKPAD_COMMON_MAC_SCOPED_TASK_SUSPEND_H_
+
+#include <mach/mach.h>
+
+namespace google_breakpad {
+
+class ScopedTaskSuspend {
+ public:
+  explicit ScopedTaskSuspend(mach_port_t target) : target_(target) {
+    task_suspend(target_);
+  }
+
+  ~ScopedTaskSuspend() {
+    task_resume(target_);
+  }
+
+ private:
+  mach_port_t target_;
+};
+
+}  // namespace google_breakpad
+
+#endif  // GOOGLE_BREAKPAD_COMMON_MAC_SCOPED_TASK_SUSPEND_H_
diff --git a/3rdParty/Breakpad/src/common/mac/string_utilities.cc b/3rdParty/Breakpad/src/common/mac/string_utilities.cc
new file mode 100644
index 0000000..e1f63a9
--- /dev/null
+++ b/3rdParty/Breakpad/src/common/mac/string_utilities.cc
@@ -0,0 +1,84 @@
+// 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 "processor/scoped_ptr.h"
+#include "common/mac/string_utilities.h"
+
+namespace MacStringUtils {
+
+using google_breakpad::scoped_array;
+
+std::string ConvertToString(CFStringRef str) {
+  CFIndex length = CFStringGetLength(str);
+  std::string result;
+
+  if (!length)
+    return result;
+
+  CFIndex maxUTF8Length =
+    CFStringGetMaximumSizeForEncoding(length, kCFStringEncodingUTF8);
+  scoped_array<UInt8> buffer(new UInt8[maxUTF8Length + 1]);
+  CFIndex actualUTF8Length;
+  CFStringGetBytes(str, CFRangeMake(0, length), kCFStringEncodingUTF8, 0,
+                   false, buffer.get(), maxUTF8Length, &actualUTF8Length);
+  buffer[actualUTF8Length] = 0;
+  result.assign((const char *)buffer.get());
+
+  return result;
+}
+
+unsigned int IntegerValueAtIndex(string &str, unsigned int idx) {
+  string digits("0123456789"), temp;
+  size_t start = 0;
+  size_t end;
+  size_t found = 0;
+  unsigned int result = 0;
+
+  for (; found <= idx; ++found) {
+    end = str.find_first_not_of(digits, start);
+
+    if (end == string::npos)
+      end = str.size();
+
+    temp = str.substr(start, end - start);
+
+    if (found == idx) {
+      result = atoi(temp.c_str());
+    }
+
+    start = str.find_first_of(digits, end + 1);
+
+    if (start == string::npos)
+      break;
+  }
+
+  return result;
+}
+
+}  // namespace MacStringUtils
diff --git a/3rdParty/Breakpad/src/common/mac/string_utilities.h b/3rdParty/Breakpad/src/common/mac/string_utilities.h
new file mode 100644
index 0000000..6d89c83
--- /dev/null
+++ b/3rdParty/Breakpad/src/common/mac/string_utilities.h
@@ -0,0 +1,52 @@
+// 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.
+
+// string_utilities.h: Utilities for strings for Mac platform
+
+#ifndef COMMON_MAC_STRING_UTILITIES_H__
+#define COMMON_MAC_STRING_UTILITIES_H__
+
+#include <CoreFoundation/CoreFoundation.h>
+
+#include <string>
+
+namespace MacStringUtils {
+
+using std::string;
+
+// Convert a CoreFoundation string into a std::string
+string ConvertToString(CFStringRef str);
+
+// Return the idx'th decimal integer in str, separated by non-decimal-digits
+// E.g., str = 10.4.8, idx = 1 -> 4
+unsigned int IntegerValueAtIndex(string &str, unsigned int idx);
+
+}  // namespace MacStringUtils
+
+#endif  // COMMON_MAC_STRING_UTILITIES_H__
diff --git a/3rdParty/Breakpad/src/common/md5.cc b/3rdParty/Breakpad/src/common/md5.cc
new file mode 100644
index 0000000..bccf61c
--- /dev/null
+++ b/3rdParty/Breakpad/src/common/md5.cc
@@ -0,0 +1,251 @@
+/*
+ * written by Colin Plumb in 1993, no copyright is claimed.
+ * This code is in the public domain; do with it what you wish.
+ *
+ * Equivalent code is available from RSA Data Security, Inc.
+ * This code has been tested against that, and is equivalent,
+ * except that you don't need to include two pages of legalese
+ * with every copy.
+ *
+ * To compute the message digest of a chunk of bytes, declare an
+ * MD5Context structure, pass it to MD5Init, call MD5Update as
+ * needed on buffers full of bytes, and then call MD5Final, which
+ * will fill a supplied 16-byte array with the digest.
+ */
+
+#include <string.h>
+
+#include "common/md5.h"
+
+namespace google_breakpad {
+
+#ifndef WORDS_BIGENDIAN
+#define byteReverse(buf, len)   /* Nothing */
+#else
+/*
+ * Note: this code is harmless on little-endian machines.
+ */
+static void byteReverse(unsigned char *buf, unsigned longs)
+{
+  u32 t;
+  do {
+    t = (u32) ((unsigned) buf[3] << 8 | buf[2]) << 16 |
+      ((unsigned) buf[1] << 8 | buf[0]);
+    *(u32 *) buf = t;
+    buf += 4;
+  } while (--longs);
+}
+#endif
+
+static void MD5Transform(u32 buf[4], u32 const in[16]);
+
+/*
+ * Start MD5 accumulation.  Set bit count to 0 and buffer to mysterious
+ * initialization constants.
+ */
+void MD5Init(struct MD5Context *ctx)
+{
+  ctx->buf[0] = 0x67452301;
+  ctx->buf[1] = 0xefcdab89;
+  ctx->buf[2] = 0x98badcfe;
+  ctx->buf[3] = 0x10325476;
+
+  ctx->bits[0] = 0;
+  ctx->bits[1] = 0;
+}
+
+/*
+ * Update context to reflect the concatenation of another buffer full
+ * of bytes.
+ */
+void MD5Update(struct MD5Context *ctx, unsigned char const *buf, unsigned len)
+{
+  u32 t;
+
+  /* Update bitcount */
+
+  t = ctx->bits[0];
+  if ((ctx->bits[0] = t + ((u32) len << 3)) < t)
+    ctx->bits[1]++;         /* Carry from low to high */
+  ctx->bits[1] += len >> 29;
+
+  t = (t >> 3) & 0x3f;        /* Bytes already in shsInfo->data */
+
+  /* Handle any leading odd-sized chunks */
+
+  if (t) {
+    unsigned char *p = (unsigned char *) ctx->in + t;
+
+    t = 64 - t;
+    if (len < t) {
+      memcpy(p, buf, len);
+      return;
+    }
+    memcpy(p, buf, t);
+    byteReverse(ctx->in, 16);
+    MD5Transform(ctx->buf, (u32 *) ctx->in);
+    buf += t;
+    len -= t;
+  }
+  /* Process data in 64-byte chunks */
+
+  while (len >= 64) {
+    memcpy(ctx->in, buf, 64);
+    byteReverse(ctx->in, 16);
+    MD5Transform(ctx->buf, (u32 *) ctx->in);
+    buf += 64;
+    len -= 64;
+  }
+
+  /* Handle any remaining bytes of data. */
+
+  memcpy(ctx->in, buf, len);
+}
+
+/*
+ * Final wrapup - pad to 64-byte boundary with the bit pattern
+ * 1 0* (64-bit count of bits processed, MSB-first)
+ */
+void MD5Final(unsigned char digest[16], struct MD5Context *ctx)
+{
+  unsigned count;
+  unsigned char *p;
+
+  /* Compute number of bytes mod 64 */
+  count = (ctx->bits[0] >> 3) & 0x3F;
+
+  /* Set the first char of padding to 0x80.  This is safe since there is
+     always at least one byte free */
+  p = ctx->in + count;
+  *p++ = 0x80;
+
+  /* Bytes of padding needed to make 64 bytes */
+  count = 64 - 1 - count;
+
+  /* Pad out to 56 mod 64 */
+  if (count < 8) {
+    /* Two lots of padding:  Pad the first block to 64 bytes */
+    memset(p, 0, count);
+    byteReverse(ctx->in, 16);
+    MD5Transform(ctx->buf, (u32 *) ctx->in);
+
+    /* Now fill the next block with 56 bytes */
+    memset(ctx->in, 0, 56);
+  } else {
+    /* Pad block to 56 bytes */
+    memset(p, 0, count - 8);
+  }
+  byteReverse(ctx->in, 14);
+
+  /* Append length in bits and transform */
+  ((u32 *) ctx->in)[14] = ctx->bits[0];
+  ((u32 *) ctx->in)[15] = ctx->bits[1];
+
+  MD5Transform(ctx->buf, (u32 *) ctx->in);
+  byteReverse((unsigned char *) ctx->buf, 4);
+  memcpy(digest, ctx->buf, 16);
+  memset(ctx, 0, sizeof(*ctx));        /* In case it's sensitive */
+}
+
+/* The four core functions - F1 is optimized somewhat */
+
+/* #define F1(x, y, z) (x & y | ~x & z) */
+#define F1(x, y, z) (z ^ (x & (y ^ z)))
+#define F2(x, y, z) F1(z, x, y)
+#define F3(x, y, z) (x ^ y ^ z)
+#define F4(x, y, z) (y ^ (x | ~z))
+
+/* This is the central step in the MD5 algorithm. */
+#define MD5STEP(f, w, x, y, z, data, s) \
+  ( w += f(x, y, z) + data,  w = w<<s | w>>(32-s),  w += x )
+
+/*
+ * The core of the MD5 algorithm, this alters an existing MD5 hash to
+ * reflect the addition of 16 longwords of new data.  MD5Update blocks
+ * the data and converts bytes into longwords for this routine.
+ */
+static void MD5Transform(u32 buf[4], u32 const in[16])
+{
+  register u32 a, b, c, d;
+
+  a = buf[0];
+  b = buf[1];
+  c = buf[2];
+  d = buf[3];
+
+  MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7);
+  MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12);
+  MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17);
+  MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22);
+  MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7);
+  MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12);
+  MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17);
+  MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22);
+  MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7);
+  MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12);
+  MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
+  MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
+  MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7);
+  MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);
+  MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);
+  MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);
+
+  MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5);
+  MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9);
+  MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
+  MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20);
+  MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5);
+  MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9);
+  MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
+  MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20);
+  MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5);
+  MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9);
+  MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14);
+  MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20);
+  MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);
+  MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9);
+  MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14);
+  MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
+
+  MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4);
+  MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11);
+  MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
+  MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
+  MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4);
+  MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11);
+  MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16);
+  MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
+  MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4);
+  MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11);
+  MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16);
+  MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23);
+  MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4);
+  MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
+  MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
+  MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23);
+
+  MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6);
+  MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10);
+  MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
+  MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21);
+  MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6);
+  MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10);
+  MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
+  MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21);
+  MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6);
+  MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
+  MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15);
+  MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
+  MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6);
+  MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
+  MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15);
+  MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21);
+
+  buf[0] += a;
+  buf[1] += b;
+  buf[2] += c;
+  buf[3] += d;
+}
+
+}  // namespace google_breakpad
+
diff --git a/3rdParty/Breakpad/src/common/md5.h b/3rdParty/Breakpad/src/common/md5.h
new file mode 100644
index 0000000..e96521e
--- /dev/null
+++ b/3rdParty/Breakpad/src/common/md5.h
@@ -0,0 +1,27 @@
+// Copyright 2007 Google Inc. All Rights Reserved.
+// Author: liuli@google.com (Liu Li)
+#ifndef COMMON_MD5_H__
+#define COMMON_MD5_H__
+
+#include <stdint.h>
+
+namespace google_breakpad {
+
+typedef uint32_t u32;
+typedef uint8_t u8;
+
+struct MD5Context {
+  u32 buf[4];
+  u32 bits[2];
+  u8 in[64];
+};
+
+void MD5Init(struct MD5Context *ctx);
+
+void MD5Update(struct MD5Context *ctx, unsigned char const *buf, unsigned len);
+
+void MD5Final(unsigned char digest[16], struct MD5Context *ctx);
+
+}  // namespace google_breakpad
+
+#endif  // COMMON_MD5_H__
diff --git a/3rdParty/Breakpad/src/common/memory.h b/3rdParty/Breakpad/src/common/memory.h
new file mode 100644
index 0000000..e90bd52
--- /dev/null
+++ b/3rdParty/Breakpad/src/common/memory.h
@@ -0,0 +1,218 @@
+// 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.
+
+#ifndef GOOGLE_BREAKPAD_COMMON_MEMORY_H_
+#define GOOGLE_BREAKPAD_COMMON_MEMORY_H_
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/mman.h>
+
+#ifdef __APPLE__
+#define sys_mmap mmap
+#define sys_mmap2 mmap
+#define sys_munmap munmap
+#define MAP_ANONYMOUS MAP_ANON
+#else
+#include "third_party/lss/linux_syscall_support.h"
+#endif
+
+namespace google_breakpad {
+
+// This is very simple allocator which fetches pages from the kernel directly.
+// Thus, it can be used even when the heap may be corrupted.
+//
+// There is no free operation. The pages are only freed when the object is
+// destroyed.
+class PageAllocator {
+ public:
+  PageAllocator()
+      : page_size_(getpagesize()),
+        last_(NULL),
+        current_page_(NULL),
+        page_offset_(0) {
+  }
+
+  ~PageAllocator() {
+    FreeAll();
+  }
+
+  void *Alloc(unsigned bytes) {
+    if (!bytes)
+      return NULL;
+
+    if (current_page_ && page_size_ - page_offset_ >= bytes) {
+      uint8_t *const ret = current_page_ + page_offset_;
+      page_offset_ += bytes;
+      if (page_offset_ == page_size_) {
+        page_offset_ = 0;
+        current_page_ = NULL;
+      }
+
+      return ret;
+    }
+
+    const unsigned pages =
+        (bytes + sizeof(PageHeader) + page_size_ - 1) / page_size_;
+    uint8_t *const ret = GetNPages(pages);
+    if (!ret)
+      return NULL;
+
+    page_offset_ = (page_size_ - (page_size_ * pages - (bytes + sizeof(PageHeader)))) % page_size_;
+    current_page_ = page_offset_ ? ret + page_size_ * (pages - 1) : NULL;
+
+    return ret + sizeof(PageHeader);
+  }
+
+ private:
+  uint8_t *GetNPages(unsigned num_pages) {
+#ifdef __x86_64
+    void *a = sys_mmap(NULL, page_size_ * num_pages, PROT_READ | PROT_WRITE,
+                       MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+#else
+    void *a = sys_mmap2(NULL, page_size_ * num_pages, PROT_READ | PROT_WRITE,
+                        MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+#endif
+    if (a == MAP_FAILED)
+      return NULL;
+
+    struct PageHeader *header = reinterpret_cast<PageHeader*>(a);
+    header->next = last_;
+    header->num_pages = num_pages;
+    last_ = header;
+
+    return reinterpret_cast<uint8_t*>(a);
+  }
+
+  void FreeAll() {
+    PageHeader *next;
+
+    for (PageHeader *cur = last_; cur; cur = next) {
+      next = cur->next;
+      sys_munmap(cur, cur->num_pages * page_size_);
+    }
+  }
+
+  struct PageHeader {
+    PageHeader *next;  // pointer to the start of the next set of pages.
+    unsigned num_pages;  // the number of pages in this set.
+  };
+
+  const unsigned page_size_;
+  PageHeader *last_;
+  uint8_t *current_page_;
+  unsigned page_offset_;
+};
+
+// A wasteful vector is like a normal std::vector, except that it's very much
+// simplier and it allocates memory from a PageAllocator. It's wasteful
+// because, when resizing, it always allocates a whole new array since the
+// PageAllocator doesn't support realloc.
+template<class T>
+class wasteful_vector {
+ public:
+  wasteful_vector(PageAllocator *allocator, unsigned size_hint = 16)
+      : allocator_(allocator),
+        a_((T*) allocator->Alloc(sizeof(T) * size_hint)),
+        allocated_(size_hint),
+        used_(0) {
+  }
+
+  T& back() {
+    return a_[used_ - 1];
+  }
+
+  const T& back() const {
+    return a_[used_ - 1];
+  }
+
+  bool empty() const {
+    return used_ == 0;
+  }
+
+  void push_back(const T& new_element) {
+    if (used_ == allocated_)
+      Realloc(allocated_ * 2);
+    a_[used_++] = new_element;
+  }
+
+  size_t size() const {
+    return used_;
+  }
+
+  void resize(unsigned sz, T c = T()) {
+    // No need to test "sz >= 0", as "sz" is unsigned.
+    if (sz <= used_) {
+      used_ = sz;
+    } else {
+      unsigned a = allocated_;
+      if (sz > a) {
+        while (sz > a) {
+          a *= 2;
+        }
+        Realloc(a);
+      }
+      while (sz > used_) {
+        a_[used_++] = c;
+      }
+    }
+  }
+
+  T& operator[](size_t index) {
+    return a_[index];
+  }
+
+  const T& operator[](size_t index) const {
+    return a_[index];
+  }
+
+ private:
+  void Realloc(unsigned new_size) {
+    T *new_array =
+        reinterpret_cast<T*>(allocator_->Alloc(sizeof(T) * new_size));
+    memcpy(new_array, a_, used_ * sizeof(T));
+    a_ = new_array;
+    allocated_ = new_size;
+  }
+
+  PageAllocator *const allocator_;
+  T *a_;  // pointer to an array of |allocated_| elements.
+  unsigned allocated_;  // size of |a_|, in elements.
+  unsigned used_;  // number of used slots in |a_|.
+};
+
+}  // namespace google_breakpad
+
+inline void* operator new(size_t nbytes,
+                          google_breakpad::PageAllocator& allocator) {
+   return allocator.Alloc(nbytes);
+}
+
+#endif  // GOOGLE_BREAKPAD_COMMON_MEMORY_H_
diff --git a/3rdParty/Breakpad/src/common/module.cc b/3rdParty/Breakpad/src/common/module.cc
new file mode 100644
index 0000000..4e257d1
--- /dev/null
+++ b/3rdParty/Breakpad/src/common/module.cc
@@ -0,0 +1,294 @@
+// 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.
+
+// Original author: Jim Blandy <jimb@mozilla.com> <jimb@red-bean.com>
+
+// module.cc: Implement google_breakpad::Module.  See module.h.
+
+#include "common/module.h"
+
+#include <assert.h>
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <iostream>
+#include <utility>
+
+namespace google_breakpad {
+
+using std::dec;
+using std::endl;
+using std::hex;
+
+
+Module::Module(const string &name, const string &os,
+               const string &architecture, const string &id) :
+    name_(name),
+    os_(os),
+    architecture_(architecture),
+    id_(id),
+    load_address_(0) { }
+
+Module::~Module() {
+  for (FileByNameMap::iterator it = files_.begin(); it != files_.end(); ++it)
+    delete it->second;
+  for (FunctionSet::iterator it = functions_.begin();
+       it != functions_.end(); ++it) {
+    delete *it;
+  }
+  for (vector<StackFrameEntry *>::iterator it = stack_frame_entries_.begin();
+       it != stack_frame_entries_.end(); ++it) {
+    delete *it;
+  }
+  for (ExternSet::iterator it = externs_.begin(); it != externs_.end(); ++it)
+    delete *it;
+}
+
+void Module::SetLoadAddress(Address address) {
+  load_address_ = address;
+}
+
+void Module::AddFunction(Function *function) {
+  // FUNC lines must not hold an empty name, so catch the problem early if
+  // callers try to add one.
+  assert(!function->name.empty());
+  std::pair<FunctionSet::iterator,bool> ret = functions_.insert(function);
+  if (!ret.second) {
+    // Free the duplicate that was not inserted because this Module
+    // now owns it.
+    delete function;
+  }
+}
+
+void Module::AddFunctions(vector<Function *>::iterator begin,
+                          vector<Function *>::iterator end) {
+  for (vector<Function *>::iterator it = begin; it != end; ++it)
+    AddFunction(*it);
+}
+
+void Module::AddStackFrameEntry(StackFrameEntry *stack_frame_entry) {
+  stack_frame_entries_.push_back(stack_frame_entry);
+}
+
+void Module::AddExtern(Extern *ext) {
+  std::pair<ExternSet::iterator,bool> ret = externs_.insert(ext);
+  if (!ret.second) {
+    // Free the duplicate that was not inserted because this Module
+    // now owns it.
+    delete ext;
+  }
+}
+
+void Module::GetFunctions(vector<Function *> *vec,
+                          vector<Function *>::iterator i) {
+  vec->insert(i, functions_.begin(), functions_.end());
+}
+
+void Module::GetExterns(vector<Extern *> *vec,
+                        vector<Extern *>::iterator i) {
+  vec->insert(i, externs_.begin(), externs_.end());
+}
+
+Module::File *Module::FindFile(const string &name) {
+  // A tricky bit here.  The key of each map entry needs to be a
+  // pointer to the entry's File's name string.  This means that we
+  // can't do the initial lookup with any operation that would create
+  // an empty entry for us if the name isn't found (like, say,
+  // operator[] or insert do), because such a created entry's key will
+  // be a pointer the string passed as our argument.  Since the key of
+  // a map's value type is const, we can't fix it up once we've
+  // created our file.  lower_bound does the lookup without doing an
+  // insertion, and returns a good hint iterator to pass to insert.
+  // Our "destiny" is where we belong, whether we're there or not now.
+  FileByNameMap::iterator destiny = files_.lower_bound(&name);
+  if (destiny == files_.end()
+      || *destiny->first != name) {  // Repeated string comparison, boo hoo.
+    File *file = new File;
+    file->name = name;
+    file->source_id = -1;
+    destiny = files_.insert(destiny,
+                            FileByNameMap::value_type(&file->name, file));
+  }
+  return destiny->second;
+}
+
+Module::File *Module::FindFile(const char *name) {
+  string name_string = name;
+  return FindFile(name_string);
+}
+
+Module::File *Module::FindExistingFile(const string &name) {
+  FileByNameMap::iterator it = files_.find(&name);
+  return (it == files_.end()) ? NULL : it->second;
+}
+
+void Module::GetFiles(vector<File *> *vec) {
+  vec->clear();
+  for (FileByNameMap::iterator it = files_.begin(); it != files_.end(); ++it)
+    vec->push_back(it->second);
+}
+
+void Module::GetStackFrameEntries(vector<StackFrameEntry *> *vec) {
+  *vec = stack_frame_entries_;
+}
+
+void Module::AssignSourceIds() {
+  // First, give every source file an id of -1.
+  for (FileByNameMap::iterator file_it = files_.begin();
+       file_it != files_.end(); ++file_it) {
+    file_it->second->source_id = -1;
+  }
+
+  // Next, mark all files actually cited by our functions' line number
+  // info, by setting each one's source id to zero.
+  for (FunctionSet::const_iterator func_it = functions_.begin();
+       func_it != functions_.end(); ++func_it) {
+    Function *func = *func_it;
+    for (vector<Line>::iterator line_it = func->lines.begin();
+         line_it != func->lines.end(); ++line_it)
+      line_it->file->source_id = 0;
+  }
+
+  // Finally, assign source ids to those files that have been marked.
+  // We could have just assigned source id numbers while traversing
+  // the line numbers, but doing it this way numbers the files in
+  // lexicographical order by name, which is neat.
+  int next_source_id = 0;
+  for (FileByNameMap::iterator file_it = files_.begin();
+       file_it != files_.end(); ++file_it) {
+    if (!file_it->second->source_id)
+      file_it->second->source_id = next_source_id++;
+  }
+}
+
+bool Module::ReportError() {
+  fprintf(stderr, "error writing symbol file: %s\n",
+          strerror(errno));
+  return false;
+}
+
+bool Module::WriteRuleMap(const RuleMap &rule_map, std::ostream &stream) {
+  for (RuleMap::const_iterator it = rule_map.begin();
+       it != rule_map.end(); ++it) {
+    if (it != rule_map.begin())
+      stream << ' ';
+    stream << it->first << ": " << it->second;
+  }
+  return stream.good();
+}
+
+bool Module::Write(std::ostream &stream, bool cfi) {
+  stream << "MODULE " << os_ << " " << architecture_ << " "
+         << id_ << " " << name_ << endl;
+  if (!stream.good())
+    return ReportError();
+
+  AssignSourceIds();
+
+  // Write out files.
+  for (FileByNameMap::iterator file_it = files_.begin();
+       file_it != files_.end(); ++file_it) {
+    File *file = file_it->second;
+    if (file->source_id >= 0) {
+      stream << "FILE " << file->source_id << " " <<  file->name << endl;
+      if (!stream.good())
+        return ReportError();
+    }
+  }
+
+  // Write out functions and their lines.
+  for (FunctionSet::const_iterator func_it = functions_.begin();
+       func_it != functions_.end(); ++func_it) {
+    Function *func = *func_it;
+    stream << "FUNC " << hex
+           << (func->address - load_address_) << " "
+           << func->size << " "
+           << func->parameter_size << " "
+           << func->name << dec << endl;
+
+    if (!stream.good())
+      return ReportError();
+    for (vector<Line>::iterator line_it = func->lines.begin();
+         line_it != func->lines.end(); ++line_it) {
+      stream << hex
+             << (line_it->address - load_address_) << " "
+             << line_it->size << " "
+             << dec
+             << line_it->number << " "
+             << line_it->file->source_id << endl;
+      if (!stream.good())
+        return ReportError();
+    }
+  }
+
+  // Write out 'PUBLIC' records.
+  for (ExternSet::const_iterator extern_it = externs_.begin();
+       extern_it != externs_.end(); ++extern_it) {
+    Extern *ext = *extern_it;
+    stream << "PUBLIC " << hex
+           << (ext->address - load_address_) << " 0 "
+           << ext->name << dec << endl;
+    if (!stream.good())
+      return ReportError();
+  }
+
+  if (cfi) {
+    // Write out 'STACK CFI INIT' and 'STACK CFI' records.
+    vector<StackFrameEntry *>::const_iterator frame_it;
+    for (frame_it = stack_frame_entries_.begin();
+         frame_it != stack_frame_entries_.end(); ++frame_it) {
+      StackFrameEntry *entry = *frame_it;
+      stream << "STACK CFI INIT " << hex
+             << (entry->address - load_address_) << " "
+             << entry->size << " " << dec;
+      if (!stream.good()
+          || !WriteRuleMap(entry->initial_rules, stream))
+        return ReportError();
+
+      stream << endl;
+
+      // Write out this entry's delta rules as 'STACK CFI' records.
+      for (RuleChangeMap::const_iterator delta_it = entry->rule_changes.begin();
+           delta_it != entry->rule_changes.end(); ++delta_it) {
+        stream << "STACK CFI " << hex
+               << (delta_it->first - load_address_) << " " << dec;
+        if (!stream.good()
+            || !WriteRuleMap(delta_it->second, stream))
+          return ReportError();
+
+        stream << endl;
+      }
+    }
+  }
+
+  return true;
+}
+
+}  // namespace google_breakpad
diff --git a/3rdParty/Breakpad/src/common/module.h b/3rdParty/Breakpad/src/common/module.h
new file mode 100644
index 0000000..cc89bba
--- /dev/null
+++ b/3rdParty/Breakpad/src/common/module.h
@@ -0,0 +1,321 @@
+// -*- mode: c++ -*-
+
+// 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>
+
+// module.h: Define google_breakpad::Module. A Module holds debugging
+// information, and can write that information out as a Breakpad
+// symbol file.
+
+#ifndef COMMON_LINUX_MODULE_H__
+#define COMMON_LINUX_MODULE_H__
+
+#include <iostream>
+#include <map>
+#include <set>
+#include <string>
+#include <vector>
+
+#include "common/using_std_string.h"
+#include "google_breakpad/common/breakpad_types.h"
+
+namespace google_breakpad {
+
+using std::set;
+using std::vector;
+using std::map;
+
+// A Module represents the contents of a module, and supports methods
+// for adding information produced by parsing STABS or DWARF data
+// --- possibly both from the same file --- and then writing out the
+// unified contents as a Breakpad-format symbol file.
+class Module {
+ public:
+  // The type of addresses and sizes in a symbol table.
+  typedef u_int64_t Address;
+  struct File;
+  struct Function;
+  struct Line;
+  struct Extern;
+
+  // Addresses appearing in File, Function, and Line structures are
+  // absolute, not relative to the the module's load address.  That
+  // is, if the module were loaded at its nominal load address, the
+  // addresses would be correct.
+
+  // A source file.
+  struct File {
+    // The name of the source file.
+    string name;
+
+    // The file's source id.  The Write member function clears this
+    // field and assigns source ids a fresh, so any value placed here
+    // before calling Write will be lost.
+    int source_id;
+  };
+
+  // A function.
+  struct Function {
+    // For sorting by address.  (Not style-guide compliant, but it's
+    // stupid not to put this in the struct.)
+    static bool CompareByAddress(const Function *x, const Function *y) {
+      return x->address < y->address;
+    }
+
+    // The function's name.
+    string name;
+
+    // The start address and length of the function's code.
+    Address address, size;
+
+    // The function's parameter size.
+    Address parameter_size;
+
+    // Source lines belonging to this function, sorted by increasing
+    // address.
+    vector<Line> lines;
+  };
+
+  // A source line.
+  struct Line {
+    // For sorting by address.  (Not style-guide compliant, but it's
+    // stupid not to put this in the struct.)
+    static bool CompareByAddress(const Module::Line &x, const Module::Line &y) {
+      return x.address < y.address;
+    }
+
+    Address address, size;    // The address and size of the line's code.
+    File *file;                // The source file.
+    int number;                // The source line number.
+  };
+
+  // An exported symbol.
+  struct Extern {
+    Address address;
+    string name;
+  };
+
+  // A map from register names to postfix expressions that recover
+  // their their values. This can represent a complete set of rules to
+  // follow at some address, or a set of changes to be applied to an
+  // extant set of rules.
+  typedef map<string, string> RuleMap;
+
+  // A map from addresses to RuleMaps, representing changes that take
+  // effect at given addresses.
+  typedef map<Address, RuleMap> RuleChangeMap;
+
+  // A range of 'STACK CFI' stack walking information. An instance of
+  // this structure corresponds to a 'STACK CFI INIT' record and the
+  // subsequent 'STACK CFI' records that fall within its range.
+  struct StackFrameEntry {
+    // The starting address and number of bytes of machine code this
+    // entry covers.
+    Address address, size;
+
+    // The initial register recovery rules, in force at the starting
+    // address.
+    RuleMap initial_rules;
+
+    // A map from addresses to rule changes. To find the rules in
+    // force at a given address, start with initial_rules, and then
+    // apply the changes given in this map for all addresses up to and
+    // including the address you're interested in.
+    RuleChangeMap rule_changes;
+  };
+
+  struct FunctionCompare {
+    bool operator() (const Function *lhs,
+                     const Function *rhs) const {
+      if (lhs->address == rhs->address)
+        return lhs->name < rhs->name;
+      return lhs->address < rhs->address;
+    }
+  };
+
+  struct ExternCompare {
+    bool operator() (const Extern *lhs,
+                     const Extern *rhs) const {
+      return lhs->address < rhs->address;
+    }
+  };
+
+  // Create a new module with the given name, operating system,
+  // architecture, and ID string.
+  Module(const string &name, const string &os, const string &architecture,
+         const string &id);
+  ~Module();
+
+  // Set the module's load address to LOAD_ADDRESS; addresses given
+  // for functions and lines will be written to the Breakpad symbol
+  // file as offsets from this address.  Construction initializes this
+  // module's load address to zero: addresses written to the symbol
+  // file will be the same as they appear in the Function, Line, and
+  // StackFrameEntry structures.
+  //
+  // Note that this member function has no effect on addresses stored
+  // in the data added to this module; the Write member function
+  // simply subtracts off the load address from addresses before it
+  // prints them. Only the last load address given before calling
+  // Write is used.
+  void SetLoadAddress(Address load_address);
+
+  // Add FUNCTION to the module. FUNCTION's name must not be empty.
+  // This module owns all Function objects added with this function:
+  // destroying the module destroys them as well.
+  void AddFunction(Function *function);
+
+  // Add all the functions in [BEGIN,END) to the module.
+  // This module owns all Function objects added with this function:
+  // destroying the module destroys them as well.
+  void AddFunctions(vector<Function *>::iterator begin,
+                    vector<Function *>::iterator end);
+
+  // Add STACK_FRAME_ENTRY to the module.
+  // This module owns all StackFrameEntry objects added with this
+  // function: destroying the module destroys them as well.
+  void AddStackFrameEntry(StackFrameEntry *stack_frame_entry);
+
+  // Add PUBLIC to the module.
+  // This module owns all Extern objects added with this function:
+  // destroying the module destroys them as well.
+  void AddExtern(Extern *ext);
+
+  // If this module has a file named NAME, return a pointer to it. If
+  // it has none, then create one and return a pointer to the new
+  // file. This module owns all File objects created using these
+  // functions; destroying the module destroys them as well.
+  File *FindFile(const string &name);
+  File *FindFile(const char *name);
+
+  // If this module has a file named NAME, return a pointer to it.
+  // Otherwise, return NULL.
+  File *FindExistingFile(const string &name);
+
+  // Insert pointers to the functions added to this module at I in
+  // VEC. The pointed-to Functions are still owned by this module.
+  // (Since this is effectively a copy of the function list, this is
+  // mostly useful for testing; other uses should probably get a more
+  // appropriate interface.)
+  void GetFunctions(vector<Function *> *vec, vector<Function *>::iterator i);
+
+  // Insert pointers to the externs added to this module at I in
+  // VEC. The pointed-to Externs are still owned by this module.
+  // (Since this is effectively a copy of the extern list, this is
+  // mostly useful for testing; other uses should probably get a more
+  // appropriate interface.)
+  void GetExterns(vector<Extern *> *vec, vector<Extern *>::iterator i);
+
+  // Clear VEC and fill it with pointers to the Files added to this
+  // module, sorted by name. The pointed-to Files are still owned by
+  // this module. (Since this is effectively a copy of the file list,
+  // this is mostly useful for testing; other uses should probably get
+  // a more appropriate interface.)
+  void GetFiles(vector<File *> *vec);
+
+  // Clear VEC and fill it with pointers to the StackFrameEntry
+  // objects that have been added to this module. (Since this is
+  // effectively a copy of the stack frame entry list, this is mostly
+  // useful for testing; other uses should probably get
+  // a more appropriate interface.)
+  void GetStackFrameEntries(vector<StackFrameEntry *> *vec);
+
+  // Find those files in this module that are actually referred to by
+  // functions' line number data, and assign them source id numbers.
+  // Set the source id numbers for all other files --- unused by the
+  // source line data --- to -1.  We do this before writing out the
+  // symbol file, at which point we omit any unused files.
+  void AssignSourceIds();
+
+  // Call AssignSourceIds, and write this module to STREAM in the
+  // breakpad symbol format. Return true if all goes well, or false if
+  // an error occurs. This method writes out:
+  // - a header based on the values given to the constructor,
+  // - the source files added via FindFile,
+  // - the functions added via AddFunctions, each with its lines,
+  // - all public records,
+  // - and if CFI is true, all CFI records.
+  // Addresses in the output are all relative to the load address
+  // established by SetLoadAddress.
+  bool Write(std::ostream &stream, bool cfi);
+
+ private:
+  // Report an error that has occurred writing the symbol file, using
+  // errno to find the appropriate cause.  Return false.
+  static bool ReportError();
+
+  // Write RULE_MAP to STREAM, in the form appropriate for 'STACK CFI'
+  // records, without a final newline. Return true if all goes well;
+  // if an error occurs, return false, and leave errno set.
+  static bool WriteRuleMap(const RuleMap &rule_map, std::ostream &stream);
+
+  // Module header entries.
+  string name_, os_, architecture_, id_;
+
+  // The module's nominal load address.  Addresses for functions and
+  // lines are absolute, assuming the module is loaded at this
+  // address.
+  Address load_address_;
+
+  // Relation for maps whose keys are strings shared with some other
+  // structure.
+  struct CompareStringPtrs {
+    bool operator()(const string *x, const string *y) { return *x < *y; }
+  };
+
+  // A map from filenames to File structures.  The map's keys are
+  // pointers to the Files' names.
+  typedef map<const string *, File *, CompareStringPtrs> FileByNameMap;
+
+  // A set containing Function structures, sorted by address.
+  typedef set<Function *, FunctionCompare> FunctionSet;
+
+  // A set containing Extern structures, sorted by address.
+  typedef set<Extern *, ExternCompare> ExternSet;
+
+  // The module owns all the files and functions that have been added
+  // to it; destroying the module frees the Files and Functions these
+  // point to.
+  FileByNameMap files_;    // This module's source files.
+  FunctionSet functions_;  // This module's functions.
+
+  // The module owns all the call frame info entries that have been
+  // added to it.
+  vector<StackFrameEntry *> stack_frame_entries_;
+
+  // The module owns all the externs that have been added to it;
+  // destroying the module frees the Externs these point to.
+  ExternSet externs_;
+};
+
+}  // namespace google_breakpad
+
+#endif  // COMMON_LINUX_MODULE_H__
diff --git a/3rdParty/Breakpad/src/common/stabs_reader.cc b/3rdParty/Breakpad/src/common/stabs_reader.cc
new file mode 100644
index 0000000..6019fc7
--- /dev/null
+++ b/3rdParty/Breakpad/src/common/stabs_reader.cc
@@ -0,0 +1,315 @@
+// 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>
+
+// This file implements the google_breakpad::StabsReader class.
+// See stabs_reader.h.
+
+#include "common/stabs_reader.h"
+
+#include <assert.h>
+#include <stab.h>
+#include <string.h>
+
+#include <string>
+
+#include "common/using_std_string.h"
+
+using std::vector;
+
+namespace google_breakpad {
+
+StabsReader::EntryIterator::EntryIterator(const ByteBuffer *buffer,
+                                          bool big_endian, size_t value_size)
+    : value_size_(value_size), cursor_(buffer, big_endian) {
+  // Actually, we could handle weird sizes just fine, but they're
+  // probably mistakes --- expressed in bits, say.
+  assert(value_size == 4 || value_size == 8);
+  entry_.index = 0;
+  Fetch();
+}
+
+void StabsReader::EntryIterator::Fetch() {
+  cursor_
+      .Read(4, false, &entry_.name_offset)
+      .Read(1, false, &entry_.type)
+      .Read(1, false, &entry_.other)
+      .Read(2, false, &entry_.descriptor)
+      .Read(value_size_, false, &entry_.value);
+  entry_.at_end = !cursor_;
+}
+
+StabsReader::StabsReader(const uint8_t *stab,    size_t stab_size,
+                         const uint8_t *stabstr, size_t stabstr_size,
+                         bool big_endian, size_t value_size, bool unitized,
+                         StabsHandler *handler)
+    : entries_(stab, stab_size),
+      strings_(stabstr, stabstr_size),
+      iterator_(&entries_, big_endian, value_size),
+      unitized_(unitized),
+      handler_(handler),
+      string_offset_(0),
+      next_cu_string_offset_(0),
+      current_source_file_(NULL) { }
+
+const char *StabsReader::SymbolString() {
+  ptrdiff_t offset = string_offset_ + iterator_->name_offset;
+  if (offset < 0 || (size_t) offset >= strings_.Size()) {
+    handler_->Warning("symbol %d: name offset outside the string section\n",
+                      iterator_->index);
+    // Return our null string, to keep our promise about all names being
+    // taken from the string section.
+    offset = 0;
+  }
+  return reinterpret_cast<const char *>(strings_.start + offset);
+}
+
+bool StabsReader::Process() {
+  while (!iterator_->at_end) {
+    if (iterator_->type == N_SO) {
+      if (! ProcessCompilationUnit())
+        return false;
+    } else if (iterator_->type == N_UNDF && unitized_) {
+      // In unitized STABS (including Linux STABS, and pretty much anything
+      // else that puts STABS data in sections), at the head of each
+      // compilation unit's entries there is an N_UNDF stab giving the
+      // number of symbols in the compilation unit, and the number of bytes
+      // that compilation unit's strings take up in the .stabstr section.
+      // Each CU's strings are separate; the n_strx values are offsets
+      // within the current CU's portion of the .stabstr section.
+      //
+      // As an optimization, the GNU linker combines all the
+      // compilation units into one, with a single N_UNDF at the
+      // beginning. However, other linkers, like Gold, do not perform
+      // this optimization.
+      string_offset_ = next_cu_string_offset_;
+      next_cu_string_offset_ = iterator_->value;
+      ++iterator_;
+    }
+#if defined(HAVE_MACH_O_NLIST_H)
+    // Export symbols in Mach-O binaries look like this.
+    // This is necessary in order to be able to dump symbols
+    // from OS X system libraries.
+    else if ((iterator_->type & N_STAB) == 0 &&
+               (iterator_->type & N_TYPE) == N_SECT) {
+      ProcessExtern();
+    }
+#endif
+    else {
+      ++iterator_;
+    }
+  }
+  return true;
+}
+
+bool StabsReader::ProcessCompilationUnit() {
+  assert(!iterator_->at_end && iterator_->type == N_SO);
+
+  // There may be an N_SO entry whose name ends with a slash,
+  // indicating the directory in which the compilation occurred.
+  // The build directory defaults to NULL.
+  const char *build_directory = NULL;
+  {
+    const char *name = SymbolString();
+    if (name[0] && name[strlen(name) - 1] == '/') {
+      build_directory = name;
+      ++iterator_;
+    }
+  }
+
+  // We expect to see an N_SO entry with a filename next, indicating
+  // the start of the compilation unit.
+  {
+    if (iterator_->at_end || iterator_->type != N_SO)
+      return true;
+    const char *name = SymbolString();
+    if (name[0] == '\0') {
+      // This seems to be a stray end-of-compilation-unit marker;
+      // consume it, but don't report the end, since we didn't see a
+      // beginning.
+      ++iterator_;
+      return true;
+    }
+    current_source_file_ = name;
+  }
+
+  if (! handler_->StartCompilationUnit(current_source_file_,
+                                       iterator_->value,
+                                       build_directory))
+    return false;
+
+  ++iterator_;
+
+  // The STABS documentation says that some compilers may emit
+  // additional N_SO entries with names immediately following the
+  // first, and that they should be ignored.  However, the original
+  // Breakpad STABS reader doesn't ignore them, so we won't either.
+
+  // Process the body of the compilation unit, up to the next N_SO.
+  while (!iterator_->at_end && iterator_->type != N_SO) {
+    if (iterator_->type == N_FUN) {
+      if (! ProcessFunction())
+        return false;
+    } else if (iterator_->type == N_SLINE) {
+      // Mac OS X STABS place SLINE records before functions.
+      Line line;
+      // The value of an N_SLINE entry that appears outside a function is
+      // the absolute address of the line.
+      line.address = iterator_->value;
+      line.filename = current_source_file_;
+      // The n_desc of a N_SLINE entry is the line number.  It's a
+      // signed 16-bit field; line numbers from 32768 to 65535 are
+      // stored as n-65536.
+      line.number = (uint16_t) iterator_->descriptor;
+      queued_lines_.push_back(line);
+      ++iterator_;
+    } else if (iterator_->type == N_SOL) {
+      current_source_file_ = SymbolString();
+      ++iterator_;
+    } else {
+      // Ignore anything else.
+      ++iterator_;
+    }
+  }
+
+  // An N_SO with an empty name indicates the end of the compilation
+  // unit.  Default to zero.
+  uint64_t ending_address = 0;
+  if (!iterator_->at_end) {
+    assert(iterator_->type == N_SO);
+    const char *name = SymbolString();
+    if (name[0] == '\0') {
+      ending_address = iterator_->value;
+      ++iterator_;
+    }
+  }
+
+  if (! handler_->EndCompilationUnit(ending_address))
+    return false;
+
+  queued_lines_.clear();
+
+  return true;
+}
+
+bool StabsReader::ProcessFunction() {
+  assert(!iterator_->at_end && iterator_->type == N_FUN);
+
+  uint64_t function_address = iterator_->value;
+  // The STABS string for an N_FUN entry is the name of the function,
+  // followed by a colon, followed by type information for the
+  // function.  We want to pass the name alone to StartFunction.
+  const char *stab_string = SymbolString();
+  const char *name_end = strchr(stab_string, ':');
+  if (! name_end)
+    name_end = stab_string + strlen(stab_string);
+  string name(stab_string, name_end - stab_string);
+  if (! handler_->StartFunction(name, function_address))
+    return false;
+  ++iterator_;
+
+  // If there were any SLINE records given before the function, report them now.
+  for (vector<Line>::const_iterator it = queued_lines_.begin();
+       it != queued_lines_.end(); it++) {
+    if (!handler_->Line(it->address, it->filename, it->number))
+      return false;
+  }
+  queued_lines_.clear();
+
+  while (!iterator_->at_end) {
+    if (iterator_->type == N_SO || iterator_->type == N_FUN)
+      break;
+    else if (iterator_->type == N_SLINE) {
+      // The value of an N_SLINE entry is the offset of the line from
+      // the function's start address.
+      uint64_t line_address = function_address + iterator_->value;
+      // The n_desc of a N_SLINE entry is the line number.  It's a
+      // signed 16-bit field; line numbers from 32768 to 65535 are
+      // stored as n-65536.
+      uint16_t line_number = iterator_->descriptor;
+      if (! handler_->Line(line_address, current_source_file_, line_number))
+        return false;
+      ++iterator_;
+    } else if (iterator_->type == N_SOL) {
+      current_source_file_ = SymbolString();
+      ++iterator_;
+    } else
+      // Ignore anything else.
+      ++iterator_;
+  }
+
+  // We've reached the end of the function. See if we can figure out its
+  // ending address.
+  uint64_t ending_address = 0;
+  if (!iterator_->at_end) {
+    assert(iterator_->type == N_SO || iterator_->type == N_FUN);
+    if (iterator_->type == N_FUN) {
+      const char *symbol_name = SymbolString();
+      if (symbol_name[0] == '\0') {
+        // An N_FUN entry with no name is a terminator for this function;
+        // its value is the function's size.
+        ending_address = function_address + iterator_->value;
+        ++iterator_;
+      } else {
+        // An N_FUN entry with a name is the next function, and we can take
+        // its value as our ending address. Don't advance the iterator, as
+        // we'll use this symbol to start the next function as well.
+        ending_address = iterator_->value;
+      }
+    } else {
+      // An N_SO entry could be an end-of-compilation-unit marker, or the
+      // start of the next compilation unit, but in either case, its value
+      // is our ending address. We don't advance the iterator;
+      // ProcessCompilationUnit will decide what to do with this symbol.
+      ending_address = iterator_->value;
+    }
+  }
+
+  if (! handler_->EndFunction(ending_address))
+    return false;
+
+  return true;
+}
+
+bool StabsReader::ProcessExtern() {
+#if defined(HAVE_MACH_O_NLIST_H)
+  assert(!iterator_->at_end &&
+         (iterator_->type & N_STAB) == 0 &&
+         (iterator_->type & N_TYPE) == N_SECT);
+#endif
+
+  // TODO(mark): only do symbols in the text section?
+  if (!handler_->Extern(SymbolString(), iterator_->value))
+    return false;
+
+  ++iterator_;
+  return true;
+}
+
+} // namespace google_breakpad
diff --git a/3rdParty/Breakpad/src/common/stabs_reader.h b/3rdParty/Breakpad/src/common/stabs_reader.h
new file mode 100644
index 0000000..d89afc0
--- /dev/null
+++ b/3rdParty/Breakpad/src/common/stabs_reader.h
@@ -0,0 +1,326 @@
+// -*- mode: c++ -*-
+
+// 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>
+
+// stabs_reader.h: Define StabsReader, a parser for STABS debugging
+// information. A description of the STABS debugging format can be
+// found at:
+//
+//    http://sourceware.org/gdb/current/onlinedocs/stabs_toc.html
+//
+// The comments here assume you understand the format.
+//
+// This parser can handle big-endian and little-endian data, and the symbol
+// values may be either 32 or 64 bits long. It handles both STABS in
+// sections (as used on Linux) and STABS appearing directly in an
+// a.out-like symbol table (as used in Darwin OS X Mach-O files).
+
+#ifndef COMMON_STABS_READER_H__
+#define COMMON_STABS_READER_H__
+
+#include <stddef.h>
+#include <stdint.h>
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef HAVE_A_OUT_H
+#include <a.out.h>
+#endif
+#ifdef HAVE_MACH_O_NLIST_H
+#include <mach-o/nlist.h>
+#endif
+
+#include <string>
+#include <vector>
+
+#include "common/byte_cursor.h"
+#include "common/using_std_string.h"
+
+namespace google_breakpad {
+
+class StabsHandler;
+
+class StabsReader {
+ public:
+  // Create a reader for the STABS debug information whose .stab section is
+  // being traversed by ITERATOR, and whose .stabstr section is referred to
+  // by STRINGS. The reader will call the member functions of HANDLER to
+  // report the information it finds, when the reader's 'Process' member
+  // function is called.
+  //
+  // BIG_ENDIAN should be true if the entries in the .stab section are in
+  // big-endian form, or false if they are in little-endian form.
+  //
+  // VALUE_SIZE should be either 4 or 8, indicating the size of the 'value'
+  // field in each entry in bytes.
+  //
+  // UNITIZED should be true if the STABS data is stored in units with
+  // N_UNDF headers. This is usually the case for STABS stored in sections,
+  // like .stab/.stabstr, and usually not the case for STABS stored in the
+  // actual symbol table; UNITIZED should be true when parsing Linux stabs,
+  // false when parsing Mac OS X STABS. For details, see:
+  // http://sourceware.org/gdb/current/onlinedocs/stabs/Stab-Section-Basics.html
+  // 
+  // Note that, in ELF, the .stabstr section should be found using the
+  // 'sh_link' field of the .stab section header, not by name.
+  StabsReader(const uint8_t *stab,    size_t stab_size,
+              const uint8_t *stabstr, size_t stabstr_size,
+              bool big_endian, size_t value_size, bool unitized,
+              StabsHandler *handler);
+
+  // Process the STABS data, calling the handler's member functions to
+  // report what we find.  While the handler functions return true,
+  // continue to process until we reach the end of the section.  If we
+  // processed the entire section and all handlers returned true,
+  // return true.  If any handler returned false, return false.
+  // 
+  // This is only meant to be called once per StabsReader instance;
+  // resuming a prior processing pass that stopped abruptly isn't supported.
+  bool Process();
+
+ private:
+
+  // An class for walking arrays of STABS entries. This isolates the main
+  // STABS reader from the exact format (size; endianness) of the entries
+  // themselves.
+  class EntryIterator {
+   public:
+    // The contents of a STABS entry, adjusted for the host's endianness,
+    // word size, 'struct nlist' layout, and so on.
+    struct Entry {
+      // True if this iterator has reached the end of the entry array. When
+      // this is set, the other members of this structure are not valid.
+      bool at_end;
+
+      // The number of this entry within the list.
+      size_t index;
+
+      // The current entry's name offset. This is the offset within the
+      // current compilation unit's strings, as establish by the N_UNDF entries.
+      size_t name_offset;
+
+      // The current entry's type, 'other' field, descriptor, and value.
+      unsigned char type;
+      unsigned char other;
+      short descriptor;
+      uint64_t value;
+    };
+
+    // Create a EntryIterator walking the entries in BUFFER. Treat the
+    // entries as big-endian if BIG_ENDIAN is true, as little-endian
+    // otherwise. Assume each entry has a 'value' field whose size is
+    // VALUE_SIZE.
+    //
+    // This would not be terribly clean to extend to other format variations,
+    // but it's enough to handle Linux and Mac, and we'd like STABS to die
+    // anyway.
+    //
+    // For the record: on Linux, STABS entry values are always 32 bits,
+    // regardless of the architecture address size (don't ask me why); on
+    // Mac, they are 32 or 64 bits long. Oddly, the section header's entry
+    // size for a Linux ELF .stab section varies according to the ELF class
+    // from 12 to 20 even as the actual entries remain unchanged.
+    EntryIterator(const ByteBuffer *buffer, bool big_endian, size_t value_size);
+
+    // Move to the next entry. This function's behavior is undefined if
+    // at_end() is true when it is called.
+    EntryIterator &operator++() { Fetch(); entry_.index++; return *this; }
+
+    // Dereferencing this iterator produces a reference to an Entry structure
+    // that holds the current entry's values. The entry is owned by this
+    // EntryIterator, and will be invalidated at the next call to operator++.
+    const Entry &operator*() const { return entry_; }
+    const Entry *operator->() const { return &entry_; }
+
+   private:
+    // Read the STABS entry at cursor_, and set entry_ appropriately.
+    void Fetch();
+
+    // The size of entries' value field, in bytes.
+    size_t value_size_;
+
+    // A byte cursor traversing buffer_.
+    ByteCursor cursor_;
+
+    // Values for the entry this iterator refers to.
+    Entry entry_;
+  };
+
+  // A source line, saved to be reported later.
+  struct Line {
+    uint64_t address;
+    const char *filename;
+    int number;
+  };
+
+  // Return the name of the current symbol.
+  const char *SymbolString();
+
+  // Process a compilation unit starting at symbol_.  Return true
+  // to continue processing, or false to abort.
+  bool ProcessCompilationUnit();
+
+  // Process a function in current_source_file_ starting at symbol_.
+  // Return true to continue processing, or false to abort.
+  bool ProcessFunction();
+
+  // Process an exported function symbol.
+  // Return true to continue processing, or false to abort.
+  bool ProcessExtern();
+
+  // The STABS entries being parsed.
+  ByteBuffer entries_;
+
+  // The string section to which the entries refer.
+  ByteBuffer strings_;
+
+  // The iterator walking the STABS entries.
+  EntryIterator iterator_;
+
+  // True if the data is "unitized"; see the explanation in the comment for
+  // StabsReader::StabsReader.
+  bool unitized_;
+
+  StabsHandler *handler_;
+
+  // The offset of the current compilation unit's strings within stabstr_.
+  size_t string_offset_;
+
+  // The value string_offset_ should have for the next compilation unit,
+  // as established by N_UNDF entries.
+  size_t next_cu_string_offset_;
+
+  // The current source file name.
+  const char *current_source_file_;
+
+  // Mac OS X STABS place SLINE records before functions; we accumulate a
+  // vector of these until we see the FUN record, and then report them
+  // after the StartFunction call.
+  std::vector<Line> queued_lines_;
+};
+
+// Consumer-provided callback structure for the STABS reader.  Clients
+// of the STABS reader provide an instance of this structure.  The
+// reader then invokes the member functions of that instance to report
+// the information it finds.
+//
+// The default definitions of the member functions do nothing, and return
+// true so processing will continue.
+class StabsHandler {
+ public:
+  StabsHandler() { }
+  virtual ~StabsHandler() { }
+
+  // Some general notes about the handler callback functions:
+
+  // Processing proceeds until the end of the .stabs section, or until
+  // one of these functions returns false.
+
+  // The addresses given are as reported in the STABS info, without
+  // regard for whether the module may be loaded at different
+  // addresses at different times (a shared library, say).  When
+  // processing STABS from an ELF shared library, the addresses given
+  // all assume the library is loaded at its nominal load address.
+  // They are *not* offsets from the nominal load address.  If you
+  // want offsets, you must subtract off the library's nominal load
+  // address.
+
+  // The arguments to these functions named FILENAME are all
+  // references to strings stored in the .stabstr section.  Because
+  // both the Linux and Solaris linkers factor out duplicate strings
+  // from the .stabstr section, the consumer can assume that if two
+  // FILENAME values are different addresses, they represent different
+  // file names.
+  //
+  // Thus, it's safe to use (say) std::map<char *, ...>, which does
+  // string address comparisons, not string content comparisons.
+  // Since all the strings are in same array of characters --- the
+  // .stabstr section --- comparing their addresses produces
+  // predictable, if not lexicographically meaningful, results.
+
+  // Begin processing a compilation unit whose main source file is
+  // named FILENAME, and whose base address is ADDRESS.  If
+  // BUILD_DIRECTORY is non-NULL, it is the name of the build
+  // directory in which the compilation occurred.
+  virtual bool StartCompilationUnit(const char *filename, uint64_t address,
+                                    const char *build_directory) {
+    return true;
+  }
+
+  // Finish processing the compilation unit.  If ADDRESS is non-zero,
+  // it is the ending address of the compilation unit.  If ADDRESS is
+  // zero, then the compilation unit's ending address is not
+  // available, and the consumer must infer it by other means.
+  virtual bool EndCompilationUnit(uint64_t address) { return true; }
+
+  // Begin processing a function named NAME, whose starting address is
+  // ADDRESS.  This function belongs to the compilation unit that was
+  // most recently started but not ended.
+  //
+  // Note that, unlike filenames, NAME is not a pointer into the
+  // .stabstr section; this is because the name as it appears in the
+  // STABS data is followed by type information.  The value passed to
+  // StartFunction is the function name alone.
+  //
+  // In languages that use name mangling, like C++, NAME is mangled.
+  virtual bool StartFunction(const string &name, uint64_t address) {
+    return true;
+  }
+
+  // Finish processing the function.  If ADDRESS is non-zero, it is
+  // the ending address for the function.  If ADDRESS is zero, then
+  // the function's ending address is not available, and the consumer
+  // must infer it by other means.
+  virtual bool EndFunction(uint64_t address) { return true; }
+  
+  // Report that the code at ADDRESS is attributable to line NUMBER of
+  // the source file named FILENAME.  The caller must infer the ending
+  // address of the line.
+  virtual bool Line(uint64_t address, const char *filename, int number) {
+    return true;
+  }
+
+  // Report that an exported function NAME is present at ADDRESS.
+  // The size of the function is unknown.
+  virtual bool Extern(const string &name, uint64_t address) {
+    return true;
+  }
+
+  // Report a warning.  FORMAT is a printf-like format string,
+  // specifying how to format the subsequent arguments.
+  virtual void Warning(const char *format, ...) = 0;
+};
+
+} // namespace google_breakpad
+
+#endif  // COMMON_STABS_READER_H__
diff --git a/3rdParty/Breakpad/src/common/stabs_to_module.cc b/3rdParty/Breakpad/src/common/stabs_to_module.cc
new file mode 100644
index 0000000..e59aebd
--- /dev/null
+++ b/3rdParty/Breakpad/src/common/stabs_to_module.cc
@@ -0,0 +1,200 @@
+// 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>
+
+// dump_stabs.cc --- implement the StabsToModule class.
+
+#include <assert.h>
+#include <cxxabi.h>
+#include <stdarg.h>
+#include <stdio.h>
+
+#include <algorithm>
+
+#include "common/stabs_to_module.h"
+#include "common/using_std_string.h"
+
+namespace google_breakpad {
+
+// Demangle using abi call.
+// Older GCC may not support it.
+static string Demangle(const string &mangled) {
+  int status = 0;
+  char *demangled = abi::__cxa_demangle(mangled.c_str(), NULL, NULL, &status);
+  if (status == 0 && demangled != NULL) {
+    string str(demangled);
+    free(demangled);
+    return str;
+  }
+  return string(mangled);
+}
+
+StabsToModule::~StabsToModule() {
+  // Free any functions we've accumulated but not added to the module.
+  for (vector<Module::Function *>::const_iterator func_it = functions_.begin();
+       func_it != functions_.end(); func_it++)
+    delete *func_it;
+  // Free any function that we're currently within.
+  delete current_function_;
+}
+
+bool StabsToModule::StartCompilationUnit(const char *name, uint64_t address,
+                                         const char *build_directory) {
+  assert(!in_compilation_unit_);
+  in_compilation_unit_ = true;
+  current_source_file_name_ = name;
+  current_source_file_ = module_->FindFile(name);
+  comp_unit_base_address_ = address;
+  boundaries_.push_back(static_cast<Module::Address>(address));
+  return true;
+}
+
+bool StabsToModule::EndCompilationUnit(uint64_t address) {
+  assert(in_compilation_unit_);
+  in_compilation_unit_ = false;
+  comp_unit_base_address_ = 0;
+  current_source_file_ = NULL;
+  current_source_file_name_ = NULL;
+  if (address)
+    boundaries_.push_back(static_cast<Module::Address>(address));
+  return true;
+}
+
+bool StabsToModule::StartFunction(const string &name,
+                                  uint64_t address) {
+  assert(!current_function_);
+  Module::Function *f = new Module::Function;
+  f->name = Demangle(name);
+  f->address = address;
+  f->size = 0;           // We compute this in StabsToModule::Finalize().
+  f->parameter_size = 0; // We don't provide this information.
+  current_function_ = f;
+  boundaries_.push_back(static_cast<Module::Address>(address));
+  return true;
+}
+
+bool StabsToModule::EndFunction(uint64_t address) {
+  assert(current_function_);
+  // Functions in this compilation unit should have address bigger
+  // than the compilation unit's starting address.  There may be a lot
+  // of duplicated entries for functions in the STABS data. We will
+  // count on the Module to remove the duplicates.
+  if (current_function_->address >= comp_unit_base_address_)
+    functions_.push_back(current_function_);
+  else
+    delete current_function_;
+  current_function_ = NULL;
+  if (address)
+    boundaries_.push_back(static_cast<Module::Address>(address));
+  return true;
+}
+
+bool StabsToModule::Line(uint64_t address, const char *name, int number) {
+  assert(current_function_);
+  assert(current_source_file_);
+  if (name != current_source_file_name_) {
+    current_source_file_ = module_->FindFile(name);
+    current_source_file_name_ = name;
+  }
+  Module::Line line;
+  line.address = address;
+  line.size = 0;  // We compute this in StabsToModule::Finalize().
+  line.file = current_source_file_;
+  line.number = number;
+  current_function_->lines.push_back(line);
+  return true;
+}
+
+bool StabsToModule::Extern(const string &name, uint64_t address) {
+  Module::Extern *ext = new Module::Extern;
+  // Older libstdc++ demangle implementations can crash on unexpected
+  // input, so be careful about what gets passed in.
+  if (name.compare(0, 3, "__Z") == 0) {
+    ext->name = Demangle(name.substr(1));
+  } else if (name[0] == '_') {
+    ext->name = name.substr(1);
+  } else {
+    ext->name = name;
+  }
+  ext->address = address;
+  module_->AddExtern(ext);
+  return true;
+}
+
+void StabsToModule::Warning(const char *format, ...) {
+  va_list args;
+  va_start(args, format);
+  vfprintf(stderr, format, args);
+  va_end(args);
+}
+
+void StabsToModule::Finalize() {
+  // Sort our boundary list, so we can search it quickly.
+  sort(boundaries_.begin(), boundaries_.end());
+  // Sort all functions by address, just for neatness.
+  sort(functions_.begin(), functions_.end(),
+       Module::Function::CompareByAddress);
+
+  for (vector<Module::Function *>::const_iterator func_it = functions_.begin();
+       func_it != functions_.end();
+       func_it++) {
+    Module::Function *f = *func_it;
+    // Compute the function f's size.
+    vector<Module::Address>::const_iterator boundary
+        = std::upper_bound(boundaries_.begin(), boundaries_.end(), f->address);
+    if (boundary != boundaries_.end())
+      f->size = *boundary - f->address;
+    else
+      // If this is the last function in the module, and the STABS
+      // reader was unable to give us its ending address, then assign
+      // it a bogus, very large value.  This will happen at most once
+      // per module: since we've added all functions' addresses to the
+      // boundary table, only one can be the last.
+      f->size = kFallbackSize;
+
+    // Compute sizes for each of the function f's lines --- if it has any.
+    if (!f->lines.empty()) {
+      stable_sort(f->lines.begin(), f->lines.end(),
+                  Module::Line::CompareByAddress);
+      vector<Module::Line>::iterator last_line = f->lines.end() - 1;
+      for (vector<Module::Line>::iterator line_it = f->lines.begin();
+           line_it != last_line; line_it++)
+        line_it[0].size = line_it[1].address - line_it[0].address;
+      // Compute the size of the last line from f's end address.
+      last_line->size = (f->address + f->size) - last_line->address;
+    }
+  }
+  // Now that everything has a size, add our functions to the module, and
+  // dispose of our private list.
+  module_->AddFunctions(functions_.begin(), functions_.end());
+  functions_.clear();
+}
+
+} // namespace google_breakpad
diff --git a/3rdParty/Breakpad/src/common/stabs_to_module.h b/3rdParty/Breakpad/src/common/stabs_to_module.h
new file mode 100644
index 0000000..5e04fa7
--- /dev/null
+++ b/3rdParty/Breakpad/src/common/stabs_to_module.h
@@ -0,0 +1,143 @@
+// -*- mode: C++ -*-
+
+// 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>
+
+// dump_stabs.h: Define the StabsToModule class, which receives
+// STABS debugging information from a parser and adds it to a Breakpad
+// symbol file.
+
+#ifndef BREAKPAD_COMMON_STABS_TO_MODULE_H_
+#define BREAKPAD_COMMON_STABS_TO_MODULE_H_
+
+#include <stdint.h>
+
+#include <string>
+#include <vector>
+
+#include "common/module.h"
+#include "common/stabs_reader.h"
+#include "common/using_std_string.h"
+
+namespace google_breakpad {
+
+using std::vector;
+
+// A StabsToModule is a handler that receives parsed STABS debugging 
+// information from a StabsReader, and uses that to populate
+// a Module. (All classes are in the google_breakpad namespace.) A
+// Module represents the contents of a Breakpad symbol file, and knows
+// how to write itself out as such. A StabsToModule thus acts as
+// the bridge between STABS and Breakpad data.
+// When processing Darwin Mach-O files, this also receives public linker
+// symbols, like those found in system libraries.
+class StabsToModule: public google_breakpad::StabsHandler {
+ public:
+  // Receive parsed debugging information from a StabsReader, and
+  // store it all in MODULE.
+  StabsToModule(Module *module) :
+      module_(module),
+      in_compilation_unit_(false),
+      comp_unit_base_address_(0),
+      current_function_(NULL),
+      current_source_file_(NULL),
+      current_source_file_name_(NULL) { }
+  ~StabsToModule();
+
+  // The standard StabsHandler virtual member functions.
+  bool StartCompilationUnit(const char *name, uint64_t address,
+                            const char *build_directory);
+  bool EndCompilationUnit(uint64_t address);
+  bool StartFunction(const string &name, uint64_t address);
+  bool EndFunction(uint64_t address);
+  bool Line(uint64_t address, const char *name, int number);
+  bool Extern(const string &name, uint64_t address);
+  void Warning(const char *format, ...);
+
+  // Do any final processing necessary to make module_ contain all the
+  // data provided by the STABS reader.
+  //
+  // Because STABS does not provide reliable size information for
+  // functions and lines, we need to make a pass over the data after
+  // processing all the STABS to compute those sizes.  We take care of
+  // that here.
+  void Finalize();
+
+ private:
+
+  // An arbitrary, but very large, size to use for functions whose
+  // size we can't compute properly.
+  static const uint64_t kFallbackSize = 0x10000000;
+
+  // The module we're contributing debugging info to.
+  Module *module_;
+
+  // The functions we've generated so far.  We don't add these to
+  // module_ as we parse them.  Instead, we wait until we've computed
+  // their ending address, and their lines' ending addresses.
+  //
+  // We could just stick them in module_ from the outset, but if
+  // module_ already contains data gathered from other debugging
+  // formats, that would complicate the size computation.
+  vector<Module::Function *> functions_;
+
+  // Boundary addresses.  STABS doesn't necessarily supply sizes for
+  // functions and lines, so we need to compute them ourselves by
+  // finding the next object.
+  vector<Module::Address> boundaries_;
+
+  // True if we are currently within a compilation unit: we have gotten a
+  // StartCompilationUnit call, but no matching EndCompilationUnit call
+  // yet. We use this for sanity checks.
+  bool in_compilation_unit_;
+
+  // The base address of the current compilation unit.  We use this to
+  // recognize functions we should omit from the symbol file.  (If you
+  // know the details of why we omit these, please patch this
+  // comment.)
+  Module::Address comp_unit_base_address_;
+
+  // The function we're currently contributing lines to.
+  Module::Function *current_function_;
+
+  // The last Module::File we got a line number in.
+  Module::File *current_source_file_;
+
+  // The pointer in the .stabstr section of the name that
+  // current_source_file_ is built from.  This allows us to quickly
+  // recognize when the current line is in the same file as the
+  // previous one (which it usually is).
+  const char *current_source_file_name_;
+};
+
+}  // namespace google_breakpad
+
+#endif  // BREAKPAD_COMMON_STABS_TO_MODULE_H_
diff --git a/3rdParty/Breakpad/src/common/string_conversion.cc b/3rdParty/Breakpad/src/common/string_conversion.cc
new file mode 100644
index 0000000..27fb8cd
--- /dev/null
+++ b/3rdParty/Breakpad/src/common/string_conversion.cc
@@ -0,0 +1,155 @@
+// 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 <string.h>
+
+#include "common/convert_UTF.h"
+#include "common/string_conversion.h"
+#include "common/using_std_string.h"
+#include "processor/scoped_ptr.h"
+
+namespace google_breakpad {
+
+using std::vector;
+
+void UTF8ToUTF16(const char *in, vector<u_int16_t> *out) {
+  size_t source_length = strlen(in);
+  const UTF8 *source_ptr = reinterpret_cast<const UTF8 *>(in);
+  const UTF8 *source_end_ptr = source_ptr + source_length;
+  // Erase the contents and zero fill to the expected size
+  out->clear();
+  out->insert(out->begin(), source_length, 0);
+  u_int16_t *target_ptr = &(*out)[0];
+  u_int16_t *target_end_ptr = target_ptr + out->capacity() * sizeof(u_int16_t);
+  ConversionResult result = ConvertUTF8toUTF16(&source_ptr, source_end_ptr,
+                                               &target_ptr, target_end_ptr,
+                                               strictConversion);
+
+  // Resize to be the size of the # of converted characters + NULL
+  out->resize(result == conversionOK ? target_ptr - &(*out)[0] + 1: 0);
+}
+
+int UTF8ToUTF16Char(const char *in, int in_length, u_int16_t out[2]) {
+  const UTF8 *source_ptr = reinterpret_cast<const UTF8 *>(in);
+  const UTF8 *source_end_ptr = source_ptr + sizeof(char);
+  u_int16_t *target_ptr = out;
+  u_int16_t *target_end_ptr = target_ptr + 2 * sizeof(u_int16_t);
+  out[0] = out[1] = 0;
+
+  // Process one character at a time
+  while (1) {
+    ConversionResult result = ConvertUTF8toUTF16(&source_ptr, source_end_ptr,
+                                                 &target_ptr, target_end_ptr,
+                                                 strictConversion);
+
+    if (result == conversionOK)
+      return static_cast<int>(source_ptr - reinterpret_cast<const UTF8 *>(in));
+
+    // Add another character to the input stream and try again
+    source_ptr = reinterpret_cast<const UTF8 *>(in);
+    ++source_end_ptr;
+
+    if (source_end_ptr > reinterpret_cast<const UTF8 *>(in) + in_length)
+      break;
+  }
+
+  return 0;
+}
+
+void UTF32ToUTF16(const wchar_t *in, vector<u_int16_t> *out) {
+  size_t source_length = wcslen(in);
+  const UTF32 *source_ptr = reinterpret_cast<const UTF32 *>(in);
+  const UTF32 *source_end_ptr = source_ptr + source_length;
+  // Erase the contents and zero fill to the expected size
+  out->clear();
+  out->insert(out->begin(), source_length, 0);
+  u_int16_t *target_ptr = &(*out)[0];
+  u_int16_t *target_end_ptr = target_ptr + out->capacity() * sizeof(u_int16_t);
+  ConversionResult result = ConvertUTF32toUTF16(&source_ptr, source_end_ptr,
+                                                &target_ptr, target_end_ptr,
+                                                strictConversion);
+
+  // Resize to be the size of the # of converted characters + NULL
+  out->resize(result == conversionOK ? target_ptr - &(*out)[0] + 1: 0);
+}
+
+void UTF32ToUTF16Char(wchar_t in, u_int16_t out[2]) {
+  const UTF32 *source_ptr = reinterpret_cast<const UTF32 *>(&in);
+  const UTF32 *source_end_ptr = source_ptr + 1;
+  u_int16_t *target_ptr = out;
+  u_int16_t *target_end_ptr = target_ptr + 2 * sizeof(u_int16_t);
+  out[0] = out[1] = 0;
+  ConversionResult result = ConvertUTF32toUTF16(&source_ptr, source_end_ptr,
+                                                &target_ptr, target_end_ptr,
+                                                strictConversion);
+
+  if (result != conversionOK) {
+    out[0] = out[1] = 0;
+  }
+}
+
+static inline u_int16_t Swap(u_int16_t value) {
+  return (value >> 8) | (value << 8);
+}
+
+string UTF16ToUTF8(const vector<u_int16_t> &in, bool swap) {
+  const UTF16 *source_ptr = &in[0];
+  scoped_ptr<u_int16_t> source_buffer;
+
+  // If we're to swap, we need to make a local copy and swap each byte pair
+  if (swap) {
+    int idx = 0;
+    source_buffer.reset(new u_int16_t[in.size()]);
+    UTF16 *source_buffer_ptr = source_buffer.get();
+    for (vector<u_int16_t>::const_iterator it = in.begin();
+         it != in.end(); ++it, ++idx)
+      source_buffer_ptr[idx] = Swap(*it);
+
+    source_ptr = source_buffer.get();
+  }
+
+  // The maximum expansion would be 4x the size of the input string.
+  const UTF16 *source_end_ptr = source_ptr + in.size();
+  size_t target_capacity = in.size() * 4;
+  scoped_array<UTF8> target_buffer(new UTF8[target_capacity]);
+  UTF8 *target_ptr = target_buffer.get();
+  UTF8 *target_end_ptr = target_ptr + target_capacity;
+  ConversionResult result = ConvertUTF16toUTF8(&source_ptr, source_end_ptr, 
+                                               &target_ptr, target_end_ptr,
+                                               strictConversion);
+
+  if (result == conversionOK) {
+    const char *targetPtr = reinterpret_cast<const char *>(target_buffer.get());
+    return targetPtr;
+  }
+
+  return "";
+}
+
+}  // namespace google_breakpad
diff --git a/3rdParty/Breakpad/src/common/string_conversion.h b/3rdParty/Breakpad/src/common/string_conversion.h
new file mode 100644
index 0000000..eeed4d2
--- /dev/null
+++ b/3rdParty/Breakpad/src/common/string_conversion.h
@@ -0,0 +1,68 @@
+// 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.
+
+// string_conversion.h: Conversion between different UTF-8/16/32 encodings.
+
+#ifndef COMMON_STRING_CONVERSION_H__
+#define COMMON_STRING_CONVERSION_H__
+
+#include <string>
+#include <vector>
+
+#include "common/using_std_string.h"
+#include "google_breakpad/common/breakpad_types.h"
+
+namespace google_breakpad {
+  
+using std::vector;
+
+// Convert |in| to UTF-16 into |out|.  Use platform byte ordering.  If the
+// conversion failed, |out| will be zero length.
+void UTF8ToUTF16(const char *in, vector<u_int16_t> *out);
+
+// Convert at least one character (up to a maximum of |in_length|) from |in|
+// to UTF-16 into |out|.  Return the number of characters consumed from |in|.
+// Any unused characters in |out| will be initialized to 0.  No memory will
+// be allocated by this routine.
+int UTF8ToUTF16Char(const char *in, int in_length, u_int16_t out[2]);
+
+// Convert |in| to UTF-16 into |out|.  Use platform byte ordering.  If the
+// conversion failed, |out| will be zero length.
+void UTF32ToUTF16(const wchar_t *in, vector<u_int16_t> *out);
+
+// Convert |in| to UTF-16 into |out|.  Any unused characters in |out| will be
+// initialized to 0.  No memory will be allocated by this routine.
+void UTF32ToUTF16Char(wchar_t in, u_int16_t out[2]);
+
+// Convert |in| to UTF-8.  If |swap| is true, swap bytes before converting.
+string UTF16ToUTF8(const vector<u_int16_t> &in, bool swap);
+
+}  // namespace google_breakpad
+
+#endif  // COMMON_STRING_CONVERSION_H__
diff --git a/3rdParty/Breakpad/src/common/using_std_string.h b/3rdParty/Breakpad/src/common/using_std_string.h
new file mode 100644
index 0000000..13c1da5
--- /dev/null
+++ b/3rdParty/Breakpad/src/common/using_std_string.h
@@ -0,0 +1,65 @@
+// -*- mode: C++ -*-
+
+// 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.
+
+// Original author: Ivan Penkov
+
+// using_std_string.h: Allows building this code in environments where
+//                     global string (::string) exists.
+//
+// The problem:
+// -------------
+// Let's say you want to build this code in an environment where a global
+// string type is defined (i.e. ::string).  Now, let's suppose that ::string
+// is different that std::string and you'd like to have the option to easily
+// choose between the two string types.  Ideally you'd like to control which
+// string type is chosen by simply #defining an identifier.
+//
+// The solution:
+// -------------
+// #define HAS_GLOBAL_STRING somewhere in a global header file and then
+// globally replace std::string with string.  Then include this header
+// file everywhere where string is used.  If you want to revert back to
+// using std::string, simply remove the #define (HAS_GLOBAL_STRING).
+
+#ifndef THIRD_PARTY_BREAKPAD_SRC_COMMON_USING_STD_STRING_H_
+#define THIRD_PARTY_BREAKPAD_SRC_COMMON_USING_STD_STRING_H_
+
+#ifdef HAS_GLOBAL_STRING
+  typedef ::string google_breakpad_string;
+#else
+  using std::string;
+  typedef std::string google_breakpad_string;
+#endif
+
+// Inicates that type google_breakpad_string is defined
+#define HAS_GOOGLE_BREAKPAD_STRING
+
+#endif  // THIRD_PARTY_BREAKPAD_SRC_COMMON_USING_STD_STRING_H_
diff --git a/3rdParty/Breakpad/src/common/windows/guid_string.cc b/3rdParty/Breakpad/src/common/windows/guid_string.cc
new file mode 100644
index 0000000..b7f877e
--- /dev/null
+++ b/3rdParty/Breakpad/src/common/windows/guid_string.cc
@@ -0,0 +1,76 @@
+// 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.
+
+// guid_string.cc: Convert GUIDs to strings.
+//
+// See guid_string.h for documentation.
+
+#include <wchar.h>
+
+#include "common/windows/string_utils-inl.h"
+
+#include "common/windows/guid_string.h"
+
+namespace google_breakpad {
+
+// static
+wstring GUIDString::GUIDToWString(GUID *guid) {
+  wchar_t guid_string[37];
+  swprintf(
+      guid_string, sizeof(guid_string) / sizeof(guid_string[0]),
+      L"%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
+      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]);
+
+  // remove when VC++7.1 is no longer supported
+  guid_string[sizeof(guid_string) / sizeof(guid_string[0]) - 1] = L'\0';
+
+  return wstring(guid_string);
+}
+
+// static
+wstring GUIDString::GUIDToSymbolServerWString(GUID *guid) {
+  wchar_t guid_string[33];
+  swprintf(
+      guid_string, sizeof(guid_string) / sizeof(guid_string[0]),
+      L"%08X%04X%04X%02X%02X%02X%02X%02X%02X%02X%02X",
+      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]);
+
+  // remove when VC++7.1 is no longer supported
+  guid_string[sizeof(guid_string) / sizeof(guid_string[0]) - 1] = L'\0';
+
+  return wstring(guid_string);
+}
+
+}  // namespace google_breakpad
diff --git a/3rdParty/Breakpad/src/common/windows/guid_string.h b/3rdParty/Breakpad/src/common/windows/guid_string.h
new file mode 100644
index 0000000..f8aa8a2
--- /dev/null
+++ b/3rdParty/Breakpad/src/common/windows/guid_string.h
@@ -0,0 +1,58 @@
+// 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.
+
+// guid_string.cc: Convert GUIDs to strings.
+
+#ifndef COMMON_WINDOWS_GUID_STRING_H__
+#define COMMON_WINDOWS_GUID_STRING_H__
+
+#include <Guiddef.h>
+
+#include <string>
+
+namespace google_breakpad {
+
+using std::wstring;
+
+class GUIDString {
+ public:
+  // Converts guid to a string in the format recommended by RFC 4122 and
+  // returns the string.
+  static wstring GUIDToWString(GUID *guid);
+
+  // Converts guid to a string formatted as uppercase hexadecimal, with
+  // no separators, and returns the string.  This is the format used for
+  // symbol server identifiers, although identifiers have an age tacked
+  // on to the string.
+  static wstring GUIDToSymbolServerWString(GUID *guid);
+};
+
+}  // namespace google_breakpad
+
+#endif  // COMMON_WINDOWS_GUID_STRING_H__
diff --git a/3rdParty/Breakpad/src/common/windows/string_utils-inl.h b/3rdParty/Breakpad/src/common/windows/string_utils-inl.h
new file mode 100644
index 0000000..d281aaa
--- /dev/null
+++ b/3rdParty/Breakpad/src/common/windows/string_utils-inl.h
@@ -0,0 +1,142 @@
+// 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.
+
+// string_utils-inl.h: Safer string manipulation on Windows, supporting
+// pre-MSVC8 environments.
+
+#ifndef COMMON_WINDOWS_STRING_UTILS_INL_H__
+#define COMMON_WINDOWS_STRING_UTILS_INL_H__
+
+#include <stdarg.h>
+#include <wchar.h>
+
+#include <string>
+
+// The "ll" printf format size specifier corresponding to |long long| was
+// intrudced in MSVC8.  Earlier versions did not provide this size specifier,
+// but "I64" can be used to print 64-bit types.  Don't use "I64" where "ll"
+// is available, in the event of oddball systems where |long long| is not
+// 64 bits wide.
+#if _MSC_VER >= 1400  // MSVC 2005/8
+#define WIN_STRING_FORMAT_LL "ll"
+#else  // MSC_VER >= 1400
+#define WIN_STRING_FORMAT_LL "I64"
+#endif  // MSC_VER >= 1400
+
+// A nonconforming version of swprintf, without the length argument, was
+// included with the CRT prior to MSVC8.  Although a conforming version was
+// also available via an overload, it is not reliably chosen.  _snwprintf
+// behaves as a standards-confirming swprintf should, so force the use of
+// _snwprintf when using older CRTs.
+#if _MSC_VER < 1400  // MSVC 2005/8
+#define swprintf _snwprintf
+#else
+// For MSVC8 and newer, swprintf_s is the recommended method. Conveniently,
+// it takes the same argument list as swprintf.
+#define swprintf swprintf_s
+#endif  // MSC_VER < 1400
+
+namespace google_breakpad {
+
+using std::string;
+using std::wstring;
+
+class WindowsStringUtils {
+ public:
+  // Roughly equivalent to MSVC8's wcscpy_s, except pre-MSVC8, this does
+  // not fail if source is longer than destination_size.  The destination
+  // buffer is always 0-terminated.
+  static void safe_wcscpy(wchar_t *destination, size_t destination_size,
+                          const wchar_t *source);
+
+  // Roughly equivalent to MSVC8's wcsncpy_s, except that _TRUNCATE cannot
+  // be passed directly, and pre-MSVC8, this will not fail if source or count
+  // are longer than destination_size.  The destination buffer is always
+  // 0-terminated.
+  static void safe_wcsncpy(wchar_t *destination, size_t destination_size,
+                           const wchar_t *source, size_t count);
+
+  // Performs multi-byte to wide character conversion on C++ strings, using
+  // mbstowcs_s (MSVC8) or mbstowcs (pre-MSVC8).  Returns false on failure,
+  // without setting wcs.
+  static bool safe_mbstowcs(const string &mbs, wstring *wcs);
+
+  // The inverse of safe_mbstowcs.
+  static bool safe_wcstombs(const wstring &wcs, string *mbs);
+
+  // Returns the base name of a file, e.g. strips off the path.
+  static wstring GetBaseName(const wstring &filename);
+
+ private:
+  // Disallow instantiation and other object-based operations.
+  WindowsStringUtils();
+  WindowsStringUtils(const WindowsStringUtils&);
+  ~WindowsStringUtils();
+  void operator=(const WindowsStringUtils&);
+};
+
+// static
+inline void WindowsStringUtils::safe_wcscpy(wchar_t *destination,
+                                            size_t destination_size,
+                                            const wchar_t *source) {
+#if _MSC_VER >= 1400  // MSVC 2005/8
+  wcscpy_s(destination, destination_size, source);
+#else  // _MSC_VER >= 1400
+  // Pre-MSVC 2005/8 doesn't have wcscpy_s.  Simulate it with wcsncpy.
+  // wcsncpy doesn't 0-terminate the destination buffer if the source string
+  // is longer than size.  Ensure that the destination is 0-terminated.
+  wcsncpy(destination, source, destination_size);
+  if (destination && destination_size)
+    destination[destination_size - 1] = 0;
+#endif  // _MSC_VER >= 1400
+}
+
+// static
+inline void WindowsStringUtils::safe_wcsncpy(wchar_t *destination,
+                                             size_t destination_size,
+                                             const wchar_t *source,
+                                             size_t count) {
+#if _MSC_VER >= 1400  // MSVC 2005/8
+  wcsncpy_s(destination, destination_size, source, count);
+#else  // _MSC_VER >= 1400
+  // Pre-MSVC 2005/8 doesn't have wcsncpy_s.  Simulate it with wcsncpy.
+  // wcsncpy doesn't 0-terminate the destination buffer if the source string
+  // is longer than size.  Ensure that the destination is 0-terminated.
+  if (destination_size < count)
+    count = destination_size;
+
+  wcsncpy(destination, source, count);
+  if (destination && count)
+    destination[count - 1] = 0;
+#endif  // _MSC_VER >= 1400
+}
+
+}  // namespace google_breakpad
+
+#endif  // COMMON_WINDOWS_STRING_UTILS_INL_H__
diff --git a/3rdParty/Breakpad/src/google_breakpad/common/breakpad_types.h b/3rdParty/Breakpad/src/google_breakpad/common/breakpad_types.h
new file mode 100644
index 0000000..926b47f
--- /dev/null
+++ b/3rdParty/Breakpad/src/google_breakpad/common/breakpad_types.h
@@ -0,0 +1,83 @@
+/* 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. */
+
+/* breakpad_types.h: Precise-width types
+ *
+ * (This is C99 source, please don't corrupt it with C++.)
+ *
+ * This file ensures that types u_intN_t are defined for N = 8, 16, 32, and
+ * 64.  Types of precise widths are crucial to the task of writing data
+ * structures on one platform and reading them on another.
+ *
+ * Author: Mark Mentovai */
+
+#ifndef GOOGLE_BREAKPAD_COMMON_BREAKPAD_TYPES_H__
+#define GOOGLE_BREAKPAD_COMMON_BREAKPAD_TYPES_H__
+
+#ifndef _WIN32
+
+#include <sys/types.h>
+#ifndef __STDC_FORMAT_MACROS
+#define __STDC_FORMAT_MACROS
+#endif  /* __STDC_FORMAT_MACROS */
+#include <inttypes.h>
+
+#if defined(__SUNPRO_CC) || (defined(__GNUC__) && defined(__sun__))
+typedef uint8_t u_int8_t;
+typedef uint16_t u_int16_t;
+typedef uint32_t u_int32_t;
+typedef uint64_t u_int64_t;
+#endif
+
+#else  /* !_WIN32 */
+
+#include <WTypes.h>
+
+typedef unsigned __int8  u_int8_t;
+typedef unsigned __int16 u_int16_t;
+typedef unsigned __int32 u_int32_t;
+typedef unsigned __int64 u_int64_t;
+
+#endif  /* !_WIN32 */
+
+typedef struct {
+  u_int64_t high;
+  u_int64_t low;
+} u_int128_t;
+
+typedef u_int64_t breakpad_time_t;
+
+/* Try to get PRIx64 from inttypes.h, but if it's not defined, fall back to
+ * llx, which is the format string for "long long" - this is a 64-bit
+ * integral type on many systems. */
+#ifndef PRIx64
+#define PRIx64 "llx"
+#endif  /* !PRIx64 */
+
+#endif  /* GOOGLE_BREAKPAD_COMMON_BREAKPAD_TYPES_H__ */
diff --git a/3rdParty/Breakpad/src/google_breakpad/common/minidump_cpu_amd64.h b/3rdParty/Breakpad/src/google_breakpad/common/minidump_cpu_amd64.h
new file mode 100644
index 0000000..fa6a996
--- /dev/null
+++ b/3rdParty/Breakpad/src/google_breakpad/common/minidump_cpu_amd64.h
@@ -0,0 +1,235 @@
+/* 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_format.h: A cross-platform reimplementation of minidump-related
+ * portions of DbgHelp.h from the Windows Platform SDK.
+ *
+ * (This is C99 source, please don't corrupt it with C++.)
+ *
+ * This file contains the necessary definitions to read minidump files
+ * produced on amd64.  These files may be read on any platform provided
+ * that the alignments of these structures on the processing system are
+ * identical to the alignments of these structures on the producing system.
+ * For this reason, precise-sized types are used.  The structures defined
+ * by this file have been laid out to minimize alignment problems by ensuring
+ * ensuring that all members are aligned on their natural boundaries.  In
+ * In some cases, tail-padding may be significant when different ABIs specify
+ * different tail-padding behaviors.  To avoid problems when reading or
+ * writing affected structures, MD_*_SIZE macros are provided where needed,
+ * containing the useful size of the structures without padding.
+ *
+ * Structures that are defined by Microsoft to contain a zero-length array
+ * are instead defined here to contain an array with one element, as
+ * zero-length arrays are forbidden by standard C and C++.  In these cases,
+ * *_minsize constants are provided to be used in place of sizeof.  For a
+ * cleaner interface to these sizes when using C++, see minidump_size.h.
+ *
+ * These structures are also sufficient to populate minidump files.
+ *
+ * These definitions may be extended to support handling minidump files
+ * for other CPUs and other operating systems.
+ *
+ * Because precise data type sizes are crucial for this implementation to
+ * function properly and portably in terms of interoperability with minidumps
+ * produced by DbgHelp on Windows, a set of primitive types with known sizes
+ * are used as the basis of each structure defined by this file.  DbgHelp
+ * on Windows is assumed to be the reference implementation; this file
+ * seeks to provide a cross-platform compatible implementation.  To avoid
+ * collisions with the types and values defined and used by DbgHelp in the
+ * event that this implementation is used on Windows, each type and value
+ * defined here is given a new name, beginning with "MD".  Names of the
+ * equivalent types and values in the Windows Platform SDK are given in
+ * comments.
+ *
+ * Author: Mark Mentovai 
+ * Change to split into its own file: Neal Sidhwaney */
+
+#ifndef GOOGLE_BREAKPAD_COMMON_MINIDUMP_CPU_AMD64_H__
+#define GOOGLE_BREAKPAD_COMMON_MINIDUMP_CPU_AMD64_H__
+
+
+/*
+ * AMD64 support, see WINNT.H
+ */
+
+typedef struct {
+  u_int16_t  control_word;
+  u_int16_t  status_word;
+  u_int8_t   tag_word;
+  u_int8_t   reserved1;
+  u_int16_t  error_opcode;
+  u_int32_t  error_offset;
+  u_int16_t  error_selector;
+  u_int16_t  reserved2;
+  u_int32_t  data_offset;
+  u_int16_t  data_selector;
+  u_int16_t  reserved3;
+  u_int32_t  mx_csr;
+  u_int32_t  mx_csr_mask;
+  u_int128_t float_registers[8];
+  u_int128_t xmm_registers[16];
+  u_int8_t   reserved4[96];
+} MDXmmSaveArea32AMD64;  /* XMM_SAVE_AREA32 */
+
+#define MD_CONTEXT_AMD64_VR_COUNT 26
+
+typedef struct {
+  /*
+   * Register parameter home addresses.
+   */
+  u_int64_t  p1_home;
+  u_int64_t  p2_home;
+  u_int64_t  p3_home;
+  u_int64_t  p4_home;
+  u_int64_t  p5_home;
+  u_int64_t  p6_home;
+
+  /* The next field determines the layout of the structure, and which parts
+   * of it are populated */
+  u_int32_t  context_flags;
+  u_int32_t  mx_csr;
+
+  /* The next register is included with MD_CONTEXT_AMD64_CONTROL */
+  u_int16_t  cs;
+
+  /* The next 4 registers are included with MD_CONTEXT_AMD64_SEGMENTS */
+  u_int16_t  ds;
+  u_int16_t  es;
+  u_int16_t  fs;
+  u_int16_t  gs;
+
+  /* The next 2 registers are included with MD_CONTEXT_AMD64_CONTROL */
+  u_int16_t  ss;
+  u_int32_t  eflags;
+  
+  /* The next 6 registers are included with MD_CONTEXT_AMD64_DEBUG_REGISTERS */
+  u_int64_t  dr0;
+  u_int64_t  dr1;
+  u_int64_t  dr2;
+  u_int64_t  dr3;
+  u_int64_t  dr6;
+  u_int64_t  dr7;
+
+  /* The next 4 registers are included with MD_CONTEXT_AMD64_INTEGER */
+  u_int64_t  rax;
+  u_int64_t  rcx;
+  u_int64_t  rdx;
+  u_int64_t  rbx;
+
+  /* The next register is included with MD_CONTEXT_AMD64_CONTROL */
+  u_int64_t  rsp;
+
+  /* The next 11 registers are included with MD_CONTEXT_AMD64_INTEGER */
+  u_int64_t  rbp;
+  u_int64_t  rsi;
+  u_int64_t  rdi;
+  u_int64_t  r8;
+  u_int64_t  r9;
+  u_int64_t  r10;
+  u_int64_t  r11;
+  u_int64_t  r12;
+  u_int64_t  r13;
+  u_int64_t  r14;
+  u_int64_t  r15;
+
+  /* The next register is included with MD_CONTEXT_AMD64_CONTROL */
+  u_int64_t  rip;
+
+  /* The next set of registers are included with
+   * MD_CONTEXT_AMD64_FLOATING_POINT
+   */
+  union {
+    MDXmmSaveArea32AMD64 flt_save;
+    struct {
+      u_int128_t header[2];
+      u_int128_t legacy[8];
+      u_int128_t xmm0;
+      u_int128_t xmm1;
+      u_int128_t xmm2;
+      u_int128_t xmm3;
+      u_int128_t xmm4;
+      u_int128_t xmm5;
+      u_int128_t xmm6;
+      u_int128_t xmm7;
+      u_int128_t xmm8;
+      u_int128_t xmm9;
+      u_int128_t xmm10;
+      u_int128_t xmm11;
+      u_int128_t xmm12;
+      u_int128_t xmm13;
+      u_int128_t xmm14;
+      u_int128_t xmm15;
+    } sse_registers;
+  };
+
+  u_int128_t vector_register[MD_CONTEXT_AMD64_VR_COUNT];
+  u_int64_t  vector_control;
+
+  /* The next 5 registers are included with MD_CONTEXT_AMD64_DEBUG_REGISTERS */
+  u_int64_t debug_control;
+  u_int64_t last_branch_to_rip;
+  u_int64_t last_branch_from_rip;
+  u_int64_t last_exception_to_rip;
+  u_int64_t last_exception_from_rip;
+  
+} MDRawContextAMD64;  /* CONTEXT */
+
+/* For (MDRawContextAMD64).context_flags.  These values indicate the type of
+ * context stored in the structure.  The high 24 bits identify the CPU, the
+ * low 8 bits identify the type of context saved. */
+#define MD_CONTEXT_AMD64 0x00100000  /* CONTEXT_AMD64 */
+#define MD_CONTEXT_AMD64_CONTROL         (MD_CONTEXT_AMD64 | 0x00000001)
+     /* CONTEXT_CONTROL */
+#define MD_CONTEXT_AMD64_INTEGER         (MD_CONTEXT_AMD64 | 0x00000002)
+     /* CONTEXT_INTEGER */
+#define MD_CONTEXT_AMD64_SEGMENTS        (MD_CONTEXT_AMD64 | 0x00000004)
+     /* CONTEXT_SEGMENTS */
+#define MD_CONTEXT_AMD64_FLOATING_POINT  (MD_CONTEXT_AMD64 | 0x00000008)
+     /* CONTEXT_FLOATING_POINT */
+#define MD_CONTEXT_AMD64_DEBUG_REGISTERS (MD_CONTEXT_AMD64 | 0x00000010)
+     /* CONTEXT_DEBUG_REGISTERS */
+#define MD_CONTEXT_AMD64_XSTATE          (MD_CONTEXT_AMD64 | 0x00000040)
+     /* CONTEXT_XSTATE */
+
+/* WinNT.h refers to CONTEXT_MMX_REGISTERS but doesn't appear to define it
+ * I think it really means CONTEXT_FLOATING_POINT.
+ */
+
+#define MD_CONTEXT_AMD64_FULL            (MD_CONTEXT_AMD64_CONTROL | \
+                                          MD_CONTEXT_AMD64_INTEGER | \
+                                          MD_CONTEXT_AMD64_FLOATING_POINT)
+     /* CONTEXT_FULL */
+
+#define MD_CONTEXT_AMD64_ALL             (MD_CONTEXT_AMD64_FULL | \
+                                          MD_CONTEXT_AMD64_SEGMENTS | \
+                                          MD_CONTEXT_X86_DEBUG_REGISTERS)
+     /* CONTEXT_ALL */
+
+
+#endif /* GOOGLE_BREAKPAD_COMMON_MINIDUMP_CPU_AMD64_H__ */
diff --git a/3rdParty/Breakpad/src/google_breakpad/common/minidump_cpu_arm.h b/3rdParty/Breakpad/src/google_breakpad/common/minidump_cpu_arm.h
new file mode 100644
index 0000000..dd07129
--- /dev/null
+++ b/3rdParty/Breakpad/src/google_breakpad/common/minidump_cpu_arm.h
@@ -0,0 +1,151 @@
+/* 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. */
+
+/* minidump_format.h: A cross-platform reimplementation of minidump-related
+ * portions of DbgHelp.h from the Windows Platform SDK.
+ *
+ * (This is C99 source, please don't corrupt it with C++.)
+ *
+ * This file contains the necessary definitions to read minidump files
+ * produced on ARM.  These files may be read on any platform provided
+ * that the alignments of these structures on the processing system are
+ * identical to the alignments of these structures on the producing system.
+ * For this reason, precise-sized types are used.  The structures defined
+ * by this file have been laid out to minimize alignment problems by
+ * ensuring that all members are aligned on their natural boundaries.
+ * In some cases, tail-padding may be significant when different ABIs specify
+ * different tail-padding behaviors.  To avoid problems when reading or
+ * writing affected structures, MD_*_SIZE macros are provided where needed,
+ * containing the useful size of the structures without padding.
+ *
+ * Structures that are defined by Microsoft to contain a zero-length array
+ * are instead defined here to contain an array with one element, as
+ * zero-length arrays are forbidden by standard C and C++.  In these cases,
+ * *_minsize constants are provided to be used in place of sizeof.  For a
+ * cleaner interface to these sizes when using C++, see minidump_size.h.
+ *
+ * These structures are also sufficient to populate minidump files.
+ *
+ * Because precise data type sizes are crucial for this implementation to
+ * function properly and portably, a set of primitive types with known sizes
+ * are used as the basis of each structure defined by this file.
+ *
+ * Author: Julian Seward
+ */
+
+/*
+ * ARM support
+ */
+
+#ifndef GOOGLE_BREAKPAD_COMMON_MINIDUMP_CPU_ARM_H__
+#define GOOGLE_BREAKPAD_COMMON_MINIDUMP_CPU_ARM_H__
+
+#define MD_FLOATINGSAVEAREA_ARM_FPR_COUNT 32
+#define MD_FLOATINGSAVEAREA_ARM_FPEXTRA_COUNT 8
+
+/*
+ * Note that these structures *do not* map directly to the CONTEXT
+ * structure defined in WinNT.h in the Windows Mobile SDK. That structure
+ * does not accomodate VFPv3, and I'm unsure if it was ever used in the
+ * wild anyway, as Windows CE only seems to produce "cedumps" which
+ * are not exactly minidumps.
+ */
+typedef struct {
+  u_int64_t	fpscr;      /* FPU status register */
+
+  /* 32 64-bit floating point registers, d0 .. d31. */
+  u_int64_t	regs[MD_FLOATINGSAVEAREA_ARM_FPR_COUNT];
+
+  /* Miscellaneous control words */
+  u_int32_t     extra[MD_FLOATINGSAVEAREA_ARM_FPEXTRA_COUNT];
+} MDFloatingSaveAreaARM;
+
+#define MD_CONTEXT_ARM_GPR_COUNT 16
+
+typedef struct {
+  /* The next field determines the layout of the structure, and which parts
+   * of it are populated
+   */
+  u_int32_t	context_flags;
+
+  /* 16 32-bit integer registers, r0 .. r15
+   * Note the following fixed uses:
+   *   r13 is the stack pointer
+   *   r14 is the link register
+   *   r15 is the program counter
+   */
+  u_int32_t     iregs[MD_CONTEXT_ARM_GPR_COUNT];
+
+  /* CPSR (flags, basically): 32 bits:
+        bit 31 - N (negative)
+        bit 30 - Z (zero)
+        bit 29 - C (carry)
+        bit 28 - V (overflow)
+        bit 27 - Q (saturation flag, sticky)
+     All other fields -- ignore */
+  u_int32_t    cpsr;
+
+  /* The next field is included with MD_CONTEXT_ARM_FLOATING_POINT */
+  MDFloatingSaveAreaARM float_save;
+
+} MDRawContextARM;
+
+/* Indices into iregs for registers with a dedicated or conventional 
+ * purpose.
+ */
+enum MDARMRegisterNumbers {
+  MD_CONTEXT_ARM_REG_IOS_FP = 7,
+  MD_CONTEXT_ARM_REG_FP     = 11,
+  MD_CONTEXT_ARM_REG_SP     = 13,
+  MD_CONTEXT_ARM_REG_LR     = 14,
+  MD_CONTEXT_ARM_REG_PC     = 15
+};
+
+/* For (MDRawContextARM).context_flags.  These values indicate the type of
+ * context stored in the structure. */
+/* CONTEXT_ARM from the Windows CE 5.0 SDK. This value isn't correct
+ * because this bit can be used for flags. Presumably this value was
+ * never actually used in minidumps, but only in "CEDumps" which
+ * are a whole parallel minidump file format for Windows CE.
+ * Therefore, Breakpad defines its own value for ARM CPUs.
+ */
+#define MD_CONTEXT_ARM_OLD               0x00000040
+/* This value was chosen to avoid likely conflicts with MD_CONTEXT_*
+ * for other CPUs. */
+#define MD_CONTEXT_ARM                   0x40000000
+#define MD_CONTEXT_ARM_INTEGER           (MD_CONTEXT_ARM | 0x00000002)
+#define MD_CONTEXT_ARM_FLOATING_POINT    (MD_CONTEXT_ARM | 0x00000004)
+
+#define MD_CONTEXT_ARM_FULL              (MD_CONTEXT_ARM_INTEGER | \
+                                          MD_CONTEXT_ARM_FLOATING_POINT)
+
+#define MD_CONTEXT_ARM_ALL               (MD_CONTEXT_ARM_INTEGER | \
+                                          MD_CONTEXT_ARM_FLOATING_POINT)
+
+#endif  /* GOOGLE_BREAKPAD_COMMON_MINIDUMP_CPU_ARM_H__ */
diff --git a/3rdParty/Breakpad/src/google_breakpad/common/minidump_cpu_ppc.h b/3rdParty/Breakpad/src/google_breakpad/common/minidump_cpu_ppc.h
new file mode 100644
index 0000000..038e921
--- /dev/null
+++ b/3rdParty/Breakpad/src/google_breakpad/common/minidump_cpu_ppc.h
@@ -0,0 +1,163 @@
+/* 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_format.h: A cross-platform reimplementation of minidump-related
+ * portions of DbgHelp.h from the Windows Platform SDK.
+ *
+ * (This is C99 source, please don't corrupt it with C++.)
+ *
+ * This file contains the necessary definitions to read minidump files
+ * produced on ppc.  These files may be read on any platform provided
+ * that the alignments of these structures on the processing system are
+ * identical to the alignments of these structures on the producing system.
+ * For this reason, precise-sized types are used.  The structures defined
+ * by this file have been laid out to minimize alignment problems by ensuring
+ * ensuring that all members are aligned on their natural boundaries.  In
+ * In some cases, tail-padding may be significant when different ABIs specify
+ * different tail-padding behaviors.  To avoid problems when reading or
+ * writing affected structures, MD_*_SIZE macros are provided where needed,
+ * containing the useful size of the structures without padding.
+ *
+ * Structures that are defined by Microsoft to contain a zero-length array
+ * are instead defined here to contain an array with one element, as
+ * zero-length arrays are forbidden by standard C and C++.  In these cases,
+ * *_minsize constants are provided to be used in place of sizeof.  For a
+ * cleaner interface to these sizes when using C++, see minidump_size.h.
+ *
+ * These structures are also sufficient to populate minidump files.
+ *
+ * These definitions may be extended to support handling minidump files
+ * for other CPUs and other operating systems.
+ *
+ * Because precise data type sizes are crucial for this implementation to
+ * function properly and portably in terms of interoperability with minidumps
+ * produced by DbgHelp on Windows, a set of primitive types with known sizes
+ * are used as the basis of each structure defined by this file.  DbgHelp
+ * on Windows is assumed to be the reference implementation; this file
+ * seeks to provide a cross-platform compatible implementation.  To avoid
+ * collisions with the types and values defined and used by DbgHelp in the
+ * event that this implementation is used on Windows, each type and value
+ * defined here is given a new name, beginning with "MD".  Names of the
+ * equivalent types and values in the Windows Platform SDK are given in
+ * comments.
+ *
+ * Author: Mark Mentovai 
+ * Change to split into its own file: Neal Sidhwaney */
+
+/*
+ * Breakpad minidump extension for PowerPC support.  Based on Darwin/Mac OS X'
+ * mach/ppc/_types.h
+ */
+
+#ifndef GOOGLE_BREAKPAD_COMMON_MINIDUMP_CPU_PPC_H__
+#define GOOGLE_BREAKPAD_COMMON_MINIDUMP_CPU_PPC_H__
+
+#define MD_FLOATINGSAVEAREA_PPC_FPR_COUNT 32
+
+typedef struct {
+  /* fpregs is a double[32] in mach/ppc/_types.h, but a u_int64_t is used
+   * here for precise sizing. */
+  u_int64_t fpregs[MD_FLOATINGSAVEAREA_PPC_FPR_COUNT];
+  u_int32_t fpscr_pad;
+  u_int32_t fpscr;      /* Status/control */
+} MDFloatingSaveAreaPPC;  /* Based on ppc_float_state */
+
+
+#define MD_VECTORSAVEAREA_PPC_VR_COUNT 32
+
+typedef struct {
+  /* Vector registers (including vscr) are 128 bits, but mach/ppc/_types.h
+   * exposes them as four 32-bit quantities. */
+  u_int128_t save_vr[MD_VECTORSAVEAREA_PPC_VR_COUNT];
+  u_int128_t save_vscr;  /* Status/control */
+  u_int32_t  save_pad5[4];
+  u_int32_t  save_vrvalid;  /* Identifies which vector registers are saved */
+  u_int32_t  save_pad6[7];
+} MDVectorSaveAreaPPC;  /* ppc_vector_state */
+
+
+#define MD_CONTEXT_PPC_GPR_COUNT 32
+
+/* Use the same 32-bit alignment when accessing this structure from 64-bit code
+ * as is used natively in 32-bit code.  #pragma pack is a MSVC extension
+ * supported by gcc. */
+#if defined(__SUNPRO_C) || defined(__SUNPRO_CC)
+#pragma pack(4)
+#else
+#pragma pack(push, 4)
+#endif
+
+typedef struct {
+  /* context_flags is not present in ppc_thread_state, but it aids
+   * identification of MDRawContextPPC among other raw context types,
+   * and it guarantees alignment when we get to float_save. */
+  u_int32_t             context_flags;
+
+  u_int32_t             srr0;    /* Machine status save/restore: stores pc
+                                  * (instruction) */
+  u_int32_t             srr1;    /* Machine status save/restore: stores msr
+                                  * (ps, program/machine state) */
+  /* ppc_thread_state contains 32 fields, r0 .. r31.  Here, an array is
+   * used for brevity. */
+  u_int32_t             gpr[MD_CONTEXT_PPC_GPR_COUNT];
+  u_int32_t             cr;      /* Condition */
+  u_int32_t             xer;     /* Integer (fiXed-point) exception */
+  u_int32_t             lr;      /* Link */
+  u_int32_t             ctr;     /* Count */
+  u_int32_t             mq;      /* Multiply/Quotient (PPC 601, POWER only) */
+  u_int32_t             vrsave;  /* Vector save */
+
+  /* float_save and vector_save aren't present in ppc_thread_state, but
+   * are represented in separate structures that still define a thread's
+   * context. */
+  MDFloatingSaveAreaPPC float_save;
+  MDVectorSaveAreaPPC   vector_save;
+} MDRawContextPPC;  /* Based on ppc_thread_state */
+
+#if defined(__SUNPRO_C) || defined(__SUNPRO_CC)
+#pragma pack(0)
+#else
+#pragma pack(pop)
+#endif
+
+/* For (MDRawContextPPC).context_flags.  These values indicate the type of
+ * context stored in the structure.  MD_CONTEXT_PPC is Breakpad-defined.  Its
+ * value was chosen to avoid likely conflicts with MD_CONTEXT_* for other
+ * CPUs. */
+#define MD_CONTEXT_PPC                0x20000000
+#define MD_CONTEXT_PPC_BASE           (MD_CONTEXT_PPC | 0x00000001)
+#define MD_CONTEXT_PPC_FLOATING_POINT (MD_CONTEXT_PPC | 0x00000008)
+#define MD_CONTEXT_PPC_VECTOR         (MD_CONTEXT_PPC | 0x00000020)
+
+#define MD_CONTEXT_PPC_FULL           MD_CONTEXT_PPC_BASE
+#define MD_CONTEXT_PPC_ALL            (MD_CONTEXT_PPC_FULL | \
+                                       MD_CONTEXT_PPC_FLOATING_POINT | \
+                                       MD_CONTEXT_PPC_VECTOR)
+
+#endif /* GOOGLE_BREAKPAD_COMMON_MINIDUMP_CPU_PPC_H__ */
diff --git a/3rdParty/Breakpad/src/google_breakpad/common/minidump_cpu_ppc64.h b/3rdParty/Breakpad/src/google_breakpad/common/minidump_cpu_ppc64.h
new file mode 100644
index 0000000..a788e5d
--- /dev/null
+++ b/3rdParty/Breakpad/src/google_breakpad/common/minidump_cpu_ppc64.h
@@ -0,0 +1,129 @@
+/* Copyright (c) 2008, 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_format.h: A cross-platform reimplementation of minidump-related
+ * portions of DbgHelp.h from the Windows Platform SDK.
+ *
+ * (This is C99 source, please don't corrupt it with C++.)
+ *
+ * This file contains the necessary definitions to read minidump files
+ * produced on ppc64.  These files may be read on any platform provided
+ * that the alignments of these structures on the processing system are
+ * identical to the alignments of these structures on the producing system.
+ * For this reason, precise-sized types are used.  The structures defined
+ * by this file have been laid out to minimize alignment problems by ensuring
+ * ensuring that all members are aligned on their natural boundaries.  In
+ * In some cases, tail-padding may be significant when different ABIs specify
+ * different tail-padding behaviors.  To avoid problems when reading or
+ * writing affected structures, MD_*_SIZE macros are provided where needed,
+ * containing the useful size of the structures without padding.
+ *
+ * Structures that are defined by Microsoft to contain a zero-length array
+ * are instead defined here to contain an array with one element, as
+ * zero-length arrays are forbidden by standard C and C++.  In these cases,
+ * *_minsize constants are provided to be used in place of sizeof.  For a
+ * cleaner interface to these sizes when using C++, see minidump_size.h.
+ *
+ * These structures are also sufficient to populate minidump files.
+ *
+ * These definitions may be extended to support handling minidump files
+ * for other CPUs and other operating systems.
+ *
+ * Because precise data type sizes are crucial for this implementation to
+ * function properly and portably in terms of interoperability with minidumps
+ * produced by DbgHelp on Windows, a set of primitive types with known sizes
+ * are used as the basis of each structure defined by this file.  DbgHelp
+ * on Windows is assumed to be the reference implementation; this file
+ * seeks to provide a cross-platform compatible implementation.  To avoid
+ * collisions with the types and values defined and used by DbgHelp in the
+ * event that this implementation is used on Windows, each type and value
+ * defined here is given a new name, beginning with "MD".  Names of the
+ * equivalent types and values in the Windows Platform SDK are given in
+ * comments.
+ *
+ * Author: Neal Sidhwaney */
+
+
+/*
+ * Breakpad minidump extension for PPC64 support.  Based on Darwin/Mac OS X'
+ * mach/ppc/_types.h
+ */
+
+#ifndef GOOGLE_BREAKPAD_COMMON_MINIDUMP_CPU_PPC64_H__
+#define GOOGLE_BREAKPAD_COMMON_MINIDUMP_CPU_PPC64_H__
+
+#include "minidump_cpu_ppc.h"
+
+// these types are the same in ppc64 & ppc
+typedef MDFloatingSaveAreaPPC MDFloatingSaveAreaPPC64;
+typedef MDVectorSaveAreaPPC MDVectorSaveAreaPPC64;
+
+#define MD_CONTEXT_PPC64_GPR_COUNT MD_CONTEXT_PPC_GPR_COUNT
+
+typedef struct {
+  /* context_flags is not present in ppc_thread_state, but it aids
+   * identification of MDRawContextPPC among other raw context types,
+   * and it guarantees alignment when we get to float_save. */
+  u_int64_t             context_flags;
+
+  u_int64_t             srr0;    /* Machine status save/restore: stores pc
+                                  * (instruction) */
+  u_int64_t             srr1;    /* Machine status save/restore: stores msr
+                                  * (ps, program/machine state) */
+  /* ppc_thread_state contains 32 fields, r0 .. r31.  Here, an array is
+   * used for brevity. */
+  u_int64_t             gpr[MD_CONTEXT_PPC64_GPR_COUNT];
+  u_int64_t             cr;      /* Condition */
+  u_int64_t             xer;     /* Integer (fiXed-point) exception */
+  u_int64_t             lr;      /* Link */
+  u_int64_t             ctr;     /* Count */
+  u_int64_t             vrsave;  /* Vector save */
+
+  /* float_save and vector_save aren't present in ppc_thread_state, but
+   * are represented in separate structures that still define a thread's
+   * context. */
+  MDFloatingSaveAreaPPC float_save;
+  MDVectorSaveAreaPPC   vector_save;
+} MDRawContextPPC64;  /* Based on ppc_thread_state */
+
+/* For (MDRawContextPPC).context_flags.  These values indicate the type of
+ * context stored in the structure.  MD_CONTEXT_PPC is Breakpad-defined.  Its
+ * value was chosen to avoid likely conflicts with MD_CONTEXT_* for other
+ * CPUs. */
+#define MD_CONTEXT_PPC                0x20000000
+#define MD_CONTEXT_PPC_BASE           (MD_CONTEXT_PPC | 0x00000001)
+#define MD_CONTEXT_PPC_FLOATING_POINT (MD_CONTEXT_PPC | 0x00000008)
+#define MD_CONTEXT_PPC_VECTOR         (MD_CONTEXT_PPC | 0x00000020)
+
+#define MD_CONTEXT_PPC_FULL           MD_CONTEXT_PPC_BASE
+#define MD_CONTEXT_PPC_ALL            (MD_CONTEXT_PPC_FULL | \
+                                       MD_CONTEXT_PPC_FLOATING_POINT | \
+                                       MD_CONTEXT_PPC_VECTOR)
+
+#endif /* GOOGLE_BREAKPAD_COMMON_MINIDUMP_CPU_PPC64_H__ */
diff --git a/3rdParty/Breakpad/src/google_breakpad/common/minidump_cpu_sparc.h b/3rdParty/Breakpad/src/google_breakpad/common/minidump_cpu_sparc.h
new file mode 100644
index 0000000..ee95b64
--- /dev/null
+++ b/3rdParty/Breakpad/src/google_breakpad/common/minidump_cpu_sparc.h
@@ -0,0 +1,158 @@
+/* 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_format.h: A cross-platform reimplementation of minidump-related
+ * portions of DbgHelp.h from the Windows Platform SDK.
+ *
+ * (This is C99 source, please don't corrupt it with C++.)
+ *
+ * This file contains the necessary definitions to read minidump files
+ * produced on sparc.  These files may be read on any platform provided
+ * that the alignments of these structures on the processing system are
+ * identical to the alignments of these structures on the producing system.
+ * For this reason, precise-sized types are used.  The structures defined
+ * by this file have been laid out to minimize alignment problems by ensuring
+ * ensuring that all members are aligned on their natural boundaries.  In
+ * In some cases, tail-padding may be significant when different ABIs specify
+ * different tail-padding behaviors.  To avoid problems when reading or
+ * writing affected structures, MD_*_SIZE macros are provided where needed,
+ * containing the useful size of the structures without padding.
+ *
+ * Structures that are defined by Microsoft to contain a zero-length array
+ * are instead defined here to contain an array with one element, as
+ * zero-length arrays are forbidden by standard C and C++.  In these cases,
+ * *_minsize constants are provided to be used in place of sizeof.  For a
+ * cleaner interface to these sizes when using C++, see minidump_size.h.
+ *
+ * These structures are also sufficient to populate minidump files.
+ *
+ * These definitions may be extended to support handling minidump files
+ * for other CPUs and other operating systems.
+ *
+ * Because precise data type sizes are crucial for this implementation to
+ * function properly and portably in terms of interoperability with minidumps
+ * produced by DbgHelp on Windows, a set of primitive types with known sizes
+ * are used as the basis of each structure defined by this file.  DbgHelp
+ * on Windows is assumed to be the reference implementation; this file
+ * seeks to provide a cross-platform compatible implementation.  To avoid
+ * collisions with the types and values defined and used by DbgHelp in the
+ * event that this implementation is used on Windows, each type and value
+ * defined here is given a new name, beginning with "MD".  Names of the
+ * equivalent types and values in the Windows Platform SDK are given in
+ * comments.
+ *
+ * Author: Mark Mentovai
+ * Change to split into its own file: Neal Sidhwaney */
+
+/*
+ * SPARC support, see (solaris)sys/procfs_isa.h also
+ */
+
+#ifndef GOOGLE_BREAKPAD_COMMON_MINIDUMP_CPU_SPARC_H__
+#define GOOGLE_BREAKPAD_COMMON_MINIDUMP_CPU_SPARC_H__
+
+#define MD_FLOATINGSAVEAREA_SPARC_FPR_COUNT 32
+
+typedef struct {
+
+  /* FPU floating point regs */
+  u_int64_t	regs[MD_FLOATINGSAVEAREA_SPARC_FPR_COUNT];
+
+  u_int64_t	filler;
+  u_int64_t	fsr;        /* FPU status register */
+} MDFloatingSaveAreaSPARC;  /* FLOATING_SAVE_AREA */
+
+#define MD_CONTEXT_SPARC_GPR_COUNT 32
+
+typedef struct {
+  /* The next field determines the layout of the structure, and which parts
+   * of it are populated
+   */
+  u_int32_t	context_flags;
+  u_int32_t	flag_pad;
+  /*
+   * General register access (SPARC).
+   * Don't confuse definitions here with definitions in <sys/regset.h>.
+   * Registers are 32 bits for ILP32, 64 bits for LP64.
+   * SPARC V7/V8 is for 32bit, SPARC V9 is for 64bit
+   */
+
+  /* 32 Integer working registers */
+
+  /* g_r[0-7]   global registers(g0-g7)
+   * g_r[8-15]  out registers(o0-o7)
+   * g_r[16-23] local registers(l0-l7)
+   * g_r[24-31] in registers(i0-i7)
+   */
+  u_int64_t     g_r[MD_CONTEXT_SPARC_GPR_COUNT];
+
+  /* several control registers */
+
+  /* Processor State register(PSR) for SPARC V7/V8
+   * Condition Code register (CCR) for SPARC V9
+   */
+  u_int64_t     ccr;
+
+  u_int64_t     pc;     /* Program Counter register (PC) */
+  u_int64_t     npc;    /* Next Program Counter register (nPC) */
+  u_int64_t     y;      /* Y register (Y) */
+
+  /* Address Space Identifier register (ASI) for SPARC V9
+   * WIM for SPARC V7/V8
+   */
+  u_int64_t     asi;
+
+  /* Floating-Point Registers State register (FPRS) for SPARC V9
+   * TBR for for SPARC V7/V8
+   */
+  u_int64_t     fprs;
+
+  /* The next field is included with MD_CONTEXT_SPARC_FLOATING_POINT */
+  MDFloatingSaveAreaSPARC float_save;
+
+} MDRawContextSPARC;  /* CONTEXT_SPARC */
+
+/* For (MDRawContextSPARC).context_flags.  These values indicate the type of
+ * context stored in the structure.  MD_CONTEXT_SPARC is Breakpad-defined.  Its
+ * value was chosen to avoid likely conflicts with MD_CONTEXT_* for other
+ * CPUs. */
+#define MD_CONTEXT_SPARC                 0x10000000
+#define MD_CONTEXT_SPARC_CONTROL         (MD_CONTEXT_SPARC | 0x00000001)
+#define MD_CONTEXT_SPARC_INTEGER         (MD_CONTEXT_SPARC | 0x00000002)
+#define MD_CONTEXT_SAPARC_FLOATING_POINT (MD_CONTEXT_SPARC | 0x00000004)
+#define MD_CONTEXT_SAPARC_EXTRA          (MD_CONTEXT_SPARC | 0x00000008)
+
+#define MD_CONTEXT_SPARC_FULL            (MD_CONTEXT_SPARC_CONTROL | \
+                                          MD_CONTEXT_SPARC_INTEGER)
+
+#define MD_CONTEXT_SPARC_ALL             (MD_CONTEXT_SPARC_FULL | \
+                                          MD_CONTEXT_SAPARC_FLOATING_POINT | \
+                                          MD_CONTEXT_SAPARC_EXTRA)
+
+#endif /* GOOGLE_BREAKPAD_COMMON_MINIDUMP_CPU_SPARC_H__ */
diff --git a/3rdParty/Breakpad/src/google_breakpad/common/minidump_cpu_x86.h b/3rdParty/Breakpad/src/google_breakpad/common/minidump_cpu_x86.h
new file mode 100644
index 0000000..32aff8a
--- /dev/null
+++ b/3rdParty/Breakpad/src/google_breakpad/common/minidump_cpu_x86.h
@@ -0,0 +1,174 @@
+/* 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_format.h: A cross-platform reimplementation of minidump-related
+ * portions of DbgHelp.h from the Windows Platform SDK.
+ *
+ * (This is C99 source, please don't corrupt it with C++.)
+ *
+ * This file contains the necessary definitions to read minidump files
+ * produced on x86.  These files may be read on any platform provided
+ * that the alignments of these structures on the processing system are
+ * identical to the alignments of these structures on the producing system.
+ * For this reason, precise-sized types are used.  The structures defined
+ * by this file have been laid out to minimize alignment problems by ensuring
+ * ensuring that all members are aligned on their natural boundaries.  In
+ * In some cases, tail-padding may be significant when different ABIs specify
+ * different tail-padding behaviors.  To avoid problems when reading or
+ * writing affected structures, MD_*_SIZE macros are provided where needed,
+ * containing the useful size of the structures without padding.
+ *
+ * Structures that are defined by Microsoft to contain a zero-length array
+ * are instead defined here to contain an array with one element, as
+ * zero-length arrays are forbidden by standard C and C++.  In these cases,
+ * *_minsize constants are provided to be used in place of sizeof.  For a
+ * cleaner interface to these sizes when using C++, see minidump_size.h.
+ *
+ * These structures are also sufficient to populate minidump files.
+ *
+ * These definitions may be extended to support handling minidump files
+ * for other CPUs and other operating systems.
+ *
+ * Because precise data type sizes are crucial for this implementation to
+ * function properly and portably in terms of interoperability with minidumps
+ * produced by DbgHelp on Windows, a set of primitive types with known sizes
+ * are used as the basis of each structure defined by this file.  DbgHelp
+ * on Windows is assumed to be the reference implementation; this file
+ * seeks to provide a cross-platform compatible implementation.  To avoid
+ * collisions with the types and values defined and used by DbgHelp in the
+ * event that this implementation is used on Windows, each type and value
+ * defined here is given a new name, beginning with "MD".  Names of the
+ * equivalent types and values in the Windows Platform SDK are given in
+ * comments.
+ *
+ * Author: Mark Mentovai */
+
+#ifndef GOOGLE_BREAKPAD_COMMON_MINIDUMP_CPU_X86_H__
+#define GOOGLE_BREAKPAD_COMMON_MINIDUMP_CPU_X86_H__
+
+#define MD_FLOATINGSAVEAREA_X86_REGISTERAREA_SIZE 80
+     /* SIZE_OF_80387_REGISTERS */
+
+typedef struct {
+  u_int32_t control_word;
+  u_int32_t status_word;
+  u_int32_t tag_word;
+  u_int32_t error_offset;
+  u_int32_t error_selector;
+  u_int32_t data_offset;
+  u_int32_t data_selector;
+
+  /* register_area contains eight 80-bit (x87 "long double") quantities for
+   * floating-point registers %st0 (%mm0) through %st7 (%mm7). */
+  u_int8_t  register_area[MD_FLOATINGSAVEAREA_X86_REGISTERAREA_SIZE];
+  u_int32_t cr0_npx_state;
+} MDFloatingSaveAreaX86;  /* FLOATING_SAVE_AREA */
+
+
+#define MD_CONTEXT_X86_EXTENDED_REGISTERS_SIZE 512
+     /* MAXIMUM_SUPPORTED_EXTENSION */
+
+typedef struct {
+  /* The next field determines the layout of the structure, and which parts
+   * of it are populated */
+  u_int32_t             context_flags;
+
+  /* The next 6 registers are included with MD_CONTEXT_X86_DEBUG_REGISTERS */
+  u_int32_t             dr0;
+  u_int32_t             dr1;
+  u_int32_t             dr2;
+  u_int32_t             dr3;
+  u_int32_t             dr6;
+  u_int32_t             dr7;
+
+  /* The next field is included with MD_CONTEXT_X86_FLOATING_POINT */
+  MDFloatingSaveAreaX86 float_save;
+
+  /* The next 4 registers are included with MD_CONTEXT_X86_SEGMENTS */
+  u_int32_t             gs; 
+  u_int32_t             fs;
+  u_int32_t             es;
+  u_int32_t             ds;
+  /* The next 6 registers are included with MD_CONTEXT_X86_INTEGER */
+  u_int32_t             edi;
+  u_int32_t             esi;
+  u_int32_t             ebx;
+  u_int32_t             edx;
+  u_int32_t             ecx;
+  u_int32_t             eax;
+
+  /* The next 6 registers are included with MD_CONTEXT_X86_CONTROL */
+  u_int32_t             ebp;
+  u_int32_t             eip;
+  u_int32_t             cs;      /* WinNT.h says "must be sanitized" */
+  u_int32_t             eflags;  /* WinNT.h says "must be sanitized" */
+  u_int32_t             esp;
+  u_int32_t             ss;
+
+  /* The next field is included with MD_CONTEXT_X86_EXTENDED_REGISTERS.
+   * It contains vector (MMX/SSE) registers.  It it laid out in the
+   * format used by the fxsave and fsrstor instructions, so it includes
+   * a copy of the x87 floating-point registers as well.  See FXSAVE in
+   * "Intel Architecture Software Developer's Manual, Volume 2." */
+  u_int8_t              extended_registers[
+                         MD_CONTEXT_X86_EXTENDED_REGISTERS_SIZE];
+} MDRawContextX86;  /* CONTEXT */
+
+/* For (MDRawContextX86).context_flags.  These values indicate the type of
+ * context stored in the structure.  The high 24 bits identify the CPU, the
+ * low 8 bits identify the type of context saved. */
+#define MD_CONTEXT_X86                    0x00010000
+     /* CONTEXT_i386, CONTEXT_i486: identifies CPU */
+#define MD_CONTEXT_X86_CONTROL            (MD_CONTEXT_X86 | 0x00000001)
+     /* CONTEXT_CONTROL */
+#define MD_CONTEXT_X86_INTEGER            (MD_CONTEXT_X86 | 0x00000002)
+     /* CONTEXT_INTEGER */
+#define MD_CONTEXT_X86_SEGMENTS           (MD_CONTEXT_X86 | 0x00000004)
+     /* CONTEXT_SEGMENTS */
+#define MD_CONTEXT_X86_FLOATING_POINT     (MD_CONTEXT_X86 | 0x00000008)
+     /* CONTEXT_FLOATING_POINT */
+#define MD_CONTEXT_X86_DEBUG_REGISTERS    (MD_CONTEXT_X86 | 0x00000010)
+     /* CONTEXT_DEBUG_REGISTERS */
+#define MD_CONTEXT_X86_EXTENDED_REGISTERS (MD_CONTEXT_X86 | 0x00000020)
+     /* CONTEXT_EXTENDED_REGISTERS */
+#define MD_CONTEXT_X86_XSTATE             (MD_CONTEXT_X86 | 0x00000040)
+     /* CONTEXT_XSTATE */
+
+#define MD_CONTEXT_X86_FULL              (MD_CONTEXT_X86_CONTROL | \
+                                          MD_CONTEXT_X86_INTEGER | \
+                                          MD_CONTEXT_X86_SEGMENTS)
+     /* CONTEXT_FULL */
+
+#define MD_CONTEXT_X86_ALL               (MD_CONTEXT_X86_FULL | \
+                                          MD_CONTEXT_X86_FLOATING_POINT | \
+                                          MD_CONTEXT_X86_DEBUG_REGISTERS | \
+                                          MD_CONTEXT_X86_EXTENDED_REGISTERS)
+     /* CONTEXT_ALL */
+
+#endif /* GOOGLE_BREAKPAD_COMMON_MINIDUMP_CPU_X86_H__ */
diff --git a/3rdParty/Breakpad/src/google_breakpad/common/minidump_exception_linux.h b/3rdParty/Breakpad/src/google_breakpad/common/minidump_exception_linux.h
new file mode 100644
index 0000000..d52c751
--- /dev/null
+++ b/3rdParty/Breakpad/src/google_breakpad/common/minidump_exception_linux.h
@@ -0,0 +1,85 @@
+/* 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_exception_linux.h: A definition of exception codes for
+ * Linux
+ *
+ * (This is C99 source, please don't corrupt it with C++.)
+ *
+ * Author: Mark Mentovai
+ * Split into its own file: Neal Sidhwaney */
+ 
+
+#ifndef GOOGLE_BREAKPAD_COMMON_MINIDUMP_EXCEPTION_LINUX_H__
+#define GOOGLE_BREAKPAD_COMMON_MINIDUMP_EXCEPTION_LINUX_H__
+
+#include <stddef.h>
+
+#include "google_breakpad/common/breakpad_types.h"
+
+
+/* For (MDException).exception_code.  These values come from bits/signum.h.
+ */
+typedef enum {
+  MD_EXCEPTION_CODE_LIN_SIGHUP = 1,      /* Hangup (POSIX) */
+  MD_EXCEPTION_CODE_LIN_SIGINT = 2,      /* Interrupt (ANSI) */
+  MD_EXCEPTION_CODE_LIN_SIGQUIT = 3,     /* Quit (POSIX) */
+  MD_EXCEPTION_CODE_LIN_SIGILL = 4,      /* Illegal instruction (ANSI) */
+  MD_EXCEPTION_CODE_LIN_SIGTRAP = 5,     /* Trace trap (POSIX) */
+  MD_EXCEPTION_CODE_LIN_SIGABRT = 6,     /* Abort (ANSI) */
+  MD_EXCEPTION_CODE_LIN_SIGBUS = 7,      /* BUS error (4.2 BSD) */
+  MD_EXCEPTION_CODE_LIN_SIGFPE = 8,      /* Floating-point exception (ANSI) */
+  MD_EXCEPTION_CODE_LIN_SIGKILL = 9,     /* Kill, unblockable (POSIX) */
+  MD_EXCEPTION_CODE_LIN_SIGUSR1 = 10,    /* User-defined signal 1 (POSIX).  */
+  MD_EXCEPTION_CODE_LIN_SIGSEGV = 11,    /* Segmentation violation (ANSI) */
+  MD_EXCEPTION_CODE_LIN_SIGUSR2 = 12,    /* User-defined signal 2 (POSIX) */
+  MD_EXCEPTION_CODE_LIN_SIGPIPE = 13,    /* Broken pipe (POSIX) */
+  MD_EXCEPTION_CODE_LIN_SIGALRM = 14,    /* Alarm clock (POSIX) */
+  MD_EXCEPTION_CODE_LIN_SIGTERM = 15,    /* Termination (ANSI) */
+  MD_EXCEPTION_CODE_LIN_SIGSTKFLT = 16,  /* Stack faultd */
+  MD_EXCEPTION_CODE_LIN_SIGCHLD = 17,    /* Child status has changed (POSIX) */
+  MD_EXCEPTION_CODE_LIN_SIGCONT = 18,    /* Continue (POSIX) */
+  MD_EXCEPTION_CODE_LIN_SIGSTOP = 19,    /* Stop, unblockable (POSIX) */
+  MD_EXCEPTION_CODE_LIN_SIGTSTP = 20,    /* Keyboard stop (POSIX) */
+  MD_EXCEPTION_CODE_LIN_SIGTTIN = 21,    /* Background read from tty (POSIX) */
+  MD_EXCEPTION_CODE_LIN_SIGTTOU = 22,    /* Background write to tty (POSIX) */
+  MD_EXCEPTION_CODE_LIN_SIGURG = 23,
+    /* Urgent condition on socket (4.2 BSD) */
+  MD_EXCEPTION_CODE_LIN_SIGXCPU = 24,    /* CPU limit exceeded (4.2 BSD) */
+  MD_EXCEPTION_CODE_LIN_SIGXFSZ = 25,
+    /* File size limit exceeded (4.2 BSD) */
+  MD_EXCEPTION_CODE_LIN_SIGVTALRM = 26,  /* Virtual alarm clock (4.2 BSD) */
+  MD_EXCEPTION_CODE_LIN_SIGPROF = 27,    /* Profiling alarm clock (4.2 BSD) */
+  MD_EXCEPTION_CODE_LIN_SIGWINCH = 28,   /* Window size change (4.3 BSD, Sun) */
+  MD_EXCEPTION_CODE_LIN_SIGIO = 29,      /* I/O now possible (4.2 BSD) */
+  MD_EXCEPTION_CODE_LIN_SIGPWR = 30,     /* Power failure restart (System V) */
+  MD_EXCEPTION_CODE_LIN_SIGSYS = 31      /* Bad system call */
+} MDExceptionCodeLinux;
+
+#endif  /* GOOGLE_BREAKPAD_COMMON_MINIDUMP_EXCEPTION_LINUX_H__ */
diff --git a/3rdParty/Breakpad/src/google_breakpad/common/minidump_exception_mac.h b/3rdParty/Breakpad/src/google_breakpad/common/minidump_exception_mac.h
new file mode 100644
index 0000000..01f8feb
--- /dev/null
+++ b/3rdParty/Breakpad/src/google_breakpad/common/minidump_exception_mac.h
@@ -0,0 +1,195 @@
+/* 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_exception_mac.h: A definition of exception codes for Mac
+ * OS X
+ *
+ * (This is C99 source, please don't corrupt it with C++.)
+ *
+ * Author: Mark Mentovai
+ * Split into its own file: Neal Sidhwaney */
+ 
+
+#ifndef GOOGLE_BREAKPAD_COMMON_MINIDUMP_EXCEPTION_MAC_H__
+#define GOOGLE_BREAKPAD_COMMON_MINIDUMP_EXCEPTION_MAC_H__
+
+#include <stddef.h>
+
+#include "google_breakpad/common/breakpad_types.h"
+
+/* For (MDException).exception_code.  Breakpad minidump extension for Mac OS X
+ * support.  Based on Darwin/Mac OS X' mach/exception_types.h.  This is
+ * what Mac OS X calls an "exception", not a "code". */
+typedef enum {
+  /* Exception code.  The high 16 bits of exception_code contains one of
+   * these values. */
+  MD_EXCEPTION_MAC_BAD_ACCESS      = 1,  /* code can be a kern_return_t */
+      /* EXC_BAD_ACCESS */
+  MD_EXCEPTION_MAC_BAD_INSTRUCTION = 2,  /* code is CPU-specific */
+      /* EXC_BAD_INSTRUCTION */
+  MD_EXCEPTION_MAC_ARITHMETIC      = 3,  /* code is CPU-specific */
+      /* EXC_ARITHMETIC */
+  MD_EXCEPTION_MAC_EMULATION       = 4,  /* code is CPU-specific */
+      /* EXC_EMULATION */
+  MD_EXCEPTION_MAC_SOFTWARE        = 5,
+      /* EXC_SOFTWARE */
+  MD_EXCEPTION_MAC_BREAKPOINT      = 6,  /* code is CPU-specific */
+      /* EXC_BREAKPOINT */
+  MD_EXCEPTION_MAC_SYSCALL         = 7,
+      /* EXC_SYSCALL */
+  MD_EXCEPTION_MAC_MACH_SYSCALL    = 8,
+      /* EXC_MACH_SYSCALL */
+  MD_EXCEPTION_MAC_RPC_ALERT       = 9
+      /* EXC_RPC_ALERT */
+} MDExceptionMac;
+
+/* For (MDException).exception_flags.  Breakpad minidump extension for Mac OS X
+ * support.  Based on Darwin/Mac OS X' mach/ppc/exception.h and
+ * mach/i386/exception.h.  This is what Mac OS X calls a "code". */
+typedef enum {
+  /* With MD_EXCEPTION_BAD_ACCESS.  These are relevant kern_return_t values
+   * from mach/kern_return.h. */
+  MD_EXCEPTION_CODE_MAC_INVALID_ADDRESS    =  1,
+      /* KERN_INVALID_ADDRESS */
+  MD_EXCEPTION_CODE_MAC_PROTECTION_FAILURE =  2,
+      /* KERN_PROTECTION_FAILURE */
+  MD_EXCEPTION_CODE_MAC_NO_ACCESS          =  8,
+      /* KERN_NO_ACCESS */
+  MD_EXCEPTION_CODE_MAC_MEMORY_FAILURE     =  9,
+      /* KERN_MEMORY_FAILURE */
+  MD_EXCEPTION_CODE_MAC_MEMORY_ERROR       = 10,
+      /* KERN_MEMORY_ERROR */
+
+  /* With MD_EXCEPTION_SOFTWARE */
+  MD_EXCEPTION_CODE_MAC_BAD_SYSCALL  = 0x00010000,  /* Mach SIGSYS */
+  MD_EXCEPTION_CODE_MAC_BAD_PIPE     = 0x00010001,  /* Mach SIGPIPE */
+  MD_EXCEPTION_CODE_MAC_ABORT        = 0x00010002,  /* Mach SIGABRT */
+  /* Custom values */
+  MD_EXCEPTION_CODE_MAC_NS_EXCEPTION = 0xDEADC0DE,  /* uncaught NSException */
+
+  /* With MD_EXCEPTION_MAC_BAD_ACCESS on ppc */
+  MD_EXCEPTION_CODE_MAC_PPC_VM_PROT_READ = 0x0101,
+      /* EXC_PPC_VM_PROT_READ */
+  MD_EXCEPTION_CODE_MAC_PPC_BADSPACE     = 0x0102,
+      /* EXC_PPC_BADSPACE */
+  MD_EXCEPTION_CODE_MAC_PPC_UNALIGNED    = 0x0103,
+      /* EXC_PPC_UNALIGNED */
+
+  /* With MD_EXCEPTION_MAC_BAD_INSTRUCTION on ppc */
+  MD_EXCEPTION_CODE_MAC_PPC_INVALID_SYSCALL           = 1,
+      /* EXC_PPC_INVALID_SYSCALL */
+  MD_EXCEPTION_CODE_MAC_PPC_UNIMPLEMENTED_INSTRUCTION = 2,
+      /* EXC_PPC_UNIPL_INST */
+  MD_EXCEPTION_CODE_MAC_PPC_PRIVILEGED_INSTRUCTION    = 3,
+      /* EXC_PPC_PRIVINST */
+  MD_EXCEPTION_CODE_MAC_PPC_PRIVILEGED_REGISTER       = 4,
+      /* EXC_PPC_PRIVREG */
+  MD_EXCEPTION_CODE_MAC_PPC_TRACE                     = 5,
+      /* EXC_PPC_TRACE */
+  MD_EXCEPTION_CODE_MAC_PPC_PERFORMANCE_MONITOR       = 6,
+      /* EXC_PPC_PERFMON */
+
+  /* With MD_EXCEPTION_MAC_ARITHMETIC on ppc */
+  MD_EXCEPTION_CODE_MAC_PPC_OVERFLOW           = 1,
+      /* EXC_PPC_OVERFLOW */
+  MD_EXCEPTION_CODE_MAC_PPC_ZERO_DIVIDE        = 2,
+      /* EXC_PPC_ZERO_DIVIDE */
+  MD_EXCEPTION_CODE_MAC_PPC_FLOAT_INEXACT      = 3,
+      /* EXC_FLT_INEXACT */
+  MD_EXCEPTION_CODE_MAC_PPC_FLOAT_ZERO_DIVIDE  = 4,
+      /* EXC_PPC_FLT_ZERO_DIVIDE */
+  MD_EXCEPTION_CODE_MAC_PPC_FLOAT_UNDERFLOW    = 5,
+      /* EXC_PPC_FLT_UNDERFLOW */
+  MD_EXCEPTION_CODE_MAC_PPC_FLOAT_OVERFLOW     = 6,
+      /* EXC_PPC_FLT_OVERFLOW */
+  MD_EXCEPTION_CODE_MAC_PPC_FLOAT_NOT_A_NUMBER = 7,
+      /* EXC_PPC_FLT_NOT_A_NUMBER */
+
+  /* With MD_EXCEPTION_MAC_EMULATION on ppc */
+  MD_EXCEPTION_CODE_MAC_PPC_NO_EMULATION   = 8,
+      /* EXC_PPC_NOEMULATION */
+  MD_EXCEPTION_CODE_MAC_PPC_ALTIVEC_ASSIST = 9,
+      /* EXC_PPC_ALTIVECASSIST */
+
+  /* With MD_EXCEPTION_MAC_SOFTWARE on ppc */
+  MD_EXCEPTION_CODE_MAC_PPC_TRAP    = 0x00000001,  /* EXC_PPC_TRAP */
+  MD_EXCEPTION_CODE_MAC_PPC_MIGRATE = 0x00010100,  /* EXC_PPC_MIGRATE */
+
+  /* With MD_EXCEPTION_MAC_BREAKPOINT on ppc */
+  MD_EXCEPTION_CODE_MAC_PPC_BREAKPOINT = 1,  /* EXC_PPC_BREAKPOINT */
+
+  /* With MD_EXCEPTION_MAC_BAD_INSTRUCTION on x86, see also x86 interrupt
+   * values below. */
+  MD_EXCEPTION_CODE_MAC_X86_INVALID_OPERATION = 1,  /* EXC_I386_INVOP */
+
+  /* With MD_EXCEPTION_MAC_ARITHMETIC on x86 */
+  MD_EXCEPTION_CODE_MAC_X86_DIV       = 1,  /* EXC_I386_DIV */
+  MD_EXCEPTION_CODE_MAC_X86_INTO      = 2,  /* EXC_I386_INTO */
+  MD_EXCEPTION_CODE_MAC_X86_NOEXT     = 3,  /* EXC_I386_NOEXT */
+  MD_EXCEPTION_CODE_MAC_X86_EXTOVR    = 4,  /* EXC_I386_EXTOVR */
+  MD_EXCEPTION_CODE_MAC_X86_EXTERR    = 5,  /* EXC_I386_EXTERR */
+  MD_EXCEPTION_CODE_MAC_X86_EMERR     = 6,  /* EXC_I386_EMERR */
+  MD_EXCEPTION_CODE_MAC_X86_BOUND     = 7,  /* EXC_I386_BOUND */
+  MD_EXCEPTION_CODE_MAC_X86_SSEEXTERR = 8,  /* EXC_I386_SSEEXTERR */
+
+  /* With MD_EXCEPTION_MAC_BREAKPOINT on x86 */
+  MD_EXCEPTION_CODE_MAC_X86_SGL = 1,  /* EXC_I386_SGL */
+  MD_EXCEPTION_CODE_MAC_X86_BPT = 2,  /* EXC_I386_BPT */
+
+  /* With MD_EXCEPTION_MAC_BAD_INSTRUCTION on x86.  These are the raw
+   * x86 interrupt codes.  Most of these are mapped to other Mach
+   * exceptions and codes, are handled, or should not occur in user space.
+   * A few of these will do occur with MD_EXCEPTION_MAC_BAD_INSTRUCTION. */
+  /* EXC_I386_DIVERR    =  0: mapped to EXC_ARITHMETIC/EXC_I386_DIV */
+  /* EXC_I386_SGLSTP    =  1: mapped to EXC_BREAKPOINT/EXC_I386_SGL */
+  /* EXC_I386_NMIFLT    =  2: should not occur in user space */
+  /* EXC_I386_BPTFLT    =  3: mapped to EXC_BREAKPOINT/EXC_I386_BPT */
+  /* EXC_I386_INTOFLT   =  4: mapped to EXC_ARITHMETIC/EXC_I386_INTO */
+  /* EXC_I386_BOUNDFLT  =  5: mapped to EXC_ARITHMETIC/EXC_I386_BOUND */
+  /* EXC_I386_INVOPFLT  =  6: mapped to EXC_BAD_INSTRUCTION/EXC_I386_INVOP */
+  /* EXC_I386_NOEXTFLT  =  7: should be handled by the kernel */
+  /* EXC_I386_DBLFLT    =  8: should be handled (if possible) by the kernel */
+  /* EXC_I386_EXTOVRFLT =  9: mapped to EXC_BAD_ACCESS/(PROT_READ|PROT_EXEC) */
+  MD_EXCEPTION_CODE_MAC_X86_INVALID_TASK_STATE_SEGMENT = 10,
+      /* EXC_INVTSSFLT */
+  MD_EXCEPTION_CODE_MAC_X86_SEGMENT_NOT_PRESENT        = 11,
+      /* EXC_SEGNPFLT */
+  MD_EXCEPTION_CODE_MAC_X86_STACK_FAULT                = 12,
+      /* EXC_STKFLT */
+  MD_EXCEPTION_CODE_MAC_X86_GENERAL_PROTECTION_FAULT   = 13,
+      /* EXC_GPFLT */
+  /* EXC_I386_PGFLT     = 14: should not occur in user space */
+  /* EXC_I386_EXTERRFLT = 16: mapped to EXC_ARITHMETIC/EXC_I386_EXTERR */
+  MD_EXCEPTION_CODE_MAC_X86_ALIGNMENT_FAULT            = 17
+      /* EXC_ALIGNFLT (for vector operations) */
+  /* EXC_I386_ENOEXTFLT = 32: should be handled by the kernel */
+  /* EXC_I386_ENDPERR   = 33: should not occur */
+} MDExceptionCodeMac;
+
+#endif  /* GOOGLE_BREAKPAD_COMMON_MINIDUMP_EXCEPTION_MAC_OSX_H__ */
diff --git a/3rdParty/Breakpad/src/google_breakpad/common/minidump_exception_solaris.h b/3rdParty/Breakpad/src/google_breakpad/common/minidump_exception_solaris.h
new file mode 100644
index 0000000..f18ddf4
--- /dev/null
+++ b/3rdParty/Breakpad/src/google_breakpad/common/minidump_exception_solaris.h
@@ -0,0 +1,94 @@
+/* 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_exception_solaris.h: A definition of exception codes for
+ * Solaris
+ *
+ * (This is C99 source, please don't corrupt it with C++.)
+ *
+ * Author: Mark Mentovai
+ * Split into its own file: Neal Sidhwaney */
+
+
+#ifndef GOOGLE_BREAKPAD_COMMON_MINIDUMP_EXCEPTION_SOLARIS_H__
+#define GOOGLE_BREAKPAD_COMMON_MINIDUMP_EXCEPTION_SOLARIS_H__
+
+#include <stddef.h>
+
+#include "google_breakpad/common/breakpad_types.h"
+
+/* For (MDException).exception_code.  These values come from sys/iso/signal_iso.h
+ */
+typedef enum {
+  MD_EXCEPTION_CODE_SOL_SIGHUP = 1,      /* Hangup */
+  MD_EXCEPTION_CODE_SOL_SIGINT = 2,      /* interrupt (rubout) */
+  MD_EXCEPTION_CODE_SOL_SIGQUIT = 3,     /* quit (ASCII FS) */
+  MD_EXCEPTION_CODE_SOL_SIGILL = 4,      /* illegal instruction (not reset when caught) */
+  MD_EXCEPTION_CODE_SOL_SIGTRAP = 5,     /* trace trap (not reset when caught) */
+  MD_EXCEPTION_CODE_SOL_SIGIOT = 6,      /* IOT instruction */
+  MD_EXCEPTION_CODE_SOL_SIGABRT = 6,     /* used by abort, replace SIGIOT in the future */
+  MD_EXCEPTION_CODE_SOL_SIGEMT = 7,      /* EMT instruction */
+  MD_EXCEPTION_CODE_SOL_SIGFPE = 8,      /* floating point exception */
+  MD_EXCEPTION_CODE_SOL_SIGKILL = 9,     /* kill (cannot be caught or ignored) */
+  MD_EXCEPTION_CODE_SOL_SIGBUS = 10,     /* bus error */
+  MD_EXCEPTION_CODE_SOL_SIGSEGV = 11,    /* segmentation violation */
+  MD_EXCEPTION_CODE_SOL_SIGSYS = 12,     /* bad argument to system call */
+  MD_EXCEPTION_CODE_SOL_SIGPIPE = 13,    /* write on a pipe with no one to read it */
+  MD_EXCEPTION_CODE_SOL_SIGALRM = 14,    /* alarm clock */
+  MD_EXCEPTION_CODE_SOL_SIGTERM = 15,    /* software termination signal from kill */
+  MD_EXCEPTION_CODE_SOL_SIGUSR1 = 16,    /* user defined signal 1 */
+  MD_EXCEPTION_CODE_SOL_SIGUSR2 = 17,    /* user defined signal 2 */
+  MD_EXCEPTION_CODE_SOL_SIGCLD = 18,     /* child status change */
+  MD_EXCEPTION_CODE_SOL_SIGCHLD = 18,    /* child status change alias (POSIX) */
+  MD_EXCEPTION_CODE_SOL_SIGPWR = 19,     /* power-fail restart */
+  MD_EXCEPTION_CODE_SOL_SIGWINCH = 20,   /* window size change */
+  MD_EXCEPTION_CODE_SOL_SIGURG = 21,     /* urgent socket condition */
+  MD_EXCEPTION_CODE_SOL_SIGPOLL = 22,    /* pollable event occurred */
+  MD_EXCEPTION_CODE_SOL_SIGIO = 22,      /* socket I/O possible (SIGPOLL alias) */
+  MD_EXCEPTION_CODE_SOL_SIGSTOP = 23,    /* stop (cannot be caught or ignored) */
+  MD_EXCEPTION_CODE_SOL_SIGTSTP = 24,    /* user stop requested from tty */
+  MD_EXCEPTION_CODE_SOL_SIGCONT = 25,    /* stopped process has been continued */
+  MD_EXCEPTION_CODE_SOL_SIGTTIN = 26,    /* background tty read attempted */
+  MD_EXCEPTION_CODE_SOL_SIGTTOU = 27,    /* background tty write attempted */
+  MD_EXCEPTION_CODE_SOL_SIGVTALRM = 28,  /* virtual timer expired */
+  MD_EXCEPTION_CODE_SOL_SIGPROF = 29,    /* profiling timer expired */
+  MD_EXCEPTION_CODE_SOL_SIGXCPU = 30,    /* exceeded cpu limit */
+  MD_EXCEPTION_CODE_SOL_SIGXFSZ = 31,    /* exceeded file size limit */
+  MD_EXCEPTION_CODE_SOL_SIGWAITING = 32, /* reserved signal no longer used by threading code */
+  MD_EXCEPTION_CODE_SOL_SIGLWP = 33,     /* reserved signal no longer used by threading code */
+  MD_EXCEPTION_CODE_SOL_SIGFREEZE = 34,  /* special signal used by CPR */
+  MD_EXCEPTION_CODE_SOL_SIGTHAW = 35,    /* special signal used by CPR */
+  MD_EXCEPTION_CODE_SOL_SIGCANCEL = 36,  /* reserved signal for thread cancellation */
+  MD_EXCEPTION_CODE_SOL_SIGLOST = 37,    /* resource lost (eg, record-lock lost) */
+  MD_EXCEPTION_CODE_SOL_SIGXRES = 38,    /* resource control exceeded */
+  MD_EXCEPTION_CODE_SOL_SIGJVM1 = 39,    /* reserved signal for Java Virtual Machine */
+  MD_EXCEPTION_CODE_SOL_SIGJVM2 = 40     /* reserved signal for Java Virtual Machine */
+} MDExceptionCodeSolaris;
+
+#endif  /* GOOGLE_BREAKPAD_COMMON_MINIDUMP_EXCEPTION_SOLARIS_H__ */
diff --git a/3rdParty/Breakpad/src/google_breakpad/common/minidump_exception_win32.h b/3rdParty/Breakpad/src/google_breakpad/common/minidump_exception_win32.h
new file mode 100644
index 0000000..458a705
--- /dev/null
+++ b/3rdParty/Breakpad/src/google_breakpad/common/minidump_exception_win32.h
@@ -0,0 +1,116 @@
+/* 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_exception_win32.h: Definitions of exception codes for
+ * Win32 platform
+ *
+ * (This is C99 source, please don't corrupt it with C++.)
+ *
+ * Author: Mark Mentovai
+ * Split into its own file: Neal Sidhwaney */
+
+
+#ifndef GOOGLE_BREAKPAD_COMMON_MINIDUMP_EXCEPTION_WIN32_H__
+#define GOOGLE_BREAKPAD_COMMON_MINIDUMP_EXCEPTION_WIN32_H__
+
+#include <stddef.h>
+
+#include "google_breakpad/common/breakpad_types.h"
+
+
+/* For (MDException).exception_code.  These values come from WinBase.h
+ * and WinNT.h (names beginning with EXCEPTION_ are in WinBase.h,
+ * they are STATUS_ in WinNT.h). */
+typedef enum {
+  MD_EXCEPTION_CODE_WIN_CONTROL_C                = 0x40010005,
+      /* DBG_CONTROL_C */
+  MD_EXCEPTION_CODE_WIN_GUARD_PAGE_VIOLATION     = 0x80000001,
+      /* EXCEPTION_GUARD_PAGE */
+  MD_EXCEPTION_CODE_WIN_DATATYPE_MISALIGNMENT    = 0x80000002,
+      /* EXCEPTION_DATATYPE_MISALIGNMENT */
+  MD_EXCEPTION_CODE_WIN_BREAKPOINT               = 0x80000003,
+      /* EXCEPTION_BREAKPOINT */
+  MD_EXCEPTION_CODE_WIN_SINGLE_STEP              = 0x80000004,
+      /* EXCEPTION_SINGLE_STEP */
+  MD_EXCEPTION_CODE_WIN_ACCESS_VIOLATION         = 0xc0000005,
+      /* EXCEPTION_ACCESS_VIOLATION */
+  MD_EXCEPTION_CODE_WIN_IN_PAGE_ERROR            = 0xc0000006,
+      /* EXCEPTION_IN_PAGE_ERROR */
+  MD_EXCEPTION_CODE_WIN_INVALID_HANDLE           = 0xc0000008,
+      /* EXCEPTION_INVALID_HANDLE */
+  MD_EXCEPTION_CODE_WIN_ILLEGAL_INSTRUCTION      = 0xc000001d,
+      /* EXCEPTION_ILLEGAL_INSTRUCTION */
+  MD_EXCEPTION_CODE_WIN_NONCONTINUABLE_EXCEPTION = 0xc0000025,
+      /* EXCEPTION_NONCONTINUABLE_EXCEPTION */
+  MD_EXCEPTION_CODE_WIN_INVALID_DISPOSITION      = 0xc0000026,
+      /* EXCEPTION_INVALID_DISPOSITION */
+  MD_EXCEPTION_CODE_WIN_ARRAY_BOUNDS_EXCEEDED    = 0xc000008c,
+      /* EXCEPTION_BOUNDS_EXCEEDED */
+  MD_EXCEPTION_CODE_WIN_FLOAT_DENORMAL_OPERAND   = 0xc000008d,
+      /* EXCEPTION_FLT_DENORMAL_OPERAND */
+  MD_EXCEPTION_CODE_WIN_FLOAT_DIVIDE_BY_ZERO     = 0xc000008e,
+      /* EXCEPTION_FLT_DIVIDE_BY_ZERO */
+  MD_EXCEPTION_CODE_WIN_FLOAT_INEXACT_RESULT     = 0xc000008f,
+      /* EXCEPTION_FLT_INEXACT_RESULT */
+  MD_EXCEPTION_CODE_WIN_FLOAT_INVALID_OPERATION  = 0xc0000090,
+      /* EXCEPTION_FLT_INVALID_OPERATION */
+  MD_EXCEPTION_CODE_WIN_FLOAT_OVERFLOW           = 0xc0000091,
+      /* EXCEPTION_FLT_OVERFLOW */
+  MD_EXCEPTION_CODE_WIN_FLOAT_STACK_CHECK        = 0xc0000092,
+      /* EXCEPTION_FLT_STACK_CHECK */
+  MD_EXCEPTION_CODE_WIN_FLOAT_UNDERFLOW          = 0xc0000093,
+      /* EXCEPTION_FLT_UNDERFLOW */
+  MD_EXCEPTION_CODE_WIN_INTEGER_DIVIDE_BY_ZERO   = 0xc0000094,
+      /* EXCEPTION_INT_DIVIDE_BY_ZERO */
+  MD_EXCEPTION_CODE_WIN_INTEGER_OVERFLOW         = 0xc0000095,
+      /* EXCEPTION_INT_OVERFLOW */
+  MD_EXCEPTION_CODE_WIN_PRIVILEGED_INSTRUCTION   = 0xc0000096,
+      /* EXCEPTION_PRIV_INSTRUCTION */
+  MD_EXCEPTION_CODE_WIN_STACK_OVERFLOW           = 0xc00000fd,
+      /* EXCEPTION_STACK_OVERFLOW */
+  MD_EXCEPTION_CODE_WIN_POSSIBLE_DEADLOCK        = 0xc0000194,
+      /* EXCEPTION_POSSIBLE_DEADLOCK */
+  MD_EXCEPTION_CODE_WIN_STACK_BUFFER_OVERRUN     = 0xc0000409,
+      /* STATUS_STACK_BUFFER_OVERRUN */
+  MD_EXCEPTION_CODE_WIN_HEAP_CORRUPTION          = 0xc0000374,
+      /* STATUS_HEAP_CORRUPTION */
+  MD_EXCEPTION_CODE_WIN_UNHANDLED_CPP_EXCEPTION  = 0xe06d7363
+      /* Per http://support.microsoft.com/kb/185294,
+         generated by Visual C++ compiler */
+} MDExceptionCodeWin;
+
+// These constants are defined in the MSDN documentation of
+// the EXCEPTION_RECORD structure.
+typedef enum {
+  MD_ACCESS_VIOLATION_WIN_READ  = 0,
+  MD_ACCESS_VIOLATION_WIN_WRITE = 1,
+  MD_ACCESS_VIOLATION_WIN_EXEC  = 8
+} MDAccessViolationTypeWin;
+
+#endif  /* GOOGLE_BREAKPAD_COMMON_MINIDUMP_EXCEPTION_WIN32_H__ */
diff --git a/3rdParty/Breakpad/src/google_breakpad/common/minidump_format.h b/3rdParty/Breakpad/src/google_breakpad/common/minidump_format.h
new file mode 100644
index 0000000..28a81d4
--- /dev/null
+++ b/3rdParty/Breakpad/src/google_breakpad/common/minidump_format.h
@@ -0,0 +1,822 @@
+/* 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_format.h: A cross-platform reimplementation of minidump-related
+ * portions of DbgHelp.h from the Windows Platform SDK.
+ *
+ * (This is C99 source, please don't corrupt it with C++.)
+ *
+ * Structures that are defined by Microsoft to contain a zero-length array
+ * are instead defined here to contain an array with one element, as
+ * zero-length arrays are forbidden by standard C and C++.  In these cases,
+ * *_minsize constants are provided to be used in place of sizeof.  For a
+ * cleaner interface to these sizes when using C++, see minidump_size.h.
+ *
+ * These structures are also sufficient to populate minidump files.
+ *
+ * These definitions may be extended to support handling minidump files
+ * for other CPUs and other operating systems.
+ *
+ * Because precise data type sizes are crucial for this implementation to
+ * function properly and portably in terms of interoperability with minidumps
+ * produced by DbgHelp on Windows, a set of primitive types with known sizes
+ * are used as the basis of each structure defined by this file.  DbgHelp
+ * on Windows is assumed to be the reference implementation; this file
+ * seeks to provide a cross-platform compatible implementation.  To avoid
+ * collisions with the types and values defined and used by DbgHelp in the
+ * event that this implementation is used on Windows, each type and value
+ * defined here is given a new name, beginning with "MD".  Names of the
+ * equivalent types and values in the Windows Platform SDK are given in
+ * comments.
+ *
+ * Author: Mark Mentovai */
+
+
+#ifndef GOOGLE_BREAKPAD_COMMON_MINIDUMP_FORMAT_H__
+#define GOOGLE_BREAKPAD_COMMON_MINIDUMP_FORMAT_H__
+
+#include <stddef.h>
+
+#include "google_breakpad/common/breakpad_types.h"
+
+
+#if defined(_MSC_VER)
+/* Disable "zero-sized array in struct/union" warnings when compiling in
+ * MSVC.  DbgHelp.h does this too. */
+#pragma warning(push)
+#pragma warning(disable:4200)
+#endif  /* _MSC_VER */
+
+
+/*
+ * guiddef.h
+ */
+
+typedef struct {
+  u_int32_t data1;
+  u_int16_t data2;
+  u_int16_t data3;
+  u_int8_t  data4[8];
+} MDGUID;  /* GUID */
+
+
+/*
+ * WinNT.h
+ */
+
+/* Non-x86 CPU identifiers found in the high 24 bits of
+ * (MDRawContext*).context_flags.  These aren't used by Breakpad, but are
+ * defined here for reference, to avoid assigning values that conflict
+ * (although some values already conflict). */
+#define MD_CONTEXT_IA64  0x00080000  /* CONTEXT_IA64 */
+/* Additional values from winnt.h in the Windows CE 5.0 SDK: */
+#define MD_CONTEXT_SHX   0x000000c0  /* CONTEXT_SH4 (Super-H, includes SH3) */
+#define MD_CONTEXT_MIPS  0x00010000  /* CONTEXT_R4000 (same value as x86?) */
+#define MD_CONTEXT_ALPHA 0x00020000  /* CONTEXT_ALPHA */
+
+/* As of Windows 7 SP1, the number of flag bits has increased to
+ * include 0x40 (CONTEXT_XSTATE):
+ * http://msdn.microsoft.com/en-us/library/hh134238%28v=vs.85%29.aspx */
+#define MD_CONTEXT_CPU_MASK 0xffffff00
+
+
+/* This is a base type for MDRawContextX86 and MDRawContextPPC.  This
+ * structure should never be allocated directly.  The actual structure type
+ * can be determined by examining the context_flags field. */
+typedef struct {
+  u_int32_t context_flags;
+} MDRawContextBase;
+
+#include "minidump_cpu_amd64.h"
+#include "minidump_cpu_arm.h"
+#include "minidump_cpu_ppc.h"
+#include "minidump_cpu_ppc64.h"
+#include "minidump_cpu_sparc.h"
+#include "minidump_cpu_x86.h"
+
+/*
+ * WinVer.h
+ */
+
+
+typedef struct {
+  u_int32_t signature;
+  u_int32_t struct_version;
+  u_int32_t file_version_hi;
+  u_int32_t file_version_lo;
+  u_int32_t product_version_hi;
+  u_int32_t product_version_lo;
+  u_int32_t file_flags_mask;    /* Identifies valid bits in fileFlags */
+  u_int32_t file_flags;
+  u_int32_t file_os;
+  u_int32_t file_type;
+  u_int32_t file_subtype;
+  u_int32_t file_date_hi;
+  u_int32_t file_date_lo;
+} MDVSFixedFileInfo;  /* VS_FIXEDFILEINFO */
+
+/* For (MDVSFixedFileInfo).signature */
+#define MD_VSFIXEDFILEINFO_SIGNATURE 0xfeef04bd
+     /* VS_FFI_SIGNATURE */
+
+/* For (MDVSFixedFileInfo).version */
+#define MD_VSFIXEDFILEINFO_VERSION 0x00010000
+     /* VS_FFI_STRUCVERSION */
+
+/* For (MDVSFixedFileInfo).file_flags_mask and
+ * (MDVSFixedFileInfo).file_flags */
+#define MD_VSFIXEDFILEINFO_FILE_FLAGS_DEBUG        0x00000001
+     /* VS_FF_DEBUG */
+#define MD_VSFIXEDFILEINFO_FILE_FLAGS_PRERELEASE   0x00000002
+     /* VS_FF_PRERELEASE */
+#define MD_VSFIXEDFILEINFO_FILE_FLAGS_PATCHED      0x00000004
+     /* VS_FF_PATCHED */
+#define MD_VSFIXEDFILEINFO_FILE_FLAGS_PRIVATEBUILD 0x00000008
+     /* VS_FF_PRIVATEBUILD */
+#define MD_VSFIXEDFILEINFO_FILE_FLAGS_INFOINFERRED 0x00000010
+     /* VS_FF_INFOINFERRED */
+#define MD_VSFIXEDFILEINFO_FILE_FLAGS_SPECIALBUILD 0x00000020
+     /* VS_FF_SPECIALBUILD */
+
+/* For (MDVSFixedFileInfo).file_os: high 16 bits */
+#define MD_VSFIXEDFILEINFO_FILE_OS_UNKNOWN    0          /* VOS_UNKNOWN */
+#define MD_VSFIXEDFILEINFO_FILE_OS_DOS        (1 << 16)  /* VOS_DOS */
+#define MD_VSFIXEDFILEINFO_FILE_OS_OS216      (2 << 16)  /* VOS_OS216 */
+#define MD_VSFIXEDFILEINFO_FILE_OS_OS232      (3 << 16)  /* VOS_OS232 */
+#define MD_VSFIXEDFILEINFO_FILE_OS_NT         (4 << 16)  /* VOS_NT */
+#define MD_VSFIXEDFILEINFO_FILE_OS_WINCE      (5 << 16)  /* VOS_WINCE */
+/* Low 16 bits */
+#define MD_VSFIXEDFILEINFO_FILE_OS__BASE      0          /* VOS__BASE */
+#define MD_VSFIXEDFILEINFO_FILE_OS__WINDOWS16 1          /* VOS__WINDOWS16 */
+#define MD_VSFIXEDFILEINFO_FILE_OS__PM16      2          /* VOS__PM16 */
+#define MD_VSFIXEDFILEINFO_FILE_OS__PM32      3          /* VOS__PM32 */
+#define MD_VSFIXEDFILEINFO_FILE_OS__WINDOWS32 4          /* VOS__WINDOWS32 */
+
+/* For (MDVSFixedFileInfo).file_type */
+#define MD_VSFIXEDFILEINFO_FILE_TYPE_UNKNOWN    0  /* VFT_UNKNOWN */
+#define MD_VSFIXEDFILEINFO_FILE_TYPE_APP        1  /* VFT_APP */
+#define MD_VSFIXEDFILEINFO_FILE_TYPE_DLL        2  /* VFT_DLL */
+#define MD_VSFIXEDFILEINFO_FILE_TYPE_DRV        3  /* VFT_DLL */
+#define MD_VSFIXEDFILEINFO_FILE_TYPE_FONT       4  /* VFT_FONT */
+#define MD_VSFIXEDFILEINFO_FILE_TYPE_VXD        5  /* VFT_VXD */
+#define MD_VSFIXEDFILEINFO_FILE_TYPE_STATIC_LIB 7  /* VFT_STATIC_LIB */
+
+/* For (MDVSFixedFileInfo).file_subtype */
+#define MD_VSFIXEDFILEINFO_FILE_SUBTYPE_UNKNOWN                0
+     /* VFT2_UNKNOWN */
+/* with file_type = MD_VSFIXEDFILEINFO_FILETYPE_DRV */
+#define MD_VSFIXEDFILEINFO_FILE_SUBTYPE_DRV_PRINTER            1
+     /* VFT2_DRV_PRINTER */
+#define MD_VSFIXEDFILEINFO_FILE_SUBTYPE_DRV_KEYBOARD           2
+     /* VFT2_DRV_KEYBOARD */
+#define MD_VSFIXEDFILEINFO_FILE_SUBTYPE_DRV_LANGUAGE           3
+     /* VFT2_DRV_LANGUAGE */
+#define MD_VSFIXEDFILEINFO_FILE_SUBTYPE_DRV_DISPLAY            4
+     /* VFT2_DRV_DISPLAY */
+#define MD_VSFIXEDFILEINFO_FILE_SUBTYPE_DRV_MOUSE              5
+     /* VFT2_DRV_MOUSE */
+#define MD_VSFIXEDFILEINFO_FILE_SUBTYPE_DRV_NETWORK            6
+     /* VFT2_DRV_NETWORK */
+#define MD_VSFIXEDFILEINFO_FILE_SUBTYPE_DRV_SYSTEM             7
+     /* VFT2_DRV_SYSTEM */
+#define MD_VSFIXEDFILEINFO_FILE_SUBTYPE_DRV_INSTALLABLE        8
+     /* VFT2_DRV_INSTALLABLE */
+#define MD_VSFIXEDFILEINFO_FILE_SUBTYPE_DRV_SOUND              9
+     /* VFT2_DRV_SOUND */
+#define MD_VSFIXEDFILEINFO_FILE_SUBTYPE_DRV_COMM              10
+     /* VFT2_DRV_COMM */
+#define MD_VSFIXEDFILEINFO_FILE_SUBTYPE_DRV_INPUTMETHOD       11
+     /* VFT2_DRV_INPUTMETHOD */
+#define MD_VSFIXEDFILEINFO_FILE_SUBTYPE_DRV_VERSIONED_PRINTER 12
+     /* VFT2_DRV_VERSIONED_PRINTER */
+/* with file_type = MD_VSFIXEDFILEINFO_FILETYPE_FONT */
+#define MD_VSFIXEDFILEINFO_FILE_SUBTYPE_FONT_RASTER            1
+     /* VFT2_FONT_RASTER */
+#define MD_VSFIXEDFILEINFO_FILE_SUBTYPE_FONT_VECTOR            2
+     /* VFT2_FONT_VECTOR */
+#define MD_VSFIXEDFILEINFO_FILE_SUBTYPE_FONT_TRUETYPE          3
+     /* VFT2_FONT_TRUETYPE */
+
+
+/*
+ * DbgHelp.h
+ */
+
+
+/* An MDRVA is an offset into the minidump file.  The beginning of the
+ * MDRawHeader is at offset 0. */
+typedef u_int32_t MDRVA;  /* RVA */
+
+typedef struct {
+  u_int32_t data_size;
+  MDRVA     rva;
+} MDLocationDescriptor;  /* MINIDUMP_LOCATION_DESCRIPTOR */
+
+
+typedef struct {
+  /* The base address of the memory range on the host that produced the
+   * minidump. */
+  u_int64_t            start_of_memory_range;
+
+  MDLocationDescriptor memory;
+} MDMemoryDescriptor;  /* MINIDUMP_MEMORY_DESCRIPTOR */
+
+
+typedef struct {
+  u_int32_t signature;
+  u_int32_t version;
+  u_int32_t stream_count;
+  MDRVA     stream_directory_rva;  /* A |stream_count|-sized array of
+                                    * MDRawDirectory structures. */
+  u_int32_t checksum;              /* Can be 0.  In fact, that's all that's
+                                    * been found in minidump files. */
+  u_int32_t time_date_stamp;       /* time_t */
+  u_int64_t flags;
+} MDRawHeader;  /* MINIDUMP_HEADER */
+
+/* For (MDRawHeader).signature and (MDRawHeader).version.  Note that only the
+ * low 16 bits of (MDRawHeader).version are MD_HEADER_VERSION.  Per the
+ * documentation, the high 16 bits are implementation-specific. */
+#define MD_HEADER_SIGNATURE 0x504d444d /* 'PMDM' */
+     /* MINIDUMP_SIGNATURE */
+#define MD_HEADER_VERSION   0x0000a793 /* 42899 */
+     /* MINIDUMP_VERSION */
+
+/* For (MDRawHeader).flags: */
+typedef enum {
+  /* MD_NORMAL is the standard type of minidump.  It includes full
+   * streams for the thread list, module list, exception, system info,
+   * and miscellaneous info.  A memory list stream is also present,
+   * pointing to the same stack memory contained in the thread list,
+   * as well as a 256-byte region around the instruction address that
+   * was executing when the exception occurred.  Stack memory is from
+   * 4 bytes below a thread's stack pointer up to the top of the
+   * memory region encompassing the stack. */
+  MD_NORMAL                            = 0x00000000,
+  MD_WITH_DATA_SEGS                    = 0x00000001,
+  MD_WITH_FULL_MEMORY                  = 0x00000002,
+  MD_WITH_HANDLE_DATA                  = 0x00000004,
+  MD_FILTER_MEMORY                     = 0x00000008,
+  MD_SCAN_MEMORY                       = 0x00000010,
+  MD_WITH_UNLOADED_MODULES             = 0x00000020,
+  MD_WITH_INDIRECTLY_REFERENCED_MEMORY = 0x00000040,
+  MD_FILTER_MODULE_PATHS               = 0x00000080,
+  MD_WITH_PROCESS_THREAD_DATA          = 0x00000100,
+  MD_WITH_PRIVATE_READ_WRITE_MEMORY    = 0x00000200,
+  MD_WITHOUT_OPTIONAL_DATA             = 0x00000400,
+  MD_WITH_FULL_MEMORY_INFO             = 0x00000800,
+  MD_WITH_THREAD_INFO                  = 0x00001000,
+  MD_WITH_CODE_SEGS                    = 0x00002000,
+  MD_WITHOUT_AUXILLIARY_SEGS           = 0x00004000,
+  MD_WITH_FULL_AUXILLIARY_STATE        = 0x00008000,
+  MD_WITH_PRIVATE_WRITE_COPY_MEMORY    = 0x00010000,
+  MD_IGNORE_INACCESSIBLE_MEMORY        = 0x00020000,
+  MD_WITH_TOKEN_INFORMATION            = 0x00040000
+} MDType;  /* MINIDUMP_TYPE */
+
+
+typedef struct {
+  u_int32_t            stream_type;
+  MDLocationDescriptor location;
+} MDRawDirectory;  /* MINIDUMP_DIRECTORY */
+
+/* For (MDRawDirectory).stream_type */
+typedef enum {
+  MD_UNUSED_STREAM               =  0,
+  MD_RESERVED_STREAM_0           =  1,
+  MD_RESERVED_STREAM_1           =  2,
+  MD_THREAD_LIST_STREAM          =  3,  /* MDRawThreadList */
+  MD_MODULE_LIST_STREAM          =  4,  /* MDRawModuleList */
+  MD_MEMORY_LIST_STREAM          =  5,  /* MDRawMemoryList */
+  MD_EXCEPTION_STREAM            =  6,  /* MDRawExceptionStream */
+  MD_SYSTEM_INFO_STREAM          =  7,  /* MDRawSystemInfo */
+  MD_THREAD_EX_LIST_STREAM       =  8,
+  MD_MEMORY_64_LIST_STREAM       =  9,
+  MD_COMMENT_STREAM_A            = 10,
+  MD_COMMENT_STREAM_W            = 11,
+  MD_HANDLE_DATA_STREAM          = 12,
+  MD_FUNCTION_TABLE_STREAM       = 13,
+  MD_UNLOADED_MODULE_LIST_STREAM = 14,
+  MD_MISC_INFO_STREAM            = 15,  /* MDRawMiscInfo */
+  MD_MEMORY_INFO_LIST_STREAM     = 16,  /* MDRawMemoryInfoList */
+  MD_THREAD_INFO_LIST_STREAM     = 17,
+  MD_HANDLE_OPERATION_LIST_STREAM = 18,
+  MD_LAST_RESERVED_STREAM        = 0x0000ffff,
+
+  /* Breakpad extension types.  0x4767 = "Gg" */
+  MD_BREAKPAD_INFO_STREAM        = 0x47670001,  /* MDRawBreakpadInfo  */
+  MD_ASSERTION_INFO_STREAM       = 0x47670002,  /* MDRawAssertionInfo */
+  /* These are additional minidump stream values which are specific to
+   * the linux breakpad implementation. */
+  MD_LINUX_CPU_INFO              = 0x47670003,  /* /proc/cpuinfo      */
+  MD_LINUX_PROC_STATUS           = 0x47670004,  /* /proc/$x/status    */
+  MD_LINUX_LSB_RELEASE           = 0x47670005,  /* /etc/lsb-release   */
+  MD_LINUX_CMD_LINE              = 0x47670006,  /* /proc/$x/cmdline   */
+  MD_LINUX_ENVIRON               = 0x47670007,  /* /proc/$x/environ   */
+  MD_LINUX_AUXV                  = 0x47670008,  /* /proc/$x/auxv      */
+  MD_LINUX_MAPS                  = 0x47670009,  /* /proc/$x/maps      */
+  MD_LINUX_DSO_DEBUG             = 0x4767000A   /* MDRawDebug         */
+} MDStreamType;  /* MINIDUMP_STREAM_TYPE */
+
+
+typedef struct {
+  u_int32_t length;     /* Length of buffer in bytes (not characters),
+                         * excluding 0-terminator */
+  u_int16_t buffer[1];  /* UTF-16-encoded, 0-terminated */
+} MDString;  /* MINIDUMP_STRING */
+
+static const size_t MDString_minsize = offsetof(MDString, buffer[0]);
+
+
+typedef struct {
+  u_int32_t            thread_id;
+  u_int32_t            suspend_count;
+  u_int32_t            priority_class;
+  u_int32_t            priority;
+  u_int64_t            teb;             /* Thread environment block */
+  MDMemoryDescriptor   stack;
+  MDLocationDescriptor thread_context;  /* MDRawContext[CPU] */
+} MDRawThread;  /* MINIDUMP_THREAD */
+
+
+typedef struct {
+  u_int32_t   number_of_threads;
+  MDRawThread threads[1];
+} MDRawThreadList;  /* MINIDUMP_THREAD_LIST */
+
+static const size_t MDRawThreadList_minsize = offsetof(MDRawThreadList,
+                                                       threads[0]);
+
+
+typedef struct {
+  u_int64_t            base_of_image;
+  u_int32_t            size_of_image;
+  u_int32_t            checksum;         /* 0 if unknown */
+  u_int32_t            time_date_stamp;  /* time_t */
+  MDRVA                module_name_rva;  /* MDString, pathname or filename */
+  MDVSFixedFileInfo    version_info;
+
+  /* The next field stores a CodeView record and is populated when a module's
+   * debug information resides in a PDB file.  It identifies the PDB file. */
+  MDLocationDescriptor cv_record;
+
+  /* The next field is populated when a module's debug information resides
+   * in a DBG file.  It identifies the DBG file.  This field is effectively
+   * obsolete with modules built by recent toolchains. */
+  MDLocationDescriptor misc_record;
+
+  /* Alignment problem: reserved0 and reserved1 are defined by the platform
+   * SDK as 64-bit quantities.  However, that results in a structure whose
+   * alignment is unpredictable on different CPUs and ABIs.  If the ABI
+   * specifies full alignment of 64-bit quantities in structures (as ppc
+   * does), there will be padding between miscRecord and reserved0.  If
+   * 64-bit quantities can be aligned on 32-bit boundaries (as on x86),
+   * this padding will not exist.  (Note that the structure up to this point
+   * contains 1 64-bit member followed by 21 32-bit members.)
+   * As a workaround, reserved0 and reserved1 are instead defined here as
+   * four 32-bit quantities.  This should be harmless, as there are
+   * currently no known uses for these fields. */
+  u_int32_t            reserved0[2];
+  u_int32_t            reserved1[2];
+} MDRawModule;  /* MINIDUMP_MODULE */
+
+/* The inclusion of a 64-bit type in MINIDUMP_MODULE forces the struct to
+ * be tail-padded out to a multiple of 64 bits under some ABIs (such as PPC).
+ * This doesn't occur on systems that don't tail-pad in this manner.  Define
+ * this macro to be the usable size of the MDRawModule struct, and use it in
+ * place of sizeof(MDRawModule). */
+#define MD_MODULE_SIZE 108
+
+
+/* (MDRawModule).cv_record can reference MDCVInfoPDB20 or MDCVInfoPDB70.
+ * Ref.: http://www.debuginfo.com/articles/debuginfomatch.html
+ * MDCVInfoPDB70 is the expected structure type with recent toolchains. */
+
+typedef struct {
+  u_int32_t signature;
+  u_int32_t offset;     /* Offset to debug data (expect 0 in minidump) */
+} MDCVHeader;
+
+typedef struct {
+  MDCVHeader cv_header;
+  u_int32_t  signature;         /* time_t debug information created */
+  u_int32_t  age;               /* revision of PDB file */
+  u_int8_t   pdb_file_name[1];  /* Pathname or filename of PDB file */
+} MDCVInfoPDB20;
+
+static const size_t MDCVInfoPDB20_minsize = offsetof(MDCVInfoPDB20,
+                                                     pdb_file_name[0]);
+
+#define MD_CVINFOPDB20_SIGNATURE 0x3031424e  /* cvHeader.signature = '01BN' */
+
+typedef struct {
+  u_int32_t cv_signature;
+  MDGUID    signature;         /* GUID, identifies PDB file */
+  u_int32_t age;               /* Identifies incremental changes to PDB file */
+  u_int8_t  pdb_file_name[1];  /* Pathname or filename of PDB file,
+                                * 0-terminated 8-bit character data (UTF-8?) */
+} MDCVInfoPDB70;
+
+static const size_t MDCVInfoPDB70_minsize = offsetof(MDCVInfoPDB70,
+                                                     pdb_file_name[0]);
+
+#define MD_CVINFOPDB70_SIGNATURE 0x53445352  /* cvSignature = 'SDSR' */
+
+typedef struct {
+  u_int32_t data1[2];
+  u_int32_t data2;
+  u_int32_t data3;
+  u_int32_t data4;
+  u_int32_t data5[3];
+  u_int8_t extra[2];
+} MDCVInfoELF;
+
+/* In addition to the two CodeView record formats above, used for linking
+ * to external pdb files, it is possible for debugging data to be carried
+ * directly in the CodeView record itself.  These signature values will
+ * be found in the first 4 bytes of the CodeView record.  Additional values
+ * not commonly experienced in the wild are given by "Microsoft Symbol and
+ * Type Information", http://www.x86.org/ftp/manuals/tools/sym.pdf, section
+ * 7.2.  An in-depth description of the CodeView 4.1 format is given by
+ * "Undocumented Windows 2000 Secrets", Windows 2000 Debugging Support/
+ * Microsoft Symbol File Internals/CodeView Subsections,
+ * http://www.rawol.com/features/undocumented/sbs-w2k-1-windows-2000-debugging-support.pdf
+ */
+#define MD_CVINFOCV41_SIGNATURE 0x3930424e  /* '90BN', CodeView 4.10. */
+#define MD_CVINFOCV50_SIGNATURE 0x3131424e  /* '11BN', CodeView 5.0,
+                                             * MS C7-format (/Z7). */
+
+#define MD_CVINFOUNKNOWN_SIGNATURE 0xffffffff  /* An unlikely value. */
+
+/* (MDRawModule).miscRecord can reference MDImageDebugMisc.  The Windows
+ * structure is actually defined in WinNT.h.  This structure is effectively
+ * obsolete with modules built by recent toolchains. */
+
+typedef struct {
+  u_int32_t data_type;    /* IMAGE_DEBUG_TYPE_*, not defined here because
+                           * this debug record type is mostly obsolete. */
+  u_int32_t length;       /* Length of entire MDImageDebugMisc structure */
+  u_int8_t  unicode;      /* True if data is multibyte */
+  u_int8_t  reserved[3];
+  u_int8_t  data[1];
+} MDImageDebugMisc;  /* IMAGE_DEBUG_MISC */
+
+static const size_t MDImageDebugMisc_minsize = offsetof(MDImageDebugMisc,
+                                                        data[0]);
+
+
+typedef struct {
+  u_int32_t   number_of_modules;
+  MDRawModule modules[1];
+} MDRawModuleList;  /* MINIDUMP_MODULE_LIST */
+
+static const size_t MDRawModuleList_minsize = offsetof(MDRawModuleList,
+                                                       modules[0]);
+
+
+typedef struct {
+  u_int32_t          number_of_memory_ranges;
+  MDMemoryDescriptor memory_ranges[1];
+} MDRawMemoryList;  /* MINIDUMP_MEMORY_LIST */
+
+static const size_t MDRawMemoryList_minsize = offsetof(MDRawMemoryList,
+                                                       memory_ranges[0]);
+
+
+#define MD_EXCEPTION_MAXIMUM_PARAMETERS 15
+
+typedef struct {
+  u_int32_t exception_code;     /* Windows: MDExceptionCodeWin,
+                                 * Mac OS X: MDExceptionMac,
+                                 * Linux: MDExceptionCodeLinux. */
+  u_int32_t exception_flags;    /* Windows: 1 if noncontinuable,
+                                   Mac OS X: MDExceptionCodeMac. */
+  u_int64_t exception_record;   /* Address (in the minidump-producing host's
+                                 * memory) of another MDException, for
+                                 * nested exceptions. */
+  u_int64_t exception_address;  /* The address that caused the exception.
+                                 * Mac OS X: exception subcode (which is
+                                 *           typically the address). */
+  u_int32_t number_parameters;  /* Number of valid elements in
+                                 * exception_information. */
+  u_int32_t __align;
+  u_int64_t exception_information[MD_EXCEPTION_MAXIMUM_PARAMETERS];
+} MDException;  /* MINIDUMP_EXCEPTION */
+
+#include "minidump_exception_win32.h"
+#include "minidump_exception_mac.h"
+#include "minidump_exception_linux.h"
+#include "minidump_exception_solaris.h"
+
+typedef struct {
+  u_int32_t            thread_id;         /* Thread in which the exception
+                                           * occurred.  Corresponds to
+                                           * (MDRawThread).thread_id. */
+  u_int32_t            __align;
+  MDException          exception_record;
+  MDLocationDescriptor thread_context;    /* MDRawContext[CPU] */
+} MDRawExceptionStream;  /* MINIDUMP_EXCEPTION_STREAM */
+
+
+typedef union {
+  struct {
+    u_int32_t vendor_id[3];               /* cpuid 0: ebx, edx, ecx */
+    u_int32_t version_information;        /* cpuid 1: eax */
+    u_int32_t feature_information;        /* cpuid 1: edx */
+    u_int32_t amd_extended_cpu_features;  /* cpuid 0x80000001, ebx */
+  } x86_cpu_info;
+  struct {
+    u_int64_t processor_features[2];
+  } other_cpu_info;
+} MDCPUInformation;  /* CPU_INFORMATION */
+
+
+typedef struct {
+  /* The next 3 fields and numberOfProcessors are from the SYSTEM_INFO
+   * structure as returned by GetSystemInfo */
+  u_int16_t        processor_architecture;
+  u_int16_t        processor_level;         /* x86: 5 = 586, 6 = 686, ... */
+  u_int16_t        processor_revision;      /* x86: 0xMMSS, where MM=model,
+                                             *      SS=stepping */
+
+  u_int8_t         number_of_processors;
+  u_int8_t         product_type;            /* Windows: VER_NT_* from WinNT.h */
+
+  /* The next 5 fields are from the OSVERSIONINFO structure as returned
+   * by GetVersionEx */
+  u_int32_t        major_version;
+  u_int32_t        minor_version;
+  u_int32_t        build_number;
+  u_int32_t        platform_id;
+  MDRVA            csd_version_rva;  /* MDString further identifying the
+                                      * host OS.
+                                      * Windows: name of the installed OS
+                                      *          service pack.
+                                      * Mac OS X: the Apple OS build number
+                                      *           (sw_vers -buildVersion).
+                                      * Linux: uname -srvmo */
+
+  u_int16_t        suite_mask;       /* Windows: VER_SUITE_* from WinNT.h */
+  u_int16_t        reserved2;
+
+  MDCPUInformation cpu;
+} MDRawSystemInfo;  /* MINIDUMP_SYSTEM_INFO */
+
+/* For (MDRawSystemInfo).processor_architecture: */
+typedef enum {
+  MD_CPU_ARCHITECTURE_X86       =  0,  /* PROCESSOR_ARCHITECTURE_INTEL */
+  MD_CPU_ARCHITECTURE_MIPS      =  1,  /* PROCESSOR_ARCHITECTURE_MIPS */
+  MD_CPU_ARCHITECTURE_ALPHA     =  2,  /* PROCESSOR_ARCHITECTURE_ALPHA */
+  MD_CPU_ARCHITECTURE_PPC       =  3,  /* PROCESSOR_ARCHITECTURE_PPC */
+  MD_CPU_ARCHITECTURE_SHX       =  4,  /* PROCESSOR_ARCHITECTURE_SHX
+                                        * (Super-H) */
+  MD_CPU_ARCHITECTURE_ARM       =  5,  /* PROCESSOR_ARCHITECTURE_ARM */
+  MD_CPU_ARCHITECTURE_IA64      =  6,  /* PROCESSOR_ARCHITECTURE_IA64 */
+  MD_CPU_ARCHITECTURE_ALPHA64   =  7,  /* PROCESSOR_ARCHITECTURE_ALPHA64 */
+  MD_CPU_ARCHITECTURE_MSIL      =  8,  /* PROCESSOR_ARCHITECTURE_MSIL
+                                        * (Microsoft Intermediate Language) */
+  MD_CPU_ARCHITECTURE_AMD64     =  9,  /* PROCESSOR_ARCHITECTURE_AMD64 */
+  MD_CPU_ARCHITECTURE_X86_WIN64 = 10,
+      /* PROCESSOR_ARCHITECTURE_IA32_ON_WIN64 (WoW64) */
+  MD_CPU_ARCHITECTURE_SPARC     = 0x8001, /* Breakpad-defined value for SPARC */
+  MD_CPU_ARCHITECTURE_UNKNOWN   = 0xffff  /* PROCESSOR_ARCHITECTURE_UNKNOWN */
+} MDCPUArchitecture;
+
+/* For (MDRawSystemInfo).platform_id: */
+typedef enum {
+  MD_OS_WIN32S        = 0,  /* VER_PLATFORM_WIN32s (Windows 3.1) */
+  MD_OS_WIN32_WINDOWS = 1,  /* VER_PLATFORM_WIN32_WINDOWS (Windows 95-98-Me) */
+  MD_OS_WIN32_NT      = 2,  /* VER_PLATFORM_WIN32_NT (Windows NT, 2000+) */
+  MD_OS_WIN32_CE      = 3,  /* VER_PLATFORM_WIN32_CE, VER_PLATFORM_WIN32_HH
+                             * (Windows CE, Windows Mobile, "Handheld") */
+
+  /* The following values are Breakpad-defined. */
+  MD_OS_UNIX          = 0x8000,  /* Generic Unix-ish */
+  MD_OS_MAC_OS_X      = 0x8101,  /* Mac OS X/Darwin */
+  MD_OS_IOS           = 0x8102,  /* iOS */
+  MD_OS_LINUX         = 0x8201,  /* Linux */
+  MD_OS_SOLARIS       = 0x8202,  /* Solaris */
+  MD_OS_ANDROID       = 0x8203   /* Android */
+} MDOSPlatform;
+
+
+typedef struct {
+  u_int32_t size_of_info;  /* Length of entire MDRawMiscInfo structure. */
+  u_int32_t flags1;
+
+  /* The next field is only valid if flags1 contains
+   * MD_MISCINFO_FLAGS1_PROCESS_ID. */
+  u_int32_t process_id;
+
+  /* The next 3 fields are only valid if flags1 contains
+   * MD_MISCINFO_FLAGS1_PROCESS_TIMES. */
+  u_int32_t process_create_time;  /* time_t process started */
+  u_int32_t process_user_time;    /* seconds of user CPU time */
+  u_int32_t process_kernel_time;  /* seconds of kernel CPU time */
+
+  /* The following fields are not present in MINIDUMP_MISC_INFO but are
+   * in MINIDUMP_MISC_INFO_2.  When this struct is populated, these values
+   * may not be set.  Use flags1 or sizeOfInfo to determine whether these
+   * values are present.  These are only valid when flags1 contains
+   * MD_MISCINFO_FLAGS1_PROCESSOR_POWER_INFO. */
+  u_int32_t processor_max_mhz;
+  u_int32_t processor_current_mhz;
+  u_int32_t processor_mhz_limit;
+  u_int32_t processor_max_idle_state;
+  u_int32_t processor_current_idle_state;
+} MDRawMiscInfo;  /* MINIDUMP_MISC_INFO, MINIDUMP_MISC_INFO2 */
+
+#define MD_MISCINFO_SIZE 24
+#define MD_MISCINFO2_SIZE 44
+
+/* For (MDRawMiscInfo).flags1.  These values indicate which fields in the
+ * MDRawMiscInfoStructure are valid. */
+typedef enum {
+  MD_MISCINFO_FLAGS1_PROCESS_ID           = 0x00000001,
+      /* MINIDUMP_MISC1_PROCESS_ID */
+  MD_MISCINFO_FLAGS1_PROCESS_TIMES        = 0x00000002,
+      /* MINIDUMP_MISC1_PROCESS_TIMES */
+  MD_MISCINFO_FLAGS1_PROCESSOR_POWER_INFO = 0x00000004
+      /* MINIDUMP_MISC1_PROCESSOR_POWER_INFO */
+} MDMiscInfoFlags1;
+
+/* 
+ * Around DbgHelp version 6.0, the style of new LIST structures changed
+ * from including an array of length 1 at the end of the struct to
+ * represent the variable-length data to including explicit
+ * "size of header", "size of entry" and "number of entries" fields
+ * in the header, presumably to allow backwards-compatibly-extending
+ * the structures in the future. The actual list entries follow the
+ * header data directly in this case.
+ */
+
+typedef struct {
+  u_int32_t size_of_header;    /* sizeof(MDRawMemoryInfoList) */
+  u_int32_t size_of_entry;     /* sizeof(MDRawMemoryInfo) */
+  u_int64_t number_of_entries;
+} MDRawMemoryInfoList;  /* MINIDUMP_MEMORY_INFO_LIST */
+
+typedef struct {
+  u_int64_t base_address;           /* Base address of a region of pages */
+  u_int64_t allocation_base;        /* Base address of a range of pages
+                                     * within this region. */
+  u_int32_t allocation_protection;  /* Memory protection when this region
+                                     * was originally allocated:
+                                     * MDMemoryProtection */
+  u_int32_t __alignment1;
+  u_int64_t region_size;
+  u_int32_t state;                  /* MDMemoryState */
+  u_int32_t protection;             /* MDMemoryProtection */
+  u_int32_t type;                   /* MDMemoryType */
+  u_int32_t __alignment2;
+} MDRawMemoryInfo;  /* MINIDUMP_MEMORY_INFO */
+
+/* For (MDRawMemoryInfo).state */
+typedef enum {
+  MD_MEMORY_STATE_COMMIT   = 0x1000,  /* physical storage has been allocated */
+  MD_MEMORY_STATE_RESERVE  = 0x2000,  /* reserved, but no physical storage */
+  MD_MEMORY_STATE_FREE     = 0x10000  /* available to be allocated */
+} MDMemoryState;
+
+/* For (MDRawMemoryInfo).allocation_protection and .protection */
+typedef enum {
+  MD_MEMORY_PROTECT_NOACCESS          = 0x01,  /* PAGE_NOACCESS */
+  MD_MEMORY_PROTECT_READONLY          = 0x02,  /* PAGE_READONLY */
+  MD_MEMORY_PROTECT_READWRITE         = 0x04,  /* PAGE_READWRITE */
+  MD_MEMORY_PROTECT_WRITECOPY         = 0x08,  /* PAGE_WRITECOPY */
+  MD_MEMORY_PROTECT_EXECUTE           = 0x10,  /* PAGE_EXECUTE */
+  MD_MEMORY_PROTECT_EXECUTE_READ      = 0x20,  /* PAGE_EXECUTE_READ */
+  MD_MEMORY_PROTECT_EXECUTE_READWRITE = 0x40,  /* PAGE_EXECUTE_READWRITE */
+  MD_MEMORY_PROTECT_EXECUTE_WRITECOPY = 0x80,  /* PAGE_EXECUTE_WRITECOPY */
+  /* These options can be combined with the previous flags. */
+  MD_MEMORY_PROTECT_GUARD             = 0x100,  /* PAGE_GUARD */
+  MD_MEMORY_PROTECT_NOCACHE           = 0x200,  /* PAGE_NOCACHE */
+  MD_MEMORY_PROTECT_WRITECOMBINE      = 0x400,  /* PAGE_WRITECOMBINE */
+} MDMemoryProtection;
+
+/* Used to mask the mutually exclusive options from the combinable flags. */
+const u_int32_t MD_MEMORY_PROTECTION_ACCESS_MASK = 0xFF;
+
+/* For (MDRawMemoryInfo).type */
+typedef enum {
+  MD_MEMORY_TYPE_PRIVATE = 0x20000,   /* not shared by other processes */
+  MD_MEMORY_TYPE_MAPPED  = 0x40000,   /* mapped into the view of a section */
+  MD_MEMORY_TYPE_IMAGE   = 0x1000000  /* mapped into the view of an image */
+} MDMemoryType;
+
+/*
+ * Breakpad extension types
+ */
+
+
+typedef struct {
+  /* validity is a bitmask with values from MDBreakpadInfoValidity, indicating
+   * which of the other fields in the structure are valid. */
+  u_int32_t validity;
+
+  /* Thread ID of the handler thread.  dump_thread_id should correspond to
+   * the thread_id of an MDRawThread in the minidump's MDRawThreadList if
+   * a dedicated thread in that list was used to produce the minidump.  If
+   * the MDRawThreadList does not contain a dedicated thread used to produce
+   * the minidump, this field should be set to 0 and the validity field
+   * must not contain MD_BREAKPAD_INFO_VALID_DUMP_THREAD_ID. */
+  u_int32_t dump_thread_id;
+
+  /* Thread ID of the thread that requested the minidump be produced.  As
+   * with dump_thread_id, requesting_thread_id should correspond to the
+   * thread_id of an MDRawThread in the minidump's MDRawThreadList.  For
+   * minidumps produced as a result of an exception, requesting_thread_id
+   * will be the same as the MDRawExceptionStream's thread_id field.  For
+   * minidumps produced "manually" at the program's request,
+   * requesting_thread_id will indicate which thread caused the dump to be
+   * written.  If the minidump was produced at the request of something
+   * other than a thread in the MDRawThreadList, this field should be set
+   * to 0 and the validity field must not contain
+   * MD_BREAKPAD_INFO_VALID_REQUESTING_THREAD_ID. */
+  u_int32_t requesting_thread_id;
+} MDRawBreakpadInfo;
+
+/* For (MDRawBreakpadInfo).validity: */
+typedef enum {
+  /* When set, the dump_thread_id field is valid. */
+  MD_BREAKPAD_INFO_VALID_DUMP_THREAD_ID       = 1 << 0,
+
+  /* When set, the requesting_thread_id field is valid. */
+  MD_BREAKPAD_INFO_VALID_REQUESTING_THREAD_ID = 1 << 1
+} MDBreakpadInfoValidity;
+
+typedef struct {
+  /* expression, function, and file are 0-terminated UTF-16 strings.  They
+   * may be truncated if necessary, but should always be 0-terminated when
+   * written to a file.
+   * Fixed-length strings are used because MiniDumpWriteDump doesn't offer
+   * a way for user streams to point to arbitrary RVAs for strings. */
+  u_int16_t expression[128];  /* Assertion that failed... */
+  u_int16_t function[128];    /* ...within this function... */
+  u_int16_t file[128];        /* ...in this file... */
+  u_int32_t line;             /* ...at this line. */
+  u_int32_t type;
+} MDRawAssertionInfo;
+
+/* For (MDRawAssertionInfo).type: */
+typedef enum {
+  MD_ASSERTION_INFO_TYPE_UNKNOWN = 0,
+
+  /* Used for assertions that would be raised by the MSVC CRT but are
+   * directed to an invalid parameter handler instead. */
+  MD_ASSERTION_INFO_TYPE_INVALID_PARAMETER,
+
+  /* Used for assertions that would be raised by the MSVC CRT but are
+   * directed to a pure virtual call handler instead. */
+  MD_ASSERTION_INFO_TYPE_PURE_VIRTUAL_CALL
+} MDAssertionInfoData;
+
+/* These structs are used to store the DSO debug data in Linux minidumps,
+ * which is necessary for converting minidumps to usable coredumps. */
+typedef struct {
+  void*     addr;
+  MDRVA     name;
+  void*     ld;
+} MDRawLinkMap;
+
+typedef struct {
+  u_int32_t version;
+  MDRVA     map;
+  u_int32_t dso_count;
+  void*     brk;
+  void*     ldbase;
+  void*     dynamic;
+} MDRawDebug;
+
+#if defined(_MSC_VER)
+#pragma warning(pop)
+#endif  /* _MSC_VER */
+
+
+#endif  /* GOOGLE_BREAKPAD_COMMON_MINIDUMP_FORMAT_H__ */
diff --git a/3rdParty/Breakpad/src/google_breakpad/common/minidump_size.h b/3rdParty/Breakpad/src/google_breakpad/common/minidump_size.h
new file mode 100644
index 0000000..918544b
--- /dev/null
+++ b/3rdParty/Breakpad/src/google_breakpad/common/minidump_size.h
@@ -0,0 +1,107 @@
+// 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. */
+
+// minidump_size.h: Provides a C++ template for programmatic access to
+// the sizes of various types defined in minidump_format.h.
+//
+// Author: Mark Mentovai
+
+#ifndef GOOGLE_BREAKPAD_COMMON_MINIDUMP_SIZE_H__
+#define GOOGLE_BREAKPAD_COMMON_MINIDUMP_SIZE_H__
+
+#include <sys/types.h>
+
+#include "google_breakpad/common/minidump_format.h"
+
+namespace google_breakpad {
+
+template<typename T>
+class minidump_size {
+ public:
+  static size_t size() { return sizeof(T); }
+};
+
+// Explicit specializations for variable-length types.  The size returned
+// for these should be the size for an object without its variable-length
+// section.
+
+template<>
+class minidump_size<MDString> {
+ public:
+  static size_t size() { return MDString_minsize; }
+};
+
+template<>
+class minidump_size<MDRawThreadList> {
+ public:
+  static size_t size() { return MDRawThreadList_minsize; }
+};
+
+template<>
+class minidump_size<MDCVInfoPDB20> {
+ public:
+  static size_t size() { return MDCVInfoPDB20_minsize; }
+};
+
+template<>
+class minidump_size<MDCVInfoPDB70> {
+ public:
+  static size_t size() { return MDCVInfoPDB70_minsize; }
+};
+
+template<>
+class minidump_size<MDImageDebugMisc> {
+ public:
+  static size_t size() { return MDImageDebugMisc_minsize; }
+};
+
+template<>
+class minidump_size<MDRawModuleList> {
+ public:
+  static size_t size() { return MDRawModuleList_minsize; }
+};
+
+template<>
+class minidump_size<MDRawMemoryList> {
+ public:
+  static size_t size() { return MDRawMemoryList_minsize; }
+};
+
+// Explicit specialization for MDRawModule, for which sizeof may include
+// tail-padding on some architectures but not others.
+
+template<>
+class minidump_size<MDRawModule> {
+ public:
+  static size_t size() { return MD_MODULE_SIZE; }
+};
+
+}  // namespace google_breakpad
+
+#endif  // GOOGLE_BREAKPAD_COMMON_MINIDUMP_SIZE_H__
diff --git a/3rdParty/Breakpad/src/processor/scoped_ptr.h b/3rdParty/Breakpad/src/processor/scoped_ptr.h
new file mode 100644
index 0000000..0d4f7fd
--- /dev/null
+++ b/3rdParty/Breakpad/src/processor/scoped_ptr.h
@@ -0,0 +1,335 @@
+//  (C) Copyright Greg Colvin and Beman Dawes 1998, 1999.
+//  Copyright (c) 2001, 2002 Peter Dimov
+//
+//  Permission to copy, use, modify, sell and distribute this software
+//  is granted provided this copyright notice appears in all copies.
+//  This software is provided "as is" without express or implied
+//  warranty, and with no claim as to its suitability for any purpose.
+//
+//  See http://www.boost.org/libs/smart_ptr/scoped_ptr.htm for documentation.
+//
+
+//  scoped_ptr mimics a built-in pointer except that it guarantees deletion
+//  of the object pointed to, either on destruction of the scoped_ptr or via
+//  an explicit reset(). scoped_ptr is a simple solution for simple needs;
+//  use shared_ptr or std::auto_ptr if your needs are more complex.
+
+//  *** NOTE ***
+//  If your scoped_ptr is a class member of class FOO pointing to a 
+//  forward declared type BAR (as shown below), then you MUST use a non-inlined 
+//  version of the destructor.  The destructor of a scoped_ptr (called from
+//  FOO's destructor) must have a complete definition of BAR in order to 
+//  destroy it.  Example:
+//
+//  -- foo.h --
+//  class BAR;
+//
+//  class FOO {
+//   public:
+//    FOO();
+//    ~FOO();  // Required for sources that instantiate class FOO to compile!
+//    
+//   private:
+//    scoped_ptr<BAR> bar_;
+//  };
+//
+//  -- foo.cc --
+//  #include "foo.h"
+//  FOO::~FOO() {} // Empty, but must be non-inlined to FOO's class definition.
+
+//  scoped_ptr_malloc added by Google
+//  When one of these goes out of scope, instead of doing a delete or
+//  delete[], it calls free().  scoped_ptr_malloc<char> is likely to see
+//  much more use than any other specializations.
+
+//  release() added by Google
+//  Use this to conditionally transfer ownership of a heap-allocated object
+//  to the caller, usually on method success.
+
+#ifndef PROCESSOR_SCOPED_PTR_H__
+#define PROCESSOR_SCOPED_PTR_H__
+
+#include <cstddef>            // for std::ptrdiff_t
+#include <assert.h>           // for assert
+#include <stdlib.h>           // for free() decl
+
+namespace google_breakpad {
+
+template <typename T>
+class scoped_ptr {
+ private:
+
+  T* ptr;
+
+  scoped_ptr(scoped_ptr const &);
+  scoped_ptr & operator=(scoped_ptr const &);
+
+ public:
+
+  typedef T element_type;
+
+  explicit scoped_ptr(T* p = 0): ptr(p) {}
+
+  ~scoped_ptr() {
+    typedef char type_must_be_complete[sizeof(T)];
+    delete ptr;
+  }
+
+  void reset(T* p = 0) {
+    typedef char type_must_be_complete[sizeof(T)];
+
+    if (ptr != p) {
+      delete ptr;
+      ptr = p;
+    }
+  }
+
+  T& operator*() const {
+    assert(ptr != 0);
+    return *ptr;
+  }
+
+  T* operator->() const  {
+    assert(ptr != 0);
+    return ptr;
+  }
+
+  bool operator==(T* p) const {
+    return ptr == p;
+  }
+
+  bool operator!=(T* p) const {
+    return ptr != p;
+  }
+
+  T* get() const  {
+    return ptr;
+  }
+
+  void swap(scoped_ptr & b) {
+    T* tmp = b.ptr;
+    b.ptr = ptr;
+    ptr = tmp;
+  }
+
+  T* release() {
+    T* tmp = ptr;
+    ptr = 0;
+    return tmp;
+  }
+
+ private:
+
+  // no reason to use these: each scoped_ptr should have its own object
+  template <typename U> bool operator==(scoped_ptr<U> const& p) const;
+  template <typename U> bool operator!=(scoped_ptr<U> const& p) const;
+};
+
+template<typename T> inline
+void swap(scoped_ptr<T>& a, scoped_ptr<T>& b) {
+  a.swap(b);
+}
+
+template<typename T> inline
+bool operator==(T* p, const scoped_ptr<T>& b) {
+  return p == b.get();
+}
+
+template<typename T> inline
+bool operator!=(T* p, const scoped_ptr<T>& b) {
+  return p != b.get();
+}
+
+//  scoped_array extends scoped_ptr to arrays. Deletion of the array pointed to
+//  is guaranteed, either on destruction of the scoped_array or via an explicit
+//  reset(). Use shared_array or std::vector if your needs are more complex.
+
+template<typename T>
+class scoped_array {
+ private:
+
+  T* ptr;
+
+  scoped_array(scoped_array const &);
+  scoped_array & operator=(scoped_array const &);
+
+ public:
+
+  typedef T element_type;
+
+  explicit scoped_array(T* p = 0) : ptr(p) {}
+
+  ~scoped_array() {
+    typedef char type_must_be_complete[sizeof(T)];
+    delete[] ptr;
+  }
+
+  void reset(T* p = 0) {
+    typedef char type_must_be_complete[sizeof(T)];
+
+    if (ptr != p) {
+      delete [] ptr;
+      ptr = p;
+    }
+  }
+
+  T& operator[](std::ptrdiff_t i) const {
+    assert(ptr != 0);
+    assert(i >= 0);
+    return ptr[i];
+  }
+
+  bool operator==(T* p) const {
+    return ptr == p;
+  }
+
+  bool operator!=(T* p) const {
+    return ptr != p;
+  }
+
+  T* get() const {
+    return ptr;
+  }
+
+  void swap(scoped_array & b) {
+    T* tmp = b.ptr;
+    b.ptr = ptr;
+    ptr = tmp;
+  }
+
+  T* release() {
+    T* tmp = ptr;
+    ptr = 0;
+    return tmp;
+  }
+
+ private:
+
+  // no reason to use these: each scoped_array should have its own object
+  template <typename U> bool operator==(scoped_array<U> const& p) const;
+  template <typename U> bool operator!=(scoped_array<U> const& p) const;
+};
+
+template<class T> inline
+void swap(scoped_array<T>& a, scoped_array<T>& b) {
+  a.swap(b);
+}
+
+template<typename T> inline
+bool operator==(T* p, const scoped_array<T>& b) {
+  return p == b.get();
+}
+
+template<typename T> inline
+bool operator!=(T* p, const scoped_array<T>& b) {
+  return p != b.get();
+}
+
+
+// This class wraps the c library function free() in a class that can be
+// passed as a template argument to scoped_ptr_malloc below.
+class ScopedPtrMallocFree {
+ public:
+  inline void operator()(void* x) const {
+    free(x);
+  }
+};
+
+// scoped_ptr_malloc<> is similar to scoped_ptr<>, but it accepts a
+// second template argument, the functor used to free the object.
+
+template<typename T, typename FreeProc = ScopedPtrMallocFree>
+class scoped_ptr_malloc {
+ private:
+
+  T* ptr;
+
+  scoped_ptr_malloc(scoped_ptr_malloc const &);
+  scoped_ptr_malloc & operator=(scoped_ptr_malloc const &);
+
+ public:
+
+  typedef T element_type;
+
+  explicit scoped_ptr_malloc(T* p = 0): ptr(p) {}
+
+  ~scoped_ptr_malloc() {
+    typedef char type_must_be_complete[sizeof(T)];
+    free_((void*) ptr);
+  }
+
+  void reset(T* p = 0) {
+    typedef char type_must_be_complete[sizeof(T)];
+
+    if (ptr != p) {
+      free_((void*) ptr);
+      ptr = p;
+    }
+  }
+
+  T& operator*() const {
+    assert(ptr != 0);
+    return *ptr;
+  }
+
+  T* operator->() const {
+    assert(ptr != 0);
+    return ptr;
+  }
+
+  bool operator==(T* p) const {
+    return ptr == p;
+  }
+
+  bool operator!=(T* p) const {
+    return ptr != p;
+  }
+
+  T* get() const {
+    return ptr;
+  }
+
+  void swap(scoped_ptr_malloc & b) {
+    T* tmp = b.ptr;
+    b.ptr = ptr;
+    ptr = tmp;
+  }
+
+  T* release() {
+    T* tmp = ptr;
+    ptr = 0;
+    return tmp;
+  }
+
+ private:
+
+  // no reason to use these: each scoped_ptr_malloc should have its own object
+  template <typename U, typename GP>
+  bool operator==(scoped_ptr_malloc<U, GP> const& p) const;
+  template <typename U, typename GP>
+  bool operator!=(scoped_ptr_malloc<U, GP> const& p) const;
+
+  static FreeProc const free_;
+};
+
+template<typename T, typename FP>
+FP const scoped_ptr_malloc<T,FP>::free_ = FP();
+
+template<typename T, typename FP> inline
+void swap(scoped_ptr_malloc<T,FP>& a, scoped_ptr_malloc<T,FP>& b) {
+  a.swap(b);
+}
+
+template<typename T, typename FP> inline
+bool operator==(T* p, const scoped_ptr_malloc<T,FP>& b) {
+  return p == b.get();
+}
+
+template<typename T, typename FP> inline
+bool operator!=(T* p, const scoped_ptr_malloc<T,FP>& b) {
+  return p != b.get();
+}
+
+}  // namespace google_breakpad
+
+#endif  // PROCESSOR_SCOPED_PTR_H__
diff --git a/BuildTools/SCons/SConscript.boot b/BuildTools/SCons/SConscript.boot
index e8ccd7a..d6977fe 100644
--- a/BuildTools/SCons/SConscript.boot
+++ b/BuildTools/SCons/SConscript.boot
@@ -130,8 +130,7 @@ env["OBJCCFLAGS"] = []
 
 if env["optimize"] :
 	if env["PLATFORM"] == "win32" :
-		env.Append(CCFLAGS = ["/O2", "/GL"])
-		env.Append(LINKFLAGS = ["/LTCG"])
+		env.Append(CCFLAGS = ["/O2"])
 	else :
 		env.Append(CCFLAGS = ["-O2"])
 
@@ -140,10 +139,15 @@ if env["target"] == "xcode" and os.environ["CONFIGURATION"] == "Release" :
 
 if env["debug"] :
 	if env["PLATFORM"] == "win32" :
-		env.Append(CCFLAGS = ["/Zi", "/MDd"])
+		env.Append(CCFLAGS = ["/Z7"])
 		env.Append(LINKFLAGS = ["/DEBUG"])
 		if env["set_iterator_debug_level"] :
 			env.Append(CPPDEFINES = ["_ITERATOR_DEBUG_LEVEL=0"])
+		if env["optimize"] :
+			env.Append(LINKFLAGS = ["/OPT:NOREF"])
+			env.Append(CCFLAGS = ["/MD"])
+		else :
+			env.Append(CCFLAGS = ["/MDd"])
 	else :
 		env.Append(CCFLAGS = ["-g"])
 elif env["PLATFORM"] == "win32" :
diff --git a/SwifTools/CrashReporter.cpp b/SwifTools/CrashReporter.cpp
new file mode 100644
index 0000000..4a07e40
--- /dev/null
+++ b/SwifTools/CrashReporter.cpp
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2012 Remko Tronçon
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+
+
+#include <SwifTools/CrashReporter.h>
+#include <Swiften/Base/Platform.h>
+
+#if defined(HAVE_BREAKPAD)
+
+#pragma GCC diagnostic ignored "-Wold-style-cast"
+
+#include <boost/smart_ptr/make_shared.hpp>
+
+#ifdef SWIFTEN_PLATFORM_MACOSX
+#include "client/mac/handler/exception_handler.h"
+#endif
+#ifdef SWIFTEN_PLATFORM_WINDOWS
+#include "client/windows/handler/exception_handler.h"
+#endif
+
+#if defined(SWIFTEN_PLATFORM_WINDOWS)
+static bool handleDump(const wchar_t* /* dir */, const wchar_t* /* id*/, void* /* context */, EXCEPTION_POINTERS*, MDRawAssertionInfo*, bool /* succeeded */) {
+	return false;
+}
+#else
+static bool handleDump(const char* /* dir */, const char* /* id*/, void* /* context */, bool /* succeeded */) {
+	return false;
+}
+#endif
+
+namespace Swift {
+
+struct CrashReporter::Private {
+	boost::shared_ptr<google_breakpad::ExceptionHandler> handler;
+};
+
+CrashReporter::CrashReporter(const boost::filesystem::path& path) {
+	// Create the path that will contain the crash dumps
+	if (!boost::filesystem::exists(path)) {
+		try {
+			boost::filesystem::create_directories(path);
+		}
+		catch (const boost::filesystem::filesystem_error& e) {
+			std::cerr << "ERROR: " << e.what() << std::endl;
+		}
+	}
+
+	p = boost::make_shared<Private>();
+#if defined(SWIFTEN_PLATFORM_WINDOWS)
+	// FIXME: Need UTF8 conversion from string to wstring
+	std::string pathString = path.string();
+	p->handler = boost::make_shared<google_breakpad::ExceptionHandler>(
+			std::wstring(pathString.begin(), pathString.end()), 
+			(google_breakpad::ExceptionHandler::FilterCallback) 0, 
+			handleDump, 
+			(void*) 0, 
+			google_breakpad::ExceptionHandler::HANDLER_ALL);
+// Turning it off for Mac, because it doesn't really help us
+//#elif defined(SWIFTEN_PLATFORM_MACOSX)
+//	p->handler = boost::make_shared<google_breakpad::ExceptionHandler>(path.string(), (google_breakpad::ExceptionHandler::FilterCallback) 0, handleDump, (void*) 0, true, (const char*) 0);
+#endif
+}
+
+};
+
+#else
+
+// Dummy implementation
+namespace Swift {
+	CrashReporter::CrashReporter(const boost::filesystem::path&) {}
+};
+
+#endif
diff --git a/SwifTools/CrashReporter.h b/SwifTools/CrashReporter.h
new file mode 100644
index 0000000..834e8af
--- /dev/null
+++ b/SwifTools/CrashReporter.h
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2012 Remko Tronçon
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+
+#pragma once
+
+#include <boost/shared_ptr.hpp>
+#include <boost/filesystem.hpp>
+#include <string>
+
+namespace Swift {
+	class CrashReporter {
+		public:
+			CrashReporter(const boost::filesystem::path& path);
+
+		private:
+			struct Private;
+			boost::shared_ptr<Private> p;
+	};
+}
diff --git a/SwifTools/SConscript b/SwifTools/SConscript
index 5b97bed..3b25269 100644
--- a/SwifTools/SConscript
+++ b/SwifTools/SConscript
@@ -16,8 +16,8 @@ if env["SCONS_STAGE"] == "flags" :
 
 if env["SCONS_STAGE"] == "build" :
 	swiftools_env = env.Clone()
-	swiftools_env.MergeFlags(swiftools_env["SWIFTEN_FLAGS"])
-	swiftools_env.MergeFlags(swiftools_env["BOOST_FLAGS"])
+	swiftools_env.UseFlags(swiftools_env["SWIFTEN_FLAGS"])
+	swiftools_env.UseFlags(swiftools_env["BOOST_FLAGS"])
 
 	sources = [
 			"Idle/IdleDetector.cpp",
@@ -44,6 +44,9 @@ if env["SCONS_STAGE"] == "build" :
 	elif swiftools_env["HAVE_XSS"] :
 		swiftools_env.Append(CPPDEFINES = ["HAVE_XSS"])
 		sources += ["Idle/XSSIdleQuerier.cpp"]
+
+	swiftools_env.UseFlags(swiftools_env["BREAKPAD_FLAGS"])
+	sources += ["CrashReporter.cpp"]
 	
 	swiftools_env["SWIFTOOLS_OBJECTS"] = []
 	Export("swiftools_env")
diff --git a/Swift/QtUI/SConscript b/Swift/QtUI/SConscript
index f935530..064faab 100644
--- a/Swift/QtUI/SConscript
+++ b/Swift/QtUI/SConscript
@@ -31,6 +31,7 @@ if myenv["HAVE_SPARKLE"] :
   myenv.UseFlags(env["SPARKLE_FLAGS"])
 myenv.UseFlags(env["SWIFTEN_FLAGS"])
 myenv.UseFlags(env["SWIFTEN_DEP_FLAGS"])
+myenv.UseFlags(env["BREAKPAD_FLAGS"])
 if myenv.get("HAVE_GROWL", False) :
 	myenv.UseFlags(myenv["GROWL_FLAGS"])
 	myenv.Append(CPPDEFINES = ["HAVE_GROWL"])
diff --git a/Swift/QtUI/main.cpp b/Swift/QtUI/main.cpp
index fc3bf15..9c99394 100644
--- a/Swift/QtUI/main.cpp
+++ b/Swift/QtUI/main.cpp
@@ -19,6 +19,7 @@
 #include <Swift/Controllers/ApplicationInfo.h>
 #include <Swift/Controllers/BuildVersion.h>
 #include <SwifTools/Application/PlatformApplicationPathProvider.h>
+#include <SwifTools/CrashReporter.h>
 
 #include "QtSwift.h"
 #include "QtTranslator.h"
@@ -27,11 +28,16 @@
 int main(int argc, char* argv[]) {
 	QApplication app(argc, argv);
 
+	Swift::PlatformApplicationPathProvider applicationPathProvider(SWIFT_APPLICATION_NAME);
+
+	Swift::CrashReporter crashReporter(applicationPathProvider.getDataDir() / "crashes");
+
 	QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8"));
 
 	// Translation
 	QTextCodec::setCodecForTr(QTextCodec::codecForName("UTF-8"));
-	boost::filesystem::path someTranslationPath = Swift::PlatformApplicationPathProvider(SWIFT_APPLICATION_NAME).getResourcePath("/translations/swift_en.qm");
+	boost::filesystem::path someTranslationPath = applicationPathProvider.getResourcePath("/translations/swift_en.qm");
+
 	QTranslator qtTranslator;
 	if (!someTranslationPath.empty()) {
 #if QT_VERSION >= 0x040800
-- 
cgit v0.10.2-6-g49f6