Adding binaries for f766c4d7

This fixes the problem of missing includes, which "make install"
forgets to copy. Upstream patch for this is pending review.
diff --git a/build-breakpad.sh b/build-breakpad.sh
index 45c8dba..e8e7485 100755
--- a/build-breakpad.sh
+++ b/build-breakpad.sh
@@ -1,12 +1,40 @@
 #!/bin/bash -ex
 # Download & build breakpad on the local machine
-# works on Linux and OS X
-# TODO: get it working on Windows
+# works on Linux, OS X and Windows
 # leaves output in /tmp/prebuilts/google-breakpad/$OS-x86
 
+build_and_install()
+{
+	solution=$1
+	project=$2
+	if [ x"$project" == x ]; then
+		project_switch=""
+	else
+		project_switch="/Project $project"
+	fi
+
+	$RD/gyp/gyp --no-circular-check $solution.gyp
+	_CL_=/MDd devenv.com $solution.sln /Build Debug $project_switch
+	_CL_=/MD devenv.com $solution.sln /Build Release $project_switch
+	for build in Debug Release; do
+		find $build -name '*.exe' -exec cp -va -t $INSTALL/$build {} +
+		find $build -name '*.lib' -exec cp -va -t $INSTALL/$build {} +
+	done
+}
+
+install_headers()
+{
+	mkdir -p $INSTALL/include/breakpad
+	cd $RD/sources/src
+	rsync -av --include '*/' --include '*.h' --exclude '*' --prune-empty-dirs . $INSTALL/include/breakpad
+}
+
 PROJ=google-breakpad
-VER=282996a9
+VER=f766c4d7
 LSS_VER=92920301
+GYP_VER=265f495c
+
+MSVS=2013
 
 source $(dirname "$0")/build-common.sh build-common.sh
 
@@ -19,12 +47,60 @@
 cd lss
 git checkout $LSS_VER
 
-mkdir $RD/build
-cd $RD/build
+cd $RD
+git clone https://chromium.googlesource.com/external/gyp --no-checkout gyp
+cd gyp
+git checkout $GYP_VER
+cd ..
 
-../sources/configure --prefix=/
-make -j$CORES
+case "$OS" in
+	linux)
+		mkdir build
+		cd build
+		../sources/configure --prefix=/
+		make -j$CORES
+		make install DESTDIR=$INSTALL
 
-make install DESTDIR=$INSTALL
+                # make install does not actually install all the headers. Let's finish the job
+                # for him.
+                # TODO: This can be removed when the upstream installation patch lands
+                install_headers
+        ;;
+        darwin)
+                cd $RD/sources/src/tools/mac/dump_syms
+                xcodebuild -project dump_syms.xcodeproj -configuration Release -target dump_syms -sdk macosx10.9 GCC_VERSION= GCC_TREAT_WARNINGS_AS_ERRORS=no
+                mkdir $INSTALL/bin
+                cp build/Release/dump_syms $INSTALL/bin
+
+                cd $RD/sources/src/client/mac
+                xcodebuild -project Breakpad.xcodeproj -configuration Release -target Breakpad -sdk macosx10.9 GCC_VERSION=
+                install_name_tool -id @executable_path/../Breakpad.framework/Resources/breakpadUtilities.dylib build/Release/breakpadUtilities.dylib
+                install_name_tool -id @executable_path/../Breakpad.framework/Breakpad build/Release/Breakpad.framework/Breakpad
+                install_name_tool -change @executable_path/../Frameworks/Breakpad.framework/Resources/breakpadUtilities.dylib @executable_path/../Breakpad.framework/Resources/breakpadUtilities.dylib build/Release/Breakpad.framework/Breakpad
+                cp -r build/Release/Breakpad.framework $INSTALL
+
+		install_headers
+	;;
+	windows)
+		mkdir $INSTALL/Release $INSTALL/Debug
+
+		cd $RD/sources/src/client/windows/handler
+		build_and_install exception_handler exception_handler
+
+		cd $RD/sources/src/client/windows/crash_generation
+		build_and_install crash_generation crash_generation_client
+
+		cd $RD/sources/src/common/windows
+		build_and_install common_windows common_windows_lib
+
+		cd $RD/sources/src/tools/windows/dump_syms
+		build_and_install dump_syms dump_syms
+
+		cd $RD/sources/src/tools/windows/symupload
+		build_and_install symupload symupload
+
+		install_headers
+	;;
+esac
 
 commit_and_push
diff --git a/build-common.sh b/build-common.sh
index efa4af6..0f252ea 100755
--- a/build-common.sh
+++ b/build-common.sh
@@ -46,7 +46,7 @@
         # MINGW32_NT-*
         PATH_PREFIX=
     fi
-    SCRATCH=$PATH_PREFIX/d/src/tmp
+    SCRATCH=/tmp
     USER=$USERNAME
     OS='windows'
     CORES=$NUMBER_OF_PROCESSORS
@@ -114,9 +114,10 @@
     rm -rf $SCRATCH/prebuilts/$PROJ/
     mkdir -p $SCRATCH/prebuilts/$PROJ/
     cd $SCRATCH/prebuilts/$PROJ/
-    git clone persistent-https://googleplex-android.git.corp.google.com/platform/prebuilts/$PROJ/$OS-x86
+    git clone persistent-https://googleplex-android.git.corp.google.com/platform/prebuilts/$PROJ/$OS-x86 --no-checkout
     GIT_REPO="$SCRATCH/prebuilts/$PROJ/$OS-x86"
     cd $GIT_REPO
+    git checkout lldb-master-dev
     git rm -r * || true  # ignore error caused by empty directory
     mv $INSTALL/* $GIT_REPO
     cp $SCRIPT_FILE $GIT_REPO
diff --git a/include/breakpad/breakpad_googletest_includes.h b/include/breakpad/breakpad_googletest_includes.h
new file mode 100644
index 0000000..1cc324b
--- /dev/null
+++ b/include/breakpad/breakpad_googletest_includes.h
@@ -0,0 +1,57 @@
+// 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 BREAKPAD_GOOGLETEST_INCLUDES_H__
+#define BREAKPAD_GOOGLETEST_INCLUDES_H__
+
+#include "testing/gtest/include/gtest/gtest.h"
+#include "testing/include/gmock/gmock.h"
+
+// If AddressSanitizer is used, NULL pointer dereferences generate SIGILL
+// (illegal instruction) instead of SIGSEGV (segmentation fault).  Also,
+// the number of memory regions differs, so there is no point in running
+// this test if AddressSanitizer is used.
+//
+// Ideally we'd use this attribute to disable ASAN on a per-func basis,
+// but this doesn't seem to actually work, and it's changed names over
+// time.  So just stick with disabling the actual tests.
+// http://crbug.com/304575
+//#define NO_ASAN __attribute__((no_sanitize_address))
+#if defined(__clang__) && defined(__has_feature)
+// Have to keep this check sep from above as newer gcc will barf on it.
+# if __has_feature(address_sanitizer)
+#  define ADDRESS_SANITIZER
+# endif
+#elif defined(__GNUC__) && defined(__SANITIZE_ADDRESS__)
+# define ADDRESS_SANITIZER
+#else
+# undef ADDRESS_SANITIZER
+#endif
+
+#endif  // BREAKPAD_GOOGLETEST_INCLUDES_H__
diff --git a/include/breakpad/client/apple/Framework/BreakpadDefines.h b/include/breakpad/client/apple/Framework/BreakpadDefines.h
new file mode 100644
index 0000000..410a5a6
--- /dev/null
+++ b/include/breakpad/client/apple/Framework/BreakpadDefines.h
@@ -0,0 +1,73 @@
+// 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.
+
+// Keys for configuration file
+#define kReporterMinidumpDirectoryKey "MinidumpDir"
+#define kReporterMinidumpIDKey        "MinidumpID"
+
+// Filename for recording uploaded IDs
+#define kReporterLogFilename          "uploads.log"
+
+// The default subdirectory of the Library to put crash dumps in
+// The subdirectory is
+//  ~/Library/<kDefaultLibrarySubdirectory>/<GoogleBreakpadProduct>
+#define kDefaultLibrarySubdirectory   "Breakpad"
+
+// Specify some special keys to be used in the configuration file that is
+// generated by Breakpad and consumed by the crash_sender.
+#define BREAKPAD_PRODUCT               "BreakpadProduct"
+#define BREAKPAD_PRODUCT_DISPLAY       "BreakpadProductDisplay"
+#define BREAKPAD_VERSION               "BreakpadVersion"
+#define BREAKPAD_VENDOR                "BreakpadVendor"
+#define BREAKPAD_URL                   "BreakpadURL"
+#define BREAKPAD_REPORT_INTERVAL       "BreakpadReportInterval"
+#define BREAKPAD_SKIP_CONFIRM          "BreakpadSkipConfirm"
+#define BREAKPAD_CONFIRM_TIMEOUT       "BreakpadConfirmTimeout"
+#define BREAKPAD_SEND_AND_EXIT         "BreakpadSendAndExit"
+#define BREAKPAD_DUMP_DIRECTORY        "BreakpadMinidumpLocation"
+#define BREAKPAD_INSPECTOR_LOCATION    "BreakpadInspectorLocation"
+#define BREAKPAD_REPORTER_EXE_LOCATION \
+  "BreakpadReporterExeLocation"
+#define BREAKPAD_LOGFILES              "BreakpadLogFiles"
+#define BREAKPAD_LOGFILE_UPLOAD_SIZE   "BreakpadLogFileTailSize"
+#define BREAKPAD_REQUEST_COMMENTS      "BreakpadRequestComments"
+#define BREAKPAD_COMMENTS              "BreakpadComments"
+#define BREAKPAD_REQUEST_EMAIL         "BreakpadRequestEmail"
+#define BREAKPAD_EMAIL                 "BreakpadEmail"
+#define BREAKPAD_SERVER_TYPE           "BreakpadServerType"
+#define BREAKPAD_SERVER_PARAMETER_DICT "BreakpadServerParameters"
+#define BREAKPAD_IN_PROCESS            "BreakpadInProcess"
+
+// The keys below are NOT user supplied, and are used internally.
+#define BREAKPAD_PROCESS_START_TIME       "BreakpadProcStartTime"
+#define BREAKPAD_PROCESS_UP_TIME          "BreakpadProcessUpTime"
+#define BREAKPAD_PROCESS_CRASH_TIME       "BreakpadProcessCrashTime"
+#define BREAKPAD_LOGFILE_KEY_PREFIX       "BreakpadAppLogFile"
+#define BREAKPAD_SERVER_PARAMETER_PREFIX  "BreakpadServerParameterPrefix_"
+#define BREAKPAD_ON_DEMAND                "BreakpadOnDemand"
diff --git a/include/breakpad/client/ios/Breakpad.h b/include/breakpad/client/ios/Breakpad.h
new file mode 100644
index 0000000..c099ad0
--- /dev/null
+++ b/include/breakpad/client/ios/Breakpad.h
@@ -0,0 +1,246 @@
+// 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.
+
+// Framework to provide a simple C API to crash reporting for
+// applications.  By default, if any machine-level exception (e.g.,
+// EXC_BAD_ACCESS) occurs, it will be handled by the BreakpadRef
+// object as follows:
+//
+// 1. Create a minidump file (see Breakpad for details)
+// 2. Create a config file.
+//
+// These files can then be uploaded to a server.
+
+typedef void *BreakpadRef;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <Foundation/Foundation.h>
+
+#include <client/apple/Framework/BreakpadDefines.h>
+
+// The keys in the dictionary returned by |BreakpadGenerateReport|.
+#define BREAKPAD_OUTPUT_DUMP_FILE   "BreakpadDumpFile"
+#define BREAKPAD_OUTPUT_CONFIG_FILE "BreakpadConfigFile"
+
+// Optional user-defined function to decide if we should handle this crash or
+// forward it along.
+// Return true if you want Breakpad to handle it.
+// Return false if you want Breakpad to skip it
+// The exception handler always returns false, as if SEND_AND_EXIT were false
+// (which means the next exception handler will take the exception)
+typedef bool (*BreakpadFilterCallback)(int exception_type,
+                                       int exception_code,
+                                       mach_port_t crashing_thread,
+                                       void *context);
+
+// Create a new BreakpadRef object and install it as an exception
+// handler.  The |parameters| will typically be the contents of your
+// bundle's Info.plist.
+//
+// You can also specify these additional keys for customizable behavior:
+// Key:                           Value:
+// BREAKPAD_PRODUCT               Product name (e.g., "MyAwesomeProduct")
+//                                This one is used as the key to identify
+//                                the product when uploading. Falls back to
+//                                CFBundleName if not specified.
+//                                REQUIRED
+//
+// BREAKPAD_PRODUCT_DISPLAY       This is the display name, e.g. a pretty
+//                                name for the product when the crash_sender
+//                                pops up UI for the user. Falls back first to
+//                                CFBundleDisplayName and then to
+//                                BREAKPAD_PRODUCT if not specified.
+//
+// BREAKPAD_VERSION               Product version (e.g., 1.2.3), used
+//                                as metadata for crash report. Falls back to
+//                                CFBundleVersion if not specified.
+//                                REQUIRED
+//
+// BREAKPAD_VENDOR                Vendor name, used in UI (e.g. "A report has
+//                                been created that you can send to <vendor>")
+//
+// BREAKPAD_URL                   URL destination for reporting
+//                                REQUIRED
+//
+// BREAKPAD_DUMP_DIRECTORY        The directory to store crash-dumps
+//                                in. By default, we use
+//                                ~/Library/Cache/Breakpad/<BREAKPAD_PRODUCT>
+//                                The path you specify here is tilde-expanded.
+//
+// BREAKPAD_SERVER_TYPE           A parameter that tells Breakpad how to
+//                                rewrite the upload parameters for a specific
+//                                server type.  The currently valid values are
+//                                'socorro' or 'google'.  If you want to add
+//                                other types, see the function in
+//                                crash_report_sender.m that maps parameters to
+//                                URL parameters.  Defaults to 'google'.
+//
+// BREAKPAD_SERVER_PARAMETER_DICT A plist dictionary of static
+//                                parameters that are uploaded to the
+//                                server.  The parameters are sent as
+//                                is to the crash server.  Their
+//                                content isn't added to the minidump
+//                                but pass as URL parameters when
+//                                uploading theminidump to the crash
+//                                server.
+//=============================================================================
+// The BREAKPAD_PRODUCT, BREAKPAD_VERSION and BREAKPAD_URL are
+// required to have non-NULL values.  By default, the BREAKPAD_PRODUCT
+// will be the CFBundleName and the BREAKPAD_VERSION will be the
+// CFBundleVersion when these keys are present in the bundle's
+// Info.plist, which is usually passed in to BreakpadCreate() as an
+// NSDictionary (you could also pass in another dictionary that had
+// the same keys configured).  If the BREAKPAD_PRODUCT or
+// BREAKPAD_VERSION are ultimately undefined, BreakpadCreate() will
+// fail.  You have been warned.
+//
+// If you are running in a debugger, Breakpad will not install, unless the
+// BREAKPAD_IGNORE_DEBUGGER envionment variable is set and/or non-zero.
+//
+//=============================================================================
+// The following are NOT user-supplied but are documented here for
+// completeness.  They are calculated by Breakpad during initialization &
+// crash-dump generation, or entered in by the user.
+//
+// BREAKPAD_PROCESS_START_TIME       The time, in seconds since the Epoch, the
+//                                   process started
+//
+// BREAKPAD_PROCESS_CRASH_TIME       The time, in seconds since the Epoch, the
+//                                   process crashed.
+//
+// BREAKPAD_PROCESS_UP_TIME          The total time in milliseconds the process
+//                                   has been running.  This parameter is not
+//                                   set until the crash-dump-generation phase.
+//
+// BREAKPAD_SERVER_PARAMETER_PREFIX  This prefix is used by Breakpad
+//                                   internally, because Breakpad uses
+//                                   the same dictionary internally to
+//                                   track both its internal
+//                                   configuration parameters and
+//                                   parameters meant to be uploaded
+//                                   to the server.  This string is
+//                                   used internally by Breakpad to
+//                                   prefix user-supplied parameter
+//                                   names so those can be sent to the
+//                                   server without leaking Breakpad's
+//                                   internal values.
+
+// Returns a new BreakpadRef object on success, NULL otherwise.
+BreakpadRef BreakpadCreate(NSDictionary *parameters);
+
+// Uninstall and release the data associated with |ref|.
+void BreakpadRelease(BreakpadRef ref);
+
+// User defined key and value string storage.  Generally this is used
+// to configure Breakpad's internal operation, such as whether the
+// crash_sender should prompt the user, or the filesystem location for
+// the minidump file.  See Breakpad.h for some parameters that can be
+// set.  Anything longer than 255 bytes will be truncated. Note that
+// the string is converted to UTF8 before truncation, so any multibyte
+// character that straddles the 255(256 - 1 for terminator) byte limit
+// will be mangled.
+//
+// A maximum number of 64 key/value pairs are supported.  An assert()
+// will fire if more than this number are set.  Unfortunately, right
+// now, the same dictionary is used for both Breakpad's parameters AND
+// the Upload parameters.
+//
+// TODO (nealsid): Investigate how necessary this is if we don't
+// automatically upload parameters to the server anymore.
+// TODO (nealsid): separate server parameter dictionary from the
+// dictionary used to configure Breakpad, and document limits for each
+// independently.
+void BreakpadSetKeyValue(BreakpadRef ref, NSString *key, NSString *value);
+NSString *BreakpadKeyValue(BreakpadRef ref, NSString *key);
+void BreakpadRemoveKeyValue(BreakpadRef ref, NSString *key);
+
+// You can use this method to specify parameters that will be uploaded
+// to the crash server.  They will be automatically encoded as
+// necessary.  Note that as mentioned above there are limits on both
+// the number of keys and their length.
+void BreakpadAddUploadParameter(BreakpadRef ref, NSString *key,
+                                NSString *value);
+
+// This method will remove a previously-added parameter from the
+// upload parameter set.
+void BreakpadRemoveUploadParameter(BreakpadRef ref, NSString *key);
+
+// Method to handle uploading data to the server
+
+// Returns the number of crash reports waiting to send to the server.
+int BreakpadGetCrashReportCount(BreakpadRef ref);
+
+// Returns the next upload configuration. The report file is deleted.
+NSDictionary *BreakpadGetNextReportConfiguration(BreakpadRef ref);
+
+// Upload next report to the server.
+void BreakpadUploadNextReport(BreakpadRef ref);
+
+// Upload next report to the server.
+// |server_parameters| is additional server parameters to send.
+void BreakpadUploadNextReportWithParameters(BreakpadRef ref,
+                                            NSDictionary *server_parameters);
+
+// Upload a report to the server.
+// |server_parameters| is additional server parameters to send.
+// |configuration| is the configuration of the breakpad report to send.
+void BreakpadUploadReportWithParametersAndConfiguration(
+    BreakpadRef ref,
+    NSDictionary *server_parameters,
+    NSDictionary *configuration);
+
+// Handles the network response of a breakpad upload. This function is needed if
+// the actual upload is done by the Breakpad client.
+// |configuration| is the configuration of the upload. It must contain the same
+// fields as the configuration passed to
+// BreakpadUploadReportWithParametersAndConfiguration.
+// |data| and |error| contain the network response.
+void BreakpadHandleNetworkResponse(BreakpadRef ref,
+                                   NSDictionary *configuration,
+                                   NSData *data,
+                                   NSError *error);
+
+// Upload a file to the server. |data| is the content of the file to sent.
+// |server_parameters| is additional server parameters to send.
+void BreakpadUploadData(BreakpadRef ref, NSData *data, NSString *name,
+                        NSDictionary *server_parameters);
+
+// Generate a breakpad minidump and configuration file in the dump directory.
+// The report will be available for uploading. The paths of the created files
+// are returned in the dictionary. |server_parameters| is additional server
+// parameters to add in the config file.
+NSDictionary *BreakpadGenerateReport(BreakpadRef ref,
+                                     NSDictionary *server_parameters);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/include/breakpad/client/ios/BreakpadController.h b/include/breakpad/client/ios/BreakpadController.h
new file mode 100644
index 0000000..13609cb
--- /dev/null
+++ b/include/breakpad/client/ios/BreakpadController.h
@@ -0,0 +1,141 @@
+// 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 CLIENT_IOS_HANDLER_IOS_BREAKPAD_CONTROLLER_H_
+#define CLIENT_IOS_HANDLER_IOS_BREAKPAD_CONTROLLER_H_
+
+#import <Foundation/Foundation.h>
+
+#import "client/ios/Breakpad.h"
+
+// This class is used to offer a higher level API around BreakpadRef. It
+// configures it, ensures thread-safety, and sends crash reports back to the
+// collecting server. By default, no crash reports are sent, the user must call
+// |setUploadingEnabled:YES| to start the uploading.
+@interface BreakpadController : NSObject {
+ @private
+  // The dispatch queue that will own the breakpad reference.
+  dispatch_queue_t queue_;
+
+  // Instance of Breakpad crash reporter. This is owned by the queue, but can
+  // be created on the main thread at startup.
+  BreakpadRef breakpadRef_;
+
+  // The dictionary that contains configuration for breakpad. Modifying it
+  // should only happen when the controller is not started. The initial value
+  // is the infoDictionary of the bundle of the application.
+  NSMutableDictionary* configuration_;
+
+  // Whether or not crash reports should be uploaded.
+  BOOL enableUploads_;
+
+  // Whether the controller has been started on the main thread. This is only
+  // used to assert the initialization order is correct.
+  BOOL started_;
+
+  // The interval to wait between two uploads. Value is 0 if no upload must be
+  // done.
+  int uploadIntervalInSeconds_;
+
+  // The dictionary that contains additional server parameters to send when
+  // uploading crash reports.
+  NSDictionary* uploadTimeParameters_;
+}
+
+// Singleton.
++ (BreakpadController*)sharedInstance;
+
+// Update the controller configuration. Merges its old configuration with the
+// new one. Merge is done by replacing the old values by the new values.
+- (void)updateConfiguration:(NSDictionary*)configuration;
+
+// Reset the controller configuration to its initial value, which is the
+// infoDictionary of the bundle of the application.
+- (void)resetConfiguration;
+
+// Configure the URL to upload the report to. This must be called at least once
+// if the URL is not in the bundle information.
+- (void)setUploadingURL:(NSString*)url;
+
+// Set the minimal interval between two uploads in seconds. This must be called
+// at least once if the interval is not in the bundle information. A value of 0
+// will prevent uploads.
+- (void)setUploadInterval:(int)intervalInSeconds;
+
+// Set additional server parameters to send when uploading crash reports.
+- (void)setParametersToAddAtUploadTime:(NSDictionary*)uploadTimeParameters;
+
+// Specify an upload parameter that will be added to the crash report when a
+// crash report is generated. See |BreakpadAddUploadParameter|.
+- (void)addUploadParameter:(NSString*)value forKey:(NSString*)key;
+
+// Remove a previously-added parameter from the upload parameter set. See
+// |BreakpadRemoveUploadParameter|.
+- (void)removeUploadParameterForKey:(NSString*)key;
+
+// Access the underlying BreakpadRef. This method is asynchronous, and will be
+// executed on the thread owning the BreakpadRef variable. Moreover, if the
+// controller is not started, the block will be called with a NULL parameter.
+- (void)withBreakpadRef:(void(^)(BreakpadRef))callback;
+
+// Starts the BreakpadController by registering crash handlers. If
+// |onCurrentThread| is YES, all setup is done on the current thread, otherwise
+// it is done on a private queue.
+- (void)start:(BOOL)onCurrentThread;
+
+// Unregisters the crash handlers.
+- (void)stop;
+
+// Enables or disables uploading of crash reports, but does not stop the
+// BreakpadController.
+- (void)setUploadingEnabled:(BOOL)enabled;
+
+// Check if there is currently a crash report to upload.
+- (void)hasReportToUpload:(void(^)(BOOL))callback;
+
+// Get the number of crash reports waiting to upload.
+- (void)getCrashReportCount:(void(^)(int))callback;
+
+// Get the next report to upload.
+// - If upload is disabled, callback will be called with (nil, -1).
+// - If a delay is to be waited before sending, callback will be called with
+//   (nil, n), with n (> 0) being the number of seconds to wait.
+// - if no delay is needed, callback will be called with (0, configuration),
+//   configuration being next report to upload, or nil if none is pending.
+- (void)getNextReportConfigurationOrSendDelay:
+    (void(^)(NSDictionary*, int))callback;
+
+// Sends synchronously the report specified by |configuration|. This method is
+// NOT thread safe and must be called from the breakpad thread.
+- (void)threadUnsafeSendReportWithConfiguration:(NSDictionary*)configuration
+                                withBreakpadRef:(BreakpadRef)ref;
+
+@end
+
+#endif  // CLIENT_IOS_HANDLER_IOS_BREAKPAD_CONTROLLER_H_
diff --git a/include/breakpad/client/ios/handler/ios_exception_minidump_generator.h b/include/breakpad/client/ios/handler/ios_exception_minidump_generator.h
new file mode 100644
index 0000000..21133e6
--- /dev/null
+++ b/include/breakpad/client/ios/handler/ios_exception_minidump_generator.h
@@ -0,0 +1,74 @@
+// 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.
+
+// ios_exception_minidump_generator.h:  Create a fake minidump from a
+// NSException.
+
+#ifndef CLIENT_IOS_HANDLER_IOS_EXCEPTION_MINIDUMP_GENERATOR_H_
+#define CLIENT_IOS_HANDLER_IOS_EXCEPTION_MINIDUMP_GENERATOR_H_
+
+#include <Foundation/Foundation.h>
+
+#include "client/mac/handler/minidump_generator.h"
+
+namespace google_breakpad {
+
+class IosExceptionMinidumpGenerator : public MinidumpGenerator {
+ public:
+  explicit IosExceptionMinidumpGenerator(NSException *exception);
+  virtual ~IosExceptionMinidumpGenerator();
+
+ protected:
+  virtual bool WriteExceptionStream(MDRawDirectory *exception_stream);
+  virtual bool WriteThreadStream(mach_port_t thread_id, MDRawThread *thread);
+
+ private:
+
+  // Get the crashing program counter from the exception.
+  uintptr_t GetPCFromException();
+
+  // Get the crashing link register from the exception.
+  uintptr_t GetLRFromException();
+
+  // Write a virtual thread context for the crashing site.
+  bool WriteCrashingContext(MDLocationDescriptor *register_location);
+  // Per-CPU implementations of the above method.
+#ifdef HAS_ARM_SUPPORT
+  bool WriteCrashingContextARM(MDLocationDescriptor *register_location);
+#endif
+#ifdef HAS_ARM64_SUPPORT
+  bool WriteCrashingContextARM64(MDLocationDescriptor *register_location);
+#endif
+
+  NSArray *return_addresses_;
+};
+
+}  // namespace google_breakpad
+
+#endif  // CLIENT_IOS_HANDLER_IOS_EXCEPTION_MINIDUMP_GENERATOR_H_
diff --git a/include/breakpad/client/linux/dump_writer_common/mapping_info.h b/include/breakpad/client/linux/dump_writer_common/mapping_info.h
new file mode 100644
index 0000000..5f247cf
--- /dev/null
+++ b/include/breakpad/client/linux/dump_writer_common/mapping_info.h
@@ -0,0 +1,61 @@
+// Copyright (c) 2014, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef CLIENT_LINUX_DUMP_WRITER_COMMON_MAPPING_INFO_H_
+#define CLIENT_LINUX_DUMP_WRITER_COMMON_MAPPING_INFO_H_
+
+#include <limits.h>
+#include <list>
+#include <stdint.h>
+
+#include "google_breakpad/common/minidump_format.h"
+
+namespace google_breakpad {
+
+// One of these is produced for each mapping in the process (i.e. line in
+// /proc/$x/maps).
+struct MappingInfo {
+  uintptr_t start_addr;
+  size_t size;
+  size_t offset;  // offset into the backed file.
+  bool exec;  // true if the mapping has the execute bit set.
+  char name[NAME_MAX];
+};
+
+struct MappingEntry {
+  MappingInfo first;
+  uint8_t second[sizeof(MDGUID)];
+};
+
+// A list of <MappingInfo, GUID>
+typedef std::list<MappingEntry> MappingList;
+
+}  // namespace google_breakpad
+
+#endif  // CLIENT_LINUX_DUMP_WRITER_COMMON_MAPPING_INFO_H_
diff --git a/include/breakpad/client/linux/dump_writer_common/raw_context_cpu.h b/include/breakpad/client/linux/dump_writer_common/raw_context_cpu.h
new file mode 100644
index 0000000..e2ef45d
--- /dev/null
+++ b/include/breakpad/client/linux/dump_writer_common/raw_context_cpu.h
@@ -0,0 +1,53 @@
+// Copyright (c) 2014, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef CLIENT_LINUX_DUMP_WRITER_COMMON_RAW_CONTEXT_CPU_H
+#define CLIENT_LINUX_DUMP_WRITER_COMMON_RAW_CONTEXT_CPU_H
+
+#include "google_breakpad/common/minidump_format.h"
+
+namespace google_breakpad {
+
+#if defined(__i386__)
+typedef MDRawContextX86 RawContextCPU;
+#elif defined(__x86_64)
+typedef MDRawContextAMD64 RawContextCPU;
+#elif defined(__ARM_EABI__)
+typedef MDRawContextARM RawContextCPU;
+#elif defined(__aarch64__)
+typedef MDRawContextARM64 RawContextCPU;
+#elif defined(__mips__)
+typedef MDRawContextMIPS RawContextCPU;
+#else
+#error "This code has not been ported to your platform yet."
+#endif
+
+}  // namespace google_breakpad
+
+#endif  // CLIENT_LINUX_DUMP_WRITER_COMMON_RAW_CONTEXT_CPU_H
diff --git a/include/breakpad/client/linux/dump_writer_common/thread_info.h b/include/breakpad/client/linux/dump_writer_common/thread_info.h
new file mode 100644
index 0000000..99093d2
--- /dev/null
+++ b/include/breakpad/client/linux/dump_writer_common/thread_info.h
@@ -0,0 +1,91 @@
+// Copyright (c) 2014, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef CLIENT_LINUX_DUMP_WRITER_COMMON_THREAD_INFO_H_
+#define CLIENT_LINUX_DUMP_WRITER_COMMON_THREAD_INFO_H_
+
+#include <sys/ucontext.h>
+#include <sys/user.h>
+
+#include "client/linux/dump_writer_common/raw_context_cpu.h"
+#include "common/memory.h"
+#include "google_breakpad/common/minidump_format.h"
+
+namespace google_breakpad {
+
+#if defined(__i386) || defined(__x86_64)
+typedef __typeof__(((struct user*) 0)->u_debugreg[0]) debugreg_t;
+#endif
+
+// We produce one of these structures for each thread in the crashed process.
+struct ThreadInfo {
+  pid_t tgid;   // thread group id
+  pid_t ppid;   // parent process
+
+  uintptr_t stack_pointer;  // thread stack pointer
+
+
+#if defined(__i386) || defined(__x86_64)
+  user_regs_struct regs;
+  user_fpregs_struct fpregs;
+  static const unsigned kNumDebugRegisters = 8;
+  debugreg_t dregs[8];
+#if defined(__i386)
+  user_fpxregs_struct fpxregs;
+#endif  // defined(__i386)
+
+#elif defined(__ARM_EABI__)
+  // Mimicking how strace does this(see syscall.c, search for GETREGS)
+  struct user_regs regs;
+  struct user_fpregs fpregs;
+#elif defined(__aarch64__)
+  // Use the structures defined in <sys/user.h>
+  struct user_regs_struct regs;
+  struct user_fpsimd_struct fpregs;
+#elif defined(__mips__)
+  // Use the structure defined in <sys/ucontext.h>.
+  mcontext_t mcontext;
+#endif
+
+  // Returns the instruction pointer (platform-dependent impl.).
+  uintptr_t GetInstructionPointer() const;
+
+  // Fills a RawContextCPU using the context in the ThreadInfo object.
+  void FillCPUContext(RawContextCPU* out) const;
+
+  // Returns the pointer and size of general purpose register area.
+  void GetGeneralPurposeRegisters(void** gp_regs, size_t* size);
+
+  // Returns the pointer and size of float point register area.
+  void GetFloatingPointRegisters(void** fp_regs, size_t* size);
+};
+
+}  // namespace google_breakpad
+
+#endif  // CLIENT_LINUX_DUMP_WRITER_COMMON_THREAD_INFO_H_
diff --git a/include/breakpad/client/linux/dump_writer_common/ucontext_reader.h b/include/breakpad/client/linux/dump_writer_common/ucontext_reader.h
new file mode 100644
index 0000000..b6e77b4
--- /dev/null
+++ b/include/breakpad/client/linux/dump_writer_common/ucontext_reader.h
@@ -0,0 +1,64 @@
+// Copyright (c) 2014, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef CLIENT_LINUX_DUMP_WRITER_COMMON_UCONTEXT_READER_H
+#define CLIENT_LINUX_DUMP_WRITER_COMMON_UCONTEXT_READER_H
+
+#include <sys/ucontext.h>
+#include <sys/user.h>
+
+#include "client/linux/dump_writer_common/raw_context_cpu.h"
+#include "common/memory.h"
+#include "google_breakpad/common/minidump_format.h"
+
+namespace google_breakpad {
+
+// Wraps platform-dependent implementations of accessors to ucontext structs.
+struct UContextReader {
+  static uintptr_t GetStackPointer(const struct ucontext* uc);
+
+  static uintptr_t GetInstructionPointer(const struct ucontext* uc);
+
+  // Juggle a arch-specific ucontext into a minidump format
+  //   out: the minidump structure
+  //   info: the collection of register structures.
+#if defined(__i386__) || defined(__x86_64)
+  static void FillCPUContext(RawContextCPU *out, const ucontext *uc,
+                             const struct _libc_fpstate* fp);
+#elif defined(__aarch64__)
+  static void FillCPUContext(RawContextCPU *out, const ucontext *uc,
+                             const struct fpsimd_context* fpregs);
+#else
+  static void FillCPUContext(RawContextCPU *out, const ucontext *uc);
+#endif
+};
+
+}  // namespace google_breakpad
+
+#endif  // CLIENT_LINUX_DUMP_WRITER_COMMON_UCONTEXT_READER_H
diff --git a/include/breakpad/client/linux/log/log.h b/include/breakpad/client/linux/log/log.h
new file mode 100644
index 0000000..f94bbd5
--- /dev/null
+++ b/include/breakpad/client/linux/log/log.h
@@ -0,0 +1,55 @@
+// 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 CLIENT_LINUX_LOG_LOG_H_
+#define CLIENT_LINUX_LOG_LOG_H_
+
+#include <stddef.h>
+
+namespace logger {
+
+int write(const char* buf, size_t nbytes);
+
+// In the case of Android the log can be written to the default system log
+// (default behavior of write() above, or to the crash log (see
+// writeToCrashLog() below).
+#if defined(__ANDROID__)
+
+// The logger must be initialized in a non-compromised context.
+void initializeCrashLogWriter();
+
+// Once initialized, writeToCrashLog is safe to use in a compromised context,
+// even if the initialization failed, in which case this will silently fall
+// back on write().
+int writeToCrashLog(const char* buf);
+#endif
+
+}  // namespace logger
+
+#endif  // CLIENT_LINUX_LOG_LOG_H_
diff --git a/include/breakpad/client/linux/microdump_writer/microdump_writer.h b/include/breakpad/client/linux/microdump_writer/microdump_writer.h
new file mode 100644
index 0000000..e218558
--- /dev/null
+++ b/include/breakpad/client/linux/microdump_writer/microdump_writer.h
@@ -0,0 +1,64 @@
+// Copyright (c) 2014, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef CLIENT_LINUX_MINIDUMP_WRITER_MICRODUMP_WRITER_H_
+#define CLIENT_LINUX_MINIDUMP_WRITER_MICRODUMP_WRITER_H_
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include "client/linux/dump_writer_common/mapping_info.h"
+
+namespace google_breakpad {
+
+// Writes a microdump (a reduced dump containing only the state of the crashing
+// thread) on the console (logcat on Android). These functions do not malloc nor
+// use libc functions which may. Thus, it can be used in contexts where the
+// state of the heap may be corrupt.
+// Args:
+//   crashing_process: the pid of the crashing process. This must be trusted.
+//   blob: a blob of data from the crashing process. See exception_handler.h
+//   blob_size: the length of |blob| in bytes.
+//   mappings: a list of additional mappings provided by the application.
+//   build_fingerprint: a (optional) C string which determines the OS
+//     build fingerprint (e.g., aosp/occam/mako:5.1.1/LMY47W/1234:eng/dev-keys).
+//   product_info: a (optional) C string which determines the product name and
+//     version (e.g., WebView:42.0.2311.136).
+//
+// Returns true iff successful.
+bool WriteMicrodump(pid_t crashing_process,
+                    const void* blob,
+                    size_t blob_size,
+                    const MappingList& mappings,
+                    const char* build_fingerprint,
+                    const char* product_info);
+
+}  // namespace google_breakpad
+
+#endif  // CLIENT_LINUX_MINIDUMP_WRITER_MICRODUMP_WRITER_H_
diff --git a/include/breakpad/client/mac/Framework/Breakpad.h b/include/breakpad/client/mac/Framework/Breakpad.h
new file mode 100644
index 0000000..dc7e45d
--- /dev/null
+++ b/include/breakpad/client/mac/Framework/Breakpad.h
@@ -0,0 +1,285 @@
+// 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.
+//
+// Framework to provide a simple C API to crash reporting for
+// applications.  By default, if any machine-level exception (e.g.,
+// EXC_BAD_ACCESS) occurs, it will be handled by the BreakpadRef
+// object as follows:
+//
+// 1. Create a minidump file (see Breakpad for details)
+// 2. Prompt the user (using CFUserNotification)
+// 3. Invoke a command line reporting tool to send the minidump to a
+//    server
+//
+// By specifying parameters to the BreakpadCreate function, you can
+// modify the default behavior to suit your needs and wants and
+// desires.
+
+// A service name associated with the original bootstrap parent port, saved in
+// OnDemandServer and restored in Inspector.
+#define BREAKPAD_BOOTSTRAP_PARENT_PORT    "com.Breakpad.BootstrapParent"
+
+typedef void *BreakpadRef;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <CoreFoundation/CoreFoundation.h>
+#include <Foundation/Foundation.h>
+
+#include "BreakpadDefines.h"
+
+// Optional user-defined function to dec to decide if we should handle
+// this crash or forward it along.
+// Return true if you want Breakpad to handle it.
+// Return false if you want Breakpad to skip it
+// The exception handler always returns false, as if SEND_AND_EXIT were false
+// (which means the next exception handler will take the exception)
+typedef bool (*BreakpadFilterCallback)(int exception_type,
+                                       int exception_code,
+                                       mach_port_t crashing_thread,
+                                       void *context);
+
+// Create a new BreakpadRef object and install it as an exception
+// handler.  The |parameters| will typically be the contents of your
+// bundle's Info.plist.
+//
+// You can also specify these additional keys for customizable behavior:
+// Key:                           Value:
+// BREAKPAD_PRODUCT               Product name (e.g., "MyAwesomeProduct")
+//                                This one is used as the key to identify
+//                                the product when uploading. Falls back to
+//                                CFBundleName if not specified.
+//                                REQUIRED
+//
+// BREAKPAD_PRODUCT_DISPLAY       This is the display name, e.g. a pretty
+//                                name for the product when the crash_sender
+//                                pops up UI for the user. Falls back first to
+//                                CFBundleDisplayName and then to
+//                                BREAKPAD_PRODUCT if not specified.
+//
+// BREAKPAD_VERSION               Product version (e.g., 1.2.3), used
+//                                as metadata for crash report. Falls back to
+//                                CFBundleVersion if not specified.
+//                                REQUIRED
+//
+// BREAKPAD_VENDOR                Vendor name, used in UI (e.g. "A report has
+//                                been created that you can send to <vendor>")
+//
+// BREAKPAD_URL                   URL destination for reporting
+//                                REQUIRED
+//
+// BREAKPAD_REPORT_INTERVAL       # of seconds between sending
+//                                reports.  If an additional report is
+//                                generated within this time, it will
+//                                be ignored.  Default: 3600sec.
+//                                Specify 0 to send all reports.
+//
+// BREAKPAD_SKIP_CONFIRM          If true, the reporter will send the report
+//                                without any user intervention.
+//                                Defaults to NO
+//
+// BREAKPAD_CONFIRM_TIMEOUT       Number of seconds before the upload
+//                                confirmation dialog will be automatically
+//                                dismissed (cancelling the upload).
+//                                Default: 300 seconds (min of 60).
+//                                Specify 0 to prevent timeout.
+//
+// BREAKPAD_SEND_AND_EXIT         If true, the handler will exit after sending.
+//                                This will prevent any other handler (e.g.,
+//                                CrashReporter) from getting the crash.
+//                                Defaults TO YES
+//
+// BREAKPAD_DUMP_DIRECTORY        The directory to store crash-dumps
+//                                in. By default, we use
+//                                ~/Library/Breakpad/<BREAKPAD_PRODUCT>
+//                                The path you specify here is tilde-expanded.
+//
+// BREAKPAD_INSPECTOR_LOCATION    The full path to the Inspector executable.
+//                                Defaults to <Framework resources>/Inspector
+//
+// BREAKPAD_REPORTER_EXE_LOCATION The full path to the Reporter/sender
+//                                executable.
+//                                Default:
+//                                <Framework Resources>/crash_report_sender.app
+//
+// BREAKPAD_LOGFILES              Indicates an array of log file paths that
+//                                should be uploaded at crash time.
+//
+// BREAKPAD_REQUEST_COMMENTS      If true, the message dialog will have a
+//                                text box for the user to enter comments.
+//                                Default: NO
+//
+// BREAKPAD_REQUEST_EMAIL         If true and BREAKPAD_REQUEST_COMMENTS is also
+//                                true, the message dialog will have a text
+//                                box for the user to enter their email address.
+//                                Default: NO
+//
+// BREAKPAD_SERVER_TYPE           A parameter that tells Breakpad how to
+//                                rewrite the upload parameters for a specific
+//                                server type.  The currently valid values are
+//                                'socorro' or 'google'.  If you want to add
+//                                other types, see the function in
+//                                crash_report_sender.m that maps parameters to
+//                                URL parameters.  Defaults to 'google'.
+//
+// BREAKPAD_SERVER_PARAMETER_DICT A plist dictionary of static
+//                                parameters that are uploaded to the
+//                                server.  The parameters are sent as
+//                                is to the crash server.  Their
+//                                content isn't added to the minidump
+//                                but pass as URL parameters when
+//                                uploading theminidump to the crash
+//                                server.
+//
+// BREAKPAD_IN_PROCESS            A boolean NSNumber value. If YES, Breakpad
+//                                will write the dump file in-process and then
+//                                launch the reporter executable as a child
+//                                process.
+//=============================================================================
+// The BREAKPAD_PRODUCT, BREAKPAD_VERSION and BREAKPAD_URL are
+// required to have non-NULL values.  By default, the BREAKPAD_PRODUCT
+// will be the CFBundleName and the BREAKPAD_VERSION will be the
+// CFBundleVersion when these keys are present in the bundle's
+// Info.plist, which is usually passed in to BreakpadCreate() as an
+// NSDictionary (you could also pass in another dictionary that had
+// the same keys configured).  If the BREAKPAD_PRODUCT or
+// BREAKPAD_VERSION are ultimately undefined, BreakpadCreate() will
+// fail.  You have been warned.
+//
+// If you are running in a debugger, Breakpad will not install, unless the
+// BREAKPAD_IGNORE_DEBUGGER envionment variable is set and/or non-zero.
+//
+// The BREAKPAD_SKIP_CONFIRM and BREAKPAD_SEND_AND_EXIT default
+// values are NO and YES.  However, they can be controlled by setting their
+// values in a user or global plist.
+//
+// It's easiest to use Breakpad via the Framework, but if you're compiling the
+// code in directly, BREAKPAD_INSPECTOR_LOCATION and
+// BREAKPAD_REPORTER_EXE_LOCATION allow you to specify custom paths
+// to the helper executables.
+//
+//=============================================================================
+// The following are NOT user-supplied but are documented here for
+// completeness.  They are calculated by Breakpad during initialization &
+// crash-dump generation, or entered in by the user.
+//
+// BREAKPAD_PROCESS_START_TIME       The time, in seconds since the Epoch, the
+//                                   process started
+//
+// BREAKPAD_PROCESS_CRASH_TIME       The time, in seconds since the Epoch, the
+//                                   process crashed.
+//
+// BREAKPAD_PROCESS_UP_TIME          The total time in milliseconds the process
+//                                   has been running.  This parameter is not
+//                                   set until the crash-dump-generation phase.
+//
+// BREAKPAD_LOGFILE_KEY_PREFIX       Used to find out which parameters in the
+//                                   parameter dictionary correspond to log
+//                                   file paths.
+//
+// BREAKPAD_SERVER_PARAMETER_PREFIX  This prefix is used by Breakpad
+//                                   internally, because Breakpad uses
+//                                   the same dictionary internally to
+//                                   track both its internal
+//                                   configuration parameters and
+//                                   parameters meant to be uploaded
+//                                   to the server.  This string is
+//                                   used internally by Breakpad to
+//                                   prefix user-supplied parameter
+//                                   names so those can be sent to the
+//                                   server without leaking Breakpad's
+//                                   internal values.
+//
+// BREAKPAD_ON_DEMAND                Used internally to indicate to the
+//                                   Reporter that we're sending on-demand,
+//                                   not as result of a crash.
+//
+// BREAKPAD_COMMENTS                 The text the user provided as comments.
+//                                   Only used in crash_report_sender.
+
+// Returns a new BreakpadRef object on success, NULL otherwise.
+BreakpadRef BreakpadCreate(NSDictionary *parameters);
+
+// Uninstall and release the data associated with |ref|.
+void BreakpadRelease(BreakpadRef ref);
+
+// Clients may set an optional callback which gets called when a crash
+// occurs.  The callback function should return |true| if we should
+// handle the crash, generate a crash report, etc. or |false| if we
+// should ignore it and forward the crash (normally to CrashReporter).
+// Context is a pointer to arbitrary data to make the callback with.
+void BreakpadSetFilterCallback(BreakpadRef ref,
+                               BreakpadFilterCallback callback,
+                               void *context);
+
+// User defined key and value string storage.  Generally this is used
+// to configure Breakpad's internal operation, such as whether the
+// crash_sender should prompt the user, or the filesystem location for
+// the minidump file.  See Breakpad.h for some parameters that can be
+// set.  Anything longer than 255 bytes will be truncated. Note that
+// the string is converted to UTF8 before truncation, so any multibyte
+// character that straddles the 255(256 - 1 for terminator) byte limit
+// will be mangled.
+//
+// A maximum number of 64 key/value pairs are supported.  An assert()
+// will fire if more than this number are set.  Unfortunately, right
+// now, the same dictionary is used for both Breakpad's parameters AND
+// the Upload parameters.
+//
+// TODO (nealsid): Investigate how necessary this is if we don't
+// automatically upload parameters to the server anymore.
+// TODO (nealsid): separate server parameter dictionary from the
+// dictionary used to configure Breakpad, and document limits for each
+// independently.
+void BreakpadSetKeyValue(BreakpadRef ref, NSString *key, NSString *value);
+NSString *BreakpadKeyValue(BreakpadRef ref, NSString *key);
+void BreakpadRemoveKeyValue(BreakpadRef ref, NSString *key);
+
+// You can use this method to specify parameters that will be uploaded
+// to the crash server.  They will be automatically encoded as
+// necessary.  Note that as mentioned above there are limits on both
+// the number of keys and their length.
+void BreakpadAddUploadParameter(BreakpadRef ref, NSString *key,
+                                NSString *value);
+
+// This method will remove a previously-added parameter from the
+// upload parameter set.
+void BreakpadRemoveUploadParameter(BreakpadRef ref, NSString *key);
+
+// Add a log file for Breakpad to read and send upon crash dump
+void BreakpadAddLogFile(BreakpadRef ref, NSString *logPathname);
+
+// Generate a minidump and send
+void BreakpadGenerateAndSendReport(BreakpadRef ref);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/include/breakpad/client/mac/Framework/OnDemandServer.h b/include/breakpad/client/mac/Framework/OnDemandServer.h
new file mode 100644
index 0000000..b8aabbe
--- /dev/null
+++ b/include/breakpad/client/mac/Framework/OnDemandServer.h
@@ -0,0 +1,145 @@
+// 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 <mach/mach.h>
+#include <servers/bootstrap.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+//==============================================================================
+// class OnDemandServer :
+//    A basic on-demand server launcher supporting a single named service port
+//
+// Example Usage :
+//
+//  kern_return_t result;
+//  OnDemandServer *server = OnDemandServer::Create("/tmp/myserver",
+//                                                  "com.MyCompany.MyServiceName",
+//                                                  true,
+//                                                  &result);
+//
+//  if (server) {
+//    server->LaunchOnDemand();
+//    mach_port_t service_port = GetServicePort();
+//
+//    // Send a mach message to service_port and "myserver" will be launched
+//  }
+//
+//
+//                  ---- Now in the server code ----
+//
+//  // "myserver" should get the service port and read the message which
+//  // launched it:
+//  mach_port_t service_rcv_port_;
+//  kern_return_t kr = bootstrap_check_in(bootstrap_port,
+//                                      "com.MyCompany.MyServiceName",
+//                                      &service_rcv_port_);
+//  // mach_msg() read service_rcv_port_ ....
+//
+//  ....
+//
+//  // Later "myserver" may want to unregister the service if it doesn't
+//  // want its bootstrap service to stick around after it exits.
+//
+//  // DO NOT use mach_port_deallocate() here -- it will fail and the
+//  // following bootstrap_register() will also fail leaving our service
+//  // name hanging around forever (until reboot)
+//  kern_return_t kr = mach_port_destroy(mach_task_self(), service_rcv_port_);
+//
+//  kr = bootstrap_register(bootstrap_port,
+//                          "com.MyCompany.MyServiceName",
+//                          MACH_PORT_NULL);
+
+class OnDemandServer {
+ public:
+  // must call Initialize() to be useful
+  OnDemandServer()
+    : server_port_(MACH_PORT_NULL),
+      service_port_(MACH_PORT_NULL),
+      unregister_on_cleanup_(true) {
+  }
+
+  // Creates the bootstrap server and service
+  kern_return_t Initialize(const char *server_command,
+                           const char *service_name,
+                           bool unregister_on_cleanup);
+
+  // Returns an OnDemandServer object if successful, or NULL if there's
+  // an error.  The error result will be returned in out_result.
+  //
+  //    server_command : the full path name including optional command-line
+  //      arguments to the executable representing the server
+  //
+  //    service_name : represents service name
+  //      something like "com.company.ServiceName"
+  //
+  //    unregister_on_cleanup : if true, unregisters the service name
+  //      when the OnDemandServer is deleted -- unregistering will
+  //      ONLY be possible if LaunchOnDemand() has NOT been called.
+  //      If false, then the service will continue to be registered
+  //      even after the current process quits.
+  //
+  //    out_result : if non-NULL, returns the result
+  //      this value will be KERN_SUCCESS if Create() returns non-NULL
+  //
+  static OnDemandServer *Create(const char *server_command,
+                                const char *service_name,
+                                bool unregister_on_cleanup,
+                                kern_return_t *out_result);
+
+  // Cleans up and if LaunchOnDemand() has not yet been called then
+  // the bootstrap service will be unregistered.
+  ~OnDemandServer();
+
+  // This must be called if we intend to commit to launching the server
+  // by sending a mach message to our service port.  Do not call it otherwise
+  // or it will be difficult (impossible?) to unregister the service name.
+  void LaunchOnDemand();
+
+  // This is the port we need to send a mach message to after calling
+  // LaunchOnDemand().  Sending a message causing an immediate launch
+  // of the server
+  mach_port_t GetServicePort() { return service_port_; };
+
+ private:
+  // Disallow copy constructor
+  OnDemandServer(const OnDemandServer&);
+
+  // Cleans up and if LaunchOnDemand() has not yet been called then
+  // the bootstrap service will be unregistered.
+  void Unregister();
+
+  name_t      service_name_;
+
+  mach_port_t server_port_;
+  mach_port_t service_port_;
+  bool        unregister_on_cleanup_;
+};
diff --git a/include/breakpad/client/mac/crash_generation/ConfigFile.h b/include/breakpad/client/mac/crash_generation/ConfigFile.h
new file mode 100644
index 0000000..5662e8b
--- /dev/null
+++ b/include/breakpad/client/mac/crash_generation/ConfigFile.h
@@ -0,0 +1,83 @@
+// 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.
+//
+// Utility class that can persist a SimpleStringDictionary to disk.
+
+#import <Foundation/Foundation.h>
+
+#include "common/simple_string_dictionary.h"
+
+namespace google_breakpad {
+
+BOOL EnsureDirectoryPathExists(NSString *dirPath);
+
+//=============================================================================
+class ConfigFile {
+ public:
+  ConfigFile() {
+    config_file_ = -1;
+    config_file_path_[0] = 0;
+    has_created_file_ = false;
+  };
+
+  ~ConfigFile() {
+  };
+
+  void WriteFile(const char* directory,
+                 const SimpleStringDictionary *configurationParameters,
+                 const char *dump_dir,
+                 const char *minidump_id);
+
+  const char *GetFilePath() { return config_file_path_; }
+
+  void Unlink() {
+    if (config_file_ != -1)
+      unlink(config_file_path_);
+
+    config_file_ = -1;
+  }
+
+ private:
+  BOOL WriteData(const void *data, size_t length);
+
+  BOOL AppendConfigData(const char *key,
+                        const void *data,
+                        size_t length);
+
+  BOOL AppendConfigString(const char *key,
+                          const char *value);
+
+  BOOL AppendCrashTimeParameters(const char *processStartTimeString);
+
+  int   config_file_;                    // descriptor for config file
+  char  config_file_path_[PATH_MAX];     // Path to configuration file
+  bool  has_created_file_;
+};
+
+} // namespace google_breakpad
diff --git a/include/breakpad/client/mac/crash_generation/Inspector.h b/include/breakpad/client/mac/crash_generation/Inspector.h
new file mode 100644
index 0000000..6712355
--- /dev/null
+++ b/include/breakpad/client/mac/crash_generation/Inspector.h
@@ -0,0 +1,162 @@
+// 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.
+//
+// Interface file between the Breakpad.framework and
+// the Inspector process.
+
+#include "common/simple_string_dictionary.h"
+
+#import <Foundation/Foundation.h>
+#include <mach/mach.h>
+
+#import "client/mac/crash_generation/ConfigFile.h"
+#import "client/mac/handler/minidump_generator.h"
+
+
+// Types of mach messsages (message IDs)
+enum {
+  kMsgType_InspectorInitialInfo = 0,    // data is InspectorInfo
+  kMsgType_InspectorKeyValuePair = 1,   // data is KeyValueMessageData
+  kMsgType_InspectorAcknowledgement = 2 // no data sent
+};
+
+// Initial information sent from the crashed process by
+// Breakpad.framework to the Inspector process
+// The mach message with this struct as data will also include
+// several descriptors for sending mach port rights to the crashed
+// task, etc.
+struct InspectorInfo {
+  int           exception_type;
+  int           exception_code;
+  int           exception_subcode;
+  unsigned int  parameter_count;  // key-value pairs
+};
+
+// Key/value message data to be sent to the Inspector
+struct KeyValueMessageData {
+ public:
+  KeyValueMessageData() {}
+  explicit KeyValueMessageData(
+      const google_breakpad::SimpleStringDictionary::Entry &inEntry) {
+    strlcpy(key, inEntry.key, sizeof(key) );
+    strlcpy(value, inEntry.value, sizeof(value) );
+  }
+
+  char key[google_breakpad::SimpleStringDictionary::key_size];
+  char value[google_breakpad::SimpleStringDictionary::value_size];
+};
+
+using std::string;
+using google_breakpad::MinidumpGenerator;
+
+namespace google_breakpad {
+
+//=============================================================================
+class MinidumpLocation {
+ public:
+  MinidumpLocation(NSString *minidumpDir) {
+    // Ensure that the path exists.  Fallback to /tmp if unable to locate path.
+    assert(minidumpDir);
+    if (!EnsureDirectoryPathExists(minidumpDir)) {
+      minidumpDir = @"/tmp";
+    }
+
+    strlcpy(minidump_dir_path_, [minidumpDir fileSystemRepresentation],
+            sizeof(minidump_dir_path_));
+
+    // now generate a unique ID
+    string dump_path(minidump_dir_path_);
+    string next_minidump_id;
+
+    string next_minidump_path_ =
+      (MinidumpGenerator::UniqueNameInDirectory(dump_path, &next_minidump_id));
+
+    strlcpy(minidump_id_, next_minidump_id.c_str(), sizeof(minidump_id_));
+  };
+
+  const char *GetPath() { return minidump_dir_path_; }
+  const char *GetID() { return minidump_id_; }
+
+ private:
+  char minidump_dir_path_[PATH_MAX];             // Path to minidump directory
+  char minidump_id_[128];
+};
+
+//=============================================================================
+class Inspector {
+ public:
+  Inspector() {};
+
+  // given a bootstrap service name, receives mach messages
+  // from a crashed process, then inspects it, creates a minidump file
+  // and asks the user if he wants to upload it to a server.
+  void            Inspect(const char *receive_port_name);
+
+ private:
+  // The Inspector is invoked with its bootstrap port set to the bootstrap
+  // subset established in OnDemandServer.mm OnDemandServer::Initialize.
+  // For proper communication with the system, the sender (which will inherit
+  // the Inspector's bootstrap port) needs the per-session bootstrap namespace
+  // available directly in its bootstrap port. OnDemandServer stashed this
+  // port into the subset namespace under a special name. ResetBootstrapPort
+  // recovers this port and switches this task to use it as its own bootstrap
+  // (ensuring that children like the sender will inherit it), and saves the
+  // subset in bootstrap_subset_port_ for use by ServiceCheckIn and
+  // ServiceCheckOut.
+  kern_return_t   ResetBootstrapPort();
+
+  kern_return_t   ServiceCheckIn(const char *receive_port_name);
+  kern_return_t   ServiceCheckOut(const char *receive_port_name);
+
+  kern_return_t   ReadMessages();
+
+  bool            InspectTask();
+  kern_return_t   SendAcknowledgement();
+
+  // The bootstrap port in which the inspector is registered and into which it
+  // must check in.
+  mach_port_t     bootstrap_subset_port_;
+
+  mach_port_t     service_rcv_port_;
+
+  int             exception_type_;
+  int             exception_code_;
+  int             exception_subcode_;
+  mach_port_t     remote_task_;
+  mach_port_t     crashing_thread_;
+  mach_port_t     handler_thread_;
+  mach_port_t     ack_port_;
+
+  SimpleStringDictionary config_params_;
+
+  ConfigFile      config_file_;
+};
+
+
+} // namespace google_breakpad
diff --git a/include/breakpad/client/mac/crash_generation/client_info.h b/include/breakpad/client/mac/crash_generation/client_info.h
new file mode 100644
index 0000000..a3a95dc
--- /dev/null
+++ b/include/breakpad/client/mac/crash_generation/client_info.h
@@ -0,0 +1,47 @@
+// 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 CLIENT_MAC_CRASH_GENERATION_CLIENT_INFO_H_
+#define CLIENT_MAC_CRASH_GENERATION_CLIENT_INFO_H_
+
+namespace google_breakpad {
+
+class ClientInfo {
+ public:
+  explicit ClientInfo(pid_t pid) : pid_(pid) {}
+
+  pid_t pid() const { return pid_; }
+
+ private:
+  pid_t pid_;
+};
+
+}  // namespace google_breakpad
+
+#endif  // CLIENT_MAC_CRASH_GENERATION_CLIENT_INFO_H_
diff --git a/include/breakpad/client/mac/crash_generation/crash_generation_client.h b/include/breakpad/client/mac/crash_generation/crash_generation_client.h
new file mode 100644
index 0000000..527f577
--- /dev/null
+++ b/include/breakpad/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/include/breakpad/client/mac/crash_generation/crash_generation_server.h b/include/breakpad/client/mac/crash_generation/crash_generation_server.h
new file mode 100644
index 0000000..85bd5b5
--- /dev/null
+++ b/include/breakpad/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/include/breakpad/client/mac/handler/breakpad_nlist_64.h b/include/breakpad/client/mac/handler/breakpad_nlist_64.h
new file mode 100644
index 0000000..1d2c639
--- /dev/null
+++ b/include/breakpad/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/include/breakpad/client/mac/handler/dynamic_images.h b/include/breakpad/client/mac/handler/dynamic_images.h
new file mode 100644
index 0000000..6514790
--- /dev/null
+++ b/include/breakpad/client/mac/handler/dynamic_images.h
@@ -0,0 +1,319 @@
+// 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;
+#elif defined(__aarch64__)
+    return CPU_TYPE_ARM64;
+#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/include/breakpad/client/mac/handler/exception_handler.h b/include/breakpad/client/mac/handler/exception_handler.h
new file mode 100644
index 0000000..f1d9ae9
--- /dev/null
+++ b/include/breakpad/client/mac/handler/exception_handler.h
@@ -0,0 +1,281 @@
+// 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 "client/mac/handler/ucontext_compat.h"
+#include "common/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.
+  // |task_context| can be NULL. If not, it will be used to retrieve the
+  // context of the current thread, instead of using |thread_get_state|.
+  bool WriteMinidumpWithException(int exception_type,
+                                  int exception_code,
+                                  int exception_subcode,
+                                  breakpad_ucontext_t *task_context,
+                                  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/include/breakpad/client/mac/handler/mach_vm_compat.h b/include/breakpad/client/mac/handler/mach_vm_compat.h
new file mode 100644
index 0000000..9e9028b
--- /dev/null
+++ b/include/breakpad/client/mac/handler/mach_vm_compat.h
@@ -0,0 +1,48 @@
+// 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 and higher, mach/mach_vm.h is not supported. Use the corresponding
+// vm_map functions instead.
+#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_recurse vm_region_recurse_64
+#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/include/breakpad/client/mac/handler/minidump_generator.h b/include/breakpad/client/mac/handler/minidump_generator.h
new file mode 100644
index 0000000..4e4b4a6
--- /dev/null
+++ b/include/breakpad/client/mac/handler/minidump_generator.h
@@ -0,0 +1,236 @@
+// 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/mac/handler/ucontext_compat.h"
+#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(__aarch64__)
+#define HAS_ARM64_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;
+  }
+
+  // Specify the task context. If |task_context| is not NULL, it will be used
+  // to retrieve the context of the current thread, instead of using
+  // |thread_get_state|.
+  void SetTaskContext(breakpad_ucontext_t *task_context);
+
+  // 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
+  uint64_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);
+  uint64_t CurrentPCForStackARM(breakpad_thread_state_data_t state);
+#endif
+#ifdef HAS_ARM64_SUPPORT
+  bool WriteStackARM64(breakpad_thread_state_data_t state,
+                       MDMemoryDescriptor *stack_location);
+  bool WriteContextARM64(breakpad_thread_state_data_t state,
+                         MDLocationDescriptor *register_location);
+  uint64_t CurrentPCForStackARM64(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);
+  uint64_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);
+  uint64_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);
+  uint64_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);
+  uint64_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_;
+
+  // Context of the task to dump.
+  breakpad_ucontext_t *task_context_;
+
+  // 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/include/breakpad/client/mac/handler/protected_memory_allocator.h b/include/breakpad/client/mac/handler/protected_memory_allocator.h
new file mode 100644
index 0000000..7e188db
--- /dev/null
+++ b/include/breakpad/client/mac/handler/protected_memory_allocator.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.
+//
+// ProtectedMemoryAllocator
+//
+// A very simple allocator class which allows allocation, but not deallocation.
+// The allocations can be made read-only with the Protect() method.
+// This class is NOT useful as a general-purpose memory allocation system,
+// since it does not allow deallocation.  It is useful to use for a group
+// of allocations which are created in the same time-frame and destroyed
+// in the same time-frame.  It is useful for making allocations of memory
+// which will not need to change often once initialized.  This memory can then
+// be protected from memory smashers by calling the Protect() method.
+
+#ifndef PROTECTED_MEMORY_ALLOCATOR_H__
+#define PROTECTED_MEMORY_ALLOCATOR_H__
+
+#include <mach/mach.h>
+
+//
+class ProtectedMemoryAllocator {
+ public:
+  ProtectedMemoryAllocator(vm_size_t pool_size);  
+  ~ProtectedMemoryAllocator();
+  
+  // Returns a pointer to an allocation of size n within the pool.
+  // Fails by returning NULL is no more space is available.
+  // Please note that the pointers returned from this method should not
+  // be freed in any way (for example by calling free() on them ).
+  char *         Allocate(vm_size_t n);
+  
+  // Returns the base address of the allocation pool.
+  char *         GetBaseAddress() { return (char*)base_address_; }
+
+  // Returns the size of the allocation pool, including allocated
+  // plus free space.
+  vm_size_t      GetTotalSize() { return pool_size_; }
+
+  // Returns the number of bytes already allocated in the pool.
+  vm_size_t      GetAllocatedSize() { return next_alloc_offset_; }
+
+  // Returns the number of bytes available for allocation.
+  vm_size_t      GetFreeSize() { return pool_size_ - next_alloc_offset_; }
+  
+  // Makes the entire allocation pool read-only including, of course,
+  // all allocations made from the pool.
+  kern_return_t  Protect();  
+
+  // Makes the entire allocation pool read/write.
+  kern_return_t  Unprotect();  
+  
+ private:
+  vm_size_t      pool_size_;
+  vm_address_t   base_address_;
+  vm_size_t      next_alloc_offset_;
+  bool           valid_;
+};
+
+#endif // PROTECTED_MEMORY_ALLOCATOR_H__
diff --git a/include/breakpad/client/mac/handler/testcases/DynamicImagesTests.h b/include/breakpad/client/mac/handler/testcases/DynamicImagesTests.h
new file mode 100644
index 0000000..e1e7999
--- /dev/null
+++ b/include/breakpad/client/mac/handler/testcases/DynamicImagesTests.h
@@ -0,0 +1,52 @@
+// 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.
+
+//
+//  DynamicImagesTests.h
+//  minidump_test
+//
+//  Created by Neal Sidhwaney on 4/17/08.
+//  Copyright 2008 Google Inc. All rights reserved.
+//
+//
+
+#ifndef _CLIENT_MAC_HANDLER_TESTCASES_DYNAMICIMAGESTESTS_H__
+#define _CLIENT_MAC_HANDLER_TESTCASES_DYNAMICIMAGESTESTS_H__
+
+#include <CPlusTest/CPlusTest.h>
+
+class DynamicImagesTests : public TestCase {
+ public:
+  explicit DynamicImagesTests(TestInvocation* invocation);
+  virtual ~DynamicImagesTests();
+
+  void ReadTaskMemoryTest();
+  void ReadLibrariesFromLocalTaskTest();
+};
+
+#endif /* _CLIENT_MAC_HANDLER_TESTCASES_DYNAMICIMAGESTESTS_H__ */
diff --git a/include/breakpad/client/mac/handler/testcases/breakpad_nlist_test.h b/include/breakpad/client/mac/handler/testcases/breakpad_nlist_test.h
new file mode 100644
index 0000000..e93657c
--- /dev/null
+++ b/include/breakpad/client/mac/handler/testcases/breakpad_nlist_test.h
@@ -0,0 +1,62 @@
+// 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_test.h
+//  minidump_test
+//
+//  Created by Neal Sidhwaney on 4/13/08.
+//  Copyright 2008 Google Inc. All rights reserved.
+//
+//
+
+#ifndef CLIENT_MAC_HANDLER_TESTCASES_BREAKPAD_NLIST_TEST_H__
+#define CLIENT_MAC_HANDLER_TESTCASES_BREAKPAD_NLIST_TEST_H__
+
+#include <CPlusTest/CPlusTest.h>
+
+class BreakpadNlistTest : public TestCase {
+ private:
+
+  // nm dumps multiple addresses for the same symbol in
+  // /usr/lib/dyld. So we track those so we don't report failures
+  // in mismatches between what our nlist returns and what nm has
+  // for the duplicate symbols.
+  bool IsSymbolMoreThanOnceInDyld(const char *symbolName);
+
+ public:
+  explicit BreakpadNlistTest(TestInvocation* invocation);
+  virtual ~BreakpadNlistTest();
+
+
+  /* This test case runs nm on /usr/lib/dyld and then compares the
+     output of every symbol to what our nlist implementation returns */
+  void CompareToNM();
+};
+
+#endif /* CLIENT_MAC_HANDLER_TESTCASES_BREAKPAD_NLIST_TEST_H__*/
diff --git a/include/breakpad/client/mac/handler/testcases/dwarftests.h b/include/breakpad/client/mac/handler/testcases/dwarftests.h
new file mode 100644
index 0000000..21ff7a4
--- /dev/null
+++ b/include/breakpad/client/mac/handler/testcases/dwarftests.h
@@ -0,0 +1,46 @@
+// 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.
+
+//
+//  dwarftests.h
+//  minidump_test
+//
+//  Created by Neal Sidhwaney on 9/24/08.
+//  Copyright 2008 Google Inc. All rights reserved.
+//
+
+#import <SenTestingKit/SenTestingKit.h>
+
+
+@interface dwarftests : SenTestCase {
+
+}
+
+- (void) testDWARFSymbolFileGeneration;
+
+@end
diff --git a/include/breakpad/client/mac/handler/ucontext_compat.h b/include/breakpad/client/mac/handler/ucontext_compat.h
new file mode 100644
index 0000000..1e4b752
--- /dev/null
+++ b/include/breakpad/client/mac/handler/ucontext_compat.h
@@ -0,0 +1,47 @@
+// Copyright 2013 Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef CLIENT_MAC_HANDLER_UCONTEXT_COMPAT_H_
+#define CLIENT_MAC_HANDLER_UCONTEXT_COMPAT_H_
+
+#include <sys/ucontext.h>
+
+// The purpose of this file is to work around the fact that ucontext_t's
+// uc_mcontext member is an mcontext_t rather than an mcontext64_t on ARM64.
+#if defined(__aarch64__)
+// <sys/ucontext.h> doesn't include the below file.
+#include <sys/_types/_ucontext64.h>
+typedef ucontext64_t breakpad_ucontext_t;
+#define breakpad_uc_mcontext uc_mcontext64
+#else
+typedef ucontext_t breakpad_ucontext_t;
+#define breakpad_uc_mcontext uc_mcontext
+#endif  // defined(__aarch64__)
+
+#endif  // CLIENT_MAC_HANDLER_UCONTEXT_COMPAT_H_
diff --git a/include/breakpad/client/mac/sender/crash_report_sender.h b/include/breakpad/client/mac/sender/crash_report_sender.h
new file mode 100644
index 0000000..6a29d48
--- /dev/null
+++ b/include/breakpad/client/mac/sender/crash_report_sender.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.
+//
+// This component uses the HTTPMultipartUpload of the breakpad project to send
+// the minidump and associated data to the crash reporting servers.
+// It will perform throttling based on the parameters passed to it and will
+// prompt the user to send the minidump.
+
+#import <Cocoa/Cocoa.h>
+
+#include "client/mac/sender/uploader.h"
+#import "GTMDefines.h"
+
+// We're sublcassing NSTextField in order to override a particular
+// method (see the implementation) that lets us reject changes if they
+// are longer than a particular length.  Bindings would normally solve
+// this problem, but when we implemented a validation method, and
+// returned NO for strings that were too long, the UI was not updated
+// right away, which was a poor user experience.  The UI would be
+// updated as soon as the text field lost first responder status,
+// which isn't soon enough.  It is a known bug that the UI KVO didn't
+// work in the middle of a validation.
+@interface LengthLimitingTextField : NSTextField {
+  @private
+   NSUInteger maximumLength_;
+}
+
+- (void)setMaximumLength:(NSUInteger)maxLength;
+@end
+
+@interface Reporter : NSObject {
+ @public
+  IBOutlet NSWindow *alertWindow_;        // The alert window
+
+  // Grouping boxes used for resizing.
+  IBOutlet NSBox *headerBox_;
+  IBOutlet NSBox *preEmailBox_;
+  IBOutlet NSBox *emailSectionBox_;
+  // Localized elements (or things that need to be moved during localization).
+  IBOutlet NSTextField                *dialogTitle_;
+  IBOutlet NSTextField                *commentMessage_;
+  IBOutlet NSTextField                *emailMessage_;
+  IBOutlet NSTextField                *emailLabel_;
+  IBOutlet NSTextField                *privacyLinkLabel_;
+  IBOutlet NSButton                   *sendButton_;
+  IBOutlet NSButton                   *cancelButton_;
+  IBOutlet LengthLimitingTextField    *emailEntryField_;
+  IBOutlet LengthLimitingTextField    *commentsEntryField_;
+  IBOutlet NSTextField                *countdownLabel_;
+  IBOutlet NSView                     *privacyLinkArrow_;
+
+  // Text field bindings, for user input.
+  NSString *commentsValue_;                // Comments from the user
+  NSString *emailValue_;                   // Email from the user
+  NSString *countdownMessage_;             // Message indicating time
+                                           // left for input.
+ @private
+  NSTimeInterval remainingDialogTime_;     // Keeps track of how long
+                                           // we have until we cancel
+                                           // the dialog
+  NSTimer *messageTimer_;                  // Timer we use to update
+                                           // the dialog
+  Uploader* uploader_;                     // Uploader we use to send the data.
+}
+
+// Stops the modal panel with an NSAlertDefaultReturn value. This is the action
+// invoked by the "Send Report" button.
+- (IBAction)sendReport:(id)sender;
+// Stops the modal panel with an NSAlertAlternateReturn value. This is the
+// action invoked by the "Cancel" button.
+- (IBAction)cancel:(id)sender;
+// Opens the Privacy Policy url in the default web browser.
+- (IBAction)showPrivacyPolicy:(id)sender;
+
+// Delegate methods for the NSTextField for comments. We want to capture the
+// Return key and use it to send the message when no text has been entered.
+// Otherwise, we want Return to add a carriage return to the comments field.
+- (BOOL)control:(NSControl *)control textView:(NSTextView *)textView
+                          doCommandBySelector:(SEL)commandSelector;
+
+// Accessors to make bindings work
+- (NSString *)commentsValue;
+- (void)setCommentsValue:(NSString *)value;
+
+- (NSString *)emailValue;
+- (void)setEmailValue:(NSString *)value;
+
+- (NSString *)countdownMessage;
+- (void)setCountdownMessage:(NSString *)value;
+
+@end
diff --git a/include/breakpad/client/mac/sender/uploader.h b/include/breakpad/client/mac/sender/uploader.h
new file mode 100644
index 0000000..5f6aa46
--- /dev/null
+++ b/include/breakpad/client/mac/sender/uploader.h
@@ -0,0 +1,89 @@
+// Copyright (c) 2011, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// This component uses the HTTPMultipartUpload of the breakpad project to send
+// the minidump and associated data to the crash reporting servers.
+// It will perform throttling based on the parameters passed to it and will
+// prompt the user to send the minidump.
+
+#include <Foundation/Foundation.h>
+
+#import "common/mac/GTMDefines.h"
+
+#define kClientIdPreferenceKey @"clientid"
+
+extern NSString *const kGoogleServerType;
+extern NSString *const kSocorroServerType;
+extern NSString *const kDefaultServerType;
+
+@interface Uploader : NSObject {
+ @private
+  NSMutableDictionary *parameters_;        // Key value pairs of data (STRONG)
+  NSData *minidumpContents_;               // The data in the minidump (STRONG)
+  NSData *logFileData_;                    // An NSdata for the tar,
+                                           // bz2'd log file.
+  NSMutableDictionary *serverDictionary_;  // The dictionary mapping a
+                                           // server type name to a
+                                           // dictionary of server
+                                           // parameter names.
+  NSMutableDictionary *socorroDictionary_; // The dictionary for
+                                           // Socorro.
+  NSMutableDictionary *googleDictionary_;  // The dictionary for
+                                           // Google.
+  NSMutableDictionary *extraServerVars_;   // A dictionary containing
+                                           // extra key/value pairs
+                                           // that are uploaded to the
+                                           // crash server with the
+                                           // minidump.
+}
+
+- (id)initWithConfigFile:(const char *)configFile;
+
+- (id)initWithConfig:(NSDictionary *)config;
+
+// Reads the file |configFile| and returns the corresponding NSDictionary.
+// |configFile| will be deleted after reading.
++ (NSDictionary *)readConfigurationDataFromFile:(NSString *)configFile;
+
+- (NSMutableDictionary *)parameters;
+
+- (void)report;
+
+// Upload the given data to the crash server.
+- (void)uploadData:(NSData *)data name:(NSString *)name;
+
+// This method adds a key/value pair to the dictionary that
+// will be uploaded to the crash server.
+- (void)addServerParameter:(id)value forKey:(NSString *)key;
+
+// This method process the HTTP response and renames the minidump file with the
+// new ID.
+- (void)handleNetworkResponse:(NSData *)data withError:(NSError *)error;
+
+@end
diff --git a/include/breakpad/client/mac/testapp/Controller.h b/include/breakpad/client/mac/testapp/Controller.h
new file mode 100644
index 0000000..7b3be2d
--- /dev/null
+++ b/include/breakpad/client/mac/testapp/Controller.h
@@ -0,0 +1,65 @@
+// 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.
+
+#import <Cocoa/Cocoa.h>
+
+#import <Breakpad/Breakpad.h>
+
+enum BreakpadForkBehavior {
+  DONOTHING = 0,
+  UNINSTALL,
+  RESETEXCEPTIONPORT
+};
+
+enum BreakpadForkTestCrashPoint {
+  DURINGLAUNCH = 5,
+  AFTERLAUNCH = 6,
+  BETWEENFORKEXEC = 7
+};
+
+@interface Controller : NSObject {
+  IBOutlet NSWindow *window_;
+  IBOutlet NSWindow *forkTestOptions_;
+
+  BreakpadRef breakpad_;
+
+  enum BreakpadForkBehavior bpForkOption;
+
+  BOOL useVFork;
+  enum BreakpadForkTestCrashPoint progCrashPoint;
+}
+
+- (IBAction)crash:(id)sender;
+- (IBAction)forkTestOptions:(id)sender;
+- (IBAction)forkTestGo:(id)sender;
+- (IBAction)showForkTestWindow:(id) sender;
+- (void)generateReportWithoutCrash:(id)sender;
+- (void)awakeFromNib;
+
+@end
diff --git a/include/breakpad/client/mac/testapp/TestClass.h b/include/breakpad/client/mac/testapp/TestClass.h
new file mode 100644
index 0000000..0a6d736
--- /dev/null
+++ b/include/breakpad/client/mac/testapp/TestClass.h
@@ -0,0 +1,37 @@
+// 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.
+
+#import <Cocoa/Cocoa.h>
+
+@interface TestClass : NSObject {
+}
+
+- (void)wait;
+
+@end
diff --git a/include/breakpad/client/mac/tests/spawn_child_process.h b/include/breakpad/client/mac/tests/spawn_child_process.h
new file mode 100644
index 0000000..e52ff6b
--- /dev/null
+++ b/include/breakpad/client/mac/tests/spawn_child_process.h
@@ -0,0 +1,149 @@
+// 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.
+
+// Utility functions for spawning a helper process using a different
+// CPU architecture.
+
+#ifndef GOOGLE_BREAKPAD_CLIENT_MAC_TESTS_SPAWN_CHILD_PROCESS
+#define GOOGLE_BREAKPAD_CLIENT_MAC_TESTS_SPAWN_CHILD_PROCESS
+
+#include <AvailabilityMacros.h>
+#ifndef MAC_OS_X_VERSION_10_6
+#define MAC_OS_X_VERSION_10_6 1060
+#endif
+#include <crt_externs.h>
+#include <mach-o/dyld.h>
+#if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_6
+#include <spawn.h>
+#endif
+
+#include <string>
+#include <vector>
+
+#include "google_breakpad/common/minidump_format.h"
+
+namespace google_breakpad_test {
+
+using std::string;
+using std::vector;
+
+const MDCPUArchitecture kNativeArchitecture =
+#if defined(__i386__)
+  MD_CPU_ARCHITECTURE_X86
+#elif defined(__x86_64__)
+  MD_CPU_ARCHITECTURE_AMD64
+#elif defined(__ppc__) || defined(__ppc64__)
+  MD_CPU_ARCHITECTURE_PPC
+#else
+#error "This file has not been ported to this CPU architecture."
+#endif
+  ;
+
+const uint32_t kNativeContext =
+#if defined(__i386__)
+  MD_CONTEXT_X86
+#elif defined(__x86_64__)
+  MD_CONTEXT_AMD64
+#elif defined(__ppc__) || defined(__ppc64__)
+  MD_CONTEXT_PPC
+#else
+#error "This file has not been ported to this CPU architecture."
+#endif
+  ;
+
+string GetExecutablePath() {
+  char self_path[PATH_MAX];
+  uint32_t size = sizeof(self_path);
+  if (_NSGetExecutablePath(self_path, &size) != 0)
+    return "";
+  return self_path;
+}
+
+string GetHelperPath() {
+  string helper_path(GetExecutablePath());
+  size_t pos = helper_path.rfind('/');
+  if (pos == string::npos)
+    return "";
+
+  helper_path.erase(pos + 1);
+  helper_path += "minidump_generator_test_helper";
+  return helper_path;
+}
+
+#if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_6
+
+pid_t spawn_child_process(const char** argv) {
+  posix_spawnattr_t spawnattr;
+  if (posix_spawnattr_init(&spawnattr) != 0)
+    return (pid_t)-1;
+
+  cpu_type_t pref_cpu_types[2] = {
+#if defined(__x86_64__)
+    CPU_TYPE_X86,
+#elif defined(__i386__)
+    CPU_TYPE_X86_64,
+#endif
+    CPU_TYPE_ANY
+  };
+
+  // Set spawn attributes.
+  size_t attr_count = sizeof(pref_cpu_types) / sizeof(pref_cpu_types[0]);
+  size_t attr_ocount = 0;
+  if (posix_spawnattr_setbinpref_np(&spawnattr,
+                                    attr_count,
+                                    pref_cpu_types,
+                                    &attr_ocount) != 0 ||
+      attr_ocount != attr_count) {
+    posix_spawnattr_destroy(&spawnattr);
+    return (pid_t)-1;
+  }
+
+  // Create an argv array.
+  vector<char*> argv_v;
+  while (*argv) {
+    argv_v.push_back(strdup(*argv));
+    argv++;
+  }
+  argv_v.push_back(NULL);
+  pid_t new_pid = 0;
+  int result = posix_spawnp(&new_pid, argv_v[0], NULL, &spawnattr,
+                            &argv_v[0], *_NSGetEnviron());
+  posix_spawnattr_destroy(&spawnattr);
+  
+  for (unsigned i = 0; i < argv_v.size(); i++) {
+    free(argv_v[i]);
+  }
+
+  return result == 0 ? new_pid : -1;
+}
+#endif
+
+}  // namespace google_breakpad_test
+
+#endif  // GOOGLE_BREAKPAD_CLIENT_MAC_TESTS_SPAWN_CHILD_PROCESS
diff --git a/include/breakpad/client/mac/tests/testlogging.h b/include/breakpad/client/mac/tests/testlogging.h
new file mode 100644
index 0000000..c6b6be6
--- /dev/null
+++ b/include/breakpad/client/mac/tests/testlogging.h
@@ -0,0 +1,9 @@
+// This file exists to override the processor logging for unit tests,
+// since it confuses XCode into thinking unit tests have failed.
+#include <sstream>
+
+namespace google_breakpad {
+extern std::ostringstream info_log;
+}
+
+#define BPLOG_INFO_STREAM google_breakpad::info_log
diff --git a/include/breakpad/client/minidump_file_writer-inl.h b/include/breakpad/client/minidump_file_writer-inl.h
new file mode 100644
index 0000000..0e12e00
--- /dev/null
+++ b/include/breakpad/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/include/breakpad/client/minidump_file_writer.h b/include/breakpad/client/minidump_file_writer.h
new file mode 100644
index 0000000..ce32b6d
--- /dev/null
+++ b/include/breakpad/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. If |path| already
+  // exists, then Open() will fail.
+  // 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<uint32_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/include/breakpad/client/solaris/handler/exception_handler.h b/include/breakpad/client/solaris/handler/exception_handler.h
new file mode 100644
index 0000000..4d72485
--- /dev/null
+++ b/include/breakpad/client/solaris/handler/exception_handler.h
@@ -0,0 +1,201 @@
+// Copyright (c) 2007, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: Alfred Peng
+
+#ifndef CLIENT_SOLARIS_HANDLER_EXCEPTION_HANDLER_H__
+#define CLIENT_SOLARIS_HANDLER_EXCEPTION_HANDLER_H__
+
+#include <map>
+#include <string>
+#include <vector>
+
+#include "client/solaris/handler/minidump_generator.h"
+
+namespace google_breakpad {
+
+using std::string;
+
+//
+// ExceptionHandler
+//
+// 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).
+// (NOTE): There should be only one this kind of exception handler
+// object per process.
+//
+// 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.
+//
+// Caller should try to make the callbacks as crash-friendly as possible,
+// it should avoid use heap memory allocation as much as possible.
+//
+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_path>/<minidump_id>.dmp.  context is the parameter supplied
+  // by the user as callback_context when the handler was created.  succeeded
+  // indicates whether a minidump file was successfully written.
+  //
+  // 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).
+  typedef bool (*MinidumpCallback)(const char *dump_path,
+                                   const char *minidump_id,
+                                   void *context,
+                                   bool succeeded);
+
+  // 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.
+  // 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.
+  ExceptionHandler(const string &dump_path,
+                   FilterCallback filter, MinidumpCallback 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();
+  }
+
+  // Writes a minidump immediately.  This can be used to capture the
+  // execution state independently of a crash.  Returns true on success.
+  bool WriteMinidump();
+
+  // Convenience form of WriteMinidump which does not require an
+  // ExceptionHandler instance.
+  static bool WriteMinidump(const string &dump_path,
+                            MinidumpCallback callback,
+                            void *callback_context);
+
+ private:
+  // Setup crash handler.
+  void SetupHandler();
+  // Setup signal handler for a signal.
+  void SetupHandler(int signo);
+  // Teardown the handler for a signal.
+  void TeardownHandler(int signo);
+  // Teardown all handlers.
+  void TeardownAllHandlers();
+
+  // Runs the main loop for the exception handler thread.
+  static void* ExceptionHandlerThreadMain(void *lpParameter);
+
+  // Signal handler.
+  static void HandleException(int signo);
+
+  // Write all the information to the dump file.
+  // If called from a signal handler, sighandler_ebp is the ebp of
+  // that signal handler's frame, and sig_ctx is an out parameter
+  // that will be set to point at the ucontext_t that was placed
+  // on the stack by the kernel.  You can pass zero and NULL
+  // for the second and third parameters if you are not calling
+  // this from a signal handler.
+  bool InternalWriteMinidump(int signo, uintptr_t sighandler_ebp,
+                             ucontext_t **sig_ctx);
+
+ private:
+  // The callbacks before and after writing the dump file.
+  FilterCallback filter_;
+  MinidumpCallback callback_;
+  void *callback_context_;
+
+  // The directory in which a minidump will be written, set by the dump_path
+  // argument to the constructor, or set_dump_path.
+  string dump_path_;
+  // C style dump path. Keep this when setting dump path, since calling
+  // c_str() of std::string when crashing may not be safe.
+  const char *dump_path_c_;
+
+  // True if the ExceptionHandler installed an unhandled exception filter
+  // when created (with an install_handler parameter set to true).
+  bool installed_handler_;
+
+  // Keep the previous handlers for the signal.
+  typedef void (*sighandler_t)(int);
+  std::map<int, sighandler_t> old_handlers_;
+
+  // The global exception handler stack. This is need becuase there may exist
+  // multiple ExceptionHandler instances in a process. Each will have itself
+  // registered in this stack.
+  static std::vector<ExceptionHandler *> *handler_stack_;
+  // The index of the handler that should handle the next exception.
+  static int handler_stack_index_;
+  static pthread_mutex_t handler_stack_mutex_;
+
+  // The minidump generator.
+  MinidumpGenerator minidump_generator_;
+
+  // disallow copy ctor and operator=
+  explicit ExceptionHandler(const ExceptionHandler &);
+  void operator=(const ExceptionHandler &);
+};
+
+}  // namespace google_breakpad
+
+#endif  // CLIENT_SOLARIS_HANDLER_EXCEPTION_HANDLER_H__
diff --git a/include/breakpad/client/solaris/handler/minidump_generator.h b/include/breakpad/client/solaris/handler/minidump_generator.h
new file mode 100644
index 0000000..882f9e1
--- /dev/null
+++ b/include/breakpad/client/solaris/handler/minidump_generator.h
@@ -0,0 +1,70 @@
+// Copyright (c) 2007, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: Alfred Peng
+
+#ifndef CLIENT_SOLARIS_HANDLER_MINIDUMP_GENERATOR_H__
+#define CLIENT_SOLARIS_HANDLER_MINIDUMP_GENERATOR_H__
+
+#include <ucontext.h>
+
+#include "client/minidump_file_writer.h"
+#include "client/solaris/handler/solaris_lwp.h"
+#include "google_breakpad/common/breakpad_types.h"
+#include "google_breakpad/common/minidump_format.h"
+
+namespace google_breakpad {
+
+//
+// MinidumpGenerator
+//
+// A minidump generator should be created before any exception happen.
+//
+class MinidumpGenerator {
+  // Callback run for writing lwp information in the process.
+  friend bool LwpInformationCallback(lwpstatus_t *lsp, void *context);
+
+  // Callback run for writing module information in the process.
+  friend bool ModuleInfoCallback(const ModuleInfo &module_info, void *context);
+
+ public:
+  MinidumpGenerator();
+
+  ~MinidumpGenerator();
+
+  // Write minidump.
+  bool WriteMinidumpToFile(const char *file_pathname,
+                           int signo,
+                           uintptr_t sighandler_ebp,
+                           ucontext_t **sig_ctx) const;
+};
+
+}  // namespace google_breakpad
+
+#endif   // CLIENT_SOLARIS_HANDLER_MINIDUMP_GENERATOR_H_
diff --git a/include/breakpad/client/solaris/handler/solaris_lwp.h b/include/breakpad/client/solaris/handler/solaris_lwp.h
new file mode 100644
index 0000000..0914cfc
--- /dev/null
+++ b/include/breakpad/client/solaris/handler/solaris_lwp.h
@@ -0,0 +1,160 @@
+// Copyright (c) 2007, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: Alfred Peng
+
+#ifndef CLIENT_SOLARIS_HANDLER_SOLARIS_LWP_H__
+#define CLIENT_SOLARIS_HANDLER_SOLARIS_LWP_H__
+
+#if defined(sparc) || defined(__sparc)
+#define TARGET_CPU_SPARC 1
+#elif defined(i386) || defined(__i386)
+#define TARGET_CPU_X86 1
+#else
+#error "cannot determine cpu type"
+#endif
+
+#include <signal.h>
+#include <stdint.h>
+#include <sys/user.h>
+#include <ucontext.h>
+
+#ifndef _KERNEL
+#define _KERNEL
+#define MUST_UNDEF_KERNEL
+#endif  // _KERNEL
+#include <sys/procfs.h>
+#ifdef MUST_UNDEF_KERNEL
+#undef _KERNEL
+#undef MUST_UNDEF_KERNEL
+#endif  // MUST_UNDEF_KERNEL
+
+namespace google_breakpad {
+
+// Max module path name length.
+static const int kMaxModuleNameLength = 256;
+
+// Holding infomaton about a module in the process.
+struct ModuleInfo {
+  char name[kMaxModuleNameLength];
+  uintptr_t start_addr;
+  int size;
+};
+
+// A callback to run when getting a lwp in the process.
+// Return true will go on to the next lwp while return false will stop the
+// iteration.
+typedef bool (*LwpCallback)(lwpstatus_t* lsp, void *context); 
+
+// A callback to run when a new module is found in the process.
+// Return true will go on to the next module while return false will stop the
+// iteration.
+typedef bool (*ModuleCallback)(const ModuleInfo &module_info, void *context);
+
+// A callback to run when getting a lwpid in the process.
+// Return true will go on to the next lwp while return false will stop the
+// iteration.
+typedef bool (*LwpidCallback)(int lwpid, void *context);
+
+// Holding the callback information.
+template<class CallbackFunc>
+struct CallbackParam {
+  // Callback function address.
+  CallbackFunc call_back;
+  // Callback context;
+  void *context;
+
+  CallbackParam() : call_back(NULL), context(NULL) {
+  }
+
+  CallbackParam(CallbackFunc func, void *func_context) :
+    call_back(func), context(func_context) {
+  }
+};
+
+///////////////////////////////////////////////////////////////////////////////
+
+//
+// SolarisLwp
+//
+// Provides handy support for operation on Solaris lwps.
+// It uses proc file system to get lwp information.
+//
+// TODO(Alfred): Currently it only supports x86. Add SPARC support.
+//
+class SolarisLwp {
+ public:
+  // Create a SolarisLwp instance to list all the lwps in a process.
+  explicit SolarisLwp(int pid);
+  ~SolarisLwp();
+
+  int getpid() const { return this->pid_; }
+
+  // Control all the lwps in the process.
+  // Return the number of suspended/resumed lwps in the process.
+  // Return -1 means failed to control lwps.
+  int ControlAllLwps(bool suspend);
+
+  // Get the count of lwps in the process.
+  // Return -1 means error.
+  int GetLwpCount() const;
+
+  // Iterate the lwps of process.
+  // Whenever there is a lwp found, the callback will be invoked to process
+  // the information.
+  // Return the callback return value or -1 on error.
+  int Lwp_iter_all(int pid, CallbackParam<LwpCallback> *callback_param) const;
+
+  // Get the module count of the current process.
+  int GetModuleCount() const;
+
+  // Get the mapped modules in the address space.
+  // Whenever a module is found, the callback will be invoked to process the
+  // information.
+  // Return how may modules are found.
+  int ListModules(CallbackParam<ModuleCallback> *callback_param) const;
+
+  // Get the bottom of the stack from esp.
+  uintptr_t GetLwpStackBottom(uintptr_t current_esp) const;
+
+  // Finds a signal context on the stack given the ebp of our signal handler.
+  bool FindSigContext(uintptr_t sighandler_ebp, ucontext_t **sig_ctx);
+
+ private:
+  // Check if the address is a valid virtual address.
+  bool IsAddressMapped(uintptr_t address) const;
+
+ private:
+  // The pid of the process we are listing lwps.
+  int pid_;
+};
+
+}  // namespace google_breakpad
+
+#endif  // CLIENT_SOLARIS_HANDLER_SOLARIS_LWP_H__
diff --git a/include/breakpad/client/windows/common/auto_critical_section.h b/include/breakpad/client/windows/common/auto_critical_section.h
new file mode 100644
index 0000000..3fd4b9b
--- /dev/null
+++ b/include/breakpad/client/windows/common/auto_critical_section.h
@@ -0,0 +1,81 @@
+// 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_AUTO_CRITICAL_SECTION_H__
+#define CLIENT_WINDOWS_COMMON_AUTO_CRITICAL_SECTION_H__
+
+#include <windows.h>
+
+namespace google_breakpad {
+
+// Automatically enters the critical section in the constructor and leaves
+// the critical section in the destructor.
+class AutoCriticalSection {
+ public:
+  // Creates a new instance with the given critical section object
+  // and enters the critical section immediately.
+  explicit AutoCriticalSection(CRITICAL_SECTION* cs) : cs_(cs), taken_(false) {
+    assert(cs_);
+    Acquire();
+  }
+
+  // Destructor: leaves the critical section.
+  ~AutoCriticalSection() {
+    if (taken_) {
+      Release();
+    }
+  }
+
+  // Enters the critical section. Recursive Acquire() calls are not allowed.
+  void Acquire() {
+    assert(!taken_);
+    EnterCriticalSection(cs_);
+    taken_ = true;
+  }
+
+  // Leaves the critical section. The caller should not call Release() unless
+  // the critical seciton has been entered already.
+  void Release() {
+    assert(taken_);
+    taken_ = false;
+    LeaveCriticalSection(cs_);
+  }
+
+ private:
+  // Disable copy ctor and operator=.
+  AutoCriticalSection(const AutoCriticalSection&);
+  AutoCriticalSection& operator=(const AutoCriticalSection&);
+
+  CRITICAL_SECTION* cs_;
+  bool taken_;
+};
+
+}  // namespace google_breakpad
+
+#endif  // CLIENT_WINDOWS_COMMON_AUTO_CRITICAL_SECTION_H__
diff --git a/include/breakpad/client/windows/common/ipc_protocol.h b/include/breakpad/client/windows/common/ipc_protocol.h
new file mode 100644
index 0000000..c748681
--- /dev/null
+++ b/include/breakpad/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/include/breakpad/client/windows/crash_generation/client_info.h b/include/breakpad/client/windows/crash_generation/client_info.h
new file mode 100644
index 0000000..6a8fba3
--- /dev/null
+++ b/include/breakpad/client/windows/crash_generation/client_info.h
@@ -0,0 +1,177 @@
+// 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_CLIENT_INFO_H__
+#define CLIENT_WINDOWS_CRASH_GENERATION_CLIENT_INFO_H__
+
+#include <windows.h>
+#include <dbghelp.h>
+#include "client/windows/common/ipc_protocol.h"
+#include "common/scoped_ptr.h"
+#include "google_breakpad/common/minidump_format.h"
+
+namespace google_breakpad {
+
+class CrashGenerationServer;
+
+// Abstraction for a crash client process.
+class ClientInfo {
+ public:
+  // Creates an instance with the given values. Gets the process
+  // handle for the given process id and creates necessary event
+  // objects.
+  ClientInfo(CrashGenerationServer* crash_server,
+             DWORD pid,
+             MINIDUMP_TYPE dump_type,
+             DWORD* thread_id,
+             EXCEPTION_POINTERS** ex_info,
+             MDRawAssertionInfo* assert_info,
+             const CustomClientInfo& custom_client_info);
+
+  ~ClientInfo();
+
+  CrashGenerationServer* crash_server() const { return crash_server_; }
+  DWORD pid() const { return pid_; }
+  MINIDUMP_TYPE dump_type() const { return dump_type_; }
+  EXCEPTION_POINTERS** ex_info() const { return ex_info_; }
+  MDRawAssertionInfo* assert_info() const { return assert_info_; }
+  DWORD* thread_id() const { return thread_id_; }
+  HANDLE process_handle() const { return process_handle_; }
+  HANDLE dump_requested_handle() const { return dump_requested_handle_; }
+  HANDLE dump_generated_handle() const { return dump_generated_handle_; }
+  DWORD crash_id() const { return crash_id_; }
+  const CustomClientInfo& custom_client_info() const {
+    return custom_client_info_;
+  }
+
+  void set_dump_request_wait_handle(HANDLE value) {
+    dump_request_wait_handle_ = value;
+  }
+
+  void set_process_exit_wait_handle(HANDLE value) {
+    process_exit_wait_handle_ = value;
+  }
+
+  // Unregister the dump request wait operation and wait for all callbacks
+  // that might already be running to complete before returning.
+  void UnregisterDumpRequestWaitAndBlockUntilNoPending();
+
+  // Unregister the process exit wait operation.  If block_until_no_pending is
+  // true, wait for all callbacks that might already be running to complete
+  // before returning.
+  void UnregisterProcessExitWait(bool block_until_no_pending);
+
+  bool Initialize();
+  bool GetClientExceptionInfo(EXCEPTION_POINTERS** ex_info) const;
+  bool GetClientThreadId(DWORD* thread_id) const;
+
+  // Reads the custom information from the client process address space.
+  bool PopulateCustomInfo();
+
+  // Returns the client custom information.
+  CustomClientInfo GetCustomInfo() const;
+
+ private:
+  // Calcualtes the uptime for the client process, converts it to a string and
+  // stores it in the last entry of client custom info.
+  void SetProcessUptime();
+
+  // Crash generation server.
+  CrashGenerationServer* crash_server_;
+
+  // Client process ID.
+  DWORD pid_;
+
+  // Dump type requested by the client.
+  MINIDUMP_TYPE dump_type_;
+
+  // Address of an EXCEPTION_POINTERS* variable in the client
+  // process address space that will point to an instance of
+  // EXCEPTION_POINTERS containing information about crash.
+  //
+  // WARNING: Do not dereference these pointers as they are pointers
+  // in the address space of another process.
+  EXCEPTION_POINTERS** ex_info_;
+
+  // Address of an instance of MDRawAssertionInfo in the client
+  // process address space that will contain information about
+  // non-exception related crashes like invalid parameter assertion
+  // failures and pure calls.
+  //
+  // WARNING: Do not dereference these pointers as they are pointers
+  // in the address space of another process.
+  MDRawAssertionInfo* assert_info_;
+
+  // Custom information about the client.
+  CustomClientInfo custom_client_info_;
+
+  // Contains the custom client info entries read from the client process
+  // memory. This will be populated only if the method GetClientCustomInfo
+  // is called.
+  scoped_array<CustomInfoEntry> custom_info_entries_;
+
+  // Address of a variable in the client process address space that
+  // will contain the thread id of the crashing client thread.
+  //
+  // WARNING: Do not dereference these pointers as they are pointers
+  // in the address space of another process.
+  DWORD* thread_id_;
+
+  // Client process handle.
+  HANDLE process_handle_;
+
+  // Dump request event handle.
+  HANDLE dump_requested_handle_;
+
+  // Dump generated event handle.
+  HANDLE dump_generated_handle_;
+
+  // Wait handle for dump request event.
+  HANDLE dump_request_wait_handle_;
+
+  // Wait handle for process exit event.
+  HANDLE process_exit_wait_handle_;
+
+  // Time when the client process started. It is used to determine the uptime
+  // for the client process when it signals a crash.
+  FILETIME start_time_;
+
+  // The crash id which can be used to request an upload. This will be the
+  // value of the low order dword of the process creation time for the process
+  // being dumped.
+  DWORD crash_id_;
+
+  // Disallow copy ctor and operator=.
+  ClientInfo(const ClientInfo& client_info);
+  ClientInfo& operator=(const ClientInfo& client_info);
+};
+
+}  // namespace google_breakpad
+
+#endif  // CLIENT_WINDOWS_CRASH_GENERATION_CLIENT_INFO_H__
diff --git a/include/breakpad/client/windows/crash_generation/crash_generation_client.h b/include/breakpad/client/windows/crash_generation/crash_generation_client.h
new file mode 100644
index 0000000..457f731
--- /dev/null
+++ b/include/breakpad/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 "common/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/include/breakpad/client/windows/crash_generation/crash_generation_server.h b/include/breakpad/client/windows/crash_generation/crash_generation_server.h
new file mode 100644
index 0000000..0ea90e5
--- /dev/null
+++ b/include/breakpad/client/windows/crash_generation/crash_generation_server.h
@@ -0,0 +1,299 @@
+// 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_SERVER_H__
+#define CLIENT_WINDOWS_CRASH_GENERATION_CRASH_GENERATION_SERVER_H__
+
+#include <list>
+#include <string>
+#include "client/windows/common/ipc_protocol.h"
+#include "client/windows/crash_generation/minidump_generator.h"
+#include "common/scoped_ptr.h"
+
+namespace google_breakpad {
+class ClientInfo;
+
+// Abstraction for server side implementation of out-of-process crash
+// generation protocol for Windows platform only. It generates Windows
+// minidump files for client processes that request dump generation. When
+// the server is requested to start listening for clients (by calling the
+// Start method), it creates a named pipe and waits for the clients to
+// register. In response, it hands them event handles that the client can
+// signal to request dump generation. When the clients request dump
+// generation in this way, the server generates Windows minidump files.
+class CrashGenerationServer {
+ public:
+  typedef void (*OnClientConnectedCallback)(void* context,
+                                            const ClientInfo* client_info);
+
+  typedef void (*OnClientDumpRequestCallback)(void* context,
+                                              const ClientInfo* client_info,
+                                              const std::wstring* file_path);
+
+  typedef void (*OnClientExitedCallback)(void* context,
+                                         const ClientInfo* client_info);
+
+  typedef void (*OnClientUploadRequestCallback)(void* context,
+                                                const DWORD crash_id);
+
+  // Creates an instance with the given parameters.
+  //
+  // Parameter pipe_name: Name of the Windows named pipe
+  // Parameter pipe_sec_attrs Security attributes to set on the pipe. Pass
+  //     NULL to use default security on the pipe. By default, the pipe created
+  //     allows Local System, Administrators and the Creator full control and
+  //     the Everyone group read access on the pipe.
+  // Parameter connect_callback: Callback for a new client connection.
+  // Parameter connect_context: Context for client connection callback.
+  // Parameter crash_callback: Callback for a client crash dump request.
+  // Parameter crash_context: Context for client crash dump request callback.
+  // Parameter exit_callback: Callback for client process exit.
+  // Parameter exit_context: Context for client exit callback.
+  // Parameter 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.
+  // Parameter dump_path: Path for generating dumps; required only if true is
+  // passed for generateDumps parameter; NULL can be passed otherwise.
+  CrashGenerationServer(const std::wstring& pipe_name,
+                        SECURITY_ATTRIBUTES* pipe_sec_attrs,
+                        OnClientConnectedCallback connect_callback,
+                        void* connect_context,
+                        OnClientDumpRequestCallback dump_callback,
+                        void* dump_context,
+                        OnClientExitedCallback exit_callback,
+                        void* exit_context,
+                        OnClientUploadRequestCallback upload_request_callback,
+                        void* upload_context,
+                        bool generate_dumps,
+                        const std::wstring* dump_path);
+
+  ~CrashGenerationServer();
+
+  // Performs initialization steps needed to start listening to clients. Upon
+  // successful return clients may connect to this server's pipe.
+  //
+  // Returns true if initialization is successful; false otherwise.
+  bool Start();
+
+  void pre_fetch_custom_info(bool do_pre_fetch) {
+    pre_fetch_custom_info_ = do_pre_fetch;
+  }
+
+ private:
+  // Various states the client can be in during the handshake with
+  // the server.
+  enum IPCServerState {
+    // Server starts in this state.
+    IPC_SERVER_STATE_UNINITIALIZED,
+
+    // Server is in error state and it cannot serve any clients.
+    IPC_SERVER_STATE_ERROR,
+
+    // Server starts in this state.
+    IPC_SERVER_STATE_INITIAL,
+
+    // Server has issued an async connect to the pipe and it is waiting
+    // for the connection to be established.
+    IPC_SERVER_STATE_CONNECTING,
+
+    // Server is connected successfully.
+    IPC_SERVER_STATE_CONNECTED,
+
+    // Server has issued an async read from the pipe and it is waiting for
+    // the read to finish.
+    IPC_SERVER_STATE_READING,
+
+    // Server is done reading from the pipe.
+    IPC_SERVER_STATE_READ_DONE,
+
+    // Server has issued an async write to the pipe and it is waiting for
+    // the write to finish.
+    IPC_SERVER_STATE_WRITING,
+
+    // Server is done writing to the pipe.
+    IPC_SERVER_STATE_WRITE_DONE,
+
+    // Server has issued an async read from the pipe for an ack and it
+    // is waiting for the read to finish.
+    IPC_SERVER_STATE_READING_ACK,
+
+    // Server is done writing to the pipe and it is now ready to disconnect
+    // and reconnect.
+    IPC_SERVER_STATE_DISCONNECTING
+  };
+
+  //
+  // Helper methods to handle various server IPC states.
+  //
+  void HandleErrorState();
+  void HandleInitialState();
+  void HandleConnectingState();
+  void HandleConnectedState();
+  void HandleReadingState();
+  void HandleReadDoneState();
+  void HandleWritingState();
+  void HandleWriteDoneState();
+  void HandleReadingAckState();
+  void HandleDisconnectingState();
+
+  // Prepares reply for a client from the given parameters.
+  bool PrepareReply(const ClientInfo& client_info,
+                    ProtocolMessage* reply) const;
+
+  // Duplicates various handles in the ClientInfo object for the client
+  // process and stores them in the given ProtocolMessage instance. If
+  // creating any handle fails, ProtocolMessage will contain the handles
+  // already created successfully, which should be closed by the caller.
+  bool CreateClientHandles(const ClientInfo& client_info,
+                           ProtocolMessage* reply) const;
+
+  // Response to the given client. Return true if all steps of
+  // responding to the client succeed, false otherwise.
+  bool RespondToClient(ClientInfo* client_info);
+
+  // Handles a connection request from the client.
+  void HandleConnectionRequest();
+
+  // Handles a dump request from the client.
+  void HandleDumpRequest(const ClientInfo& client_info);
+
+  // Callback for pipe connected event.
+  static void CALLBACK OnPipeConnected(void* context, BOOLEAN timer_or_wait);
+
+  // Callback for a dump request.
+  static void CALLBACK OnDumpRequest(void* context, BOOLEAN timer_or_wait);
+
+  // Callback for client process exit event.
+  static void CALLBACK OnClientEnd(void* context, BOOLEAN timer_or_wait);
+
+  // Handles client process exit.
+  void HandleClientProcessExit(ClientInfo* client_info);
+
+  // Adds the given client to the list of registered clients.
+  bool AddClient(ClientInfo* client_info);
+
+  // Generates dump for the given client.
+  bool GenerateDump(const ClientInfo& client, std::wstring* dump_path);
+
+  // Puts the server in a permanent error state and sets a signal such that
+  // the state will be immediately entered after the current state transition
+  // is complete.
+  void EnterErrorState();
+
+  // Puts the server in the specified state and sets a signal such that the
+  // state is immediately entered after the current state transition is
+  // complete.
+  void EnterStateImmediately(IPCServerState state);
+
+  // Puts the server in the specified state. No signal will be set, so the state
+  // transition will only occur when signaled manually or by completion of an
+  // asynchronous IO operation.
+  void EnterStateWhenSignaled(IPCServerState state);
+
+  // Sync object for thread-safe access to the shared list of clients.
+  CRITICAL_SECTION sync_;
+
+  // List of clients.
+  std::list<ClientInfo*> clients_;
+
+  // Pipe name.
+  std::wstring pipe_name_;
+
+  // Pipe security attributes
+  SECURITY_ATTRIBUTES* pipe_sec_attrs_;
+
+  // Handle to the pipe used for handshake with clients.
+  HANDLE pipe_;
+
+  // Pipe wait handle.
+  HANDLE pipe_wait_handle_;
+
+  // Handle to server-alive mutex.
+  HANDLE server_alive_handle_;
+
+  // Callback for a successful client connection.
+  OnClientConnectedCallback connect_callback_;
+
+  // Context for client connected callback.
+  void* connect_context_;
+
+  // Callback for a client dump request.
+  OnClientDumpRequestCallback dump_callback_;
+
+  // Context for client dump request callback.
+  void* dump_context_;
+
+  // Callback for client process exit.
+  OnClientExitedCallback exit_callback_;
+
+  // Context for client process exit callback.
+  void* exit_context_;
+
+  // Callback for upload request.
+  OnClientUploadRequestCallback upload_request_callback_;
+
+  // Context for upload request callback.
+  void* upload_context_;
+
+  // Whether to generate dumps.
+  bool generate_dumps_;
+
+  // Wether to populate custom information up-front.
+  bool pre_fetch_custom_info_;
+
+  // The dump path for the server.
+  const std::wstring dump_path_;
+
+  // State of the server in performing the IPC with the client.
+  // Note that since we restrict the pipe to one instance, we
+  // only need to keep one state of the server. Otherwise, server
+  // would have one state per client it is talking to.
+  IPCServerState server_state_;
+
+  // Whether the server is shutting down.
+  bool shutting_down_;
+
+  // Overlapped instance for async I/O on the pipe.
+  OVERLAPPED overlapped_;
+
+  // Message object used in IPC with the client.
+  ProtocolMessage msg_;
+
+  // Client Info for the client that's connecting to the server.
+  ClientInfo* client_info_;
+
+  // Disable copy ctor and operator=.
+  CrashGenerationServer(const CrashGenerationServer& crash_server);
+  CrashGenerationServer& operator=(const CrashGenerationServer& crash_server);
+};
+
+}  // namespace google_breakpad
+
+#endif  // CLIENT_WINDOWS_CRASH_GENERATION_CRASH_GENERATION_SERVER_H__
diff --git a/include/breakpad/client/windows/crash_generation/minidump_generator.h b/include/breakpad/client/windows/crash_generation/minidump_generator.h
new file mode 100644
index 0000000..a3c1230
--- /dev/null
+++ b/include/breakpad/client/windows/crash_generation/minidump_generator.h
@@ -0,0 +1,199 @@
+// 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_MINIDUMP_GENERATOR_H_
+#define CLIENT_WINDOWS_CRASH_GENERATION_MINIDUMP_GENERATOR_H_
+
+#include <windows.h>
+#include <dbghelp.h>
+#include <rpc.h>
+#include <list>
+#include <string>
+#include "google_breakpad/common/minidump_format.h"
+
+namespace google_breakpad {
+
+// Abstraction for various objects and operations needed to generate
+// minidump on Windows. This abstraction is useful to hide all the gory
+// details for minidump generation and provide a clean interface to
+// the clients to generate minidumps.
+class MinidumpGenerator {
+ public:
+  // Creates an instance with the given parameters.
+  // is_client_pointers specifies whether the exception_pointers and
+  // assert_info point into the process that is being dumped.
+  // Before calling WriteMinidump on the returned instance a dump file muct be
+  // specified by a call to either SetDumpFile() or GenerateDumpFile().
+  // If a full dump file will be requested via a subsequent call to either
+  // SetFullDumpFile or GenerateFullDumpFile() dump_type must include
+  // MiniDumpWithFullMemory.
+  MinidumpGenerator(const std::wstring& dump_path,
+                    const HANDLE process_handle,
+                    const DWORD process_id,
+                    const DWORD thread_id,
+                    const DWORD requesting_thread_id,
+                    EXCEPTION_POINTERS* exception_pointers,
+                    MDRawAssertionInfo* assert_info,
+                    const MINIDUMP_TYPE dump_type,
+                    const bool is_client_pointers);
+
+  ~MinidumpGenerator();
+
+  void SetDumpFile(const HANDLE dump_file) { dump_file_ = dump_file; }
+  void SetFullDumpFile(const HANDLE full_dump_file) {
+    full_dump_file_ = full_dump_file;
+  }
+
+  // Generate the name for the dump file that will be written to once
+  // WriteMinidump() is called. Can only be called once and cannot be called
+  // if the dump file is set via SetDumpFile().
+  bool GenerateDumpFile(std::wstring* dump_path);
+
+  // Generate the name for the full dump file that will be written to once
+  // WriteMinidump() is called. Cannot be called unless the minidump type
+  // includes MiniDumpWithFullMemory. Can only be called once and cannot be
+  // called if the dump file is set via SetFullDumpFile().
+  bool GenerateFullDumpFile(std::wstring* full_dump_path);
+
+  void SetAdditionalStreams(
+      MINIDUMP_USER_STREAM_INFORMATION* additional_streams) {
+    additional_streams_ = additional_streams;
+  }
+
+  void SetCallback(MINIDUMP_CALLBACK_INFORMATION* callback_info) {
+    callback_info_ = callback_info;
+  }
+
+  // Writes the minidump with the given parameters. Stores the
+  // dump file path in the dump_path parameter if dump generation
+  // succeeds.
+  bool WriteMinidump();
+
+ private:
+  // Function pointer type for MiniDumpWriteDump, which is looked up
+  // dynamically.
+  typedef BOOL (WINAPI* MiniDumpWriteDumpType)(
+      HANDLE hProcess,
+      DWORD ProcessId,
+      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* UuidCreateType)(UUID* Uuid);
+
+  // Loads the appropriate DLL lazily in a thread safe way.
+  HMODULE GetDbghelpModule();
+
+  // Loads the appropriate DLL and gets a pointer to the MiniDumpWriteDump
+  // function lazily and in a thread-safe manner.
+  MiniDumpWriteDumpType GetWriteDump();
+
+  // Loads the appropriate DLL lazily in a thread safe way.
+  HMODULE GetRpcrt4Module();
+
+  // Loads the appropriate DLL and gets a pointer to the UuidCreate
+  // function lazily and in a thread-safe manner.
+  UuidCreateType GetCreateUuid();
+
+  // Returns the path for the file to write dump to.
+  bool GenerateDumpFilePath(std::wstring* file_path);
+
+  // Handle to dynamically loaded DbgHelp.dll.
+  HMODULE dbghelp_module_;
+
+  // Pointer to the MiniDumpWriteDump function.
+  MiniDumpWriteDumpType write_dump_;
+
+  // Handle to dynamically loaded rpcrt4.dll.
+  HMODULE rpcrt4_module_;
+
+  // Pointer to the UuidCreate function.
+  UuidCreateType create_uuid_;
+
+  // Handle for the process to dump.
+  HANDLE process_handle_;
+
+  // Process ID for the process to dump.
+  DWORD process_id_;
+
+  // The crashing thread ID.
+  DWORD thread_id_;
+
+  // The thread ID which is requesting the dump.
+  DWORD requesting_thread_id_;
+
+  // Pointer to the exception information for the crash. This may point to an
+  // address in the crashing process so it should not be dereferenced.
+  EXCEPTION_POINTERS* exception_pointers_;
+
+  // Assertion info for the report.
+  MDRawAssertionInfo* assert_info_;
+
+  // Type of minidump to generate.
+  MINIDUMP_TYPE dump_type_;
+
+  // Specifies whether the exception_pointers_ reference memory in the crashing
+  // process.
+  bool is_client_pointers_;
+
+  // Folder path to store dump files.
+  std::wstring dump_path_;
+
+  // The file where the dump will be written.
+  HANDLE dump_file_;
+
+  // The file where the full dump will be written.
+  HANDLE full_dump_file_;
+
+  // Tracks whether the dump file handle is managed externally.
+  bool dump_file_is_internal_;
+
+  // Tracks whether the full dump file handle is managed externally.
+  bool full_dump_file_is_internal_;
+
+  // Additional streams to be written to the dump.
+  MINIDUMP_USER_STREAM_INFORMATION* additional_streams_;
+
+  // The user defined callback for the various stages of the dump process.
+  MINIDUMP_CALLBACK_INFORMATION* callback_info_;
+
+  // Critical section to sychronize action of loading modules dynamically.
+  CRITICAL_SECTION module_load_sync_;
+
+  // Critical section to synchronize action of dynamically getting function
+  // addresses from modules.
+  CRITICAL_SECTION get_proc_address_sync_;
+};
+
+}  // namespace google_breakpad
+
+#endif  // CLIENT_WINDOWS_CRASH_GENERATION_MINIDUMP_GENERATOR_H_
diff --git a/include/breakpad/client/windows/handler/exception_handler.h b/include/breakpad/client/windows/handler/exception_handler.h
new file mode 100644
index 0000000..e3cd814
--- /dev/null
+++ b/include/breakpad/client/windows/handler/exception_handler.h
@@ -0,0 +1,522 @@
+// 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 <list>
+#include <string>
+#include <vector>
+
+#include "client/windows/common/ipc_protocol.h"
+#include "client/windows/crash_generation/crash_generation_client.h"
+#include "common/scoped_ptr.h"
+#include "google_breakpad/common/minidump_format.h"
+
+namespace google_breakpad {
+
+using std::vector;
+using std::wstring;
+
+// These entries store a list of memory regions that the client wants included
+// in the minidump.
+struct AppMemory {
+  ULONG64 ptr;
+  ULONG length;
+
+  bool operator==(const struct AppMemory& other) const {
+    return ptr == other.ptr;
+  }
+
+  bool operator==(const void* other) const {
+    return ptr == reinterpret_cast<ULONG64>(other);
+  }
+};
+typedef std::list<AppMemory> AppMemoryList;
+
+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 that ENSURES out-of-process dump generation.  Expects a
+  // crash generation client that is already registered with a crash generation
+  // server.  Takes ownership of the passed-in crash_generation_client.
+  //
+  // Usage example:
+  //   crash_generation_client = new CrashGenerationClient(..);
+  //   if (crash_generation_client->Register()) {
+  //     // Registration with the crash generation server succeeded.
+  //     // Out-of-process dump generation is guaranteed.
+  //     g_handler = new ExceptionHandler(.., crash_generation_client, ..);
+  //     return true;
+  //   }
+  ExceptionHandler(const wstring& dump_path,
+                   FilterCallback filter,
+                   MinidumpCallback callback,
+                   void* callback_context,
+                   int handler_types,
+                   CrashGenerationClient* crash_generation_client);
+
+  ~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);
+
+  // Write a minidump of |child| immediately.  This can be used to
+  // capture the execution state of |child| independently of a crash.
+  // Pass a meaningful |child_blamed_thread| to make that thread in
+  // the child process the one from which a crash signature is
+  // extracted.
+  static bool WriteMinidumpForChild(HANDLE child,
+                                    DWORD child_blamed_thread,
+                                    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;
+  }
+
+  // Controls behavior of EXCEPTION_INVALID_HANDLE.
+  bool get_consume_invalid_handle_exceptions() const {
+    return consume_invalid_handle_exceptions_;
+  }
+  void set_consume_invalid_handle_exceptions(
+      bool consume_invalid_handle_exceptions) {
+    consume_invalid_handle_exceptions_ = consume_invalid_handle_exceptions;
+  }
+
+  // Returns whether out-of-process dump generation is used or not.
+  bool IsOutOfProcess() const { return crash_generation_client_.get() != NULL; }
+
+  // Calling RegisterAppMemory(p, len) causes len bytes starting
+  // at address p to be copied to the minidump when a crash happens.
+  void RegisterAppMemory(void* ptr, size_t length);
+  void UnregisterAppMemory(void* ptr);
+
+ 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,
+                  CrashGenerationClient* crash_generation_client,
+                  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 is called on the handler thread.  It calls into
+  // WriteMinidumpWithExceptionForProcess() with a handle to the
+  // current process.  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);
+
+  // 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 that information is
+  // meaningful.  If the dump is requested as a result of an
+  // exception, exinfo contains exception information, otherwise, it
+  // is NULL.  process is the one that will be dumped.  If
+  // requesting_thread_id is meaningful and should be added to the
+  // minidump, write_requester_stream is |true|.
+  bool WriteMinidumpWithExceptionForProcess(DWORD requesting_thread_id,
+                                            EXCEPTION_POINTERS* exinfo,
+                                            MDRawAssertionInfo* assertion,
+                                            HANDLE process,
+                                            bool write_requester_stream);
+
+  // 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_;
+
+  // If true, the handler will consume any EXCEPTION_INVALID_HANDLE exceptions.
+  // Leave this false (the default) to handle these exceptions as normal.
+  bool consume_invalid_handle_exceptions_;
+
+  // Callers can request additional memory regions to be included in
+  // the dump.
+  AppMemoryList app_memory_info_;
+
+  // 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.
+  static volatile 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/include/breakpad/client/windows/sender/crash_report_sender.h b/include/breakpad/client/windows/sender/crash_report_sender.h
new file mode 100644
index 0000000..da1ed0a
--- /dev/null
+++ b/include/breakpad/client/windows/sender/crash_report_sender.h
@@ -0,0 +1,125 @@
+// 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.
+
+#ifndef CLIENT_WINDOWS_SENDER_CRASH_REPORT_SENDER_H__
+#define CLIENT_WINDOWS_SENDER_CRASH_REPORT_SENDER_H__
+
+// CrashReportSender is a "static" class which provides an API to upload
+// crash reports via HTTP(S).  A crash report is formatted as a multipart POST
+// request, which contains a set of caller-supplied string key/value pairs,
+// and a minidump file to upload.
+//
+// To use this library in your project, you will need to link against
+// wininet.lib.
+
+#pragma warning( push )
+// Disable exception handler warnings.
+#pragma warning( disable : 4530 ) 
+
+#include <map>
+#include <string>
+
+namespace google_breakpad {
+
+using std::wstring;
+using std::map;
+
+typedef enum {
+  RESULT_FAILED = 0,  // Failed to communicate with the server; try later.
+  RESULT_REJECTED,    // Successfully sent the crash report, but the
+                      // server rejected it; don't resend this report.
+  RESULT_SUCCEEDED,   // The server accepted the crash report.
+  RESULT_THROTTLED    // No attempt was made to send the crash report, because
+                      // we exceeded the maximum reports per day.
+} ReportResult;
+
+class CrashReportSender {
+ public:
+  // Initializes a CrashReportSender instance.
+  // If checkpoint_file is non-empty, breakpad will persist crash report
+  // state to this file.  A checkpoint file is required for
+  // set_max_reports_per_day() to function properly.
+  explicit CrashReportSender(const wstring &checkpoint_file);
+  ~CrashReportSender() {}
+
+  // Sets the maximum number of crash reports that will be sent in a 24-hour
+  // period.  This uses the state persisted to the checkpoint file.
+  // The default value of -1 means that there is no limit on reports sent.
+  void set_max_reports_per_day(int reports) {
+    max_reports_per_day_ = reports;
+  }
+
+  int max_reports_per_day() const { return max_reports_per_day_; }
+
+  // Sends the specified minidump file, along with the map of
+  // name value pairs, as a multipart POST request to the given URL.
+  // Parameter names must contain only printable ASCII characters,
+  // and may not contain a quote (") character.
+  // Only HTTP(S) URLs are currently supported.  The return value indicates
+  // the result of the operation (see above for possible results).
+  // If report_code is non-NULL and the report is sent successfully (that is,
+  // the return value is RESULT_SUCCEEDED), a code uniquely identifying the
+  // report will be returned in report_code.
+  // (Otherwise, report_code will be unchanged.)
+  ReportResult SendCrashReport(const wstring &url,
+                               const map<wstring, wstring> &parameters,
+                               const wstring &dump_file_name,
+                               wstring *report_code);
+
+ private:
+  // Reads persistent state from a checkpoint file.
+  void ReadCheckpoint(FILE *fd);
+
+  // Called when a new report has been sent, to update the checkpoint state.
+  void ReportSent(int today);
+
+  // Returns today's date (UTC) formatted as YYYYMMDD.
+  int GetCurrentDate() const;
+
+  // Opens the checkpoint file with the specified mode.
+  // Returns zero on success, or an error code on failure.
+  int OpenCheckpointFile(const wchar_t *mode, FILE **fd);
+
+  wstring checkpoint_file_;
+  int max_reports_per_day_;
+  // The last date on which we sent a report, expressed as YYYYMMDD.
+  int last_sent_date_;
+  // Number of reports sent on last_sent_date_
+  int reports_sent_;
+
+  // Disallow copy constructor and operator=
+  explicit CrashReportSender(const CrashReportSender &);
+  void operator=(const CrashReportSender &);
+};
+
+}  // namespace google_breakpad
+
+#pragma warning( pop )
+
+#endif  // CLIENT_WINDOWS_SENDER_CRASH_REPORT_SENDER_H__
diff --git a/include/breakpad/client/windows/tests/crash_generation_app/abstract_class.h b/include/breakpad/client/windows/tests/crash_generation_app/abstract_class.h
new file mode 100644
index 0000000..e3f2a4f
--- /dev/null
+++ b/include/breakpad/client/windows/tests/crash_generation_app/abstract_class.h
@@ -0,0 +1,57 @@
+// 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_TESTS_CRASH_GENERATION_APP_ABSTRACT_CLASS_H__
+#define CLIENT_WINDOWS_TESTS_CRASH_GENERATION_APP_ABSTRACT_CLASS_H__
+
+namespace google_breakpad {
+
+// Dummy classes to help generate a pure call violation.
+
+class Derived;
+
+class Base {
+ public:
+  Base(Derived* derived);
+  virtual ~Base();
+  virtual void DoSomething() = 0;
+
+ private:
+  Derived* derived_;
+};
+
+class Derived : public Base {
+ public:
+  Derived();
+  virtual void DoSomething();
+};
+
+}  // namespace google_breakpad
+
+#endif  // CLIENT_WINDOWS_TESTS_CRASH_GENERATION_APP_CRASH_GENERATION_APP_H__
diff --git a/include/breakpad/client/windows/tests/crash_generation_app/crash_generation_app.h b/include/breakpad/client/windows/tests/crash_generation_app/crash_generation_app.h
new file mode 100644
index 0000000..4d3bb6e
--- /dev/null
+++ b/include/breakpad/client/windows/tests/crash_generation_app/crash_generation_app.h
@@ -0,0 +1,35 @@
+// 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_TESTS_CRASH_GENERATION_APP_CRASH_GENERATION_APP_H__
+#define CLIENT_WINDOWS_TESTS_CRASH_GENERATION_APP_CRASH_GENERATION_APP_H__
+
+#include "resource.h"
+
+#endif  // CLIENT_WINDOWS_TESTS_CRASH_GENERATION_APP_CRASH_GENERATION_APP_H__
diff --git a/include/breakpad/client/windows/tests/crash_generation_app/resource.h b/include/breakpad/client/windows/tests/crash_generation_app/resource.h
new file mode 100644
index 0000000..8c7f657
--- /dev/null
+++ b/include/breakpad/client/windows/tests/crash_generation_app/resource.h
@@ -0,0 +1,73 @@
+// 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.
+
+// PreCompile.h : include file for standard system include files,
+// or project specific include files that are used frequently, but
+// are changed infrequently
+//
+
+#ifndef CLIENT_WINDOWS_TESTS_CRASH_GENERATION_APP_RESOURCE_H__
+#define CLIENT_WINDOWS_TESTS_CRASH_GENERATION_APP_RESOURCE_H__
+
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by crash_generation_app.rc
+//
+#define IDC_MYICON                      2
+#define IDD_CRASHGENERATIONAPP_DIALOG   102
+#define IDS_APP_TITLE                   103
+#define IDD_ABOUTBOX                    103
+#define IDM_ABOUT                       104
+#define IDM_EXIT                        105
+#define IDI_CRASHGENERATIONAPP          107
+#define IDI_SMALL                       108
+#define IDC_CRASHGENERATIONAPP          109
+#define IDR_MAINFRAME                   128
+#define ID_SERVER_START                 32771
+#define ID_SERVER_STOP                  32772
+#define ID_CLIENT_INVALIDPARAM          32773
+#define ID_CLIENT_ASSERTFAILURE         32774
+#define ID_CLIENT_DEREFZERO             32775
+#define ID_CLIENT_PURECALL              32777
+#define ID_CLIENT_REQUESTEXPLICITDUMP   32778
+#define IDC_STATIC                      -1
+
+// Next default values for new objects
+// 
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NO_MFC                     1
+#define _APS_NEXT_RESOURCE_VALUE        129
+#define _APS_NEXT_COMMAND_VALUE         32780
+#define _APS_NEXT_CONTROL_VALUE         1000
+#define _APS_NEXT_SYMED_VALUE           110
+#endif
+#endif
+
+#endif  // CLIENT_WINDOWS_TESTS_CRASH_GENERATION_APP_RESOURCE_H__
diff --git a/include/breakpad/client/windows/unittests/dump_analysis.h b/include/breakpad/client/windows/unittests/dump_analysis.h
new file mode 100644
index 0000000..6cef48d
--- /dev/null
+++ b/include/breakpad/client/windows/unittests/dump_analysis.h
@@ -0,0 +1,102 @@
+// 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 CLIENT_WINDOWS_UNITTESTS_DUMP_ANALYSIS_H_
+#define CLIENT_WINDOWS_UNITTESTS_DUMP_ANALYSIS_H_
+
+#include "client/windows/crash_generation/minidump_generator.h"
+
+// Convenience to get to the PEB pointer in a TEB.
+struct FakeTEB {
+  char dummy[0x30];
+  void* peb;
+};
+
+class DumpAnalysis {
+ public:
+  explicit DumpAnalysis(const std::wstring& file_path)
+      : dump_file_(file_path), dump_file_view_(NULL), dump_file_mapping_(NULL),
+        dump_file_handle_(NULL) {
+    EnsureDumpMapped();
+  }
+  ~DumpAnalysis();
+
+  bool HasStream(ULONG stream_number) const;
+
+  // This is template to keep type safety in the front, but we end up casting
+  // to void** inside the implementation to pass the pointer to Win32. So
+  // casting here is considered safe.
+  template <class StreamType>
+  size_t GetStream(ULONG stream_number, StreamType** stream) const {
+    return GetStreamImpl(stream_number, reinterpret_cast<void**>(stream));
+  }
+
+  bool HasTebs() const;
+  bool HasPeb() const;
+  bool HasMemory(ULONG64 address) const {
+    return HasMemory<BYTE>(address, NULL);
+  }
+
+  bool HasMemory(const void* address) const {
+    return HasMemory<BYTE>(address, NULL);
+  }
+
+  template <class StructureType>
+  bool HasMemory(ULONG64 address, StructureType** structure = NULL) const {
+    // We can't cope with 64 bit addresses for now.
+    if (address > 0xFFFFFFFFUL)
+      return false;
+
+    return HasMemory(reinterpret_cast<void*>(address), structure);
+  }
+
+  template <class StructureType>
+  bool HasMemory(const void* addr_in, StructureType** structure = NULL) const {
+    return HasMemoryImpl(addr_in, sizeof(StructureType),
+                             reinterpret_cast<void**>(structure));
+  }
+
+ protected:
+  void EnsureDumpMapped();
+
+  HANDLE dump_file_mapping_;
+  HANDLE dump_file_handle_;
+  void* dump_file_view_;
+  std::wstring dump_file_;
+
+ private:
+  // This is the implementation of GetStream<>.
+  size_t GetStreamImpl(ULONG stream_number, void** stream) const;
+
+  // This is the implementation of HasMemory<>.
+  bool HasMemoryImpl(const void* addr_in, size_t pointersize,
+                     void** structure) const;
+};
+
+#endif  // CLIENT_WINDOWS_UNITTESTS_DUMP_ANALYSIS_H_
diff --git a/include/breakpad/client/windows/unittests/exception_handler_test.h b/include/breakpad/client/windows/unittests/exception_handler_test.h
new file mode 100644
index 0000000..ef973e5
--- /dev/null
+++ b/include/breakpad/client/windows/unittests/exception_handler_test.h
@@ -0,0 +1,61 @@
+// Copyright 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 CLIENT_WINDOWS_UNITTESTS_EXCEPTION_HANDLER_TEST_H_
+#define CLIENT_WINDOWS_UNITTESTS_EXCEPTION_HANDLER_TEST_H_
+
+namespace testing {
+
+// By default, GTest (on Windows) installs a SEH filter (and a handler) before
+// starting to run all the tests in order to avoid test interruptions is some
+// of the tests are crashing.  Unfortunately, this functionality prevents the
+// execution to reach the UnhandledExceptionFilter installed by Google-Breakpad
+// ExceptionHandler so in order to test the Google-Breakpad exception handling
+// code the exception handling done by GTest must be disabled.
+// Usage:
+//
+//  google_breakpad::ExceptionHandler exc(...);
+//
+//  // Disable GTest SEH handler
+//  testing::DisableExceptionHandlerInScope disable_exception_handler;
+//  ...
+//  ASSERT_DEATH( ... some crash ...);
+//
+class DisableExceptionHandlerInScope {
+ public:
+  DisableExceptionHandlerInScope();
+  ~DisableExceptionHandlerInScope();
+
+ private:
+  bool catch_exceptions_;
+};
+
+}  // namespace testing
+
+#endif  // CLIENT_WINDOWS_UNITTESTS_EXCEPTION_HANDLER_TEST_H_
diff --git a/include/breakpad/common/android/include/elf.h b/include/breakpad/common/android/include/elf.h
new file mode 100644
index 0000000..b2a28df
--- /dev/null
+++ b/include/breakpad/common/android/include/elf.h
@@ -0,0 +1,168 @@
+// 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 GOOGLE_BREAKPAD_COMMON_ANDROID_INCLUDE_ELF_H
+#define GOOGLE_BREAKPAD_COMMON_ANDROID_INCLUDE_ELF_H
+
+#include <stdint.h>
+#include <libgen.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif  // __cplusplus
+
+// The Android <elf.h> provides BSD-based definitions for the ElfXX_Nhdr
+// types
+// always source-compatible with the GLibc/kernel ones. To overcome this
+// issue without modifying a lot of code in Breakpad, use an ugly macro
+// renaming trick with #include_next
+
+// Avoid conflict with BSD-based definition of ElfXX_Nhdr.
+// Unfortunately, their field member names do not use a 'n_' prefix.
+#define Elf32_Nhdr   __bsd_Elf32_Nhdr
+#define Elf64_Nhdr   __bsd_Elf64_Nhdr
+
+// In case they are defined by the NDK version
+#define Elf32_auxv_t  __bionic_Elf32_auxv_t
+#define Elf64_auxv_t  __bionic_Elf64_auxv_t
+
+#define Elf32_Dyn     __bionic_Elf32_Dyn
+#define Elf64_Dyn     __bionic_Elf64_Dyn
+
+#include_next <elf.h>
+
+#undef Elf32_Nhdr
+#undef Elf64_Nhdr
+
+typedef struct {
+  Elf32_Word n_namesz;
+  Elf32_Word n_descsz;
+  Elf32_Word n_type;
+} Elf32_Nhdr;
+
+typedef struct {
+  Elf64_Word n_namesz;
+  Elf64_Word n_descsz;
+  Elf64_Word n_type;
+} Elf64_Nhdr;
+
+#undef Elf32_auxv_t
+#undef Elf64_auxv_t
+
+typedef struct {
+    uint32_t a_type;
+    union {
+      uint32_t a_val;
+    } a_un;
+} Elf32_auxv_t;
+
+typedef struct {
+    uint64_t a_type;
+    union {
+      uint64_t a_val;
+    } a_un;
+} Elf64_auxv_t;
+
+#undef Elf32_Dyn
+#undef Elf64_Dyn
+
+typedef struct {
+  Elf32_Sword   d_tag;
+  union {
+    Elf32_Word  d_val;
+    Elf32_Addr  d_ptr;
+  } d_un;
+} Elf32_Dyn;
+
+typedef struct {
+  Elf64_Sxword   d_tag;
+  union {
+    Elf64_Xword  d_val;
+    Elf64_Addr   d_ptr;
+  } d_un;
+} Elf64_Dyn;
+
+
+// __WORDSIZE is GLibc-specific and used by Google Breakpad on Linux.
+#ifndef __WORDSIZE
+#if defined(__i386__) ||  defined(__ARM_EABI__) || defined(__mips__)
+#define __WORDSIZE 32
+#elif defined(__x86_64__) || defined(__aarch64__)
+#define __WORDSIZE 64
+#else
+#error "Unsupported Android CPU ABI"
+#endif
+#endif
+
+// The Android headers don't always define this constant.
+#ifndef EM_X86_64
+#define EM_X86_64  62
+#endif
+
+#ifndef EM_PPC64
+#define EM_PPC64   21
+#endif
+
+#ifndef EM_S390
+#define EM_S390    22
+#endif
+
+#if !defined(AT_SYSINFO_EHDR)
+#define AT_SYSINFO_EHDR 33
+#endif
+
+#if !defined(NT_PRSTATUS)
+#define NT_PRSTATUS 1
+#endif
+
+#if !defined(NT_PRPSINFO)
+#define NT_PRPSINFO 3
+#endif
+
+#if !defined(NT_AUXV)
+#define NT_AUXV   6
+#endif
+
+#if !defined(NT_PRXFPREG)
+#define NT_PRXFPREG 0x46e62b7f
+#endif
+
+#if !defined(NT_FPREGSET)
+#define NT_FPREGSET 2
+#endif
+
+#if !defined(SHT_MIPS_DWARF)
+#define SHT_MIPS_DWARF 0x7000001e
+#endif
+
+#ifdef __cplusplus
+}  // extern "C"
+#endif  // __cplusplus
+
+#endif  // GOOGLE_BREAKPAD_COMMON_ANDROID_INCLUDE_ELF_H
diff --git a/include/breakpad/common/android/include/link.h b/include/breakpad/common/android/include/link.h
new file mode 100644
index 0000000..e7ff8e2
--- /dev/null
+++ b/include/breakpad/common/android/include/link.h
@@ -0,0 +1,71 @@
+// 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 GOOGLE_BREAKPAD_ANDROID_INCLUDE_LINK_H
+#define GOOGLE_BREAKPAD_ANDROID_INCLUDE_LINK_H
+
+/* Android doesn't provide all the data-structures required in its <link.h>.
+   Provide custom version here. */
+#include_next <link.h>
+
+// TODO(rmcilroy): Remove this file once the ndk is updated for other
+// architectures - crbug.com/358831
+#if !defined(__aarch64__) && !defined(__x86_64__) && \
+    !(defined(__mips__) && _MIPS_SIM == _ABI64)
+
+#ifdef __cplusplus
+extern "C" {
+#endif  // __cplusplus
+
+struct r_debug {
+  int              r_version;
+  struct link_map* r_map;
+  ElfW(Addr)       r_brk;
+  enum {
+    RT_CONSISTENT,
+    RT_ADD,
+    RT_DELETE }    r_state;
+  ElfW(Addr)       r_ldbase;
+};
+
+struct link_map {
+  ElfW(Addr)       l_addr;
+  char*            l_name;
+  ElfW(Dyn)*       l_ld;
+  struct link_map* l_next;
+  struct link_map* l_prev;
+};
+
+#ifdef __cplusplus
+}  // extern "C"
+#endif  // __cplusplus
+
+#endif  // !defined(__aarch64__) && !defined(__x86_64__)
+
+#endif /* GOOGLE_BREAKPAD_ANDROID_INCLUDE_LINK_H */
diff --git a/include/breakpad/common/android/include/sgidefs.h b/include/breakpad/common/android/include/sgidefs.h
new file mode 100644
index 0000000..33796dc
--- /dev/null
+++ b/include/breakpad/common/android/include/sgidefs.h
@@ -0,0 +1,41 @@
+// Copyright (c) 2013, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef GOOGLE_BREAKPAD_ANDROID_INCLUDE_SGIDEFS_H
+#define GOOGLE_BREAKPAD_ANDROID_INCLUDE_SGIDEFS_H
+
+#ifdef __mips__
+
+// Android doesn't contain sgidefs.h, but does have <asm/sgidefs.h> which
+// contains what we need.
+#include <asm/sgidefs.h>
+
+#endif  // __mips__
+
+#endif  // GOOGLE_BREAKPAD_ANDROID_INCLUDE_SGIDEFS_H
diff --git a/include/breakpad/common/android/include/stab.h b/include/breakpad/common/android/include/stab.h
new file mode 100644
index 0000000..cd92902
--- /dev/null
+++ b/include/breakpad/common/android/include/stab.h
@@ -0,0 +1,100 @@
+// 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 GOOGLE_BREAKPAD_COMMON_ANDROID_INCLUDE_STAB_H
+#define GOOGLE_BREAKPAD_COMMON_ANDROID_INCLUDE_STAB_H
+
+#include <sys/cdefs.h>
+
+#ifdef __BIONIC_HAVE_STAB_H
+#include <stab.h>
+#else
+
+#ifdef __cplusplus
+extern "C" {
+#endif  // __cplusplus
+
+#define _STAB_CODE_LIST       \
+  _STAB_CODE_DEF(UNDF,0x00)   \
+  _STAB_CODE_DEF(GSYM,0x20)   \
+  _STAB_CODE_DEF(FNAME,0x22)  \
+  _STAB_CODE_DEF(FUN,0x24)    \
+  _STAB_CODE_DEF(STSYM,0x26)  \
+  _STAB_CODE_DEF(LCSYM,0x28)  \
+  _STAB_CODE_DEF(MAIN,0x2a)   \
+  _STAB_CODE_DEF(PC,0x30)     \
+  _STAB_CODE_DEF(NSYMS,0x32)  \
+  _STAB_CODE_DEF(NOMAP,0x34)  \
+  _STAB_CODE_DEF(OBJ,0x38)    \
+  _STAB_CODE_DEF(OPT,0x3c)    \
+  _STAB_CODE_DEF(RSYM,0x40)   \
+  _STAB_CODE_DEF(M2C,0x42)    \
+  _STAB_CODE_DEF(SLINE,0x44)  \
+  _STAB_CODE_DEF(DSLINE,0x46) \
+  _STAB_CODE_DEF(BSLINE,0x48) \
+  _STAB_CODE_DEF(BROWS,0x48)  \
+  _STAB_CODE_DEF(DEFD,0x4a)   \
+  _STAB_CODE_DEF(EHDECL,0x50) \
+  _STAB_CODE_DEF(MOD2,0x50)   \
+  _STAB_CODE_DEF(CATCH,0x54)  \
+  _STAB_CODE_DEF(SSYM,0x60)   \
+  _STAB_CODE_DEF(SO,0x64)     \
+  _STAB_CODE_DEF(LSYM,0x80)   \
+  _STAB_CODE_DEF(BINCL,0x82)  \
+  _STAB_CODE_DEF(SOL,0x84)    \
+  _STAB_CODE_DEF(PSYM,0xa0)   \
+  _STAB_CODE_DEF(EINCL,0xa2)  \
+  _STAB_CODE_DEF(ENTRY,0xa4)  \
+  _STAB_CODE_DEF(LBRAC,0xc0)  \
+  _STAB_CODE_DEF(EXCL,0xc2)   \
+  _STAB_CODE_DEF(SCOPE,0xc4)  \
+  _STAB_CODE_DEF(RBRAC,0xe0)  \
+  _STAB_CODE_DEF(BCOMM,0xe2)  \
+  _STAB_CODE_DEF(ECOMM,0xe4)  \
+  _STAB_CODE_DEF(ECOML,0xe8)  \
+  _STAB_CODE_DEF(NBTEXT,0xf0) \
+  _STAB_CODE_DEF(NBDATA,0xf2) \
+  _STAB_CODE_DEF(NBBSS,0xf4)  \
+  _STAB_CODE_DEF(NBSTS,0xf6)  \
+  _STAB_CODE_DEF(NBLCS,0xf8)  \
+  _STAB_CODE_DEF(LENG,0xfe)
+
+enum __stab_debug_code {
+#define _STAB_CODE_DEF(x,y)  N_##x = y,
+_STAB_CODE_LIST
+#undef _STAB_CODE_DEF
+};
+
+#ifdef __cplusplus
+}  // extern "C"
+#endif  // __cplusplus
+
+#endif  // __BIONIC_HAVE_STAB_H
+
+#endif  // GOOGLE_BREAKPAD_COMMON_ANDROID_INCLUDE_STAB_H
diff --git a/include/breakpad/common/android/include/sys/procfs.h b/include/breakpad/common/android/include/sys/procfs.h
new file mode 100644
index 0000000..27223ea
--- /dev/null
+++ b/include/breakpad/common/android/include/sys/procfs.h
@@ -0,0 +1,124 @@
+// 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 GOOGLE_BREAKPAD_COMMON_ANDROID_SYS_PROCFS_H
+#define GOOGLE_BREAKPAD_COMMON_ANDROID_SYS_PROCFS_H
+
+#ifdef __BIONIC_HAVE_SYS_PROCFS_H
+
+#include_next <sys/procfs.h>
+
+#else
+
+#include <asm/ptrace.h>
+#include <sys/cdefs.h>
+#if defined (__mips__)
+#include <sys/types.h>
+#endif
+#include <sys/user.h>
+#include <unistd.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif  // __cplusplus
+
+#if defined(__x86_64__) || defined(__aarch64__)
+typedef unsigned long long elf_greg_t;
+#else
+typedef unsigned long  elf_greg_t;
+#endif
+
+#ifdef __arm__
+#define ELF_NGREG (sizeof(struct user_regs) / sizeof(elf_greg_t))
+#elif defined(__aarch64__)
+#define ELF_NGREG (sizeof(struct user_pt_regs) / sizeof(elf_greg_t))
+#elif defined(__mips__)
+#define ELF_NGREG 45
+#else
+#define ELF_NGREG (sizeof(struct user_regs_struct) / sizeof(elf_greg_t))
+#endif
+
+typedef elf_greg_t elf_gregset_t[ELF_NGREG];
+
+struct elf_siginfo {
+  int si_signo;
+  int si_code;
+  int si_errno;
+};
+
+struct elf_prstatus {
+  struct elf_siginfo pr_info;
+  short              pr_cursig;
+  unsigned long      pr_sigpend;
+  unsigned long      pr_sighold;
+  pid_t              pr_pid;
+  pid_t              pr_ppid;
+  pid_t              pr_pgrp;
+  pid_t              pd_sid;
+  struct timeval     pr_utime;
+  struct timeval     pr_stime;
+  struct timeval     pr_cutime;
+  struct timeval     pr_cstime;
+  elf_gregset_t      pr_reg;
+  int                pr_fpvalid;
+};
+
+#define ELF_PRARGSZ 80
+
+struct elf_prpsinfo {
+  char           pr_state;
+  char           pr_sname;
+  char           pr_zomb;
+  char           pr_nice;
+  unsigned long  pr_flags;
+#ifdef __x86_64__
+  unsigned int   pr_uid;
+  unsigned int   pr_gid;
+#elif defined(__mips__)
+  unsigned long  pr_uid;
+  unsigned long  pr_gid;
+#else
+  unsigned short pr_uid;
+  unsigned short pr_gid;
+#endif
+  int pr_pid;
+  int pr_ppid;
+  int pr_pgrp;
+  int pr_sid;
+  char pr_fname[16];
+  char pr_psargs[ELF_PRARGSZ];
+};
+
+#ifdef __cplusplus
+}  // extern "C"
+#endif  // __cplusplus
+
+#endif  // __BIONIC_HAVE_SYS_PROCFS_H
+
+#endif  // GOOGLE_BREAKPAD_COMMON_ANDROID_SYS_PROCFS_H
diff --git a/include/breakpad/common/android/include/sys/signal.h b/include/breakpad/common/android/include/sys/signal.h
new file mode 100644
index 0000000..20c81e9
--- /dev/null
+++ b/include/breakpad/common/android/include/sys/signal.h
@@ -0,0 +1,35 @@
+// 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 GOOGLE_BREAKPAD_COMMON_ANDROID_INCLUDE_SYS_SIGNAL_H
+#define GOOGLE_BREAKPAD_COMMON_ANDROID_INCLUDE_SYS_SIGNAL_H
+
+#include <signal.h>
+
+#endif  // GOOGLE_BREAKPAD_COMMON_ANDROID_INCLUDE_SYS_SIGNAL_H
diff --git a/include/breakpad/common/android/include/sys/user.h b/include/breakpad/common/android/include/sys/user.h
new file mode 100644
index 0000000..5f03604
--- /dev/null
+++ b/include/breakpad/common/android/include/sys/user.h
@@ -0,0 +1,75 @@
+// 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 GOOGLE_BREAKPAD_COMMON_ANDROID_INCLUDE_SYS_USER_H
+#define GOOGLE_BREAKPAD_COMMON_ANDROID_INCLUDE_SYS_USER_H
+
+// The purpose of this file is to glue the mismatching headers (Android NDK vs
+// glibc) and therefore avoid doing otherwise awkward #ifdefs in the code.
+// The following quirks are currently handled by this file:
+// - i386: Use the Android NDK but alias user_fxsr_struct > user_fpxregs_struct.
+// - aarch64: Add missing user_regs_struct and user_fpsimd_struct structs.
+// - Other platforms: Just use the Android NDK unchanged.
+
+// TODO(primiano): remove these changes after Chromium has stably rolled to
+// an NDK with the appropriate fixes.
+
+#include_next <sys/user.h>
+
+#ifdef __i386__
+#ifdef __cplusplus
+extern "C" {
+#endif  // __cplusplus
+typedef struct user_fxsr_struct user_fpxregs_struct;
+#ifdef __cplusplus
+}  // extern "C"
+#endif  // __cplusplus
+#endif  // __i386__
+
+#ifdef __aarch64__
+#ifdef __cplusplus
+extern "C" {
+#endif  // __cplusplus
+struct user_regs_struct {
+ __u64 regs[31];
+ __u64 sp;
+ __u64 pc;
+ __u64 pstate;
+};
+struct user_fpsimd_struct {
+ __uint128_t vregs[32];
+ __u32 fpsr;
+ __u32 fpcr;
+};
+#ifdef __cplusplus
+}  // extern "C"
+#endif  // __cplusplus
+#endif  // __aarch64__
+
+#endif  // GOOGLE_BREAKPAD_COMMON_ANDROID_INCLUDE_SYS_USER_H
diff --git a/include/breakpad/common/android/include/ucontext.h b/include/breakpad/common/android/include/ucontext.h
new file mode 100644
index 0000000..29db8ad
--- /dev/null
+++ b/include/breakpad/common/android/include/ucontext.h
@@ -0,0 +1,56 @@
+// 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 GOOGLE_BREAKPAD_COMMON_ANDROID_INCLUDE_UCONTEXT_H
+#define GOOGLE_BREAKPAD_COMMON_ANDROID_INCLUDE_UCONTEXT_H
+
+#include <sys/cdefs.h>
+
+#ifdef __BIONIC_UCONTEXT_H
+#include <ucontext.h>
+#else
+
+#include <sys/ucontext.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif  // __cplusplus
+
+// Provided by src/android/common/breakpad_getcontext.S
+int breakpad_getcontext(ucontext_t* ucp);
+
+#define getcontext(x)   breakpad_getcontext(x)
+
+#ifdef __cplusplus
+}  // extern "C"
+#endif  // __cplusplus
+
+#endif  // __BIONIC_UCONTEXT_H
+
+#endif  // GOOGLE_BREAKPAD_COMMON_ANDROID_INCLUDE_UCONTEXT_H
diff --git a/include/breakpad/common/android/testing/include/wchar.h b/include/breakpad/common/android/testing/include/wchar.h
new file mode 100644
index 0000000..85373fd
--- /dev/null
+++ b/include/breakpad/common/android/testing/include/wchar.h
@@ -0,0 +1,76 @@
+// 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.
+
+// Android doesn't provide wcscasecmp(), so provide an alternative here.
+//
+// Note that this header is not needed when Breakpad is compiled against
+// a recent version of Googletest. It shall be considered for removal once
+// src/testing/ is updated to an appropriate revision in the future.
+
+#ifndef GOOGLEBREAKPAD_COMMON_ANDROID_INCLUDE_WCHAR_H
+#define GOOGLEBREAKPAD_COMMON_ANDROID_INCLUDE_WCHAR_H
+
+#include_next <wchar.h>
+
+#if !defined(__aarch64__) && !defined(__x86_64__) && \
+    !(defined(__mips__) && _MIPS_SIM == _ABI64)
+
+// This needs to be in an extern "C" namespace, or Googletest will not
+// compile against it.
+#ifdef __cplusplus
+extern "C" {
+#endif  // __cplusplus
+
+static wchar_t inline wcstolower(wchar_t ch) {
+  if (ch >= L'a' && ch <= L'A')
+    ch -= L'a' - L'A';
+  return ch;
+}
+
+static int inline wcscasecmp(const wchar_t* s1, const wchar_t* s2) {
+  for (;;) {
+    wchar_t c1 = wcstolower(*s1);
+    wchar_t c2 = wcstolower(*s2);
+    if (c1 < c2)
+      return -1;
+    if (c1 > c2)
+      return 1;
+    if (c1 == L'0')
+      return 0;
+    s1++;
+    s2++;
+  }
+}
+
+#ifdef __cplusplus
+}  // extern "C"
+#endif  // __cplusplus
+#endif
+
+#endif  // GOOGLEBREAKPAD_COMMON_ANDROID_INCLUDE_WCHAR_H
diff --git a/include/breakpad/common/android/testing/mkdtemp.h b/include/breakpad/common/android/testing/mkdtemp.h
new file mode 100644
index 0000000..b86e2cd
--- /dev/null
+++ b/include/breakpad/common/android/testing/mkdtemp.h
@@ -0,0 +1,110 @@
+// 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.
+
+// mkdtemp() wasn't declared in <stdlib.h> until NDK r9b due to a simple
+// packaging bug (the function has always been implemented in all versions
+// of the C library). This header is provided to build Breakpad with earlier
+// NDK revisions (e.g. the one used by Chromium). It may be removed in the
+// future once all major projects upgrade to use a more recent NDK.
+//
+// The reason this is inlined here is to avoid linking a new object file
+// into each unit test program (i.e. keep build files simple).
+
+#ifndef GOOGLE_BREAKPAD_COMMON_ANDROID_TESTING_MKDTEMP_H
+#define GOOGLE_BREAKPAD_COMMON_ANDROID_TESTING_MKDTEMP_H
+
+#include <assert.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/stat.h>
+
+// Using a macro renaming trick here is necessary when building against
+// NDK r9b. Otherwise the compiler will complain that calls to mkdtemp()
+// are ambiguous.
+#define mkdtemp breakpad_mkdtemp
+
+namespace {
+
+char* breakpad_mkdtemp(char* path) {
+  if (path == NULL) {
+    errno = EINVAL;
+    return NULL;
+  }
+
+  // 'path' must be terminated with six 'X'
+  const char kSuffix[] = "XXXXXX";
+  const size_t kSuffixLen = strlen(kSuffix);
+  char* path_end = path + strlen(path);
+
+  if (static_cast<size_t>(path_end - path) < kSuffixLen ||
+      memcmp(path_end - kSuffixLen, kSuffix, kSuffixLen) != 0) {
+    errno = EINVAL;
+    return NULL;
+  }
+
+  // If 'path' contains a directory separator, check that it exists to
+  // avoid looping later.
+  char* sep = strrchr(path, '/');
+  if (sep != NULL) {
+    struct stat st;
+    int ret;
+    *sep = '\0';  // temporarily zero-terminate the dirname.
+    ret = stat(path, &st);
+    *sep = '/';   // restore full path.
+    if (ret < 0)
+      return NULL;
+    if (!S_ISDIR(st.st_mode)) {
+      errno = ENOTDIR;
+      return NULL;
+    }
+  }
+
+  // Loop. On each iteration, replace the XXXXXX suffix with a random
+  // number.
+  int tries;
+  for (tries = 128; tries > 0; tries--) {
+    int random = rand() % 1000000;
+
+    snprintf(path_end - kSuffixLen, kSuffixLen + 1, "%0d", random);
+    if (mkdir(path, 0700) == 0)
+      return path;  // Success
+
+    if (errno != EEXIST)
+      return NULL;
+  }
+
+  assert(errno == EEXIST);
+  return NULL;
+}
+
+}  // namespace
+
+#endif  // GOOGLE_BREAKPAD_COMMON_ANDROID_TESTING_MKDTEMP_H
diff --git a/include/breakpad/common/android/testing/pthread_fixes.h b/include/breakpad/common/android/testing/pthread_fixes.h
new file mode 100644
index 0000000..15c6309
--- /dev/null
+++ b/include/breakpad/common/android/testing/pthread_fixes.h
@@ -0,0 +1,99 @@
+// 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.
+
+// This contains Pthread-related functions not provided by the Android NDK
+// but required by the Breakpad unit test. The functions are inlined here
+// in a C++ anonymous namespace in order to keep the build files simples.
+
+#ifndef GOOGLE_BREAKPAD_COMMON_ANDROID_TESTING_PTHREAD_FIXES_H
+#define GOOGLE_BREAKPAD_COMMON_ANDROID_TESTING_PTHREAD_FIXES_H
+
+#include <pthread.h>
+
+namespace {
+
+// Android doesn't provide pthread_barrier_t for now.
+#ifndef PTHREAD_BARRIER_SERIAL_THREAD
+
+// Anything except 0 will do here.
+#define PTHREAD_BARRIER_SERIAL_THREAD  0x12345
+
+typedef struct {
+  pthread_mutex_t  mutex;
+  pthread_cond_t   cond;
+  unsigned         count;
+} pthread_barrier_t;
+
+int pthread_barrier_init(pthread_barrier_t* barrier,
+                         const void* /* barrier_attr */,
+                         unsigned count) {
+  barrier->count = count;
+  pthread_mutex_init(&barrier->mutex, NULL);
+  pthread_cond_init(&barrier->cond, NULL);
+  return 0;
+}
+
+int pthread_barrier_wait(pthread_barrier_t* barrier) {
+  // Lock the mutex
+  pthread_mutex_lock(&barrier->mutex);
+  // Decrement the count. If this is the first thread to reach 0, wake up
+  // waiters, unlock the mutex, then return PTHREAD_BARRIER_SERIAL_THREAD.
+  if (--barrier->count == 0) {
+    // First thread to reach the barrier
+    pthread_cond_broadcast(&barrier->cond);
+    pthread_mutex_unlock(&barrier->mutex);
+    return PTHREAD_BARRIER_SERIAL_THREAD;
+  }
+  // Otherwise, wait for other threads until the count reaches 0, then
+  // return 0 to indicate this is not the first thread.
+  do {
+    pthread_cond_wait(&barrier->cond, &barrier->mutex);
+  } while (barrier->count > 0);
+
+  pthread_mutex_unlock(&barrier->mutex);
+  return 0;
+}
+
+int pthread_barrier_destroy(pthread_barrier_t *barrier) {
+  barrier->count = 0;
+  pthread_cond_destroy(&barrier->cond);
+  pthread_mutex_destroy(&barrier->mutex);
+  return 0;
+}
+
+#endif  // defined(PTHREAD_BARRIER_SERIAL_THREAD)
+
+int pthread_yield(void) {
+  sched_yield();
+  return 0;
+}
+
+}  // namespace
+
+#endif  // GOOGLE_BREAKPAD_COMMON_ANDROID_TESTING_PTHREAD_FIXES_H
diff --git a/include/breakpad/common/android/ucontext_constants.h b/include/breakpad/common/android/ucontext_constants.h
new file mode 100644
index 0000000..1932d57
--- /dev/null
+++ b/include/breakpad/common/android/ucontext_constants.h
@@ -0,0 +1,144 @@
+// 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.
+
+// This header can be included either from a C, C++ or Assembly file.
+// Its purpose is to contain constants that must match the offsets of
+// various fields in ucontext_t.
+//
+// They should match the definitions from
+// src/common/android/include/sys/ucontext.h
+//
+// Used by src/common/android/breakpad_getcontext.S
+// Tested by src/common/android/testing/breakpad_getcontext_unittest.cc
+
+#ifndef GOOGLEBREAKPAD_COMMON_ANDROID_UCONTEXT_CONSTANTS_H
+#define GOOGLEBREAKPAD_COMMON_ANDROID_UCONTEXT_CONSTANTS_H
+
+#if defined(__arm__)
+
+#define  MCONTEXT_GREGS_OFFSET     32
+#define  UCONTEXT_SIGMASK_OFFSET   104
+
+#elif defined(__aarch64__)
+
+#define  UCONTEXT_SIGMASK_OFFSET     40
+
+#define  MCONTEXT_GREGS_OFFSET       184
+#define  MCONTEXT_SP_OFFSET          432
+#define  MCONTEXT_PC_OFFSET          440
+#define  MCONTEXT_PSTATE_OFFSET      448
+#define  MCONTEXT_EXTENSION_OFFSET   464
+
+#define  FPSIMD_MAGIC                0x46508001
+
+#define  FPSIMD_CONTEXT_MAGIC_OFFSET 0
+#define  FPSIMD_CONTEXT_SIZE_OFFSET  4
+#define  FPSIMD_CONTEXT_FPSR_OFFSET  8
+#define  FPSIMD_CONTEXT_FPCR_OFFSET  12
+#define  FPSIMD_CONTEXT_VREGS_OFFSET 16
+#define  FPSIMD_CONTEXT_SIZE         528
+
+#define  REGISTER_SIZE               8
+#define  SIMD_REGISTER_SIZE          16
+
+#elif defined(__i386__)
+
+#define  MCONTEXT_GREGS_OFFSET     20
+#define  MCONTEXT_GS_OFFSET        (MCONTEXT_GREGS_OFFSET + 0*4)
+#define  MCONTEXT_FS_OFFSET        (MCONTEXT_GREGS_OFFSET + 1*4)
+#define  MCONTEXT_ES_OFFSET        (MCONTEXT_GREGS_OFFSET + 2*4)
+#define  MCONTEXT_DS_OFFSET        (MCONTEXT_GREGS_OFFSET + 3*4)
+#define  MCONTEXT_EDI_OFFSET       (MCONTEXT_GREGS_OFFSET + 4*4)
+#define  MCONTEXT_ESI_OFFSET       (MCONTEXT_GREGS_OFFSET + 5*4)
+#define  MCONTEXT_EBP_OFFSET       (MCONTEXT_GREGS_OFFSET + 6*4)
+#define  MCONTEXT_ESP_OFFSET       (MCONTEXT_GREGS_OFFSET + 7*4)
+#define  MCONTEXT_EBX_OFFSET       (MCONTEXT_GREGS_OFFSET + 8*4)
+#define  MCONTEXT_EDX_OFFSET       (MCONTEXT_GREGS_OFFSET + 9*4)
+#define  MCONTEXT_ECX_OFFSET       (MCONTEXT_GREGS_OFFSET + 10*4)
+#define  MCONTEXT_EAX_OFFSET       (MCONTEXT_GREGS_OFFSET + 11*4)
+#define  MCONTEXT_TRAPNO_OFFSET    (MCONTEXT_GREGS_OFFSET + 12*4)
+#define  MCONTEXT_ERR_OFFSET       (MCONTEXT_GREGS_OFFSET + 13*4)
+#define  MCONTEXT_EIP_OFFSET       (MCONTEXT_GREGS_OFFSET + 14*4)
+#define  MCONTEXT_CS_OFFSET        (MCONTEXT_GREGS_OFFSET + 15*4)
+#define  MCONTEXT_EFL_OFFSET       (MCONTEXT_GREGS_OFFSET + 16*4)
+#define  MCONTEXT_UESP_OFFSET      (MCONTEXT_GREGS_OFFSET + 17*4)
+#define  MCONTEXT_SS_OFFSET        (MCONTEXT_GREGS_OFFSET + 18*4)
+
+#define  UCONTEXT_SIGMASK_OFFSET   108
+
+#define  UCONTEXT_FPREGS_OFFSET       96
+#define  UCONTEXT_FPREGS_MEM_OFFSET   116
+
+#elif defined(__mips__)
+
+#if _MIPS_SIM == _ABIO32
+#define  MCONTEXT_PC_OFFSET        32
+#define  MCONTEXT_GREGS_OFFSET     40
+#define  MCONTEXT_FPREGS_OFFSET    296
+#define  MCONTEXT_FPC_CSR          556
+#define  UCONTEXT_SIGMASK_OFFSET   616
+#else
+#define  MCONTEXT_GREGS_OFFSET     40
+#define  MCONTEXT_FPREGS_OFFSET    296
+#define  MCONTEXT_PC_OFFSET        616
+#define  MCONTEXT_FPC_CSR          624
+#define  UCONTEXT_SIGMASK_OFFSET   640
+#endif
+
+#elif defined(__x86_64__)
+
+#define MCONTEXT_GREGS_OFFSET     40
+#define UCONTEXT_SIGMASK_OFFSET   296
+
+#define MCONTEXT_GREGS_R8    40
+#define MCONTEXT_GREGS_R9    48
+#define MCONTEXT_GREGS_R10   56
+#define MCONTEXT_GREGS_R11   64
+#define MCONTEXT_GREGS_R12   72
+#define MCONTEXT_GREGS_R13   80
+#define MCONTEXT_GREGS_R14   88
+#define MCONTEXT_GREGS_R15   96
+#define MCONTEXT_GREGS_RDI   104
+#define MCONTEXT_GREGS_RSI   112
+#define MCONTEXT_GREGS_RBP   120
+#define MCONTEXT_GREGS_RBX   128
+#define MCONTEXT_GREGS_RDX   136
+#define MCONTEXT_GREGS_RAX   144
+#define MCONTEXT_GREGS_RCX   152
+#define MCONTEXT_GREGS_RSP   160
+#define MCONTEXT_GREGS_RIP   168
+#define MCONTEXT_FPREGS_PTR  224
+#define MCONTEXT_FPREGS_MEM  304
+#define FPREGS_OFFSET_MXCSR  24
+
+#else
+#error "This header has not been ported for your CPU"
+#endif
+
+#endif  // GOOGLEBREAKPAD_COMMON_ANDROID_UCONTEXT_CONSTANTS_H
diff --git a/include/breakpad/common/dwarf/bytereader-inl.h b/include/breakpad/common/dwarf/bytereader-inl.h
new file mode 100644
index 0000000..3c16708
--- /dev/null
+++ b/include/breakpad/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/include/breakpad/common/dwarf/bytereader.h b/include/breakpad/common/dwarf/bytereader.h
new file mode 100644
index 0000000..e389427
--- /dev/null
+++ b/include/breakpad/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/include/breakpad/common/dwarf/cfi_assembler.h b/include/breakpad/common/dwarf/cfi_assembler.h
new file mode 100644
index 0000000..227812b
--- /dev/null
+++ b/include/breakpad/common/dwarf/cfi_assembler.h
@@ -0,0 +1,269 @@
+// -*- 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>
+
+// cfi_assembler.h: Define CFISection, a class for creating properly
+// (and improperly) formatted DWARF CFI data for unit tests.
+
+#ifndef PROCESSOR_CFI_ASSEMBLER_H_
+#define PROCESSOR_CFI_ASSEMBLER_H_
+
+#include <string>
+
+#include "common/dwarf/dwarf2enums.h"
+#include "common/test_assembler.h"
+#include "common/using_std_string.h"
+#include "google_breakpad/common/breakpad_types.h"
+
+namespace google_breakpad {
+
+using dwarf2reader::DwarfPointerEncoding;
+using google_breakpad::test_assembler::Endianness;
+using google_breakpad::test_assembler::Label;
+using google_breakpad::test_assembler::Section;
+
+class CFISection: public Section {
+ public:
+
+  // CFI augmentation strings beginning with 'z', defined by the
+  // Linux/IA-64 C++ ABI, can specify interesting encodings for
+  // addresses appearing in FDE headers and call frame instructions (and
+  // for additional fields whose presence the augmentation string
+  // specifies). In particular, pointers can be specified to be relative
+  // to various base address: the start of the .text section, the
+  // location holding the address itself, and so on. These allow the
+  // frame data to be position-independent even when they live in
+  // write-protected pages. These variants are specified at the
+  // following two URLs:
+  //
+  // 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
+  //
+  // CFISection leaves the production of well-formed 'z'-augmented CIEs and
+  // FDEs to the user, but does provide EncodedPointer, to emit
+  // properly-encoded addresses for a given pointer encoding.
+  // EncodedPointer uses an instance of this structure to find the base
+  // addresses it should use; you can establish a default for all encoded
+  // pointers appended to this section with SetEncodedPointerBases.
+  struct EncodedPointerBases {
+    EncodedPointerBases() : cfi(), text(), data() { }
+
+    // The starting address of this CFI section in memory, for
+    // DW_EH_PE_pcrel. DW_EH_PE_pcrel pointers may only be used in data
+    // that has is loaded into the program's address space.
+    uint64_t cfi;
+
+    // The starting address of this file's .text section, for DW_EH_PE_textrel.
+    uint64_t text;
+
+    // The starting address of this file's .got or .eh_frame_hdr section,
+    // for DW_EH_PE_datarel.
+    uint64_t data;
+  };
+
+  // Create a CFISection whose endianness is ENDIANNESS, and where
+  // machine addresses are ADDRESS_SIZE bytes long. If EH_FRAME is
+  // true, use the .eh_frame format, as described by the Linux
+  // Standards Base Core Specification, instead of the DWARF CFI
+  // format.
+  CFISection(Endianness endianness, size_t address_size,
+             bool eh_frame = false)
+      : Section(endianness), address_size_(address_size), eh_frame_(eh_frame),
+        pointer_encoding_(dwarf2reader::DW_EH_PE_absptr),
+        encoded_pointer_bases_(), entry_length_(NULL), in_fde_(false) {
+    // The 'start', 'Here', and 'Mark' members of a CFISection all refer
+    // to section offsets.
+    start() = 0;
+  }
+
+  // Return this CFISection's address size.
+  size_t AddressSize() const { return address_size_; }
+
+  // Return true if this CFISection uses the .eh_frame format, or
+  // false if it contains ordinary DWARF CFI data.
+  bool ContainsEHFrame() const { return eh_frame_; }
+
+  // Use ENCODING for pointers in calls to FDEHeader and EncodedPointer.
+  void SetPointerEncoding(DwarfPointerEncoding encoding) {
+    pointer_encoding_ = encoding;
+  }
+
+  // Use the addresses in BASES as the base addresses for encoded
+  // pointers in subsequent calls to FDEHeader or EncodedPointer.
+  // This function makes a copy of BASES.
+  void SetEncodedPointerBases(const EncodedPointerBases &bases) {
+    encoded_pointer_bases_ = bases;
+  }
+
+  // Append a Common Information Entry header to this section with the
+  // given values. If dwarf64 is true, use the 64-bit DWARF initial
+  // length format for the CIE's initial length. Return a reference to
+  // this section. You should call FinishEntry after writing the last
+  // instruction for the CIE.
+  //
+  // Before calling this function, you will typically want to use Mark
+  // or Here to make a label to pass to FDEHeader that refers to this
+  // CIE's position in the section.
+  CFISection &CIEHeader(uint64_t code_alignment_factor,
+                        int data_alignment_factor,
+                        unsigned return_address_register,
+                        uint8_t version = 3,
+                        const string &augmentation = "",
+                        bool dwarf64 = false);
+
+  // Append a Frame Description Entry header to this section with the
+  // given values. If dwarf64 is true, use the 64-bit DWARF initial
+  // length format for the CIE's initial length. Return a reference to
+  // this section. You should call FinishEntry after writing the last
+  // instruction for the CIE.
+  //
+  // This function doesn't support entries that are longer than
+  // 0xffffff00 bytes. (The "initial length" is always a 32-bit
+  // value.) Nor does it support .debug_frame sections longer than
+  // 0xffffff00 bytes.
+  CFISection &FDEHeader(Label cie_pointer,
+                        uint64_t initial_location,
+                        uint64_t address_range,
+                        bool dwarf64 = false);
+
+  // Note the current position as the end of the last CIE or FDE we
+  // started, after padding with DW_CFA_nops for alignment. This
+  // defines the label representing the entry's length, cited in the
+  // entry's header. Return a reference to this section.
+  CFISection &FinishEntry();
+
+  // Append the contents of BLOCK as a DW_FORM_block value: an
+  // unsigned LEB128 length, followed by that many bytes of data.
+  CFISection &Block(const string &block) {
+    ULEB128(block.size());
+    Append(block);
+    return *this;
+  }
+
+  // Append ADDRESS to this section, in the appropriate size and
+  // endianness. Return a reference to this section.
+  CFISection &Address(uint64_t address) {
+    Section::Append(endianness(), address_size_, address);
+    return *this;
+  }
+  CFISection &Address(Label address) {
+    Section::Append(endianness(), address_size_, address);
+    return *this;
+  }
+
+  // Append ADDRESS to this section, using ENCODING and BASES. ENCODING
+  // defaults to this section's default encoding, established by
+  // SetPointerEncoding. BASES defaults to this section's bases, set by
+  // SetEncodedPointerBases. If the DW_EH_PE_indirect bit is set in the
+  // encoding, assume that ADDRESS is where the true address is stored.
+  // Return a reference to this section.
+  // 
+  // (C++ doesn't let me use default arguments here, because I want to
+  // refer to members of *this in the default argument expression.)
+  CFISection &EncodedPointer(uint64_t address) {
+    return EncodedPointer(address, pointer_encoding_, encoded_pointer_bases_);
+  }
+  CFISection &EncodedPointer(uint64_t address, DwarfPointerEncoding encoding) {
+    return EncodedPointer(address, encoding, encoded_pointer_bases_);
+  }
+  CFISection &EncodedPointer(uint64_t address, DwarfPointerEncoding encoding,
+                             const EncodedPointerBases &bases);
+
+  // Restate some member functions, to keep chaining working nicely.
+  CFISection &Mark(Label *label)   { Section::Mark(label); return *this; }
+  CFISection &D8(uint8_t v)       { Section::D8(v);       return *this; }
+  CFISection &D16(uint16_t v)     { Section::D16(v);      return *this; }
+  CFISection &D16(Label v)         { Section::D16(v);      return *this; }
+  CFISection &D32(uint32_t v)     { Section::D32(v);      return *this; }
+  CFISection &D32(const Label &v)  { Section::D32(v);      return *this; }
+  CFISection &D64(uint64_t v)     { Section::D64(v);      return *this; }
+  CFISection &D64(const Label &v)  { Section::D64(v);      return *this; }
+  CFISection &LEB128(long long v)  { Section::LEB128(v);   return *this; }
+  CFISection &ULEB128(uint64_t v) { Section::ULEB128(v);  return *this; }
+
+ private:
+  // A length value that we've appended to the section, but is not yet
+  // known. LENGTH is the appended value; START is a label referring
+  // to the start of the data whose length was cited.
+  struct PendingLength {
+    Label length;
+    Label start;
+  };
+
+  // Constants used in CFI/.eh_frame data:
+
+  // If the first four bytes of an "initial length" are this constant, then
+  // the data uses the 64-bit DWARF format, and the length itself is the
+  // subsequent eight bytes.
+  static const uint32_t kDwarf64InitialLengthMarker = 0xffffffffU;
+
+  // The CIE identifier for 32- and 64-bit DWARF CFI and .eh_frame data.
+  static const uint32_t kDwarf32CIEIdentifier = ~(uint32_t)0;
+  static const uint64_t kDwarf64CIEIdentifier = ~(uint64_t)0;
+  static const uint32_t kEHFrame32CIEIdentifier = 0;
+  static const uint64_t kEHFrame64CIEIdentifier = 0;
+
+  // The size of a machine address for the data in this section.
+  size_t address_size_;
+
+  // If true, we are generating a Linux .eh_frame section, instead of
+  // a standard DWARF .debug_frame section.
+  bool eh_frame_;
+
+  // The encoding to use for FDE pointers.
+  DwarfPointerEncoding pointer_encoding_;
+
+  // The base addresses to use when emitting encoded pointers.
+  EncodedPointerBases encoded_pointer_bases_;
+
+  // The length value for the current entry.
+  //
+  // Oddly, this must be dynamically allocated. Labels never get new
+  // values; they only acquire constraints on the value they already
+  // have, or assert if you assign them something incompatible. So
+  // each header needs truly fresh Label objects to cite in their
+  // headers and track their positions. The alternative is explicit
+  // destructor invocation and a placement new. Ick.
+  PendingLength *entry_length_;
+
+  // True if we are currently emitting an FDE --- that is, we have
+  // called FDEHeader but have not yet called FinishEntry.
+  bool in_fde_;
+
+  // If in_fde_ is true, this is its starting address. We use this for
+  // emitting DW_EH_PE_funcrel pointers.
+  uint64_t fde_start_address_;
+};
+
+}  // namespace google_breakpad
+
+#endif  // PROCESSOR_CFI_ASSEMBLER_H_
diff --git a/include/breakpad/common/dwarf/dwarf2diehandler.h b/include/breakpad/common/dwarf/dwarf2diehandler.h
new file mode 100644
index 0000000..81f40f0
--- /dev/null
+++ b/include/breakpad/common/dwarf/dwarf2diehandler.h
@@ -0,0 +1,363 @@
+// -*- 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.
+  //
+  // The default definition skips all children.
+  virtual DIEHandler *FindChildHandler(uint64 offset, enum DwarfTag tag) {
+    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) { 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);
+  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/include/breakpad/common/dwarf/dwarf2enums.h b/include/breakpad/common/dwarf/dwarf2enums.h
new file mode 100644
index 0000000..5565d66
--- /dev/null
+++ b/include/breakpad/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/include/breakpad/common/dwarf/dwarf2reader.h b/include/breakpad/common/dwarf/dwarf2reader.h
new file mode 100644
index 0000000..8824bf9
--- /dev/null
+++ b/include/breakpad/common/dwarf/dwarf2reader.h
@@ -0,0 +1,1050 @@
+// -*- 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) { 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/include/breakpad/common/dwarf/dwarf2reader_test_common.h b/include/breakpad/common/dwarf/dwarf2reader_test_common.h
new file mode 100644
index 0000000..e91de90
--- /dev/null
+++ b/include/breakpad/common/dwarf/dwarf2reader_test_common.h
@@ -0,0 +1,149 @@
+// -*- 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: Jim Blandy <jimb@mozilla.com> <jimb@red-bean.com>
+
+// dwarf2reader_test_common.h: Define TestCompilationUnit and
+// TestAbbrevTable, classes for creating properly (and improperly)
+// formatted DWARF compilation unit data for unit tests.
+
+#ifndef COMMON_DWARF_DWARF2READER_TEST_COMMON_H__
+#define COMMON_DWARF_DWARF2READER_TEST_COMMON_H__
+
+#include "common/test_assembler.h"
+#include "common/dwarf/dwarf2enums.h"
+
+// A subclass of test_assembler::Section, specialized for constructing
+// DWARF compilation units.
+class TestCompilationUnit: public google_breakpad::test_assembler::Section {
+ public:
+  typedef dwarf2reader::DwarfTag DwarfTag;
+  typedef dwarf2reader::DwarfAttribute DwarfAttribute;
+  typedef dwarf2reader::DwarfForm DwarfForm;
+  typedef google_breakpad::test_assembler::Label Label;
+
+  // Set the section's DWARF format size (the 32-bit DWARF format or the
+  // 64-bit DWARF format, for lengths and section offsets --- not the
+  // address size) to format_size.
+  void set_format_size(size_t format_size) {
+    assert(format_size == 4 || format_size == 8);
+    format_size_ = format_size;
+  }
+    
+  // Append a DWARF section offset value, of the appropriate size for this
+  // compilation unit.
+  template<typename T>
+  void SectionOffset(T offset) {
+    if (format_size_ == 4)
+      D32(offset);
+    else
+      D64(offset);
+  }
+
+  // Append a DWARF compilation unit header to the section, with the given
+  // DWARF version, abbrev table offset, and address size.
+  TestCompilationUnit &Header(int version, const Label &abbrev_offset,
+                              size_t address_size) {
+    if (format_size_ == 4) {
+      D32(length_);
+    } else {
+      D32(0xffffffff);
+      D64(length_);
+    }
+    post_length_offset_ = Size();
+    D16(version);
+    SectionOffset(abbrev_offset);
+    D8(address_size);
+    return *this;
+  }
+
+  // Mark the end of this header's DIEs.
+  TestCompilationUnit &Finish() {
+    length_ = Size() - post_length_offset_;
+    return *this;
+  }
+
+ private:
+  // The DWARF format size for this compilation unit.
+  size_t format_size_;
+
+  // The offset of the point in the compilation unit header immediately
+  // after the initial length field.
+  uint64_t post_length_offset_;
+
+  // The length of the compilation unit, not including the initial length field.
+  Label length_;
+};
+
+// A subclass of test_assembler::Section specialized for constructing DWARF
+// abbreviation tables.
+class TestAbbrevTable: public google_breakpad::test_assembler::Section {
+ public:
+  typedef dwarf2reader::DwarfTag DwarfTag;
+  typedef dwarf2reader::DwarfAttribute DwarfAttribute;
+  typedef dwarf2reader::DwarfForm DwarfForm;
+  typedef dwarf2reader::DwarfHasChild DwarfHasChild;
+  typedef google_breakpad::test_assembler::Label Label;
+
+  // Start a new abbreviation table entry for abbreviation code |code|,
+  // encoding a DIE whose tag is |tag|, and which has children if and only
+  // if |has_children| is true.
+  TestAbbrevTable &Abbrev(int code, DwarfTag tag, DwarfHasChild has_children) {
+    assert(code != 0);
+    ULEB128(code);
+    ULEB128(static_cast<unsigned>(tag));
+    D8(static_cast<unsigned>(has_children));
+    return *this;
+  };
+
+  // Add an attribute to the current abbreviation code whose name is |name|
+  // and whose form is |form|.
+  TestAbbrevTable &Attribute(DwarfAttribute name, DwarfForm form) {
+    ULEB128(static_cast<unsigned>(name));
+    ULEB128(static_cast<unsigned>(form));
+    return *this;
+  }
+
+  // Finish the current abbreviation code.
+  TestAbbrevTable &EndAbbrev() {
+    ULEB128(0);
+    ULEB128(0);
+    return *this;
+  }
+
+  // Finish the current abbreviation table.
+  TestAbbrevTable &EndTable() {
+    ULEB128(0);
+    return *this;
+  }
+};
+
+#endif // COMMON_DWARF_DWARF2READER_TEST_COMMON_H__
diff --git a/include/breakpad/common/dwarf/functioninfo.h b/include/breakpad/common/dwarf/functioninfo.h
new file mode 100644
index 0000000..0b08a5f
--- /dev/null
+++ b/include/breakpad/common/dwarf/functioninfo.h
@@ -0,0 +1,188 @@
+// 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.
+
+
+// This file contains the definitions for a DWARF2/3 information
+// collector that uses the DWARF2/3 reader interface to build a mapping
+// of addresses to files, lines, and functions.
+
+#ifndef COMMON_DWARF_FUNCTIONINFO_H__
+#define COMMON_DWARF_FUNCTIONINFO_H__
+
+#include <map>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "common/dwarf/dwarf2reader.h"
+#include "common/using_std_string.h"
+
+
+namespace dwarf2reader {
+
+struct FunctionInfo {
+  // Name of the function
+  string name;
+  // Mangled name of the function
+  string mangled_name;
+  // File containing this function
+  string file;
+  // Line number for start of function.
+  uint32 line;
+  // Beginning address for this function
+  uint64 lowpc;
+  // End address for this function.
+  uint64 highpc;
+};
+
+struct SourceFileInfo {
+  // Name of the source file name
+  string name;
+  // Low address of source file name
+  uint64 lowpc;
+};
+
+typedef std::map<uint64, FunctionInfo*> FunctionMap;
+typedef std::map<uint64, std::pair<string, uint32> > LineMap;
+
+// This class is a basic line info handler that fills in the dirs,
+// file, and linemap passed into it with the data produced from the
+// LineInfoHandler.
+class CULineInfoHandler: public LineInfoHandler {
+ public:
+
+  //
+  CULineInfoHandler(std::vector<SourceFileInfo>* files,
+                    std::vector<string>* dirs,
+                    LineMap* linemap);
+  virtual ~CULineInfoHandler() { }
+
+  // Called when we define a directory.  We just place NAME into dirs_
+  // at position DIR_NUM.
+  virtual void DefineDir(const string& name, uint32 dir_num);
+
+  // Called when we define a filename.  We just place
+  // concat(dirs_[DIR_NUM], NAME) into files_ at position FILE_NUM.
+  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);
+
+ private:
+  LineMap* linemap_;
+  std::vector<SourceFileInfo>* files_;
+  std::vector<string>* dirs_;
+};
+
+class CUFunctionInfoHandler: public Dwarf2Handler {
+ public:
+  CUFunctionInfoHandler(std::vector<SourceFileInfo>* files,
+                        std::vector<string>* dirs,
+                        LineMap* linemap,
+                        FunctionMap* offset_to_funcinfo,
+                        FunctionMap* address_to_funcinfo,
+                        CULineInfoHandler* linehandler,
+                        const SectionMap& sections,
+                        ByteReader* reader)
+      : files_(files), dirs_(dirs), linemap_(linemap),
+        offset_to_funcinfo_(offset_to_funcinfo),
+        address_to_funcinfo_(address_to_funcinfo),
+        linehandler_(linehandler), sections_(sections),
+        reader_(reader), current_function_info_(NULL) { }
+
+  virtual ~CUFunctionInfoHandler() { }
+
+  // Start to process a compilation unit at OFFSET from the beginning of the
+  // .debug_info section.  We want to see all compilation units, so we
+  // always return true.
+
+  virtual bool StartCompilationUnit(uint64 offset, uint8 address_size,
+                                    uint8 offset_size, uint64 cu_length,
+                                    uint8 dwarf_version);
+
+  // Start to process a DIE at OFFSET from the beginning of the
+  // .debug_info section.  We only care about function related DIE's.
+  virtual bool StartDIE(uint64 offset, enum DwarfTag tag);
+
+  // 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, has a name of ATTR, a form of
+  // FORM, and the actual data of the attribute is in DATA.
+  virtual void ProcessAttributeUnsigned(uint64 offset,
+                                        enum DwarfAttribute attr,
+                                        enum DwarfForm form,
+                                        uint64 data);
+
+  // Called when we have an attribute with a DIE reference to give to
+  // our handler.  The attribute is for the DIE at OFFSET from the
+  // beginning of the .debug_info section, has a name of ATTR, a form of
+  // FORM, and the offset of the referenced DIE from the start of the
+  // .debug_info section is in DATA.
+  virtual void ProcessAttributeReference(uint64 offset,
+                                         enum DwarfAttribute attr,
+                                         enum DwarfForm form,
+                                         uint64 data);
+
+  // 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, has a name of ATTR, a form of
+  // FORM, and the actual data of the attribute is in DATA.
+  virtual void ProcessAttributeString(uint64 offset,
+                                      enum DwarfAttribute attr,
+                                      enum DwarfForm form,
+                                      const string& data);
+
+  // 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);
+
+ private:
+  std::vector<SourceFileInfo>* files_;
+  std::vector<string>* dirs_;
+  LineMap* linemap_;
+  FunctionMap* offset_to_funcinfo_;
+  FunctionMap* address_to_funcinfo_;
+  CULineInfoHandler* linehandler_;
+  const SectionMap& sections_;
+  ByteReader* reader_;
+  FunctionInfo* current_function_info_;
+  uint64 current_compilation_unit_offset_;
+};
+
+}  // namespace dwarf2reader
+#endif  // COMMON_DWARF_FUNCTIONINFO_H__
diff --git a/include/breakpad/common/dwarf/line_state_machine.h b/include/breakpad/common/dwarf/line_state_machine.h
new file mode 100644
index 0000000..0ff72ab
--- /dev/null
+++ b/include/breakpad/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/include/breakpad/common/dwarf/types.h b/include/breakpad/common/dwarf/types.h
new file mode 100644
index 0000000..61ca457
--- /dev/null
+++ b/include/breakpad/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/include/breakpad/common/linux/tests/auto_testfile.h b/include/breakpad/common/linux/tests/auto_testfile.h
new file mode 100644
index 0000000..92fe017
--- /dev/null
+++ b/include/breakpad/common/linux/tests/auto_testfile.h
@@ -0,0 +1,124 @@
+// Copyright (c) 2013, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Utility class for creating a temporary file for unit tests
+// that is deleted in the destructor.
+
+#ifndef GOOGLE_BREAKPAD_COMMON_LINUX_TESTS_AUTO_TESTFILE
+#define GOOGLE_BREAKPAD_COMMON_LINUX_TESTS_AUTO_TESTFILE
+
+#include <unistd.h>
+#include <sys/types.h>
+
+#include <string>
+
+#include "breakpad_googletest_includes.h"
+#include "common/linux/eintr_wrapper.h"
+#include "common/tests/auto_tempdir.h"
+
+namespace google_breakpad {
+
+class AutoTestFile {
+ public:
+  // Create a new empty test file.
+  // test_prefix: (input) test-specific prefix, can't be NULL.
+  explicit AutoTestFile(const char* test_prefix) {
+    Init(test_prefix);
+  }
+
+  // Create a new test file, and fill it with initial data from a C string.
+  // The terminating zero is not written.
+  // test_prefix: (input) test-specific prefix, can't be NULL.
+  // text: (input) initial content.
+  AutoTestFile(const char* test_prefix, const char* text) {
+    Init(test_prefix);
+    if (fd_ >= 0)
+      WriteText(text, static_cast<size_t>(strlen(text)));
+  }
+
+  AutoTestFile(const char* test_prefix, const char* text, size_t text_len) {
+    Init(test_prefix);
+    if (fd_ >= 0)
+      WriteText(text, text_len);
+  }
+
+  // Destroy test file on scope exit.
+  ~AutoTestFile() {
+    if (fd_ >= 0) {
+      close(fd_);
+      fd_ = -1;
+    }
+  }
+
+  // Returns true iff the test file could be created properly.
+  // Useful in tests inside EXPECT_TRUE(file.IsOk());
+  bool IsOk() {
+    return fd_ >= 0;
+  }
+
+  // Returns the Posix file descriptor for the test file, or -1
+  // If IsOk() returns false. Note: on Windows, this always returns -1.
+  int GetFd() {
+    return fd_;
+  }
+
+ private:
+  void Init(const char* test_prefix) {
+    fd_ = -1;
+    char path_templ[PATH_MAX];
+    int ret = snprintf(path_templ, sizeof(path_templ),
+                       TEMPDIR "/%s-unittest.XXXXXX",
+                       test_prefix);
+    if (ret >= static_cast<int>(sizeof(path_templ)))
+      return;
+
+    fd_ = mkstemp(path_templ);
+    if (fd_ < 0)
+      return;
+
+    unlink(path_templ);
+  }
+
+  void WriteText(const char* text, size_t text_len) {
+    ssize_t r = HANDLE_EINTR(write(fd_, text, text_len));
+    if (r != static_cast<ssize_t>(text_len)) {
+      close(fd_);
+      fd_ = -1;
+      return;
+    }
+
+    lseek(fd_, 0, SEEK_SET);
+  }
+
+  int fd_;
+};
+
+}  // namespace google_breakpad
+
+#endif  // GOOGLE_BREAKPAD_COMMON_LINUX_TESTS_AUTO_TESTFILE
diff --git a/include/breakpad/common/linux/tests/crash_generator.h b/include/breakpad/common/linux/tests/crash_generator.h
new file mode 100644
index 0000000..7e2fcbf
--- /dev/null
+++ b/include/breakpad/common/linux/tests/crash_generator.h
@@ -0,0 +1,117 @@
+// 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.
+
+// crash_generator.h: Define the google_breakpad::CrashGenerator class,
+// which is used to generate a crash (and a core dump file) for testing.
+
+#ifndef COMMON_LINUX_TESTS_CRASH_GENERATOR_H_
+#define COMMON_LINUX_TESTS_CRASH_GENERATOR_H_
+
+#include <sys/resource.h>
+
+#include <string>
+
+#include "common/tests/auto_tempdir.h"
+#include "common/using_std_string.h"
+
+namespace google_breakpad {
+
+// A utility class for generating a crash (and a core dump file) for
+// testing. It creates a child process with the specified number of
+// threads, which is then termainated by the specified signal. A core
+// dump file is expected to be created upon the termination of the child
+// process, which can then be used for testing code that processes core
+// dump files.
+class CrashGenerator {
+ public:
+  CrashGenerator();
+
+  ~CrashGenerator();
+
+  // Returns true if a core dump file named 'core' will be generated in
+  // the current directory for a test that produces a crash by checking
+  // if /proc/sys/kernel/core_pattern has the default value 'core'.
+  bool HasDefaultCorePattern() const;
+
+  // Returns the expected path of the core dump file.
+  string GetCoreFilePath() const;
+
+  // Returns the directory of a copy of proc files of the child process.
+  string GetDirectoryOfProcFilesCopy() const;
+
+  // Creates a crash (and a core dump file) by creating a child process with
+  // |num_threads| threads, and the terminating the child process by sending
+  // a signal with number |crash_signal| to the |crash_thread|-th thread.
+  // Returns true on success.
+  bool CreateChildCrash(unsigned num_threads, unsigned crash_thread,
+                        int crash_signal, pid_t* child_pid);
+
+  // Returns the thread ID of the |index|-th thread in the child process.
+  // This method does not validate |index|.
+  pid_t GetThreadId(unsigned index) const;
+
+ private:
+  // Copies the following proc files of the process with |pid| to the directory
+  // at |path|: auxv, cmdline, environ, maps, status
+  // The directory must have been created. Returns true on success.
+  bool CopyProcFiles(pid_t pid, const char* path) const;
+
+  // Creates |num_threads| threads in the child process.
+  void CreateThreadsInChildProcess(unsigned num_threads);
+
+  // Sets the maximum size of core dump file (both the soft and hard limit)
+  // to |limit| bytes. Returns true on success.
+  bool SetCoreFileSizeLimit(rlim_t limit) const;
+
+  // Creates a shared memory of |memory_size| bytes for communicating thread
+  // IDs between the parent and child process. Returns true on success.
+  bool MapSharedMemory(size_t memory_size);
+
+  // Releases any shared memory created by MapSharedMemory(). Returns true on
+  // success.
+  bool UnmapSharedMemory();
+
+  // Returns the pointer to the thread ID of the |index|-th thread in the child
+  // process. This method does not validate |index|.
+  pid_t* GetThreadIdPointer(unsigned index);
+
+  // Temporary directory in which a core file is generated.
+  AutoTempDir temp_dir_;
+
+  // Shared memory for communicating thread IDs between the parent and
+  // child process.
+  void* shared_memory_;
+
+  // Number of bytes mapped for |shared_memory_|.
+  size_t shared_memory_size_;
+};
+
+}  // namespace google_breakpad
+
+#endif  // COMMON_LINUX_TESTS_CRASH_GENERATOR_H_
diff --git a/include/breakpad/common/mac/GTMDefines.h b/include/breakpad/common/mac/GTMDefines.h
new file mode 100644
index 0000000..14ffa7e
--- /dev/null
+++ b/include/breakpad/common/mac/GTMDefines.h
@@ -0,0 +1,456 @@
+//
+// GTMDefines.h
+//
+//  Copyright 2008 Google Inc.
+//
+//  Licensed under the Apache License, Version 2.0 (the "License"); you may not
+//  use this file except in compliance with the License.  You may obtain a copy
+//  of the License at
+//
+//  http://www.apache.org/licenses/LICENSE-2.0
+//
+//  Unless required by applicable law or agreed to in writing, software
+//  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+//  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+//  License for the specific language governing permissions and limitations under
+//  the License.
+//
+
+// ============================================================================
+
+#include <AvailabilityMacros.h>
+#include <TargetConditionals.h>
+
+#ifdef __OBJC__
+#include <Foundation/NSObjCRuntime.h>
+#endif  // __OBJC__
+
+#if TARGET_OS_IPHONE
+#include <Availability.h>
+#endif  // TARGET_OS_IPHONE
+
+// Not all MAC_OS_X_VERSION_10_X macros defined in past SDKs
+#ifndef MAC_OS_X_VERSION_10_5
+  #define MAC_OS_X_VERSION_10_5 1050
+#endif
+#ifndef MAC_OS_X_VERSION_10_6
+  #define MAC_OS_X_VERSION_10_6 1060
+#endif
+#ifndef MAC_OS_X_VERSION_10_7
+  #define MAC_OS_X_VERSION_10_7 1070
+#endif
+
+// Not all __IPHONE_X macros defined in past SDKs
+#ifndef __IPHONE_3_0
+  #define __IPHONE_3_0 30000
+#endif
+#ifndef __IPHONE_3_1
+  #define __IPHONE_3_1 30100
+#endif
+#ifndef __IPHONE_3_2
+  #define __IPHONE_3_2 30200
+#endif
+#ifndef __IPHONE_4_0
+  #define __IPHONE_4_0 40000
+#endif
+#ifndef __IPHONE_4_3
+  #define __IPHONE_4_3 40300
+#endif
+#ifndef __IPHONE_5_0
+  #define __IPHONE_5_0 50000
+#endif
+
+// ----------------------------------------------------------------------------
+// CPP symbols that can be overridden in a prefix to control how the toolbox
+// is compiled.
+// ----------------------------------------------------------------------------
+
+
+// By setting the GTM_CONTAINERS_VALIDATION_FAILED_LOG and
+// GTM_CONTAINERS_VALIDATION_FAILED_ASSERT macros you can control what happens
+// when a validation fails. If you implement your own validators, you may want
+// to control their internals using the same macros for consistency.
+#ifndef GTM_CONTAINERS_VALIDATION_FAILED_ASSERT
+  #define GTM_CONTAINERS_VALIDATION_FAILED_ASSERT 0
+#endif
+
+// Give ourselves a consistent way to do inlines.  Apple's macros even use
+// a few different actual definitions, so we're based off of the foundation
+// one.
+#if !defined(GTM_INLINE)
+  #if (defined (__GNUC__) && (__GNUC__ == 4)) || defined (__clang__)
+    #define GTM_INLINE static __inline__ __attribute__((always_inline))
+  #else
+    #define GTM_INLINE static __inline__
+  #endif
+#endif
+
+// Give ourselves a consistent way of doing externs that links up nicely
+// when mixing objc and objc++
+#if !defined (GTM_EXTERN)
+  #if defined __cplusplus
+    #define GTM_EXTERN extern "C"
+    #define GTM_EXTERN_C_BEGIN extern "C" {
+    #define GTM_EXTERN_C_END }
+  #else
+    #define GTM_EXTERN extern
+    #define GTM_EXTERN_C_BEGIN
+    #define GTM_EXTERN_C_END
+  #endif
+#endif
+
+// Give ourselves a consistent way of exporting things if we have visibility
+// set to hidden.
+#if !defined (GTM_EXPORT)
+  #define GTM_EXPORT __attribute__((visibility("default")))
+#endif
+
+// Give ourselves a consistent way of declaring something as unused. This
+// doesn't use __unused because that is only supported in gcc 4.2 and greater.
+#if !defined (GTM_UNUSED)
+#define GTM_UNUSED(x) ((void)(x))
+#endif
+
+// _GTMDevLog & _GTMDevAssert
+//
+// _GTMDevLog & _GTMDevAssert are meant to be a very lightweight shell for
+// developer level errors.  This implementation simply macros to NSLog/NSAssert.
+// It is not intended to be a general logging/reporting system.
+//
+// Please see http://code.google.com/p/google-toolbox-for-mac/wiki/DevLogNAssert
+// for a little more background on the usage of these macros.
+//
+//    _GTMDevLog           log some error/problem in debug builds
+//    _GTMDevAssert        assert if conditon isn't met w/in a method/function
+//                           in all builds.
+//
+// To replace this system, just provide different macro definitions in your
+// prefix header.  Remember, any implementation you provide *must* be thread
+// safe since this could be called by anything in what ever situtation it has
+// been placed in.
+//
+
+// We only define the simple macros if nothing else has defined this.
+#ifndef _GTMDevLog
+
+#ifdef DEBUG
+  #define _GTMDevLog(...) NSLog(__VA_ARGS__)
+#else
+  #define _GTMDevLog(...) do { } while (0)
+#endif
+
+#endif // _GTMDevLog
+
+#ifndef _GTMDevAssert
+// we directly invoke the NSAssert handler so we can pass on the varargs
+// (NSAssert doesn't have a macro we can use that takes varargs)
+#if !defined(NS_BLOCK_ASSERTIONS)
+  #define _GTMDevAssert(condition, ...)                                       \
+    do {                                                                      \
+      if (!(condition)) {                                                     \
+        [[NSAssertionHandler currentHandler]                                  \
+            handleFailureInFunction:[NSString stringWithUTF8String:__PRETTY_FUNCTION__] \
+                               file:[NSString stringWithUTF8String:__FILE__]  \
+                         lineNumber:__LINE__                                  \
+                        description:__VA_ARGS__];                             \
+      }                                                                       \
+    } while(0)
+#else // !defined(NS_BLOCK_ASSERTIONS)
+  #define _GTMDevAssert(condition, ...) do { } while (0)
+#endif // !defined(NS_BLOCK_ASSERTIONS)
+
+#endif // _GTMDevAssert
+
+// _GTMCompileAssert
+// _GTMCompileAssert is an assert that is meant to fire at compile time if you
+// want to check things at compile instead of runtime. For example if you
+// want to check that a wchar is 4 bytes instead of 2 you would use
+// _GTMCompileAssert(sizeof(wchar_t) == 4, wchar_t_is_4_bytes_on_OS_X)
+// Note that the second "arg" is not in quotes, and must be a valid processor
+// symbol in it's own right (no spaces, punctuation etc).
+
+// Wrapping this in an #ifndef allows external groups to define their own
+// compile time assert scheme.
+#ifndef _GTMCompileAssert
+  // We got this technique from here:
+  // http://unixjunkie.blogspot.com/2007/10/better-compile-time-asserts_29.html
+
+  #define _GTMCompileAssertSymbolInner(line, msg) _GTMCOMPILEASSERT ## line ## __ ## msg
+  #define _GTMCompileAssertSymbol(line, msg) _GTMCompileAssertSymbolInner(line, msg)
+  #define _GTMCompileAssert(test, msg) \
+    typedef char _GTMCompileAssertSymbol(__LINE__, msg) [ ((test) ? 1 : -1) ]
+#endif // _GTMCompileAssert
+
+// ----------------------------------------------------------------------------
+// CPP symbols defined based on the project settings so the GTM code has
+// simple things to test against w/o scattering the knowledge of project
+// setting through all the code.
+// ----------------------------------------------------------------------------
+
+// Provide a single constant CPP symbol that all of GTM uses for ifdefing
+// iPhone code.
+#if TARGET_OS_IPHONE // iPhone SDK
+  // For iPhone specific stuff
+  #define GTM_IPHONE_SDK 1
+  #if TARGET_IPHONE_SIMULATOR
+    #define GTM_IPHONE_DEVICE 0
+    #define GTM_IPHONE_SIMULATOR 1
+  #else
+    #define GTM_IPHONE_DEVICE 1
+    #define GTM_IPHONE_SIMULATOR 0
+  #endif  // TARGET_IPHONE_SIMULATOR
+  // By default, GTM has provided it's own unittesting support, define this
+  // to use the support provided by Xcode, especially for the Xcode4 support
+  // for unittesting.
+  #ifndef GTM_IPHONE_USE_SENTEST
+    #define GTM_IPHONE_USE_SENTEST 0
+  #endif
+  #define GTM_MACOS_SDK 0
+#else
+  // For MacOS specific stuff
+  #define GTM_MACOS_SDK 1
+  #define GTM_IPHONE_SDK 0
+  #define GTM_IPHONE_SIMULATOR 0
+  #define GTM_IPHONE_DEVICE 0
+  #define GTM_IPHONE_USE_SENTEST 0
+#endif
+
+// Some of our own availability macros
+#if GTM_MACOS_SDK
+#define GTM_AVAILABLE_ONLY_ON_IPHONE UNAVAILABLE_ATTRIBUTE
+#define GTM_AVAILABLE_ONLY_ON_MACOS
+#else
+#define GTM_AVAILABLE_ONLY_ON_IPHONE
+#define GTM_AVAILABLE_ONLY_ON_MACOS UNAVAILABLE_ATTRIBUTE
+#endif
+
+// GC was dropped by Apple, define the old constant incase anyone still keys
+// off of it.
+#ifndef GTM_SUPPORT_GC
+  #define GTM_SUPPORT_GC 0
+#endif
+
+// To simplify support for 64bit (and Leopard in general), we provide the type
+// defines for non Leopard SDKs
+#if !(MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5)
+ // NSInteger/NSUInteger and Max/Mins
+  #ifndef NSINTEGER_DEFINED
+    #if (defined(__LP64__) && __LP64__) || NS_BUILD_32_LIKE_64
+      typedef long NSInteger;
+      typedef unsigned long NSUInteger;
+    #else
+      typedef int NSInteger;
+      typedef unsigned int NSUInteger;
+    #endif
+    #define NSIntegerMax    LONG_MAX
+    #define NSIntegerMin    LONG_MIN
+    #define NSUIntegerMax   ULONG_MAX
+    #define NSINTEGER_DEFINED 1
+  #endif  // NSINTEGER_DEFINED
+  // CGFloat
+  #ifndef CGFLOAT_DEFINED
+    #if defined(__LP64__) && __LP64__
+      // This really is an untested path (64bit on Tiger?)
+      typedef double CGFloat;
+      #define CGFLOAT_MIN DBL_MIN
+      #define CGFLOAT_MAX DBL_MAX
+      #define CGFLOAT_IS_DOUBLE 1
+    #else /* !defined(__LP64__) || !__LP64__ */
+      typedef float CGFloat;
+      #define CGFLOAT_MIN FLT_MIN
+      #define CGFLOAT_MAX FLT_MAX
+      #define CGFLOAT_IS_DOUBLE 0
+    #endif /* !defined(__LP64__) || !__LP64__ */
+    #define CGFLOAT_DEFINED 1
+  #endif // CGFLOAT_DEFINED
+#endif  // MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5
+
+// Some support for advanced clang static analysis functionality
+// See http://clang-analyzer.llvm.org/annotations.html
+#ifndef __has_feature      // Optional.
+  #define __has_feature(x) 0 // Compatibility with non-clang compilers.
+#endif
+
+#ifndef NS_RETURNS_RETAINED
+  #if __has_feature(attribute_ns_returns_retained)
+    #define NS_RETURNS_RETAINED __attribute__((ns_returns_retained))
+  #else
+    #define NS_RETURNS_RETAINED
+  #endif
+#endif
+
+#ifndef NS_RETURNS_NOT_RETAINED
+  #if __has_feature(attribute_ns_returns_not_retained)
+    #define NS_RETURNS_NOT_RETAINED __attribute__((ns_returns_not_retained))
+  #else
+    #define NS_RETURNS_NOT_RETAINED
+  #endif
+#endif
+
+#ifndef CF_RETURNS_RETAINED
+  #if __has_feature(attribute_cf_returns_retained)
+    #define CF_RETURNS_RETAINED __attribute__((cf_returns_retained))
+  #else
+    #define CF_RETURNS_RETAINED
+  #endif
+#endif
+
+#ifndef CF_RETURNS_NOT_RETAINED
+  #if __has_feature(attribute_cf_returns_not_retained)
+    #define CF_RETURNS_NOT_RETAINED __attribute__((cf_returns_not_retained))
+  #else
+    #define CF_RETURNS_NOT_RETAINED
+  #endif
+#endif
+
+#ifndef NS_CONSUMED
+  #if __has_feature(attribute_ns_consumed)
+    #define NS_CONSUMED __attribute__((ns_consumed))
+  #else
+    #define NS_CONSUMED
+  #endif
+#endif
+
+#ifndef CF_CONSUMED
+  #if __has_feature(attribute_cf_consumed)
+    #define CF_CONSUMED __attribute__((cf_consumed))
+  #else
+    #define CF_CONSUMED
+  #endif
+#endif
+
+#ifndef NS_CONSUMES_SELF
+  #if __has_feature(attribute_ns_consumes_self)
+    #define NS_CONSUMES_SELF __attribute__((ns_consumes_self))
+  #else
+    #define NS_CONSUMES_SELF
+  #endif
+#endif
+
+// Defined on 10.6 and above.
+#ifndef NS_FORMAT_ARGUMENT
+  #define NS_FORMAT_ARGUMENT(A)
+#endif
+
+// Defined on 10.6 and above.
+#ifndef NS_FORMAT_FUNCTION
+  #define NS_FORMAT_FUNCTION(F,A)
+#endif
+
+// Defined on 10.6 and above.
+#ifndef CF_FORMAT_ARGUMENT
+  #define CF_FORMAT_ARGUMENT(A)
+#endif
+
+// Defined on 10.6 and above.
+#ifndef CF_FORMAT_FUNCTION
+  #define CF_FORMAT_FUNCTION(F,A)
+#endif
+
+#ifndef GTM_NONNULL
+  #if defined(__has_attribute)
+    #if __has_attribute(nonnull)
+      #define GTM_NONNULL(x) __attribute__((nonnull x))
+    #else
+      #define GTM_NONNULL(x)
+    #endif
+  #else
+    #define GTM_NONNULL(x)
+  #endif
+#endif
+
+// Invalidates the initializer from which it's called.
+#ifndef GTMInvalidateInitializer
+  #if __has_feature(objc_arc)
+    #define GTMInvalidateInitializer() \
+      do { \
+        [self class]; /* Avoid warning of dead store to |self|. */ \
+        _GTMDevAssert(NO, @"Invalid initializer."); \
+        return nil; \
+      } while (0)
+  #else
+    #define GTMInvalidateInitializer() \
+      do { \
+        [self release]; \
+        _GTMDevAssert(NO, @"Invalid initializer."); \
+        return nil; \
+      } while (0)
+  #endif
+#endif
+
+#ifndef GTMCFAutorelease
+  #if __has_feature(objc_arc)
+    #define GTMCFAutorelease(x) CFBridgingRelease(x)
+  #else
+    #define GTMCFAutorelease(x) ([(id)x autorelease])
+  #endif
+#endif
+
+#ifdef __OBJC__
+
+// Declared here so that it can easily be used for logging tracking if
+// necessary. See GTMUnitTestDevLog.h for details.
+@class NSString;
+GTM_EXTERN void _GTMUnitTestDevLog(NSString *format, ...) NS_FORMAT_FUNCTION(1, 2);
+
+// Macro to allow you to create NSStrings out of other macros.
+// #define FOO foo
+// NSString *fooString = GTM_NSSTRINGIFY(FOO);
+#if !defined (GTM_NSSTRINGIFY)
+  #define GTM_NSSTRINGIFY_INNER(x) @#x
+  #define GTM_NSSTRINGIFY(x) GTM_NSSTRINGIFY_INNER(x)
+#endif
+
+// Macro to allow fast enumeration when building for 10.5 or later, and
+// reliance on NSEnumerator for 10.4.  Remember, NSDictionary w/ FastEnumeration
+// does keys, so pick the right thing, nothing is done on the FastEnumeration
+// side to be sure you're getting what you wanted.
+#ifndef GTM_FOREACH_OBJECT
+  #if TARGET_OS_IPHONE || !(MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5)
+    #define GTM_FOREACH_ENUMEREE(element, enumeration) \
+      for (element in enumeration)
+    #define GTM_FOREACH_OBJECT(element, collection) \
+      for (element in collection)
+    #define GTM_FOREACH_KEY(element, collection) \
+      for (element in collection)
+  #else
+    #define GTM_FOREACH_ENUMEREE(element, enumeration) \
+      for (NSEnumerator *_ ## element ## _enum = enumeration; \
+           (element = [_ ## element ## _enum nextObject]) != nil; )
+    #define GTM_FOREACH_OBJECT(element, collection) \
+      GTM_FOREACH_ENUMEREE(element, [collection objectEnumerator])
+    #define GTM_FOREACH_KEY(element, collection) \
+      GTM_FOREACH_ENUMEREE(element, [collection keyEnumerator])
+  #endif
+#endif
+
+// ============================================================================
+
+// To simplify support for both Leopard and Snow Leopard we declare
+// the Snow Leopard protocols that we need here.
+#if !defined(GTM_10_6_PROTOCOLS_DEFINED) && !(MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6)
+#define GTM_10_6_PROTOCOLS_DEFINED 1
+@protocol NSConnectionDelegate
+@end
+@protocol NSAnimationDelegate
+@end
+@protocol NSImageDelegate
+@end
+@protocol NSTabViewDelegate
+@end
+#endif  // !defined(GTM_10_6_PROTOCOLS_DEFINED) && !(MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6)
+
+// GTM_SEL_STRING is for specifying selector (usually property) names to KVC
+// or KVO methods.
+// In debug it will generate warnings for undeclared selectors if
+// -Wunknown-selector is turned on.
+// In release it will have no runtime overhead.
+#ifndef GTM_SEL_STRING
+  #ifdef DEBUG
+    #define GTM_SEL_STRING(selName) NSStringFromSelector(@selector(selName))
+  #else
+    #define GTM_SEL_STRING(selName) @#selName
+  #endif  // DEBUG
+#endif  // GTM_SEL_STRING
+
+#endif  // __OBJC__
diff --git a/include/breakpad/common/mac/GTMLogger.h b/include/breakpad/common/mac/GTMLogger.h
new file mode 100644
index 0000000..c4fd140
--- /dev/null
+++ b/include/breakpad/common/mac/GTMLogger.h
@@ -0,0 +1,504 @@
+//
+//  GTMLogger.h
+//
+//  Copyright 2007-2008 Google Inc.
+//
+//  Licensed under the Apache License, Version 2.0 (the "License"); you may not
+//  use this file except in compliance with the License.  You may obtain a copy
+//  of the License at
+//
+//  http://www.apache.org/licenses/LICENSE-2.0
+//
+//  Unless required by applicable law or agreed to in writing, software
+//  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+//  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+//  License for the specific language governing permissions and limitations under
+//  the License.
+//
+
+// Key Abstractions
+// ----------------
+//
+// This file declares multiple classes and protocols that are used by the
+// GTMLogger logging system. The 4 main abstractions used in this file are the
+// following:
+//
+//   * logger (GTMLogger) - The main logging class that users interact with. It
+//   has methods for logging at different levels and uses a log writer, a log
+//   formatter, and a log filter to get the job done.
+//
+//   * log writer (GTMLogWriter) - Writes a given string to some log file, where
+//   a "log file" can be a physical file on disk, a POST over HTTP to some URL,
+//   or even some in-memory structure (e.g., a ring buffer).
+//
+//   * log formatter (GTMLogFormatter) - Given a format string and arguments as
+//   a va_list, returns a single formatted NSString. A "formatted string" could
+//   be a string with the date prepended, a string with values in a CSV format,
+//   or even a string of XML.
+//
+//   * log filter (GTMLogFilter) - Given a formatted log message as an NSString
+//   and the level at which the message is to be logged, this class will decide
+//   whether the given message should be logged or not. This is a flexible way
+//   to filter out messages logged at a certain level, messages that contain
+//   certain text, or filter nothing out at all. This gives the caller the
+//   flexibility to dynamically enable debug logging in Release builds.
+//
+// This file also declares some classes to handle the common log writer, log
+// formatter, and log filter cases. Callers can also create their own writers,
+// formatters, and filters and they can even build them on top of the ones
+// declared here. Keep in mind that your custom writer/formatter/filter may be
+// called from multiple threads, so it must be thread-safe.
+
+#import <Foundation/Foundation.h>
+#import "GTMDefines.h"
+
+// Predeclaration of used protocols that are declared later in this file.
+@protocol GTMLogWriter, GTMLogFormatter, GTMLogFilter;
+
+// GTMLogger
+//
+// GTMLogger is the primary user-facing class for an object-oriented logging
+// system. It is built on the concept of log formatters (GTMLogFormatter), log
+// writers (GTMLogWriter), and log filters (GTMLogFilter). When a message is
+// sent to a GTMLogger to log a message, the message is formatted using the log
+// formatter, then the log filter is consulted to see if the message should be
+// logged, and if so, the message is sent to the log writer to be written out.
+//
+// GTMLogger is intended to be a flexible and thread-safe logging solution. Its
+// flexibility comes from the fact that GTMLogger instances can be customized
+// with user defined formatters, filters, and writers. And these writers,
+// filters, and formatters can be combined, stacked, and customized in arbitrary
+// ways to suit the needs at hand. For example, multiple writers can be used at
+// the same time, and a GTMLogger instance can even be used as another
+// GTMLogger's writer. This allows for arbitrarily deep logging trees.
+//
+// A standard GTMLogger uses a writer that sends messages to standard out, a
+// formatter that smacks a timestamp and a few other bits of interesting
+// information on the message, and a filter that filters out debug messages from
+// release builds. Using the standard log settings, a log message will look like
+// the following:
+//
+//   2007-12-30 10:29:24.177 myapp[4588/0xa07d0f60] [lvl=1] foo=<Foo: 0x123>
+//
+// The output contains the date and time of the log message, the name of the
+// process followed by its process ID/thread ID, the log level at which the
+// message was logged (in the previous example the level was 1:
+// kGTMLoggerLevelDebug), and finally, the user-specified log message itself (in
+// this case, the log message was @"foo=%@", foo).
+//
+// Multiple instances of GTMLogger can be created, each configured their own
+// way.  Though GTMLogger is not a singleton (in the GoF sense), it does provide
+// access to a shared (i.e., globally accessible) GTMLogger instance. This makes
+// it convenient for all code in a process to use the same GTMLogger instance.
+// The shared GTMLogger instance can also be configured in an arbitrary, and
+// these configuration changes will affect all code that logs through the shared
+// instance.
+
+//
+// Log Levels
+// ----------
+// GTMLogger has 3 different log levels: Debug, Info, and Error. GTMLogger
+// doesn't take any special action based on the log level; it simply forwards
+// this information on to formatters, filters, and writers, each of which may
+// optionally take action based on the level. Since log level filtering is
+// performed at runtime, log messages are typically not filtered out at compile
+// time.  The exception to this rule is that calls to the GTMLoggerDebug() macro
+// *ARE* filtered out of non-DEBUG builds. This is to be backwards compatible
+// with behavior that many developers are currently used to. Note that this
+// means that GTMLoggerDebug(@"hi") will be compiled out of Release builds, but
+// [[GTMLogger sharedLogger] logDebug:@"hi"] will NOT be compiled out.
+//
+// Standard loggers are created with the GTMLogLevelFilter log filter, which
+// filters out certain log messages based on log level, and some other settings.
+//
+// In addition to the -logDebug:, -logInfo:, and -logError: methods defined on
+// GTMLogger itself, there are also C macros that make usage of the shared
+// GTMLogger instance very convenient. These macros are:
+//
+//   GTMLoggerDebug(...)
+//   GTMLoggerInfo(...)
+//   GTMLoggerError(...)
+//
+// Again, a notable feature of these macros is that GTMLogDebug() calls *will be
+// compiled out of non-DEBUG builds*.
+//
+// Standard Loggers
+// ----------------
+// GTMLogger has the concept of "standard loggers". A standard logger is simply
+// a logger that is pre-configured with some standard/common writer, formatter,
+// and filter combination. Standard loggers are created using the creation
+// methods beginning with "standard". The alternative to a standard logger is a
+// regular logger, which will send messages to stdout, with no special
+// formatting, and no filtering.
+//
+// How do I use GTMLogger?
+// ----------------------
+// The typical way you will want to use GTMLogger is to simply use the
+// GTMLogger*() macros for logging from code. That way we can easily make
+// changes to the GTMLogger class and simply update the macros accordingly. Only
+// your application startup code (perhaps, somewhere in main()) should use the
+// GTMLogger class directly in order to configure the shared logger, which all
+// of the code using the macros will be using. Again, this is just the typical
+// situation.
+//
+// To be complete, there are cases where you may want to use GTMLogger directly,
+// or even create separate GTMLogger instances for some reason. That's fine,
+// too.
+//
+// Examples
+// --------
+// The following show some common GTMLogger use cases.
+//
+// 1. You want to log something as simply as possible. Also, this call will only
+//    appear in debug builds. In non-DEBUG builds it will be completely removed.
+//
+//      GTMLoggerDebug(@"foo = %@", foo);
+//
+// 2. The previous example is similar to the following. The major difference is
+//    that the previous call (example 1) will be compiled out of Release builds
+//    but this statement will not be compiled out.
+//
+//      [[GTMLogger sharedLogger] logDebug:@"foo = %@", foo];
+//
+// 3. Send all logging output from the shared logger to a file. We do this by
+//    creating an NSFileHandle for writing associated with a file, and setting
+//    that file handle as the logger's writer.
+//
+//      NSFileHandle *f = [NSFileHandle fileHandleForWritingAtPath:@"/tmp/f.log"
+//                                                          create:YES];
+//      [[GTMLogger sharedLogger] setWriter:f];
+//      GTMLoggerError(@"hi");  // This will be sent to /tmp/f.log
+//
+// 4. Create a new GTMLogger that will log to a file. This example differs from
+//    the previous one because here we create a new GTMLogger that is different
+//    from the shared logger.
+//
+//      GTMLogger *logger = [GTMLogger standardLoggerWithPath:@"/tmp/temp.log"];
+//      [logger logInfo:@"hi temp log file"];
+//
+// 5. Create a logger that writes to stdout and does NOT do any formatting to
+//    the log message. This might be useful, for example, when writing a help
+//    screen for a command-line tool to standard output.
+//
+//      GTMLogger *logger = [GTMLogger logger];
+//      [logger logInfo:@"%@ version 0.1 usage", progName];
+//
+// 6. Send log output to stdout AND to a log file. The trick here is that
+//    NSArrays function as composite log writers, which means when an array is
+//    set as the log writer, it forwards all logging messages to all of its
+//    contained GTMLogWriters.
+//
+//      // Create array of GTMLogWriters
+//      NSArray *writers = [NSArray arrayWithObjects:
+//          [NSFileHandle fileHandleForWritingAtPath:@"/tmp/f.log" create:YES],
+//          [NSFileHandle fileHandleWithStandardOutput], nil];
+//
+//      GTMLogger *logger = [GTMLogger standardLogger];
+//      [logger setWriter:writers];
+//      [logger logInfo:@"hi"];  // Output goes to stdout and /tmp/f.log
+//
+// For futher details on log writers, formatters, and filters, see the
+// documentation below.
+//
+// NOTE: GTMLogger is application level logging.  By default it does nothing
+// with _GTMDevLog/_GTMDevAssert (see GTMDefines.h).  An application can choose
+// to bridge _GTMDevLog/_GTMDevAssert to GTMLogger by providing macro
+// definitions in its prefix header (see GTMDefines.h for how one would do
+// that).
+//
+@interface GTMLogger : NSObject {
+ @private
+  id<GTMLogWriter> writer_;
+  id<GTMLogFormatter> formatter_;
+  id<GTMLogFilter> filter_;
+}
+
+//
+// Accessors for the shared logger instance
+//
+
+// Returns a shared/global standard GTMLogger instance. Callers should typically
+// use this method to get a GTMLogger instance, unless they explicitly want
+// their own instance to configure for their own needs. This is the only method
+// that returns a shared instance; all the rest return new GTMLogger instances.
++ (id)sharedLogger;
+
+// Sets the shared logger instance to |logger|. Future calls to +sharedLogger
+// will return |logger| instead.
++ (void)setSharedLogger:(GTMLogger *)logger;
+
+//
+// Creation methods
+//
+
+// Returns a new autoreleased GTMLogger instance that will log to stdout, using
+// the GTMLogStandardFormatter, and the GTMLogLevelFilter filter.
++ (id)standardLogger;
+
+// Same as +standardLogger, but logs to stderr.
++ (id)standardLoggerWithStderr;
+
+// Same as +standardLogger but levels >= kGTMLoggerLevelError are routed to
+// stderr, everything else goes to stdout.
++ (id)standardLoggerWithStdoutAndStderr;
+
+// Returns a new standard GTMLogger instance with a log writer that will
+// write to the file at |path|, and will use the GTMLogStandardFormatter and
+// GTMLogLevelFilter classes. If |path| does not exist, it will be created.
++ (id)standardLoggerWithPath:(NSString *)path;
+
+// Returns an autoreleased GTMLogger instance that will use the specified
+// |writer|, |formatter|, and |filter|.
++ (id)loggerWithWriter:(id<GTMLogWriter>)writer
+             formatter:(id<GTMLogFormatter>)formatter
+                filter:(id<GTMLogFilter>)filter;
+
+// Returns an autoreleased GTMLogger instance that logs to stdout, with the
+// basic formatter, and no filter. The returned logger differs from the logger
+// returned by +standardLogger because this one does not do any filtering and
+// does not do any special log formatting; this is the difference between a
+// "regular" logger and a "standard" logger.
++ (id)logger;
+
+// Designated initializer. This method returns a GTMLogger initialized with the
+// specified |writer|, |formatter|, and |filter|. See the setter methods below
+// for what values will be used if nil is passed for a parameter.
+- (id)initWithWriter:(id<GTMLogWriter>)writer
+           formatter:(id<GTMLogFormatter>)formatter
+              filter:(id<GTMLogFilter>)filter;
+
+//
+// Logging  methods
+//
+
+// Logs a message at the debug level (kGTMLoggerLevelDebug).
+- (void)logDebug:(NSString *)fmt, ... NS_FORMAT_FUNCTION(1, 2);
+// Logs a message at the info level (kGTMLoggerLevelInfo).
+- (void)logInfo:(NSString *)fmt, ... NS_FORMAT_FUNCTION(1, 2);
+// Logs a message at the error level (kGTMLoggerLevelError).
+- (void)logError:(NSString *)fmt, ... NS_FORMAT_FUNCTION(1, 2);
+// Logs a message at the assert level (kGTMLoggerLevelAssert).
+- (void)logAssert:(NSString *)fmt, ... NS_FORMAT_FUNCTION(1, 2);
+
+
+//
+// Accessors
+//
+
+// Accessor methods for the log writer. If the log writer is set to nil,
+// [NSFileHandle fileHandleWithStandardOutput] is used.
+- (id<GTMLogWriter>)writer;
+- (void)setWriter:(id<GTMLogWriter>)writer;
+
+// Accessor methods for the log formatter. If the log formatter is set to nil,
+// GTMLogBasicFormatter is used. This formatter will format log messages in a
+// plain printf style.
+- (id<GTMLogFormatter>)formatter;
+- (void)setFormatter:(id<GTMLogFormatter>)formatter;
+
+// Accessor methods for the log filter. If the log filter is set to nil,
+// GTMLogNoFilter is used, which allows all log messages through.
+- (id<GTMLogFilter>)filter;
+- (void)setFilter:(id<GTMLogFilter>)filter;
+
+@end  // GTMLogger
+
+
+// Helper functions that are used by the convenience GTMLogger*() macros that
+// enable the logging of function names.
+@interface GTMLogger (GTMLoggerMacroHelpers)
+- (void)logFuncDebug:(const char *)func msg:(NSString *)fmt, ...
+  NS_FORMAT_FUNCTION(2, 3);
+- (void)logFuncInfo:(const char *)func msg:(NSString *)fmt, ...
+  NS_FORMAT_FUNCTION(2, 3);
+- (void)logFuncError:(const char *)func msg:(NSString *)fmt, ...
+  NS_FORMAT_FUNCTION(2, 3);
+- (void)logFuncAssert:(const char *)func msg:(NSString *)fmt, ...
+  NS_FORMAT_FUNCTION(2, 3);
+@end  // GTMLoggerMacroHelpers
+
+
+// The convenience macros are only defined if they haven't already been defined.
+#ifndef GTMLoggerInfo
+
+// Convenience macros that log to the shared GTMLogger instance. These macros
+// are how users should typically log to GTMLogger. Notice that GTMLoggerDebug()
+// calls will be compiled out of non-Debug builds.
+#define GTMLoggerDebug(...)  \
+  [[GTMLogger sharedLogger] logFuncDebug:__func__ msg:__VA_ARGS__]
+#define GTMLoggerInfo(...)   \
+  [[GTMLogger sharedLogger] logFuncInfo:__func__ msg:__VA_ARGS__]
+#define GTMLoggerError(...)  \
+  [[GTMLogger sharedLogger] logFuncError:__func__ msg:__VA_ARGS__]
+#define GTMLoggerAssert(...) \
+  [[GTMLogger sharedLogger] logFuncAssert:__func__ msg:__VA_ARGS__]
+
+// If we're not in a debug build, remove the GTMLoggerDebug statements. This
+// makes calls to GTMLoggerDebug "compile out" of Release builds
+#ifndef DEBUG
+#undef GTMLoggerDebug
+#define GTMLoggerDebug(...) do {} while(0)
+#endif
+
+#endif  // !defined(GTMLoggerInfo)
+
+// Log levels.
+typedef enum {
+  kGTMLoggerLevelUnknown,
+  kGTMLoggerLevelDebug,
+  kGTMLoggerLevelInfo,
+  kGTMLoggerLevelError,
+  kGTMLoggerLevelAssert,
+} GTMLoggerLevel;
+
+
+//
+//   Log Writers
+//
+
+// Protocol to be implemented by a GTMLogWriter instance.
+@protocol GTMLogWriter <NSObject>
+// Writes the given log message to where the log writer is configured to write.
+- (void)logMessage:(NSString *)msg level:(GTMLoggerLevel)level;
+@end  // GTMLogWriter
+
+
+// Simple category on NSFileHandle that makes NSFileHandles valid log writers.
+// This is convenient because something like, say, +fileHandleWithStandardError
+// now becomes a valid log writer. Log messages are written to the file handle
+// with a newline appended.
+@interface NSFileHandle (GTMFileHandleLogWriter) <GTMLogWriter>
+// Opens the file at |path| in append mode, and creates the file with |mode|
+// if it didn't previously exist.
++ (id)fileHandleForLoggingAtPath:(NSString *)path mode:(mode_t)mode;
+@end  // NSFileHandle
+
+
+// This category makes NSArray a GTMLogWriter that can be composed of other
+// GTMLogWriters. This is the classic Composite GoF design pattern. When the
+// GTMLogWriter -logMessage:level: message is sent to the array, the array
+// forwards the message to all of its elements that implement the GTMLogWriter
+// protocol.
+//
+// This is useful in situations where you would like to send log output to
+// multiple log writers at the same time. Simply create an NSArray of the log
+// writers you wish to use, then set the array as the "writer" for your
+// GTMLogger instance.
+@interface NSArray (GTMArrayCompositeLogWriter) <GTMLogWriter>
+@end  // GTMArrayCompositeLogWriter
+
+
+// This category adapts the GTMLogger interface so that it can be used as a log
+// writer; it's an "adapter" in the GoF Adapter pattern sense.
+//
+// This is useful when you want to configure a logger to log to a specific
+// writer with a specific formatter and/or filter. But you want to also compose
+// that with a different log writer that may have its own formatter and/or
+// filter.
+@interface GTMLogger (GTMLoggerLogWriter) <GTMLogWriter>
+@end  // GTMLoggerLogWriter
+
+
+//
+//   Log Formatters
+//
+
+// Protocol to be implemented by a GTMLogFormatter instance.
+@protocol GTMLogFormatter <NSObject>
+// Returns a formatted string using the format specified in |fmt| and the va
+// args specified in |args|.
+- (NSString *)stringForFunc:(NSString *)func
+                 withFormat:(NSString *)fmt
+                     valist:(va_list)args
+                      level:(GTMLoggerLevel)level NS_FORMAT_FUNCTION(2, 0);
+@end  // GTMLogFormatter
+
+
+// A basic log formatter that formats a string the same way that NSLog (or
+// printf) would. It does not do anything fancy, nor does it add any data of its
+// own.
+@interface GTMLogBasicFormatter : NSObject <GTMLogFormatter>
+
+// Helper method for prettying C99 __func__ and GCC __PRETTY_FUNCTION__
+- (NSString *)prettyNameForFunc:(NSString *)func;
+
+@end  // GTMLogBasicFormatter
+
+
+// A log formatter that formats the log string like the basic formatter, but
+// also prepends a timestamp and some basic process info to the message, as
+// shown in the following sample output.
+//   2007-12-30 10:29:24.177 myapp[4588/0xa07d0f60] [lvl=1] log mesage here
+@interface GTMLogStandardFormatter : GTMLogBasicFormatter {
+ @private
+  NSDateFormatter *dateFormatter_;  // yyyy-MM-dd HH:mm:ss.SSS
+  NSString *pname_;
+  pid_t pid_;
+}
+@end  // GTMLogStandardFormatter
+
+
+//
+//   Log Filters
+//
+
+// Protocol to be imlemented by a GTMLogFilter instance.
+@protocol GTMLogFilter <NSObject>
+// Returns YES if |msg| at |level| should be filtered out; NO otherwise.
+- (BOOL)filterAllowsMessage:(NSString *)msg level:(GTMLoggerLevel)level;
+@end  // GTMLogFilter
+
+
+// A log filter that filters messages at the kGTMLoggerLevelDebug level out of
+// non-debug builds. Messages at the kGTMLoggerLevelInfo level are also filtered
+// out of non-debug builds unless GTMVerboseLogging is set in the environment or
+// the processes's defaults. Messages at the kGTMLoggerLevelError level are
+// never filtered.
+@interface GTMLogLevelFilter : NSObject <GTMLogFilter>
+@end  // GTMLogLevelFilter
+
+// A simple log filter that does NOT filter anything out;
+// -filterAllowsMessage:level will always return YES. This can be a convenient
+// way to enable debug-level logging in release builds (if you so desire).
+@interface GTMLogNoFilter : NSObject <GTMLogFilter>
+@end  // GTMLogNoFilter
+
+
+// Base class for custom level filters. Not for direct use, use the minimum
+// or maximum level subclasses below.
+@interface GTMLogAllowedLevelFilter : NSObject <GTMLogFilter> {
+ @private
+  NSIndexSet *allowedLevels_;
+}
+@end
+
+// A log filter that allows you to set a minimum log level. Messages below this
+// level will be filtered.
+@interface GTMLogMininumLevelFilter : GTMLogAllowedLevelFilter
+
+// Designated initializer, logs at levels < |level| will be filtered.
+- (id)initWithMinimumLevel:(GTMLoggerLevel)level;
+
+@end
+
+// A log filter that allows you to set a maximum log level. Messages whose level
+// exceeds this level will be filtered. This is really only useful if you have
+// a composite GTMLogger that is sending the other messages elsewhere.
+@interface GTMLogMaximumLevelFilter : GTMLogAllowedLevelFilter
+
+// Designated initializer, logs at levels > |level| will be filtered.
+- (id)initWithMaximumLevel:(GTMLoggerLevel)level;
+
+@end
+
+
+// For subclasses only
+@interface GTMLogger (PrivateMethods)
+
+- (void)logInternalFunc:(const char *)func
+                 format:(NSString *)fmt
+                 valist:(va_list)args
+                  level:(GTMLoggerLevel)level NS_FORMAT_FUNCTION(2, 0);
+
+@end
+
diff --git a/include/breakpad/common/mac/HTTPMultipartUpload.h b/include/breakpad/common/mac/HTTPMultipartUpload.h
new file mode 100644
index 0000000..42e8fed
--- /dev/null
+++ b/include/breakpad/common/mac/HTTPMultipartUpload.h
@@ -0,0 +1,61 @@
+// Copyright (c) 2006, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// HTTPMultipartUpload: A multipart/form-data HTTP uploader.
+// Each parameter pair is sent as a boundary
+// Each file is sent with a name field in addition to the filename and data
+// The data will be sent synchronously.
+
+#import <Foundation/Foundation.h>
+
+@interface HTTPMultipartUpload : NSObject {
+ @protected
+  NSURL *url_;                  // The destination URL (STRONG)
+  NSDictionary *parameters_;    // The key/value pairs for sending data (STRONG)
+  NSMutableDictionary *files_;  // Dictionary of name/file-path (STRONG)
+  NSString *boundary_;          // The boundary string (STRONG)
+  NSHTTPURLResponse *response_; // The response from the send (STRONG)
+}
+
+- (id)initWithURL:(NSURL *)url;
+
+- (NSURL *)URL;
+
+- (void)setParameters:(NSDictionary *)parameters;
+- (NSDictionary *)parameters;
+
+- (void)addFileAtPath:(NSString *)path name:(NSString *)name;
+- (void)addFileContents:(NSData *)data name:(NSString *)name;
+- (NSDictionary *)files;
+
+// Set the data and return the response
+- (NSData *)send:(NSError **)error;
+- (NSHTTPURLResponse *)response;
+
+@end
diff --git a/include/breakpad/common/mac/MachIPC.h b/include/breakpad/common/mac/MachIPC.h
new file mode 100644
index 0000000..8df9165
--- /dev/null
+++ b/include/breakpad/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
+  uint8_t *GetData() {
+    return GetDataLength() > 0 ? GetDataPacket()->data : NULL;
+  }
+
+  uint32_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
+    uint8_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;
+  uint8_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/include/breakpad/common/mac/arch_utilities.h b/include/breakpad/common/mac/arch_utilities.h
new file mode 100644
index 0000000..397c1f5
--- /dev/null
+++ b/include/breakpad/common/mac/arch_utilities.h
@@ -0,0 +1,47 @@
+// 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.
+
+// arch_utilities.h: Utilities for architecture introspection for Mac platform.
+
+#ifndef COMMON_MAC_ARCH_UTILITIES_H__
+#define COMMON_MAC_ARCH_UTILITIES_H__
+
+#include <mach-o/arch.h>
+
+namespace google_breakpad {
+
+// Custom implementation of |NXGetArchInfoFromName| and
+// |NXGetArchInfoFromCpuType| that handle newer CPU on older OSes.
+const NXArchInfo* BreakpadGetArchInfoFromName(const char* arch_name);
+const NXArchInfo* BreakpadGetArchInfoFromCpuType(cpu_type_t cpu_type,
+                                                 cpu_subtype_t cpu_subtype);
+
+}  // namespace google_breakpad
+
+#endif  // COMMON_MAC_ARCH_UTILITIES_H__
diff --git a/include/breakpad/common/mac/bootstrap_compat.h b/include/breakpad/common/mac/bootstrap_compat.h
new file mode 100644
index 0000000..8ca7357
--- /dev/null
+++ b/include/breakpad/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/include/breakpad/common/mac/byteswap.h b/include/breakpad/common/mac/byteswap.h
new file mode 100644
index 0000000..a5d745b
--- /dev/null
+++ b/include/breakpad/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/include/breakpad/common/mac/dump_syms.h b/include/breakpad/common/mac/dump_syms.h
new file mode 100644
index 0000000..babed70
--- /dev/null
+++ b/include/breakpad/common/mac/dump_syms.h
@@ -0,0 +1,194 @@
+// -*- 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/mac/super_fat_arch.h"
+#include "common/module.h"
+#include "common/symbol_data.h"
+
+namespace google_breakpad {
+
+class DumpSymbols {
+ public:
+  DumpSymbols(SymbolData symbol_data, bool handle_inter_cu_refs)
+      : symbol_data_(symbol_data),
+        handle_inter_cu_refs_(handle_inter_cu_refs),
+        input_pathname_(),
+        object_filename_(),
+        contents_(),
+        object_files_(),
+        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 SuperFatArch 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 SuperFatArch* 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|. Return true on success; if an error occurs, report it and
+  // return false.
+  bool WriteSymbolFile(std::ostream &stream);
+
+  // As above, but simply return the debugging information in module
+  // instead of writing it to a stream. The caller owns the resulting
+  // module object and must delete it when finished.
+  bool ReadSymbolData(Module** module);
+
+ private:
+  // Used internally.
+  class DumperLineToModule;
+  class LoadCommandDumper;
+
+  // This method behaves similarly to NXFindBestFatArch, but it supports
+  // SuperFatArch.
+  SuperFatArch* FindBestMatchForArchitecture(
+      cpu_type_t cpu_type, cpu_subtype_t cpu_subtype);
+
+  // 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,
+                 bool handle_inter_cu_refs) 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 selection of what type of symbol data to read/write.
+  const SymbolData symbol_data_;
+
+  // Whether to handle references between compilation units.
+  const bool handle_inter_cu_refs_;
+
+  // 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 SuperFatArch 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<SuperFatArch> object_files_;
+
+  // The object file in object_files_ selected to dump, or NULL if
+  // SetArchitecture hasn't been called yet.
+  const SuperFatArch *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/include/breakpad/common/mac/file_id.h b/include/breakpad/common/mac/file_id.h
new file mode 100644
index 0000000..1d6dfde
--- /dev/null
+++ b/include/breakpad/common/mac/file_id.h
@@ -0,0 +1,81 @@
+// 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>
+#include <mach/machine.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| and |cpu_subtype| (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. If |cpu_subtype| is
+  // CPU_SUBTYPE_MULTIPLE, the match is only done on |cpu_type|.
+  // Returns false if opening the file failed or if the |cpu_type|/|cpu_subtype|
+  // 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(cpu_type_t cpu_type,
+                       cpu_subtype_t cpu_subtype,
+                       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/include/breakpad/common/mac/launch_reporter.h b/include/breakpad/common/mac/launch_reporter.h
new file mode 100644
index 0000000..4531123
--- /dev/null
+++ b/include/breakpad/common/mac/launch_reporter.h
@@ -0,0 +1,43 @@
+// Copyright (c) 2014, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef COMMON_MAC_LAUNCH_REPORTER_H__
+#define COMMON_MAC_LAUNCH_REPORTER_H__
+
+namespace google_breakpad {
+
+// Launch the crash dump sender app.
+// |reporter_executable_path| is the path to the sender executable.
+// |config_file_path| is the path to the config file.
+void LaunchReporter(const char *reporter_executable_path,
+                    const char *config_file_path);
+
+}  // namespace google_breakpad
+
+#endif  // COMMON_MAC_LAUNCH_REPORTER_H__
diff --git a/include/breakpad/common/mac/macho_id.h b/include/breakpad/common/mac/macho_id.h
new file mode 100644
index 0000000..1037549
--- /dev/null
+++ b/include/breakpad/common/mac/macho_id.h
@@ -0,0 +1,131 @@
+// 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/machine.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| and |cpu_subtype|, return a UUID from the LC_UUID
+  // command.
+  // Return false if there isn't a LC_UUID command.
+  bool UUIDCommand(cpu_type_t cpu_type,
+                   cpu_subtype_t cpu_subtype,
+                   unsigned char identifier[16]);
+
+  // For the given |cpu_type| and |cpu_subtype|, return a UUID from the
+  // LC_ID_DYLIB command.
+  // Return false if there isn't a LC_ID_DYLIB command.
+  bool IDCommand(cpu_type_t cpu_type,
+                 cpu_subtype_t cpu_subtype,
+                 unsigned char identifier[16]);
+
+  // For the given |cpu_type| and |cpu_subtype|, 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(cpu_type_t cpu_type,
+                   cpu_subtype_t cpu_subtype);
+
+  // For the given |cpu_type|, and |cpu_subtype| return the MD5 for the mach-o
+  // data segment(s).
+  // Return true on success, false otherwise
+  bool MD5(cpu_type_t cpu_type,
+           cpu_subtype_t cpu_subtype,
+           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(cpu_type_t cpu_type, cpu_subtype_t cpu_subtype,
+                  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/include/breakpad/common/mac/macho_reader.h b/include/breakpad/common/mac/macho_reader.h
new file mode 100644
index 0000000..30db742
--- /dev/null
+++ b/include/breakpad/common/mac/macho_reader.h
@@ -0,0 +1,460 @@
+// -*- 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"
+#include "common/mac/super_fat_arch.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 'SuperFatArch' 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 SuperFatArch 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 SuperFatArch* 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<SuperFatArch> 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/include/breakpad/common/mac/macho_utilities.h b/include/breakpad/common/mac/macho_utilities.h
new file mode 100644
index 0000000..a200c0f
--- /dev/null
+++ b/include/breakpad/common/mac/macho_utilities.h
@@ -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.
+
+// 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
+
+// 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/include/breakpad/common/mac/macho_walker.h b/include/breakpad/common/mac/macho_walker.h
new file mode 100644
index 0000000..dd53581
--- /dev/null
+++ b/include/breakpad/common/mac/macho_walker.h
@@ -0,0 +1,119 @@
+// 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/machine.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| and |cpu_subtype|.  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). If |cpu_subtype| is CPU_SUBTYPE_MULTIPLE, the match is
+  // only done on |cpu_type|.
+  // Returns false if opening the file failed or if the |cpu_type|/|cpu_subtype|
+  // is not present in the file.
+  bool WalkHeader(cpu_type_t cpu_type, cpu_subtype_t cpu_subtype);
+
+  // 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:
+  // Locate (if any) the header offset for |cpu_type| and return in |offset|.
+  // Return true if found, false otherwise.
+  bool FindHeader(cpu_type_t cpu_type,
+                  cpu_subtype_t cpu_subtype,
+                  off_t &offset);
+
+  // 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/include/breakpad/common/mac/scoped_task_suspend-inl.h b/include/breakpad/common/mac/scoped_task_suspend-inl.h
new file mode 100644
index 0000000..d6d1bef
--- /dev/null
+++ b/include/breakpad/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/include/breakpad/common/mac/string_utilities.h b/include/breakpad/common/mac/string_utilities.h
new file mode 100644
index 0000000..6d89c83
--- /dev/null
+++ b/include/breakpad/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/include/breakpad/common/mac/super_fat_arch.h b/include/breakpad/common/mac/super_fat_arch.h
new file mode 100644
index 0000000..501c865
--- /dev/null
+++ b/include/breakpad/common/mac/super_fat_arch.h
@@ -0,0 +1,88 @@
+// Copyright (c) 2015, 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: Erik Chen <erikchen@chromium.org>
+
+// super_fat_arch.h: A class to handle 64-bit object files. Has conversions to
+// and from struct fat_arch.
+
+#ifndef BREAKPAD_COMMON_MAC_SUPER_FAT_ARCH_H_
+#define BREAKPAD_COMMON_MAC_SUPER_FAT_ARCH_H_
+
+#include <limits>
+#include <mach-o/fat.h>
+#include <stdint.h>
+
+// Similar to struct fat_arch, except size-related parameters support
+// 64-bits.
+class SuperFatArch {
+ public:
+  uint32_t cputype;
+  uint32_t cpusubtype;
+  uint64_t offset;
+  uint64_t size;
+  uint64_t align;
+
+  SuperFatArch() :
+      cputype(0),
+      cpusubtype(0),
+      offset(0),
+      size(0),
+      align(0) {
+  }
+
+  explicit SuperFatArch(const struct fat_arch &arch) :
+      cputype(arch.cputype),
+      cpusubtype(arch.cpusubtype),
+      offset(arch.offset),
+      size(arch.size),
+      align(arch.align) {
+  }
+
+  // Returns false if the conversion cannot be made.
+  // If the conversion succeeds, the result is placed in |output_arch|.
+  bool ConvertToFatArch(struct fat_arch* output_arch) const {
+    if (offset > std::numeric_limits<uint32_t>::max())
+      return false;
+    if (size > std::numeric_limits<uint32_t>::max())
+      return false;
+    if (align > std::numeric_limits<uint32_t>::max())
+      return false;
+    struct fat_arch arch;
+    arch.cputype = cputype;
+    arch.cpusubtype = cpusubtype;
+    arch.offset = offset;
+    arch.size = size;
+    arch.align = align;
+    *output_arch = arch;
+    return true;
+  }
+};
+
+#endif  // BREAKPAD_COMMON_MAC_SUPER_FAT_ARCH_H_
diff --git a/include/breakpad/common/mac/testing/GTMSenTestCase.h b/include/breakpad/common/mac/testing/GTMSenTestCase.h
new file mode 100644
index 0000000..ce3d902
--- /dev/null
+++ b/include/breakpad/common/mac/testing/GTMSenTestCase.h
@@ -0,0 +1,1110 @@
+//
+//  GTMSenTestCase.h
+//
+//  Copyright 2007-2008 Google Inc.
+//
+//  Licensed under the Apache License, Version 2.0 (the "License"); you may not
+//  use this file except in compliance with the License.  You may obtain a copy
+//  of the License at
+//
+//  http://www.apache.org/licenses/LICENSE-2.0
+//
+//  Unless required by applicable law or agreed to in writing, software
+//  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+//  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+//  License for the specific language governing permissions and limitations under
+//  the License.
+//
+
+// Portions of this file fall under the following license, marked with
+// SENTE_BEGIN - SENTE_END
+//
+// Copyright (c) 1997-2005, Sen:te (Sente SA).  All rights reserved.
+//
+// Use of this source code is governed by the following license:
+//
+// 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.
+//
+// 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 Sente SA 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.
+//
+// Note: this license is equivalent to the FreeBSD license.
+//
+// This notice may not be removed from this file.
+
+// Some extra test case macros that would have been convenient for SenTestingKit
+// to provide. I didn't stick GTM in front of the Macro names, so that they would
+// be easy to remember.
+
+#import "GTMDefines.h"
+
+#if (!GTM_IPHONE_SDK) || (GTM_IPHONE_USE_SENTEST)
+#import <SenTestingKit/SenTestingKit.h>
+#else
+#import <Foundation/Foundation.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
+  
+#if defined __clang__
+// gcc and gcc-llvm do not allow you to use STAssert(blah, nil) with nil
+// as a description if you have the NS_FORMAT_FUNCTION on.
+// clang however will not compile without warnings if you don't have it.
+NSString *STComposeString(NSString *, ...) NS_FORMAT_FUNCTION(1, 2);
+#else
+NSString *STComposeString(NSString *, ...);
+#endif  // __clang__
+  
+#ifdef __cplusplus
+}
+#endif
+
+#endif  // !GTM_IPHONE_SDK || GTM_IPHONE_USE_SENTEST
+
+// Generates a failure when a1 != noErr
+//  Args:
+//    a1: should be either an OSErr or an OSStatus
+//    description: A format string as in the printf() function. Can be nil or
+//                 an empty string but must be present.
+//    ...: A variable number of arguments to the format string. Can be absent.
+#define STAssertNoErr(a1, description, ...) \
+do { \
+  @try { \
+    OSStatus a1value = (a1); \
+    if (a1value != noErr) { \
+      NSString *_expression = [NSString stringWithFormat:@"Expected noErr, got %ld for (%s)", (long)a1value, #a1]; \
+      [self failWithException:([NSException failureInCondition:_expression \
+                       isTrue:NO \
+                       inFile:[NSString stringWithUTF8String:__FILE__] \
+                       atLine:__LINE__ \
+              withDescription:@"%@", STComposeString(description, ##__VA_ARGS__)])]; \
+    } \
+  } \
+  @catch (id anException) { \
+    [self failWithException:[NSException failureInRaise:[NSString stringWithFormat:@"(%s) == noErr fails", #a1] \
+                                              exception:anException \
+                                                 inFile:[NSString stringWithUTF8String:__FILE__] \
+                                                 atLine:__LINE__ \
+                                        withDescription:@"%@", STComposeString(description, ##__VA_ARGS__)]]; \
+  } \
+} while(0)
+
+// Generates a failure when a1 != a2
+//  Args:
+//    a1: received value. Should be either an OSErr or an OSStatus
+//    a2: expected value. Should be either an OSErr or an OSStatus
+//    description: A format string as in the printf() function. Can be nil or
+//                 an empty string but must be present.
+//    ...: A variable number of arguments to the format string. Can be absent.
+#define STAssertErr(a1, a2, description, ...) \
+do { \
+  @try { \
+    OSStatus a1value = (a1); \
+    OSStatus a2value = (a2); \
+    if (a1value != a2value) { \
+      NSString *_expression = [NSString stringWithFormat:@"Expected %s(%ld) but got %ld for (%s)", #a2, (long)a2value, (long)a1value, #a1]; \
+      [self failWithException:([NSException failureInCondition:_expression \
+                       isTrue:NO \
+                       inFile:[NSString stringWithUTF8String:__FILE__] \
+                       atLine:__LINE__ \
+              withDescription:@"%@", STComposeString(description, ##__VA_ARGS__)])]; \
+    } \
+  } \
+  @catch (id anException) { \
+    [self failWithException:[NSException failureInRaise:[NSString stringWithFormat:@"(%s) == (%s) fails", #a1, #a2] \
+                                              exception:anException \
+                                                 inFile:[NSString stringWithUTF8String:__FILE__] \
+                                                 atLine:__LINE__ \
+                                        withDescription:@"%@", STComposeString(description, ##__VA_ARGS__)]]; \
+  } \
+} while(0)
+
+
+// Generates a failure when a1 is NULL
+//  Args:
+//    a1: should be a pointer (use STAssertNotNil for an object)
+//    description: A format string as in the printf() function. Can be nil or
+//                 an empty string but must be present.
+//    ...: A variable number of arguments to the format string. Can be absent.
+#define STAssertNotNULL(a1, description, ...) \
+do { \
+  @try { \
+    __typeof__(a1) a1value = (a1); \
+    if (a1value == (__typeof__(a1))NULL) { \
+      NSString *_expression = [NSString stringWithFormat:@"((%s) != NULL)", #a1]; \
+      [self failWithException:([NSException failureInCondition:_expression \
+                       isTrue:NO \
+                       inFile:[NSString stringWithUTF8String:__FILE__] \
+                       atLine:__LINE__ \
+              withDescription:@"%@", STComposeString(description, ##__VA_ARGS__)])]; \
+    } \
+  } \
+  @catch (id anException) { \
+    [self failWithException:[NSException failureInRaise:[NSString stringWithFormat:@"(%s) != NULL fails", #a1] \
+                                              exception:anException \
+                                                 inFile:[NSString stringWithUTF8String:__FILE__] \
+                                                 atLine:__LINE__ \
+                                        withDescription:@"%@", STComposeString(description, ##__VA_ARGS__)]]; \
+  } \
+} while(0)
+
+// Generates a failure when a1 is not NULL
+//  Args:
+//    a1: should be a pointer (use STAssertNil for an object)
+//    description: A format string as in the printf() function. Can be nil or
+//                 an empty string but must be present.
+//    ...: A variable number of arguments to the format string. Can be absent.
+#define STAssertNULL(a1, description, ...) \
+do { \
+  @try { \
+    __typeof__(a1) a1value = (a1); \
+    if (a1value != (__typeof__(a1))NULL) { \
+      NSString *_expression = [NSString stringWithFormat:@"((%s) == NULL)", #a1]; \
+      [self failWithException:([NSException failureInCondition:_expression \
+                                                        isTrue:NO \
+                                                        inFile:[NSString stringWithUTF8String:__FILE__] \
+                                                        atLine:__LINE__ \
+                                               withDescription:@"%@", STComposeString(description, ##__VA_ARGS__)])]; \
+    } \
+  } \
+  @catch (id anException) { \
+    [self failWithException:[NSException failureInRaise:[NSString stringWithFormat:@"(%s) == NULL fails", #a1] \
+                                              exception:anException \
+                                                 inFile:[NSString stringWithUTF8String:__FILE__] \
+                                                 atLine:__LINE__ \
+                                        withDescription:@"%@", STComposeString(description, ##__VA_ARGS__)]]; \
+  } \
+} while(0)
+
+// Generates a failure when a1 is equal to a2. This test is for C scalars,
+// structs and unions.
+//  Args:
+//    a1: argument 1
+//    a2: argument 2
+//    description: A format string as in the printf() function. Can be nil or
+//                 an empty string but must be present.
+//    ...: A variable number of arguments to the format string. Can be absent.
+#define STAssertNotEquals(a1, a2, description, ...) \
+do { \
+  @try { \
+    if (strcmp(@encode(__typeof__(a1)), @encode(__typeof__(a2)))) { \
+      [self failWithException:[NSException failureInFile:[NSString stringWithUTF8String:__FILE__] \
+                                                  atLine:__LINE__ \
+                                         withDescription:@"Type mismatch -- %@", STComposeString(description, ##__VA_ARGS__)]]; \
+    } else { \
+      __typeof__(a1) a1value = (a1); \
+      __typeof__(a2) a2value = (a2); \
+      NSValue *a1encoded = [NSValue value:&a1value withObjCType:@encode(__typeof__(a1))]; \
+      NSValue *a2encoded = [NSValue value:&a2value withObjCType:@encode(__typeof__(a2))]; \
+      if ([a1encoded isEqualToValue:a2encoded]) { \
+        NSString *_expression = [NSString stringWithFormat:@"((%s) != (%s))", #a1, #a2]; \
+        [self failWithException:([NSException failureInCondition:_expression \
+                         isTrue:NO \
+                         inFile:[NSString stringWithUTF8String:__FILE__] \
+                         atLine:__LINE__ \
+                withDescription:@"%@", STComposeString(description, ##__VA_ARGS__)])]; \
+      }\
+    } \
+  } \
+  @catch (id anException) { \
+    [self failWithException:[NSException failureInRaise:[NSString stringWithFormat:@"(%s) != (%s)", #a1, #a2] \
+                                              exception:anException \
+                                                 inFile:[NSString stringWithUTF8String:__FILE__] \
+                                                 atLine:__LINE__ \
+            withDescription:@"%@", STComposeString(description, ##__VA_ARGS__)]]; \
+  } \
+} while(0)
+
+// Generates a failure when a1 is equal to a2. This test is for objects.
+//  Args:
+//    a1: argument 1. object.
+//    a2: argument 2. object.
+//    description: A format string as in the printf() function. Can be nil or
+//                 an empty string but must be present.
+//    ...: A variable number of arguments to the format string. Can be absent.
+#define STAssertNotEqualObjects(a1, a2, description, ...) \
+do { \
+  @try {\
+    id a1value = (a1); \
+    id a2value = (a2); \
+    if ( (strcmp(@encode(__typeof__(a1value)), @encode(id)) == 0) && \
+         (strcmp(@encode(__typeof__(a2value)), @encode(id)) == 0) && \
+         (![(id)a1value isEqual:(id)a2value]) ) continue; \
+    [self failWithException:([NSException failureInEqualityBetweenObject:a1value \
+                  andObject:a2value \
+                     inFile:[NSString stringWithUTF8String:__FILE__] \
+                     atLine:__LINE__ \
+            withDescription:@"%@", STComposeString(description, ##__VA_ARGS__)])]; \
+  }\
+  @catch (id anException) {\
+    [self failWithException:([NSException failureInRaise:[NSString stringWithFormat:@"(%s) != (%s)", #a1, #a2] \
+                                               exception:anException \
+                                                  inFile:[NSString stringWithUTF8String:__FILE__] \
+                                                  atLine:__LINE__ \
+                                         withDescription:@"%@", STComposeString(description, ##__VA_ARGS__)])]; \
+  }\
+} while(0)
+
+// Generates a failure when a1 is not 'op' to a2. This test is for C scalars.
+//  Args:
+//    a1: argument 1
+//    a2: argument 2
+//    op: operation
+//    description: A format string as in the printf() function. Can be nil or
+//                 an empty string but must be present.
+//    ...: A variable number of arguments to the format string. Can be absent.
+#define STAssertOperation(a1, a2, op, description, ...) \
+do { \
+  @try { \
+    if (strcmp(@encode(__typeof__(a1)), @encode(__typeof__(a2)))) { \
+      [self failWithException:[NSException failureInFile:[NSString stringWithUTF8String:__FILE__] \
+                                                  atLine:__LINE__ \
+                                         withDescription:@"Type mismatch -- %@", STComposeString(description, ##__VA_ARGS__)]]; \
+    } else { \
+      __typeof__(a1) a1value = (a1); \
+      __typeof__(a2) a2value = (a2); \
+      if (!(a1value op a2value)) { \
+        double a1DoubleValue = a1value; \
+        double a2DoubleValue = a2value; \
+        NSString *_expression = [NSString stringWithFormat:@"(%s (%lg) %s %s (%lg))", #a1, a1DoubleValue, #op, #a2, a2DoubleValue]; \
+        [self failWithException:([NSException failureInCondition:_expression \
+                         isTrue:NO \
+                         inFile:[NSString stringWithUTF8String:__FILE__] \
+                         atLine:__LINE__ \
+                withDescription:@"%@", STComposeString(description, ##__VA_ARGS__)])]; \
+      } \
+    } \
+  } \
+  @catch (id anException) { \
+    [self failWithException:[NSException \
+             failureInRaise:[NSString stringWithFormat:@"(%s) %s (%s)", #a1, #op, #a2] \
+                  exception:anException \
+                     inFile:[NSString stringWithUTF8String:__FILE__] \
+                     atLine:__LINE__ \
+            withDescription:@"%@", STComposeString(description, ##__VA_ARGS__)]]; \
+  } \
+} while(0)
+
+// Generates a failure when a1 is not > a2. This test is for C scalars.
+//  Args:
+//    a1: argument 1
+//    a2: argument 2
+//    op: operation
+//    description: A format string as in the printf() function. Can be nil or
+//                 an empty string but must be present.
+//    ...: A variable number of arguments to the format string. Can be absent.
+#define STAssertGreaterThan(a1, a2, description, ...) \
+  STAssertOperation(a1, a2, >, description, ##__VA_ARGS__)
+
+// Generates a failure when a1 is not >= a2. This test is for C scalars.
+//  Args:
+//    a1: argument 1
+//    a2: argument 2
+//    op: operation
+//    description: A format string as in the printf() function. Can be nil or
+//                 an empty string but must be present.
+//    ...: A variable number of arguments to the format string. Can be absent.
+#define STAssertGreaterThanOrEqual(a1, a2, description, ...) \
+  STAssertOperation(a1, a2, >=, description, ##__VA_ARGS__)
+
+// Generates a failure when a1 is not < a2. This test is for C scalars.
+//  Args:
+//    a1: argument 1
+//    a2: argument 2
+//    op: operation
+//    description: A format string as in the printf() function. Can be nil or
+//                 an empty string but must be present.
+//    ...: A variable number of arguments to the format string. Can be absent.
+#define STAssertLessThan(a1, a2, description, ...) \
+  STAssertOperation(a1, a2, <, description, ##__VA_ARGS__)
+
+// Generates a failure when a1 is not <= a2. This test is for C scalars.
+//  Args:
+//    a1: argument 1
+//    a2: argument 2
+//    op: operation
+//    description: A format string as in the printf() function. Can be nil or
+//                 an empty string but must be present.
+//    ...: A variable number of arguments to the format string. Can be absent.
+#define STAssertLessThanOrEqual(a1, a2, description, ...) \
+  STAssertOperation(a1, a2, <=, description, ##__VA_ARGS__)
+
+// Generates a failure when string a1 is not equal to string a2. This call
+// differs from STAssertEqualObjects in that strings that are different in
+// composition (precomposed vs decomposed) will compare equal if their final
+// representation is equal.
+// ex O + umlaut decomposed is the same as O + umlaut composed.
+//  Args:
+//    a1: string 1
+//    a2: string 2
+//    description: A format string as in the printf() function. Can be nil or
+//                 an empty string but must be present.
+//    ...: A variable number of arguments to the format string. Can be absent.
+#define STAssertEqualStrings(a1, a2, description, ...) \
+do { \
+  @try { \
+    id a1value = (a1); \
+    id a2value = (a2); \
+    if (a1value == a2value) continue; \
+    if ([a1value isKindOfClass:[NSString class]] && \
+        [a2value isKindOfClass:[NSString class]] && \
+        [a1value compare:a2value options:0] == NSOrderedSame) continue; \
+     [self failWithException:[NSException failureInEqualityBetweenObject:a1value \
+                                                               andObject:a2value \
+                                                                  inFile:[NSString stringWithUTF8String:__FILE__] \
+                                                                  atLine:__LINE__ \
+                                                         withDescription:@"%@", STComposeString(description, ##__VA_ARGS__)]]; \
+  } \
+  @catch (id anException) { \
+    [self failWithException:[NSException failureInRaise:[NSString stringWithFormat:@"(%s) == (%s)", #a1, #a2] \
+                                              exception:anException \
+                                                 inFile:[NSString stringWithUTF8String:__FILE__] \
+                                                 atLine:__LINE__ \
+                                        withDescription:@"%@", STComposeString(description, ##__VA_ARGS__)]]; \
+  } \
+} while(0)
+
+// Generates a failure when string a1 is equal to string a2. This call
+// differs from STAssertEqualObjects in that strings that are different in
+// composition (precomposed vs decomposed) will compare equal if their final
+// representation is equal.
+// ex O + umlaut decomposed is the same as O + umlaut composed.
+//  Args:
+//    a1: string 1
+//    a2: string 2
+//    description: A format string as in the printf() function. Can be nil or
+//                 an empty string but must be present.
+//    ...: A variable number of arguments to the format string. Can be absent.
+#define STAssertNotEqualStrings(a1, a2, description, ...) \
+do { \
+  @try { \
+    id a1value = (a1); \
+    id a2value = (a2); \
+    if ([a1value isKindOfClass:[NSString class]] && \
+        [a2value isKindOfClass:[NSString class]] && \
+        [a1value compare:a2value options:0] != NSOrderedSame) continue; \
+     [self failWithException:[NSException failureInEqualityBetweenObject:a1value \
+                                                               andObject:a2value \
+                                                                  inFile:[NSString stringWithUTF8String:__FILE__] \
+                                                                  atLine:__LINE__ \
+                                                         withDescription:@"%@", STComposeString(description, ##__VA_ARGS__)]]; \
+  } \
+  @catch (id anException) { \
+    [self failWithException:[NSException failureInRaise:[NSString stringWithFormat:@"(%s) != (%s)", #a1, #a2] \
+                                              exception:anException \
+                                                 inFile:[NSString stringWithUTF8String:__FILE__] \
+                                                 atLine:__LINE__ \
+                                        withDescription:@"%@", STComposeString(description, ##__VA_ARGS__)]]; \
+  } \
+} while(0)
+
+// Generates a failure when c-string a1 is not equal to c-string a2.
+//  Args:
+//    a1: string 1
+//    a2: string 2
+//    description: A format string as in the printf() function. Can be nil or
+//                 an empty string but must be present.
+//    ...: A variable number of arguments to the format string. Can be absent.
+#define STAssertEqualCStrings(a1, a2, description, ...) \
+do { \
+  @try { \
+    const char* a1value = (a1); \
+    const char* a2value = (a2); \
+    if (a1value == a2value) continue; \
+    if (strcmp(a1value, a2value) == 0) continue; \
+    [self failWithException:[NSException failureInEqualityBetweenObject:[NSString stringWithUTF8String:a1value] \
+                                                              andObject:[NSString stringWithUTF8String:a2value] \
+                                                                 inFile:[NSString stringWithUTF8String:__FILE__] \
+                                                                 atLine:__LINE__ \
+                                                        withDescription:@"%@", STComposeString(description, ##__VA_ARGS__)]]; \
+  } \
+  @catch (id anException) { \
+    [self failWithException:[NSException failureInRaise:[NSString stringWithFormat:@"(%s) == (%s)", #a1, #a2] \
+                                              exception:anException \
+                                                 inFile:[NSString stringWithUTF8String:__FILE__] \
+                                                 atLine:__LINE__ \
+                                        withDescription:@"%@", STComposeString(description, ##__VA_ARGS__)]]; \
+  } \
+} while(0)
+
+// Generates a failure when c-string a1 is equal to c-string a2.
+//  Args:
+//    a1: string 1
+//    a2: string 2
+//    description: A format string as in the printf() function. Can be nil or
+//                 an empty string but must be present.
+//    ...: A variable number of arguments to the format string. Can be absent.
+#define STAssertNotEqualCStrings(a1, a2, description, ...) \
+do { \
+  @try { \
+    const char* a1value = (a1); \
+    const char* a2value = (a2); \
+    if (strcmp(a1value, a2value) != 0) continue; \
+    [self failWithException:[NSException failureInEqualityBetweenObject:[NSString stringWithUTF8String:a1value] \
+                                                              andObject:[NSString stringWithUTF8String:a2value] \
+                                                                 inFile:[NSString stringWithUTF8String:__FILE__] \
+                                                                 atLine:__LINE__ \
+                                                        withDescription:@"%@", STComposeString(description, ##__VA_ARGS__)]]; \
+  } \
+  @catch (id anException) { \
+    [self failWithException:[NSException failureInRaise:[NSString stringWithFormat:@"(%s) != (%s)", #a1, #a2] \
+                                              exception:anException \
+                                                 inFile:[NSString stringWithUTF8String:__FILE__] \
+                                                 atLine:__LINE__ \
+                                        withDescription:@"%@", STComposeString(description, ##__VA_ARGS__)]]; \
+  } \
+} while(0)
+
+/*" Generates a failure when a1 is not equal to a2 within + or - accuracy is false.
+  This test is for GLKit types (GLKVector, GLKMatrix) where small differences
+  could  make these items not exactly equal. Do not use this version directly.
+  Use the explicit STAssertEqualGLKVectors and STAssertEqualGLKMatrices defined
+  below.
+  _{a1    The GLKType on the left.}
+  _{a2    The GLKType on the right.}
+  _{accuracy  The maximum difference between a1 and a2 for these values to be
+  considered equal.}
+  _{description A format string as in the printf() function. Can be nil or
+                      an empty string but must be present.}
+  _{... A variable number of arguments to the format string. Can be absent.}
+"*/
+
+#define STInternalAssertEqualGLKVectorsOrMatrices(a1, a2, accuracy, description, ...) \
+do { \
+  @try { \
+    if (strcmp(@encode(__typeof__(a1)), @encode(__typeof__(a2)))) { \
+      [self failWithException:[NSException failureInFile:[NSString stringWithUTF8String:__FILE__] \
+                                                                                 atLine:__LINE__ \
+                                                                        withDescription:@"Type mismatch -- %@", STComposeString(description, ##__VA_ARGS__)]]; \
+    } else { \
+      __typeof__(a1) a1GLKValue = (a1); \
+      __typeof__(a2) a2GLKValue = (a2); \
+      __typeof__(accuracy) accuracyvalue = (accuracy); \
+      float *a1FloatValue = ((float*)&a1GLKValue); \
+      float *a2FloatValue = ((float*)&a2GLKValue); \
+      for (size_t i = 0; i < sizeof(__typeof__(a1)) / sizeof(float); ++i) { \
+        float a1value = a1FloatValue[i]; \
+        float a2value = a2FloatValue[i]; \
+        if (STAbsoluteDifference(a1value, a2value) > accuracyvalue) { \
+          NSMutableArray *strings = [NSMutableArray arrayWithCapacity:sizeof(a1) / sizeof(float)]; \
+          NSString *string; \
+          for (size_t j = 0; j < sizeof(__typeof__(a1)) / sizeof(float); ++j) { \
+            string = [NSString stringWithFormat:@"(%0.3f == %0.3f)", a1FloatValue[j], a2FloatValue[j]]; \
+            [strings addObject:string]; \
+          } \
+          string = [strings componentsJoinedByString:@", "]; \
+          NSString *desc = STComposeString(description, ##__VA_ARGS__); \
+          desc = [NSString stringWithFormat:@"%@ With Accuracy %0.3f: %@", string, (float)accuracyvalue, desc]; \
+          [self failWithException:[NSException failureInFile:[NSString stringWithUTF8String:__FILE__] \
+                                                      atLine:__LINE__ \
+                                             withDescription:@"%@", desc]]; \
+          break; \
+        } \
+      } \
+    } \
+  } \
+  @catch (id anException) { \
+    [self failWithException:[NSException failureInRaise:[NSString stringWithFormat:@"(%s) == (%s)", #a1, #a2] \
+                                              exception:anException \
+                                                 inFile:[NSString stringWithUTF8String:__FILE__] \
+                                                 atLine:__LINE__ \
+                                        withDescription:@"%@", STComposeString(description, ##__VA_ARGS__)]]; \
+  } \
+} while(0)
+
+#define STAssertEqualGLKVectors(a1, a2, accuracy, description, ...) \
+     STInternalAssertEqualGLKVectorsOrMatrices(a1, a2, accuracy, description, ##__VA_ARGS__)
+
+#define STAssertEqualGLKMatrices(a1, a2, accuracy, description, ...) \
+     STInternalAssertEqualGLKVectorsOrMatrices(a1, a2, accuracy, description, ##__VA_ARGS__)
+
+#define STAssertEqualGLKQuaternions(a1, a2, accuracy, description, ...) \
+     STInternalAssertEqualGLKVectorsOrMatrices(a1, a2, accuracy, description, ##__VA_ARGS__)
+
+#if GTM_IPHONE_SDK && !GTM_IPHONE_USE_SENTEST
+// When not using the Xcode provided version, define everything ourselves.
+
+// SENTE_BEGIN
+/*" Generates a failure when !{ [a1 isEqualTo:a2] } is false
+	(or one is nil and the other is not).
+	_{a1    The object on the left.}
+	_{a2    The object on the right.}
+	_{description A format string as in the printf() function. Can be nil or
+		an empty string but must be present.}
+	_{... A variable number of arguments to the format string. Can be absent.}
+"*/
+#define STAssertEqualObjects(a1, a2, description, ...) \
+do { \
+  @try { \
+    id a1value = (a1); \
+    id a2value = (a2); \
+    if (a1value == a2value) continue; \
+    if ((strcmp(@encode(__typeof__(a1value)), @encode(id)) == 0) && \
+        (strcmp(@encode(__typeof__(a2value)), @encode(id)) == 0) && \
+        [(id)a1value isEqual:(id)a2value]) continue; \
+    [self failWithException:[NSException failureInEqualityBetweenObject:a1value \
+                                                              andObject:a2value \
+                                                                 inFile:[NSString stringWithUTF8String:__FILE__] \
+                                                                 atLine:__LINE__ \
+                                                        withDescription:@"%@", STComposeString(description, ##__VA_ARGS__)]]; \
+  } \
+  @catch (id anException) { \
+    [self failWithException:[NSException failureInRaise:[NSString stringWithFormat:@"(%s) == (%s)", #a1, #a2] \
+                                              exception:anException \
+                                                 inFile:[NSString stringWithUTF8String:__FILE__] \
+                                                 atLine:__LINE__ \
+                                        withDescription:@"%@", STComposeString(description, ##__VA_ARGS__)]]; \
+  } \
+} while(0)
+
+
+/*" Generates a failure when a1 is not equal to a2. This test is for
+    C scalars, structs and unions.
+    _{a1    The argument on the left.}
+    _{a2    The argument on the right.}
+    _{description A format string as in the printf() function. Can be nil or
+                        an empty string but must be present.}
+    _{... A variable number of arguments to the format string. Can be absent.}
+"*/
+#define STAssertEquals(a1, a2, description, ...) \
+do { \
+  @try { \
+    if (strcmp(@encode(__typeof__(a1)), @encode(__typeof__(a2)))) { \
+      [self failWithException:[NSException failureInFile:[NSString stringWithUTF8String:__FILE__] \
+                                                                                 atLine:__LINE__ \
+                                                                        withDescription:@"Type mismatch -- %@", STComposeString(description, ##__VA_ARGS__)]]; \
+    } else { \
+      __typeof__(a1) a1value = (a1); \
+      __typeof__(a2) a2value = (a2); \
+      NSValue *a1encoded = [NSValue value:&a1value withObjCType:@encode(__typeof__(a1))]; \
+      NSValue *a2encoded = [NSValue value:&a2value withObjCType:@encode(__typeof__(a2))]; \
+      if (![a1encoded isEqualToValue:a2encoded]) { \
+        [self failWithException:[NSException failureInEqualityBetweenValue:a1encoded \
+                                                                  andValue:a2encoded \
+                                                              withAccuracy:nil \
+                                                                    inFile:[NSString stringWithUTF8String:__FILE__] \
+                                                                    atLine:__LINE__ \
+                                                           withDescription:@"%@", STComposeString(description, ##__VA_ARGS__)]]; \
+      } \
+    } \
+  } \
+  @catch (id anException) { \
+    [self failWithException:[NSException failureInRaise:[NSString stringWithFormat:@"(%s) == (%s)", #a1, #a2] \
+                                              exception:anException \
+                                                 inFile:[NSString stringWithUTF8String:__FILE__] \
+                                                 atLine:__LINE__ \
+                                        withDescription:@"%@", STComposeString(description, ##__VA_ARGS__)]]; \
+  } \
+} while(0)
+
+#define STAbsoluteDifference(left,right) (MAX(left,right)-MIN(left,right))
+
+
+/*" Generates a failure when a1 is not equal to a2 within + or - accuracy is false.
+  This test is for scalars such as floats and doubles where small differences
+  could make these items not exactly equal, but also works for all scalars.
+  _{a1    The scalar on the left.}
+  _{a2    The scalar on the right.}
+  _{accuracy  The maximum difference between a1 and a2 for these values to be
+  considered equal.}
+  _{description A format string as in the printf() function. Can be nil or
+                      an empty string but must be present.}
+  _{... A variable number of arguments to the format string. Can be absent.}
+"*/
+
+#define STAssertEqualsWithAccuracy(a1, a2, accuracy, description, ...) \
+do { \
+  @try { \
+    if (strcmp(@encode(__typeof__(a1)), @encode(__typeof__(a2)))) { \
+      [self failWithException:[NSException failureInFile:[NSString stringWithUTF8String:__FILE__] \
+                                                                                 atLine:__LINE__ \
+                                                                        withDescription:@"Type mismatch -- %@", STComposeString(description, ##__VA_ARGS__)]]; \
+    } else { \
+      __typeof__(a1) a1value = (a1); \
+      __typeof__(a2) a2value = (a2); \
+      __typeof__(accuracy) accuracyvalue = (accuracy); \
+      if (STAbsoluteDifference(a1value, a2value) > accuracyvalue) { \
+              NSValue *a1encoded = [NSValue value:&a1value withObjCType:@encode(__typeof__(a1))]; \
+              NSValue *a2encoded = [NSValue value:&a2value withObjCType:@encode(__typeof__(a2))]; \
+              NSValue *accuracyencoded = [NSValue value:&accuracyvalue withObjCType:@encode(__typeof__(accuracy))]; \
+              [self failWithException:[NSException failureInEqualityBetweenValue:a1encoded \
+                                                                        andValue:a2encoded \
+                                                                    withAccuracy:accuracyencoded \
+                                                                          inFile:[NSString stringWithUTF8String:__FILE__] \
+                                                                          atLine:__LINE__ \
+                                                                 withDescription:@"%@", STComposeString(description, ##__VA_ARGS__)]]; \
+      } \
+    } \
+  } \
+  @catch (id anException) { \
+    [self failWithException:[NSException failureInRaise:[NSString stringWithFormat:@"(%s) == (%s)", #a1, #a2] \
+                                                                         exception:anException \
+                                                                            inFile:[NSString stringWithUTF8String:__FILE__] \
+                                                                            atLine:__LINE__ \
+                                                                   withDescription:@"%@", STComposeString(description, ##__VA_ARGS__)]]; \
+  } \
+} while(0)
+
+
+
+/*" Generates a failure unconditionally.
+  _{description A format string as in the printf() function. Can be nil or
+                      an empty string but must be present.}
+  _{... A variable number of arguments to the format string. Can be absent.}
+"*/
+#define STFail(description, ...) \
+[self failWithException:[NSException failureInFile:[NSString stringWithUTF8String:__FILE__] \
+                                            atLine:__LINE__ \
+                                   withDescription:@"%@", STComposeString(description, ##__VA_ARGS__)]]
+
+
+
+/*" Generates a failure when a1 is not nil.
+  _{a1    An object.}
+  _{description A format string as in the printf() function. Can be nil or
+    an empty string but must be present.}
+  _{... A variable number of arguments to the format string. Can be absent.}
+"*/
+#define STAssertNil(a1, description, ...) \
+do { \
+  @try { \
+    id a1value = (a1); \
+    if (a1value != nil) { \
+      NSString *_a1 = [NSString stringWithUTF8String:#a1]; \
+      NSString *_expression = [NSString stringWithFormat:@"((%@) == nil)", _a1]; \
+      [self failWithException:[NSException failureInCondition:_expression \
+                                                       isTrue:NO \
+                                                       inFile:[NSString stringWithUTF8String:__FILE__] \
+                                                       atLine:__LINE__ \
+                                              withDescription:@"%@", STComposeString(description, ##__VA_ARGS__)]]; \
+    } \
+  } \
+  @catch (id anException) { \
+    [self failWithException:[NSException failureInRaise:[NSString stringWithFormat:@"(%s) == nil fails", #a1] \
+                                              exception:anException \
+                                                 inFile:[NSString stringWithUTF8String:__FILE__] \
+                                                 atLine:__LINE__ \
+                                        withDescription:@"%@", STComposeString(description, ##__VA_ARGS__)]]; \
+  } \
+} while(0)
+
+
+/*" Generates a failure when a1 is nil.
+  _{a1    An object.}
+  _{description A format string as in the printf() function. Can be nil or
+  an empty string but must be present.}
+  _{... A variable number of arguments to the format string. Can be absent.}
+"*/
+#define STAssertNotNil(a1, description, ...) \
+do { \
+  @try { \
+    id a1value = (a1); \
+    if (a1value == nil) { \
+      NSString *_a1 = [NSString stringWithUTF8String:#a1]; \
+      NSString *_expression = [NSString stringWithFormat:@"((%@) != nil)", _a1]; \
+      [self failWithException:[NSException failureInCondition:_expression \
+                                                       isTrue:NO \
+                                                       inFile:[NSString stringWithUTF8String:__FILE__] \
+                                                       atLine:__LINE__ \
+                                              withDescription:@"%@", STComposeString(description, ##__VA_ARGS__)]]; \
+    } \
+  } \
+  @catch (id anException) { \
+    [self failWithException:[NSException failureInRaise:[NSString stringWithFormat:@"(%s) != nil fails", #a1] \
+                                              exception:anException \
+                                                 inFile:[NSString stringWithUTF8String:__FILE__] \
+                                                 atLine:__LINE__ \
+                                        withDescription:@"%@", STComposeString(description, ##__VA_ARGS__)]]; \
+  } \
+} while(0)
+
+
+/*" Generates a failure when expression evaluates to false.
+  _{expr    The expression that is tested.}
+  _{description A format string as in the printf() function. Can be nil or
+  an empty string but must be present.}
+  _{... A variable number of arguments to the format string. Can be absent.}
+"*/
+#define STAssertTrue(expr, description, ...) \
+do { \
+  BOOL _evaluatedExpression = (expr); \
+  if (!_evaluatedExpression) { \
+    NSString *_expression = [NSString stringWithUTF8String:#expr]; \
+    [self failWithException:[NSException failureInCondition:_expression \
+                                                     isTrue:NO \
+                                                     inFile:[NSString stringWithUTF8String:__FILE__] \
+                                                     atLine:__LINE__ \
+                                            withDescription:@"%@", STComposeString(description, ##__VA_ARGS__)]]; \
+  } \
+} while (0)
+
+
+/*" Generates a failure when expression evaluates to false and in addition will
+  generate error messages if an exception is encountered.
+  _{expr    The expression that is tested.}
+  _{description A format string as in the printf() function. Can be nil or
+  an empty string but must be present.}
+  _{... A variable number of arguments to the format string. Can be absent.}
+"*/
+#define STAssertTrueNoThrow(expr, description, ...) \
+do { \
+  @try { \
+    BOOL _evaluatedExpression = (expr); \
+    if (!_evaluatedExpression) { \
+      NSString *_expression = [NSString stringWithUTF8String:#expr]; \
+      [self failWithException:[NSException failureInCondition:_expression \
+                                                       isTrue:NO \
+                                                       inFile:[NSString stringWithUTF8String:__FILE__] \
+                                                       atLine:__LINE__ \
+                                              withDescription:@"%@", STComposeString(description, ##__VA_ARGS__)]]; \
+    } \
+  } \
+  @catch (id anException) { \
+    [self failWithException:[NSException failureInRaise:[NSString stringWithFormat:@"(%s) ", #expr] \
+                                              exception:anException \
+                                                 inFile:[NSString stringWithUTF8String:__FILE__] \
+                                                 atLine:__LINE__ \
+                                        withDescription:@"%@", STComposeString(description, ##__VA_ARGS__)]]; \
+  } \
+} while (0)
+
+
+/*" Generates a failure when the expression evaluates to true.
+  _{expr    The expression that is tested.}
+  _{description A format string as in the printf() function. Can be nil or
+  an empty string but must be present.}
+  _{... A variable number of arguments to the format string. Can be absent.}
+"*/
+#define STAssertFalse(expr, description, ...) \
+do { \
+  BOOL _evaluatedExpression = (expr); \
+  if (_evaluatedExpression) { \
+    NSString *_expression = [NSString stringWithUTF8String:#expr]; \
+    [self failWithException:[NSException failureInCondition:_expression \
+                                                     isTrue:YES \
+                                                     inFile:[NSString stringWithUTF8String:__FILE__] \
+                                                     atLine:__LINE__ \
+                                            withDescription:@"%@", STComposeString(description, ##__VA_ARGS__)]]; \
+  } \
+} while (0)
+
+
+/*" Generates a failure when the expression evaluates to true and in addition
+  will generate error messages if an exception is encountered.
+  _{expr    The expression that is tested.}
+  _{description A format string as in the printf() function. Can be nil or
+  an empty string but must be present.}
+  _{... A variable number of arguments to the format string. Can be absent.}
+"*/
+#define STAssertFalseNoThrow(expr, description, ...) \
+do { \
+  @try { \
+    BOOL _evaluatedExpression = (expr); \
+    if (_evaluatedExpression) { \
+      NSString *_expression = [NSString stringWithUTF8String:#expr]; \
+      [self failWithException:[NSException failureInCondition:_expression \
+                                                       isTrue:YES \
+                                                       inFile:[NSString stringWithUTF8String:__FILE__] \
+                                                       atLine:__LINE__ \
+                                              withDescription:@"%@", STComposeString(description, ##__VA_ARGS__)]]; \
+    } \
+  } \
+  @catch (id anException) { \
+    [self failWithException:[NSException failureInRaise:[NSString stringWithFormat:@"!(%s) ", #expr] \
+                                              exception:anException \
+                                                 inFile:[NSString stringWithUTF8String:__FILE__] \
+                                                 atLine:__LINE__ \
+                                        withDescription:@"%@", STComposeString(description, ##__VA_ARGS__)]]; \
+  } \
+} while (0)
+
+
+/*" Generates a failure when expression does not throw an exception.
+  _{expression    The expression that is evaluated.}
+  _{description A format string as in the printf() function. Can be nil or
+  an empty string but must be present.}
+  _{... A variable number of arguments to the format string. Can be absent.
+"*/
+#define STAssertThrows(expr, description, ...) \
+do { \
+  @try { \
+    (expr); \
+  } \
+  @catch (id anException) { \
+    continue; \
+  } \
+  [self failWithException:[NSException failureInRaise:[NSString stringWithUTF8String:#expr] \
+                                            exception:nil \
+                                               inFile:[NSString stringWithUTF8String:__FILE__] \
+                                               atLine:__LINE__ \
+                                      withDescription:@"%@", STComposeString(description, ##__VA_ARGS__)]]; \
+} while (0)
+
+
+/*" Generates a failure when expression does not throw an exception of a
+  specific class.
+  _{expression    The expression that is evaluated.}
+  _{specificException    The specified class of the exception.}
+  _{description A format string as in the printf() function. Can be nil or
+  an empty string but must be present.}
+  _{... A variable number of arguments to the format string. Can be absent.}
+"*/
+#define STAssertThrowsSpecific(expr, specificException, description, ...) \
+do { \
+  @try { \
+    (expr); \
+  } \
+  @catch (specificException *anException) { \
+    continue; \
+  } \
+  @catch (id anException) { \
+    NSString *_descrip = STComposeString(@"(Expected exception: %@) %@", NSStringFromClass([specificException class]), description); \
+    [self failWithException:[NSException failureInRaise:[NSString stringWithUTF8String:#expr] \
+                                              exception:anException \
+                                                 inFile:[NSString stringWithUTF8String:__FILE__] \
+                                                 atLine:__LINE__ \
+                                        withDescription:@"%@", STComposeString(_descrip, ##__VA_ARGS__)]]; \
+                                            continue; \
+  } \
+  NSString *_descrip = STComposeString(@"(Expected exception: %@) %@", NSStringFromClass([specificException class]), description); \
+  [self failWithException:[NSException failureInRaise:[NSString stringWithUTF8String:#expr] \
+                                            exception:nil \
+                                               inFile:[NSString stringWithUTF8String:__FILE__] \
+                                               atLine:__LINE__ \
+                                      withDescription:@"%@", STComposeString(_descrip, ##__VA_ARGS__)]]; \
+} while (0)
+
+
+/*" Generates a failure when expression does not throw an exception of a
+  specific class with a specific name.  Useful for those frameworks like
+  AppKit or Foundation that throw generic NSException w/specific names
+  (NSInvalidArgumentException, etc).
+  _{expression    The expression that is evaluated.}
+  _{specificException    The specified class of the exception.}
+  _{aName    The name of the specified exception.}
+  _{description A format string as in the printf() function. Can be nil or
+  an empty string but must be present.}
+  _{... A variable number of arguments to the format string. Can be absent.}
+
+"*/
+#define STAssertThrowsSpecificNamed(expr, specificException, aName, description, ...) \
+do { \
+  @try { \
+    (expr); \
+  } \
+  @catch (specificException *anException) { \
+    if ([aName isEqualToString:[anException name]]) continue; \
+    NSString *_descrip = STComposeString(@"(Expected exception: %@ (name: %@)) %@", NSStringFromClass([specificException class]), aName, description); \
+    [self failWithException: \
+      [NSException failureInRaise:[NSString stringWithUTF8String:#expr] \
+                        exception:anException \
+                           inFile:[NSString stringWithUTF8String:__FILE__] \
+                           atLine:__LINE__ \
+                  withDescription:@"%@", STComposeString(_descrip, ##__VA_ARGS__)]]; \
+    continue; \
+  } \
+  @catch (id anException) { \
+    NSString *_descrip = STComposeString(@"(Expected exception: %@) %@", NSStringFromClass([specificException class]), description); \
+    [self failWithException: \
+      [NSException failureInRaise:[NSString stringWithUTF8String:#expr] \
+                        exception:anException \
+                           inFile:[NSString stringWithUTF8String:__FILE__] \
+                           atLine:__LINE__ \
+                  withDescription:@"%@", STComposeString(_descrip, ##__VA_ARGS__)]]; \
+    continue; \
+  } \
+  NSString *_descrip = STComposeString(@"(Expected exception: %@) %@", NSStringFromClass([specificException class]), description); \
+  [self failWithException: \
+    [NSException failureInRaise:[NSString stringWithUTF8String:#expr] \
+                      exception:nil \
+                         inFile:[NSString stringWithUTF8String:__FILE__] \
+                         atLine:__LINE__ \
+                withDescription:@"%@", STComposeString(_descrip, ##__VA_ARGS__)]]; \
+} while (0)
+
+
+/*" Generates a failure when expression does throw an exception.
+  _{expression    The expression that is evaluated.}
+  _{description A format string as in the printf() function. Can be nil or
+  an empty string but must be present.}
+  _{... A variable number of arguments to the format string. Can be absent.}
+"*/
+#define STAssertNoThrow(expr, description, ...) \
+do { \
+  @try { \
+    (expr); \
+  } \
+  @catch (id anException) { \
+    [self failWithException:[NSException failureInRaise:[NSString stringWithUTF8String:#expr] \
+                                              exception:anException \
+                                                 inFile:[NSString stringWithUTF8String:__FILE__] \
+                                                 atLine:__LINE__ \
+                                        withDescription:@"%@", STComposeString(description, ##__VA_ARGS__)]]; \
+  } \
+} while (0)
+
+
+/*" Generates a failure when expression does throw an exception of the specitied
+  class. Any other exception is okay (i.e. does not generate a failure).
+  _{expression    The expression that is evaluated.}
+  _{specificException    The specified class of the exception.}
+  _{description A format string as in the printf() function. Can be nil or
+  an empty string but must be present.}
+  _{... A variable number of arguments to the format string. Can be absent.}
+"*/
+#define STAssertNoThrowSpecific(expr, specificException, description, ...) \
+do { \
+  @try { \
+    (expr); \
+  } \
+  @catch (specificException *anException) { \
+    [self failWithException:[NSException failureInRaise:[NSString stringWithUTF8String:#expr] \
+                                              exception:anException \
+                                                 inFile:[NSString stringWithUTF8String:__FILE__] \
+                                                 atLine:__LINE__ \
+                                        withDescription:@"%@", STComposeString(description, ##__VA_ARGS__)]]; \
+  } \
+  @catch (id anythingElse) { \
+    ; \
+  } \
+} while (0)
+
+
+/*" Generates a failure when expression does throw an exception of a
+  specific class with a specific name.  Useful for those frameworks like
+  AppKit or Foundation that throw generic NSException w/specific names
+  (NSInvalidArgumentException, etc).
+  _{expression    The expression that is evaluated.}
+  _{specificException    The specified class of the exception.}
+  _{aName    The name of the specified exception.}
+  _{description A format string as in the printf() function. Can be nil or
+  an empty string but must be present.}
+  _{... A variable number of arguments to the format string. Can be absent.}
+
+"*/
+#define STAssertNoThrowSpecificNamed(expr, specificException, aName, description, ...) \
+do { \
+  @try { \
+    (expr); \
+  } \
+  @catch (specificException *anException) { \
+    if ([aName isEqualToString:[anException name]]) { \
+      NSString *_descrip = STComposeString(@"(Expected exception: %@ (name: %@)) %@", NSStringFromClass([specificException class]), aName, description); \
+      [self failWithException: \
+        [NSException failureInRaise:[NSString stringWithUTF8String:#expr] \
+                          exception:anException \
+                             inFile:[NSString stringWithUTF8String:__FILE__] \
+                             atLine:__LINE__ \
+                    withDescription:@"%@", STComposeString(_descrip, ##__VA_ARGS__)]]; \
+    } \
+    continue; \
+  } \
+  @catch (id anythingElse) { \
+    ; \
+  } \
+} while (0)
+
+
+
+@interface NSException (GTMSenTestAdditions)
++ (NSException *)failureInFile:(NSString *)filename
+                        atLine:(int)lineNumber
+               withDescription:(NSString *)formatString, ... NS_FORMAT_FUNCTION(3, 4);
++ (NSException *)failureInCondition:(NSString *)condition
+                             isTrue:(BOOL)isTrue
+                             inFile:(NSString *)filename
+                             atLine:(int)lineNumber
+                    withDescription:(NSString *)formatString, ... NS_FORMAT_FUNCTION(5, 6);
++ (NSException *)failureInEqualityBetweenObject:(id)left
+                                      andObject:(id)right
+                                         inFile:(NSString *)filename
+                                         atLine:(int)lineNumber
+                                withDescription:(NSString *)formatString, ... NS_FORMAT_FUNCTION(5, 6);
++ (NSException *)failureInEqualityBetweenValue:(NSValue *)left
+                                      andValue:(NSValue *)right
+                                  withAccuracy:(NSValue *)accuracy
+                                        inFile:(NSString *)filename
+                                        atLine:(int) ineNumber
+                               withDescription:(NSString *)formatString, ... NS_FORMAT_FUNCTION(6, 7);
++ (NSException *)failureInRaise:(NSString *)expression
+                         inFile:(NSString *)filename
+                         atLine:(int)lineNumber
+                withDescription:(NSString *)formatString, ... NS_FORMAT_FUNCTION(4, 5);
++ (NSException *)failureInRaise:(NSString *)expression
+                      exception:(NSException *)exception
+                         inFile:(NSString *)filename
+                         atLine:(int)lineNumber
+                withDescription:(NSString *)formatString, ... NS_FORMAT_FUNCTION(5, 6);
+@end
+
+// SENTE_END
+
+@protocol SenTestCase
++ (id)testCaseWithInvocation:(NSInvocation *)anInvocation;
+- (id)initWithInvocation:(NSInvocation *)anInvocation;
+- (void)setUp;
+- (void)invokeTest;
+- (void)tearDown;
+- (void)performTest;
+- (void)failWithException:(NSException*)exception;
+- (NSInvocation *)invocation;
+- (SEL)selector;
++ (NSArray *)testInvocations;
+@end
+
+@interface SenTestCase : NSObject<SenTestCase> {
+ @private
+  NSInvocation *invocation_;
+}
+@end
+
+GTM_EXTERN NSString *const SenTestFailureException;
+
+GTM_EXTERN NSString *const SenTestFilenameKey;
+GTM_EXTERN NSString *const SenTestLineNumberKey;
+
+#endif // GTM_IPHONE_SDK && !GTM_IPHONE_USE_SENTEST
+
+// All unittest cases in GTM should inherit from GTMTestCase. It makes sure
+// to set up our logging system correctly to verify logging calls.
+// See GTMUnitTestDevLog.h for details
+@interface GTMTestCase : SenTestCase
+
+// Returns YES if this is an abstract testCase class as opposed to a concrete
+// testCase class that you want tests run against. SenTestCase is not designed
+// out of the box to handle an abstract class hierarchy descending from it with
+// some concrete subclasses.  In some cases we want all the "concrete"
+// subclasses of an abstract subclass of SenTestCase to run a test, but we don't
+// want that test to be run against an instance of an abstract subclass itself.
+// By returning "YES" here, the tests defined by this class won't be run against
+// an instance of this class. As an example class hierarchy:
+//
+//                                            FooExtensionTestCase
+// GTMTestCase <- ExtensionAbstractTestCase <
+//                                            BarExtensionTestCase
+//
+// So FooExtensionTestCase and BarExtensionTestCase inherit from
+// ExtensionAbstractTestCase (and probably FooExtension and BarExtension inherit
+// from a class named Extension). We want the tests in ExtensionAbstractTestCase
+// to be run as part of FooExtensionTestCase and BarExtensionTestCase, but we
+// don't want them run against ExtensionAbstractTestCase. The default
+// implementation checks to see if the name of the class contains the word
+// "AbstractTest" (case sensitive).
++ (BOOL)isAbstractTestCase;
+
+@end
diff --git a/include/breakpad/common/solaris/dump_symbols.h b/include/breakpad/common/solaris/dump_symbols.h
new file mode 100644
index 0000000..7f4baad
--- /dev/null
+++ b/include/breakpad/common/solaris/dump_symbols.h
@@ -0,0 +1,49 @@
+// Copyright (c) 2007, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// dump_symbols.cc: Implements a Solaris stab debugging format dumper.
+//
+// Author: Alfred Peng
+
+#ifndef COMMON_SOLARIS_DUMP_SYMBOLS_H__
+#define COMMON_SOLARIS_DUMP_SYMBOLS_H__
+
+#include <string>
+
+namespace google_breakpad {
+
+class DumpSymbols {
+ public:
+  bool WriteSymbolFile(const std::string &obj_file,
+                       int sym_fd);
+};
+
+}  // namespace google_breakpad
+
+#endif  // COMMON_SOLARIS_DUMP_SYMBOLS_H__
diff --git a/include/breakpad/common/solaris/file_id.h b/include/breakpad/common/solaris/file_id.h
new file mode 100644
index 0000000..375e857
--- /dev/null
+++ b/include/breakpad/common/solaris/file_id.h
@@ -0,0 +1,66 @@
+// 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.
+
+// file_id.h: Return a unique identifier for a file
+//
+// Author: Alfred Peng
+
+#ifndef COMMON_SOLARIS_FILE_ID_H__
+#define COMMON_SOLARIS_FILE_ID_H__
+
+#include <limits.h>
+
+namespace google_breakpad {
+
+class FileID {
+ public:
+  FileID(const char *path);
+  ~FileID() {};
+
+  // Load the identifier for the elf 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 ElfFileIdentifier(unsigned char identifier[16]);
+
+  // Convert the |identifier| data to a NULL terminated string.  The string will
+  // be formatted as a MDCVInfoPDB70 struct.
+  // The |buffer| should be at least 34 bytes long to receive all of the data
+  // and termination. Shorter buffers will return false.
+  static bool 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_SOLARIS_FILE_ID_H__
diff --git a/include/breakpad/common/solaris/guid_creator.h b/include/breakpad/common/solaris/guid_creator.h
new file mode 100644
index 0000000..4aee3a1
--- /dev/null
+++ b/include/breakpad/common/solaris/guid_creator.h
@@ -0,0 +1,50 @@
+// Copyright (c) 2007, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: Alfred Peng
+
+#ifndef COMMON_SOLARIS_GUID_CREATOR_H__
+#define COMMON_SOLARIS_GUID_CREATOR_H__
+
+#include "google_breakpad/common/minidump_format.h"
+
+typedef MDGUID GUID;
+
+// Format string for parsing GUID.
+#define kGUIDFormatString "%08x-%04x-%04x-%08x-%08x"
+// Length of GUID string. Don't count the ending '\0'.
+#define kGUIDStringLength 36
+
+// Create a guid.
+bool CreateGUID(GUID *guid);
+
+// Get the string from guid.
+bool GUIDToString(const GUID *guid, char *buf, int buf_len);
+
+#endif  // COMMON_SOLARIS_GUID_CREATOR_H__
diff --git a/include/breakpad/common/solaris/message_output.h b/include/breakpad/common/solaris/message_output.h
new file mode 100644
index 0000000..3e3b1d4
--- /dev/null
+++ b/include/breakpad/common/solaris/message_output.h
@@ -0,0 +1,54 @@
+// Copyright (c) 2007, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: Alfred Peng
+
+#ifndef COMMON_SOLARIS_MESSAGE_OUTPUT_H__
+#define COMMON_SOLARIS_MESSAGE_OUTPUT_H__
+
+namespace google_breakpad {
+
+const int MESSAGE_MAX = 1000;
+
+// Message output macros.
+// snprintf doesn't operate heap on Solaris, while printf and fprintf do.
+// Use snprintf here to avoid heap allocation.
+#define print_message1(std, message) \
+  char buffer[MESSAGE_MAX]; \
+  int len = snprintf(buffer, MESSAGE_MAX, message); \
+  write(std, buffer, len)
+
+#define print_message2(std, message, para) \
+  char buffer[MESSAGE_MAX]; \
+  int len = snprintf(buffer, MESSAGE_MAX, message, para); \
+  write(std, buffer, len);
+
+}  // namespace google_breakpad
+
+#endif  // COMMON_SOLARIS_MESSAGE_OUTPUT_H__
diff --git a/include/breakpad/common/testdata/func-line-pairing.h b/include/breakpad/common/testdata/func-line-pairing.h
new file mode 100644
index 0000000..05538f9
--- /dev/null
+++ b/include/breakpad/common/testdata/func-line-pairing.h
@@ -0,0 +1,676 @@
+// -*- mode: c++ -*-
+
+// Test data for pairing functions and lines.
+// 
+// For a pair of functions that are adjacent (10,20),(20,25) and a
+// pair that are not (10,15),(20,25), we include a test case for every
+// possible arrangement of two lines relative to those functions. We
+// include cases only for non-empty ranges, since empty functions and
+// lines are dropped before we do any pairing.
+//
+// Each test case is represented by a macro call of the form:
+// 
+//   PAIRING(func1_start, func1_end, func2_start, func2_end,
+//           line1_start, line1_end, line2_start, line2_end,
+//           func1_num_lines, func2_num_lines,
+//           func1_line1_start, func1_line1_end,
+//           func1_line2_start, func1_line2_end,
+//           func2_line1_start, func2_line1_end,
+//           func2_line2_start, func2_line2_end,
+//           uncovered_funcs, uncovered_lines)
+//
+// where:
+// - funcN_{start,end} is the range of the N'th function
+// - lineN_{start,end} is the range of the N'th function
+// - funcN_num_lines is the number of source lines that should be
+//   paired with the N'th function
+// - funcN_lineM_{start,end} is the range of the M'th line
+//   paired with the N'th function, where 0,0 indicates that
+//   there should be no such line paired
+// - uncovered_funcs is the number of functions with area that is
+//   uncovered by any line, and
+// - uncovered_lines is the reverse.
+
+//      func1   func2    line1   line2    num    pairing1        pairing2       uncovered
+PAIRING(10, 20, 20, 25,  6,  7,  7,  8,   0, 0,  0,  0,  0,  0,  0,  0,  0,  0,   2, 2) // #0
+PAIRING(10, 20, 20, 25,  6,  7,  7, 10,   0, 0,  0,  0,  0,  0,  0,  0,  0,  0,   2, 2) // #1
+PAIRING(10, 20, 20, 25,  6,  7,  7, 11,   1, 0, 10, 11,  0,  0,  0,  0,  0,  0,   2, 2) // #2
+PAIRING(10, 20, 20, 25,  6,  7,  7, 20,   1, 0, 10, 20,  0,  0,  0,  0,  0,  0,   1, 2) // #3
+PAIRING(10, 20, 20, 25,  6,  7,  7, 21,   1, 1, 10, 20,  0,  0, 20, 21,  0,  0,   1, 2) // #4
+PAIRING(10, 20, 20, 25,  6,  7,  7, 25,   1, 1, 10, 20,  0,  0, 20, 25,  0,  0,   0, 2) // #5
+PAIRING(10, 20, 20, 25,  6,  7,  7, 26,   1, 1, 10, 20,  0,  0, 20, 25,  0,  0,   0, 2) // #6
+PAIRING(10, 20, 20, 25,  6,  7,  8,  9,   0, 0,  0,  0,  0,  0,  0,  0,  0,  0,   2, 2) // #7
+PAIRING(10, 20, 20, 25,  6,  7,  8, 10,   0, 0,  0,  0,  0,  0,  0,  0,  0,  0,   2, 2) // #8
+PAIRING(10, 20, 20, 25,  6,  7,  8, 11,   1, 0, 10, 11,  0,  0,  0,  0,  0,  0,   2, 2) // #9
+PAIRING(10, 20, 20, 25,  6,  7,  8, 20,   1, 0, 10, 20,  0,  0,  0,  0,  0,  0,   1, 2) // #10
+PAIRING(10, 20, 20, 25,  6,  7,  8, 21,   1, 1, 10, 20,  0,  0, 20, 21,  0,  0,   1, 2) // #11
+PAIRING(10, 20, 20, 25,  6,  7,  8, 25,   1, 1, 10, 20,  0,  0, 20, 25,  0,  0,   0, 2) // #12
+PAIRING(10, 20, 20, 25,  6,  7,  8, 26,   1, 1, 10, 20,  0,  0, 20, 25,  0,  0,   0, 2) // #13
+PAIRING(10, 20, 20, 25,  6,  7, 10, 11,   1, 0, 10, 11,  0,  0,  0,  0,  0,  0,   2, 1) // #14
+PAIRING(10, 20, 20, 25,  6,  7, 10, 20,   1, 0, 10, 20,  0,  0,  0,  0,  0,  0,   1, 1) // #15
+PAIRING(10, 20, 20, 25,  6,  7, 10, 21,   1, 1, 10, 20,  0,  0, 20, 21,  0,  0,   1, 1) // #16
+PAIRING(10, 20, 20, 25,  6,  7, 10, 25,   1, 1, 10, 20,  0,  0, 20, 25,  0,  0,   0, 1) // #17
+PAIRING(10, 20, 20, 25,  6,  7, 10, 26,   1, 1, 10, 20,  0,  0, 20, 25,  0,  0,   0, 2) // #18
+PAIRING(10, 20, 20, 25,  6,  7, 11, 12,   1, 0, 11, 12,  0,  0,  0,  0,  0,  0,   2, 1) // #19
+PAIRING(10, 20, 20, 25,  6,  7, 11, 20,   1, 0, 11, 20,  0,  0,  0,  0,  0,  0,   2, 1) // #20
+PAIRING(10, 20, 20, 25,  6,  7, 11, 21,   1, 1, 11, 20,  0,  0, 20, 21,  0,  0,   2, 1) // #21
+PAIRING(10, 20, 20, 25,  6,  7, 11, 25,   1, 1, 11, 20,  0,  0, 20, 25,  0,  0,   1, 1) // #22
+PAIRING(10, 20, 20, 25,  6,  7, 11, 26,   1, 1, 11, 20,  0,  0, 20, 25,  0,  0,   1, 2) // #23
+PAIRING(10, 20, 20, 25,  6,  7, 20, 21,   0, 1,  0,  0,  0,  0, 20, 21,  0,  0,   2, 1) // #24
+PAIRING(10, 20, 20, 25,  6,  7, 20, 25,   0, 1,  0,  0,  0,  0, 20, 25,  0,  0,   1, 1) // #25
+PAIRING(10, 20, 20, 25,  6,  7, 20, 26,   0, 1,  0,  0,  0,  0, 20, 25,  0,  0,   1, 2) // #26
+PAIRING(10, 20, 20, 25,  6,  7, 21, 22,   0, 1,  0,  0,  0,  0, 21, 22,  0,  0,   2, 1) // #27
+PAIRING(10, 20, 20, 25,  6,  7, 21, 25,   0, 1,  0,  0,  0,  0, 21, 25,  0,  0,   2, 1) // #28
+PAIRING(10, 20, 20, 25,  6,  7, 21, 26,   0, 1,  0,  0,  0,  0, 21, 25,  0,  0,   2, 2) // #29
+PAIRING(10, 20, 20, 25,  6,  7, 25, 26,   0, 0,  0,  0,  0,  0,  0,  0,  0,  0,   2, 2) // #30
+PAIRING(10, 20, 20, 25,  6,  7, 26, 27,   0, 0,  0,  0,  0,  0,  0,  0,  0,  0,   2, 2) // #31
+PAIRING(10, 20, 20, 25,  6, 10, 10, 11,   1, 0, 10, 11,  0,  0,  0,  0,  0,  0,   2, 1) // #32
+PAIRING(10, 20, 20, 25,  6, 10, 10, 20,   1, 0, 10, 20,  0,  0,  0,  0,  0,  0,   1, 1) // #33
+PAIRING(10, 20, 20, 25,  6, 10, 10, 21,   1, 1, 10, 20,  0,  0, 20, 21,  0,  0,   1, 1) // #34
+PAIRING(10, 20, 20, 25,  6, 10, 10, 25,   1, 1, 10, 20,  0,  0, 20, 25,  0,  0,   0, 1) // #35
+PAIRING(10, 20, 20, 25,  6, 10, 10, 26,   1, 1, 10, 20,  0,  0, 20, 25,  0,  0,   0, 2) // #36
+PAIRING(10, 20, 20, 25,  6, 10, 11, 12,   1, 0, 11, 12,  0,  0,  0,  0,  0,  0,   2, 1) // #37
+PAIRING(10, 20, 20, 25,  6, 10, 11, 20,   1, 0, 11, 20,  0,  0,  0,  0,  0,  0,   2, 1) // #38
+PAIRING(10, 20, 20, 25,  6, 10, 11, 21,   1, 1, 11, 20,  0,  0, 20, 21,  0,  0,   2, 1) // #39
+PAIRING(10, 20, 20, 25,  6, 10, 11, 25,   1, 1, 11, 20,  0,  0, 20, 25,  0,  0,   1, 1) // #40
+PAIRING(10, 20, 20, 25,  6, 10, 11, 26,   1, 1, 11, 20,  0,  0, 20, 25,  0,  0,   1, 2) // #41
+PAIRING(10, 20, 20, 25,  6, 10, 20, 21,   0, 1,  0,  0,  0,  0, 20, 21,  0,  0,   2, 1) // #42
+PAIRING(10, 20, 20, 25,  6, 10, 20, 25,   0, 1,  0,  0,  0,  0, 20, 25,  0,  0,   1, 1) // #43
+PAIRING(10, 20, 20, 25,  6, 10, 20, 26,   0, 1,  0,  0,  0,  0, 20, 25,  0,  0,   1, 2) // #44
+PAIRING(10, 20, 20, 25,  6, 10, 21, 22,   0, 1,  0,  0,  0,  0, 21, 22,  0,  0,   2, 1) // #45
+PAIRING(10, 20, 20, 25,  6, 10, 21, 25,   0, 1,  0,  0,  0,  0, 21, 25,  0,  0,   2, 1) // #46
+PAIRING(10, 20, 20, 25,  6, 10, 21, 26,   0, 1,  0,  0,  0,  0, 21, 25,  0,  0,   2, 2) // #47
+PAIRING(10, 20, 20, 25,  6, 10, 25, 26,   0, 0,  0,  0,  0,  0,  0,  0,  0,  0,   2, 2) // #48
+PAIRING(10, 20, 20, 25,  6, 10, 26, 27,   0, 0,  0,  0,  0,  0,  0,  0,  0,  0,   2, 2) // #49
+PAIRING(10, 20, 20, 25,  6, 11, 11, 12,   2, 0, 10, 11, 11, 12,  0,  0,  0,  0,   2, 1) // #50
+PAIRING(10, 20, 20, 25,  6, 11, 11, 20,   2, 0, 10, 11, 11, 20,  0,  0,  0,  0,   1, 1) // #51
+PAIRING(10, 20, 20, 25,  6, 11, 11, 21,   2, 1, 10, 11, 11, 20, 20, 21,  0,  0,   1, 1) // #52
+PAIRING(10, 20, 20, 25,  6, 11, 11, 25,   2, 1, 10, 11, 11, 20, 20, 25,  0,  0,   0, 1) // #53
+PAIRING(10, 20, 20, 25,  6, 11, 11, 26,   2, 1, 10, 11, 11, 20, 20, 25,  0,  0,   0, 2) // #54
+PAIRING(10, 20, 20, 25,  6, 11, 12, 13,   2, 0, 10, 11, 12, 13,  0,  0,  0,  0,   2, 1) // #55
+PAIRING(10, 20, 20, 25,  6, 11, 12, 20,   2, 0, 10, 11, 12, 20,  0,  0,  0,  0,   2, 1) // #56
+PAIRING(10, 20, 20, 25,  6, 11, 12, 21,   2, 1, 10, 11, 12, 20, 20, 21,  0,  0,   2, 1) // #57
+PAIRING(10, 20, 20, 25,  6, 11, 12, 25,   2, 1, 10, 11, 12, 20, 20, 25,  0,  0,   1, 1) // #58
+PAIRING(10, 20, 20, 25,  6, 11, 12, 26,   2, 1, 10, 11, 12, 20, 20, 25,  0,  0,   1, 2) // #59
+PAIRING(10, 20, 20, 25,  6, 11, 20, 21,   1, 1, 10, 11,  0,  0, 20, 21,  0,  0,   2, 1) // #60
+PAIRING(10, 20, 20, 25,  6, 11, 20, 25,   1, 1, 10, 11,  0,  0, 20, 25,  0,  0,   1, 1) // #61
+PAIRING(10, 20, 20, 25,  6, 11, 20, 26,   1, 1, 10, 11,  0,  0, 20, 25,  0,  0,   1, 2) // #62
+PAIRING(10, 20, 20, 25,  6, 11, 21, 22,   1, 1, 10, 11,  0,  0, 21, 22,  0,  0,   2, 1) // #63
+PAIRING(10, 20, 20, 25,  6, 11, 21, 25,   1, 1, 10, 11,  0,  0, 21, 25,  0,  0,   2, 1) // #64
+PAIRING(10, 20, 20, 25,  6, 11, 21, 26,   1, 1, 10, 11,  0,  0, 21, 25,  0,  0,   2, 2) // #65
+PAIRING(10, 20, 20, 25,  6, 11, 25, 26,   1, 0, 10, 11,  0,  0,  0,  0,  0,  0,   2, 2) // #66
+PAIRING(10, 20, 20, 25,  6, 11, 26, 27,   1, 0, 10, 11,  0,  0,  0,  0,  0,  0,   2, 2) // #67
+PAIRING(10, 20, 20, 25,  6, 20, 20, 21,   1, 1, 10, 20,  0,  0, 20, 21,  0,  0,   1, 1) // #68
+PAIRING(10, 20, 20, 25,  6, 20, 20, 25,   1, 1, 10, 20,  0,  0, 20, 25,  0,  0,   0, 1) // #69
+PAIRING(10, 20, 20, 25,  6, 20, 20, 26,   1, 1, 10, 20,  0,  0, 20, 25,  0,  0,   0, 2) // #70
+PAIRING(10, 20, 20, 25,  6, 20, 21, 22,   1, 1, 10, 20,  0,  0, 21, 22,  0,  0,   1, 1) // #71
+PAIRING(10, 20, 20, 25,  6, 20, 21, 25,   1, 1, 10, 20,  0,  0, 21, 25,  0,  0,   1, 1) // #72
+PAIRING(10, 20, 20, 25,  6, 20, 21, 26,   1, 1, 10, 20,  0,  0, 21, 25,  0,  0,   1, 2) // #73
+PAIRING(10, 20, 20, 25,  6, 20, 25, 26,   1, 0, 10, 20,  0,  0,  0,  0,  0,  0,   1, 2) // #74
+PAIRING(10, 20, 20, 25,  6, 20, 26, 27,   1, 0, 10, 20,  0,  0,  0,  0,  0,  0,   1, 2) // #75
+PAIRING(10, 20, 20, 25,  6, 21, 21, 22,   1, 2, 10, 20,  0,  0, 20, 21, 21, 22,   1, 1) // #76
+PAIRING(10, 20, 20, 25,  6, 21, 21, 25,   1, 2, 10, 20,  0,  0, 20, 21, 21, 25,   0, 1) // #77
+PAIRING(10, 20, 20, 25,  6, 21, 21, 26,   1, 2, 10, 20,  0,  0, 20, 21, 21, 25,   0, 2) // #78
+PAIRING(10, 20, 20, 25,  6, 21, 22, 23,   1, 2, 10, 20,  0,  0, 20, 21, 22, 23,   1, 1) // #79
+PAIRING(10, 20, 20, 25,  6, 21, 22, 25,   1, 2, 10, 20,  0,  0, 20, 21, 22, 25,   1, 1) // #80
+PAIRING(10, 20, 20, 25,  6, 21, 22, 26,   1, 2, 10, 20,  0,  0, 20, 21, 22, 25,   1, 2) // #81
+PAIRING(10, 20, 20, 25,  6, 21, 25, 26,   1, 1, 10, 20,  0,  0, 20, 21,  0,  0,   1, 2) // #82
+PAIRING(10, 20, 20, 25,  6, 21, 26, 27,   1, 1, 10, 20,  0,  0, 20, 21,  0,  0,   1, 2) // #83
+PAIRING(10, 20, 20, 25,  6, 25, 25, 26,   1, 1, 10, 20,  0,  0, 20, 25,  0,  0,   0, 2) // #84
+PAIRING(10, 20, 20, 25,  6, 25, 26, 27,   1, 1, 10, 20,  0,  0, 20, 25,  0,  0,   0, 2) // #85
+PAIRING(10, 20, 20, 25,  6, 26, 26, 27,   1, 1, 10, 20,  0,  0, 20, 25,  0,  0,   0, 2) // #86
+PAIRING(10, 20, 20, 25,  6, 26, 27, 28,   1, 1, 10, 20,  0,  0, 20, 25,  0,  0,   0, 2) // #87
+PAIRING(10, 20, 20, 25, 10, 11, 11, 12,   2, 0, 10, 11, 11, 12,  0,  0,  0,  0,   2, 0) // #88
+PAIRING(10, 20, 20, 25, 10, 11, 11, 20,   2, 0, 10, 11, 11, 20,  0,  0,  0,  0,   1, 0) // #89
+PAIRING(10, 20, 20, 25, 10, 11, 11, 21,   2, 1, 10, 11, 11, 20, 20, 21,  0,  0,   1, 0) // #90
+PAIRING(10, 20, 20, 25, 10, 11, 11, 25,   2, 1, 10, 11, 11, 20, 20, 25,  0,  0,   0, 0) // #91
+PAIRING(10, 20, 20, 25, 10, 11, 11, 26,   2, 1, 10, 11, 11, 20, 20, 25,  0,  0,   0, 1) // #92
+PAIRING(10, 20, 20, 25, 10, 11, 12, 13,   2, 0, 10, 11, 12, 13,  0,  0,  0,  0,   2, 0) // #93
+PAIRING(10, 20, 20, 25, 10, 11, 12, 20,   2, 0, 10, 11, 12, 20,  0,  0,  0,  0,   2, 0) // #94
+PAIRING(10, 20, 20, 25, 10, 11, 12, 21,   2, 1, 10, 11, 12, 20, 20, 21,  0,  0,   2, 0) // #95
+PAIRING(10, 20, 20, 25, 10, 11, 12, 25,   2, 1, 10, 11, 12, 20, 20, 25,  0,  0,   1, 0) // #96
+PAIRING(10, 20, 20, 25, 10, 11, 12, 26,   2, 1, 10, 11, 12, 20, 20, 25,  0,  0,   1, 1) // #97
+PAIRING(10, 20, 20, 25, 10, 11, 20, 21,   1, 1, 10, 11,  0,  0, 20, 21,  0,  0,   2, 0) // #98
+PAIRING(10, 20, 20, 25, 10, 11, 20, 25,   1, 1, 10, 11,  0,  0, 20, 25,  0,  0,   1, 0) // #99
+PAIRING(10, 20, 20, 25, 10, 11, 20, 26,   1, 1, 10, 11,  0,  0, 20, 25,  0,  0,   1, 1) // #100
+PAIRING(10, 20, 20, 25, 10, 11, 21, 22,   1, 1, 10, 11,  0,  0, 21, 22,  0,  0,   2, 0) // #101
+PAIRING(10, 20, 20, 25, 10, 11, 21, 25,   1, 1, 10, 11,  0,  0, 21, 25,  0,  0,   2, 0) // #102
+PAIRING(10, 20, 20, 25, 10, 11, 21, 26,   1, 1, 10, 11,  0,  0, 21, 25,  0,  0,   2, 1) // #103
+PAIRING(10, 20, 20, 25, 10, 11, 25, 26,   1, 0, 10, 11,  0,  0,  0,  0,  0,  0,   2, 1) // #104
+PAIRING(10, 20, 20, 25, 10, 11, 26, 27,   1, 0, 10, 11,  0,  0,  0,  0,  0,  0,   2, 1) // #105
+PAIRING(10, 20, 20, 25, 10, 20, 20, 21,   1, 1, 10, 20,  0,  0, 20, 21,  0,  0,   1, 0) // #106
+PAIRING(10, 20, 20, 25, 10, 20, 20, 25,   1, 1, 10, 20,  0,  0, 20, 25,  0,  0,   0, 0) // #107
+PAIRING(10, 20, 20, 25, 10, 20, 20, 26,   1, 1, 10, 20,  0,  0, 20, 25,  0,  0,   0, 1) // #108
+PAIRING(10, 20, 20, 25, 10, 20, 21, 22,   1, 1, 10, 20,  0,  0, 21, 22,  0,  0,   1, 0) // #109
+PAIRING(10, 20, 20, 25, 10, 20, 21, 25,   1, 1, 10, 20,  0,  0, 21, 25,  0,  0,   1, 0) // #110
+PAIRING(10, 20, 20, 25, 10, 20, 21, 26,   1, 1, 10, 20,  0,  0, 21, 25,  0,  0,   1, 1) // #111
+PAIRING(10, 20, 20, 25, 10, 20, 25, 26,   1, 0, 10, 20,  0,  0,  0,  0,  0,  0,   1, 1) // #112
+PAIRING(10, 20, 20, 25, 10, 20, 26, 27,   1, 0, 10, 20,  0,  0,  0,  0,  0,  0,   1, 1) // #113
+PAIRING(10, 20, 20, 25, 10, 21, 21, 22,   1, 2, 10, 20,  0,  0, 20, 21, 21, 22,   1, 0) // #114
+PAIRING(10, 20, 20, 25, 10, 21, 21, 25,   1, 2, 10, 20,  0,  0, 20, 21, 21, 25,   0, 0) // #115
+PAIRING(10, 20, 20, 25, 10, 21, 21, 26,   1, 2, 10, 20,  0,  0, 20, 21, 21, 25,   0, 1) // #116
+PAIRING(10, 20, 20, 25, 10, 21, 22, 23,   1, 2, 10, 20,  0,  0, 20, 21, 22, 23,   1, 0) // #117
+PAIRING(10, 20, 20, 25, 10, 21, 22, 25,   1, 2, 10, 20,  0,  0, 20, 21, 22, 25,   1, 0) // #118
+PAIRING(10, 20, 20, 25, 10, 21, 22, 26,   1, 2, 10, 20,  0,  0, 20, 21, 22, 25,   1, 1) // #119
+PAIRING(10, 20, 20, 25, 10, 21, 25, 26,   1, 1, 10, 20,  0,  0, 20, 21,  0,  0,   1, 1) // #120
+PAIRING(10, 20, 20, 25, 10, 21, 26, 27,   1, 1, 10, 20,  0,  0, 20, 21,  0,  0,   1, 1) // #121
+PAIRING(10, 20, 20, 25, 10, 25, 25, 26,   1, 1, 10, 20,  0,  0, 20, 25,  0,  0,   0, 1) // #122
+PAIRING(10, 20, 20, 25, 10, 25, 26, 27,   1, 1, 10, 20,  0,  0, 20, 25,  0,  0,   0, 1) // #123
+PAIRING(10, 20, 20, 25, 10, 26, 26, 27,   1, 1, 10, 20,  0,  0, 20, 25,  0,  0,   0, 2) // #124
+PAIRING(10, 20, 20, 25, 10, 26, 27, 28,   1, 1, 10, 20,  0,  0, 20, 25,  0,  0,   0, 2) // #125
+PAIRING(10, 20, 20, 25, 11, 12, 12, 13,   2, 0, 11, 12, 12, 13,  0,  0,  0,  0,   2, 0) // #126
+PAIRING(10, 20, 20, 25, 11, 12, 12, 20,   2, 0, 11, 12, 12, 20,  0,  0,  0,  0,   2, 0) // #127
+PAIRING(10, 20, 20, 25, 11, 12, 12, 21,   2, 1, 11, 12, 12, 20, 20, 21,  0,  0,   2, 0) // #128
+PAIRING(10, 20, 20, 25, 11, 12, 12, 25,   2, 1, 11, 12, 12, 20, 20, 25,  0,  0,   1, 0) // #129
+PAIRING(10, 20, 20, 25, 11, 12, 12, 26,   2, 1, 11, 12, 12, 20, 20, 25,  0,  0,   1, 1) // #130
+PAIRING(10, 20, 20, 25, 11, 12, 13, 14,   2, 0, 11, 12, 13, 14,  0,  0,  0,  0,   2, 0) // #131
+PAIRING(10, 20, 20, 25, 11, 12, 13, 20,   2, 0, 11, 12, 13, 20,  0,  0,  0,  0,   2, 0) // #132
+PAIRING(10, 20, 20, 25, 11, 12, 13, 21,   2, 1, 11, 12, 13, 20, 20, 21,  0,  0,   2, 0) // #133
+PAIRING(10, 20, 20, 25, 11, 12, 13, 25,   2, 1, 11, 12, 13, 20, 20, 25,  0,  0,   1, 0) // #134
+PAIRING(10, 20, 20, 25, 11, 12, 13, 26,   2, 1, 11, 12, 13, 20, 20, 25,  0,  0,   1, 1) // #135
+PAIRING(10, 20, 20, 25, 11, 12, 20, 21,   1, 1, 11, 12,  0,  0, 20, 21,  0,  0,   2, 0) // #136
+PAIRING(10, 20, 20, 25, 11, 12, 20, 25,   1, 1, 11, 12,  0,  0, 20, 25,  0,  0,   1, 0) // #137
+PAIRING(10, 20, 20, 25, 11, 12, 20, 26,   1, 1, 11, 12,  0,  0, 20, 25,  0,  0,   1, 1) // #138
+PAIRING(10, 20, 20, 25, 11, 12, 21, 22,   1, 1, 11, 12,  0,  0, 21, 22,  0,  0,   2, 0) // #139
+PAIRING(10, 20, 20, 25, 11, 12, 21, 25,   1, 1, 11, 12,  0,  0, 21, 25,  0,  0,   2, 0) // #140
+PAIRING(10, 20, 20, 25, 11, 12, 21, 26,   1, 1, 11, 12,  0,  0, 21, 25,  0,  0,   2, 1) // #141
+PAIRING(10, 20, 20, 25, 11, 12, 25, 26,   1, 0, 11, 12,  0,  0,  0,  0,  0,  0,   2, 1) // #142
+PAIRING(10, 20, 20, 25, 11, 12, 26, 27,   1, 0, 11, 12,  0,  0,  0,  0,  0,  0,   2, 1) // #143
+PAIRING(10, 20, 20, 25, 11, 20, 20, 21,   1, 1, 11, 20,  0,  0, 20, 21,  0,  0,   2, 0) // #144
+PAIRING(10, 20, 20, 25, 11, 20, 20, 25,   1, 1, 11, 20,  0,  0, 20, 25,  0,  0,   1, 0) // #145
+PAIRING(10, 20, 20, 25, 11, 20, 20, 26,   1, 1, 11, 20,  0,  0, 20, 25,  0,  0,   1, 1) // #146
+PAIRING(10, 20, 20, 25, 11, 20, 21, 22,   1, 1, 11, 20,  0,  0, 21, 22,  0,  0,   2, 0) // #147
+PAIRING(10, 20, 20, 25, 11, 20, 21, 25,   1, 1, 11, 20,  0,  0, 21, 25,  0,  0,   2, 0) // #148
+PAIRING(10, 20, 20, 25, 11, 20, 21, 26,   1, 1, 11, 20,  0,  0, 21, 25,  0,  0,   2, 1) // #149
+PAIRING(10, 20, 20, 25, 11, 20, 25, 26,   1, 0, 11, 20,  0,  0,  0,  0,  0,  0,   2, 1) // #150
+PAIRING(10, 20, 20, 25, 11, 20, 26, 27,   1, 0, 11, 20,  0,  0,  0,  0,  0,  0,   2, 1) // #151
+PAIRING(10, 20, 20, 25, 11, 21, 21, 22,   1, 2, 11, 20,  0,  0, 20, 21, 21, 22,   2, 0) // #152
+PAIRING(10, 20, 20, 25, 11, 21, 21, 25,   1, 2, 11, 20,  0,  0, 20, 21, 21, 25,   1, 0) // #153
+PAIRING(10, 20, 20, 25, 11, 21, 21, 26,   1, 2, 11, 20,  0,  0, 20, 21, 21, 25,   1, 1) // #154
+PAIRING(10, 20, 20, 25, 11, 21, 22, 23,   1, 2, 11, 20,  0,  0, 20, 21, 22, 23,   2, 0) // #155
+PAIRING(10, 20, 20, 25, 11, 21, 22, 25,   1, 2, 11, 20,  0,  0, 20, 21, 22, 25,   2, 0) // #156
+PAIRING(10, 20, 20, 25, 11, 21, 22, 26,   1, 2, 11, 20,  0,  0, 20, 21, 22, 25,   2, 1) // #157
+PAIRING(10, 20, 20, 25, 11, 21, 25, 26,   1, 1, 11, 20,  0,  0, 20, 21,  0,  0,   2, 1) // #158
+PAIRING(10, 20, 20, 25, 11, 21, 26, 27,   1, 1, 11, 20,  0,  0, 20, 21,  0,  0,   2, 1) // #159
+PAIRING(10, 20, 20, 25, 11, 25, 25, 26,   1, 1, 11, 20,  0,  0, 20, 25,  0,  0,   1, 1) // #160
+PAIRING(10, 20, 20, 25, 11, 25, 26, 27,   1, 1, 11, 20,  0,  0, 20, 25,  0,  0,   1, 1) // #161
+PAIRING(10, 20, 20, 25, 11, 26, 26, 27,   1, 1, 11, 20,  0,  0, 20, 25,  0,  0,   1, 2) // #162
+PAIRING(10, 20, 20, 25, 11, 26, 27, 28,   1, 1, 11, 20,  0,  0, 20, 25,  0,  0,   1, 2) // #163
+PAIRING(10, 20, 20, 25, 20, 21, 21, 22,   0, 2,  0,  0,  0,  0, 20, 21, 21, 22,   2, 0) // #164
+PAIRING(10, 20, 20, 25, 20, 21, 21, 25,   0, 2,  0,  0,  0,  0, 20, 21, 21, 25,   1, 0) // #165
+PAIRING(10, 20, 20, 25, 20, 21, 21, 26,   0, 2,  0,  0,  0,  0, 20, 21, 21, 25,   1, 1) // #166
+PAIRING(10, 20, 20, 25, 20, 21, 22, 23,   0, 2,  0,  0,  0,  0, 20, 21, 22, 23,   2, 0) // #167
+PAIRING(10, 20, 20, 25, 20, 21, 22, 25,   0, 2,  0,  0,  0,  0, 20, 21, 22, 25,   2, 0) // #168
+PAIRING(10, 20, 20, 25, 20, 21, 22, 26,   0, 2,  0,  0,  0,  0, 20, 21, 22, 25,   2, 1) // #169
+PAIRING(10, 20, 20, 25, 20, 21, 25, 26,   0, 1,  0,  0,  0,  0, 20, 21,  0,  0,   2, 1) // #170
+PAIRING(10, 20, 20, 25, 20, 21, 26, 27,   0, 1,  0,  0,  0,  0, 20, 21,  0,  0,   2, 1) // #171
+PAIRING(10, 20, 20, 25, 20, 25, 25, 26,   0, 1,  0,  0,  0,  0, 20, 25,  0,  0,   1, 1) // #172
+PAIRING(10, 20, 20, 25, 20, 25, 26, 27,   0, 1,  0,  0,  0,  0, 20, 25,  0,  0,   1, 1) // #173
+PAIRING(10, 20, 20, 25, 20, 26, 26, 27,   0, 1,  0,  0,  0,  0, 20, 25,  0,  0,   1, 2) // #174
+PAIRING(10, 20, 20, 25, 20, 26, 27, 28,   0, 1,  0,  0,  0,  0, 20, 25,  0,  0,   1, 2) // #175
+PAIRING(10, 20, 20, 25, 21, 22, 22, 23,   0, 2,  0,  0,  0,  0, 21, 22, 22, 23,   2, 0) // #176
+PAIRING(10, 20, 20, 25, 21, 22, 22, 25,   0, 2,  0,  0,  0,  0, 21, 22, 22, 25,   2, 0) // #177
+PAIRING(10, 20, 20, 25, 21, 22, 22, 26,   0, 2,  0,  0,  0,  0, 21, 22, 22, 25,   2, 1) // #178
+PAIRING(10, 20, 20, 25, 21, 22, 23, 24,   0, 2,  0,  0,  0,  0, 21, 22, 23, 24,   2, 0) // #179
+PAIRING(10, 20, 20, 25, 21, 22, 23, 25,   0, 2,  0,  0,  0,  0, 21, 22, 23, 25,   2, 0) // #180
+PAIRING(10, 20, 20, 25, 21, 22, 23, 26,   0, 2,  0,  0,  0,  0, 21, 22, 23, 25,   2, 1) // #181
+PAIRING(10, 20, 20, 25, 21, 22, 25, 26,   0, 1,  0,  0,  0,  0, 21, 22,  0,  0,   2, 1) // #182
+PAIRING(10, 20, 20, 25, 21, 22, 26, 27,   0, 1,  0,  0,  0,  0, 21, 22,  0,  0,   2, 1) // #183
+PAIRING(10, 20, 20, 25, 21, 25, 25, 26,   0, 1,  0,  0,  0,  0, 21, 25,  0,  0,   2, 1) // #184
+PAIRING(10, 20, 20, 25, 21, 25, 26, 27,   0, 1,  0,  0,  0,  0, 21, 25,  0,  0,   2, 1) // #185
+PAIRING(10, 20, 20, 25, 21, 26, 26, 27,   0, 1,  0,  0,  0,  0, 21, 25,  0,  0,   2, 2) // #186
+PAIRING(10, 20, 20, 25, 21, 26, 27, 28,   0, 1,  0,  0,  0,  0, 21, 25,  0,  0,   2, 2) // #187
+PAIRING(10, 20, 20, 25, 25, 26, 26, 27,   0, 0,  0,  0,  0,  0,  0,  0,  0,  0,   2, 2) // #188
+PAIRING(10, 20, 20, 25, 25, 26, 27, 28,   0, 0,  0,  0,  0,  0,  0,  0,  0,  0,   2, 2) // #189
+PAIRING(10, 20, 20, 25, 26, 27, 27, 28,   0, 0,  0,  0,  0,  0,  0,  0,  0,  0,   2, 2) // #190
+PAIRING(10, 20, 20, 25, 26, 27, 28, 29,   0, 0,  0,  0,  0,  0,  0,  0,  0,  0,   2, 2) // #191
+PAIRING(10, 15, 20, 25,  6,  7,  7,  8,   0, 0,  0,  0,  0,  0,  0,  0,  0,  0,   2, 2) // #192
+PAIRING(10, 15, 20, 25,  6,  7,  7, 10,   0, 0,  0,  0,  0,  0,  0,  0,  0,  0,   2, 2) // #193
+PAIRING(10, 15, 20, 25,  6,  7,  7, 11,   1, 0, 10, 11,  0,  0,  0,  0,  0,  0,   2, 2) // #194
+PAIRING(10, 15, 20, 25,  6,  7,  7, 15,   1, 0, 10, 15,  0,  0,  0,  0,  0,  0,   1, 2) // #195
+PAIRING(10, 15, 20, 25,  6,  7,  7, 16,   1, 0, 10, 15,  0,  0,  0,  0,  0,  0,   1, 2) // #196
+PAIRING(10, 15, 20, 25,  6,  7,  7, 20,   1, 0, 10, 15,  0,  0,  0,  0,  0,  0,   1, 2) // #197
+PAIRING(10, 15, 20, 25,  6,  7,  7, 21,   1, 1, 10, 15,  0,  0, 20, 21,  0,  0,   1, 2) // #198
+PAIRING(10, 15, 20, 25,  6,  7,  7, 25,   1, 1, 10, 15,  0,  0, 20, 25,  0,  0,   0, 2) // #199
+PAIRING(10, 15, 20, 25,  6,  7,  7, 26,   1, 1, 10, 15,  0,  0, 20, 25,  0,  0,   0, 2) // #200
+PAIRING(10, 15, 20, 25,  6,  7,  8,  9,   0, 0,  0,  0,  0,  0,  0,  0,  0,  0,   2, 2) // #201
+PAIRING(10, 15, 20, 25,  6,  7,  8, 10,   0, 0,  0,  0,  0,  0,  0,  0,  0,  0,   2, 2) // #202
+PAIRING(10, 15, 20, 25,  6,  7,  8, 11,   1, 0, 10, 11,  0,  0,  0,  0,  0,  0,   2, 2) // #203
+PAIRING(10, 15, 20, 25,  6,  7,  8, 15,   1, 0, 10, 15,  0,  0,  0,  0,  0,  0,   1, 2) // #204
+PAIRING(10, 15, 20, 25,  6,  7,  8, 16,   1, 0, 10, 15,  0,  0,  0,  0,  0,  0,   1, 2) // #205
+PAIRING(10, 15, 20, 25,  6,  7,  8, 20,   1, 0, 10, 15,  0,  0,  0,  0,  0,  0,   1, 2) // #206
+PAIRING(10, 15, 20, 25,  6,  7,  8, 21,   1, 1, 10, 15,  0,  0, 20, 21,  0,  0,   1, 2) // #207
+PAIRING(10, 15, 20, 25,  6,  7,  8, 25,   1, 1, 10, 15,  0,  0, 20, 25,  0,  0,   0, 2) // #208
+PAIRING(10, 15, 20, 25,  6,  7,  8, 26,   1, 1, 10, 15,  0,  0, 20, 25,  0,  0,   0, 2) // #209
+PAIRING(10, 15, 20, 25,  6,  7, 10, 11,   1, 0, 10, 11,  0,  0,  0,  0,  0,  0,   2, 1) // #210
+PAIRING(10, 15, 20, 25,  6,  7, 10, 15,   1, 0, 10, 15,  0,  0,  0,  0,  0,  0,   1, 1) // #211
+PAIRING(10, 15, 20, 25,  6,  7, 10, 16,   1, 0, 10, 15,  0,  0,  0,  0,  0,  0,   1, 2) // #212
+PAIRING(10, 15, 20, 25,  6,  7, 10, 20,   1, 0, 10, 15,  0,  0,  0,  0,  0,  0,   1, 1) // #213
+PAIRING(10, 15, 20, 25,  6,  7, 10, 21,   1, 1, 10, 15,  0,  0, 20, 21,  0,  0,   1, 2) // #214
+PAIRING(10, 15, 20, 25,  6,  7, 10, 25,   1, 1, 10, 15,  0,  0, 20, 25,  0,  0,   0, 2) // #215
+PAIRING(10, 15, 20, 25,  6,  7, 10, 26,   1, 1, 10, 15,  0,  0, 20, 25,  0,  0,   0, 2) // #216
+PAIRING(10, 15, 20, 25,  6,  7, 11, 12,   1, 0, 11, 12,  0,  0,  0,  0,  0,  0,   2, 1) // #217
+PAIRING(10, 15, 20, 25,  6,  7, 11, 15,   1, 0, 11, 15,  0,  0,  0,  0,  0,  0,   2, 1) // #218
+PAIRING(10, 15, 20, 25,  6,  7, 11, 16,   1, 0, 11, 15,  0,  0,  0,  0,  0,  0,   2, 2) // #219
+PAIRING(10, 15, 20, 25,  6,  7, 11, 20,   1, 0, 11, 15,  0,  0,  0,  0,  0,  0,   2, 1) // #220
+PAIRING(10, 15, 20, 25,  6,  7, 11, 21,   1, 1, 11, 15,  0,  0, 20, 21,  0,  0,   2, 2) // #221
+PAIRING(10, 15, 20, 25,  6,  7, 11, 25,   1, 1, 11, 15,  0,  0, 20, 25,  0,  0,   1, 2) // #222
+PAIRING(10, 15, 20, 25,  6,  7, 11, 26,   1, 1, 11, 15,  0,  0, 20, 25,  0,  0,   1, 2) // #223
+PAIRING(10, 15, 20, 25,  6,  7, 15, 16,   0, 0,  0,  0,  0,  0,  0,  0,  0,  0,   2, 2) // #224
+PAIRING(10, 15, 20, 25,  6,  7, 15, 20,   0, 0,  0,  0,  0,  0,  0,  0,  0,  0,   2, 2) // #225
+PAIRING(10, 15, 20, 25,  6,  7, 15, 21,   0, 1,  0,  0,  0,  0, 20, 21,  0,  0,   2, 2) // #226
+PAIRING(10, 15, 20, 25,  6,  7, 15, 25,   0, 1,  0,  0,  0,  0, 20, 25,  0,  0,   1, 2) // #227
+PAIRING(10, 15, 20, 25,  6,  7, 15, 26,   0, 1,  0,  0,  0,  0, 20, 25,  0,  0,   1, 2) // #228
+PAIRING(10, 15, 20, 25,  6,  7, 16, 17,   0, 0,  0,  0,  0,  0,  0,  0,  0,  0,   2, 2) // #229
+PAIRING(10, 15, 20, 25,  6,  7, 16, 20,   0, 0,  0,  0,  0,  0,  0,  0,  0,  0,   2, 2) // #230
+PAIRING(10, 15, 20, 25,  6,  7, 16, 21,   0, 1,  0,  0,  0,  0, 20, 21,  0,  0,   2, 2) // #231
+PAIRING(10, 15, 20, 25,  6,  7, 16, 25,   0, 1,  0,  0,  0,  0, 20, 25,  0,  0,   1, 2) // #232
+PAIRING(10, 15, 20, 25,  6,  7, 16, 26,   0, 1,  0,  0,  0,  0, 20, 25,  0,  0,   1, 2) // #233
+PAIRING(10, 15, 20, 25,  6,  7, 20, 21,   0, 1,  0,  0,  0,  0, 20, 21,  0,  0,   2, 1) // #234
+PAIRING(10, 15, 20, 25,  6,  7, 20, 25,   0, 1,  0,  0,  0,  0, 20, 25,  0,  0,   1, 1) // #235
+PAIRING(10, 15, 20, 25,  6,  7, 20, 26,   0, 1,  0,  0,  0,  0, 20, 25,  0,  0,   1, 2) // #236
+PAIRING(10, 15, 20, 25,  6,  7, 21, 22,   0, 1,  0,  0,  0,  0, 21, 22,  0,  0,   2, 1) // #237
+PAIRING(10, 15, 20, 25,  6,  7, 21, 25,   0, 1,  0,  0,  0,  0, 21, 25,  0,  0,   2, 1) // #238
+PAIRING(10, 15, 20, 25,  6,  7, 21, 26,   0, 1,  0,  0,  0,  0, 21, 25,  0,  0,   2, 2) // #239
+PAIRING(10, 15, 20, 25,  6,  7, 25, 26,   0, 0,  0,  0,  0,  0,  0,  0,  0,  0,   2, 2) // #240
+PAIRING(10, 15, 20, 25,  6,  7, 26, 27,   0, 0,  0,  0,  0,  0,  0,  0,  0,  0,   2, 2) // #241
+PAIRING(10, 15, 20, 25,  6, 10, 10, 11,   1, 0, 10, 11,  0,  0,  0,  0,  0,  0,   2, 1) // #242
+PAIRING(10, 15, 20, 25,  6, 10, 10, 15,   1, 0, 10, 15,  0,  0,  0,  0,  0,  0,   1, 1) // #243
+PAIRING(10, 15, 20, 25,  6, 10, 10, 16,   1, 0, 10, 15,  0,  0,  0,  0,  0,  0,   1, 2) // #244
+PAIRING(10, 15, 20, 25,  6, 10, 10, 20,   1, 0, 10, 15,  0,  0,  0,  0,  0,  0,   1, 1) // #245
+PAIRING(10, 15, 20, 25,  6, 10, 10, 21,   1, 1, 10, 15,  0,  0, 20, 21,  0,  0,   1, 2) // #246
+PAIRING(10, 15, 20, 25,  6, 10, 10, 25,   1, 1, 10, 15,  0,  0, 20, 25,  0,  0,   0, 2) // #247
+PAIRING(10, 15, 20, 25,  6, 10, 10, 26,   1, 1, 10, 15,  0,  0, 20, 25,  0,  0,   0, 2) // #248
+PAIRING(10, 15, 20, 25,  6, 10, 11, 12,   1, 0, 11, 12,  0,  0,  0,  0,  0,  0,   2, 1) // #249
+PAIRING(10, 15, 20, 25,  6, 10, 11, 15,   1, 0, 11, 15,  0,  0,  0,  0,  0,  0,   2, 1) // #250
+PAIRING(10, 15, 20, 25,  6, 10, 11, 16,   1, 0, 11, 15,  0,  0,  0,  0,  0,  0,   2, 2) // #251
+PAIRING(10, 15, 20, 25,  6, 10, 11, 20,   1, 0, 11, 15,  0,  0,  0,  0,  0,  0,   2, 1) // #252
+PAIRING(10, 15, 20, 25,  6, 10, 11, 21,   1, 1, 11, 15,  0,  0, 20, 21,  0,  0,   2, 2) // #253
+PAIRING(10, 15, 20, 25,  6, 10, 11, 25,   1, 1, 11, 15,  0,  0, 20, 25,  0,  0,   1, 2) // #254
+PAIRING(10, 15, 20, 25,  6, 10, 11, 26,   1, 1, 11, 15,  0,  0, 20, 25,  0,  0,   1, 2) // #255
+PAIRING(10, 15, 20, 25,  6, 10, 15, 16,   0, 0,  0,  0,  0,  0,  0,  0,  0,  0,   2, 2) // #256
+PAIRING(10, 15, 20, 25,  6, 10, 15, 20,   0, 0,  0,  0,  0,  0,  0,  0,  0,  0,   2, 2) // #257
+PAIRING(10, 15, 20, 25,  6, 10, 15, 21,   0, 1,  0,  0,  0,  0, 20, 21,  0,  0,   2, 2) // #258
+PAIRING(10, 15, 20, 25,  6, 10, 15, 25,   0, 1,  0,  0,  0,  0, 20, 25,  0,  0,   1, 2) // #259
+PAIRING(10, 15, 20, 25,  6, 10, 15, 26,   0, 1,  0,  0,  0,  0, 20, 25,  0,  0,   1, 2) // #260
+PAIRING(10, 15, 20, 25,  6, 10, 16, 17,   0, 0,  0,  0,  0,  0,  0,  0,  0,  0,   2, 2) // #261
+PAIRING(10, 15, 20, 25,  6, 10, 16, 20,   0, 0,  0,  0,  0,  0,  0,  0,  0,  0,   2, 2) // #262
+PAIRING(10, 15, 20, 25,  6, 10, 16, 21,   0, 1,  0,  0,  0,  0, 20, 21,  0,  0,   2, 2) // #263
+PAIRING(10, 15, 20, 25,  6, 10, 16, 25,   0, 1,  0,  0,  0,  0, 20, 25,  0,  0,   1, 2) // #264
+PAIRING(10, 15, 20, 25,  6, 10, 16, 26,   0, 1,  0,  0,  0,  0, 20, 25,  0,  0,   1, 2) // #265
+PAIRING(10, 15, 20, 25,  6, 10, 20, 21,   0, 1,  0,  0,  0,  0, 20, 21,  0,  0,   2, 1) // #266
+PAIRING(10, 15, 20, 25,  6, 10, 20, 25,   0, 1,  0,  0,  0,  0, 20, 25,  0,  0,   1, 1) // #267
+PAIRING(10, 15, 20, 25,  6, 10, 20, 26,   0, 1,  0,  0,  0,  0, 20, 25,  0,  0,   1, 2) // #268
+PAIRING(10, 15, 20, 25,  6, 10, 21, 22,   0, 1,  0,  0,  0,  0, 21, 22,  0,  0,   2, 1) // #269
+PAIRING(10, 15, 20, 25,  6, 10, 21, 25,   0, 1,  0,  0,  0,  0, 21, 25,  0,  0,   2, 1) // #270
+PAIRING(10, 15, 20, 25,  6, 10, 21, 26,   0, 1,  0,  0,  0,  0, 21, 25,  0,  0,   2, 2) // #271
+PAIRING(10, 15, 20, 25,  6, 10, 25, 26,   0, 0,  0,  0,  0,  0,  0,  0,  0,  0,   2, 2) // #272
+PAIRING(10, 15, 20, 25,  6, 10, 26, 27,   0, 0,  0,  0,  0,  0,  0,  0,  0,  0,   2, 2) // #273
+PAIRING(10, 15, 20, 25,  6, 11, 11, 12,   2, 0, 10, 11, 11, 12,  0,  0,  0,  0,   2, 1) // #274
+PAIRING(10, 15, 20, 25,  6, 11, 11, 15,   2, 0, 10, 11, 11, 15,  0,  0,  0,  0,   1, 1) // #275
+PAIRING(10, 15, 20, 25,  6, 11, 11, 16,   2, 0, 10, 11, 11, 15,  0,  0,  0,  0,   1, 2) // #276
+PAIRING(10, 15, 20, 25,  6, 11, 11, 20,   2, 0, 10, 11, 11, 15,  0,  0,  0,  0,   1, 1) // #277
+PAIRING(10, 15, 20, 25,  6, 11, 11, 21,   2, 1, 10, 11, 11, 15, 20, 21,  0,  0,   1, 2) // #278
+PAIRING(10, 15, 20, 25,  6, 11, 11, 25,   2, 1, 10, 11, 11, 15, 20, 25,  0,  0,   0, 2) // #279
+PAIRING(10, 15, 20, 25,  6, 11, 11, 26,   2, 1, 10, 11, 11, 15, 20, 25,  0,  0,   0, 2) // #280
+PAIRING(10, 15, 20, 25,  6, 11, 12, 13,   2, 0, 10, 11, 12, 13,  0,  0,  0,  0,   2, 1) // #281
+PAIRING(10, 15, 20, 25,  6, 11, 12, 15,   2, 0, 10, 11, 12, 15,  0,  0,  0,  0,   2, 1) // #282
+PAIRING(10, 15, 20, 25,  6, 11, 12, 16,   2, 0, 10, 11, 12, 15,  0,  0,  0,  0,   2, 2) // #283
+PAIRING(10, 15, 20, 25,  6, 11, 12, 20,   2, 0, 10, 11, 12, 15,  0,  0,  0,  0,   2, 1) // #284
+PAIRING(10, 15, 20, 25,  6, 11, 12, 21,   2, 1, 10, 11, 12, 15, 20, 21,  0,  0,   2, 2) // #285
+PAIRING(10, 15, 20, 25,  6, 11, 12, 25,   2, 1, 10, 11, 12, 15, 20, 25,  0,  0,   1, 2) // #286
+PAIRING(10, 15, 20, 25,  6, 11, 12, 26,   2, 1, 10, 11, 12, 15, 20, 25,  0,  0,   1, 2) // #287
+PAIRING(10, 15, 20, 25,  6, 11, 15, 16,   1, 0, 10, 11,  0,  0,  0,  0,  0,  0,   2, 2) // #288
+PAIRING(10, 15, 20, 25,  6, 11, 15, 20,   1, 0, 10, 11,  0,  0,  0,  0,  0,  0,   2, 2) // #289
+PAIRING(10, 15, 20, 25,  6, 11, 15, 21,   1, 1, 10, 11,  0,  0, 20, 21,  0,  0,   2, 2) // #290
+PAIRING(10, 15, 20, 25,  6, 11, 15, 25,   1, 1, 10, 11,  0,  0, 20, 25,  0,  0,   1, 2) // #291
+PAIRING(10, 15, 20, 25,  6, 11, 15, 26,   1, 1, 10, 11,  0,  0, 20, 25,  0,  0,   1, 2) // #292
+PAIRING(10, 15, 20, 25,  6, 11, 16, 17,   1, 0, 10, 11,  0,  0,  0,  0,  0,  0,   2, 2) // #293
+PAIRING(10, 15, 20, 25,  6, 11, 16, 20,   1, 0, 10, 11,  0,  0,  0,  0,  0,  0,   2, 2) // #294
+PAIRING(10, 15, 20, 25,  6, 11, 16, 21,   1, 1, 10, 11,  0,  0, 20, 21,  0,  0,   2, 2) // #295
+PAIRING(10, 15, 20, 25,  6, 11, 16, 25,   1, 1, 10, 11,  0,  0, 20, 25,  0,  0,   1, 2) // #296
+PAIRING(10, 15, 20, 25,  6, 11, 16, 26,   1, 1, 10, 11,  0,  0, 20, 25,  0,  0,   1, 2) // #297
+PAIRING(10, 15, 20, 25,  6, 11, 20, 21,   1, 1, 10, 11,  0,  0, 20, 21,  0,  0,   2, 1) // #298
+PAIRING(10, 15, 20, 25,  6, 11, 20, 25,   1, 1, 10, 11,  0,  0, 20, 25,  0,  0,   1, 1) // #299
+PAIRING(10, 15, 20, 25,  6, 11, 20, 26,   1, 1, 10, 11,  0,  0, 20, 25,  0,  0,   1, 2) // #300
+PAIRING(10, 15, 20, 25,  6, 11, 21, 22,   1, 1, 10, 11,  0,  0, 21, 22,  0,  0,   2, 1) // #301
+PAIRING(10, 15, 20, 25,  6, 11, 21, 25,   1, 1, 10, 11,  0,  0, 21, 25,  0,  0,   2, 1) // #302
+PAIRING(10, 15, 20, 25,  6, 11, 21, 26,   1, 1, 10, 11,  0,  0, 21, 25,  0,  0,   2, 2) // #303
+PAIRING(10, 15, 20, 25,  6, 11, 25, 26,   1, 0, 10, 11,  0,  0,  0,  0,  0,  0,   2, 2) // #304
+PAIRING(10, 15, 20, 25,  6, 11, 26, 27,   1, 0, 10, 11,  0,  0,  0,  0,  0,  0,   2, 2) // #305
+PAIRING(10, 15, 20, 25,  6, 15, 15, 16,   1, 0, 10, 15,  0,  0,  0,  0,  0,  0,   1, 2) // #306
+PAIRING(10, 15, 20, 25,  6, 15, 15, 20,   1, 0, 10, 15,  0,  0,  0,  0,  0,  0,   1, 2) // #307
+PAIRING(10, 15, 20, 25,  6, 15, 15, 21,   1, 1, 10, 15,  0,  0, 20, 21,  0,  0,   1, 2) // #308
+PAIRING(10, 15, 20, 25,  6, 15, 15, 25,   1, 1, 10, 15,  0,  0, 20, 25,  0,  0,   0, 2) // #309
+PAIRING(10, 15, 20, 25,  6, 15, 15, 26,   1, 1, 10, 15,  0,  0, 20, 25,  0,  0,   0, 2) // #310
+PAIRING(10, 15, 20, 25,  6, 15, 16, 17,   1, 0, 10, 15,  0,  0,  0,  0,  0,  0,   1, 2) // #311
+PAIRING(10, 15, 20, 25,  6, 15, 16, 20,   1, 0, 10, 15,  0,  0,  0,  0,  0,  0,   1, 2) // #312
+PAIRING(10, 15, 20, 25,  6, 15, 16, 21,   1, 1, 10, 15,  0,  0, 20, 21,  0,  0,   1, 2) // #313
+PAIRING(10, 15, 20, 25,  6, 15, 16, 25,   1, 1, 10, 15,  0,  0, 20, 25,  0,  0,   0, 2) // #314
+PAIRING(10, 15, 20, 25,  6, 15, 16, 26,   1, 1, 10, 15,  0,  0, 20, 25,  0,  0,   0, 2) // #315
+PAIRING(10, 15, 20, 25,  6, 15, 20, 21,   1, 1, 10, 15,  0,  0, 20, 21,  0,  0,   1, 1) // #316
+PAIRING(10, 15, 20, 25,  6, 15, 20, 25,   1, 1, 10, 15,  0,  0, 20, 25,  0,  0,   0, 1) // #317
+PAIRING(10, 15, 20, 25,  6, 15, 20, 26,   1, 1, 10, 15,  0,  0, 20, 25,  0,  0,   0, 2) // #318
+PAIRING(10, 15, 20, 25,  6, 15, 21, 22,   1, 1, 10, 15,  0,  0, 21, 22,  0,  0,   1, 1) // #319
+PAIRING(10, 15, 20, 25,  6, 15, 21, 25,   1, 1, 10, 15,  0,  0, 21, 25,  0,  0,   1, 1) // #320
+PAIRING(10, 15, 20, 25,  6, 15, 21, 26,   1, 1, 10, 15,  0,  0, 21, 25,  0,  0,   1, 2) // #321
+PAIRING(10, 15, 20, 25,  6, 15, 25, 26,   1, 0, 10, 15,  0,  0,  0,  0,  0,  0,   1, 2) // #322
+PAIRING(10, 15, 20, 25,  6, 15, 26, 27,   1, 0, 10, 15,  0,  0,  0,  0,  0,  0,   1, 2) // #323
+PAIRING(10, 15, 20, 25,  6, 16, 16, 17,   1, 0, 10, 15,  0,  0,  0,  0,  0,  0,   1, 2) // #324
+PAIRING(10, 15, 20, 25,  6, 16, 16, 20,   1, 0, 10, 15,  0,  0,  0,  0,  0,  0,   1, 2) // #325
+PAIRING(10, 15, 20, 25,  6, 16, 16, 21,   1, 1, 10, 15,  0,  0, 20, 21,  0,  0,   1, 2) // #326
+PAIRING(10, 15, 20, 25,  6, 16, 16, 25,   1, 1, 10, 15,  0,  0, 20, 25,  0,  0,   0, 2) // #327
+PAIRING(10, 15, 20, 25,  6, 16, 16, 26,   1, 1, 10, 15,  0,  0, 20, 25,  0,  0,   0, 2) // #328
+PAIRING(10, 15, 20, 25,  6, 16, 17, 18,   1, 0, 10, 15,  0,  0,  0,  0,  0,  0,   1, 2) // #329
+PAIRING(10, 15, 20, 25,  6, 16, 17, 20,   1, 0, 10, 15,  0,  0,  0,  0,  0,  0,   1, 2) // #330
+PAIRING(10, 15, 20, 25,  6, 16, 17, 21,   1, 1, 10, 15,  0,  0, 20, 21,  0,  0,   1, 2) // #331
+PAIRING(10, 15, 20, 25,  6, 16, 17, 25,   1, 1, 10, 15,  0,  0, 20, 25,  0,  0,   0, 2) // #332
+PAIRING(10, 15, 20, 25,  6, 16, 17, 26,   1, 1, 10, 15,  0,  0, 20, 25,  0,  0,   0, 2) // #333
+PAIRING(10, 15, 20, 25,  6, 16, 20, 21,   1, 1, 10, 15,  0,  0, 20, 21,  0,  0,   1, 1) // #334
+PAIRING(10, 15, 20, 25,  6, 16, 20, 25,   1, 1, 10, 15,  0,  0, 20, 25,  0,  0,   0, 1) // #335
+PAIRING(10, 15, 20, 25,  6, 16, 20, 26,   1, 1, 10, 15,  0,  0, 20, 25,  0,  0,   0, 2) // #336
+PAIRING(10, 15, 20, 25,  6, 16, 21, 22,   1, 1, 10, 15,  0,  0, 21, 22,  0,  0,   1, 1) // #337
+PAIRING(10, 15, 20, 25,  6, 16, 21, 25,   1, 1, 10, 15,  0,  0, 21, 25,  0,  0,   1, 1) // #338
+PAIRING(10, 15, 20, 25,  6, 16, 21, 26,   1, 1, 10, 15,  0,  0, 21, 25,  0,  0,   1, 2) // #339
+PAIRING(10, 15, 20, 25,  6, 16, 25, 26,   1, 0, 10, 15,  0,  0,  0,  0,  0,  0,   1, 2) // #340
+PAIRING(10, 15, 20, 25,  6, 16, 26, 27,   1, 0, 10, 15,  0,  0,  0,  0,  0,  0,   1, 2) // #341
+PAIRING(10, 15, 20, 25,  6, 20, 20, 21,   1, 1, 10, 15,  0,  0, 20, 21,  0,  0,   1, 1) // #342
+PAIRING(10, 15, 20, 25,  6, 20, 20, 25,   1, 1, 10, 15,  0,  0, 20, 25,  0,  0,   0, 1) // #343
+PAIRING(10, 15, 20, 25,  6, 20, 20, 26,   1, 1, 10, 15,  0,  0, 20, 25,  0,  0,   0, 2) // #344
+PAIRING(10, 15, 20, 25,  6, 20, 21, 22,   1, 1, 10, 15,  0,  0, 21, 22,  0,  0,   1, 1) // #345
+PAIRING(10, 15, 20, 25,  6, 20, 21, 25,   1, 1, 10, 15,  0,  0, 21, 25,  0,  0,   1, 1) // #346
+PAIRING(10, 15, 20, 25,  6, 20, 21, 26,   1, 1, 10, 15,  0,  0, 21, 25,  0,  0,   1, 2) // #347
+PAIRING(10, 15, 20, 25,  6, 20, 25, 26,   1, 0, 10, 15,  0,  0,  0,  0,  0,  0,   1, 2) // #348
+PAIRING(10, 15, 20, 25,  6, 20, 26, 27,   1, 0, 10, 15,  0,  0,  0,  0,  0,  0,   1, 2) // #349
+PAIRING(10, 15, 20, 25,  6, 21, 21, 22,   1, 2, 10, 15,  0,  0, 20, 21, 21, 22,   1, 1) // #350
+PAIRING(10, 15, 20, 25,  6, 21, 21, 25,   1, 2, 10, 15,  0,  0, 20, 21, 21, 25,   0, 1) // #351
+PAIRING(10, 15, 20, 25,  6, 21, 21, 26,   1, 2, 10, 15,  0,  0, 20, 21, 21, 25,   0, 2) // #352
+PAIRING(10, 15, 20, 25,  6, 21, 22, 23,   1, 2, 10, 15,  0,  0, 20, 21, 22, 23,   1, 1) // #353
+PAIRING(10, 15, 20, 25,  6, 21, 22, 25,   1, 2, 10, 15,  0,  0, 20, 21, 22, 25,   1, 1) // #354
+PAIRING(10, 15, 20, 25,  6, 21, 22, 26,   1, 2, 10, 15,  0,  0, 20, 21, 22, 25,   1, 2) // #355
+PAIRING(10, 15, 20, 25,  6, 21, 25, 26,   1, 1, 10, 15,  0,  0, 20, 21,  0,  0,   1, 2) // #356
+PAIRING(10, 15, 20, 25,  6, 21, 26, 27,   1, 1, 10, 15,  0,  0, 20, 21,  0,  0,   1, 2) // #357
+PAIRING(10, 15, 20, 25,  6, 25, 25, 26,   1, 1, 10, 15,  0,  0, 20, 25,  0,  0,   0, 2) // #358
+PAIRING(10, 15, 20, 25,  6, 25, 26, 27,   1, 1, 10, 15,  0,  0, 20, 25,  0,  0,   0, 2) // #359
+PAIRING(10, 15, 20, 25,  6, 26, 26, 27,   1, 1, 10, 15,  0,  0, 20, 25,  0,  0,   0, 2) // #360
+PAIRING(10, 15, 20, 25,  6, 26, 27, 28,   1, 1, 10, 15,  0,  0, 20, 25,  0,  0,   0, 2) // #361
+PAIRING(10, 15, 20, 25, 10, 11, 11, 12,   2, 0, 10, 11, 11, 12,  0,  0,  0,  0,   2, 0) // #362
+PAIRING(10, 15, 20, 25, 10, 11, 11, 15,   2, 0, 10, 11, 11, 15,  0,  0,  0,  0,   1, 0) // #363
+PAIRING(10, 15, 20, 25, 10, 11, 11, 16,   2, 0, 10, 11, 11, 15,  0,  0,  0,  0,   1, 1) // #364
+PAIRING(10, 15, 20, 25, 10, 11, 11, 20,   2, 0, 10, 11, 11, 15,  0,  0,  0,  0,   1, 0) // #365
+PAIRING(10, 15, 20, 25, 10, 11, 11, 21,   2, 1, 10, 11, 11, 15, 20, 21,  0,  0,   1, 1) // #366
+PAIRING(10, 15, 20, 25, 10, 11, 11, 25,   2, 1, 10, 11, 11, 15, 20, 25,  0,  0,   0, 1) // #367
+PAIRING(10, 15, 20, 25, 10, 11, 11, 26,   2, 1, 10, 11, 11, 15, 20, 25,  0,  0,   0, 1) // #368
+PAIRING(10, 15, 20, 25, 10, 11, 12, 13,   2, 0, 10, 11, 12, 13,  0,  0,  0,  0,   2, 0) // #369
+PAIRING(10, 15, 20, 25, 10, 11, 12, 15,   2, 0, 10, 11, 12, 15,  0,  0,  0,  0,   2, 0) // #370
+PAIRING(10, 15, 20, 25, 10, 11, 12, 16,   2, 0, 10, 11, 12, 15,  0,  0,  0,  0,   2, 1) // #371
+PAIRING(10, 15, 20, 25, 10, 11, 12, 20,   2, 0, 10, 11, 12, 15,  0,  0,  0,  0,   2, 0) // #372
+PAIRING(10, 15, 20, 25, 10, 11, 12, 21,   2, 1, 10, 11, 12, 15, 20, 21,  0,  0,   2, 1) // #373
+PAIRING(10, 15, 20, 25, 10, 11, 12, 25,   2, 1, 10, 11, 12, 15, 20, 25,  0,  0,   1, 1) // #374
+PAIRING(10, 15, 20, 25, 10, 11, 12, 26,   2, 1, 10, 11, 12, 15, 20, 25,  0,  0,   1, 1) // #375
+PAIRING(10, 15, 20, 25, 10, 11, 15, 16,   1, 0, 10, 11,  0,  0,  0,  0,  0,  0,   2, 1) // #376
+PAIRING(10, 15, 20, 25, 10, 11, 15, 20,   1, 0, 10, 11,  0,  0,  0,  0,  0,  0,   2, 1) // #377
+PAIRING(10, 15, 20, 25, 10, 11, 15, 21,   1, 1, 10, 11,  0,  0, 20, 21,  0,  0,   2, 1) // #378
+PAIRING(10, 15, 20, 25, 10, 11, 15, 25,   1, 1, 10, 11,  0,  0, 20, 25,  0,  0,   1, 1) // #379
+PAIRING(10, 15, 20, 25, 10, 11, 15, 26,   1, 1, 10, 11,  0,  0, 20, 25,  0,  0,   1, 1) // #380
+PAIRING(10, 15, 20, 25, 10, 11, 16, 17,   1, 0, 10, 11,  0,  0,  0,  0,  0,  0,   2, 1) // #381
+PAIRING(10, 15, 20, 25, 10, 11, 16, 20,   1, 0, 10, 11,  0,  0,  0,  0,  0,  0,   2, 1) // #382
+PAIRING(10, 15, 20, 25, 10, 11, 16, 21,   1, 1, 10, 11,  0,  0, 20, 21,  0,  0,   2, 1) // #383
+PAIRING(10, 15, 20, 25, 10, 11, 16, 25,   1, 1, 10, 11,  0,  0, 20, 25,  0,  0,   1, 1) // #384
+PAIRING(10, 15, 20, 25, 10, 11, 16, 26,   1, 1, 10, 11,  0,  0, 20, 25,  0,  0,   1, 1) // #385
+PAIRING(10, 15, 20, 25, 10, 11, 20, 21,   1, 1, 10, 11,  0,  0, 20, 21,  0,  0,   2, 0) // #386
+PAIRING(10, 15, 20, 25, 10, 11, 20, 25,   1, 1, 10, 11,  0,  0, 20, 25,  0,  0,   1, 0) // #387
+PAIRING(10, 15, 20, 25, 10, 11, 20, 26,   1, 1, 10, 11,  0,  0, 20, 25,  0,  0,   1, 1) // #388
+PAIRING(10, 15, 20, 25, 10, 11, 21, 22,   1, 1, 10, 11,  0,  0, 21, 22,  0,  0,   2, 0) // #389
+PAIRING(10, 15, 20, 25, 10, 11, 21, 25,   1, 1, 10, 11,  0,  0, 21, 25,  0,  0,   2, 0) // #390
+PAIRING(10, 15, 20, 25, 10, 11, 21, 26,   1, 1, 10, 11,  0,  0, 21, 25,  0,  0,   2, 1) // #391
+PAIRING(10, 15, 20, 25, 10, 11, 25, 26,   1, 0, 10, 11,  0,  0,  0,  0,  0,  0,   2, 1) // #392
+PAIRING(10, 15, 20, 25, 10, 11, 26, 27,   1, 0, 10, 11,  0,  0,  0,  0,  0,  0,   2, 1) // #393
+PAIRING(10, 15, 20, 25, 10, 15, 15, 16,   1, 0, 10, 15,  0,  0,  0,  0,  0,  0,   1, 1) // #394
+PAIRING(10, 15, 20, 25, 10, 15, 15, 20,   1, 0, 10, 15,  0,  0,  0,  0,  0,  0,   1, 1) // #395
+PAIRING(10, 15, 20, 25, 10, 15, 15, 21,   1, 1, 10, 15,  0,  0, 20, 21,  0,  0,   1, 1) // #396
+PAIRING(10, 15, 20, 25, 10, 15, 15, 25,   1, 1, 10, 15,  0,  0, 20, 25,  0,  0,   0, 1) // #397
+PAIRING(10, 15, 20, 25, 10, 15, 15, 26,   1, 1, 10, 15,  0,  0, 20, 25,  0,  0,   0, 1) // #398
+PAIRING(10, 15, 20, 25, 10, 15, 16, 17,   1, 0, 10, 15,  0,  0,  0,  0,  0,  0,   1, 1) // #399
+PAIRING(10, 15, 20, 25, 10, 15, 16, 20,   1, 0, 10, 15,  0,  0,  0,  0,  0,  0,   1, 1) // #400
+PAIRING(10, 15, 20, 25, 10, 15, 16, 21,   1, 1, 10, 15,  0,  0, 20, 21,  0,  0,   1, 1) // #401
+PAIRING(10, 15, 20, 25, 10, 15, 16, 25,   1, 1, 10, 15,  0,  0, 20, 25,  0,  0,   0, 1) // #402
+PAIRING(10, 15, 20, 25, 10, 15, 16, 26,   1, 1, 10, 15,  0,  0, 20, 25,  0,  0,   0, 1) // #403
+PAIRING(10, 15, 20, 25, 10, 15, 20, 21,   1, 1, 10, 15,  0,  0, 20, 21,  0,  0,   1, 0) // #404
+PAIRING(10, 15, 20, 25, 10, 15, 20, 25,   1, 1, 10, 15,  0,  0, 20, 25,  0,  0,   0, 0) // #405
+PAIRING(10, 15, 20, 25, 10, 15, 20, 26,   1, 1, 10, 15,  0,  0, 20, 25,  0,  0,   0, 1) // #406
+PAIRING(10, 15, 20, 25, 10, 15, 21, 22,   1, 1, 10, 15,  0,  0, 21, 22,  0,  0,   1, 0) // #407
+PAIRING(10, 15, 20, 25, 10, 15, 21, 25,   1, 1, 10, 15,  0,  0, 21, 25,  0,  0,   1, 0) // #408
+PAIRING(10, 15, 20, 25, 10, 15, 21, 26,   1, 1, 10, 15,  0,  0, 21, 25,  0,  0,   1, 1) // #409
+PAIRING(10, 15, 20, 25, 10, 15, 25, 26,   1, 0, 10, 15,  0,  0,  0,  0,  0,  0,   1, 1) // #410
+PAIRING(10, 15, 20, 25, 10, 15, 26, 27,   1, 0, 10, 15,  0,  0,  0,  0,  0,  0,   1, 1) // #411
+PAIRING(10, 15, 20, 25, 10, 16, 16, 17,   1, 0, 10, 15,  0,  0,  0,  0,  0,  0,   1, 2) // #412
+PAIRING(10, 15, 20, 25, 10, 16, 16, 20,   1, 0, 10, 15,  0,  0,  0,  0,  0,  0,   1, 2) // #413
+PAIRING(10, 15, 20, 25, 10, 16, 16, 21,   1, 1, 10, 15,  0,  0, 20, 21,  0,  0,   1, 2) // #414
+PAIRING(10, 15, 20, 25, 10, 16, 16, 25,   1, 1, 10, 15,  0,  0, 20, 25,  0,  0,   0, 2) // #415
+PAIRING(10, 15, 20, 25, 10, 16, 16, 26,   1, 1, 10, 15,  0,  0, 20, 25,  0,  0,   0, 2) // #416
+PAIRING(10, 15, 20, 25, 10, 16, 17, 18,   1, 0, 10, 15,  0,  0,  0,  0,  0,  0,   1, 2) // #417
+PAIRING(10, 15, 20, 25, 10, 16, 17, 20,   1, 0, 10, 15,  0,  0,  0,  0,  0,  0,   1, 2) // #418
+PAIRING(10, 15, 20, 25, 10, 16, 17, 21,   1, 1, 10, 15,  0,  0, 20, 21,  0,  0,   1, 2) // #419
+PAIRING(10, 15, 20, 25, 10, 16, 17, 25,   1, 1, 10, 15,  0,  0, 20, 25,  0,  0,   0, 2) // #420
+PAIRING(10, 15, 20, 25, 10, 16, 17, 26,   1, 1, 10, 15,  0,  0, 20, 25,  0,  0,   0, 2) // #421
+PAIRING(10, 15, 20, 25, 10, 16, 20, 21,   1, 1, 10, 15,  0,  0, 20, 21,  0,  0,   1, 1) // #422
+PAIRING(10, 15, 20, 25, 10, 16, 20, 25,   1, 1, 10, 15,  0,  0, 20, 25,  0,  0,   0, 1) // #423
+PAIRING(10, 15, 20, 25, 10, 16, 20, 26,   1, 1, 10, 15,  0,  0, 20, 25,  0,  0,   0, 2) // #424
+PAIRING(10, 15, 20, 25, 10, 16, 21, 22,   1, 1, 10, 15,  0,  0, 21, 22,  0,  0,   1, 1) // #425
+PAIRING(10, 15, 20, 25, 10, 16, 21, 25,   1, 1, 10, 15,  0,  0, 21, 25,  0,  0,   1, 1) // #426
+PAIRING(10, 15, 20, 25, 10, 16, 21, 26,   1, 1, 10, 15,  0,  0, 21, 25,  0,  0,   1, 2) // #427
+PAIRING(10, 15, 20, 25, 10, 16, 25, 26,   1, 0, 10, 15,  0,  0,  0,  0,  0,  0,   1, 2) // #428
+PAIRING(10, 15, 20, 25, 10, 16, 26, 27,   1, 0, 10, 15,  0,  0,  0,  0,  0,  0,   1, 2) // #429
+PAIRING(10, 15, 20, 25, 10, 20, 20, 21,   1, 1, 10, 15,  0,  0, 20, 21,  0,  0,   1, 0) // #430
+PAIRING(10, 15, 20, 25, 10, 20, 20, 25,   1, 1, 10, 15,  0,  0, 20, 25,  0,  0,   0, 0) // #431
+PAIRING(10, 15, 20, 25, 10, 20, 20, 26,   1, 1, 10, 15,  0,  0, 20, 25,  0,  0,   0, 1) // #432
+PAIRING(10, 15, 20, 25, 10, 20, 21, 22,   1, 1, 10, 15,  0,  0, 21, 22,  0,  0,   1, 0) // #433
+PAIRING(10, 15, 20, 25, 10, 20, 21, 25,   1, 1, 10, 15,  0,  0, 21, 25,  0,  0,   1, 0) // #434
+PAIRING(10, 15, 20, 25, 10, 20, 21, 26,   1, 1, 10, 15,  0,  0, 21, 25,  0,  0,   1, 1) // #435
+PAIRING(10, 15, 20, 25, 10, 20, 25, 26,   1, 0, 10, 15,  0,  0,  0,  0,  0,  0,   1, 1) // #436
+PAIRING(10, 15, 20, 25, 10, 20, 26, 27,   1, 0, 10, 15,  0,  0,  0,  0,  0,  0,   1, 1) // #437
+PAIRING(10, 15, 20, 25, 10, 21, 21, 22,   1, 2, 10, 15,  0,  0, 20, 21, 21, 22,   1, 1) // #438
+PAIRING(10, 15, 20, 25, 10, 21, 21, 25,   1, 2, 10, 15,  0,  0, 20, 21, 21, 25,   0, 1) // #439
+PAIRING(10, 15, 20, 25, 10, 21, 21, 26,   1, 2, 10, 15,  0,  0, 20, 21, 21, 25,   0, 2) // #440
+PAIRING(10, 15, 20, 25, 10, 21, 22, 23,   1, 2, 10, 15,  0,  0, 20, 21, 22, 23,   1, 1) // #441
+PAIRING(10, 15, 20, 25, 10, 21, 22, 25,   1, 2, 10, 15,  0,  0, 20, 21, 22, 25,   1, 1) // #442
+PAIRING(10, 15, 20, 25, 10, 21, 22, 26,   1, 2, 10, 15,  0,  0, 20, 21, 22, 25,   1, 2) // #443
+PAIRING(10, 15, 20, 25, 10, 21, 25, 26,   1, 1, 10, 15,  0,  0, 20, 21,  0,  0,   1, 2) // #444
+PAIRING(10, 15, 20, 25, 10, 21, 26, 27,   1, 1, 10, 15,  0,  0, 20, 21,  0,  0,   1, 2) // #445
+PAIRING(10, 15, 20, 25, 10, 25, 25, 26,   1, 1, 10, 15,  0,  0, 20, 25,  0,  0,   0, 2) // #446
+PAIRING(10, 15, 20, 25, 10, 25, 26, 27,   1, 1, 10, 15,  0,  0, 20, 25,  0,  0,   0, 2) // #447
+PAIRING(10, 15, 20, 25, 10, 26, 26, 27,   1, 1, 10, 15,  0,  0, 20, 25,  0,  0,   0, 2) // #448
+PAIRING(10, 15, 20, 25, 10, 26, 27, 28,   1, 1, 10, 15,  0,  0, 20, 25,  0,  0,   0, 2) // #449
+PAIRING(10, 15, 20, 25, 11, 12, 12, 13,   2, 0, 11, 12, 12, 13,  0,  0,  0,  0,   2, 0) // #450
+PAIRING(10, 15, 20, 25, 11, 12, 12, 15,   2, 0, 11, 12, 12, 15,  0,  0,  0,  0,   2, 0) // #451
+PAIRING(10, 15, 20, 25, 11, 12, 12, 16,   2, 0, 11, 12, 12, 15,  0,  0,  0,  0,   2, 1) // #452
+PAIRING(10, 15, 20, 25, 11, 12, 12, 20,   2, 0, 11, 12, 12, 15,  0,  0,  0,  0,   2, 0) // #453
+PAIRING(10, 15, 20, 25, 11, 12, 12, 21,   2, 1, 11, 12, 12, 15, 20, 21,  0,  0,   2, 1) // #454
+PAIRING(10, 15, 20, 25, 11, 12, 12, 25,   2, 1, 11, 12, 12, 15, 20, 25,  0,  0,   1, 1) // #455
+PAIRING(10, 15, 20, 25, 11, 12, 12, 26,   2, 1, 11, 12, 12, 15, 20, 25,  0,  0,   1, 1) // #456
+PAIRING(10, 15, 20, 25, 11, 12, 13, 14,   2, 0, 11, 12, 13, 14,  0,  0,  0,  0,   2, 0) // #457
+PAIRING(10, 15, 20, 25, 11, 12, 13, 15,   2, 0, 11, 12, 13, 15,  0,  0,  0,  0,   2, 0) // #458
+PAIRING(10, 15, 20, 25, 11, 12, 13, 16,   2, 0, 11, 12, 13, 15,  0,  0,  0,  0,   2, 1) // #459
+PAIRING(10, 15, 20, 25, 11, 12, 13, 20,   2, 0, 11, 12, 13, 15,  0,  0,  0,  0,   2, 0) // #460
+PAIRING(10, 15, 20, 25, 11, 12, 13, 21,   2, 1, 11, 12, 13, 15, 20, 21,  0,  0,   2, 1) // #461
+PAIRING(10, 15, 20, 25, 11, 12, 13, 25,   2, 1, 11, 12, 13, 15, 20, 25,  0,  0,   1, 1) // #462
+PAIRING(10, 15, 20, 25, 11, 12, 13, 26,   2, 1, 11, 12, 13, 15, 20, 25,  0,  0,   1, 1) // #463
+PAIRING(10, 15, 20, 25, 11, 12, 15, 16,   1, 0, 11, 12,  0,  0,  0,  0,  0,  0,   2, 1) // #464
+PAIRING(10, 15, 20, 25, 11, 12, 15, 20,   1, 0, 11, 12,  0,  0,  0,  0,  0,  0,   2, 1) // #465
+PAIRING(10, 15, 20, 25, 11, 12, 15, 21,   1, 1, 11, 12,  0,  0, 20, 21,  0,  0,   2, 1) // #466
+PAIRING(10, 15, 20, 25, 11, 12, 15, 25,   1, 1, 11, 12,  0,  0, 20, 25,  0,  0,   1, 1) // #467
+PAIRING(10, 15, 20, 25, 11, 12, 15, 26,   1, 1, 11, 12,  0,  0, 20, 25,  0,  0,   1, 1) // #468
+PAIRING(10, 15, 20, 25, 11, 12, 16, 17,   1, 0, 11, 12,  0,  0,  0,  0,  0,  0,   2, 1) // #469
+PAIRING(10, 15, 20, 25, 11, 12, 16, 20,   1, 0, 11, 12,  0,  0,  0,  0,  0,  0,   2, 1) // #470
+PAIRING(10, 15, 20, 25, 11, 12, 16, 21,   1, 1, 11, 12,  0,  0, 20, 21,  0,  0,   2, 1) // #471
+PAIRING(10, 15, 20, 25, 11, 12, 16, 25,   1, 1, 11, 12,  0,  0, 20, 25,  0,  0,   1, 1) // #472
+PAIRING(10, 15, 20, 25, 11, 12, 16, 26,   1, 1, 11, 12,  0,  0, 20, 25,  0,  0,   1, 1) // #473
+PAIRING(10, 15, 20, 25, 11, 12, 20, 21,   1, 1, 11, 12,  0,  0, 20, 21,  0,  0,   2, 0) // #474
+PAIRING(10, 15, 20, 25, 11, 12, 20, 25,   1, 1, 11, 12,  0,  0, 20, 25,  0,  0,   1, 0) // #475
+PAIRING(10, 15, 20, 25, 11, 12, 20, 26,   1, 1, 11, 12,  0,  0, 20, 25,  0,  0,   1, 1) // #476
+PAIRING(10, 15, 20, 25, 11, 12, 21, 22,   1, 1, 11, 12,  0,  0, 21, 22,  0,  0,   2, 0) // #477
+PAIRING(10, 15, 20, 25, 11, 12, 21, 25,   1, 1, 11, 12,  0,  0, 21, 25,  0,  0,   2, 0) // #478
+PAIRING(10, 15, 20, 25, 11, 12, 21, 26,   1, 1, 11, 12,  0,  0, 21, 25,  0,  0,   2, 1) // #479
+PAIRING(10, 15, 20, 25, 11, 12, 25, 26,   1, 0, 11, 12,  0,  0,  0,  0,  0,  0,   2, 1) // #480
+PAIRING(10, 15, 20, 25, 11, 12, 26, 27,   1, 0, 11, 12,  0,  0,  0,  0,  0,  0,   2, 1) // #481
+PAIRING(10, 15, 20, 25, 11, 15, 15, 16,   1, 0, 11, 15,  0,  0,  0,  0,  0,  0,   2, 1) // #482
+PAIRING(10, 15, 20, 25, 11, 15, 15, 20,   1, 0, 11, 15,  0,  0,  0,  0,  0,  0,   2, 1) // #483
+PAIRING(10, 15, 20, 25, 11, 15, 15, 21,   1, 1, 11, 15,  0,  0, 20, 21,  0,  0,   2, 1) // #484
+PAIRING(10, 15, 20, 25, 11, 15, 15, 25,   1, 1, 11, 15,  0,  0, 20, 25,  0,  0,   1, 1) // #485
+PAIRING(10, 15, 20, 25, 11, 15, 15, 26,   1, 1, 11, 15,  0,  0, 20, 25,  0,  0,   1, 1) // #486
+PAIRING(10, 15, 20, 25, 11, 15, 16, 17,   1, 0, 11, 15,  0,  0,  0,  0,  0,  0,   2, 1) // #487
+PAIRING(10, 15, 20, 25, 11, 15, 16, 20,   1, 0, 11, 15,  0,  0,  0,  0,  0,  0,   2, 1) // #488
+PAIRING(10, 15, 20, 25, 11, 15, 16, 21,   1, 1, 11, 15,  0,  0, 20, 21,  0,  0,   2, 1) // #489
+PAIRING(10, 15, 20, 25, 11, 15, 16, 25,   1, 1, 11, 15,  0,  0, 20, 25,  0,  0,   1, 1) // #490
+PAIRING(10, 15, 20, 25, 11, 15, 16, 26,   1, 1, 11, 15,  0,  0, 20, 25,  0,  0,   1, 1) // #491
+PAIRING(10, 15, 20, 25, 11, 15, 20, 21,   1, 1, 11, 15,  0,  0, 20, 21,  0,  0,   2, 0) // #492
+PAIRING(10, 15, 20, 25, 11, 15, 20, 25,   1, 1, 11, 15,  0,  0, 20, 25,  0,  0,   1, 0) // #493
+PAIRING(10, 15, 20, 25, 11, 15, 20, 26,   1, 1, 11, 15,  0,  0, 20, 25,  0,  0,   1, 1) // #494
+PAIRING(10, 15, 20, 25, 11, 15, 21, 22,   1, 1, 11, 15,  0,  0, 21, 22,  0,  0,   2, 0) // #495
+PAIRING(10, 15, 20, 25, 11, 15, 21, 25,   1, 1, 11, 15,  0,  0, 21, 25,  0,  0,   2, 0) // #496
+PAIRING(10, 15, 20, 25, 11, 15, 21, 26,   1, 1, 11, 15,  0,  0, 21, 25,  0,  0,   2, 1) // #497
+PAIRING(10, 15, 20, 25, 11, 15, 25, 26,   1, 0, 11, 15,  0,  0,  0,  0,  0,  0,   2, 1) // #498
+PAIRING(10, 15, 20, 25, 11, 15, 26, 27,   1, 0, 11, 15,  0,  0,  0,  0,  0,  0,   2, 1) // #499
+PAIRING(10, 15, 20, 25, 11, 16, 16, 17,   1, 0, 11, 15,  0,  0,  0,  0,  0,  0,   2, 2) // #500
+PAIRING(10, 15, 20, 25, 11, 16, 16, 20,   1, 0, 11, 15,  0,  0,  0,  0,  0,  0,   2, 2) // #501
+PAIRING(10, 15, 20, 25, 11, 16, 16, 21,   1, 1, 11, 15,  0,  0, 20, 21,  0,  0,   2, 2) // #502
+PAIRING(10, 15, 20, 25, 11, 16, 16, 25,   1, 1, 11, 15,  0,  0, 20, 25,  0,  0,   1, 2) // #503
+PAIRING(10, 15, 20, 25, 11, 16, 16, 26,   1, 1, 11, 15,  0,  0, 20, 25,  0,  0,   1, 2) // #504
+PAIRING(10, 15, 20, 25, 11, 16, 17, 18,   1, 0, 11, 15,  0,  0,  0,  0,  0,  0,   2, 2) // #505
+PAIRING(10, 15, 20, 25, 11, 16, 17, 20,   1, 0, 11, 15,  0,  0,  0,  0,  0,  0,   2, 2) // #506
+PAIRING(10, 15, 20, 25, 11, 16, 17, 21,   1, 1, 11, 15,  0,  0, 20, 21,  0,  0,   2, 2) // #507
+PAIRING(10, 15, 20, 25, 11, 16, 17, 25,   1, 1, 11, 15,  0,  0, 20, 25,  0,  0,   1, 2) // #508
+PAIRING(10, 15, 20, 25, 11, 16, 17, 26,   1, 1, 11, 15,  0,  0, 20, 25,  0,  0,   1, 2) // #509
+PAIRING(10, 15, 20, 25, 11, 16, 20, 21,   1, 1, 11, 15,  0,  0, 20, 21,  0,  0,   2, 1) // #510
+PAIRING(10, 15, 20, 25, 11, 16, 20, 25,   1, 1, 11, 15,  0,  0, 20, 25,  0,  0,   1, 1) // #511
+PAIRING(10, 15, 20, 25, 11, 16, 20, 26,   1, 1, 11, 15,  0,  0, 20, 25,  0,  0,   1, 2) // #512
+PAIRING(10, 15, 20, 25, 11, 16, 21, 22,   1, 1, 11, 15,  0,  0, 21, 22,  0,  0,   2, 1) // #513
+PAIRING(10, 15, 20, 25, 11, 16, 21, 25,   1, 1, 11, 15,  0,  0, 21, 25,  0,  0,   2, 1) // #514
+PAIRING(10, 15, 20, 25, 11, 16, 21, 26,   1, 1, 11, 15,  0,  0, 21, 25,  0,  0,   2, 2) // #515
+PAIRING(10, 15, 20, 25, 11, 16, 25, 26,   1, 0, 11, 15,  0,  0,  0,  0,  0,  0,   2, 2) // #516
+PAIRING(10, 15, 20, 25, 11, 16, 26, 27,   1, 0, 11, 15,  0,  0,  0,  0,  0,  0,   2, 2) // #517
+PAIRING(10, 15, 20, 25, 11, 20, 20, 21,   1, 1, 11, 15,  0,  0, 20, 21,  0,  0,   2, 0) // #518
+PAIRING(10, 15, 20, 25, 11, 20, 20, 25,   1, 1, 11, 15,  0,  0, 20, 25,  0,  0,   1, 0) // #519
+PAIRING(10, 15, 20, 25, 11, 20, 20, 26,   1, 1, 11, 15,  0,  0, 20, 25,  0,  0,   1, 1) // #520
+PAIRING(10, 15, 20, 25, 11, 20, 21, 22,   1, 1, 11, 15,  0,  0, 21, 22,  0,  0,   2, 0) // #521
+PAIRING(10, 15, 20, 25, 11, 20, 21, 25,   1, 1, 11, 15,  0,  0, 21, 25,  0,  0,   2, 0) // #522
+PAIRING(10, 15, 20, 25, 11, 20, 21, 26,   1, 1, 11, 15,  0,  0, 21, 25,  0,  0,   2, 1) // #523
+PAIRING(10, 15, 20, 25, 11, 20, 25, 26,   1, 0, 11, 15,  0,  0,  0,  0,  0,  0,   2, 1) // #524
+PAIRING(10, 15, 20, 25, 11, 20, 26, 27,   1, 0, 11, 15,  0,  0,  0,  0,  0,  0,   2, 1) // #525
+PAIRING(10, 15, 20, 25, 11, 21, 21, 22,   1, 2, 11, 15,  0,  0, 20, 21, 21, 22,   2, 1) // #526
+PAIRING(10, 15, 20, 25, 11, 21, 21, 25,   1, 2, 11, 15,  0,  0, 20, 21, 21, 25,   1, 1) // #527
+PAIRING(10, 15, 20, 25, 11, 21, 21, 26,   1, 2, 11, 15,  0,  0, 20, 21, 21, 25,   1, 2) // #528
+PAIRING(10, 15, 20, 25, 11, 21, 22, 23,   1, 2, 11, 15,  0,  0, 20, 21, 22, 23,   2, 1) // #529
+PAIRING(10, 15, 20, 25, 11, 21, 22, 25,   1, 2, 11, 15,  0,  0, 20, 21, 22, 25,   2, 1) // #530
+PAIRING(10, 15, 20, 25, 11, 21, 22, 26,   1, 2, 11, 15,  0,  0, 20, 21, 22, 25,   2, 2) // #531
+PAIRING(10, 15, 20, 25, 11, 21, 25, 26,   1, 1, 11, 15,  0,  0, 20, 21,  0,  0,   2, 2) // #532
+PAIRING(10, 15, 20, 25, 11, 21, 26, 27,   1, 1, 11, 15,  0,  0, 20, 21,  0,  0,   2, 2) // #533
+PAIRING(10, 15, 20, 25, 11, 25, 25, 26,   1, 1, 11, 15,  0,  0, 20, 25,  0,  0,   1, 2) // #534
+PAIRING(10, 15, 20, 25, 11, 25, 26, 27,   1, 1, 11, 15,  0,  0, 20, 25,  0,  0,   1, 2) // #535
+PAIRING(10, 15, 20, 25, 11, 26, 26, 27,   1, 1, 11, 15,  0,  0, 20, 25,  0,  0,   1, 2) // #536
+PAIRING(10, 15, 20, 25, 11, 26, 27, 28,   1, 1, 11, 15,  0,  0, 20, 25,  0,  0,   1, 2) // #537
+PAIRING(10, 15, 20, 25, 15, 16, 16, 17,   0, 0,  0,  0,  0,  0,  0,  0,  0,  0,   2, 2) // #538
+PAIRING(10, 15, 20, 25, 15, 16, 16, 20,   0, 0,  0,  0,  0,  0,  0,  0,  0,  0,   2, 2) // #539
+PAIRING(10, 15, 20, 25, 15, 16, 16, 21,   0, 1,  0,  0,  0,  0, 20, 21,  0,  0,   2, 2) // #540
+PAIRING(10, 15, 20, 25, 15, 16, 16, 25,   0, 1,  0,  0,  0,  0, 20, 25,  0,  0,   1, 2) // #541
+PAIRING(10, 15, 20, 25, 15, 16, 16, 26,   0, 1,  0,  0,  0,  0, 20, 25,  0,  0,   1, 2) // #542
+PAIRING(10, 15, 20, 25, 15, 16, 17, 18,   0, 0,  0,  0,  0,  0,  0,  0,  0,  0,   2, 2) // #543
+PAIRING(10, 15, 20, 25, 15, 16, 17, 20,   0, 0,  0,  0,  0,  0,  0,  0,  0,  0,   2, 2) // #544
+PAIRING(10, 15, 20, 25, 15, 16, 17, 21,   0, 1,  0,  0,  0,  0, 20, 21,  0,  0,   2, 2) // #545
+PAIRING(10, 15, 20, 25, 15, 16, 17, 25,   0, 1,  0,  0,  0,  0, 20, 25,  0,  0,   1, 2) // #546
+PAIRING(10, 15, 20, 25, 15, 16, 17, 26,   0, 1,  0,  0,  0,  0, 20, 25,  0,  0,   1, 2) // #547
+PAIRING(10, 15, 20, 25, 15, 16, 20, 21,   0, 1,  0,  0,  0,  0, 20, 21,  0,  0,   2, 1) // #548
+PAIRING(10, 15, 20, 25, 15, 16, 20, 25,   0, 1,  0,  0,  0,  0, 20, 25,  0,  0,   1, 1) // #549
+PAIRING(10, 15, 20, 25, 15, 16, 20, 26,   0, 1,  0,  0,  0,  0, 20, 25,  0,  0,   1, 2) // #550
+PAIRING(10, 15, 20, 25, 15, 16, 21, 22,   0, 1,  0,  0,  0,  0, 21, 22,  0,  0,   2, 1) // #551
+PAIRING(10, 15, 20, 25, 15, 16, 21, 25,   0, 1,  0,  0,  0,  0, 21, 25,  0,  0,   2, 1) // #552
+PAIRING(10, 15, 20, 25, 15, 16, 21, 26,   0, 1,  0,  0,  0,  0, 21, 25,  0,  0,   2, 2) // #553
+PAIRING(10, 15, 20, 25, 15, 16, 25, 26,   0, 0,  0,  0,  0,  0,  0,  0,  0,  0,   2, 2) // #554
+PAIRING(10, 15, 20, 25, 15, 16, 26, 27,   0, 0,  0,  0,  0,  0,  0,  0,  0,  0,   2, 2) // #555
+PAIRING(10, 15, 20, 25, 15, 20, 20, 21,   0, 1,  0,  0,  0,  0, 20, 21,  0,  0,   2, 1) // #556
+PAIRING(10, 15, 20, 25, 15, 20, 20, 25,   0, 1,  0,  0,  0,  0, 20, 25,  0,  0,   1, 1) // #557
+PAIRING(10, 15, 20, 25, 15, 20, 20, 26,   0, 1,  0,  0,  0,  0, 20, 25,  0,  0,   1, 2) // #558
+PAIRING(10, 15, 20, 25, 15, 20, 21, 22,   0, 1,  0,  0,  0,  0, 21, 22,  0,  0,   2, 1) // #559
+PAIRING(10, 15, 20, 25, 15, 20, 21, 25,   0, 1,  0,  0,  0,  0, 21, 25,  0,  0,   2, 1) // #560
+PAIRING(10, 15, 20, 25, 15, 20, 21, 26,   0, 1,  0,  0,  0,  0, 21, 25,  0,  0,   2, 2) // #561
+PAIRING(10, 15, 20, 25, 15, 20, 25, 26,   0, 0,  0,  0,  0,  0,  0,  0,  0,  0,   2, 2) // #562
+PAIRING(10, 15, 20, 25, 15, 20, 26, 27,   0, 0,  0,  0,  0,  0,  0,  0,  0,  0,   2, 2) // #563
+PAIRING(10, 15, 20, 25, 15, 21, 21, 22,   0, 2,  0,  0,  0,  0, 20, 21, 21, 22,   2, 1) // #564
+PAIRING(10, 15, 20, 25, 15, 21, 21, 25,   0, 2,  0,  0,  0,  0, 20, 21, 21, 25,   1, 1) // #565
+PAIRING(10, 15, 20, 25, 15, 21, 21, 26,   0, 2,  0,  0,  0,  0, 20, 21, 21, 25,   1, 2) // #566
+PAIRING(10, 15, 20, 25, 15, 21, 22, 23,   0, 2,  0,  0,  0,  0, 20, 21, 22, 23,   2, 1) // #567
+PAIRING(10, 15, 20, 25, 15, 21, 22, 25,   0, 2,  0,  0,  0,  0, 20, 21, 22, 25,   2, 1) // #568
+PAIRING(10, 15, 20, 25, 15, 21, 22, 26,   0, 2,  0,  0,  0,  0, 20, 21, 22, 25,   2, 2) // #569
+PAIRING(10, 15, 20, 25, 15, 21, 25, 26,   0, 1,  0,  0,  0,  0, 20, 21,  0,  0,   2, 2) // #570
+PAIRING(10, 15, 20, 25, 15, 21, 26, 27,   0, 1,  0,  0,  0,  0, 20, 21,  0,  0,   2, 2) // #571
+PAIRING(10, 15, 20, 25, 15, 25, 25, 26,   0, 1,  0,  0,  0,  0, 20, 25,  0,  0,   1, 2) // #572
+PAIRING(10, 15, 20, 25, 15, 25, 26, 27,   0, 1,  0,  0,  0,  0, 20, 25,  0,  0,   1, 2) // #573
+PAIRING(10, 15, 20, 25, 15, 26, 26, 27,   0, 1,  0,  0,  0,  0, 20, 25,  0,  0,   1, 2) // #574
+PAIRING(10, 15, 20, 25, 15, 26, 27, 28,   0, 1,  0,  0,  0,  0, 20, 25,  0,  0,   1, 2) // #575
+PAIRING(10, 15, 20, 25, 16, 17, 17, 18,   0, 0,  0,  0,  0,  0,  0,  0,  0,  0,   2, 2) // #576
+PAIRING(10, 15, 20, 25, 16, 17, 17, 20,   0, 0,  0,  0,  0,  0,  0,  0,  0,  0,   2, 2) // #577
+PAIRING(10, 15, 20, 25, 16, 17, 17, 21,   0, 1,  0,  0,  0,  0, 20, 21,  0,  0,   2, 2) // #578
+PAIRING(10, 15, 20, 25, 16, 17, 17, 25,   0, 1,  0,  0,  0,  0, 20, 25,  0,  0,   1, 2) // #579
+PAIRING(10, 15, 20, 25, 16, 17, 17, 26,   0, 1,  0,  0,  0,  0, 20, 25,  0,  0,   1, 2) // #580
+PAIRING(10, 15, 20, 25, 16, 17, 18, 19,   0, 0,  0,  0,  0,  0,  0,  0,  0,  0,   2, 2) // #581
+PAIRING(10, 15, 20, 25, 16, 17, 18, 20,   0, 0,  0,  0,  0,  0,  0,  0,  0,  0,   2, 2) // #582
+PAIRING(10, 15, 20, 25, 16, 17, 18, 21,   0, 1,  0,  0,  0,  0, 20, 21,  0,  0,   2, 2) // #583
+PAIRING(10, 15, 20, 25, 16, 17, 18, 25,   0, 1,  0,  0,  0,  0, 20, 25,  0,  0,   1, 2) // #584
+PAIRING(10, 15, 20, 25, 16, 17, 18, 26,   0, 1,  0,  0,  0,  0, 20, 25,  0,  0,   1, 2) // #585
+PAIRING(10, 15, 20, 25, 16, 17, 20, 21,   0, 1,  0,  0,  0,  0, 20, 21,  0,  0,   2, 1) // #586
+PAIRING(10, 15, 20, 25, 16, 17, 20, 25,   0, 1,  0,  0,  0,  0, 20, 25,  0,  0,   1, 1) // #587
+PAIRING(10, 15, 20, 25, 16, 17, 20, 26,   0, 1,  0,  0,  0,  0, 20, 25,  0,  0,   1, 2) // #588
+PAIRING(10, 15, 20, 25, 16, 17, 21, 22,   0, 1,  0,  0,  0,  0, 21, 22,  0,  0,   2, 1) // #589
+PAIRING(10, 15, 20, 25, 16, 17, 21, 25,   0, 1,  0,  0,  0,  0, 21, 25,  0,  0,   2, 1) // #590
+PAIRING(10, 15, 20, 25, 16, 17, 21, 26,   0, 1,  0,  0,  0,  0, 21, 25,  0,  0,   2, 2) // #591
+PAIRING(10, 15, 20, 25, 16, 17, 25, 26,   0, 0,  0,  0,  0,  0,  0,  0,  0,  0,   2, 2) // #592
+PAIRING(10, 15, 20, 25, 16, 17, 26, 27,   0, 0,  0,  0,  0,  0,  0,  0,  0,  0,   2, 2) // #593
+PAIRING(10, 15, 20, 25, 16, 20, 20, 21,   0, 1,  0,  0,  0,  0, 20, 21,  0,  0,   2, 1) // #594
+PAIRING(10, 15, 20, 25, 16, 20, 20, 25,   0, 1,  0,  0,  0,  0, 20, 25,  0,  0,   1, 1) // #595
+PAIRING(10, 15, 20, 25, 16, 20, 20, 26,   0, 1,  0,  0,  0,  0, 20, 25,  0,  0,   1, 2) // #596
+PAIRING(10, 15, 20, 25, 16, 20, 21, 22,   0, 1,  0,  0,  0,  0, 21, 22,  0,  0,   2, 1) // #597
+PAIRING(10, 15, 20, 25, 16, 20, 21, 25,   0, 1,  0,  0,  0,  0, 21, 25,  0,  0,   2, 1) // #598
+PAIRING(10, 15, 20, 25, 16, 20, 21, 26,   0, 1,  0,  0,  0,  0, 21, 25,  0,  0,   2, 2) // #599
+PAIRING(10, 15, 20, 25, 16, 20, 25, 26,   0, 0,  0,  0,  0,  0,  0,  0,  0,  0,   2, 2) // #600
+PAIRING(10, 15, 20, 25, 16, 20, 26, 27,   0, 0,  0,  0,  0,  0,  0,  0,  0,  0,   2, 2) // #601
+PAIRING(10, 15, 20, 25, 16, 21, 21, 22,   0, 2,  0,  0,  0,  0, 20, 21, 21, 22,   2, 1) // #602
+PAIRING(10, 15, 20, 25, 16, 21, 21, 25,   0, 2,  0,  0,  0,  0, 20, 21, 21, 25,   1, 1) // #603
+PAIRING(10, 15, 20, 25, 16, 21, 21, 26,   0, 2,  0,  0,  0,  0, 20, 21, 21, 25,   1, 2) // #604
+PAIRING(10, 15, 20, 25, 16, 21, 22, 23,   0, 2,  0,  0,  0,  0, 20, 21, 22, 23,   2, 1) // #605
+PAIRING(10, 15, 20, 25, 16, 21, 22, 25,   0, 2,  0,  0,  0,  0, 20, 21, 22, 25,   2, 1) // #606
+PAIRING(10, 15, 20, 25, 16, 21, 22, 26,   0, 2,  0,  0,  0,  0, 20, 21, 22, 25,   2, 2) // #607
+PAIRING(10, 15, 20, 25, 16, 21, 25, 26,   0, 1,  0,  0,  0,  0, 20, 21,  0,  0,   2, 2) // #608
+PAIRING(10, 15, 20, 25, 16, 21, 26, 27,   0, 1,  0,  0,  0,  0, 20, 21,  0,  0,   2, 2) // #609
+PAIRING(10, 15, 20, 25, 16, 25, 25, 26,   0, 1,  0,  0,  0,  0, 20, 25,  0,  0,   1, 2) // #610
+PAIRING(10, 15, 20, 25, 16, 25, 26, 27,   0, 1,  0,  0,  0,  0, 20, 25,  0,  0,   1, 2) // #611
+PAIRING(10, 15, 20, 25, 16, 26, 26, 27,   0, 1,  0,  0,  0,  0, 20, 25,  0,  0,   1, 2) // #612
+PAIRING(10, 15, 20, 25, 16, 26, 27, 28,   0, 1,  0,  0,  0,  0, 20, 25,  0,  0,   1, 2) // #613
+PAIRING(10, 15, 20, 25, 20, 21, 21, 22,   0, 2,  0,  0,  0,  0, 20, 21, 21, 22,   2, 0) // #614
+PAIRING(10, 15, 20, 25, 20, 21, 21, 25,   0, 2,  0,  0,  0,  0, 20, 21, 21, 25,   1, 0) // #615
+PAIRING(10, 15, 20, 25, 20, 21, 21, 26,   0, 2,  0,  0,  0,  0, 20, 21, 21, 25,   1, 1) // #616
+PAIRING(10, 15, 20, 25, 20, 21, 22, 23,   0, 2,  0,  0,  0,  0, 20, 21, 22, 23,   2, 0) // #617
+PAIRING(10, 15, 20, 25, 20, 21, 22, 25,   0, 2,  0,  0,  0,  0, 20, 21, 22, 25,   2, 0) // #618
+PAIRING(10, 15, 20, 25, 20, 21, 22, 26,   0, 2,  0,  0,  0,  0, 20, 21, 22, 25,   2, 1) // #619
+PAIRING(10, 15, 20, 25, 20, 21, 25, 26,   0, 1,  0,  0,  0,  0, 20, 21,  0,  0,   2, 1) // #620
+PAIRING(10, 15, 20, 25, 20, 21, 26, 27,   0, 1,  0,  0,  0,  0, 20, 21,  0,  0,   2, 1) // #621
+PAIRING(10, 15, 20, 25, 20, 25, 25, 26,   0, 1,  0,  0,  0,  0, 20, 25,  0,  0,   1, 1) // #622
+PAIRING(10, 15, 20, 25, 20, 25, 26, 27,   0, 1,  0,  0,  0,  0, 20, 25,  0,  0,   1, 1) // #623
+PAIRING(10, 15, 20, 25, 20, 26, 26, 27,   0, 1,  0,  0,  0,  0, 20, 25,  0,  0,   1, 2) // #624
+PAIRING(10, 15, 20, 25, 20, 26, 27, 28,   0, 1,  0,  0,  0,  0, 20, 25,  0,  0,   1, 2) // #625
+PAIRING(10, 15, 20, 25, 21, 22, 22, 23,   0, 2,  0,  0,  0,  0, 21, 22, 22, 23,   2, 0) // #626
+PAIRING(10, 15, 20, 25, 21, 22, 22, 25,   0, 2,  0,  0,  0,  0, 21, 22, 22, 25,   2, 0) // #627
+PAIRING(10, 15, 20, 25, 21, 22, 22, 26,   0, 2,  0,  0,  0,  0, 21, 22, 22, 25,   2, 1) // #628
+PAIRING(10, 15, 20, 25, 21, 22, 23, 24,   0, 2,  0,  0,  0,  0, 21, 22, 23, 24,   2, 0) // #629
+PAIRING(10, 15, 20, 25, 21, 22, 23, 25,   0, 2,  0,  0,  0,  0, 21, 22, 23, 25,   2, 0) // #630
+PAIRING(10, 15, 20, 25, 21, 22, 23, 26,   0, 2,  0,  0,  0,  0, 21, 22, 23, 25,   2, 1) // #631
+PAIRING(10, 15, 20, 25, 21, 22, 25, 26,   0, 1,  0,  0,  0,  0, 21, 22,  0,  0,   2, 1) // #632
+PAIRING(10, 15, 20, 25, 21, 22, 26, 27,   0, 1,  0,  0,  0,  0, 21, 22,  0,  0,   2, 1) // #633
+PAIRING(10, 15, 20, 25, 21, 25, 25, 26,   0, 1,  0,  0,  0,  0, 21, 25,  0,  0,   2, 1) // #634
+PAIRING(10, 15, 20, 25, 21, 25, 26, 27,   0, 1,  0,  0,  0,  0, 21, 25,  0,  0,   2, 1) // #635
+PAIRING(10, 15, 20, 25, 21, 26, 26, 27,   0, 1,  0,  0,  0,  0, 21, 25,  0,  0,   2, 2) // #636
+PAIRING(10, 15, 20, 25, 21, 26, 27, 28,   0, 1,  0,  0,  0,  0, 21, 25,  0,  0,   2, 2) // #637
+PAIRING(10, 15, 20, 25, 25, 26, 26, 27,   0, 0,  0,  0,  0,  0,  0,  0,  0,  0,   2, 2) // #638
+PAIRING(10, 15, 20, 25, 25, 26, 27, 28,   0, 0,  0,  0,  0,  0,  0,  0,  0,  0,   2, 2) // #639
+PAIRING(10, 15, 20, 25, 26, 27, 27, 28,   0, 0,  0,  0,  0,  0,  0,  0,  0,  0,   2, 2) // #640
+PAIRING(10, 15, 20, 25, 26, 27, 28, 29,   0, 0,  0,  0,  0,  0,  0,  0,  0,  0,   2, 2) // #641
diff --git a/include/breakpad/common/tests/auto_tempdir.h b/include/breakpad/common/tests/auto_tempdir.h
new file mode 100644
index 0000000..1df88db
--- /dev/null
+++ b/include/breakpad/common/tests/auto_tempdir.h
@@ -0,0 +1,100 @@
+// 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.
+
+// Utility class for creating a temporary directory for unit tests
+// that is deleted in the destructor.
+#ifndef GOOGLE_BREAKPAD_COMMON_TESTS_AUTO_TEMPDIR
+#define GOOGLE_BREAKPAD_COMMON_TESTS_AUTO_TEMPDIR
+
+#include <dirent.h>
+#include <sys/types.h>
+
+#include <string>
+
+#include "breakpad_googletest_includes.h"
+#include "common/using_std_string.h"
+
+#if !defined(__ANDROID__)
+#define TEMPDIR "/tmp"
+#else
+#define TEMPDIR "/data/local/tmp"
+#include "common/android/testing/mkdtemp.h"
+#endif
+
+namespace google_breakpad {
+
+class AutoTempDir {
+ public:
+  AutoTempDir() {
+    char temp_dir[] = TEMPDIR "/breakpad.XXXXXX";
+    EXPECT_TRUE(mkdtemp(temp_dir) != NULL);
+    path_.assign(temp_dir);
+  }
+
+  ~AutoTempDir() {
+    DeleteRecursively(path_);
+  }
+
+  const string& path() const {
+    return path_;
+  }
+
+ private:
+  void DeleteRecursively(const string& path) {
+    // First remove any files in the dir
+    DIR* dir = opendir(path.c_str());
+    if (!dir)
+      return;
+
+    dirent* entry;
+    while ((entry = readdir(dir)) != NULL) {
+      if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)
+        continue;
+      string entry_path = path + "/" + entry->d_name;
+      struct stat stats;
+      EXPECT_TRUE(lstat(entry_path.c_str(), &stats) == 0);
+      if (S_ISDIR(stats.st_mode))
+        DeleteRecursively(entry_path);
+      else
+        EXPECT_TRUE(unlink(entry_path.c_str()) == 0);
+    }
+    EXPECT_TRUE(closedir(dir) == 0);
+    EXPECT_TRUE(rmdir(path.c_str()) == 0);
+  }
+
+  // prevent copy construction and assignment
+  AutoTempDir(const AutoTempDir&);
+  AutoTempDir& operator=(const AutoTempDir&);
+
+  string path_;
+};
+
+}  // namespace google_breakpad
+
+#endif  // GOOGLE_BREAKPAD_COMMON_TESTS_AUTO_TEMPDIR
diff --git a/include/breakpad/common/tests/file_utils.h b/include/breakpad/common/tests/file_utils.h
new file mode 100644
index 0000000..c98a9bf
--- /dev/null
+++ b/include/breakpad/common/tests/file_utils.h
@@ -0,0 +1,52 @@
+// 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.
+
+// file_utils.h: Define utility functions for file manipulation, which
+// are used for testing.
+
+#ifndef COMMON_TESTS_FILE_UTILS_H_
+#define COMMON_TESTS_FILE_UTILS_H_
+
+namespace google_breakpad {
+
+// Copies a file from |from_path| to |to_path|. Returns true on success.
+bool CopyFile(const char* from_path, const char* to_path);
+
+// Reads the content of a file at |path| into |buffer|. |buffer_size| specifies
+// the size of |buffer| in bytes and returns the number of bytes read from the
+// file on success. Returns true on success.
+bool ReadFile(const char* path, void* buffer, ssize_t* buffer_size);
+
+// Writes |buffer_size| bytes of the content in |buffer| to a file at |path|.
+// Returns true on success.
+bool WriteFile(const char* path, const void* buffer, size_t buffer_size);
+
+}  // namespace google_breakpad
+
+#endif  // COMMON_TESTS_FILE_UTILS_H_
diff --git a/include/breakpad/common/windows/dia_util.h b/include/breakpad/common/windows/dia_util.h
new file mode 100644
index 0000000..b9e0df2
--- /dev/null
+++ b/include/breakpad/common/windows/dia_util.h
@@ -0,0 +1,64 @@
+// Copyright 2013 Google Inc. All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Utilities for loading debug streams and tables from a PDB file.
+
+#ifndef COMMON_WINDOWS_DIA_UTIL_H_
+#define COMMON_WINDOWS_DIA_UTIL_H_
+
+#include <Windows.h>
+#include <dia2.h>
+
+namespace google_breakpad {
+
+// Find the debug stream of the given |name| in the given |session|. Returns
+// true on success, false on error of if the stream does not exist. On success
+// the stream will be returned via |debug_stream|.
+bool FindDebugStream(const wchar_t* name,
+                     IDiaSession* session,
+                     IDiaEnumDebugStreamData** debug_stream);
+
+// Finds the first table implementing the COM interface with ID |iid| in the
+// given |session|. Returns true on success, false on error or if no such
+// table is found. On success the table will be returned via |table|.
+bool FindTable(REFIID iid, IDiaSession* session, void** table);
+
+// A templated version of FindTable. Finds the first table implementing type
+// |InterfaceType| in the given |session|. Returns true on success, false on
+// error or if no such table is found. On success the table will be returned via
+// |table|.
+template<typename InterfaceType>
+bool FindTable(IDiaSession* session, InterfaceType** table) {
+  return FindTable(__uuidof(InterfaceType),
+                   session,
+                   reinterpret_cast<void**>(table));
+}
+
+}  // namespace google_breakpad
+
+#endif  // COMMON_WINDOWS_DIA_UTIL_H_
diff --git a/include/breakpad/common/windows/guid_string.h b/include/breakpad/common/windows/guid_string.h
new file mode 100644
index 0000000..48a5c1d
--- /dev/null
+++ b/include/breakpad/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/include/breakpad/common/windows/http_upload.h b/include/breakpad/common/windows/http_upload.h
new file mode 100644
index 0000000..e485b70
--- /dev/null
+++ b/include/breakpad/common/windows/http_upload.h
@@ -0,0 +1,131 @@
+// 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.
+
+// HTTPUpload provides a "nice" API to send a multipart HTTP(S) POST
+// request using wininet.  It currently supports requests that contain
+// a set of string parameters (key/value pairs), and a file to upload.
+
+#ifndef COMMON_WINDOWS_HTTP_UPLOAD_H_
+#define COMMON_WINDOWS_HTTP_UPLOAD_H_
+
+#pragma warning(push)
+// Disable exception handler warnings.
+#pragma warning(disable : 4530)
+
+#include <windows.h>
+#include <wininet.h>
+
+#include <map>
+#include <string>
+#include <vector>
+
+namespace google_breakpad {
+
+using std::string;
+using std::wstring;
+using std::map;
+using std::vector;
+
+class HTTPUpload {
+ public:
+  // Sends the given set of parameters, along with the contents of
+  // upload_file, as a multipart POST request to the given URL.
+  // file_part_name contains the name of the file part of the request
+  // (i.e. it corresponds to the name= attribute on an <input type="file">.
+  // Parameter names must contain only printable ASCII characters,
+  // and may not contain a quote (") character.
+  // Only HTTP(S) URLs are currently supported.  Returns true on success.
+  // If the request is successful and response_body is non-NULL,
+  // the response body will be returned in response_body.
+  // If response_code is non-NULL, it will be set to the HTTP response code
+  // received (or 0 if the request failed before getting an HTTP response).
+  static bool SendRequest(const wstring &url,
+                          const map<wstring, wstring> &parameters,
+                          const wstring &upload_file,
+                          const wstring &file_part_name,
+                          int *timeout,
+                          wstring *response_body,
+                          int *response_code);
+
+ private:
+  class AutoInternetHandle;
+
+  // Retrieves the HTTP response.  If NULL is passed in for response,
+  // this merely checks (via the return value) that we were successfully
+  // able to retrieve exactly as many bytes of content in the response as
+  // were specified in the Content-Length header.
+  static bool ReadResponse(HINTERNET request, wstring* response);
+
+  // Generates a new multipart boundary for a POST request
+  static wstring GenerateMultipartBoundary();
+
+  // Generates a HTTP request header for a multipart form submit.
+  static wstring GenerateRequestHeader(const wstring &boundary);
+
+  // Given a set of parameters, an upload filename, and a file part name,
+  // generates a multipart request body string with these parameters
+  // and minidump contents.  Returns true on success.
+  static bool GenerateRequestBody(const map<wstring, wstring> &parameters,
+                                  const wstring &upload_file,
+                                  const wstring &file_part_name,
+                                  const wstring &boundary,
+                                  string *request_body);
+
+  // Fills the supplied vector with the contents of filename.
+  static bool GetFileContents(const wstring &filename, vector<char> *contents);
+
+  // Converts a UTF8 string to UTF16.
+  static wstring UTF8ToWide(const string &utf8);
+
+  // Converts a UTF16 string to UTF8.
+  static string WideToUTF8(const wstring &wide) {
+      return WideToMBCP(wide, CP_UTF8);
+  }
+
+  // Converts a UTF16 string to specified code page.
+  static string WideToMBCP(const wstring &wide, unsigned int cp);
+
+  // Checks that the given list of parameters has only printable
+  // ASCII characters in the parameter name, and does not contain
+  // any quote (") characters.  Returns true if so.
+  static bool CheckParameters(const map<wstring, wstring> &parameters);
+
+  // No instances of this class should be created.
+  // Disallow all constructors, destructors, and operator=.
+  HTTPUpload();
+  explicit HTTPUpload(const HTTPUpload &);
+  void operator=(const HTTPUpload &);
+  ~HTTPUpload();
+};
+
+}  // namespace google_breakpad
+
+#pragma warning(pop)
+
+#endif  // COMMON_WINDOWS_HTTP_UPLOAD_H_
diff --git a/include/breakpad/common/windows/omap.h b/include/breakpad/common/windows/omap.h
new file mode 100644
index 0000000..bc293af
--- /dev/null
+++ b/include/breakpad/common/windows/omap.h
@@ -0,0 +1,72 @@
+// Copyright 2013 Google Inc. All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Provides an API for mapping symbols through OMAP information, if a PDB file
+// is augmented with it. This allows breakpad to work with addresses in
+// transformed images by transforming the symbols themselves, rather than
+// transforming addresses prior to querying symbols (the way it is typically
+// done by Windows-native tools, including the DIA).
+
+#ifndef COMMON_WINDOWS_OMAP_H_
+#define COMMON_WINDOWS_OMAP_H_
+
+#include "common/windows/omap_internal.h"
+
+namespace google_breakpad {
+
+// If the given session contains OMAP data this extracts it, populating
+// |omap_data|, and then disabling automatic translation for the session.
+// OMAP data is present in the PDB if |omap_data| is not empty. This returns
+// true on success, false otherwise.
+bool GetOmapDataAndDisableTranslation(IDiaSession* dia_session,
+                                      OmapData* omap_data);
+
+// Given raw OMAP data builds an ImageMap. This can be used to query individual
+// image ranges using MapAddressRange.
+// |omap_data|| is the OMAP data extracted from the PDB.
+// |image_map| will be populated with a description of the image mapping. If
+//     |omap_data| is empty then this will also be empty.
+void BuildImageMap(const OmapData& omap_data, ImageMap* image_map);
+
+// Given an address range in the original image space determines how exactly it
+// has been tranformed.
+// |omap_data| is the OMAP data extracted from the PDB, which must not be
+//     empty.
+// |original_range| is the address range in the original image being queried.
+// |mapped_ranges| will be populated with a full description of the mapping.
+//     They may be disjoint in the transformed image so a vector is needed to
+//     fully represent the mapping. This will be appended to if it is not
+//     empty. If |omap_data| is empty then |mapped_ranges| will simply be
+//     populated with a copy of |original_range| (the identity transform).
+void MapAddressRange(const ImageMap& image_map,
+                     const AddressRange& original_range,
+                     AddressRangeVector* mapped_ranges);
+
+}  // namespace google_breakpad
+
+#endif  // COMMON_WINDOWS_OMAP_H_
diff --git a/include/breakpad/common/windows/omap_internal.h b/include/breakpad/common/windows/omap_internal.h
new file mode 100644
index 0000000..3f904d7
--- /dev/null
+++ b/include/breakpad/common/windows/omap_internal.h
@@ -0,0 +1,137 @@
+// Copyright 2013 Google Inc. All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Declares internal implementation details for functionality in omap.h and
+// omap.cc.
+
+#ifndef COMMON_WINDOWS_OMAP_INTERNAL_H_
+#define COMMON_WINDOWS_OMAP_INTERNAL_H_
+
+#include <windows.h>
+#include <dia2.h>
+
+#include <vector>
+
+namespace google_breakpad {
+
+// The OMAP struct is defined by debughlp.h, which doesn't play nicely with
+// imagehlp.h. We simply redefine it.
+struct OMAP {
+  DWORD rva;
+  DWORD rvaTo;
+};
+static_assert(sizeof(OMAP) == 8, "Wrong size for OMAP structure.");
+typedef std::vector<OMAP> OmapTable;
+
+// This contains the OMAP data extracted from an image.
+struct OmapData {
+  // The table of OMAP entries describing the transformation from the
+  // original image to the transformed image.
+  OmapTable omap_from;  
+  // The table of OMAP entries describing the transformation from the
+  // instrumented image to the original image.
+  OmapTable omap_to;
+  // The length of the original untransformed image.
+  DWORD length_original;
+
+  OmapData() : length_original(0) { }
+};
+
+// This represents a range of addresses in an image.
+struct AddressRange {
+  DWORD rva;
+  DWORD length;
+
+  AddressRange() : rva(0), length(0) { }
+  AddressRange(DWORD rva, DWORD length) : rva(rva), length(length) { }
+
+  // Returns the end address of this range.
+  DWORD end() const { return rva + length; }
+
+  // Addreses only compare as less-than or greater-than if they are not
+  // overlapping. Otherwise, they compare equal.
+  int Compare(const AddressRange& rhs) const;
+  bool operator<(const AddressRange& rhs) const { return Compare(rhs) == -1; }
+  bool operator>(const AddressRange& rhs) const { return Compare(rhs) == 1; }
+
+  // Equality operators compare exact values.
+  bool operator==(const AddressRange& rhs) const {
+    return rva == rhs.rva && length == rhs.length;
+  }
+  bool operator!=(const  AddressRange& rhs) const { return !((*this) == rhs); }
+};
+
+typedef std::vector<AddressRange> AddressRangeVector;
+
+// This represents an address range in an original image, and its corresponding
+// range in the transformed image.
+struct MappedRange {
+  // An address in the original image.
+  DWORD rva_original;
+  // The corresponding addresses in the transformed image.
+  DWORD rva_transformed;
+  // The length of the address range.
+  DWORD length;
+  // It is possible for code to be injected into a transformed image, for which
+  // there is no corresponding code in the original image. If this range of
+  // transformed image is immediately followed by such injected code we maintain
+  // a record of its length here.
+  DWORD injected;
+  // It is possible for code to be removed from the original image. This happens
+  // for things like padding between blocks. There is no actual content lost,
+  // but the spacing between items may be lost. This keeps track of any removed
+  // content immediately following the |original| range.
+  DWORD removed;
+};
+// A vector of mapped ranges is used as a more useful representation of
+// OMAP data.
+typedef std::vector<MappedRange> Mapping;
+
+// Used as a secondary search structure accompanying a Mapping.
+struct EndpointIndex {
+  DWORD endpoint;
+  size_t index;
+};
+typedef std::vector<EndpointIndex> EndpointIndexMap;
+
+// An ImageMap is vector of mapped ranges, plus a secondary index into it for
+// doing interval searches. (An interval tree would also work, but is overkill
+// because we don't need insertion and deletion.)
+struct ImageMap {
+  // This is a description of the mapping between original and transformed
+  // image, sorted by addresses in the original image.
+  Mapping mapping;
+  // For all interval endpoints in |mapping| this stores the minimum index of
+  // an interval in |mapping| that contains the endpoint. Useful for doing
+  // interval intersection queries.
+  EndpointIndexMap endpoint_index_map;
+};
+
+}  // namespace google_breakpad
+
+#endif  // COMMON_WINDOWS_OMAP_INTERNAL_H_
diff --git a/include/breakpad/common/windows/pdb_source_line_writer.h b/include/breakpad/common/windows/pdb_source_line_writer.h
new file mode 100644
index 0000000..e9e89bb
--- /dev/null
+++ b/include/breakpad/common/windows/pdb_source_line_writer.h
@@ -0,0 +1,257 @@
+// 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.
+
+// PDBSourceLineWriter uses a pdb file produced by Visual C++ to output
+// a line/address map for use with BasicSourceLineResolver.
+
+#ifndef COMMON_WINDOWS_PDB_SOURCE_LINE_WRITER_H_
+#define COMMON_WINDOWS_PDB_SOURCE_LINE_WRITER_H_
+
+#include <atlcomcli.h>
+
+#include <unordered_map>
+#include <string>
+
+#include "common/windows/omap.h"
+
+struct IDiaEnumLineNumbers;
+struct IDiaSession;
+struct IDiaSymbol;
+
+namespace google_breakpad {
+
+using std::wstring;
+using std::unordered_map;
+
+// A structure that carries information that identifies a pdb file.
+struct PDBModuleInfo {
+ public:
+  // The basename of the pdb file from which information was loaded.
+  wstring debug_file;
+
+  // The pdb's identifier.  For recent pdb files, the identifier consists
+  // of the pdb's guid, in uppercase hexadecimal form without any dashes
+  // or separators, followed immediately by the pdb's age, also in
+  // uppercase hexadecimal form.  For older pdb files which have no guid,
+  // the identifier is the pdb's 32-bit signature value, in zero-padded
+  // hexadecimal form, followed immediately by the pdb's age, in lowercase
+  // hexadecimal form.
+  wstring debug_identifier;
+
+  // A string identifying the cpu that the pdb is associated with.
+  // Currently, this may be "x86" or "unknown".
+  wstring cpu;
+};
+
+// A structure that carries information that identifies a PE file,
+// either an EXE or a DLL.
+struct PEModuleInfo {
+  // The basename of the PE file.
+  wstring code_file;
+
+  // The PE file's code identifier, which consists of its timestamp
+  // and file size concatenated together into a single hex string.
+  // (The fields IMAGE_OPTIONAL_HEADER::SizeOfImage and
+  // IMAGE_FILE_HEADER::TimeDateStamp, as defined in the ImageHlp
+  // documentation.) This is not well documented, if it's documented
+  // at all, but it's what symstore does and what DbgHelp supports.
+  wstring code_identifier;
+};
+
+class PDBSourceLineWriter {
+ public:
+  enum FileFormat {
+    PDB_FILE,  // a .pdb file containing debug symbols
+    EXE_FILE,  // a .exe or .dll file
+    ANY_FILE   // try PDB_FILE and then EXE_FILE
+  };
+
+  explicit PDBSourceLineWriter();
+  ~PDBSourceLineWriter();
+
+  // Opens the given file.  For executable files, the corresponding pdb
+  // file must be available; Open will be if it is not.
+  // If there is already a pdb file open, it is automatically closed.
+  // Returns true on success.
+  bool Open(const wstring &file, FileFormat format);
+
+  // Sets the code file full path.  This is optional for 32-bit modules.  It is
+  // also optional for 64-bit modules when there is an executable file stored
+  // in the same directory as the PDB file.  It is only required for 64-bit
+  // modules when the executable file is not in the same location as the PDB
+  // file and it must be called after Open() and before WriteMap().
+  // If Open() was called for an executable file, then it is an error to call
+  // SetCodeFile() with a different file path and it will return false.
+  bool SetCodeFile(const wstring &exe_file);
+
+  // Writes a map file from the current pdb file to the given file stream.
+  // Returns true on success.
+  bool WriteMap(FILE *map_file);
+
+  // Closes the current pdb file and its associated resources.
+  void Close();
+
+  // Retrieves information about the module's debugging file.  Returns
+  // true on success and false on failure.
+  bool GetModuleInfo(PDBModuleInfo *info);
+
+  // Retrieves information about the module's PE file.  Returns
+  // true on success and false on failure.
+  bool GetPEInfo(PEModuleInfo *info);
+
+  // Sets uses_guid to true if the opened file uses a new-style CodeView
+  // record with a 128-bit GUID, or false if the opened file uses an old-style
+  // CodeView record.  When no GUID is available, a 32-bit signature should be
+  // used to identify the module instead.  If the information cannot be
+  // determined, this method returns false.
+  bool UsesGUID(bool *uses_guid);
+
+ private:
+  // Outputs the line/address pairs for each line in the enumerator.
+  // Returns true on success.
+  bool PrintLines(IDiaEnumLineNumbers *lines);
+
+  // Outputs a function address and name, followed by its source line list.
+  // block can be the same object as function, or it can be a reference
+  // to a code block that is lexically part of this function, but
+  // resides at a separate address.
+  // Returns true on success.
+  bool PrintFunction(IDiaSymbol *function, IDiaSymbol *block);
+
+  // Outputs all functions as described above.  Returns true on success.
+  bool PrintFunctions();
+
+  // Outputs all of the source files in the session's pdb file.
+  // Returns true on success.
+  bool PrintSourceFiles();
+
+  // Outputs all of the frame information necessary to construct stack
+  // backtraces in the absence of frame pointers. For x86 data stored in
+  // .pdb files. Returns true on success.
+  bool PrintFrameDataUsingPDB();
+
+  // Outputs all of the frame information necessary to construct stack
+  // backtraces in the absence of frame pointers. For x64 data stored in
+  // .exe, .dll files. Returns true on success.
+  bool PrintFrameDataUsingEXE();
+
+  // Outputs all of the frame information necessary to construct stack
+  // backtraces in the absence of frame pointers.  Returns true on success.
+  bool PrintFrameData();
+
+  // Outputs a single public symbol address and name, if the symbol corresponds
+  // to a code address.  Returns true on success.  If symbol is does not
+  // correspond to code, returns true without outputting anything.
+  bool PrintCodePublicSymbol(IDiaSymbol *symbol);
+
+  // Outputs a line identifying the PDB file that is being dumped, along with
+  // its uuid and age.
+  bool PrintPDBInfo();
+
+  // Outputs a line identifying the PE file corresponding to the PDB
+  // file that is being dumped, along with its code identifier,
+  // which consists of its timestamp and file size.
+  bool PrintPEInfo();
+
+  // Returns true if this filename has already been seen,
+  // and an ID is stored for it, or false if it has not.
+  bool FileIDIsCached(const wstring &file) {
+    return unique_files_.find(file) != unique_files_.end();
+  }
+
+  // Cache this filename and ID for later reuse.
+  void CacheFileID(const wstring &file, DWORD id) {
+    unique_files_[file] = id;
+  }
+
+  // Store this ID in the cache as a duplicate for this filename.
+  void StoreDuplicateFileID(const wstring &file, DWORD id) {
+    unordered_map<wstring, DWORD>::iterator iter = unique_files_.find(file);
+    if (iter != unique_files_.end()) {
+      // map this id to the previously seen one
+      file_ids_[id] = iter->second;
+    }
+  }
+
+  // Given a file's unique ID, return the ID that should be used to
+  // reference it. There may be multiple files with identical filenames
+  // but different unique IDs. The cache attempts to coalesce these into
+  // one ID per unique filename.
+  DWORD GetRealFileID(DWORD id) {
+    unordered_map<DWORD, DWORD>::iterator iter = file_ids_.find(id);
+    if (iter == file_ids_.end())
+      return id;
+    return iter->second;
+  }
+
+  // Find the PE file corresponding to the loaded PDB file, and
+  // set the code_file_ member. Returns false on failure.
+  bool FindPEFile();
+
+  // Returns the function name for a symbol.  If possible, the name is
+  // undecorated.  If the symbol's decorated form indicates the size of
+  // parameters on the stack, this information is returned in stack_param_size.
+  // Returns true on success.  If the symbol doesn't encode parameter size
+  // information, stack_param_size is set to -1.
+  static bool GetSymbolFunctionName(IDiaSymbol *function, BSTR *name,
+                                    int *stack_param_size);
+
+  // Returns the number of bytes of stack space used for a function's
+  // parameters.  function must have the tag SymTagFunction.  In the event of
+  // a failure, returns 0, which is also a valid number of bytes.
+  static int GetFunctionStackParamSize(IDiaSymbol *function);
+
+  // The filename of the PE file corresponding to the currently-open
+  // pdb file.
+  wstring code_file_;
+
+  // The session for the currently-open pdb file.
+  CComPtr<IDiaSession> session_;
+
+  // The current output file for this WriteMap invocation.
+  FILE *output_;
+
+  // There may be many duplicate filenames with different IDs.
+  // This maps from the DIA "unique ID" to a single ID per unique
+  // filename.
+  unordered_map<DWORD, DWORD> file_ids_;
+  // This maps unique filenames to file IDs.
+  unordered_map<wstring, DWORD> unique_files_;
+
+  // This is used for calculating post-transform symbol addresses and lengths.
+  ImageMap image_map_;
+
+  // Disallow copy ctor and operator=
+  PDBSourceLineWriter(const PDBSourceLineWriter&);
+  void operator=(const PDBSourceLineWriter&);
+};
+
+}  // namespace google_breakpad
+
+#endif  // COMMON_WINDOWS_PDB_SOURCE_LINE_WRITER_H_
diff --git a/include/breakpad/common/windows/string_utils-inl.h b/include/breakpad/common/windows/string_utils-inl.h
new file mode 100644
index 0000000..9b63607
--- /dev/null
+++ b/include/breakpad/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/include/breakpad/google_breakpad/processor/basic_source_line_resolver.h b/include/breakpad/google_breakpad/processor/basic_source_line_resolver.h
new file mode 100644
index 0000000..6bb6d86
--- /dev/null
+++ b/include/breakpad/google_breakpad/processor/basic_source_line_resolver.h
@@ -0,0 +1,144 @@
+// 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.
+
+// basic_source_line_resolver.h: BasicSourceLineResolver is derived from
+// SourceLineResolverBase, and is a concrete implementation of
+// SourceLineResolverInterface, using address map files produced by a
+// compatible writer, e.g. PDBSourceLineWriter.
+//
+// see "processor/source_line_resolver_base.h"
+// and "source_line_resolver_interface.h" for more documentation.
+
+#ifndef GOOGLE_BREAKPAD_PROCESSOR_BASIC_SOURCE_LINE_RESOLVER_H__
+#define GOOGLE_BREAKPAD_PROCESSOR_BASIC_SOURCE_LINE_RESOLVER_H__
+
+#include <map>
+#include <string>
+
+#include "common/using_std_string.h"
+#include "google_breakpad/processor/source_line_resolver_base.h"
+
+namespace google_breakpad {
+
+using std::map;
+
+class BasicSourceLineResolver : public SourceLineResolverBase {
+ public:
+  BasicSourceLineResolver();
+  virtual ~BasicSourceLineResolver() { }
+
+  using SourceLineResolverBase::LoadModule;
+  using SourceLineResolverBase::LoadModuleUsingMapBuffer;
+  using SourceLineResolverBase::LoadModuleUsingMemoryBuffer;
+  using SourceLineResolverBase::ShouldDeleteMemoryBufferAfterLoadModule;
+  using SourceLineResolverBase::UnloadModule;
+  using SourceLineResolverBase::HasModule;
+  using SourceLineResolverBase::IsModuleCorrupt;
+  using SourceLineResolverBase::FillSourceLineInfo;
+  using SourceLineResolverBase::FindWindowsFrameInfo;
+  using SourceLineResolverBase::FindCFIFrameInfo;
+
+ private:
+  // friend declarations:
+  friend class BasicModuleFactory;
+  friend class ModuleComparer;
+  friend class ModuleSerializer;
+  template<class> friend class SimpleSerializer;
+
+  // Function derives from SourceLineResolverBase::Function.
+  struct Function;
+  // Module implements SourceLineResolverBase::Module interface.
+  class Module;
+
+  // Disallow unwanted copy ctor and assignment operator
+  BasicSourceLineResolver(const BasicSourceLineResolver&);
+  void operator=(const BasicSourceLineResolver&);
+};
+
+// Helper class, containing useful methods for parsing of Breakpad symbol files.
+class SymbolParseHelper {
+ public:
+  // Parses a |file_line| declaration.  Returns true on success.
+  // Format: FILE <id> <filename>.
+  // Notice, that this method modifies the input |file_line| which is why it
+  // can't be const.  On success, <id>, and <filename> are stored in |*index|,
+  // and |*filename|.  No allocation is done, |*filename| simply points inside
+  // |file_line|.
+  static bool ParseFile(char *file_line,   // in
+                        long *index,       // out
+                        char **filename);  // out
+
+  // Parses a |function_line| declaration.  Returns true on success.
+  // Format:  FUNC <address> <size> <stack_param_size> <name>.
+  // Notice, that this method modifies the input |function_line| which is why it
+  // can't be const.  On success, <address>, <size>, <stack_param_size>, and
+  // <name> are stored in |*address|, |*size|, |*stack_param_size|, and |*name|.
+  // No allocation is done, |*name| simply points inside |function_line|.
+  static bool ParseFunction(char *function_line,     // in
+                            uint64_t *address,       // out
+                            uint64_t *size,          // out
+                            long *stack_param_size,  // out
+                            char **name);            // out
+
+  // Parses a |line| declaration.  Returns true on success.
+  // Format:  <address> <size> <line number> <source file id>
+  // Notice, that this method modifies the input |function_line| which is why
+  // it can't be const.  On success, <address>, <size>, <line number>, and
+  // <source file id> are stored in |*address|, |*size|, |*line_number|, and
+  // |*source_file|.
+  static bool ParseLine(char *line_line,     // in
+                        uint64_t *address,   // out
+                        uint64_t *size,      // out
+                        long *line_number,   // out
+                        long *source_file);  // out
+
+  // Parses a |public_line| declaration.  Returns true on success.
+  // Format:  PUBLIC <address> <stack_param_size> <name>
+  // Notice, that this method modifies the input |function_line| which is why
+  // it can't be const.  On success, <address>, <stack_param_size>, <name>
+  // are stored in |*address|, |*stack_param_size|, and |*name|.
+  // No allocation is done, |*name| simply points inside |public_line|.
+  static bool ParsePublicSymbol(char *public_line,       // in
+                                uint64_t *address,       // out
+                                long *stack_param_size,  // out
+                                char **name);            // out
+
+ private:
+  // Used for success checks after strtoull and strtol.
+  static bool IsValidAfterNumber(char *after_number);
+
+  // Only allow static methods.
+  SymbolParseHelper();
+  SymbolParseHelper(const SymbolParseHelper&);
+  void operator=(const SymbolParseHelper&);
+};
+
+}  // namespace google_breakpad
+
+#endif  // GOOGLE_BREAKPAD_PROCESSOR_BASIC_SOURCE_LINE_RESOLVER_H__
diff --git a/include/breakpad/google_breakpad/processor/call_stack.h b/include/breakpad/google_breakpad/processor/call_stack.h
new file mode 100644
index 0000000..21f595e
--- /dev/null
+++ b/include/breakpad/google_breakpad/processor/call_stack.h
@@ -0,0 +1,77 @@
+// 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.
+
+// call_stack.h: A call stack comprised of stack frames.
+//
+// This class manages a vector of stack frames.  It is used instead of
+// exposing the vector directly to allow the CallStack to own StackFrame
+// pointers without having to publicly export the linked_ptr class.  A
+// CallStack must be composed of pointers instead of objects to allow for
+// CPU-specific StackFrame subclasses.
+//
+// By convention, the stack frame at index 0 is the innermost callee frame,
+// and the frame at the highest index in a call stack is the outermost
+// caller.  CallStack only allows stacks to be built by pushing frames,
+// beginning with the innermost callee frame.
+//
+// Author: Mark Mentovai
+
+#ifndef GOOGLE_BREAKPAD_PROCESSOR_CALL_STACK_H__
+#define GOOGLE_BREAKPAD_PROCESSOR_CALL_STACK_H__
+
+#include <vector>
+
+namespace google_breakpad {
+
+using std::vector;
+
+struct StackFrame;
+template<typename T> class linked_ptr;
+
+class CallStack {
+ public:
+  CallStack() { Clear(); }
+  ~CallStack();
+
+  // Resets the CallStack to its initial empty state
+  void Clear();
+  
+  const vector<StackFrame*>* frames() const { return &frames_; }
+
+ private:
+  // Stackwalker is responsible for building the frames_ vector.
+  friend class Stackwalker;
+
+  // Storage for pushed frames.
+  vector<StackFrame*> frames_;
+};
+
+}  // namespace google_breakpad
+
+#endif  // GOOGLE_BREAKPAD_PROCSSOR_CALL_STACK_H__
diff --git a/include/breakpad/google_breakpad/processor/code_module.h b/include/breakpad/google_breakpad/processor/code_module.h
new file mode 100644
index 0000000..4e89282
--- /dev/null
+++ b/include/breakpad/google_breakpad/processor/code_module.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.
+
+// code_module.h: Carries information about code modules that are loaded
+// into a process.
+//
+// Author: Mark Mentovai
+
+#ifndef GOOGLE_BREAKPAD_PROCESSOR_CODE_MODULE_H__
+#define GOOGLE_BREAKPAD_PROCESSOR_CODE_MODULE_H__
+
+#include <string>
+
+#include "common/using_std_string.h"
+#include "google_breakpad/common/breakpad_types.h"
+
+namespace google_breakpad {
+
+class CodeModule {
+ public:
+  virtual ~CodeModule() {}
+
+  // The base address of this code module as it was loaded by the process.
+  // (uint64_t)-1 on error.
+  virtual uint64_t base_address() const = 0;
+
+  // The size of the code module.  0 on error.
+  virtual uint64_t size() const = 0;
+
+  // The path or file name that the code module was loaded from.  Empty on
+  // error.
+  virtual string code_file() const = 0;
+
+  // An identifying string used to discriminate between multiple versions and
+  // builds of the same code module.  This may contain a uuid, timestamp,
+  // version number, or any combination of this or other information, in an
+  // implementation-defined format.  Empty on error.
+  virtual string code_identifier() const = 0;
+
+  // The filename containing debugging information associated with the code
+  // module.  If debugging information is stored in a file separate from the
+  // code module itself (as is the case when .pdb or .dSYM files are used),
+  // this will be different from code_file.  If debugging information is
+  // stored in the code module itself (possibly prior to stripping), this
+  // will be the same as code_file.  Empty on error.
+  virtual string debug_file() const = 0;
+
+  // An identifying string similar to code_identifier, but identifies a
+  // specific version and build of the associated debug file.  This may be
+  // the same as code_identifier when the debug_file and code_file are
+  // identical or when the same identifier is used to identify distinct
+  // debug and code files.
+  virtual string debug_identifier() const = 0;
+
+  // A human-readable representation of the code module's version.  Empty on
+  // error.
+  virtual string version() const = 0;
+
+  // Creates a new copy of this CodeModule object, which the caller takes
+  // ownership of.  The new CodeModule may be of a different concrete class
+  // than the CodeModule being copied, but will behave identically to the
+  // copied CodeModule as far as the CodeModule interface is concerned.
+  virtual const CodeModule* Copy() const = 0;
+};
+
+}  // namespace google_breakpad
+
+#endif  // GOOGLE_BREAKPAD_PROCESSOR_CODE_MODULE_H__
diff --git a/include/breakpad/google_breakpad/processor/code_modules.h b/include/breakpad/google_breakpad/processor/code_modules.h
new file mode 100644
index 0000000..a38579a
--- /dev/null
+++ b/include/breakpad/google_breakpad/processor/code_modules.h
@@ -0,0 +1,98 @@
+// 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.
+
+// code_modules.h: Contains all of the CodeModule objects that were loaded
+// into a single process.
+//
+// Author: Mark Mentovai
+
+#ifndef GOOGLE_BREAKPAD_PROCESSOR_CODE_MODULES_H__
+#define GOOGLE_BREAKPAD_PROCESSOR_CODE_MODULES_H__
+
+#include "google_breakpad/common/breakpad_types.h"
+
+namespace google_breakpad {
+
+class CodeModule;
+
+class CodeModules {
+ public:
+  virtual ~CodeModules() {}
+
+  // The number of contained CodeModule objects.
+  virtual unsigned int module_count() const = 0;
+
+  // Random access to modules.  Returns the module whose code is present
+  // at the address indicated by |address|.  If no module is present at this
+  // address, returns NULL.  Ownership of the returned CodeModule is retained
+  // by the CodeModules object; pointers returned by this method are valid for
+  // comparison with pointers returned by the other Get methods.
+  virtual const CodeModule* GetModuleForAddress(uint64_t address) const = 0;
+
+  // Returns the module corresponding to the main executable.  If there is
+  // no main executable, returns NULL.  Ownership of the returned CodeModule
+  // is retained by the CodeModules object; pointers returned by this method
+  // are valid for comparison with pointers returned by the other Get
+  // methods.
+  virtual const CodeModule* GetMainModule() const = 0;
+
+  // Sequential access to modules.  A sequence number of 0 corresponds to the
+  // module residing lowest in memory.  If the sequence number is out of
+  // range, returns NULL.  Ownership of the returned CodeModule is retained
+  // by the CodeModules object; pointers returned by this method are valid for
+  // comparison with pointers returned by the other Get methods.
+  virtual const CodeModule* GetModuleAtSequence(
+      unsigned int sequence) const = 0;
+
+  // Sequential access to modules.  This is similar to GetModuleAtSequence,
+  // except no ordering requirement is enforced.  A CodeModules implementation
+  // may return CodeModule objects from GetModuleAtIndex in any order it
+  // wishes, provided that the order remain the same throughout the life of
+  // the CodeModules object.  Typically, GetModuleAtIndex would be used by
+  // a caller to enumerate all CodeModule objects quickly when the enumeration
+  // does not require any ordering.  If the index argument is out of range,
+  // returns NULL.  Ownership of the returned CodeModule is retained by
+  // the CodeModules object; pointers returned by this method are valid for
+  // comparison with pointers returned by the other Get methods.
+  virtual const CodeModule* GetModuleAtIndex(unsigned int index) const = 0;
+
+  // Creates a new copy of this CodeModules object, which the caller takes
+  // ownership of.  The new object will also contain copies of the existing
+  // object's child CodeModule objects.  The new CodeModules object may be of
+  // a different concrete class than the object being copied, but will behave
+  // identically to the copied object as far as the CodeModules and CodeModule
+  // interfaces are concerned, except that the order that GetModuleAtIndex
+  // returns objects in may differ between a copy and the original CodeModules
+  // object.
+  virtual const CodeModules* Copy() const = 0;
+};
+
+}  // namespace google_breakpad
+
+#endif  // GOOGLE_BREAKPAD_PROCESSOR_CODE_MODULES_H__
diff --git a/include/breakpad/google_breakpad/processor/dump_context.h b/include/breakpad/google_breakpad/processor/dump_context.h
new file mode 100644
index 0000000..df80bf7
--- /dev/null
+++ b/include/breakpad/google_breakpad/processor/dump_context.h
@@ -0,0 +1,116 @@
+// Copyright (c) 2014 Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// dump_context.h: A (mini/micro) dump CPU-specific context.
+
+#ifndef GOOGLE_BREAKPAD_PROCESSOR_DUMP_CONTEXT_H__
+#define GOOGLE_BREAKPAD_PROCESSOR_DUMP_CONTEXT_H__
+
+#include "google_breakpad/common/minidump_format.h"
+#include "google_breakpad/processor/dump_object.h"
+
+namespace google_breakpad {
+
+// DumpContext carries a CPU-specific MDRawContext structure, which contains CPU
+// context such as register states.
+class DumpContext : public DumpObject {
+ public:
+  virtual ~DumpContext();
+
+  // Returns an MD_CONTEXT_* value such as MD_CONTEXT_X86 or MD_CONTEXT_PPC
+  // identifying the CPU type that the context was collected from.  The
+  // returned value will identify the CPU only, and will have any other
+  // MD_CONTEXT_* bits masked out.  Returns 0 on failure.
+  uint32_t GetContextCPU() const;
+
+  // Return the raw value of |context_flags_|
+  uint32_t GetContextFlags() const;
+
+  // Returns raw CPU-specific context data for the named CPU type.  If the
+  // context data does not match the CPU type or does not exist, returns NULL.
+  const MDRawContextAMD64* GetContextAMD64() const;
+  const MDRawContextARM*   GetContextARM() const;
+  const MDRawContextARM64* GetContextARM64() const;
+  const MDRawContextMIPS*  GetContextMIPS() const;
+  const MDRawContextPPC*   GetContextPPC() const;
+  const MDRawContextPPC64* GetContextPPC64() const;
+  const MDRawContextSPARC* GetContextSPARC() const;
+  const MDRawContextX86*   GetContextX86() const;
+
+  // A convenience method to get the instruction pointer out of the
+  // MDRawContext, since it varies per-CPU architecture.
+  bool GetInstructionPointer(uint64_t* ip) const;
+
+  // Similar to the GetInstructionPointer method, this method gets the stack
+  // pointer for all CPU architectures.
+  bool GetStackPointer(uint64_t* sp) const;
+
+  // Print a human-readable representation of the object to stdout.
+  void Print();
+
+ protected:
+  DumpContext();
+
+  // Sets row CPU-specific context data for the names CPU type.
+  void SetContextFlags(uint32_t context_flags);
+  void SetContextX86(MDRawContextX86* x86);
+  void SetContextPPC(MDRawContextPPC* ppc);
+  void SetContextPPC64(MDRawContextPPC64* ppc64);
+  void SetContextAMD64(MDRawContextAMD64* amd64);
+  void SetContextSPARC(MDRawContextSPARC* ctx_sparc);
+  void SetContextARM(MDRawContextARM* arm);
+  void SetContextARM64(MDRawContextARM64* arm64);
+  void SetContextMIPS(MDRawContextMIPS* ctx_mips);
+
+  // Free the CPU-specific context structure.
+  void FreeContext();
+
+ private:
+  // The CPU-specific context structure.
+  union {
+    MDRawContextBase*  base;
+    MDRawContextX86*   x86;
+    MDRawContextPPC*   ppc;
+    MDRawContextPPC64* ppc64;
+    MDRawContextAMD64* amd64;
+    // on Solaris SPARC, sparc is defined as a numeric constant,
+    // so variables can NOT be named as sparc
+    MDRawContextSPARC* ctx_sparc;
+    MDRawContextARM*   arm;
+    MDRawContextARM64* arm64;
+    MDRawContextMIPS*  ctx_mips;
+  } context_;
+
+  // Store this separately because of the weirdo AMD64 context
+  uint32_t context_flags_;
+};
+
+}  // namespace google_breakpad
+
+#endif  // GOOGLE_BREAKPAD_PROCESSOR_DUMP_CONTEXT_H__
diff --git a/include/breakpad/google_breakpad/processor/dump_object.h b/include/breakpad/google_breakpad/processor/dump_object.h
new file mode 100644
index 0000000..112f687
--- /dev/null
+++ b/include/breakpad/google_breakpad/processor/dump_object.h
@@ -0,0 +1,53 @@
+// Copyright (c) 2014 Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// dump_object.h: A base class for all mini/micro dump object.
+
+#ifndef GOOGLE_BREAKPAD_PROCESSOR_DUMP_OBJECT_H__
+#define GOOGLE_BREAKPAD_PROCESSOR_DUMP_OBJECT_H__
+
+namespace google_breakpad {
+
+// DumpObject is the base of various mini/micro dump's objects.
+class DumpObject {
+ public:
+  DumpObject();
+
+  bool valid() const { return valid_; }
+
+ protected:
+  // DumpObjects are not valid when created.  When a subclass populates its own
+  // fields, it can set valid_ to true.  Accessors and mutators may wish to
+  // consider or alter the valid_ state as they interact with objects.
+  bool valid_;
+};
+
+}  // namespace google_breakpad
+
+#endif  // GOOGLE_BREAKPAD_PROCESSOR_DUMP_OBJECT_H__
diff --git a/include/breakpad/google_breakpad/processor/exploitability.h b/include/breakpad/google_breakpad/processor/exploitability.h
new file mode 100644
index 0000000..014413c
--- /dev/null
+++ b/include/breakpad/google_breakpad/processor/exploitability.h
@@ -0,0 +1,82 @@
+// 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.
+
+// exploitability_engine.h: Generic exploitability engine.
+//
+// The Exploitability class is an abstract base class providing common
+// generic methods that apply to exploitability engines for specific platforms.
+// Specific implementations will extend this class by providing run
+// methods to fill in the exploitability_ enumeration of the ProcessState
+// for a crash.
+//
+// Author: Cris Neckar
+
+#ifndef GOOGLE_BREAKPAD_PROCESSOR_EXPLOITABILITY_H_
+#define GOOGLE_BREAKPAD_PROCESSOR_EXPLOITABILITY_H_
+
+#include "google_breakpad/common/breakpad_types.h"
+#include "google_breakpad/processor/minidump.h"
+#include "google_breakpad/processor/process_state.h"
+
+namespace google_breakpad {
+
+class Exploitability {
+ public:
+  virtual ~Exploitability() {}
+
+  static Exploitability *ExploitabilityForPlatform(Minidump *dump,
+                                                   ProcessState *process_state);
+
+  // The boolean parameter signals whether the exploitability engine is
+  // enabled to call out to objdump for disassembly. This is disabled by
+  // default. It is used to check the identity of the instruction that
+  // caused the program to crash. This should not be enabled if there are
+  // portability concerns.
+  static Exploitability *ExploitabilityForPlatform(Minidump *dump,
+                                                   ProcessState *process_state,
+                                                   bool enable_objdump);
+
+  ExploitabilityRating CheckExploitability();
+  bool AddressIsAscii(uint64_t);
+
+ protected:
+  Exploitability(Minidump *dump,
+                 ProcessState *process_state);
+
+  Minidump *dump_;
+  ProcessState *process_state_;
+  SystemInfo *system_info_;
+
+ private:
+  virtual ExploitabilityRating CheckPlatformExploitability() = 0;
+};
+
+}  // namespace google_breakpad
+
+#endif  // GOOGLE_BREAKPAD_PROCESSOR_EXPLOITABILITY_H_
diff --git a/include/breakpad/google_breakpad/processor/fast_source_line_resolver.h b/include/breakpad/google_breakpad/processor/fast_source_line_resolver.h
new file mode 100644
index 0000000..fdf9107
--- /dev/null
+++ b/include/breakpad/google_breakpad/processor/fast_source_line_resolver.h
@@ -0,0 +1,100 @@
+// 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.
+//
+// fast_source_line_resolver.h: FastSourceLineResolver is derived from
+// SourceLineResolverBase, and is a concrete implementation of
+// SourceLineResolverInterface.
+//
+// FastSourceLineResolver is a sibling class of BasicSourceLineResolver.  The
+// difference is FastSourceLineResolver loads a serialized memory chunk of data
+// which can be used directly a Module without parsing or copying of underlying
+// data.  Therefore loading a symbol in FastSourceLineResolver is much faster
+// and more memory-efficient than BasicSourceLineResolver.
+//
+// See "source_line_resolver_base.h" and
+// "google_breakpad/source_line_resolver_interface.h" for more reference.
+//
+// Author: Siyang Xie (lambxsy@google.com)
+
+#ifndef GOOGLE_BREAKPAD_PROCESSOR_FAST_SOURCE_LINE_RESOLVER_H__
+#define GOOGLE_BREAKPAD_PROCESSOR_FAST_SOURCE_LINE_RESOLVER_H__
+
+#include <map>
+#include <string>
+
+#include "google_breakpad/processor/source_line_resolver_base.h"
+
+namespace google_breakpad {
+
+using std::map;
+
+class FastSourceLineResolver : public SourceLineResolverBase {
+ public:
+  FastSourceLineResolver();
+  virtual ~FastSourceLineResolver() { }
+
+  using SourceLineResolverBase::FillSourceLineInfo;
+  using SourceLineResolverBase::FindCFIFrameInfo;
+  using SourceLineResolverBase::FindWindowsFrameInfo;
+  using SourceLineResolverBase::HasModule;
+  using SourceLineResolverBase::IsModuleCorrupt;
+  using SourceLineResolverBase::LoadModule;
+  using SourceLineResolverBase::LoadModuleUsingMapBuffer;
+  using SourceLineResolverBase::LoadModuleUsingMemoryBuffer;
+  using SourceLineResolverBase::UnloadModule;
+
+ private:
+  // Friend declarations.
+  friend class ModuleComparer;
+  friend class ModuleSerializer;
+  friend class FastModuleFactory;
+
+  // Nested types that will derive from corresponding nested types defined in
+  // SourceLineResolverBase.
+  struct Line;
+  struct Function;
+  struct PublicSymbol;
+  class Module;
+
+  // Deserialize raw memory data to construct a WindowsFrameInfo object.
+  static WindowsFrameInfo CopyWFI(const char *raw_memory);
+
+  // FastSourceLineResolver requires the memory buffer stays alive during the
+  // lifetime of a corresponding module, therefore it needs to redefine this
+  // virtual method.
+  virtual bool ShouldDeleteMemoryBufferAfterLoadModule();
+
+  // Disallow unwanted copy ctor and assignment operator
+  FastSourceLineResolver(const FastSourceLineResolver&);
+  void operator=(const FastSourceLineResolver&);
+};
+
+}  // namespace google_breakpad
+
+#endif  // GOOGLE_BREAKPAD_PROCESSOR_FAST_SOURCE_LINE_RESOLVER_H__
diff --git a/include/breakpad/google_breakpad/processor/memory_region.h b/include/breakpad/google_breakpad/processor/memory_region.h
new file mode 100644
index 0000000..30f88df
--- /dev/null
+++ b/include/breakpad/google_breakpad/processor/memory_region.h
@@ -0,0 +1,79 @@
+// 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.
+
+// memory_region.h: Access to memory regions.
+//
+// A MemoryRegion provides virtual access to a range of memory.  It is an
+// abstraction allowing the actual source of memory to be independent of
+// methods which need to access a virtual memory space.
+//
+// Author: Mark Mentovai
+
+#ifndef GOOGLE_BREAKPAD_PROCESSOR_MEMORY_REGION_H__
+#define GOOGLE_BREAKPAD_PROCESSOR_MEMORY_REGION_H__
+
+
+#include "google_breakpad/common/breakpad_types.h"
+
+
+namespace google_breakpad {
+
+
+class MemoryRegion {
+ public:
+  virtual ~MemoryRegion() {}
+
+  // The base address of this memory region.
+  virtual uint64_t GetBase() const = 0;
+
+  // The size of this memory region.
+  virtual uint32_t GetSize() const = 0;
+
+  // Access to data of various sizes within the memory region.  address
+  // is a pointer to read, and it must lie within the memory region as
+  // defined by its base address and size.  The location pointed to by
+  // value is set to the value at address.  Byte-swapping is performed
+  // if necessary so that the value is appropriate for the running
+  // program.  Returns true on success.  Fails and returns false if address
+  // is out of the region's bounds (after considering the width of value),
+  // or for other types of errors.
+  virtual bool GetMemoryAtAddress(uint64_t address, uint8_t*  value) const = 0;
+  virtual bool GetMemoryAtAddress(uint64_t address, uint16_t* value) const = 0;
+  virtual bool GetMemoryAtAddress(uint64_t address, uint32_t* value) const = 0;
+  virtual bool GetMemoryAtAddress(uint64_t address, uint64_t* value) const = 0;
+
+  // Print a human-readable representation of the object to stdout.
+  virtual void Print() const = 0;
+};
+
+
+}  // namespace google_breakpad
+
+
+#endif  // GOOGLE_BREAKPAD_PROCESSOR_MEMORY_REGION_H__
diff --git a/include/breakpad/google_breakpad/processor/microdump.h b/include/breakpad/google_breakpad/processor/microdump.h
new file mode 100644
index 0000000..abdaecb
--- /dev/null
+++ b/include/breakpad/google_breakpad/processor/microdump.h
@@ -0,0 +1,126 @@
+// Copyright (c) 2014 Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// microdump.h: A microdump reader.  Microdump is a minified variant of a
+// minidump (see minidump.h for documentation) which contains the minimum
+// amount of information required to get a stack trace for the crashing thread.
+// The information contained in a microdump is:
+// - the crashing thread stack
+// - system information (os type / version)
+// - cpu context (state of the registers)
+// - list of mmaps
+
+#ifndef GOOGLE_BREAKPAD_PROCESSOR_MICRODUMP_H__
+#define GOOGLE_BREAKPAD_PROCESSOR_MICRODUMP_H__
+
+#include <string>
+#include <vector>
+
+#include "common/scoped_ptr.h"
+#include "common/using_std_string.h"
+#include "google_breakpad/processor/dump_context.h"
+#include "google_breakpad/processor/memory_region.h"
+#include "google_breakpad/processor/system_info.h"
+#include "processor/basic_code_modules.h"
+
+namespace google_breakpad {
+
+// MicrodumpModuleList contains all of the loaded code modules for a process
+// in the form of MicrodumpModules.  It maintains a vector of these modules
+// and provides access to a code module corresponding to a specific address.
+class MicrodumpModules : public BasicCodeModules {
+ public:
+  // Takes over ownership of |module|.
+  void Add(const CodeModule* module);
+};
+
+// MicrodumpContext carries a CPU-specific context.
+// See dump_context.h for documentation.
+class MicrodumpContext : public DumpContext {
+ public:
+  virtual void SetContextARM(MDRawContextARM* arm);
+  virtual void SetContextARM64(MDRawContextARM64* arm64);
+};
+
+// This class provides access to microdump memory regions.
+// See memory_region.h for documentation.
+class MicrodumpMemoryRegion : public MemoryRegion {
+ public:
+  MicrodumpMemoryRegion();
+  virtual ~MicrodumpMemoryRegion() {}
+
+  // Set this region's address and contents. If we have placed an
+  // instance of this class in a test fixture class, individual tests
+  // can use this to provide the region's contents.
+  void Init(uint64_t base_address, const std::vector<uint8_t>& contents);
+
+  virtual uint64_t GetBase() const;
+  virtual uint32_t GetSize() const;
+
+  virtual bool GetMemoryAtAddress(uint64_t address, uint8_t* value) const;
+  virtual bool GetMemoryAtAddress(uint64_t address, uint16_t* value) const;
+  virtual bool GetMemoryAtAddress(uint64_t address, uint32_t* value) const;
+  virtual bool GetMemoryAtAddress(uint64_t address, uint64_t* value) const;
+
+  // Print a human-readable representation of the object to stdout.
+  virtual void Print() const;
+
+ private:
+  // Fetch a little-endian value from ADDRESS in contents_ whose size
+  // is BYTES, and store it in *VALUE.  Returns true on success.
+  template<typename ValueType>
+  bool GetMemoryLittleEndian(uint64_t address, ValueType* value) const;
+
+  uint64_t base_address_;
+  std::vector<uint8_t> contents_;
+};
+
+// Microdump is the user's interface to a microdump file.  It provides access to
+// the microdump's context, memory regions and modules.
+class Microdump {
+ public:
+  explicit Microdump(const string& contents);
+  virtual ~Microdump() {}
+
+  DumpContext* GetContext() { return context_.get(); }
+  MicrodumpMemoryRegion* GetMemory() { return stack_region_.get(); }
+  MicrodumpModules* GetModules() { return modules_.get(); }
+  SystemInfo* GetSystemInfo() { return system_info_.get(); }
+
+ private:
+  scoped_ptr<MicrodumpContext> context_;
+  scoped_ptr<MicrodumpMemoryRegion> stack_region_;
+  scoped_ptr<MicrodumpModules> modules_;
+  scoped_ptr<SystemInfo> system_info_;
+};
+
+}  // namespace google_breakpad
+
+#endif  // GOOGLE_BREAKPAD_PROCESSOR_MICRODUMP_H__
+
diff --git a/include/breakpad/google_breakpad/processor/microdump_processor.h b/include/breakpad/google_breakpad/processor/microdump_processor.h
new file mode 100644
index 0000000..1322a01
--- /dev/null
+++ b/include/breakpad/google_breakpad/processor/microdump_processor.h
@@ -0,0 +1,63 @@
+// Copyright (c) 2014, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// The processor for microdump (a reduced dump containing only the state of the
+// crashing thread). See crbug.com/410294 for more info and design docs.
+
+#ifndef GOOGLE_BREAKPAD_PROCESSOR_MICRODUMP_PROCESSOR_H__
+#define GOOGLE_BREAKPAD_PROCESSOR_MICRODUMP_PROCESSOR_H__
+
+#include <string>
+
+#include "common/using_std_string.h"
+#include "google_breakpad/processor/process_result.h"
+
+namespace google_breakpad {
+
+class ProcessState;
+class StackFrameSymbolizer;
+ 
+class MicrodumpProcessor {
+ public:
+  // Initializes the MicrodumpProcessor with a stack frame symbolizer.
+  // Does not take ownership of frame_symbolizer, which must NOT be NULL.
+  explicit MicrodumpProcessor(StackFrameSymbolizer* frame_symbolizer);
+
+  virtual ~MicrodumpProcessor();
+
+  // Processes the microdump contents and fills process_state with the result.
+  google_breakpad::ProcessResult Process(const string& microdump_contents,
+                                         ProcessState* process_state);
+ private:
+  StackFrameSymbolizer* frame_symbolizer_;
+};
+
+}  // namespace google_breakpad
+
+#endif  // GOOGLE_BREAKPAD_PROCESSOR_MICRODUMP_PROCESSOR_H__
diff --git a/include/breakpad/google_breakpad/processor/minidump.h b/include/breakpad/google_breakpad/processor/minidump.h
new file mode 100644
index 0000000..2b5025e
--- /dev/null
+++ b/include/breakpad/google_breakpad/processor/minidump.h
@@ -0,0 +1,1130 @@
+// 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.
+
+// minidump.h: A minidump reader.
+//
+// The basic structure of this module tracks the structure of the minidump
+// file itself.  At the top level, a minidump file is represented by a
+// Minidump object.  Like most other classes in this module, Minidump
+// provides a Read method that initializes the object with information from
+// the file.  Most of the classes in this file are wrappers around the
+// "raw" structures found in the minidump file itself, and defined in
+// minidump_format.h.  For example, each thread is represented by a
+// MinidumpThread object, whose parameters are specified in an MDRawThread
+// structure.  A properly byte-swapped MDRawThread can be obtained from a
+// MinidumpThread easily by calling its thread() method.
+//
+// Most of the module lazily reads only the portion of the minidump file
+// necessary to fulfill the user's request.  Calling Minidump::Read
+// only reads the minidump's directory.  The thread list is not read until
+// it is needed, and even once it's read, the memory regions for each
+// thread's stack aren't read until they're needed.  This strategy avoids
+// unnecessary file input, and allocating memory for data in which the user
+// has no interest.  Note that although memory allocations for a typical
+// minidump file are not particularly large, it is possible for legitimate
+// minidumps to be sizable.  A full-memory minidump, for example, contains
+// a snapshot of the entire mapped memory space.  Even a normal minidump,
+// with stack memory only, can be large if, for example, the dump was
+// generated in response to a crash that occurred due to an infinite-
+// recursion bug that caused the stack's limits to be exceeded.  Finally,
+// some users of this library will unfortunately find themselves in the
+// position of having to process potentially-hostile minidumps that might
+// attempt to cause problems by forcing the minidump processor to over-
+// allocate memory.
+//
+// Memory management in this module is based on a strict
+// you-don't-own-anything policy.  The only object owned by the user is
+// the top-level Minidump object, the creation and destruction of which
+// must be the user's own responsibility.  All other objects obtained
+// through interaction with this module are ultimately owned by the
+// Minidump object, and will be freed upon the Minidump object's destruction.
+// Because memory regions can potentially involve large allocations, a
+// FreeMemory method is provided by MinidumpMemoryRegion, allowing the user
+// to release data when it is no longer needed.  Use of this method is
+// optional but recommended.  If freed data is later required, it will
+// be read back in from the minidump file again.
+//
+// There is one exception to this memory management policy:
+// Minidump::ReadString will return a string object to the user, and the user
+// is responsible for its deletion.
+//
+// Author: Mark Mentovai
+
+#ifndef GOOGLE_BREAKPAD_PROCESSOR_MINIDUMP_H__
+#define GOOGLE_BREAKPAD_PROCESSOR_MINIDUMP_H__
+
+#include <stdint.h>
+
+#ifndef _WIN32
+#include <unistd.h>
+#endif
+
+#include <iostream>
+#include <map>
+#include <string>
+#include <vector>
+
+#include "common/basictypes.h"
+#include "common/using_std_string.h"
+#include "google_breakpad/processor/code_module.h"
+#include "google_breakpad/processor/code_modules.h"
+#include "google_breakpad/processor/dump_context.h"
+#include "google_breakpad/processor/dump_object.h"
+#include "google_breakpad/processor/memory_region.h"
+#include "google_breakpad/processor/proc_maps_linux.h"
+
+
+namespace google_breakpad {
+
+
+using std::map;
+using std::vector;
+
+
+class Minidump;
+template<typename AddressType, typename EntryType> class RangeMap;
+
+
+// MinidumpObject is the base of all Minidump* objects except for Minidump
+// itself.
+class MinidumpObject : public DumpObject {
+ public:
+  virtual ~MinidumpObject() {}
+
+ protected:
+  explicit MinidumpObject(Minidump* minidump);
+
+  // Refers to the Minidump object that is the ultimate parent of this
+  // Some MinidumpObjects are owned by other MinidumpObjects, but at the
+  // root of the ownership tree is always a Minidump.  The Minidump object
+  // is kept here for access to its seeking and reading facilities, and
+  // for access to data about the minidump file itself, such as whether
+  // it should be byte-swapped.
+  Minidump* minidump_;
+};
+
+
+// This class exists primarily to provide a virtual destructor in a base
+// class common to all objects that might be stored in
+// Minidump::mStreamObjects.  Some object types will never be stored in
+// Minidump::mStreamObjects, but are represented as streams and adhere to the
+// same interface, and may be derived from this class.
+class MinidumpStream : public MinidumpObject {
+ public:
+  virtual ~MinidumpStream() {}
+
+ protected:
+  explicit MinidumpStream(Minidump* minidump);
+
+ private:
+  // Populate (and validate) the MinidumpStream.  minidump_ is expected
+  // to be positioned at the beginning of the stream, so that the next
+  // read from the minidump will be at the beginning of the stream.
+  // expected_size should be set to the stream's length as contained in
+  // the MDRawDirectory record or other identifying record.  A class
+  // that implements MinidumpStream can compare expected_size to a
+  // known size as an integrity check.
+  virtual bool Read(uint32_t expected_size) = 0;
+};
+
+
+// MinidumpContext carries a CPU-specific MDRawContext structure, which
+// contains CPU context such as register states.  Each thread has its
+// own context, and the exception record, if present, also has its own
+// context.  Note that if the exception record is present, the context it
+// refers to is probably what the user wants to use for the exception
+// thread, instead of that thread's own context.  The exception thread's
+// context (as opposed to the exception record's context) will contain
+// context for the exception handler (which performs minidump generation),
+// and not the context that caused the exception (which is probably what the
+// user wants).
+class MinidumpContext : public DumpContext {
+ public:
+  virtual ~MinidumpContext();
+
+ protected:
+  explicit MinidumpContext(Minidump* minidump);
+
+ private:
+  friend class MinidumpThread;
+  friend class MinidumpException;
+
+  bool Read(uint32_t expected_size);
+
+  // If the minidump contains a SYSTEM_INFO_STREAM, makes sure that the
+  // system info stream gives an appropriate CPU type matching the context
+  // CPU type in context_cpu_type.  Returns false if the CPU type does not
+  // match.  Returns true if the CPU type matches or if the minidump does
+  // not contain a system info stream.
+  bool CheckAgainstSystemInfo(uint32_t context_cpu_type);
+
+  // Refers to the Minidump object that is the ultimate parent of this
+  // Some MinidumpObjects are owned by other MinidumpObjects, but at the
+  // root of the ownership tree is always a Minidump.  The Minidump object
+  // is kept here for access to its seeking and reading facilities, and
+  // for access to data about the minidump file itself, such as whether
+  // it should be byte-swapped.
+  Minidump* minidump_;
+};
+
+
+// MinidumpMemoryRegion does not wrap any MDRaw structure, and only contains
+// a reference to an MDMemoryDescriptor.  This object is intended to wrap
+// portions of a minidump file that contain memory dumps.  In normal
+// minidumps, each MinidumpThread owns a MinidumpMemoryRegion corresponding
+// to the thread's stack memory.  MinidumpMemoryList also gives access to
+// memory regions in its list as MinidumpMemoryRegions.  This class
+// adheres to MemoryRegion so that it may be used as a data provider to
+// the Stackwalker family of classes.
+class MinidumpMemoryRegion : public MinidumpObject,
+                             public MemoryRegion {
+ public:
+  virtual ~MinidumpMemoryRegion();
+
+  static void set_max_bytes(uint32_t max_bytes) { max_bytes_ = max_bytes; }
+  static uint32_t max_bytes() { return max_bytes_; }
+
+  // Returns a pointer to the base of the memory region.  Returns the
+  // cached value if available, otherwise, reads the minidump file and
+  // caches the memory region.
+  const uint8_t* GetMemory() const;
+
+  // The address of the base of the memory region.
+  uint64_t GetBase() const;
+
+  // The size, in bytes, of the memory region.
+  uint32_t GetSize() const;
+
+  // Frees the cached memory region, if cached.
+  void FreeMemory();
+
+  // Obtains the value of memory at the pointer specified by address.
+  bool GetMemoryAtAddress(uint64_t address, uint8_t*  value) const;
+  bool GetMemoryAtAddress(uint64_t address, uint16_t* value) const;
+  bool GetMemoryAtAddress(uint64_t address, uint32_t* value) const;
+  bool GetMemoryAtAddress(uint64_t address, uint64_t* value) const;
+
+  // Print a human-readable representation of the object to stdout.
+  void Print() const;
+
+ protected:
+  explicit MinidumpMemoryRegion(Minidump* minidump);
+
+ private:
+  friend class MinidumpThread;
+  friend class MinidumpMemoryList;
+
+  // Identify the base address and size of the memory region, and the
+  // location it may be found in the minidump file.
+  void SetDescriptor(MDMemoryDescriptor* descriptor);
+
+  // Implementation for GetMemoryAtAddress
+  template<typename T> bool GetMemoryAtAddressInternal(uint64_t address,
+                                                       T*        value) const;
+
+  // The largest memory region that will be read from a minidump.  The
+  // default is 1MB.
+  static uint32_t max_bytes_;
+
+  // Base address and size of the memory region, and its position in the
+  // minidump file.
+  MDMemoryDescriptor* descriptor_;
+
+  // Cached memory.
+  mutable vector<uint8_t>* memory_;
+};
+
+
+// MinidumpThread contains information about a thread of execution,
+// including a snapshot of the thread's stack and CPU context.  For
+// the thread that caused an exception, the context carried by
+// MinidumpException is probably desired instead of the CPU context
+// provided here.
+// Note that a MinidumpThread may be valid() even if it does not
+// contain a memory region or context.
+class MinidumpThread : public MinidumpObject {
+ public:
+  virtual ~MinidumpThread();
+
+  const MDRawThread* thread() const { return valid_ ? &thread_ : NULL; }
+  // GetMemory may return NULL even if the MinidumpThread is valid,
+  // if the thread memory cannot be read.
+  virtual MinidumpMemoryRegion* GetMemory();
+  // GetContext may return NULL even if the MinidumpThread is valid.
+  virtual MinidumpContext* GetContext();
+
+  // The thread ID is used to determine if a thread is the exception thread,
+  // so a special getter is provided to retrieve this data from the
+  // MDRawThread structure.  Returns false if the thread ID cannot be
+  // determined.
+  virtual bool GetThreadID(uint32_t *thread_id) const;
+
+  // Print a human-readable representation of the object to stdout.
+  void Print();
+
+  // Returns the start address of the thread stack memory region.  Returns 0 if
+  // MinidumpThread is invalid.  Note that this method can be called even when
+  // the thread memory cannot be read and GetMemory returns NULL.
+  virtual uint64_t GetStartOfStackMemoryRange() const;
+
+ protected:
+  explicit MinidumpThread(Minidump* minidump);
+
+ private:
+  // These objects are managed by MinidumpThreadList.
+  friend class MinidumpThreadList;
+
+  // This works like MinidumpStream::Read, but is driven by
+  // MinidumpThreadList.  No size checking is done, because
+  // MinidumpThreadList handles that directly.
+  bool Read();
+
+  MDRawThread           thread_;
+  MinidumpMemoryRegion* memory_;
+  MinidumpContext*      context_;
+};
+
+
+// MinidumpThreadList contains all of the threads (as MinidumpThreads) in
+// a process.
+class MinidumpThreadList : public MinidumpStream {
+ public:
+  virtual ~MinidumpThreadList();
+
+  static void set_max_threads(uint32_t max_threads) {
+    max_threads_ = max_threads;
+  }
+  static uint32_t max_threads() { return max_threads_; }
+
+  virtual unsigned int thread_count() const {
+    return valid_ ? thread_count_ : 0;
+  }
+
+  // Sequential access to threads.
+  virtual MinidumpThread* GetThreadAtIndex(unsigned int index) const;
+
+  // Random access to threads.
+  MinidumpThread* GetThreadByID(uint32_t thread_id);
+
+  // Print a human-readable representation of the object to stdout.
+  void Print();
+
+ protected:
+  explicit MinidumpThreadList(Minidump* aMinidump);
+
+ private:
+  friend class Minidump;
+
+  typedef map<uint32_t, MinidumpThread*> IDToThreadMap;
+  typedef vector<MinidumpThread> MinidumpThreads;
+
+  static const uint32_t kStreamType = MD_THREAD_LIST_STREAM;
+
+  bool Read(uint32_t aExpectedSize);
+
+  // The largest number of threads that will be read from a minidump.  The
+  // default is 256.
+  static uint32_t max_threads_;
+
+  // Access to threads using the thread ID as the key.
+  IDToThreadMap    id_to_thread_map_;
+
+  // The list of threads.
+  MinidumpThreads* threads_;
+  uint32_t        thread_count_;
+};
+
+
+// MinidumpModule wraps MDRawModule, which contains information about loaded
+// code modules.  Access is provided to various data referenced indirectly
+// by MDRawModule, such as the module's name and a specification for where
+// to locate debugging information for the module.
+class MinidumpModule : public MinidumpObject,
+                       public CodeModule {
+ public:
+  virtual ~MinidumpModule();
+
+  static void set_max_cv_bytes(uint32_t max_cv_bytes) {
+    max_cv_bytes_ = max_cv_bytes;
+  }
+  static uint32_t max_cv_bytes() { return max_cv_bytes_; }
+
+  static void set_max_misc_bytes(uint32_t max_misc_bytes) {
+    max_misc_bytes_ = max_misc_bytes;
+  }
+  static uint32_t max_misc_bytes() { return max_misc_bytes_; }
+
+  const MDRawModule* module() const { return valid_ ? &module_ : NULL; }
+
+  // CodeModule implementation
+  virtual uint64_t base_address() const {
+    return valid_ ? module_.base_of_image : static_cast<uint64_t>(-1);
+  }
+  virtual uint64_t size() const { return valid_ ? module_.size_of_image : 0; }
+  virtual string code_file() const;
+  virtual string code_identifier() const;
+  virtual string debug_file() const;
+  virtual string debug_identifier() const;
+  virtual string version() const;
+  virtual const CodeModule* Copy() const;
+
+  // The CodeView record, which contains information to locate the module's
+  // debugging information (pdb).  This is returned as uint8_t* because
+  // the data can be of types MDCVInfoPDB20* or MDCVInfoPDB70*, or it may be
+  // of a type unknown to Breakpad, in which case the raw data will still be
+  // returned but no byte-swapping will have been performed.  Check the
+  // record's signature in the first four bytes to differentiate between
+  // the various types.  Current toolchains generate modules which carry
+  // MDCVInfoPDB70 by default.  Returns a pointer to the CodeView record on
+  // success, and NULL on failure.  On success, the optional |size| argument
+  // is set to the size of the CodeView record.
+  const uint8_t* GetCVRecord(uint32_t* size);
+
+  // The miscellaneous debug record, which is obsolete.  Current toolchains
+  // do not generate this type of debugging information (dbg), and this
+  // field is not expected to be present.  Returns a pointer to the debugging
+  // record on success, and NULL on failure.  On success, the optional |size|
+  // argument is set to the size of the debugging record.
+  const MDImageDebugMisc* GetMiscRecord(uint32_t* size);
+
+  // Print a human-readable representation of the object to stdout.
+  void Print();
+
+ private:
+  // These objects are managed by MinidumpModuleList.
+  friend class MinidumpModuleList;
+
+  explicit MinidumpModule(Minidump* minidump);
+
+  // This works like MinidumpStream::Read, but is driven by
+  // MinidumpModuleList.  No size checking is done, because
+  // MinidumpModuleList handles that directly.
+  bool Read();
+
+  // Reads indirectly-referenced data, including the module name, CodeView
+  // record, and miscellaneous debugging record.  This is necessary to allow
+  // MinidumpModuleList to fully construct MinidumpModule objects without
+  // requiring seeks to read a contiguous set of MinidumpModule objects.
+  // All auxiliary data should be available when Read is called, in order to
+  // allow the CodeModule getters to be const methods.
+  bool ReadAuxiliaryData();
+
+  // The largest number of bytes that will be read from a minidump for a
+  // CodeView record or miscellaneous debugging record, respectively.  The
+  // default for each is 1024.
+  static uint32_t max_cv_bytes_;
+  static uint32_t max_misc_bytes_;
+
+  // True after a successful Read.  This is different from valid_, which is
+  // not set true until ReadAuxiliaryData also completes successfully.
+  // module_valid_ is only used by ReadAuxiliaryData and the functions it
+  // calls to determine whether the object is ready for auxiliary data to
+  // be read.
+  bool              module_valid_;
+
+  // True if debug info was read from the module.  Certain modules
+  // may contain debug records in formats we don't support,
+  // so we can just set this to false to ignore them.
+  bool              has_debug_info_;
+
+  MDRawModule       module_;
+
+  // Cached module name.
+  const string*     name_;
+
+  // Cached CodeView record - this is MDCVInfoPDB20 or (likely)
+  // MDCVInfoPDB70, or possibly something else entirely.  Stored as a uint8_t
+  // because the structure contains a variable-sized string and its exact
+  // size cannot be known until it is processed.
+  vector<uint8_t>* cv_record_;
+
+  // If cv_record_ is present, cv_record_signature_ contains a copy of the
+  // CodeView record's first four bytes, for ease of determinining the
+  // type of structure that cv_record_ contains.
+  uint32_t cv_record_signature_;
+
+  // Cached MDImageDebugMisc (usually not present), stored as uint8_t
+  // because the structure contains a variable-sized string and its exact
+  // size cannot be known until it is processed.
+  vector<uint8_t>* misc_record_;
+};
+
+
+// MinidumpModuleList contains all of the loaded code modules for a process
+// in the form of MinidumpModules.  It maintains a map of these modules
+// so that it may easily provide a code module corresponding to a specific
+// address.
+class MinidumpModuleList : public MinidumpStream,
+                           public CodeModules {
+ public:
+  virtual ~MinidumpModuleList();
+
+  static void set_max_modules(uint32_t max_modules) {
+    max_modules_ = max_modules;
+  }
+  static uint32_t max_modules() { return max_modules_; }
+
+  // CodeModules implementation.
+  virtual unsigned int module_count() const {
+    return valid_ ? module_count_ : 0;
+  }
+  virtual const MinidumpModule* GetModuleForAddress(uint64_t address) const;
+  virtual const MinidumpModule* GetMainModule() const;
+  virtual const MinidumpModule* GetModuleAtSequence(
+      unsigned int sequence) const;
+  virtual const MinidumpModule* GetModuleAtIndex(unsigned int index) const;
+  virtual const CodeModules* Copy() const;
+
+  // Print a human-readable representation of the object to stdout.
+  void Print();
+
+ protected:
+  explicit MinidumpModuleList(Minidump* minidump);
+
+ private:
+  friend class Minidump;
+
+  typedef vector<MinidumpModule> MinidumpModules;
+
+  static const uint32_t kStreamType = MD_MODULE_LIST_STREAM;
+
+  bool Read(uint32_t expected_size);
+
+  // The largest number of modules that will be read from a minidump.  The
+  // default is 1024.
+  static uint32_t max_modules_;
+
+  // Access to modules using addresses as the key.
+  RangeMap<uint64_t, unsigned int> *range_map_;
+
+  MinidumpModules *modules_;
+  uint32_t module_count_;
+};
+
+
+// MinidumpMemoryList corresponds to a minidump's MEMORY_LIST_STREAM stream,
+// which references the snapshots of all of the memory regions contained
+// within the minidump.  For a normal minidump, this includes stack memory
+// (also referenced by each MinidumpThread, in fact, the MDMemoryDescriptors
+// here and in MDRawThread both point to exactly the same data in a
+// minidump file, conserving space), as well as a 256-byte snapshot of memory
+// surrounding the instruction pointer in the case of an exception.  Other
+// types of minidumps may contain significantly more memory regions.  Full-
+// memory minidumps contain all of a process' mapped memory.
+class MinidumpMemoryList : public MinidumpStream {
+ public:
+  virtual ~MinidumpMemoryList();
+
+  static void set_max_regions(uint32_t max_regions) {
+    max_regions_ = max_regions;
+  }
+  static uint32_t max_regions() { return max_regions_; }
+
+  unsigned int region_count() const { return valid_ ? region_count_ : 0; }
+
+  // Sequential access to memory regions.
+  MinidumpMemoryRegion* GetMemoryRegionAtIndex(unsigned int index);
+
+  // Random access to memory regions.  Returns the region encompassing
+  // the address identified by address.
+  virtual MinidumpMemoryRegion* GetMemoryRegionForAddress(uint64_t address);
+
+  // Print a human-readable representation of the object to stdout.
+  void Print();
+
+ private:
+  friend class Minidump;
+  friend class MockMinidumpMemoryList;
+
+  typedef vector<MDMemoryDescriptor>   MemoryDescriptors;
+  typedef vector<MinidumpMemoryRegion> MemoryRegions;
+
+  static const uint32_t kStreamType = MD_MEMORY_LIST_STREAM;
+
+  explicit MinidumpMemoryList(Minidump* minidump);
+
+  bool Read(uint32_t expected_size);
+
+  // The largest number of memory regions that will be read from a minidump.
+  // The default is 256.
+  static uint32_t max_regions_;
+
+  // Access to memory regions using addresses as the key.
+  RangeMap<uint64_t, unsigned int> *range_map_;
+
+  // The list of descriptors.  This is maintained separately from the list
+  // of regions, because MemoryRegion doesn't own its MemoryDescriptor, it
+  // maintains a pointer to it.  descriptors_ provides the storage for this
+  // purpose.
+  MemoryDescriptors *descriptors_;
+
+  // The list of regions.
+  MemoryRegions *regions_;
+  uint32_t region_count_;
+};
+
+
+// MinidumpException wraps MDRawExceptionStream, which contains information
+// about the exception that caused the minidump to be generated, if the
+// minidump was generated in an exception handler called as a result of an
+// exception.  It also provides access to a MinidumpContext object, which
+// contains the CPU context for the exception thread at the time the exception
+// occurred.
+class MinidumpException : public MinidumpStream {
+ public:
+  virtual ~MinidumpException();
+
+  const MDRawExceptionStream* exception() const {
+    return valid_ ? &exception_ : NULL;
+  }
+
+  // The thread ID is used to determine if a thread is the exception thread,
+  // so a special getter is provided to retrieve this data from the
+  // MDRawExceptionStream structure.  Returns false if the thread ID cannot
+  // be determined.
+  bool GetThreadID(uint32_t *thread_id) const;
+
+  MinidumpContext* GetContext();
+
+  // Print a human-readable representation of the object to stdout.
+  void Print();
+
+ private:
+  friend class Minidump;
+
+  static const uint32_t kStreamType = MD_EXCEPTION_STREAM;
+
+  explicit MinidumpException(Minidump* minidump);
+
+  bool Read(uint32_t expected_size);
+
+  MDRawExceptionStream exception_;
+  MinidumpContext*     context_;
+};
+
+// MinidumpAssertion wraps MDRawAssertionInfo, which contains information
+// about an assertion that caused the minidump to be generated.
+class MinidumpAssertion : public MinidumpStream {
+ public:
+  virtual ~MinidumpAssertion();
+
+  const MDRawAssertionInfo* assertion() const {
+    return valid_ ? &assertion_ : NULL;
+  }
+
+  string expression() const {
+    return valid_ ? expression_ : "";
+  }
+
+  string function() const {
+    return valid_ ? function_ : "";
+  }
+
+  string file() const {
+    return valid_ ? file_ : "";
+  }
+
+  // Print a human-readable representation of the object to stdout.
+  void Print();
+
+ private:
+  friend class Minidump;
+
+  static const uint32_t kStreamType = MD_ASSERTION_INFO_STREAM;
+
+  explicit MinidumpAssertion(Minidump* minidump);
+
+  bool Read(uint32_t expected_size);
+
+  MDRawAssertionInfo assertion_;
+  string expression_;
+  string function_;
+  string file_;
+};
+
+
+// MinidumpSystemInfo wraps MDRawSystemInfo and provides information about
+// the system on which the minidump was generated.  See also MinidumpMiscInfo.
+class MinidumpSystemInfo : public MinidumpStream {
+ public:
+  virtual ~MinidumpSystemInfo();
+
+  const MDRawSystemInfo* system_info() const {
+    return valid_ ? &system_info_ : NULL;
+  }
+
+  // GetOS and GetCPU return textual representations of the operating system
+  // and CPU that produced the minidump.  Unlike most other Minidump* methods,
+  // they return string objects, not weak pointers.  Defined values for
+  // GetOS() are "mac", "windows", and "linux".  Defined values for GetCPU
+  // are "x86" and "ppc".  These methods return an empty string when their
+  // values are unknown.
+  string GetOS();
+  string GetCPU();
+
+  // I don't know what CSD stands for, but this field is documented as
+  // returning a textual representation of the OS service pack.  On other
+  // platforms, this provides additional information about an OS version
+  // level beyond major.minor.micro.  Returns NULL if unknown.
+  const string* GetCSDVersion();
+
+  // If a CPU vendor string can be determined, returns a pointer to it,
+  // otherwise, returns NULL.  CPU vendor strings can be determined from
+  // x86 CPUs with CPUID 0.
+  const string* GetCPUVendor();
+
+  // Print a human-readable representation of the object to stdout.
+  void Print();
+
+ protected:
+  explicit MinidumpSystemInfo(Minidump* minidump);
+  MDRawSystemInfo system_info_;
+
+  // Textual representation of the OS service pack, for minidumps produced
+  // by MiniDumpWriteDump on Windows.
+  const string* csd_version_;
+
+ private:
+  friend class Minidump;
+
+  static const uint32_t kStreamType = MD_SYSTEM_INFO_STREAM;
+
+  bool Read(uint32_t expected_size);
+
+  // A string identifying the CPU vendor, if known.
+  const string* cpu_vendor_;
+};
+
+
+// MinidumpMiscInfo wraps MDRawMiscInfo and provides information about
+// the process that generated the minidump, and optionally additional system
+// information.  See also MinidumpSystemInfo.
+class MinidumpMiscInfo : public MinidumpStream {
+ public:
+  const MDRawMiscInfo* misc_info() const {
+    return valid_ ? &misc_info_ : NULL;
+  }
+
+  // Print a human-readable representation of the object to stdout.
+  void Print();
+
+ private:
+  friend class Minidump;
+  friend class TestMinidumpMiscInfo;
+
+  static const uint32_t kStreamType = MD_MISC_INFO_STREAM;
+
+  explicit MinidumpMiscInfo(Minidump* minidump_);
+
+  bool Read(uint32_t expected_size_);
+
+  MDRawMiscInfo misc_info_;
+
+  // Populated by Read.  Contains the converted strings from the corresponding
+  // UTF-16 fields in misc_info_
+  string standard_name_;
+  string daylight_name_;
+  string build_string_;
+  string dbg_bld_str_;
+};
+
+
+// MinidumpBreakpadInfo wraps MDRawBreakpadInfo, which is an optional stream in
+// a minidump that provides additional information about the process state
+// at the time the minidump was generated.
+class MinidumpBreakpadInfo : public MinidumpStream {
+ public:
+  const MDRawBreakpadInfo* breakpad_info() const {
+    return valid_ ? &breakpad_info_ : NULL;
+  }
+
+  // These thread IDs are used to determine if threads deserve special
+  // treatment, so special getters are provided to retrieve this data from
+  // the MDRawBreakpadInfo structure.  The getters return false if the thread
+  // IDs cannot be determined.
+  bool GetDumpThreadID(uint32_t *thread_id) const;
+  bool GetRequestingThreadID(uint32_t *thread_id) const;
+
+  // Print a human-readable representation of the object to stdout.
+  void Print();
+
+ private:
+  friend class Minidump;
+
+  static const uint32_t kStreamType = MD_BREAKPAD_INFO_STREAM;
+
+  explicit MinidumpBreakpadInfo(Minidump* minidump_);
+
+  bool Read(uint32_t expected_size_);
+
+  MDRawBreakpadInfo breakpad_info_;
+};
+
+// MinidumpMemoryInfo wraps MDRawMemoryInfo, which provides information
+// about mapped memory regions in a process, including their ranges
+// and protection.
+class MinidumpMemoryInfo : public MinidumpObject {
+ public:
+  const MDRawMemoryInfo* info() const { return valid_ ? &memory_info_ : NULL; }
+
+  // The address of the base of the memory region.
+  uint64_t GetBase() const { return valid_ ? memory_info_.base_address : 0; }
+
+  // The size, in bytes, of the memory region.
+  uint64_t GetSize() const { return valid_ ? memory_info_.region_size : 0; }
+
+  // Return true if the memory protection allows execution.
+  bool IsExecutable() const;
+
+  // Return true if the memory protection allows writing.
+  bool IsWritable() const;
+
+  // Print a human-readable representation of the object to stdout.
+  void Print();
+
+ private:
+  // These objects are managed by MinidumpMemoryInfoList.
+  friend class MinidumpMemoryInfoList;
+
+  explicit MinidumpMemoryInfo(Minidump* minidump_);
+
+  // This works like MinidumpStream::Read, but is driven by
+  // MinidumpMemoryInfoList.  No size checking is done, because
+  // MinidumpMemoryInfoList handles that directly.
+  bool Read();
+
+  MDRawMemoryInfo memory_info_;
+};
+
+// MinidumpMemoryInfoList contains a list of information about
+// mapped memory regions for a process in the form of MDRawMemoryInfo.
+// It maintains a map of these structures so that it may easily provide
+// info corresponding to a specific address.
+class MinidumpMemoryInfoList : public MinidumpStream {
+ public:
+  virtual ~MinidumpMemoryInfoList();
+
+  unsigned int info_count() const { return valid_ ? info_count_ : 0; }
+
+  const MinidumpMemoryInfo* GetMemoryInfoForAddress(uint64_t address) const;
+  const MinidumpMemoryInfo* GetMemoryInfoAtIndex(unsigned int index) const;
+
+  // Print a human-readable representation of the object to stdout.
+  void Print();
+
+ private:
+  friend class Minidump;
+
+  typedef vector<MinidumpMemoryInfo> MinidumpMemoryInfos;
+
+  static const uint32_t kStreamType = MD_MEMORY_INFO_LIST_STREAM;
+
+  explicit MinidumpMemoryInfoList(Minidump* minidump_);
+
+  bool Read(uint32_t expected_size);
+
+  // Access to memory info using addresses as the key.
+  RangeMap<uint64_t, unsigned int> *range_map_;
+
+  MinidumpMemoryInfos* infos_;
+  uint32_t info_count_;
+};
+
+// MinidumpLinuxMaps wraps information about a single mapped memory region
+// from /proc/self/maps.
+class MinidumpLinuxMaps : public MinidumpObject {
+ public:
+  // The memory address of the base of the mapped region.
+  uint64_t GetBase() const { return valid_ ? region_.start : 0; }
+  // The size of the mapped region.
+  uint64_t GetSize() const { return valid_ ? region_.end - region_.start : 0; }
+
+  // The permissions of the mapped region.
+  bool IsReadable() const {
+    return valid_ ? region_.permissions & MappedMemoryRegion::READ : false;
+  }
+  bool IsWriteable() const {
+    return valid_ ? region_.permissions & MappedMemoryRegion::WRITE : false;
+  }
+  bool IsExecutable() const {
+    return valid_ ? region_.permissions & MappedMemoryRegion::EXECUTE : false;
+  }
+  bool IsPrivate() const {
+    return valid_ ? region_.permissions & MappedMemoryRegion::PRIVATE : false;
+  }
+
+  // The offset of the mapped region.
+  uint64_t GetOffset() const { return valid_ ? region_.offset : 0; }
+
+  // The major device number.
+  uint8_t GetMajorDevice() const { return valid_ ? region_.major_device : 0; }
+  // The minor device number.
+  uint8_t GetMinorDevice() const { return valid_ ? region_.minor_device : 0; }
+
+  // The inode of the mapped region.
+  uint64_t GetInode() const { return valid_ ? region_.inode : 0; }
+
+  // The pathname of the mapped region.
+  const string GetPathname() const { return valid_ ? region_.path : ""; }
+
+  // Print the contents of this mapping.
+  void Print() const;
+
+ private:
+  // These objects are managed by MinidumpLinuxMapsList.
+  friend class MinidumpLinuxMapsList;
+
+  // This caller owns the pointer.
+  explicit MinidumpLinuxMaps(Minidump *minidump);
+
+  // The memory region struct that this class wraps.
+  MappedMemoryRegion region_;
+
+  DISALLOW_COPY_AND_ASSIGN(MinidumpLinuxMaps);
+};
+
+// MinidumpLinuxMapsList corresponds to the Linux-exclusive MD_LINUX_MAPS
+// stream, which contains the contents of /prod/self/maps, which contains
+// the mapped memory regions and their access permissions.
+class MinidumpLinuxMapsList : public MinidumpStream {
+ public:
+  virtual ~MinidumpLinuxMapsList();
+
+  // Get number of mappings.
+  unsigned int get_maps_count() const { return valid_ ? maps_count_ : 0; }
+
+  // Get mapping at the given memory address. The caller owns the pointer.
+  const MinidumpLinuxMaps *GetLinuxMapsForAddress(uint64_t address) const;
+  // Get mapping at the given index. The caller owns the pointer.
+  const MinidumpLinuxMaps *GetLinuxMapsAtIndex(unsigned int index) const;
+
+  // Print the contents of /proc/self/maps to stdout.
+  void Print() const;
+
+ private:
+  friend class Minidump;
+
+  typedef vector<MinidumpLinuxMaps *> MinidumpLinuxMappings;
+
+  static const uint32_t kStreamType = MD_LINUX_MAPS;
+
+  // The caller owns the pointer.
+  explicit MinidumpLinuxMapsList(Minidump *minidump);
+
+  // Read and load the contents of the process mapping data.
+  // The stream should have data in the form of /proc/self/maps.
+  // This method returns whether the stream was read successfully.
+  bool Read(uint32_t expected_size);
+
+  // The list of individual mappings.
+  MinidumpLinuxMappings *maps_;
+  // The number of mappings.
+  uint32_t maps_count_;
+
+  DISALLOW_COPY_AND_ASSIGN(MinidumpLinuxMapsList);
+};
+
+// Minidump is the user's interface to a minidump file.  It wraps MDRawHeader
+// and provides access to the minidump's top-level stream directory.
+class Minidump {
+ public:
+  // path is the pathname of a file containing the minidump.
+  explicit Minidump(const string& path);
+  // input is an istream wrapping minidump data. Minidump holds a
+  // weak pointer to input, and the caller must ensure that the stream
+  // is valid as long as the Minidump object is.
+  explicit Minidump(std::istream& input);
+
+  virtual ~Minidump();
+
+  // path may be empty if the minidump was not opened from a file
+  virtual string path() const {
+    return path_;
+  }
+  static void set_max_streams(uint32_t max_streams) {
+    max_streams_ = max_streams;
+  }
+  static uint32_t max_streams() { return max_streams_; }
+
+  static void set_max_string_length(uint32_t max_string_length) {
+    max_string_length_ = max_string_length;
+  }
+  static uint32_t max_string_length() { return max_string_length_; }
+
+  virtual const MDRawHeader* header() const { return valid_ ? &header_ : NULL; }
+
+  // Reads the CPU information from the system info stream and generates the
+  // appropriate CPU flags.  The returned context_cpu_flags are the same as
+  // if the CPU type bits were set in the context_flags of a context record.
+  // On success, context_cpu_flags will have the flags that identify the CPU.
+  // If a system info stream is missing, context_cpu_flags will be 0.
+  // Returns true if the current position in the stream was not changed.
+  // Returns false when the current location in the stream was changed and the
+  // attempt to restore the original position failed.
+  bool GetContextCPUFlagsFromSystemInfo(uint32_t* context_cpu_flags);
+
+  // Reads the minidump file's header and top-level stream directory.
+  // The minidump is expected to be positioned at the beginning of the
+  // header.  Read() sets up the stream list and map, and validates the
+  // Minidump object.
+  virtual bool Read();
+
+  // The next set of methods are stubs that call GetStream.  They exist to
+  // force code generation of the templatized API within the module, and
+  // to avoid exposing an ugly API (GetStream needs to accept a garbage
+  // parameter).
+  virtual MinidumpThreadList* GetThreadList();
+  virtual MinidumpModuleList* GetModuleList();
+  virtual MinidumpMemoryList* GetMemoryList();
+  virtual MinidumpException* GetException();
+  virtual MinidumpAssertion* GetAssertion();
+  virtual MinidumpSystemInfo* GetSystemInfo();
+  virtual MinidumpMiscInfo* GetMiscInfo();
+  virtual MinidumpBreakpadInfo* GetBreakpadInfo();
+  virtual MinidumpMemoryInfoList* GetMemoryInfoList();
+
+  // The next method also calls GetStream, but is exclusive for Linux dumps.
+  virtual MinidumpLinuxMapsList *GetLinuxMapsList();
+
+  // The next set of methods are provided for users who wish to access
+  // data in minidump files directly, while leveraging the rest of
+  // this class and related classes to handle the basic minidump
+  // structure and known stream types.
+
+  unsigned int GetDirectoryEntryCount() const {
+    return valid_ ? header_.stream_count : 0;
+  }
+  const MDRawDirectory* GetDirectoryEntryAtIndex(unsigned int index) const;
+
+  // The next 2 methods are lower-level I/O routines.  They use fd_.
+
+  // Reads count bytes from the minidump at the current position into
+  // the storage area pointed to by bytes.  bytes must be of sufficient
+  // size.  After the read, the file position is advanced by count.
+  bool ReadBytes(void* bytes, size_t count);
+
+  // Sets the position of the minidump file to offset.
+  bool SeekSet(off_t offset);
+
+  // Returns the current position of the minidump file.
+  off_t Tell();
+
+  // The next 2 methods are medium-level I/O routines.
+
+  // ReadString returns a string which is owned by the caller!  offset
+  // specifies the offset that a length-encoded string is stored at in the
+  // minidump file.
+  string* ReadString(off_t offset);
+
+  // SeekToStreamType positions the file at the beginning of a stream
+  // identified by stream_type, and informs the caller of the stream's
+  // length by setting *stream_length.  Because stream_map maps each stream
+  // type to only one stream in the file, this might mislead the user into
+  // thinking that the stream that this seeks to is the only stream with
+  // type stream_type.  That can't happen for streams that these classes
+  // deal with directly, because they're only supposed to be present in the
+  // file singly, and that's verified when stream_map_ is built.  Users who
+  // are looking for other stream types should be aware of this
+  // possibility, and consider using GetDirectoryEntryAtIndex (possibly
+  // with GetDirectoryEntryCount) if expecting multiple streams of the same
+  // type in a single minidump file.
+  bool SeekToStreamType(uint32_t stream_type, uint32_t* stream_length);
+
+  bool swap() const { return valid_ ? swap_ : false; }
+
+  // Print a human-readable representation of the object to stdout.
+  void Print();
+
+ private:
+  // MinidumpStreamInfo is used in the MinidumpStreamMap.  It lets
+  // the Minidump object locate interesting streams quickly, and
+  // provides a convenient place to stash MinidumpStream objects.
+  struct MinidumpStreamInfo {
+    MinidumpStreamInfo() : stream_index(0), stream(NULL) {}
+    ~MinidumpStreamInfo() { delete stream; }
+
+    // Index into the MinidumpDirectoryEntries vector
+    unsigned int    stream_index;
+
+    // Pointer to the stream if cached, or NULL if not yet populated
+    MinidumpStream* stream;
+  };
+
+  typedef vector<MDRawDirectory> MinidumpDirectoryEntries;
+  typedef map<uint32_t, MinidumpStreamInfo> MinidumpStreamMap;
+
+  template<typename T> T* GetStream(T** stream);
+
+  // Opens the minidump file, or if already open, seeks to the beginning.
+  bool Open();
+
+  // The largest number of top-level streams that will be read from a minidump.
+  // Note that streams are only read (and only consume memory) as needed,
+  // when directed by the caller.  The default is 128.
+  static uint32_t max_streams_;
+
+  // The maximum length of a UTF-16 string that will be read from a minidump
+  // in 16-bit words.  The default is 1024.  UTF-16 strings are converted
+  // to UTF-8 when stored in memory, and each UTF-16 word will be represented
+  // by as many as 3 bytes in UTF-8.
+  static unsigned int max_string_length_;
+
+  MDRawHeader               header_;
+
+  // The list of streams.
+  MinidumpDirectoryEntries* directory_;
+
+  // Access to streams using the stream type as the key.
+  MinidumpStreamMap*        stream_map_;
+
+  // The pathname of the minidump file to process, set in the constructor.
+  // This may be empty if the minidump was opened directly from a stream.
+  const string              path_;
+
+  // The stream for all file I/O.  Used by ReadBytes and SeekSet.
+  // Set based on the path in Open, or directly in the constructor.
+  std::istream*             stream_;
+
+  // swap_ is true if the minidump file should be byte-swapped.  If the
+  // minidump was produced by a CPU that is other-endian than the CPU
+  // processing the minidump, this will be true.  If the two CPUs are
+  // same-endian, this will be false.
+  bool                      swap_;
+
+  // Validity of the Minidump structure, false immediately after
+  // construction or after a failed Read(); true following a successful
+  // Read().
+  bool                      valid_;
+};
+
+
+}  // namespace google_breakpad
+
+
+#endif  // GOOGLE_BREAKPAD_PROCESSOR_MINIDUMP_H__
diff --git a/include/breakpad/google_breakpad/processor/minidump_processor.h b/include/breakpad/google_breakpad/processor/minidump_processor.h
new file mode 100644
index 0000000..387115e
--- /dev/null
+++ b/include/breakpad/google_breakpad/processor/minidump_processor.h
@@ -0,0 +1,147 @@
+// 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.
+
+#ifndef GOOGLE_BREAKPAD_PROCESSOR_MINIDUMP_PROCESSOR_H__
+#define GOOGLE_BREAKPAD_PROCESSOR_MINIDUMP_PROCESSOR_H__
+
+#include <assert.h>
+#include <string>
+
+#include "common/using_std_string.h"
+#include "google_breakpad/common/breakpad_types.h"
+#include "google_breakpad/processor/process_result.h"
+
+namespace google_breakpad {
+
+class Minidump;
+class ProcessState;
+class StackFrameSymbolizer;
+class SourceLineResolverInterface;
+class SymbolSupplier;
+struct SystemInfo;
+
+class MinidumpProcessor {
+ public:
+  // Initializes this MinidumpProcessor.  supplier should be an
+  // implementation of the SymbolSupplier abstract base class.
+  MinidumpProcessor(SymbolSupplier* supplier,
+                    SourceLineResolverInterface* resolver);
+
+  // Initializes the MinidumpProcessor with the option of
+  // enabling the exploitability framework to analyze dumps
+  // for probable security relevance.
+  MinidumpProcessor(SymbolSupplier* supplier,
+                    SourceLineResolverInterface* resolver,
+                    bool enable_exploitability);
+
+  // Initializes the MinidumpProcessor with source line resolver helper, and
+  // the option of enabling the exploitability framework to analyze dumps
+  // for probable security relevance.
+  // Does not take ownership of resolver_helper, which must NOT be NULL.
+  MinidumpProcessor(StackFrameSymbolizer* stack_frame_symbolizer,
+                    bool enable_exploitability);
+
+  ~MinidumpProcessor();
+
+  // Processes the minidump file and fills process_state with the result.
+  ProcessResult Process(const string &minidump_file,
+                        ProcessState* process_state);
+
+  // Processes the minidump structure and fills process_state with the
+  // result.
+  ProcessResult Process(Minidump* minidump,
+                        ProcessState* process_state);
+  // Populates the cpu_* fields of the |info| parameter with textual
+  // representations of the CPU type that the minidump in |dump| was
+  // produced on.  Returns false if this information is not available in
+  // the minidump.
+  static bool GetCPUInfo(Minidump* dump, SystemInfo* info);
+
+  // Populates the os_* fields of the |info| parameter with textual
+  // representations of the operating system that the minidump in |dump|
+  // was produced on.  Returns false if this information is not available in
+  // the minidump.
+  static bool GetOSInfo(Minidump* dump, SystemInfo* info);
+
+  // Populates the |process_create_time| parameter with the create time of the
+  // crashed process.  Returns false if this information is not available in
+  // the minidump |dump|.
+  static bool GetProcessCreateTime(Minidump* dump,
+                                   uint32_t* process_create_time);
+
+  // Returns a textual representation of the reason that a crash occurred,
+  // if the minidump in dump was produced as a result of a crash.  Returns
+  // an empty string if this information cannot be determined.  If address
+  // is non-NULL, it will be set to contain the address that caused the
+  // exception, if this information is available.  This will be a code
+  // address when the crash was caused by problems such as illegal
+  // instructions or divisions by zero, or a data address when the crash
+  // was caused by a memory access violation.
+  static string GetCrashReason(Minidump* dump, uint64_t* address);
+
+  // This function returns true if the passed-in error code is
+  // something unrecoverable(i.e. retry should not happen).  For
+  // instance, if the minidump is corrupt, then it makes no sense to
+  // retry as we won't be able to glean additional information.
+  // However, as an example of the other case, the symbol supplier can
+  // return an error code indicating it was 'interrupted', which can
+  // happen of the symbols are fetched from a remote store, and a
+  // retry might be successful later on.
+  // You should not call this method with PROCESS_OK! Test for
+  // that separately before calling this.
+  static bool IsErrorUnrecoverable(ProcessResult p) {
+    assert(p !=  PROCESS_OK);
+    return (p != PROCESS_SYMBOL_SUPPLIER_INTERRUPTED);
+  }
+
+  // Returns a textual representation of an assertion included
+  // in the minidump.  Returns an empty string if this information
+  // does not exist or cannot be determined.
+  static string GetAssertion(Minidump* dump);
+
+  void set_enable_objdump(bool enabled) { enable_objdump_ = enabled; }
+
+ private:
+  StackFrameSymbolizer* frame_symbolizer_;
+  // Indicate whether resolver_helper_ is owned by this instance.
+  bool own_frame_symbolizer_;
+
+  // This flag enables the exploitability scanner which attempts to
+  // guess how likely it is that the crash represents an exploitable
+  // memory corruption issue.
+  bool enable_exploitability_;
+
+  // This flag permits the exploitability scanner to shell out to objdump
+  // for purposes of disassembly.
+  bool enable_objdump_;
+};
+
+}  // namespace google_breakpad
+
+#endif  // GOOGLE_BREAKPAD_PROCESSOR_MINIDUMP_PROCESSOR_H__
diff --git a/include/breakpad/google_breakpad/processor/proc_maps_linux.h b/include/breakpad/google_breakpad/processor/proc_maps_linux.h
new file mode 100644
index 0000000..b8e6eb9
--- /dev/null
+++ b/include/breakpad/google_breakpad/processor/proc_maps_linux.h
@@ -0,0 +1,60 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef BASE_DEBUG_PROC_MAPS_LINUX_H_
+#define BASE_DEBUG_PROC_MAPS_LINUX_H_
+
+#include <string>
+#include <vector>
+
+#include "common/using_std_string.h"
+#include "google_breakpad/common/breakpad_types.h"
+
+namespace google_breakpad {
+
+// Describes a region of mapped memory and the path of the file mapped.
+struct MappedMemoryRegion {
+  enum Permission {
+    READ = 1 << 0,
+    WRITE = 1 << 1,
+    EXECUTE = 1 << 2,
+    PRIVATE = 1 << 3,  // If set, region is private, otherwise it is shared.
+  };
+
+  // The address range [start,end) of mapped memory.
+  uint64_t start;
+  uint64_t end;
+
+  // Byte offset into |path| of the range mapped into memory.
+  uint64_t offset;
+
+  // Bitmask of read/write/execute/private/shared permissions.
+  uint8_t permissions;
+
+  // Major and minor devices.
+  uint8_t major_device;
+  uint8_t minor_device;
+
+  // Value of the inode.
+  uint64_t inode;
+
+  // Name of the file mapped into memory.
+  //
+  // NOTE: path names aren't guaranteed to point at valid files. For example,
+  // "[heap]" and "[stack]" are used to represent the location of the process'
+  // heap and stack, respectively.
+  string path;
+
+  // The line from /proc/<pid>/maps that this struct represents.
+  string line;
+};
+
+// Parses /proc/<pid>/maps input data and stores in |regions|. Returns true
+// and updates |regions| if and only if all of |input| was successfully parsed.
+bool ParseProcMaps(const std::string& input,
+                   std::vector<MappedMemoryRegion>* regions);
+
+}  // namespace google_breakpad
+
+#endif  // BASE_DEBUG_PROC_MAPS_LINUX_H_
diff --git a/include/breakpad/google_breakpad/processor/process_result.h b/include/breakpad/google_breakpad/processor/process_result.h
new file mode 100644
index 0000000..15c7213
--- /dev/null
+++ b/include/breakpad/google_breakpad/processor/process_result.h
@@ -0,0 +1,66 @@
+// Copyright (c) 2014, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef GOOGLE_BREAKPAD_PROCESSOR_PROCESS_RESULT_H__
+#define GOOGLE_BREAKPAD_PROCESSOR_PROCESS_RESULT_H__
+
+namespace google_breakpad {
+
+// Return type for MinidumpProcessor or MicrodumpProcessor's Process()
+enum ProcessResult {
+  PROCESS_OK,                                  // The dump was processed
+                                               // successfully.
+
+  PROCESS_ERROR_MINIDUMP_NOT_FOUND,            // The minidump file was not
+                                               // found.
+
+  PROCESS_ERROR_NO_MINIDUMP_HEADER,            // The minidump file had no
+                                               // header.
+
+  PROCESS_ERROR_NO_THREAD_LIST,                // The minidump file has no
+                                               // thread list.
+
+  PROCESS_ERROR_GETTING_THREAD,                // There was an error getting one
+                                               // thread's data from th dump.
+
+  PROCESS_ERROR_GETTING_THREAD_ID,             // There was an error getting a
+                                               // thread id from the thread's
+                                               // data.
+
+  PROCESS_ERROR_DUPLICATE_REQUESTING_THREADS,  // There was more than one
+                                               // requesting thread.
+
+  PROCESS_SYMBOL_SUPPLIER_INTERRUPTED          // The dump processing was
+                                               // interrupted by the
+                                               // SymbolSupplier(not fatal).
+};
+
+}  // namespace google_breakpad
+
+#endif  // GOOGLE_BREAKPAD_PROCESSOR_PROCESS_RESULT_H__
diff --git a/include/breakpad/google_breakpad/processor/process_state.h b/include/breakpad/google_breakpad/processor/process_state.h
new file mode 100644
index 0000000..728656f
--- /dev/null
+++ b/include/breakpad/google_breakpad/processor/process_state.h
@@ -0,0 +1,189 @@
+// 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.
+
+// process_state.h: A snapshot of a process, in a fully-digested state.
+//
+// Author: Mark Mentovai
+
+#ifndef GOOGLE_BREAKPAD_PROCESSOR_PROCESS_STATE_H__
+#define GOOGLE_BREAKPAD_PROCESSOR_PROCESS_STATE_H__
+
+#include <string>
+#include <vector>
+
+#include "common/using_std_string.h"
+#include "google_breakpad/common/breakpad_types.h"
+#include "google_breakpad/processor/system_info.h"
+#include "google_breakpad/processor/minidump.h"
+
+namespace google_breakpad {
+
+using std::vector;
+
+class CallStack;
+class CodeModules;
+
+enum ExploitabilityRating {
+  EXPLOITABILITY_HIGH,                 // The crash likely represents
+                                       // a exploitable memory corruption
+                                       // vulnerability.
+
+  EXPLOITABILITY_MEDIUM,               // The crash appears to corrupt
+                                       // memory in a way which may be
+                                       // exploitable in some situations.
+
+  EXPLOITABLITY_MEDIUM = EXPLOITABILITY_MEDIUM,  // an old misspelling
+
+  EXPLOITABILITY_LOW,                  // The crash either does not corrupt
+                                       // memory directly or control over
+                                       // the affected data is limited. The
+                                       // issue may still be exploitable
+                                       // on certain platforms or situations.
+
+  EXPLOITABILITY_INTERESTING,          // The crash does not appear to be
+                                       // directly exploitable. However it
+                                       // represents a condition which should
+                                       // be further analyzed.
+
+  EXPLOITABILITY_NONE,                 // The crash does not appear to represent
+                                       // an exploitable condition.
+
+  EXPLOITABILITY_NOT_ANALYZED,         // The crash was not analyzed for
+                                       // exploitability because the engine
+                                       // was disabled.
+
+  EXPLOITABILITY_ERR_NOENGINE,         // The supplied minidump's platform does
+                                       // not have a exploitability engine
+                                       // associated with it.
+
+  EXPLOITABILITY_ERR_PROCESSING        // An error occured within the
+                                       // exploitability engine and no rating
+                                       // was calculated.
+};
+
+class ProcessState {
+ public:
+  ProcessState() : modules_(NULL) { Clear(); }
+  ~ProcessState();
+
+  // Resets the ProcessState to its default values
+  void Clear();
+
+  // Accessors.  See the data declarations below.
+  uint32_t time_date_stamp() const { return time_date_stamp_; }
+  uint32_t process_create_time() const { return process_create_time_; }
+  bool crashed() const { return crashed_; }
+  string crash_reason() const { return crash_reason_; }
+  uint64_t crash_address() const { return crash_address_; }
+  string assertion() const { return assertion_; }
+  int requesting_thread() const { return requesting_thread_; }
+  const vector<CallStack*>* threads() const { return &threads_; }
+  const vector<MemoryRegion*>* thread_memory_regions() const {
+    return &thread_memory_regions_;
+  }
+  const SystemInfo* system_info() const { return &system_info_; }
+  const CodeModules* modules() const { return modules_; }
+  const vector<const CodeModule*>* modules_without_symbols() const {
+    return &modules_without_symbols_;
+  }
+  const vector<const CodeModule*>* modules_with_corrupt_symbols() const {
+    return &modules_with_corrupt_symbols_;
+  }
+  ExploitabilityRating exploitability() const { return exploitability_; }
+
+ private:
+  // MinidumpProcessor and MicrodumpProcessor are responsible for building
+  // ProcessState objects.
+  friend class MinidumpProcessor;
+  friend class MicrodumpProcessor;
+
+  // The time-date stamp of the minidump (time_t format)
+  uint32_t time_date_stamp_;
+
+  // The time-date stamp when the process was created (time_t format)
+  uint32_t process_create_time_;
+
+  // True if the process crashed, false if the dump was produced outside
+  // of an exception handler.
+  bool crashed_;
+
+  // If the process crashed, the type of crash.  OS- and possibly CPU-
+  // specific.  For example, "EXCEPTION_ACCESS_VIOLATION" (Windows),
+  // "EXC_BAD_ACCESS / KERN_INVALID_ADDRESS" (Mac OS X), "SIGSEGV"
+  // (other Unix).
+  string crash_reason_;
+
+  // If the process crashed, and if crash_reason implicates memory,
+  // the memory address that caused the crash.  For data access errors,
+  // this will be the data address that caused the fault.  For code errors,
+  // this will be the address of the instruction that caused the fault.
+  uint64_t crash_address_;
+
+  // If there was an assertion that was hit, a textual representation
+  // of that assertion, possibly including the file and line at which
+  // it occurred.
+  string assertion_;
+
+  // The index of the thread that requested a dump be written in the
+  // threads vector.  If a dump was produced as a result of a crash, this
+  // will point to the thread that crashed.  If the dump was produced as
+  // by user code without crashing, and the dump contains extended Breakpad
+  // information, this will point to the thread that requested the dump.
+  // If the dump was not produced as a result of an exception and no
+  // extended Breakpad information is present, this field will be set to -1,
+  // indicating that the dump thread is not available.
+  int requesting_thread_;
+
+  // Stacks for each thread (except possibly the exception handler
+  // thread) at the time of the crash.
+  vector<CallStack*> threads_;
+  vector<MemoryRegion*> thread_memory_regions_;
+
+  // OS and CPU information.
+  SystemInfo system_info_;
+
+  // The modules that were loaded into the process represented by the
+  // ProcessState.
+  const CodeModules *modules_;
+
+  // The modules that didn't have symbols when the report was processed.
+  vector<const CodeModule*> modules_without_symbols_;
+
+  // The modules that had corrupt symbols when the report was processed.
+  vector<const CodeModule*> modules_with_corrupt_symbols_;
+
+  // The exploitability rating as determined by the exploitability
+  // engine. When the exploitability engine is not enabled this
+  // defaults to EXPLOITABILITY_NOT_ANALYZED.
+  ExploitabilityRating exploitability_;
+};
+
+}  // namespace google_breakpad
+
+#endif  // GOOGLE_BREAKPAD_PROCESSOR_PROCESS_STATE_H__
diff --git a/include/breakpad/google_breakpad/processor/source_line_resolver_base.h b/include/breakpad/google_breakpad/processor/source_line_resolver_base.h
new file mode 100644
index 0000000..c720b0c
--- /dev/null
+++ b/include/breakpad/google_breakpad/processor/source_line_resolver_base.h
@@ -0,0 +1,128 @@
+// 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.
+//
+// source_line_resolver_base.h: SourceLineResolverBase, an (incomplete)
+// implementation of SourceLineResolverInterface.  It serves as a common base
+// class for concrete implementations: FastSourceLineResolver and
+// BasicSourceLineResolver.  It is designed for refactoring that removes
+// code redundancy in the two concrete source line resolver classes.
+//
+// See "google_breakpad/processor/source_line_resolver_interface.h" for more
+// documentation.
+
+// Author: Siyang Xie (lambxsy@google.com)
+
+#ifndef GOOGLE_BREAKPAD_PROCESSOR_SOURCE_LINE_RESOLVER_BASE_H__
+#define GOOGLE_BREAKPAD_PROCESSOR_SOURCE_LINE_RESOLVER_BASE_H__
+
+#include <map>
+#include <set>
+#include <string>
+
+#include "google_breakpad/processor/source_line_resolver_interface.h"
+
+namespace google_breakpad {
+
+using std::map;
+using std::set;
+
+// Forward declaration.
+// ModuleFactory is a simple factory interface for creating a Module instance
+// at run-time.
+class ModuleFactory;
+
+class SourceLineResolverBase : public SourceLineResolverInterface {
+ public:
+  // Read the symbol_data from a file with given file_name.
+  // The part of code was originally in BasicSourceLineResolver::Module's
+  // LoadMap() method.
+  // Place dynamically allocated heap buffer in symbol_data. Caller has the
+  // ownership of the buffer, and should call delete [] to free the buffer.
+  static bool ReadSymbolFile(const string &file_name,
+                             char **symbol_data,
+                             size_t *symbol_data_size);
+
+ protected:
+  // Users are not allowed create SourceLineResolverBase instance directly.
+  SourceLineResolverBase(ModuleFactory *module_factory);
+  virtual ~SourceLineResolverBase();
+
+  // Virtual methods inherited from SourceLineResolverInterface.
+  virtual bool LoadModule(const CodeModule *module, const string &map_file);
+  virtual bool LoadModuleUsingMapBuffer(const CodeModule *module,
+                                        const string &map_buffer);
+  virtual bool LoadModuleUsingMemoryBuffer(const CodeModule *module,
+                                           char *memory_buffer,
+                                           size_t memory_buffer_size);
+  virtual bool ShouldDeleteMemoryBufferAfterLoadModule();
+  virtual void UnloadModule(const CodeModule *module);
+  virtual bool HasModule(const CodeModule *module);
+  virtual bool IsModuleCorrupt(const CodeModule *module);
+  virtual void FillSourceLineInfo(StackFrame *frame);
+  virtual WindowsFrameInfo *FindWindowsFrameInfo(const StackFrame *frame);
+  virtual CFIFrameInfo *FindCFIFrameInfo(const StackFrame *frame);
+
+  // Nested structs and classes.
+  struct Line;
+  struct Function;
+  struct PublicSymbol;
+  struct CompareString {
+    bool operator()(const string &s1, const string &s2) const;
+  };
+  // Module is an interface for an in-memory symbol file.
+  class Module;
+  class AutoFileCloser;
+
+  // All of the modules that are loaded.
+  typedef map<string, Module*, CompareString> ModuleMap;
+  ModuleMap *modules_;
+
+  // The loaded modules that were detecting to be corrupt during load.
+  typedef set<string, CompareString> ModuleSet;
+  ModuleSet *corrupt_modules_;
+
+  // All of heap-allocated buffers that are owned locally by resolver.
+  typedef std::map<string, char*, CompareString> MemoryMap;
+  MemoryMap *memory_buffers_;
+
+  // Creates a concrete module at run-time.
+  ModuleFactory *module_factory_;
+
+ private:
+  // ModuleFactory needs to have access to protected type Module.
+  friend class ModuleFactory;
+
+  // Disallow unwanted copy ctor and assignment operator
+  SourceLineResolverBase(const SourceLineResolverBase&);
+  void operator=(const SourceLineResolverBase&);
+};
+
+}  // namespace google_breakpad
+
+#endif  // GOOGLE_BREAKPAD_PROCESSOR_SOURCE_LINE_RESOLVER_BASE_H__
diff --git a/include/breakpad/google_breakpad/processor/source_line_resolver_interface.h b/include/breakpad/google_breakpad/processor/source_line_resolver_interface.h
new file mode 100644
index 0000000..a694bf2
--- /dev/null
+++ b/include/breakpad/google_breakpad/processor/source_line_resolver_interface.h
@@ -0,0 +1,117 @@
+// -*- 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.
+
+// Abstract interface to return function/file/line info for a memory address.
+
+#ifndef GOOGLE_BREAKPAD_PROCESSOR_SOURCE_LINE_RESOLVER_INTERFACE_H__
+#define GOOGLE_BREAKPAD_PROCESSOR_SOURCE_LINE_RESOLVER_INTERFACE_H__
+
+#include <string>
+
+#include "common/using_std_string.h"
+#include "google_breakpad/common/breakpad_types.h"
+#include "google_breakpad/processor/code_module.h"
+
+namespace google_breakpad {
+
+struct StackFrame;
+struct WindowsFrameInfo;
+class CFIFrameInfo;
+
+class SourceLineResolverInterface {
+ public:
+  typedef uint64_t MemAddr;
+
+  virtual ~SourceLineResolverInterface() {}
+
+  // Adds a module to this resolver, returning true on success.
+  //
+  // module should have at least the code_file, debug_file,
+  // and debug_identifier members populated.
+  //
+  // map_file should contain line/address mappings for this module.
+  virtual bool LoadModule(const CodeModule *module,
+                          const string &map_file) = 0;
+  // Same as above, but takes the contents of a pre-read map buffer
+  virtual bool LoadModuleUsingMapBuffer(const CodeModule *module,
+                                        const string &map_buffer) = 0;
+
+  // Add an interface to load symbol using C-String data instead of string.
+  // This is useful in the optimization design for avoiding unnecessary copying
+  // of symbol data, in order to improve memory efficiency.
+  // LoadModuleUsingMemoryBuffer() does NOT take ownership of memory_buffer.
+  // LoadModuleUsingMemoryBuffer() null terminates the passed in buffer, if
+  // the last character is not a null terminator.
+  virtual bool LoadModuleUsingMemoryBuffer(const CodeModule *module,
+                                           char *memory_buffer,
+                                           size_t memory_buffer_size) = 0;
+
+  // Return true if the memory buffer should be deleted immediately after
+  // LoadModuleUsingMemoryBuffer(). Return false if the memory buffer has to be
+  // alive during the lifetime of the corresponding Module.
+  virtual bool ShouldDeleteMemoryBufferAfterLoadModule() = 0;
+
+  // Request that the specified module be unloaded from this resolver.
+  // A resolver may choose to ignore such a request.
+  virtual void UnloadModule(const CodeModule *module) = 0;
+
+  // Returns true if the module has been loaded.
+  virtual bool HasModule(const CodeModule *module) = 0;
+
+  // Returns true if the module has been loaded and it is corrupt.
+  virtual bool IsModuleCorrupt(const CodeModule *module) = 0;
+
+  // Fills in the function_base, function_name, source_file_name,
+  // and source_line fields of the StackFrame.  The instruction and
+  // module_name fields must already be filled in.
+  virtual void FillSourceLineInfo(StackFrame *frame) = 0;
+
+  // If Windows stack walking information is available covering
+  // FRAME's instruction address, return a WindowsFrameInfo structure
+  // describing it. If the information is not available, returns NULL.
+  // A NULL return value does not indicate an error. The caller takes
+  // ownership of any returned WindowsFrameInfo object.
+  virtual WindowsFrameInfo *FindWindowsFrameInfo(const StackFrame *frame) = 0;
+
+  // If CFI stack walking information is available covering ADDRESS,
+  // return a CFIFrameInfo structure describing it. If the information
+  // is not available, return NULL. The caller takes ownership of any
+  // returned CFIFrameInfo object.
+  virtual CFIFrameInfo *FindCFIFrameInfo(const StackFrame *frame) = 0;
+
+ protected:
+  // SourceLineResolverInterface cannot be instantiated except by subclasses
+  SourceLineResolverInterface() {}
+};
+
+}  // namespace google_breakpad
+
+#endif  // GOOGLE_BREAKPAD_PROCESSOR_SOURCE_LINE_RESOLVER_INTERFACE_H__
diff --git a/include/breakpad/google_breakpad/processor/stack_frame.h b/include/breakpad/google_breakpad/processor/stack_frame.h
new file mode 100644
index 0000000..b55eb9c
--- /dev/null
+++ b/include/breakpad/google_breakpad/processor/stack_frame.h
@@ -0,0 +1,144 @@
+// 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.
+
+#ifndef GOOGLE_BREAKPAD_PROCESSOR_STACK_FRAME_H__
+#define GOOGLE_BREAKPAD_PROCESSOR_STACK_FRAME_H__
+
+#include <string>
+
+#include "common/using_std_string.h"
+#include "google_breakpad/common/breakpad_types.h"
+
+namespace google_breakpad {
+
+class CodeModule;
+
+struct StackFrame {
+  // Indicates how well the instruction pointer derived during
+  // stack walking is trusted. Since the stack walker can resort to
+  // stack scanning, it can wind up with dubious frames.
+  // In rough order of "trust metric".
+  enum FrameTrust {
+    FRAME_TRUST_NONE,      // Unknown
+    FRAME_TRUST_SCAN,      // Scanned the stack, found this
+    FRAME_TRUST_CFI_SCAN,  // Found while scanning stack using call frame info
+    FRAME_TRUST_FP,        // Derived from frame pointer
+    FRAME_TRUST_CFI,       // Derived from call frame info
+    FRAME_TRUST_PREWALKED, // Explicitly provided by some external stack walker.
+    FRAME_TRUST_CONTEXT    // Given as instruction pointer in a context
+  };
+
+  StackFrame()
+      : instruction(),
+        module(NULL),
+        function_name(),
+        function_base(),
+        source_file_name(),
+        source_line(),
+        source_line_base(),
+        trust(FRAME_TRUST_NONE) {}
+  virtual ~StackFrame() {}
+
+  // Return a string describing how this stack frame was found
+  // by the stackwalker.
+  string trust_description() const {
+    switch (trust) {
+      case StackFrame::FRAME_TRUST_CONTEXT:
+        return "given as instruction pointer in context";
+      case StackFrame::FRAME_TRUST_PREWALKED:
+        return "recovered by external stack walker";
+      case StackFrame::FRAME_TRUST_CFI:
+        return "call frame info";
+      case StackFrame::FRAME_TRUST_CFI_SCAN:
+        return "call frame info with scanning";
+      case StackFrame::FRAME_TRUST_FP:
+        return "previous frame's frame pointer";
+      case StackFrame::FRAME_TRUST_SCAN:
+        return "stack scanning";
+      default:
+        return "unknown";
+    }
+  };
+
+  // Return the actual return address, as saved on the stack or in a
+  // register. See the comments for 'instruction', below, for details.
+  virtual uint64_t ReturnAddress() const { return instruction; }
+
+  // The program counter location as an absolute virtual address.
+  //
+  // - For the innermost called frame in a stack, this will be an exact
+  //   program counter or instruction pointer value.
+  //
+  // - For all other frames, this address is within the instruction that
+  //   caused execution to branch to this frame's callee (although it may
+  //   not point to the exact beginning of that instruction). This ensures
+  //   that, when we look up the source code location for this frame, we
+  //   get the source location of the call, not of the point at which
+  //   control will resume when the call returns, which may be on the next
+  //   line. (If the compiler knows the callee never returns, it may even
+  //   place the call instruction at the very end of the caller's machine
+  //   code, such that the "return address" (which will never be used)
+  //   immediately after the call instruction is in an entirely different
+  //   function, perhaps even from a different source file.)
+  //
+  // On some architectures, the return address as saved on the stack or in
+  // a register is fine for looking up the point of the call. On others, it
+  // requires adjustment. ReturnAddress returns the address as saved by the
+  // machine.
+  uint64_t instruction;
+
+  // The module in which the instruction resides.
+  const CodeModule *module;
+
+  // The function name, may be omitted if debug symbols are not available.
+  string function_name;
+
+  // The start address of the function, may be omitted if debug symbols
+  // are not available.
+  uint64_t function_base;
+
+  // The source file name, may be omitted if debug symbols are not available.
+  string source_file_name;
+
+  // The (1-based) source line number, may be omitted if debug symbols are
+  // not available.
+  int source_line;
+
+  // The start address of the source line, may be omitted if debug symbols
+  // are not available.
+  uint64_t source_line_base;
+
+  // Amount of trust the stack walker has in the instruction pointer
+  // of this frame.
+  FrameTrust trust;
+};
+
+}  // namespace google_breakpad
+
+#endif  // GOOGLE_BREAKPAD_PROCESSOR_STACK_FRAME_H__
diff --git a/include/breakpad/google_breakpad/processor/stack_frame_cpu.h b/include/breakpad/google_breakpad/processor/stack_frame_cpu.h
new file mode 100644
index 0000000..dc5d8ae
--- /dev/null
+++ b/include/breakpad/google_breakpad/processor/stack_frame_cpu.h
@@ -0,0 +1,405 @@
+// -*- 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.
+
+// stack_frame_cpu.h: CPU-specific StackFrame extensions.
+//
+// These types extend the StackFrame structure to carry CPU-specific register
+// state.  They are defined in this header instead of stack_frame.h to
+// avoid the need to include minidump_format.h when only the generic
+// StackFrame type is needed.
+//
+// Author: Mark Mentovai
+
+#ifndef GOOGLE_BREAKPAD_PROCESSOR_STACK_FRAME_CPU_H__
+#define GOOGLE_BREAKPAD_PROCESSOR_STACK_FRAME_CPU_H__
+
+#include "google_breakpad/common/minidump_format.h"
+#include "google_breakpad/processor/stack_frame.h"
+
+namespace google_breakpad {
+
+struct WindowsFrameInfo;
+class CFIFrameInfo;
+
+struct StackFrameX86 : public StackFrame {
+  // ContextValidity has one entry for each relevant hardware pointer
+  // register (%eip and %esp) and one entry for each general-purpose
+  // register. It's worthwhile having validity flags for caller-saves
+  // registers: they are valid in the youngest frame, and such a frame
+  // might save a callee-saves register in a caller-saves register, but
+  // SimpleCFIWalker won't touch registers unless they're marked as valid.
+  enum ContextValidity {
+    CONTEXT_VALID_NONE = 0,
+    CONTEXT_VALID_EIP  = 1 << 0,
+    CONTEXT_VALID_ESP  = 1 << 1,
+    CONTEXT_VALID_EBP  = 1 << 2,
+    CONTEXT_VALID_EAX  = 1 << 3,
+    CONTEXT_VALID_EBX  = 1 << 4,
+    CONTEXT_VALID_ECX  = 1 << 5,
+    CONTEXT_VALID_EDX  = 1 << 6,
+    CONTEXT_VALID_ESI  = 1 << 7,
+    CONTEXT_VALID_EDI  = 1 << 8,
+    CONTEXT_VALID_ALL  = -1
+  };
+
+  StackFrameX86()
+     : context(),
+       context_validity(CONTEXT_VALID_NONE),
+       windows_frame_info(NULL),
+       cfi_frame_info(NULL) {}
+  ~StackFrameX86();
+
+  // Overriden to return the return address as saved on the stack.
+  virtual uint64_t ReturnAddress() const;
+
+  // Register state.  This is only fully valid for the topmost frame in a
+  // stack.  In other frames, the values of nonvolatile registers may be
+  // present, given sufficient debugging information.  Refer to
+  // context_validity.
+  MDRawContextX86 context;
+
+  // context_validity is actually ContextValidity, but int is used because
+  // the OR operator doesn't work well with enumerated types.  This indicates
+  // which fields in context are valid.
+  int context_validity;
+
+  // Any stack walking information we found describing this.instruction.
+  // These may be NULL if there is no such information for that address.
+  WindowsFrameInfo *windows_frame_info;
+  CFIFrameInfo *cfi_frame_info;
+};
+
+struct StackFramePPC : public StackFrame {
+  // ContextValidity should eventually contain entries for the validity of
+  // other nonvolatile (callee-save) registers as in
+  // StackFrameX86::ContextValidity, but the ppc stackwalker doesn't currently
+  // locate registers other than the ones listed here.
+  enum ContextValidity {
+    CONTEXT_VALID_NONE = 0,
+    CONTEXT_VALID_SRR0 = 1 << 0,
+    CONTEXT_VALID_GPR1 = 1 << 1,
+    CONTEXT_VALID_ALL  = -1
+  };
+
+  StackFramePPC() : context(), context_validity(CONTEXT_VALID_NONE) {}
+
+  // Register state.  This is only fully valid for the topmost frame in a
+  // stack.  In other frames, the values of nonvolatile registers may be
+  // present, given sufficient debugging information.  Refer to
+  // context_validity.
+  MDRawContextPPC context;
+
+  // context_validity is actually ContextValidity, but int is used because
+  // the OR operator doesn't work well with enumerated types.  This indicates
+  // which fields in context are valid.
+  int context_validity;
+};
+
+struct StackFramePPC64 : public StackFrame {
+  // ContextValidity should eventually contain entries for the validity of
+  // other nonvolatile (callee-save) registers as in
+  // StackFrameX86::ContextValidity, but the ppc stackwalker doesn't currently
+  // locate registers other than the ones listed here.
+  enum ContextValidity {
+    CONTEXT_VALID_NONE = 0,
+    CONTEXT_VALID_SRR0 = 1 << 0,
+    CONTEXT_VALID_GPR1 = 1 << 1,
+    CONTEXT_VALID_ALL  = -1
+  };
+
+  StackFramePPC64() : context(), context_validity(CONTEXT_VALID_NONE) {}
+
+  // Register state.  This is only fully valid for the topmost frame in a
+  // stack.  In other frames, the values of nonvolatile registers may be
+  // present, given sufficient debugging information.  Refer to
+  // context_validity.
+  MDRawContextPPC64 context;
+
+  // context_validity is actually ContextValidity, but int is used because
+  // the OR operator doesn't work well with enumerated types.  This indicates
+  // which fields in context are valid.
+  int context_validity;
+};
+
+struct StackFrameAMD64 : public StackFrame {
+  // ContextValidity has one entry for each register that we might be able
+  // to recover.
+  enum ContextValidity {
+    CONTEXT_VALID_NONE  = 0,
+    CONTEXT_VALID_RAX   = 1 << 0,
+    CONTEXT_VALID_RDX   = 1 << 1,
+    CONTEXT_VALID_RCX   = 1 << 2,
+    CONTEXT_VALID_RBX   = 1 << 3,
+    CONTEXT_VALID_RSI   = 1 << 4,
+    CONTEXT_VALID_RDI   = 1 << 5,
+    CONTEXT_VALID_RBP   = 1 << 6,
+    CONTEXT_VALID_RSP   = 1 << 7,
+    CONTEXT_VALID_R8    = 1 << 8,
+    CONTEXT_VALID_R9    = 1 << 9,
+    CONTEXT_VALID_R10   = 1 << 10,
+    CONTEXT_VALID_R11   = 1 << 11,
+    CONTEXT_VALID_R12   = 1 << 12,
+    CONTEXT_VALID_R13   = 1 << 13,
+    CONTEXT_VALID_R14   = 1 << 14,
+    CONTEXT_VALID_R15   = 1 << 15,
+    CONTEXT_VALID_RIP   = 1 << 16,
+    CONTEXT_VALID_ALL  = -1
+  };
+
+  StackFrameAMD64() : context(), context_validity(CONTEXT_VALID_NONE) {}
+
+  // Overriden to return the return address as saved on the stack.
+  virtual uint64_t ReturnAddress() const;
+
+  // Register state. This is only fully valid for the topmost frame in a
+  // stack. In other frames, which registers are present depends on what
+  // debugging information we had available. Refer to context_validity.
+  MDRawContextAMD64 context;
+
+  // For each register in context whose value has been recovered, we set
+  // the corresponding CONTEXT_VALID_ bit in context_validity.
+  //
+  // context_validity's type should actually be ContextValidity, but
+  // we use int instead because the bitwise inclusive or operator
+  // yields an int when applied to enum values, and C++ doesn't
+  // silently convert from ints to enums.
+  int context_validity;
+};
+
+struct StackFrameSPARC : public StackFrame {
+  // to be confirmed
+  enum ContextValidity {
+    CONTEXT_VALID_NONE = 0,
+    CONTEXT_VALID_PC   = 1 << 0,
+    CONTEXT_VALID_SP   = 1 << 1,
+    CONTEXT_VALID_FP   = 1 << 2,
+    CONTEXT_VALID_ALL  = -1
+  };
+
+  StackFrameSPARC() : context(), context_validity(CONTEXT_VALID_NONE) {}
+
+  // Register state.  This is only fully valid for the topmost frame in a
+  // stack.  In other frames, the values of nonvolatile registers may be
+  // present, given sufficient debugging information.  Refer to
+  // context_validity.
+  MDRawContextSPARC context;
+
+  // context_validity is actually ContextValidity, but int is used because
+  // the OR operator doesn't work well with enumerated types.  This indicates
+  // which fields in context are valid.
+  int context_validity;
+};
+
+struct StackFrameARM : public StackFrame {
+  // A flag for each register we might know.
+  enum ContextValidity {
+    CONTEXT_VALID_NONE = 0,
+    CONTEXT_VALID_R0   = 1 << 0,
+    CONTEXT_VALID_R1   = 1 << 1,
+    CONTEXT_VALID_R2   = 1 << 2,
+    CONTEXT_VALID_R3   = 1 << 3,
+    CONTEXT_VALID_R4   = 1 << 4,
+    CONTEXT_VALID_R5   = 1 << 5,
+    CONTEXT_VALID_R6   = 1 << 6,
+    CONTEXT_VALID_R7   = 1 << 7,
+    CONTEXT_VALID_R8   = 1 << 8,
+    CONTEXT_VALID_R9   = 1 << 9,
+    CONTEXT_VALID_R10  = 1 << 10,
+    CONTEXT_VALID_R11  = 1 << 11,
+    CONTEXT_VALID_R12  = 1 << 12,
+    CONTEXT_VALID_R13  = 1 << 13,
+    CONTEXT_VALID_R14  = 1 << 14,
+    CONTEXT_VALID_R15  = 1 << 15,
+    CONTEXT_VALID_ALL  = ~CONTEXT_VALID_NONE,
+
+    // Aliases for registers with dedicated or conventional roles.
+    CONTEXT_VALID_FP   = CONTEXT_VALID_R11,
+    CONTEXT_VALID_SP   = CONTEXT_VALID_R13,
+    CONTEXT_VALID_LR   = CONTEXT_VALID_R14,
+    CONTEXT_VALID_PC   = CONTEXT_VALID_R15
+  };
+
+  StackFrameARM() : context(), context_validity(CONTEXT_VALID_NONE) {}
+
+  // Return the ContextValidity flag for register rN.
+  static ContextValidity RegisterValidFlag(int n) {
+    return ContextValidity(1 << n);
+  }
+
+  // Register state.  This is only fully valid for the topmost frame in a
+  // stack.  In other frames, the values of nonvolatile registers may be
+  // present, given sufficient debugging information.  Refer to
+  // context_validity.
+  MDRawContextARM context;
+
+  // For each register in context whose value has been recovered, we set
+  // the corresponding CONTEXT_VALID_ bit in context_validity.
+  //
+  // context_validity's type should actually be ContextValidity, but
+  // we use int instead because the bitwise inclusive or operator
+  // yields an int when applied to enum values, and C++ doesn't
+  // silently convert from ints to enums.
+  int context_validity;
+};
+
+struct StackFrameARM64 : public StackFrame {
+  // A flag for each register we might know. Note that we can't use an enum
+  // here as there are 33 values to represent.
+  static const uint64_t CONTEXT_VALID_NONE = 0;
+  static const uint64_t CONTEXT_VALID_X0   = 1ULL << 0;
+  static const uint64_t CONTEXT_VALID_X1   = 1ULL << 1;
+  static const uint64_t CONTEXT_VALID_X2   = 1ULL << 2;
+  static const uint64_t CONTEXT_VALID_X3   = 1ULL << 3;
+  static const uint64_t CONTEXT_VALID_X4   = 1ULL << 4;
+  static const uint64_t CONTEXT_VALID_X5   = 1ULL << 5;
+  static const uint64_t CONTEXT_VALID_X6   = 1ULL << 6;
+  static const uint64_t CONTEXT_VALID_X7   = 1ULL << 7;
+  static const uint64_t CONTEXT_VALID_X8   = 1ULL << 8;
+  static const uint64_t CONTEXT_VALID_X9   = 1ULL << 9;
+  static const uint64_t CONTEXT_VALID_X10  = 1ULL << 10;
+  static const uint64_t CONTEXT_VALID_X11  = 1ULL << 11;
+  static const uint64_t CONTEXT_VALID_X12  = 1ULL << 12;
+  static const uint64_t CONTEXT_VALID_X13  = 1ULL << 13;
+  static const uint64_t CONTEXT_VALID_X14  = 1ULL << 14;
+  static const uint64_t CONTEXT_VALID_X15  = 1ULL << 15;
+  static const uint64_t CONTEXT_VALID_X16  = 1ULL << 16;
+  static const uint64_t CONTEXT_VALID_X17  = 1ULL << 17;
+  static const uint64_t CONTEXT_VALID_X18  = 1ULL << 18;
+  static const uint64_t CONTEXT_VALID_X19  = 1ULL << 19;
+  static const uint64_t CONTEXT_VALID_X20  = 1ULL << 20;
+  static const uint64_t CONTEXT_VALID_X21  = 1ULL << 21;
+  static const uint64_t CONTEXT_VALID_X22  = 1ULL << 22;
+  static const uint64_t CONTEXT_VALID_X23  = 1ULL << 23;
+  static const uint64_t CONTEXT_VALID_X24  = 1ULL << 24;
+  static const uint64_t CONTEXT_VALID_X25  = 1ULL << 25;
+  static const uint64_t CONTEXT_VALID_X26  = 1ULL << 26;
+  static const uint64_t CONTEXT_VALID_X27  = 1ULL << 27;
+  static const uint64_t CONTEXT_VALID_X28  = 1ULL << 28;
+  static const uint64_t CONTEXT_VALID_X29  = 1ULL << 29;
+  static const uint64_t CONTEXT_VALID_X30  = 1ULL << 30;
+  static const uint64_t CONTEXT_VALID_X31  = 1ULL << 31;
+  static const uint64_t CONTEXT_VALID_X32  = 1ULL << 32;
+  static const uint64_t CONTEXT_VALID_ALL  = ~CONTEXT_VALID_NONE;
+
+  // Aliases for registers with dedicated or conventional roles.
+  static const uint64_t CONTEXT_VALID_FP   = CONTEXT_VALID_X29;
+  static const uint64_t CONTEXT_VALID_LR   = CONTEXT_VALID_X30;
+  static const uint64_t CONTEXT_VALID_SP   = CONTEXT_VALID_X31;
+  static const uint64_t CONTEXT_VALID_PC   = CONTEXT_VALID_X32;
+
+  StackFrameARM64() : context(),
+                      context_validity(CONTEXT_VALID_NONE) {}
+
+  // Return the validity flag for register xN.
+  static uint64_t RegisterValidFlag(int n) {
+    return 1ULL << n;
+  }
+
+  // Register state.  This is only fully valid for the topmost frame in a
+  // stack.  In other frames, the values of nonvolatile registers may be
+  // present, given sufficient debugging information.  Refer to
+  // context_validity.
+  MDRawContextARM64 context;
+
+  // For each register in context whose value has been recovered, we set
+  // the corresponding CONTEXT_VALID_ bit in context_validity.
+  uint64_t context_validity;
+};
+
+struct StackFrameMIPS : public StackFrame {  
+  // MIPS callee save registers for o32 ABI (32bit registers) are: 
+  // 1. $s0-$s7, 
+  // 2. $sp, $fp
+  // 3. $f20-$f31 
+  // 
+  // The register structure is available at
+  // http://en.wikipedia.org/wiki/MIPS_architecture#Compiler_register_usage
+
+#define INDEX_MIPS_REG_S0 MD_CONTEXT_MIPS_REG_S0  // 16
+#define INDEX_MIPS_REG_S7 MD_CONTEXT_MIPS_REG_S7  // 23
+#define INDEX_MIPS_REG_GP MD_CONTEXT_MIPS_REG_GP  // 28
+#define INDEX_MIPS_REG_RA MD_CONTEXT_MIPS_REG_RA  // 31
+#define INDEX_MIPS_REG_PC 34 
+#define SHIFT_MIPS_REG_S0 0
+#define SHIFT_MIPS_REG_GP 8
+#define SHIFT_MIPS_REG_PC 12 
+
+  enum ContextValidity {
+    CONTEXT_VALID_NONE = 0,
+    CONTEXT_VALID_S0 = 1 << 0,  // $16
+    CONTEXT_VALID_S1 = 1 << 1,  // $17
+    CONTEXT_VALID_S2 = 1 << 2,  // $18
+    CONTEXT_VALID_S3 = 1 << 3,  // $19
+    CONTEXT_VALID_S4 = 1 << 4,  // $20
+    CONTEXT_VALID_S5 = 1 << 5,  // $21
+    CONTEXT_VALID_S6 = 1 << 6,  // $22
+    CONTEXT_VALID_S7 = 1 << 7,  // $23
+    // GP is not calee-save for o32 abi.
+    CONTEXT_VALID_GP = 1 << 8,  // $28
+    CONTEXT_VALID_SP = 1 << 9,  // $29
+    CONTEXT_VALID_FP = 1 << 10,  // $30
+    CONTEXT_VALID_RA = 1 << 11,  // $31  
+    CONTEXT_VALID_PC = 1 << 12,  // $34
+    CONTEXT_VALID_ALL = ~CONTEXT_VALID_NONE
+  };
+  
+  // Return the ContextValidity flag for register rN.
+  static ContextValidity RegisterValidFlag(int n) {
+    if (n >= INDEX_MIPS_REG_S0 && n <= INDEX_MIPS_REG_S7)
+      return ContextValidity(1 << (n - INDEX_MIPS_REG_S0 + SHIFT_MIPS_REG_S0));
+    else if (n >= INDEX_MIPS_REG_GP && n <= INDEX_MIPS_REG_RA)
+      return ContextValidity(1 << (n - INDEX_MIPS_REG_GP + SHIFT_MIPS_REG_GP));
+    else if (n == INDEX_MIPS_REG_PC)
+      return ContextValidity(1 << SHIFT_MIPS_REG_PC);
+
+    return CONTEXT_VALID_NONE;
+  }
+
+  StackFrameMIPS() : context(), context_validity(CONTEXT_VALID_NONE) {}
+
+  // Register state. This is only fully valid for the topmost frame in a
+  // stack. In other frames, which registers are present depends on what
+  // debugging information were available. Refer to 'context_validity' below.
+  MDRawContextMIPS context;   
+
+  // For each register in context whose value has been recovered,
+  // the corresponding CONTEXT_VALID_ bit in 'context_validity' is set.
+  //
+  // context_validity's type should actually be ContextValidity, but
+  // type int is used instead because the bitwise inclusive or operator
+  // yields an int when applied to enum values, and C++ doesn't
+  // silently convert from ints to enums.
+  int context_validity;
+};
+
+}  // namespace google_breakpad
+
+#endif  // GOOGLE_BREAKPAD_PROCESSOR_STACK_FRAME_CPU_H__
diff --git a/include/breakpad/google_breakpad/processor/stack_frame_symbolizer.h b/include/breakpad/google_breakpad/processor/stack_frame_symbolizer.h
new file mode 100644
index 0000000..074907c
--- /dev/null
+++ b/include/breakpad/google_breakpad/processor/stack_frame_symbolizer.h
@@ -0,0 +1,108 @@
+// -*- 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.
+
+// Helper class that encapsulates the logic of how symbol supplier interacts
+// with source line resolver to fill stack frame information.
+
+#ifndef GOOGLE_BREAKPAD_PROCESSOR_STACK_FRAME_SYMBOLIZER_H__
+#define GOOGLE_BREAKPAD_PROCESSOR_STACK_FRAME_SYMBOLIZER_H__
+
+#include <set>
+#include <string>
+
+#include "common/using_std_string.h"
+#include "google_breakpad/common/breakpad_types.h"
+#include "google_breakpad/processor/code_module.h"
+
+namespace google_breakpad {
+class CFIFrameInfo;
+class CodeModules;
+class SymbolSupplier;
+class SourceLineResolverInterface;
+struct StackFrame;
+struct SystemInfo;
+struct WindowsFrameInfo;
+
+class StackFrameSymbolizer {
+ public:
+  enum SymbolizerResult {
+    // Symbol data was found and successfully loaded in resolver.
+    // This does NOT guarantee source line info is found within symbol file.
+    kNoError,
+    // This indicates non-critical error, such as, no code module found for
+    // frame's instruction, no symbol file, or resolver failed to load symbol.
+    kError,
+    // This indicates error for which stack walk should be interrupted
+    // and retried in future.
+    kInterrupt,
+    // Symbol data was found and loaded in resolver however some corruptions
+    // were detected.
+    kWarningCorruptSymbols,
+  };
+
+  StackFrameSymbolizer(SymbolSupplier* supplier,
+                       SourceLineResolverInterface* resolver);
+
+  virtual ~StackFrameSymbolizer() { }
+
+  // Encapsulate the step of resolving source line info for a stack frame.
+  // "frame" must not be NULL.
+  virtual SymbolizerResult FillSourceLineInfo(const CodeModules* modules,
+                                              const SystemInfo* system_info,
+                                              StackFrame* stack_frame);
+
+  virtual WindowsFrameInfo* FindWindowsFrameInfo(const StackFrame* frame);
+
+  virtual CFIFrameInfo* FindCFIFrameInfo(const StackFrame* frame);
+
+  // Reset internal (locally owned) data as if the helper is re-instantiated.
+  // A typical case is to call Reset() after processing an individual report
+  // before start to process next one, in order to reset internal information
+  // about missing symbols found so far.
+  virtual void Reset() { no_symbol_modules_.clear(); }
+
+  // Returns true if there is valid implementation for stack symbolization.
+  virtual bool HasImplementation() { return resolver_ && supplier_; }
+
+  SourceLineResolverInterface* resolver() { return resolver_; }
+  SymbolSupplier* supplier() { return supplier_; }
+
+ protected:
+  SymbolSupplier* supplier_;
+  SourceLineResolverInterface* resolver_;
+  // A list of modules known to have symbols missing. This helps avoid
+  // repeated lookups for the missing symbols within one minidump.
+  std::set<string> no_symbol_modules_;
+};
+
+}  // namespace google_breakpad
+
+#endif  // GOOGLE_BREAKPAD_PROCESSOR_STACK_FRAME_SYMBOLIZER_H__
diff --git a/include/breakpad/google_breakpad/processor/stackwalker.h b/include/breakpad/google_breakpad/processor/stackwalker.h
new file mode 100644
index 0000000..a1bd3e7
--- /dev/null
+++ b/include/breakpad/google_breakpad/processor/stackwalker.h
@@ -0,0 +1,235 @@
+// 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.
+
+// stackwalker.h: Generic stackwalker.
+//
+// The Stackwalker class is an abstract base class providing common generic
+// methods that apply to stacks from all systems.  Specific implementations
+// will extend this class by providing GetContextFrame and GetCallerFrame
+// methods to fill in system-specific data in a StackFrame structure.
+// Stackwalker assembles these StackFrame strucutres into a CallStack.
+//
+// Author: Mark Mentovai
+
+
+#ifndef GOOGLE_BREAKPAD_PROCESSOR_STACKWALKER_H__
+#define GOOGLE_BREAKPAD_PROCESSOR_STACKWALKER_H__
+
+#include <set>
+#include <string>
+#include <vector>
+
+#include "common/using_std_string.h"
+#include "google_breakpad/common/breakpad_types.h"
+#include "google_breakpad/processor/code_modules.h"
+#include "google_breakpad/processor/memory_region.h"
+#include "google_breakpad/processor/stack_frame_symbolizer.h"
+
+namespace google_breakpad {
+
+class CallStack;
+class DumpContext;
+class StackFrameSymbolizer;
+
+using std::set;
+using std::vector;
+
+class Stackwalker {
+ public:
+  virtual ~Stackwalker() {}
+
+  // Populates the given CallStack by calling GetContextFrame and
+  // GetCallerFrame.  The frames are further processed to fill all available
+  // data.  Returns true if the stackwalk completed, or false if it was
+  // interrupted by SymbolSupplier::GetSymbolFile().
+  // Upon return, |modules_without_symbols| will be populated with pointers to
+  // the code modules (CodeModule*) that DON'T have symbols.
+  // |modules_with_corrupt_symbols| will be populated with pointers to the
+  // modules which have corrupt symbols.  |modules_without_symbols| and
+  // |modules_with_corrupt_symbols| DO NOT take ownership of the code modules.
+  // The lifetime of these code modules is the same as the lifetime of the
+  // CodeModules passed to the StackWalker constructor (which currently
+  // happens to be the lifetime of the Breakpad's ProcessingState object).
+  // There is a check for duplicate modules so no duplicates are expected.
+  bool Walk(CallStack* stack,
+            vector<const CodeModule*>* modules_without_symbols,
+            vector<const CodeModule*>* modules_with_corrupt_symbols);
+
+  // Returns a new concrete subclass suitable for the CPU that a stack was
+  // generated on, according to the CPU type indicated by the context
+  // argument.  If no suitable concrete subclass exists, returns NULL.
+  static Stackwalker* StackwalkerForCPU(
+     const SystemInfo* system_info,
+     DumpContext* context,
+     MemoryRegion* memory,
+     const CodeModules* modules,
+     StackFrameSymbolizer* resolver_helper);
+
+  static void set_max_frames(uint32_t max_frames) {
+    max_frames_ = max_frames;
+    max_frames_set_ = true;
+  }
+  static uint32_t max_frames() { return max_frames_; }
+
+  static void set_max_frames_scanned(uint32_t max_frames_scanned) {
+    max_frames_scanned_ = max_frames_scanned;
+  }
+
+ protected:
+  // system_info identifies the operating system, NULL or empty if unknown.
+  // memory identifies a MemoryRegion that provides the stack memory
+  // for the stack to walk.  modules, if non-NULL, is a CodeModules
+  // object that is used to look up which code module each stack frame is
+  // associated with.  frame_symbolizer is a StackFrameSymbolizer object that
+  // encapsulates the logic of how source line resolver interacts with symbol
+  // supplier to symbolize stack frame and look up caller frame information
+  // (see stack_frame_symbolizer.h).
+  // frame_symbolizer MUST NOT be NULL (asserted).
+  Stackwalker(const SystemInfo* system_info,
+              MemoryRegion* memory,
+              const CodeModules* modules,
+              StackFrameSymbolizer* frame_symbolizer);
+
+  // This can be used to filter out potential return addresses when
+  // the stack walker resorts to stack scanning.
+  // Returns true if any of:
+  // * This address is within a loaded module, but we don't have symbols
+  //   for that module.
+  // * This address is within a loaded module for which we have symbols,
+  //   and falls inside a function in that module.
+  // Returns false otherwise.
+  bool InstructionAddressSeemsValid(uint64_t address);
+
+  // The default number of words to search through on the stack
+  // for a return address.
+  static const int kRASearchWords;
+
+  template<typename InstructionType>
+  bool ScanForReturnAddress(InstructionType location_start,
+                            InstructionType* location_found,
+                            InstructionType* ip_found,
+                            bool is_context_frame) {
+    // When searching for the caller of the context frame,
+    // allow the scanner to look farther down the stack.
+    const int search_words = is_context_frame ?
+      kRASearchWords * 4 :
+      kRASearchWords;
+
+    return ScanForReturnAddress(location_start, location_found, ip_found,
+                                search_words);
+  }
+
+  // Scan the stack starting at location_start, looking for an address
+  // that looks like a valid instruction pointer. Addresses must
+  // 1) be contained in the current stack memory
+  // 2) pass the checks in InstructionAddressSeemsValid
+  //
+  // Returns true if a valid-looking instruction pointer was found.
+  // When returning true, sets location_found to the address at which
+  // the value was found, and ip_found to the value contained at that
+  // location in memory.
+  template<typename InstructionType>
+  bool ScanForReturnAddress(InstructionType location_start,
+                            InstructionType* location_found,
+                            InstructionType* ip_found,
+                            int searchwords) {
+    for (InstructionType location = location_start;
+         location <= location_start + searchwords * sizeof(InstructionType);
+         location += sizeof(InstructionType)) {
+      InstructionType ip;
+      if (!memory_->GetMemoryAtAddress(location, &ip))
+        break;
+
+      if (modules_ && modules_->GetModuleForAddress(ip) &&
+          InstructionAddressSeemsValid(ip)) {
+        *ip_found = ip;
+        *location_found = location;
+        return true;
+      }
+    }
+    // nothing found
+    return false;
+  }
+
+  // Information about the system that produced the minidump.  Subclasses
+  // and the SymbolSupplier may find this information useful.
+  const SystemInfo* system_info_;
+
+  // The stack memory to walk.  Subclasses will require this region to
+  // get information from the stack.
+  MemoryRegion* memory_;
+
+  // A list of modules, for populating each StackFrame's module information.
+  // This field is optional and may be NULL.
+  const CodeModules* modules_;
+
+ protected:
+  // The StackFrameSymbolizer implementation.
+  StackFrameSymbolizer* frame_symbolizer_;
+
+ private:
+  // Obtains the context frame, the innermost called procedure in a stack
+  // trace.  Returns NULL on failure.  GetContextFrame allocates a new
+  // StackFrame (or StackFrame subclass), ownership of which is taken by
+  // the caller.
+  virtual StackFrame* GetContextFrame() = 0;
+
+  // Obtains a caller frame.  Each call to GetCallerFrame should return the
+  // frame that called the last frame returned by GetContextFrame or
+  // GetCallerFrame.  To aid this purpose, stack contains the CallStack
+  // made of frames that have already been walked.  GetCallerFrame should
+  // return NULL on failure or when there are no more caller frames (when
+  // the end of the stack has been reached).  GetCallerFrame allocates a new
+  // StackFrame (or StackFrame subclass), ownership of which is taken by
+  // the caller.  |stack_scan_allowed| controls whether stack scanning is
+  // an allowable frame-recovery method, since it is desirable to be able to
+  // disable stack scanning in performance-critical use cases.
+  virtual StackFrame* GetCallerFrame(const CallStack* stack,
+                                     bool stack_scan_allowed) = 0;
+
+  // The maximum number of frames Stackwalker will walk through.
+  // This defaults to 1024 to prevent infinite loops.
+  static uint32_t max_frames_;
+
+  // Keep track of whether max_frames_ has been set by the user, since
+  // it affects whether or not an error message is printed in the case
+  // where an unwind got stopped by the limit.
+  static bool max_frames_set_;
+
+  // The maximum number of stack-scanned and otherwise untrustworthy
+  // frames allowed.  Stack-scanning can be expensive, so the option to
+  // disable or limit it is helpful in cases where unwind performance is
+  // important.  This defaults to 1024, the same as max_frames_.
+  static uint32_t max_frames_scanned_;
+};
+
+}  // namespace google_breakpad
+
+
+#endif  // GOOGLE_BREAKPAD_PROCESSOR_STACKWALKER_H__
diff --git a/include/breakpad/google_breakpad/processor/symbol_supplier.h b/include/breakpad/google_breakpad/processor/symbol_supplier.h
new file mode 100644
index 0000000..a042081
--- /dev/null
+++ b/include/breakpad/google_breakpad/processor/symbol_supplier.h
@@ -0,0 +1,99 @@
+// 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.
+
+// The caller may implement the SymbolSupplier abstract base class
+// to provide symbols for a given module.
+
+#ifndef GOOGLE_BREAKPAD_PROCESSOR_SYMBOL_SUPPLIER_H__
+#define GOOGLE_BREAKPAD_PROCESSOR_SYMBOL_SUPPLIER_H__
+
+#include <string>
+#include "common/using_std_string.h"
+
+namespace google_breakpad {
+
+class CodeModule;
+struct SystemInfo;
+
+class SymbolSupplier {
+ public:
+  // Result type for GetSymbolFile
+  enum SymbolResult {
+    // no symbols were found, but continue processing
+    NOT_FOUND,
+
+    // symbols were found, and the path has been placed in symbol_file
+    FOUND,
+
+    // stops processing the minidump immediately
+    INTERRUPT
+  };
+
+  virtual ~SymbolSupplier() {}
+
+  // Retrieves the symbol file for the given CodeModule, placing the
+  // path in symbol_file if successful.  system_info contains strings
+  // identifying the operating system and CPU; SymbolSupplier may use
+  // to help locate the symbol file.  system_info may be NULL or its
+  // fields may be empty if these values are unknown.  symbol_file
+  // must be a pointer to a valid string
+  virtual SymbolResult GetSymbolFile(const CodeModule *module,
+                                     const SystemInfo *system_info,
+                                     string *symbol_file) = 0;
+  // Same as above, except also places symbol data into symbol_data.
+  // If symbol_data is NULL, the data is not returned.
+  // TODO(nealsid) Once we have symbol data caching behavior implemented
+  // investigate making all symbol suppliers implement all methods,
+  // and make this pure virtual
+  virtual SymbolResult GetSymbolFile(const CodeModule *module,
+                                     const SystemInfo *system_info,
+                                     string *symbol_file,
+                                     string *symbol_data) = 0;
+
+  // Same as above, except allocates data buffer on heap and then places the
+  // symbol data into the buffer as C-string.
+  // SymbolSupplier is responsible for deleting the data buffer. After the call
+  // to GetCStringSymbolData(), the caller should call FreeSymbolData(const
+  // Module *module) once the data buffer is no longer needed.
+  // If symbol_data is not NULL, symbol supplier won't return FOUND unless it
+  // returns a valid buffer in symbol_data, e.g., returns INTERRUPT on memory
+  // allocation failure.
+  virtual SymbolResult GetCStringSymbolData(const CodeModule *module,
+                                            const SystemInfo *system_info,
+                                            string *symbol_file,
+                                            char **symbol_data,
+                                            size_t *symbol_data_size) = 0;
+
+  // Frees the data buffer allocated for the module in GetCStringSymbolData.
+  virtual void FreeSymbolData(const CodeModule *module) = 0;
+};
+
+}  // namespace google_breakpad
+
+#endif  // GOOGLE_BREAKPAD_PROCESSOR_SYMBOL_SUPPLIER_H__
diff --git a/include/breakpad/google_breakpad/processor/system_info.h b/include/breakpad/google_breakpad/processor/system_info.h
new file mode 100644
index 0000000..9583d9e
--- /dev/null
+++ b/include/breakpad/google_breakpad/processor/system_info.h
@@ -0,0 +1,98 @@
+// 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.
+
+// system_info.h: Information about the system that was running a program
+// when a crash report was produced.
+//
+// Author: Mark Mentovai
+
+#ifndef GOOGLE_BREAKPAD_PROCESSOR_SYSTEM_INFO_H__
+#define GOOGLE_BREAKPAD_PROCESSOR_SYSTEM_INFO_H__
+
+#include <string>
+
+#include "common/using_std_string.h"
+
+namespace google_breakpad {
+
+struct SystemInfo {
+ public:
+  SystemInfo() : os(), os_short(), os_version(), cpu(), cpu_info(),
+    cpu_count(0) {}
+
+  // Resets the SystemInfo object to its default values.
+  void Clear() {
+    os.clear();
+    os_short.clear();
+    os_version.clear();
+    cpu.clear();
+    cpu_info.clear();
+    cpu_count = 0;
+  }
+
+  // A string identifying the operating system, such as "Windows NT",
+  // "Mac OS X", or "Linux".  If the information is present in the dump but
+  // its value is unknown, this field will contain a numeric value.  If
+  // the information is not present in the dump, this field will be empty.
+  string os;
+
+  // A short form of the os string, using lowercase letters and no spaces,
+  // suitable for use in a filesystem.  Possible values include "windows",
+  // "mac", "linux" and "nacl".  Empty if the information is not present
+  // in the dump or if the OS given by the dump is unknown.  The values
+  // stored in this field should match those used by
+  // MinidumpSystemInfo::GetOS.
+  string os_short;
+
+  // A string identifying the version of the operating system, such as
+  // "5.1.2600 Service Pack 2" or "10.4.8 8L2127".  If the dump does not
+  // contain this information, this field will be empty.
+  string os_version;
+
+  // A string identifying the basic CPU family, such as "x86" or "ppc".
+  // If this information is present in the dump but its value is unknown,
+  // this field will contain a numeric value.  If the information is not
+  // present in the dump, this field will be empty.  The values stored in
+  // this field should match those used by MinidumpSystemInfo::GetCPU.
+  string cpu;
+
+  // A string further identifying the specific CPU, such as
+  // "GenuineIntel level 6 model 13 stepping 8".  If the information is not
+  // present in the dump, or additional identifying information is not
+  // defined for the CPU family, this field will be empty.
+  string cpu_info;
+
+  // The number of processors in the system.  Will be greater than one for
+  // multi-core systems.
+  int cpu_count;
+};
+
+}  // namespace google_breakpad
+
+#endif  // GOOGLE_BREAKPAD_PROCESSOR_SYSTEM_INFO_H__
diff --git a/include/breakpad/third_party/curl/curl.h b/include/breakpad/third_party/curl/curl.h
new file mode 100644
index 0000000..0d80936
--- /dev/null
+++ b/include/breakpad/third_party/curl/curl.h
@@ -0,0 +1,1936 @@
+#ifndef __CURL_CURL_H
+#define __CURL_CURL_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2009, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ * $Id: curl.h,v 1.396 2009-10-16 13:30:31 yangtse Exp $
+ ***************************************************************************/
+
+/*
+ * If you have libcurl problems, all docs and details are found here:
+ *   http://curl.haxx.se/libcurl/
+ *
+ * curl-library mailing list subscription and unsubscription web interface:
+ *   http://cool.haxx.se/mailman/listinfo/curl-library/
+ */
+
+/*
+ * Leading 'curl' path on the 'curlbuild.h' include statement is
+ * required to properly allow building outside of the source tree,
+ * due to the fact that in this case 'curlbuild.h' is generated in
+ * a subdirectory of the build tree while 'curl.h actually remains
+ * in a subdirectory of the source tree.
+ */
+
+#include "third_party/curl/curlver.h"         /* libcurl version defines   */
+#include "third_party/curl/curlbuild.h"       /* libcurl build definitions */
+#include "third_party/curl/curlrules.h"       /* libcurl rules enforcement */
+
+/*
+ * Define WIN32 when build target is Win32 API
+ */
+
+#if (defined(_WIN32) || defined(__WIN32__)) && \
+     !defined(WIN32) && !defined(__SYMBIAN32__)
+#define WIN32
+#endif
+
+#include <stdio.h>
+#include <limits.h>
+
+/* The include stuff here below is mainly for time_t! */
+#include <sys/types.h>
+#include <time.h>
+
+#if defined(WIN32) && !defined(_WIN32_WCE) && !defined(__GNUC__) && \
+  !defined(__CYGWIN__) || defined(__MINGW32__)
+#if !(defined(_WINSOCKAPI_) || defined(_WINSOCK_H))
+/* The check above prevents the winsock2 inclusion if winsock.h already was
+   included, since they can't co-exist without problems */
+#include <winsock2.h>
+#include <ws2tcpip.h>
+#endif
+#else
+
+/* HP-UX systems version 9, 10 and 11 lack sys/select.h and so does oldish
+   libc5-based Linux systems. Only include it on system that are known to
+   require it! */
+#if defined(_AIX) || defined(__NOVELL_LIBC__) || defined(__NetBSD__) || \
+    defined(__minix) || defined(__SYMBIAN32__) || defined(__INTEGRITY) || \
+    defined(__ANDROID__)
+#include <sys/select.h>
+#endif
+
+#ifndef _WIN32_WCE
+#include <sys/socket.h>
+#endif
+#if !defined(WIN32) && !defined(__WATCOMC__) && !defined(__VXWORKS__)
+#include <sys/time.h>
+#endif
+#include <sys/types.h>
+#endif
+
+#ifdef __BEOS__
+#include <support/SupportDefs.h>
+#endif
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+typedef void CURL;
+
+/*
+ * Decorate exportable functions for Win32 and Symbian OS DLL linking.
+ * This avoids using a .def file for building libcurl.dll.
+ */
+#if (defined(WIN32) || defined(_WIN32) || defined(__SYMBIAN32__)) && \
+     !defined(CURL_STATICLIB)
+#if defined(BUILDING_LIBCURL)
+#define CURL_EXTERN  __declspec(dllexport)
+#else
+#define CURL_EXTERN  __declspec(dllimport)
+#endif
+#else
+
+#ifdef CURL_HIDDEN_SYMBOLS
+/*
+ * This definition is used to make external definitions visible in the
+ * shared library when symbols are hidden by default.  It makes no
+ * difference when compiling applications whether this is set or not,
+ * only when compiling the library.
+ */
+#define CURL_EXTERN CURL_EXTERN_SYMBOL
+#else
+#define CURL_EXTERN
+#endif
+#endif
+
+#ifndef curl_socket_typedef
+/* socket typedef */
+#ifdef WIN32
+typedef SOCKET curl_socket_t;
+#define CURL_SOCKET_BAD INVALID_SOCKET
+#else
+typedef int curl_socket_t;
+#define CURL_SOCKET_BAD -1
+#endif
+#define curl_socket_typedef
+#endif /* curl_socket_typedef */
+
+struct curl_httppost {
+  struct curl_httppost *next;       /* next entry in the list */
+  char *name;                       /* pointer to allocated name */
+  long namelength;                  /* length of name length */
+  char *contents;                   /* pointer to allocated data contents */
+  long contentslength;              /* length of contents field */
+  char *buffer;                     /* pointer to allocated buffer contents */
+  long bufferlength;                /* length of buffer field */
+  char *contenttype;                /* Content-Type */
+  struct curl_slist* contentheader; /* list of extra headers for this form */
+  struct curl_httppost *more;       /* if one field name has more than one
+                                       file, this link should link to following
+                                       files */
+  long flags;                       /* as defined below */
+#define HTTPPOST_FILENAME (1<<0)    /* specified content is a file name */
+#define HTTPPOST_READFILE (1<<1)    /* specified content is a file name */
+#define HTTPPOST_PTRNAME (1<<2)     /* name is only stored pointer
+                                       do not free in formfree */
+#define HTTPPOST_PTRCONTENTS (1<<3) /* contents is only stored pointer
+                                       do not free in formfree */
+#define HTTPPOST_BUFFER (1<<4)      /* upload file from buffer */
+#define HTTPPOST_PTRBUFFER (1<<5)   /* upload file from pointer contents */
+#define HTTPPOST_CALLBACK (1<<6)    /* upload file contents by using the
+                                       regular read callback to get the data
+                                       and pass the given pointer as custom
+                                       pointer */
+
+  char *showfilename;               /* The file name to show. If not set, the
+                                       actual file name will be used (if this
+                                       is a file part) */
+  void *userp;                      /* custom pointer used for
+                                       HTTPPOST_CALLBACK posts */
+};
+
+typedef int (*curl_progress_callback)(void *clientp,
+                                      double dltotal,
+                                      double dlnow,
+                                      double ultotal,
+                                      double ulnow);
+
+#ifndef CURL_MAX_WRITE_SIZE
+  /* Tests have proven that 20K is a very bad buffer size for uploads on
+     Windows, while 16K for some odd reason performed a lot better.
+     We do the ifndef check to allow this value to easier be changed at build
+     time for those who feel adventurous. */
+#define CURL_MAX_WRITE_SIZE 16384
+#endif
+
+#ifndef CURL_MAX_HTTP_HEADER
+/* The only reason to have a max limit for this is to avoid the risk of a bad
+   server feeding libcurl with a never-ending header that will cause reallocs
+   infinitely */
+#define CURL_MAX_HTTP_HEADER (100*1024)
+#endif
+
+
+/* This is a magic return code for the write callback that, when returned,
+   will signal libcurl to pause receiving on the current transfer. */
+#define CURL_WRITEFUNC_PAUSE 0x10000001
+typedef size_t (*curl_write_callback)(char *buffer,
+                                      size_t size,
+                                      size_t nitems,
+                                      void *outstream);
+
+/* These are the return codes for the seek callbacks */
+#define CURL_SEEKFUNC_OK       0
+#define CURL_SEEKFUNC_FAIL     1 /* fail the entire transfer */
+#define CURL_SEEKFUNC_CANTSEEK 2 /* tell libcurl seeking can't be done, so
+                                    libcurl might try other means instead */
+typedef int (*curl_seek_callback)(void *instream,
+                                  curl_off_t offset,
+                                  int origin); /* 'whence' */
+
+/* This is a return code for the read callback that, when returned, will
+   signal libcurl to immediately abort the current transfer. */
+#define CURL_READFUNC_ABORT 0x10000000
+/* This is a return code for the read callback that, when returned, will
+   signal libcurl to pause sending data on the current transfer. */
+#define CURL_READFUNC_PAUSE 0x10000001
+
+typedef size_t (*curl_read_callback)(char *buffer,
+                                      size_t size,
+                                      size_t nitems,
+                                      void *instream);
+
+typedef enum  {
+  CURLSOCKTYPE_IPCXN, /* socket created for a specific IP connection */
+  CURLSOCKTYPE_LAST   /* never use */
+} curlsocktype;
+
+typedef int (*curl_sockopt_callback)(void *clientp,
+                                     curl_socket_t curlfd,
+                                     curlsocktype purpose);
+
+struct curl_sockaddr {
+  int family;
+  int socktype;
+  int protocol;
+  unsigned int addrlen; /* addrlen was a socklen_t type before 7.18.0 but it
+                           turned really ugly and painful on the systems that
+                           lack this type */
+  struct sockaddr addr;
+};
+
+typedef curl_socket_t
+(*curl_opensocket_callback)(void *clientp,
+                            curlsocktype purpose,
+                            struct curl_sockaddr *address);
+
+#ifndef CURL_NO_OLDIES
+  /* not used since 7.10.8, will be removed in a future release */
+typedef int (*curl_passwd_callback)(void *clientp,
+                                    const char *prompt,
+                                    char *buffer,
+                                    int buflen);
+#endif
+
+typedef enum {
+  CURLIOE_OK,            /* I/O operation successful */
+  CURLIOE_UNKNOWNCMD,    /* command was unknown to callback */
+  CURLIOE_FAILRESTART,   /* failed to restart the read */
+  CURLIOE_LAST           /* never use */
+} curlioerr;
+
+typedef enum  {
+  CURLIOCMD_NOP,         /* no operation */
+  CURLIOCMD_RESTARTREAD, /* restart the read stream from start */
+  CURLIOCMD_LAST         /* never use */
+} curliocmd;
+
+typedef curlioerr (*curl_ioctl_callback)(CURL *handle,
+                                         int cmd,
+                                         void *clientp);
+
+/*
+ * The following typedef's are signatures of malloc, free, realloc, strdup and
+ * calloc respectively.  Function pointers of these types can be passed to the
+ * curl_global_init_mem() function to set user defined memory management
+ * callback routines.
+ */
+typedef void *(*curl_malloc_callback)(size_t size);
+typedef void (*curl_free_callback)(void *ptr);
+typedef void *(*curl_realloc_callback)(void *ptr, size_t size);
+typedef char *(*curl_strdup_callback)(const char *str);
+typedef void *(*curl_calloc_callback)(size_t nmemb, size_t size);
+
+/* the kind of data that is passed to information_callback*/
+typedef enum {
+  CURLINFO_TEXT = 0,
+  CURLINFO_HEADER_IN,    /* 1 */
+  CURLINFO_HEADER_OUT,   /* 2 */
+  CURLINFO_DATA_IN,      /* 3 */
+  CURLINFO_DATA_OUT,     /* 4 */
+  CURLINFO_SSL_DATA_IN,  /* 5 */
+  CURLINFO_SSL_DATA_OUT, /* 6 */
+  CURLINFO_END
+} curl_infotype;
+
+typedef int (*curl_debug_callback)
+       (CURL *handle,      /* the handle/transfer this concerns */
+        curl_infotype type, /* what kind of data */
+        char *data,        /* points to the data */
+        size_t size,       /* size of the data pointed to */
+        void *userptr);    /* whatever the user please */
+
+/* All possible error codes from all sorts of curl functions. Future versions
+   may return other values, stay prepared.
+
+   Always add new return codes last. Never *EVER* remove any. The return
+   codes must remain the same!
+ */
+
+typedef enum {
+  CURLE_OK = 0,
+  CURLE_UNSUPPORTED_PROTOCOL,    /* 1 */
+  CURLE_FAILED_INIT,             /* 2 */
+  CURLE_URL_MALFORMAT,           /* 3 */
+  CURLE_OBSOLETE4,               /* 4 - NOT USED */
+  CURLE_COULDNT_RESOLVE_PROXY,   /* 5 */
+  CURLE_COULDNT_RESOLVE_HOST,    /* 6 */
+  CURLE_COULDNT_CONNECT,         /* 7 */
+  CURLE_FTP_WEIRD_SERVER_REPLY,  /* 8 */
+  CURLE_REMOTE_ACCESS_DENIED,    /* 9 a service was denied by the server
+                                    due to lack of access - when login fails
+                                    this is not returned. */
+  CURLE_OBSOLETE10,              /* 10 - NOT USED */
+  CURLE_FTP_WEIRD_PASS_REPLY,    /* 11 */
+  CURLE_OBSOLETE12,              /* 12 - NOT USED */
+  CURLE_FTP_WEIRD_PASV_REPLY,    /* 13 */
+  CURLE_FTP_WEIRD_227_FORMAT,    /* 14 */
+  CURLE_FTP_CANT_GET_HOST,       /* 15 */
+  CURLE_OBSOLETE16,              /* 16 - NOT USED */
+  CURLE_FTP_COULDNT_SET_TYPE,    /* 17 */
+  CURLE_PARTIAL_FILE,            /* 18 */
+  CURLE_FTP_COULDNT_RETR_FILE,   /* 19 */
+  CURLE_OBSOLETE20,              /* 20 - NOT USED */
+  CURLE_QUOTE_ERROR,             /* 21 - quote command failure */
+  CURLE_HTTP_RETURNED_ERROR,     /* 22 */
+  CURLE_WRITE_ERROR,             /* 23 */
+  CURLE_OBSOLETE24,              /* 24 - NOT USED */
+  CURLE_UPLOAD_FAILED,           /* 25 - failed upload "command" */
+  CURLE_READ_ERROR,              /* 26 - couldn't open/read from file */
+  CURLE_OUT_OF_MEMORY,           /* 27 */
+  /* Note: CURLE_OUT_OF_MEMORY may sometimes indicate a conversion error
+           instead of a memory allocation error if CURL_DOES_CONVERSIONS
+           is defined
+  */
+  CURLE_OPERATION_TIMEDOUT,      /* 28 - the timeout time was reached */
+  CURLE_OBSOLETE29,              /* 29 - NOT USED */
+  CURLE_FTP_PORT_FAILED,         /* 30 - FTP PORT operation failed */
+  CURLE_FTP_COULDNT_USE_REST,    /* 31 - the REST command failed */
+  CURLE_OBSOLETE32,              /* 32 - NOT USED */
+  CURLE_RANGE_ERROR,             /* 33 - RANGE "command" didn't work */
+  CURLE_HTTP_POST_ERROR,         /* 34 */
+  CURLE_SSL_CONNECT_ERROR,       /* 35 - wrong when connecting with SSL */
+  CURLE_BAD_DOWNLOAD_RESUME,     /* 36 - couldn't resume download */
+  CURLE_FILE_COULDNT_READ_FILE,  /* 37 */
+  CURLE_LDAP_CANNOT_BIND,        /* 38 */
+  CURLE_LDAP_SEARCH_FAILED,      /* 39 */
+  CURLE_OBSOLETE40,              /* 40 - NOT USED */
+  CURLE_FUNCTION_NOT_FOUND,      /* 41 */
+  CURLE_ABORTED_BY_CALLBACK,     /* 42 */
+  CURLE_BAD_FUNCTION_ARGUMENT,   /* 43 */
+  CURLE_OBSOLETE44,              /* 44 - NOT USED */
+  CURLE_INTERFACE_FAILED,        /* 45 - CURLOPT_INTERFACE failed */
+  CURLE_OBSOLETE46,              /* 46 - NOT USED */
+  CURLE_TOO_MANY_REDIRECTS ,     /* 47 - catch endless re-direct loops */
+  CURLE_UNKNOWN_TELNET_OPTION,   /* 48 - User specified an unknown option */
+  CURLE_TELNET_OPTION_SYNTAX ,   /* 49 - Malformed telnet option */
+  CURLE_OBSOLETE50,              /* 50 - NOT USED */
+  CURLE_PEER_FAILED_VERIFICATION, /* 51 - peer's certificate or fingerprint
+                                     wasn't verified fine */
+  CURLE_GOT_NOTHING,             /* 52 - when this is a specific error */
+  CURLE_SSL_ENGINE_NOTFOUND,     /* 53 - SSL crypto engine not found */
+  CURLE_SSL_ENGINE_SETFAILED,    /* 54 - can not set SSL crypto engine as
+                                    default */
+  CURLE_SEND_ERROR,              /* 55 - failed sending network data */
+  CURLE_RECV_ERROR,              /* 56 - failure in receiving network data */
+  CURLE_OBSOLETE57,              /* 57 - NOT IN USE */
+  CURLE_SSL_CERTPROBLEM,         /* 58 - problem with the local certificate */
+  CURLE_SSL_CIPHER,              /* 59 - couldn't use specified cipher */
+  CURLE_SSL_CACERT,              /* 60 - problem with the CA cert (path?) */
+  CURLE_BAD_CONTENT_ENCODING,    /* 61 - Unrecognized transfer encoding */
+  CURLE_LDAP_INVALID_URL,        /* 62 - Invalid LDAP URL */
+  CURLE_FILESIZE_EXCEEDED,       /* 63 - Maximum file size exceeded */
+  CURLE_USE_SSL_FAILED,          /* 64 - Requested FTP SSL level failed */
+  CURLE_SEND_FAIL_REWIND,        /* 65 - Sending the data requires a rewind
+                                    that failed */
+  CURLE_SSL_ENGINE_INITFAILED,   /* 66 - failed to initialise ENGINE */
+  CURLE_LOGIN_DENIED,            /* 67 - user, password or similar was not
+                                    accepted and we failed to login */
+  CURLE_TFTP_NOTFOUND,           /* 68 - file not found on server */
+  CURLE_TFTP_PERM,               /* 69 - permission problem on server */
+  CURLE_REMOTE_DISK_FULL,        /* 70 - out of disk space on server */
+  CURLE_TFTP_ILLEGAL,            /* 71 - Illegal TFTP operation */
+  CURLE_TFTP_UNKNOWNID,          /* 72 - Unknown transfer ID */
+  CURLE_REMOTE_FILE_EXISTS,      /* 73 - File already exists */
+  CURLE_TFTP_NOSUCHUSER,         /* 74 - No such user */
+  CURLE_CONV_FAILED,             /* 75 - conversion failed */
+  CURLE_CONV_REQD,               /* 76 - caller must register conversion
+                                    callbacks using curl_easy_setopt options
+                                    CURLOPT_CONV_FROM_NETWORK_FUNCTION,
+                                    CURLOPT_CONV_TO_NETWORK_FUNCTION, and
+                                    CURLOPT_CONV_FROM_UTF8_FUNCTION */
+  CURLE_SSL_CACERT_BADFILE,      /* 77 - could not load CACERT file, missing
+                                    or wrong format */
+  CURLE_REMOTE_FILE_NOT_FOUND,   /* 78 - remote file not found */
+  CURLE_SSH,                     /* 79 - error from the SSH layer, somewhat
+                                    generic so the error message will be of
+                                    interest when this has happened */
+
+  CURLE_SSL_SHUTDOWN_FAILED,     /* 80 - Failed to shut down the SSL
+                                    connection */
+  CURLE_AGAIN,                   /* 81 - socket is not ready for send/recv,
+                                    wait till it's ready and try again (Added
+                                    in 7.18.2) */
+  CURLE_SSL_CRL_BADFILE,         /* 82 - could not load CRL file, missing or
+                                    wrong format (Added in 7.19.0) */
+  CURLE_SSL_ISSUER_ERROR,        /* 83 - Issuer check failed.  (Added in
+                                    7.19.0) */
+  CURL_LAST /* never use! */
+} CURLcode;
+
+#ifndef CURL_NO_OLDIES /* define this to test if your app builds with all
+                          the obsolete stuff removed! */
+
+/* Backwards compatibility with older names */
+
+/* The following were added in 7.17.1 */
+/* These are scheduled to disappear by 2009 */
+#define CURLE_SSL_PEER_CERTIFICATE CURLE_PEER_FAILED_VERIFICATION
+
+/* The following were added in 7.17.0 */
+/* These are scheduled to disappear by 2009 */
+#define CURLE_OBSOLETE CURLE_OBSOLETE50 /* noone should be using this! */
+#define CURLE_BAD_PASSWORD_ENTERED CURLE_OBSOLETE46
+#define CURLE_BAD_CALLING_ORDER CURLE_OBSOLETE44
+#define CURLE_FTP_USER_PASSWORD_INCORRECT CURLE_OBSOLETE10
+#define CURLE_FTP_CANT_RECONNECT CURLE_OBSOLETE16
+#define CURLE_FTP_COULDNT_GET_SIZE CURLE_OBSOLETE32
+#define CURLE_FTP_COULDNT_SET_ASCII CURLE_OBSOLETE29
+#define CURLE_FTP_WEIRD_USER_REPLY CURLE_OBSOLETE12
+#define CURLE_FTP_WRITE_ERROR CURLE_OBSOLETE20
+#define CURLE_LIBRARY_NOT_FOUND CURLE_OBSOLETE40
+#define CURLE_MALFORMAT_USER CURLE_OBSOLETE24
+#define CURLE_SHARE_IN_USE CURLE_OBSOLETE57
+#define CURLE_URL_MALFORMAT_USER CURLE_OBSOLETE4
+
+#define CURLE_FTP_ACCESS_DENIED CURLE_REMOTE_ACCESS_DENIED
+#define CURLE_FTP_COULDNT_SET_BINARY CURLE_FTP_COULDNT_SET_TYPE
+#define CURLE_FTP_QUOTE_ERROR CURLE_QUOTE_ERROR
+#define CURLE_TFTP_DISKFULL CURLE_REMOTE_DISK_FULL
+#define CURLE_TFTP_EXISTS CURLE_REMOTE_FILE_EXISTS
+#define CURLE_HTTP_RANGE_ERROR CURLE_RANGE_ERROR
+#define CURLE_FTP_SSL_FAILED CURLE_USE_SSL_FAILED
+
+/* The following were added earlier */
+
+#define CURLE_OPERATION_TIMEOUTED CURLE_OPERATION_TIMEDOUT
+
+#define CURLE_HTTP_NOT_FOUND CURLE_HTTP_RETURNED_ERROR
+#define CURLE_HTTP_PORT_FAILED CURLE_INTERFACE_FAILED
+#define CURLE_FTP_COULDNT_STOR_FILE CURLE_UPLOAD_FAILED
+
+#define CURLE_FTP_PARTIAL_FILE CURLE_PARTIAL_FILE
+#define CURLE_FTP_BAD_DOWNLOAD_RESUME CURLE_BAD_DOWNLOAD_RESUME
+
+/* This was the error code 50 in 7.7.3 and a few earlier versions, this
+   is no longer used by libcurl but is instead #defined here only to not
+   make programs break */
+#define CURLE_ALREADY_COMPLETE 99999
+
+#endif /*!CURL_NO_OLDIES*/
+
+/* This prototype applies to all conversion callbacks */
+typedef CURLcode (*curl_conv_callback)(char *buffer, size_t length);
+
+typedef CURLcode (*curl_ssl_ctx_callback)(CURL *curl,    /* easy handle */
+                                          void *ssl_ctx, /* actually an
+                                                            OpenSSL SSL_CTX */
+                                          void *userptr);
+
+typedef enum {
+  CURLPROXY_HTTP = 0,   /* added in 7.10, new in 7.19.4 default is to use
+                           CONNECT HTTP/1.1 */
+  CURLPROXY_HTTP_1_0 = 1,   /* added in 7.19.4, force to use CONNECT
+                               HTTP/1.0  */
+  CURLPROXY_SOCKS4 = 4, /* support added in 7.15.2, enum existed already
+                           in 7.10 */
+  CURLPROXY_SOCKS5 = 5, /* added in 7.10 */
+  CURLPROXY_SOCKS4A = 6, /* added in 7.18.0 */
+  CURLPROXY_SOCKS5_HOSTNAME = 7 /* Use the SOCKS5 protocol but pass along the
+                                   host name rather than the IP address. added
+                                   in 7.18.0 */
+} curl_proxytype;  /* this enum was added in 7.10 */
+
+#define CURLAUTH_NONE         0       /* nothing */
+#define CURLAUTH_BASIC        (1<<0)  /* Basic (default) */
+#define CURLAUTH_DIGEST       (1<<1)  /* Digest */
+#define CURLAUTH_GSSNEGOTIATE (1<<2)  /* GSS-Negotiate */
+#define CURLAUTH_NTLM         (1<<3)  /* NTLM */
+#define CURLAUTH_DIGEST_IE    (1<<4)  /* Digest with IE flavour */
+#define CURLAUTH_ANY (~CURLAUTH_DIGEST_IE)  /* all fine types set */
+#define CURLAUTH_ANYSAFE (~(CURLAUTH_BASIC|CURLAUTH_DIGEST_IE))
+
+#define CURLSSH_AUTH_ANY       ~0     /* all types supported by the server */
+#define CURLSSH_AUTH_NONE      0      /* none allowed, silly but complete */
+#define CURLSSH_AUTH_PUBLICKEY (1<<0) /* public/private key files */
+#define CURLSSH_AUTH_PASSWORD  (1<<1) /* password */
+#define CURLSSH_AUTH_HOST      (1<<2) /* host key files */
+#define CURLSSH_AUTH_KEYBOARD  (1<<3) /* keyboard interactive */
+#define CURLSSH_AUTH_DEFAULT CURLSSH_AUTH_ANY
+
+#define CURL_ERROR_SIZE 256
+
+struct curl_khkey {
+  const char *key; /* points to a zero-terminated string encoded with base64
+                      if len is zero, otherwise to the "raw" data */
+  size_t len;
+  enum type {
+    CURLKHTYPE_UNKNOWN,
+    CURLKHTYPE_RSA1,
+    CURLKHTYPE_RSA,
+    CURLKHTYPE_DSS
+  } keytype;
+};
+
+/* this is the set of return values expected from the curl_sshkeycallback
+   callback */
+enum curl_khstat {
+  CURLKHSTAT_FINE_ADD_TO_FILE,
+  CURLKHSTAT_FINE,
+  CURLKHSTAT_REJECT, /* reject the connection, return an error */
+  CURLKHSTAT_DEFER,  /* do not accept it, but we can't answer right now so
+                        this causes a CURLE_DEFER error but otherwise the
+                        connection will be left intact etc */
+  CURLKHSTAT_LAST    /* not for use, only a marker for last-in-list */
+};
+
+/* this is the set of status codes pass in to the callback */
+enum curl_khmatch {
+  CURLKHMATCH_OK,       /* match */
+  CURLKHMATCH_MISMATCH, /* host found, key mismatch! */
+  CURLKHMATCH_MISSING,  /* no matching host/key found */
+  CURLKHMATCH_LAST      /* not for use, only a marker for last-in-list */
+};
+
+typedef int
+  (*curl_sshkeycallback) (CURL *easy,     /* easy handle */
+                          const struct curl_khkey *knownkey, /* known */
+                          const struct curl_khkey *foundkey, /* found */
+                          enum curl_khmatch, /* libcurl's view on the keys */
+                          void *clientp); /* custom pointer passed from app */
+
+/* parameter for the CURLOPT_USE_SSL option */
+typedef enum {
+  CURLUSESSL_NONE,    /* do not attempt to use SSL */
+  CURLUSESSL_TRY,     /* try using SSL, proceed anyway otherwise */
+  CURLUSESSL_CONTROL, /* SSL for the control connection or fail */
+  CURLUSESSL_ALL,     /* SSL for all communication or fail */
+  CURLUSESSL_LAST     /* not an option, never use */
+} curl_usessl;
+
+#ifndef CURL_NO_OLDIES /* define this to test if your app builds with all
+                          the obsolete stuff removed! */
+
+/* Backwards compatibility with older names */
+/* These are scheduled to disappear by 2009 */
+
+#define CURLFTPSSL_NONE CURLUSESSL_NONE
+#define CURLFTPSSL_TRY CURLUSESSL_TRY
+#define CURLFTPSSL_CONTROL CURLUSESSL_CONTROL
+#define CURLFTPSSL_ALL CURLUSESSL_ALL
+#define CURLFTPSSL_LAST CURLUSESSL_LAST
+#define curl_ftpssl curl_usessl
+#endif /*!CURL_NO_OLDIES*/
+
+/* parameter for the CURLOPT_FTP_SSL_CCC option */
+typedef enum {
+  CURLFTPSSL_CCC_NONE,    /* do not send CCC */
+  CURLFTPSSL_CCC_PASSIVE, /* Let the server initiate the shutdown */
+  CURLFTPSSL_CCC_ACTIVE,  /* Initiate the shutdown */
+  CURLFTPSSL_CCC_LAST     /* not an option, never use */
+} curl_ftpccc;
+
+/* parameter for the CURLOPT_FTPSSLAUTH option */
+typedef enum {
+  CURLFTPAUTH_DEFAULT, /* let libcurl decide */
+  CURLFTPAUTH_SSL,     /* use "AUTH SSL" */
+  CURLFTPAUTH_TLS,     /* use "AUTH TLS" */
+  CURLFTPAUTH_LAST /* not an option, never use */
+} curl_ftpauth;
+
+/* parameter for the CURLOPT_FTP_CREATE_MISSING_DIRS option */
+typedef enum {
+  CURLFTP_CREATE_DIR_NONE,  /* do NOT create missing dirs! */
+  CURLFTP_CREATE_DIR,       /* (FTP/SFTP) if CWD fails, try MKD and then CWD
+                               again if MKD succeeded, for SFTP this does
+                               similar magic */
+  CURLFTP_CREATE_DIR_RETRY, /* (FTP only) if CWD fails, try MKD and then CWD
+                               again even if MKD failed! */
+  CURLFTP_CREATE_DIR_LAST   /* not an option, never use */
+} curl_ftpcreatedir;
+
+/* parameter for the CURLOPT_FTP_FILEMETHOD option */
+typedef enum {
+  CURLFTPMETHOD_DEFAULT,   /* let libcurl pick */
+  CURLFTPMETHOD_MULTICWD,  /* single CWD operation for each path part */
+  CURLFTPMETHOD_NOCWD,     /* no CWD at all */
+  CURLFTPMETHOD_SINGLECWD, /* one CWD to full dir, then work on file */
+  CURLFTPMETHOD_LAST       /* not an option, never use */
+} curl_ftpmethod;
+
+/* CURLPROTO_ defines are for the CURLOPT_*PROTOCOLS options */
+#define CURLPROTO_HTTP   (1<<0)
+#define CURLPROTO_HTTPS  (1<<1)
+#define CURLPROTO_FTP    (1<<2)
+#define CURLPROTO_FTPS   (1<<3)
+#define CURLPROTO_SCP    (1<<4)
+#define CURLPROTO_SFTP   (1<<5)
+#define CURLPROTO_TELNET (1<<6)
+#define CURLPROTO_LDAP   (1<<7)
+#define CURLPROTO_LDAPS  (1<<8)
+#define CURLPROTO_DICT   (1<<9)
+#define CURLPROTO_FILE   (1<<10)
+#define CURLPROTO_TFTP   (1<<11)
+#define CURLPROTO_ALL    (~0) /* enable everything */
+
+/* long may be 32 or 64 bits, but we should never depend on anything else
+   but 32 */
+#define CURLOPTTYPE_LONG          0
+#define CURLOPTTYPE_OBJECTPOINT   10000
+#define CURLOPTTYPE_FUNCTIONPOINT 20000
+#define CURLOPTTYPE_OFF_T         30000
+
+/* name is uppercase CURLOPT_<name>,
+   type is one of the defined CURLOPTTYPE_<type>
+   number is unique identifier */
+#ifdef CINIT
+#undef CINIT
+#endif
+
+#ifdef CURL_ISOCPP
+#define CINIT(name,type,number) CURLOPT_ ## name = CURLOPTTYPE_ ## type + number
+#else
+/* The macro "##" is ISO C, we assume pre-ISO C doesn't support it. */
+#define LONG          CURLOPTTYPE_LONG
+#define OBJECTPOINT   CURLOPTTYPE_OBJECTPOINT
+#define FUNCTIONPOINT CURLOPTTYPE_FUNCTIONPOINT
+#define OFF_T         CURLOPTTYPE_OFF_T
+#define CINIT(name,type,number) CURLOPT_/**/name = type + number
+#endif
+
+/*
+ * This macro-mania below setups the CURLOPT_[what] enum, to be used with
+ * curl_easy_setopt(). The first argument in the CINIT() macro is the [what]
+ * word.
+ */
+
+typedef enum {
+  /* This is the FILE * or void * the regular output should be written to. */
+  CINIT(FILE, OBJECTPOINT, 1),
+
+  /* The full URL to get/put */
+  CINIT(URL,  OBJECTPOINT, 2),
+
+  /* Port number to connect to, if other than default. */
+  CINIT(PORT, LONG, 3),
+
+  /* Name of proxy to use. */
+  CINIT(PROXY, OBJECTPOINT, 4),
+
+  /* "name:password" to use when fetching. */
+  CINIT(USERPWD, OBJECTPOINT, 5),
+
+  /* "name:password" to use with proxy. */
+  CINIT(PROXYUSERPWD, OBJECTPOINT, 6),
+
+  /* Range to get, specified as an ASCII string. */
+  CINIT(RANGE, OBJECTPOINT, 7),
+
+  /* not used */
+
+  /* Specified file stream to upload from (use as input): */
+  CINIT(INFILE, OBJECTPOINT, 9),
+
+  /* Buffer to receive error messages in, must be at least CURL_ERROR_SIZE
+   * bytes big. If this is not used, error messages go to stderr instead: */
+  CINIT(ERRORBUFFER, OBJECTPOINT, 10),
+
+  /* Function that will be called to store the output (instead of fwrite). The
+   * parameters will use fwrite() syntax, make sure to follow them. */
+  CINIT(WRITEFUNCTION, FUNCTIONPOINT, 11),
+
+  /* Function that will be called to read the input (instead of fread). The
+   * parameters will use fread() syntax, make sure to follow them. */
+  CINIT(READFUNCTION, FUNCTIONPOINT, 12),
+
+  /* Time-out the read operation after this amount of seconds */
+  CINIT(TIMEOUT, LONG, 13),
+
+  /* If the CURLOPT_INFILE is used, this can be used to inform libcurl about
+   * how large the file being sent really is. That allows better error
+   * checking and better verifies that the upload was successful. -1 means
+   * unknown size.
+   *
+   * For large file support, there is also a _LARGE version of the key
+   * which takes an off_t type, allowing platforms with larger off_t
+   * sizes to handle larger files.  See below for INFILESIZE_LARGE.
+   */
+  CINIT(INFILESIZE, LONG, 14),
+
+  /* POST static input fields. */
+  CINIT(POSTFIELDS, OBJECTPOINT, 15),
+
+  /* Set the referrer page (needed by some CGIs) */
+  CINIT(REFERER, OBJECTPOINT, 16),
+
+  /* Set the FTP PORT string (interface name, named or numerical IP address)
+     Use i.e '-' to use default address. */
+  CINIT(FTPPORT, OBJECTPOINT, 17),
+
+  /* Set the User-Agent string (examined by some CGIs) */
+  CINIT(USERAGENT, OBJECTPOINT, 18),
+
+  /* If the download receives less than "low speed limit" bytes/second
+   * during "low speed time" seconds, the operations is aborted.
+   * You could i.e if you have a pretty high speed connection, abort if
+   * it is less than 2000 bytes/sec during 20 seconds.
+   */
+
+  /* Set the "low speed limit" */
+  CINIT(LOW_SPEED_LIMIT, LONG, 19),
+
+  /* Set the "low speed time" */
+  CINIT(LOW_SPEED_TIME, LONG, 20),
+
+  /* Set the continuation offset.
+   *
+   * Note there is also a _LARGE version of this key which uses
+   * off_t types, allowing for large file offsets on platforms which
+   * use larger-than-32-bit off_t's.  Look below for RESUME_FROM_LARGE.
+   */
+  CINIT(RESUME_FROM, LONG, 21),
+
+  /* Set cookie in request: */
+  CINIT(COOKIE, OBJECTPOINT, 22),
+
+  /* This points to a linked list of headers, struct curl_slist kind */
+  CINIT(HTTPHEADER, OBJECTPOINT, 23),
+
+  /* This points to a linked list of post entries, struct curl_httppost */
+  CINIT(HTTPPOST, OBJECTPOINT, 24),
+
+  /* name of the file keeping your private SSL-certificate */
+  CINIT(SSLCERT, OBJECTPOINT, 25),
+
+  /* password for the SSL or SSH private key */
+  CINIT(KEYPASSWD, OBJECTPOINT, 26),
+
+  /* send TYPE parameter? */
+  CINIT(CRLF, LONG, 27),
+
+  /* send linked-list of QUOTE commands */
+  CINIT(QUOTE, OBJECTPOINT, 28),
+
+  /* send FILE * or void * to store headers to, if you use a callback it
+     is simply passed to the callback unmodified */
+  CINIT(WRITEHEADER, OBJECTPOINT, 29),
+
+  /* point to a file to read the initial cookies from, also enables
+     "cookie awareness" */
+  CINIT(COOKIEFILE, OBJECTPOINT, 31),
+
+  /* What version to specifically try to use.
+     See CURL_SSLVERSION defines below. */
+  CINIT(SSLVERSION, LONG, 32),
+
+  /* What kind of HTTP time condition to use, see defines */
+  CINIT(TIMECONDITION, LONG, 33),
+
+  /* Time to use with the above condition. Specified in number of seconds
+     since 1 Jan 1970 */
+  CINIT(TIMEVALUE, LONG, 34),
+
+  /* 35 = OBSOLETE */
+
+  /* Custom request, for customizing the get command like
+     HTTP: DELETE, TRACE and others
+     FTP: to use a different list command
+     */
+  CINIT(CUSTOMREQUEST, OBJECTPOINT, 36),
+
+  /* HTTP request, for odd commands like DELETE, TRACE and others */
+  CINIT(STDERR, OBJECTPOINT, 37),
+
+  /* 38 is not used */
+
+  /* send linked-list of post-transfer QUOTE commands */
+  CINIT(POSTQUOTE, OBJECTPOINT, 39),
+
+  /* Pass a pointer to string of the output using full variable-replacement
+     as described elsewhere. */
+  CINIT(WRITEINFO, OBJECTPOINT, 40),
+
+  CINIT(VERBOSE, LONG, 41),      /* talk a lot */
+  CINIT(HEADER, LONG, 42),       /* throw the header out too */
+  CINIT(NOPROGRESS, LONG, 43),   /* shut off the progress meter */
+  CINIT(NOBODY, LONG, 44),       /* use HEAD to get http document */
+  CINIT(FAILONERROR, LONG, 45),  /* no output on http error codes >= 300 */
+  CINIT(UPLOAD, LONG, 46),       /* this is an upload */
+  CINIT(POST, LONG, 47),         /* HTTP POST method */
+  CINIT(DIRLISTONLY, LONG, 48),  /* return bare names when listing directories */
+
+  CINIT(APPEND, LONG, 50),       /* Append instead of overwrite on upload! */
+
+  /* Specify whether to read the user+password from the .netrc or the URL.
+   * This must be one of the CURL_NETRC_* enums below. */
+  CINIT(NETRC, LONG, 51),
+
+  CINIT(FOLLOWLOCATION, LONG, 52),  /* use Location: Luke! */
+
+  CINIT(TRANSFERTEXT, LONG, 53), /* transfer data in text/ASCII format */
+  CINIT(PUT, LONG, 54),          /* HTTP PUT */
+
+  /* 55 = OBSOLETE */
+
+  /* Function that will be called instead of the internal progress display
+   * function. This function should be defined as the curl_progress_callback
+   * prototype defines. */
+  CINIT(PROGRESSFUNCTION, FUNCTIONPOINT, 56),
+
+  /* Data passed to the progress callback */
+  CINIT(PROGRESSDATA, OBJECTPOINT, 57),
+
+  /* We want the referrer field set automatically when following locations */
+  CINIT(AUTOREFERER, LONG, 58),
+
+  /* Port of the proxy, can be set in the proxy string as well with:
+     "[host]:[port]" */
+  CINIT(PROXYPORT, LONG, 59),
+
+  /* size of the POST input data, if strlen() is not good to use */
+  CINIT(POSTFIELDSIZE, LONG, 60),
+
+  /* tunnel non-http operations through a HTTP proxy */
+  CINIT(HTTPPROXYTUNNEL, LONG, 61),
+
+  /* Set the interface string to use as outgoing network interface */
+  CINIT(INTERFACE, OBJECTPOINT, 62),
+
+  /* Set the krb4/5 security level, this also enables krb4/5 awareness.  This
+   * is a string, 'clear', 'safe', 'confidential' or 'private'.  If the string
+   * is set but doesn't match one of these, 'private' will be used.  */
+  CINIT(KRBLEVEL, OBJECTPOINT, 63),
+
+  /* Set if we should verify the peer in ssl handshake, set 1 to verify. */
+  CINIT(SSL_VERIFYPEER, LONG, 64),
+
+  /* The CApath or CAfile used to validate the peer certificate
+     this option is used only if SSL_VERIFYPEER is true */
+  CINIT(CAINFO, OBJECTPOINT, 65),
+
+  /* 66 = OBSOLETE */
+  /* 67 = OBSOLETE */
+
+  /* Maximum number of http redirects to follow */
+  CINIT(MAXREDIRS, LONG, 68),
+
+  /* Pass a long set to 1 to get the date of the requested document (if
+     possible)! Pass a zero to shut it off. */
+  CINIT(FILETIME, LONG, 69),
+
+  /* This points to a linked list of telnet options */
+  CINIT(TELNETOPTIONS, OBJECTPOINT, 70),
+
+  /* Max amount of cached alive connections */
+  CINIT(MAXCONNECTS, LONG, 71),
+
+  /* What policy to use when closing connections when the cache is filled
+     up */
+  CINIT(CLOSEPOLICY, LONG, 72),
+
+  /* 73 = OBSOLETE */
+
+  /* Set to explicitly use a new connection for the upcoming transfer.
+     Do not use this unless you're absolutely sure of this, as it makes the
+     operation slower and is less friendly for the network. */
+  CINIT(FRESH_CONNECT, LONG, 74),
+
+  /* Set to explicitly forbid the upcoming transfer's connection to be re-used
+     when done. Do not use this unless you're absolutely sure of this, as it
+     makes the operation slower and is less friendly for the network. */
+  CINIT(FORBID_REUSE, LONG, 75),
+
+  /* Set to a file name that contains random data for libcurl to use to
+     seed the random engine when doing SSL connects. */
+  CINIT(RANDOM_FILE, OBJECTPOINT, 76),
+
+  /* Set to the Entropy Gathering Daemon socket pathname */
+  CINIT(EGDSOCKET, OBJECTPOINT, 77),
+
+  /* Time-out connect operations after this amount of seconds, if connects
+     are OK within this time, then fine... This only aborts the connect
+     phase. [Only works on unix-style/SIGALRM operating systems] */
+  CINIT(CONNECTTIMEOUT, LONG, 78),
+
+  /* Function that will be called to store headers (instead of fwrite). The
+   * parameters will use fwrite() syntax, make sure to follow them. */
+  CINIT(HEADERFUNCTION, FUNCTIONPOINT, 79),
+
+  /* Set this to force the HTTP request to get back to GET. Only really usable
+     if POST, PUT or a custom request have been used first.
+   */
+  CINIT(HTTPGET, LONG, 80),
+
+  /* Set if we should verify the Common name from the peer certificate in ssl
+   * handshake, set 1 to check existence, 2 to ensure that it matches the
+   * provided hostname. */
+  CINIT(SSL_VERIFYHOST, LONG, 81),
+
+  /* Specify which file name to write all known cookies in after completed
+     operation. Set file name to "-" (dash) to make it go to stdout. */
+  CINIT(COOKIEJAR, OBJECTPOINT, 82),
+
+  /* Specify which SSL ciphers to use */
+  CINIT(SSL_CIPHER_LIST, OBJECTPOINT, 83),
+
+  /* Specify which HTTP version to use! This must be set to one of the
+     CURL_HTTP_VERSION* enums set below. */
+  CINIT(HTTP_VERSION, LONG, 84),
+
+  /* Specifically switch on or off the FTP engine's use of the EPSV command. By
+     default, that one will always be attempted before the more traditional
+     PASV command. */
+  CINIT(FTP_USE_EPSV, LONG, 85),
+
+  /* type of the file keeping your SSL-certificate ("DER", "PEM", "ENG") */
+  CINIT(SSLCERTTYPE, OBJECTPOINT, 86),
+
+  /* name of the file keeping your private SSL-key */
+  CINIT(SSLKEY, OBJECTPOINT, 87),
+
+  /* type of the file keeping your private SSL-key ("DER", "PEM", "ENG") */
+  CINIT(SSLKEYTYPE, OBJECTPOINT, 88),
+
+  /* crypto engine for the SSL-sub system */
+  CINIT(SSLENGINE, OBJECTPOINT, 89),
+
+  /* set the crypto engine for the SSL-sub system as default
+     the param has no meaning...
+   */
+  CINIT(SSLENGINE_DEFAULT, LONG, 90),
+
+  /* Non-zero value means to use the global dns cache */
+  CINIT(DNS_USE_GLOBAL_CACHE, LONG, 91), /* To become OBSOLETE soon */
+
+  /* DNS cache timeout */
+  CINIT(DNS_CACHE_TIMEOUT, LONG, 92),
+
+  /* send linked-list of pre-transfer QUOTE commands */
+  CINIT(PREQUOTE, OBJECTPOINT, 93),
+
+  /* set the debug function */
+  CINIT(DEBUGFUNCTION, FUNCTIONPOINT, 94),
+
+  /* set the data for the debug function */
+  CINIT(DEBUGDATA, OBJECTPOINT, 95),
+
+  /* mark this as start of a cookie session */
+  CINIT(COOKIESESSION, LONG, 96),
+
+  /* The CApath directory used to validate the peer certificate
+     this option is used only if SSL_VERIFYPEER is true */
+  CINIT(CAPATH, OBJECTPOINT, 97),
+
+  /* Instruct libcurl to use a smaller receive buffer */
+  CINIT(BUFFERSIZE, LONG, 98),
+
+  /* Instruct libcurl to not use any signal/alarm handlers, even when using
+     timeouts. This option is useful for multi-threaded applications.
+     See libcurl-the-guide for more background information. */
+  CINIT(NOSIGNAL, LONG, 99),
+
+  /* Provide a CURLShare for mutexing non-ts data */
+  CINIT(SHARE, OBJECTPOINT, 100),
+
+  /* indicates type of proxy. accepted values are CURLPROXY_HTTP (default),
+     CURLPROXY_SOCKS4, CURLPROXY_SOCKS4A and CURLPROXY_SOCKS5. */
+  CINIT(PROXYTYPE, LONG, 101),
+
+  /* Set the Accept-Encoding string. Use this to tell a server you would like
+     the response to be compressed. */
+  CINIT(ENCODING, OBJECTPOINT, 102),
+
+  /* Set pointer to private data */
+  CINIT(PRIVATE, OBJECTPOINT, 103),
+
+  /* Set aliases for HTTP 200 in the HTTP Response header */
+  CINIT(HTTP200ALIASES, OBJECTPOINT, 104),
+
+  /* Continue to send authentication (user+password) when following locations,
+     even when hostname changed. This can potentially send off the name
+     and password to whatever host the server decides. */
+  CINIT(UNRESTRICTED_AUTH, LONG, 105),
+
+  /* Specifically switch on or off the FTP engine's use of the EPRT command ( it
+     also disables the LPRT attempt). By default, those ones will always be
+     attempted before the good old traditional PORT command. */
+  CINIT(FTP_USE_EPRT, LONG, 106),
+
+  /* Set this to a bitmask value to enable the particular authentications
+     methods you like. Use this in combination with CURLOPT_USERPWD.
+     Note that setting multiple bits may cause extra network round-trips. */
+  CINIT(HTTPAUTH, LONG, 107),
+
+  /* Set the ssl context callback function, currently only for OpenSSL ssl_ctx
+     in second argument. The function must be matching the
+     curl_ssl_ctx_callback proto. */
+  CINIT(SSL_CTX_FUNCTION, FUNCTIONPOINT, 108),
+
+  /* Set the userdata for the ssl context callback function's third
+     argument */
+  CINIT(SSL_CTX_DATA, OBJECTPOINT, 109),
+
+  /* FTP Option that causes missing dirs to be created on the remote server.
+     In 7.19.4 we introduced the convenience enums for this option using the
+     CURLFTP_CREATE_DIR prefix.
+  */
+  CINIT(FTP_CREATE_MISSING_DIRS, LONG, 110),
+
+  /* Set this to a bitmask value to enable the particular authentications
+     methods you like. Use this in combination with CURLOPT_PROXYUSERPWD.
+     Note that setting multiple bits may cause extra network round-trips. */
+  CINIT(PROXYAUTH, LONG, 111),
+
+  /* FTP option that changes the timeout, in seconds, associated with
+     getting a response.  This is different from transfer timeout time and
+     essentially places a demand on the FTP server to acknowledge commands
+     in a timely manner. */
+  CINIT(FTP_RESPONSE_TIMEOUT, LONG, 112),
+
+  /* Set this option to one of the CURL_IPRESOLVE_* defines (see below) to
+     tell libcurl to resolve names to those IP versions only. This only has
+     affect on systems with support for more than one, i.e IPv4 _and_ IPv6. */
+  CINIT(IPRESOLVE, LONG, 113),
+
+  /* Set this option to limit the size of a file that will be downloaded from
+     an HTTP or FTP server.
+
+     Note there is also _LARGE version which adds large file support for
+     platforms which have larger off_t sizes.  See MAXFILESIZE_LARGE below. */
+  CINIT(MAXFILESIZE, LONG, 114),
+
+  /* See the comment for INFILESIZE above, but in short, specifies
+   * the size of the file being uploaded.  -1 means unknown.
+   */
+  CINIT(INFILESIZE_LARGE, OFF_T, 115),
+
+  /* Sets the continuation offset.  There is also a LONG version of this;
+   * look above for RESUME_FROM.
+   */
+  CINIT(RESUME_FROM_LARGE, OFF_T, 116),
+
+  /* Sets the maximum size of data that will be downloaded from
+   * an HTTP or FTP server.  See MAXFILESIZE above for the LONG version.
+   */
+  CINIT(MAXFILESIZE_LARGE, OFF_T, 117),
+
+  /* Set this option to the file name of your .netrc file you want libcurl
+     to parse (using the CURLOPT_NETRC option). If not set, libcurl will do
+     a poor attempt to find the user's home directory and check for a .netrc
+     file in there. */
+  CINIT(NETRC_FILE, OBJECTPOINT, 118),
+
+  /* Enable SSL/TLS for FTP, pick one of:
+     CURLFTPSSL_TRY     - try using SSL, proceed anyway otherwise
+     CURLFTPSSL_CONTROL - SSL for the control connection or fail
+     CURLFTPSSL_ALL     - SSL for all communication or fail
+  */
+  CINIT(USE_SSL, LONG, 119),
+
+  /* The _LARGE version of the standard POSTFIELDSIZE option */
+  CINIT(POSTFIELDSIZE_LARGE, OFF_T, 120),
+
+  /* Enable/disable the TCP Nagle algorithm */
+  CINIT(TCP_NODELAY, LONG, 121),
+
+  /* 122 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */
+  /* 123 OBSOLETE. Gone in 7.16.0 */
+  /* 124 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */
+  /* 125 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */
+  /* 126 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */
+  /* 127 OBSOLETE. Gone in 7.16.0 */
+  /* 128 OBSOLETE. Gone in 7.16.0 */
+
+  /* When FTP over SSL/TLS is selected (with CURLOPT_USE_SSL), this option
+     can be used to change libcurl's default action which is to first try
+     "AUTH SSL" and then "AUTH TLS" in this order, and proceed when a OK
+     response has been received.
+
+     Available parameters are:
+     CURLFTPAUTH_DEFAULT - let libcurl decide
+     CURLFTPAUTH_SSL     - try "AUTH SSL" first, then TLS
+     CURLFTPAUTH_TLS     - try "AUTH TLS" first, then SSL
+  */
+  CINIT(FTPSSLAUTH, LONG, 129),
+
+  CINIT(IOCTLFUNCTION, FUNCTIONPOINT, 130),
+  CINIT(IOCTLDATA, OBJECTPOINT, 131),
+
+  /* 132 OBSOLETE. Gone in 7.16.0 */
+  /* 133 OBSOLETE. Gone in 7.16.0 */
+
+  /* zero terminated string for pass on to the FTP server when asked for
+     "account" info */
+  CINIT(FTP_ACCOUNT, OBJECTPOINT, 134),
+
+  /* feed cookies into cookie engine */
+  CINIT(COOKIELIST, OBJECTPOINT, 135),
+
+  /* ignore Content-Length */
+  CINIT(IGNORE_CONTENT_LENGTH, LONG, 136),
+
+  /* Set to non-zero to skip the IP address received in a 227 PASV FTP server
+     response. Typically used for FTP-SSL purposes but is not restricted to
+     that. libcurl will then instead use the same IP address it used for the
+     control connection. */
+  CINIT(FTP_SKIP_PASV_IP, LONG, 137),
+
+  /* Select "file method" to use when doing FTP, see the curl_ftpmethod
+     above. */
+  CINIT(FTP_FILEMETHOD, LONG, 138),
+
+  /* Local port number to bind the socket to */
+  CINIT(LOCALPORT, LONG, 139),
+
+  /* Number of ports to try, including the first one set with LOCALPORT.
+     Thus, setting it to 1 will make no additional attempts but the first.
+  */
+  CINIT(LOCALPORTRANGE, LONG, 140),
+
+  /* no transfer, set up connection and let application use the socket by
+     extracting it with CURLINFO_LASTSOCKET */
+  CINIT(CONNECT_ONLY, LONG, 141),
+
+  /* Function that will be called to convert from the
+     network encoding (instead of using the iconv calls in libcurl) */
+  CINIT(CONV_FROM_NETWORK_FUNCTION, FUNCTIONPOINT, 142),
+
+  /* Function that will be called to convert to the
+     network encoding (instead of using the iconv calls in libcurl) */
+  CINIT(CONV_TO_NETWORK_FUNCTION, FUNCTIONPOINT, 143),
+
+  /* Function that will be called to convert from UTF8
+     (instead of using the iconv calls in libcurl)
+     Note that this is used only for SSL certificate processing */
+  CINIT(CONV_FROM_UTF8_FUNCTION, FUNCTIONPOINT, 144),
+
+  /* if the connection proceeds too quickly then need to slow it down */
+  /* limit-rate: maximum number of bytes per second to send or receive */
+  CINIT(MAX_SEND_SPEED_LARGE, OFF_T, 145),
+  CINIT(MAX_RECV_SPEED_LARGE, OFF_T, 146),
+
+  /* Pointer to command string to send if USER/PASS fails. */
+  CINIT(FTP_ALTERNATIVE_TO_USER, OBJECTPOINT, 147),
+
+  /* callback function for setting socket options */
+  CINIT(SOCKOPTFUNCTION, FUNCTIONPOINT, 148),
+  CINIT(SOCKOPTDATA, OBJECTPOINT, 149),
+
+  /* set to 0 to disable session ID re-use for this transfer, default is
+     enabled (== 1) */
+  CINIT(SSL_SESSIONID_CACHE, LONG, 150),
+
+  /* allowed SSH authentication methods */
+  CINIT(SSH_AUTH_TYPES, LONG, 151),
+
+  /* Used by scp/sftp to do public/private key authentication */
+  CINIT(SSH_PUBLIC_KEYFILE, OBJECTPOINT, 152),
+  CINIT(SSH_PRIVATE_KEYFILE, OBJECTPOINT, 153),
+
+  /* Send CCC (Clear Command Channel) after authentication */
+  CINIT(FTP_SSL_CCC, LONG, 154),
+
+  /* Same as TIMEOUT and CONNECTTIMEOUT, but with ms resolution */
+  CINIT(TIMEOUT_MS, LONG, 155),
+  CINIT(CONNECTTIMEOUT_MS, LONG, 156),
+
+  /* set to zero to disable the libcurl's decoding and thus pass the raw body
+     data to the application even when it is encoded/compressed */
+  CINIT(HTTP_TRANSFER_DECODING, LONG, 157),
+  CINIT(HTTP_CONTENT_DECODING, LONG, 158),
+
+  /* Permission used when creating new files and directories on the remote
+     server for protocols that support it, SFTP/SCP/FILE */
+  CINIT(NEW_FILE_PERMS, LONG, 159),
+  CINIT(NEW_DIRECTORY_PERMS, LONG, 160),
+
+  /* Set the behaviour of POST when redirecting. Values must be set to one
+     of CURL_REDIR* defines below. This used to be called CURLOPT_POST301 */
+  CINIT(POSTREDIR, LONG, 161),
+
+  /* used by scp/sftp to verify the host's public key */
+  CINIT(SSH_HOST_PUBLIC_KEY_MD5, OBJECTPOINT, 162),
+
+  /* Callback function for opening socket (instead of socket(2)). Optionally,
+     callback is able change the address or refuse to connect returning
+     CURL_SOCKET_BAD.  The callback should have type
+     curl_opensocket_callback */
+  CINIT(OPENSOCKETFUNCTION, FUNCTIONPOINT, 163),
+  CINIT(OPENSOCKETDATA, OBJECTPOINT, 164),
+
+  /* POST volatile input fields. */
+  CINIT(COPYPOSTFIELDS, OBJECTPOINT, 165),
+
+  /* set transfer mode (;type=<a|i>) when doing FTP via an HTTP proxy */
+  CINIT(PROXY_TRANSFER_MODE, LONG, 166),
+
+  /* Callback function for seeking in the input stream */
+  CINIT(SEEKFUNCTION, FUNCTIONPOINT, 167),
+  CINIT(SEEKDATA, OBJECTPOINT, 168),
+
+  /* CRL file */
+  CINIT(CRLFILE, OBJECTPOINT, 169),
+
+  /* Issuer certificate */
+  CINIT(ISSUERCERT, OBJECTPOINT, 170),
+
+  /* (IPv6) Address scope */
+  CINIT(ADDRESS_SCOPE, LONG, 171),
+
+  /* Collect certificate chain info and allow it to get retrievable with
+     CURLINFO_CERTINFO after the transfer is complete. (Unfortunately) only
+     working with OpenSSL-powered builds. */
+  CINIT(CERTINFO, LONG, 172),
+
+  /* "name" and "pwd" to use when fetching. */
+  CINIT(USERNAME, OBJECTPOINT, 173),
+  CINIT(PASSWORD, OBJECTPOINT, 174),
+
+    /* "name" and "pwd" to use with Proxy when fetching. */
+  CINIT(PROXYUSERNAME, OBJECTPOINT, 175),
+  CINIT(PROXYPASSWORD, OBJECTPOINT, 176),
+
+  /* Comma separated list of hostnames defining no-proxy zones. These should
+     match both hostnames directly, and hostnames within a domain. For
+     example, local.com will match local.com and www.local.com, but NOT
+     notlocal.com or www.notlocal.com. For compatibility with other
+     implementations of this, .local.com will be considered to be the same as
+     local.com. A single * is the only valid wildcard, and effectively
+     disables the use of proxy. */
+  CINIT(NOPROXY, OBJECTPOINT, 177),
+
+  /* block size for TFTP transfers */
+  CINIT(TFTP_BLKSIZE, LONG, 178),
+
+  /* Socks Service */
+  CINIT(SOCKS5_GSSAPI_SERVICE, OBJECTPOINT, 179),
+
+  /* Socks Service */
+  CINIT(SOCKS5_GSSAPI_NEC, LONG, 180),
+
+  /* set the bitmask for the protocols that are allowed to be used for the
+     transfer, which thus helps the app which takes URLs from users or other
+     external inputs and want to restrict what protocol(s) to deal
+     with. Defaults to CURLPROTO_ALL. */
+  CINIT(PROTOCOLS, LONG, 181),
+
+  /* set the bitmask for the protocols that libcurl is allowed to follow to,
+     as a subset of the CURLOPT_PROTOCOLS ones. That means the protocol needs
+     to be set in both bitmasks to be allowed to get redirected to. Defaults
+     to all protocols except FILE and SCP. */
+  CINIT(REDIR_PROTOCOLS, LONG, 182),
+
+  /* set the SSH knownhost file name to use */
+  CINIT(SSH_KNOWNHOSTS, OBJECTPOINT, 183),
+
+  /* set the SSH host key callback, must point to a curl_sshkeycallback
+     function */
+  CINIT(SSH_KEYFUNCTION, FUNCTIONPOINT, 184),
+
+  /* set the SSH host key callback custom pointer */
+  CINIT(SSH_KEYDATA, OBJECTPOINT, 185),
+
+  CURLOPT_LASTENTRY /* the last unused */
+} CURLoption;
+
+#ifndef CURL_NO_OLDIES /* define this to test if your app builds with all
+                          the obsolete stuff removed! */
+
+/* Backwards compatibility with older names */
+/* These are scheduled to disappear by 2011 */
+
+/* This was added in version 7.19.1 */
+#define CURLOPT_POST301 CURLOPT_POSTREDIR
+
+/* These are scheduled to disappear by 2009 */
+
+/* The following were added in 7.17.0 */
+#define CURLOPT_SSLKEYPASSWD CURLOPT_KEYPASSWD
+#define CURLOPT_FTPAPPEND CURLOPT_APPEND
+#define CURLOPT_FTPLISTONLY CURLOPT_DIRLISTONLY
+#define CURLOPT_FTP_SSL CURLOPT_USE_SSL
+
+/* The following were added earlier */
+
+#define CURLOPT_SSLCERTPASSWD CURLOPT_KEYPASSWD
+#define CURLOPT_KRB4LEVEL CURLOPT_KRBLEVEL
+
+#else
+/* This is set if CURL_NO_OLDIES is defined at compile-time */
+#undef CURLOPT_DNS_USE_GLOBAL_CACHE /* soon obsolete */
+#endif
+
+
+  /* Below here follows defines for the CURLOPT_IPRESOLVE option. If a host
+     name resolves addresses using more than one IP protocol version, this
+     option might be handy to force libcurl to use a specific IP version. */
+#define CURL_IPRESOLVE_WHATEVER 0 /* default, resolves addresses to all IP
+                                     versions that your system allows */
+#define CURL_IPRESOLVE_V4       1 /* resolve to ipv4 addresses */
+#define CURL_IPRESOLVE_V6       2 /* resolve to ipv6 addresses */
+
+  /* three convenient "aliases" that follow the name scheme better */
+#define CURLOPT_WRITEDATA CURLOPT_FILE
+#define CURLOPT_READDATA  CURLOPT_INFILE
+#define CURLOPT_HEADERDATA CURLOPT_WRITEHEADER
+
+  /* These enums are for use with the CURLOPT_HTTP_VERSION option. */
+enum {
+  CURL_HTTP_VERSION_NONE, /* setting this means we don't care, and that we'd
+                             like the library to choose the best possible
+                             for us! */
+  CURL_HTTP_VERSION_1_0,  /* please use HTTP 1.0 in the request */
+  CURL_HTTP_VERSION_1_1,  /* please use HTTP 1.1 in the request */
+
+  CURL_HTTP_VERSION_LAST /* *ILLEGAL* http version */
+};
+
+  /* These enums are for use with the CURLOPT_NETRC option. */
+enum CURL_NETRC_OPTION {
+  CURL_NETRC_IGNORED,     /* The .netrc will never be read.
+                           * This is the default. */
+  CURL_NETRC_OPTIONAL,    /* A user:password in the URL will be preferred
+                           * to one in the .netrc. */
+  CURL_NETRC_REQUIRED,    /* A user:password in the URL will be ignored.
+                           * Unless one is set programmatically, the .netrc
+                           * will be queried. */
+  CURL_NETRC_LAST
+};
+
+enum {
+  CURL_SSLVERSION_DEFAULT,
+  CURL_SSLVERSION_TLSv1,
+  CURL_SSLVERSION_SSLv2,
+  CURL_SSLVERSION_SSLv3,
+
+  CURL_SSLVERSION_LAST /* never use, keep last */
+};
+
+/* symbols to use with CURLOPT_POSTREDIR.
+   CURL_REDIR_POST_301 and CURL_REDIR_POST_302 can be bitwise ORed so that
+   CURL_REDIR_POST_301 | CURL_REDIR_POST_302 == CURL_REDIR_POST_ALL */
+
+#define CURL_REDIR_GET_ALL  0
+#define CURL_REDIR_POST_301 1
+#define CURL_REDIR_POST_302 2
+#define CURL_REDIR_POST_ALL (CURL_REDIR_POST_301|CURL_REDIR_POST_302)
+
+typedef enum {
+  CURL_TIMECOND_NONE,
+
+  CURL_TIMECOND_IFMODSINCE,
+  CURL_TIMECOND_IFUNMODSINCE,
+  CURL_TIMECOND_LASTMOD,
+
+  CURL_TIMECOND_LAST
+} curl_TimeCond;
+
+
+/* curl_strequal() and curl_strnequal() are subject for removal in a future
+   libcurl, see lib/README.curlx for details */
+CURL_EXTERN int (curl_strequal)(const char *s1, const char *s2);
+CURL_EXTERN int (curl_strnequal)(const char *s1, const char *s2, size_t n);
+
+/* name is uppercase CURLFORM_<name> */
+#ifdef CFINIT
+#undef CFINIT
+#endif
+
+#ifdef CURL_ISOCPP
+#define CFINIT(name) CURLFORM_ ## name
+#else
+/* The macro "##" is ISO C, we assume pre-ISO C doesn't support it. */
+#define CFINIT(name) CURLFORM_/**/name
+#endif
+
+typedef enum {
+  CFINIT(NOTHING),        /********* the first one is unused ************/
+
+  /*  */
+  CFINIT(COPYNAME),
+  CFINIT(PTRNAME),
+  CFINIT(NAMELENGTH),
+  CFINIT(COPYCONTENTS),
+  CFINIT(PTRCONTENTS),
+  CFINIT(CONTENTSLENGTH),
+  CFINIT(FILECONTENT),
+  CFINIT(ARRAY),
+  CFINIT(OBSOLETE),
+  CFINIT(FILE),
+
+  CFINIT(BUFFER),
+  CFINIT(BUFFERPTR),
+  CFINIT(BUFFERLENGTH),
+
+  CFINIT(CONTENTTYPE),
+  CFINIT(CONTENTHEADER),
+  CFINIT(FILENAME),
+  CFINIT(END),
+  CFINIT(OBSOLETE2),
+
+  CFINIT(STREAM),
+
+  CURLFORM_LASTENTRY /* the last unused */
+} CURLformoption;
+
+#undef CFINIT /* done */
+
+/* structure to be used as parameter for CURLFORM_ARRAY */
+struct curl_forms {
+  CURLformoption option;
+  const char     *value;
+};
+
+/* use this for multipart formpost building */
+/* Returns code for curl_formadd()
+ *
+ * Returns:
+ * CURL_FORMADD_OK             on success
+ * CURL_FORMADD_MEMORY         if the FormInfo allocation fails
+ * CURL_FORMADD_OPTION_TWICE   if one option is given twice for one Form
+ * CURL_FORMADD_NULL           if a null pointer was given for a char
+ * CURL_FORMADD_MEMORY         if the allocation of a FormInfo struct failed
+ * CURL_FORMADD_UNKNOWN_OPTION if an unknown option was used
+ * CURL_FORMADD_INCOMPLETE     if the some FormInfo is not complete (or error)
+ * CURL_FORMADD_MEMORY         if a curl_httppost struct cannot be allocated
+ * CURL_FORMADD_MEMORY         if some allocation for string copying failed.
+ * CURL_FORMADD_ILLEGAL_ARRAY  if an illegal option is used in an array
+ *
+ ***************************************************************************/
+typedef enum {
+  CURL_FORMADD_OK, /* first, no error */
+
+  CURL_FORMADD_MEMORY,
+  CURL_FORMADD_OPTION_TWICE,
+  CURL_FORMADD_NULL,
+  CURL_FORMADD_UNKNOWN_OPTION,
+  CURL_FORMADD_INCOMPLETE,
+  CURL_FORMADD_ILLEGAL_ARRAY,
+  CURL_FORMADD_DISABLED, /* libcurl was built with this disabled */
+
+  CURL_FORMADD_LAST /* last */
+} CURLFORMcode;
+
+/*
+ * NAME curl_formadd()
+ *
+ * DESCRIPTION
+ *
+ * Pretty advanced function for building multi-part formposts. Each invoke
+ * adds one part that together construct a full post. Then use
+ * CURLOPT_HTTPPOST to send it off to libcurl.
+ */
+CURL_EXTERN CURLFORMcode curl_formadd(struct curl_httppost **httppost,
+                                      struct curl_httppost **last_post,
+                                      ...);
+
+/*
+ * callback function for curl_formget()
+ * The void *arg pointer will be the one passed as second argument to
+ *   curl_formget().
+ * The character buffer passed to it must not be freed.
+ * Should return the buffer length passed to it as the argument "len" on
+ *   success.
+ */
+typedef size_t (*curl_formget_callback)(void *arg, const char *buf, size_t len);
+
+/*
+ * NAME curl_formget()
+ *
+ * DESCRIPTION
+ *
+ * Serialize a curl_httppost struct built with curl_formadd().
+ * Accepts a void pointer as second argument which will be passed to
+ * the curl_formget_callback function.
+ * Returns 0 on success.
+ */
+CURL_EXTERN int curl_formget(struct curl_httppost *form, void *arg,
+                             curl_formget_callback append);
+/*
+ * NAME curl_formfree()
+ *
+ * DESCRIPTION
+ *
+ * Free a multipart formpost previously built with curl_formadd().
+ */
+CURL_EXTERN void curl_formfree(struct curl_httppost *form);
+
+/*
+ * NAME curl_getenv()
+ *
+ * DESCRIPTION
+ *
+ * Returns a malloc()'ed string that MUST be curl_free()ed after usage is
+ * complete. DEPRECATED - see lib/README.curlx
+ */
+CURL_EXTERN char *curl_getenv(const char *variable);
+
+/*
+ * NAME curl_version()
+ *
+ * DESCRIPTION
+ *
+ * Returns a static ascii string of the libcurl version.
+ */
+CURL_EXTERN char *curl_version(void);
+
+/*
+ * NAME curl_easy_escape()
+ *
+ * DESCRIPTION
+ *
+ * Escapes URL strings (converts all letters consider illegal in URLs to their
+ * %XX versions). This function returns a new allocated string or NULL if an
+ * error occurred.
+ */
+CURL_EXTERN char *curl_easy_escape(CURL *handle,
+                                   const char *string,
+                                   int length);
+
+/* the previous version: */
+CURL_EXTERN char *curl_escape(const char *string,
+                              int length);
+
+
+/*
+ * NAME curl_easy_unescape()
+ *
+ * DESCRIPTION
+ *
+ * Unescapes URL encoding in strings (converts all %XX codes to their 8bit
+ * versions). This function returns a new allocated string or NULL if an error
+ * occurred.
+ * Conversion Note: On non-ASCII platforms the ASCII %XX codes are
+ * converted into the host encoding.
+ */
+CURL_EXTERN char *curl_easy_unescape(CURL *handle,
+                                     const char *string,
+                                     int length,
+                                     int *outlength);
+
+/* the previous version */
+CURL_EXTERN char *curl_unescape(const char *string,
+                                int length);
+
+/*
+ * NAME curl_free()
+ *
+ * DESCRIPTION
+ *
+ * Provided for de-allocation in the same translation unit that did the
+ * allocation. Added in libcurl 7.10
+ */
+CURL_EXTERN void curl_free(void *p);
+
+/*
+ * NAME curl_global_init()
+ *
+ * DESCRIPTION
+ *
+ * curl_global_init() should be invoked exactly once for each application that
+ * uses libcurl and before any call of other libcurl functions.
+ *
+ * This function is not thread-safe!
+ */
+CURL_EXTERN CURLcode curl_global_init(long flags);
+
+/*
+ * NAME curl_global_init_mem()
+ *
+ * DESCRIPTION
+ *
+ * curl_global_init() or curl_global_init_mem() should be invoked exactly once
+ * for each application that uses libcurl.  This function can be used to
+ * initialize libcurl and set user defined memory management callback
+ * functions.  Users can implement memory management routines to check for
+ * memory leaks, check for mis-use of the curl library etc.  User registered
+ * callback routines with be invoked by this library instead of the system
+ * memory management routines like malloc, free etc.
+ */
+CURL_EXTERN CURLcode curl_global_init_mem(long flags,
+                                          curl_malloc_callback m,
+                                          curl_free_callback f,
+                                          curl_realloc_callback r,
+                                          curl_strdup_callback s,
+                                          curl_calloc_callback c);
+
+/*
+ * NAME curl_global_cleanup()
+ *
+ * DESCRIPTION
+ *
+ * curl_global_cleanup() should be invoked exactly once for each application
+ * that uses libcurl
+ */
+CURL_EXTERN void curl_global_cleanup(void);
+
+/* linked-list structure for the CURLOPT_QUOTE option (and other) */
+struct curl_slist {
+  char *data;
+  struct curl_slist *next;
+};
+
+/*
+ * NAME curl_slist_append()
+ *
+ * DESCRIPTION
+ *
+ * Appends a string to a linked list. If no list exists, it will be created
+ * first. Returns the new list, after appending.
+ */
+CURL_EXTERN struct curl_slist *curl_slist_append(struct curl_slist *,
+                                                 const char *);
+
+/*
+ * NAME curl_slist_free_all()
+ *
+ * DESCRIPTION
+ *
+ * free a previously built curl_slist.
+ */
+CURL_EXTERN void curl_slist_free_all(struct curl_slist *);
+
+/*
+ * NAME curl_getdate()
+ *
+ * DESCRIPTION
+ *
+ * Returns the time, in seconds since 1 Jan 1970 of the time string given in
+ * the first argument. The time argument in the second parameter is unused
+ * and should be set to NULL.
+ */
+CURL_EXTERN time_t curl_getdate(const char *p, const time_t *unused);
+
+/* info about the certificate chain, only for OpenSSL builds. Asked
+   for with CURLOPT_CERTINFO / CURLINFO_CERTINFO */
+struct curl_certinfo {
+  int num_of_certs;             /* number of certificates with information */
+  struct curl_slist **certinfo; /* for each index in this array, there's a
+                                   linked list with textual information in the
+                                   format "name: value" */
+};
+
+#define CURLINFO_STRING   0x100000
+#define CURLINFO_LONG     0x200000
+#define CURLINFO_DOUBLE   0x300000
+#define CURLINFO_SLIST    0x400000
+#define CURLINFO_MASK     0x0fffff
+#define CURLINFO_TYPEMASK 0xf00000
+
+typedef enum {
+  CURLINFO_NONE, /* first, never use this */
+  CURLINFO_EFFECTIVE_URL    = CURLINFO_STRING + 1,
+  CURLINFO_RESPONSE_CODE    = CURLINFO_LONG   + 2,
+  CURLINFO_TOTAL_TIME       = CURLINFO_DOUBLE + 3,
+  CURLINFO_NAMELOOKUP_TIME  = CURLINFO_DOUBLE + 4,
+  CURLINFO_CONNECT_TIME     = CURLINFO_DOUBLE + 5,
+  CURLINFO_PRETRANSFER_TIME = CURLINFO_DOUBLE + 6,
+  CURLINFO_SIZE_UPLOAD      = CURLINFO_DOUBLE + 7,
+  CURLINFO_SIZE_DOWNLOAD    = CURLINFO_DOUBLE + 8,
+  CURLINFO_SPEED_DOWNLOAD   = CURLINFO_DOUBLE + 9,
+  CURLINFO_SPEED_UPLOAD     = CURLINFO_DOUBLE + 10,
+  CURLINFO_HEADER_SIZE      = CURLINFO_LONG   + 11,
+  CURLINFO_REQUEST_SIZE     = CURLINFO_LONG   + 12,
+  CURLINFO_SSL_VERIFYRESULT = CURLINFO_LONG   + 13,
+  CURLINFO_FILETIME         = CURLINFO_LONG   + 14,
+  CURLINFO_CONTENT_LENGTH_DOWNLOAD   = CURLINFO_DOUBLE + 15,
+  CURLINFO_CONTENT_LENGTH_UPLOAD     = CURLINFO_DOUBLE + 16,
+  CURLINFO_STARTTRANSFER_TIME = CURLINFO_DOUBLE + 17,
+  CURLINFO_CONTENT_TYPE     = CURLINFO_STRING + 18,
+  CURLINFO_REDIRECT_TIME    = CURLINFO_DOUBLE + 19,
+  CURLINFO_REDIRECT_COUNT   = CURLINFO_LONG   + 20,
+  CURLINFO_PRIVATE          = CURLINFO_STRING + 21,
+  CURLINFO_HTTP_CONNECTCODE = CURLINFO_LONG   + 22,
+  CURLINFO_HTTPAUTH_AVAIL   = CURLINFO_LONG   + 23,
+  CURLINFO_PROXYAUTH_AVAIL  = CURLINFO_LONG   + 24,
+  CURLINFO_OS_ERRNO         = CURLINFO_LONG   + 25,
+  CURLINFO_NUM_CONNECTS     = CURLINFO_LONG   + 26,
+  CURLINFO_SSL_ENGINES      = CURLINFO_SLIST  + 27,
+  CURLINFO_COOKIELIST       = CURLINFO_SLIST  + 28,
+  CURLINFO_LASTSOCKET       = CURLINFO_LONG   + 29,
+  CURLINFO_FTP_ENTRY_PATH   = CURLINFO_STRING + 30,
+  CURLINFO_REDIRECT_URL     = CURLINFO_STRING + 31,
+  CURLINFO_PRIMARY_IP       = CURLINFO_STRING + 32,
+  CURLINFO_APPCONNECT_TIME  = CURLINFO_DOUBLE + 33,
+  CURLINFO_CERTINFO         = CURLINFO_SLIST  + 34,
+  CURLINFO_CONDITION_UNMET  = CURLINFO_LONG   + 35,
+  /* Fill in new entries below here! */
+
+  CURLINFO_LASTONE          = 35
+} CURLINFO;
+
+/* CURLINFO_RESPONSE_CODE is the new name for the option previously known as
+   CURLINFO_HTTP_CODE */
+#define CURLINFO_HTTP_CODE CURLINFO_RESPONSE_CODE
+
+typedef enum {
+  CURLCLOSEPOLICY_NONE, /* first, never use this */
+
+  CURLCLOSEPOLICY_OLDEST,
+  CURLCLOSEPOLICY_LEAST_RECENTLY_USED,
+  CURLCLOSEPOLICY_LEAST_TRAFFIC,
+  CURLCLOSEPOLICY_SLOWEST,
+  CURLCLOSEPOLICY_CALLBACK,
+
+  CURLCLOSEPOLICY_LAST /* last, never use this */
+} curl_closepolicy;
+
+#define CURL_GLOBAL_SSL (1<<0)
+#define CURL_GLOBAL_WIN32 (1<<1)
+#define CURL_GLOBAL_ALL (CURL_GLOBAL_SSL|CURL_GLOBAL_WIN32)
+#define CURL_GLOBAL_NOTHING 0
+#define CURL_GLOBAL_DEFAULT CURL_GLOBAL_ALL
+
+
+/*****************************************************************************
+ * Setup defines, protos etc for the sharing stuff.
+ */
+
+/* Different data locks for a single share */
+typedef enum {
+  CURL_LOCK_DATA_NONE = 0,
+  /*  CURL_LOCK_DATA_SHARE is used internally to say that
+   *  the locking is just made to change the internal state of the share
+   *  itself.
+   */
+  CURL_LOCK_DATA_SHARE,
+  CURL_LOCK_DATA_COOKIE,
+  CURL_LOCK_DATA_DNS,
+  CURL_LOCK_DATA_SSL_SESSION,
+  CURL_LOCK_DATA_CONNECT,
+  CURL_LOCK_DATA_LAST
+} curl_lock_data;
+
+/* Different lock access types */
+typedef enum {
+  CURL_LOCK_ACCESS_NONE = 0,   /* unspecified action */
+  CURL_LOCK_ACCESS_SHARED = 1, /* for read perhaps */
+  CURL_LOCK_ACCESS_SINGLE = 2, /* for write perhaps */
+  CURL_LOCK_ACCESS_LAST        /* never use */
+} curl_lock_access;
+
+typedef void (*curl_lock_function)(CURL *handle,
+                                   curl_lock_data data,
+                                   curl_lock_access locktype,
+                                   void *userptr);
+typedef void (*curl_unlock_function)(CURL *handle,
+                                     curl_lock_data data,
+                                     void *userptr);
+
+typedef void CURLSH;
+
+typedef enum {
+  CURLSHE_OK,  /* all is fine */
+  CURLSHE_BAD_OPTION, /* 1 */
+  CURLSHE_IN_USE,     /* 2 */
+  CURLSHE_INVALID,    /* 3 */
+  CURLSHE_NOMEM,      /* out of memory */
+  CURLSHE_LAST /* never use */
+} CURLSHcode;
+
+typedef enum {
+  CURLSHOPT_NONE,  /* don't use */
+  CURLSHOPT_SHARE,   /* specify a data type to share */
+  CURLSHOPT_UNSHARE, /* specify which data type to stop sharing */
+  CURLSHOPT_LOCKFUNC,   /* pass in a 'curl_lock_function' pointer */
+  CURLSHOPT_UNLOCKFUNC, /* pass in a 'curl_unlock_function' pointer */
+  CURLSHOPT_USERDATA,   /* pass in a user data pointer used in the lock/unlock
+                           callback functions */
+  CURLSHOPT_LAST  /* never use */
+} CURLSHoption;
+
+CURL_EXTERN CURLSH *curl_share_init(void);
+CURL_EXTERN CURLSHcode curl_share_setopt(CURLSH *, CURLSHoption option, ...);
+CURL_EXTERN CURLSHcode curl_share_cleanup(CURLSH *);
+
+/****************************************************************************
+ * Structures for querying information about the curl library at runtime.
+ */
+
+typedef enum {
+  CURLVERSION_FIRST,
+  CURLVERSION_SECOND,
+  CURLVERSION_THIRD,
+  CURLVERSION_FOURTH,
+  CURLVERSION_LAST /* never actually use this */
+} CURLversion;
+
+/* The 'CURLVERSION_NOW' is the symbolic name meant to be used by
+   basically all programs ever that want to get version information. It is
+   meant to be a built-in version number for what kind of struct the caller
+   expects. If the struct ever changes, we redefine the NOW to another enum
+   from above. */
+#define CURLVERSION_NOW CURLVERSION_FOURTH
+
+typedef struct {
+  CURLversion age;          /* age of the returned struct */
+  const char *version;      /* LIBCURL_VERSION */
+  unsigned int version_num; /* LIBCURL_VERSION_NUM */
+  const char *host;         /* OS/host/cpu/machine when configured */
+  int features;             /* bitmask, see defines below */
+  const char *ssl_version;  /* human readable string */
+  long ssl_version_num;     /* not used anymore, always 0 */
+  const char *libz_version; /* human readable string */
+  /* protocols is terminated by an entry with a NULL protoname */
+  const char * const *protocols;
+
+  /* The fields below this were added in CURLVERSION_SECOND */
+  const char *ares;
+  int ares_num;
+
+  /* This field was added in CURLVERSION_THIRD */
+  const char *libidn;
+
+  /* These field were added in CURLVERSION_FOURTH */
+
+  /* Same as '_libiconv_version' if built with HAVE_ICONV */
+  int iconv_ver_num;
+
+  const char *libssh_version; /* human readable string */
+
+} curl_version_info_data;
+
+#define CURL_VERSION_IPV6      (1<<0)  /* IPv6-enabled */
+#define CURL_VERSION_KERBEROS4 (1<<1)  /* kerberos auth is supported */
+#define CURL_VERSION_SSL       (1<<2)  /* SSL options are present */
+#define CURL_VERSION_LIBZ      (1<<3)  /* libz features are present */
+#define CURL_VERSION_NTLM      (1<<4)  /* NTLM auth is supported */
+#define CURL_VERSION_GSSNEGOTIATE (1<<5) /* Negotiate auth support */
+#define CURL_VERSION_DEBUG     (1<<6)  /* built with debug capabilities */
+#define CURL_VERSION_ASYNCHDNS (1<<7)  /* asynchronous dns resolves */
+#define CURL_VERSION_SPNEGO    (1<<8)  /* SPNEGO auth */
+#define CURL_VERSION_LARGEFILE (1<<9)  /* supports files bigger than 2GB */
+#define CURL_VERSION_IDN       (1<<10) /* International Domain Names support */
+#define CURL_VERSION_SSPI      (1<<11) /* SSPI is supported */
+#define CURL_VERSION_CONV      (1<<12) /* character conversions supported */
+#define CURL_VERSION_CURLDEBUG (1<<13) /* debug memory tracking supported */
+
+/*
+ * NAME curl_version_info()
+ *
+ * DESCRIPTION
+ *
+ * This function returns a pointer to a static copy of the version info
+ * struct. See above.
+ */
+CURL_EXTERN curl_version_info_data *curl_version_info(CURLversion);
+
+/*
+ * NAME curl_easy_strerror()
+ *
+ * DESCRIPTION
+ *
+ * The curl_easy_strerror function may be used to turn a CURLcode value
+ * into the equivalent human readable error string.  This is useful
+ * for printing meaningful error messages.
+ */
+CURL_EXTERN const char *curl_easy_strerror(CURLcode);
+
+/*
+ * NAME curl_share_strerror()
+ *
+ * DESCRIPTION
+ *
+ * The curl_share_strerror function may be used to turn a CURLSHcode value
+ * into the equivalent human readable error string.  This is useful
+ * for printing meaningful error messages.
+ */
+CURL_EXTERN const char *curl_share_strerror(CURLSHcode);
+
+/*
+ * NAME curl_easy_pause()
+ *
+ * DESCRIPTION
+ *
+ * The curl_easy_pause function pauses or unpauses transfers. Select the new
+ * state by setting the bitmask, use the convenience defines below.
+ *
+ */
+CURL_EXTERN CURLcode curl_easy_pause(CURL *handle, int bitmask);
+
+#define CURLPAUSE_RECV      (1<<0)
+#define CURLPAUSE_RECV_CONT (0)
+
+#define CURLPAUSE_SEND      (1<<2)
+#define CURLPAUSE_SEND_CONT (0)
+
+#define CURLPAUSE_ALL       (CURLPAUSE_RECV|CURLPAUSE_SEND)
+#define CURLPAUSE_CONT      (CURLPAUSE_RECV_CONT|CURLPAUSE_SEND_CONT)
+
+#ifdef  __cplusplus
+}
+#endif
+
+/* unfortunately, the easy.h and multi.h include files need options and info
+  stuff before they can be included! */
+#include "easy.h" /* nothing in curl is fun without the easy stuff */
+#include "multi.h"
+
+/* the typechecker doesn't work in C++ (yet) */
+#if defined(__GNUC__) && defined(__GNUC_MINOR__) && \
+    ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) && \
+    !defined(__cplusplus) && !defined(CURL_DISABLE_TYPECHECK)
+#include "typecheck-gcc.h"
+#else
+#if defined(__STDC__) && (__STDC__ >= 1)
+/* This preprocessor magic that replaces a call with the exact same call is
+   only done to make sure application authors pass exactly three arguments
+   to these functions. */
+#define curl_easy_setopt(handle,opt,param) curl_easy_setopt(handle,opt,param)
+#define curl_easy_getinfo(handle,info,arg) curl_easy_getinfo(handle,info,arg)
+#define curl_share_setopt(share,opt,param) curl_share_setopt(share,opt,param)
+#define curl_multi_setopt(handle,opt,param) curl_multi_setopt(handle,opt,param)
+#endif /* __STDC__ >= 1 */
+#endif /* gcc >= 4.3 && !__cplusplus */
+
+#endif /* __CURL_CURL_H */
diff --git a/include/breakpad/third_party/curl/curlbuild.h b/include/breakpad/third_party/curl/curlbuild.h
new file mode 100644
index 0000000..b0a53e6
--- /dev/null
+++ b/include/breakpad/third_party/curl/curlbuild.h
@@ -0,0 +1,202 @@
+/* include/curl/curlbuild.h.  Generated from curlbuild.h.in by configure.  */
+#ifndef __CURL_CURLBUILD_H
+#define __CURL_CURLBUILD_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2009, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ * $Id: curlbuild.h.in,v 1.8 2009-04-29 15:15:38 yangtse Exp $
+ ***************************************************************************/
+
+/* ================================================================ */
+/*               NOTES FOR CONFIGURE CAPABLE SYSTEMS                */
+/* ================================================================ */
+
+/*
+ * NOTE 1:
+ * -------
+ *
+ * Nothing in this file is intended to be modified or adjusted by the
+ * curl library user nor by the curl library builder.
+ *
+ * If you think that something actually needs to be changed, adjusted
+ * or fixed in this file, then, report it on the libcurl development
+ * mailing list: http://cool.haxx.se/mailman/listinfo/curl-library/
+ *
+ * This header file shall only export symbols which are 'curl' or 'CURL'
+ * prefixed, otherwise public name space would be polluted.
+ *
+ * NOTE 2:
+ * -------
+ *
+ * Right now you might be staring at file include/curl/curlbuild.h.in or
+ * at file include/curl/curlbuild.h, this is due to the following reason:
+ *
+ * On systems capable of running the configure script, the configure process
+ * will overwrite the distributed include/curl/curlbuild.h file with one that
+ * is suitable and specific to the library being configured and built, which
+ * is generated from the include/curl/curlbuild.h.in template file.
+ *
+ */
+
+/* ================================================================ */
+/*  DEFINITION OF THESE SYMBOLS SHALL NOT TAKE PLACE ANYWHERE ELSE  */
+/* ================================================================ */
+
+#ifdef CURL_SIZEOF_LONG
+#  error "CURL_SIZEOF_LONG shall not be defined except in curlbuild.h"
+   Error Compilation_aborted_CURL_SIZEOF_LONG_already_defined
+#endif
+
+#ifdef CURL_TYPEOF_CURL_SOCKLEN_T
+#  error "CURL_TYPEOF_CURL_SOCKLEN_T shall not be defined except in curlbuild.h"
+   Error Compilation_aborted_CURL_TYPEOF_CURL_SOCKLEN_T_already_defined
+#endif
+
+#ifdef CURL_SIZEOF_CURL_SOCKLEN_T
+#  error "CURL_SIZEOF_CURL_SOCKLEN_T shall not be defined except in curlbuild.h"
+   Error Compilation_aborted_CURL_SIZEOF_CURL_SOCKLEN_T_already_defined
+#endif
+
+#ifdef CURL_TYPEOF_CURL_OFF_T
+#  error "CURL_TYPEOF_CURL_OFF_T shall not be defined except in curlbuild.h"
+   Error Compilation_aborted_CURL_TYPEOF_CURL_OFF_T_already_defined
+#endif
+
+#ifdef CURL_FORMAT_CURL_OFF_T
+#  error "CURL_FORMAT_CURL_OFF_T shall not be defined except in curlbuild.h"
+   Error Compilation_aborted_CURL_FORMAT_CURL_OFF_T_already_defined
+#endif
+
+#ifdef CURL_FORMAT_CURL_OFF_TU
+#  error "CURL_FORMAT_CURL_OFF_TU shall not be defined except in curlbuild.h"
+   Error Compilation_aborted_CURL_FORMAT_CURL_OFF_TU_already_defined
+#endif
+
+#ifdef CURL_FORMAT_OFF_T
+#  error "CURL_FORMAT_OFF_T shall not be defined except in curlbuild.h"
+   Error Compilation_aborted_CURL_FORMAT_OFF_T_already_defined
+#endif
+
+#ifdef CURL_SIZEOF_CURL_OFF_T
+#  error "CURL_SIZEOF_CURL_OFF_T shall not be defined except in curlbuild.h"
+   Error Compilation_aborted_CURL_SIZEOF_CURL_OFF_T_already_defined
+#endif
+
+#ifdef CURL_SUFFIX_CURL_OFF_T
+#  error "CURL_SUFFIX_CURL_OFF_T shall not be defined except in curlbuild.h"
+   Error Compilation_aborted_CURL_SUFFIX_CURL_OFF_T_already_defined
+#endif
+
+#ifdef CURL_SUFFIX_CURL_OFF_TU
+#  error "CURL_SUFFIX_CURL_OFF_TU shall not be defined except in curlbuild.h"
+   Error Compilation_aborted_CURL_SUFFIX_CURL_OFF_TU_already_defined
+#endif
+
+/* ================================================================ */
+/*  EXTERNAL INTERFACE SETTINGS FOR CONFIGURE CAPABLE SYSTEMS ONLY  */
+/* ================================================================ */
+
+/* Configure process defines this to 1 when it finds out that system  */
+/* header file ws2tcpip.h must be included by the external interface. */
+/* #undef CURL_PULL_WS2TCPIP_H */
+#ifdef CURL_PULL_WS2TCPIP_H
+#  ifndef WIN32_LEAN_AND_MEAN
+#    define WIN32_LEAN_AND_MEAN
+#  endif
+#  include <windows.h>
+#  include <winsock2.h>
+#  include <ws2tcpip.h>
+#endif
+
+/* Configure process defines this to 1 when it finds out that system   */
+/* header file sys/types.h must be included by the external interface. */
+#define CURL_PULL_SYS_TYPES_H 1
+#ifdef CURL_PULL_SYS_TYPES_H
+#  include <sys/types.h>
+#endif
+
+/* Configure process defines this to 1 when it finds out that system */
+/* header file stdint.h must be included by the external interface.  */
+/* #undef CURL_PULL_STDINT_H */
+#ifdef CURL_PULL_STDINT_H
+#  include <stdint.h>
+#endif
+
+/* Configure process defines this to 1 when it finds out that system  */
+/* header file inttypes.h must be included by the external interface. */
+/* #undef CURL_PULL_INTTYPES_H */
+#ifdef CURL_PULL_INTTYPES_H
+#  include <inttypes.h>
+#endif
+
+/* Configure process defines this to 1 when it finds out that system    */
+/* header file sys/socket.h must be included by the external interface. */
+#define CURL_PULL_SYS_SOCKET_H 1
+#ifdef CURL_PULL_SYS_SOCKET_H
+#  include <sys/socket.h>
+#endif
+
+/* The size of `long', as computed by sizeof. */
+#if defined(_M_X64) || (defined(__x86_64__) && !defined(__ILP32__)) ||      \
+    defined(__aarch64__) || (defined(__mips__) && _MIPS_SIM == _ABI64)
+#define CURL_SIZEOF_LONG 8
+#else
+#define CURL_SIZEOF_LONG 4
+#endif
+
+/* Integral data type used for curl_socklen_t. */
+#define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t
+
+/* The size of `curl_socklen_t', as computed by sizeof. */
+#define CURL_SIZEOF_CURL_SOCKLEN_T 4
+
+/* Data type definition of curl_socklen_t. */
+typedef CURL_TYPEOF_CURL_SOCKLEN_T curl_socklen_t;
+
+/* Signed integral data type used for curl_off_t. */
+#if defined(_M_X64) || (defined(__x86_64__) && !defined(__ILP32__)) ||      \
+    defined(__aarch64__)
+#define CURL_TYPEOF_CURL_OFF_T long
+#else
+#define CURL_TYPEOF_CURL_OFF_T int64_t
+#endif
+
+/* Data type definition of curl_off_t. */
+typedef CURL_TYPEOF_CURL_OFF_T curl_off_t;
+
+/* curl_off_t formatting string directive without "%" conversion specifier. */
+#define CURL_FORMAT_CURL_OFF_T "ld"
+
+/* unsigned curl_off_t formatting string without "%" conversion specifier. */
+#define CURL_FORMAT_CURL_OFF_TU "lu"
+
+/* curl_off_t formatting string directive with "%" conversion specifier. */
+#define CURL_FORMAT_OFF_T "%ld"
+
+/* The size of `curl_off_t', as computed by sizeof. */
+#define CURL_SIZEOF_CURL_OFF_T 8
+
+/* curl_off_t constant suffix. */
+#define CURL_SUFFIX_CURL_OFF_T L
+
+/* unsigned curl_off_t constant suffix. */
+#define CURL_SUFFIX_CURL_OFF_TU UL
+
+#endif /* __CURL_CURLBUILD_H */
diff --git a/include/breakpad/third_party/curl/curlrules.h b/include/breakpad/third_party/curl/curlrules.h
new file mode 100644
index 0000000..abac439
--- /dev/null
+++ b/include/breakpad/third_party/curl/curlrules.h
@@ -0,0 +1,249 @@
+#ifndef __CURL_CURLRULES_H
+#define __CURL_CURLRULES_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2009, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ * $Id: curlrules.h,v 1.7 2009-10-27 16:56:20 yangtse Exp $
+ ***************************************************************************/
+
+/* ================================================================ */
+/*                    COMPILE TIME SANITY CHECKS                    */
+/* ================================================================ */
+
+/*
+ * NOTE 1:
+ * -------
+ *
+ * All checks done in this file are intentionally placed in a public
+ * header file which is pulled by curl/curl.h when an application is
+ * being built using an already built libcurl library. Additionally
+ * this file is also included and used when building the library.
+ *
+ * If compilation fails on this file it is certainly sure that the
+ * problem is elsewhere. It could be a problem in the curlbuild.h
+ * header file, or simply that you are using different compilation
+ * settings than those used to build the library.
+ *
+ * Nothing in this file is intended to be modified or adjusted by the
+ * curl library user nor by the curl library builder.
+ *
+ * Do not deactivate any check, these are done to make sure that the
+ * library is properly built and used.
+ *
+ * You can find further help on the libcurl development mailing list:
+ * http://cool.haxx.se/mailman/listinfo/curl-library/
+ *
+ * NOTE 2
+ * ------
+ *
+ * Some of the following compile time checks are based on the fact
+ * that the dimension of a constant array can not be a negative one.
+ * In this way if the compile time verification fails, the compilation
+ * will fail issuing an error. The error description wording is compiler
+ * dependent but it will be quite similar to one of the following:
+ *
+ *   "negative subscript or subscript is too large"
+ *   "array must have at least one element"
+ *   "-1 is an illegal array size"
+ *   "size of array is negative"
+ *
+ * If you are building an application which tries to use an already
+ * built libcurl library and you are getting this kind of errors on
+ * this file, it is a clear indication that there is a mismatch between
+ * how the library was built and how you are trying to use it for your
+ * application. Your already compiled or binary library provider is the
+ * only one who can give you the details you need to properly use it.
+ */
+
+/*
+ * Verify that some macros are actually defined.
+ */
+
+#ifndef CURL_SIZEOF_LONG
+#  error "CURL_SIZEOF_LONG definition is missing!"
+   Error Compilation_aborted_CURL_SIZEOF_LONG_is_missing
+#endif
+
+#ifndef CURL_TYPEOF_CURL_SOCKLEN_T
+#  error "CURL_TYPEOF_CURL_SOCKLEN_T definition is missing!"
+   Error Compilation_aborted_CURL_TYPEOF_CURL_SOCKLEN_T_is_missing
+#endif
+
+#ifndef CURL_SIZEOF_CURL_SOCKLEN_T
+#  error "CURL_SIZEOF_CURL_SOCKLEN_T definition is missing!"
+   Error Compilation_aborted_CURL_SIZEOF_CURL_SOCKLEN_T_is_missing
+#endif
+
+#ifndef CURL_TYPEOF_CURL_OFF_T
+#  error "CURL_TYPEOF_CURL_OFF_T definition is missing!"
+   Error Compilation_aborted_CURL_TYPEOF_CURL_OFF_T_is_missing
+#endif
+
+#ifndef CURL_FORMAT_CURL_OFF_T
+#  error "CURL_FORMAT_CURL_OFF_T definition is missing!"
+   Error Compilation_aborted_CURL_FORMAT_CURL_OFF_T_is_missing
+#endif
+
+#ifndef CURL_FORMAT_CURL_OFF_TU
+#  error "CURL_FORMAT_CURL_OFF_TU definition is missing!"
+   Error Compilation_aborted_CURL_FORMAT_CURL_OFF_TU_is_missing
+#endif
+
+#ifndef CURL_FORMAT_OFF_T
+#  error "CURL_FORMAT_OFF_T definition is missing!"
+   Error Compilation_aborted_CURL_FORMAT_OFF_T_is_missing
+#endif
+
+#ifndef CURL_SIZEOF_CURL_OFF_T
+#  error "CURL_SIZEOF_CURL_OFF_T definition is missing!"
+   Error Compilation_aborted_CURL_SIZEOF_CURL_OFF_T_is_missing
+#endif
+
+#ifndef CURL_SUFFIX_CURL_OFF_T
+#  error "CURL_SUFFIX_CURL_OFF_T definition is missing!"
+   Error Compilation_aborted_CURL_SUFFIX_CURL_OFF_T_is_missing
+#endif
+
+#ifndef CURL_SUFFIX_CURL_OFF_TU
+#  error "CURL_SUFFIX_CURL_OFF_TU definition is missing!"
+   Error Compilation_aborted_CURL_SUFFIX_CURL_OFF_TU_is_missing
+#endif
+
+/*
+ * Macros private to this header file.
+ */
+
+#define CurlchkszEQ(t, s) sizeof(t) == s ? 1 : -1
+
+#define CurlchkszGE(t1, t2) sizeof(t1) >= sizeof(t2) ? 1 : -1
+
+/*
+ * Verify that the size previously defined and expected for long
+ * is the same as the one reported by sizeof() at compile time.
+ */
+
+typedef char
+  __curl_rule_01__
+    [CurlchkszEQ(long, CURL_SIZEOF_LONG)];
+
+/*
+ * Verify that the size previously defined and expected for
+ * curl_off_t is actually the the same as the one reported
+ * by sizeof() at compile time.
+ */
+
+typedef char
+  __curl_rule_02__
+    [CurlchkszEQ(curl_off_t, CURL_SIZEOF_CURL_OFF_T)];
+
+/*
+ * Verify at compile time that the size of curl_off_t as reported
+ * by sizeof() is greater or equal than the one reported for long
+ * for the current compilation.
+ */
+
+typedef char
+  __curl_rule_03__
+    [CurlchkszGE(curl_off_t, long)];
+
+/*
+ * Verify that the size previously defined and expected for
+ * curl_socklen_t is actually the the same as the one reported
+ * by sizeof() at compile time.
+ */
+
+typedef char
+  __curl_rule_04__
+    [CurlchkszEQ(curl_socklen_t, CURL_SIZEOF_CURL_SOCKLEN_T)];
+
+/*
+ * Verify at compile time that the size of curl_socklen_t as reported
+ * by sizeof() is greater or equal than the one reported for int for
+ * the current compilation.
+ */
+
+typedef char
+  __curl_rule_05__
+    [CurlchkszGE(curl_socklen_t, int)];
+
+/* ================================================================ */
+/*          EXTERNALLY AND INTERNALLY VISIBLE DEFINITIONS           */
+/* ================================================================ */
+
+/* 
+ * CURL_ISOCPP and CURL_OFF_T_C definitions are done here in order to allow
+ * these to be visible and exported by the external libcurl interface API,
+ * while also making them visible to the library internals, simply including
+ * setup.h, without actually needing to include curl.h internally.
+ * If some day this section would grow big enough, all this should be moved
+ * to its own header file.
+ */
+
+/*
+ * Figure out if we can use the ## preprocessor operator, which is supported
+ * by ISO/ANSI C and C++. Some compilers support it without setting __STDC__
+ * or  __cplusplus so we need to carefully check for them too.
+ */
+
+#if defined(__STDC__) || defined(_MSC_VER) || defined(__cplusplus) || \
+  defined(__HP_aCC) || defined(__BORLANDC__) || defined(__LCC__) || \
+  defined(__POCC__) || defined(__SALFORDC__) || defined(__HIGHC__) || \
+  defined(__ILEC400__)
+  /* This compiler is believed to have an ISO compatible preprocessor */
+#define CURL_ISOCPP
+#else
+  /* This compiler is believed NOT to have an ISO compatible preprocessor */
+#undef CURL_ISOCPP
+#endif
+
+/*
+ * Macros for minimum-width signed and unsigned curl_off_t integer constants.
+ */
+
+#ifdef CURL_ISOCPP
+#  define __CURL_OFF_T_C_HELPER2(Val,Suffix) Val ## Suffix
+#else
+#  define __CURL_OFF_T_C_HELPER2(Val,Suffix) Val/**/Suffix
+#endif
+#define __CURL_OFF_T_C_HELPER1(Val,Suffix) __CURL_OFF_T_C_HELPER2(Val,Suffix)
+#define CURL_OFF_T_C(Val)  __CURL_OFF_T_C_HELPER1(Val,CURL_SUFFIX_CURL_OFF_T)
+#define CURL_OFF_TU_C(Val) __CURL_OFF_T_C_HELPER1(Val,CURL_SUFFIX_CURL_OFF_TU)
+
+/*
+ * Get rid of macros private to this header file.
+ */
+
+#undef CurlchkszEQ
+#undef CurlchkszGE
+
+/*
+ * Get rid of macros not intended to exist beyond this point.
+ */
+
+#undef CURL_PULL_WS2TCPIP_H
+#undef CURL_PULL_SYS_TYPES_H
+#undef CURL_PULL_SYS_SOCKET_H
+#undef CURL_PULL_STDINT_H
+#undef CURL_PULL_INTTYPES_H
+
+#undef CURL_TYPEOF_CURL_SOCKLEN_T
+#undef CURL_TYPEOF_CURL_OFF_T
+
+#endif /* __CURL_CURLRULES_H */
diff --git a/include/breakpad/third_party/curl/curlver.h b/include/breakpad/third_party/curl/curlver.h
new file mode 100644
index 0000000..afa85c1
--- /dev/null
+++ b/include/breakpad/third_party/curl/curlver.h
@@ -0,0 +1,70 @@
+#ifndef __CURL_CURLVER_H
+#define __CURL_CURLVER_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2009, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ * $Id: curlver.h,v 1.48 2009-08-12 11:24:52 bagder Exp $
+ ***************************************************************************/
+
+/* This header file contains nothing but libcurl version info, generated by
+   a script at release-time. This was made its own header file in 7.11.2 */
+
+/* This is the global package copyright */
+#define LIBCURL_COPYRIGHT "1996 - 2009 Daniel Stenberg, <daniel@haxx.se>."
+
+/* This is the version number of the libcurl package from which this header
+   file origins: */
+#define LIBCURL_VERSION "7.19.7"
+
+/* The numeric version number is also available "in parts" by using these
+   defines: */
+#define LIBCURL_VERSION_MAJOR 7
+#define LIBCURL_VERSION_MINOR 19
+#define LIBCURL_VERSION_PATCH 7
+
+/* This is the numeric version of the libcurl version number, meant for easier
+   parsing and comparions by programs. The LIBCURL_VERSION_NUM define will
+   always follow this syntax:
+
+         0xXXYYZZ
+
+   Where XX, YY and ZZ are the main version, release and patch numbers in
+   hexadecimal (using 8 bits each). All three numbers are always represented
+   using two digits.  1.2 would appear as "0x010200" while version 9.11.7
+   appears as "0x090b07".
+
+   This 6-digit (24 bits) hexadecimal number does not show pre-release number,
+   and it is always a greater number in a more recent release. It makes
+   comparisons with greater than and less than work.
+*/
+#define LIBCURL_VERSION_NUM 0x071307
+
+/*
+ * This is the date and time when the full source package was created. The
+ * timestamp is not stored in CVS, as the timestamp is properly set in the
+ * tarballs by the maketgz script.
+ *
+ * The format of the date should follow this template:
+ *
+ * "Mon Feb 12 11:35:33 UTC 2007"
+ */
+#define LIBCURL_TIMESTAMP "Wed Nov  4 12:34:59 UTC 2009"
+
+#endif /* __CURL_CURLVER_H */
diff --git a/include/breakpad/third_party/curl/easy.h b/include/breakpad/third_party/curl/easy.h
new file mode 100644
index 0000000..40449c3
--- /dev/null
+++ b/include/breakpad/third_party/curl/easy.h
@@ -0,0 +1,103 @@
+#ifndef __CURL_EASY_H
+#define __CURL_EASY_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2008, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ * $Id: easy.h,v 1.14 2008-05-12 21:43:28 bagder Exp $
+ ***************************************************************************/
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+CURL_EXTERN CURL *curl_easy_init(void);
+CURL_EXTERN CURLcode curl_easy_setopt(CURL *curl, CURLoption option, ...);
+CURL_EXTERN CURLcode curl_easy_perform(CURL *curl);
+CURL_EXTERN void curl_easy_cleanup(CURL *curl);
+
+/*
+ * NAME curl_easy_getinfo()
+ *
+ * DESCRIPTION
+ *
+ * Request internal information from the curl session with this function.  The
+ * third argument MUST be a pointer to a long, a pointer to a char * or a
+ * pointer to a double (as the documentation describes elsewhere).  The data
+ * pointed to will be filled in accordingly and can be relied upon only if the
+ * function returns CURLE_OK.  This function is intended to get used *AFTER* a
+ * performed transfer, all results from this function are undefined until the
+ * transfer is completed.
+ */
+CURL_EXTERN CURLcode curl_easy_getinfo(CURL *curl, CURLINFO info, ...);
+
+
+/*
+ * NAME curl_easy_duphandle()
+ *
+ * DESCRIPTION
+ *
+ * Creates a new curl session handle with the same options set for the handle
+ * passed in. Duplicating a handle could only be a matter of cloning data and
+ * options, internal state info and things like persistant connections cannot
+ * be transfered. It is useful in multithreaded applications when you can run
+ * curl_easy_duphandle() for each new thread to avoid a series of identical
+ * curl_easy_setopt() invokes in every thread.
+ */
+CURL_EXTERN CURL* curl_easy_duphandle(CURL *curl);
+
+/*
+ * NAME curl_easy_reset()
+ *
+ * DESCRIPTION
+ *
+ * Re-initializes a CURL handle to the default values. This puts back the
+ * handle to the same state as it was in when it was just created.
+ *
+ * It does keep: live connections, the Session ID cache, the DNS cache and the
+ * cookies.
+ */
+CURL_EXTERN void curl_easy_reset(CURL *curl);
+
+/*
+ * NAME curl_easy_recv()
+ *
+ * DESCRIPTION
+ *
+ * Receives data from the connected socket. Use after successful
+ * curl_easy_perform() with CURLOPT_CONNECT_ONLY option.
+ */
+CURL_EXTERN CURLcode curl_easy_recv(CURL *curl, void *buffer, size_t buflen,
+                                    size_t *n);
+
+/*
+ * NAME curl_easy_send()
+ *
+ * DESCRIPTION
+ *
+ * Sends data over the connected socket. Use after successful
+ * curl_easy_perform() with CURLOPT_CONNECT_ONLY option.
+ */
+CURL_EXTERN CURLcode curl_easy_send(CURL *curl, const void *buffer,
+                                    size_t buflen, size_t *n);
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/breakpad/third_party/curl/mprintf.h b/include/breakpad/third_party/curl/mprintf.h
new file mode 100644
index 0000000..d7202de
--- /dev/null
+++ b/include/breakpad/third_party/curl/mprintf.h
@@ -0,0 +1,82 @@
+#ifndef __CURL_MPRINTF_H
+#define __CURL_MPRINTF_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ * $Id: mprintf.h,v 1.16 2008-05-20 10:21:50 patrickm Exp $
+ ***************************************************************************/
+
+#include <stdarg.h>
+#include <stdio.h> /* needed for FILE */
+
+#include "curl.h"
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+CURL_EXTERN int curl_mprintf(const char *format, ...);
+CURL_EXTERN int curl_mfprintf(FILE *fd, const char *format, ...);
+CURL_EXTERN int curl_msprintf(char *buffer, const char *format, ...);
+CURL_EXTERN int curl_msnprintf(char *buffer, size_t maxlength,
+                               const char *format, ...);
+CURL_EXTERN int curl_mvprintf(const char *format, va_list args);
+CURL_EXTERN int curl_mvfprintf(FILE *fd, const char *format, va_list args);
+CURL_EXTERN int curl_mvsprintf(char *buffer, const char *format, va_list args);
+CURL_EXTERN int curl_mvsnprintf(char *buffer, size_t maxlength,
+                                const char *format, va_list args);
+CURL_EXTERN char *curl_maprintf(const char *format, ...);
+CURL_EXTERN char *curl_mvaprintf(const char *format, va_list args);
+
+#ifdef _MPRINTF_REPLACE
+# undef printf
+# undef fprintf
+# undef sprintf
+# undef vsprintf
+# undef snprintf
+# undef vprintf
+# undef vfprintf
+# undef vsnprintf
+# undef aprintf
+# undef vaprintf
+# define printf curl_mprintf
+# define fprintf curl_mfprintf
+#ifdef CURLDEBUG
+/* When built with CURLDEBUG we define away the sprintf() functions since we
+   don't want internal code to be using them */
+# define sprintf sprintf_was_used
+# define vsprintf vsprintf_was_used
+#else
+# define sprintf curl_msprintf
+# define vsprintf curl_mvsprintf
+#endif
+# define snprintf curl_msnprintf
+# define vprintf curl_mvprintf
+# define vfprintf curl_mvfprintf
+# define vsnprintf curl_mvsnprintf
+# define aprintf curl_maprintf
+# define vaprintf curl_mvaprintf
+#endif
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif /* __CURL_MPRINTF_H */
diff --git a/include/breakpad/third_party/curl/multi.h b/include/breakpad/third_party/curl/multi.h
new file mode 100644
index 0000000..153f772
--- /dev/null
+++ b/include/breakpad/third_party/curl/multi.h
@@ -0,0 +1,346 @@
+#ifndef __CURL_MULTI_H
+#define __CURL_MULTI_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ * $Id: multi.h,v 1.45 2008-05-20 10:21:50 patrickm Exp $
+ ***************************************************************************/
+/*
+  This is an "external" header file. Don't give away any internals here!
+
+  GOALS
+
+  o Enable a "pull" interface. The application that uses libcurl decides where
+    and when to ask libcurl to get/send data.
+
+  o Enable multiple simultaneous transfers in the same thread without making it
+    complicated for the application.
+
+  o Enable the application to select() on its own file descriptors and curl's
+    file descriptors simultaneous easily.
+
+*/
+
+/*
+ * This header file should not really need to include "curl.h" since curl.h
+ * itself includes this file and we expect user applications to do #include
+ * <curl/curl.h> without the need for especially including multi.h.
+ *
+ * For some reason we added this include here at one point, and rather than to
+ * break existing (wrongly written) libcurl applications, we leave it as-is
+ * but with this warning attached.
+ */
+#include "curl.h"
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+typedef void CURLM;
+
+typedef enum {
+  CURLM_CALL_MULTI_PERFORM = -1, /* please call curl_multi_perform() or
+                                    curl_multi_socket*() soon */
+  CURLM_OK,
+  CURLM_BAD_HANDLE,      /* the passed-in handle is not a valid CURLM handle */
+  CURLM_BAD_EASY_HANDLE, /* an easy handle was not good/valid */
+  CURLM_OUT_OF_MEMORY,   /* if you ever get this, you're in deep sh*t */
+  CURLM_INTERNAL_ERROR,  /* this is a libcurl bug */
+  CURLM_BAD_SOCKET,      /* the passed in socket argument did not match */
+  CURLM_UNKNOWN_OPTION,  /* curl_multi_setopt() with unsupported option */
+  CURLM_LAST
+} CURLMcode;
+
+/* just to make code nicer when using curl_multi_socket() you can now check
+   for CURLM_CALL_MULTI_SOCKET too in the same style it works for
+   curl_multi_perform() and CURLM_CALL_MULTI_PERFORM */
+#define CURLM_CALL_MULTI_SOCKET CURLM_CALL_MULTI_PERFORM
+
+typedef enum {
+  CURLMSG_NONE, /* first, not used */
+  CURLMSG_DONE, /* This easy handle has completed. 'result' contains
+                   the CURLcode of the transfer */
+  CURLMSG_LAST /* last, not used */
+} CURLMSG;
+
+struct CURLMsg {
+  CURLMSG msg;       /* what this message means */
+  CURL *easy_handle; /* the handle it concerns */
+  union {
+    void *whatever;    /* message-specific data */
+    CURLcode result;   /* return code for transfer */
+  } data;
+};
+typedef struct CURLMsg CURLMsg;
+
+/*
+ * Name:    curl_multi_init()
+ *
+ * Desc:    inititalize multi-style curl usage
+ *
+ * Returns: a new CURLM handle to use in all 'curl_multi' functions.
+ */
+CURL_EXTERN CURLM *curl_multi_init(void);
+
+/*
+ * Name:    curl_multi_add_handle()
+ *
+ * Desc:    add a standard curl handle to the multi stack
+ *
+ * Returns: CURLMcode type, general multi error code.
+ */
+CURL_EXTERN CURLMcode curl_multi_add_handle(CURLM *multi_handle,
+                                            CURL *curl_handle);
+
+ /*
+  * Name:    curl_multi_remove_handle()
+  *
+  * Desc:    removes a curl handle from the multi stack again
+  *
+  * Returns: CURLMcode type, general multi error code.
+  */
+CURL_EXTERN CURLMcode curl_multi_remove_handle(CURLM *multi_handle,
+                                               CURL *curl_handle);
+
+ /*
+  * Name:    curl_multi_fdset()
+  *
+  * Desc:    Ask curl for its fd_set sets. The app can use these to select() or
+  *          poll() on. We want curl_multi_perform() called as soon as one of
+  *          them are ready.
+  *
+  * Returns: CURLMcode type, general multi error code.
+  */
+CURL_EXTERN CURLMcode curl_multi_fdset(CURLM *multi_handle,
+                                       fd_set *read_fd_set,
+                                       fd_set *write_fd_set,
+                                       fd_set *exc_fd_set,
+                                       int *max_fd);
+
+ /*
+  * Name:    curl_multi_perform()
+  *
+  * Desc:    When the app thinks there's data available for curl it calls this
+  *          function to read/write whatever there is right now. This returns
+  *          as soon as the reads and writes are done. This function does not
+  *          require that there actually is data available for reading or that
+  *          data can be written, it can be called just in case. It returns
+  *          the number of handles that still transfer data in the second
+  *          argument's integer-pointer.
+  *
+  * Returns: CURLMcode type, general multi error code. *NOTE* that this only
+  *          returns errors etc regarding the whole multi stack. There might
+  *          still have occurred problems on invidual transfers even when this
+  *          returns OK.
+  */
+CURL_EXTERN CURLMcode curl_multi_perform(CURLM *multi_handle,
+                                         int *running_handles);
+
+ /*
+  * Name:    curl_multi_cleanup()
+  *
+  * Desc:    Cleans up and removes a whole multi stack. It does not free or
+  *          touch any individual easy handles in any way. We need to define
+  *          in what state those handles will be if this function is called
+  *          in the middle of a transfer.
+  *
+  * Returns: CURLMcode type, general multi error code.
+  */
+CURL_EXTERN CURLMcode curl_multi_cleanup(CURLM *multi_handle);
+
+/*
+ * Name:    curl_multi_info_read()
+ *
+ * Desc:    Ask the multi handle if there's any messages/informationals from
+ *          the individual transfers. Messages include informationals such as
+ *          error code from the transfer or just the fact that a transfer is
+ *          completed. More details on these should be written down as well.
+ *
+ *          Repeated calls to this function will return a new struct each
+ *          time, until a special "end of msgs" struct is returned as a signal
+ *          that there is no more to get at this point.
+ *
+ *          The data the returned pointer points to will not survive calling
+ *          curl_multi_cleanup().
+ *
+ *          The 'CURLMsg' struct is meant to be very simple and only contain
+ *          very basic informations. If more involved information is wanted,
+ *          we will provide the particular "transfer handle" in that struct
+ *          and that should/could/would be used in subsequent
+ *          curl_easy_getinfo() calls (or similar). The point being that we
+ *          must never expose complex structs to applications, as then we'll
+ *          undoubtably get backwards compatibility problems in the future.
+ *
+ * Returns: A pointer to a filled-in struct, or NULL if it failed or ran out
+ *          of structs. It also writes the number of messages left in the
+ *          queue (after this read) in the integer the second argument points
+ *          to.
+ */
+CURL_EXTERN CURLMsg *curl_multi_info_read(CURLM *multi_handle,
+                                          int *msgs_in_queue);
+
+/*
+ * Name:    curl_multi_strerror()
+ *
+ * Desc:    The curl_multi_strerror function may be used to turn a CURLMcode
+ *          value into the equivalent human readable error string.  This is
+ *          useful for printing meaningful error messages.
+ *
+ * Returns: A pointer to a zero-terminated error message.
+ */
+CURL_EXTERN const char *curl_multi_strerror(CURLMcode);
+
+/*
+ * Name:    curl_multi_socket() and
+ *          curl_multi_socket_all()
+ *
+ * Desc:    An alternative version of curl_multi_perform() that allows the
+ *          application to pass in one of the file descriptors that have been
+ *          detected to have "action" on them and let libcurl perform.
+ *          See man page for details.
+ */
+#define CURL_POLL_NONE   0
+#define CURL_POLL_IN     1
+#define CURL_POLL_OUT    2
+#define CURL_POLL_INOUT  3
+#define CURL_POLL_REMOVE 4
+
+#define CURL_SOCKET_TIMEOUT CURL_SOCKET_BAD
+
+#define CURL_CSELECT_IN   0x01
+#define CURL_CSELECT_OUT  0x02
+#define CURL_CSELECT_ERR  0x04
+
+typedef int (*curl_socket_callback)(CURL *easy,      /* easy handle */
+                                    curl_socket_t s, /* socket */
+                                    int what,        /* see above */
+                                    void *userp,     /* private callback
+                                                        pointer */
+                                    void *socketp);  /* private socket
+                                                        pointer */
+/*
+ * Name:    curl_multi_timer_callback
+ *
+ * Desc:    Called by libcurl whenever the library detects a change in the
+ *          maximum number of milliseconds the app is allowed to wait before
+ *          curl_multi_socket() or curl_multi_perform() must be called
+ *          (to allow libcurl's timed events to take place).
+ *
+ * Returns: The callback should return zero.
+ */
+typedef int (*curl_multi_timer_callback)(CURLM *multi,    /* multi handle */
+                                         long timeout_ms, /* see above */
+                                         void *userp);    /* private callback
+                                                             pointer */
+
+CURL_EXTERN CURLMcode curl_multi_socket(CURLM *multi_handle, curl_socket_t s,
+                                        int *running_handles);
+
+CURL_EXTERN CURLMcode curl_multi_socket_action(CURLM *multi_handle,
+                                               curl_socket_t s,
+                                               int ev_bitmask,
+                                               int *running_handles);
+
+CURL_EXTERN CURLMcode curl_multi_socket_all(CURLM *multi_handle,
+                                            int *running_handles);
+
+#ifndef CURL_ALLOW_OLD_MULTI_SOCKET
+/* This macro below was added in 7.16.3 to push users who recompile to use
+   the new curl_multi_socket_action() instead of the old curl_multi_socket()
+*/
+#define curl_multi_socket(x,y,z) curl_multi_socket_action(x,y,0,z)
+#endif
+
+/*
+ * Name:    curl_multi_timeout()
+ *
+ * Desc:    Returns the maximum number of milliseconds the app is allowed to
+ *          wait before curl_multi_socket() or curl_multi_perform() must be
+ *          called (to allow libcurl's timed events to take place).
+ *
+ * Returns: CURLM error code.
+ */
+CURL_EXTERN CURLMcode curl_multi_timeout(CURLM *multi_handle,
+                                         long *milliseconds);
+
+#undef CINIT /* re-using the same name as in curl.h */
+
+#ifdef CURL_ISOCPP
+#define CINIT(name,type,num) CURLMOPT_ ## name = CURLOPTTYPE_ ## type + num
+#else
+/* The macro "##" is ISO C, we assume pre-ISO C doesn't support it. */
+#define LONG          CURLOPTTYPE_LONG
+#define OBJECTPOINT   CURLOPTTYPE_OBJECTPOINT
+#define FUNCTIONPOINT CURLOPTTYPE_FUNCTIONPOINT
+#define OFF_T         CURLOPTTYPE_OFF_T
+#define CINIT(name,type,number) CURLMOPT_/**/name = type + number
+#endif
+
+typedef enum {
+  /* This is the socket callback function pointer */
+  CINIT(SOCKETFUNCTION, FUNCTIONPOINT, 1),
+
+  /* This is the argument passed to the socket callback */
+  CINIT(SOCKETDATA, OBJECTPOINT, 2),
+
+    /* set to 1 to enable pipelining for this multi handle */
+  CINIT(PIPELINING, LONG, 3),
+
+   /* This is the timer callback function pointer */
+  CINIT(TIMERFUNCTION, FUNCTIONPOINT, 4),
+
+  /* This is the argument passed to the timer callback */
+  CINIT(TIMERDATA, OBJECTPOINT, 5),
+
+  /* maximum number of entries in the connection cache */
+  CINIT(MAXCONNECTS, LONG, 6),
+
+  CURLMOPT_LASTENTRY /* the last unused */
+} CURLMoption;
+
+
+/*
+ * Name:    curl_multi_setopt()
+ *
+ * Desc:    Sets options for the multi handle.
+ *
+ * Returns: CURLM error code.
+ */
+CURL_EXTERN CURLMcode curl_multi_setopt(CURLM *multi_handle,
+                                        CURLMoption option, ...);
+
+
+/*
+ * Name:    curl_multi_assign()
+ *
+ * Desc:    This function sets an association in the multi handle between the
+ *          given socket and a private pointer of the application. This is
+ *          (only) useful for curl_multi_socket uses.
+ *
+ * Returns: CURLM error code.
+ */
+CURL_EXTERN CURLMcode curl_multi_assign(CURLM *multi_handle,
+                                        curl_socket_t sockfd, void *sockp);
+
+#ifdef __cplusplus
+} /* end of extern "C" */
+#endif
+
+#endif
diff --git a/include/breakpad/third_party/curl/stdcheaders.h b/include/breakpad/third_party/curl/stdcheaders.h
new file mode 100644
index 0000000..f739d7f
--- /dev/null
+++ b/include/breakpad/third_party/curl/stdcheaders.h
@@ -0,0 +1,34 @@
+#ifndef __STDC_HEADERS_H
+#define __STDC_HEADERS_H
+/***************************************************************************
+ *                                  _   _ ____  _     
+ *  Project                     ___| | | |  _ \| |    
+ *                             / __| | | | |_) | |    
+ *                            | (__| |_| |  _ <| |___ 
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2009, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ * 
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ * $Id: stdcheaders.h,v 1.9 2009-05-18 12:25:45 yangtse Exp $
+ ***************************************************************************/
+
+#include <sys/types.h>
+
+size_t fread (void *, size_t, size_t, FILE *);
+size_t fwrite (const void *, size_t, size_t, FILE *);
+
+int strcasecmp(const char *, const char *);
+int strncasecmp(const char *, const char *, size_t);
+
+#endif
diff --git a/include/breakpad/third_party/curl/typecheck-gcc.h b/include/breakpad/third_party/curl/typecheck-gcc.h
new file mode 100644
index 0000000..9788305
--- /dev/null
+++ b/include/breakpad/third_party/curl/typecheck-gcc.h
@@ -0,0 +1,551 @@
+#ifndef __CURL_TYPECHECK_GCC_H
+#define __CURL_TYPECHECK_GCC_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2009, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ * $Id: typecheck-gcc.h,v 1.9 2009-01-25 23:26:31 bagder Exp $
+ ***************************************************************************/
+
+/* wraps curl_easy_setopt() with typechecking */
+
+/* To add a new kind of warning, add an
+ *   if(_curl_is_sometype_option(_curl_opt) && ! _curl_is_sometype(value))
+ *     _curl_easy_setopt_err_sometype();
+ * block and define _curl_is_sometype_option, _curl_is_sometype and
+ * _curl_easy_setopt_err_sometype below
+ *
+ * To add an option that uses the same type as an existing option, you'll just
+ * need to extend the appropriate _curl_*_option macro
+ */
+#define curl_easy_setopt(handle, option, value)                               \
+__extension__ ({                                                              \
+  __typeof__ (option) _curl_opt = option;                                     \
+  if (__builtin_constant_p(_curl_opt)) {                                      \
+    if (_curl_is_long_option(_curl_opt) && !_curl_is_long(value))             \
+      _curl_easy_setopt_err_long();                                           \
+    if (_curl_is_off_t_option(_curl_opt) && !_curl_is_off_t(value))           \
+      _curl_easy_setopt_err_curl_off_t();                                     \
+    if (_curl_is_string_option(_curl_opt) && !_curl_is_string(value))         \
+      _curl_easy_setopt_err_string();                                         \
+    if (_curl_is_write_cb_option(_curl_opt) && !_curl_is_write_cb(value))     \
+      _curl_easy_setopt_err_write_callback();                                 \
+    if ((_curl_opt) == CURLOPT_READFUNCTION && !_curl_is_read_cb(value))      \
+      _curl_easy_setopt_err_read_cb();                                        \
+    if ((_curl_opt) == CURLOPT_IOCTLFUNCTION && !_curl_is_ioctl_cb(value))    \
+      _curl_easy_setopt_err_ioctl_cb();                                       \
+    if ((_curl_opt) == CURLOPT_SOCKOPTFUNCTION && !_curl_is_sockopt_cb(value))\
+      _curl_easy_setopt_err_sockopt_cb();                                     \
+    if ((_curl_opt) == CURLOPT_OPENSOCKETFUNCTION &&                          \
+            !_curl_is_opensocket_cb(value))                                   \
+      _curl_easy_setopt_err_opensocket_cb();                                  \
+    if ((_curl_opt) == CURLOPT_PROGRESSFUNCTION &&                            \
+            !_curl_is_progress_cb(value))                                     \
+      _curl_easy_setopt_err_progress_cb();                                    \
+    if ((_curl_opt) == CURLOPT_DEBUGFUNCTION && !_curl_is_debug_cb(value))    \
+      _curl_easy_setopt_err_debug_cb();                                       \
+    if ((_curl_opt) == CURLOPT_SSL_CTX_FUNCTION &&                            \
+            !_curl_is_ssl_ctx_cb(value))                                      \
+      _curl_easy_setopt_err_ssl_ctx_cb();                                     \
+    if (_curl_is_conv_cb_option(_curl_opt) && !_curl_is_conv_cb(value))       \
+      _curl_easy_setopt_err_conv_cb();                                        \
+    if ((_curl_opt) == CURLOPT_SEEKFUNCTION && !_curl_is_seek_cb(value))      \
+      _curl_easy_setopt_err_seek_cb();                                        \
+    if (_curl_is_cb_data_option(_curl_opt) && !_curl_is_cb_data(value))       \
+      _curl_easy_setopt_err_cb_data();                                        \
+    if ((_curl_opt) == CURLOPT_ERRORBUFFER && !_curl_is_error_buffer(value))  \
+      _curl_easy_setopt_err_error_buffer();                                   \
+    if ((_curl_opt) == CURLOPT_STDERR && !_curl_is_FILE(value))               \
+      _curl_easy_setopt_err_FILE();                                           \
+    if (_curl_is_postfields_option(_curl_opt) && !_curl_is_postfields(value)) \
+      _curl_easy_setopt_err_postfields();                                     \
+    if ((_curl_opt) == CURLOPT_HTTPPOST &&                                    \
+            !_curl_is_arr((value), struct curl_httppost))                     \
+      _curl_easy_setopt_err_curl_httpost();                                   \
+    if (_curl_is_slist_option(_curl_opt) &&                                   \
+            !_curl_is_arr((value), struct curl_slist))                        \
+      _curl_easy_setopt_err_curl_slist();                                     \
+    if ((_curl_opt) == CURLOPT_SHARE && !_curl_is_ptr((value), CURLSH))       \
+      _curl_easy_setopt_err_CURLSH();                                         \
+  }                                                                           \
+  curl_easy_setopt(handle, _curl_opt, value);                                 \
+})
+
+/* wraps curl_easy_getinfo() with typechecking */
+/* FIXME: don't allow const pointers */
+#define curl_easy_getinfo(handle, info, arg)                                  \
+__extension__ ({                                                              \
+  __typeof__ (info) _curl_info = info;                                        \
+  if (__builtin_constant_p(_curl_info)) {                                     \
+    if (_curl_is_string_info(_curl_info) && !_curl_is_arr((arg), char *))     \
+      _curl_easy_getinfo_err_string();                                        \
+    if (_curl_is_long_info(_curl_info) && !_curl_is_arr((arg), long))         \
+      _curl_easy_getinfo_err_long();                                          \
+    if (_curl_is_double_info(_curl_info) && !_curl_is_arr((arg), double))     \
+      _curl_easy_getinfo_err_double();                                        \
+    if (_curl_is_slist_info(_curl_info) &&                                    \
+           !_curl_is_arr((arg), struct curl_slist *))                         \
+      _curl_easy_getinfo_err_curl_slist();                                    \
+  }                                                                           \
+  curl_easy_getinfo(handle, _curl_info, arg);                                 \
+})
+
+/* TODO: typechecking for curl_share_setopt() and curl_multi_setopt(),
+ * for now just make sure that the functions are called with three
+ * arguments
+ */
+#define curl_share_setopt(share,opt,param) curl_share_setopt(share,opt,param)
+#define curl_multi_setopt(handle,opt,param) curl_multi_setopt(handle,opt,param)
+
+
+/* the actual warnings, triggered by calling the _curl_easy_setopt_err*
+ * functions */
+
+/* To define a new warning, use _CURL_WARNING(identifier, "message") */
+#define _CURL_WARNING(id, message)                                            \
+  static void __attribute__((warning(message))) __attribute__((unused))       \
+  __attribute__((noinline)) id(void) { __asm__(""); }
+
+_CURL_WARNING(_curl_easy_setopt_err_long,
+  "curl_easy_setopt expects a long argument for this option")
+_CURL_WARNING(_curl_easy_setopt_err_curl_off_t,
+  "curl_easy_setopt expects a curl_off_t argument for this option")
+_CURL_WARNING(_curl_easy_setopt_err_string,
+  "curl_easy_setopt expects a string (char* or char[]) argument for this option"
+  )
+_CURL_WARNING(_curl_easy_setopt_err_write_callback,
+  "curl_easy_setopt expects a curl_write_callback argument for this option")
+_CURL_WARNING(_curl_easy_setopt_err_read_cb,
+  "curl_easy_setopt expects a curl_read_callback argument for this option")
+_CURL_WARNING(_curl_easy_setopt_err_ioctl_cb,
+  "curl_easy_setopt expects a curl_ioctl_callback argument for this option")
+_CURL_WARNING(_curl_easy_setopt_err_sockopt_cb,
+  "curl_easy_setopt expects a curl_sockopt_callback argument for this option")
+_CURL_WARNING(_curl_easy_setopt_err_opensocket_cb,
+  "curl_easy_setopt expects a curl_opensocket_callback argument for this option"
+  )
+_CURL_WARNING(_curl_easy_setopt_err_progress_cb,
+  "curl_easy_setopt expects a curl_progress_callback argument for this option")
+_CURL_WARNING(_curl_easy_setopt_err_debug_cb,
+  "curl_easy_setopt expects a curl_debug_callback argument for this option")
+_CURL_WARNING(_curl_easy_setopt_err_ssl_ctx_cb,
+  "curl_easy_setopt expects a curl_ssl_ctx_callback argument for this option")
+_CURL_WARNING(_curl_easy_setopt_err_conv_cb,
+  "curl_easy_setopt expects a curl_conv_callback argument for this option")
+_CURL_WARNING(_curl_easy_setopt_err_seek_cb,
+  "curl_easy_setopt expects a curl_seek_callback argument for this option")
+_CURL_WARNING(_curl_easy_setopt_err_cb_data,
+  "curl_easy_setopt expects a private data pointer as argument for this option")
+_CURL_WARNING(_curl_easy_setopt_err_error_buffer,
+  "curl_easy_setopt expects a char buffer of CURL_ERROR_SIZE as argument for this option")
+_CURL_WARNING(_curl_easy_setopt_err_FILE,
+  "curl_easy_setopt expects a FILE* argument for this option")
+_CURL_WARNING(_curl_easy_setopt_err_postfields,
+  "curl_easy_setopt expects a void* or char* argument for this option")
+_CURL_WARNING(_curl_easy_setopt_err_curl_httpost,
+  "curl_easy_setopt expects a struct curl_httppost* argument for this option")
+_CURL_WARNING(_curl_easy_setopt_err_curl_slist,
+  "curl_easy_setopt expects a struct curl_slist* argument for this option")
+_CURL_WARNING(_curl_easy_setopt_err_CURLSH,
+  "curl_easy_setopt expects a CURLSH* argument for this option")
+
+_CURL_WARNING(_curl_easy_getinfo_err_string,
+  "curl_easy_getinfo expects a pointer to char * for this info")
+_CURL_WARNING(_curl_easy_getinfo_err_long,
+  "curl_easy_getinfo expects a pointer to long for this info")
+_CURL_WARNING(_curl_easy_getinfo_err_double,
+  "curl_easy_getinfo expects a pointer to double for this info")
+_CURL_WARNING(_curl_easy_getinfo_err_curl_slist,
+  "curl_easy_getinfo expects a pointer to struct curl_slist * for this info")
+
+/* groups of curl_easy_setops options that take the same type of argument */
+
+/* To add a new option to one of the groups, just add
+ *   (option) == CURLOPT_SOMETHING
+ * to the or-expression. If the option takes a long or curl_off_t, you don't
+ * have to do anything
+ */
+
+/* evaluates to true if option takes a long argument */
+#define _curl_is_long_option(option)                                          \
+  (0 < (option) && (option) < CURLOPTTYPE_OBJECTPOINT)
+
+#define _curl_is_off_t_option(option)                                         \
+  ((option) > CURLOPTTYPE_OFF_T)
+
+/* evaluates to true if option takes a char* argument */
+#define _curl_is_string_option(option)                                        \
+  ((option) == CURLOPT_URL ||                                                 \
+   (option) == CURLOPT_PROXY ||                                               \
+   (option) == CURLOPT_INTERFACE ||                                           \
+   (option) == CURLOPT_NETRC_FILE ||                                          \
+   (option) == CURLOPT_USERPWD ||                                             \
+   (option) == CURLOPT_USERNAME ||                                            \
+   (option) == CURLOPT_PASSWORD ||                                            \
+   (option) == CURLOPT_PROXYUSERPWD ||                                        \
+   (option) == CURLOPT_PROXYUSERNAME ||                                       \
+   (option) == CURLOPT_PROXYPASSWORD ||                                       \
+   (option) == CURLOPT_NOPROXY ||                                             \
+   (option) == CURLOPT_ENCODING ||                                            \
+   (option) == CURLOPT_REFERER ||                                             \
+   (option) == CURLOPT_USERAGENT ||                                           \
+   (option) == CURLOPT_COOKIE ||                                              \
+   (option) == CURLOPT_COOKIEFILE ||                                          \
+   (option) == CURLOPT_COOKIEJAR ||                                           \
+   (option) == CURLOPT_COOKIELIST ||                                          \
+   (option) == CURLOPT_FTPPORT ||                                             \
+   (option) == CURLOPT_FTP_ALTERNATIVE_TO_USER ||                             \
+   (option) == CURLOPT_FTP_ACCOUNT ||                                         \
+   (option) == CURLOPT_RANGE ||                                               \
+   (option) == CURLOPT_CUSTOMREQUEST ||                                       \
+   (option) == CURLOPT_SSLCERT ||                                             \
+   (option) == CURLOPT_SSLCERTTYPE ||                                         \
+   (option) == CURLOPT_SSLKEY ||                                              \
+   (option) == CURLOPT_SSLKEYTYPE ||                                          \
+   (option) == CURLOPT_KEYPASSWD ||                                           \
+   (option) == CURLOPT_SSLENGINE ||                                           \
+   (option) == CURLOPT_CAINFO ||                                              \
+   (option) == CURLOPT_CAPATH ||                                              \
+   (option) == CURLOPT_RANDOM_FILE ||                                         \
+   (option) == CURLOPT_EGDSOCKET ||                                           \
+   (option) == CURLOPT_SSL_CIPHER_LIST ||                                     \
+   (option) == CURLOPT_KRBLEVEL ||                                            \
+   (option) == CURLOPT_SSH_HOST_PUBLIC_KEY_MD5 ||                             \
+   (option) == CURLOPT_SSH_PUBLIC_KEYFILE ||                                  \
+   (option) == CURLOPT_SSH_PRIVATE_KEYFILE ||                                 \
+   (option) == CURLOPT_CRLFILE ||                                             \
+   (option) == CURLOPT_ISSUERCERT ||                                          \
+   0)
+
+/* evaluates to true if option takes a curl_write_callback argument */
+#define _curl_is_write_cb_option(option)                                      \
+  ((option) == CURLOPT_HEADERFUNCTION ||                                      \
+   (option) == CURLOPT_WRITEFUNCTION)
+
+/* evaluates to true if option takes a curl_conv_callback argument */
+#define _curl_is_conv_cb_option(option)                                       \
+  ((option) == CURLOPT_CONV_TO_NETWORK_FUNCTION ||                            \
+   (option) == CURLOPT_CONV_FROM_NETWORK_FUNCTION ||                          \
+   (option) == CURLOPT_CONV_FROM_UTF8_FUNCTION)
+
+/* evaluates to true if option takes a data argument to pass to a callback */
+#define _curl_is_cb_data_option(option)                                       \
+  ((option) == CURLOPT_WRITEDATA ||                                           \
+   (option) == CURLOPT_READDATA ||                                            \
+   (option) == CURLOPT_IOCTLDATA ||                                           \
+   (option) == CURLOPT_SOCKOPTDATA ||                                         \
+   (option) == CURLOPT_OPENSOCKETDATA ||                                      \
+   (option) == CURLOPT_PROGRESSDATA ||                                        \
+   (option) == CURLOPT_WRITEHEADER ||                                         \
+   (option) == CURLOPT_DEBUGDATA ||                                           \
+   (option) == CURLOPT_SSL_CTX_DATA ||                                        \
+   (option) == CURLOPT_SEEKDATA ||                                            \
+   (option) == CURLOPT_PRIVATE ||                                             \
+   0)
+
+/* evaluates to true if option takes a POST data argument (void* or char*) */
+#define _curl_is_postfields_option(option)                                    \
+  ((option) == CURLOPT_POSTFIELDS ||                                          \
+   (option) == CURLOPT_COPYPOSTFIELDS ||                                      \
+   0)
+
+/* evaluates to true if option takes a struct curl_slist * argument */
+#define _curl_is_slist_option(option)                                         \
+  ((option) == CURLOPT_HTTPHEADER ||                                          \
+   (option) == CURLOPT_HTTP200ALIASES ||                                      \
+   (option) == CURLOPT_QUOTE ||                                               \
+   (option) == CURLOPT_POSTQUOTE ||                                           \
+   (option) == CURLOPT_PREQUOTE ||                                            \
+   (option) == CURLOPT_TELNETOPTIONS ||                                       \
+   0)
+
+/* groups of curl_easy_getinfo infos that take the same type of argument */
+
+/* evaluates to true if info expects a pointer to char * argument */
+#define _curl_is_string_info(info)                                            \
+  (CURLINFO_STRING < (info) && (info) < CURLINFO_LONG)
+
+/* evaluates to true if info expects a pointer to long argument */
+#define _curl_is_long_info(info)                                              \
+  (CURLINFO_LONG < (info) && (info) < CURLINFO_DOUBLE)
+
+/* evaluates to true if info expects a pointer to double argument */
+#define _curl_is_double_info(info)                                            \
+  (CURLINFO_DOUBLE < (info) && (info) < CURLINFO_SLIST)
+
+/* true if info expects a pointer to struct curl_slist * argument */
+#define _curl_is_slist_info(info)                                             \
+  (CURLINFO_SLIST < (info))
+
+
+/* typecheck helpers -- check whether given expression has requested type*/
+
+/* For pointers, you can use the _curl_is_ptr/_curl_is_arr macros,
+ * otherwise define a new macro. Search for __builtin_types_compatible_p
+ * in the GCC manual.
+ * NOTE: these macros MUST NOT EVALUATE their arguments! The argument is
+ * the actual expression passed to the curl_easy_setopt macro. This
+ * means that you can only apply the sizeof and __typeof__ operators, no
+ * == or whatsoever.
+ */
+
+/* XXX: should evaluate to true iff expr is a pointer */
+#define _curl_is_any_ptr(expr)                                                \
+  (sizeof(expr) == sizeof(void*))
+
+/* evaluates to true if expr is NULL */
+/* XXX: must not evaluate expr, so this check is not accurate */
+#define _curl_is_NULL(expr)                                                   \
+  (__builtin_types_compatible_p(__typeof__(expr), __typeof__(NULL)))
+
+/* evaluates to true if expr is type*, const type* or NULL */
+#define _curl_is_ptr(expr, type)                                              \
+  (_curl_is_NULL(expr) ||                                                     \
+   __builtin_types_compatible_p(__typeof__(expr), type *) ||                  \
+   __builtin_types_compatible_p(__typeof__(expr), const type *))
+
+/* evaluates to true if expr is one of type[], type*, NULL or const type* */
+#define _curl_is_arr(expr, type)                                              \
+  (_curl_is_ptr((expr), type) ||                                              \
+   __builtin_types_compatible_p(__typeof__(expr), type []))
+
+/* evaluates to true if expr is a string */
+#define _curl_is_string(expr)                                                 \
+  (_curl_is_arr((expr), char) ||                                              \
+   _curl_is_arr((expr), signed char) ||                                       \
+   _curl_is_arr((expr), unsigned char))
+
+/* evaluates to true if expr is a long (no matter the signedness)
+ * XXX: for now, int is also accepted (and therefore short and char, which
+ * are promoted to int when passed to a variadic function) */
+#define _curl_is_long(expr)                                                   \
+  (__builtin_types_compatible_p(__typeof__(expr), long) ||                    \
+   __builtin_types_compatible_p(__typeof__(expr), signed long) ||             \
+   __builtin_types_compatible_p(__typeof__(expr), unsigned long) ||           \
+   __builtin_types_compatible_p(__typeof__(expr), int) ||                     \
+   __builtin_types_compatible_p(__typeof__(expr), signed int) ||              \
+   __builtin_types_compatible_p(__typeof__(expr), unsigned int) ||            \
+   __builtin_types_compatible_p(__typeof__(expr), short) ||                   \
+   __builtin_types_compatible_p(__typeof__(expr), signed short) ||            \
+   __builtin_types_compatible_p(__typeof__(expr), unsigned short) ||          \
+   __builtin_types_compatible_p(__typeof__(expr), char) ||                    \
+   __builtin_types_compatible_p(__typeof__(expr), signed char) ||             \
+   __builtin_types_compatible_p(__typeof__(expr), unsigned char))
+
+/* evaluates to true if expr is of type curl_off_t */
+#define _curl_is_off_t(expr)                                                  \
+  (__builtin_types_compatible_p(__typeof__(expr), curl_off_t))
+
+/* evaluates to true if expr is abuffer suitable for CURLOPT_ERRORBUFFER */
+/* XXX: also check size of an char[] array? */
+#define _curl_is_error_buffer(expr)                                           \
+  (__builtin_types_compatible_p(__typeof__(expr), char *) ||                  \
+   __builtin_types_compatible_p(__typeof__(expr), char[]))
+
+/* evaluates to true if expr is of type (const) void* or (const) FILE* */
+#if 0
+#define _curl_is_cb_data(expr)                                                \
+  (_curl_is_ptr((expr), void) ||                                              \
+   _curl_is_ptr((expr), FILE))
+#else /* be less strict */
+#define _curl_is_cb_data(expr)                                                \
+  _curl_is_any_ptr(expr)
+#endif
+
+/* evaluates to true if expr is of type FILE* */
+#define _curl_is_FILE(expr)                                                   \
+  (__builtin_types_compatible_p(__typeof__(expr), FILE *))
+
+/* evaluates to true if expr can be passed as POST data (void* or char*) */
+#define _curl_is_postfields(expr)                                             \
+  (_curl_is_ptr((expr), void) ||                                              \
+   _curl_is_arr((expr), char))
+
+/* FIXME: the whole callback checking is messy...
+ * The idea is to tolerate char vs. void and const vs. not const
+ * pointers in arguments at least
+ */
+/* helper: __builtin_types_compatible_p distinguishes between functions and
+ * function pointers, hide it */
+#define _curl_callback_compatible(func, type)                                 \
+  (__builtin_types_compatible_p(__typeof__(func), type) ||                    \
+   __builtin_types_compatible_p(__typeof__(func), type*))
+
+/* evaluates to true if expr is of type curl_read_callback or "similar" */
+#define _curl_is_read_cb(expr)                                          \
+  (_curl_is_NULL(expr) ||                                                     \
+   __builtin_types_compatible_p(__typeof__(expr), __typeof__(fread)) ||       \
+   __builtin_types_compatible_p(__typeof__(expr), curl_read_callback) ||      \
+   _curl_callback_compatible((expr), _curl_read_callback1) ||                 \
+   _curl_callback_compatible((expr), _curl_read_callback2) ||                 \
+   _curl_callback_compatible((expr), _curl_read_callback3) ||                 \
+   _curl_callback_compatible((expr), _curl_read_callback4) ||                 \
+   _curl_callback_compatible((expr), _curl_read_callback5) ||                 \
+   _curl_callback_compatible((expr), _curl_read_callback6))
+typedef size_t (_curl_read_callback1)(char *, size_t, size_t, void*);
+typedef size_t (_curl_read_callback2)(char *, size_t, size_t, const void*);
+typedef size_t (_curl_read_callback3)(char *, size_t, size_t, FILE*);
+typedef size_t (_curl_read_callback4)(void *, size_t, size_t, void*);
+typedef size_t (_curl_read_callback5)(void *, size_t, size_t, const void*);
+typedef size_t (_curl_read_callback6)(void *, size_t, size_t, FILE*);
+
+/* evaluates to true if expr is of type curl_write_callback or "similar" */
+#define _curl_is_write_cb(expr)                                               \
+  (_curl_is_read_cb(expr) ||                                            \
+   __builtin_types_compatible_p(__typeof__(expr), __typeof__(fwrite)) ||      \
+   __builtin_types_compatible_p(__typeof__(expr), curl_write_callback) ||     \
+   _curl_callback_compatible((expr), _curl_write_callback1) ||                \
+   _curl_callback_compatible((expr), _curl_write_callback2) ||                \
+   _curl_callback_compatible((expr), _curl_write_callback3) ||                \
+   _curl_callback_compatible((expr), _curl_write_callback4) ||                \
+   _curl_callback_compatible((expr), _curl_write_callback5) ||                \
+   _curl_callback_compatible((expr), _curl_write_callback6))
+typedef size_t (_curl_write_callback1)(const char *, size_t, size_t, void*);
+typedef size_t (_curl_write_callback2)(const char *, size_t, size_t,
+                                       const void*);
+typedef size_t (_curl_write_callback3)(const char *, size_t, size_t, FILE*);
+typedef size_t (_curl_write_callback4)(const void *, size_t, size_t, void*);
+typedef size_t (_curl_write_callback5)(const void *, size_t, size_t,
+                                       const void*);
+typedef size_t (_curl_write_callback6)(const void *, size_t, size_t, FILE*);
+
+/* evaluates to true if expr is of type curl_ioctl_callback or "similar" */
+#define _curl_is_ioctl_cb(expr)                                         \
+  (_curl_is_NULL(expr) ||                                                     \
+   __builtin_types_compatible_p(__typeof__(expr), curl_ioctl_callback) ||     \
+   _curl_callback_compatible((expr), _curl_ioctl_callback1) ||                \
+   _curl_callback_compatible((expr), _curl_ioctl_callback2) ||                \
+   _curl_callback_compatible((expr), _curl_ioctl_callback3) ||                \
+   _curl_callback_compatible((expr), _curl_ioctl_callback4))
+typedef curlioerr (_curl_ioctl_callback1)(CURL *, int, void*);
+typedef curlioerr (_curl_ioctl_callback2)(CURL *, int, const void*);
+typedef curlioerr (_curl_ioctl_callback3)(CURL *, curliocmd, void*);
+typedef curlioerr (_curl_ioctl_callback4)(CURL *, curliocmd, const void*);
+
+/* evaluates to true if expr is of type curl_sockopt_callback or "similar" */
+#define _curl_is_sockopt_cb(expr)                                       \
+  (_curl_is_NULL(expr) ||                                                     \
+   __builtin_types_compatible_p(__typeof__(expr), curl_sockopt_callback) ||   \
+   _curl_callback_compatible((expr), _curl_sockopt_callback1) ||              \
+   _curl_callback_compatible((expr), _curl_sockopt_callback2))
+typedef int (_curl_sockopt_callback1)(void *, curl_socket_t, curlsocktype);
+typedef int (_curl_sockopt_callback2)(const void *, curl_socket_t,
+                                      curlsocktype);
+
+/* evaluates to true if expr is of type curl_opensocket_callback or "similar" */
+#define _curl_is_opensocket_cb(expr)                                    \
+  (_curl_is_NULL(expr) ||                                                     \
+   __builtin_types_compatible_p(__typeof__(expr), curl_opensocket_callback) ||\
+   _curl_callback_compatible((expr), _curl_opensocket_callback1) ||           \
+   _curl_callback_compatible((expr), _curl_opensocket_callback2) ||           \
+   _curl_callback_compatible((expr), _curl_opensocket_callback3) ||           \
+   _curl_callback_compatible((expr), _curl_opensocket_callback4))
+typedef curl_socket_t (_curl_opensocket_callback1)
+  (void *, curlsocktype, struct curl_sockaddr *);
+typedef curl_socket_t (_curl_opensocket_callback2)
+  (void *, curlsocktype, const struct curl_sockaddr *);
+typedef curl_socket_t (_curl_opensocket_callback3)
+  (const void *, curlsocktype, struct curl_sockaddr *);
+typedef curl_socket_t (_curl_opensocket_callback4)
+  (const void *, curlsocktype, const struct curl_sockaddr *);
+
+/* evaluates to true if expr is of type curl_progress_callback or "similar" */
+#define _curl_is_progress_cb(expr)                                      \
+  (_curl_is_NULL(expr) ||                                                     \
+   __builtin_types_compatible_p(__typeof__(expr), curl_progress_callback) ||  \
+   _curl_callback_compatible((expr), _curl_progress_callback1) ||             \
+   _curl_callback_compatible((expr), _curl_progress_callback2))
+typedef int (_curl_progress_callback1)(void *,
+    double, double, double, double);
+typedef int (_curl_progress_callback2)(const void *,
+    double, double, double, double);
+
+/* evaluates to true if expr is of type curl_debug_callback or "similar" */
+#define _curl_is_debug_cb(expr)                                         \
+  (_curl_is_NULL(expr) ||                                                     \
+   __builtin_types_compatible_p(__typeof__(expr), curl_debug_callback) ||     \
+   _curl_callback_compatible((expr), _curl_debug_callback1) ||                \
+   _curl_callback_compatible((expr), _curl_debug_callback2) ||                \
+   _curl_callback_compatible((expr), _curl_debug_callback3) ||                \
+   _curl_callback_compatible((expr), _curl_debug_callback4))
+typedef int (_curl_debug_callback1) (CURL *,
+    curl_infotype, char *, size_t, void *);
+typedef int (_curl_debug_callback2) (CURL *,
+    curl_infotype, char *, size_t, const void *);
+typedef int (_curl_debug_callback3) (CURL *,
+    curl_infotype, const char *, size_t, void *);
+typedef int (_curl_debug_callback4) (CURL *,
+    curl_infotype, const char *, size_t, const void *);
+
+/* evaluates to true if expr is of type curl_ssl_ctx_callback or "similar" */
+/* this is getting even messier... */
+#define _curl_is_ssl_ctx_cb(expr)                                       \
+  (_curl_is_NULL(expr) ||                                                     \
+   __builtin_types_compatible_p(__typeof__(expr), curl_ssl_ctx_callback) ||   \
+   _curl_callback_compatible((expr), _curl_ssl_ctx_callback1) ||              \
+   _curl_callback_compatible((expr), _curl_ssl_ctx_callback2) ||              \
+   _curl_callback_compatible((expr), _curl_ssl_ctx_callback3) ||              \
+   _curl_callback_compatible((expr), _curl_ssl_ctx_callback4) ||              \
+   _curl_callback_compatible((expr), _curl_ssl_ctx_callback5) ||              \
+   _curl_callback_compatible((expr), _curl_ssl_ctx_callback6) ||              \
+   _curl_callback_compatible((expr), _curl_ssl_ctx_callback7) ||              \
+   _curl_callback_compatible((expr), _curl_ssl_ctx_callback8))
+typedef CURLcode (_curl_ssl_ctx_callback1)(CURL *, void *, void *);
+typedef CURLcode (_curl_ssl_ctx_callback2)(CURL *, void *, const void *);
+typedef CURLcode (_curl_ssl_ctx_callback3)(CURL *, const void *, void *);
+typedef CURLcode (_curl_ssl_ctx_callback4)(CURL *, const void *, const void *);
+#ifdef HEADER_SSL_H
+/* hack: if we included OpenSSL's ssl.h, we know about SSL_CTX
+ * this will of course break if we're included before OpenSSL headers...
+ */
+typedef CURLcode (_curl_ssl_ctx_callback5)(CURL *, SSL_CTX, void *);
+typedef CURLcode (_curl_ssl_ctx_callback6)(CURL *, SSL_CTX, const void *);
+typedef CURLcode (_curl_ssl_ctx_callback7)(CURL *, const SSL_CTX, void *);
+typedef CURLcode (_curl_ssl_ctx_callback8)(CURL *, const SSL_CTX, const void *);
+#else
+typedef _curl_ssl_ctx_callback1 _curl_ssl_ctx_callback5;
+typedef _curl_ssl_ctx_callback1 _curl_ssl_ctx_callback6;
+typedef _curl_ssl_ctx_callback1 _curl_ssl_ctx_callback7;
+typedef _curl_ssl_ctx_callback1 _curl_ssl_ctx_callback8;
+#endif
+
+/* evaluates to true if expr is of type curl_conv_callback or "similar" */
+#define _curl_is_conv_cb(expr)                                          \
+  (_curl_is_NULL(expr) ||                                                     \
+   __builtin_types_compatible_p(__typeof__(expr), curl_conv_callback) ||      \
+   _curl_callback_compatible((expr), _curl_conv_callback1) ||                 \
+   _curl_callback_compatible((expr), _curl_conv_callback2) ||                 \
+   _curl_callback_compatible((expr), _curl_conv_callback3) ||                 \
+   _curl_callback_compatible((expr), _curl_conv_callback4))
+typedef CURLcode (*_curl_conv_callback1)(char *, size_t length);
+typedef CURLcode (*_curl_conv_callback2)(const char *, size_t length);
+typedef CURLcode (*_curl_conv_callback3)(void *, size_t length);
+typedef CURLcode (*_curl_conv_callback4)(const void *, size_t length);
+
+/* evaluates to true if expr is of type curl_seek_callback or "similar" */
+#define _curl_is_seek_cb(expr)                                          \
+  (_curl_is_NULL(expr) ||                                                     \
+   __builtin_types_compatible_p(__typeof__(expr), curl_seek_callback) ||      \
+   _curl_callback_compatible((expr), _curl_seek_callback1) ||                 \
+   _curl_callback_compatible((expr), _curl_seek_callback2))
+typedef CURLcode (*_curl_seek_callback1)(void *, curl_off_t, int);
+typedef CURLcode (*_curl_seek_callback2)(const void *, curl_off_t, int);
+
+
+#endif /* __CURL_TYPECHECK_GCC_H */
diff --git a/include/breakpad/third_party/curl/types.h b/include/breakpad/third_party/curl/types.h
new file mode 100644
index 0000000..d37d6ae
--- /dev/null
+++ b/include/breakpad/third_party/curl/types.h
@@ -0,0 +1 @@
+/* not used */
diff --git a/include/breakpad/third_party/libdisasm/ia32_implicit.h b/include/breakpad/third_party/libdisasm/ia32_implicit.h
new file mode 100644
index 0000000..0002b28
--- /dev/null
+++ b/include/breakpad/third_party/libdisasm/ia32_implicit.h
@@ -0,0 +1,13 @@
+#ifndef IA32_IMPLICIT_H
+#define IA32_IMPLICIT_H
+
+#include "libdis.h"
+
+/* OK, this is a hack to deal with prefixes having implicit operands...
+ * thought I had removed all the old hackishness ;( */
+
+#define IDX_IMPLICIT_REP 41	/* change this if the table changes! */
+
+unsigned int ia32_insn_implicit_ops( x86_insn_t *insn, unsigned int impl_idx );
+
+#endif
diff --git a/include/breakpad/third_party/libdisasm/ia32_insn.h b/include/breakpad/third_party/libdisasm/ia32_insn.h
new file mode 100644
index 0000000..d3f36c3
--- /dev/null
+++ b/include/breakpad/third_party/libdisasm/ia32_insn.h
@@ -0,0 +1,506 @@
+#ifndef IA32_INSN_H
+#define IA32_INSN_H
+/* this file contains the structure of opcode definitions and the
+ * constants they use */
+
+#include <sys/types.h>
+#include "libdis.h"
+
+
+#define GET_BYTE( buf, buf_len ) buf_len ? *buf : 0
+
+#define OP_SIZE_16	1
+#define OP_SIZE_32	2
+#define ADDR_SIZE_16	4
+#define ADDR_SIZE_32	8
+
+#define MAX_INSTRUCTION_SIZE 20
+
+/* invalid instructions are handled by returning 0 [error] from the
+ * function, setting the size of the insn to 1 byte, and copying
+ * the byte at the start of the invalid insn into the x86_insn_t.
+ * if the caller is saving the x86_insn_t for invalid instructions,
+ * instead of discarding them, this will maintain a consistent
+ * address space in the x86_insn_ts */
+
+#define INVALID_INSN ((size_t) -1)	/* return value for invalid insn */
+#define MAKE_INVALID( i, buf )                          \
+                strcpy( i->mnemonic, "invalid" );       \
+                x86_oplist_free( i );                   \
+                i->size = 1;                            \
+                i->group = insn_none;                   \
+                i->type = insn_invalid;                 \
+                memcpy( i->bytes, buf, 1 );
+
+
+size_t ia32_disasm_addr( unsigned char * buf, size_t buf_len, 
+		x86_insn_t *insn);
+
+
+/* --------------------------------------------------------- Table Lookup */
+/* IA32 Instruction defintion for ia32_opcodes.c */
+typedef struct {
+   unsigned int table;          /* escape to this sub-table */
+   unsigned int mnem_flag;      /* Flags referring to mnemonic */
+   unsigned int notes;          /* Notes for this instruction */
+   unsigned int dest_flag, src_flag, aux_flag; /* and for specific operands */
+   unsigned int cpu;            /* minimumCPU [AND with clocks?? */
+   char mnemonic[16];           /* buffers for building instruction */
+   char mnemonic_att[16];       /* at&t style mnemonic name */
+   int32_t dest;
+   int32_t src;
+   int32_t aux;
+   unsigned int flags_effected;
+   unsigned int implicit_ops;	/* implicit operands */
+} ia32_insn_t;
+
+
+
+/* --------------------------------------------------------- Prefixes */
+/* Prefix Flags */
+/* Prefixes, same order as in the manual */
+/* had to reverse the values of the first three as they were entered into
+ * libdis.h incorrectly. */
+#define PREFIX_LOCK       0x0004
+#define PREFIX_REPNZ      0x0002
+#define PREFIX_REPZ       0x0001
+#define PREFIX_OP_SIZE    0x0010
+#define PREFIX_ADDR_SIZE  0x0020
+#define PREFIX_CS         0x0100
+#define PREFIX_SS         0x0200
+#define PREFIX_DS         0x0300
+#define PREFIX_ES         0x0400
+#define PREFIX_FS         0x0500
+#define PREFIX_GS         0x0600
+#define PREFIX_TAKEN      0x1000	/* branch taken */
+#define PREFIX_NOTTAKEN   0x2000	/* branch not taken */
+#define PREFIX_REG_MASK   0x0F00
+#define BRANCH_HINT_MASK  0x3000 
+#define PREFIX_PRINT_MASK 0x000F	/* printable prefixes */
+#define PREFIX_MASK       0xFFFF
+
+/* ---------------------------------------------------------- CPU Type */
+
+#define cpu_8086         0x0001
+#define cpu_80286        0x0002
+#define cpu_80386        0x0003
+#define cpu_80387        0x0004 /* originally these were a co-proc */
+#define cpu_80486        0x0005
+#define cpu_PENTIUM      0x0006
+#define cpu_PENTPRO      0x0007
+#define cpu_PENTIUM2     0x0008
+#define cpu_PENTIUM3     0x0009
+#define cpu_PENTIUM4     0x000A
+#define cpu_K6		 0x0010
+#define cpu_K7		 0x0020
+#define cpu_ATHLON	 0x0030
+#define CPU_MODEL_MASK	 0xFFFF
+#define CPU_MODEL(cpu)	 (cpu & CPU_MODEL_MASK)
+/* intel instruction subsets */
+#define isa_GP		 0x10000	/* General Purpose Instructions */
+#define isa_FPU		 0x20000	/* FPU instructions */
+#define isa_FPUMGT	 0x30000	/* FPU/SIMD Management */
+#define isa_MMX		 0x40000	/* MMX */
+#define isa_SSE1	 0x50000	/* SSE */
+#define isa_SSE2	 0x60000	/* SSE 2 */
+#define isa_SSE3	 0x70000	/* SSE 3 */
+#define isa_3DNOW	 0x80000	/* AMD 3d Now */
+#define isa_SYS		 0x90000	/* System Instructions */
+#define ISA_SUBSET_MASK	 0xFFFF0000
+#define ISA_SUBSET(isa)	(isa & ISA_SUBSET_MASK)
+
+
+/* ------------------------------------------------------ Operand Decoding */
+#define ARG_NONE         0
+
+/* Using a mask allows us to store info such as OP_SIGNED in the
+ * operand flags field */
+#define   OPFLAGS_MASK 	0x0000FFFF
+
+/* Operand Addressing Methods, per intel manual */
+#define   ADDRMETH_MASK	0x00FF0000
+
+/* note: for instructions with implied operands, use no ADDRMETH */
+#define   ADDRMETH_A  	0x00010000   
+#define   ADDRMETH_C   	0x00020000
+#define   ADDRMETH_D   	0x00030000
+#define   ADDRMETH_E   	0x00040000
+#define   ADDRMETH_F   	0x00050000
+#define   ADDRMETH_G   	0x00060000
+#define   ADDRMETH_I   	0x00070000
+#define   ADDRMETH_J   	0x00080000
+#define   ADDRMETH_M   	0x00090000
+#define   ADDRMETH_O   	0x000A0000
+#define   ADDRMETH_P   	0x000B0000
+#define   ADDRMETH_Q   	0x000C0000
+#define   ADDRMETH_R   	0x000D0000
+#define   ADDRMETH_S   	0x000E0000
+#define   ADDRMETH_T   	0x000F0000
+#define   ADDRMETH_V   	0x00100000
+#define   ADDRMETH_W   	0x00110000
+#define   ADDRMETH_X   	0x00120000
+#define   ADDRMETH_Y   	0x00130000
+#define	  ADDRMETH_RR  	0x00140000	/* gen reg hard-coded in opcode */
+#define	  ADDRMETH_RS  	0x00150000	/* seg reg hard-coded in opcode */
+#define	  ADDRMETH_RT  	0x00160000	/* test reg hard-coded in opcode */
+#define	  ADDRMETH_RF  	0x00170000	/* fpu reg hard-coded in opcode */
+#define	  ADDRMETH_II  	0x00180000	/* immediate hard-coded in opcode */
+#define   ADDRMETH_PP   0x00190000	/* mm reg ONLY in modr/m field */
+#define   ADDRMETH_VV   0x001A0000	/* xmm reg ONLY in mod/rm field */
+
+/* Operand Types, per intel manual */
+#define OPTYPE_MASK	0xFF000000
+
+#define OPTYPE_a	0x01000000 /* BOUND: h:h or w:w */
+#define OPTYPE_b   	0x02000000 /* byte */
+#define OPTYPE_c   	0x03000000 /* byte or word */
+#define OPTYPE_d   	0x04000000 /* word */
+#define OPTYPE_dq   	0x05000000 /* qword */
+#define OPTYPE_p   	0x06000000 /* 16:16 or 16:32 pointer */
+#define OPTYPE_pi   	0x07000000 /* dword MMX reg */
+#define OPTYPE_ps   	0x08000000 /* 128-bit single fp */
+#define OPTYPE_q   	0x09000000 /* dword */
+#define OPTYPE_s   	0x0A000000 /* 6-byte descriptor */
+#define OPTYPE_ss   	0x0B000000 /* scalar of 128-bit single fp */
+#define OPTYPE_si   	0x0C000000 /* word general register */
+#define OPTYPE_v   	0x0D000000 /* hword or word */
+#define OPTYPE_w   	0x0E000000 /* hword */
+#define OPTYPE_m   	0x0F000000	/* to handle LEA */
+#define OPTYPE_none 0xFF000000 /* no valid operand size, INVLPG */
+
+/* custom ones for FPU instructions */
+#define OPTYPE_fs	0x10000000	/* pointer to single-real*/
+#define OPTYPE_fd	0x20000000	/* pointer to double real */
+#define OPTYPE_fe	0x30000000	/* pointer to extended real */
+#define OPTYPE_fb	0x40000000	/* pointer to packed BCD */
+#define OPTYPE_fv	0x50000000	/* pointer to FPU env: 14|28-bytes */
+#define OPTYPE_ft	0x60000000	/* pointer to FPU state: 94|108-bytes */
+#define OPTYPE_fx       0x70000000      /* pointer to FPU regs: 512 bites */
+#define OPTYPE_fp       0x80000000      /* general fpu register: dbl ext */
+
+/* SSE2 operand types */
+#define OPTYPE_sd	0x90000000	/* scalar of 128-bit double fp */
+#define OPTYPE_pd	0xA0000000	/* 128-bit double fp */
+
+
+
+/* ---------------------------------------------- Opcode Table Descriptions */
+/* the table type describes how to handle byte/size increments before 
+ * and after lookup. Some tables re-use the current byte, others
+ * consume a byte only if the ModR/M encodes no operands, etc */
+enum ia32_tbl_type_id {
+	tbl_opcode = 0,	/* standard opcode table: no surprises */
+	tbl_prefix,	/* Prefix Override, e.g. 66/F2/F3 */
+	tbl_suffix,	/* 3D Now style */
+	tbl_extension,	/* ModR/M extension: 00-FF -> 00-07 */
+	tbl_ext_ext,	/* extension of modr/m using R/M field */
+	tbl_fpu,	/* fpu table: 00-BF -> 00-0F */
+	tbl_fpu_ext	/* fpu extension : C0-FF -> 00-1F */
+ };
+
+/* How it works:
+ * Bytes are 'consumed' if the next table lookup requires that the byte
+ * pointer be advanced in the instruction stream. 'Does not consume' means
+ * that, when the lookup function recurses, the same byte it re-used in the
+ * new table. It also means that size is not decremented, for example when
+ * a ModR/M byte is used. Note that tbl_extension (ModR/M) instructions that
+ * do not increase the size of an insn with their operands have a forced
+ 3 size increase in the lookup algo. Weird, yes, confusing, yes, welcome
+ * to the Intel ISA. Another note: tbl_prefix is used as an override, so an
+ * empty insn in a prefix table causes the instruction in the original table
+ * to be used, rather than an invalid insn being generated.
+ * 	tbl_opcode uses current byte and consumes it
+ * 	tbl_prefix uses current byte but does not consume it
+ * 	tbl_suffix uses and consumes last byte in insn
+ * 	tbl_extension uses current byte but does not consume it
+ * 	tbl_ext_ext uses current byte but does not consume it
+ * 	tbl_fpu uses current byte and consumes it
+ * 	tbl_fpu_ext uses current byte but does not consume it 
+ */
+
+/* Convenience struct for opcode tables : these will be stored in a 
+ * 'table of tables' so we can use a table index instead of a pointer */
+typedef struct {		/* Assembly instruction tables */
+   ia32_insn_t *table;		/* Pointer to table of instruction encodings */
+   enum ia32_tbl_type_id type;
+   unsigned char shift;		/* amount to shift modrm byte */
+   unsigned char mask;		/* bit mask for look up */
+   unsigned char minlim,maxlim;	/* limits on min/max entries. */
+} ia32_table_desc_t;
+
+
+/* ---------------------------------------------- 'Cooked' Operand Type Info */
+/*                   Permissions: */
+#define OP_R         0x001      /* operand is READ */
+#define OP_W         0x002      /* operand is WRITTEN */
+#define OP_RW        0x003	/* (OP_R|OP_W): convenience macro */
+#define OP_X         0x004      /* operand is EXECUTED */
+
+#define OP_PERM_MASK 0x0000007  /* perms are NOT mutually exclusive */
+#define OP_PERM( type )       (type & OP_PERM_MASK)
+
+/* Flags */
+#define OP_SIGNED    0x010   	/* operand is signed */
+
+#define OP_FLAG_MASK  0x0F0  /* mods are NOT mutually exclusive */
+#define OP_FLAGS( type )        (type & OP_FLAG_MASK)
+
+#define OP_REG_MASK    0x0000FFFF /* lower WORD is register ID */
+#define OP_REGTBL_MASK 0xFFFF0000 /* higher word is register type [gen/dbg] */
+#define OP_REGID( type )      (type & OP_REG_MASK)
+#define OP_REGTYPE( type )    (type & OP_REGTBL_MASK)
+
+/* ------------------------------------------'Cooked' Instruction Type Info */
+/* high-bit opcode types/insn meta-types */
+#define INS_FLAG_PREFIX		0x10000000	/* insn is a prefix */
+#define INS_FLAG_SUFFIX		0x20000000	/* followed by a suffix byte */
+#define INS_FLAG_MASK    	0xFF000000
+
+/* insn notes */
+#define INS_NOTE_RING0		0x00000001	/* insn is privileged */
+#define INS_NOTE_SMM		0x00000002	/* Sys Mgt Mode only */
+#define INS_NOTE_SERIAL		0x00000004	/* serializes */
+#define INS_NOTE_NONSWAP    0x00000008  /* insn is not swapped in att format */ // could be separate field?
+#define INS_NOTE_NOSUFFIX   0x00000010  /* insn has no size suffix in att format */ // could be separate field?
+//#define INS_NOTE_NMI		
+
+#define INS_INVALID 	0
+
+/* instruction groups */
+#define INS_EXEC	0x1000
+#define INS_ARITH	0x2000
+#define INS_LOGIC	0x3000
+#define INS_STACK	0x4000
+#define INS_COND	0x5000
+#define INS_LOAD	0x6000
+#define INS_ARRAY	0x7000
+#define INS_BIT		0x8000
+#define INS_FLAG	0x9000
+#define INS_FPU		0xA000
+#define INS_TRAPS	0xD000
+#define INS_SYSTEM	0xE000
+#define INS_OTHER	0xF000
+
+#define INS_GROUP_MASK	0xF000
+#define INS_GROUP( type )     ( type & INS_GROUP_MASK )
+
+/* INS_EXEC group */
+#define INS_BRANCH	(INS_EXEC | 0x01)	/* Unconditional branch */
+#define INS_BRANCHCC	(INS_EXEC | 0x02)	/* Conditional branch */
+#define INS_CALL	(INS_EXEC | 0x03)	/* Jump to subroutine */
+#define INS_CALLCC	(INS_EXEC | 0x04)	/* Jump to subroutine */
+#define INS_RET		(INS_EXEC | 0x05)	/* Return from subroutine */
+
+/* INS_ARITH group */
+#define INS_ADD 	(INS_ARITH | 0x01)
+#define INS_SUB		(INS_ARITH | 0x02)
+#define INS_MUL		(INS_ARITH | 0x03)
+#define INS_DIV		(INS_ARITH | 0x04)
+#define INS_INC		(INS_ARITH | 0x05)	/* increment */
+#define INS_DEC		(INS_ARITH | 0x06)	/* decrement */
+#define INS_SHL		(INS_ARITH | 0x07)	/* shift right */
+#define INS_SHR		(INS_ARITH | 0x08)	/* shift left */
+#define INS_ROL		(INS_ARITH | 0x09)	/* rotate left */
+#define INS_ROR		(INS_ARITH | 0x0A)	/* rotate right */
+#define INS_MIN		(INS_ARITH | 0x0B)	/* min func */
+#define INS_MAX		(INS_ARITH | 0x0C)	/* max func */
+#define INS_AVG		(INS_ARITH | 0x0D)	/* avg func */
+#define INS_FLR		(INS_ARITH | 0x0E)	/* floor func */
+#define INS_CEIL	(INS_ARITH | 0x0F)	/* ceiling func */
+
+/* INS_LOGIC group */
+#define INS_AND		(INS_LOGIC | 0x01)
+#define INS_OR		(INS_LOGIC | 0x02)
+#define INS_XOR		(INS_LOGIC | 0x03)
+#define INS_NOT		(INS_LOGIC | 0x04)
+#define INS_NEG		(INS_LOGIC | 0x05)
+#define INS_NAND	(INS_LOGIC | 0x06)
+
+/* INS_STACK group */
+#define INS_PUSH	(INS_STACK | 0x01)
+#define INS_POP		(INS_STACK | 0x02)
+#define INS_PUSHREGS	(INS_STACK | 0x03)	/* push register context */
+#define INS_POPREGS	(INS_STACK | 0x04)	/* pop register context */
+#define INS_PUSHFLAGS	(INS_STACK | 0x05)	/* push all flags */
+#define INS_POPFLAGS	(INS_STACK | 0x06)	/* pop all flags */
+#define INS_ENTER	(INS_STACK | 0x07)	/* enter stack frame */
+#define INS_LEAVE	(INS_STACK | 0x08)	/* leave stack frame */
+
+/* INS_COND group */
+#define INS_TEST	(INS_COND | 0x01)
+#define INS_CMP		(INS_COND | 0x02)
+
+/* INS_LOAD group */
+#define INS_MOV		(INS_LOAD | 0x01)
+#define INS_MOVCC	(INS_LOAD | 0x02)
+#define INS_XCHG	(INS_LOAD | 0x03)
+#define INS_XCHGCC	(INS_LOAD | 0x04)
+#define INS_CONV	(INS_LOAD | 0x05)	/* move and convert type */
+
+/* INS_ARRAY group */
+#define INS_STRCMP	(INS_ARRAY | 0x01)
+#define INS_STRLOAD	(INS_ARRAY | 0x02)
+#define INS_STRMOV	(INS_ARRAY | 0x03)
+#define INS_STRSTOR	(INS_ARRAY | 0x04)
+#define INS_XLAT	(INS_ARRAY | 0x05)
+
+/* INS_BIT group */
+#define INS_BITTEST	(INS_BIT | 0x01)
+#define INS_BITSET	(INS_BIT | 0x02)
+#define INS_BITCLR	(INS_BIT | 0x03)
+
+/* INS_FLAG group */
+#define INS_CLEARCF	(INS_FLAG | 0x01)	/* clear Carry flag */
+#define INS_CLEARZF	(INS_FLAG | 0x02)	/* clear Zero flag */
+#define INS_CLEAROF	(INS_FLAG | 0x03)	/* clear Overflow flag */
+#define INS_CLEARDF	(INS_FLAG | 0x04)	/* clear Direction flag */
+#define INS_CLEARSF	(INS_FLAG | 0x05)	/* clear Sign flag */
+#define INS_CLEARPF	(INS_FLAG | 0x06)	/* clear Parity flag */
+#define INS_SETCF	(INS_FLAG | 0x07)
+#define INS_SETZF	(INS_FLAG | 0x08)
+#define INS_SETOF	(INS_FLAG | 0x09)
+#define INS_SETDF	(INS_FLAG | 0x0A)
+#define INS_SETSF	(INS_FLAG | 0x0B)
+#define INS_SETPF	(INS_FLAG | 0x0C)
+#define INS_TOGCF	(INS_FLAG | 0x10)	/* toggle */
+#define INS_TOGZF	(INS_FLAG | 0x20)
+#define INS_TOGOF	(INS_FLAG | 0x30)
+#define INS_TOGDF	(INS_FLAG | 0x40)
+#define INS_TOGSF	(INS_FLAG | 0x50)
+#define INS_TOGPF	(INS_FLAG | 0x60)
+
+/* INS_FPU */
+#define INS_FMOV       (INS_FPU | 0x1)
+#define INS_FMOVCC     (INS_FPU | 0x2)
+#define INS_FNEG       (INS_FPU | 0x3)
+#define INS_FABS       (INS_FPU | 0x4)
+#define INS_FADD       (INS_FPU | 0x5)
+#define INS_FSUB       (INS_FPU | 0x6)
+#define INS_FMUL       (INS_FPU | 0x7)
+#define INS_FDIV       (INS_FPU | 0x8)
+#define INS_FSQRT      (INS_FPU | 0x9)
+#define INS_FCMP       (INS_FPU | 0xA)
+#define INS_FCOS       (INS_FPU | 0xC)               /* cosine */
+#define INS_FLDPI      (INS_FPU | 0xD)               /* load pi */
+#define INS_FLDZ       (INS_FPU | 0xE)               /* load 0 */
+#define INS_FTAN       (INS_FPU | 0xF)               /* tanget */
+#define INS_FSINE      (INS_FPU | 0x10)              /* sine */
+#define INS_FSYS       (INS_FPU | 0x20)              /* misc */
+
+/* INS_TRAP */
+#define INS_TRAP	(INS_TRAPS | 0x01)	/* generate trap */
+#define INS_TRAPCC	(INS_TRAPS | 0x02)	/* conditional trap gen */
+#define INS_TRET	(INS_TRAPS | 0x03)	/* return from trap */
+#define INS_BOUNDS	(INS_TRAPS | 0x04)	/* gen bounds trap */
+#define INS_DEBUG	(INS_TRAPS | 0x05)	/* gen breakpoint trap */
+#define INS_TRACE	(INS_TRAPS | 0x06)	/* gen single step trap */
+#define INS_INVALIDOP	(INS_TRAPS | 0x07)	/* gen invalid insn */
+#define INS_OFLOW	(INS_TRAPS | 0x08)	/* gen overflow trap */
+#define INS_ICEBP	(INS_TRAPS | 0x09)	/* ICE breakpoint */
+
+/* INS_SYSTEM */
+#define INS_HALT	(INS_SYSTEM | 0x01)	/* halt machine */
+#define INS_IN		(INS_SYSTEM | 0x02)	/* input form port */
+#define INS_OUT		(INS_SYSTEM | 0x03)	/* output to port */
+#define INS_CPUID	(INS_SYSTEM | 0x04)	/* identify cpu */
+
+/* INS_OTHER */
+#define INS_NOP		(INS_OTHER | 0x01)
+#define INS_BCDCONV	(INS_OTHER | 0x02)	/* convert to/from BCD */
+#define INS_SZCONV	(INS_OTHER | 0x03)	/* convert size of operand */
+#define INS_SALC	(INS_OTHER | 0x04)	/* set %al on carry */
+#define INS_UNKNOWN	(INS_OTHER | 0x05)
+ 
+
+#define INS_TYPE_MASK	0xFFFF
+#define INS_TYPE( type )      ( type & INS_TYPE_MASK )
+
+   /* flags effected by instruction */
+#define INS_TEST_CARRY        0x01    /* carry */
+#define INS_TEST_ZERO         0x02    /* zero/equal */
+#define INS_TEST_OFLOW        0x04    /* overflow */
+#define INS_TEST_DIR          0x08    /* direction */
+#define INS_TEST_SIGN         0x10    /* negative */
+#define INS_TEST_PARITY       0x20    /* parity */
+#define INS_TEST_OR           0x40    /* used in jle */
+#define INS_TEST_NCARRY       0x100	/* ! carry */
+#define INS_TEST_NZERO        0x200	/* ! zero */
+#define INS_TEST_NOFLOW       0x400	/* ! oflow */
+#define INS_TEST_NDIR         0x800	/* ! dir */
+#define INS_TEST_NSIGN        0x100	/* ! sign */
+#define INS_TEST_NPARITY      0x2000	/* ! parity */
+/* SF == OF */
+#define INS_TEST_SFEQOF       0x4000
+/* SF != OF */
+#define INS_TEST_SFNEOF       0x8000
+
+#define INS_TEST_ALL		INS_TEST_CARRY | INS_TEST_ZERO | \
+				INS_TEST_OFLOW | INS_TEST_SIGN | \
+				INS_TEST_PARITY
+
+#define INS_SET_CARRY        0x010000    /* carry */
+#define INS_SET_ZERO         0x020000    /* zero/equal */
+#define INS_SET_OFLOW        0x040000    /* overflow */
+#define INS_SET_DIR          0x080000    /* direction */
+#define INS_SET_SIGN         0x100000    /* negative */
+#define INS_SET_PARITY       0x200000    /* parity */
+#define INS_SET_NCARRY       0x1000000 
+#define INS_SET_NZERO        0x2000000
+#define INS_SET_NOFLOW       0x4000000
+#define INS_SET_NDIR         0x8000000
+#define INS_SET_NSIGN        0x10000000
+#define INS_SET_NPARITY      0x20000000
+#define INS_SET_SFEQOF       0x40000000
+#define INS_SET_SFNEOF       0x80000000
+
+#define INS_SET_ALL		INS_SET_CARRY | INS_SET_ZERO | \
+				INS_SET_OFLOW | INS_SET_SIGN | \
+				INS_SET_PARITY
+
+#define INS_TEST_MASK          0x0000FFFF
+#define INS_FLAGS_TEST(x)      (x & INS_TEST_MASK)
+#define INS_SET_MASK           0xFFFF0000
+#define INS_FLAGS_SET(x)       (x & INS_SET_MASK)
+
+#if 0
+/* TODO: actually start using these */
+#define X86_PAIR_NP	1		/* not pairable; execs in U */
+#define X86_PAIR_PU	2		/* pairable in U pipe */
+#define X86_PAIR_PV	3		/* pairable in V pipe */
+#define X86_PAIR_UV	4		/* pairable in UV pipe */
+#define X86_PAIR_FX	5		/* pairable with FXCH */
+
+#define X86_EXEC_PORT_0	1
+#define X86_EXEC_PORT_1	2
+#define X86_EXEC_PORT_2	4
+#define X86_EXEC_PORT_3	8
+#define X86_EXEC_PORT_4	16
+
+#define X86_EXEC_UNITS
+
+typedef struct {	/* representation of an insn during decoding */
+	uint32_t flags;		/* runtime settings */
+	/* instruction prefixes and other foolishness */
+	uint32_t prefix;		/* encoding of prefix */
+	char prefix_str[16];		/* mnemonics for prefix */
+	uint32_t branch_hint;	/* gah! */
+	unsigned int cpu_ver;		/* TODO: cpu version */
+	unsigned int clocks;		/* TODO: clock cycles: min/max */
+	unsigned char last_prefix;
+	/* runtime intruction decoding helpers */
+	unsigned char mode;		/* 16, 32, 64 */
+	unsigned char gen_regs;		/* offset of default general reg set */
+	unsigned char sz_operand;	/* operand size for insn */
+	unsigned char sz_address;	/* address size for insn */
+	unsigned char uops;		/* uops per insn */
+	unsigned char pairing;		/* np,pu,pv.lv */
+	unsigned char exec_unit;
+	unsigned char exec_port;
+	unsigned char latency;
+} ia32_info_t;
+#define MODE_32 0	/* default */
+#define MODE_16 1
+#define MODE_64 2
+#endif
+
+#endif
diff --git a/include/breakpad/third_party/libdisasm/ia32_invariant.h b/include/breakpad/third_party/libdisasm/ia32_invariant.h
new file mode 100644
index 0000000..e1cea60
--- /dev/null
+++ b/include/breakpad/third_party/libdisasm/ia32_invariant.h
@@ -0,0 +1,11 @@
+#ifndef IA32_INVARIANT_H
+#define IA32_INVARIANT_H
+
+#include "libdis.h"
+
+size_t ia32_disasm_invariant( unsigned char *buf, size_t buf_len, 
+		x86_invariant_t *inv);
+
+size_t ia32_disasm_size( unsigned char *buf, size_t buf_len );
+
+#endif
diff --git a/include/breakpad/third_party/libdisasm/ia32_modrm.h b/include/breakpad/third_party/libdisasm/ia32_modrm.h
new file mode 100644
index 0000000..765cb08
--- /dev/null
+++ b/include/breakpad/third_party/libdisasm/ia32_modrm.h
@@ -0,0 +1,13 @@
+#ifndef IA32_MODRM_H
+#define IA32_MODRM_H
+
+#include "libdis.h"
+#include "ia32_insn.h"
+
+size_t ia32_modrm_decode( unsigned char *buf, unsigned int buf_len,
+			    x86_op_t *op, x86_insn_t *insn,
+			    size_t gen_regs );
+
+void ia32_reg_decode( unsigned char byte, x86_op_t *op, size_t gen_regs );
+
+#endif
diff --git a/include/breakpad/third_party/libdisasm/ia32_opcode_tables.h b/include/breakpad/third_party/libdisasm/ia32_opcode_tables.h
new file mode 100644
index 0000000..bbd4fae
--- /dev/null
+++ b/include/breakpad/third_party/libdisasm/ia32_opcode_tables.h
@@ -0,0 +1,57 @@
+#define idx_Main 0
+#define idx_66 1
+#define idx_F2 2
+#define idx_F3 3
+#define idx_0F 4
+#define idx_660F 5
+#define idx_F20F 6
+#define idx_F30F 7
+#define idx_0F00 8
+#define idx_0F01 9
+#define idx_0F0111 10
+#define idx_0F12 11
+#define idx_0F16 12
+#define idx_0F18 13
+#define idx_0F71 14
+#define idx_660F71 15
+#define idx_0F72 16
+#define idx_660F72 17
+#define idx_0F73 18
+#define idx_660F73 19
+#define idx_0FAE 20
+#define idx_0FBA 21
+#define idx_0FC7 22
+#define idx_0FB9 23
+#define idx_C6 24
+#define idx_C7 25
+#define idx_80 26
+#define idx_81 27
+#define idx_82 28
+#define idx_83 29
+#define idx_C0 30
+#define idx_C1 31
+#define idx_D0 32
+#define idx_D1 33
+#define idx_D2 34
+#define idx_D3 35
+#define idx_F6 36
+#define idx_F7 37
+#define idx_FE 38
+#define idx_FF 39
+#define idx_D8 40
+#define idx_D8C0 41
+#define idx_D9 42
+#define idx_D9C0 43
+#define idx_DA 44
+#define idx_DAC0 45
+#define idx_DB 46
+#define idx_DBC0 47
+#define idx_DC 48
+#define idx_DCC0 49
+#define idx_DD 50
+#define idx_DDC0 51
+#define idx_DE 52
+#define idx_DEC0 53
+#define idx_DF 54
+#define idx_DFC0 55
+#define idx_0F0F 56
diff --git a/include/breakpad/third_party/libdisasm/ia32_operand.h b/include/breakpad/third_party/libdisasm/ia32_operand.h
new file mode 100644
index 0000000..08c3074
--- /dev/null
+++ b/include/breakpad/third_party/libdisasm/ia32_operand.h
@@ -0,0 +1,11 @@
+#ifndef IA32_OPERAND_H
+#define IA32_OPERAND_H
+
+#include "libdis.h"
+#include "ia32_insn.h"
+
+size_t ia32_decode_operand( unsigned char *buf, size_t buf_len,
+			      x86_insn_t *insn, unsigned int raw_op, 
+			      unsigned int raw_flags, unsigned int prefixes,
+			      unsigned char modrm );
+#endif
diff --git a/include/breakpad/third_party/libdisasm/ia32_reg.h b/include/breakpad/third_party/libdisasm/ia32_reg.h
new file mode 100644
index 0000000..fbbc77a
--- /dev/null
+++ b/include/breakpad/third_party/libdisasm/ia32_reg.h
@@ -0,0 +1,41 @@
+#ifndef IA32_REG_H
+#define IA32_REG_H
+
+#include <sys/types.h>	/* for size_t */
+#include "libdis.h"	/* for x86_reg_t */
+
+/* NOTE these are used in opcode tables for hard-coded registers */
+#define REG_DWORD_OFFSET 	 1	/* 0 + 1 */
+#define REG_ECX_INDEX		 2	/* 0 + 1 + 1 */
+#define REG_ESP_INDEX		 5	/* 0 + 4 + 1 */
+#define REG_EBP_INDEX		 6	/* 0 + 5 + 1 */
+#define REG_ESI_INDEX		 7	/* 0 + 6 + 1 */
+#define REG_EDI_INDEX		 8	/* 0 + 7 + 1 */
+#define REG_WORD_OFFSET 	 9	/* 1 * 8 + 1 */
+#define REG_BYTE_OFFSET 	17	/* 2 * 8 + 1 */
+#define REG_MMX_OFFSET 		25	/* 3 * 8 + 1 */
+#define REG_SIMD_OFFSET 	33	/* 4 * 8 + 1 */
+#define REG_DEBUG_OFFSET 	41	/* 5 * 8 + 1 */
+#define REG_CTRL_OFFSET 	49	/* 6 * 8 + 1 */
+#define REG_TEST_OFFSET 	57	/* 7 * 8 + 1 */
+#define REG_SEG_OFFSET 		65	/* 8 * 8 + 1 */
+#define REG_LDTR_INDEX		71	/* 8 * 8 + 1 + 1 */
+#define REG_GDTR_INDEX		72	/* 8 * 8 + 2 + 1 */
+#define REG_FPU_OFFSET 		73	/* 9 * 8 + 1 */
+#define REG_FLAGS_INDEX 	81	/* 10 * 8 + 1 */
+#define REG_FPCTRL_INDEX 	82	/* 10 * 8 + 1 + 1 */
+#define REG_FPSTATUS_INDEX 	83	/* 10 * 8 + 2 + 1 */
+#define REG_FPTAG_INDEX 	84	/* 10 * 8 + 3 + 1 */
+#define REG_EIP_INDEX 		85	/* 10 * 8 + 4 + 1 */
+#define REG_IP_INDEX 		86	/* 10 * 8 + 5 + 1 */
+#define REG_IDTR_INDEX		87	/* 10 * 8 + 6 + 1 */
+#define REG_MXCSG_INDEX		88	/* 10 * 8 + 7 + 1 */
+#define REG_TR_INDEX		89	/* 10 * 8 + 8 + 1 */
+#define REG_CSMSR_INDEX		90	/* 10 * 8 + 9 + 1 */
+#define REG_ESPMSR_INDEX	91	/* 10 * 8 + 10 + 1 */
+#define REG_EIPMSR_INDEX	92	/* 10 * 8 + 11 + 1 */
+
+void ia32_handle_register( x86_reg_t *reg, size_t id );
+size_t ia32_true_register_id( size_t id );
+
+#endif
diff --git a/include/breakpad/third_party/libdisasm/ia32_settings.h b/include/breakpad/third_party/libdisasm/ia32_settings.h
new file mode 100644
index 0000000..769c0e9
--- /dev/null
+++ b/include/breakpad/third_party/libdisasm/ia32_settings.h
@@ -0,0 +1,27 @@
+#ifndef IA32_SETTINGS_H
+#define IA32_SETTINGS_H
+
+#include "libdis.h"
+
+typedef struct {
+	/* options */
+	unsigned char endian,		/* 0 = big, 1 = little */
+		      wc_byte,		/* wildcard byte */
+		      max_insn,		/* max insn size */
+		      sz_addr,		/* default address size */
+		      sz_oper,		/* default operand size */
+		      sz_byte,		/* # bits in byte */
+		      sz_word,		/* # bytes in machine word */
+		      sz_dword;		/* # bytes in machine dword */
+	unsigned int id_sp_reg,		/* id of stack pointer */
+		     id_fp_reg,		/* id of frame pointer */
+		     id_ip_reg,		/* id of instruction pointer */
+		     id_flag_reg,	/* id of flags register */
+		     offset_gen_regs,	/* start of general regs */
+		     offset_seg_regs,	/* start of segment regs */
+		     offset_fpu_regs;	/* start of floating point regs */
+	/* user-controlled settings */
+	enum x86_options options;
+} ia32_settings_t;
+
+#endif
diff --git a/include/breakpad/third_party/libdisasm/libdis.h b/include/breakpad/third_party/libdisasm/libdis.h
new file mode 100644
index 0000000..9410339
--- /dev/null
+++ b/include/breakpad/third_party/libdisasm/libdis.h
@@ -0,0 +1,836 @@
+#ifndef LIBDISASM_H
+#define LIBDISASM_H
+
+#ifdef WIN32
+#include <windows.h>
+#endif
+
+#include <stdint.h>
+
+/* 'NEW" types
+ * __________________________________________________________________________*/
+#ifndef LIBDISASM_QWORD_H       /* do not interfere with qword.h */
+        #define LIBDISASM_QWORD_H
+        #ifdef _MSC_VER
+                typedef __int64         qword_t;
+        #else
+                typedef int64_t         qword_t;
+        #endif
+#endif
+
+#include <sys/types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* 'NEW" x86 API
+ * __________________________________________________________________________*/
+
+
+/* ========================================= Error Reporting */
+/* REPORT CODES
+ *      These are passed to a reporter function passed at initialization.
+ *      Each code determines the type of the argument passed to the reporter;
+ *      this allows the report to recover from errors, or just log them.
+ */
+enum x86_report_codes {
+        report_disasm_bounds,   /* RVA OUT OF BOUNDS : The disassembler could
+                                   not disassemble the supplied RVA as it is
+                                   out of the range of the buffer. The
+                                   application should store the address and
+                                   attempt to determine what section of the
+                                   binary it is in, then disassemble the
+                                   address from the bytes in that section.
+                                        data: uint32_t rva */
+        report_insn_bounds,     /* INSTRUCTION OUT OF BOUNDS: The disassembler
+                                   could not disassemble the instruction as
+                                   the instruction would require bytes beyond
+                                   the end of the current buffer. This usually
+                                   indicated garbage bytes at the end of a
+                                   buffer, or an incorrectly-sized buffer.
+                                        data: uint32_t rva */
+        report_invalid_insn,    /* INVALID INSTRUCTION: The disassembler could
+                                   not disassemble the instruction as it has an
+                                   invalid combination of opcodes and operands.
+                                   This will stop automated disassembly; the
+                                   application can restart the disassembly
+                                   after the invalid instruction.
+                                        data: uint32_t rva */
+        report_unknown
+};
+
+/* 'arg' is optional arbitrary data provided by the code passing the 
+ *       callback -- for example, it could be 'this' or 'self' in OOP code.
+ * 'code' is provided by libdisasm, it is one of the above
+ * 'data' is provided by libdisasm and is context-specific, per the enums */
+typedef void (*DISASM_REPORTER)( enum x86_report_codes code, 
+				 void *data, void *arg );
+
+
+/* x86_report_error : Call the register reporter to report an error */
+void x86_report_error( enum x86_report_codes code, void *data );
+
+/* ========================================= Libdisasm Management Routines */
+enum x86_options {		/* these can be ORed together */
+        opt_none= 0,
+        opt_ignore_nulls=1,     /* ignore sequences of > 4 NULL bytes */
+        opt_16_bit=2,           /* 16-bit/DOS disassembly */
+        opt_att_mnemonics=4,    /* use AT&T syntax names for alternate opcode mnemonics */
+};
+
+/* management routines */
+/* 'arg' is caller-specific data which is passed as the first argument
+ * to the reporter callback routine */
+int x86_init( enum x86_options options, DISASM_REPORTER reporter, void *arg);
+void x86_set_reporter( DISASM_REPORTER reporter, void *arg);
+void x86_set_options( enum x86_options options );
+enum x86_options x86_get_options( void );
+int x86_cleanup(void);
+
+
+/* ========================================= Instruction Representation */
+/* these defines are only intended for use in the array decl's */
+#define MAX_REGNAME 8
+
+#define MAX_PREFIX_STR 32
+#define MAX_MNEM_STR 16
+#define MAX_INSN_SIZE 20        /* same as in i386.h */
+#define MAX_OP_STRING 32        /* max possible operand size in string form */
+#define MAX_OP_RAW_STRING 64    /* max possible operand size in raw form */
+#define MAX_OP_XML_STRING 256   /* max possible operand size in xml form */
+#define MAX_NUM_OPERANDS 8	/* max # implicit and explicit operands */
+/* in these, the '2 *' is arbitrary: the max # of operands should require
+ * more space than the rest of the insn */
+#define MAX_INSN_STRING 512        /* 2 * 8 * MAX_OP_STRING */
+#define MAX_INSN_RAW_STRING 1024   /* 2 * 8 * MAX_OP_RAW_STRING */
+#define MAX_INSN_XML_STRING 4096   /* 2 * 8 * MAX_OP_XML_STRING */
+
+enum x86_reg_type {     /* NOTE: these may be ORed together */
+        reg_gen         = 0x00001,      /* general purpose */
+        reg_in          = 0x00002,      /* incoming args, ala RISC */
+        reg_out         = 0x00004,      /* args to calls, ala RISC */
+        reg_local       = 0x00008,      /* local vars, ala RISC */
+        reg_fpu         = 0x00010,      /* FPU data register */
+        reg_seg         = 0x00020,      /* segment register */
+        reg_simd        = 0x00040,      /* SIMD/MMX reg */
+        reg_sys         = 0x00080,      /* restricted/system register */
+        reg_sp          = 0x00100,      /* stack pointer */
+        reg_fp          = 0x00200,      /* frame pointer */
+        reg_pc          = 0x00400,      /* program counter */
+        reg_retaddr     = 0x00800,      /* return addr for func */
+        reg_cond        = 0x01000,      /* condition code / flags */
+        reg_zero        = 0x02000,      /* zero register, ala RISC */
+        reg_ret         = 0x04000,      /* return value */
+        reg_src         = 0x10000,      /* array/rep source */
+        reg_dest        = 0x20000,      /* array/rep destination */
+        reg_count       = 0x40000       /* array/rep/loop counter */
+};
+
+/* x86_reg_t : an X86 CPU register */
+typedef struct {
+        char name[MAX_REGNAME];
+        enum x86_reg_type type;         /* what register is used for */
+        unsigned int size;              /* size of register in bytes */
+        unsigned int id;                /* register ID #, for quick compares */
+	unsigned int alias;		/* ID of reg this is an alias for */
+	unsigned int shift;		/* amount to shift aliased reg by */
+} x86_reg_t;
+
+/* x86_ea_t : an X86 effective address (address expression) */
+typedef struct {
+        unsigned int     scale;         /* scale factor */
+        x86_reg_t        index, base;   /* index, base registers */
+        int32_t          disp;          /* displacement */
+        char             disp_sign;     /* is negative? 1/0 */
+        char             disp_size;     /* 0, 1, 2, 4 */
+} x86_ea_t;
+
+/* x86_absolute_t : an X86 segment:offset address (descriptor) */
+typedef struct {
+	unsigned short	segment;	/* loaded directly into CS */
+	union {
+		unsigned short	off16;	/* loaded directly into IP */
+		uint32_t		off32;	/* loaded directly into EIP */
+	} offset;	
+} x86_absolute_t;
+
+enum x86_op_type {      /* mutually exclusive */
+        op_unused = 0,          /* empty/unused operand: should never occur */
+        op_register = 1,        /* CPU register */
+        op_immediate = 2,       /* Immediate Value */
+        op_relative_near = 3,   /* Relative offset from IP */
+        op_relative_far = 4,    /* Relative offset from IP */
+        op_absolute = 5,        /* Absolute address (ptr16:32) */
+        op_expression = 6,      /* Address expression (scale/index/base/disp) */
+        op_offset = 7,          /* Offset from start of segment (m32) */
+        op_unknown
+};
+
+#define x86_optype_is_address( optype ) \
+	( optype == op_absolute || optype == op_offset )
+#define x86_optype_is_relative( optype ) \
+	( optype == op_relative_near || optype == op_relative_far )
+#define x86_optype_is_memory( optype ) \
+	( optype > op_immediate && optype < op_unknown )
+
+enum x86_op_datatype {          /* these use Intel's lame terminology */
+        op_byte = 1,            /* 1 byte integer */
+        op_word = 2,            /* 2 byte integer */
+        op_dword = 3,           /* 4 byte integer */
+        op_qword = 4,           /* 8 byte integer */
+        op_dqword = 5,          /* 16 byte integer */
+        op_sreal = 6,           /* 4 byte real (single real) */
+        op_dreal = 7,           /* 8 byte real (double real) */
+        op_extreal = 8,         /* 10 byte real (extended real) */
+        op_bcd = 9,             /* 10 byte binary-coded decimal */
+        op_ssimd = 10,          /* 16 byte : 4 packed single FP (SIMD, MMX) */
+        op_dsimd = 11,          /* 16 byte : 2 packed double FP (SIMD, MMX) */
+        op_sssimd = 12,         /* 4 byte : scalar single FP (SIMD, MMX) */
+        op_sdsimd = 13,         /* 8 byte : scalar double FP (SIMD, MMX) */
+	op_descr32 = 14,	/* 6 byte Intel descriptor 2:4 */
+	op_descr16 = 15,	/* 4 byte Intel descriptor 2:2 */
+	op_pdescr32 = 16,	/* 6 byte Intel pseudo-descriptor 32:16 */
+	op_pdescr16 = 17,	/* 6 byte Intel pseudo-descriptor 8:24:16 */
+	op_bounds16 = 18,	/* signed 16:16 lower:upper bounds */
+	op_bounds32 = 19,	/* signed 32:32 lower:upper bounds */
+        op_fpuenv16 = 20,	/* 14 byte FPU control/environment data */
+        op_fpuenv32 = 21,	/* 28 byte FPU control/environment data */
+	op_fpustate16 = 22,	/* 94 byte FPU state (env & reg stack) */
+	op_fpustate32 = 23,	/* 108 byte FPU state (env & reg stack) */
+	op_fpregset = 24,	/* 512 bytes: register set */
+	op_fpreg = 25,		/* FPU register */
+    op_none = 0xFF,     /* operand without a datatype (INVLPG) */
+};
+
+enum x86_op_access {    /* ORed together */
+        op_read = 1,
+        op_write = 2,
+        op_execute = 4
+};
+
+enum x86_op_flags {     /* ORed together, but segs are mutually exclusive */
+        op_signed = 1,          /* signed integer */
+        op_string = 2,          /* possible string or array */
+        op_constant = 4,        /* symbolic constant */
+        op_pointer = 8,         /* operand points to a memory address */
+	op_sysref = 0x010,	/* operand is a syscall number */
+	op_implied = 0x020,	/* operand is implicit in the insn */
+	op_hardcode = 0x40,	/* operand is hardcoded in insn definition */
+	/* NOTE: an 'implied' operand is one which can be considered a side
+	 * effect of the insn, e.g. %esp being modified by PUSH or POP. A
+	 * 'hard-coded' operand is one which is specified in the instruction
+	 * definition, e.g. %es:%edi in MOVSB or 1 in ROL Eb, 1. The difference
+	 * is that hard-coded operands are printed by disassemblers and are
+	 * required to re-assemble, while implicit operands are invisible. */
+        op_es_seg = 0x100,      /* ES segment override */
+        op_cs_seg = 0x200,      /* CS segment override */
+        op_ss_seg = 0x300,      /* SS segment override */
+        op_ds_seg = 0x400,      /* DS segment override */
+        op_fs_seg = 0x500,      /* FS segment override */
+        op_gs_seg = 0x600       /* GS segment override */
+};
+
+/* x86_op_t : an X86 instruction operand */
+typedef struct {
+        enum x86_op_type        type;           /* operand type */
+        enum x86_op_datatype    datatype;       /* operand size */
+        enum x86_op_access      access;         /* operand access [RWX] */
+        enum x86_op_flags       flags;          /* misc flags */
+        union {
+		/* sizeof will have to work on these union members! */
+                /* immediate values */
+                char            sbyte;
+                short           sword;
+                int32_t         sdword;
+                qword_t         sqword;
+                unsigned char   byte;
+                unsigned short  word;
+                uint32_t        dword;
+                qword_t         qword;
+                float           sreal;
+                double          dreal;
+                /* misc large/non-native types */
+                unsigned char   extreal[10];
+                unsigned char   bcd[10];
+                qword_t         dqword[2];
+                unsigned char   simd[16];
+                unsigned char   fpuenv[28];
+                /* offset from segment */
+                uint32_t        offset;
+                /* ID of CPU register */
+                x86_reg_t       reg;
+                /* offsets from current insn */
+                char            relative_near;
+                int32_t         relative_far;
+		/* segment:offset */
+		x86_absolute_t	absolute;
+                /* effective address [expression] */
+                x86_ea_t        expression;
+        } data;
+	/* this is needed to make formatting operands more sane */
+	void * insn;		/* pointer to x86_insn_t owning operand */
+} x86_op_t;
+
+/* Linked list of x86_op_t; provided for manual traversal of the operand
+ * list in an insn. Users wishing to add operands to this list, e.g. to add
+ * implicit operands, should use x86_operand_new in x86_operand_list.h */
+typedef struct x86_operand_list {
+	x86_op_t op;
+	struct x86_operand_list *next;
+} x86_oplist_t;
+
+enum x86_insn_group {
+	insn_none = 0,		/* invalid instruction */
+        insn_controlflow = 1,
+        insn_arithmetic = 2,
+        insn_logic = 3,
+        insn_stack = 4,
+        insn_comparison = 5,
+        insn_move = 6,
+        insn_string = 7,
+        insn_bit_manip = 8,
+        insn_flag_manip = 9,
+        insn_fpu = 10,
+        insn_interrupt = 13,
+        insn_system = 14,
+        insn_other = 15
+};
+
+enum x86_insn_type {
+	insn_invalid = 0,	/* invalid instruction */
+        /* insn_controlflow */
+        insn_jmp = 0x1001,
+        insn_jcc = 0x1002,
+        insn_call = 0x1003,
+        insn_callcc = 0x1004,
+        insn_return = 0x1005,
+        /* insn_arithmetic */
+        insn_add = 0x2001,
+        insn_sub = 0x2002,
+        insn_mul = 0x2003,
+        insn_div = 0x2004,
+        insn_inc = 0x2005,
+        insn_dec = 0x2006,
+        insn_shl = 0x2007,
+        insn_shr = 0x2008,
+        insn_rol = 0x2009,
+        insn_ror = 0x200A,
+        /* insn_logic */
+        insn_and = 0x3001,
+        insn_or = 0x3002,
+        insn_xor = 0x3003,
+        insn_not = 0x3004,
+        insn_neg = 0x3005,
+        /* insn_stack */
+        insn_push = 0x4001,
+        insn_pop = 0x4002,
+        insn_pushregs = 0x4003,
+        insn_popregs = 0x4004,
+        insn_pushflags = 0x4005,
+        insn_popflags = 0x4006,
+        insn_enter = 0x4007,
+        insn_leave = 0x4008,
+        /* insn_comparison */
+        insn_test = 0x5001,
+        insn_cmp = 0x5002,
+        /* insn_move */
+        insn_mov = 0x6001,      /* move */
+        insn_movcc = 0x6002,    /* conditional move */
+        insn_xchg = 0x6003,     /* exchange */
+        insn_xchgcc = 0x6004,   /* conditional exchange */
+        /* insn_string */
+        insn_strcmp = 0x7001,
+        insn_strload = 0x7002,
+        insn_strmov = 0x7003,
+        insn_strstore = 0x7004,
+        insn_translate = 0x7005,        /* xlat */
+        /* insn_bit_manip */
+        insn_bittest = 0x8001,
+        insn_bitset = 0x8002,
+        insn_bitclear = 0x8003,
+        /* insn_flag_manip */
+        insn_clear_carry = 0x9001,
+        insn_clear_zero = 0x9002,
+        insn_clear_oflow = 0x9003,
+        insn_clear_dir = 0x9004,
+        insn_clear_sign = 0x9005,
+        insn_clear_parity = 0x9006,
+        insn_set_carry = 0x9007,
+        insn_set_zero = 0x9008,
+        insn_set_oflow = 0x9009,
+        insn_set_dir = 0x900A,
+        insn_set_sign = 0x900B,
+        insn_set_parity = 0x900C,
+        insn_tog_carry = 0x9010,
+        insn_tog_zero = 0x9020,
+        insn_tog_oflow = 0x9030,
+        insn_tog_dir = 0x9040,
+        insn_tog_sign = 0x9050,
+        insn_tog_parity = 0x9060,
+        /* insn_fpu */
+        insn_fmov = 0xA001,
+        insn_fmovcc = 0xA002,
+        insn_fneg = 0xA003,
+        insn_fabs = 0xA004,
+        insn_fadd = 0xA005,
+        insn_fsub = 0xA006,
+        insn_fmul = 0xA007,
+        insn_fdiv = 0xA008,
+        insn_fsqrt = 0xA009,
+        insn_fcmp = 0xA00A,
+        insn_fcos = 0xA00C,
+        insn_fldpi = 0xA00D,
+        insn_fldz = 0xA00E,
+        insn_ftan = 0xA00F,
+        insn_fsine = 0xA010,
+        insn_fsys = 0xA020,
+        /* insn_interrupt */
+        insn_int = 0xD001,
+        insn_intcc = 0xD002,    /* not present in x86 ISA */
+        insn_iret = 0xD003,
+        insn_bound = 0xD004,
+        insn_debug = 0xD005,
+        insn_trace = 0xD006,
+        insn_invalid_op = 0xD007,
+        insn_oflow = 0xD008,
+        /* insn_system */
+        insn_halt = 0xE001,
+        insn_in = 0xE002,       /* input from port/bus */
+        insn_out = 0xE003,      /* output to port/bus */
+        insn_cpuid = 0xE004,
+        /* insn_other */
+        insn_nop = 0xF001,
+        insn_bcdconv = 0xF002,  /* convert to or from BCD */
+        insn_szconv = 0xF003    /* change size of operand */
+};
+
+/* These flags specify special characteristics of the instruction, such as
+ * whether the inatruction is privileged or whether it serializes the
+ * pipeline.
+ * NOTE : These may not be accurate for all instructions; updates to the
+ * opcode tables have not been completed. */
+enum x86_insn_note {
+	insn_note_ring0		= 1,	/* Only available in ring 0 */
+	insn_note_smm		= 2,	/* "" in System Management Mode */
+	insn_note_serial	= 4,	/* Serializing instruction */
+	insn_note_nonswap	= 8,	/* Does not swap arguments in att-style formatting */
+	insn_note_nosuffix  = 16,	/* Does not have size suffix in att-style formatting */
+};
+
+/* This specifies what effects the instruction has on the %eflags register */
+enum x86_flag_status {
+        insn_carry_set = 0x1,			/* CF */
+        insn_zero_set = 0x2,			/* ZF */
+        insn_oflow_set = 0x4,			/* OF */
+        insn_dir_set = 0x8,			/* DF */
+        insn_sign_set = 0x10,			/* SF */
+        insn_parity_set = 0x20,			/* PF */
+        insn_carry_or_zero_set = 0x40,
+        insn_zero_set_or_sign_ne_oflow = 0x80,
+        insn_carry_clear = 0x100,
+        insn_zero_clear = 0x200,
+        insn_oflow_clear = 0x400,
+        insn_dir_clear = 0x800,
+        insn_sign_clear = 0x1000,
+        insn_parity_clear = 0x2000,
+        insn_sign_eq_oflow = 0x4000,
+        insn_sign_ne_oflow = 0x8000
+};
+
+/* The CPU model in which the insturction first appeared; this can be used
+ * to mask out instructions appearing in earlier or later models or to
+ * check the portability of a binary.
+ * NOTE : These may not be accurate for all instructions; updates to the
+ * opcode tables have not been completed. */
+enum x86_insn_cpu {
+	cpu_8086 	= 1,	/* Intel */
+	cpu_80286	= 2,
+	cpu_80386	= 3,
+	cpu_80387	= 4,
+	cpu_80486	= 5,
+	cpu_pentium	= 6,
+	cpu_pentiumpro	= 7,
+	cpu_pentium2	= 8,
+	cpu_pentium3	= 9,
+	cpu_pentium4	= 10,
+	cpu_k6		= 16,	/* AMD */
+	cpu_k7		= 32,
+	cpu_athlon	= 48
+};
+
+/* CPU ISA subsets: These are derived from the Instruction Groups in
+ * Intel Vol 1 Chapter 5; they represent subsets of the IA32 ISA but
+ * do not reflect the 'type' of the instruction in the same way that
+ * x86_insn_group does. In short, these are AMD/Intel's somewhat useless 
+ * designations.
+ * NOTE : These may not be accurate for all instructions; updates to the
+ * opcode tables have not been completed. */
+enum x86_insn_isa {
+	isa_gp		= 1,	/* general purpose */
+	isa_fp		= 2,	/* floating point */
+	isa_fpumgt	= 3,	/* FPU/SIMD management */
+	isa_mmx		= 4,	/* Intel MMX */
+	isa_sse1	= 5,	/* Intel SSE SIMD */
+	isa_sse2	= 6,	/* Intel SSE2 SIMD */
+	isa_sse3	= 7,	/* Intel SSE3 SIMD */
+	isa_3dnow	= 8,	/* AMD 3DNow! SIMD */
+	isa_sys		= 9	/* system instructions */
+};
+
+enum x86_insn_prefix {
+        insn_no_prefix = 0,
+        insn_rep_zero = 1,	/* REPZ and REPE */
+        insn_rep_notzero = 2,	/* REPNZ and REPNZ */
+        insn_lock = 4		/* LOCK: */
+};
+
+/* TODO: maybe provide insn_new/free(), and have disasm return new insn_t */
+/* x86_insn_t : an X86 instruction */
+typedef struct {
+        /* information about the instruction */
+        uint32_t addr;             /* load address */
+        uint32_t offset;           /* offset into file/buffer */
+        enum x86_insn_group group;      /* meta-type, e.g. INS_EXEC */
+        enum x86_insn_type type;        /* type, e.g. INS_BRANCH */
+	enum x86_insn_note note;	/* note, e.g. RING0 */
+        unsigned char bytes[MAX_INSN_SIZE];
+        unsigned char size;             /* size of insn in bytes */
+	/* 16/32-bit mode settings */
+	unsigned char addr_size;	/* default address size : 2 or 4 */
+	unsigned char op_size;		/* default operand size : 2 or 4 */
+	/* CPU/instruction set */
+	enum x86_insn_cpu cpu;
+	enum x86_insn_isa isa;
+	/* flags */
+        enum x86_flag_status flags_set; /* flags set or tested by insn */
+        enum x86_flag_status flags_tested;
+	/* stack */
+	unsigned char stack_mod;	/* 0 or 1 : is the stack modified? */
+	int32_t stack_mod_val;		/* val stack is modified by if known */
+
+        /* the instruction proper */
+        enum x86_insn_prefix prefix;	/* prefixes ORed together */
+        char prefix_string[MAX_PREFIX_STR]; /* prefixes [might be truncated] */
+        char mnemonic[MAX_MNEM_STR];
+        x86_oplist_t *operands;		/* list of explicit/implicit operands */
+	size_t operand_count;		/* total number of operands */
+	size_t explicit_count;		/* number of explicit operands */
+        /* convenience fields for user */
+        void *block;                    /* code block containing this insn */
+        void *function;                 /* function containing this insn */
+        int tag;			/* tag the insn as seen/processed */
+} x86_insn_t;
+
+
+/* returns 0 if an instruction is invalid, 1 if valid */
+int x86_insn_is_valid( x86_insn_t *insn );
+
+/* DISASSEMBLY ROUTINES
+ *      Canonical order of arguments is
+ *        (buf, buf_len, buf_rva, offset, len, insn, func, arg, resolve_func)
+ *      ...but of course all of these are not used at the same time.
+ */
+
+
+/* Function prototype for caller-supplied callback routine
+ *      These callbacks are intended to process 'insn' further, e.g. by
+ *      adding it to a linked list, database, etc */
+typedef void (*DISASM_CALLBACK)( x86_insn_t *insn, void * arg );
+
+/* Function prototype for caller-supplied address resolver.
+ *      This routine is used to determine the rva to disassemble next, given
+ *      the 'dest' operand of a jump/call. This allows the caller to resolve
+ *      jump/call targets stored in a register or on the stack, and also allows
+ *      the caller to prevent endless loops by checking if an address has
+ *      already been disassembled. If an address cannot be resolved from the
+ *      operand, or if the address has already been disassembled, this routine
+ *      should return -1; in all other cases the RVA to be disassembled next
+ *      should be returned. */
+typedef int32_t (*DISASM_RESOLVER)( x86_op_t *op, x86_insn_t * current_insn,
+				 void *arg );
+
+
+/* x86_disasm: Disassemble a single instruction from a buffer of bytes.
+ *             Returns size of instruction in bytes.
+ *             Caller is responsible for calling x86_oplist_free() on
+ *             a reused "insn" to avoid leaking memory when calling this
+ *             function repeatedly.
+ *      buf     : Buffer of bytes to disassemble
+ *      buf_len : Length of the buffer
+ *      buf_rva : Load address of the start of the buffer
+ *      offset  : Offset in buffer to disassemble
+ *      insn    : Structure to fill with disassembled instruction
+ */
+unsigned int x86_disasm( unsigned char *buf, unsigned int buf_len,
+                	 uint32_t buf_rva, unsigned int offset,
+                	 x86_insn_t * insn );
+
+/* x86_disasm_range: Sequential disassembly of a range of bytes in a buffer,
+ *                   invoking a callback function each time an instruction
+ *                   is successfully disassembled. The 'range' refers to the
+ *                   bytes between 'offset' and 'offset + len' in the buffer;
+ *                   'len' is assumed to be less than the length of the buffer.
+ *                   Returns number of instructions processed.
+ *      buf     : Buffer of bytes to disassemble (e.g. .text section)
+ *      buf_rva : Load address of buffer (e.g. ELF Virtual Address)
+ *      offset  : Offset in buffer to start disassembly at
+ *      len     : Number of bytes to disassemble
+ *      func    : Callback function to invoke (may be NULL)
+ *      arg     : Arbitrary data to pass to callback (may be NULL)
+ */
+unsigned int x86_disasm_range( unsigned char *buf, uint32_t buf_rva,
+	                       unsigned int offset, unsigned int len,
+	                       DISASM_CALLBACK func, void *arg );
+
+/* x86_disasm_forward: Flow-of-execution disassembly of the bytes in a buffer,
+ *                     invoking a callback function each time an instruction
+ *                     is successfully disassembled.
+ *      buf     : Buffer to disassemble (e.g. .text section)
+ *      buf_len : Number of bytes in buffer
+ *      buf_rva : Load address of buffer (e.g. ELF Virtual Address)
+ *      offset  : Offset in buffer to start disassembly at (e.g. entry point)
+ *      func    : Callback function to invoke (may be NULL)
+ *      arg     : Arbitrary data to pass to callback (may be NULL)
+ *      resolver: Caller-supplied address resolver. If no resolver is
+ *                supplied, a default internal one is used -- however the
+ *                internal resolver does NOT catch loops and could end up
+ *                disassembling forever..
+ *      r_arg	: Arbitrary data to pass to resolver (may be NULL)
+ */
+unsigned int x86_disasm_forward( unsigned char *buf, unsigned int buf_len,
+	                         uint32_t buf_rva, unsigned int offset,
+	                         DISASM_CALLBACK func, void *arg,
+	                         DISASM_RESOLVER resolver, void *r_arg );
+
+/* Instruction operands: these are stored as a list of explicit and
+ * implicit operands. It is recommended that the 'foreach' routines
+ * be used to when examining operands for purposes of data flow analysis */
+
+/* Operand FOREACH callback: 'arg' is an abritrary parameter passed to the
+ * foreach routine, 'insn' is the x86_insn_t whose operands are being
+ * iterated over, and 'op' is the current x86_op_t */
+typedef void (*x86_operand_fn)(x86_op_t *op, x86_insn_t *insn, void *arg);
+
+/* FOREACH types: these are used to limit the foreach results to 
+ * operands which match a certain "type" (implicit or explicit)
+ * or which are accessed in certain ways (e.g. read or write). Note
+ * that this operates on the operand list of single instruction, so
+ * specifying the 'real' operand type (register, memory, etc) is not
+ * useful. Note also that by definition Execute Access implies Read
+ * Access and implies Not Write Access.
+ * The "type" (implicit or explicit) and the access method can
+ * be ORed together, e.g. op_wo | op_explicit */
+enum x86_op_foreach_type {
+	op_any 	= 0,		/* ALL operands (explicit, implicit, rwx) */
+	op_dest = 1,		/* operands with Write access */
+	op_src 	= 2,		/* operands with Read access */
+	op_ro 	= 3,		/* operands with Read but not Write access */
+	op_wo 	= 4,		/* operands with Write but not Read access */
+	op_xo 	= 5,		/* operands with Execute access */
+	op_rw 	= 6,		/* operands with Read AND Write access */
+	op_implicit = 0x10,	/* operands that are implied by the opcode */
+	op_explicit = 0x20	/* operands that are not side-effects */
+};
+
+
+/* free the operand list associated with an instruction -- useful for
+ * preventing memory leaks when free()ing an x86_insn_t */
+void x86_oplist_free( x86_insn_t *insn );
+
+/* Operand foreach: invokes 'func' with 'insn' and 'arg' as arguments. The
+ * 'type' parameter is used to select only operands matching specific
+ * criteria. */
+int x86_operand_foreach( x86_insn_t *insn, x86_operand_fn func, void *arg,
+	       	  	 enum x86_op_foreach_type type);
+
+/* convenience routine: returns count of operands matching 'type' */
+size_t x86_operand_count( x86_insn_t *insn, enum x86_op_foreach_type type );
+
+/* accessor functions for the operands */
+x86_op_t * x86_operand_1st( x86_insn_t *insn );
+x86_op_t * x86_operand_2nd( x86_insn_t *insn );
+x86_op_t * x86_operand_3rd( x86_insn_t *insn );
+
+/* these allow libdisasm 2.0 accessor functions to still be used */
+#define x86_get_dest_operand( insn ) x86_operand_1st( insn )
+#define x86_get_src_operand( insn ) x86_operand_2nd( insn )
+#define x86_get_imm_operand( insn ) x86_operand_3rd( insn )
+
+/* get size of operand data in bytes */
+unsigned int x86_operand_size( x86_op_t *op );
+
+/* Operand Convenience Routines: the following three routines are common
+ * operations on operands, intended to ease the burden of the programmer. */
+
+/* Get Address: return the value of an offset operand, or the offset of
+ * a segment:offset absolute address */
+uint32_t x86_get_address( x86_insn_t *insn );
+
+/* Get Relative Offset: return as a sign-extended int32_t the near or far
+ * relative offset operand, or 0 if there is none. There can be only one
+ * relaive offset operand in an instruction. */
+int32_t x86_get_rel_offset( x86_insn_t *insn );
+
+/* Get Branch Target: return the x86_op_t containing the target of
+ * a jump or call operand, or NULL if there is no branch target. 
+ * Internally, a 'branch target' is defined as any operand with
+ * Execute Access set. There can be only one branch target per instruction. */
+x86_op_t * x86_get_branch_target( x86_insn_t *insn );
+
+/* Get Immediate: return the x86_op_t containing the immediate operand
+ * for this instruction, or NULL if there is no immediate operand. There
+ * can be only one immediate operand per instruction */
+x86_op_t * x86_get_imm( x86_insn_t *insn );
+
+/* Get Raw Immediate Data: returns a pointer to the immediate data encoded
+ * in the instruction. This is useful for large data types [>32 bits] currently
+ * not supported by libdisasm, or for determining if the disassembler
+ * screwed up the conversion of the immediate data. Note that 'imm' in this
+ * context refers to immediate data encoded at the end of an instruction as
+ * detailed in the Intel Manual Vol II Chapter 2; it does not refer to the
+ * 'op_imm' operand (the third operand in instructions like 'mul' */
+unsigned char * x86_get_raw_imm( x86_insn_t *insn );
+
+
+/* More accessor fuctions, this time for user-defined info... */
+/* set the address (usually RVA) of the insn */
+void x86_set_insn_addr( x86_insn_t *insn, uint32_t addr );
+
+/* set the offset (usually offset into file) of the insn */
+void x86_set_insn_offset( x86_insn_t *insn, unsigned int offset );
+
+/* set a pointer to the function owning the instruction. The 
+ * type of 'func' is user-defined; libdisasm does not use the func field. */
+void x86_set_insn_function( x86_insn_t *insn, void * func );
+
+/* set a pointer to the block of code owning the instruction. The 
+ * type of 'block' is user-defined; libdisasm does not use the block field. */
+void x86_set_insn_block( x86_insn_t *insn, void * block );
+
+/* instruction tagging: these routines allow the programmer to mark
+ * instructions as "seen" in a DFS, for example. libdisasm does not use
+ * the tag field.*/ 
+/* set insn->tag to 1 */
+void x86_tag_insn( x86_insn_t *insn );
+/* set insn->tag to 0 */
+void x86_untag_insn( x86_insn_t *insn );
+/* return insn->tag */
+int x86_insn_is_tagged( x86_insn_t *insn );
+
+
+/* Disassembly formats:
+ *      AT&T is standard AS/GAS-style: "mnemonic\tsrc, dest, imm"
+ *      Intel is standard MASM/NASM/TASM: "mnemonic\tdest,src, imm"
+ *      Native is tab-delimited: "RVA\tbytes\tmnemonic\tdest\tsrc\timm"
+ *      XML is your typical <insn> ... </insn>
+ *      Raw is addr|offset|size|bytes|prefix... see libdisasm_formats.7
+ */
+enum x86_asm_format { 
+	unknown_syntax = 0,		/* never use! */
+	native_syntax, 			/* header: 35 bytes */
+	intel_syntax, 			/* header: 23 bytes */
+	att_syntax,  			/* header: 23 bytes */
+	xml_syntax,			/* header: 679 bytes */
+	raw_syntax			/* header: 172 bytes */
+};
+
+/* format (sprintf) an operand into 'buf' using specified syntax */
+int x86_format_operand(x86_op_t *op, char *buf, int len,
+                  enum x86_asm_format format);
+
+/* format (sprintf) an instruction mnemonic into 'buf' using specified syntax */
+int x86_format_mnemonic(x86_insn_t *insn, char *buf, int len,
+                        enum x86_asm_format format);
+
+/* format (sprintf) an instruction into 'buf' using specified syntax;
+ * this includes formatting all operands */
+int x86_format_insn(x86_insn_t *insn, char *buf, int len, enum x86_asm_format);
+
+/* fill 'buf' with a description of the format's syntax */
+int x86_format_header( char *buf, int len, enum x86_asm_format format);
+
+/* Endianness of an x86 CPU : 0 is big, 1 is little; always returns 1 */
+unsigned int x86_endian(void);
+
+/* Default address and operand size in bytes */
+unsigned int x86_addr_size(void);
+unsigned int x86_op_size(void);
+
+/* Size of a machine word in bytes */
+unsigned int x86_word_size(void);
+
+/* maximum size of a code instruction */
+#define x86_max_inst_size(x) x86_max_insn_size(x)
+unsigned int x86_max_insn_size(void);
+
+/* register IDs of Stack, Frame, Instruction pointer and Flags register */
+unsigned int x86_sp_reg(void);
+unsigned int x86_fp_reg(void);
+unsigned int x86_ip_reg(void);
+unsigned int x86_flag_reg(void);
+
+/* fill 'reg' struct with details of register 'id' */
+void x86_reg_from_id( unsigned int id, x86_reg_t * reg );
+
+/* convenience macro demonstrating how to get an aliased register; proto is
+ *   void x86_get_aliased_reg( x86_reg_t *alias_reg, x86_reg_t *output_reg )
+ * where 'alias_reg' is a reg operand and 'output_reg' is filled with the
+ * register that the operand is an alias for */
+#define x86_get_aliased_reg( alias_reg, output_reg )			\
+	x86_reg_from_id( alias_reg->alias, output_reg )
+
+
+/* ================================== Invariant Instruction Representation */
+/* Invariant instructions are used for generating binary signatures; 
+ * the instruction is modified so that all variant bytes in an instruction
+ * are replaced with a wildcard byte. 
+ *
+ * A 'variant byte' is one that is expected to be modified by either the 
+ * static or the dynamic linker: for example, an address encoded in an 
+ * instruction. 
+ *
+ * By comparing the invariant representation of one instruction [or of a
+ * sequence of instructions] with the invariant representation of another,
+ * one determine whether the two invariant representations are from the same
+ * relocatable object [.o] file. Thus one can use binary signatures [which
+ * are just sequences of invariant instruction representations] to look for
+ * library routines which have been statically-linked into a binary.
+ *
+ * The invariant routines are faster and smaller than the disassembly
+ * routines; they can be used to determine the size of an instruction 
+ * without all of the overhead of a full instruction disassembly.
+ */
+
+/* This byte is used to replace variant bytes */
+#define X86_WILDCARD_BYTE 0xF4
+
+typedef struct {
+        enum x86_op_type        type;           /* operand type */
+        enum x86_op_datatype    datatype;       /* operand size */
+        enum x86_op_access      access;         /* operand access [RWX] */
+        enum x86_op_flags       flags;          /* misc flags */
+} x86_invariant_op_t;
+
+typedef struct {
+	unsigned char bytes[64];	/* invariant representation */
+	unsigned int  size;		/* number of bytes in insn */
+        enum x86_insn_group group;      /* meta-type, e.g. INS_EXEC */
+        enum x86_insn_type type;        /* type, e.g. INS_BRANCH */
+	x86_invariant_op_t operands[3];	/* operands: dest, src, imm */
+} x86_invariant_t;
+ 
+
+/* return a version of the instruction with the variant bytes masked out */
+size_t x86_invariant_disasm( unsigned char *buf, int buf_len, 
+			  x86_invariant_t *inv );
+/* return the size in bytes of the intruction pointed to by 'buf';
+ * this used x86_invariant_disasm since it faster than x86_disasm */
+size_t x86_size_disasm( unsigned char *buf, unsigned int buf_len );
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/include/breakpad/third_party/libdisasm/qword.h b/include/breakpad/third_party/libdisasm/qword.h
new file mode 100644
index 0000000..5f0e803
--- /dev/null
+++ b/include/breakpad/third_party/libdisasm/qword.h
@@ -0,0 +1,14 @@
+#ifndef LIBDISASM_QWORD_H
+#define LIBDISASM_QWORD_H
+
+#include <stdint.h>
+
+/* platform independent data types */
+
+#ifdef _MSC_VER
+	typedef __int64         qword_t;
+#else
+	typedef int64_t         qword_t;
+#endif
+
+#endif
diff --git a/include/breakpad/third_party/libdisasm/x86_imm.h b/include/breakpad/third_party/libdisasm/x86_imm.h
new file mode 100644
index 0000000..fa35ff2
--- /dev/null
+++ b/include/breakpad/third_party/libdisasm/x86_imm.h
@@ -0,0 +1,18 @@
+#ifndef x86_IMM_H
+#define x86_IMM_H
+
+#include "./qword.h"
+#include <sys/types.h>
+
+#ifdef WIN32
+#include <windows.h>
+#endif
+
+/* these are in the global x86 namespace but are not a part of the
+ * official API */
+unsigned int x86_imm_sized( unsigned char *buf, size_t buf_len, void *dest,
+			    unsigned int size );
+
+unsigned int x86_imm_signsized( unsigned char *buf, size_t buf_len, void *dest,
+				unsigned int size );
+#endif
diff --git a/include/breakpad/third_party/libdisasm/x86_operand_list.h b/include/breakpad/third_party/libdisasm/x86_operand_list.h
new file mode 100644
index 0000000..5366865
--- /dev/null
+++ b/include/breakpad/third_party/libdisasm/x86_operand_list.h
@@ -0,0 +1,8 @@
+#ifndef X86_OPERAND_LIST_H
+#define X86_OPERAND_LIST_H
+#include "libdis.h"
+
+
+x86_op_t * x86_operand_new( x86_insn_t *insn );
+
+#endif
diff --git a/include/breakpad/third_party/linux/include/gflags/gflags.h b/include/breakpad/third_party/linux/include/gflags/gflags.h
new file mode 100644
index 0000000..08a3b63
--- /dev/null
+++ b/include/breakpad/third_party/linux/include/gflags/gflags.h
@@ -0,0 +1,533 @@
+// 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.
+
+// ---
+// Author: Ray Sidney
+// Revamped and reorganized by Craig Silverstein
+//
+// This is the file that should be included by any file which declares
+// or defines a command line flag or wants to parse command line flags
+// or print a program usage message (which will include information about
+// flags).  Executive summary, in the form of an example foo.cc file:
+//
+//    #include "foo.h"         // foo.h has a line "DECLARE_int32(start);"
+//
+//    DEFINE_int32(end, 1000, "The last record to read");
+//    DECLARE_bool(verbose);   // some other file has a DEFINE_bool(verbose, ...)
+//
+//    void MyFunc() {
+//      if (FLAGS_verbose) printf("Records %d-%d\n", FLAGS_start, FLAGS_end);
+//    }
+//
+// Then, at the command-line:
+//    ./foo --noverbose --start=5 --end=100
+//
+// For more details, see
+//    doc/gflags.html
+//
+// --- A note about thread-safety:
+//
+// We describe many functions in this routine as being thread-hostile,
+// thread-compatible, or thread-safe.  Here are the meanings we use:
+//
+// thread-safe: it is safe for multiple threads to call this routine
+//   (or, when referring to a class, methods of this class)
+//   concurrently.
+// thread-hostile: it is not safe for multiple threads to call this
+//   routine (or methods of this class) concurrently.  In gflags,
+//   most thread-hostile routines are intended to be called early in,
+//   or even before, main() -- that is, before threads are spawned.
+// thread-compatible: it is safe for multiple threads to read from
+//   this variable (when applied to variables), or to call const
+//   methods of this class (when applied to classes), as long as no
+//   other thread is writing to the variable or calling non-const
+//   methods of this class.
+
+#ifndef GOOGLE_GFLAGS_H_
+#define GOOGLE_GFLAGS_H_
+
+#include <string>
+#include <vector>
+
+// We care a lot about number of bits things take up.  Unfortunately,
+// systems define their bit-specific ints in a lot of different ways.
+// We use our own way, and have a typedef to get there.
+// Note: these commands below may look like "#if 1" or "#if 0", but
+// that's because they were constructed that way at ./configure time.
+// Look at gflags.h.in to see how they're calculated (based on your config).
+#if 1
+#include <stdint.h>             // the normal place uint16_t is defined
+#endif
+#if 1
+#include <sys/types.h>          // the normal place u_int16_t is defined
+#endif
+#if 1
+#include <inttypes.h>           // a third place for uint16_t or u_int16_t
+#endif
+
+namespace google {
+
+#if 1      // the C99 format
+typedef int32_t int32;
+typedef uint32_t uint32;
+typedef int64_t int64;
+typedef uint64_t uint64;
+#elif 1   // the BSD format
+typedef int32_t int32;
+typedef u_int32_t uint32;
+typedef int64_t int64;
+typedef u_int64_t uint64;
+#elif 0     // the windows (vc7) format
+typedef __int32 int32;
+typedef unsigned __int32 uint32;
+typedef __int64 int64;
+typedef unsigned __int64 uint64;
+#else
+#error Do not know how to define a 32-bit integer quantity on your system
+#endif
+
+// --------------------------------------------------------------------
+// To actually define a flag in a file, use DEFINE_bool,
+// DEFINE_string, etc. at the bottom of this file.  You may also find
+// it useful to register a validator with the flag.  This ensures that
+// when the flag is parsed from the commandline, or is later set via
+// SetCommandLineOption, we call the validation function.
+//
+// The validation function should return true if the flag value is valid, and
+// false otherwise. If the function returns false for the new setting of the
+// flag, the flag will retain its current value. If it returns false for the
+// default value, InitGoogle will die.
+//
+// This function is safe to call at global construct time (as in the
+// example below).
+//
+// Example use:
+//    static bool ValidatePort(const char* flagname, int32 value) {
+//       if (value > 0 && value < 32768)   // value is ok
+//         return true;
+//       printf("Invalid value for --%s: %d\n", flagname, (int)value);
+//       return false;
+//    }
+//    DEFINE_int32(port, 0, "What port to listen on");
+//    static bool dummy = RegisterFlagValidator(&FLAGS_port, &ValidatePort);
+
+// Returns true if successfully registered, false if not (because the
+// first argument doesn't point to a command-line flag, or because a
+// validator is already registered for this flag).
+bool RegisterFlagValidator(const bool* flag,
+                           bool (*validate_fn)(const char*, bool));
+bool RegisterFlagValidator(const int32* flag,
+                           bool (*validate_fn)(const char*, int32));
+bool RegisterFlagValidator(const int64* flag,
+                           bool (*validate_fn)(const char*, int64));
+bool RegisterFlagValidator(const uint64* flag,
+                           bool (*validate_fn)(const char*, uint64));
+bool RegisterFlagValidator(const double* flag,
+                           bool (*validate_fn)(const char*, double));
+bool RegisterFlagValidator(const std::string* flag,
+                           bool (*validate_fn)(const char*, const std::string&));
+
+
+// --------------------------------------------------------------------
+// These methods are the best way to get access to info about the
+// list of commandline flags.  Note that these routines are pretty slow.
+//   GetAllFlags: mostly-complete info about the list, sorted by file.
+//   ShowUsageWithFlags: pretty-prints the list to stdout (what --help does)
+//   ShowUsageWithFlagsRestrict: limit to filenames with restrict as a substr
+//
+// In addition to accessing flags, you can also access argv[0] (the program
+// name) and argv (the entire commandline), which we sock away a copy of.
+// These variables are static, so you should only set them once.
+
+struct CommandLineFlagInfo {
+  std::string name;           // the name of the flag
+  std::string type;           // the type of the flag: int32, etc
+  std::string description;    // the "help text" associated with the flag
+  std::string current_value;  // the current value, as a string
+  std::string default_value;  // the default value, as a string
+  std::string filename;       // 'cleaned' version of filename holding the flag
+  bool has_validator_fn;      // true if RegisterFlagValidator called on flag
+  bool is_default;            // true if the flag has default value
+};
+
+extern void GetAllFlags(std::vector<CommandLineFlagInfo>* OUTPUT);
+// These two are actually defined in commandlineflags_reporting.cc.
+extern void ShowUsageWithFlags(const char *argv0);  // what --help does
+extern void ShowUsageWithFlagsRestrict(const char *argv0, const char *restrict);
+
+// Create a descriptive string for a flag.
+// Goes to some trouble to make pretty line breaks.
+extern std::string DescribeOneFlag(const CommandLineFlagInfo& flag);
+
+// Thread-hostile; meant to be called before any threads are spawned.
+extern void SetArgv(int argc, const char** argv);
+// The following functions are thread-safe as long as SetArgv() is
+// only called before any threads start.
+extern const std::vector<std::string>& GetArgvs();  // all of argv as a vector
+extern const char* GetArgv();               // all of argv as a string
+extern const char* GetArgv0();              // only argv0
+extern uint32 GetArgvSum();                 // simple checksum of argv
+extern const char* ProgramInvocationName(); // argv0, or "UNKNOWN" if not set
+extern const char* ProgramInvocationShortName();   // basename(argv0)
+// ProgramUsage() is thread-safe as long as SetUsageMessage() is only
+// called before any threads start.
+extern const char* ProgramUsage();          // string set by SetUsageMessage()
+
+
+// --------------------------------------------------------------------
+// Normally you access commandline flags by just saying "if (FLAGS_foo)"
+// or whatever, and set them by calling "FLAGS_foo = bar" (or, more
+// commonly, via the DEFINE_foo macro).  But if you need a bit more
+// control, we have programmatic ways to get/set the flags as well.
+// These programmatic ways to access flags are thread-safe, but direct
+// access is only thread-compatible.
+
+// Return true iff the flagname was found.
+// OUTPUT is set to the flag's value, or unchanged if we return false.
+extern bool GetCommandLineOption(const char* name, std::string* OUTPUT);
+
+// Return true iff the flagname was found. OUTPUT is set to the flag's
+// CommandLineFlagInfo or unchanged if we return false.
+extern bool GetCommandLineFlagInfo(const char* name,
+                                   CommandLineFlagInfo* OUTPUT);
+
+// Return the CommandLineFlagInfo of the flagname.  exit() if name not found.
+// Example usage, to check if a flag's value is currently the default value:
+//   if (GetCommandLineFlagInfoOrDie("foo").is_default) ...
+extern CommandLineFlagInfo GetCommandLineFlagInfoOrDie(const char* name);
+
+enum FlagSettingMode {
+  // update the flag's value (can call this multiple times).
+  SET_FLAGS_VALUE,
+  // update the flag's value, but *only if* it has not yet been updated
+  // with SET_FLAGS_VALUE, SET_FLAG_IF_DEFAULT, or "FLAGS_xxx = nondef".
+  SET_FLAG_IF_DEFAULT,
+  // set the flag's default value to this.  If the flag has not yet updated
+  // yet (via SET_FLAGS_VALUE, SET_FLAG_IF_DEFAULT, or "FLAGS_xxx = nondef")
+  // change the flag's current value to the new default value as well.
+  SET_FLAGS_DEFAULT
+};
+
+// Set a particular flag ("command line option").  Returns a string
+// describing the new value that the option has been set to.  The
+// return value API is not well-specified, so basically just depend on
+// it to be empty if the setting failed for some reason -- the name is
+// not a valid flag name, or the value is not a valid value -- and
+// non-empty else.
+
+// SetCommandLineOption uses set_mode == SET_FLAGS_VALUE (the common case)
+extern std::string SetCommandLineOption(const char* name, const char* value);
+extern std::string SetCommandLineOptionWithMode(const char* name, const char* value,
+                                                FlagSettingMode set_mode);
+
+
+// --------------------------------------------------------------------
+// Saves the states (value, default value, whether the user has set
+// the flag, registered validators, etc) of all flags, and restores
+// them when the FlagSaver is destroyed.  This is very useful in
+// tests, say, when you want to let your tests change the flags, but
+// make sure that they get reverted to the original states when your
+// test is complete.
+//
+// Example usage:
+//   void TestFoo() {
+//     FlagSaver s1;
+//     FLAG_foo = false;
+//     FLAG_bar = "some value";
+//
+//     // test happens here.  You can return at any time
+//     // without worrying about restoring the FLAG values.
+//   }
+//
+// Note: This class is marked with __attribute__((unused)) because all the
+// work is done in the constructor and destructor, so in the standard
+// usage example above, the compiler would complain that it's an
+// unused variable.
+//
+// This class is thread-safe.
+
+class FlagSaver {
+ public:
+  FlagSaver();
+  ~FlagSaver();
+
+ private:
+  class FlagSaverImpl* impl_;   // we use pimpl here to keep API steady
+
+  FlagSaver(const FlagSaver&);  // no copying!
+  void operator=(const FlagSaver&);
+} __attribute__ ((unused));
+
+// --------------------------------------------------------------------
+// Some deprecated or hopefully-soon-to-be-deprecated functions.
+
+// This is often used for logging.  TODO(csilvers): figure out a better way
+extern std::string CommandlineFlagsIntoString();
+// Usually where this is used, a FlagSaver should be used instead.
+extern bool ReadFlagsFromString(const std::string& flagfilecontents,
+                                const char* prog_name,
+                                bool errors_are_fatal); // uses SET_FLAGS_VALUE
+
+// These let you manually implement --flagfile functionality.
+// DEPRECATED.
+extern bool AppendFlagsIntoFile(const std::string& filename, const char* prog_name);
+extern bool SaveCommandFlags();  // actually defined in google.cc !
+extern bool ReadFromFlagsFile(const std::string& filename, const char* prog_name,
+                              bool errors_are_fatal);   // uses SET_FLAGS_VALUE
+
+
+// --------------------------------------------------------------------
+// Useful routines for initializing flags from the environment.
+// In each case, if 'varname' does not exist in the environment
+// return defval.  If 'varname' does exist but is not valid
+// (e.g., not a number for an int32 flag), abort with an error.
+// Otherwise, return the value.  NOTE: for booleans, for true use
+// 't' or 'T' or 'true' or '1', for false 'f' or 'F' or 'false' or '0'.
+
+extern bool BoolFromEnv(const char *varname, bool defval);
+extern int32 Int32FromEnv(const char *varname, int32 defval);
+extern int64 Int64FromEnv(const char *varname, int64 defval);
+extern uint64 Uint64FromEnv(const char *varname, uint64 defval);
+extern double DoubleFromEnv(const char *varname, double defval);
+extern const char *StringFromEnv(const char *varname, const char *defval);
+
+
+// --------------------------------------------------------------------
+// The next two functions parse commandlineflags from main():
+
+// Set the "usage" message for this program.  For example:
+//   string usage("This program does nothing.  Sample usage:\n");
+//   usage += argv[0] + " <uselessarg1> <uselessarg2>";
+//   SetUsageMessage(usage);
+// Do not include commandline flags in the usage: we do that for you!
+// Thread-hostile; meant to be called before any threads are spawned.
+extern void SetUsageMessage(const std::string& usage);
+
+// Looks for flags in argv and parses them.  Rearranges argv to put
+// flags first, or removes them entirely if remove_flags is true.
+// If a flag is defined more than once in the command line or flag
+// file, the last definition is used.
+// See top-of-file for more details on this function.
+#ifndef SWIG   // In swig, use ParseCommandLineFlagsScript() instead.
+extern uint32 ParseCommandLineFlags(int *argc, char*** argv,
+                                    bool remove_flags);
+#endif
+
+
+// Calls to ParseCommandLineNonHelpFlags and then to
+// HandleCommandLineHelpFlags can be used instead of a call to
+// ParseCommandLineFlags during initialization, in order to allow for
+// changing default values for some FLAGS (via
+// e.g. SetCommandLineOptionWithMode calls) between the time of
+// command line parsing and the time of dumping help information for
+// the flags as a result of command line parsing.
+// If a flag is defined more than once in the command line or flag
+// file, the last definition is used.
+extern uint32 ParseCommandLineNonHelpFlags(int *argc, char*** argv,
+                                           bool remove_flags);
+// This is actually defined in commandlineflags_reporting.cc.
+// This function is misnamed (it also handles --version, etc.), but
+// it's too late to change that now. :-(
+extern void HandleCommandLineHelpFlags();   // in commandlineflags_reporting.cc
+
+// Allow command line reparsing.  Disables the error normally
+// generated when an unknown flag is found, since it may be found in a
+// later parse.  Thread-hostile; meant to be called before any threads
+// are spawned.
+extern void AllowCommandLineReparsing();
+
+// Reparse the flags that have not yet been recognized.
+// Only flags registered since the last parse will be recognized.
+// Any flag value must be provided as part of the argument using "=",
+// not as a separate command line argument that follows the flag argument.
+// Intended for handling flags from dynamically loaded libraries,
+// since their flags are not registered until they are loaded.
+extern uint32 ReparseCommandLineNonHelpFlags();
+
+
+// --------------------------------------------------------------------
+// Now come the command line flag declaration/definition macros that
+// will actually be used.  They're kind of hairy.  A major reason
+// for this is initialization: we want people to be able to access
+// variables in global constructors and have that not crash, even if
+// their global constructor runs before the global constructor here.
+// (Obviously, we can't guarantee the flags will have the correct
+// default value in that case, but at least accessing them is safe.)
+// The only way to do that is have flags point to a static buffer.
+// So we make one, using a union to ensure proper alignment, and
+// then use placement-new to actually set up the flag with the
+// correct default value.  In the same vein, we have to worry about
+// flag access in global destructors, so FlagRegisterer has to be
+// careful never to destroy the flag-values it constructs.
+//
+// Note that when we define a flag variable FLAGS_<name>, we also
+// preemptively define a junk variable, FLAGS_no<name>.  This is to
+// cause a link-time error if someone tries to define 2 flags with
+// names like "logging" and "nologging".  We do this because a bool
+// flag FLAG can be set from the command line to true with a "-FLAG"
+// argument, and to false with a "-noFLAG" argument, and so this can
+// potentially avert confusion.
+//
+// We also put flags into their own namespace.  It is purposefully
+// named in an opaque way that people should have trouble typing
+// directly.  The idea is that DEFINE puts the flag in the weird
+// namespace, and DECLARE imports the flag from there into the current
+// namespace.  The net result is to force people to use DECLARE to get
+// access to a flag, rather than saying "extern bool FLAGS_whatever;"
+// or some such instead.  We want this so we can put extra
+// functionality (like sanity-checking) in DECLARE if we want, and
+// make sure it is picked up everywhere.
+//
+// We also put the type of the variable in the namespace, so that
+// people can't DECLARE_int32 something that they DEFINE_bool'd
+// elsewhere.
+
+class FlagRegisterer {
+ public:
+  FlagRegisterer(const char* name, const char* type,
+                 const char* help, const char* filename,
+                 void* current_storage, void* defvalue_storage);
+};
+
+extern bool FlagsTypeWarn(const char *name);
+
+// If your application #defines STRIP_FLAG_HELP to a non-zero value
+// before #including this file, we remove the help message from the
+// binary file. This can reduce the size of the resulting binary
+// somewhat, and may also be useful for security reasons.
+
+extern const char kStrippedFlagHelp[];
+
+}
+
+#ifndef SWIG  // In swig, ignore the main flag declarations
+
+#if defined(STRIP_FLAG_HELP) && STRIP_FLAG_HELP > 0
+// Need this construct to avoid the 'defined but not used' warning.
+#define MAYBE_STRIPPED_HELP(txt) (false ? (txt) : kStrippedFlagHelp)
+#else
+#define MAYBE_STRIPPED_HELP(txt) txt
+#endif
+
+// Each command-line flag has two variables associated with it: one
+// with the current value, and one with the default value.  However,
+// we have a third variable, which is where value is assigned; it's a
+// constant.  This guarantees that FLAG_##value is initialized at
+// static initialization time (e.g. before program-start) rather than
+// than global construction time (which is after program-start but
+// before main), at least when 'value' is a compile-time constant.  We
+// use a small trick for the "default value" variable, and call it
+// FLAGS_no<name>.  This serves the second purpose of assuring a
+// compile error if someone tries to define a flag named no<name>
+// which is illegal (--foo and --nofoo both affect the "foo" flag).
+#define DEFINE_VARIABLE(type, shorttype, name, value, help) \
+  namespace fL##shorttype {                                     \
+    static const type FLAGS_nono##name = value;                 \
+    type FLAGS_##name = FLAGS_nono##name;                       \
+    type FLAGS_no##name = FLAGS_nono##name;                     \
+    static ::google::FlagRegisterer o_##name(      \
+      #name, #type, MAYBE_STRIPPED_HELP(help), __FILE__,        \
+      &FLAGS_##name, &FLAGS_no##name);                          \
+  }                                                             \
+  using fL##shorttype::FLAGS_##name
+
+#define DECLARE_VARIABLE(type, shorttype, name) \
+  namespace fL##shorttype {                     \
+    extern type FLAGS_##name;                   \
+  }                                             \
+  using fL##shorttype::FLAGS_##name
+
+// For DEFINE_bool, we want to do the extra check that the passed-in
+// value is actually a bool, and not a string or something that can be
+// coerced to a bool.  These declarations (no definition needed!) will
+// help us do that, and never evaluate From, which is important.
+// We'll use 'sizeof(IsBool(val))' to distinguish. This code requires
+// that the compiler have different sizes for bool & double. Since
+// this is not guaranteed by the standard, we check it with a
+// compile-time assert (msg[-1] will give a compile-time error).
+namespace fLB {
+struct CompileAssert {};
+typedef CompileAssert expected_sizeof_double_neq_sizeof_bool[
+                      (sizeof(double) != sizeof(bool)) ? 1 : -1];
+template<typename From> double IsBoolFlag(const From& from);
+bool IsBoolFlag(bool from);
+}  // namespace fLB
+
+#define DECLARE_bool(name)          DECLARE_VARIABLE(bool,B, name)
+#define DEFINE_bool(name,val,txt)                                         \
+  namespace fLB {                                                         \
+    typedef CompileAssert FLAG_##name##_value_is_not_a_bool[              \
+            (sizeof(::fLB::IsBoolFlag(val)) != sizeof(double)) ? 1 : -1]; \
+  }                                                                       \
+  DEFINE_VARIABLE(bool,B, name, val, txt)
+
+#define DECLARE_int32(name)         DECLARE_VARIABLE(::google::int32,I, name)
+#define DEFINE_int32(name,val,txt)  DEFINE_VARIABLE(::google::int32,I, name, val, txt)
+
+#define DECLARE_int64(name)         DECLARE_VARIABLE(::google::int64,I64, name)
+#define DEFINE_int64(name,val,txt)  DEFINE_VARIABLE(::google::int64,I64, name, val, txt)
+
+#define DECLARE_uint64(name)        DECLARE_VARIABLE(::google::uint64,U64, name)
+#define DEFINE_uint64(name,val,txt) DEFINE_VARIABLE(::google::uint64,U64, name, val, txt)
+
+#define DECLARE_double(name)        DECLARE_VARIABLE(double,D, name)
+#define DEFINE_double(name,val,txt) DEFINE_VARIABLE(double,D, name, val, txt)
+
+// Strings are trickier, because they're not a POD, so we can't
+// construct them at static-initialization time (instead they get
+// constructed at global-constructor time, which is much later).  To
+// try to avoid crashes in that case, we use a char buffer to store
+// the string, which we can static-initialize, and then placement-new
+// into it later.  It's not perfect, but the best we can do.
+#define DECLARE_string(name)  namespace fLS { extern std::string& FLAGS_##name; } \
+                              using fLS::FLAGS_##name
+
+// We need to define a var named FLAGS_no##name so people don't define
+// --string and --nostring.  And we need a temporary place to put val
+// so we don't have to evaluate it twice.  Two great needs that go
+// great together!
+// The weird 'using' + 'extern' inside the fLS namespace is to work around
+// an unknown compiler bug/issue with the gcc 4.2.1 on SUSE 10.  See
+//    http://code.google.com/p/google-gflags/issues/detail?id=20
+#define DEFINE_string(name, val, txt)                                     \
+  namespace fLS {                                                         \
+    static union { void* align; char s[sizeof(std::string)]; } s_##name[2]; \
+    const std::string* const FLAGS_no##name = new (s_##name[0].s) std::string(val); \
+    static ::google::FlagRegisterer o_##name(                \
+      #name, "string", MAYBE_STRIPPED_HELP(txt), __FILE__,                \
+      s_##name[0].s, new (s_##name[1].s) std::string(*FLAGS_no##name));   \
+    extern std::string& FLAGS_##name;                                     \
+    using fLS::FLAGS_##name;                                              \
+    std::string& FLAGS_##name = *(reinterpret_cast<std::string*>(s_##name[0].s));   \
+  }                                                                       \
+  using fLS::FLAGS_##name
+
+#endif  // SWIG
+
+#endif  // GOOGLE_GFLAGS_H_
diff --git a/include/breakpad/third_party/linux/include/gflags/gflags_completions.h b/include/breakpad/third_party/linux/include/gflags/gflags_completions.h
new file mode 100644
index 0000000..9d9ce7a
--- /dev/null
+++ b/include/breakpad/third_party/linux/include/gflags/gflags_completions.h
@@ -0,0 +1,121 @@
+// 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.
+//
+// ---
+// Author: Dave Nicponski
+//
+// Implement helpful bash-style command line flag completions
+//
+// ** Functional API:
+// HandleCommandLineCompletions() should be called early during
+// program startup, but after command line flag code has been
+// initialized, such as the beginning of HandleCommandLineHelpFlags().
+// It checks the value of the flag --tab_completion_word.  If this
+// flag is empty, nothing happens here.  If it contains a string,
+// however, then HandleCommandLineCompletions() will hijack the
+// process, attempting to identify the intention behind this
+// completion.  Regardless of the outcome of this deduction, the
+// process will be terminated, similar to --helpshort flag
+// handling.
+//
+// ** Overview of Bash completions:
+// Bash can be told to programatically determine completions for the
+// current 'cursor word'.  It does this by (in this case) invoking a
+// command with some additional arguments identifying the command
+// being executed, the word being completed, and the previous word
+// (if any).  Bash then expects a sequence of output lines to be
+// printed to stdout.  If these lines all contain a common prefix
+// longer than the cursor word, bash will replace the cursor word
+// with that common prefix, and display nothing.  If there isn't such
+// a common prefix, bash will display the lines in pages using 'more'.
+//
+// ** Strategy taken for command line completions:
+// If we can deduce either the exact flag intended, or a common flag
+// prefix, we'll output exactly that.  Otherwise, if information
+// must be displayed to the user, we'll take the opportunity to add
+// some helpful information beyond just the flag name (specifically,
+// we'll include the default flag value and as much of the flag's
+// description as can fit on a single terminal line width, as specified
+// by the flag --tab_completion_columns).  Furthermore, we'll try to
+// make bash order the output such that the most useful or relevent
+// flags are the most likely to be shown at the top.
+//
+// ** Additional features:
+// To assist in finding that one really useful flag, substring matching
+// was implemented.  Before pressing a <TAB> to get completion for the
+// current word, you can append one or more '?' to the flag to do
+// substring matching.  Here's the semantics:
+//   --foo<TAB>     Show me all flags with names prefixed by 'foo'
+//   --foo?<TAB>    Show me all flags with 'foo' somewhere in the name
+//   --foo??<TAB>   Same as prior case, but also search in module
+//                  definition path for 'foo'
+//   --foo???<TAB>  Same as prior case, but also search in flag
+//                  descriptions for 'foo'
+// Finally, we'll trim the output to a relatively small number of
+// flags to keep bash quiet about the verbosity of output.  If one
+// really wanted to see all possible matches, appending a '+' to the
+// search word will force the exhaustive list of matches to be printed.
+//
+// ** How to have bash accept completions from a binary:
+// Bash requires that it be informed about each command that programmatic
+// completion should be enabled for.  Example addition to a .bashrc
+// file would be (your path to gflags_completions.sh file may differ):
+
+/*
+$ complete -o bashdefault -o default -o nospace -C                        \
+ '/usr/local/bin/gflags_completions.sh --tab_completion_columns $COLUMNS' \
+  time  env  binary_name  another_binary  [...]
+*/
+
+// This would allow the following to work:
+//   $ /path/to/binary_name --vmodule<TAB>
+// Or:
+//   $ ./bin/path/another_binary --gfs_u<TAB>
+// (etc)
+//
+// Sadly, it appears that bash gives no easy way to force this behavior for
+// all commands.  That's where the "time" in the above example comes in.
+// If you haven't specifically added a command to the list of completion
+// supported commands, you can still get completions by prefixing the
+// entire command with "env".
+//   $ env /some/brand/new/binary --vmod<TAB>
+// Assuming that "binary" is a newly compiled binary, this should still
+// produce the expected completion output.
+
+
+#ifndef GOOGLE_GFLAGS_COMPLETIONS_H_
+#define GOOGLE_GFLAGS_COMPLETIONS_H_
+
+namespace google {
+
+void HandleCommandLineCompletions(void);
+
+}
+
+#endif  // GOOGLE_GFLAGS_COMPLETIONS_H_
diff --git a/include/breakpad/tools/linux/md2core/minidump_memory_range.h b/include/breakpad/tools/linux/md2core/minidump_memory_range.h
new file mode 100644
index 0000000..a793e2c
--- /dev/null
+++ b/include/breakpad/tools/linux/md2core/minidump_memory_range.h
@@ -0,0 +1,89 @@
+// Copyright (c) 2011, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// minidump_memory_range.h: Define the google_breakpad::MinidumpMemoryRange
+// class, which adds methods for handling minidump specific data structures
+// on top of google_breakpad::MemoryRange. See common/memory_range.h for
+// more details on MemoryRange.
+
+#ifndef TOOLS_LINUX_MD2CORE_MINIDUMP_MEMORY_RANGE_H_
+#define TOOLS_LINUX_MD2CORE_MINIDUMP_MEMORY_RANGE_H_
+
+#include <string>
+
+#include "common/memory_range.h"
+#include "google_breakpad/common/minidump_format.h"
+
+namespace google_breakpad {
+
+// A derived class of MemoryRange with added methods for handling minidump
+// specific data structures. To avoid virtual functions, it is not designed
+// to be used polymorphically.
+class MinidumpMemoryRange : public MemoryRange {
+ public:
+  MinidumpMemoryRange() {}
+
+  MinidumpMemoryRange(const void* data, size_t length)
+      : MemoryRange(data, length) {}
+
+  // Returns a subrange of |length| bytes at |offset| bytes of this memory
+  // range, or an empty range if the subrange is out of bounds.
+  // This methods overrides the base implemementation in order to return
+  // an instance of MinidumpMemoryRange instead of MemoryRange.
+  MinidumpMemoryRange Subrange(size_t sub_offset, size_t sub_length) const {
+    if (Covers(sub_offset, sub_length))
+      return MinidumpMemoryRange(data() + sub_offset, sub_length);
+    return MinidumpMemoryRange();
+  }
+
+  // Returns a subrange that covers the offset and length specified by
+  // |location|, or an empty range if the subrange is out of bounds.
+  MinidumpMemoryRange Subrange(const MDLocationDescriptor& location) const {
+    return MinidumpMemoryRange::Subrange(location.rva, location.data_size);
+  }
+
+  // Gets a STL string from a MDString at |sub_offset| bytes of this memory
+  // range. This method only works correctly for ASCII characters and does
+  // not convert between UTF-16 and UTF-8.
+  const std::string GetAsciiMDString(size_t sub_offset) const {
+    std::string str;
+    const MDString* md_str = GetData<MDString>(sub_offset);
+    if (md_str) {
+      const uint16_t* buffer = &md_str->buffer[0];
+      for (uint32_t i = 0; i < md_str->length && buffer[i]; ++i) {
+        str.push_back(buffer[i]);
+      }
+    }
+    return str;
+  }
+};
+
+}  // namespace google_breakpad
+
+#endif  // TOOLS_LINUX_MD2CORE_MINIDUMP_MEMORY_RANGE_H_
diff --git a/include/breakpad/tools/mac/crash_report/on_demand_symbol_supplier.h b/include/breakpad/tools/mac/crash_report/on_demand_symbol_supplier.h
new file mode 100644
index 0000000..3fbe108
--- /dev/null
+++ b/include/breakpad/tools/mac/crash_report/on_demand_symbol_supplier.h
@@ -0,0 +1,111 @@
+// Copyright (c) 2006, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// on_demand_symbol_supplier.h: Provides a Symbol Supplier that will create
+// a breakpad symbol file on demand.
+
+#ifndef TOOLS_MAC_CRASH_REPORT_ON_DEMAND_SYMBOL_SUPPLIER_H__
+#define TOOLS_MAC_CRASH_REPORT_ON_DEMAND_SYMBOL_SUPPLIER_H__
+
+#include <map>
+#include <string>
+#include "google_breakpad/processor/symbol_supplier.h"
+
+namespace google_breakpad {
+
+using std::map;
+using std::string;
+class MinidumpModule;
+
+class OnDemandSymbolSupplier : public SymbolSupplier {
+ public:
+  // |search_dir| is the directory to search for alternative symbols with
+  // the same name as the module in the minidump
+  OnDemandSymbolSupplier(const string &search_dir,
+                         const string &symbol_search_dir);
+  virtual ~OnDemandSymbolSupplier() {}
+
+  // Returns the path to the symbol file for the given module.
+  virtual SymbolResult GetSymbolFile(const CodeModule *module,
+                                     const SystemInfo *system_info,
+                                     string *symbol_file);
+
+  // Returns the path to the symbol file for the given module.
+  virtual SymbolResult GetSymbolFile(const CodeModule *module,
+                                     const SystemInfo *system_info,
+                                     string *symbol_file,
+                                     string *symbol_data);
+  // Allocates data buffer on heap, and takes the ownership of
+  // the data buffer.
+  virtual SymbolResult GetCStringSymbolData(const CodeModule *module,
+                                            const SystemInfo *system_info,
+                                            string *symbol_file,
+                                            char **symbol_data,
+                                            size_t *symbol_data_size);
+
+  // Delete the data buffer allocated for module in GetCStringSymbolData().
+  virtual void FreeSymbolData(const CodeModule *module);
+
+ protected:
+  // Search directory
+  string search_dir_;
+  string symbol_search_dir_;
+
+  // When we create a symbol file for a module, save the name of the module
+  // and the path to that module's symbol file.
+  map<string, string> module_file_map_;
+
+  // Map of allocated data buffers, keyed by module->code_file().
+  map<string, char *> memory_buffers_;
+
+  // Return the name for |module|  This will be the value used as the key
+  // to the |module_file_map_|.
+  string GetNameForModule(const CodeModule *module);
+
+  // Find the module on local system.  If the module resides in a different
+  // location than the full path in the minidump, this will be the location
+  // used.
+  string GetLocalModulePath(const CodeModule *module);
+
+  // Return the full path for |module|.
+  string GetModulePath(const CodeModule *module);
+
+  // Return the path to the symbol file for |module|.  If an empty string is
+  // returned, then |module| doesn't have a symbol file.
+  string GetModuleSymbolFile(const CodeModule *module);
+
+  // Generate the breakpad symbol file for |module|.  Return true if successful.
+  // File is generated in /tmp.
+  bool GenerateSymbolFile(const CodeModule *module,
+                          const SystemInfo *system_info);
+};
+
+}  // namespace google_breakpad
+
+#endif  // TOOLS_MAC_CRASH_REPORT_ON_DEMAND_SYMBOL_SUPPLIER_H__
diff --git a/include/breakpad/tools/mac/upload_system_symbols/arch_constants.h b/include/breakpad/tools/mac/upload_system_symbols/arch_constants.h
new file mode 100644
index 0000000..2115e54
--- /dev/null
+++ b/include/breakpad/tools/mac/upload_system_symbols/arch_constants.h
@@ -0,0 +1,61 @@
+/* Copyright 2014, Google Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+ * Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the following disclaimer
+in the documentation and/or other materials provided with the
+distribution.
+ * Neither the name of Google Inc. nor the names of its
+contributors may be used to endorse or promote products derived from
+this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include <mach-o/arch.h>
+#include <mach-o/loader.h>
+#include <mach/machine.h>
+
+// Go/Cgo does not support #define constants, so turn them into symbols
+// that are reachable from Go.
+
+#ifndef CPU_TYPE_ARM64
+#define CPU_TYPE_ARM64 (CPU_TYPE_ARM | CPU_ARCH_ABI64)
+#endif
+
+#ifndef CPU_SUBTYPE_ARM64_ALL
+#define CPU_SUBTYPE_ARM64_ALL 0
+#endif
+
+const cpu_type_t kCPU_TYPE_ARM = CPU_TYPE_ARM;
+const cpu_type_t kCPU_TYPE_ARM64 = CPU_TYPE_ARM64;
+
+const cpu_subtype_t kCPU_SUBTYPE_ARM64_ALL = CPU_SUBTYPE_ARM64_ALL;
+const cpu_subtype_t kCPU_SUBTYPE_ARM_V7S = CPU_SUBTYPE_ARM_V7S;
+
+const char* GetNXArchInfoName(cpu_type_t cpu_type, cpu_subtype_t cpu_subtype) {
+  const NXArchInfo* arch_info = NXGetArchInfoFromCpuType(cpu_type, cpu_subtype);
+  if (!arch_info)
+    return 0;
+  return arch_info->name;
+}
+
+const uint32_t kMachHeaderFtypeDylib = MH_DYLIB;
+const uint32_t kMachHeaderFtypeBundle = MH_BUNDLE;
+const uint32_t kMachHeaderFtypeExe = MH_EXECUTE;
diff --git a/include/breakpad/tools/windows/converter/ms_symbol_server_converter.h b/include/breakpad/tools/windows/converter/ms_symbol_server_converter.h
new file mode 100644
index 0000000..d601b43
--- /dev/null
+++ b/include/breakpad/tools/windows/converter/ms_symbol_server_converter.h
@@ -0,0 +1,219 @@
+// Copyright (c) 2007, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// ms_symbol_server_converter.h: Obtain symbol files from a Microsoft
+// symbol server, and convert them to Breakpad's dumped format.
+//
+// At runtime, MSSymbolServerConverter and code that it calls depend on being
+// able to locate suitable versions of dbghelp.dll and symsrv.dll.  For best
+// results, place these files in the same directory as the executable.
+// dbghelp.dll and symsrv.dll as supplied with Debugging Tools for Windows are
+// both redistributable, as indicated by the package's redist.txt file.
+//
+// When connecting to Microsoft's symbol server at
+// http://msdl.microsoft.com/download/symbols/, which provides access to
+// symbols for the operating system itself, symsrv.dll requires agreement to
+// Microsoft's "Terms of Use for Microsoft Symbols and Binaries."  Because this
+// library places the symbol engine into a promptless mode, the dialog with the
+// terms will not appear, and use of Microsoft's symbol server will not be
+// possible.  To indicate agreement to the terms, create a file called
+// symsrv.yes in the same directory as symsrv.dll.  (Note that symsrv.dll will
+// also recognize a symsrv.no file as indicating that you do not accept the
+// terms; the .yes file takes priority over the .no file.)  The terms of use
+// are contained within symsrv.dll; they were formerly available online at
+// http://www.microsoft.com/whdc/devtools/debugging/symsrvTOU2.mspx , but
+// do not appear to be available online any longer as of January, 2007.  It is
+// possible to view the terms from within WinDbg (Debugging Tools for Windows)
+// by removing any symsrv.yes and symsrv.no files from WinDbg's directory,
+// setting the symbol path to include Microsoft's symbol server (.sympath), and
+// attempting to load symbols from their server (.reload).
+//
+// This code has been tested with dbghelp.dll 6.5.3.7 and symsrv.dll 6.5.3.8,
+// included with Microsoft Visual Studio 8 in Common7/IDE.  This has also been
+// tested with dbghelp.dll and symsrv.dll versions 6.6.7.5 and 6.12.2.633,
+// included with the same versions of Debugging Tools for Windows, available at
+// http://www.microsoft.com/whdc/devtools/debugging/ .
+//
+// Author: Mark Mentovai
+
+#ifndef TOOLS_WINDOWS_MS_SYMBOL_SERVER_CONVERTER_H_
+#define TOOLS_WINDOWS_MS_SYMBOL_SERVER_CONVERTER_H_
+
+#include <windows.h>
+
+#include <string>
+#include <vector>
+
+namespace google_breakpad {
+
+using std::string;
+using std::vector;
+
+// MissingSymbolInfo contains the subset of the information in the processor's
+// CodeModule structure relevant to obtaining a missing symbol file.  Only
+// debug_file and debug_identifier are relevant in actually obtaining the
+// missing file; the other fields are for convenience.
+struct MissingSymbolInfo {
+  string code_file;
+  string code_identifier;
+  string debug_file;
+  string debug_identifier;
+  string version;
+};
+
+class GUIDOrSignatureIdentifier {
+ public:
+  enum GUIDOrSignatureType {
+    TYPE_NONE = 0,
+    TYPE_GUID,
+    TYPE_SIGNATURE
+  };
+
+  GUIDOrSignatureIdentifier() : type_(TYPE_NONE) {}
+
+  // Converts |identifier|, a debug_identifier-formatted string, into its
+  // component fields: either a GUID and age, or signature and age.  If
+  // successful, sets the relevant fields in the object, including the type
+  // field, and returns true.  On error, returns false.
+  bool InitializeFromString(const string &identifier);
+
+  GUIDOrSignatureType type() const { return type_; }
+  GUID guid() const { return guid_; }
+  DWORD signature() const { return signature_; }
+  int age() const { return age_; }
+  const void *guid_or_signature_pointer() const { return &guid_; }
+
+ private:
+  GUIDOrSignatureType type_;
+
+  // An identifier contains either a 128-bit uuid or a 32-bit signature.
+  union {
+    GUID guid_;
+    DWORD signature_;
+  };
+
+  // All identifiers used here have age fields, which indicate a specific
+  // revision given a uuid or signature.
+  int age_;
+};
+
+class MSSymbolServerConverter {
+ public:
+  enum LocateResult {
+    LOCATE_FAILURE = 0,
+    LOCATE_NOT_FOUND,    // Authoritative: the file is not present.
+    LOCATE_RETRY,        // Transient (network?) error, try again later.
+    LOCATE_SUCCESS
+  };
+
+  // Create a new object.  local_cache is the location (pathname) of a local
+  // symbol store used to hold downloaded and converted symbol files.  This
+  // directory will be created by LocateSymbolFile when it successfully
+  // retrieves a symbol file. symbol_servers contains a list of locations (URLs
+  // or pathnames) of the upstream symbol server stores, given in order of
+  // preference, with the first string in the vector identifying the first
+  // store to try.  The vector must contain at least one string.  None of the
+  // strings passed to this constructor may contain asterisk ('*') or semicolon
+  // (';') characters, as the symbol engine uses these characters as separators.
+  MSSymbolServerConverter(const string &local_cache,
+                          const vector<string> &symbol_servers);
+
+  // Locates the PE file (DLL or EXE) specified by the identifying information
+  // in |missing|, by checking the symbol stores identified when the object
+  // was created.  When returning LOCATE_SUCCESS, pe_file is set to
+  // the pathname of the decompressed PE file as it is stored in the
+  // local cache.
+  LocateResult LocatePEFile(const MissingSymbolInfo &missing, string *pe_file);
+
+  // Locates the symbol file specified by the identifying information in
+  // |missing|, by checking the symbol stores identified when the object
+  // was created.  When returning LOCATE_SUCCESS, symbol_file is set to
+  // the pathname of the decompressed symbol file as it is stored in the
+  // local cache.
+  LocateResult LocateSymbolFile(const MissingSymbolInfo &missing,
+                                string *symbol_file);
+
+  // Calls LocateSymbolFile and converts the returned symbol file to the
+  // dumped-symbol format, storing it adjacent to the symbol file.  The
+  // only conversion supported is from pdb files.  Returns the return
+  // value of LocateSymbolFile, or if LocateSymbolFile succeeds but
+  // conversion fails, returns LOCATE_FAILURE.  The pathname to the
+  // pdb file and to the converted symbol file are returned in
+  // |converted_symbol_file|, |symbol_file|, and |pe_file|.  |symbol_file| and
+  // |pe_file| are optional and may be NULL.  If only the converted symbol file
+  // is desired, set |keep_symbol_file| and |keep_pe_file| to false to indicate
+  // that the original symbol file (pdb) and executable file (exe, dll) should
+  // be deleted after conversion.
+  LocateResult LocateAndConvertSymbolFile(const MissingSymbolInfo &missing,
+                                          bool keep_symbol_file,
+                                          bool keep_pe_file,
+                                          string *converted_symbol_file,
+                                          string *symbol_file,
+                                          string *pe_file);
+
+ private:
+  // Locates the PDB or PE file (DLL or EXE) specified by the identifying
+  // information in |debug_or_code_file| and |debug_or_code_id|, by checking
+  // the symbol stores identified when the object was created.  When
+  // returning LOCATE_SUCCESS, file_name is set to the pathname of the
+  // decompressed PDB or PE file file as it is stored in the local cache.
+  LocateResult LocateFile(const string &debug_or_code_file,
+                          const string &debug_or_code_id,
+                          const string &version, string *file_name);
+
+  // Called by various SymSrv functions to report status as progress is made
+  // and to allow the callback to influence processing.  Messages sent to this
+  // callback can be used to distinguish between the various failure modes
+  // that SymFindFileInPath might encounter.
+  static BOOL CALLBACK SymCallback(HANDLE process, ULONG action, ULONG64 data,
+                                   ULONG64 context);
+
+  // Called by SymFindFileInPath (in LocateSymbolFile) after a candidate
+  // symbol file is located, when it's present in the local cache.
+  // SymFindFileInPath actually seems to accept NULL for a callback function
+  // and behave properly for our needs in that case, but the documentation
+  // doesn't mention it, so this little callback is provided.
+  static BOOL CALLBACK SymFindFileInPathCallback(const char *filename,
+                                                 void *context);
+
+  // The search path used by SymSrv, built based on the arguments to the
+  // constructor.
+  string symbol_path_;
+
+  // SymCallback will set at least one of these failure variables if
+  // SymFindFileInPath fails for an expected reason.
+  bool fail_dns_;        // DNS failures (fail_not_found_ will also be set).
+  bool fail_timeout_;    // Timeouts (fail_not_found_ will also be set).
+  bool fail_not_found_;  // The file could not be found.  If this is the only
+                         // fail_* member set, then it is authoritative.
+};
+
+}  // namespace google_breakpad
+
+#endif  // TOOLS_WINDOWS_MS_SYMBOL_SERVER_CONVERTER_H_
diff --git a/lib/libbreakpad.a b/lib/libbreakpad.a
index 98745f8..61edcdb 100644
--- a/lib/libbreakpad.a
+++ b/lib/libbreakpad.a
Binary files differ
diff --git a/lib/libbreakpad_client.a b/lib/libbreakpad_client.a
index 90c9e3b..91e15ce 100644
--- a/lib/libbreakpad_client.a
+++ b/lib/libbreakpad_client.a
Binary files differ