google-breakpad: Merge with upstream breakpad r1148

BUG=none
TEST=Verified the following:
1. emerge google-breadpad for {x86,amd64,arm}-generic
2. cros_run_unit_tests google-breakpad for {x86,amd64}-generic
3. Run the following autotest tests:
   - logging_CrashSender
   - logging_UserCrash

Change-Id: I674a1a29a769641aa7e56b1169eebee41512230e
diff --git a/Makefile.am b/Makefile.am
index 93f0ea8..3e219c3 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -46,12 +46,13 @@
 if GCC
 # These are good warnings to be treated as errors
 AM_CXXFLAGS += \
-	-Werror=non-virtual-dtor \
-	-Werror=vla \
-	-Werror=unused-variable \
 	-Werror=missing-braces \
+	-Werror=non-virtual-dtor \
 	-Werror=overloaded-virtual \
-	-Werror=sign-compare
+	-Werror=reorder \
+	-Werror=sign-compare \
+	-Werror=unused-variable \
+	-Werror=vla
 endif
 
 if LINUX_HOST
@@ -177,7 +178,6 @@
 	src/processor/process_state.cc \
 	src/processor/range_map-inl.h \
 	src/processor/range_map.h \
-	src/processor/scoped_ptr.h \
 	src/processor/simple_serializer-inl.h \
 	src/processor/simple_serializer.h \
 	src/processor/simple_symbol_supplier.cc \
@@ -193,6 +193,8 @@
 	src/processor/stackwalker_arm.h \
 	src/processor/stackwalker_ppc.cc \
 	src/processor/stackwalker_ppc.h \
+	src/processor/stackwalker_ppc64.cc \
+	src/processor/stackwalker_ppc64.h \
 	src/processor/stackwalker_sparc.cc \
 	src/processor/stackwalker_sparc.h \
 	src/processor/stackwalker_x86.cc \
@@ -632,6 +634,7 @@
 	src/processor/stackwalker_amd64.o \
 	src/processor/stackwalker_arm.o \
 	src/processor/stackwalker_ppc.o \
+	src/processor/stackwalker_ppc64.o \
 	src/processor/stackwalker_sparc.o \
 	src/processor/stackwalker_x86.o \
 	src/processor/tokenize.o \
@@ -720,6 +723,7 @@
 	src/processor/stackwalker_amd64.o \
 	src/processor/stackwalker_arm.o \
 	src/processor/stackwalker_ppc.o \
+	src/processor/stackwalker_ppc64.o \
 	src/processor/stackwalker_sparc.o \
 	src/processor/stackwalker_x86.o \
 	src/processor/tokenize.o \
@@ -844,6 +848,7 @@
 	src/processor/stackwalker_amd64.o \
 	src/processor/stackwalker_arm.o \
 	src/processor/stackwalker_ppc.o \
+	src/processor/stackwalker_ppc64.o \
 	src/processor/stackwalker_sparc.o \
 	src/processor/stackwalker_x86.o \
 	src/processor/tokenize.o \
@@ -964,6 +969,7 @@
 	src/processor/stackwalker_amd64.o \
 	src/processor/stackwalker_arm.o \
 	src/processor/stackwalker_ppc.o \
+	src/processor/stackwalker_ppc64.o \
 	src/processor/stackwalker_sparc.o \
 	src/processor/stackwalker_x86.o \
 	src/processor/tokenize.o \
@@ -1052,6 +1058,7 @@
 	src/common/mac/string_utilities.h \
 	src/common/md5.cc \
 	src/common/md5.h \
+	src/common/scoped_ptr.h \
 	src/common/solaris/dump_symbols.cc \
 	src/common/solaris/dump_symbols.h \
 	src/common/solaris/file_id.cc \
diff --git a/Makefile.in b/Makefile.in
index b10601b..072e13b 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -76,12 +76,13 @@
 
 # These are good warnings to be treated as errors
 @GCC_TRUE@am__append_2 = \
-@GCC_TRUE@	-Werror=non-virtual-dtor \
-@GCC_TRUE@	-Werror=vla \
-@GCC_TRUE@	-Werror=unused-variable \
 @GCC_TRUE@	-Werror=missing-braces \
+@GCC_TRUE@	-Werror=non-virtual-dtor \
 @GCC_TRUE@	-Werror=overloaded-virtual \
-@GCC_TRUE@	-Werror=sign-compare
+@GCC_TRUE@	-Werror=reorder \
+@GCC_TRUE@	-Werror=sign-compare \
+@GCC_TRUE@	-Werror=unused-variable \
+@GCC_TRUE@	-Werror=vla
 
 
 # Build as PIC on Linux, for linux_client_unittest_shlib
@@ -309,7 +310,7 @@
 	src/processor/postfix_evaluator-inl.h \
 	src/processor/postfix_evaluator.h \
 	src/processor/process_state.cc src/processor/range_map-inl.h \
-	src/processor/range_map.h src/processor/scoped_ptr.h \
+	src/processor/range_map.h \
 	src/processor/simple_serializer-inl.h \
 	src/processor/simple_serializer.h \
 	src/processor/simple_symbol_supplier.cc \
@@ -325,6 +326,8 @@
 	src/processor/stackwalker_arm.h \
 	src/processor/stackwalker_ppc.cc \
 	src/processor/stackwalker_ppc.h \
+	src/processor/stackwalker_ppc64.cc \
+	src/processor/stackwalker_ppc64.h \
 	src/processor/stackwalker_sparc.cc \
 	src/processor/stackwalker_sparc.h \
 	src/processor/stackwalker_x86.cc \
@@ -362,6 +365,7 @@
 @DISABLE_PROCESSOR_FALSE@	src/processor/stackwalker_amd64.$(OBJEXT) \
 @DISABLE_PROCESSOR_FALSE@	src/processor/stackwalker_arm.$(OBJEXT) \
 @DISABLE_PROCESSOR_FALSE@	src/processor/stackwalker_ppc.$(OBJEXT) \
+@DISABLE_PROCESSOR_FALSE@	src/processor/stackwalker_ppc64.$(OBJEXT) \
 @DISABLE_PROCESSOR_FALSE@	src/processor/stackwalker_sparc.$(OBJEXT) \
 @DISABLE_PROCESSOR_FALSE@	src/processor/stackwalker_x86.$(OBJEXT) \
 @DISABLE_PROCESSOR_FALSE@	src/processor/tokenize.$(OBJEXT)
@@ -729,6 +733,7 @@
 @DISABLE_PROCESSOR_FALSE@	src/processor/stackwalker_amd64.o \
 @DISABLE_PROCESSOR_FALSE@	src/processor/stackwalker_arm.o \
 @DISABLE_PROCESSOR_FALSE@	src/processor/stackwalker_ppc.o \
+@DISABLE_PROCESSOR_FALSE@	src/processor/stackwalker_ppc64.o \
 @DISABLE_PROCESSOR_FALSE@	src/processor/stackwalker_sparc.o \
 @DISABLE_PROCESSOR_FALSE@	src/processor/stackwalker_x86.o \
 @DISABLE_PROCESSOR_FALSE@	src/processor/tokenize.o \
@@ -806,6 +811,7 @@
 @DISABLE_PROCESSOR_FALSE@	src/processor/stackwalker_amd64.o \
 @DISABLE_PROCESSOR_FALSE@	src/processor/stackwalker_arm.o \
 @DISABLE_PROCESSOR_FALSE@	src/processor/stackwalker_ppc.o \
+@DISABLE_PROCESSOR_FALSE@	src/processor/stackwalker_ppc64.o \
 @DISABLE_PROCESSOR_FALSE@	src/processor/stackwalker_sparc.o \
 @DISABLE_PROCESSOR_FALSE@	src/processor/stackwalker_x86.o \
 @DISABLE_PROCESSOR_FALSE@	src/processor/tokenize.o \
@@ -838,6 +844,7 @@
 @DISABLE_PROCESSOR_FALSE@	src/processor/stackwalker_amd64.o \
 @DISABLE_PROCESSOR_FALSE@	src/processor/stackwalker_arm.o \
 @DISABLE_PROCESSOR_FALSE@	src/processor/stackwalker_ppc.o \
+@DISABLE_PROCESSOR_FALSE@	src/processor/stackwalker_ppc64.o \
 @DISABLE_PROCESSOR_FALSE@	src/processor/stackwalker_sparc.o \
 @DISABLE_PROCESSOR_FALSE@	src/processor/stackwalker_x86.o \
 @DISABLE_PROCESSOR_FALSE@	src/processor/tokenize.o \
@@ -948,6 +955,7 @@
 @DISABLE_PROCESSOR_FALSE@	src/processor/stackwalker_amd64.o \
 @DISABLE_PROCESSOR_FALSE@	src/processor/stackwalker_arm.o \
 @DISABLE_PROCESSOR_FALSE@	src/processor/stackwalker_ppc.o \
+@DISABLE_PROCESSOR_FALSE@	src/processor/stackwalker_ppc64.o \
 @DISABLE_PROCESSOR_FALSE@	src/processor/stackwalker_sparc.o \
 @DISABLE_PROCESSOR_FALSE@	src/processor/stackwalker_x86.o \
 @DISABLE_PROCESSOR_FALSE@	src/processor/tokenize.o \
@@ -1445,7 +1453,6 @@
 @DISABLE_PROCESSOR_FALSE@	src/processor/process_state.cc \
 @DISABLE_PROCESSOR_FALSE@	src/processor/range_map-inl.h \
 @DISABLE_PROCESSOR_FALSE@	src/processor/range_map.h \
-@DISABLE_PROCESSOR_FALSE@	src/processor/scoped_ptr.h \
 @DISABLE_PROCESSOR_FALSE@	src/processor/simple_serializer-inl.h \
 @DISABLE_PROCESSOR_FALSE@	src/processor/simple_serializer.h \
 @DISABLE_PROCESSOR_FALSE@	src/processor/simple_symbol_supplier.cc \
@@ -1461,6 +1468,8 @@
 @DISABLE_PROCESSOR_FALSE@	src/processor/stackwalker_arm.h \
 @DISABLE_PROCESSOR_FALSE@	src/processor/stackwalker_ppc.cc \
 @DISABLE_PROCESSOR_FALSE@	src/processor/stackwalker_ppc.h \
+@DISABLE_PROCESSOR_FALSE@	src/processor/stackwalker_ppc64.cc \
+@DISABLE_PROCESSOR_FALSE@	src/processor/stackwalker_ppc64.h \
 @DISABLE_PROCESSOR_FALSE@	src/processor/stackwalker_sparc.cc \
 @DISABLE_PROCESSOR_FALSE@	src/processor/stackwalker_sparc.h \
 @DISABLE_PROCESSOR_FALSE@	src/processor/stackwalker_x86.cc \
@@ -1804,6 +1813,7 @@
 @DISABLE_PROCESSOR_FALSE@	src/processor/stackwalker_amd64.o \
 @DISABLE_PROCESSOR_FALSE@	src/processor/stackwalker_arm.o \
 @DISABLE_PROCESSOR_FALSE@	src/processor/stackwalker_ppc.o \
+@DISABLE_PROCESSOR_FALSE@	src/processor/stackwalker_ppc64.o \
 @DISABLE_PROCESSOR_FALSE@	src/processor/stackwalker_sparc.o \
 @DISABLE_PROCESSOR_FALSE@	src/processor/stackwalker_x86.o \
 @DISABLE_PROCESSOR_FALSE@	src/processor/tokenize.o \
@@ -1900,6 +1910,7 @@
 @DISABLE_PROCESSOR_FALSE@	src/processor/stackwalker_amd64.o \
 @DISABLE_PROCESSOR_FALSE@	src/processor/stackwalker_arm.o \
 @DISABLE_PROCESSOR_FALSE@	src/processor/stackwalker_ppc.o \
+@DISABLE_PROCESSOR_FALSE@	src/processor/stackwalker_ppc64.o \
 @DISABLE_PROCESSOR_FALSE@	src/processor/stackwalker_sparc.o \
 @DISABLE_PROCESSOR_FALSE@	src/processor/stackwalker_x86.o \
 @DISABLE_PROCESSOR_FALSE@	src/processor/tokenize.o \
@@ -2038,6 +2049,7 @@
 @DISABLE_PROCESSOR_FALSE@	src/processor/stackwalker_amd64.o \
 @DISABLE_PROCESSOR_FALSE@	src/processor/stackwalker_arm.o \
 @DISABLE_PROCESSOR_FALSE@	src/processor/stackwalker_ppc.o \
+@DISABLE_PROCESSOR_FALSE@	src/processor/stackwalker_ppc64.o \
 @DISABLE_PROCESSOR_FALSE@	src/processor/stackwalker_sparc.o \
 @DISABLE_PROCESSOR_FALSE@	src/processor/stackwalker_x86.o \
 @DISABLE_PROCESSOR_FALSE@	src/processor/tokenize.o \
@@ -2165,6 +2177,7 @@
 @DISABLE_PROCESSOR_FALSE@	src/processor/stackwalker_amd64.o \
 @DISABLE_PROCESSOR_FALSE@	src/processor/stackwalker_arm.o \
 @DISABLE_PROCESSOR_FALSE@	src/processor/stackwalker_ppc.o \
+@DISABLE_PROCESSOR_FALSE@	src/processor/stackwalker_ppc64.o \
 @DISABLE_PROCESSOR_FALSE@	src/processor/stackwalker_sparc.o \
 @DISABLE_PROCESSOR_FALSE@	src/processor/stackwalker_x86.o \
 @DISABLE_PROCESSOR_FALSE@	src/processor/tokenize.o \
@@ -2246,6 +2259,7 @@
 	src/common/mac/string_utilities.h \
 	src/common/md5.cc \
 	src/common/md5.h \
+	src/common/scoped_ptr.h \
 	src/common/solaris/dump_symbols.cc \
 	src/common/solaris/dump_symbols.h \
 	src/common/solaris/file_id.cc \
@@ -2566,6 +2580,9 @@
 src/processor/stackwalker_ppc.$(OBJEXT):  \
 	src/processor/$(am__dirstamp) \
 	src/processor/$(DEPDIR)/$(am__dirstamp)
+src/processor/stackwalker_ppc64.$(OBJEXT):  \
+	src/processor/$(am__dirstamp) \
+	src/processor/$(DEPDIR)/$(am__dirstamp)
 src/processor/stackwalker_sparc.$(OBJEXT):  \
 	src/processor/$(am__dirstamp) \
 	src/processor/$(DEPDIR)/$(am__dirstamp)
@@ -3498,6 +3515,7 @@
 	-rm -f src/processor/stackwalker_amd64.$(OBJEXT)
 	-rm -f src/processor/stackwalker_arm.$(OBJEXT)
 	-rm -f src/processor/stackwalker_ppc.$(OBJEXT)
+	-rm -f src/processor/stackwalker_ppc64.$(OBJEXT)
 	-rm -f src/processor/stackwalker_selftest.$(OBJEXT)
 	-rm -f src/processor/stackwalker_sparc.$(OBJEXT)
 	-rm -f src/processor/stackwalker_x86.$(OBJEXT)
@@ -3732,6 +3750,7 @@
 @AMDEP_TRUE@@am__include@ @am__quote@src/processor/$(DEPDIR)/stackwalker_amd64.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@src/processor/$(DEPDIR)/stackwalker_arm.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@src/processor/$(DEPDIR)/stackwalker_ppc.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@src/processor/$(DEPDIR)/stackwalker_ppc64.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@src/processor/$(DEPDIR)/stackwalker_selftest.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@src/processor/$(DEPDIR)/stackwalker_sparc.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@src/processor/$(DEPDIR)/stackwalker_x86.Po@am__quote@
diff --git a/src/client/ios/Breakpad.mm b/src/client/ios/Breakpad.mm
index f355406..c3758a9 100644
--- a/src/client/ios/Breakpad.mm
+++ b/src/client/ios/Breakpad.mm
@@ -38,20 +38,32 @@
 #define DEBUGLOG if (gDebugLog) fprintf
 #define IGNORE_DEBUGGER "BREAKPAD_IGNORE_DEBUGGER"
 
-#import "common/mac/SimpleStringDictionary.h"
+#import "client/ios/Breakpad.h"
+
+#import <Foundation/Foundation.h>
+#include <pthread.h>
+#include <sys/stat.h>
+#include <sys/sysctl.h>
 
 #import "client/mac/crash_generation/ConfigFile.h"
-#import "client/mac/sender/uploader.h"
 #import "client/mac/handler/exception_handler.h"
 #import "client/mac/handler/minidump_generator.h"
-#import "client/ios/Breakpad.h"
+#import "client/mac/sender/uploader.h"
+#import "common/mac/SimpleStringDictionary.h"
 #import "client/ios/handler/ios_exception_minidump_generator.h"
 #import "client/mac/handler/protected_memory_allocator.h"
 
-#import <sys/stat.h>
-#import <sys/sysctl.h>
-
-#import <Foundation/Foundation.h>
+#ifndef __EXCEPTIONS
+// This file uses C++ try/catch (but shouldn't). Duplicate the macros from
+// <c++/4.2.1/exception_defines.h> allowing this file to work properly with
+// exceptions disabled even when other C++ libraries are used. #undef the try
+// and catch macros first in case libstdc++ is in use and has already provided
+// its own definitions.
+#undef try
+#define try       if (true)
+#undef catch
+#define catch(X)  if (false)
+#endif  // __EXCEPTIONS
 
 using google_breakpad::ConfigFile;
 using google_breakpad::EnsureDirectoryPathExists;
diff --git a/src/client/ios/BreakpadController.h b/src/client/ios/BreakpadController.h
index 6eb826b..6e6229a 100644
--- a/src/client/ios/BreakpadController.h
+++ b/src/client/ios/BreakpadController.h
@@ -55,6 +55,10 @@
   // 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_;
@@ -101,6 +105,9 @@
 // BreakpadController.
 - (void)setUploadingEnabled:(BOOL)enabled;
 
+// Check if there is currently a crash report to upload.
+- (void)hasReportToUpload:(void(^)(BOOL))callback;
+
 @end
 
 #endif  // CLIENT_IOS_HANDLER_IOS_BREAKPAD_CONTROLLER_H_
diff --git a/src/client/ios/BreakpadController.mm b/src/client/ios/BreakpadController.mm
index 0c24e26..31affa1 100644
--- a/src/client/ios/BreakpadController.mm
+++ b/src/client/ios/BreakpadController.mm
@@ -36,7 +36,7 @@
 #include <unistd.h>
 #include <sys/sysctl.h>
 
-#include <processor/scoped_ptr.h>
+#include <common/scoped_ptr.h>
 
 #pragma mark -
 #pragma mark Private Methods
@@ -110,6 +110,7 @@
     queue_ = dispatch_queue_create("com.google.BreakpadQueue", NULL);
     configuration_ = [[[NSBundle mainBundle] infoDictionary] mutableCopy];
     enableUploads_ = NO;
+    started_ = NO;
     NSString* uploadInterval =
         [configuration_ valueForKey:@BREAKPAD_REPORT_INTERVAL];
     [self setUploadInterval:[uploadInterval intValue]];
@@ -128,6 +129,9 @@
 #pragma mark -
 
 - (void)start:(BOOL)onCurrentThread {
+  if (started_)
+    return;
+  started_ = YES;
   void(^startBlock)() = ^{
       assert(!breakpadRef_);
       breakpadRef_ = BreakpadCreate(configuration_);
@@ -142,6 +146,9 @@
 }
 
 - (void)stop {
+  if (!started_)
+    return;
+  started_ = NO;
   dispatch_sync(queue_, ^{
       if (breakpadRef_) {
         BreakpadRelease(breakpadRef_);
@@ -151,6 +158,8 @@
 }
 
 - (void)setUploadingEnabled:(BOOL)enabled {
+  NSAssert(started_,
+      @"The controller must be started before setUploadingEnabled is called");
   dispatch_async(queue_, ^{
       if (enabled == enableUploads_)
         return;
@@ -169,6 +178,8 @@
 }
 
 - (void)updateConfiguration:(NSDictionary*)configuration {
+  NSAssert(!started_,
+      @"The controller must not be started when updateConfiguration is called");
   [configuration_ addEntriesFromDictionary:configuration];
   NSString* uploadInterval =
       [configuration_ valueForKey:@BREAKPAD_REPORT_INTERVAL];
@@ -177,10 +188,14 @@
 }
 
 - (void)setUploadingURL:(NSString*)url {
+  NSAssert(!started_,
+      @"The controller must not be started when setUploadingURL is called");
   [configuration_ setValue:url forKey:@BREAKPAD_URL];
 }
 
 - (void)setUploadInterval:(int)intervalInSeconds {
+  NSAssert(!started_,
+      @"The controller must not be started when setUploadInterval is called");
   [configuration_ removeObjectForKey:@BREAKPAD_REPORT_INTERVAL];
   uploadIntervalInSeconds_ = intervalInSeconds;
   if (uploadIntervalInSeconds_ < 0)
@@ -188,6 +203,8 @@
 }
 
 - (void)addUploadParameter:(NSString*)value forKey:(NSString*)key {
+  NSAssert(started_,
+      @"The controller must be started before addUploadParameter is called");
   dispatch_async(queue_, ^{
       if (breakpadRef_)
         BreakpadAddUploadParameter(breakpadRef_, key, value);
@@ -195,6 +212,8 @@
 }
 
 - (void)removeUploadParameterForKey:(NSString*)key {
+  NSAssert(started_, @"The controller must be started before "
+                     "removeUploadParameterForKey is called");
   dispatch_async(queue_, ^{
       if (breakpadRef_)
         BreakpadRemoveUploadParameter(breakpadRef_, key);
@@ -202,11 +221,20 @@
 }
 
 - (void)withBreakpadRef:(void(^)(BreakpadRef))callback {
+  NSAssert(started_,
+      @"The controller must be started before withBreakpadRef is called");
   dispatch_async(queue_, ^{
       callback(breakpadRef_);
   });
 }
 
+- (void)hasReportToUpload:(void(^)(BOOL))callback {
+  NSAssert(started_, @"The controller must be started before "
+                     "hasReportToUpload is called");
+  dispatch_async(queue_, ^{
+      callback(breakpadRef_ && BreakpadHasCrashReportToUpload(breakpadRef_));
+  });
+}
 
 #pragma mark -
 
diff --git a/src/client/ios/handler/ios_exception_minidump_generator.mm b/src/client/ios/handler/ios_exception_minidump_generator.mm
index b8aebc2..912c431 100644
--- a/src/client/ios/handler/ios_exception_minidump_generator.mm
+++ b/src/client/ios/handler/ios_exception_minidump_generator.mm
@@ -31,7 +31,7 @@
 
 #include "google_breakpad/common/minidump_exception_mac.h"
 #include "client/minidump_file_writer-inl.h"
-#include "processor/scoped_ptr.h"
+#include "common/scoped_ptr.h"
 
 namespace {
 
diff --git a/src/client/linux/crash_generation/crash_generation_server.cc b/src/client/linux/crash_generation/crash_generation_server.cc
index ff89135..f1e16b1 100644
--- a/src/client/linux/crash_generation/crash_generation_server.cc
+++ b/src/client/linux/crash_generation/crash_generation_server.cc
@@ -90,7 +90,7 @@
   }
 
   char* endptr;
-  const u_int64_t inode_ul =
+  const uint64_t inode_ul =
       strtoull(buf + sizeof(kSocketLinkPrefix) - 1, &endptr, 10);
   if (*endptr != ']')
     return false;
diff --git a/src/client/linux/handler/exception_handler.cc b/src/client/linux/handler/exception_handler.cc
index e6265a1..55834e0 100644
--- a/src/client/linux/handler/exception_handler.cc
+++ b/src/client/linux/handler/exception_handler.cc
@@ -415,8 +415,11 @@
 // This is a public interface to HandleSignal that allows the client to
 // generate a crash dump. This function may run in a compromised context.
 bool ExceptionHandler::SimulateSignalDelivery(int sig) {
-  siginfo_t siginfo;
-  my_memset(&siginfo, 0, sizeof(siginfo_t));
+  siginfo_t siginfo = {};
+  // Mimic a trusted signal to allow tracing the process (see
+  // ExceptionHandler::HandleSignal().
+  siginfo.si_code = SI_USER;
+  siginfo.si_pid = getpid();
   struct ucontext context;
   getcontext(&context);
   return HandleSignal(sig, &siginfo, &context);
@@ -594,7 +597,7 @@
 }
 
 void ExceptionHandler::AddMappingInfo(const string& name,
-                                      const u_int8_t identifier[sizeof(MDGUID)],
+                                      const uint8_t identifier[sizeof(MDGUID)],
                                       uintptr_t start_address,
                                       size_t mapping_size,
                                       size_t file_offset) {
diff --git a/src/client/linux/handler/exception_handler.h b/src/client/linux/handler/exception_handler.h
index 7e6f864..7155419 100644
--- a/src/client/linux/handler/exception_handler.h
+++ b/src/client/linux/handler/exception_handler.h
@@ -42,9 +42,9 @@
 #include "client/linux/crash_generation/crash_generation_client.h"
 #include "client/linux/handler/minidump_descriptor.h"
 #include "client/linux/minidump_writer/minidump_writer.h"
+#include "common/scoped_ptr.h"
 #include "common/using_std_string.h"
 #include "google_breakpad/common/minidump_format.h"
-#include "processor/scoped_ptr.h"
 
 namespace google_breakpad {
 
@@ -205,7 +205,7 @@
   // a custom library loader is used that maps things in a way
   // that the linux dumper can't handle by reading the maps file.
   void AddMappingInfo(const string& name,
-                      const u_int8_t identifier[sizeof(MDGUID)],
+                      const uint8_t identifier[sizeof(MDGUID)],
                       uintptr_t start_address,
                       size_t mapping_size,
                       size_t file_offset);
diff --git a/src/client/linux/handler/exception_handler_unittest.cc b/src/client/linux/handler/exception_handler_unittest.cc
index 4b3ec07..0ba5216 100644
--- a/src/client/linux/handler/exception_handler_unittest.cc
+++ b/src/client/linux/handler/exception_handler_unittest.cc
@@ -54,6 +54,27 @@
 
 namespace {
 
+// Flush the instruction cache for a given memory range.
+// Only required on ARM.
+void FlushInstructionCache(const char* memory, uint32_t memory_size) {
+#if defined(__arm__)
+  long begin = reinterpret_cast<long>(memory);
+  long end = begin + static_cast<long>(memory_size);
+# if defined(__ANDROID__)
+  // Provided by Android's <unistd.h>
+  cacheflush(begin, end, 0);
+# elif defined(__linux__)
+  // GLibc/ARM doesn't provide a wrapper for it, do a direct syscall.
+#  ifndef __ARM_NR_cacheflush
+#  define __ARM_NR_cacheflush 0xf0002
+#  endif
+  syscall(__ARM_NR_cacheflush, begin, end, 0);
+# else
+#   error "Your operating system is not supported yet"
+# endif
+#endif
+}
+
 // Length of a formatted GUID string =
 // sizeof(MDGUID) * 2 + 4 (for dashes) + 1 (null terminator)
 const int kGUIDStringSize = 37;
@@ -423,7 +444,7 @@
 
   // These are defined here so the parent can use them to check the
   // data from the minidump afterwards.
-  const u_int32_t kMemorySize = 256;  // bytes
+  const uint32_t kMemorySize = 256;  // bytes
   const int kOffset = kMemorySize / 2;
   // This crashes with SIGILL on x86/x86-64/arm.
   const unsigned char instructions[] = { 0xff, 0xff, 0xff, 0xff };
@@ -449,6 +470,7 @@
     // of the block of memory, because the minidump should contain 128
     // bytes on either side of the instruction pointer.
     memcpy(memory + kOffset, instructions, sizeof(instructions));
+    FlushInstructionCache(memory, kMemorySize);
 
     // Now execute the instructions, which should crash.
     typedef void (*void_function)(void);
@@ -483,7 +505,7 @@
   MinidumpContext* context = exception->GetContext();
   ASSERT_TRUE(context);
 
-  u_int64_t instruction_pointer;
+  uint64_t instruction_pointer;
   ASSERT_TRUE(context->GetInstructionPointer(&instruction_pointer));
 
   MinidumpMemoryRegion* region =
@@ -491,11 +513,11 @@
   ASSERT_TRUE(region);
 
   EXPECT_EQ(kMemorySize, region->GetSize());
-  const u_int8_t* bytes = region->GetMemory();
+  const uint8_t* bytes = region->GetMemory();
   ASSERT_TRUE(bytes);
 
-  u_int8_t prefix_bytes[kOffset];
-  u_int8_t suffix_bytes[kMemorySize - kOffset - sizeof(instructions)];
+  uint8_t prefix_bytes[kOffset];
+  uint8_t suffix_bytes[kMemorySize - kOffset - sizeof(instructions)];
   memset(prefix_bytes, 0, sizeof(prefix_bytes));
   memset(suffix_bytes, 0, sizeof(suffix_bytes));
   EXPECT_TRUE(memcmp(bytes, prefix_bytes, sizeof(prefix_bytes)) == 0);
@@ -515,7 +537,7 @@
 
   // These are defined here so the parent can use them to check the
   // data from the minidump afterwards.
-  const u_int32_t kMemorySize = 256;  // bytes
+  const uint32_t kMemorySize = 256;  // bytes
   const int kOffset = 0;
   // This crashes with SIGILL on x86/x86-64/arm.
   const unsigned char instructions[] = { 0xff, 0xff, 0xff, 0xff };
@@ -541,6 +563,7 @@
     // of the block of memory, because the minidump should contain 128
     // bytes on either side of the instruction pointer.
     memcpy(memory + kOffset, instructions, sizeof(instructions));
+    FlushInstructionCache(memory, kMemorySize);
 
     // Now execute the instructions, which should crash.
     typedef void (*void_function)(void);
@@ -575,7 +598,7 @@
   MinidumpContext* context = exception->GetContext();
   ASSERT_TRUE(context);
 
-  u_int64_t instruction_pointer;
+  uint64_t instruction_pointer;
   ASSERT_TRUE(context->GetInstructionPointer(&instruction_pointer));
 
   MinidumpMemoryRegion* region =
@@ -583,10 +606,10 @@
   ASSERT_TRUE(region);
 
   EXPECT_EQ(kMemorySize / 2, region->GetSize());
-  const u_int8_t* bytes = region->GetMemory();
+  const uint8_t* bytes = region->GetMemory();
   ASSERT_TRUE(bytes);
 
-  u_int8_t suffix_bytes[kMemorySize / 2 - sizeof(instructions)];
+  uint8_t suffix_bytes[kMemorySize / 2 - sizeof(instructions)];
   memset(suffix_bytes, 0, sizeof(suffix_bytes));
   EXPECT_TRUE(memcmp(bytes + kOffset, instructions, sizeof(instructions)) == 0);
   EXPECT_TRUE(memcmp(bytes + kOffset + sizeof(instructions),
@@ -606,7 +629,7 @@
   // Use 4k here because the OS will hand out a single page even
   // if a smaller size is requested, and this test wants to
   // test the upper bound of the memory range.
-  const u_int32_t kMemorySize = 4096;  // bytes
+  const uint32_t kMemorySize = 4096;  // bytes
   // This crashes with SIGILL on x86/x86-64/arm.
   const unsigned char instructions[] = { 0xff, 0xff, 0xff, 0xff };
   const int kOffset = kMemorySize - sizeof(instructions);
@@ -632,6 +655,7 @@
     // of the block of memory, because the minidump should contain 128
     // bytes on either side of the instruction pointer.
     memcpy(memory + kOffset, instructions, sizeof(instructions));
+    FlushInstructionCache(memory, kMemorySize);
 
     // Now execute the instructions, which should crash.
     typedef void (*void_function)(void);
@@ -665,7 +689,7 @@
   MinidumpContext* context = exception->GetContext();
   ASSERT_TRUE(context);
 
-  u_int64_t instruction_pointer;
+  uint64_t instruction_pointer;
   ASSERT_TRUE(context->GetInstructionPointer(&instruction_pointer));
 
   MinidumpMemoryRegion* region =
@@ -674,10 +698,10 @@
 
   const size_t kPrefixSize = 128;  // bytes
   EXPECT_EQ(kPrefixSize + sizeof(instructions), region->GetSize());
-  const u_int8_t* bytes = region->GetMemory();
+  const uint8_t* bytes = region->GetMemory();
   ASSERT_TRUE(bytes);
 
-  u_int8_t prefix_bytes[kPrefixSize];
+  uint8_t prefix_bytes[kPrefixSize];
   memset(prefix_bytes, 0, sizeof(prefix_bytes));
   EXPECT_TRUE(memcmp(bytes, prefix_bytes, sizeof(prefix_bytes)) == 0);
   EXPECT_TRUE(memcmp(bytes + kPrefixSize,
@@ -742,9 +766,9 @@
 TEST(ExceptionHandlerTest, ModuleInfo) {
   // These are defined here so the parent can use them to check the
   // data from the minidump afterwards.
-  const u_int32_t kMemorySize = sysconf(_SC_PAGESIZE);
+  const uint32_t kMemorySize = sysconf(_SC_PAGESIZE);
   const char* kMemoryName = "a fake module";
-  const u_int8_t kModuleGUID[sizeof(MDGUID)] = {
+  const uint8_t kModuleGUID[sizeof(MDGUID)] = {
     0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
     0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF
   };
@@ -889,7 +913,7 @@
   const ssize_t n = HANDLE_EINTR(recvmsg(fds[0], &msg, 0));
   ASSERT_EQ(static_cast<ssize_t>(kCrashContextSize), n);
   ASSERT_EQ(kControlMsgSize, msg.msg_controllen);
-  ASSERT_EQ(0, msg.msg_flags);
+  ASSERT_EQ(static_cast<typeof(msg.msg_flags)>(0), msg.msg_flags);
   ASSERT_EQ(0, close(fds[0]));
 
   pid_t crashing_pid = -1;
@@ -998,15 +1022,15 @@
 
 // Test that an additional memory region can be added to the minidump.
 TEST(ExceptionHandlerTest, AdditionalMemory) {
-  const u_int32_t kMemorySize = sysconf(_SC_PAGESIZE);
+  const uint32_t kMemorySize = sysconf(_SC_PAGESIZE);
 
   // Get some heap memory.
-  u_int8_t* memory = new u_int8_t[kMemorySize];
+  uint8_t* memory = new uint8_t[kMemorySize];
   const uintptr_t kMemoryAddress = reinterpret_cast<uintptr_t>(memory);
   ASSERT_TRUE(memory);
 
   // Stick some data into the memory so the contents can be verified.
-  for (u_int32_t i = 0; i < kMemorySize; ++i) {
+  for (uint32_t i = 0; i < kMemorySize; ++i) {
     memory[i] = i % 255;
   }
 
@@ -1042,10 +1066,10 @@
 // Test that a memory region that was previously registered
 // can be unregistered.
 TEST(ExceptionHandlerTest, AdditionalMemoryRemove) {
-  const u_int32_t kMemorySize = sysconf(_SC_PAGESIZE);
+  const uint32_t kMemorySize = sysconf(_SC_PAGESIZE);
 
   // Get some heap memory.
-  u_int8_t* memory = new u_int8_t[kMemorySize];
+  uint8_t* memory = new uint8_t[kMemorySize];
   const uintptr_t kMemoryAddress = reinterpret_cast<uintptr_t>(memory);
   ASSERT_TRUE(memory);
 
@@ -1109,7 +1133,7 @@
   // Check that the crashing thread is the main thread of |child|
   MinidumpException* exception = minidump.GetException();
   ASSERT_TRUE(exception);
-  u_int32_t thread_id;
+  uint32_t thread_id;
   ASSERT_TRUE(exception->GetThreadID(&thread_id));
   EXPECT_EQ(child, static_cast<int32_t>(thread_id));
 
diff --git a/src/client/linux/handler/minidump_descriptor.cc b/src/client/linux/handler/minidump_descriptor.cc
index 07b70a0..c4618ad 100644
--- a/src/client/linux/handler/minidump_descriptor.cc
+++ b/src/client/linux/handler/minidump_descriptor.cc
@@ -38,7 +38,8 @@
 MinidumpDescriptor::MinidumpDescriptor(const MinidumpDescriptor& descriptor)
     : fd_(descriptor.fd_),
       directory_(descriptor.directory_),
-      c_path_(NULL) {
+      c_path_(NULL),
+      size_limit_(descriptor.size_limit_) {
   // The copy constructor is not allowed to be called on a MinidumpDescriptor
   // with a valid path_, as getting its c_path_ would require the heap which
   // can cause problems in compromised environments.
@@ -57,6 +58,7 @@
     c_path_ = NULL;
     UpdatePath();
   }
+  size_limit_ = descriptor.size_limit_;
   return *this;
 }
 
diff --git a/src/client/linux/handler/minidump_descriptor.h b/src/client/linux/handler/minidump_descriptor.h
index 3036cad..9ffe622 100644
--- a/src/client/linux/handler/minidump_descriptor.h
+++ b/src/client/linux/handler/minidump_descriptor.h
@@ -45,7 +45,7 @@
 
 class MinidumpDescriptor {
  public:
-  MinidumpDescriptor() : fd_(-1) {}
+  MinidumpDescriptor() : fd_(-1), size_limit_(-1) {}
 
   explicit MinidumpDescriptor(const string& directory)
       : fd_(-1),
diff --git a/src/client/linux/minidump_writer/linux_dumper.cc b/src/client/linux/minidump_writer/linux_dumper.cc
index 2124224..6a75ba9 100644
--- a/src/client/linux/minidump_writer/linux_dumper.cc
+++ b/src/client/linux/minidump_writer/linux_dumper.cc
@@ -99,15 +99,14 @@
 
   // Special-case linux-gate because it's not a real file.
   if (my_strcmp(mapping.name, kLinuxGateLibraryName) == 0) {
-    const uintptr_t kPageSize = getpagesize();
     void* linux_gate = NULL;
     if (pid_ == sys_getpid()) {
       linux_gate = reinterpret_cast<void*>(mapping.start_addr);
     } else {
-      linux_gate = allocator_.Alloc(kPageSize);
+      linux_gate = allocator_.Alloc(mapping.size);
       CopyFromProcess(linux_gate, pid_,
                       reinterpret_cast<const void*>(mapping.start_addr),
-                      kPageSize);
+                      mapping.size);
     }
     return FileID::ElfFileIdentifierFromMappedFile(linux_gate, identifier);
   }
diff --git a/src/client/linux/minidump_writer/linux_dumper_unittest_helper.cc b/src/client/linux/minidump_writer/linux_dumper_unittest_helper.cc
index df4ecec..6802069 100644
--- a/src/client/linux/minidump_writer/linux_dumper_unittest_helper.cc
+++ b/src/client/linux/minidump_writer/linux_dumper_unittest_helper.cc
@@ -38,7 +38,7 @@
 #include <sys/syscall.h>
 #include <unistd.h>
 
-#include "processor/scoped_ptr.h"
+#include "common/scoped_ptr.h"
 #include "third_party/lss/linux_syscall_support.h"
 
 #if defined(__ARM_EABI__)
diff --git a/src/client/linux/minidump_writer/minidump_writer.cc b/src/client/linux/minidump_writer/minidump_writer.cc
index 6b6a2c0..34091db 100644
--- a/src/client/linux/minidump_writer/minidump_writer.cc
+++ b/src/client/linux/minidump_writer/minidump_writer.cc
@@ -333,7 +333,7 @@
   out->cpsr = 0;
 #if !defined(__ANDROID__)
   out->float_save.fpscr = info.fpregs.fpsr |
-    (static_cast<u_int64_t>(info.fpregs.fpcr) << 32);
+    (static_cast<uint64_t>(info.fpregs.fpcr) << 32);
   // TODO: sort this out, actually collect floating point registers
   my_memset(&out->float_save.regs, 0, sizeof(out->float_save.regs));
   my_memset(&out->float_save.extra, 0, sizeof(out->float_save.extra));
@@ -535,8 +535,8 @@
   void PopSeccompStackFrame(RawContextCPU* cpu, const MDRawThread& thread,
                             uint8_t* stack_copy) {
 #if defined(__x86_64)
-    u_int64_t bp = cpu->rbp;
-    u_int64_t top = thread.stack.start_of_memory_range;
+    uint64_t bp = cpu->rbp;
+    uint64_t top = thread.stack.start_of_memory_range;
     for (int i = 4; i--; ) {
       if (bp < top ||
           bp + sizeof(bp) > thread.stack.start_of_memory_range +
@@ -546,7 +546,7 @@
       }
       uint64_t old_top = top;
       top = bp;
-      u_int8_t* bp_addr = stack_copy + bp - thread.stack.start_of_memory_range;
+      uint8_t* bp_addr = stack_copy + bp - thread.stack.start_of_memory_range;
       my_memcpy(&bp, bp_addr, sizeof(bp));
       if (bp == 0xDEADBEEFDEADBEEFull) {
         struct {
@@ -598,8 +598,8 @@
       }
     }
 #elif defined(__i386)
-    u_int32_t bp = cpu->ebp;
-    u_int32_t top = thread.stack.start_of_memory_range;
+    uint32_t bp = cpu->ebp;
+    uint32_t top = thread.stack.start_of_memory_range;
     for (int i = 4; i--; ) {
       if (bp < top ||
           bp + sizeof(bp) > thread.stack.start_of_memory_range +
@@ -609,7 +609,7 @@
       }
       uint32_t old_top = top;
       top = bp;
-      u_int8_t* bp_addr = stack_copy + bp - thread.stack.start_of_memory_range;
+      uint8_t* bp_addr = stack_copy + bp - thread.stack.start_of_memory_range;
       my_memcpy(&bp, bp_addr, sizeof(bp));
       if (bp == 0xDEADBEEFu) {
         struct {
@@ -721,7 +721,7 @@
 
         // Copy 256 bytes around crashing instruction pointer to minidump.
         const size_t kIPMemorySize = 256;
-        u_int64_t ip = GetInstructionPointer();
+        uint64_t ip = GetInstructionPointer();
         // Bound it to the upper and lower bounds of the memory map
         // it's contained within. If it's not in mapped memory,
         // don't bother trying to write it.
@@ -921,7 +921,7 @@
                      bool member,
                      unsigned int mapping_id,
                      MDRawModule& mod,
-                     const u_int8_t* identifier) {
+                     const uint8_t* identifier) {
     my_memset(&mod, 0, MD_MODULE_SIZE);
 
     mod.base_of_image = mapping.start_addr;
@@ -1144,11 +1144,10 @@
     debug.get()->ldbase = (void*)debug_entry.r_ldbase;
     debug.get()->dynamic = dynamic;
 
-    char* dso_debug_data = new char[dynamic_length];
-    dumper_->CopyFromProcess(dso_debug_data, GetCrashThread(), dynamic,
+    wasteful_vector<char> dso_debug_data(dumper_->allocator(), dynamic_length);
+    dumper_->CopyFromProcess(&dso_debug_data[0], GetCrashThread(), dynamic,
                              dynamic_length);
-    debug.CopyIndexAfterObject(0, dso_debug_data, dynamic_length);
-    delete[] dso_debug_data;
+    debug.CopyIndexAfterObject(0, &dso_debug_data[0], dynamic_length);
 
     return true;
   }
@@ -1221,9 +1220,11 @@
       bool found;
     } cpu_info_table[] = {
       { "processor", -1, false },
+#if defined(__i386) || defined(__x86_64)
       { "model", 0, false },
       { "stepping",  0, false },
       { "cpu family", 0, false },
+#endif
     };
 
     // processor_architecture should always be set, do this first
@@ -1325,9 +1326,11 @@
     cpu_info_table[0].value++;
 
     sys_info->number_of_processors = cpu_info_table[0].value;
+#if defined(__i386) || defined(__x86_64)
     sys_info->processor_level      = cpu_info_table[3].value;
     sys_info->processor_revision   = cpu_info_table[1].value << 8 |
                                      cpu_info_table[2].value;
+#endif
 
     if (vendor_id[0] != '\0') {
       my_memcpy(sys_info->cpu.x86_cpu_info.vendor_id, vendor_id,
diff --git a/src/client/linux/minidump_writer/minidump_writer.h b/src/client/linux/minidump_writer/minidump_writer.h
index 790ff72..c9e150a 100644
--- a/src/client/linux/minidump_writer/minidump_writer.h
+++ b/src/client/linux/minidump_writer/minidump_writer.h
@@ -46,7 +46,7 @@
 
 struct MappingEntry {
   MappingInfo first;
-  u_int8_t second[sizeof(MDGUID)];
+  uint8_t second[sizeof(MDGUID)];
 };
 
 // A list of <MappingInfo, GUID>
diff --git a/src/client/linux/minidump_writer/minidump_writer_unittest.cc b/src/client/linux/minidump_writer/minidump_writer_unittest.cc
index 1cb0326..7d6b866 100644
--- a/src/client/linux/minidump_writer/minidump_writer_unittest.cc
+++ b/src/client/linux/minidump_writer/minidump_writer_unittest.cc
@@ -46,11 +46,11 @@
 #include "common/linux/file_id.h"
 #include "common/linux/ignore_ret.h"
 #include "common/linux/safe_readlink.h"
+#include "common/scoped_ptr.h"
 #include "common/tests/auto_tempdir.h"
 #include "common/tests/file_utils.h"
 #include "common/using_std_string.h"
 #include "google_breakpad/processor/minidump.h"
-#include "processor/scoped_ptr.h"
 
 using namespace google_breakpad;
 
@@ -131,9 +131,9 @@
 
   // These are defined here so the parent can use them to check the
   // data from the minidump afterwards.
-  const u_int32_t memory_size = sysconf(_SC_PAGESIZE);
+  const uint32_t memory_size = sysconf(_SC_PAGESIZE);
   const char* kMemoryName = "a fake module";
-  const u_int8_t kModuleGUID[sizeof(MDGUID)] = {
+  const uint8_t kModuleGUID[sizeof(MDGUID)] = {
     0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
     0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF
   };
@@ -199,7 +199,7 @@
   // Read the minidump. Load the module list, and ensure that
   // the mmap'ed |memory| is listed with the given module name
   // and debug ID.
-  Minidump minidump(templ.c_str());
+  Minidump minidump(templ);
   ASSERT_TRUE(minidump.Read());
 
   MinidumpModuleList* module_list = minidump.GetModuleList();
@@ -213,7 +213,7 @@
   EXPECT_EQ(kMemoryName, module->code_file());
   EXPECT_EQ(module_identifier, module->debug_identifier());
 
-  u_int32_t len;
+  uint32_t len;
   // These streams are expected to be there
   EXPECT_TRUE(minidump.SeekToStreamType(MD_THREAD_LIST_STREAM, &len));
   EXPECT_TRUE(minidump.SeekToStreamType(MD_MEMORY_LIST_STREAM, &len));
@@ -241,7 +241,7 @@
   // data from the minidump afterwards.
   const int32_t memory_size = sysconf(_SC_PAGESIZE);
   const char* kMemoryName = "a fake module";
-  const u_int8_t kModuleGUID[sizeof(MDGUID)] = {
+  const uint8_t kModuleGUID[sizeof(MDGUID)] = {
     0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
     0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF
   };
@@ -318,7 +318,7 @@
   // Read the minidump. Load the module list, and ensure that
   // the mmap'ed |memory| is listed with the given module name
   // and debug ID.
-  Minidump minidump(dumpfile.c_str());
+  Minidump minidump(dumpfile);
   ASSERT_TRUE(minidump.Read());
 
   MinidumpModuleList* module_list = minidump.GetModuleList();
@@ -400,7 +400,7 @@
   ASSERT_EQ(0, stat(templ.c_str(), &st));
   ASSERT_GT(st.st_size, 0);
 
-  Minidump minidump(templ.c_str());
+  Minidump minidump(templ);
   ASSERT_TRUE(minidump.Read());
 
   // Check that the main module filename is correct.
@@ -435,15 +435,15 @@
 
   // These are defined here so the parent can use them to check the
   // data from the minidump afterwards.
-  const u_int32_t kMemorySize = sysconf(_SC_PAGESIZE);
+  const uint32_t kMemorySize = sysconf(_SC_PAGESIZE);
 
   // Get some heap memory.
-  u_int8_t* memory = new u_int8_t[kMemorySize];
+  uint8_t* memory = new uint8_t[kMemorySize];
   const uintptr_t kMemoryAddress = reinterpret_cast<uintptr_t>(memory);
   ASSERT_TRUE(memory);
 
   // Stick some data into the memory so the contents can be verified.
-  for (u_int32_t i = 0; i < kMemorySize; ++i) {
+  for (uint32_t i = 0; i < kMemorySize; ++i) {
     memory[i] = i % 255;
   }
 
@@ -481,7 +481,7 @@
                             mappings, memory_list));
 
   // Read the minidump. Ensure that the memory region is present
-  Minidump minidump(templ.c_str());
+  Minidump minidump(templ);
   ASSERT_TRUE(minidump.Read());
 
   MinidumpMemoryList* dump_memory_list = minidump.GetMemoryList();
@@ -551,7 +551,7 @@
   ASSERT_TRUE(WriteMinidump(templ.c_str(), child, &context, sizeof(context)));
 
   // Read the minidump. Ensure that the memory region is present
-  Minidump minidump(templ.c_str());
+  Minidump minidump(templ);
   ASSERT_TRUE(minidump.Read());
 
   // TODO(ted.mielczarek,mkrebs): Enable this part of the test once
@@ -652,7 +652,7 @@
     ASSERT_GT(st.st_size, 0);
     normal_file_size = st.st_size;
 
-    Minidump minidump(normal_dump.c_str());
+    Minidump minidump(normal_dump);
     ASSERT_TRUE(minidump.Read());
     MinidumpThreadList* dump_thread_list = minidump.GetThreadList();
     ASSERT_TRUE(dump_thread_list);
@@ -689,9 +689,22 @@
 
   // Third, write a minidump with a size limit small enough to be triggered.
   {
-    // Set size limit to the normal file size minus some arbitrary amount --
-    // enough to make the limiting code kick in.
-    const off_t minidump_size_limit = normal_file_size - 64*1024;
+    // Set size limit to some arbitrary amount, such that the limiting code
+    // will kick in.  The equation used to set this value was determined by
+    // simply reversing the size-limit logic a little bit in order to pick a
+    // size we know will trigger it.  The definition of
+    // kLimitAverageThreadStackLength here was copied from class
+    // MinidumpWriter in minidump_writer.cc.
+    static const unsigned kLimitAverageThreadStackLength = 8 * 1024;
+    off_t minidump_size_limit = kNumberOfThreadsInHelperProgram *
+        kLimitAverageThreadStackLength;
+    // If, in reality, each of the threads' stack is *smaller* than
+    // kLimitAverageThreadStackLength, the normal file size could very well be
+    // smaller than the arbitrary limit that was just set.  In that case,
+    // either of these numbers should trigger the size-limiting code, but we
+    // might as well pick the smallest.
+    if (normal_file_size < minidump_size_limit)
+      minidump_size_limit = normal_file_size;
 
     string limit_dump = temp_dir.path() +
         "/minidump-writer-unittest-limit.dmp";
@@ -701,10 +714,12 @@
     struct stat st;
     ASSERT_EQ(0, stat(limit_dump.c_str(), &st));
     ASSERT_GT(st.st_size, 0);
-    // Make sure the file size is at least smaller than the original.
+    // Make sure the file size is at least smaller than the original.  If this
+    // fails because it's the same size, then the size-limit logic didn't kick
+    // in like it was supposed to.
     EXPECT_LT(st.st_size, normal_file_size);
 
-    Minidump minidump(limit_dump.c_str());
+    Minidump minidump(limit_dump);
     ASSERT_TRUE(minidump.Read());
     MinidumpThreadList* dump_thread_list = minidump.GetThreadList();
     ASSERT_TRUE(dump_thread_list);
@@ -721,6 +736,12 @@
     // Make sure stack size shrunk by at least 1KB per extra thread.  The
     // definition of kLimitBaseThreadCount here was copied from class
     // MinidumpWriter in minidump_writer.cc.
+    // Note: The 1KB is arbitrary, and assumes that the thread stacks are big
+    // enough to shrink by that much.  For example, if each thread stack was
+    // originally only 2KB, the current size-limit logic wouldn't actually
+    // shrink them because that's the size to which it tries to shrink.  If
+    // you fail this part of the test due to something like that, the test
+    // logic should probably be improved to account for your situation.
     const unsigned kLimitBaseThreadCount = 20;
     const unsigned kMinPerExtraThreadStackReduction = 1024;
     const int min_expected_reduction = (kNumberOfThreadsInHelperProgram -
diff --git a/src/client/mac/Framework/Breakpad.mm b/src/client/mac/Framework/Breakpad.mm
index 2817f38..4762516 100644
--- a/src/client/mac/Framework/Breakpad.mm
+++ b/src/client/mac/Framework/Breakpad.mm
@@ -42,8 +42,9 @@
 #import "client/mac/Framework/Breakpad.h"
 
 #import <Foundation/Foundation.h>
-#import <sys/stat.h>
-#import <sys/sysctl.h>
+#include <pthread.h>
+#include <sys/stat.h>
+#include <sys/sysctl.h>
 
 #import "client/mac/crash_generation/Inspector.h"
 #import "client/mac/handler/exception_handler.h"
@@ -53,6 +54,18 @@
 #import "common/mac/MachIPC.h"
 #import "common/mac/SimpleStringDictionary.h"
 
+#ifndef __EXCEPTIONS
+// This file uses C++ try/catch (but shouldn't). Duplicate the macros from
+// <c++/4.2.1/exception_defines.h> allowing this file to work properly with
+// exceptions disabled even when other C++ libraries are used. #undef the try
+// and catch macros first in case libstdc++ is in use and has already provided
+// its own definitions.
+#undef try
+#define try       if (true)
+#undef catch
+#define catch(X)  if (false)
+#endif  // __EXCEPTIONS
+
 using google_breakpad::KeyValueEntry;
 using google_breakpad::MachPortSender;
 using google_breakpad::MachReceiveMessage;
diff --git a/src/client/mac/handler/dynamic_images.cc b/src/client/mac/handler/dynamic_images.cc
index efed388..fbd6dcf 100644
--- a/src/client/mac/handler/dynamic_images.cc
+++ b/src/client/mac/handler/dynamic_images.cc
@@ -41,6 +41,7 @@
 #include <mach/task_info.h>
 #include <sys/sysctl.h>
 #include <TargetConditionals.h>
+#include <unistd.h>
 
 #include <algorithm>
 #include <string>
diff --git a/src/client/mac/handler/exception_handler.cc b/src/client/mac/handler/exception_handler.cc
index c88b680..6862322 100644
--- a/src/client/mac/handler/exception_handler.cc
+++ b/src/client/mac/handler/exception_handler.cc
@@ -27,19 +27,32 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-#include <map>
 #include <mach/exc.h>
 #include <mach/mig.h>
 #include <pthread.h>
 #include <signal.h>
 #include <TargetConditionals.h>
 
+#include <map>
+
 #include "client/mac/handler/exception_handler.h"
 #include "client/mac/handler/minidump_generator.h"
 #include "common/mac/macho_utilities.h"
 #include "common/mac/scoped_task_suspend-inl.h"
 #include "google_breakpad/common/minidump_exception_mac.h"
 
+#ifndef __EXCEPTIONS
+// This file uses C++ try/catch (but shouldn't). Duplicate the macros from
+// <c++/4.2.1/exception_defines.h> allowing this file to work properly with
+// exceptions disabled even when other C++ libraries are used. #undef the try
+// and catch macros first in case libstdc++ is in use and has already provided
+// its own definitions.
+#undef try
+#define try       if (true)
+#undef catch
+#define catch(X)  if (false)
+#endif  // __EXCEPTIONS
+
 #ifndef USE_PROTECTED_ALLOCATIONS
 #if TARGET_OS_IPHONE
 #define USE_PROTECTED_ALLOCATIONS 1
@@ -350,11 +363,14 @@
       // decide if this should be sent.
       if (filter_ && !filter_(callback_context_))
         return false;
-      return crash_generation_client_->RequestDumpForException(
+      result = crash_generation_client_->RequestDumpForException(
           exception_type,
           exception_code,
           exception_subcode,
           thread_name);
+      if (result && exit_after_write) {
+        _exit(exception_type);
+      }
     }
 #endif
   } else {
diff --git a/src/client/mac/handler/exception_handler.h b/src/client/mac/handler/exception_handler.h
index 7babcf6..b5e8bba 100644
--- a/src/client/mac/handler/exception_handler.h
+++ b/src/client/mac/handler/exception_handler.h
@@ -41,7 +41,7 @@
 
 #include <string>
 
-#include "processor/scoped_ptr.h"
+#include "common/scoped_ptr.h"
 
 #if !TARGET_OS_IPHONE
 #include "client/mac/crash_generation/crash_generation_client.h"
diff --git a/src/client/mac/handler/minidump_generator.cc b/src/client/mac/handler/minidump_generator.cc
index fac1a60..85c53eb 100644
--- a/src/client/mac/handler/minidump_generator.cc
+++ b/src/client/mac/handler/minidump_generator.cc
@@ -410,7 +410,7 @@
   }
 }
 
-u_int64_t MinidumpGenerator::CurrentPCForStack(
+uint64_t MinidumpGenerator::CurrentPCForStack(
     breakpad_thread_state_data_t state) {
   switch (cpu_type_) {
 #ifdef HAS_ARM_SUPPORT
@@ -444,7 +444,7 @@
   return WriteStackFromStartAddress(start_addr, stack_location);
 }
 
-u_int64_t
+uint64_t
 MinidumpGenerator::CurrentPCForStackARM(breakpad_thread_state_data_t state) {
   arm_thread_state_t *machine_state =
       reinterpret_cast<arm_thread_state_t *>(state);
@@ -510,7 +510,7 @@
   return WriteStackFromStartAddress(start_addr, stack_location);
 }
 
-u_int64_t
+uint64_t
 MinidumpGenerator::CurrentPCForStackPPC(breakpad_thread_state_data_t state) {
   ppc_thread_state_t *machine_state =
       reinterpret_cast<ppc_thread_state_t *>(state);
@@ -518,7 +518,7 @@
   return REGISTER_FROM_THREADSTATE(machine_state, srr0);
 }
 
-u_int64_t
+uint64_t
 MinidumpGenerator::CurrentPCForStackPPC64(breakpad_thread_state_data_t state) {
   ppc_thread_state64_t *machine_state =
       reinterpret_cast<ppc_thread_state64_t *>(state);
@@ -672,7 +672,7 @@
   return WriteStackFromStartAddress(start_addr, stack_location);
 }
 
-u_int64_t
+uint64_t
 MinidumpGenerator::CurrentPCForStackX86(breakpad_thread_state_data_t state) {
   i386_thread_state_t *machine_state =
       reinterpret_cast<i386_thread_state_t *>(state);
@@ -680,7 +680,7 @@
   return REGISTER_FROM_THREADSTATE(machine_state, eip);
 }
 
-u_int64_t
+uint64_t
 MinidumpGenerator::CurrentPCForStackX86_64(breakpad_thread_state_data_t state) {
   x86_thread_state64_t *machine_state =
       reinterpret_cast<x86_thread_state64_t *>(state);
@@ -764,7 +764,7 @@
   // not used in the flags register.  Since the minidump format
   // specifies 32 bits for the flags register, we can truncate safely
   // with no loss.
-  context_ptr->eflags = static_cast<u_int32_t>(REGISTER_FROM_THREADSTATE(machine_state, rflags));
+  context_ptr->eflags = static_cast<uint32_t>(REGISTER_FROM_THREADSTATE(machine_state, rflags));
   AddReg(cs);
   AddReg(fs);
   AddReg(gs);
@@ -899,7 +899,7 @@
       = static_cast<mach_msg_type_number_t>(sizeof(state));
 
     if (GetThreadState(exception_thread_, state, &stateCount)) {
-      u_int64_t ip = CurrentPCForStack(state);
+      uint64_t ip = CurrentPCForStack(state);
       // Bound it to the upper and lower bounds of the region
       // it's contained within. If it's not in a known memory region,
       // don't bother trying to write it.
@@ -1162,7 +1162,7 @@
       return false;
 
     module->base_of_image = image->GetVMAddr() + image->GetVMAddrSlide();
-    module->size_of_image = static_cast<u_int32_t>(image->GetVMSize());
+    module->size_of_image = static_cast<uint32_t>(image->GetVMSize());
     module->module_name_rva = string_location.rva;
 
     // We'll skip the executable module, because they don't have
@@ -1228,7 +1228,7 @@
             return false;
 
           module->base_of_image = seg->vmaddr + slide;
-          module->size_of_image = static_cast<u_int32_t>(seg->vmsize);
+          module->size_of_image = static_cast<uint32_t>(seg->vmsize);
           module->module_name_rva = string_location.rva;
 
           bool in_memory = false;
@@ -1287,7 +1287,7 @@
 
   size_t module_name_length = strlen(module_name);
 
-  if (!cv.AllocateObjectAndArray(module_name_length + 1, sizeof(u_int8_t)))
+  if (!cv.AllocateObjectAndArray(module_name_length + 1, sizeof(uint8_t)))
     return false;
 
   if (!cv.CopyIndexAfterObject(0, module_name, module_name_length))
@@ -1388,7 +1388,7 @@
   misc_info_stream->location = info.location();
 
   MDRawMiscInfo *info_ptr = info.get();
-  info_ptr->size_of_info = static_cast<u_int32_t>(sizeof(MDRawMiscInfo));
+  info_ptr->size_of_info = static_cast<uint32_t>(sizeof(MDRawMiscInfo));
   info_ptr->flags1 = MD_MISCINFO_FLAGS1_PROCESS_ID |
     MD_MISCINFO_FLAGS1_PROCESS_TIMES |
     MD_MISCINFO_FLAGS1_PROCESSOR_POWER_INFO;
@@ -1401,18 +1401,18 @@
   if (getrusage(RUSAGE_SELF, &usage) != -1) {
     // Omit the fractional time since the MDRawMiscInfo only wants seconds
     info_ptr->process_user_time =
-        static_cast<u_int32_t>(usage.ru_utime.tv_sec);
+        static_cast<uint32_t>(usage.ru_utime.tv_sec);
     info_ptr->process_kernel_time =
-        static_cast<u_int32_t>(usage.ru_stime.tv_sec);
+        static_cast<uint32_t>(usage.ru_stime.tv_sec);
   }
   int mib[4] = { CTL_KERN, KERN_PROC, KERN_PROC_PID,
                  static_cast<int>(info_ptr->process_id) };
-  u_int mibsize = static_cast<u_int>(sizeof(mib) / sizeof(mib[0]));
+  uint mibsize = static_cast<uint>(sizeof(mib) / sizeof(mib[0]));
   struct kinfo_proc proc;
   size_t size = sizeof(proc);
   if (sysctl(mib, mibsize, &proc, &size, NULL, 0) == 0) {
     info_ptr->process_create_time =
-        static_cast<u_int32_t>(proc.kp_proc.p_starttime.tv_sec);
+        static_cast<uint32_t>(proc.kp_proc.p_starttime.tv_sec);
   }
 
   // Speed
@@ -1420,11 +1420,11 @@
   const uint64_t kOneMillion = 1000 * 1000;
   size = sizeof(speed);
   sysctlbyname("hw.cpufrequency_max", &speed, &size, NULL, 0);
-  info_ptr->processor_max_mhz = static_cast<u_int32_t>(speed / kOneMillion);
-  info_ptr->processor_mhz_limit = static_cast<u_int32_t>(speed / kOneMillion);
+  info_ptr->processor_max_mhz = static_cast<uint32_t>(speed / kOneMillion);
+  info_ptr->processor_mhz_limit = static_cast<uint32_t>(speed / kOneMillion);
   size = sizeof(speed);
   sysctlbyname("hw.cpufrequency", &speed, &size, NULL, 0);
-  info_ptr->processor_current_mhz = static_cast<u_int32_t>(speed / kOneMillion);
+  info_ptr->processor_current_mhz = static_cast<uint32_t>(speed / kOneMillion);
 
   return true;
 }
diff --git a/src/client/mac/handler/minidump_generator.h b/src/client/mac/handler/minidump_generator.h
index ef94784..c79873f 100644
--- a/src/client/mac/handler/minidump_generator.h
+++ b/src/client/mac/handler/minidump_generator.h
@@ -130,7 +130,7 @@
   bool WriteBreakpadInfoStream(MDRawDirectory *breakpad_info_stream);
 
   // Helpers
-  u_int64_t CurrentPCForStack(breakpad_thread_state_data_t state);
+  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,
@@ -151,31 +151,31 @@
                      MDMemoryDescriptor *stack_location);
   bool WriteContextARM(breakpad_thread_state_data_t state,
                        MDLocationDescriptor *register_location);
-  u_int64_t CurrentPCForStackARM(breakpad_thread_state_data_t state);
+  uint64_t CurrentPCForStackARM(breakpad_thread_state_data_t state);
 #endif
 #ifdef HAS_PPC_SUPPORT
   bool WriteStackPPC(breakpad_thread_state_data_t state,
                      MDMemoryDescriptor *stack_location);
   bool WriteContextPPC(breakpad_thread_state_data_t state,
                        MDLocationDescriptor *register_location);
-  u_int64_t CurrentPCForStackPPC(breakpad_thread_state_data_t state);
+  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);
-  u_int64_t CurrentPCForStackPPC64(breakpad_thread_state_data_t state);
+  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);
-  u_int64_t CurrentPCForStackX86(breakpad_thread_state_data_t state);
+  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);
-  u_int64_t CurrentPCForStackX86_64(breakpad_thread_state_data_t state);
+  uint64_t CurrentPCForStackX86_64(breakpad_thread_state_data_t state);
 #endif
 
   // disallow copy ctor and operator=
diff --git a/src/client/mac/tests/crash_generation_server_test.cc b/src/client/mac/tests/crash_generation_server_test.cc
index ff8ff78..0164f4a 100644
--- a/src/client/mac/tests/crash_generation_server_test.cc
+++ b/src/client/mac/tests/crash_generation_server_test.cc
@@ -318,7 +318,7 @@
   MD_CPU_ARCHITECTURE_AMD64
 #endif
   ;
-const u_int32_t kExpectedContext =
+const uint32_t kExpectedContext =
 #if defined(__i386__)
   MD_CONTEXT_AMD64
 #elif defined(__x86_64__)
diff --git a/src/client/mac/tests/exception_handler_test.cc b/src/client/mac/tests/exception_handler_test.cc
index 8325d44..d108d43 100644
--- a/src/client/mac/tests/exception_handler_test.cc
+++ b/src/client/mac/tests/exception_handler_test.cc
@@ -277,7 +277,7 @@
 
   // These are defined here so the parent can use them to check the
   // data from the minidump afterwards.
-  const u_int32_t kMemorySize = 256;  // bytes
+  const uint32_t kMemorySize = 256;  // bytes
   const int kOffset = kMemorySize / 2;
   // This crashes with SIGILL on x86/x86-64/arm.
   const unsigned char instructions[] = { 0xff, 0xff, 0xff, 0xff };
@@ -346,7 +346,7 @@
   MinidumpContext* context = exception->GetContext();
   ASSERT_TRUE(context);
 
-  u_int64_t instruction_pointer;
+  uint64_t instruction_pointer;
   ASSERT_TRUE(context->GetInstructionPointer(&instruction_pointer));
 
   MinidumpMemoryRegion* region =
@@ -354,11 +354,11 @@
   EXPECT_TRUE(region);
 
   EXPECT_EQ(kMemorySize, region->GetSize());
-  const u_int8_t* bytes = region->GetMemory();
+  const uint8_t* bytes = region->GetMemory();
   ASSERT_TRUE(bytes);
 
-  u_int8_t prefix_bytes[kOffset];
-  u_int8_t suffix_bytes[kMemorySize - kOffset - sizeof(instructions)];
+  uint8_t prefix_bytes[kOffset];
+  uint8_t suffix_bytes[kMemorySize - kOffset - sizeof(instructions)];
   memset(prefix_bytes, 0, sizeof(prefix_bytes));
   memset(suffix_bytes, 0, sizeof(suffix_bytes));
   EXPECT_TRUE(memcmp(bytes, prefix_bytes, sizeof(prefix_bytes)) == 0);
@@ -376,7 +376,7 @@
 
   // These are defined here so the parent can use them to check the
   // data from the minidump afterwards.
-  const u_int32_t kMemorySize = 256;  // bytes
+  const uint32_t kMemorySize = 256;  // bytes
   const int kOffset = 0;
   // This crashes with SIGILL on x86/x86-64/arm.
   const unsigned char instructions[] = { 0xff, 0xff, 0xff, 0xff };
@@ -445,7 +445,7 @@
   MinidumpContext* context = exception->GetContext();
   ASSERT_TRUE(context);
 
-  u_int64_t instruction_pointer;
+  uint64_t instruction_pointer;
   ASSERT_TRUE(context->GetInstructionPointer(&instruction_pointer));
 
   MinidumpMemoryRegion* region =
@@ -453,10 +453,10 @@
   EXPECT_TRUE(region);
 
   EXPECT_EQ(kMemorySize / 2, region->GetSize());
-  const u_int8_t* bytes = region->GetMemory();
+  const uint8_t* bytes = region->GetMemory();
   ASSERT_TRUE(bytes);
 
-  u_int8_t suffix_bytes[kMemorySize / 2 - sizeof(instructions)];
+  uint8_t suffix_bytes[kMemorySize / 2 - sizeof(instructions)];
   memset(suffix_bytes, 0, sizeof(suffix_bytes));
   EXPECT_TRUE(memcmp(bytes + kOffset, instructions, sizeof(instructions)) == 0);
   EXPECT_TRUE(memcmp(bytes + kOffset + sizeof(instructions),
@@ -475,7 +475,7 @@
   // Use 4k here because the OS will hand out a single page even
   // if a smaller size is requested, and this test wants to
   // test the upper bound of the memory range.
-  const u_int32_t kMemorySize = 4096;  // bytes
+  const uint32_t kMemorySize = 4096;  // bytes
   // This crashes with SIGILL on x86/x86-64/arm.
   const unsigned char instructions[] = { 0xff, 0xff, 0xff, 0xff };
   const int kOffset = kMemorySize - sizeof(instructions);
@@ -544,7 +544,7 @@
   MinidumpContext* context = exception->GetContext();
   ASSERT_TRUE(context);
 
-  u_int64_t instruction_pointer;
+  uint64_t instruction_pointer;
   ASSERT_TRUE(context->GetInstructionPointer(&instruction_pointer));
 
   MinidumpMemoryRegion* region =
@@ -553,10 +553,10 @@
 
   const size_t kPrefixSize = 128;  // bytes
   EXPECT_EQ(kPrefixSize + sizeof(instructions), region->GetSize());
-  const u_int8_t* bytes = region->GetMemory();
+  const uint8_t* bytes = region->GetMemory();
   ASSERT_TRUE(bytes);
 
-  u_int8_t prefix_bytes[kPrefixSize];
+  uint8_t prefix_bytes[kPrefixSize];
   memset(prefix_bytes, 0, sizeof(prefix_bytes));
   EXPECT_TRUE(memcmp(bytes, prefix_bytes, sizeof(prefix_bytes)) == 0);
   EXPECT_TRUE(memcmp(bytes + kPrefixSize,
diff --git a/src/client/mac/tests/minidump_generator_test.cc b/src/client/mac/tests/minidump_generator_test.cc
index b3f8f0a..d40c7d9 100644
--- a/src/client/mac/tests/minidump_generator_test.cc
+++ b/src/client/mac/tests/minidump_generator_test.cc
@@ -280,7 +280,7 @@
   MD_CPU_ARCHITECTURE_AMD64
 #endif
   ;
-const u_int32_t kExpectedContext =
+const uint32_t kExpectedContext =
 #if defined(__i386__)
   MD_CONTEXT_AMD64
 #elif defined(__x86_64__)
diff --git a/src/client/mac/tests/spawn_child_process.h b/src/client/mac/tests/spawn_child_process.h
index bdd293b..e52ff6b 100644
--- a/src/client/mac/tests/spawn_child_process.h
+++ b/src/client/mac/tests/spawn_child_process.h
@@ -65,7 +65,7 @@
 #endif
   ;
 
-const u_int32_t kNativeContext =
+const uint32_t kNativeContext =
 #if defined(__i386__)
   MD_CONTEXT_X86
 #elif defined(__x86_64__)
diff --git a/src/client/minidump_file_writer.cc b/src/client/minidump_file_writer.cc
index c267410..1e18d24 100644
--- a/src/client/minidump_file_writer.cc
+++ b/src/client/minidump_file_writer.cc
@@ -99,11 +99,11 @@
                                               unsigned int length,
                                               TypedMDRVA<MDString> *mdstring) {
   bool result = true;
-  if (sizeof(wchar_t) == sizeof(u_int16_t)) {
+  if (sizeof(wchar_t) == sizeof(uint16_t)) {
     // Shortcut if wchar_t is the same size as MDString's buffer
     result = mdstring->Copy(str, mdstring->get()->length);
   } else {
-    u_int16_t out[2];
+    uint16_t out[2];
     int out_idx = 0;
 
     // Copy the string character by character
@@ -120,7 +120,7 @@
       // zero, but the second one may be zero, depending on the conversion from
       // UTF-32.
       int out_count = out[1] ? 2 : 1;
-      size_t out_size = sizeof(u_int16_t) * out_count;
+      size_t out_size = sizeof(uint16_t) * out_count;
       result = mdstring->CopyIndexAfterObject(out_idx, out, out_size);
       out_idx += out_count;
     }
@@ -132,7 +132,7 @@
                                               unsigned int length,
                                               TypedMDRVA<MDString> *mdstring) {
   bool result = true;
-  u_int16_t out[2];
+  uint16_t out[2];
   int out_idx = 0;
 
   // Copy the string character by character
@@ -147,7 +147,7 @@
 
     // Append the one or two UTF-16 characters
     int out_count = out[1] ? 2 : 1;
-    size_t out_size = sizeof(u_int16_t) * out_count;
+    size_t out_size = sizeof(uint16_t) * out_count;
     result = mdstring->CopyIndexAfterObject(out_idx, out, out_size);
     out_idx += out_count;
   }
@@ -170,17 +170,17 @@
 
   // Allocate the string buffer
   TypedMDRVA<MDString> mdstring(this);
-  if (!mdstring.AllocateObjectAndArray(mdstring_length + 1, sizeof(u_int16_t)))
+  if (!mdstring.AllocateObjectAndArray(mdstring_length + 1, sizeof(uint16_t)))
     return false;
 
   // Set length excluding the NULL and copy the string
   mdstring.get()->length =
-      static_cast<u_int32_t>(mdstring_length * sizeof(u_int16_t));
+      static_cast<uint32_t>(mdstring_length * sizeof(uint16_t));
   bool result = CopyStringToMDString(str, mdstring_length, &mdstring);
 
   // NULL terminate
   if (result) {
-    u_int16_t ch = 0;
+    uint16_t ch = 0;
     result = mdstring.CopyIndexAfterObject(mdstring_length, &ch, sizeof(ch));
 
     if (result)
@@ -211,7 +211,7 @@
   if (!mem.Copy(src, mem.size()))
     return false;
 
-  output->start_of_memory_range = reinterpret_cast<u_int64_t>(src);
+  output->start_of_memory_range = reinterpret_cast<uint64_t>(src);
   output->memory = mem.location();
 
   return true;
diff --git a/src/client/minidump_file_writer.h b/src/client/minidump_file_writer.h
index 313b250..538e854 100644
--- a/src/client/minidump_file_writer.h
+++ b/src/client/minidump_file_writer.h
@@ -172,7 +172,7 @@
 
   // Return size and position
   inline MDLocationDescriptor location() const {
-    MDLocationDescriptor location = { static_cast<u_int32_t>(size_),
+    MDLocationDescriptor location = { static_cast<uint32_t>(size_),
                                       position_ };
     return location;
   }
diff --git a/src/client/solaris/handler/minidump_generator.cc b/src/client/solaris/handler/minidump_generator.cc
index ea046cf..7485025 100644
--- a/src/client/solaris/handler/minidump_generator.cc
+++ b/src/client/solaris/handler/minidump_generator.cc
@@ -455,7 +455,7 @@
   snprintf(path, sizeof(path), "/proc/self/object/%s", module_name);
 
   size_t module_name_length = strlen(realname);
-  if (!cv.AllocateObjectAndArray(module_name_length + 1, sizeof(u_int8_t)))
+  if (!cv.AllocateObjectAndArray(module_name_length + 1, sizeof(uint8_t)))
     return false;
   if (!cv.CopyIndexAfterObject(0, realname, module_name_length))
     return false;
@@ -522,7 +522,7 @@
   if (!callback_context->minidump_writer->WriteString(realname, 0, &loc))
     return false;
 
-  module.base_of_image = (u_int64_t)module_info.start_addr;
+  module.base_of_image = (uint64_t)module_info.start_addr;
   module.size_of_image = module_info.size;
   module.module_name_rva = loc.rva;
 
diff --git a/src/client/windows/build/common.gypi b/src/client/windows/build/common.gypi
index 23122f7..dfd29bd 100644
--- a/src/client/windows/build/common.gypi
+++ b/src/client/windows/build/common.gypi
@@ -199,14 +199,6 @@
     # to ~/.gyp/include.gypi, gclient runhooks --force, and do a release build.
     'win_use_allocator_shim%': 1, # 0 = shim allocator via libcmt; 1 = msvcrt
 
-    # To do a shared build on linux we need to be able to choose between type
-    # static_library and shared_library. We default to doing a static build
-    # but you can override this with "gyp -Dlibrary=shared_library" or you
-    # can add the following line (without the #) to ~/.gyp/include.gypi
-    # {'variables': {'library': 'shared_library'}}
-    # to compile as shared by default
-    'library%': 'static_library',
-
     # Whether usage of OpenMAX is enabled.
     'enable_openmax%': 0,
 
@@ -831,7 +823,7 @@
           'IMPLICIT_COMMAND_DEPENDENCIES': 0,
           # -rpath is only used when building with shared libraries.
           'conditions': [
-            [ 'library=="shared_library"', {
+            [ 'component=="shared_library"', {
               'RPATH': '$LIB_DIR',
             }],
           ],
diff --git a/src/client/windows/crash_generation/client_info.h b/src/client/windows/crash_generation/client_info.h
index a24a82e..ce33a46 100644
--- a/src/client/windows/crash_generation/client_info.h
+++ b/src/client/windows/crash_generation/client_info.h
@@ -33,8 +33,8 @@
 #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"
-#include "processor/scoped_ptr.h"
 
 namespace google_breakpad {
 
diff --git a/src/client/windows/crash_generation/crash_generation.gyp b/src/client/windows/crash_generation/crash_generation.gyp
index ecc82d0..23862d7 100644
--- a/src/client/windows/crash_generation/crash_generation.gyp
+++ b/src/client/windows/crash_generation/crash_generation.gyp
@@ -34,7 +34,7 @@
   'targets': [
     {
       'target_name': 'crash_generation_server',
-      'type': '<(library)',
+      'type': 'static_library',
       'sources': [
         'client_info.cc',
         'crash_generation_server.cc',
@@ -50,7 +50,7 @@
     },
     {
       'target_name': 'crash_generation_client',
-      'type': '<(library)',
+      'type': 'static_library',
       'include_dirs': [
         '<(DEPTH)',
       ],
diff --git a/src/client/windows/crash_generation/crash_generation_client.h b/src/client/windows/crash_generation/crash_generation_client.h
index 2ce14dd..457f731 100644
--- a/src/client/windows/crash_generation/crash_generation_client.h
+++ b/src/client/windows/crash_generation/crash_generation_client.h
@@ -35,7 +35,7 @@
 #include <string>
 #include <utility>
 #include "client/windows/common/ipc_protocol.h"
-#include "processor/scoped_ptr.h"
+#include "common/scoped_ptr.h"
 
 namespace google_breakpad {
 
diff --git a/src/client/windows/crash_generation/crash_generation_server.cc b/src/client/windows/crash_generation/crash_generation_server.cc
index 8f6f986..676dec2 100644
--- a/src/client/windows/crash_generation/crash_generation_server.cc
+++ b/src/client/windows/crash_generation/crash_generation_server.cc
@@ -32,7 +32,7 @@
 #include <cassert>
 #include <list>
 #include "client/windows/common/auto_critical_section.h"
-#include "processor/scoped_ptr.h"
+#include "common/scoped_ptr.h"
 
 #include "client/windows/crash_generation/client_info.h"
 
diff --git a/src/client/windows/crash_generation/crash_generation_server.h b/src/client/windows/crash_generation/crash_generation_server.h
index 3727848..4dcc532 100644
--- a/src/client/windows/crash_generation/crash_generation_server.h
+++ b/src/client/windows/crash_generation/crash_generation_server.h
@@ -34,7 +34,7 @@
 #include <string>
 #include "client/windows/common/ipc_protocol.h"
 #include "client/windows/crash_generation/minidump_generator.h"
-#include "processor/scoped_ptr.h"
+#include "common/scoped_ptr.h"
 
 namespace google_breakpad {
 class ClientInfo;
diff --git a/src/client/windows/crash_generation/minidump_generator.h b/src/client/windows/crash_generation/minidump_generator.h
old mode 100644
new mode 100755
index 5f9e4b5..5a1aea0
--- a/src/client/windows/crash_generation/minidump_generator.h
+++ b/src/client/windows/crash_generation/minidump_generator.h
@@ -32,6 +32,7 @@
 
 #include <windows.h>
 #include <dbghelp.h>
+#include <rpc.h>
 #include <list>
 #include "google_breakpad/common/minidump_format.h"
 
diff --git a/src/client/windows/handler/exception_handler.gyp b/src/client/windows/handler/exception_handler.gyp
index e1e65ee..7729362 100644
--- a/src/client/windows/handler/exception_handler.gyp
+++ b/src/client/windows/handler/exception_handler.gyp
@@ -34,7 +34,7 @@
   'targets': [
     {
       'target_name': 'exception_handler',
-      'type': '<(library)',
+      'type': 'static_library',
       'sources': [
         "exception_handler.cc",
         "exception_handler.h",
diff --git a/src/client/windows/handler/exception_handler.h b/src/client/windows/handler/exception_handler.h
index c1945e1..ec9aabc 100644
--- a/src/client/windows/handler/exception_handler.h
+++ b/src/client/windows/handler/exception_handler.h
@@ -71,8 +71,8 @@
 
 #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"
-#include "processor/scoped_ptr.h"
 
 namespace google_breakpad {
 
diff --git a/src/client/windows/sender/crash_report_sender.gyp b/src/client/windows/sender/crash_report_sender.gyp
index 0c2421d..e4db3a8 100644
--- a/src/client/windows/sender/crash_report_sender.gyp
+++ b/src/client/windows/sender/crash_report_sender.gyp
@@ -34,7 +34,7 @@
   'targets': [
     {
       'target_name': 'crash_report_sender',
-      'type': '<(library)',
+      'type': 'static_library',
       'sources': [
         'crash_report_sender.cc',
         'crash_report_sender.h',
diff --git a/src/client/windows/unittests/exception_handler_death_test.cc b/src/client/windows/unittests/exception_handler_death_test.cc
index 9d6acbc..c4cb993 100644
--- a/src/client/windows/unittests/exception_handler_death_test.cc
+++ b/src/client/windows/unittests/exception_handler_death_test.cc
@@ -265,7 +265,7 @@
   testing::DisableExceptionHandlerInScope disable_exception_handler;
 
   // Get some executable memory.
-  const u_int32_t kMemorySize = 256;  // bytes
+  const uint32_t kMemorySize = 256;  // bytes
   const int kOffset = kMemorySize / 2;
   // This crashes with SIGILL on x86/x86-64/arm.
   const unsigned char instructions[] = { 0xff, 0xff, 0xff, 0xff };
@@ -314,7 +314,7 @@
     MinidumpContext* context = exception->GetContext();
     ASSERT_TRUE(context);
 
-    u_int64_t instruction_pointer;
+    uint64_t instruction_pointer;
     ASSERT_TRUE(context->GetInstructionPointer(&instruction_pointer));
 
     MinidumpMemoryRegion* region =
@@ -322,11 +322,11 @@
     ASSERT_TRUE(region);
 
     EXPECT_EQ(kMemorySize, region->GetSize());
-    const u_int8_t* bytes = region->GetMemory();
+    const uint8_t* bytes = region->GetMemory();
     ASSERT_TRUE(bytes);
 
-    u_int8_t prefix_bytes[kOffset];
-    u_int8_t suffix_bytes[kMemorySize - kOffset - sizeof(instructions)];
+    uint8_t prefix_bytes[kOffset];
+    uint8_t suffix_bytes[kMemorySize - kOffset - sizeof(instructions)];
     memset(prefix_bytes, 0, sizeof(prefix_bytes));
     memset(suffix_bytes, 0, sizeof(suffix_bytes));
     EXPECT_TRUE(memcmp(bytes, prefix_bytes, sizeof(prefix_bytes)) == 0);
@@ -352,7 +352,7 @@
   SYSTEM_INFO sSysInfo;         // Useful information about the system
   GetSystemInfo(&sSysInfo);     // Initialize the structure.
 
-  const u_int32_t kMemorySize = 256;  // bytes
+  const uint32_t kMemorySize = 256;  // bytes
   const DWORD kPageSize = sSysInfo.dwPageSize;
   const int kOffset = 0;
   // This crashes with SIGILL on x86/x86-64/arm.
@@ -407,7 +407,7 @@
     MinidumpContext* context = exception->GetContext();
     ASSERT_TRUE(context);
 
-    u_int64_t instruction_pointer;
+    uint64_t instruction_pointer;
     ASSERT_TRUE(context->GetInstructionPointer(&instruction_pointer));
 
     MinidumpMemoryRegion* region =
@@ -415,10 +415,10 @@
     ASSERT_TRUE(region);
 
     EXPECT_EQ(kMemorySize / 2, region->GetSize());
-    const u_int8_t* bytes = region->GetMemory();
+    const uint8_t* bytes = region->GetMemory();
     ASSERT_TRUE(bytes);
 
-    u_int8_t suffix_bytes[kMemorySize / 2 - sizeof(instructions)];
+    uint8_t suffix_bytes[kMemorySize / 2 - sizeof(instructions)];
     memset(suffix_bytes, 0, sizeof(suffix_bytes));
     EXPECT_TRUE(memcmp(bytes + kOffset,
                        instructions, sizeof(instructions)) == 0);
@@ -492,7 +492,7 @@
     MinidumpContext* context = exception->GetContext();
     ASSERT_TRUE(context);
 
-    u_int64_t instruction_pointer;
+    uint64_t instruction_pointer;
     ASSERT_TRUE(context->GetInstructionPointer(&instruction_pointer));
 
     MinidumpMemoryRegion* region =
@@ -501,10 +501,10 @@
 
     const size_t kPrefixSize = 128;  // bytes
     EXPECT_EQ(kPrefixSize + sizeof(instructions), region->GetSize());
-    const u_int8_t* bytes = region->GetMemory();
+    const uint8_t* bytes = region->GetMemory();
     ASSERT_TRUE(bytes);
 
-    u_int8_t prefix_bytes[kPrefixSize];
+    uint8_t prefix_bytes[kPrefixSize];
     memset(prefix_bytes, 0, sizeof(prefix_bytes));
     EXPECT_TRUE(memcmp(bytes, prefix_bytes, sizeof(prefix_bytes)) == 0);
     EXPECT_TRUE(memcmp(bytes + kPrefixSize,
diff --git a/src/client/windows/unittests/exception_handler_test.cc b/src/client/windows/unittests/exception_handler_test.cc
index be9397b..7b50e30 100644
--- a/src/client/windows/unittests/exception_handler_test.cc
+++ b/src/client/windows/unittests/exception_handler_test.cc
@@ -397,15 +397,15 @@
 TEST_F(ExceptionHandlerTest, AdditionalMemory) {
   SYSTEM_INFO si;
   GetSystemInfo(&si);
-  const u_int32_t kMemorySize = si.dwPageSize;
+  const uint32_t kMemorySize = si.dwPageSize;
 
   // Get some heap memory.
-  u_int8_t* memory = new u_int8_t[kMemorySize];
+  uint8_t* memory = new uint8_t[kMemorySize];
   const uintptr_t kMemoryAddress = reinterpret_cast<uintptr_t>(memory);
   ASSERT_TRUE(memory);
 
   // Stick some data into the memory so the contents can be verified.
-  for (u_int32_t i = 0; i < kMemorySize; ++i) {
+  for (uint32_t i = 0; i < kMemorySize; ++i) {
     memory[i] = i % 255;
   }
 
@@ -451,15 +451,15 @@
 TEST_F(ExceptionHandlerTest, AdditionalMemoryRemove) {
   SYSTEM_INFO si;
   GetSystemInfo(&si);
-  const u_int32_t kMemorySize = si.dwPageSize;
+  const uint32_t kMemorySize = si.dwPageSize;
 
   // Get some heap memory.
-  u_int8_t* memory = new u_int8_t[kMemorySize];
+  uint8_t* memory = new uint8_t[kMemorySize];
   const uintptr_t kMemoryAddress = reinterpret_cast<uintptr_t>(memory);
   ASSERT_TRUE(memory);
 
   // Stick some data into the memory so the contents can be verified.
-  for (u_int32_t i = 0; i < kMemorySize; ++i) {
+  for (uint32_t i = 0; i < kMemorySize; ++i) {
     memory[i] = i % 255;
   }
 
diff --git a/src/client/windows/unittests/testing.gyp b/src/client/windows/unittests/testing.gyp
index 8585428..3234f46 100644
--- a/src/client/windows/unittests/testing.gyp
+++ b/src/client/windows/unittests/testing.gyp
@@ -36,7 +36,7 @@
   'targets': [
     {
       'target_name': 'gtest',
-      'type': '<(library)',
+      'type': 'static_library',
       'include_dirs': [
         '<(DEPTH)/testing/include',
         '<(DEPTH)/testing/gtest',
@@ -49,12 +49,17 @@
         'include_dirs': [
           '<(DEPTH)/testing/include',
           '<(DEPTH)/testing/gtest/include',
-        ]
+        ],
+        # Visual C++ implements variadic templates strangely, and
+        # VC++2012 broke Google Test by lowering this value. See
+        # http://stackoverflow.com/questions/12558327/google-test-in-visual-studio-2012
+        'defines': ['_VARIADIC_MAX=10'],
       },
+      'defines': ['_VARIADIC_MAX=10'],
     },
     {
       'target_name': 'gmock',
-      'type': '<(library)',
+      'type': 'static_library',
       'include_dirs': [
         '<(DEPTH)/testing/include',
         '<(DEPTH)/testing/',
@@ -69,8 +74,10 @@
         'include_dirs': [
           '<(DEPTH)/testing/include',
           '<(DEPTH)/testing/gtest/include',
-        ]
+        ],
+        'defines': ['_VARIADIC_MAX=10'],
       },
+      'defines': ['_VARIADIC_MAX=10'],
     },
 
   ],
diff --git a/src/common/android/breakpad_getcontext_unittest.cc b/src/common/android/breakpad_getcontext_unittest.cc
index 004390c..3bafb9a 100644
--- a/src/common/android/breakpad_getcontext_unittest.cc
+++ b/src/common/android/breakpad_getcontext_unittest.cc
@@ -36,11 +36,13 @@
 #ifdef __arm__
   // There is no gregs[] array on ARM, so compare to the offset of
   // first register fields, since they're stored in order.
-  ASSERT_EQ(MCONTEXT_GREGS_OFFSET, offsetof(ucontext_t,uc_mcontext.arm_r0));
+  ASSERT_EQ(static_cast<size_t>(MCONTEXT_GREGS_OFFSET),
+            offsetof(ucontext_t,uc_mcontext.arm_r0));
 #elif defined(__i386__)
-  ASSERT_EQ(MCONTEXT_GREGS_OFFSET, offsetof(ucontext_t,uc_mcontext.gregs));
+  ASSERT_EQ(static_cast<size_t>(MCONTEXT_GREGS_OFFSET),
+            offsetof(ucontext_t,uc_mcontext.gregs));
 #define CHECK_REG(x) \
-  ASSERT_EQ(MCONTEXT_##x##_OFFSET, \
+  ASSERT_EQ(static_cast<size_t>(MCONTEXT_##x##_OFFSET),         \
             offsetof(ucontext_t,uc_mcontext.gregs[REG_##x]))
   CHECK_REG(GS);
   CHECK_REG(FS);
@@ -62,15 +64,18 @@
   CHECK_REG(UESP);
   CHECK_REG(SS);
 
-  ASSERT_EQ(UCONTEXT_FPREGS_OFFSET, offsetof(ucontext_t,uc_mcontext.fpregs));
+  ASSERT_EQ(static_cast<size_t>(UCONTEXT_FPREGS_OFFSET),
+            offsetof(ucontext_t,uc_mcontext.fpregs));
 
-  ASSERT_EQ(UCONTEXT_FPREGS_MEM_OFFSET,
+  ASSERT_EQ(static_cast<size_t>(UCONTEXT_FPREGS_MEM_OFFSET),
             offsetof(ucontext_t,__fpregs_mem));
 #else
-  ASSERT_EQ(MCONTEXT_GREGS_OFFSET, offsetof(ucontext_t,uc_mcontext.gregs));
+  ASSERT_EQ(static_cast<size_t>(MCONTEXT_GREGS_OFFSET),
+            offsetof(ucontext_t,uc_mcontext.gregs));
 #endif
 }
 
 TEST(AndroidUContext, SigmakOffset) {
-  ASSERT_EQ(UCONTEXT_SIGMASK_OFFSET, offsetof(ucontext_t,uc_sigmask));
+  ASSERT_EQ(static_cast<size_t>(UCONTEXT_SIGMASK_OFFSET),
+            offsetof(ucontext_t,uc_sigmask));
 }
diff --git a/src/common/android/testing/mkdtemp.h b/src/common/android/testing/mkdtemp.h
index 063e356..85644c9 100644
--- a/src/common/android/testing/mkdtemp.h
+++ b/src/common/android/testing/mkdtemp.h
@@ -57,7 +57,7 @@
   const size_t kSuffixLen = strlen(kSuffix);
   char* path_end = path + strlen(path);
 
-  if (path_end - path < kSuffixLen ||
+  if (static_cast<size_t>(path_end - path) < kSuffixLen ||
       memcmp(path_end - kSuffixLen, kSuffix, kSuffixLen) != 0) {
     errno = EINVAL;
     return NULL;
diff --git a/src/common/dwarf/cfi_assembler.cc b/src/common/dwarf/cfi_assembler.cc
index a6a5aca..dbc2efa 100644
--- a/src/common/dwarf/cfi_assembler.cc
+++ b/src/common/dwarf/cfi_assembler.cc
@@ -41,10 +41,10 @@
 
 using dwarf2reader::DwarfPointerEncoding;
   
-CFISection &CFISection::CIEHeader(u_int64_t code_alignment_factor,
+CFISection &CFISection::CIEHeader(uint64_t code_alignment_factor,
                                   int data_alignment_factor,
                                   unsigned return_address_register,
-                                  u_int8_t version,
+                                  uint8_t version,
                                   const string &augmentation,
                                   bool dwarf64) {
   assert(!entry_length_);
@@ -73,8 +73,8 @@
 }
 
 CFISection &CFISection::FDEHeader(Label cie_pointer,
-                                  u_int64_t initial_location,
-                                  u_int64_t address_range,
+                                  uint64_t initial_location,
+                                  uint64_t address_range,
                                   bool dwarf64) {
   assert(!entry_length_);
   entry_length_ = new PendingLength();
@@ -117,7 +117,7 @@
   return *this;
 }
 
-CFISection &CFISection::EncodedPointer(u_int64_t address,
+CFISection &CFISection::EncodedPointer(uint64_t address,
                                        DwarfPointerEncoding encoding,
                                        const EncodedPointerBases &bases) {
   // Omitted data is extremely easy to emit.
@@ -131,7 +131,7 @@
 
   // Find the base address to which this pointer is relative. The upper
   // nybble of the encoding specifies this.
-  u_int64_t base;
+  uint64_t base;
   switch (encoding & 0xf0) {
     case dwarf2reader::DW_EH_PE_absptr:  base = 0;                  break;
     case dwarf2reader::DW_EH_PE_pcrel:   base = bases.cfi + Size(); break;
@@ -189,10 +189,10 @@
   return *this;
 };
 
-const u_int32_t CFISection::kDwarf64InitialLengthMarker;
-const u_int32_t CFISection::kDwarf32CIEIdentifier;
-const u_int64_t CFISection::kDwarf64CIEIdentifier;
-const u_int32_t CFISection::kEHFrame32CIEIdentifier;
-const u_int64_t CFISection::kEHFrame64CIEIdentifier;
+const uint32_t CFISection::kDwarf64InitialLengthMarker;
+const uint32_t CFISection::kDwarf32CIEIdentifier;
+const uint64_t CFISection::kDwarf64CIEIdentifier;
+const uint32_t CFISection::kEHFrame32CIEIdentifier;
+const uint64_t CFISection::kEHFrame64CIEIdentifier;
 
 } // namespace google_breakpad
diff --git a/src/common/dwarf/cfi_assembler.h b/src/common/dwarf/cfi_assembler.h
index 00ff6f0..227812b 100644
--- a/src/common/dwarf/cfi_assembler.h
+++ b/src/common/dwarf/cfi_assembler.h
@@ -80,14 +80,14 @@
     // 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.
-    u_int64_t cfi;
+    uint64_t cfi;
 
     // The starting address of this file's .text section, for DW_EH_PE_textrel.
-    u_int64_t text;
+    uint64_t text;
 
     // The starting address of this file's .got or .eh_frame_hdr section,
     // for DW_EH_PE_datarel.
-    u_int64_t data;
+    uint64_t data;
   };
 
   // Create a CFISection whose endianness is ENDIANNESS, and where
@@ -133,10 +133,10 @@
   // 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(u_int64_t code_alignment_factor,
+  CFISection &CIEHeader(uint64_t code_alignment_factor,
                         int data_alignment_factor,
                         unsigned return_address_register,
-                        u_int8_t version = 3,
+                        uint8_t version = 3,
                         const string &augmentation = "",
                         bool dwarf64 = false);
 
@@ -151,8 +151,8 @@
   // value.) Nor does it support .debug_frame sections longer than
   // 0xffffff00 bytes.
   CFISection &FDEHeader(Label cie_pointer,
-                        u_int64_t initial_location,
-                        u_int64_t address_range,
+                        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
@@ -171,7 +171,7 @@
 
   // Append ADDRESS to this section, in the appropriate size and
   // endianness. Return a reference to this section.
-  CFISection &Address(u_int64_t address) {
+  CFISection &Address(uint64_t address) {
     Section::Append(endianness(), address_size_, address);
     return *this;
   }
@@ -189,26 +189,26 @@
   // 
   // (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(u_int64_t address) {
+  CFISection &EncodedPointer(uint64_t address) {
     return EncodedPointer(address, pointer_encoding_, encoded_pointer_bases_);
   }
-  CFISection &EncodedPointer(u_int64_t address, DwarfPointerEncoding encoding) {
+  CFISection &EncodedPointer(uint64_t address, DwarfPointerEncoding encoding) {
     return EncodedPointer(address, encoding, encoded_pointer_bases_);
   }
-  CFISection &EncodedPointer(u_int64_t address, DwarfPointerEncoding encoding,
+  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(u_int8_t v)       { Section::D8(v);       return *this; }
-  CFISection &D16(u_int16_t v)     { Section::D16(v);      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(u_int32_t v)     { Section::D32(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(u_int64_t v)     { Section::D64(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(u_int64_t v) { Section::ULEB128(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
@@ -224,13 +224,13 @@
   // 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 u_int32_t kDwarf64InitialLengthMarker = 0xffffffffU;
+  static const uint32_t kDwarf64InitialLengthMarker = 0xffffffffU;
 
   // The CIE identifier for 32- and 64-bit DWARF CFI and .eh_frame data.
-  static const u_int32_t kDwarf32CIEIdentifier = ~(u_int32_t)0;
-  static const u_int64_t kDwarf64CIEIdentifier = ~(u_int64_t)0;
-  static const u_int32_t kEHFrame32CIEIdentifier = 0;
-  static const u_int64_t kEHFrame64CIEIdentifier = 0;
+  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_;
@@ -261,7 +261,7 @@
 
   // If in_fde_ is true, this is its starting address. We use this for
   // emitting DW_EH_PE_funcrel pointers.
-  u_int64_t fde_start_address_;
+  uint64_t fde_start_address_;
 };
 
 }  // namespace google_breakpad
diff --git a/src/common/dwarf/dwarf2diehandler.cc b/src/common/dwarf/dwarf2diehandler.cc
index c741d69..20c15fa 100644
--- a/src/common/dwarf/dwarf2diehandler.cc
+++ b/src/common/dwarf/dwarf2diehandler.cc
@@ -57,8 +57,7 @@
                                              dwarf_version);
 }
 
-bool DIEDispatcher::StartDIE(uint64 offset, enum DwarfTag tag,
-                             const AttributeList& attrs) {
+bool DIEDispatcher::StartDIE(uint64 offset, enum DwarfTag tag) {
   // The stack entry for the parent of this DIE, if there is one.
   HandlerStack *parent = die_handlers_.empty() ? NULL : &die_handlers_.top();
 
@@ -82,7 +81,7 @@
   if (parent) {
     if (parent->handler_)
       // Ask the parent to find a handler.
-      handler = parent->handler_->FindChildHandler(offset, tag, attrs);
+      handler = parent->handler_->FindChildHandler(offset, tag);
     else
       // No parent handler means we're not interested in any of our
       // children.
@@ -92,7 +91,7 @@
     // decides whether to visit it, but the root DIE has no parent
     // handler, so we have a special method on the root DIE handler
     // itself to decide.
-    if (root_handler_->StartRootDIE(offset, tag, attrs))
+    if (root_handler_->StartRootDIE(offset, tag))
       handler = root_handler_;
     else
       handler = NULL;
diff --git a/src/common/dwarf/dwarf2diehandler.h b/src/common/dwarf/dwarf2diehandler.h
index 12b8d3a..81f40f0 100644
--- a/src/common/dwarf/dwarf2diehandler.h
+++ b/src/common/dwarf/dwarf2diehandler.h
@@ -239,12 +239,10 @@
   // that child DIE (and all its descendants).
   //
   // OFFSET is the offset of the child; TAG indicates what kind of DIE
-  // it is; and ATTRS is the list of attributes the DIE will have, and
-  // their forms (their values are not provided).
+  // it is.
   //
   // The default definition skips all children.
-  virtual DIEHandler *FindChildHandler(uint64 offset, enum DwarfTag tag,
-                                       const AttributeList &attrs) {
+  virtual DIEHandler *FindChildHandler(uint64 offset, enum DwarfTag tag) {
     return NULL;
   }
 
@@ -280,8 +278,7 @@
   // unit.
   //
   // The default definition elects to visit the root DIE.
-  virtual bool StartRootDIE(uint64 offset, enum DwarfTag tag,
-                            const AttributeList& attrs) { return true; }
+  virtual bool StartRootDIE(uint64 offset, enum DwarfTag tag) { return true; }
 };
 
 class DIEDispatcher: public Dwarf2Handler {
@@ -296,8 +293,7 @@
   bool StartCompilationUnit(uint64 offset, uint8 address_size,
                             uint8 offset_size, uint64 cu_length,
                             uint8 dwarf_version);
-  bool StartDIE(uint64 offset, enum DwarfTag tag,
-                const AttributeList &attrs);
+  bool StartDIE(uint64 offset, enum DwarfTag tag);
   void ProcessAttributeUnsigned(uint64 offset,
                                 enum DwarfAttribute attr,
                                 enum DwarfForm form,
diff --git a/src/common/dwarf/dwarf2diehandler_unittest.cc b/src/common/dwarf/dwarf2diehandler_unittest.cc
index 6a73119..c0a532a 100644
--- a/src/common/dwarf/dwarf2diehandler_unittest.cc
+++ b/src/common/dwarf/dwarf2diehandler_unittest.cc
@@ -51,7 +51,6 @@
 using ::testing::Sequence;
 using ::testing::StrEq;
 
-using dwarf2reader::AttributeList;
 using dwarf2reader::DIEDispatcher;
 using dwarf2reader::DIEHandler;
 using dwarf2reader::DwarfAttribute;
@@ -74,8 +73,7 @@
   MOCK_METHOD3(ProcessAttributeSignature,
                void(DwarfAttribute, DwarfForm, uint64));
   MOCK_METHOD0(EndAttributes, bool());
-  MOCK_METHOD3(FindChildHandler, DIEHandler *(uint64, DwarfTag,
-                                              const AttributeList &));
+  MOCK_METHOD2(FindChildHandler, DIEHandler *(uint64, DwarfTag));
   MOCK_METHOD0(Finish, void());
 };
 
@@ -94,11 +92,10 @@
   MOCK_METHOD3(ProcessAttributeSignature,
                void(DwarfAttribute, DwarfForm, uint64));
   MOCK_METHOD0(EndAttributes, bool());
-  MOCK_METHOD3(FindChildHandler, DIEHandler *(uint64, DwarfTag,
-                                              const AttributeList &));
+  MOCK_METHOD2(FindChildHandler, DIEHandler *(uint64, DwarfTag));
   MOCK_METHOD0(Finish, void());
   MOCK_METHOD5(StartCompilationUnit, bool(uint64, uint8, uint8, uint64, uint8));
-  MOCK_METHOD3(StartRootDIE, bool(uint64, DwarfTag, const AttributeList &));
+  MOCK_METHOD2(StartRootDIE, bool(uint64, DwarfTag));
 };
 
 // If the handler elects to skip the compilation unit, the dispatcher
@@ -129,18 +126,13 @@
   MockRootDIEHandler mock_root_handler;
   DIEDispatcher die_dispatcher(&mock_root_handler);
 
-  AttributeList mock_attribute_list;
-  mock_attribute_list.push_back(make_pair(dwarf2reader::DW_AT_name,
-                                          dwarf2reader::DW_FORM_string));
-
   EXPECT_CALL(mock_root_handler,
               StartCompilationUnit(0xde8994029fc8b999LL, 0xf4, 0x02,
                                    0xb00febffa76e2b2bLL, 0x5c))
       .InSequence(s)
       .WillOnce(Return(true));
   EXPECT_CALL(mock_root_handler,
-              StartRootDIE(0x7d08242b4b510cf2LL, (DwarfTag) 0xb4f98da6,
-                           ContainerEq(mock_attribute_list)))
+              StartRootDIE(0x7d08242b4b510cf2LL, (DwarfTag) 0xb4f98da6))
       .InSequence(s)
       .WillOnce(Return(false));
 
@@ -148,8 +140,7 @@
                                                   0xf4, 0x02,
                                                   0xb00febffa76e2b2bLL, 0x5c));
   EXPECT_FALSE(die_dispatcher.StartDIE(0x7d08242b4b510cf2LL,
-                                       (DwarfTag) 0xb4f98da6,
-                                       mock_attribute_list));
+                                       (DwarfTag) 0xb4f98da6));
   die_dispatcher.EndDIE(0x7d08242b4b510cf2LL);
 }
 
@@ -160,8 +151,6 @@
   MockRootDIEHandler mock_root_handler;
   DIEDispatcher die_dispatcher(&mock_root_handler);
 
-  AttributeList mock_attribute_list;
-
   {
     InSequence s;
 
@@ -170,8 +159,7 @@
                                      0x09f8bf0767f91675LL, 0xdb))
       .WillOnce(Return(true));
     EXPECT_CALL(mock_root_handler,
-                StartRootDIE(0x7d08242b4b510cf2LL, (DwarfTag) 0xb4f98da6,
-                             ContainerEq(mock_attribute_list)))
+                StartRootDIE(0x7d08242b4b510cf2LL, (DwarfTag) 0xb4f98da6))
       .WillOnce(Return(true));
     // Please don't tell me about my children.
     EXPECT_CALL(mock_root_handler, EndAttributes())
@@ -184,11 +172,9 @@
                                                   0x26, 0xa0,
                                                   0x09f8bf0767f91675LL, 0xdb));
   EXPECT_TRUE(die_dispatcher.StartDIE(0x7d08242b4b510cf2LL,
-                                      (DwarfTag) 0xb4f98da6,
-                                      mock_attribute_list));
+                                      (DwarfTag) 0xb4f98da6));
   EXPECT_FALSE(die_dispatcher.StartDIE(0x435150ceedccda18LL,
-                                       (DwarfTag) 0xc3a17bba,
-                                       mock_attribute_list));
+                                       (DwarfTag) 0xc3a17bba));
   die_dispatcher.EndDIE(0x435150ceedccda18LL);
   die_dispatcher.EndDIE(0x7d08242b4b510cf2LL);
 }
@@ -199,9 +185,6 @@
   MockRootDIEHandler mock_root_handler;
   DIEDispatcher die_dispatcher(&mock_root_handler);
 
-  AttributeList mock_attribute_list;
-  mock_attribute_list.push_back(make_pair(dwarf2reader::DW_AT_name,
-                                          dwarf2reader::DW_FORM_string));
   const char buffer[10] = { 0x24, 0x24, 0x35, 0x9a, 0xca,
                             0xcf, 0xa8, 0x84, 0xa7, 0x18 };
   string str = "\xc8\x26\x2e\x0d\xa4\x9c\x37\xd6\xfb\x1d";
@@ -218,8 +201,7 @@
 
     // We'll like the root DIE.
     EXPECT_CALL(mock_root_handler,
-                StartRootDIE(0xe2222da01e29f2a9LL, (DwarfTag) 0x9829445c,
-                             ContainerEq(mock_attribute_list)))
+                StartRootDIE(0xe2222da01e29f2a9LL, (DwarfTag) 0x9829445c))
       .WillOnce(Return(true));
 
     // Expect some attribute values.
@@ -255,7 +237,7 @@
       .WillOnce(Return());
     EXPECT_CALL(mock_root_handler, EndAttributes())
       .WillOnce(Return(true));
-    EXPECT_CALL(mock_root_handler, FindChildHandler(_, _, _))
+    EXPECT_CALL(mock_root_handler, FindChildHandler(_, _))
       .Times(0);
     EXPECT_CALL(mock_root_handler, Finish())
       .WillOnce(Return());
@@ -270,8 +252,7 @@
                                                   0x66));
   // Report the root DIE.
   EXPECT_TRUE(die_dispatcher.StartDIE(0xe2222da01e29f2a9LL,
-                                      (DwarfTag) 0x9829445c,
-                                      mock_attribute_list));
+                                      (DwarfTag) 0x9829445c));
 
   // Report some attribute values.
   die_dispatcher.ProcessAttributeUnsigned(0xe2222da01e29f2a9LL,
@@ -309,25 +290,6 @@
   MockDIEHandler *mock_child3_handler = new(MockDIEHandler);
   DIEDispatcher die_dispatcher(&mock_root_handler);
 
-  AttributeList root_attribute_list;
-  root_attribute_list.push_back(make_pair((DwarfAttribute) 0xb01185df,
-                                          (DwarfForm) 0xbc97cee8));
-  AttributeList child1_attribute_list;
-  child1_attribute_list.push_back(make_pair((DwarfAttribute) 0x41014e43,
-                                            (DwarfForm) 0x63155f4c));
-  AttributeList grandchild1_attribute_list;
-  grandchild1_attribute_list.push_back(make_pair((DwarfAttribute) 0xf72f823c,
-                                                 (DwarfForm) 0x0ff6a201));
-  AttributeList greatgrandchild1_attribute_list;
-  greatgrandchild1_attribute_list
-    .push_back(make_pair((DwarfAttribute) 0xbe66e5f0, (DwarfForm) 0xb4b24ff7));
-  AttributeList child2_attribute_list;
-  child1_attribute_list.push_back(make_pair((DwarfAttribute) 0xf22df14c,
-                                            (DwarfForm) 0x20676e7d));
-  AttributeList child3_attribute_list;
-  child3_attribute_list.push_back(make_pair((DwarfAttribute) 0xe8bf1201,
-                                            (DwarfForm) 0x53a5b7a8));
-
   {
     InSequence s;
 
@@ -340,8 +302,7 @@
     // Root DIE.
     {
       EXPECT_CALL(mock_root_handler,
-                  StartRootDIE(0x15f0e06bdfe3c372LL, (DwarfTag) 0xf5d60c59,
-                               ContainerEq(root_attribute_list)))
+                  StartRootDIE(0x15f0e06bdfe3c372LL, (DwarfTag) 0xf5d60c59))
         .WillOnce(Return(true));
       EXPECT_CALL(mock_root_handler,
                   ProcessAttributeSigned((DwarfAttribute) 0xf779a642,
@@ -354,8 +315,7 @@
       // First child DIE.
       EXPECT_CALL(mock_root_handler,
                   FindChildHandler(0x149f644f8116fe8cLL,
-                                   (DwarfTag) 0xac2cbd8c,
-                                   ContainerEq(child1_attribute_list)))
+                                   (DwarfTag) 0xac2cbd8c))
         .WillOnce(Return(mock_child1_handler));
       {
         EXPECT_CALL(*mock_child1_handler,
@@ -374,15 +334,13 @@
       // for this child.
       EXPECT_CALL(mock_root_handler,
                   FindChildHandler(0x97412be24875de9dLL,
-                                   (DwarfTag) 0x505a068b,
-                                   ContainerEq(child2_attribute_list)))
+                                   (DwarfTag) 0x505a068b))
         .WillOnce(Return((DIEHandler *) NULL));
 
       // Third child DIE.
       EXPECT_CALL(mock_root_handler,
                   FindChildHandler(0x753c964c8ab538aeLL,
-                                   (DwarfTag) 0x8c22970e,
-                                   ContainerEq(child3_attribute_list)))
+                                   (DwarfTag) 0x8c22970e))
         .WillOnce(Return(mock_child3_handler));
       {
         EXPECT_CALL(*mock_child3_handler,
@@ -411,8 +369,7 @@
   // Report the root DIE.
   {
     EXPECT_TRUE(die_dispatcher.StartDIE(0x15f0e06bdfe3c372LL,
-                                        (DwarfTag) 0xf5d60c59,
-                                        root_attribute_list));
+                                        (DwarfTag) 0xf5d60c59));
     die_dispatcher.ProcessAttributeSigned(0x15f0e06bdfe3c372LL,
                                           (DwarfAttribute) 0xf779a642,
                                           (DwarfForm) 0x2cb63027,
@@ -421,8 +378,7 @@
     // First child DIE.
     {
       EXPECT_TRUE(die_dispatcher.StartDIE(0x149f644f8116fe8cLL,
-                                          (DwarfTag) 0xac2cbd8c,
-                                          child1_attribute_list));
+                                          (DwarfTag) 0xac2cbd8c));
       die_dispatcher.ProcessAttributeSigned(0x149f644f8116fe8cLL,
                                             (DwarfAttribute) 0xa6fd6f65,
                                             (DwarfForm) 0xe4f64c41,
@@ -431,15 +387,13 @@
       // First grandchild DIE.  Will be skipped.
       {
         EXPECT_FALSE(die_dispatcher.StartDIE(0xd68de1ee0bd29419LL,
-                                            (DwarfTag) 0x22f05a15,
-                                            grandchild1_attribute_list));
+                                            (DwarfTag) 0x22f05a15));
         // First great-grandchild DIE.  Will be skipped without being
         // mentioned to any handler.
         {
           EXPECT_FALSE(die_dispatcher
                        .StartDIE(0xb3076285d25cac25LL,
-                                 (DwarfTag) 0xcff4061b,
-                                 greatgrandchild1_attribute_list));
+                                 (DwarfTag) 0xcff4061b));
           die_dispatcher.EndDIE(0xb3076285d25cac25LL);          
         }
         die_dispatcher.EndDIE(0xd68de1ee0bd29419LL);
@@ -450,16 +404,14 @@
     // Second child DIE.  Root handler will decline to find a handler for it.
     {
       EXPECT_FALSE(die_dispatcher.StartDIE(0x97412be24875de9dLL,
-                                           (DwarfTag) 0x505a068b,
-                                           child2_attribute_list));
+                                           (DwarfTag) 0x505a068b));
       die_dispatcher.EndDIE(0x97412be24875de9dLL);
     }
     
     // Third child DIE.
     {
       EXPECT_TRUE(die_dispatcher.StartDIE(0x753c964c8ab538aeLL,
-                                          (DwarfTag) 0x8c22970e,
-                                          child3_attribute_list));
+                                          (DwarfTag) 0x8c22970e));
       die_dispatcher.ProcessAttributeSigned(0x753c964c8ab538aeLL,
                                             (DwarfAttribute) 0x4e2b7cfb,
                                             (DwarfForm) 0x610b7ae1,
@@ -478,7 +430,6 @@
   MockRootDIEHandler mock_root_handler;
   MockDIEHandler *mock_child_handler = new(MockDIEHandler);
   MockDIEHandler *mock_grandchild_handler = new(MockDIEHandler);
-  AttributeList empty_attribute_list;
 
   {
     InSequence s;
@@ -492,8 +443,7 @@
     // Root DIE.
     {
       EXPECT_CALL(mock_root_handler,
-                  StartRootDIE(0xbf13b761691ddc91LL, (DwarfTag) 0x98980361,
-                               ContainerEq(empty_attribute_list)))
+                  StartRootDIE(0xbf13b761691ddc91LL, (DwarfTag) 0x98980361))
         .WillOnce(Return(true));
       EXPECT_CALL(mock_root_handler, EndAttributes())
         .WillOnce(Return(true));
@@ -501,8 +451,7 @@
       // Child DIE.
       EXPECT_CALL(mock_root_handler,
                   FindChildHandler(0x058f09240c5fc8c9LL,
-                                   (DwarfTag) 0x898bf0d0,
-                                   ContainerEq(empty_attribute_list)))
+                                   (DwarfTag) 0x898bf0d0))
         .WillOnce(Return(mock_child_handler));
       {
         EXPECT_CALL(*mock_child_handler, EndAttributes())
@@ -511,8 +460,7 @@
         // Grandchild DIE.
         EXPECT_CALL(*mock_child_handler,
                     FindChildHandler(0x32dc00c9945dc0c8LL,
-                                     (DwarfTag) 0x2802d007,
-                                     ContainerEq(empty_attribute_list)))
+                                     (DwarfTag) 0x2802d007))
           .WillOnce(Return(mock_grandchild_handler));
         {
           EXPECT_CALL(*mock_grandchild_handler,
@@ -548,20 +496,17 @@
   // Report the root DIE.
   {
     EXPECT_TRUE(die_dispatcher.StartDIE(0xbf13b761691ddc91LL,
-                                        (DwarfTag) 0x98980361,
-                                        empty_attribute_list));
+                                        (DwarfTag) 0x98980361));
 
     // Child DIE.
     {
       EXPECT_TRUE(die_dispatcher.StartDIE(0x058f09240c5fc8c9LL,
-                                          (DwarfTag) 0x898bf0d0,
-                                          empty_attribute_list));
+                                          (DwarfTag) 0x898bf0d0));
 
       // Grandchild DIE.
       {
         EXPECT_TRUE(die_dispatcher.StartDIE(0x32dc00c9945dc0c8LL,
-                                            (DwarfTag) 0x2802d007,
-                                            empty_attribute_list));
+                                            (DwarfTag) 0x2802d007));
         die_dispatcher.ProcessAttributeSigned(0x32dc00c9945dc0c8LL,
                                               (DwarfAttribute) 0x4e2b7cfb,
                                               (DwarfForm) 0x610b7ae1,
diff --git a/src/common/dwarf/dwarf2reader.cc b/src/common/dwarf/dwarf2reader.cc
index 7c1a29d..f1a07f0 100644
--- a/src/common/dwarf/dwarf2reader.cc
+++ b/src/common/dwarf/dwarf2reader.cc
@@ -500,7 +500,7 @@
 
     const Abbrev& abbrev = abbrevs_->at(static_cast<size_t>(abbrev_num));
     const enum DwarfTag tag = abbrev.tag;
-    if (!handler_->StartDIE(absolute_offset, tag, abbrev.attributes)) {
+    if (!handler_->StartDIE(absolute_offset, tag)) {
       dieptr = SkipDIE(dieptr, abbrev);
     } else {
       dieptr = ProcessDIE(absolute_offset, dieptr, abbrev);
diff --git a/src/common/dwarf/dwarf2reader.h b/src/common/dwarf/dwarf2reader.h
index ecf4eb2..8824bf9 100644
--- a/src/common/dwarf/dwarf2reader.h
+++ b/src/common/dwarf/dwarf2reader.h
@@ -342,8 +342,7 @@
 
   // Start to process a DIE at OFFSET from the beginning of the .debug_info
   // section. Return false if you would like to skip this DIE.
-  virtual bool StartDIE(uint64 offset, enum DwarfTag tag,
-                        const AttributeList& attrs) { return false; }
+  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
diff --git a/src/common/dwarf/dwarf2reader_cfi_unittest.cc b/src/common/dwarf/dwarf2reader_cfi_unittest.cc
index 7b79436..66c6198 100644
--- a/src/common/dwarf/dwarf2reader_cfi_unittest.cc
+++ b/src/common/dwarf/dwarf2reader_cfi_unittest.cc
@@ -2326,14 +2326,14 @@
         alignment(1), entry_size(0) { }
   Label name;
   unsigned int type;
-  u_int64_t flags;
-  u_int64_t address;
+  uint64_t flags;
+  uint64_t address;
   Label file_offset;
   Label file_size;
   unsigned int link;
   unsigned int info;
-  u_int64_t alignment;
-  u_int64_t entry_size;
+  uint64_t alignment;
+  uint64_t entry_size;
 };
 
 void AppendSectionHeader(CFISection *table, const ELFSectionHeader &header) {
diff --git a/src/common/dwarf/dwarf2reader_die_unittest.cc b/src/common/dwarf/dwarf2reader_die_unittest.cc
index 96e95b7..4e34436 100644
--- a/src/common/dwarf/dwarf2reader_die_unittest.cc
+++ b/src/common/dwarf/dwarf2reader_die_unittest.cc
@@ -50,7 +50,6 @@
 using google_breakpad::test_assembler::kBigEndian;
 using google_breakpad::test_assembler::kLittleEndian;
 
-using dwarf2reader::AttributeList;
 using dwarf2reader::ByteReader;
 using dwarf2reader::CompilationUnit;
 using dwarf2reader::Dwarf2Handler;
@@ -76,8 +75,7 @@
   MOCK_METHOD5(StartCompilationUnit, bool(uint64 offset, uint8 address_size,
                                           uint8 offset_size, uint64 cu_length,
                                           uint8 dwarf_version));
-  MOCK_METHOD3(StartDIE, bool(uint64 offset, enum DwarfTag tag,
-                              const AttributeList& attrs));
+  MOCK_METHOD2(StartDIE, bool(uint64 offset, enum DwarfTag tag));
   MOCK_METHOD4(ProcessAttributeUnsigned, void(uint64 offset,
                                               DwarfAttribute attr,
                                               enum DwarfForm form,
@@ -115,7 +113,7 @@
 
     // Default expectations for the data handler.
     EXPECT_CALL(handler, StartCompilationUnit(_, _, _, _, _)).Times(0);
-    EXPECT_CALL(handler, StartDIE(_, _, _)).Times(0);
+    EXPECT_CALL(handler, StartDIE(_, _)).Times(0);
     EXPECT_CALL(handler, ProcessAttributeUnsigned(_, _, _, _)).Times(0);
     EXPECT_CALL(handler, ProcessAttributeSigned(_, _, _, _)).Times(0);
     EXPECT_CALL(handler, ProcessAttributeReference(_, _, _, _)).Times(0);
@@ -186,7 +184,7 @@
                                      GetParam().format_size, _,
                                      GetParam().version))
         .WillOnce(Return(true));
-    EXPECT_CALL(handler, StartDIE(_, dwarf2reader::DW_TAG_compile_unit, _))
+    EXPECT_CALL(handler, StartDIE(_, dwarf2reader::DW_TAG_compile_unit))
         .WillOnce(Return(true));
     EXPECT_CALL(handler, ProcessAttributeString(_, dwarf2reader::DW_AT_name, 
                                                 dwarf2reader::DW_FORM_string,
@@ -262,7 +260,7 @@
                                      params.version))
         .InSequence(s)
         .WillOnce(Return(true));
-    EXPECT_CALL(handler, StartDIE(_, tag, _))
+    EXPECT_CALL(handler, StartDIE(_, tag))
         .InSequence(s)
         .WillOnce(Return(true));
   }
@@ -291,7 +289,7 @@
   StartSingleAttributeDIE(GetParam(), dwarf2reader::DW_TAG_compile_unit,
                           dwarf2reader::DW_AT_low_pc,
                           dwarf2reader::DW_FORM_addr);
-  u_int64_t value;
+  uint64_t value;
   if (GetParam().address_size == 4) {
     value = 0xc8e9ffcc;
     info.D32(value);
@@ -374,7 +372,7 @@
   StartSingleAttributeDIE(GetParam(), (DwarfTag) 0x1d971689,
                           (DwarfAttribute) 0xa060bfd1,
                           dwarf2reader::DW_FORM_sec_offset);
-  u_int64_t value;
+  uint64_t value;
   if (GetParam().format_size == 4) {
     value = 0xacc9c388;
     info.D32(value);
diff --git a/src/common/dwarf/dwarf2reader_test_common.h b/src/common/dwarf/dwarf2reader_test_common.h
index e46931a..e91de90 100644
--- a/src/common/dwarf/dwarf2reader_test_common.h
+++ b/src/common/dwarf/dwarf2reader_test_common.h
@@ -97,7 +97,7 @@
 
   // The offset of the point in the compilation unit header immediately
   // after the initial length field.
-  u_int64_t post_length_offset_;
+  uint64_t post_length_offset_;
 
   // The length of the compilation unit, not including the initial length field.
   Label length_;
diff --git a/src/common/dwarf/functioninfo.cc b/src/common/dwarf/functioninfo.cc
index c045622..8e4d041 100644
--- a/src/common/dwarf/functioninfo.cc
+++ b/src/common/dwarf/functioninfo.cc
@@ -36,10 +36,10 @@
 #include <map>
 #include <queue>
 #include <vector>
-#include <memory>
 
 #include "common/dwarf/functioninfo.h"
 #include "common/dwarf/bytereader.h"
+#include "common/scoped_ptr.h"
 #include "common/using_std_string.h"
 
 namespace dwarf2reader {
@@ -99,11 +99,11 @@
                        std::make_pair(files_->at(file_num).name.c_str(),
                                       line_num)));
 
-    if(address < files_->at(file_num).lowpc) {
+    if (address < files_->at(file_num).lowpc) {
       files_->at(file_num).lowpc = address;
     }
   } else {
-    fprintf(stderr,"error in AddLine");
+    fprintf(stderr, "error in AddLine");
   }
 }
 
@@ -121,8 +121,7 @@
 // subroutines. For line info, the DW_AT_stmt_list lives in the
 // compile unit tag.
 
-bool CUFunctionInfoHandler::StartDIE(uint64 offset, enum DwarfTag tag,
-                                     const AttributeList& attrs) {
+bool CUFunctionInfoHandler::StartDIE(uint64 offset, enum DwarfTag tag) {
   switch (tag) {
     case DW_TAG_subprogram:
     case DW_TAG_inlined_subroutine: {
@@ -152,7 +151,7 @@
   if (current_function_info_) {
     if (attr == DW_AT_name)
       current_function_info_->name = data;
-    else if(attr == DW_AT_MIPS_linkage_name)
+    else if (attr == DW_AT_MIPS_linkage_name)
       current_function_info_->mangled_name = data;
   }
 }
@@ -165,10 +164,9 @@
     SectionMap::const_iterator iter = sections_.find("__debug_line");
     assert(iter != sections_.end());
 
-    // this should be a scoped_ptr but we dont' use boost :-(
-    std::auto_ptr<LineInfo> lireader(new LineInfo(iter->second.first + data,
-                                                  iter->second.second  - data,
-                                                  reader_, linehandler_));
+    scoped_ptr<LineInfo> lireader(new LineInfo(iter->second.first + data,
+                                               iter->second.second  - data,
+                                               reader_, linehandler_));
     lireader->Start();
   } else if (current_function_info_) {
     switch (attr) {
@@ -209,7 +207,10 @@
           current_function_info_->mangled_name = iter->second->mangled_name;
         } else {
           // If you hit this, this code probably needs to be rewritten.
-          fprintf(stderr, "Error: DW_AT_specification was seen before the referenced DIE! (Looking for DIE at offset %08llx, in DIE at offset %08llx)\n", data, offset);
+          fprintf(stderr,
+                  "Error: DW_AT_specification was seen before the referenced "
+                  "DIE! (Looking for DIE at offset %08llx, in DIE at "
+                  "offset %08llx)\n", data, offset);
         }
         break;
       }
diff --git a/src/common/dwarf/functioninfo.h b/src/common/dwarf/functioninfo.h
index f870636..0b08a5f 100644
--- a/src/common/dwarf/functioninfo.h
+++ b/src/common/dwarf/functioninfo.h
@@ -135,8 +135,7 @@
 
   // 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,
-                        const AttributeList& attrs);
+  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
diff --git a/src/common/dwarf_cu_to_module.cc b/src/common/dwarf_cu_to_module.cc
index 1f1a174..a8b0a29 100644
--- a/src/common/dwarf_cu_to_module.cc
+++ b/src/common/dwarf_cu_to_module.cc
@@ -39,7 +39,9 @@
 #include "common/dwarf_cu_to_module.h"
 
 #include <assert.h>
+#if !defined(__ANDROID__)
 #include <cxxabi.h>
+#endif
 #include <inttypes.h>
 #include <stdio.h>
 
@@ -54,6 +56,7 @@
 using std::map;
 using std::pair;
 using std::set;
+using std::sort;
 using std::vector;
 
 // Data provided by a DWARF specification DIE.
@@ -313,7 +316,10 @@
       name_attribute_ = AddStringToPool(data);
       break;
     case dwarf2reader::DW_AT_MIPS_linkage_name: {
-      char* demangled = abi::__cxa_demangle(data.c_str(), NULL, NULL, NULL);
+      char* demangled = NULL;
+#if !defined(__ANDROID__)
+      demangled = abi::__cxa_demangle(data.c_str(), NULL, NULL, NULL);
+#endif
       if (demangled) {
         demangled_name_ = AddStringToPool(demangled);
         free(reinterpret_cast<void*>(demangled));
@@ -385,7 +391,8 @@
   FuncHandler(CUContext *cu_context, DIEContext *parent_context,
               uint64 offset)
       : GenericDIEHandler(cu_context, parent_context, offset),
-        low_pc_(0), high_pc_(0), abstract_origin_(NULL), inline_(false) { }
+        low_pc_(0), high_pc_(0), high_pc_form_(dwarf2reader::DW_FORM_addr),
+        abstract_origin_(NULL), inline_(false) { }
   void ProcessAttributeUnsigned(enum DwarfAttribute attr,
                                 enum DwarfForm form,
                                 uint64 data);
@@ -404,6 +411,7 @@
   // specification_, parent_context_.  Computed in EndAttributes.
   string name_;
   uint64 low_pc_, high_pc_; // DW_AT_low_pc, DW_AT_high_pc
+  DwarfForm high_pc_form_; // DW_AT_high_pc can be length or address.
   const AbstractOrigin* abstract_origin_;
   bool inline_;
 };
@@ -419,7 +427,11 @@
     case dwarf2reader::DW_AT_inline:      inline_  = true; break;
 
     case dwarf2reader::DW_AT_low_pc:      low_pc_  = data; break;
-    case dwarf2reader::DW_AT_high_pc:     high_pc_ = data; break;
+    case dwarf2reader::DW_AT_high_pc:
+      high_pc_form_ = form;
+      high_pc_ = data;
+      break;
+
     default:
       GenericDIEHandler::ProcessAttributeUnsigned(attr, form, data);
       break;
@@ -473,6 +485,11 @@
 }
 
 void DwarfCUToModule::FuncHandler::Finish() {
+  // Make high_pc_ an address, if it isn't already.
+  if (high_pc_form_ != dwarf2reader::DW_FORM_addr) {
+    high_pc_ += low_pc_;
+  }
+
   // Did we collect the information we need?  Not all DWARF function
   // entries have low and high addresses (for example, inlined
   // functions that were never used), but all the ones we're
@@ -511,8 +528,7 @@
                     uint64 offset)
       : GenericDIEHandler(cu_context, parent_context, offset) { }
   bool EndAttributes();
-  DIEHandler *FindChildHandler(uint64 offset, enum DwarfTag tag,
-                               const AttributeList &attrs);
+  DIEHandler *FindChildHandler(uint64 offset, enum DwarfTag tag);
 
  private:
   DIEContext child_context_; // A context for our children.
@@ -525,8 +541,7 @@
 
 dwarf2reader::DIEHandler *DwarfCUToModule::NamedScopeHandler::FindChildHandler(
     uint64 offset,
-    enum DwarfTag tag,
-    const AttributeList &/*attrs*/) {
+    enum DwarfTag tag) {
   switch (tag) {
     case dwarf2reader::DW_TAG_subprogram:
       return new FuncHandler(cu_context_, &child_context_, offset);
@@ -614,7 +629,7 @@
 }
 
 DwarfCUToModule::DwarfCUToModule(FileContext *file_context,
-                                 LineToModuleFunctor *line_reader,
+                                 LineToModuleHandler *line_reader,
                                  WarningReporter *reporter)
     : line_reader_(line_reader), has_source_line_info_(false) { 
   cu_context_ = new CUContext(file_context, reporter);
@@ -657,8 +672,16 @@
 void DwarfCUToModule::ProcessAttributeString(enum DwarfAttribute attr,
                                              enum DwarfForm form,
                                              const string &data) {
-  if (attr == dwarf2reader::DW_AT_name)
-    cu_context_->reporter->SetCUName(data);
+  switch (attr) {
+    case dwarf2reader::DW_AT_name:
+      cu_context_->reporter->SetCUName(data);
+      break;
+    case dwarf2reader::DW_AT_comp_dir:
+      line_reader_->StartCompilationUnit(data);
+      break;
+    default:
+      break;
+  }
 }
 
 bool DwarfCUToModule::EndAttributes() {
@@ -667,8 +690,7 @@
 
 dwarf2reader::DIEHandler *DwarfCUToModule::FindChildHandler(
     uint64 offset,
-    enum DwarfTag tag,
-    const AttributeList &/*attrs*/) {
+    enum DwarfTag tag) {
   switch (tag) {
     case dwarf2reader::DW_TAG_subprogram:
       return new FuncHandler(cu_context_, child_context_, offset);
@@ -736,8 +758,8 @@
     cu_context_->reporter->BadLineInfoOffset(offset);
     return;
   }
-  (*line_reader_)(section_start + offset, section_length - offset,
-                  cu_context_->file_context->module, &lines_);
+  line_reader_->ReadProgram(section_start + offset, section_length - offset,
+                            cu_context_->file_context->module, &lines_);
 }
 
 namespace {
@@ -767,9 +789,9 @@
   // complexity from here on out is linear.
 
   // Put both our functions and lines in order by address.
-  sort(functions->begin(), functions->end(),
-       Module::Function::CompareByAddress);
-  sort(lines_.begin(), lines_.end(), Module::Line::CompareByAddress);
+  std::sort(functions->begin(), functions->end(),
+            Module::Function::CompareByAddress);
+  std::sort(lines_.begin(), lines_.end(), Module::Line::CompareByAddress);
 
   // The last line that we used any piece of.  We use this only for
   // generating warnings.
@@ -978,8 +1000,7 @@
   return dwarf_version >= 2;
 }
 
-bool DwarfCUToModule::StartRootDIE(uint64 offset, enum DwarfTag tag,
-                                   const AttributeList& /*attrs*/) {
+bool DwarfCUToModule::StartRootDIE(uint64 offset, enum DwarfTag tag) {
   // We don't deal with partial compilation units (the only other tag
   // likely to be used for root DIE).
   return tag == dwarf2reader::DW_TAG_compile_unit;
diff --git a/src/common/dwarf_cu_to_module.h b/src/common/dwarf_cu_to_module.h
index ac62846..8545331 100644
--- a/src/common/dwarf_cu_to_module.h
+++ b/src/common/dwarf_cu_to_module.h
@@ -50,7 +50,6 @@
 
 namespace google_breakpad {
 
-using dwarf2reader::AttributeList;
 using dwarf2reader::DwarfAttribute;
 using dwarf2reader::DwarfForm;
 using dwarf2reader::DwarfLanguage;
@@ -93,21 +92,27 @@
     FilePrivate *file_private;
   };
 
-  // An abstract base class for functors that handle DWARF line data
+  // An abstract base class for handlers that handle DWARF line data
   // for DwarfCUToModule. DwarfCUToModule could certainly just use
   // dwarf2reader::LineInfo itself directly, but decoupling things
   // this way makes unit testing a little easier.
-  class LineToModuleFunctor {
+  class LineToModuleHandler {
    public:
-    LineToModuleFunctor() { }
-    virtual ~LineToModuleFunctor() { }
+    LineToModuleHandler() { }
+    virtual ~LineToModuleHandler() { }
+
+    // Called at the beginning of a new compilation unit, prior to calling
+    // ReadProgram(). compilation_dir will indicate the path that the
+    // current compilation unit was compiled in, consistent with the
+    // DW_AT_comp_dir DIE.
+    virtual void StartCompilationUnit(const string& compilation_dir) = 0;
 
     // Populate MODULE and LINES with source file names and code/line
     // mappings, given a pointer to some DWARF line number data
     // PROGRAM, and an overestimate of its size. Add no zero-length
     // lines to LINES.
-    virtual void operator()(const char *program, uint64 length,
-                            Module *module, vector<Module::Line> *lines) = 0;
+    virtual void ReadProgram(const char *program, uint64 length,
+                             Module *module, vector<Module::Line> *lines) = 0;
   };
 
   // The interface DwarfCUToModule uses to report warnings. The member
@@ -187,7 +192,7 @@
   // unit's line number data. Use REPORTER to report problems with the
   // data we find.
   DwarfCUToModule(FileContext *file_context,
-                  LineToModuleFunctor *line_reader,
+                  LineToModuleHandler *line_reader,
                   WarningReporter *reporter);
   ~DwarfCUToModule();
 
@@ -201,8 +206,7 @@
                               enum DwarfForm form,
                               const string &data);
   bool EndAttributes();
-  DIEHandler *FindChildHandler(uint64 offset, enum DwarfTag tag,
-                               const AttributeList &attrs);
+  DIEHandler *FindChildHandler(uint64 offset, enum DwarfTag tag);
 
   // Assign all our source Lines to the Functions that cover their
   // addresses, and then add them to module_.
@@ -211,8 +215,7 @@
   bool StartCompilationUnit(uint64 offset, uint8 address_size,
                             uint8 offset_size, uint64 cu_length,
                             uint8 dwarf_version);
-  bool StartRootDIE(uint64 offset, enum DwarfTag tag,
-                    const AttributeList& attrs);
+  bool StartRootDIE(uint64 offset, enum DwarfTag tag);
 
  private:
 
@@ -250,8 +253,8 @@
   // owned by this DwarfCUToModule: the constructor sets them, and the
   // destructor deletes them.
 
-  // The functor to use to handle line number data.
-  LineToModuleFunctor *line_reader_;
+  // The handler to use to handle line number data.
+  LineToModuleHandler *line_reader_;
 
   // This compilation unit's context.
   CUContext *cu_context_;
diff --git a/src/common/dwarf_cu_to_module_unittest.cc b/src/common/dwarf_cu_to_module_unittest.cc
index 377630e..81e629b 100644
--- a/src/common/dwarf_cu_to_module_unittest.cc
+++ b/src/common/dwarf_cu_to_module_unittest.cc
@@ -42,7 +42,6 @@
 using std::make_pair;
 using std::vector;
 
-using dwarf2reader::AttributeList;
 using dwarf2reader::DIEHandler;
 using dwarf2reader::DwarfTag;
 using dwarf2reader::DwarfAttribute;
@@ -63,14 +62,11 @@
 
 // Mock classes.
 
-class MockLineToModuleFunctor: public DwarfCUToModule::LineToModuleFunctor {
+class MockLineToModuleHandler: public DwarfCUToModule::LineToModuleHandler {
  public:
-  MOCK_METHOD4(mock_apply, void(const char *program, uint64 length,
-                                Module *module, vector<Module::Line> *lines));
-  void operator()(const char *program, uint64 length,
-                  Module *module, vector<Module::Line> *lines) {
-    mock_apply(program, length, module, lines);
-  }
+  MOCK_METHOD1(StartCompilationUnit, void(const string& compilation_dir));
+  MOCK_METHOD4(ReadProgram, void(const char* program, uint64 length,
+                                 Module *module, vector<Module::Line> *lines));
 };
 
 class MockWarningReporter: public DwarfCUToModule::WarningReporter {
@@ -103,10 +99,10 @@
   //   appender(line_program, length, module, line_vector);
   //
   // will append lines to the end of line_vector.  We can use this with
-  // MockLineToModuleFunctor like this:
+  // MockLineToModuleHandler like this:
   //
-  //   MockLineToModuleFunctor l2m;
-  //   EXPECT_CALL(l2m, mock_apply(_,_,_,_))
+  //   MockLineToModuleHandler l2m;
+  //   EXPECT_CALL(l2m, ReadProgram(_,_,_,_))
   //       .WillOnce(DoAll(Invoke(appender), Return()));
   //
   // in which case calling l2m with some line vector will append lines.
@@ -144,7 +140,8 @@
 
     // By default, expect the line program reader not to be invoked. We
     // may override this in StartCU.
-    EXPECT_CALL(line_reader_, mock_apply(_,_,_,_)).Times(0);
+    EXPECT_CALL(line_reader_, StartCompilationUnit(_)).Times(0);
+    EXPECT_CALL(line_reader_, ReadProgram(_,_,_,_)).Times(0);
 
     // The handler will consult this section map to decide what to
     // pass to our line reader.
@@ -154,7 +151,7 @@
 
   // Add a line with the given address, size, filename, and line
   // number to the end of the statement list the handler will receive
-  // when it invokes its LineToModuleFunctor. Call this before calling
+  // when it invokes its LineToModuleHandler. Call this before calling
   // StartCU.
   void PushLine(Module::Address address, Module::Address size,
                 const string &filename, int line_number);
@@ -177,11 +174,7 @@
   // this.root_handler_.EndAttributes, but not this.root_handler_.Finish.
   void StartCU();
 
-  // Add some strange attributes/form pairs to the end of ATTRS.
-  void PushBackStrangeAttributes(dwarf2reader::AttributeList *attrs);
-
   // Have HANDLER process some strange attribute/form/value triples.
-  // These will match those promised by PushBackStrangeAttributes.
   void ProcessStrangeAttributes(dwarf2reader::DIEHandler *handler);
 
   // Start a child DIE of PARENT with the given tag and name. Leave
@@ -198,12 +191,15 @@
   DIEHandler *StartSpecifiedDIE(DIEHandler *parent, DwarfTag tag,
                                 uint64 specification, const char *name = NULL);
  
-  // Define a function as a child of PARENT with the given name,
-  // address, and size. Call EndAttributes and Finish; one cannot
-  // define children of the defined function's DIE.
+  // Define a function as a child of PARENT with the given name, address, and
+  // size. If high_pc_form is DW_FORM_addr then the DW_AT_high_pc attribute
+  // will be written as an address; otherwise it will be written as the
+  // function's size. Call EndAttributes and Finish; one cannot define
+  // children of the defined function's DIE.
   void DefineFunction(DIEHandler *parent, const string &name,
                       Module::Address address, Module::Address size,
-                      const char* mangled_name);
+                      const char* mangled_name,
+                      DwarfForm high_pc_form = dwarf2reader::DW_FORM_addr);
 
   // Create a declaration DIE as a child of PARENT with the given
   // offset, tag and name. If NAME is the empty string, don't provide
@@ -273,13 +269,17 @@
   // report it as an unsigned value.
   bool language_signed_;
 
+  // If this is not empty, we'll give the CU a DW_AT_comp_dir attribute that
+  // indicates the path that this compilation unit was compiled in.
+  string compilation_dir_;
+
   // If this is not empty, we'll give the CU a DW_AT_stmt_list
   // attribute that, when passed to line_reader_, adds these lines to the
   // provided lines array.
   vector<Module::Line> lines_;
 
   // Mock line program reader.
-  MockLineToModuleFunctor line_reader_;
+  MockLineToModuleHandler line_reader_;
   AppendLinesFunctor appender_;
   static const char dummy_line_program_[];
   static const size_t dummy_line_size_;
@@ -313,6 +313,10 @@
 }
 
 void CUFixtureBase::StartCU() {
+  if (!compilation_dir_.empty())
+    EXPECT_CALL(line_reader_,
+                StartCompilationUnit(compilation_dir_)).Times(1);
+
   // If we have lines, make the line reader expect to be invoked at
   // most once. (Hey, if the handler can pass its tests without
   // bothering to read the line number data, that's great.)
@@ -320,8 +324,8 @@
   // initial expectation (no calls) in force.
   if (!lines_.empty())
     EXPECT_CALL(line_reader_,
-                mock_apply(&dummy_line_program_[0], dummy_line_size_,
-                           &module_, _))
+                ReadProgram(&dummy_line_program_[0], dummy_line_size_,
+                            &module_, _))
         .Times(AtMost(1))
         .WillOnce(DoAll(Invoke(appender_), Return()));
 
@@ -329,24 +333,16 @@
               .StartCompilationUnit(0x51182ec307610b51ULL, 0x81, 0x44,
                                     0x4241b4f33720dd5cULL, 3));
   {
-    dwarf2reader::AttributeList attrs;
-    attrs.push_back(make_pair(dwarf2reader::DW_AT_name,
-                              dwarf2reader::DW_FORM_strp));
-    if (!lines_.empty())
-      attrs.push_back(make_pair(dwarf2reader::DW_AT_stmt_list,
-                                dwarf2reader::DW_FORM_ref4));
-    if (language_ != dwarf2reader::DW_LANG_none)
-      attrs.push_back(make_pair(dwarf2reader::DW_AT_language,
-                                language_signed_
-                                ? dwarf2reader::DW_FORM_sdata 
-                                : dwarf2reader::DW_FORM_udata));
     ASSERT_TRUE(root_handler_.StartRootDIE(0x02e56bfbda9e7337ULL,
-                                           dwarf2reader::DW_TAG_compile_unit,
-                                           attrs));
+                                           dwarf2reader::DW_TAG_compile_unit));
   }
   root_handler_.ProcessAttributeString(dwarf2reader::DW_AT_name,
                                        dwarf2reader::DW_FORM_strp,
                                        "compilation-unit-name");
+  if (!compilation_dir_.empty())
+    root_handler_.ProcessAttributeString(dwarf2reader::DW_AT_comp_dir,
+                                         dwarf2reader::DW_FORM_strp,
+                                         compilation_dir_);
   if (!lines_.empty())
     root_handler_.ProcessAttributeUnsigned(dwarf2reader::DW_AT_stmt_list,
                                            dwarf2reader::DW_FORM_ref4,
@@ -364,20 +360,6 @@
   ASSERT_TRUE(root_handler_.EndAttributes());
 }
 
-void CUFixtureBase::PushBackStrangeAttributes(
-    dwarf2reader::AttributeList *attrs) {
-  attrs->push_back(make_pair((DwarfAttribute) 0xf560dead,
-                             (DwarfForm) 0x4106e4db));
-  attrs->push_back(make_pair((DwarfAttribute) 0x85380095,
-                             (DwarfForm) 0x0f16fe87));
-  attrs->push_back(make_pair((DwarfAttribute) 0xf7f7480f,
-                             (DwarfForm) 0x829e038a));
-  attrs->push_back(make_pair((DwarfAttribute) 0xa55ffb51,
-                             (DwarfForm) 0x2f43b041));
-  attrs->push_back(make_pair((DwarfAttribute) 0x2fde304a,
-                             (DwarfForm) 0x895ffa23));
-}
-
 void CUFixtureBase::ProcessStrangeAttributes(
     dwarf2reader::DIEHandler *handler) {
   handler->ProcessAttributeUnsigned((DwarfAttribute) 0xf560dead,
@@ -401,12 +383,8 @@
 DIEHandler *CUFixtureBase::StartNamedDIE(DIEHandler *parent,
                                          DwarfTag tag,
                                          const string &name) {
-  dwarf2reader::AttributeList attrs;
-  attrs.push_back(make_pair(dwarf2reader::DW_AT_name,
-                            dwarf2reader::DW_FORM_strp));
-  PushBackStrangeAttributes(&attrs);
   dwarf2reader::DIEHandler *handler
-    = parent->FindChildHandler(0x8f4c783c0467c989ULL, tag, attrs);
+    = parent->FindChildHandler(0x8f4c783c0467c989ULL, tag);
   if (!handler)
     return NULL;
   handler->ProcessAttributeString(dwarf2reader::DW_AT_name,
@@ -426,14 +404,8 @@
                                              DwarfTag tag,
                                              uint64 specification,
                                              const char *name) {
-  dwarf2reader::AttributeList attrs;
-  if (name)
-    attrs.push_back(make_pair(dwarf2reader::DW_AT_name,
-                              dwarf2reader::DW_FORM_strp));
-  attrs.push_back(make_pair(dwarf2reader::DW_AT_specification,
-                            dwarf2reader::DW_FORM_ref4));
   dwarf2reader::DIEHandler *handler
-    = parent->FindChildHandler(0x8f4c783c0467c989ULL, tag, attrs);
+    = parent->FindChildHandler(0x8f4c783c0467c989ULL, tag);
   if (!handler)
     return NULL;
   if (name)
@@ -455,19 +427,11 @@
 void CUFixtureBase::DefineFunction(dwarf2reader::DIEHandler *parent,
                                    const string &name, Module::Address address,
                                    Module::Address size,
-                                   const char* mangled_name) {
-  dwarf2reader::AttributeList func_attrs;
-  func_attrs.push_back(make_pair(dwarf2reader::DW_AT_name,
-                                 dwarf2reader::DW_FORM_strp));
-  func_attrs.push_back(make_pair(dwarf2reader::DW_AT_low_pc,
-                                 dwarf2reader::DW_FORM_addr));
-  func_attrs.push_back(make_pair(dwarf2reader::DW_AT_high_pc,
-                                 dwarf2reader::DW_FORM_addr));
-  PushBackStrangeAttributes(&func_attrs);
+                                   const char* mangled_name,
+                                   DwarfForm high_pc_form) {
   dwarf2reader::DIEHandler *func
       = parent->FindChildHandler(0xe34797c7e68590a8LL,
-                                 dwarf2reader::DW_TAG_subprogram,
-                                 func_attrs);
+                                 dwarf2reader::DW_TAG_subprogram);
   ASSERT_TRUE(func != NULL);
   func->ProcessAttributeString(dwarf2reader::DW_AT_name,
                                dwarf2reader::DW_FORM_strp,
@@ -475,9 +439,15 @@
   func->ProcessAttributeUnsigned(dwarf2reader::DW_AT_low_pc,
                                  dwarf2reader::DW_FORM_addr,
                                  address);
+
+  Module::Address high_pc = size;
+  if (high_pc_form == dwarf2reader::DW_FORM_addr) {
+    high_pc += address;
+  }
   func->ProcessAttributeUnsigned(dwarf2reader::DW_AT_high_pc,
-                                 dwarf2reader::DW_FORM_addr,
-                                 address + size);
+                                 high_pc_form,
+                                 high_pc);
+
   if (mangled_name)
     func->ProcessAttributeString(dwarf2reader::DW_AT_MIPS_linkage_name,
                                  dwarf2reader::DW_FORM_strp,
@@ -493,15 +463,7 @@
                                    DwarfTag tag,
                                    const string &name,
                                    const string &mangled_name) {
-  dwarf2reader::AttributeList attrs;
-  if (!name.empty())
-    attrs.push_back(make_pair(dwarf2reader::DW_AT_name,
-                              dwarf2reader::DW_FORM_strp));
-
-
-  attrs.push_back(make_pair(dwarf2reader::DW_AT_declaration,
-                            dwarf2reader::DW_FORM_flag));
-  dwarf2reader::DIEHandler *die = parent->FindChildHandler(offset, tag, attrs);
+  dwarf2reader::DIEHandler *die = parent->FindChildHandler(offset, tag);
   ASSERT_TRUE(die != NULL);
   if (!name.empty())
     die->ProcessAttributeString(dwarf2reader::DW_AT_name,
@@ -526,20 +488,8 @@
                                   const string &name,
                                   Module::Address address,
                                   Module::Address size) {
-  dwarf2reader::AttributeList attrs;
-  attrs.push_back(make_pair(dwarf2reader::DW_AT_specification,
-                            dwarf2reader::DW_FORM_ref4));
-  if (!name.empty())
-    attrs.push_back(make_pair(dwarf2reader::DW_AT_name,
-                              dwarf2reader::DW_FORM_strp));
-  if (size) {
-    attrs.push_back(make_pair(dwarf2reader::DW_AT_low_pc,
-                              dwarf2reader::DW_FORM_addr));
-    attrs.push_back(make_pair(dwarf2reader::DW_AT_high_pc,
-                              dwarf2reader::DW_FORM_addr));
-  }
   dwarf2reader::DIEHandler *die
-    = parent->FindChildHandler(0x6ccfea031a9e6cc9ULL, tag, attrs);
+    = parent->FindChildHandler(0x6ccfea031a9e6cc9ULL, tag);
   ASSERT_TRUE(die != NULL);
   die->ProcessAttributeReference(dwarf2reader::DW_AT_specification,
                                  dwarf2reader::DW_FORM_ref4,
@@ -567,16 +517,8 @@
                                         uint64 specification,
                                         const string &name,
                                         DwarfForm form) {
-  dwarf2reader::AttributeList attrs;
-  if (specification != 0ULL)
-    attrs.push_back(make_pair(dwarf2reader::DW_AT_specification,
-                              dwarf2reader::DW_FORM_ref4));
-  attrs.push_back(make_pair(dwarf2reader::DW_AT_inline, form));
-  if (!name.empty())
-    attrs.push_back(make_pair(dwarf2reader::DW_AT_name,
-                              dwarf2reader::DW_FORM_strp));
   dwarf2reader::DIEHandler *die
-    = parent->FindChildHandler(offset, dwarf2reader::DW_TAG_subprogram, attrs);
+    = parent->FindChildHandler(offset, dwarf2reader::DW_TAG_subprogram);
   ASSERT_TRUE(die != NULL);
   if (specification != 0ULL)
     die->ProcessAttributeReference(dwarf2reader::DW_AT_specification,
@@ -602,21 +544,9 @@
                                             uint64 origin, 
                                             Module::Address address,
                                             Module::Address size) {
-  dwarf2reader::AttributeList func_attrs;
-  if (!name.empty())
-    func_attrs.push_back(make_pair(dwarf2reader::DW_AT_name,
-                                   dwarf2reader::DW_FORM_strp));
-  func_attrs.push_back(make_pair(dwarf2reader::DW_AT_low_pc,
-                                 dwarf2reader::DW_FORM_addr));
-  func_attrs.push_back(make_pair(dwarf2reader::DW_AT_high_pc,
-                                 dwarf2reader::DW_FORM_addr));
-  func_attrs.push_back(make_pair(dwarf2reader::DW_AT_abstract_origin,
-                                 dwarf2reader::DW_FORM_ref4));
-  PushBackStrangeAttributes(&func_attrs);
   dwarf2reader::DIEHandler *func
       = parent->FindChildHandler(0x11c70f94c6e87ccdLL,
-                                 dwarf2reader::DW_TAG_subprogram,
-                                 func_attrs);
+                                 dwarf2reader::DW_TAG_subprogram);
   ASSERT_TRUE(func != NULL);
   if (!name.empty()) {
     func->ProcessAttributeString(dwarf2reader::DW_AT_name,
@@ -688,20 +618,31 @@
 
 // Include caller locations for our test subroutines.
 #define TRACE(call) do { SCOPED_TRACE("called from here"); call; } while (0)
-#define PushLine(a,b,c,d)          TRACE(PushLine((a),(b),(c),(d)))
-#define SetLanguage(a)             TRACE(SetLanguage(a))
-#define StartCU()                  TRACE(StartCU())
-#define DefineFunction(a,b,c,d,e)  TRACE(DefineFunction((a),(b),(c),(d),(e)))
-#define DeclarationDIE(a,b,c,d,e)  TRACE(DeclarationDIE((a),(b),(c),(d),(e)))
-#define DefinitionDIE(a,b,c,d,e,f) TRACE(DefinitionDIE((a),(b),(c),(d),(e),(f)))
-#define TestFunctionCount(a)       TRACE(TestFunctionCount(a))
-#define TestFunction(a,b,c,d)      TRACE(TestFunction((a),(b),(c),(d)))
-#define TestLineCount(a,b)         TRACE(TestLineCount((a),(b)))
-#define TestLine(a,b,c,d,e,f)      TRACE(TestLine((a),(b),(c),(d),(e),(f)))
+#define PushLine(a,b,c,d)         TRACE(PushLine((a),(b),(c),(d)))
+#define SetLanguage(a)            TRACE(SetLanguage(a))
+#define StartCU()                 TRACE(StartCU())
+#define DefineFunction(a,b,c,d,e) TRACE(DefineFunction((a),(b),(c),(d),(e)))
+// (DefineFunction) instead of DefineFunction to avoid macro expansion.
+#define DefineFunction6(a,b,c,d,e,f) \
+    TRACE((DefineFunction)((a),(b),(c),(d),(e),(f)))
+#define DeclarationDIE(a,b,c,d,e) TRACE(DeclarationDIE((a),(b),(c),(d),(e)))
+#define DefinitionDIE(a,b,c,d,e,f) \
+    TRACE(DefinitionDIE((a),(b),(c),(d),(e),(f)))
+#define TestFunctionCount(a)      TRACE(TestFunctionCount(a))
+#define TestFunction(a,b,c,d)     TRACE(TestFunction((a),(b),(c),(d)))
+#define TestLineCount(a,b)        TRACE(TestLineCount((a),(b)))
+#define TestLine(a,b,c,d,e,f)     TRACE(TestLine((a),(b),(c),(d),(e),(f)))
 
 class SimpleCU: public CUFixtureBase, public Test {
 };
 
+TEST_F(SimpleCU, CompilationDir) {
+  compilation_dir_ = "/src/build/";
+
+  StartCU();
+  root_handler_.Finish();
+}
+
 TEST_F(SimpleCU, OneFunc) {
   PushLine(0x938cf8c07def4d34ULL, 0x55592d727f6cd01fLL, "line-file", 246571772);
 
@@ -717,6 +658,23 @@
            246571772);
 }
 
+// As above, only DW_AT_high_pc is a length rather than an address.
+TEST_F(SimpleCU, OneFuncHighPcIsLength) {
+  PushLine(0x938cf8c07def4d34ULL, 0x55592d727f6cd01fLL, "line-file", 246571772);
+
+  StartCU();
+  DefineFunction6(&root_handler_, "function1",
+                  0x938cf8c07def4d34ULL, 0x55592d727f6cd01fLL, NULL,
+                  dwarf2reader::DW_FORM_udata);
+  root_handler_.Finish();
+
+  TestFunctionCount(1);
+  TestFunction(0, "function1", 0x938cf8c07def4d34ULL, 0x55592d727f6cd01fLL);
+  TestLineCount(0, 1);
+  TestLine(0, 0, 0x938cf8c07def4d34ULL, 0x55592d727f6cd01fLL, "line-file",
+           246571772);
+}
+
 TEST_F(SimpleCU, MangledName) {
   PushLine(0x938cf8c07def4d34ULL, 0x55592d727f6cd01fLL, "line-file", 246571772);
 
@@ -731,22 +689,19 @@
 
 TEST_F(SimpleCU, IrrelevantRootChildren) {
   StartCU();
-  dwarf2reader::AttributeList no_attrs;
   EXPECT_FALSE(root_handler_
                .FindChildHandler(0x7db32bff4e2dcfb1ULL,
-                                 dwarf2reader::DW_TAG_lexical_block, no_attrs));
+                                 dwarf2reader::DW_TAG_lexical_block));
 }
 
 TEST_F(SimpleCU, IrrelevantNamedScopeChildren) {
   StartCU();
-  dwarf2reader::AttributeList no_attrs;
   DIEHandler *class_A_handler
     = StartNamedDIE(&root_handler_, dwarf2reader::DW_TAG_class_type, "class_A");
   EXPECT_TRUE(class_A_handler != NULL);
   EXPECT_FALSE(class_A_handler
                ->FindChildHandler(0x02e55999b865e4e9ULL,
-                                  dwarf2reader::DW_TAG_lexical_block, 
-                                  no_attrs));
+                                  dwarf2reader::DW_TAG_lexical_block));
   delete class_A_handler;
 }
 
@@ -1476,9 +1431,8 @@
   Module m("module-name", "module-os", "module-arch", "module-id");
   DwarfCUToModule::FileContext fc("dwarf-filename", &m);
   EXPECT_CALL(reporter_, UncoveredFunction(_)).WillOnce(Return());
-  MockLineToModuleFunctor lr;
-  EXPECT_CALL(lr, mock_apply(_,_,_,_)).Times(0);
-  dwarf2reader::AttributeList no_attrs;
+  MockLineToModuleHandler lr;
+  EXPECT_CALL(lr, ReadProgram(_,_,_,_)).Times(0);
 
   // Kludge: satisfy reporter_'s expectation.
   reporter_.SetCUName("compilation-unit-name");
@@ -1487,10 +1441,8 @@
   {
     DwarfCUToModule root1_handler(&fc, &lr, &reporter_);
     ASSERT_TRUE(root1_handler.StartCompilationUnit(0, 1, 2, 3, 3));
-    dwarf2reader::AttributeList attrs;
-    PushBackStrangeAttributes(&attrs);
-    ASSERT_TRUE(root1_handler.StartRootDIE(1, dwarf2reader::DW_TAG_compile_unit,
-                                           attrs));
+    ASSERT_TRUE(root1_handler.StartRootDIE(1,
+                                           dwarf2reader::DW_TAG_compile_unit));
     ProcessStrangeAttributes(&root1_handler);
     ASSERT_TRUE(root1_handler.EndAttributes());
     DeclarationDIE(&root1_handler, 0xb8fbfdd5f0b26fceULL,
@@ -1502,8 +1454,8 @@
   {
     DwarfCUToModule root2_handler(&fc, &lr, &reporter_);
     ASSERT_TRUE(root2_handler.StartCompilationUnit(0, 1, 2, 3, 3));
-    ASSERT_TRUE(root2_handler.StartRootDIE(1, dwarf2reader::DW_TAG_compile_unit,
-                                           no_attrs));
+    ASSERT_TRUE(root2_handler.StartRootDIE(1,
+                                           dwarf2reader::DW_TAG_compile_unit));
     ASSERT_TRUE(root2_handler.EndAttributes());
     DIEHandler *class_A_handler
       = StartSpecifiedDIE(&root2_handler, dwarf2reader::DW_TAG_class_type,
@@ -1519,8 +1471,8 @@
   {
     DwarfCUToModule root3_handler(&fc, &lr, &reporter_);
     ASSERT_TRUE(root3_handler.StartCompilationUnit(0, 1, 2, 3, 3));
-    ASSERT_TRUE(root3_handler.StartRootDIE(1, dwarf2reader::DW_TAG_compile_unit,
-                                           no_attrs));
+    ASSERT_TRUE(root3_handler.StartRootDIE(1,
+                                           dwarf2reader::DW_TAG_compile_unit));
     ASSERT_TRUE(root3_handler.EndAttributes());
     DefinitionDIE(&root3_handler, dwarf2reader::DW_TAG_subprogram,
                   0xb01fef8b380bd1a2ULL, "",
@@ -1635,14 +1587,8 @@
   ASSERT_TRUE(root_handler_
               .StartCompilationUnit(0xc591d5b037543d7cULL, 0x11, 0xcd,
                                     0x2d7d19546cf6590cULL, 3));
-  dwarf2reader::AttributeList attrs;
-  attrs.push_back(make_pair(dwarf2reader::DW_AT_name,
-                            dwarf2reader::DW_FORM_strp));
-  attrs.push_back(make_pair(dwarf2reader::DW_AT_stmt_list,
-                            dwarf2reader::DW_FORM_ref4));
   ASSERT_TRUE(root_handler_.StartRootDIE(0xae789dc102cfca54ULL,
-                                         dwarf2reader::DW_TAG_compile_unit,
-                                         attrs));
+                                         dwarf2reader::DW_TAG_compile_unit));
   root_handler_.ProcessAttributeString(dwarf2reader::DW_AT_name,
                                        dwarf2reader::DW_FORM_strp,
                                        "compilation-unit-name");
@@ -1698,10 +1644,8 @@
                .StartCompilationUnit(0xadf6e0eb71e2b0d9ULL, 0x4d, 0x90,
                                      0xc9de224ccb99ac3eULL, 3));
 
-  dwarf2reader::AttributeList no_attrs;
   ASSERT_FALSE(root_handler_.StartRootDIE(0x02e56bfbda9e7337ULL,
-                                          dwarf2reader::DW_TAG_subprogram,
-                                          no_attrs));
+                                          dwarf2reader::DW_TAG_subprogram));
 }
 
 // Tests for DwarfCUToModule::Reporter. These just produce (or fail to
diff --git a/src/common/dwarf_line_to_module.cc b/src/common/dwarf_line_to_module.cc
index 962848d..258b0b6 100644
--- a/src/common/dwarf_line_to_module.cc
+++ b/src/common/dwarf_line_to_module.cc
@@ -48,13 +48,17 @@
   return (path.size() >= 1 && path[0] == '/');
 }
 
+static bool HasTrailingSlash(const string &path) {
+  return (path.size() >= 1 && path[path.size() - 1] == '/');
+}
+
 // If PATH is an absolute path, return PATH.  If PATH is a relative path,
 // treat it as relative to BASE and return the combined path.
 static string ExpandPath(const string &path,
                          const string &base) {
-  if (PathIsAbsolute(path))
+  if (PathIsAbsolute(path) || base.empty())
     return path;
-  return base + "/" + path;
+  return base + (HasTrailingSlash(base) ? "" : "/") + path;
 }
 
 namespace google_breakpad {
@@ -63,7 +67,7 @@
   // Directory number zero is reserved to mean the compilation
   // directory. Silently ignore attempts to redefine it.
   if (dir_num != 0)
-    directories_[dir_num] = name;
+    directories_[dir_num] = ExpandPath(name, compilation_dir_);
 }
 
 void DwarfLineToModule::DefineFile(const string &name, int32 file_num,
@@ -74,25 +78,26 @@
   else if (file_num > highest_file_number_)
     highest_file_number_ = file_num;
 
-  string full_name;
-  if (dir_num != 0) {
+  string dir_name;
+  if (dir_num == 0) {
+    // Directory number zero is the compilation directory, and is stored as
+    // an attribute on the compilation unit, rather than in the program table.
+    dir_name = compilation_dir_;
+  } else {
     DirectoryTable::const_iterator directory_it = directories_.find(dir_num);
     if (directory_it != directories_.end()) {
-      full_name = ExpandPath(name, directory_it->second);
+      dir_name = directory_it->second;
     } else {
       if (!warned_bad_directory_number_) {
         fprintf(stderr, "warning: DWARF line number data refers to undefined"
                 " directory numbers\n");
         warned_bad_directory_number_ = true;
       }
-      full_name = name; // just treat name as relative
     }
-  } else {
-    // Directory number zero is the compilation directory; we just report
-    // relative paths in that case.
-    full_name = name;
   }
 
+  string full_name = ExpandPath(name, dir_name);
+
   // Find a Module::File object of the given name, and add it to the
   // file table.
   files_[file_num] = module_->FindFile(full_name);
diff --git a/src/common/dwarf_line_to_module.h b/src/common/dwarf_line_to_module.h
index 9382e40..1fdd4cb 100644
--- a/src/common/dwarf_line_to_module.h
+++ b/src/common/dwarf_line_to_module.h
@@ -120,8 +120,10 @@
   // end of the address space, we clip it. It's up to our client to
   // sort out which lines belong to which functions; we don't add them
   // to any particular function in MODULE ourselves.
-  DwarfLineToModule(Module *module, vector<Module::Line> *lines)
+  DwarfLineToModule(Module *module, const string& compilation_dir,
+                    vector<Module::Line> *lines)
       : module_(module),
+        compilation_dir_(compilation_dir),
         lines_(lines),
         highest_file_number_(-1),
         omitted_line_end_(0),
@@ -146,6 +148,10 @@
   // client.
   Module *module_;
 
+  // The compilation directory for the current compilation unit whose
+  // lines are being accumulated.
+  string compilation_dir_;
+
   // The vector of lines we're accumulating. Owned by our client.
   //
   // In a Module, as in a breakpad symbol file, lines belong to
diff --git a/src/common/dwarf_line_to_module_unittest.cc b/src/common/dwarf_line_to_module_unittest.cc
index 1e123e9..7c0fcfd 100644
--- a/src/common/dwarf_line_to_module_unittest.cc
+++ b/src/common/dwarf_line_to_module_unittest.cc
@@ -45,7 +45,7 @@
 TEST(SimpleModule, One) {
   Module m("name", "os", "architecture", "id");
   vector<Module::Line> lines;
-  DwarfLineToModule h(&m, &lines);
+  DwarfLineToModule h(&m, "/", &lines);
 
   h.DefineFile("file1", 0x30bf0f27, 0, 0, 0);
   h.AddLine(0x6fd126fbf74f2680LL, 0x63c9a14cf556712bLL, 0x30bf0f27,
@@ -54,7 +54,7 @@
   vector<Module::File *> files;
   m.GetFiles(&files);
   EXPECT_EQ(1U, files.size());
-  EXPECT_STREQ("file1", files[0]->name.c_str());
+  EXPECT_STREQ("/file1", files[0]->name.c_str());
 
   EXPECT_EQ(1U, lines.size());
   EXPECT_EQ(0x6fd126fbf74f2680ULL, lines[0].address);
@@ -66,7 +66,7 @@
 TEST(SimpleModule, Many) {
   Module m("name", "os", "architecture", "id");
   vector<Module::Line> lines;
-  DwarfLineToModule h(&m, &lines);
+  DwarfLineToModule h(&m, "/", &lines);
 
   h.DefineDir("directory1", 0x838299ab);
   h.DefineDir("directory2", 0xf85de023);
@@ -89,11 +89,11 @@
   vector<Module::File *> files;
   m.GetFiles(&files);
   ASSERT_EQ(5U, files.size());
-  EXPECT_STREQ("directory1/file1", files[0]->name.c_str());
-  EXPECT_STREQ("directory1/file2", files[1]->name.c_str());
-  EXPECT_STREQ("directory2/file1", files[2]->name.c_str());
-  EXPECT_STREQ("directory2/file2", files[3]->name.c_str());
-  EXPECT_STREQ("file3",            files[4]->name.c_str());
+  EXPECT_STREQ("/directory1/file1", files[0]->name.c_str());
+  EXPECT_STREQ("/directory1/file2", files[1]->name.c_str());
+  EXPECT_STREQ("/directory2/file1", files[2]->name.c_str());
+  EXPECT_STREQ("/directory2/file2", files[3]->name.c_str());
+  EXPECT_STREQ("/file3",            files[4]->name.c_str());
 
   ASSERT_EQ(5U, lines.size());
 
@@ -126,7 +126,7 @@
 TEST(Filenames, Absolute) {
   Module m("name", "os", "architecture", "id");
   vector<Module::Line> lines;
-  DwarfLineToModule h(&m, &lines);
+  DwarfLineToModule h(&m, "/", &lines);
 
   h.DefineDir("directory1", 1);
   h.DefineFile("/absolute", 1, 1, 0, 0);
@@ -144,7 +144,7 @@
 TEST(Filenames, Relative) {
   Module m("name", "os", "architecture", "id");
   vector<Module::Line> lines;
-  DwarfLineToModule h(&m, &lines);
+  DwarfLineToModule h(&m, "/", &lines);
 
   h.DefineDir("directory1", 1);
   h.DefineFile("relative", 1, 1, 0, 0);
@@ -154,7 +154,7 @@
   vector<Module::File *> files;
   m.GetFiles(&files);
   ASSERT_EQ(1U, files.size());
-  EXPECT_STREQ("directory1/relative", files[0]->name.c_str());
+  EXPECT_STREQ("/directory1/relative", files[0]->name.c_str());
   ASSERT_EQ(1U, lines.size());
   EXPECT_TRUE(lines[0].file == files[0]);
 }
@@ -162,20 +162,20 @@
 TEST(Filenames, StrangeFile) {
   Module m("name", "os", "architecture", "id");
   vector<Module::Line> lines;
-  DwarfLineToModule h(&m, &lines);
+  DwarfLineToModule h(&m, "/", &lines);
 
   h.DefineDir("directory1", 1);
   h.DefineFile("", 1, 1, 0, 0);
   h.AddLine(1, 1, 1, 0, 0);
 
   ASSERT_EQ(1U, lines.size());
-  EXPECT_STREQ("directory1/", lines[0].file->name.c_str());
+  EXPECT_STREQ("/directory1/", lines[0].file->name.c_str());
 }
 
 TEST(Filenames, StrangeDirectory) {
   Module m("name", "os", "architecture", "id");
   vector<Module::Line> lines;
-  DwarfLineToModule h(&m, &lines);
+  DwarfLineToModule h(&m, "/", &lines);
 
   h.DefineDir("", 1);
   h.DefineFile("file1", 1, 1, 0, 0);
@@ -188,7 +188,7 @@
 TEST(Filenames, StrangeDirectoryAndFile) {
   Module m("name", "os", "architecture", "id");
   vector<Module::Line> lines;
-  DwarfLineToModule h(&m, &lines);
+  DwarfLineToModule h(&m, "/", &lines);
 
   h.DefineDir("", 1);
   h.DefineFile("", 1, 1, 0, 0);
@@ -198,12 +198,60 @@
   EXPECT_STREQ("/", lines[0].file->name.c_str());
 }
 
+// We should use the compilation directory when encountering a file for
+// directory number zero.
+TEST(Filenames, DirectoryZeroFileIsRelativeToCompilationDir) {
+  Module m("name", "os", "architecture", "id");
+  vector<Module::Line> lines;
+  DwarfLineToModule h(&m, "src/build", &lines);
+
+  h.DefineDir("Dir", 1);
+  h.DefineFile("File", 1, 0, 0, 0);
+
+  h.AddLine(1, 1, 1, 0, 0);
+
+  ASSERT_EQ(1U, lines.size());
+  EXPECT_STREQ("src/build/File", lines[0].file->name.c_str());
+}
+
+// We should treat non-absolute directories as relative to the compilation
+// directory.
+TEST(Filenames, IncludeDirectoryRelativeToDirectoryZero) {
+  Module m("name", "os", "architecture", "id");
+  vector<Module::Line> lines;
+  DwarfLineToModule h(&m, "src/build", &lines);
+
+  h.DefineDir("Dir", 1);
+  h.DefineFile("File", 1, 1, 0, 0);
+
+  h.AddLine(1, 1, 1, 0, 0);
+
+  ASSERT_EQ(1U, lines.size());
+  EXPECT_STREQ("src/build/Dir/File", lines[0].file->name.c_str());
+}
+
+// We should treat absolute directories as absolute, and not relative to
+// the compilation dir.
+TEST(Filenames, IncludeDirectoryAbsolute) {
+  Module m("name", "os", "architecture", "id");
+  vector<Module::Line> lines;
+  DwarfLineToModule h(&m, "src/build", &lines);
+
+  h.DefineDir("/Dir", 1);
+  h.DefineFile("File", 1, 1, 0, 0);
+
+  h.AddLine(1, 1, 1, 0, 0);
+
+  ASSERT_EQ(1U, lines.size());
+  EXPECT_STREQ("/Dir/File", lines[0].file->name.c_str());
+}
+
 // We should silently ignore attempts to define directory number zero,
 // since that is always the compilation directory.
 TEST(ModuleErrors, DirectoryZero) {
   Module m("name", "os", "architecture", "id");
   vector<Module::Line> lines;
-  DwarfLineToModule h(&m, &lines);
+  DwarfLineToModule h(&m, "/", &lines);
 
   h.DefineDir("directory0", 0); // should be ignored
   h.DefineFile("relative", 1, 0, 0, 0);
@@ -211,7 +259,7 @@
   h.AddLine(1, 1, 1, 0, 0);
 
   ASSERT_EQ(1U, lines.size());
-  EXPECT_STREQ("relative", lines[0].file->name.c_str());
+  EXPECT_STREQ("/relative", lines[0].file->name.c_str());
 }
 
 // We should refuse to add lines with bogus file numbers. We should
@@ -219,7 +267,7 @@
 TEST(ModuleErrors, BadFileNumber) {
   Module m("name", "os", "architecture", "id");
   vector<Module::Line> lines;
-  DwarfLineToModule h(&m, &lines);
+  DwarfLineToModule h(&m, "/", &lines);
 
   h.DefineFile("relative", 1, 0, 0, 0);
   h.AddLine(1, 1, 2, 0, 0); // bad file number
@@ -233,7 +281,7 @@
 TEST(ModuleErrors, BadDirectoryNumber) {
   Module m("name", "os", "architecture", "id");
   vector<Module::Line> lines;
-  DwarfLineToModule h(&m, &lines);
+  DwarfLineToModule h(&m, "/", &lines);
 
   h.DefineDir("directory1", 1);
   h.DefineFile("baddirnumber1", 1, 2, 0, 0); // bad directory number
@@ -248,7 +296,7 @@
 TEST(ModuleErrors, EmptyLine) {
   Module m("name", "os", "architecture", "id");
   vector<Module::Line> lines;
-  DwarfLineToModule h(&m, &lines);
+  DwarfLineToModule h(&m, "/", &lines);
 
   h.DefineFile("filename1", 1, 0, 0, 0);
   h.AddLine(1, 0, 1, 0, 0);
@@ -261,7 +309,7 @@
 TEST(ModuleErrors, BigLine) {
   Module m("name", "os", "architecture", "id");
   vector<Module::Line> lines;
-  DwarfLineToModule h(&m, &lines);
+  DwarfLineToModule h(&m, "/", &lines);
 
   h.DefineFile("filename1", 1, 0, 0, 0);
   h.AddLine(0xffffffffffffffffULL, 2, 1, 0, 0);
@@ -278,7 +326,7 @@
 TEST(Omitted, DroppedThenGood) {
   Module m("name", "os", "architecture", "id");
   vector<Module::Line> lines;
-  DwarfLineToModule h(&m, &lines);
+  DwarfLineToModule h(&m, "/", &lines);
 
   h.DefineFile("filename1", 1, 0, 0, 0);
   h.AddLine(0,  10, 1, 83816211, 0);   // should be omitted
@@ -291,7 +339,7 @@
 TEST(Omitted, GoodThenDropped) {
   Module m("name", "os", "architecture", "id");
   vector<Module::Line> lines;
-  DwarfLineToModule h(&m, &lines);
+  DwarfLineToModule h(&m, "/", &lines);
 
   h.DefineFile("filename1", 1, 0, 0, 0);
   h.AddLine(0x9dd6a372, 10, 1, 41454594, 0);   // should be recorded
@@ -304,7 +352,7 @@
 TEST(Omitted, Mix1) {
   Module m("name", "os", "architecture", "id");
   vector<Module::Line> lines;
-  DwarfLineToModule h(&m, &lines);
+  DwarfLineToModule h(&m, "/", &lines);
 
   h.DefineFile("filename1", 1, 0, 0, 0);
   h.AddLine(0x679ed72f,  10,   1, 58932642, 0);   // should be recorded
@@ -325,7 +373,7 @@
 TEST(Omitted, Mix2) {
   Module m("name", "os", "architecture", "id");
   vector<Module::Line> lines;
-  DwarfLineToModule h(&m, &lines);
+  DwarfLineToModule h(&m, "/", &lines);
 
   h.DefineFile("filename1", 1, 0, 0, 0);
   h.AddLine(0,           0xf2, 1, 58802211, 0);   // should be omitted
diff --git a/src/common/linux/dump_symbols.cc b/src/common/linux/dump_symbols.cc
index 8ed78a8..eec5373 100644
--- a/src/common/linux/dump_symbols.cc
+++ b/src/common/linux/dump_symbols.cc
@@ -62,8 +62,11 @@
 #include "common/linux/elf_symbols_to_module.h"
 #include "common/linux/file_id.h"
 #include "common/module.h"
+#include "common/scoped_ptr.h"
+#ifndef NO_STABS_SUPPORT
 #include "common/stabs_reader.h"
 #include "common/stabs_to_module.h"
+#endif
 #include "common/using_std_string.h"
 
 // This namespace contains helper functions.
@@ -79,7 +82,10 @@
 using google_breakpad::GetOffset;
 using google_breakpad::IsValidElf;
 using google_breakpad::Module;
+#ifndef NO_STABS_SUPPORT
 using google_breakpad::StabsToModule;
+#endif
+using google_breakpad::scoped_ptr;
 
 //
 // FDWrapper
@@ -115,8 +121,7 @@
  public:
   MmapWrapper() : is_set_(false) {}
   ~MmapWrapper() {
-    assert(is_set_);
-    if (base_ != NULL) {
+    if (is_set_ && base_ != NULL) {
       assert(size_ > 0);
       munmap(base_, size_);
     }
@@ -128,6 +133,7 @@
   }
   void release() {
     assert(is_set_);
+    is_set_ = false;
     base_ = NULL;
     size_ = 0;
   }
@@ -156,6 +162,7 @@
   return 0;
 }
 
+#ifndef NO_STABS_SUPPORT
 template<typename ElfClass>
 bool LoadStabs(const typename ElfClass::Ehdr* elf_header,
                const typename ElfClass::Shdr* stab_section,
@@ -181,22 +188,27 @@
   handler.Finalize();
   return true;
 }
+#endif  // NO_STABS_SUPPORT
 
 // A line-to-module loader that accepts line number info parsed by
 // dwarf2reader::LineInfo and populates a Module and a line vector
 // with the results.
-class DumperLineToModule: public DwarfCUToModule::LineToModuleFunctor {
+class DumperLineToModule: public DwarfCUToModule::LineToModuleHandler {
  public:
   // Create a line-to-module converter using BYTE_READER.
   explicit DumperLineToModule(dwarf2reader::ByteReader *byte_reader)
       : byte_reader_(byte_reader) { }
-  void operator()(const char *program, uint64 length,
-                  Module *module, std::vector<Module::Line> *lines) {
-    DwarfLineToModule handler(module, lines);
+  void StartCompilationUnit(const string& compilation_dir) {
+    compilation_dir_ = compilation_dir;
+  }
+  void ReadProgram(const char *program, uint64 length,
+                   Module *module, std::vector<Module::Line> *lines) {
+    DwarfLineToModule handler(module, compilation_dir_, lines);
     dwarf2reader::LineInfo parser(program, length, byte_reader_, &handler);
     parser.Start();
   }
  private:
+  string compilation_dir_;
   dwarf2reader::ByteReader *byte_reader_;
 };
 
@@ -386,7 +398,7 @@
 string ReadDebugLink(const char* debuglink,
                      size_t debuglink_size,
                      const string& obj_file,
-                     const string& debug_dir) {
+                     const std::vector<string>& debug_dirs) {
   size_t debuglink_len = strlen(debuglink) + 5;  // '\0' + CRC32.
   debuglink_len = 4 * ((debuglink_len + 3) / 4);  // Round to nearest 4 bytes.
 
@@ -397,13 +409,30 @@
     return "";
   }
 
-  string debuglink_path = debug_dir + "/" + debuglink;
-  int debuglink_fd = open(debuglink_path.c_str(), O_RDONLY);
-  if (debuglink_fd < 0) {
-    fprintf(stderr, "Failed to open debug ELF file '%s' for '%s': %s\n",
-            debuglink_path.c_str(), obj_file.c_str(), strerror(errno));
+  bool found = false;
+  int debuglink_fd = -1;
+  string debuglink_path;
+  std::vector<string>::const_iterator it;
+  for (it = debug_dirs.begin(); it < debug_dirs.end(); ++it) {
+    const string& debug_dir = *it;
+    debuglink_path = debug_dir + "/" + debuglink;
+    debuglink_fd = open(debuglink_path.c_str(), O_RDONLY);
+    if (debuglink_fd >= 0) {
+      found = true;
+      break;
+    }
+  }
+
+  if (!found) {
+    fprintf(stderr, "Failed to find debug ELF file for '%s' after trying:\n",
+            obj_file.c_str());
+    for (it = debug_dirs.begin(); it < debug_dirs.end(); ++it) {
+      const string debug_dir = *it;
+      fprintf(stderr, "  %s/%s\n", debug_dir.c_str(), debuglink);
+    }
     return "";
   }
+
   FDWrapper debuglink_fd_wrapper(debuglink_fd);
   // TODO(thestig) check the CRC-32 at the end of the .gnu_debuglink
   // section.
@@ -423,8 +452,8 @@
  public:
   typedef typename ElfClass::Addr Addr;
 
-  explicit LoadSymbolsInfo(const string &dbg_dir) :
-    debug_dir_(dbg_dir),
+  explicit LoadSymbolsInfo(const std::vector<string>& dbg_dirs) :
+    debug_dirs_(dbg_dirs),
     has_loading_addr_(false) {}
 
   // Keeps track of which sections have been loaded so sections don't
@@ -457,8 +486,8 @@
   }
 
   // Setters and getters
-  const string &debug_dir() const {
-    return debug_dir_;
+  const std::vector<string>& debug_dirs() const {
+    return debug_dirs_;
   }
 
   string debuglink_file() const {
@@ -469,7 +498,8 @@
   }
 
  private:
-  const string &debug_dir_;  // Directory with the debug ELF file.
+  const std::vector<string>& debug_dirs_; // Directories in which to
+                                          // search for the debug ELF file.
 
   string debuglink_file_;  // Full path to the debug ELF file.
 
@@ -491,6 +521,7 @@
                  const typename ElfClass::Ehdr* elf_header,
                  const bool read_gnu_debug_link,
                  LoadSymbolsInfo<ElfClass>* info,
+                 SymbolData symbol_data,
                  Module* module) {
   typedef typename ElfClass::Addr Addr;
   typedef typename ElfClass::Phdr Phdr;
@@ -511,81 +542,87 @@
   bool found_debug_info_section = false;
   bool found_usable_info = false;
 
-  // Look for STABS debugging information, and load it if present.
-  const Shdr* stab_section =
+  if (symbol_data != ONLY_CFI) {
+#ifndef NO_STABS_SUPPORT
+    // Look for STABS debugging information, and load it if present.
+    const Shdr* stab_section =
       FindElfSectionByName<ElfClass>(".stab", SHT_PROGBITS,
                                      sections, names, names_end,
                                      elf_header->e_shnum);
-  if (stab_section) {
-    const Shdr* stabstr_section = stab_section->sh_link + sections;
-    if (stabstr_section) {
-      found_debug_info_section = true;
-      found_usable_info = true;
-      info->LoadedSection(".stab");
-      if (!LoadStabs<ElfClass>(elf_header, stab_section, stabstr_section,
-                               big_endian, module)) {
-        fprintf(stderr, "%s: \".stab\" section found, but failed to load STABS"
-                " debugging information\n", obj_file.c_str());
+    if (stab_section) {
+      const Shdr* stabstr_section = stab_section->sh_link + sections;
+      if (stabstr_section) {
+        found_debug_info_section = true;
+        found_usable_info = true;
+        info->LoadedSection(".stab");
+        if (!LoadStabs<ElfClass>(elf_header, stab_section, stabstr_section,
+                                 big_endian, module)) {
+          fprintf(stderr, "%s: \".stab\" section found, but failed to load"
+                  " STABS debugging information\n", obj_file.c_str());
+        }
       }
     }
-  }
+#endif  // NO_STABS_SUPPORT
 
-  // Look for DWARF debugging information, and load it if present.
-  const Shdr* dwarf_section =
+    // Look for DWARF debugging information, and load it if present.
+    const Shdr* dwarf_section =
       FindElfSectionByName<ElfClass>(".debug_info", SHT_PROGBITS,
                                      sections, names, names_end,
                                      elf_header->e_shnum);
-  if (dwarf_section) {
-    found_debug_info_section = true;
-    found_usable_info = true;
-    info->LoadedSection(".debug_info");
-    if (!LoadDwarf<ElfClass>(obj_file, elf_header, big_endian, module))
-      fprintf(stderr, "%s: \".debug_info\" section found, but failed to load "
-              "DWARF debugging information\n", obj_file.c_str());
+    if (dwarf_section) {
+      found_debug_info_section = true;
+      found_usable_info = true;
+      info->LoadedSection(".debug_info");
+      if (!LoadDwarf<ElfClass>(obj_file, elf_header, big_endian, module))
+        fprintf(stderr, "%s: \".debug_info\" section found, but failed to load "
+                "DWARF debugging information\n", obj_file.c_str());
+    }
   }
 
-  // Dwarf Call Frame Information (CFI) is actually independent from
-  // the other DWARF debugging information, and can be used alone.
-  const Shdr* dwarf_cfi_section =
-      FindElfSectionByName<ElfClass>(".debug_frame", SHT_PROGBITS,
-                                     sections, names, names_end,
-                                     elf_header->e_shnum);
-  if (dwarf_cfi_section) {
-    // Ignore the return value of this function; even without call frame
-    // information, the other debugging information could be perfectly
-    // useful.
-    info->LoadedSection(".debug_frame");
-    bool result =
-        LoadDwarfCFI<ElfClass>(obj_file, elf_header, ".debug_frame",
-                               dwarf_cfi_section, false, 0, 0, big_endian,
-                               module);
-    found_usable_info = found_usable_info || result;
-  }
+  if (symbol_data != NO_CFI) {
+    // Dwarf Call Frame Information (CFI) is actually independent from
+    // the other DWARF debugging information, and can be used alone.
+    const Shdr* dwarf_cfi_section =
+        FindElfSectionByName<ElfClass>(".debug_frame", SHT_PROGBITS,
+                                       sections, names, names_end,
+                                       elf_header->e_shnum);
+    if (dwarf_cfi_section) {
+      // Ignore the return value of this function; even without call frame
+      // information, the other debugging information could be perfectly
+      // useful.
+      info->LoadedSection(".debug_frame");
+      bool result =
+          LoadDwarfCFI<ElfClass>(obj_file, elf_header, ".debug_frame",
+                                 dwarf_cfi_section, false, 0, 0, big_endian,
+                                 module);
+      found_usable_info = found_usable_info || result;
+    }
 
-  // Linux C++ exception handling information can also provide
-  // unwinding data.
-  const Shdr* eh_frame_section =
-      FindElfSectionByName<ElfClass>(".eh_frame", SHT_PROGBITS,
-                                     sections, names, names_end,
-                                     elf_header->e_shnum);
-  if (eh_frame_section) {
-    // Pointers in .eh_frame data may be relative to the base addresses of
-    // certain sections. Provide those sections if present.
-    const Shdr* got_section =
-        FindElfSectionByName<ElfClass>(".got", SHT_PROGBITS,
+    // Linux C++ exception handling information can also provide
+    // unwinding data.
+    const Shdr* eh_frame_section =
+        FindElfSectionByName<ElfClass>(".eh_frame", SHT_PROGBITS,
                                        sections, names, names_end,
                                        elf_header->e_shnum);
-    const Shdr* text_section =
-        FindElfSectionByName<ElfClass>(".text", SHT_PROGBITS,
-                                       sections, names, names_end,
-                                       elf_header->e_shnum);
-    info->LoadedSection(".eh_frame");
-    // As above, ignore the return value of this function.
-    bool result =
-        LoadDwarfCFI<ElfClass>(obj_file, elf_header, ".eh_frame",
-                               eh_frame_section, true,
-                               got_section, text_section, big_endian, module);
-    found_usable_info = found_usable_info || result;
+    if (eh_frame_section) {
+      // Pointers in .eh_frame data may be relative to the base addresses of
+      // certain sections. Provide those sections if present.
+      const Shdr* got_section =
+          FindElfSectionByName<ElfClass>(".got", SHT_PROGBITS,
+                                         sections, names, names_end,
+                                         elf_header->e_shnum);
+      const Shdr* text_section =
+          FindElfSectionByName<ElfClass>(".text", SHT_PROGBITS,
+                                         sections, names, names_end,
+                                         elf_header->e_shnum);
+      info->LoadedSection(".eh_frame");
+      // As above, ignore the return value of this function.
+      bool result =
+          LoadDwarfCFI<ElfClass>(obj_file, elf_header, ".eh_frame",
+                                 eh_frame_section, true,
+                                 got_section, text_section, big_endian, module);
+      found_usable_info = found_usable_info || result;
+    }
   }
 
   if (!found_debug_info_section) {
@@ -600,14 +637,14 @@
                                            sections, names,
                                            names_end, elf_header->e_shnum);
       if (gnu_debuglink_section) {
-        if (!info->debug_dir().empty()) {
+        if (!info->debug_dirs().empty()) {
           const char* debuglink_contents =
               GetOffset<ElfClass, char>(elf_header,
                                         gnu_debuglink_section->sh_offset);
           string debuglink_file
               = ReadDebugLink<ElfClass>(debuglink_contents,
                                         gnu_debuglink_section->sh_size,
-                                        obj_file, info->debug_dir());
+                                        obj_file, info->debug_dirs());
           info->set_debuglink_file(debuglink_file);
         } else {
           fprintf(stderr, ".gnu_debuglink section found in '%s', "
@@ -618,32 +655,36 @@
                 obj_file.c_str());
       }
     } else {
-      // The caller doesn't want to consult .gnu_debuglink.
-      // See if there are export symbols available.
-      const Shdr* dynsym_section =
+      if (symbol_data != ONLY_CFI) {
+        // The caller doesn't want to consult .gnu_debuglink.
+        // See if there are export symbols available.
+        const Shdr* dynsym_section =
           FindElfSectionByName<ElfClass>(".dynsym", SHT_DYNSYM,
                                          sections, names, names_end,
                                          elf_header->e_shnum);
-      const Shdr* dynstr_section =
+        const Shdr* dynstr_section =
           FindElfSectionByName<ElfClass>(".dynstr", SHT_STRTAB,
                                          sections, names, names_end,
                                          elf_header->e_shnum);
-      if (dynsym_section && dynstr_section) {
-        info->LoadedSection(".dynsym");
+        if (dynsym_section && dynstr_section) {
+          info->LoadedSection(".dynsym");
 
-        const uint8_t* dynsyms =
-            GetOffset<ElfClass, uint8_t>(elf_header, dynsym_section->sh_offset);
-        const uint8_t* dynstrs =
-            GetOffset<ElfClass, uint8_t>(elf_header, dynstr_section->sh_offset);
-        bool result =
-            ELFSymbolsToModule(dynsyms,
-                               dynsym_section->sh_size,
-                               dynstrs,
-                               dynstr_section->sh_size,
-                               big_endian,
-                               ElfClass::kAddrSize,
-                               module);
-        found_usable_info = found_usable_info || result;
+          const uint8_t* dynsyms =
+              GetOffset<ElfClass, uint8_t>(elf_header,
+                                           dynsym_section->sh_offset);
+          const uint8_t* dynstrs =
+              GetOffset<ElfClass, uint8_t>(elf_header,
+                                           dynstr_section->sh_offset);
+          bool result =
+              ELFSymbolsToModule(dynsyms,
+                                 dynsym_section->sh_size,
+                                 dynstrs,
+                                 dynstr_section->sh_size,
+                                 big_endian,
+                                 ElfClass::kAddrSize,
+                                 module);
+          found_usable_info = found_usable_info || result;
+        }
       }
 
       // Return true if some usable information was found, since
@@ -709,14 +750,16 @@
 }
 
 template<typename ElfClass>
-bool WriteSymbolFileElfClass(const typename ElfClass::Ehdr* elf_header,
+bool ReadSymbolDataElfClass(const typename ElfClass::Ehdr* elf_header,
                              const string& obj_filename,
-                             const string& debug_dir,
-                             bool cfi,
-                             std::ostream& sym_stream) {
+                             const std::vector<string>& debug_dirs,
+                             SymbolData symbol_data,
+                             Module** out_module) {
   typedef typename ElfClass::Ehdr Ehdr;
   typedef typename ElfClass::Shdr Shdr;
 
+  *out_module = NULL;
+
   unsigned char identifier[16];
   if (!google_breakpad::FileID::ElfFileIdentifierFromMappedFile(elf_header,
                                                                 identifier)) {
@@ -741,10 +784,11 @@
   string os = "Linux";
   string id = FormatIdentifier(identifier);
 
-  LoadSymbolsInfo<ElfClass> info(debug_dir);
-  Module module(name, os, architecture, id);
+  LoadSymbolsInfo<ElfClass> info(debug_dirs);
+  scoped_ptr<Module> module(new Module(name, os, architecture, id));
   if (!LoadSymbols<ElfClass>(obj_filename, big_endian, elf_header,
-                             !debug_dir.empty(), &info, &module)) {
+                             !debug_dirs.empty(), &info,
+                             symbol_data, module.get())) {
     const string debuglink_file = info.debuglink_file();
     if (debuglink_file.empty())
       return false;
@@ -782,13 +826,13 @@
     }
 
     if (!LoadSymbols<ElfClass>(debuglink_file, debug_big_endian,
-                               debug_elf_header, false, &info, &module)) {
+                               debug_elf_header, false, &info,
+                               symbol_data, module.get())) {
       return false;
     }
   }
-  if (!module.Write(sym_stream, cfi))
-    return false;
 
+  *out_module = module.release();
   return true;
 }
 
@@ -797,11 +841,11 @@
 namespace google_breakpad {
 
 // Not explicitly exported, but not static so it can be used in unit tests.
-bool WriteSymbolFileInternal(const uint8_t* obj_file,
-                             const string& obj_filename,
-                             const string& debug_dir,
-                             bool cfi,
-                             std::ostream& sym_stream) {
+bool ReadSymbolDataInternal(const uint8_t* obj_file,
+                            const string& obj_filename,
+                            const std::vector<string>& debug_dirs,
+                            SymbolData symbol_data,
+                            Module** module) {
 
   if (!IsValidElf(obj_file)) {
     fprintf(stderr, "Not a valid ELF file: %s\n", obj_filename.c_str());
@@ -810,30 +854,43 @@
 
   int elfclass = ElfClass(obj_file);
   if (elfclass == ELFCLASS32) {
-    return WriteSymbolFileElfClass<ElfClass32>(
-        reinterpret_cast<const Elf32_Ehdr*>(obj_file), obj_filename, debug_dir,
-        cfi, sym_stream);
+    return ReadSymbolDataElfClass<ElfClass32>(
+        reinterpret_cast<const Elf32_Ehdr*>(obj_file), obj_filename, debug_dirs,
+        symbol_data, module);
   }
   if (elfclass == ELFCLASS64) {
-    return WriteSymbolFileElfClass<ElfClass64>(
-        reinterpret_cast<const Elf64_Ehdr*>(obj_file), obj_filename, debug_dir,
-        cfi, sym_stream);
+    return ReadSymbolDataElfClass<ElfClass64>(
+        reinterpret_cast<const Elf64_Ehdr*>(obj_file), obj_filename, debug_dirs,
+        symbol_data, module);
   }
 
   return false;
 }
 
 bool WriteSymbolFile(const string &obj_file,
-                     const string &debug_dir,
-                     bool cfi,
+                     const std::vector<string>& debug_dirs,
+                     SymbolData symbol_data,
                      std::ostream &sym_stream) {
+  Module* module;
+  if (!ReadSymbolData(obj_file, debug_dirs, symbol_data, &module))
+    return false;
+
+  bool result = module->Write(sym_stream, symbol_data);
+  delete module;
+  return result;
+}
+
+bool ReadSymbolData(const string& obj_file,
+                    const std::vector<string>& debug_dirs,
+                    SymbolData symbol_data,
+                    Module** module) {
   MmapWrapper map_wrapper;
   void* elf_header = NULL;
   if (!LoadELF(obj_file, &map_wrapper, &elf_header))
     return false;
 
-  return WriteSymbolFileInternal(reinterpret_cast<uint8_t*>(elf_header),
-                                 obj_file, debug_dir, cfi, sym_stream);
+  return ReadSymbolDataInternal(reinterpret_cast<uint8_t*>(elf_header),
+                                obj_file, debug_dirs, symbol_data, module);
 }
 
 }  // namespace google_breakpad
diff --git a/src/common/linux/dump_symbols.h b/src/common/linux/dump_symbols.h
index 7b19281..f3c92cd 100644
--- a/src/common/linux/dump_symbols.h
+++ b/src/common/linux/dump_symbols.h
@@ -37,22 +37,34 @@
 
 #include <iostream>
 #include <string>
+#include <vector>
 
+#include "common/symbol_data.h"
 #include "common/using_std_string.h"
 
 namespace google_breakpad {
 
+class Module;
+
 // Find all the debugging information in OBJ_FILE, an ELF executable
 // or shared library, and write it to SYM_STREAM in the Breakpad symbol
 // file format.
 // If OBJ_FILE has been stripped but contains a .gnu_debuglink section,
-// then look for the debug file in DEBUG_DIR.
-// If CFI is set to false, then omit the CFI section.
+// then look for the debug file in DEBUG_DIRS.
+// SYMBOL_DATA allows limiting the type of symbol data written.
 bool WriteSymbolFile(const string &obj_file,
-                     const string &debug_dir,
-                     bool cfi,
+                     const std::vector<string>& debug_dirs,
+                     SymbolData symbol_data,
                      std::ostream &sym_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(const string& obj_file,
+                    const std::vector<string>& debug_dirs,
+                    SymbolData symbol_data,
+                    Module** module);
+
 }  // namespace google_breakpad
 
 #endif  // COMMON_LINUX_DUMP_SYMBOLS_H__
diff --git a/src/common/linux/dump_symbols_unittest.cc b/src/common/linux/dump_symbols_unittest.cc
index 2281fc7..6f5aef2 100644
--- a/src/common/linux/dump_symbols_unittest.cc
+++ b/src/common/linux/dump_symbols_unittest.cc
@@ -37,19 +37,19 @@
 #include <stdio.h>
 
 #include <sstream>
-#include <string>
 #include <vector>
 
 #include "breakpad_googletest_includes.h"
 #include "common/linux/synth_elf.h"
+#include "common/module.h"
 #include "common/using_std_string.h"
 
 namespace google_breakpad {
-bool WriteSymbolFileInternal(const uint8_t* obj_file,
-                             const string &obj_filename,
-                             const string &debug_dir,
-                             bool cfi,
-                             std::ostream &sym_stream);
+bool ReadSymbolDataInternal(const uint8_t* obj_file,
+                            const string& obj_filename,
+                            const std::vector<string>& debug_dir,
+                            SymbolData symbol_data,
+                            Module** module);
 }
 
 using google_breakpad::synth_elf::ELF;
@@ -57,7 +57,8 @@
 using google_breakpad::synth_elf::SymbolTable;
 using google_breakpad::test_assembler::kLittleEndian;
 using google_breakpad::test_assembler::Section;
-using google_breakpad::WriteSymbolFileInternal;
+using google_breakpad::Module;
+using google_breakpad::ReadSymbolDataInternal;
 using std::stringstream;
 using std::vector;
 using ::testing::Test;
@@ -81,12 +82,12 @@
 TEST_F(DumpSymbols, Invalid) {
   Elf32_Ehdr header;
   memset(&header, 0, sizeof(header));
-  stringstream s;
-  EXPECT_FALSE(WriteSymbolFileInternal(reinterpret_cast<uint8_t*>(&header),
-                                       "foo",
-                                       "",
-                                       true,
-                                       s));
+  Module* module;
+  EXPECT_FALSE(ReadSymbolDataInternal(reinterpret_cast<uint8_t*>(&header),
+                                      "foo",
+                                      vector<string>(),
+                                      ALL_SYMBOL_DATA,
+                                      &module));
 }
 
 TEST_F(DumpSymbols, SimplePublic32) {
@@ -113,15 +114,19 @@
   elf.Finish();
   GetElfContents(elf);
 
+  Module* module;
+  EXPECT_TRUE(ReadSymbolDataInternal(elfdata,
+                                     "foo",
+                                     vector<string>(),
+                                     ALL_SYMBOL_DATA,
+                                     &module));
+
   stringstream s;
-  ASSERT_TRUE(WriteSymbolFileInternal(elfdata,
-                                      "foo",
-                                      "",
-                                      true,
-                                      s));
+  module->Write(s, ALL_SYMBOL_DATA);
   EXPECT_EQ("MODULE Linux x86 000000000000000000000000000000000 foo\n"
             "PUBLIC 1000 0 superfunc\n",
             s.str());
+  delete module;
 }
 
 TEST_F(DumpSymbols, SimplePublic64) {
@@ -148,12 +153,15 @@
   elf.Finish();
   GetElfContents(elf);
 
+  Module* module;
+  EXPECT_TRUE(ReadSymbolDataInternal(elfdata,
+                                     "foo",
+                                     vector<string>(),
+                                     ALL_SYMBOL_DATA,
+                                     &module));
+
   stringstream s;
-  ASSERT_TRUE(WriteSymbolFileInternal(elfdata,
-                                      "foo",
-                                      "",
-                                      true,
-                                      s));
+  module->Write(s, ALL_SYMBOL_DATA);
   EXPECT_EQ("MODULE Linux x86_64 000000000000000000000000000000000 foo\n"
             "PUBLIC 1000 0 superfunc\n",
             s.str());
diff --git a/src/common/linux/elf_gnu_compat.h b/src/common/linux/elf_gnu_compat.h
new file mode 100644
index 0000000..f870cbc
--- /dev/null
+++ b/src/common/linux/elf_gnu_compat.h
@@ -0,0 +1,46 @@
+// -*- mode: C++ -*-
+
+// 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.
+
+// Original author: Lei Zhang <thestig@google.com>
+
+// elf_gnu_compat.h: #defines unique to glibc's elf.h.
+
+#ifndef COMMON_LINUX_ELF_GNU_COMPAT_H_
+#define COMMON_LINUX_ELF_GNU_COMPAT_H_
+
+#include <elf.h>
+
+// A note type on GNU systems corresponding to the .note.gnu.build-id section.
+#ifndef NT_GNU_BUILD_ID
+#define NT_GNU_BUILD_ID 3
+#endif
+
+#endif  // COMMON_LINUX_ELF_GNU_COMPAT_H_
diff --git a/src/common/linux/elfutils.cc b/src/common/linux/elfutils.cc
index ee2f4ac..1fd504d 100644
--- a/src/common/linux/elfutils.cc
+++ b/src/common/linux/elfutils.cc
@@ -75,6 +75,35 @@
   }
 }
 
+template<typename ElfClass>
+void FindElfClassSegment(const char *elf_base,
+                         typename ElfClass::Word segment_type,
+                         const void **segment_start,
+                         int *segment_size) {
+  typedef typename ElfClass::Ehdr Ehdr;
+  typedef typename ElfClass::Phdr Phdr;
+
+  assert(elf_base);
+  assert(segment_start);
+  assert(segment_size);
+
+  assert(my_strncmp(elf_base, ELFMAG, SELFMAG) == 0);
+
+  const Ehdr* elf_header = reinterpret_cast<const Ehdr*>(elf_base);
+  assert(elf_header->e_ident[EI_CLASS] == ElfClass::kClass);
+
+  const Phdr* phdrs =
+    GetOffset<ElfClass,Phdr>(elf_header, elf_header->e_phoff);
+
+  for (int i = 0; i < elf_header->e_phnum; ++i) {
+    if (phdrs[i].p_type == segment_type) {
+      *segment_start = elf_base + phdrs[i].p_offset;
+      *segment_size = phdrs[i].p_filesz;
+      return;
+    }
+  }
+}
+
 }  // namespace
 
 bool IsValidElf(const void* elf_base) {
@@ -126,4 +155,40 @@
   return false;
 }
 
+bool FindElfSegment(const void *elf_mapped_base,
+                    uint32_t segment_type,
+                    const void **segment_start,
+                    int *segment_size,
+                    int *elfclass) {
+  assert(elf_mapped_base);
+  assert(segment_start);
+  assert(segment_size);
+
+  *segment_start = NULL;
+  *segment_size = 0;
+
+  if (!IsValidElf(elf_mapped_base))
+    return false;
+
+  int cls = ElfClass(elf_mapped_base);
+  if (elfclass) {
+    *elfclass = cls;
+  }
+
+  const char* elf_base =
+    static_cast<const char*>(elf_mapped_base);
+
+  if (cls == ELFCLASS32) {
+    FindElfClassSegment<ElfClass32>(elf_base, segment_type,
+                                    segment_start, segment_size);
+    return *segment_start != NULL;
+  } else if (cls == ELFCLASS64) {
+    FindElfClassSegment<ElfClass64>(elf_base, segment_type,
+                                    segment_start, segment_size);
+    return *segment_start != NULL;
+  }
+
+  return false;
+}
+
 }  // namespace google_breakpad
diff --git a/src/common/linux/elfutils.h b/src/common/linux/elfutils.h
index 748da98..fe12e25 100644
--- a/src/common/linux/elfutils.h
+++ b/src/common/linux/elfutils.h
@@ -93,6 +93,17 @@
                      const char* names_end,
                      int nsection);
 
+// Attempt to find the first segment of type |segment_type| in the ELF
+// binary data at |elf_mapped_base|. On success, returns true and sets
+// |*segment_start| to point to the start of the segment data, and
+// and |*segment_size| to the size of the segment's data. If |elfclass|
+// is not NULL, set |*elfclass| to the ELF file class.
+bool FindElfSegment(const void *elf_mapped_base,
+                    uint32_t segment_type,
+                    const void **segment_start,
+                    int *segment_size,
+                    int *elfclass);
+
 // Convert an offset from an Elf header into a pointer to the mapped
 // address in the current process. Takes an extra template parameter
 // to specify the return type to avoid having to dynamic_cast the
diff --git a/src/common/linux/file_id.cc b/src/common/linux/file_id.cc
index 4e380b0..e363178 100644
--- a/src/common/linux/file_id.cc
+++ b/src/common/linux/file_id.cc
@@ -40,6 +40,7 @@
 
 #include <algorithm>
 
+#include "common/linux/elf_gnu_compat.h"
 #include "common/linux/elfutils.h"
 #include "common/linux/linux_libc_support.h"
 #include "common/linux/memory_mapped_file.h"
@@ -47,30 +48,38 @@
 
 namespace google_breakpad {
 
-#ifndef NT_GNU_BUILD_ID
-#define NT_GNU_BUILD_ID 3
-#endif
-
 FileID::FileID(const char* path) {
   strncpy(path_, path, sizeof(path_));
 }
 
-// These six functions are also used inside the crashed process, so be safe
+// ELF note name and desc are 32-bits word padded.
+#define NOTE_PADDING(a) ((a + 3) & ~3)
+
+// These functions are also used inside the crashed process, so be safe
 // and use the syscall/libc wrappers instead of direct syscalls or libc.
 
 template<typename ElfClass>
-static bool ElfClassBuildIDNoteIdentifier(const void *section,
+static bool ElfClassBuildIDNoteIdentifier(const void *section, int length,
                                           uint8_t identifier[kMDGUIDSize]) {
   typedef typename ElfClass::Nhdr Nhdr;
 
+  const void* section_end = reinterpret_cast<const char*>(section) + length;
   const Nhdr* note_header = reinterpret_cast<const Nhdr*>(section);
-  if (note_header->n_type != NT_GNU_BUILD_ID ||
+  while (reinterpret_cast<const void *>(note_header) < section_end) {
+    if (note_header->n_type == NT_GNU_BUILD_ID)
+      break;
+    note_header = reinterpret_cast<const Nhdr*>(
+                  reinterpret_cast<const char*>(note_header) + sizeof(Nhdr) +
+                  NOTE_PADDING(note_header->n_namesz) +
+                  NOTE_PADDING(note_header->n_descsz));
+  }
+  if (reinterpret_cast<const void *>(note_header) >= section_end ||
       note_header->n_descsz == 0) {
     return false;
   }
 
-  const char* build_id = reinterpret_cast<const char*>(section) +
-    sizeof(Nhdr) + note_header->n_namesz;
+  const char* build_id = reinterpret_cast<const char*>(note_header) +
+    sizeof(Nhdr) + NOTE_PADDING(note_header->n_namesz);
   // Copy as many bits of the build ID as will fit
   // into the GUID space.
   my_memset(identifier, 0, kMDGUIDSize);
@@ -86,16 +95,21 @@
                                uint8_t identifier[kMDGUIDSize]) {
   void* note_section;
   int note_size, elfclass;
-  if (!FindElfSection(elf_mapped_base, ".note.gnu.build-id", SHT_NOTE,
-                      (const void**)&note_section, &note_size, &elfclass) ||
-      note_size == 0) {
+  if ((!FindElfSegment(elf_mapped_base, PT_NOTE,
+                       (const void**)&note_section, &note_size, &elfclass) ||
+      note_size == 0)  &&
+      (!FindElfSection(elf_mapped_base, ".note.gnu.build-id", SHT_NOTE,
+                       (const void**)&note_section, &note_size, &elfclass) ||
+      note_size == 0)) {
     return false;
   }
 
   if (elfclass == ELFCLASS32) {
-    return ElfClassBuildIDNoteIdentifier<ElfClass32>(note_section, identifier);
+    return ElfClassBuildIDNoteIdentifier<ElfClass32>(note_section, note_size,
+                                                     identifier);
   } else if (elfclass == ELFCLASS64) {
-    return ElfClassBuildIDNoteIdentifier<ElfClass64>(note_section, identifier);
+    return ElfClassBuildIDNoteIdentifier<ElfClass64>(note_section, note_size,
+                                                     identifier);
   }
 
   return false;
diff --git a/src/common/linux/file_id_unittest.cc b/src/common/linux/file_id_unittest.cc
index fa3af80..4bf4f8d 100644
--- a/src/common/linux/file_id_unittest.cc
+++ b/src/common/linux/file_id_unittest.cc
@@ -34,6 +34,8 @@
 
 #include <string>
 
+#include "common/linux/elf_gnu_compat.h"
+#include "common/linux/elfutils.h"
 #include "common/linux/file_id.h"
 #include "common/linux/safe_readlink.h"
 #include "common/linux/synth_elf.h"
@@ -43,11 +45,14 @@
 #include "breakpad_googletest_includes.h"
 
 using namespace google_breakpad;
+using google_breakpad::ElfClass32;
+using google_breakpad::ElfClass64;
 using google_breakpad::SafeReadLink;
-using google_breakpad::synth_elf::BuildIDNote;
 using google_breakpad::synth_elf::ELF;
+using google_breakpad::synth_elf::Notes;
 using google_breakpad::test_assembler::kLittleEndian;
 using google_breakpad::test_assembler::Section;
+using ::testing::Types;
 
 namespace {
 
@@ -94,6 +99,7 @@
   EXPECT_STREQ(identifier_string1, identifier_string2);
 }
 
+template<typename ElfClass>
 class FileIDTest : public testing::Test {
 public:
   void GetElfContents(ELF& elf) {
@@ -110,48 +116,35 @@
   uint8_t* elfdata;
 };
 
-TEST_F(FileIDTest, ElfClass) {
+typedef Types<ElfClass32, ElfClass64> ElfClasses;
+
+TYPED_TEST_CASE(FileIDTest, ElfClasses);
+
+TYPED_TEST(FileIDTest, ElfClass) {
   uint8_t identifier[sizeof(MDGUID)];
   const char expected_identifier_string[] =
       "80808080-8080-0000-0000-008080808080";
   char identifier_string[sizeof(expected_identifier_string)];
   const size_t kTextSectionSize = 128;
 
-  ELF elf32(EM_386, ELFCLASS32, kLittleEndian);
-  Section text32(kLittleEndian);
+  ELF elf(EM_386, TypeParam::kClass, kLittleEndian);
+  Section text(kLittleEndian);
   for (size_t i = 0; i < kTextSectionSize; ++i) {
-    text32.D8(i * 3);
+    text.D8(i * 3);
   }
-  elf32.AddSection(".text", text32, SHT_PROGBITS);
-  elf32.Finish();
-  GetElfContents(elf32);
+  elf.AddSection(".text", text, SHT_PROGBITS);
+  elf.Finish();
+  this->GetElfContents(elf);
 
-  EXPECT_TRUE(FileID::ElfFileIdentifierFromMappedFile(elfdata, identifier));
-
-  FileID::ConvertIdentifierToString(identifier, identifier_string,
-                                    sizeof(identifier_string));
-  EXPECT_STREQ(expected_identifier_string, identifier_string);
-
-  memset(identifier, 0, sizeof(identifier));
-  memset(identifier_string, 0, sizeof(identifier_string));
-
-  ELF elf64(EM_X86_64, ELFCLASS64, kLittleEndian);
-  Section text64(kLittleEndian);
-  for (size_t i = 0; i < kTextSectionSize; ++i) {
-    text64.D8(i * 3);
-  }
-  elf64.AddSection(".text", text64, SHT_PROGBITS);
-  elf64.Finish();
-  GetElfContents(elf64);
-
-  EXPECT_TRUE(FileID::ElfFileIdentifierFromMappedFile(elfdata, identifier));
+  EXPECT_TRUE(FileID::ElfFileIdentifierFromMappedFile(this->elfdata,
+                                                      identifier));
 
   FileID::ConvertIdentifierToString(identifier, identifier_string,
                                     sizeof(identifier_string));
   EXPECT_STREQ(expected_identifier_string, identifier_string);
 }
 
-TEST_F(FileIDTest, BuildID) {
+TYPED_TEST(FileIDTest, BuildID) {
   const uint8_t kExpectedIdentifier[sizeof(MDGUID)] =
     {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
      0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F};
@@ -164,35 +157,54 @@
   uint8_t identifier[sizeof(MDGUID)];
   char identifier_string[sizeof(expected_identifier_string)];
 
-  ELF elf32(EM_386, ELFCLASS32, kLittleEndian);
+  ELF elf(EM_386, TypeParam::kClass, kLittleEndian);
   Section text(kLittleEndian);
   text.Append(4096, 0);
-  elf32.AddSection(".text", text, SHT_PROGBITS);
-  BuildIDNote::AppendSection(elf32,
-                             kExpectedIdentifier,
-                             sizeof(kExpectedIdentifier));
-  elf32.Finish();
-  GetElfContents(elf32);
+  elf.AddSection(".text", text, SHT_PROGBITS);
+  Notes notes(kLittleEndian);
+  notes.AddNote(NT_GNU_BUILD_ID, "GNU", kExpectedIdentifier,
+                sizeof(kExpectedIdentifier));
+  elf.AddSection(".note.gnu.build-id", notes, SHT_NOTE);
+  elf.Finish();
+  this->GetElfContents(elf);
 
-  EXPECT_TRUE(FileID::ElfFileIdentifierFromMappedFile(elfdata, identifier));
+  EXPECT_TRUE(FileID::ElfFileIdentifierFromMappedFile(this->elfdata,
+                                                      identifier));
 
   FileID::ConvertIdentifierToString(identifier, identifier_string,
                                     sizeof(identifier_string));
   EXPECT_STREQ(expected_identifier_string, identifier_string);
+}
 
-  memset(identifier, 0, sizeof(identifier));
-  memset(identifier_string, 0, sizeof(identifier_string));
+TYPED_TEST(FileIDTest, BuildIDPH) {
+  const uint8_t kExpectedIdentifier[sizeof(MDGUID)] =
+    {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+     0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F};
+  char expected_identifier_string[] =
+    "00000000-0000-0000-0000-000000000000";
+  FileID::ConvertIdentifierToString(kExpectedIdentifier,
+                                    expected_identifier_string,
+                                    sizeof(expected_identifier_string));
 
-  ELF elf64(EM_X86_64, ELFCLASS64, kLittleEndian);
-  // Re-use empty text section from previous test
-  elf64.AddSection(".text", text, SHT_PROGBITS);
-  BuildIDNote::AppendSection(elf64,
-                             kExpectedIdentifier,
-                             sizeof(kExpectedIdentifier));
-  elf64.Finish();
-  GetElfContents(elf64);
+  uint8_t identifier[sizeof(MDGUID)];
+  char identifier_string[sizeof(expected_identifier_string)];
 
-  EXPECT_TRUE(FileID::ElfFileIdentifierFromMappedFile(elfdata, identifier));
+  ELF elf(EM_386, TypeParam::kClass, kLittleEndian);
+  Section text(kLittleEndian);
+  text.Append(4096, 0);
+  elf.AddSection(".text", text, SHT_PROGBITS);
+  Notes notes(kLittleEndian);
+  notes.AddNote(0, "Linux",
+                reinterpret_cast<const uint8_t *>("\0x42\0x02\0\0"), 4);
+  notes.AddNote(NT_GNU_BUILD_ID, "GNU", kExpectedIdentifier,
+                sizeof(kExpectedIdentifier));
+  int note_idx = elf.AddSection(".note", notes, SHT_NOTE);
+  elf.AddSegment(note_idx, note_idx, PT_NOTE);
+  elf.Finish();
+  this->GetElfContents(elf);
+
+  EXPECT_TRUE(FileID::ElfFileIdentifierFromMappedFile(this->elfdata,
+                                                      identifier));
 
   FileID::ConvertIdentifierToString(identifier, identifier_string,
                                     sizeof(identifier_string));
@@ -201,7 +213,7 @@
 
 // Test to make sure two files with different text sections produce
 // different hashes when not using a build id.
-TEST_F(FileIDTest, UniqueHashes32) {
+TYPED_TEST(FileIDTest, UniqueHashes) {
   char identifier_string_1[] =
     "00000000-0000-0000-0000-000000000000";
   char identifier_string_2[] =
@@ -210,7 +222,7 @@
   uint8_t identifier_2[sizeof(MDGUID)];
 
   {
-    ELF elf1(EM_386, ELFCLASS32, kLittleEndian);
+    ELF elf1(EM_386, TypeParam::kClass, kLittleEndian);
     Section foo_1(kLittleEndian);
     PopulateSection(&foo_1, 32, 5);
     elf1.AddSection(".foo", foo_1, SHT_PROGBITS);
@@ -218,15 +230,16 @@
     PopulateSection(&text_1, 4096, 17);
     elf1.AddSection(".text", text_1, SHT_PROGBITS);
     elf1.Finish();
-    GetElfContents(elf1);
+    this->GetElfContents(elf1);
   }
 
-  EXPECT_TRUE(FileID::ElfFileIdentifierFromMappedFile(elfdata, identifier_1));
+  EXPECT_TRUE(FileID::ElfFileIdentifierFromMappedFile(this->elfdata,
+                                                      identifier_1));
   FileID::ConvertIdentifierToString(identifier_1, identifier_string_1,
                                     sizeof(identifier_string_1));
 
   {
-    ELF elf2(EM_386, ELFCLASS32, kLittleEndian);
+    ELF elf2(EM_386, TypeParam::kClass, kLittleEndian);
     Section text_2(kLittleEndian);
     Section foo_2(kLittleEndian);
     PopulateSection(&foo_2, 32, 5);
@@ -234,54 +247,11 @@
     PopulateSection(&text_2, 4096, 31);
     elf2.AddSection(".text", text_2, SHT_PROGBITS);
     elf2.Finish();
-    GetElfContents(elf2);
+    this->GetElfContents(elf2);
   }
 
-  EXPECT_TRUE(FileID::ElfFileIdentifierFromMappedFile(elfdata, identifier_2));
-  FileID::ConvertIdentifierToString(identifier_2, identifier_string_2,
-                                    sizeof(identifier_string_2));
-
-  EXPECT_STRNE(identifier_string_1, identifier_string_2);
-}
-
-// Same as UniqueHashes32, for x86-64.
-TEST_F(FileIDTest, UniqueHashes64) {
-  char identifier_string_1[] =
-    "00000000-0000-0000-0000-000000000000";
-  char identifier_string_2[] =
-    "00000000-0000-0000-0000-000000000000";
-  uint8_t identifier_1[sizeof(MDGUID)];
-  uint8_t identifier_2[sizeof(MDGUID)];
-
-  {
-    ELF elf1(EM_X86_64, ELFCLASS64, kLittleEndian);
-    Section foo_1(kLittleEndian);
-    PopulateSection(&foo_1, 32, 5);
-    elf1.AddSection(".foo", foo_1, SHT_PROGBITS);
-    Section text_1(kLittleEndian);
-    PopulateSection(&text_1, 4096, 17);
-    elf1.AddSection(".text", text_1, SHT_PROGBITS);
-    elf1.Finish();
-    GetElfContents(elf1);
-  }
-
-  EXPECT_TRUE(FileID::ElfFileIdentifierFromMappedFile(elfdata, identifier_1));
-  FileID::ConvertIdentifierToString(identifier_1, identifier_string_1,
-                                    sizeof(identifier_string_1));
-
-  {
-    ELF elf2(EM_X86_64, ELFCLASS64, kLittleEndian);
-    Section text_2(kLittleEndian);
-    Section foo_2(kLittleEndian);
-    PopulateSection(&foo_2, 32, 5);
-    elf2.AddSection(".foo", foo_2, SHT_PROGBITS);
-    PopulateSection(&text_2, 4096, 31);
-    elf2.AddSection(".text", text_2, SHT_PROGBITS);
-    elf2.Finish();
-    GetElfContents(elf2);
-  }
-
-  EXPECT_TRUE(FileID::ElfFileIdentifierFromMappedFile(elfdata, identifier_2));
+  EXPECT_TRUE(FileID::ElfFileIdentifierFromMappedFile(this->elfdata,
+                                                      identifier_2));
   FileID::ConvertIdentifierToString(identifier_2, identifier_string_2,
                                     sizeof(identifier_string_2));
 
diff --git a/src/common/linux/guid_creator.cc b/src/common/linux/guid_creator.cc
index 426f93a..bfb308e 100644
--- a/src/common/linux/guid_creator.cc
+++ b/src/common/linux/guid_creator.cc
@@ -46,14 +46,14 @@
 //
 class GUIDGenerator {
  public:
-  static u_int32_t BytesToUInt32(const u_int8_t bytes[]) {
-    return ((u_int32_t) bytes[0]
-            | ((u_int32_t) bytes[1] << 8)
-            | ((u_int32_t) bytes[2] << 16)
-            | ((u_int32_t) bytes[3] << 24));
+  static uint32_t BytesToUInt32(const uint8_t bytes[]) {
+    return ((uint32_t) bytes[0]
+            | ((uint32_t) bytes[1] << 8)
+            | ((uint32_t) bytes[2] << 16)
+            | ((uint32_t) bytes[3] << 24));
   }
 
-  static void UInt32ToBytes(u_int8_t bytes[], u_int32_t n) {
+  static void UInt32ToBytes(uint8_t bytes[], uint32_t n) {
     bytes[0] = n & 0xff;
     bytes[1] = (n >> 8) & 0xff;
     bytes[2] = (n >> 16) & 0xff;
@@ -63,8 +63,8 @@
   static bool CreateGUID(GUID *guid) {
     InitOnce();
     guid->data1 = random();
-    guid->data2 = (u_int16_t)(random());
-    guid->data3 = (u_int16_t)(random());
+    guid->data2 = (uint16_t)(random());
+    guid->data3 = (uint16_t)(random());
     UInt32ToBytes(&guid->data4[0], random());
     UInt32ToBytes(&guid->data4[4], random());
     return true;
diff --git a/src/common/linux/memory_mapped_file.cc b/src/common/linux/memory_mapped_file.cc
index 47b7eb0..853cce5 100644
--- a/src/common/linux/memory_mapped_file.cc
+++ b/src/common/linux/memory_mapped_file.cc
@@ -97,7 +97,7 @@
 
 void MemoryMappedFile::Unmap() {
   if (content_.data()) {
-    sys_munmap(const_cast<u_int8_t*>(content_.data()), content_.length());
+    sys_munmap(const_cast<uint8_t*>(content_.data()), content_.length());
     content_.Set(NULL, 0);
   }
 }
diff --git a/src/common/linux/synth_elf.cc b/src/common/linux/synth_elf.cc
index afaea02..b978550 100644
--- a/src/common/linux/synth_elf.cc
+++ b/src/common/linux/synth_elf.cc
@@ -5,21 +5,19 @@
 #include <stdio.h>
 #include <string.h>
 
+#include "common/linux/elf_gnu_compat.h"
 #include "common/using_std_string.h"
 
 namespace google_breakpad {
 namespace synth_elf {
 
-#ifndef NT_GNU_BUILD_ID
-#define NT_GNU_BUILD_ID 3
-#endif
-
 ELF::ELF(uint16_t machine,
          uint8_t file_class,
          Endianness endianness)
   : Section(endianness),
     addr_size_(file_class == ELFCLASS64 ? 8 : 4),
     program_count_(0),
+    program_header_table_(endianness),
     section_count_(0),
     section_header_table_(endianness),
     section_header_strings_(endianness) {
@@ -115,18 +113,75 @@
     // sh_entsize
     .Append(endianness(), addr_size_, entsize);
 
+  sections_.push_back(ElfSection(section, type, addr, offset, offset_label,
+                                 size));
+  return index;
+}
+
+void ELF::AppendSection(ElfSection &section) {
   // NULL and NOBITS sections have no content, so they
   // don't need to be written to the file.
-  if (type == SHT_NULL) {
-    offset_label = 0;
-  } else if (type == SHT_NOBITS) {
-    offset_label = offset;
+  if (section.type_ == SHT_NULL) {
+    section.offset_label_ = 0;
+  } else if (section.type_ == SHT_NOBITS) {
+    section.offset_label_ = section.offset_;
   } else {
-    Mark(&offset_label);
+    Mark(&section.offset_label_);
     Append(section);
     Align(4);
   }
-  return index;
+}
+
+void ELF::AddSegment(int start, int end, uint32_t type, uint32_t flags) {
+  assert(start > 0);
+  assert(size_t(start) < sections_.size());
+  assert(end > 0);
+  assert(size_t(end) < sections_.size());
+  ++program_count_;
+
+  // p_type
+  program_header_table_.D32(type);
+
+  if (addr_size_ == 8) {
+    // p_flags
+    program_header_table_.D32(flags);
+  }
+
+  size_t filesz = 0;
+  size_t memsz = 0;
+  bool prev_was_nobits = false;
+  for (int i = start; i <= end; ++i) {
+    size_t size = sections_[i].size_;
+    if (sections_[i].type_ != SHT_NOBITS) {
+      assert(!prev_was_nobits);
+      // non SHT_NOBITS sections are 4-byte aligned (see AddSection)
+      size = (size + 3) & ~3;
+      filesz += size;
+    } else {
+      prev_was_nobits = true;
+    }
+    memsz += size;
+  }
+
+  program_header_table_
+    // p_offset
+    .Append(endianness(), addr_size_, sections_[start].offset_label_)
+    // p_vaddr
+    .Append(endianness(), addr_size_, sections_[start].addr_)
+    // p_paddr
+    .Append(endianness(), addr_size_, sections_[start].addr_)
+    // p_filesz
+    .Append(endianness(), addr_size_, filesz)
+    // p_memsz
+    .Append(endianness(), addr_size_, memsz);
+
+  if (addr_size_ == 4) {
+    // p_flags
+    program_header_table_.D32(flags);
+  }
+
+  // p_align
+  program_header_table_.Append(endianness(), addr_size_, 0);
 }
 
 void ELF::Finish() {
@@ -136,10 +191,19 @@
   AddSection(".shstrtab", section_header_strings_, SHT_STRTAB);
   //printf("section_count_: %ld, sections_.size(): %ld\n",
   //     section_count_, sections_.size());
+  if (program_count_) {
+    Mark(&program_header_label_);
+    Append(program_header_table_);
+  } else {
+    program_header_label_ = 0;
+  }
+
+  for (vector<ElfSection>::iterator it = sections_.begin();
+       it < sections_.end(); ++it) {
+    AppendSection(*it);
+  }
   section_count_label_ = section_count_;
   program_count_label_ = program_count_;
-  // TODO:  allow adding entries to program header table
-  program_header_label_ = 0;
 
   // Section header table starts here.
   Mark(&section_header_label_);
@@ -176,30 +240,21 @@
   D64(size);
 }
 
-BuildIDNote::BuildIDNote(const uint8_t* id_bytes,
-                         size_t id_size,
-                         Endianness endianness) : Section(endianness) {
-  const char kNoteName[] = "GNU";
+void Notes::AddNote(int type, const string &name, const uint8_t* desc_bytes,
+                    size_t desc_size) {
   // Elf32_Nhdr and Elf64_Nhdr are exactly the same.
   Elf32_Nhdr note_header;
   memset(&note_header, 0, sizeof(note_header));
-  note_header.n_namesz = sizeof(kNoteName);
-  note_header.n_descsz = id_size;
-  note_header.n_type = NT_GNU_BUILD_ID;
+  note_header.n_namesz = name.length() + 1;
+  note_header.n_descsz = desc_size;
+  note_header.n_type = type;
 
   Append(reinterpret_cast<const uint8_t*>(&note_header),
          sizeof(note_header));
-  AppendCString(kNoteName);
-  Append(id_bytes, id_size);
-}
-
-// static
-void BuildIDNote::AppendSection(ELF& elf,
-                                const uint8_t* id_bytes,
-                                size_t id_size) {
-  const char kBuildIDSectionName[] = ".note.gnu.build-id";
-  BuildIDNote note(id_bytes, id_size, elf.endianness());
-  elf.AddSection(kBuildIDSectionName, note, SHT_NOTE);
+  AppendCString(name);
+  Align(4);
+  Append(desc_bytes, desc_size);
+  Align(4);
 }
 
 }  // namespace synth_elf
diff --git a/src/common/linux/synth_elf.h b/src/common/linux/synth_elf.h
index 1fbe749..330ceae 100644
--- a/src/common/linux/synth_elf.h
+++ b/src/common/linux/synth_elf.h
@@ -39,6 +39,7 @@
 #include "common/test_assembler.h"
 
 #include <list>
+#include <vector>
 #include <map>
 #include <string>
 #include <utility>
@@ -49,6 +50,7 @@
 namespace synth_elf {
 
 using std::list;
+using std::vector;
 using std::map;
 using std::pair;
 using test_assembler::Endianness;
@@ -102,6 +104,10 @@
                  uint32_t type, uint32_t flags = 0, uint64_t addr = 0,
                  uint32_t link = 0, uint64_t entsize = 0, uint64_t offset = 0);
                   
+  // Add a segment containing from section index start to section index end.
+  // The indexes must have been gotten from AddSection.
+  void AddSegment(int start, int end, uint32_t type, uint32_t flags = 0);
+
   // Write out all data. GetContents may be used after this.
   void Finish();
 
@@ -114,6 +120,8 @@
   // Number of entries in the program header table.
   int program_count_;
   Label program_count_label_;
+  // The program header table itself.
+  Section program_header_table_;
 
   // Offset to the section header table.
   Label section_header_label_;
@@ -128,6 +136,25 @@
   Label section_header_string_index_;
   // Section containing the names of section header table entries.
   StringTable section_header_strings_;
+
+  // Record of an added section
+  struct ElfSection : public Section {
+    ElfSection(const Section& section, uint32_t type, uint32_t addr,
+               uint32_t offset, Label offset_label, uint32_t size)
+    : Section(section), type_(type), addr_(addr), offset_(offset)
+    , offset_label_(offset_label), size_(size) {
+    }
+
+    uint32_t type_;
+    uint32_t addr_;
+    uint32_t offset_;
+    Label offset_label_;
+    uint32_t size_;
+  };
+
+  vector<ElfSection> sections_;
+
+  void AppendSection(ElfSection &section);
 };
 
 // A class to build .symtab or .dynsym sections.
@@ -150,13 +177,16 @@
   StringTable& table_;
 };
 
-// A class to build GNU Build ID note sections
-class BuildIDNote : public Section {
+// A class for note sections
+class Notes : public Section {
 public:
-  BuildIDNote(const uint8_t* id_bytes, size_t id_size, Endianness endianness);
+  Notes(Endianness endianness)
+  : Section(endianness) {
+  }
 
-  // Append a new Build ID note section to |elf|.
-  static void AppendSection(ELF& elf, const uint8_t* id_bytes, size_t id_size);
+  // Add a note.
+  void AddNote(int type, const string &name, const uint8_t* desc_bytes,
+               size_t desc_size);
 };
 
 }  // namespace synth_elf
diff --git a/src/common/linux/synth_elf_unittest.cc b/src/common/linux/synth_elf_unittest.cc
index 34a00ca..3715b6e 100644
--- a/src/common/linux/synth_elf_unittest.cc
+++ b/src/common/linux/synth_elf_unittest.cc
@@ -35,10 +35,15 @@
 #include <elf.h>
 
 #include "breakpad_googletest_includes.h"
+#include "common/linux/elfutils.h"
 #include "common/linux/synth_elf.h"
 #include "common/using_std_string.h"
 
+using google_breakpad::ElfClass32;
+using google_breakpad::ElfClass64;
 using google_breakpad::synth_elf::ELF;
+using google_breakpad::synth_elf::Notes;
+using google_breakpad::synth_elf::Section;
 using google_breakpad::synth_elf::StringTable;
 using google_breakpad::synth_elf::SymbolTable;
 using google_breakpad::test_assembler::Endianness;
@@ -46,6 +51,7 @@
 using google_breakpad::test_assembler::kLittleEndian;
 using google_breakpad::test_assembler::Label;
 using ::testing::Test;
+using ::testing::Types;
 
 class StringTableTest : public Test {
 public:
@@ -178,32 +184,41 @@
                       symbol_contents.size()));
 }
 
+template<typename ElfClass>
 class BasicElf : public Test {};
 
 // Doesn't seem worthwhile writing the tests to be endian-independent
 // when they're unlikely to ever be run on big-endian systems.
 #if defined(__i386__) || defined(__x86_64__)
 
-TEST_F(BasicElf, EmptyLE32) {
+typedef Types<ElfClass32, ElfClass64> ElfClasses;
+
+TYPED_TEST_CASE(BasicElf, ElfClasses);
+
+TYPED_TEST(BasicElf, EmptyLE) {
+  typedef typename TypeParam::Ehdr Ehdr;
+  typedef typename TypeParam::Phdr Phdr;
+  typedef typename TypeParam::Shdr Shdr;
   const size_t kStringTableSize = sizeof("\0.shstrtab");
   const size_t kStringTableAlign = 4 - kStringTableSize % 4;
-  const size_t kExpectedSize = sizeof(Elf32_Ehdr) +
+  const size_t kExpectedSize = sizeof(Ehdr) +
     // Two sections, SHT_NULL + the section header string table.
-    2 * sizeof(Elf32_Shdr) +
+    2 * sizeof(Shdr) +
     kStringTableSize + kStringTableAlign;
 
-  ELF elf(EM_386, ELFCLASS32, kLittleEndian);
+  // It doesn't really matter that the machine type is right for the class.
+  ELF elf(EM_386, TypeParam::kClass, kLittleEndian);
   elf.Finish();
   EXPECT_EQ(kExpectedSize, elf.Size());
 
   string contents;
   ASSERT_TRUE(elf.GetContents(&contents));
   ASSERT_EQ(kExpectedSize, contents.size());
-  const Elf32_Ehdr* header =
-    reinterpret_cast<const Elf32_Ehdr*>(contents.data());
+  const Ehdr* header =
+    reinterpret_cast<const Ehdr*>(contents.data());
   const uint8_t kIdent[] = {
     ELFMAG0, ELFMAG1, ELFMAG2, ELFMAG3,
-    ELFCLASS32, ELFDATA2LSB, EV_CURRENT, ELFOSABI_SYSV,
+    TypeParam::kClass, ELFDATA2LSB, EV_CURRENT, ELFOSABI_SYSV,
     0, 0, 0, 0, 0, 0, 0, 0
   };
   EXPECT_EQ(0, memcmp(kIdent, header->e_ident, sizeof(kIdent)));
@@ -212,54 +227,187 @@
   EXPECT_EQ(static_cast<unsigned int>(EV_CURRENT), header->e_version);
   EXPECT_EQ(0U, header->e_entry);
   EXPECT_EQ(0U, header->e_phoff);
-  EXPECT_EQ(sizeof(Elf32_Ehdr) + kStringTableSize + kStringTableAlign,
+  EXPECT_EQ(sizeof(Ehdr) + kStringTableSize + kStringTableAlign,
             header->e_shoff);
   EXPECT_EQ(0U, header->e_flags);
-  EXPECT_EQ(sizeof(Elf32_Ehdr), header->e_ehsize);
-  EXPECT_EQ(sizeof(Elf32_Phdr), header->e_phentsize);
+  EXPECT_EQ(sizeof(Ehdr), header->e_ehsize);
+  EXPECT_EQ(sizeof(Phdr), header->e_phentsize);
   EXPECT_EQ(0, header->e_phnum);
-  EXPECT_EQ(sizeof(Elf32_Shdr), header->e_shentsize);
+  EXPECT_EQ(sizeof(Shdr), header->e_shentsize);
   EXPECT_EQ(2, header->e_shnum);
   EXPECT_EQ(1, header->e_shstrndx);
+
+  const Shdr* shdr =
+    reinterpret_cast<const Shdr*>(contents.data() + header->e_shoff);
+  EXPECT_EQ(0U, shdr[0].sh_name);
+  EXPECT_EQ(static_cast<unsigned int>(SHT_NULL), shdr[0].sh_type);
+  EXPECT_EQ(0U, shdr[0].sh_flags);
+  EXPECT_EQ(0U, shdr[0].sh_addr);
+  EXPECT_EQ(0U, shdr[0].sh_offset);
+  EXPECT_EQ(0U, shdr[0].sh_size);
+  EXPECT_EQ(0U, shdr[0].sh_link);
+  EXPECT_EQ(0U, shdr[0].sh_info);
+  EXPECT_EQ(0U, shdr[0].sh_addralign);
+  EXPECT_EQ(0U, shdr[0].sh_entsize);
+
+  EXPECT_EQ(1U, shdr[1].sh_name);
+  EXPECT_EQ(static_cast<unsigned int>(SHT_STRTAB), shdr[1].sh_type);
+  EXPECT_EQ(0U, shdr[1].sh_flags);
+  EXPECT_EQ(0U, shdr[1].sh_addr);
+  EXPECT_EQ(sizeof(Ehdr), shdr[1].sh_offset);
+  EXPECT_EQ(kStringTableSize, shdr[1].sh_size);
+  EXPECT_EQ(0U, shdr[1].sh_link);
+  EXPECT_EQ(0U, shdr[1].sh_info);
+  EXPECT_EQ(0U, shdr[1].sh_addralign);
+  EXPECT_EQ(0U, shdr[1].sh_entsize);
 }
 
-TEST_F(BasicElf, EmptyLE64) {
-  const size_t kStringTableSize = sizeof("\0.shstrtab");
+TYPED_TEST(BasicElf, BasicLE) {
+  typedef typename TypeParam::Ehdr Ehdr;
+  typedef typename TypeParam::Phdr Phdr;
+  typedef typename TypeParam::Shdr Shdr;
+  const size_t kStringTableSize = sizeof("\0.text\0.bss\0.shstrtab");
   const size_t kStringTableAlign = 4 - kStringTableSize % 4;
-  const size_t kExpectedSize = sizeof(Elf64_Ehdr) +
-    // Two sections, SHT_NULL + the section header string table.
-    2 * sizeof(Elf64_Shdr) +
+  const size_t kExpectedSize = sizeof(Ehdr) +
+    // Four sections, SHT_NULL + the section header string table +
+    // 4096 bytes of the size-aligned .text section + one program header.
+    sizeof(Phdr) + 4 * sizeof(Shdr) + 4096 +
     kStringTableSize + kStringTableAlign;
 
-  ELF elf(EM_X86_64, ELFCLASS64, kLittleEndian);
+  // It doesn't really matter that the machine type is right for the class.
+  ELF elf(EM_386, TypeParam::kClass, kLittleEndian);
+  Section text(kLittleEndian);
+  text.Append(4094, 0);
+  int text_idx = elf.AddSection(".text", text, SHT_PROGBITS);
+  Section bss(kLittleEndian);
+  bss.Append(16, 0);
+  int bss_idx = elf.AddSection(".bss", bss, SHT_NOBITS);
+  elf.AddSegment(text_idx, bss_idx, PT_LOAD);
   elf.Finish();
   EXPECT_EQ(kExpectedSize, elf.Size());
 
   string contents;
   ASSERT_TRUE(elf.GetContents(&contents));
   ASSERT_EQ(kExpectedSize, contents.size());
-  const Elf64_Ehdr* header =
-    reinterpret_cast<const Elf64_Ehdr*>(contents.data());
+  const Ehdr* header =
+    reinterpret_cast<const Ehdr*>(contents.data());
   const uint8_t kIdent[] = {
     ELFMAG0, ELFMAG1, ELFMAG2, ELFMAG3,
-    ELFCLASS64, ELFDATA2LSB, EV_CURRENT, ELFOSABI_SYSV,
+    TypeParam::kClass, ELFDATA2LSB, EV_CURRENT, ELFOSABI_SYSV,
     0, 0, 0, 0, 0, 0, 0, 0
   };
   EXPECT_EQ(0, memcmp(kIdent, header->e_ident, sizeof(kIdent)));
   EXPECT_EQ(ET_EXEC, header->e_type);
-  EXPECT_EQ(EM_X86_64, header->e_machine);
+  EXPECT_EQ(EM_386, header->e_machine);
   EXPECT_EQ(static_cast<unsigned int>(EV_CURRENT), header->e_version);
   EXPECT_EQ(0U, header->e_entry);
-  EXPECT_EQ(0U, header->e_phoff);
-  EXPECT_EQ(sizeof(Elf64_Ehdr) + kStringTableSize + kStringTableAlign,
-            header->e_shoff);
+  EXPECT_EQ(sizeof(Ehdr), header->e_phoff);
+  EXPECT_EQ(sizeof(Ehdr) + sizeof(Phdr) + 4096 + kStringTableSize +
+            kStringTableAlign, header->e_shoff);
   EXPECT_EQ(0U, header->e_flags);
-  EXPECT_EQ(sizeof(Elf64_Ehdr), header->e_ehsize);
-  EXPECT_EQ(sizeof(Elf64_Phdr), header->e_phentsize);
-  EXPECT_EQ(0, header->e_phnum);
-  EXPECT_EQ(sizeof(Elf64_Shdr), header->e_shentsize);
-  EXPECT_EQ(2, header->e_shnum);
-  EXPECT_EQ(1, header->e_shstrndx);
+  EXPECT_EQ(sizeof(Ehdr), header->e_ehsize);
+  EXPECT_EQ(sizeof(Phdr), header->e_phentsize);
+  EXPECT_EQ(1, header->e_phnum);
+  EXPECT_EQ(sizeof(Shdr), header->e_shentsize);
+  EXPECT_EQ(4, header->e_shnum);
+  EXPECT_EQ(3, header->e_shstrndx);
+
+  const Shdr* shdr =
+    reinterpret_cast<const Shdr*>(contents.data() + header->e_shoff);
+  EXPECT_EQ(0U, shdr[0].sh_name);
+  EXPECT_EQ(static_cast<unsigned int>(SHT_NULL), shdr[0].sh_type);
+  EXPECT_EQ(0U, shdr[0].sh_flags);
+  EXPECT_EQ(0U, shdr[0].sh_addr);
+  EXPECT_EQ(0U, shdr[0].sh_offset);
+  EXPECT_EQ(0U, shdr[0].sh_size);
+  EXPECT_EQ(0U, shdr[0].sh_link);
+  EXPECT_EQ(0U, shdr[0].sh_info);
+  EXPECT_EQ(0U, shdr[0].sh_addralign);
+  EXPECT_EQ(0U, shdr[0].sh_entsize);
+
+  EXPECT_EQ(1U, shdr[1].sh_name);
+  EXPECT_EQ(static_cast<unsigned int>(SHT_PROGBITS), shdr[1].sh_type);
+  EXPECT_EQ(0U, shdr[1].sh_flags);
+  EXPECT_EQ(0U, shdr[1].sh_addr);
+  EXPECT_EQ(sizeof(Ehdr) + sizeof(Phdr), shdr[1].sh_offset);
+  EXPECT_EQ(4094U, shdr[1].sh_size);
+  EXPECT_EQ(0U, shdr[1].sh_link);
+  EXPECT_EQ(0U, shdr[1].sh_info);
+  EXPECT_EQ(0U, shdr[1].sh_addralign);
+  EXPECT_EQ(0U, shdr[1].sh_entsize);
+
+  EXPECT_EQ(sizeof("\0.text"), shdr[2].sh_name);
+  EXPECT_EQ(static_cast<unsigned int>(SHT_NOBITS), shdr[2].sh_type);
+  EXPECT_EQ(0U, shdr[2].sh_flags);
+  EXPECT_EQ(0U, shdr[2].sh_addr);
+  EXPECT_EQ(0U, shdr[2].sh_offset);
+  EXPECT_EQ(16U, shdr[2].sh_size);
+  EXPECT_EQ(0U, shdr[2].sh_link);
+  EXPECT_EQ(0U, shdr[2].sh_info);
+  EXPECT_EQ(0U, shdr[2].sh_addralign);
+  EXPECT_EQ(0U, shdr[2].sh_entsize);
+
+  EXPECT_EQ(sizeof("\0.text\0.bss"), shdr[3].sh_name);
+  EXPECT_EQ(static_cast<unsigned int>(SHT_STRTAB), shdr[3].sh_type);
+  EXPECT_EQ(0U, shdr[3].sh_flags);
+  EXPECT_EQ(0U, shdr[3].sh_addr);
+  EXPECT_EQ(sizeof(Ehdr) + sizeof(Phdr) + 4096, shdr[3].sh_offset);
+  EXPECT_EQ(kStringTableSize, shdr[3].sh_size);
+  EXPECT_EQ(0U, shdr[3].sh_link);
+  EXPECT_EQ(0U, shdr[3].sh_info);
+  EXPECT_EQ(0U, shdr[3].sh_addralign);
+  EXPECT_EQ(0U, shdr[3].sh_entsize);
+
+  const Phdr* phdr =
+    reinterpret_cast<const Phdr*>(contents.data() + header->e_phoff);
+  EXPECT_EQ(static_cast<unsigned int>(PT_LOAD), phdr->p_type);
+  EXPECT_EQ(sizeof(Ehdr) + sizeof(Phdr), phdr->p_offset);
+  EXPECT_EQ(0U, phdr->p_vaddr);
+  EXPECT_EQ(0U, phdr->p_paddr);
+  EXPECT_EQ(4096U, phdr->p_filesz);
+  EXPECT_EQ(4096U + 16U, phdr->p_memsz);
+  EXPECT_EQ(0U, phdr->p_flags);
+  EXPECT_EQ(0U, phdr->p_align);
+}
+
+class ElfNotesTest : public Test {};
+
+TEST_F(ElfNotesTest, Empty) {
+  Notes notes(kLittleEndian);
+  string contents;
+  ASSERT_TRUE(notes.GetContents(&contents));
+  EXPECT_EQ(0U, contents.size());
+}
+
+TEST_F(ElfNotesTest, Notes) {
+  Notes notes(kLittleEndian);
+  notes.AddNote(1, "Linux", reinterpret_cast<const uint8_t *>("\x42\x02\0\0"),
+                4);
+  notes.AddNote(2, "a", reinterpret_cast<const uint8_t *>("foobar"),
+                sizeof("foobar") - 1);
+
+  const uint8_t kExpectedNotesContents[] = {
+    // Note 1
+    0x06, 0x00, 0x00, 0x00, // name size, including terminating zero
+    0x04, 0x00, 0x00, 0x00, // desc size
+    0x01, 0x00, 0x00, 0x00, // type
+    'L', 'i', 'n', 'u', 'x', 0x00, 0x00, 0x00, // padded "Linux"
+    0x42, 0x02, 0x00, 0x00, // desc
+    // Note 2
+    0x02, 0x00, 0x00, 0x00, // name size
+    0x06, 0x00, 0x00, 0x00, // desc size
+    0x02, 0x00, 0x00, 0x00, // type
+    'a',  0x00, 0x00, 0x00, // padded "a"
+    'f', 'o', 'o', 'b', 'a', 'r', 0x00, 0x00, // padded "foobar"
+  };
+  const size_t kExpectedNotesSize = sizeof(kExpectedNotesContents);
+  EXPECT_EQ(kExpectedNotesSize, notes.Size());
+
+  string notes_contents;
+  ASSERT_TRUE(notes.GetContents(&notes_contents));
+  EXPECT_EQ(0, memcmp(kExpectedNotesContents,
+                      notes_contents.data(),
+                      notes_contents.size()));
 }
 
 #endif  // defined(__i386__) || defined(__x86_64__)
diff --git a/src/common/mac/MachIPC.h b/src/common/mac/MachIPC.h
index 52bed59..8df9165 100644
--- a/src/common/mac/MachIPC.h
+++ b/src/common/mac/MachIPC.h
@@ -164,11 +164,11 @@
  public:
 
   // The receiver of the message can retrieve the raw data this way
-  u_int8_t *GetData() {
+  uint8_t *GetData() {
     return GetDataLength() > 0 ? GetDataPacket()->data : NULL;
   }
 
-  u_int32_t GetDataLength() {
+  uint32_t GetDataLength() {
     return EndianU32_LtoN(GetDataPacket()->data_length);
   }
 
@@ -210,7 +210,7 @@
   struct MessageDataPacket {
     int32_t      id;          // little-endian
     int32_t      data_length; // little-endian
-    u_int8_t     data[1];     // actual size limited by sizeof(MachMessage)
+    uint8_t      data[1];     // actual size limited by sizeof(MachMessage)
   };
 
   MessageDataPacket* GetDataPacket();
@@ -223,7 +223,7 @@
 
   mach_msg_header_t  head;
   mach_msg_body_t    body;
-  u_int8_t           padding[1024]; // descriptors and data may be embedded here
+  uint8_t            padding[1024]; // descriptors and data may be embedded here
 };
 
 //==============================================================================
diff --git a/src/common/mac/dump_syms.h b/src/common/mac/dump_syms.h
index 0e2f464..f7d391f 100644
--- a/src/common/mac/dump_syms.h
+++ b/src/common/mac/dump_syms.h
@@ -47,13 +47,15 @@
 #include "common/byte_cursor.h"
 #include "common/mac/macho_reader.h"
 #include "common/module.h"
+#include "common/symbol_data.h"
 
 namespace google_breakpad {
 
 class DumpSymbols {
  public:
-  DumpSymbols()
-      : input_pathname_(),
+  explicit DumpSymbols(SymbolData symbol_data)
+      : symbol_data_(symbol_data),
+        input_pathname_(),
         object_filename_(),
         contents_(),
         selected_object_file_(),
@@ -110,9 +112,14 @@
   }
 
   // Read the selected object file's debugging information, and write it out to
-  // |stream|. Write the CFI section if |cfi| is true. Return true on success;
-  // if an error occurs, report it and return false.
-  bool WriteSymbolFile(std::ostream &stream, bool cfi);
+  // |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.
@@ -139,6 +146,9 @@
                const mach_o::Section &section,
                bool eh_frame) const;
 
+  // The selection of what type of symbol data to read/write.
+  const SymbolData symbol_data_;
+
   // 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_;
diff --git a/src/common/mac/dump_syms.mm b/src/common/mac/dump_syms.mm
index d79afe2..cd19f72 100644
--- a/src/common/mac/dump_syms.mm
+++ b/src/common/mac/dump_syms.mm
@@ -53,8 +53,10 @@
 #include "common/mac/arch_utilities.h"
 #include "common/mac/macho_reader.h"
 #include "common/module.h"
+#include "common/scoped_ptr.h"
 #include "common/stabs_reader.h"
 #include "common/stabs_to_module.h"
+#include "common/symbol_data.h"
 
 #ifndef CPU_TYPE_ARM
 #define CPU_TYPE_ARM (static_cast<cpu_type_t>(12))
@@ -70,6 +72,7 @@
 using google_breakpad::Module;
 using google_breakpad::StabsReader;
 using google_breakpad::StabsToModule;
+using google_breakpad::scoped_ptr;
 using std::make_pair;
 using std::pair;
 using std::string;
@@ -227,18 +230,24 @@
 // dwarf2reader::LineInfo and populates a Module and a line vector
 // with the results.
 class DumpSymbols::DumperLineToModule:
-      public DwarfCUToModule::LineToModuleFunctor {
+      public DwarfCUToModule::LineToModuleHandler {
  public:
   // Create a line-to-module converter using BYTE_READER.
   DumperLineToModule(dwarf2reader::ByteReader *byte_reader)
       : byte_reader_(byte_reader) { }
-  void operator()(const char *program, uint64 length,
-                  Module *module, vector<Module::Line> *lines) {
-    DwarfLineToModule handler(module, lines);
+
+  void StartCompilationUnit(const string& compilation_dir) {
+    compilation_dir_ = compilation_dir;
+  }
+
+  void ReadProgram(const char *program, uint64 length,
+                   Module *module, vector<Module::Line> *lines) {
+    DwarfLineToModule handler(module, compilation_dir_, lines);
     dwarf2reader::LineInfo parser(program, length, byte_reader_, &handler);
     parser.Start();
   }
  private:
+  string compilation_dir_;
   dwarf2reader::ByteReader *byte_reader_;  // WEAK
 };
 
@@ -364,8 +373,12 @@
   // file, and adding data to MODULE.
   LoadCommandDumper(const DumpSymbols &dumper,
                     google_breakpad::Module *module,
-                    const mach_o::Reader &reader)
-      : dumper_(dumper), module_(module), reader_(reader) { }
+                    const mach_o::Reader &reader,
+                    SymbolData symbol_data)
+      : dumper_(dumper),
+        module_(module),
+        reader_(reader),
+        symbol_data_(symbol_data) { }
 
   bool SegmentCommand(const mach_o::Segment &segment);
   bool SymtabCommand(const ByteBuffer &entries, const ByteBuffer &strings);
@@ -374,6 +387,7 @@
   const DumpSymbols &dumper_;
   google_breakpad::Module *module_;  // WEAK
   const mach_o::Reader &reader_;
+  const SymbolData symbol_data_;
 };
 
 bool DumpSymbols::LoadCommandDumper::SegmentCommand(const Segment &segment) {
@@ -381,7 +395,7 @@
   if (!reader_.MapSegmentSections(segment, &section_map))
     return false;
 
-  if (segment.name == "__TEXT") {
+  if (segment.name == "__TEXT" && symbol_data_ != NO_CFI) {
     module_->SetLoadAddress(segment.vmaddr);
     mach_o::SectionMap::const_iterator eh_frame =
         section_map.find("__eh_frame");
@@ -393,13 +407,17 @@
   }
 
   if (segment.name == "__DWARF") {
-    if (!dumper_.ReadDwarf(module_, reader_, section_map))
-      return false;
-    mach_o::SectionMap::const_iterator debug_frame
-        = section_map.find("__debug_frame");
-    if (debug_frame != section_map.end()) {
-      // If there is a problem reading this, don't treat it as a fatal error.
-      dumper_.ReadCFI(module_, reader_, debug_frame->second, false);
+    if (symbol_data_ != ONLY_CFI) {
+      if (!dumper_.ReadDwarf(module_, reader_, section_map))
+        return false;
+    }
+    if (symbol_data_ != NO_CFI) {
+      mach_o::SectionMap::const_iterator debug_frame
+          = section_map.find("__debug_frame");
+      if (debug_frame != section_map.end()) {
+        // If there is a problem reading this, don't treat it as a fatal error.
+        dumper_.ReadCFI(module_, reader_, debug_frame->second, false);
+      }
     }
   }
 
@@ -423,7 +441,7 @@
   return true;
 }
 
-bool DumpSymbols::WriteSymbolFile(std::ostream &stream, bool cfi) {
+bool DumpSymbols::ReadSymbolData(Module** out_module) {
   // Select an object file, if SetArchitecture hasn't been called to set one
   // explicitly.
   if (!selected_object_file_) {
@@ -474,8 +492,10 @@
   identifier += "0";
 
   // Create a module to hold the debugging information.
-  Module module([module_name UTF8String], "mac", selected_arch_name,
-                identifier);
+  scoped_ptr<Module> module(new Module([module_name UTF8String],
+                                       "mac",
+                                       selected_arch_name,
+                                       identifier));
 
   // Parse the selected object file.
   mach_o::Reader::Reporter reporter(selected_object_name_);
@@ -488,11 +508,26 @@
     return false;
 
   // Walk its load commands, and deal with whatever is there.
-  LoadCommandDumper load_command_dumper(*this, &module, reader);
+  LoadCommandDumper load_command_dumper(*this, module.get(), reader,
+                                        symbol_data_);
   if (!reader.WalkLoadCommands(&load_command_dumper))
     return false;
 
-  return module.Write(stream, cfi);
+  *out_module = module.release();
+
+  return true;
+}
+
+bool DumpSymbols::WriteSymbolFile(std::ostream &stream) {
+  Module* module = NULL;
+
+  if (ReadSymbolData(&module) && module) {
+    bool res = module->Write(stream, symbol_data_);
+    delete module;
+    return res;
+  }
+
+  return false;
 }
 
 }  // namespace google_breakpad
diff --git a/src/common/mac/string_utilities.cc b/src/common/mac/string_utilities.cc
index e1f63a9..07c0f42 100644
--- a/src/common/mac/string_utilities.cc
+++ b/src/common/mac/string_utilities.cc
@@ -27,7 +27,7 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-#include "processor/scoped_ptr.h"
+#include "common/scoped_ptr.h"
 #include "common/mac/string_utilities.h"
 
 namespace MacStringUtils {
diff --git a/src/common/memory_range.h b/src/common/memory_range.h
index 86bd08c..41dd2da 100644
--- a/src/common/memory_range.h
+++ b/src/common/memory_range.h
@@ -67,7 +67,7 @@
 
   // Sets this memory range to point to |data| and its length to |length|.
   void Set(const void* data, size_t length) {
-    data_ = reinterpret_cast<const u_int8_t*>(data);
+    data_ = reinterpret_cast<const uint8_t*>(data);
     // Always set |length_| to zero if |data_| is NULL.
     length_ = data ? length : 0;
   }
@@ -127,14 +127,14 @@
   }
 
   // Returns a pointer to the beginning of this memory range.
-  const u_int8_t* data() const { return data_; }
+  const uint8_t* data() const { return data_; }
 
   // Returns the length, in bytes, of this memory range.
   size_t length() const { return length_; }
 
  private:
   // Pointer to the beginning of this memory range.
-  const u_int8_t* data_;
+  const uint8_t* data_;
 
   // Length, in bytes, of this memory range.
   size_t length_;
diff --git a/src/common/memory_range_unittest.cc b/src/common/memory_range_unittest.cc
index b13f45c..f6cf8c8 100644
--- a/src/common/memory_range_unittest.cc
+++ b/src/common/memory_range_unittest.cc
@@ -37,9 +37,9 @@
 
 namespace {
 
-const u_int32_t kBuffer[10] = { 0 };
+const uint32_t kBuffer[10] = { 0 };
 const size_t kBufferSize = sizeof(kBuffer);
-const u_int8_t* kBufferPointer = reinterpret_cast<const u_int8_t*>(kBuffer);
+const uint8_t* kBufferPointer = reinterpret_cast<const uint8_t*>(kBuffer);
 
 // Test vectors for verifying Covers, GetData, and Subrange.
 const struct {
diff --git a/src/common/module.cc b/src/common/module.cc
index 4e257d1..2d2e4ef 100644
--- a/src/common/module.cc
+++ b/src/common/module.cc
@@ -204,62 +204,62 @@
   return stream.good();
 }
 
-bool Module::Write(std::ostream &stream, bool cfi) {
+bool Module::Write(std::ostream &stream, SymbolData symbol_data) {
   stream << "MODULE " << os_ << " " << architecture_ << " "
          << id_ << " " << name_ << endl;
   if (!stream.good())
     return ReportError();
 
-  AssignSourceIds();
+  if (symbol_data != ONLY_CFI) {
+    AssignSourceIds();
 
-  // Write out files.
-  for (FileByNameMap::iterator file_it = files_.begin();
-       file_it != files_.end(); ++file_it) {
-    File *file = file_it->second;
-    if (file->source_id >= 0) {
-      stream << "FILE " << file->source_id << " " <<  file->name << endl;
+    // Write out files.
+    for (FileByNameMap::iterator file_it = files_.begin();
+         file_it != files_.end(); ++file_it) {
+      File *file = file_it->second;
+      if (file->source_id >= 0) {
+        stream << "FILE " << file->source_id << " " <<  file->name << endl;
+        if (!stream.good())
+          return ReportError();
+      }
+    }
+
+    // Write out functions and their lines.
+    for (FunctionSet::const_iterator func_it = functions_.begin();
+         func_it != functions_.end(); ++func_it) {
+      Function *func = *func_it;
+      stream << "FUNC " << hex
+             << (func->address - load_address_) << " "
+             << func->size << " "
+             << func->parameter_size << " "
+             << func->name << dec << endl;
       if (!stream.good())
         return ReportError();
+
+      for (vector<Line>::iterator line_it = func->lines.begin();
+           line_it != func->lines.end(); ++line_it) {
+        stream << hex
+               << (line_it->address - load_address_) << " "
+               << line_it->size << " "
+               << dec
+               << line_it->number << " "
+               << line_it->file->source_id << endl;
+        if (!stream.good())
+          return ReportError();
+      }
+    }
+
+    // Write out 'PUBLIC' records.
+    for (ExternSet::const_iterator extern_it = externs_.begin();
+         extern_it != externs_.end(); ++extern_it) {
+      Extern *ext = *extern_it;
+      stream << "PUBLIC " << hex
+             << (ext->address - load_address_) << " 0 "
+             << ext->name << dec << endl;
     }
   }
 
-  // Write out functions and their lines.
-  for (FunctionSet::const_iterator func_it = functions_.begin();
-       func_it != functions_.end(); ++func_it) {
-    Function *func = *func_it;
-    stream << "FUNC " << hex
-           << (func->address - load_address_) << " "
-           << func->size << " "
-           << func->parameter_size << " "
-           << func->name << dec << endl;
-
-    if (!stream.good())
-      return ReportError();
-    for (vector<Line>::iterator line_it = func->lines.begin();
-         line_it != func->lines.end(); ++line_it) {
-      stream << hex
-             << (line_it->address - load_address_) << " "
-             << line_it->size << " "
-             << dec
-             << line_it->number << " "
-             << line_it->file->source_id << endl;
-      if (!stream.good())
-        return ReportError();
-    }
-  }
-
-  // Write out 'PUBLIC' records.
-  for (ExternSet::const_iterator extern_it = externs_.begin();
-       extern_it != externs_.end(); ++extern_it) {
-    Extern *ext = *extern_it;
-    stream << "PUBLIC " << hex
-           << (ext->address - load_address_) << " 0 "
-           << ext->name << dec << endl;
-    if (!stream.good())
-      return ReportError();
-  }
-
-  if (cfi) {
+  if (symbol_data != NO_CFI) {
     // Write out 'STACK CFI INIT' and 'STACK CFI' records.
     vector<StackFrameEntry *>::const_iterator frame_it;
     for (frame_it = stack_frame_entries_.begin();
diff --git a/src/common/module.h b/src/common/module.h
index cc89bba..398bc31 100644
--- a/src/common/module.h
+++ b/src/common/module.h
@@ -44,6 +44,7 @@
 #include <string>
 #include <vector>
 
+#include "common/symbol_data.h"
 #include "common/using_std_string.h"
 #include "google_breakpad/common/breakpad_types.h"
 
@@ -60,7 +61,7 @@
 class Module {
  public:
   // The type of addresses and sizes in a symbol table.
-  typedef u_int64_t Address;
+  typedef uint64_t Address;
   struct File;
   struct Function;
   struct Line;
@@ -259,13 +260,15 @@
   // breakpad symbol format. Return true if all goes well, or false if
   // an error occurs. This method writes out:
   // - a header based on the values given to the constructor,
+  // If symbol_data is not ONLY_CFI then:
   // - the source files added via FindFile,
   // - the functions added via AddFunctions, each with its lines,
   // - all public records,
-  // - and if CFI is true, all CFI records.
+  // If symbol_data is not NO_CFI then:
+  // - all CFI records.
   // Addresses in the output are all relative to the load address
   // established by SetLoadAddress.
-  bool Write(std::ostream &stream, bool cfi);
+  bool Write(std::ostream &stream, SymbolData symbol_data);
 
  private:
   // Report an error that has occurred writing the symbol file, using
@@ -288,7 +291,7 @@
   // Relation for maps whose keys are strings shared with some other
   // structure.
   struct CompareStringPtrs {
-    bool operator()(const string *x, const string *y) { return *x < *y; }
+    bool operator()(const string *x, const string *y) const { return *x < *y; }
   };
 
   // A map from filenames to File structures.  The map's keys are
diff --git a/src/common/module_unittest.cc b/src/common/module_unittest.cc
index 04dc404..5c0c697 100644
--- a/src/common/module_unittest.cc
+++ b/src/common/module_unittest.cc
@@ -70,7 +70,7 @@
 TEST(Write, Header) {
   stringstream s;
   Module m(MODULE_NAME, MODULE_OS, MODULE_ARCH, MODULE_ID);
-  m.Write(s, true);
+  m.Write(s, ALL_SYMBOL_DATA);
   string contents = s.str();
   EXPECT_STREQ("MODULE os-name architecture id-string name with spaces\n",
                contents.c_str());
@@ -91,7 +91,7 @@
   function->lines.push_back(line);
   m.AddFunction(function);
 
-  m.Write(s, true);
+  m.Write(s, ALL_SYMBOL_DATA);
   string contents = s.str();
   EXPECT_STREQ("MODULE os-name architecture id-string name with spaces\n"
                "FILE 0 file_name.cc\n"
@@ -141,7 +141,7 @@
   // the module must work fine.
   m.SetLoadAddress(0x2ab698b0b6407073LL);
 
-  m.Write(s, true);
+  m.Write(s, ALL_SYMBOL_DATA);
   string contents = s.str();
   EXPECT_STREQ("MODULE os-name architecture id-string name with spaces\n"
                "FILE 0 filename-a.cc\n"
@@ -197,7 +197,7 @@
   EXPECT_NE(-1, vec[2]->source_id);
 
   stringstream s;
-  m.Write(s, true);
+  m.Write(s, ALL_SYMBOL_DATA);
   string contents = s.str();
   EXPECT_STREQ("MODULE os-name architecture id-string name with spaces\n"
                "FILE 0 filename1\n"
@@ -245,7 +245,7 @@
   // the module must work fine.
   m.SetLoadAddress(0x2ab698b0b6407073LL);
 
-  m.Write(s, false);
+  m.Write(s, NO_CFI);
   string contents = s.str();
   EXPECT_STREQ("MODULE os-name architecture id-string name with spaces\n"
                "FILE 0 filename.cc\n"
@@ -279,7 +279,7 @@
 
   m.AddFunctions(vec.begin(), vec.end());
 
-  m.Write(s, true);
+  m.Write(s, ALL_SYMBOL_DATA);
   string contents = s.str();
   EXPECT_STREQ("MODULE os-name architecture id-string name with spaces\n"
                "FUNC 2987743d0b35b13f b369db048deb3010 938e556cb5a79988"
@@ -331,7 +331,7 @@
   m.AddStackFrameEntry(entry3);
 
   // Check that Write writes STACK CFI records properly.
-  m.Write(s, true);
+  m.Write(s, ALL_SYMBOL_DATA);
   string contents = s.str();
   EXPECT_STREQ("MODULE os-name architecture id-string name with spaces\n"
                "STACK CFI INIT ddb5f41285aa7757 1486493370dc5073 \n"
@@ -407,7 +407,7 @@
   m.AddFunction(function1);
   m.AddFunction(function2);
 
-  m.Write(s, true);
+  m.Write(s, ALL_SYMBOL_DATA);
   string contents = s.str();
   EXPECT_STREQ("MODULE os-name architecture id-string name with spaces\n"
                "FUNC d35402aac7a7ad5c 200b26e605f99071 f14ac4fed48c4a99"
@@ -426,7 +426,7 @@
   m.AddFunction(function1);
   m.AddFunction(function2);
 
-  m.Write(s, true);
+  m.Write(s, ALL_SYMBOL_DATA);
   string contents = s.str();
   EXPECT_STREQ("MODULE os-name architecture id-string name with spaces\n"
                "FUNC d35402aac7a7ad5c 200b26e605f99071 f14ac4fed48c4a99"
@@ -453,7 +453,7 @@
   m.AddExtern(extern1);
   m.AddExtern(extern2);
 
-  m.Write(s, true);
+  m.Write(s, ALL_SYMBOL_DATA);
   string contents = s.str();
 
   EXPECT_STREQ("MODULE " MODULE_OS " " MODULE_ARCH " "
@@ -480,7 +480,7 @@
   m.AddExtern(extern1);
   m.AddExtern(extern2);
 
-  m.Write(s, true);
+  m.Write(s, ALL_SYMBOL_DATA);
   string contents = s.str();
 
   EXPECT_STREQ("MODULE " MODULE_OS " " MODULE_ARCH " "
diff --git a/src/processor/scoped_ptr.h b/src/common/scoped_ptr.h
similarity index 98%
rename from src/processor/scoped_ptr.h
rename to src/common/scoped_ptr.h
index 0d4f7fd..2dbc40d 100644
--- a/src/processor/scoped_ptr.h
+++ b/src/common/scoped_ptr.h
@@ -46,8 +46,8 @@
 //  Use this to conditionally transfer ownership of a heap-allocated object
 //  to the caller, usually on method success.
 
-#ifndef PROCESSOR_SCOPED_PTR_H__
-#define PROCESSOR_SCOPED_PTR_H__
+#ifndef COMMON_SCOPED_PTR_H_
+#define COMMON_SCOPED_PTR_H_
 
 #include <cstddef>            // for std::ptrdiff_t
 #include <assert.h>           // for assert
@@ -332,4 +332,4 @@
 
 }  // namespace google_breakpad
 
-#endif  // PROCESSOR_SCOPED_PTR_H__
+#endif  // COMMON_SCOPED_PTR_H_
diff --git a/src/common/solaris/dump_symbols.cc b/src/common/solaris/dump_symbols.cc
index b1e995d..168d0b2 100644
--- a/src/common/solaris/dump_symbols.cc
+++ b/src/common/solaris/dump_symbols.cc
@@ -43,10 +43,10 @@
 #include <map>
 #include <vector>
 
+#include "common/scoped_ptr.h"
 #include "common/solaris/dump_symbols.h"
 #include "common/solaris/file_id.h"
 #include "common/solaris/guid_creator.h"
-#include "processor/scoped_ptr.h"
 
 // This namespace contains helper functions.
 namespace {
@@ -156,7 +156,7 @@
 const int demangleLen = 20000;
 
 // Offset to the string table.
-u_int64_t stringOffset = 0;
+uint64_t stringOffset = 0;
 
 // Update the offset to the start of the string index of the next
 // object module for every N_ENDM stabs.
diff --git a/src/common/solaris/guid_creator.cc b/src/common/solaris/guid_creator.cc
index 7094025..c4d58e0 100644
--- a/src/common/solaris/guid_creator.cc
+++ b/src/common/solaris/guid_creator.cc
@@ -53,10 +53,10 @@
 
   bool CreateGUID(GUID *guid) const {
     guid->data1 = random();
-    guid->data2 = (u_int16_t)(random());
-    guid->data3 = (u_int16_t)(random());
-    *reinterpret_cast<u_int32_t*>(&guid->data4[0]) = random();
-    *reinterpret_cast<u_int32_t*>(&guid->data4[4]) = random();
+    guid->data2 = (uint16_t)(random());
+    guid->data3 = (uint16_t)(random());
+    *reinterpret_cast<uint32_t*>(&guid->data4[0]) = random();
+    *reinterpret_cast<uint32_t*>(&guid->data4[4]) = random();
     return true;
   }
 };
@@ -74,8 +74,8 @@
   assert(buf_len > kGUIDStringLength);
   int num = snprintf(buf, buf_len, kGUIDFormatString,
                      guid->data1, guid->data2, guid->data3,
-                     *reinterpret_cast<const u_int32_t *>(&(guid->data4[0])),
-                     *reinterpret_cast<const u_int32_t *>(&(guid->data4[4])));
+                     *reinterpret_cast<const uint32_t *>(&(guid->data4[0])),
+                     *reinterpret_cast<const uint32_t *>(&(guid->data4[4])));
   if (num != kGUIDStringLength)
     return false;
 
diff --git a/src/common/stabs_reader_unittest.cc b/src/common/stabs_reader_unittest.cc
index edcba72..a84da1c 100644
--- a/src/common/stabs_reader_unittest.cc
+++ b/src/common/stabs_reader_unittest.cc
@@ -565,7 +565,7 @@
   stabs.set_endianness(kLittleEndian);
   stabs.set_value_size(4);
 
-  const u_int32_t kExpectedAddress = 0x9000;
+  const uint32_t kExpectedAddress = 0x9000;
   const string kExpectedFunctionName("public_function");
   stabs
     .Stab(N_SECT, 1, 0, kExpectedAddress, kExpectedFunctionName);
@@ -584,9 +584,9 @@
   stabs.set_endianness(kLittleEndian);
   stabs.set_value_size(4);
 
-  const u_int32_t kExpectedAddress1 = 0xB0B0B0B0;
+  const uint32_t kExpectedAddress1 = 0xB0B0B0B0;
   const string kExpectedFunctionName1("public_function");
-  const u_int32_t kExpectedAddress2 = 0xF0F0F0F0;
+  const uint32_t kExpectedAddress2 = 0xF0F0F0F0;
   const string kExpectedFunctionName2("something else");
   stabs
     .Stab(N_SECT, 1, 0, kExpectedAddress1, kExpectedFunctionName1)
diff --git a/src/common/string_conversion.cc b/src/common/string_conversion.cc
index b4f4d77..c4107fa 100644
--- a/src/common/string_conversion.cc
+++ b/src/common/string_conversion.cc
@@ -30,23 +30,23 @@
 #include <string.h>
 
 #include "common/convert_UTF.h"
+#include "common/scoped_ptr.h"
 #include "common/string_conversion.h"
 #include "common/using_std_string.h"
-#include "processor/scoped_ptr.h"
 
 namespace google_breakpad {
 
 using std::vector;
 
-void UTF8ToUTF16(const char *in, vector<u_int16_t> *out) {
+void UTF8ToUTF16(const char *in, vector<uint16_t> *out) {
   size_t source_length = strlen(in);
   const UTF8 *source_ptr = reinterpret_cast<const UTF8 *>(in);
   const UTF8 *source_end_ptr = source_ptr + source_length;
   // Erase the contents and zero fill to the expected size
   out->clear();
   out->insert(out->begin(), source_length, 0);
-  u_int16_t *target_ptr = &(*out)[0];
-  u_int16_t *target_end_ptr = target_ptr + out->capacity() * sizeof(u_int16_t);
+  uint16_t *target_ptr = &(*out)[0];
+  uint16_t *target_end_ptr = target_ptr + out->capacity() * sizeof(uint16_t);
   ConversionResult result = ConvertUTF8toUTF16(&source_ptr, source_end_ptr,
                                                &target_ptr, target_end_ptr,
                                                strictConversion);
@@ -55,11 +55,11 @@
   out->resize(result == conversionOK ? target_ptr - &(*out)[0] + 1: 0);
 }
 
-int UTF8ToUTF16Char(const char *in, int in_length, u_int16_t out[2]) {
+int UTF8ToUTF16Char(const char *in, int in_length, uint16_t out[2]) {
   const UTF8 *source_ptr = reinterpret_cast<const UTF8 *>(in);
   const UTF8 *source_end_ptr = source_ptr + sizeof(char);
-  u_int16_t *target_ptr = out;
-  u_int16_t *target_end_ptr = target_ptr + 2 * sizeof(u_int16_t);
+  uint16_t *target_ptr = out;
+  uint16_t *target_end_ptr = target_ptr + 2 * sizeof(uint16_t);
   out[0] = out[1] = 0;
 
   // Process one character at a time
@@ -82,15 +82,15 @@
   return 0;
 }
 
-void UTF32ToUTF16(const wchar_t *in, vector<u_int16_t> *out) {
+void UTF32ToUTF16(const wchar_t *in, vector<uint16_t> *out) {
   size_t source_length = wcslen(in);
   const UTF32 *source_ptr = reinterpret_cast<const UTF32 *>(in);
   const UTF32 *source_end_ptr = source_ptr + source_length;
   // Erase the contents and zero fill to the expected size
   out->clear();
   out->insert(out->begin(), source_length, 0);
-  u_int16_t *target_ptr = &(*out)[0];
-  u_int16_t *target_end_ptr = target_ptr + out->capacity() * sizeof(u_int16_t);
+  uint16_t *target_ptr = &(*out)[0];
+  uint16_t *target_end_ptr = target_ptr + out->capacity() * sizeof(uint16_t);
   ConversionResult result = ConvertUTF32toUTF16(&source_ptr, source_end_ptr,
                                                 &target_ptr, target_end_ptr,
                                                 strictConversion);
@@ -99,11 +99,11 @@
   out->resize(result == conversionOK ? target_ptr - &(*out)[0] + 1: 0);
 }
 
-void UTF32ToUTF16Char(wchar_t in, u_int16_t out[2]) {
+void UTF32ToUTF16Char(wchar_t in, uint16_t out[2]) {
   const UTF32 *source_ptr = reinterpret_cast<const UTF32 *>(&in);
   const UTF32 *source_end_ptr = source_ptr + 1;
-  u_int16_t *target_ptr = out;
-  u_int16_t *target_end_ptr = target_ptr + 2 * sizeof(u_int16_t);
+  uint16_t *target_ptr = out;
+  uint16_t *target_end_ptr = target_ptr + 2 * sizeof(uint16_t);
   out[0] = out[1] = 0;
   ConversionResult result = ConvertUTF32toUTF16(&source_ptr, source_end_ptr,
                                                 &target_ptr, target_end_ptr,
@@ -114,20 +114,20 @@
   }
 }
 
-static inline u_int16_t Swap(u_int16_t value) {
-  return (value >> 8) | static_cast<u_int16_t>(value << 8);
+static inline uint16_t Swap(uint16_t value) {
+  return (value >> 8) | static_cast<uint16_t>(value << 8);
 }
 
-string UTF16ToUTF8(const vector<u_int16_t> &in, bool swap) {
+string UTF16ToUTF8(const vector<uint16_t> &in, bool swap) {
   const UTF16 *source_ptr = &in[0];
-  scoped_ptr<u_int16_t> source_buffer;
+  scoped_ptr<uint16_t> source_buffer;
 
   // If we're to swap, we need to make a local copy and swap each byte pair
   if (swap) {
     int idx = 0;
-    source_buffer.reset(new u_int16_t[in.size()]);
+    source_buffer.reset(new uint16_t[in.size()]);
     UTF16 *source_buffer_ptr = source_buffer.get();
-    for (vector<u_int16_t>::const_iterator it = in.begin();
+    for (vector<uint16_t>::const_iterator it = in.begin();
          it != in.end(); ++it, ++idx)
       source_buffer_ptr[idx] = Swap(*it);
 
diff --git a/src/common/string_conversion.h b/src/common/string_conversion.h
index eeed4d2..b9ba96a 100644
--- a/src/common/string_conversion.h
+++ b/src/common/string_conversion.h
@@ -44,24 +44,24 @@
 
 // Convert |in| to UTF-16 into |out|.  Use platform byte ordering.  If the
 // conversion failed, |out| will be zero length.
-void UTF8ToUTF16(const char *in, vector<u_int16_t> *out);
+void UTF8ToUTF16(const char *in, vector<uint16_t> *out);
 
 // Convert at least one character (up to a maximum of |in_length|) from |in|
 // to UTF-16 into |out|.  Return the number of characters consumed from |in|.
 // Any unused characters in |out| will be initialized to 0.  No memory will
 // be allocated by this routine.
-int UTF8ToUTF16Char(const char *in, int in_length, u_int16_t out[2]);
+int UTF8ToUTF16Char(const char *in, int in_length, uint16_t out[2]);
 
 // Convert |in| to UTF-16 into |out|.  Use platform byte ordering.  If the
 // conversion failed, |out| will be zero length.
-void UTF32ToUTF16(const wchar_t *in, vector<u_int16_t> *out);
+void UTF32ToUTF16(const wchar_t *in, vector<uint16_t> *out);
 
 // Convert |in| to UTF-16 into |out|.  Any unused characters in |out| will be
 // initialized to 0.  No memory will be allocated by this routine.
-void UTF32ToUTF16Char(wchar_t in, u_int16_t out[2]);
+void UTF32ToUTF16Char(wchar_t in, uint16_t out[2]);
 
 // Convert |in| to UTF-8.  If |swap| is true, swap bytes before converting.
-string UTF16ToUTF8(const vector<u_int16_t> &in, bool swap);
+string UTF16ToUTF8(const vector<uint16_t> &in, bool swap);
 
 }  // namespace google_breakpad
 
diff --git a/src/common/symbol_data.h b/src/common/symbol_data.h
new file mode 100644
index 0000000..2cf15a8
--- /dev/null
+++ b/src/common/symbol_data.h
@@ -0,0 +1,42 @@
+// -*- mode: c++ -*-
+
+// 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 COMMON_SYMBOL_DATA_H_
+#define COMMON_SYMBOL_DATA_H_
+
+// Control what data is used from the symbol file.
+enum SymbolData {
+  ALL_SYMBOL_DATA,
+  NO_CFI,
+  ONLY_CFI
+};
+
+#endif  // COMMON_SYMBOL_DATA_H_
diff --git a/src/common/test_assembler.cc b/src/common/test_assembler.cc
index 7f5dd38..1e783b4 100644
--- a/src/common/test_assembler.cc
+++ b/src/common/test_assembler.cc
@@ -45,7 +45,7 @@
 using std::back_insert_iterator;
 
 Label::Label() : value_(new Binding()) { }
-Label::Label(u_int64_t value) : value_(new Binding(value)) { }
+Label::Label(uint64_t value) : value_(new Binding(value)) { }
 Label::Label(const Label &label) {
   value_ = label.value_;
   value_->Acquire();
@@ -54,7 +54,7 @@
   if (value_->Release()) delete value_;
 }
 
-Label &Label::operator=(u_int64_t value) {
+Label &Label::operator=(uint64_t value) {
   value_->Set(NULL, value);
   return *this;
 }
@@ -64,13 +64,13 @@
   return *this;
 }
 
-Label Label::operator+(u_int64_t addend) const {
+Label Label::operator+(uint64_t addend) const {
   Label l;
   l.value_->Set(this->value_, addend);
   return l;
 }
 
-Label Label::operator-(u_int64_t subtrahend) const {
+Label Label::operator-(uint64_t subtrahend) const {
   Label l;
   l.value_->Set(this->value_, -subtrahend);
   return l;
@@ -89,31 +89,31 @@
 #define ALWAYS_EVALUATE_AND_ASSERT(x) assert(x)
 #endif
 
-u_int64_t Label::operator-(const Label &label) const {
-  u_int64_t offset;
+uint64_t Label::operator-(const Label &label) const {
+  uint64_t offset;
   ALWAYS_EVALUATE_AND_ASSERT(IsKnownOffsetFrom(label, &offset));
   return offset;
 }
 
-u_int64_t Label::Value() const {
-  u_int64_t v = 0;
+uint64_t Label::Value() const {
+  uint64_t v = 0;
   ALWAYS_EVALUATE_AND_ASSERT(IsKnownConstant(&v));
   return v;
 };
 
-bool Label::IsKnownConstant(u_int64_t *value_p) const {
+bool Label::IsKnownConstant(uint64_t *value_p) const {
   Binding *base;
-  u_int64_t addend;
+  uint64_t addend;
   value_->Get(&base, &addend);
   if (base != NULL) return false;
   if (value_p) *value_p = addend;
   return true;
 }
 
-bool Label::IsKnownOffsetFrom(const Label &label, u_int64_t *offset_p) const
+bool Label::IsKnownOffsetFrom(const Label &label, uint64_t *offset_p) const
 {
   Binding *label_base, *this_base;
-  u_int64_t label_addend, this_addend;
+  uint64_t label_addend, this_addend;
   label.value_->Get(&label_base, &label_addend);
   value_->Get(&this_base, &this_addend);
   // If this and label are related, Get will find their final
@@ -126,7 +126,7 @@
 
 Label::Binding::Binding() : base_(this), addend_(), reference_count_(1) { }
 
-Label::Binding::Binding(u_int64_t addend)
+Label::Binding::Binding(uint64_t addend)
     : base_(NULL), addend_(addend), reference_count_(1) { }
 
 Label::Binding::~Binding() {
@@ -135,7 +135,7 @@
     delete base_;
 }
 
-void Label::Binding::Set(Binding *binding, u_int64_t addend) {
+void Label::Binding::Set(Binding *binding, uint64_t addend) {
   if (!base_ && !binding) {
     // We're equating two constants. This could be okay.
     assert(addend_ == addend);
@@ -150,7 +150,7 @@
       // another variable (otherwise, it wouldn't be final), this
       // guarantees we won't create cycles here, even for code like this:
       //   l = m, m = n, n = l;
-      u_int64_t binding_addend;
+      uint64_t binding_addend;
       binding->Get(&binding, &binding_addend);
       addend += binding_addend;
     }
@@ -183,14 +183,14 @@
   }
 }
 
-void Label::Binding::Get(Binding **base, u_int64_t *addend) {
+void Label::Binding::Get(Binding **base, uint64_t *addend) {
   if (base_ && base_ != this) {
     // Recurse to find the end of our reference chain (the root of our
     // tree), and then rewrite every binding along the chain to refer
     // to it directly, adjusting addends appropriately. (This is why
     // this member function isn't this-const.)
     Binding *final_base;
-    u_int64_t final_addend;
+    uint64_t final_addend;
     base_->Get(&final_base, &final_addend);
     if (final_base) final_base->Acquire();
     if (base_->Release()) delete base_;
@@ -203,7 +203,7 @@
 
 template<typename Inserter>
 static inline void InsertEndian(test_assembler::Endianness endianness,
-                                size_t size, u_int64_t number, Inserter dest) {
+                                size_t size, uint64_t number, Inserter dest) {
   assert(size > 0);
   if (endianness == kLittleEndian) {
     for (size_t i = 0; i < size; i++) {
@@ -218,7 +218,7 @@
   }
 }
 
-Section &Section::Append(Endianness endianness, size_t size, u_int64_t number) {
+Section &Section::Append(Endianness endianness, size_t size, uint64_t number) {
   InsertEndian(endianness, size, number,
                back_insert_iterator<string>(contents_));
   return *this;
@@ -228,7 +228,7 @@
                          const Label &label) {
   // If this label's value is known, there's no reason to waste an
   // entry in references_ on it.
-  u_int64_t value;
+  uint64_t value;
   if (label.IsKnownConstant(&value))
     return Append(endianness, size, value);
 
@@ -246,7 +246,7 @@
 #define ENDIANNESS(e) ENDIANNESS_ ## e
 
 #define DEFINE_SHORT_APPEND_NUMBER_ENDIAN(e, bits)                      \
-  Section &Section::e ## bits(u_int ## bits ## _t v) {                  \
+  Section &Section::e ## bits(uint ## bits ## _t v) {                  \
     InsertEndian(ENDIANNESS(e), bits / 8, v,                            \
                  back_insert_iterator<string>(contents_));              \
     return *this;                                                       \
@@ -272,7 +272,7 @@
 DEFINE_SHORT_APPEND_ENDIAN(B, 64);
 
 #define DEFINE_SHORT_APPEND_NUMBER_DEFAULT(bits)                        \
-  Section &Section::D ## bits(u_int ## bits ## _t v) {                  \
+  Section &Section::D ## bits(uint ## bits ## _t v) {                  \
     InsertEndian(endianness_, bits / 8, v,                              \
                  back_insert_iterator<string>(contents_));              \
     return *this;                                                       \
@@ -312,7 +312,7 @@
   return *this;
 }
 
-Section &Section::ULEB128(u_int64_t value) {
+Section &Section::ULEB128(uint64_t value) {
   while (value > 0x7f) {
     contents_ += (value & 0x7f) | 0x80;
     value = (value >> 7);
@@ -321,7 +321,7 @@
   return *this;
 }
 
-Section &Section::Align(size_t alignment, u_int8_t pad_byte) {
+Section &Section::Align(size_t alignment, uint8_t pad_byte) {
   // ALIGNMENT must be a power of two.
   assert(((alignment - 1) & alignment) == 0);
   size_t new_size = (contents_.size() + alignment - 1) & ~(alignment - 1);
@@ -340,7 +340,7 @@
   // the section's contents.
   for (size_t i = 0; i < references_.size(); i++) {
     Reference &r = references_[i];
-    u_int64_t value;
+    uint64_t value;
     if (!r.label.IsKnownConstant(&value)) {
       fprintf(stderr, "Undefined label #%zu at offset 0x%zx\n", i, r.offset);
       return false;
diff --git a/src/common/test_assembler.h b/src/common/test_assembler.h
index 891cf67..373dbeb 100644
--- a/src/common/test_assembler.h
+++ b/src/common/test_assembler.h
@@ -110,7 +110,7 @@
 class Label {
  public:
   Label();                      // An undefined label.
-  Label(u_int64_t value);       // A label with a fixed value
+  Label(uint64_t value);       // A label with a fixed value
   Label(const Label &value);    // A label equal to another.
   ~Label();
 
@@ -119,23 +119,23 @@
   // Providing this as a cast operator is nifty, but the conversions
   // happen in unexpected places. In particular, ISO C++ says that
   // Label + size_t becomes ambigious, because it can't decide whether
-  // to convert the Label to a u_int64_t and then to a size_t, or use
+  // to convert the Label to a uint64_t and then to a size_t, or use
   // the overloaded operator that returns a new label, even though the
   // former could fail if the label is not yet defined and the latter won't.
-  u_int64_t Value() const;
+  uint64_t Value() const;
 
-  Label &operator=(u_int64_t value);
+  Label &operator=(uint64_t value);
   Label &operator=(const Label &value);
-  Label operator+(u_int64_t addend) const;
-  Label operator-(u_int64_t subtrahend) const;
-  u_int64_t operator-(const Label &subtrahend) const;
+  Label operator+(uint64_t addend) const;
+  Label operator-(uint64_t subtrahend) const;
+  uint64_t operator-(const Label &subtrahend) const;
 
   // We could also provide == and != that work on undefined, but
   // related, labels.
 
   // Return true if this label's value is known. If VALUE_P is given,
   // set *VALUE_P to the known value if returning true.
-  bool IsKnownConstant(u_int64_t *value_p = NULL) const;
+  bool IsKnownConstant(uint64_t *value_p = NULL) const;
 
   // Return true if the offset from LABEL to this label is known. If
   // OFFSET_P is given, set *OFFSET_P to the offset when returning true.
@@ -150,12 +150,12 @@
   //   m = l + 10;
   //   l.IsKnownConstant();             // false
   //   m.IsKnownConstant();             // false
-  //   u_int64_t d;                     
+  //   uint64_t d;                     
   //   l.IsKnownOffsetFrom(m, &d);      // true, and sets d to -10.
   //   l-m                              // -10
   //   m-l                              // 10
   //   m.Value()                        // error: m's value is not known
-  bool IsKnownOffsetFrom(const Label &label, u_int64_t *offset_p = NULL) const;
+  bool IsKnownOffsetFrom(const Label &label, uint64_t *offset_p = NULL) const;
 
  private:
   // A label's value, or if that is not yet known, how the value is
@@ -173,7 +173,7 @@
   class Binding {
    public:
     Binding();
-    Binding(u_int64_t addend);
+    Binding(uint64_t addend);
     ~Binding();
 
     // Increment our reference count.
@@ -186,7 +186,7 @@
     // Update every binding on this binding's chain to point directly
     // to BINDING, or to be a constant, with addends adjusted
     // appropriately.
-    void Set(Binding *binding, u_int64_t value);
+    void Set(Binding *binding, uint64_t value);
 
     // Return what we know about the value of this binding.
     // - If this binding's value is a known constant, set BASE to
@@ -198,7 +198,7 @@
     //   value.
     // - If this binding is unconstrained, set BASE to this, and leave
     //   ADDEND unchanged.
-    void Get(Binding **base, u_int64_t *addend);
+    void Get(Binding **base, uint64_t *addend);
 
    private:
     // There are three cases:
@@ -221,7 +221,7 @@
     // binding on the chain to point directly to the final value,
     // adjusting addends as appropriate.
     Binding *base_;
-    u_int64_t addend_;
+    uint64_t addend_;
 
     // The number of Labels and Bindings pointing to this binding.
     // (When a binding points to itself, indicating a completely
@@ -233,7 +233,7 @@
   Binding *value_;
 };
 
-inline Label operator+(u_int64_t a, const Label &l) { return l + a; }
+inline Label operator+(uint64_t a, const Label &l) { return l + a; }
 // Note that int-Label isn't defined, as negating a Label is not an
 // operation we support.
 
@@ -288,7 +288,7 @@
 
   // Append the SIZE bytes at DATA or the contents of STRING to the
   // end of this section. Return a reference to this section.
-  Section &Append(const u_int8_t *data, size_t size) {
+  Section &Append(const uint8_t *data, size_t size) {
     contents_.append(reinterpret_cast<const char *>(data), size);
     return *this;
   };
@@ -299,7 +299,7 @@
 
   // Append SIZE copies of BYTE to the end of this section. Return a
   // reference to this section.
-  Section &Append(size_t size, u_int8_t byte) {
+  Section &Append(size_t size, uint8_t byte) {
     contents_.append(size, (char) byte);
     return *this;
   }
@@ -307,7 +307,7 @@
   // Append NUMBER to this section. ENDIANNESS is the endianness to
   // use to write the number. SIZE is the length of the number in
   // bytes. Return a reference to this section.
-  Section &Append(Endianness endianness, size_t size, u_int64_t number);
+  Section &Append(Endianness endianness, size_t size, uint64_t number);
   Section &Append(Endianness endianness, size_t size, const Label &label);
 
   // Append SECTION to the end of this section. The labels SECTION
@@ -352,12 +352,12 @@
   // the compiler will properly sign-extend a signed value before
   // passing it to the function, at which point the function's
   // behavior is the same either way.
-  Section &L8(u_int8_t value) { contents_ += value; return *this; }
-  Section &B8(u_int8_t value) { contents_ += value; return *this; }
-  Section &D8(u_int8_t value) { contents_ += value; return *this; }
-  Section &L16(u_int16_t), &L32(u_int32_t), &L64(u_int64_t),
-          &B16(u_int16_t), &B32(u_int32_t), &B64(u_int64_t),
-          &D16(u_int16_t), &D32(u_int32_t), &D64(u_int64_t);
+  Section &L8(uint8_t value) { contents_ += value; return *this; }
+  Section &B8(uint8_t value) { contents_ += value; return *this; }
+  Section &D8(uint8_t value) { contents_ += value; return *this; }
+  Section &L16(uint16_t), &L32(uint32_t), &L64(uint64_t),
+          &B16(uint16_t), &B32(uint32_t), &B64(uint64_t),
+          &D16(uint16_t), &D32(uint32_t), &D64(uint64_t);
   Section &L8(const Label &label),  &L16(const Label &label),
           &L32(const Label &label), &L64(const Label &label),
           &B8(const Label &label),  &B16(const Label &label),
@@ -399,13 +399,13 @@
   //
   // Note that VALUE cannot be a Label (we would have to implement
   // relaxation).
-  Section &ULEB128(u_int64_t value);
+  Section &ULEB128(uint64_t value);
 
   // Jump to the next location aligned on an ALIGNMENT-byte boundary,
   // relative to the start of the section. Fill the gap with PAD_BYTE.
   // ALIGNMENT must be a power of two. Return a reference to this
   // section.
-  Section &Align(size_t alignment, u_int8_t pad_byte = 0);
+  Section &Align(size_t alignment, uint8_t pad_byte = 0);
 
   // Clear the contents of this section.
   void Clear();
diff --git a/src/common/test_assembler_unittest.cc b/src/common/test_assembler_unittest.cc
index d4e95ef..94b5a5c 100644
--- a/src/common/test_assembler_unittest.cc
+++ b/src/common/test_assembler_unittest.cc
@@ -60,7 +60,7 @@
 
 TEST(ConstructLabel, Constant) {
   Label l(0x060b9f974eaf301eULL);
-  u_int64_t v;
+  uint64_t v;
   EXPECT_TRUE(l.IsKnownConstant(&v));
   EXPECT_EQ(v, 0x060b9f974eaf301eULL);
   EXPECT_EQ(l.Value(), 0x060b9f974eaf301eULL);
@@ -69,7 +69,7 @@
 TEST(ConstructLabel, Copy) {
   Label l;
   Label m(l);
-  u_int64_t v;
+  uint64_t v;
   EXPECT_TRUE(l.IsKnownOffsetFrom(m, &v));
   EXPECT_EQ(0U, v);
 }
@@ -82,7 +82,7 @@
   l = m;
   EXPECT_EQ(0U, l-m);
   EXPECT_TRUE(l.IsKnownOffsetFrom(m));
-  u_int64_t d;
+  uint64_t d;
   EXPECT_TRUE(l.IsKnownOffsetFrom(m, &d));
   EXPECT_EQ(0U, d);
   EXPECT_FALSE(l.IsKnownConstant());
@@ -94,7 +94,7 @@
   l = m;
   EXPECT_EQ(0U, l-m);
   EXPECT_TRUE(l.IsKnownOffsetFrom(m));
-  u_int64_t d;
+  uint64_t d;
   EXPECT_TRUE(l.IsKnownOffsetFrom(m, &d));
   EXPECT_EQ(0U, d);
   EXPECT_FALSE(l.IsKnownConstant());
@@ -106,7 +106,7 @@
   l = m;
   EXPECT_EQ(0U, l-m);
   EXPECT_TRUE(l.IsKnownOffsetFrom(m));
-  u_int64_t d;
+  uint64_t d;
   EXPECT_TRUE(l.IsKnownOffsetFrom(m, &d));
   EXPECT_EQ(0U, d);
   EXPECT_TRUE(m.IsKnownConstant());
@@ -119,7 +119,7 @@
   l = m;
   EXPECT_EQ(0U, l-n);
   EXPECT_TRUE(l.IsKnownOffsetFrom(n));
-  u_int64_t d;
+  uint64_t d;
   EXPECT_TRUE(l.IsKnownOffsetFrom(n, &d));
   EXPECT_EQ(0U, d);
   EXPECT_FALSE(l.IsKnownConstant());
@@ -132,7 +132,7 @@
   l = m;
   EXPECT_EQ(0U, n-o);
   EXPECT_TRUE(n.IsKnownOffsetFrom(o));
-  u_int64_t d;
+  uint64_t d;
   EXPECT_TRUE(n.IsKnownOffsetFrom(o, &d));
   EXPECT_EQ(0U, d);
   EXPECT_FALSE(l.IsKnownConstant());
@@ -234,7 +234,7 @@
   Label l, m;
   m = l + 0x5248d93e8bbe9497ULL;
   EXPECT_TRUE(m.IsKnownOffsetFrom(l));
-  u_int64_t d;
+  uint64_t d;
   EXPECT_TRUE(m.IsKnownOffsetFrom(l, &d));
   EXPECT_EQ(0x5248d93e8bbe9497ULL, d);
   EXPECT_FALSE(m.IsKnownConstant());
@@ -244,7 +244,7 @@
   Label l, m;
   m = 0xf51e94e00d6e3c84ULL + l;
   EXPECT_TRUE(m.IsKnownOffsetFrom(l));
-  u_int64_t d;
+  uint64_t d;
   EXPECT_TRUE(m.IsKnownOffsetFrom(l, &d));
   EXPECT_EQ(0xf51e94e00d6e3c84ULL, d);
   EXPECT_FALSE(m.IsKnownConstant());
@@ -255,7 +255,7 @@
   l = 0x16286307042ce0d8ULL;
   m = l + 0x3fdddd91306719d7ULL;
   EXPECT_TRUE(m.IsKnownOffsetFrom(l));
-  u_int64_t d;
+  uint64_t d;
   EXPECT_TRUE(m.IsKnownOffsetFrom(l, &d));
   EXPECT_EQ(0x3fdddd91306719d7ULL, d);
   EXPECT_TRUE(m.IsKnownConstant());
@@ -267,7 +267,7 @@
   l = 0x50f62d0cdd1031deULL;
   m = 0x1b13462d8577c538ULL + l;
   EXPECT_TRUE(m.IsKnownOffsetFrom(l));
-  u_int64_t d;
+  uint64_t d;
   EXPECT_TRUE(m.IsKnownOffsetFrom(l, &d));
   EXPECT_EQ(0x1b13462d8577c538ULL, d);
   EXPECT_TRUE(m.IsKnownConstant());
@@ -278,7 +278,7 @@
   Label l, m;
   m = l - 0x0620884d21d3138eULL;
   EXPECT_TRUE(m.IsKnownOffsetFrom(l));
-  u_int64_t d;
+  uint64_t d;
   EXPECT_TRUE(m.IsKnownOffsetFrom(l, &d));
   EXPECT_EQ(-0x0620884d21d3138eULL, d);
   EXPECT_FALSE(m.IsKnownConstant());
@@ -289,7 +289,7 @@
   l = 0x6237fbaf9ef7929eULL;
   m = l - 0x317730995d2ab6eeULL;
   EXPECT_TRUE(m.IsKnownOffsetFrom(l));
-  u_int64_t d;
+  uint64_t d;
   EXPECT_TRUE(m.IsKnownOffsetFrom(l, &d));
   EXPECT_EQ(-0x317730995d2ab6eeULL, d);
   EXPECT_TRUE(m.IsKnownConstant());
@@ -475,10 +475,10 @@
   b = a + 0x1;
   c = b + 0x10;
   d = c + 0x100;
-  EXPECT_EQ(-(u_int64_t)0x111U, a-x);
-  EXPECT_EQ(-(u_int64_t)0x110U, b-x);
-  EXPECT_EQ(-(u_int64_t)0x100U, c-x);
-  EXPECT_EQ(-(u_int64_t)0U,     d-x);
+  EXPECT_EQ(-(uint64_t)0x111U, a-x);
+  EXPECT_EQ(-(uint64_t)0x110U, b-x);
+  EXPECT_EQ(-(uint64_t)0x100U, c-x);
+  EXPECT_EQ(-(uint64_t)0U,     d-x);
 }
 
 TEST(LabelChain, AssignEndRelationBeforeBackward) {
@@ -488,10 +488,10 @@
   d = c + 0x100;
   c = b + 0x10;
   b = a + 0x1;
-  EXPECT_EQ(-(u_int64_t)0x111U, a-x);
-  EXPECT_EQ(-(u_int64_t)0x110U, b-x);
-  EXPECT_EQ(-(u_int64_t)0x100U, c-x);
-  EXPECT_EQ(-(u_int64_t)0U,     d-x);
+  EXPECT_EQ(-(uint64_t)0x111U, a-x);
+  EXPECT_EQ(-(uint64_t)0x110U, b-x);
+  EXPECT_EQ(-(uint64_t)0x100U, c-x);
+  EXPECT_EQ(-(uint64_t)0U,     d-x);
 }
 
 TEST(LabelChain, AssignEndRelationAfterForward) {
@@ -501,10 +501,10 @@
   c = b + 0x10;
   d = c + 0x100;
   x = d;
-  EXPECT_EQ(-(u_int64_t)0x111U, a-x);
-  EXPECT_EQ(-(u_int64_t)0x110U, b-x);
-  EXPECT_EQ(-(u_int64_t)0x100U, c-x);
-  EXPECT_EQ(-(u_int64_t)0x000U, d-x);
+  EXPECT_EQ(-(uint64_t)0x111U, a-x);
+  EXPECT_EQ(-(uint64_t)0x110U, b-x);
+  EXPECT_EQ(-(uint64_t)0x100U, c-x);
+  EXPECT_EQ(-(uint64_t)0x000U, d-x);
 }
 
 TEST(LabelChain, AssignEndRelationAfterBackward) {
@@ -514,10 +514,10 @@
   c = b + 0x10;
   b = a + 0x1;
   x = d;
-  EXPECT_EQ(-(u_int64_t)0x111U, a-x);
-  EXPECT_EQ(-(u_int64_t)0x110U, b-x);
-  EXPECT_EQ(-(u_int64_t)0x100U, c-x);
-  EXPECT_EQ(-(u_int64_t)0x000U, d-x);
+  EXPECT_EQ(-(uint64_t)0x111U, a-x);
+  EXPECT_EQ(-(uint64_t)0x110U, b-x);
+  EXPECT_EQ(-(uint64_t)0x100U, c-x);
+  EXPECT_EQ(-(uint64_t)0x000U, d-x);
 }
 
 TEST(LabelChain, AssignEndValueBeforeForward) {
@@ -623,10 +623,10 @@
   Label c(b + 0x10);
   Label d(c + 0x100);
   x = d;
-  EXPECT_EQ(-(u_int64_t)0x111U, a-x);
-  EXPECT_EQ(-(u_int64_t)0x110U, b-x);
-  EXPECT_EQ(-(u_int64_t)0x100U, c-x);
-  EXPECT_EQ(-(u_int64_t)0x000U, d-x);
+  EXPECT_EQ(-(uint64_t)0x111U, a-x);
+  EXPECT_EQ(-(uint64_t)0x110U, b-x);
+  EXPECT_EQ(-(uint64_t)0x100U, c-x);
+  EXPECT_EQ(-(uint64_t)0x000U, d-x);
 }
 
 TEST(LabelChain, ConstructEndValueAfterForward) {
@@ -732,11 +732,11 @@
  public:
   Section section;
   string contents;
-  static const u_int8_t data[];
+  static const uint8_t data[];
   static const size_t data_size;
 };
 
-const u_int8_t SectionFixture::data[] = {
+const uint8_t SectionFixture::data[] = {
   0x87, 0x4f, 0x43, 0x67, 0x30, 0xd0, 0xd4, 0x0e
 };
 
@@ -753,7 +753,7 @@
 #define ASSERT_BYTES(s, b)                                              \
   do                                                                    \
     {                                                                   \
-      static const u_int8_t expected_bytes[] = b;                       \
+      static const uint8_t expected_bytes[] = b;                       \
       ASSERT_EQ(sizeof(expected_bytes), s.size());                      \
       ASSERT_TRUE(memcmp(s.data(), (const char *) expected_bytes,       \
                          sizeof(expected_bytes)) == 0);                 \
@@ -1361,7 +1361,7 @@
   ASSERT_EQ(8 * 18U, section.Size());
   ASSERT_TRUE(section.GetContents(&contents));
 
-  static const u_int8_t expected[] = {
+  static const uint8_t expected[] = {
     0x35,    0xa6, 0x6b, 0x28, 0xf7, 0xa8, 0x99, 0xa1, 0x61,
     0x8b,    0x39, 0x44, 0x8f, 0x44, 0x40, 0x65, 0xa5, 0x0e,
     0xc9, 0x1c,    0x5e, 0x87, 0xbf, 0xa4, 0x28, 0xb9, 0xf4,
diff --git a/src/google_breakpad/common/breakpad_types.h b/src/google_breakpad/common/breakpad_types.h
index 926b47f..a60c5f3 100644
--- a/src/google_breakpad/common/breakpad_types.h
+++ b/src/google_breakpad/common/breakpad_types.h
@@ -31,7 +31,7 @@
  *
  * (This is C99 source, please don't corrupt it with C++.)
  *
- * This file ensures that types u_intN_t are defined for N = 8, 16, 32, and
+ * This file ensures that types uintN_t are defined for N = 8, 16, 32, and
  * 64.  Types of precise widths are crucial to the task of writing data
  * structures on one platform and reading them on another.
  *
@@ -42,36 +42,39 @@
 
 #ifndef _WIN32
 
-#include <sys/types.h>
 #ifndef __STDC_FORMAT_MACROS
 #define __STDC_FORMAT_MACROS
 #endif  /* __STDC_FORMAT_MACROS */
 #include <inttypes.h>
 
-#if defined(__SUNPRO_CC) || (defined(__GNUC__) && defined(__sun__))
-typedef uint8_t u_int8_t;
-typedef uint16_t u_int16_t;
-typedef uint32_t u_int32_t;
-typedef uint64_t u_int64_t;
-#endif
-
 #else  /* !_WIN32 */
 
+#if _MSC_VER >= 1600
+#include <stdint.h>
+#elif defined(BREAKPAD_CUSTOM_STDINT_H)
+/* Visual C++ Pre-2010 did not ship a stdint.h, so allow
+ * consumers of this library to provide their own because
+ * there are often subtle type incompatibilities.
+ */
+#include BREAKPAD_CUSTOM_STDINT_H
+#else
 #include <WTypes.h>
 
-typedef unsigned __int8  u_int8_t;
-typedef unsigned __int16 u_int16_t;
-typedef unsigned __int32 u_int32_t;
-typedef unsigned __int64 u_int64_t;
+typedef unsigned __int8  uint8_t;
+typedef unsigned __int16 uint16_t;
+typedef __int32 int32_t;
+typedef unsigned __int32 uint32_t;
+typedef unsigned __int64 uint64_t;
+#endif
 
 #endif  /* !_WIN32 */
 
 typedef struct {
-  u_int64_t high;
-  u_int64_t low;
-} u_int128_t;
+  uint64_t high;
+  uint64_t low;
+} uint128_struct;
 
-typedef u_int64_t breakpad_time_t;
+typedef uint64_t breakpad_time_t;
 
 /* Try to get PRIx64 from inttypes.h, but if it's not defined, fall back to
  * llx, which is the format string for "long long" - this is a 64-bit
diff --git a/src/google_breakpad/common/minidump_cpu_amd64.h b/src/google_breakpad/common/minidump_cpu_amd64.h
index fa6a996..4256706 100644
--- a/src/google_breakpad/common/minidump_cpu_amd64.h
+++ b/src/google_breakpad/common/minidump_cpu_amd64.h
@@ -67,7 +67,7 @@
  * equivalent types and values in the Windows Platform SDK are given in
  * comments.
  *
- * Author: Mark Mentovai 
+ * Author: Mark Mentovai
  * Change to split into its own file: Neal Sidhwaney */
 
 #ifndef GOOGLE_BREAKPAD_COMMON_MINIDUMP_CPU_AMD64_H__
@@ -79,22 +79,22 @@
  */
 
 typedef struct {
-  u_int16_t  control_word;
-  u_int16_t  status_word;
-  u_int8_t   tag_word;
-  u_int8_t   reserved1;
-  u_int16_t  error_opcode;
-  u_int32_t  error_offset;
-  u_int16_t  error_selector;
-  u_int16_t  reserved2;
-  u_int32_t  data_offset;
-  u_int16_t  data_selector;
-  u_int16_t  reserved3;
-  u_int32_t  mx_csr;
-  u_int32_t  mx_csr_mask;
-  u_int128_t float_registers[8];
-  u_int128_t xmm_registers[16];
-  u_int8_t   reserved4[96];
+  uint16_t       control_word;
+  uint16_t       status_word;
+  uint8_t        tag_word;
+  uint8_t        reserved1;
+  uint16_t       error_opcode;
+  uint32_t       error_offset;
+  uint16_t       error_selector;
+  uint16_t       reserved2;
+  uint32_t       data_offset;
+  uint16_t       data_selector;
+  uint16_t       reserved3;
+  uint32_t       mx_csr;
+  uint32_t       mx_csr_mask;
+  uint128_struct float_registers[8];
+  uint128_struct xmm_registers[16];
+  uint8_t        reserved4[96];
 } MDXmmSaveArea32AMD64;  /* XMM_SAVE_AREA32 */
 
 #define MD_CONTEXT_AMD64_VR_COUNT 26
@@ -103,63 +103,63 @@
   /*
    * Register parameter home addresses.
    */
-  u_int64_t  p1_home;
-  u_int64_t  p2_home;
-  u_int64_t  p3_home;
-  u_int64_t  p4_home;
-  u_int64_t  p5_home;
-  u_int64_t  p6_home;
+  uint64_t  p1_home;
+  uint64_t  p2_home;
+  uint64_t  p3_home;
+  uint64_t  p4_home;
+  uint64_t  p5_home;
+  uint64_t  p6_home;
 
   /* The next field determines the layout of the structure, and which parts
    * of it are populated */
-  u_int32_t  context_flags;
-  u_int32_t  mx_csr;
+  uint32_t  context_flags;
+  uint32_t  mx_csr;
 
   /* The next register is included with MD_CONTEXT_AMD64_CONTROL */
-  u_int16_t  cs;
+  uint16_t  cs;
 
   /* The next 4 registers are included with MD_CONTEXT_AMD64_SEGMENTS */
-  u_int16_t  ds;
-  u_int16_t  es;
-  u_int16_t  fs;
-  u_int16_t  gs;
+  uint16_t  ds;
+  uint16_t  es;
+  uint16_t  fs;
+  uint16_t  gs;
 
   /* The next 2 registers are included with MD_CONTEXT_AMD64_CONTROL */
-  u_int16_t  ss;
-  u_int32_t  eflags;
-  
+  uint16_t  ss;
+  uint32_t  eflags;
+
   /* The next 6 registers are included with MD_CONTEXT_AMD64_DEBUG_REGISTERS */
-  u_int64_t  dr0;
-  u_int64_t  dr1;
-  u_int64_t  dr2;
-  u_int64_t  dr3;
-  u_int64_t  dr6;
-  u_int64_t  dr7;
+  uint64_t  dr0;
+  uint64_t  dr1;
+  uint64_t  dr2;
+  uint64_t  dr3;
+  uint64_t  dr6;
+  uint64_t  dr7;
 
   /* The next 4 registers are included with MD_CONTEXT_AMD64_INTEGER */
-  u_int64_t  rax;
-  u_int64_t  rcx;
-  u_int64_t  rdx;
-  u_int64_t  rbx;
+  uint64_t  rax;
+  uint64_t  rcx;
+  uint64_t  rdx;
+  uint64_t  rbx;
 
   /* The next register is included with MD_CONTEXT_AMD64_CONTROL */
-  u_int64_t  rsp;
+  uint64_t  rsp;
 
   /* The next 11 registers are included with MD_CONTEXT_AMD64_INTEGER */
-  u_int64_t  rbp;
-  u_int64_t  rsi;
-  u_int64_t  rdi;
-  u_int64_t  r8;
-  u_int64_t  r9;
-  u_int64_t  r10;
-  u_int64_t  r11;
-  u_int64_t  r12;
-  u_int64_t  r13;
-  u_int64_t  r14;
-  u_int64_t  r15;
+  uint64_t  rbp;
+  uint64_t  rsi;
+  uint64_t  rdi;
+  uint64_t  r8;
+  uint64_t  r9;
+  uint64_t  r10;
+  uint64_t  r11;
+  uint64_t  r12;
+  uint64_t  r13;
+  uint64_t  r14;
+  uint64_t  r15;
 
   /* The next register is included with MD_CONTEXT_AMD64_CONTROL */
-  u_int64_t  rip;
+  uint64_t  rip;
 
   /* The next set of registers are included with
    * MD_CONTEXT_AMD64_FLOATING_POINT
@@ -167,37 +167,37 @@
   union {
     MDXmmSaveArea32AMD64 flt_save;
     struct {
-      u_int128_t header[2];
-      u_int128_t legacy[8];
-      u_int128_t xmm0;
-      u_int128_t xmm1;
-      u_int128_t xmm2;
-      u_int128_t xmm3;
-      u_int128_t xmm4;
-      u_int128_t xmm5;
-      u_int128_t xmm6;
-      u_int128_t xmm7;
-      u_int128_t xmm8;
-      u_int128_t xmm9;
-      u_int128_t xmm10;
-      u_int128_t xmm11;
-      u_int128_t xmm12;
-      u_int128_t xmm13;
-      u_int128_t xmm14;
-      u_int128_t xmm15;
+      uint128_struct header[2];
+      uint128_struct legacy[8];
+      uint128_struct xmm0;
+      uint128_struct xmm1;
+      uint128_struct xmm2;
+      uint128_struct xmm3;
+      uint128_struct xmm4;
+      uint128_struct xmm5;
+      uint128_struct xmm6;
+      uint128_struct xmm7;
+      uint128_struct xmm8;
+      uint128_struct xmm9;
+      uint128_struct xmm10;
+      uint128_struct xmm11;
+      uint128_struct xmm12;
+      uint128_struct xmm13;
+      uint128_struct xmm14;
+      uint128_struct xmm15;
     } sse_registers;
   };
 
-  u_int128_t vector_register[MD_CONTEXT_AMD64_VR_COUNT];
-  u_int64_t  vector_control;
+  uint128_struct vector_register[MD_CONTEXT_AMD64_VR_COUNT];
+  uint64_t       vector_control;
 
   /* The next 5 registers are included with MD_CONTEXT_AMD64_DEBUG_REGISTERS */
-  u_int64_t debug_control;
-  u_int64_t last_branch_to_rip;
-  u_int64_t last_branch_from_rip;
-  u_int64_t last_exception_to_rip;
-  u_int64_t last_exception_from_rip;
-  
+  uint64_t debug_control;
+  uint64_t last_branch_to_rip;
+  uint64_t last_branch_from_rip;
+  uint64_t last_exception_to_rip;
+  uint64_t last_exception_from_rip;
+
 } MDRawContextAMD64;  /* CONTEXT */
 
 /* For (MDRawContextAMD64).context_flags.  These values indicate the type of
diff --git a/src/google_breakpad/common/minidump_cpu_arm.h b/src/google_breakpad/common/minidump_cpu_arm.h
index dd07129..6a71138 100644
--- a/src/google_breakpad/common/minidump_cpu_arm.h
+++ b/src/google_breakpad/common/minidump_cpu_arm.h
@@ -77,13 +77,13 @@
  * are not exactly minidumps.
  */
 typedef struct {
-  u_int64_t	fpscr;      /* FPU status register */
+  uint64_t      fpscr;      /* FPU status register */
 
   /* 32 64-bit floating point registers, d0 .. d31. */
-  u_int64_t	regs[MD_FLOATINGSAVEAREA_ARM_FPR_COUNT];
+  uint64_t      regs[MD_FLOATINGSAVEAREA_ARM_FPR_COUNT];
 
   /* Miscellaneous control words */
-  u_int32_t     extra[MD_FLOATINGSAVEAREA_ARM_FPEXTRA_COUNT];
+  uint32_t     extra[MD_FLOATINGSAVEAREA_ARM_FPEXTRA_COUNT];
 } MDFloatingSaveAreaARM;
 
 #define MD_CONTEXT_ARM_GPR_COUNT 16
@@ -92,7 +92,7 @@
   /* The next field determines the layout of the structure, and which parts
    * of it are populated
    */
-  u_int32_t	context_flags;
+  uint32_t      context_flags;
 
   /* 16 32-bit integer registers, r0 .. r15
    * Note the following fixed uses:
@@ -100,7 +100,7 @@
    *   r14 is the link register
    *   r15 is the program counter
    */
-  u_int32_t     iregs[MD_CONTEXT_ARM_GPR_COUNT];
+  uint32_t     iregs[MD_CONTEXT_ARM_GPR_COUNT];
 
   /* CPSR (flags, basically): 32 bits:
         bit 31 - N (negative)
@@ -109,14 +109,14 @@
         bit 28 - V (overflow)
         bit 27 - Q (saturation flag, sticky)
      All other fields -- ignore */
-  u_int32_t    cpsr;
+  uint32_t    cpsr;
 
   /* The next field is included with MD_CONTEXT_ARM_FLOATING_POINT */
   MDFloatingSaveAreaARM float_save;
 
 } MDRawContextARM;
 
-/* Indices into iregs for registers with a dedicated or conventional 
+/* Indices into iregs for registers with a dedicated or conventional
  * purpose.
  */
 enum MDARMRegisterNumbers {
diff --git a/src/google_breakpad/common/minidump_cpu_ppc.h b/src/google_breakpad/common/minidump_cpu_ppc.h
index 038e921..02ac322 100644
--- a/src/google_breakpad/common/minidump_cpu_ppc.h
+++ b/src/google_breakpad/common/minidump_cpu_ppc.h
@@ -81,11 +81,11 @@
 #define MD_FLOATINGSAVEAREA_PPC_FPR_COUNT 32
 
 typedef struct {
-  /* fpregs is a double[32] in mach/ppc/_types.h, but a u_int64_t is used
+  /* fpregs is a double[32] in mach/ppc/_types.h, but a uint64_t is used
    * here for precise sizing. */
-  u_int64_t fpregs[MD_FLOATINGSAVEAREA_PPC_FPR_COUNT];
-  u_int32_t fpscr_pad;
-  u_int32_t fpscr;      /* Status/control */
+  uint64_t fpregs[MD_FLOATINGSAVEAREA_PPC_FPR_COUNT];
+  uint32_t fpscr_pad;
+  uint32_t fpscr;      /* Status/control */
 } MDFloatingSaveAreaPPC;  /* Based on ppc_float_state */
 
 
@@ -94,11 +94,11 @@
 typedef struct {
   /* Vector registers (including vscr) are 128 bits, but mach/ppc/_types.h
    * exposes them as four 32-bit quantities. */
-  u_int128_t save_vr[MD_VECTORSAVEAREA_PPC_VR_COUNT];
-  u_int128_t save_vscr;  /* Status/control */
-  u_int32_t  save_pad5[4];
-  u_int32_t  save_vrvalid;  /* Identifies which vector registers are saved */
-  u_int32_t  save_pad6[7];
+  uint128_struct save_vr[MD_VECTORSAVEAREA_PPC_VR_COUNT];
+  uint128_struct save_vscr;  /* Status/control */
+  uint32_t       save_pad5[4];
+  uint32_t       save_vrvalid;  /* Indicates which vector registers are saved */
+  uint32_t       save_pad6[7];
 } MDVectorSaveAreaPPC;  /* ppc_vector_state */
 
 
@@ -117,21 +117,21 @@
   /* context_flags is not present in ppc_thread_state, but it aids
    * identification of MDRawContextPPC among other raw context types,
    * and it guarantees alignment when we get to float_save. */
-  u_int32_t             context_flags;
+  uint32_t              context_flags;
 
-  u_int32_t             srr0;    /* Machine status save/restore: stores pc
+  uint32_t              srr0;    /* Machine status save/restore: stores pc
                                   * (instruction) */
-  u_int32_t             srr1;    /* Machine status save/restore: stores msr
+  uint32_t              srr1;    /* Machine status save/restore: stores msr
                                   * (ps, program/machine state) */
   /* ppc_thread_state contains 32 fields, r0 .. r31.  Here, an array is
    * used for brevity. */
-  u_int32_t             gpr[MD_CONTEXT_PPC_GPR_COUNT];
-  u_int32_t             cr;      /* Condition */
-  u_int32_t             xer;     /* Integer (fiXed-point) exception */
-  u_int32_t             lr;      /* Link */
-  u_int32_t             ctr;     /* Count */
-  u_int32_t             mq;      /* Multiply/Quotient (PPC 601, POWER only) */
-  u_int32_t             vrsave;  /* Vector save */
+  uint32_t              gpr[MD_CONTEXT_PPC_GPR_COUNT];
+  uint32_t              cr;      /* Condition */
+  uint32_t              xer;     /* Integer (fiXed-point) exception */
+  uint32_t              lr;      /* Link */
+  uint32_t              ctr;     /* Count */
+  uint32_t              mq;      /* Multiply/Quotient (PPC 601, POWER only) */
+  uint32_t              vrsave;  /* Vector save */
 
   /* float_save and vector_save aren't present in ppc_thread_state, but
    * are represented in separate structures that still define a thread's
diff --git a/src/google_breakpad/common/minidump_cpu_ppc64.h b/src/google_breakpad/common/minidump_cpu_ppc64.h
index a788e5d..3a88323 100644
--- a/src/google_breakpad/common/minidump_cpu_ppc64.h
+++ b/src/google_breakpad/common/minidump_cpu_ppc64.h
@@ -90,20 +90,20 @@
   /* context_flags is not present in ppc_thread_state, but it aids
    * identification of MDRawContextPPC among other raw context types,
    * and it guarantees alignment when we get to float_save. */
-  u_int64_t             context_flags;
+  uint64_t              context_flags;
 
-  u_int64_t             srr0;    /* Machine status save/restore: stores pc
+  uint64_t              srr0;    /* Machine status save/restore: stores pc
                                   * (instruction) */
-  u_int64_t             srr1;    /* Machine status save/restore: stores msr
+  uint64_t              srr1;    /* Machine status save/restore: stores msr
                                   * (ps, program/machine state) */
   /* ppc_thread_state contains 32 fields, r0 .. r31.  Here, an array is
    * used for brevity. */
-  u_int64_t             gpr[MD_CONTEXT_PPC64_GPR_COUNT];
-  u_int64_t             cr;      /* Condition */
-  u_int64_t             xer;     /* Integer (fiXed-point) exception */
-  u_int64_t             lr;      /* Link */
-  u_int64_t             ctr;     /* Count */
-  u_int64_t             vrsave;  /* Vector save */
+  uint64_t              gpr[MD_CONTEXT_PPC64_GPR_COUNT];
+  uint64_t              cr;      /* Condition */
+  uint64_t              xer;     /* Integer (fiXed-point) exception */
+  uint64_t              lr;      /* Link */
+  uint64_t              ctr;     /* Count */
+  uint64_t              vrsave;  /* Vector save */
 
   /* float_save and vector_save aren't present in ppc_thread_state, but
    * are represented in separate structures that still define a thread's
@@ -116,14 +116,14 @@
  * context stored in the structure.  MD_CONTEXT_PPC is Breakpad-defined.  Its
  * value was chosen to avoid likely conflicts with MD_CONTEXT_* for other
  * CPUs. */
-#define MD_CONTEXT_PPC                0x20000000
-#define MD_CONTEXT_PPC_BASE           (MD_CONTEXT_PPC | 0x00000001)
-#define MD_CONTEXT_PPC_FLOATING_POINT (MD_CONTEXT_PPC | 0x00000008)
-#define MD_CONTEXT_PPC_VECTOR         (MD_CONTEXT_PPC | 0x00000020)
+#define MD_CONTEXT_PPC64                0x01000000
+#define MD_CONTEXT_PPC64_BASE           (MD_CONTEXT_PPC64 | 0x00000001)
+#define MD_CONTEXT_PPC64_FLOATING_POINT (MD_CONTEXT_PPC64 | 0x00000008)
+#define MD_CONTEXT_PPC64_VECTOR         (MD_CONTEXT_PPC64 | 0x00000020)
 
-#define MD_CONTEXT_PPC_FULL           MD_CONTEXT_PPC_BASE
-#define MD_CONTEXT_PPC_ALL            (MD_CONTEXT_PPC_FULL | \
-                                       MD_CONTEXT_PPC_FLOATING_POINT | \
-                                       MD_CONTEXT_PPC_VECTOR)
+#define MD_CONTEXT_PPC64_FULL           MD_CONTEXT_PPC64_BASE
+#define MD_CONTEXT_PPC64_ALL            (MD_CONTEXT_PPC64_FULL | \
+                                         MD_CONTEXT_PPC64_FLOATING_POINT | \
+                                         MD_CONTEXT_PPC64_VECTOR)
 
 #endif /* GOOGLE_BREAKPAD_COMMON_MINIDUMP_CPU_PPC64_H__ */
diff --git a/src/google_breakpad/common/minidump_cpu_sparc.h b/src/google_breakpad/common/minidump_cpu_sparc.h
index ee95b64..ddc4c75 100644
--- a/src/google_breakpad/common/minidump_cpu_sparc.h
+++ b/src/google_breakpad/common/minidump_cpu_sparc.h
@@ -82,10 +82,10 @@
 typedef struct {
 
   /* FPU floating point regs */
-  u_int64_t	regs[MD_FLOATINGSAVEAREA_SPARC_FPR_COUNT];
+  uint64_t      regs[MD_FLOATINGSAVEAREA_SPARC_FPR_COUNT];
 
-  u_int64_t	filler;
-  u_int64_t	fsr;        /* FPU status register */
+  uint64_t      filler;
+  uint64_t      fsr;        /* FPU status register */
 } MDFloatingSaveAreaSPARC;  /* FLOATING_SAVE_AREA */
 
 #define MD_CONTEXT_SPARC_GPR_COUNT 32
@@ -94,8 +94,8 @@
   /* The next field determines the layout of the structure, and which parts
    * of it are populated
    */
-  u_int32_t	context_flags;
-  u_int32_t	flag_pad;
+  uint32_t      context_flags;
+  uint32_t      flag_pad;
   /*
    * General register access (SPARC).
    * Don't confuse definitions here with definitions in <sys/regset.h>.
@@ -110,28 +110,28 @@
    * g_r[16-23] local registers(l0-l7)
    * g_r[24-31] in registers(i0-i7)
    */
-  u_int64_t     g_r[MD_CONTEXT_SPARC_GPR_COUNT];
+  uint64_t     g_r[MD_CONTEXT_SPARC_GPR_COUNT];
 
   /* several control registers */
 
   /* Processor State register(PSR) for SPARC V7/V8
    * Condition Code register (CCR) for SPARC V9
    */
-  u_int64_t     ccr;
+  uint64_t     ccr;
 
-  u_int64_t     pc;     /* Program Counter register (PC) */
-  u_int64_t     npc;    /* Next Program Counter register (nPC) */
-  u_int64_t     y;      /* Y register (Y) */
+  uint64_t     pc;     /* Program Counter register (PC) */
+  uint64_t     npc;    /* Next Program Counter register (nPC) */
+  uint64_t     y;      /* Y register (Y) */
 
   /* Address Space Identifier register (ASI) for SPARC V9
    * WIM for SPARC V7/V8
    */
-  u_int64_t     asi;
+  uint64_t     asi;
 
   /* Floating-Point Registers State register (FPRS) for SPARC V9
    * TBR for for SPARC V7/V8
    */
-  u_int64_t     fprs;
+  uint64_t     fprs;
 
   /* The next field is included with MD_CONTEXT_SPARC_FLOATING_POINT */
   MDFloatingSaveAreaSPARC float_save;
diff --git a/src/google_breakpad/common/minidump_cpu_x86.h b/src/google_breakpad/common/minidump_cpu_x86.h
index 32aff8a..e09cb7c 100644
--- a/src/google_breakpad/common/minidump_cpu_x86.h
+++ b/src/google_breakpad/common/minidump_cpu_x86.h
@@ -76,18 +76,18 @@
      /* SIZE_OF_80387_REGISTERS */
 
 typedef struct {
-  u_int32_t control_word;
-  u_int32_t status_word;
-  u_int32_t tag_word;
-  u_int32_t error_offset;
-  u_int32_t error_selector;
-  u_int32_t data_offset;
-  u_int32_t data_selector;
+  uint32_t control_word;
+  uint32_t status_word;
+  uint32_t tag_word;
+  uint32_t error_offset;
+  uint32_t error_selector;
+  uint32_t data_offset;
+  uint32_t data_selector;
 
   /* register_area contains eight 80-bit (x87 "long double") quantities for
    * floating-point registers %st0 (%mm0) through %st7 (%mm7). */
-  u_int8_t  register_area[MD_FLOATINGSAVEAREA_X86_REGISTERAREA_SIZE];
-  u_int32_t cr0_npx_state;
+  uint8_t  register_area[MD_FLOATINGSAVEAREA_X86_REGISTERAREA_SIZE];
+  uint32_t cr0_npx_state;
 } MDFloatingSaveAreaX86;  /* FLOATING_SAVE_AREA */
 
 
@@ -97,46 +97,46 @@
 typedef struct {
   /* The next field determines the layout of the structure, and which parts
    * of it are populated */
-  u_int32_t             context_flags;
+  uint32_t             context_flags;
 
   /* The next 6 registers are included with MD_CONTEXT_X86_DEBUG_REGISTERS */
-  u_int32_t             dr0;
-  u_int32_t             dr1;
-  u_int32_t             dr2;
-  u_int32_t             dr3;
-  u_int32_t             dr6;
-  u_int32_t             dr7;
+  uint32_t             dr0;
+  uint32_t             dr1;
+  uint32_t             dr2;
+  uint32_t             dr3;
+  uint32_t             dr6;
+  uint32_t             dr7;
 
   /* The next field is included with MD_CONTEXT_X86_FLOATING_POINT */
   MDFloatingSaveAreaX86 float_save;
 
   /* The next 4 registers are included with MD_CONTEXT_X86_SEGMENTS */
-  u_int32_t             gs; 
-  u_int32_t             fs;
-  u_int32_t             es;
-  u_int32_t             ds;
+  uint32_t             gs; 
+  uint32_t             fs;
+  uint32_t             es;
+  uint32_t             ds;
   /* The next 6 registers are included with MD_CONTEXT_X86_INTEGER */
-  u_int32_t             edi;
-  u_int32_t             esi;
-  u_int32_t             ebx;
-  u_int32_t             edx;
-  u_int32_t             ecx;
-  u_int32_t             eax;
+  uint32_t             edi;
+  uint32_t             esi;
+  uint32_t             ebx;
+  uint32_t             edx;
+  uint32_t             ecx;
+  uint32_t             eax;
 
   /* The next 6 registers are included with MD_CONTEXT_X86_CONTROL */
-  u_int32_t             ebp;
-  u_int32_t             eip;
-  u_int32_t             cs;      /* WinNT.h says "must be sanitized" */
-  u_int32_t             eflags;  /* WinNT.h says "must be sanitized" */
-  u_int32_t             esp;
-  u_int32_t             ss;
+  uint32_t             ebp;
+  uint32_t             eip;
+  uint32_t             cs;      /* WinNT.h says "must be sanitized" */
+  uint32_t             eflags;  /* WinNT.h says "must be sanitized" */
+  uint32_t             esp;
+  uint32_t             ss;
 
   /* The next field is included with MD_CONTEXT_X86_EXTENDED_REGISTERS.
    * It contains vector (MMX/SSE) registers.  It it laid out in the
    * format used by the fxsave and fsrstor instructions, so it includes
    * a copy of the x87 floating-point registers as well.  See FXSAVE in
    * "Intel Architecture Software Developer's Manual, Volume 2." */
-  u_int8_t              extended_registers[
+  uint8_t              extended_registers[
                          MD_CONTEXT_X86_EXTENDED_REGISTERS_SIZE];
 } MDRawContextX86;  /* CONTEXT */
 
diff --git a/src/google_breakpad/common/minidump_format.h b/src/google_breakpad/common/minidump_format.h
index 28a81d4..7fb8c5d 100644
--- a/src/google_breakpad/common/minidump_format.h
+++ b/src/google_breakpad/common/minidump_format.h
@@ -79,10 +79,10 @@
  */
 
 typedef struct {
-  u_int32_t data1;
-  u_int16_t data2;
-  u_int16_t data3;
-  u_int8_t  data4[8];
+  uint32_t data1;
+  uint16_t data2;
+  uint16_t data3;
+  uint8_t  data4[8];
 } MDGUID;  /* GUID */
 
 
@@ -110,7 +110,7 @@
  * structure should never be allocated directly.  The actual structure type
  * can be determined by examining the context_flags field. */
 typedef struct {
-  u_int32_t context_flags;
+  uint32_t context_flags;
 } MDRawContextBase;
 
 #include "minidump_cpu_amd64.h"
@@ -126,19 +126,19 @@
 
 
 typedef struct {
-  u_int32_t signature;
-  u_int32_t struct_version;
-  u_int32_t file_version_hi;
-  u_int32_t file_version_lo;
-  u_int32_t product_version_hi;
-  u_int32_t product_version_lo;
-  u_int32_t file_flags_mask;    /* Identifies valid bits in fileFlags */
-  u_int32_t file_flags;
-  u_int32_t file_os;
-  u_int32_t file_type;
-  u_int32_t file_subtype;
-  u_int32_t file_date_hi;
-  u_int32_t file_date_lo;
+  uint32_t signature;
+  uint32_t struct_version;
+  uint32_t file_version_hi;
+  uint32_t file_version_lo;
+  uint32_t product_version_hi;
+  uint32_t product_version_lo;
+  uint32_t file_flags_mask;    /* Identifies valid bits in fileFlags */
+  uint32_t file_flags;
+  uint32_t file_os;
+  uint32_t file_type;
+  uint32_t file_subtype;
+  uint32_t file_date_hi;
+  uint32_t file_date_lo;
 } MDVSFixedFileInfo;  /* VS_FIXEDFILEINFO */
 
 /* For (MDVSFixedFileInfo).signature */
@@ -231,10 +231,10 @@
 
 /* An MDRVA is an offset into the minidump file.  The beginning of the
  * MDRawHeader is at offset 0. */
-typedef u_int32_t MDRVA;  /* RVA */
+typedef uint32_t MDRVA;  /* RVA */
 
 typedef struct {
-  u_int32_t data_size;
+  uint32_t  data_size;
   MDRVA     rva;
 } MDLocationDescriptor;  /* MINIDUMP_LOCATION_DESCRIPTOR */
 
@@ -242,22 +242,22 @@
 typedef struct {
   /* The base address of the memory range on the host that produced the
    * minidump. */
-  u_int64_t            start_of_memory_range;
+  uint64_t             start_of_memory_range;
 
   MDLocationDescriptor memory;
 } MDMemoryDescriptor;  /* MINIDUMP_MEMORY_DESCRIPTOR */
 
 
 typedef struct {
-  u_int32_t signature;
-  u_int32_t version;
-  u_int32_t stream_count;
+  uint32_t  signature;
+  uint32_t  version;
+  uint32_t  stream_count;
   MDRVA     stream_directory_rva;  /* A |stream_count|-sized array of
                                     * MDRawDirectory structures. */
-  u_int32_t checksum;              /* Can be 0.  In fact, that's all that's
+  uint32_t  checksum;              /* Can be 0.  In fact, that's all that's
                                     * been found in minidump files. */
-  u_int32_t time_date_stamp;       /* time_t */
-  u_int64_t flags;
+  uint32_t  time_date_stamp;       /* time_t */
+  uint64_t  flags;
 } MDRawHeader;  /* MINIDUMP_HEADER */
 
 /* For (MDRawHeader).signature and (MDRawHeader).version.  Note that only the
@@ -302,7 +302,7 @@
 
 
 typedef struct {
-  u_int32_t            stream_type;
+  uint32_t             stream_type;
   MDLocationDescriptor location;
 } MDRawDirectory;  /* MINIDUMP_DIRECTORY */
 
@@ -346,27 +346,27 @@
 
 
 typedef struct {
-  u_int32_t length;     /* Length of buffer in bytes (not characters),
+  uint32_t length;     /* Length of buffer in bytes (not characters),
                          * excluding 0-terminator */
-  u_int16_t buffer[1];  /* UTF-16-encoded, 0-terminated */
+  uint16_t buffer[1];  /* UTF-16-encoded, 0-terminated */
 } MDString;  /* MINIDUMP_STRING */
 
 static const size_t MDString_minsize = offsetof(MDString, buffer[0]);
 
 
 typedef struct {
-  u_int32_t            thread_id;
-  u_int32_t            suspend_count;
-  u_int32_t            priority_class;
-  u_int32_t            priority;
-  u_int64_t            teb;             /* Thread environment block */
+  uint32_t             thread_id;
+  uint32_t             suspend_count;
+  uint32_t             priority_class;
+  uint32_t             priority;
+  uint64_t             teb;             /* Thread environment block */
   MDMemoryDescriptor   stack;
   MDLocationDescriptor thread_context;  /* MDRawContext[CPU] */
 } MDRawThread;  /* MINIDUMP_THREAD */
 
 
 typedef struct {
-  u_int32_t   number_of_threads;
+  uint32_t    number_of_threads;
   MDRawThread threads[1];
 } MDRawThreadList;  /* MINIDUMP_THREAD_LIST */
 
@@ -375,10 +375,10 @@
 
 
 typedef struct {
-  u_int64_t            base_of_image;
-  u_int32_t            size_of_image;
-  u_int32_t            checksum;         /* 0 if unknown */
-  u_int32_t            time_date_stamp;  /* time_t */
+  uint64_t             base_of_image;
+  uint32_t             size_of_image;
+  uint32_t             checksum;         /* 0 if unknown */
+  uint32_t             time_date_stamp;  /* time_t */
   MDRVA                module_name_rva;  /* MDString, pathname or filename */
   MDVSFixedFileInfo    version_info;
 
@@ -402,8 +402,8 @@
    * As a workaround, reserved0 and reserved1 are instead defined here as
    * four 32-bit quantities.  This should be harmless, as there are
    * currently no known uses for these fields. */
-  u_int32_t            reserved0[2];
-  u_int32_t            reserved1[2];
+  uint32_t             reserved0[2];
+  uint32_t             reserved1[2];
 } MDRawModule;  /* MINIDUMP_MODULE */
 
 /* The inclusion of a 64-bit type in MINIDUMP_MODULE forces the struct to
@@ -419,15 +419,15 @@
  * MDCVInfoPDB70 is the expected structure type with recent toolchains. */
 
 typedef struct {
-  u_int32_t signature;
-  u_int32_t offset;     /* Offset to debug data (expect 0 in minidump) */
+  uint32_t signature;
+  uint32_t offset;     /* Offset to debug data (expect 0 in minidump) */
 } MDCVHeader;
 
 typedef struct {
   MDCVHeader cv_header;
-  u_int32_t  signature;         /* time_t debug information created */
-  u_int32_t  age;               /* revision of PDB file */
-  u_int8_t   pdb_file_name[1];  /* Pathname or filename of PDB file */
+  uint32_t   signature;         /* time_t debug information created */
+  uint32_t   age;               /* revision of PDB file */
+  uint8_t    pdb_file_name[1];  /* Pathname or filename of PDB file */
 } MDCVInfoPDB20;
 
 static const size_t MDCVInfoPDB20_minsize = offsetof(MDCVInfoPDB20,
@@ -436,10 +436,10 @@
 #define MD_CVINFOPDB20_SIGNATURE 0x3031424e  /* cvHeader.signature = '01BN' */
 
 typedef struct {
-  u_int32_t cv_signature;
+  uint32_t  cv_signature;
   MDGUID    signature;         /* GUID, identifies PDB file */
-  u_int32_t age;               /* Identifies incremental changes to PDB file */
-  u_int8_t  pdb_file_name[1];  /* Pathname or filename of PDB file,
+  uint32_t  age;               /* Identifies incremental changes to PDB file */
+  uint8_t   pdb_file_name[1];  /* Pathname or filename of PDB file,
                                 * 0-terminated 8-bit character data (UTF-8?) */
 } MDCVInfoPDB70;
 
@@ -449,12 +449,12 @@
 #define MD_CVINFOPDB70_SIGNATURE 0x53445352  /* cvSignature = 'SDSR' */
 
 typedef struct {
-  u_int32_t data1[2];
-  u_int32_t data2;
-  u_int32_t data3;
-  u_int32_t data4;
-  u_int32_t data5[3];
-  u_int8_t extra[2];
+  uint32_t data1[2];
+  uint32_t data2;
+  uint32_t data3;
+  uint32_t data4;
+  uint32_t data5[3];
+  uint8_t  extra[2];
 } MDCVInfoELF;
 
 /* In addition to the two CodeView record formats above, used for linking
@@ -479,12 +479,12 @@
  * obsolete with modules built by recent toolchains. */
 
 typedef struct {
-  u_int32_t data_type;    /* IMAGE_DEBUG_TYPE_*, not defined here because
+  uint32_t  data_type;    /* IMAGE_DEBUG_TYPE_*, not defined here because
                            * this debug record type is mostly obsolete. */
-  u_int32_t length;       /* Length of entire MDImageDebugMisc structure */
-  u_int8_t  unicode;      /* True if data is multibyte */
-  u_int8_t  reserved[3];
-  u_int8_t  data[1];
+  uint32_t  length;       /* Length of entire MDImageDebugMisc structure */
+  uint8_t   unicode;      /* True if data is multibyte */
+  uint8_t   reserved[3];
+  uint8_t   data[1];
 } MDImageDebugMisc;  /* IMAGE_DEBUG_MISC */
 
 static const size_t MDImageDebugMisc_minsize = offsetof(MDImageDebugMisc,
@@ -492,7 +492,7 @@
 
 
 typedef struct {
-  u_int32_t   number_of_modules;
+  uint32_t    number_of_modules;
   MDRawModule modules[1];
 } MDRawModuleList;  /* MINIDUMP_MODULE_LIST */
 
@@ -501,7 +501,7 @@
 
 
 typedef struct {
-  u_int32_t          number_of_memory_ranges;
+  uint32_t           number_of_memory_ranges;
   MDMemoryDescriptor memory_ranges[1];
 } MDRawMemoryList;  /* MINIDUMP_MEMORY_LIST */
 
@@ -512,21 +512,21 @@
 #define MD_EXCEPTION_MAXIMUM_PARAMETERS 15
 
 typedef struct {
-  u_int32_t exception_code;     /* Windows: MDExceptionCodeWin,
+  uint32_t  exception_code;     /* Windows: MDExceptionCodeWin,
                                  * Mac OS X: MDExceptionMac,
                                  * Linux: MDExceptionCodeLinux. */
-  u_int32_t exception_flags;    /* Windows: 1 if noncontinuable,
+  uint32_t  exception_flags;    /* Windows: 1 if noncontinuable,
                                    Mac OS X: MDExceptionCodeMac. */
-  u_int64_t exception_record;   /* Address (in the minidump-producing host's
+  uint64_t  exception_record;   /* Address (in the minidump-producing host's
                                  * memory) of another MDException, for
                                  * nested exceptions. */
-  u_int64_t exception_address;  /* The address that caused the exception.
+  uint64_t  exception_address;  /* The address that caused the exception.
                                  * Mac OS X: exception subcode (which is
                                  *           typically the address). */
-  u_int32_t number_parameters;  /* Number of valid elements in
+  uint32_t  number_parameters;  /* Number of valid elements in
                                  * exception_information. */
-  u_int32_t __align;
-  u_int64_t exception_information[MD_EXCEPTION_MAXIMUM_PARAMETERS];
+  uint32_t  __align;
+  uint64_t  exception_information[MD_EXCEPTION_MAXIMUM_PARAMETERS];
 } MDException;  /* MINIDUMP_EXCEPTION */
 
 #include "minidump_exception_win32.h"
@@ -535,10 +535,10 @@
 #include "minidump_exception_solaris.h"
 
 typedef struct {
-  u_int32_t            thread_id;         /* Thread in which the exception
+  uint32_t             thread_id;         /* Thread in which the exception
                                            * occurred.  Corresponds to
                                            * (MDRawThread).thread_id. */
-  u_int32_t            __align;
+  uint32_t             __align;
   MDException          exception_record;
   MDLocationDescriptor thread_context;    /* MDRawContext[CPU] */
 } MDRawExceptionStream;  /* MINIDUMP_EXCEPTION_STREAM */
@@ -546,13 +546,13 @@
 
 typedef union {
   struct {
-    u_int32_t vendor_id[3];               /* cpuid 0: ebx, edx, ecx */
-    u_int32_t version_information;        /* cpuid 1: eax */
-    u_int32_t feature_information;        /* cpuid 1: edx */
-    u_int32_t amd_extended_cpu_features;  /* cpuid 0x80000001, ebx */
+    uint32_t vendor_id[3];               /* cpuid 0: ebx, edx, ecx */
+    uint32_t version_information;        /* cpuid 1: eax */
+    uint32_t feature_information;        /* cpuid 1: edx */
+    uint32_t amd_extended_cpu_features;  /* cpuid 0x80000001, ebx */
   } x86_cpu_info;
   struct {
-    u_int64_t processor_features[2];
+    uint64_t processor_features[2];
   } other_cpu_info;
 } MDCPUInformation;  /* CPU_INFORMATION */
 
@@ -560,20 +560,20 @@
 typedef struct {
   /* The next 3 fields and numberOfProcessors are from the SYSTEM_INFO
    * structure as returned by GetSystemInfo */
-  u_int16_t        processor_architecture;
-  u_int16_t        processor_level;         /* x86: 5 = 586, 6 = 686, ... */
-  u_int16_t        processor_revision;      /* x86: 0xMMSS, where MM=model,
+  uint16_t         processor_architecture;
+  uint16_t         processor_level;         /* x86: 5 = 586, 6 = 686, ... */
+  uint16_t         processor_revision;      /* x86: 0xMMSS, where MM=model,
                                              *      SS=stepping */
 
-  u_int8_t         number_of_processors;
-  u_int8_t         product_type;            /* Windows: VER_NT_* from WinNT.h */
+  uint8_t          number_of_processors;
+  uint8_t          product_type;            /* Windows: VER_NT_* from WinNT.h */
 
   /* The next 5 fields are from the OSVERSIONINFO structure as returned
    * by GetVersionEx */
-  u_int32_t        major_version;
-  u_int32_t        minor_version;
-  u_int32_t        build_number;
-  u_int32_t        platform_id;
+  uint32_t         major_version;
+  uint32_t         minor_version;
+  uint32_t         build_number;
+  uint32_t         platform_id;
   MDRVA            csd_version_rva;  /* MDString further identifying the
                                       * host OS.
                                       * Windows: name of the installed OS
@@ -582,8 +582,8 @@
                                       *           (sw_vers -buildVersion).
                                       * Linux: uname -srvmo */
 
-  u_int16_t        suite_mask;       /* Windows: VER_SUITE_* from WinNT.h */
-  u_int16_t        reserved2;
+  uint16_t         suite_mask;       /* Windows: VER_SUITE_* from WinNT.h */
+  uint16_t         reserved2;
 
   MDCPUInformation cpu;
 } MDRawSystemInfo;  /* MINIDUMP_SYSTEM_INFO */
@@ -605,6 +605,7 @@
   MD_CPU_ARCHITECTURE_X86_WIN64 = 10,
       /* PROCESSOR_ARCHITECTURE_IA32_ON_WIN64 (WoW64) */
   MD_CPU_ARCHITECTURE_SPARC     = 0x8001, /* Breakpad-defined value for SPARC */
+  MD_CPU_ARCHITECTURE_PPC64     = 0x8002, /* Breakpad-defined value for PPC64 */
   MD_CPU_ARCHITECTURE_UNKNOWN   = 0xffff  /* PROCESSOR_ARCHITECTURE_UNKNOWN */
 } MDCPUArchitecture;
 
@@ -627,29 +628,29 @@
 
 
 typedef struct {
-  u_int32_t size_of_info;  /* Length of entire MDRawMiscInfo structure. */
-  u_int32_t flags1;
+  uint32_t size_of_info;  /* Length of entire MDRawMiscInfo structure. */
+  uint32_t flags1;
 
   /* The next field is only valid if flags1 contains
    * MD_MISCINFO_FLAGS1_PROCESS_ID. */
-  u_int32_t process_id;
+  uint32_t process_id;
 
   /* The next 3 fields are only valid if flags1 contains
    * MD_MISCINFO_FLAGS1_PROCESS_TIMES. */
-  u_int32_t process_create_time;  /* time_t process started */
-  u_int32_t process_user_time;    /* seconds of user CPU time */
-  u_int32_t process_kernel_time;  /* seconds of kernel CPU time */
+  uint32_t process_create_time;  /* time_t process started */
+  uint32_t process_user_time;    /* seconds of user CPU time */
+  uint32_t process_kernel_time;  /* seconds of kernel CPU time */
 
   /* The following fields are not present in MINIDUMP_MISC_INFO but are
    * in MINIDUMP_MISC_INFO_2.  When this struct is populated, these values
    * may not be set.  Use flags1 or sizeOfInfo to determine whether these
    * values are present.  These are only valid when flags1 contains
    * MD_MISCINFO_FLAGS1_PROCESSOR_POWER_INFO. */
-  u_int32_t processor_max_mhz;
-  u_int32_t processor_current_mhz;
-  u_int32_t processor_mhz_limit;
-  u_int32_t processor_max_idle_state;
-  u_int32_t processor_current_idle_state;
+  uint32_t processor_max_mhz;
+  uint32_t processor_current_mhz;
+  uint32_t processor_mhz_limit;
+  uint32_t processor_max_idle_state;
+  uint32_t processor_current_idle_state;
 } MDRawMiscInfo;  /* MINIDUMP_MISC_INFO, MINIDUMP_MISC_INFO2 */
 
 #define MD_MISCINFO_SIZE 24
@@ -666,7 +667,7 @@
       /* MINIDUMP_MISC1_PROCESSOR_POWER_INFO */
 } MDMiscInfoFlags1;
 
-/* 
+/*
  * Around DbgHelp version 6.0, the style of new LIST structures changed
  * from including an array of length 1 at the end of the struct to
  * represent the variable-length data to including explicit
@@ -677,24 +678,24 @@
  */
 
 typedef struct {
-  u_int32_t size_of_header;    /* sizeof(MDRawMemoryInfoList) */
-  u_int32_t size_of_entry;     /* sizeof(MDRawMemoryInfo) */
-  u_int64_t number_of_entries;
+  uint32_t size_of_header;    /* sizeof(MDRawMemoryInfoList) */
+  uint32_t size_of_entry;     /* sizeof(MDRawMemoryInfo) */
+  uint64_t number_of_entries;
 } MDRawMemoryInfoList;  /* MINIDUMP_MEMORY_INFO_LIST */
 
 typedef struct {
-  u_int64_t base_address;           /* Base address of a region of pages */
-  u_int64_t allocation_base;        /* Base address of a range of pages
+  uint64_t  base_address;           /* Base address of a region of pages */
+  uint64_t  allocation_base;        /* Base address of a range of pages
                                      * within this region. */
-  u_int32_t allocation_protection;  /* Memory protection when this region
+  uint32_t  allocation_protection;  /* Memory protection when this region
                                      * was originally allocated:
                                      * MDMemoryProtection */
-  u_int32_t __alignment1;
-  u_int64_t region_size;
-  u_int32_t state;                  /* MDMemoryState */
-  u_int32_t protection;             /* MDMemoryProtection */
-  u_int32_t type;                   /* MDMemoryType */
-  u_int32_t __alignment2;
+  uint32_t  __alignment1;
+  uint64_t  region_size;
+  uint32_t  state;                  /* MDMemoryState */
+  uint32_t  protection;             /* MDMemoryProtection */
+  uint32_t  type;                   /* MDMemoryType */
+  uint32_t  __alignment2;
 } MDRawMemoryInfo;  /* MINIDUMP_MEMORY_INFO */
 
 /* For (MDRawMemoryInfo).state */
@@ -721,7 +722,7 @@
 } MDMemoryProtection;
 
 /* Used to mask the mutually exclusive options from the combinable flags. */
-const u_int32_t MD_MEMORY_PROTECTION_ACCESS_MASK = 0xFF;
+const uint32_t MD_MEMORY_PROTECTION_ACCESS_MASK = 0xFF;
 
 /* For (MDRawMemoryInfo).type */
 typedef enum {
@@ -738,7 +739,7 @@
 typedef struct {
   /* validity is a bitmask with values from MDBreakpadInfoValidity, indicating
    * which of the other fields in the structure are valid. */
-  u_int32_t validity;
+  uint32_t validity;
 
   /* Thread ID of the handler thread.  dump_thread_id should correspond to
    * the thread_id of an MDRawThread in the minidump's MDRawThreadList if
@@ -746,7 +747,7 @@
    * the MDRawThreadList does not contain a dedicated thread used to produce
    * the minidump, this field should be set to 0 and the validity field
    * must not contain MD_BREAKPAD_INFO_VALID_DUMP_THREAD_ID. */
-  u_int32_t dump_thread_id;
+  uint32_t dump_thread_id;
 
   /* Thread ID of the thread that requested the minidump be produced.  As
    * with dump_thread_id, requesting_thread_id should correspond to the
@@ -759,7 +760,7 @@
    * other than a thread in the MDRawThreadList, this field should be set
    * to 0 and the validity field must not contain
    * MD_BREAKPAD_INFO_VALID_REQUESTING_THREAD_ID. */
-  u_int32_t requesting_thread_id;
+  uint32_t requesting_thread_id;
 } MDRawBreakpadInfo;
 
 /* For (MDRawBreakpadInfo).validity: */
@@ -777,11 +778,11 @@
    * written to a file.
    * Fixed-length strings are used because MiniDumpWriteDump doesn't offer
    * a way for user streams to point to arbitrary RVAs for strings. */
-  u_int16_t expression[128];  /* Assertion that failed... */
-  u_int16_t function[128];    /* ...within this function... */
-  u_int16_t file[128];        /* ...in this file... */
-  u_int32_t line;             /* ...at this line. */
-  u_int32_t type;
+  uint16_t expression[128];  /* Assertion that failed... */
+  uint16_t function[128];    /* ...within this function... */
+  uint16_t file[128];        /* ...in this file... */
+  uint32_t line;             /* ...at this line. */
+  uint32_t type;
 } MDRawAssertionInfo;
 
 /* For (MDRawAssertionInfo).type: */
@@ -806,9 +807,9 @@
 } MDRawLinkMap;
 
 typedef struct {
-  u_int32_t version;
+  uint32_t  version;
   MDRVA     map;
-  u_int32_t dso_count;
+  uint32_t  dso_count;
   void*     brk;
   void*     ldbase;
   void*     dynamic;
diff --git a/src/google_breakpad/processor/code_module.h b/src/google_breakpad/processor/code_module.h
index 24b88fb..4e89282 100644
--- a/src/google_breakpad/processor/code_module.h
+++ b/src/google_breakpad/processor/code_module.h
@@ -47,11 +47,11 @@
   virtual ~CodeModule() {}
 
   // The base address of this code module as it was loaded by the process.
-  // (u_int64_t)-1 on error.
-  virtual u_int64_t base_address() const = 0;
+  // (uint64_t)-1 on error.
+  virtual uint64_t base_address() const = 0;
 
   // The size of the code module.  0 on error.
-  virtual u_int64_t size() const = 0;
+  virtual uint64_t size() const = 0;
 
   // The path or file name that the code module was loaded from.  Empty on
   // error.
diff --git a/src/google_breakpad/processor/code_modules.h b/src/google_breakpad/processor/code_modules.h
index 29c55d4..a38579a 100644
--- a/src/google_breakpad/processor/code_modules.h
+++ b/src/google_breakpad/processor/code_modules.h
@@ -53,7 +53,7 @@
   // 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(u_int64_t address) const = 0;
+  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
diff --git a/src/google_breakpad/processor/exploitability.h b/src/google_breakpad/processor/exploitability.h
index 225206d..67255a3 100644
--- a/src/google_breakpad/processor/exploitability.h
+++ b/src/google_breakpad/processor/exploitability.h
@@ -54,7 +54,7 @@
                                                    ProcessState *process_state);
 
   ExploitabilityRating CheckExploitability();
-  bool AddressIsAscii(u_int64_t);
+  bool AddressIsAscii(uint64_t);
 
  protected:
   Exploitability(Minidump *dump,
diff --git a/src/google_breakpad/processor/memory_region.h b/src/google_breakpad/processor/memory_region.h
index 15e23dd..bd9755f 100644
--- a/src/google_breakpad/processor/memory_region.h
+++ b/src/google_breakpad/processor/memory_region.h
@@ -50,10 +50,10 @@
   virtual ~MemoryRegion() {}
 
   // The base address of this memory region.
-  virtual u_int64_t GetBase() const = 0;
+  virtual uint64_t GetBase() const = 0;
 
   // The size of this memory region.
-  virtual u_int32_t GetSize() const = 0;
+  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
@@ -63,10 +63,10 @@
   // 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(u_int64_t address, u_int8_t*  value) const =0;
-  virtual bool GetMemoryAtAddress(u_int64_t address, u_int16_t* value) const =0;
-  virtual bool GetMemoryAtAddress(u_int64_t address, u_int32_t* value) const =0;
-  virtual bool GetMemoryAtAddress(u_int64_t address, u_int64_t* value) const =0;
+  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;
 };
 
 
diff --git a/src/google_breakpad/processor/minidump.h b/src/google_breakpad/processor/minidump.h
index 5e60a77..87c0027 100644
--- a/src/google_breakpad/processor/minidump.h
+++ b/src/google_breakpad/processor/minidump.h
@@ -154,7 +154,7 @@
   // 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(u_int32_t expected_size) = 0;
+  virtual bool Read(uint32_t expected_size) = 0;
 };
 
 
@@ -176,11 +176,11 @@
   // 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.
-  u_int32_t GetContextCPU() const;
+  uint32_t GetContextCPU() const;
 
   // A convenience method to get the instruction pointer out of the
   // MDRawContext, since it varies per-CPU architecture.
-  bool GetInstructionPointer(u_int64_t* ip) const;
+  bool GetInstructionPointer(uint64_t* ip) 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
@@ -188,6 +188,7 @@
   const MDRawContextAMD64* GetContextAMD64() const;
   const MDRawContextARM*   GetContextARM() const;
   const MDRawContextPPC*   GetContextPPC() const;
+  const MDRawContextPPC64* GetContextPPC64() const;
   const MDRawContextSPARC* GetContextSPARC() const;
   const MDRawContextX86*   GetContextX86() const;
 
@@ -202,6 +203,7 @@
     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
@@ -210,13 +212,13 @@
   } context_;
 
   // Store this separately because of the weirdo AMD64 context
-  u_int32_t context_flags_;
+  uint32_t context_flags_;
 
  private:
   friend class MinidumpThread;
   friend class MinidumpException;
 
-  bool Read(u_int32_t expected_size);
+  bool Read(uint32_t expected_size);
 
   // Free the CPU-specific context structure.
   void FreeContext();
@@ -226,7 +228,7 @@
   // 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(u_int32_t context_cpu_type);
+  bool CheckAgainstSystemInfo(uint32_t context_cpu_type);
 };
 
 
@@ -243,28 +245,28 @@
  public:
   virtual ~MinidumpMemoryRegion();
 
-  static void set_max_bytes(u_int32_t max_bytes) { max_bytes_ = max_bytes; }
-  static u_int32_t max_bytes() { return max_bytes_; }
+  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 u_int8_t* GetMemory() const;
+  const uint8_t* GetMemory() const;
 
   // The address of the base of the memory region.
-  u_int64_t GetBase() const;
+  uint64_t GetBase() const;
 
   // The size, in bytes, of the memory region.
-  u_int32_t GetSize() const;
+  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(u_int64_t address, u_int8_t*  value) const;
-  bool GetMemoryAtAddress(u_int64_t address, u_int16_t* value) const;
-  bool GetMemoryAtAddress(u_int64_t address, u_int32_t* value) const;
-  bool GetMemoryAtAddress(u_int64_t address, u_int64_t* value) const;
+  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();
@@ -281,19 +283,19 @@
   void SetDescriptor(MDMemoryDescriptor* descriptor);
 
   // Implementation for GetMemoryAtAddress
-  template<typename T> bool GetMemoryAtAddressInternal(u_int64_t address,
+  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 u_int32_t max_bytes_;
+  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<u_int8_t>* memory_;
+  mutable vector<uint8_t>* memory_;
 };
 
 
@@ -319,7 +321,7 @@
   // 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(u_int32_t *thread_id) const;
+  virtual bool GetThreadID(uint32_t *thread_id) const;
 
   // Print a human-readable representation of the object to stdout.
   void Print();
@@ -348,10 +350,10 @@
  public:
   virtual ~MinidumpThreadList();
 
-  static void set_max_threads(u_int32_t max_threads) {
+  static void set_max_threads(uint32_t max_threads) {
     max_threads_ = max_threads;
   }
-  static u_int32_t max_threads() { return max_threads_; }
+  static uint32_t max_threads() { return max_threads_; }
 
   virtual unsigned int thread_count() const {
     return valid_ ? thread_count_ : 0;
@@ -361,7 +363,7 @@
   virtual MinidumpThread* GetThreadAtIndex(unsigned int index) const;
 
   // Random access to threads.
-  MinidumpThread* GetThreadByID(u_int32_t thread_id);
+  MinidumpThread* GetThreadByID(uint32_t thread_id);
 
   // Print a human-readable representation of the object to stdout.
   void Print();
@@ -372,23 +374,23 @@
  private:
   friend class Minidump;
 
-  typedef map<u_int32_t, MinidumpThread*> IDToThreadMap;
+  typedef map<uint32_t, MinidumpThread*> IDToThreadMap;
   typedef vector<MinidumpThread> MinidumpThreads;
 
-  static const u_int32_t kStreamType = MD_THREAD_LIST_STREAM;
+  static const uint32_t kStreamType = MD_THREAD_LIST_STREAM;
 
-  bool Read(u_int32_t aExpectedSize);
+  bool Read(uint32_t aExpectedSize);
 
   // The largest number of threads that will be read from a minidump.  The
   // default is 256.
-  static u_int32_t max_threads_;
+  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_;
-  u_int32_t        thread_count_;
+  uint32_t        thread_count_;
 };
 
 
@@ -401,23 +403,23 @@
  public:
   virtual ~MinidumpModule();
 
-  static void set_max_cv_bytes(u_int32_t max_cv_bytes) {
+  static void set_max_cv_bytes(uint32_t max_cv_bytes) {
     max_cv_bytes_ = max_cv_bytes;
   }
-  static u_int32_t max_cv_bytes() { return max_cv_bytes_; }
+  static uint32_t max_cv_bytes() { return max_cv_bytes_; }
 
-  static void set_max_misc_bytes(u_int32_t max_misc_bytes) {
+  static void set_max_misc_bytes(uint32_t max_misc_bytes) {
     max_misc_bytes_ = max_misc_bytes;
   }
-  static u_int32_t max_misc_bytes() { return max_misc_bytes_; }
+  static uint32_t max_misc_bytes() { return max_misc_bytes_; }
 
   const MDRawModule* module() const { return valid_ ? &module_ : NULL; }
 
   // CodeModule implementation
-  virtual u_int64_t base_address() const {
-    return valid_ ? module_.base_of_image : static_cast<u_int64_t>(-1);
+  virtual uint64_t base_address() const {
+    return valid_ ? module_.base_of_image : static_cast<uint64_t>(-1);
   }
-  virtual u_int64_t size() const { return valid_ ? module_.size_of_image : 0; }
+  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;
@@ -426,7 +428,7 @@
   virtual const CodeModule* Copy() const;
 
   // The CodeView record, which contains information to locate the module's
-  // debugging information (pdb).  This is returned as u_int8_t* because
+  // 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
@@ -435,14 +437,14 @@
   // 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 u_int8_t* GetCVRecord(u_int32_t* size);
+  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(u_int32_t* size);
+  const MDImageDebugMisc* GetMiscRecord(uint32_t* size);
 
   // Print a human-readable representation of the object to stdout.
   void Print();
@@ -469,8 +471,8 @@
   // 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 u_int32_t max_cv_bytes_;
-  static u_int32_t max_misc_bytes_;
+  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.
@@ -490,20 +492,20 @@
   const string*     name_;
 
   // Cached CodeView record - this is MDCVInfoPDB20 or (likely)
-  // MDCVInfoPDB70, or possibly something else entirely.  Stored as a u_int8_t
+  // 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<u_int8_t>* cv_record_;
+  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.
-  u_int32_t cv_record_signature_;
+  uint32_t cv_record_signature_;
 
-  // Cached MDImageDebugMisc (usually not present), stored as u_int8_t
+  // 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<u_int8_t>* misc_record_;
+  vector<uint8_t>* misc_record_;
 };
 
 
@@ -516,16 +518,16 @@
  public:
   virtual ~MinidumpModuleList();
 
-  static void set_max_modules(u_int32_t max_modules) {
+  static void set_max_modules(uint32_t max_modules) {
     max_modules_ = max_modules;
   }
-  static u_int32_t max_modules() { return 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(u_int64_t address) const;
+  virtual const MinidumpModule* GetModuleForAddress(uint64_t address) const;
   virtual const MinidumpModule* GetMainModule() const;
   virtual const MinidumpModule* GetModuleAtSequence(
       unsigned int sequence) const;
@@ -543,19 +545,19 @@
 
   typedef vector<MinidumpModule> MinidumpModules;
 
-  static const u_int32_t kStreamType = MD_MODULE_LIST_STREAM;
+  static const uint32_t kStreamType = MD_MODULE_LIST_STREAM;
 
-  bool Read(u_int32_t expected_size);
+  bool Read(uint32_t expected_size);
 
   // The largest number of modules that will be read from a minidump.  The
   // default is 1024.
-  static u_int32_t max_modules_;
+  static uint32_t max_modules_;
 
   // Access to modules using addresses as the key.
-  RangeMap<u_int64_t, unsigned int> *range_map_;
+  RangeMap<uint64_t, unsigned int> *range_map_;
 
   MinidumpModules *modules_;
-  u_int32_t module_count_;
+  uint32_t module_count_;
 };
 
 
@@ -572,10 +574,10 @@
  public:
   virtual ~MinidumpMemoryList();
 
-  static void set_max_regions(u_int32_t max_regions) {
+  static void set_max_regions(uint32_t max_regions) {
     max_regions_ = max_regions;
   }
-  static u_int32_t max_regions() { return max_regions_; }
+  static uint32_t max_regions() { return max_regions_; }
 
   unsigned int region_count() const { return valid_ ? region_count_ : 0; }
 
@@ -584,7 +586,7 @@
 
   // Random access to memory regions.  Returns the region encompassing
   // the address identified by address.
-  MinidumpMemoryRegion* GetMemoryRegionForAddress(u_int64_t address);
+  MinidumpMemoryRegion* GetMemoryRegionForAddress(uint64_t address);
 
   // Print a human-readable representation of the object to stdout.
   void Print();
@@ -595,18 +597,18 @@
   typedef vector<MDMemoryDescriptor>   MemoryDescriptors;
   typedef vector<MinidumpMemoryRegion> MemoryRegions;
 
-  static const u_int32_t kStreamType = MD_MEMORY_LIST_STREAM;
+  static const uint32_t kStreamType = MD_MEMORY_LIST_STREAM;
 
   explicit MinidumpMemoryList(Minidump* minidump);
 
-  bool Read(u_int32_t expected_size);
+  bool Read(uint32_t expected_size);
 
   // The largest number of memory regions that will be read from a minidump.
   // The default is 256.
-  static u_int32_t max_regions_;
+  static uint32_t max_regions_;
 
   // Access to memory regions using addresses as the key.
-  RangeMap<u_int64_t, unsigned int> *range_map_;
+  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
@@ -616,7 +618,7 @@
 
   // The list of regions.
   MemoryRegions *regions_;
-  u_int32_t region_count_;
+  uint32_t region_count_;
 };
 
 
@@ -638,7 +640,7 @@
   // 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(u_int32_t *thread_id) const;
+  bool GetThreadID(uint32_t *thread_id) const;
 
   MinidumpContext* GetContext();
 
@@ -648,11 +650,11 @@
  private:
   friend class Minidump;
 
-  static const u_int32_t kStreamType = MD_EXCEPTION_STREAM;
+  static const uint32_t kStreamType = MD_EXCEPTION_STREAM;
 
   explicit MinidumpException(Minidump* minidump);
 
-  bool Read(u_int32_t expected_size);
+  bool Read(uint32_t expected_size);
 
   MDRawExceptionStream exception_;
   MinidumpContext*     context_;
@@ -686,11 +688,11 @@
  private:
   friend class Minidump;
 
-  static const u_int32_t kStreamType = MD_ASSERTION_INFO_STREAM;
+  static const uint32_t kStreamType = MD_ASSERTION_INFO_STREAM;
 
   explicit MinidumpAssertion(Minidump* minidump);
 
-  bool Read(u_int32_t expected_size);
+  bool Read(uint32_t expected_size);
 
   MDRawAssertionInfo assertion_;
   string expression_;
@@ -743,9 +745,9 @@
  private:
   friend class Minidump;
 
-  static const u_int32_t kStreamType = MD_SYSTEM_INFO_STREAM;
+  static const uint32_t kStreamType = MD_SYSTEM_INFO_STREAM;
 
-  bool Read(u_int32_t expected_size);
+  bool Read(uint32_t expected_size);
 
   // A string identifying the CPU vendor, if known.
   const string* cpu_vendor_;
@@ -767,11 +769,11 @@
  private:
   friend class Minidump;
 
-  static const u_int32_t kStreamType = MD_MISC_INFO_STREAM;
+  static const uint32_t kStreamType = MD_MISC_INFO_STREAM;
 
   explicit MinidumpMiscInfo(Minidump* minidump_);
 
-  bool Read(u_int32_t expected_size_);
+  bool Read(uint32_t expected_size_);
 
   MDRawMiscInfo misc_info_;
 };
@@ -790,8 +792,8 @@
   // 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(u_int32_t *thread_id) const;
-  bool GetRequestingThreadID(u_int32_t *thread_id) const;
+  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();
@@ -799,11 +801,11 @@
  private:
   friend class Minidump;
 
-  static const u_int32_t kStreamType = MD_BREAKPAD_INFO_STREAM;
+  static const uint32_t kStreamType = MD_BREAKPAD_INFO_STREAM;
 
   explicit MinidumpBreakpadInfo(Minidump* minidump_);
 
-  bool Read(u_int32_t expected_size_);
+  bool Read(uint32_t expected_size_);
 
   MDRawBreakpadInfo breakpad_info_;
 };
@@ -816,10 +818,10 @@
   const MDRawMemoryInfo* info() const { return valid_ ? &memory_info_ : NULL; }
 
   // The address of the base of the memory region.
-  u_int64_t GetBase() const { return valid_ ? memory_info_.base_address : 0; }
+  uint64_t GetBase() const { return valid_ ? memory_info_.base_address : 0; }
 
   // The size, in bytes, of the memory region.
-  u_int32_t GetSize() const { return valid_ ? memory_info_.region_size : 0; }
+  uint32_t GetSize() const { return valid_ ? memory_info_.region_size : 0; }
 
   // Return true if the memory protection allows execution.
   bool IsExecutable() const;
@@ -854,7 +856,7 @@
 
   unsigned int info_count() const { return valid_ ? info_count_ : 0; }
 
-  const MinidumpMemoryInfo* GetMemoryInfoForAddress(u_int64_t address) const;
+  const MinidumpMemoryInfo* GetMemoryInfoForAddress(uint64_t address) const;
   const MinidumpMemoryInfo* GetMemoryInfoAtIndex(unsigned int index) const;
 
   // Print a human-readable representation of the object to stdout.
@@ -865,17 +867,17 @@
 
   typedef vector<MinidumpMemoryInfo> MinidumpMemoryInfos;
 
-  static const u_int32_t kStreamType = MD_MEMORY_INFO_LIST_STREAM;
+  static const uint32_t kStreamType = MD_MEMORY_INFO_LIST_STREAM;
 
   explicit MinidumpMemoryInfoList(Minidump* minidump);
 
-  bool Read(u_int32_t expected_size);
+  bool Read(uint32_t expected_size);
 
   // Access to memory info using addresses as the key.
-  RangeMap<u_int64_t, unsigned int> *range_map_;
+  RangeMap<uint64_t, unsigned int> *range_map_;
 
   MinidumpMemoryInfos* infos_;
-  u_int32_t info_count_;
+  uint32_t info_count_;
 };
 
 
@@ -896,18 +898,28 @@
   virtual string path() const {
     return path_;
   }
-  static void set_max_streams(u_int32_t max_streams) {
+  static void set_max_streams(uint32_t max_streams) {
     max_streams_ = max_streams;
   }
-  static u_int32_t max_streams() { return max_streams_; }
+  static uint32_t max_streams() { return max_streams_; }
 
-  static void set_max_string_length(u_int32_t max_string_length) {
+  static void set_max_string_length(uint32_t max_string_length) {
     max_string_length_ = max_string_length;
   }
-  static u_int32_t max_string_length() { return 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
@@ -970,7 +982,7 @@
   // possibility, and consider using GetDirectoryEntryAtIndex (possibly
   // with GetDirectoryEntryCount) if expecting multiple streams of the same
   // type in a single minidump file.
-  bool SeekToStreamType(u_int32_t stream_type, u_int32_t* stream_length);
+  bool SeekToStreamType(uint32_t stream_type, uint32_t* stream_length);
 
   bool swap() const { return valid_ ? swap_ : false; }
 
@@ -993,7 +1005,7 @@
   };
 
   typedef vector<MDRawDirectory> MinidumpDirectoryEntries;
-  typedef map<u_int32_t, MinidumpStreamInfo> MinidumpStreamMap;
+  typedef map<uint32_t, MinidumpStreamInfo> MinidumpStreamMap;
 
   template<typename T> T* GetStream(T** stream);
 
@@ -1003,7 +1015,7 @@
   // 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 u_int32_t max_streams_;
+  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
diff --git a/src/google_breakpad/processor/minidump_processor.h b/src/google_breakpad/processor/minidump_processor.h
index 0e10f40..33cd020 100644
--- a/src/google_breakpad/processor/minidump_processor.h
+++ b/src/google_breakpad/processor/minidump_processor.h
@@ -131,7 +131,7 @@
   // 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, u_int64_t* address);
+  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
diff --git a/src/google_breakpad/processor/process_state.h b/src/google_breakpad/processor/process_state.h
index 8d71457..d234ebb 100644
--- a/src/google_breakpad/processor/process_state.h
+++ b/src/google_breakpad/processor/process_state.h
@@ -94,10 +94,10 @@
   void Clear();
 
   // Accessors.  See the data declarations below.
-  u_int32_t time_date_stamp() const { return time_date_stamp_; }
+  uint32_t time_date_stamp() const { return time_date_stamp_; }
   bool crashed() const { return crashed_; }
   string crash_reason() const { return crash_reason_; }
-  u_int64_t crash_address() const { return crash_address_; }
+  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_; }
@@ -106,6 +106,9 @@
   }
   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_;
+  }
   ExploitabilityRating exploitability() const { return exploitability_; }
 
  private:
@@ -113,7 +116,7 @@
   friend class MinidumpProcessor;
 
   // The time-date stamp of the minidump (time_t format)
-  u_int32_t time_date_stamp_;
+  uint32_t time_date_stamp_;
 
   // True if the process crashed, false if the dump was produced outside
   // of an exception handler.
@@ -129,7 +132,7 @@
   // 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.
-  u_int64_t crash_address_;
+  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
@@ -158,6 +161,9 @@
   // ProcessState.
   const CodeModules *modules_;
 
+  // The modules that didn't have symbols when the report was processed.
+  vector<const CodeModule*> modules_without_symbols_;
+
   // The exploitability rating as determined by the exploitability
   // engine. When the exploitability engine is not enabled this
   // defaults to EXPLOITABILITY_NONE.
diff --git a/src/google_breakpad/processor/source_line_resolver_interface.h b/src/google_breakpad/processor/source_line_resolver_interface.h
index 4e9dd4b..7b69b0d 100644
--- a/src/google_breakpad/processor/source_line_resolver_interface.h
+++ b/src/google_breakpad/processor/source_line_resolver_interface.h
@@ -48,7 +48,7 @@
 
 class SourceLineResolverInterface {
  public:
-  typedef u_int64_t MemAddr;
+  typedef uint64_t MemAddr;
 
   virtual ~SourceLineResolverInterface() {}
 
diff --git a/src/google_breakpad/processor/stack_frame.h b/src/google_breakpad/processor/stack_frame.h
index 2f31e5c..23e69bb 100644
--- a/src/google_breakpad/processor/stack_frame.h
+++ b/src/google_breakpad/processor/stack_frame.h
@@ -83,12 +83,32 @@
     }
   };
 
-  // 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 will be within
-  // the instruction that caused execution to branch to a called function,
-  // but may not necessarily point to the exact beginning of that instruction.
-  u_int64_t instruction;
+  // 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;
@@ -98,7 +118,7 @@
 
   // The start address of the function, may be omitted if debug symbols
   // are not available.
-  u_int64_t function_base;
+  uint64_t function_base;
 
   // The source file name, may be omitted if debug symbols are not available.
   string source_file_name;
@@ -109,7 +129,7 @@
 
   // The start address of the source line, may be omitted if debug symbols
   // are not available.
-  u_int64_t source_line_base;
+  uint64_t source_line_base;
 
   // Amount of trust the stack walker has in the instruction pointer
   // of this frame.
diff --git a/src/google_breakpad/processor/stack_frame_cpu.h b/src/google_breakpad/processor/stack_frame_cpu.h
index 9032876..cda3a8d 100644
--- a/src/google_breakpad/processor/stack_frame_cpu.h
+++ b/src/google_breakpad/processor/stack_frame_cpu.h
@@ -77,6 +77,9 @@
        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
@@ -120,6 +123,32 @@
   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.
@@ -147,6 +176,9 @@
 
   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.
diff --git a/src/google_breakpad/processor/stack_frame_symbolizer.h b/src/google_breakpad/processor/stack_frame_symbolizer.h
index ec4a9ce..6f89167 100644
--- a/src/google_breakpad/processor/stack_frame_symbolizer.h
+++ b/src/google_breakpad/processor/stack_frame_symbolizer.h
@@ -56,13 +56,13 @@
   enum SymbolizerResult {
     // Symbol data was found and successfully loaded in resolver.
     // This does NOT guarantee source line info is found within symbol file.
-    NO_ERROR,
+    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.
-    ERROR,
+    kError,
     // This indicates error for which stack walk should be interrupted
     // and retried in future.
-    INTERRUPT,
+    kInterrupt
   };
 
   StackFrameSymbolizer(SymbolSupplier* supplier,
diff --git a/src/google_breakpad/processor/stackwalker.h b/src/google_breakpad/processor/stackwalker.h
index 2979fef..f09291f 100644
--- a/src/google_breakpad/processor/stackwalker.h
+++ b/src/google_breakpad/processor/stackwalker.h
@@ -43,6 +43,7 @@
 
 #include <set>
 #include <string>
+#include <vector>
 
 #include "common/using_std_string.h"
 #include "google_breakpad/common/breakpad_types.h"
@@ -57,6 +58,7 @@
 class StackFrameSymbolizer;
 
 using std::set;
+using std::vector;
 
 class Stackwalker {
  public:
@@ -66,7 +68,15 @@
   // 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().
-  bool Walk(CallStack* stack);
+  // Upon return, modules_without_symbols will be populated with pointers to
+  // the code modules (CodeModule*) that DON'T have symbols.
+  // modules_without_symbols DOES 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);
 
   // Returns a new concrete subclass suitable for the CPU that a stack was
   // generated on, according to the CPU type indicated by the context
@@ -78,8 +88,8 @@
      const CodeModules* modules,
      StackFrameSymbolizer* resolver_helper);
 
-  static void set_max_frames(u_int32_t max_frames) { max_frames_ = max_frames; }
-  static u_int32_t max_frames() { return max_frames_; }
+  static void set_max_frames(uint32_t max_frames) { max_frames_ = max_frames; }
+  static uint32_t max_frames() { return max_frames_; }
 
  protected:
   // system_info identifies the operating system, NULL or empty if unknown.
@@ -104,13 +114,16 @@
   // * 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(u_int64_t address);
+  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) {
-    const int kRASearchWords = 30;
     return ScanForReturnAddress(location_start, location_found, ip_found,
                                 kRASearchWords);
   }
@@ -182,10 +195,9 @@
 
   // The maximum number of frames Stackwalker will walk through.
   // This defaults to 1024 to prevent infinite loops.
-  static u_int32_t max_frames_;
+  static uint32_t max_frames_;
 };
 
-
 }  // namespace google_breakpad
 
 
diff --git a/src/processor/basic_code_module.h b/src/processor/basic_code_module.h
index 635c09a..3fe782b 100644
--- a/src/processor/basic_code_module.h
+++ b/src/processor/basic_code_module.h
@@ -63,7 +63,7 @@
         debug_identifier_(that->debug_identifier()),
         version_(that->version()) {}
 
-  BasicCodeModule(u_int64_t base_address, u_int64_t size,
+  BasicCodeModule(uint64_t base_address, uint64_t size,
 		  const string &code_file,
 		  const string &code_identifier,
 		  const string &debug_file,
@@ -81,8 +81,8 @@
 
   // See code_module.h for descriptions of these methods and the associated
   // members.
-  virtual u_int64_t base_address() const { return base_address_; }
-  virtual u_int64_t size() const { return size_; }
+  virtual uint64_t base_address() const { return base_address_; }
+  virtual uint64_t size() const { return size_; }
   virtual string code_file() const { return code_file_; }
   virtual string code_identifier() const { return code_identifier_; }
   virtual string debug_file() const { return debug_file_; }
@@ -91,8 +91,8 @@
   virtual const CodeModule* Copy() const { return new BasicCodeModule(this); }
 
  private:
-  u_int64_t base_address_;
-  u_int64_t size_;
+  uint64_t base_address_;
+  uint64_t size_;
   string code_file_;
   string code_identifier_;
   string debug_file_;
diff --git a/src/processor/basic_code_modules.cc b/src/processor/basic_code_modules.cc
index 63da899..71874be 100644
--- a/src/processor/basic_code_modules.cc
+++ b/src/processor/basic_code_modules.cc
@@ -47,7 +47,7 @@
 
 BasicCodeModules::BasicCodeModules(const CodeModules *that)
     : main_address_(0),
-      map_(new RangeMap<u_int64_t, linked_ptr<const CodeModule> >()) {
+      map_(new RangeMap<uint64_t, linked_ptr<const CodeModule> >()) {
   BPLOG_IF(ERROR, !that) << "BasicCodeModules::BasicCodeModules requires "
                             "|that|";
   assert(that);
@@ -82,7 +82,7 @@
 }
 
 const CodeModule* BasicCodeModules::GetModuleForAddress(
-    u_int64_t address) const {
+    uint64_t address) const {
   linked_ptr<const CodeModule> module;
   if (!map_->RetrieveRange(address, &module, NULL, NULL)) {
     BPLOG(INFO) << "No module at " << HexString(address);
diff --git a/src/processor/basic_code_modules.h b/src/processor/basic_code_modules.h
index df87fc4..d302287 100644
--- a/src/processor/basic_code_modules.h
+++ b/src/processor/basic_code_modules.h
@@ -61,7 +61,7 @@
 
   // See code_modules.h for descriptions of these methods.
   virtual unsigned int module_count() const;
-  virtual const CodeModule* GetModuleForAddress(u_int64_t address) const;
+  virtual const CodeModule* GetModuleForAddress(uint64_t address) const;
   virtual const CodeModule* GetMainModule() const;
   virtual const CodeModule* GetModuleAtSequence(unsigned int sequence) const;
   virtual const CodeModule* GetModuleAtIndex(unsigned int index) const;
@@ -69,11 +69,11 @@
 
  private:
   // The base address of the main module.
-  u_int64_t main_address_;
+  uint64_t main_address_;
 
   // The map used to contain each CodeModule, keyed by each CodeModule's
   // address range.
-  RangeMap<u_int64_t, linked_ptr<const CodeModule> > *map_;
+  RangeMap<uint64_t, linked_ptr<const CodeModule> > *map_;
 
   // Disallow copy constructor and assignment operator.
   BasicCodeModules(const BasicCodeModules &that);
diff --git a/src/processor/basic_source_line_resolver.cc b/src/processor/basic_source_line_resolver.cc
index ff57140..55f8f9a 100644
--- a/src/processor/basic_source_line_resolver.cc
+++ b/src/processor/basic_source_line_resolver.cc
@@ -37,7 +37,6 @@
 #include <string.h>
 #include <sys/types.h>
 #include <sys/stat.h>
-#include <unistd.h>
 
 #include <map>
 #include <utility>
@@ -55,6 +54,11 @@
 
 namespace google_breakpad {
 
+#ifdef _WIN32
+#define strtok_r strtok_s
+#define strtoull _strtoui64
+#endif
+
 static const char *kWhitespace = " \r\n";
 
 BasicSourceLineResolver::BasicSourceLineResolver() :
@@ -300,8 +304,8 @@
     return NULL;
   }
 
-  u_int64_t address    = strtoull(tokens[0], NULL, 16);
-  u_int64_t size       = strtoull(tokens[1], NULL, 16);
+  uint64_t address     = strtoull(tokens[0], NULL, 16);
+  uint64_t size        = strtoull(tokens[1], NULL, 16);
   int stack_param_size = strtoull(tokens[2], NULL, 16);
   char *name           = tokens[3];
 
@@ -316,8 +320,8 @@
     return NULL;
   }
 
-  u_int64_t address = strtoull(tokens[0], NULL, 16);
-  u_int64_t size    = strtoull(tokens[1], NULL, 16);
+  uint64_t address  = strtoull(tokens[0], NULL, 16);
+  uint64_t size     = strtoull(tokens[1], NULL, 16);
   int line_number   = atoi(tokens[2]);
   int source_file   = atoi(tokens[3]);
   if (line_number <= 0) {
@@ -338,7 +342,7 @@
     return false;
   }
 
-  u_int64_t address    = strtoull(tokens[0], NULL, 16);
+  uint64_t address     = strtoull(tokens[0], NULL, 16);
   int stack_param_size = strtoull(tokens[1], NULL, 16);
   char *name           = tokens[2];
 
@@ -373,7 +377,7 @@
   // MSVC stack frame info.
   if (strcmp(platform, "WIN") == 0) {
     int type = 0;
-    u_int64_t rva, code_size;
+    uint64_t rva, code_size;
     linked_ptr<WindowsFrameInfo>
       stack_frame_info(WindowsFrameInfo::ParseFromString(stack_info_line,
                                                          type,
diff --git a/src/processor/basic_source_line_resolver_types.h b/src/processor/basic_source_line_resolver_types.h
index 87b93db..94616dc 100644
--- a/src/processor/basic_source_line_resolver_types.h
+++ b/src/processor/basic_source_line_resolver_types.h
@@ -40,6 +40,7 @@
 #include <map>
 #include <string>
 
+#include "common/scoped_ptr.h"
 #include "google_breakpad/processor/basic_source_line_resolver.h"
 #include "processor/source_line_resolver_base_types.h"
 
@@ -48,7 +49,6 @@
 #include "processor/contained_range_map-inl.h"
 
 #include "processor/linked_ptr.h"
-#include "processor/scoped_ptr.h"
 #include "google_breakpad/processor/stack_frame.h"
 #include "processor/cfi_frame_info.h"
 #include "processor/windows_frame_info.h"
diff --git a/src/processor/basic_source_line_resolver_unittest.cc b/src/processor/basic_source_line_resolver_unittest.cc
index bf8507a..8525e9e 100644
--- a/src/processor/basic_source_line_resolver_unittest.cc
+++ b/src/processor/basic_source_line_resolver_unittest.cc
@@ -32,6 +32,7 @@
 #include <string>
 
 #include "breakpad_googletest_includes.h"
+#include "common/scoped_ptr.h"
 #include "common/using_std_string.h"
 #include "google_breakpad/processor/basic_source_line_resolver.h"
 #include "google_breakpad/processor/code_module.h"
@@ -39,7 +40,6 @@
 #include "google_breakpad/processor/memory_region.h"
 #include "processor/linked_ptr.h"
 #include "processor/logging.h"
-#include "processor/scoped_ptr.h"
 #include "processor/windows_frame_info.h"
 #include "processor/cfi_frame_info.h"
 
@@ -59,8 +59,8 @@
   TestCodeModule(string code_file) : code_file_(code_file) {}
   virtual ~TestCodeModule() {}
 
-  virtual u_int64_t base_address() const { return 0; }
-  virtual u_int64_t size() const { return 0xb000; }
+  virtual uint64_t base_address() const { return 0; }
+  virtual uint64_t size() const { return 0xb000; }
   virtual string code_file() const { return code_file_; }
   virtual string code_identifier() const { return ""; }
   virtual string debug_file() const { return ""; }
@@ -76,17 +76,17 @@
 
 // A mock memory region object, for use by the STACK CFI tests.
 class MockMemoryRegion: public MemoryRegion {
-  u_int64_t GetBase() const { return 0x10000; }
-  u_int32_t GetSize() const { return 0x01000; }
-  bool GetMemoryAtAddress(u_int64_t address, u_int8_t *value) const {
+  uint64_t GetBase() const { return 0x10000; }
+  uint32_t GetSize() const { return 0x01000; }
+  bool GetMemoryAtAddress(uint64_t address, uint8_t *value) const {
     *value = address & 0xff;
     return true;
   }
-  bool GetMemoryAtAddress(u_int64_t address, u_int16_t *value) const {
+  bool GetMemoryAtAddress(uint64_t address, uint16_t *value) const {
     *value = address & 0xffff;
     return true;
   }
-  bool GetMemoryAtAddress(u_int64_t address, u_int32_t *value) const {
+  bool GetMemoryAtAddress(uint64_t address, uint32_t *value) const {
     switch (address) {
       case 0x10008: *value = 0x98ecadc3; break; // saved %ebx
       case 0x1000c: *value = 0x878f7524; break; // saved %esi
@@ -97,7 +97,7 @@
     }
     return true;
   }
-  bool GetMemoryAtAddress(u_int64_t address, u_int64_t *value) const {
+  bool GetMemoryAtAddress(uint64_t address, uint64_t *value) const {
     *value = address;
     return true;
   }
@@ -109,9 +109,9 @@
 // ".cfa".
 static bool VerifyRegisters(
     const char *file, int line,
-    const CFIFrameInfo::RegisterValueMap<u_int32_t> &expected,
-    const CFIFrameInfo::RegisterValueMap<u_int32_t> &actual) {
-  CFIFrameInfo::RegisterValueMap<u_int32_t>::const_iterator a;
+    const CFIFrameInfo::RegisterValueMap<uint32_t> &expected,
+    const CFIFrameInfo::RegisterValueMap<uint32_t> &actual) {
+  CFIFrameInfo::RegisterValueMap<uint32_t>::const_iterator a;
   a = actual.find(".cfa");
   if (a == actual.end())
     return false;
@@ -119,7 +119,7 @@
   if (a == actual.end())
     return false;
   for (a = actual.begin(); a != actual.end(); a++) {
-    CFIFrameInfo::RegisterValueMap<u_int32_t>::const_iterator e =
+    CFIFrameInfo::RegisterValueMap<uint32_t>::const_iterator e =
       expected.find(a->first);
     if (e == expected.end()) {
       fprintf(stderr, "%s:%d: unexpected register '%s' recovered, value 0x%x\n",
@@ -252,9 +252,9 @@
   cfi_frame_info.reset(resolver.FindCFIFrameInfo(&frame));
   ASSERT_FALSE(cfi_frame_info.get());
 
-  CFIFrameInfo::RegisterValueMap<u_int32_t> current_registers;
-  CFIFrameInfo::RegisterValueMap<u_int32_t> caller_registers;
-  CFIFrameInfo::RegisterValueMap<u_int32_t> expected_caller_registers;
+  CFIFrameInfo::RegisterValueMap<uint32_t> current_registers;
+  CFIFrameInfo::RegisterValueMap<uint32_t> caller_registers;
+  CFIFrameInfo::RegisterValueMap<uint32_t> expected_caller_registers;
   MockMemoryRegion memory;
 
   // Regardless of which instruction evaluation takes place at, it
@@ -277,7 +277,7 @@
   cfi_frame_info.reset(resolver.FindCFIFrameInfo(&frame));
   ASSERT_TRUE(cfi_frame_info.get());
   ASSERT_TRUE(cfi_frame_info.get()
-              ->FindCallerRegs<u_int32_t>(current_registers, memory,
+              ->FindCallerRegs<uint32_t>(current_registers, memory,
                                           &caller_registers));
   ASSERT_TRUE(VerifyRegisters(__FILE__, __LINE__,
                               expected_caller_registers, caller_registers));
@@ -287,7 +287,7 @@
   cfi_frame_info.reset(resolver.FindCFIFrameInfo(&frame));
   ASSERT_TRUE(cfi_frame_info.get());
   ASSERT_TRUE(cfi_frame_info.get()
-              ->FindCallerRegs<u_int32_t>(current_registers, memory,
+              ->FindCallerRegs<uint32_t>(current_registers, memory,
                                           &caller_registers));
   ASSERT_TRUE(VerifyRegisters(__FILE__, __LINE__,
                               expected_caller_registers, caller_registers));
@@ -297,7 +297,7 @@
   cfi_frame_info.reset(resolver.FindCFIFrameInfo(&frame));
   ASSERT_TRUE(cfi_frame_info.get());
   ASSERT_TRUE(cfi_frame_info.get()
-              ->FindCallerRegs<u_int32_t>(current_registers, memory,
+              ->FindCallerRegs<uint32_t>(current_registers, memory,
                                           &caller_registers));
   VerifyRegisters(__FILE__, __LINE__,
                   expected_caller_registers, caller_registers);
@@ -307,7 +307,7 @@
   cfi_frame_info.reset(resolver.FindCFIFrameInfo(&frame));
   ASSERT_TRUE(cfi_frame_info.get());
   ASSERT_TRUE(cfi_frame_info.get()
-              ->FindCallerRegs<u_int32_t>(current_registers, memory,
+              ->FindCallerRegs<uint32_t>(current_registers, memory,
                                           &caller_registers));
   VerifyRegisters(__FILE__, __LINE__,
                   expected_caller_registers, caller_registers);
@@ -317,7 +317,7 @@
   cfi_frame_info.reset(resolver.FindCFIFrameInfo(&frame));
   ASSERT_TRUE(cfi_frame_info.get());
   ASSERT_TRUE(cfi_frame_info.get()
-              ->FindCallerRegs<u_int32_t>(current_registers, memory,
+              ->FindCallerRegs<uint32_t>(current_registers, memory,
                                           &caller_registers));
   VerifyRegisters(__FILE__, __LINE__,
                   expected_caller_registers, caller_registers);
@@ -327,7 +327,7 @@
   cfi_frame_info.reset(resolver.FindCFIFrameInfo(&frame));
   ASSERT_TRUE(cfi_frame_info.get());
   ASSERT_TRUE(cfi_frame_info.get()
-              ->FindCallerRegs<u_int32_t>(current_registers, memory,
+              ->FindCallerRegs<uint32_t>(current_registers, memory,
                                           &caller_registers));
   VerifyRegisters(__FILE__, __LINE__,
                   expected_caller_registers, caller_registers);
diff --git a/src/processor/binarystream.cc b/src/processor/binarystream.cc
index 9ed3b70..bf92225 100644
--- a/src/processor/binarystream.cc
+++ b/src/processor/binarystream.cc
@@ -40,7 +40,7 @@
 using std::vector;
 
 binarystream &binarystream::operator>>(string &str) {
-  u_int16_t length;
+  uint16_t length;
   *this >> length;
   if (eof())
     return *this;
@@ -55,68 +55,68 @@
   return *this;
 }
 
-binarystream &binarystream::operator>>(u_int8_t &u8) {
+binarystream &binarystream::operator>>(uint8_t &u8) {
   stream_.read((char *)&u8, 1);
   return *this;
 }
 
-binarystream &binarystream::operator>>(u_int16_t &u16) {
-  u_int16_t temp;
+binarystream &binarystream::operator>>(uint16_t &u16) {
+  uint16_t temp;
   stream_.read((char *)&temp, 2);
   if (!eof())
     u16 = ntohs(temp);
   return *this;
 }
 
-binarystream &binarystream::operator>>(u_int32_t &u32) {
-  u_int32_t temp;
+binarystream &binarystream::operator>>(uint32_t &u32) {
+  uint32_t temp;
   stream_.read((char *)&temp, 4);
   if (!eof())
     u32 = ntohl(temp);
   return *this;
 }
 
-binarystream &binarystream::operator>>(u_int64_t &u64) {
-  u_int32_t lower, upper;
+binarystream &binarystream::operator>>(uint64_t &u64) {
+  uint32_t lower, upper;
   *this >> lower >> upper;
   if (!eof())
-    u64 = static_cast<u_int64_t>(lower) | (static_cast<u_int64_t>(upper) << 32);
+    u64 = static_cast<uint64_t>(lower) | (static_cast<uint64_t>(upper) << 32);
   return *this;
 }
 
 binarystream &binarystream::operator<<(const string &str) {
   if (str.length() > USHRT_MAX) {
     // truncate to 16-bit length
-    *this << static_cast<u_int16_t>(USHRT_MAX);
+    *this << static_cast<uint16_t>(USHRT_MAX);
     stream_.write(str.c_str(), USHRT_MAX);
   } else {
-    *this << (u_int16_t)(str.length() & 0xFFFF);
+    *this << (uint16_t)(str.length() & 0xFFFF);
     stream_.write(str.c_str(), str.length());
   }
   return *this;
 }
 
-binarystream &binarystream::operator<<(u_int8_t u8) {
+binarystream &binarystream::operator<<(uint8_t u8) {
   stream_.write((const char*)&u8, 1);
   return *this;
 }
 
-binarystream &binarystream::operator<<(u_int16_t u16) {
+binarystream &binarystream::operator<<(uint16_t u16) {
   u16 = htons(u16);
   stream_.write((const char*)&u16, 2);
   return *this;
 }
 
-binarystream &binarystream::operator<<(u_int32_t u32) {
+binarystream &binarystream::operator<<(uint32_t u32) {
   u32 = htonl(u32);
   stream_.write((const char*)&u32, 4);
   return *this;
 }
 
-binarystream &binarystream::operator<<(u_int64_t u64) {
+binarystream &binarystream::operator<<(uint64_t u64) {
   // write 64-bit ints as two 32-bit ints, so we can byte-swap them easily
-  u_int32_t lower = static_cast<u_int32_t>(u64 & 0xFFFFFFFF);
-  u_int32_t upper = static_cast<u_int32_t>(u64 >> 32);
+  uint32_t lower = static_cast<uint32_t>(u64 & 0xFFFFFFFF);
+  uint32_t upper = static_cast<uint32_t>(u64 >> 32);
   *this << lower << upper;
   return *this;
 }
diff --git a/src/processor/binarystream.h b/src/processor/binarystream.h
index 0465715..172e09b 100644
--- a/src/processor/binarystream.h
+++ b/src/processor/binarystream.h
@@ -56,17 +56,17 @@
     : stream_(string(str, size), which) {}
 
   binarystream &operator>>(string &str);
-  binarystream &operator>>(u_int8_t &u8);
-  binarystream &operator>>(u_int16_t &u16);
-  binarystream &operator>>(u_int32_t &u32);
-  binarystream &operator>>(u_int64_t &u64);
+  binarystream &operator>>(uint8_t &u8);
+  binarystream &operator>>(uint16_t &u16);
+  binarystream &operator>>(uint32_t &u32);
+  binarystream &operator>>(uint64_t &u64);
 
   // Note: strings are truncated at 65535 characters
   binarystream &operator<<(const string &str);
-  binarystream &operator<<(u_int8_t u8);
-  binarystream &operator<<(u_int16_t u16);
-  binarystream &operator<<(u_int32_t u32);
-  binarystream &operator<<(u_int64_t u64);
+  binarystream &operator<<(uint8_t u8);
+  binarystream &operator<<(uint16_t u16);
+  binarystream &operator<<(uint32_t u32);
+  binarystream &operator<<(uint64_t u64);
 
   // Forward a few methods directly from the stream object
   bool eof() const { return stream_.eof(); }
diff --git a/src/processor/binarystream_unittest.cc b/src/processor/binarystream_unittest.cc
index 8a3daa3..bf020ed 100644
--- a/src/processor/binarystream_unittest.cc
+++ b/src/processor/binarystream_unittest.cc
@@ -47,14 +47,14 @@
 };
  
 TEST_F(BinaryStreamBasicTest, ReadU8) {
-  u_int8_t u8 = 0;
+  uint8_t u8 = 0;
   ASSERT_FALSE(stream.eof());
   stream >> u8;
   ASSERT_TRUE(stream.eof());
   EXPECT_EQ(0U, u8);
   stream.rewind();
   stream.clear();
-  stream << (u_int8_t)1;
+  stream << (uint8_t)1;
   ASSERT_FALSE(stream.eof());
   stream >> u8;
   EXPECT_EQ(1, u8);
@@ -62,14 +62,14 @@
 }
 
 TEST_F(BinaryStreamBasicTest, ReadU16) {
-  u_int16_t u16 = 0;
+  uint16_t u16 = 0;
   ASSERT_FALSE(stream.eof());
   stream >> u16;
   ASSERT_TRUE(stream.eof());
   EXPECT_EQ(0U, u16);
   stream.rewind();
   stream.clear();
-  stream << (u_int16_t)1;
+  stream << (uint16_t)1;
   ASSERT_FALSE(stream.eof());
   stream >> u16;
   EXPECT_EQ(1, u16);
@@ -77,14 +77,14 @@
 }
 
 TEST_F(BinaryStreamBasicTest, ReadU32) {
-  u_int32_t u32 = 0;
+  uint32_t u32 = 0;
   ASSERT_FALSE(stream.eof());
   stream >> u32;
   ASSERT_TRUE(stream.eof());
   EXPECT_EQ(0U, u32);
   stream.rewind();
   stream.clear();
-  stream << (u_int32_t)1;
+  stream << (uint32_t)1;
   ASSERT_FALSE(stream.eof());
   stream >> u32;
   EXPECT_EQ(1U, u32);
@@ -92,14 +92,14 @@
 }
 
 TEST_F(BinaryStreamBasicTest, ReadU64) {
-  u_int64_t u64 = 0;
+  uint64_t u64 = 0;
   ASSERT_FALSE(stream.eof());
   stream >> u64;
   ASSERT_TRUE(stream.eof());
   EXPECT_EQ(0U, u64);
   stream.rewind();
   stream.clear();
-  stream << (u_int64_t)1;
+  stream << (uint64_t)1;
   ASSERT_FALSE(stream.eof());
   stream >> u64;
   EXPECT_EQ(1U, u64);
@@ -137,8 +137,8 @@
 }
 
 TEST_F(BinaryStreamBasicTest, ReadMultiU8) {
-  const u_int8_t ea = 0, eb = 100, ec = 200, ed = 0xFF;
-  u_int8_t a, b, c, d, e;
+  const uint8_t ea = 0, eb = 100, ec = 200, ed = 0xFF;
+  uint8_t a, b, c, d, e;
   stream << ea << eb << ec << ed;
   stream >> a >> b >> c >> d;
   ASSERT_FALSE(stream.eof());
@@ -167,8 +167,8 @@
 }
 
 TEST_F(BinaryStreamBasicTest, ReadMultiU16) {
-  const u_int16_t ea = 0, eb = 0x100, ec = 0x8000, ed = 0xFFFF;
-  u_int16_t a, b, c, d, e;
+  const uint16_t ea = 0, eb = 0x100, ec = 0x8000, ed = 0xFFFF;
+  uint16_t a, b, c, d, e;
   stream << ea << eb << ec << ed;
   stream >> a >> b >> c >> d;
   ASSERT_FALSE(stream.eof());
@@ -197,8 +197,8 @@
 }
 
 TEST_F(BinaryStreamBasicTest, ReadMultiU32) {
-  const u_int32_t ea = 0, eb = 0x10000, ec = 0x8000000, ed = 0xFFFFFFFF;
-  u_int32_t a, b, c, d, e;
+  const uint32_t ea = 0, eb = 0x10000, ec = 0x8000000, ed = 0xFFFFFFFF;
+  uint32_t a, b, c, d, e;
   stream << ea << eb << ec << ed;
   stream >> a >> b >> c >> d;
   ASSERT_FALSE(stream.eof());
@@ -227,9 +227,9 @@
 }
 
 TEST_F(BinaryStreamBasicTest, ReadMultiU64) {
-  const u_int64_t ea = 0, eb = 0x10000, ec = 0x100000000ULL,
+  const uint64_t ea = 0, eb = 0x10000, ec = 0x100000000ULL,
     ed = 0xFFFFFFFFFFFFFFFFULL;
-  u_int64_t a, b, c, d, e;
+  uint64_t a, b, c, d, e;
   stream << ea << eb << ec << ed;
   stream >> a >> b >> c >> d;
   ASSERT_FALSE(stream.eof());
@@ -258,15 +258,15 @@
 }
 
 TEST_F(BinaryStreamBasicTest, ReadMixed) {
-  const u_int8_t e8 = 0x10;
-  const u_int16_t e16 = 0x2020;
-  const u_int32_t e32 = 0x30303030;
-  const u_int64_t e64 = 0x4040404040404040ULL;
+  const uint8_t e8 = 0x10;
+  const uint16_t e16 = 0x2020;
+  const uint32_t e32 = 0x30303030;
+  const uint64_t e64 = 0x4040404040404040ULL;
   const string es = "test";
-  u_int8_t u8 = 0;
-  u_int16_t u16 = 0;
-  u_int32_t u32 = 0;
-  u_int64_t u64 = 0;
+  uint8_t u8 = 0;
+  uint16_t u16 = 0;
+  uint32_t u32 = 0;
+  uint64_t u64 = 0;
   string s("test");
   stream << e8 << e16 << e32 << e64 << es;
   stream >> u8 >> u16 >> u32 >> u64 >> s;
@@ -280,7 +280,7 @@
 
 TEST_F(BinaryStreamBasicTest, ReadStringMissing) {
   // ensure that reading a string where only the length is present fails
-  u_int16_t u16 = 8;
+  uint16_t u16 = 8;
   stream << u16;
   stream.rewind();
   string s("");
@@ -291,9 +291,9 @@
 
 TEST_F(BinaryStreamBasicTest, ReadStringTruncated) {
   // ensure that reading a string where not all the data is present fails
-  u_int16_t u16 = 8;
+  uint16_t u16 = 8;
   stream << u16;
-  stream << (u_int8_t)'t' << (u_int8_t)'e' << (u_int8_t)'s' << (u_int8_t)'t';
+  stream << (uint8_t)'t' << (uint8_t)'e' << (uint8_t)'s' << (uint8_t)'t';
   stream.rewind();
   string s("");
   stream >> s;
@@ -303,7 +303,7 @@
 
 TEST_F(BinaryStreamBasicTest, StreamByteLength) {
   // Test that the stream buffer contains the right amount of data
-  stream << (u_int8_t)0 << (u_int16_t)1 << (u_int32_t)2 << (u_int64_t)3
+  stream << (uint8_t)0 << (uint16_t)1 << (uint32_t)2 << (uint64_t)3
          << string("test");
   string s = stream.str();
   EXPECT_EQ(21U, s.length());
@@ -313,8 +313,8 @@
   // Test that appending the str() results from two streams
   // gives the right byte length
   binarystream stream2;
-  stream << (u_int8_t)0 << (u_int16_t)1;
-  stream2 << (u_int32_t)0 << (u_int64_t)2
+  stream << (uint8_t)0 << (uint16_t)1;
+  stream2 << (uint32_t)0 << (uint64_t)2
           << string("test");
   string s = stream.str();
   string s2 = stream2.str();
@@ -344,12 +344,12 @@
   binarystream stream;
 
   void SetUp() {
-    stream << (u_int8_t)1;
+    stream << (uint8_t)1;
   }
 };
 
 TEST_F(BinaryStreamU8Test, ReadU16) {
-  u_int16_t u16 = 0;
+  uint16_t u16 = 0;
   ASSERT_FALSE(stream.eof());
   stream >> u16;
   ASSERT_TRUE(stream.eof());
@@ -357,7 +357,7 @@
 }
 
 TEST_F(BinaryStreamU8Test, ReadU32) {
-  u_int32_t u32 = 0;
+  uint32_t u32 = 0;
   ASSERT_FALSE(stream.eof());
   stream >> u32;
   ASSERT_TRUE(stream.eof());
@@ -365,7 +365,7 @@
 }
 
 TEST_F(BinaryStreamU8Test, ReadU64) {
-  u_int64_t u64 = 0;
+  uint64_t u64 = 0;
   ASSERT_FALSE(stream.eof());
   stream >> u64;
   ASSERT_TRUE(stream.eof());
@@ -384,7 +384,7 @@
 TEST(BinaryStreamTest, InitWithData) {
   const char *data = "abcd";
   binarystream stream(data);
-  u_int8_t a, b, c, d;
+  uint8_t a, b, c, d;
   stream >> a >> b >> c >> d;
   ASSERT_FALSE(stream.eof());
   EXPECT_EQ('a', a);
@@ -396,7 +396,7 @@
 TEST(BinaryStreamTest, InitWithDataLeadingNull) {
   const char *data = "\0abcd";
   binarystream stream(data, 5);
-  u_int8_t z, a, b, c, d;
+  uint8_t z, a, b, c, d;
   stream >> z >> a >> b >> c >> d;
   ASSERT_FALSE(stream.eof());
   EXPECT_EQ(0U, z);
@@ -415,7 +415,7 @@
   data.push_back('e');
   data.resize(4);
   binarystream stream(&data[0], data.size());
-  u_int8_t a, b, c, d;
+  uint8_t a, b, c, d;
   stream >> a >> b >> c >> d;
   ASSERT_FALSE(stream.eof());
   EXPECT_EQ('a', a);
diff --git a/src/processor/cfi_frame_info.cc b/src/processor/cfi_frame_info.cc
index 1ded99d..5106ba0 100644
--- a/src/processor/cfi_frame_info.cc
+++ b/src/processor/cfi_frame_info.cc
@@ -38,11 +38,15 @@
 
 #include <sstream>
 
+#include "common/scoped_ptr.h"
 #include "processor/postfix_evaluator-inl.h"
-#include "processor/scoped_ptr.h"
 
 namespace google_breakpad {
 
+#ifdef _WIN32
+#define strtok_r strtok_s
+#endif
+
 template<typename V>
 bool CFIFrameInfo::FindCallerRegs(const RegisterValueMap<V> &registers,
                                   const MemoryRegion &memory,
@@ -88,14 +92,14 @@
 }
 
 // Explicit instantiations for 32-bit and 64-bit architectures.
-template bool CFIFrameInfo::FindCallerRegs<u_int32_t>(
-    const RegisterValueMap<u_int32_t> &registers,
+template bool CFIFrameInfo::FindCallerRegs<uint32_t>(
+    const RegisterValueMap<uint32_t> &registers,
     const MemoryRegion &memory,
-    RegisterValueMap<u_int32_t> *caller_registers) const;
-template bool CFIFrameInfo::FindCallerRegs<u_int64_t>(
-    const RegisterValueMap<u_int64_t> &registers,
+    RegisterValueMap<uint32_t> *caller_registers) const;
+template bool CFIFrameInfo::FindCallerRegs<uint64_t>(
+    const RegisterValueMap<uint64_t> &registers,
     const MemoryRegion &memory,
-    RegisterValueMap<u_int64_t> *caller_registers) const;
+    RegisterValueMap<uint64_t> *caller_registers) const;
 
 string CFIFrameInfo::Serialize() const {
   std::ostringstream stream;
diff --git a/src/processor/cfi_frame_info.h b/src/processor/cfi_frame_info.h
index 4bbbd1e..bba2978 100644
--- a/src/processor/cfi_frame_info.h
+++ b/src/processor/cfi_frame_info.h
@@ -80,8 +80,8 @@
 
   // Compute the values of the calling frame's registers, according to
   // this rule set. Use ValueType in expression evaluation; this
-  // should be u_int32_t on machines with 32-bit addresses, or
-  // u_int64_t on machines with 64-bit addresses.
+  // should be uint32_t on machines with 32-bit addresses, or
+  // uint64_t on machines with 64-bit addresses.
   //
   // Return true on success, false otherwise.
   //
@@ -204,7 +204,7 @@
 // up in a class should allow the walkers to share code.
 //
 // RegisterType should be the type of this architecture's registers, either
-// u_int32_t or u_int64_t. RawContextType should be the raw context
+// uint32_t or uint64_t. RawContextType should be the raw context
 // structure type for this architecture.
 template <typename RegisterType, class RawContextType>
 class SimpleCFIWalker {
diff --git a/src/processor/cfi_frame_info_unittest.cc b/src/processor/cfi_frame_info_unittest.cc
index cd48e16..eabce11 100644
--- a/src/processor/cfi_frame_info_unittest.cc
+++ b/src/processor/cfi_frame_info_unittest.cc
@@ -54,12 +54,12 @@
 
 class MockMemoryRegion: public MemoryRegion {
  public:
-  MOCK_CONST_METHOD0(GetBase, u_int64_t());
-  MOCK_CONST_METHOD0(GetSize, u_int32_t());
-  MOCK_CONST_METHOD2(GetMemoryAtAddress, bool(u_int64_t, u_int8_t *));
-  MOCK_CONST_METHOD2(GetMemoryAtAddress, bool(u_int64_t, u_int16_t *));
-  MOCK_CONST_METHOD2(GetMemoryAtAddress, bool(u_int64_t, u_int32_t *));
-  MOCK_CONST_METHOD2(GetMemoryAtAddress, bool(u_int64_t, u_int64_t *));
+  MOCK_CONST_METHOD0(GetBase, uint64_t());
+  MOCK_CONST_METHOD0(GetSize, uint32_t());
+  MOCK_CONST_METHOD2(GetMemoryAtAddress, bool(uint64_t, uint8_t *));
+  MOCK_CONST_METHOD2(GetMemoryAtAddress, bool(uint64_t, uint16_t *));
+  MOCK_CONST_METHOD2(GetMemoryAtAddress, bool(uint64_t, uint32_t *));
+  MOCK_CONST_METHOD2(GetMemoryAtAddress, bool(uint64_t, uint64_t *));
 };
 
 // Handy definitions for all tests.
@@ -69,15 +69,15 @@
   void ExpectNoMemoryReferences() {
     EXPECT_CALL(memory, GetBase()).Times(0);
     EXPECT_CALL(memory, GetSize()).Times(0);
-    EXPECT_CALL(memory, GetMemoryAtAddress(_, A<u_int8_t *>())).Times(0);
-    EXPECT_CALL(memory, GetMemoryAtAddress(_, A<u_int16_t *>())).Times(0);
-    EXPECT_CALL(memory, GetMemoryAtAddress(_, A<u_int32_t *>())).Times(0);
-    EXPECT_CALL(memory, GetMemoryAtAddress(_, A<u_int64_t *>())).Times(0);
+    EXPECT_CALL(memory, GetMemoryAtAddress(_, A<uint8_t *>())).Times(0);
+    EXPECT_CALL(memory, GetMemoryAtAddress(_, A<uint16_t *>())).Times(0);
+    EXPECT_CALL(memory, GetMemoryAtAddress(_, A<uint32_t *>())).Times(0);
+    EXPECT_CALL(memory, GetMemoryAtAddress(_, A<uint64_t *>())).Times(0);
   }
 
   CFIFrameInfo cfi;
   MockMemoryRegion memory;
-  CFIFrameInfo::RegisterValueMap<u_int64_t> registers, caller_registers;
+  CFIFrameInfo::RegisterValueMap<uint64_t> registers, caller_registers;
 };
 
 class Simple: public CFIFixture, public Test { };
@@ -87,7 +87,7 @@
   ExpectNoMemoryReferences();
 
   cfi.SetRARule("0");
-  ASSERT_FALSE(cfi.FindCallerRegs<u_int64_t>(registers, memory,
+  ASSERT_FALSE(cfi.FindCallerRegs<uint64_t>(registers, memory,
                                              &caller_registers));
   ASSERT_EQ(".ra: 0", cfi.Serialize());
 }
@@ -97,7 +97,7 @@
   ExpectNoMemoryReferences();
 
   cfi.SetCFARule("0");
-  ASSERT_FALSE(cfi.FindCallerRegs<u_int64_t>(registers, memory,
+  ASSERT_FALSE(cfi.FindCallerRegs<uint64_t>(registers, memory,
                                              &caller_registers));
   ASSERT_EQ(".cfa: 0", cfi.Serialize());
 }
@@ -107,7 +107,7 @@
 
   cfi.SetCFARule("330903416631436410");
   cfi.SetRARule("5870666104170902211");
-  ASSERT_TRUE(cfi.FindCallerRegs<u_int64_t>(registers, memory,
+  ASSERT_TRUE(cfi.FindCallerRegs<uint64_t>(registers, memory,
                                             &caller_registers));
   ASSERT_EQ(2U, caller_registers.size());
   ASSERT_EQ(330903416631436410ULL, caller_registers[".cfa"]);
@@ -126,7 +126,7 @@
   cfi.SetRegisterRule("vodkathumbscrewingly", "24076308 .cfa +");
   cfi.SetRegisterRule("pubvexingfjordschmaltzy", ".cfa 29801007 -");
   cfi.SetRegisterRule("uncopyrightables", "92642917 .cfa /");
-  ASSERT_TRUE(cfi.FindCallerRegs<u_int64_t>(registers, memory,
+  ASSERT_TRUE(cfi.FindCallerRegs<uint64_t>(registers, memory,
                                             &caller_registers));
   ASSERT_EQ(6U, caller_registers.size());
   ASSERT_EQ(7664691U,           caller_registers[".cfa"]);
@@ -150,7 +150,7 @@
   cfi.SetCFARule("330903416631436410");
   cfi.SetRARule("5870666104170902211");
   cfi.SetCFARule("2828089117179001");
-  ASSERT_TRUE(cfi.FindCallerRegs<u_int64_t>(registers, memory,
+  ASSERT_TRUE(cfi.FindCallerRegs<uint64_t>(registers, memory,
                                             &caller_registers));
   ASSERT_EQ(2U, caller_registers.size());
   ASSERT_EQ(2828089117179001ULL, caller_registers[".cfa"]);
@@ -167,7 +167,7 @@
 
   cfi.SetCFARule(".cfa");
   cfi.SetRARule("0");
-  ASSERT_FALSE(cfi.FindCallerRegs<u_int64_t>(registers, memory,
+  ASSERT_FALSE(cfi.FindCallerRegs<uint64_t>(registers, memory,
                                              &caller_registers));
 }
 
@@ -177,7 +177,7 @@
 
   cfi.SetCFARule(".ra");
   cfi.SetRARule("0");
-  ASSERT_FALSE(cfi.FindCallerRegs<u_int64_t>(registers, memory,
+  ASSERT_FALSE(cfi.FindCallerRegs<uint64_t>(registers, memory,
                                              &caller_registers));
 }
 
@@ -190,7 +190,7 @@
   registers[".ornithorhynchus"] = 0x5e0bf850bafce9d2ULL;
   cfi.SetCFARule(".baraminology .ornithorhynchus +");
   cfi.SetRARule("0");
-  ASSERT_TRUE(cfi.FindCallerRegs<u_int64_t>(registers, memory,
+  ASSERT_TRUE(cfi.FindCallerRegs<uint64_t>(registers, memory,
                                             &caller_registers));
   ASSERT_EQ(2U, caller_registers.size());
   ASSERT_EQ(0x06a7bc63e4f13893ULL + 0x5e0bf850bafce9d2ULL,
@@ -203,7 +203,7 @@
 
   cfi.SetCFARule("48364076");
   cfi.SetRARule(".cfa");
-  ASSERT_TRUE(cfi.FindCallerRegs<u_int64_t>(registers, memory,
+  ASSERT_TRUE(cfi.FindCallerRegs<uint64_t>(registers, memory,
                                             &caller_registers));
   ASSERT_EQ(2U, caller_registers.size());
   ASSERT_EQ(48364076U, caller_registers[".ra"]);
@@ -215,7 +215,7 @@
 
   cfi.SetCFARule("0");
   cfi.SetRARule(".ra");
-  ASSERT_FALSE(cfi.FindCallerRegs<u_int64_t>(registers, memory,
+  ASSERT_FALSE(cfi.FindCallerRegs<uint64_t>(registers, memory,
                                              &caller_registers));
 }
 
@@ -227,7 +227,7 @@
   registers["noachian"] = 0x54dc4a5d8e5eb503ULL;
   cfi.SetCFARule("10359370");
   cfi.SetRARule("noachian");
-  ASSERT_TRUE(cfi.FindCallerRegs<u_int64_t>(registers, memory,
+  ASSERT_TRUE(cfi.FindCallerRegs<uint64_t>(registers, memory,
                                             &caller_registers));
   ASSERT_EQ(2U, caller_registers.size());
   ASSERT_EQ(0x54dc4a5d8e5eb503ULL, caller_registers[".ra"]);
@@ -240,7 +240,7 @@
   cfi.SetCFARule("6515179");
   cfi.SetRARule(".cfa");
   cfi.SetRegisterRule("rogerian", ".cfa");
-  ASSERT_TRUE(cfi.FindCallerRegs<u_int64_t>(registers, memory,
+  ASSERT_TRUE(cfi.FindCallerRegs<uint64_t>(registers, memory,
                                             &caller_registers));
   ASSERT_EQ(3U, caller_registers.size());
   ASSERT_EQ(6515179U, caller_registers["rogerian"]);
@@ -253,7 +253,7 @@
   cfi.SetCFARule("42740329");
   cfi.SetRARule("27045204");
   cfi.SetRegisterRule("$r1", ".ra");
-  ASSERT_FALSE(cfi.FindCallerRegs<u_int64_t>(registers, memory,
+  ASSERT_FALSE(cfi.FindCallerRegs<uint64_t>(registers, memory,
                                              &caller_registers));
 }
 
@@ -267,7 +267,7 @@
   cfi.SetRARule("30503835");
   cfi.SetRegisterRule("$r1", "$r1 42175211 = $r2");
   cfi.SetRegisterRule("$r2", "$r2 21357221 = $r1");
-  ASSERT_TRUE(cfi.FindCallerRegs<u_int64_t>(registers, memory,
+  ASSERT_TRUE(cfi.FindCallerRegs<uint64_t>(registers, memory,
                                             &caller_registers));
   ASSERT_EQ(4U, caller_registers.size());
   ASSERT_EQ(0xd27d9e742b8df6d0ULL, caller_registers["$r1"]);
@@ -280,12 +280,12 @@
 
   cfi.SetCFARule("$temp1 76569129 = $temp1");
   cfi.SetRARule("0");
-  ASSERT_TRUE(cfi.FindCallerRegs<u_int64_t>(registers, memory,
+  ASSERT_TRUE(cfi.FindCallerRegs<uint64_t>(registers, memory,
                                             &caller_registers));
 
   cfi.SetCFARule("$temp1 76569129 = $temp1");
   cfi.SetRARule("$temp1");
-  ASSERT_FALSE(cfi.FindCallerRegs<u_int64_t>(registers, memory,
+  ASSERT_FALSE(cfi.FindCallerRegs<uint64_t>(registers, memory,
                                              &caller_registers));
 }
 
@@ -427,7 +427,7 @@
   handler.RARule("reg-for-ra");
   registers["reg-for-cfa"] = 0x268a9a4a3821a797ULL;
   registers["reg-for-ra"] = 0x6301b475b8b91c02ULL;
-  ASSERT_TRUE(cfi.FindCallerRegs<u_int64_t>(registers, memory,
+  ASSERT_TRUE(cfi.FindCallerRegs<uint64_t>(registers, memory,
                                             &caller_registers));
   ASSERT_EQ(0x268a9a4a3821a797ULL, caller_registers[".cfa"]);
   ASSERT_EQ(0x6301b475b8b91c02ULL, caller_registers[".ra"]);
@@ -442,7 +442,7 @@
   registers["reg-for-ra"] = 0x6301b475b8b91c02ULL;
   registers["reg-for-reg1"] = 0x06cde8e2ff062481ULL;
   registers["reg-for-reg2"] = 0xff0c4f76403173e2ULL;
-  ASSERT_TRUE(cfi.FindCallerRegs<u_int64_t>(registers, memory,
+  ASSERT_TRUE(cfi.FindCallerRegs<uint64_t>(registers, memory,
                                             &caller_registers));
   ASSERT_EQ(0x268a9a4a3821a797ULL, caller_registers[".cfa"]);
   ASSERT_EQ(0x6301b475b8b91c02ULL, caller_registers[".ra"]);
@@ -452,7 +452,7 @@
 
 struct SimpleCFIWalkerFixture {
   struct RawContext {
-    u_int64_t r0, r1, r2, r3, r4, sp, pc;
+    uint64_t r0, r1, r2, r3, r4, sp, pc;
   };
   enum Validity {
     R0_VALID = 0x01,
@@ -463,7 +463,7 @@
     SP_VALID = 0x20,
     PC_VALID = 0x40
   };
-  typedef SimpleCFIWalker<u_int64_t, RawContext> CFIWalker;
+  typedef SimpleCFIWalker<uint64_t, RawContext> CFIWalker;
 
   SimpleCFIWalkerFixture()
       : walker(register_map,
@@ -504,16 +504,16 @@
   // r4 is not recoverable, even though it is a callee-saves register.
   //    Some earlier frame's unwinder must have failed to recover it.
 
-  u_int64_t stack_top = 0x83254944b20d5512ULL;
+  uint64_t stack_top = 0x83254944b20d5512ULL;
 
   // Saved r0.
   EXPECT_CALL(memory,
-              GetMemoryAtAddress(stack_top, A<u_int64_t *>()))
+              GetMemoryAtAddress(stack_top, A<uint64_t *>()))
       .WillRepeatedly(DoAll(SetArgumentPointee<1>(0xdc1975eba8602302ULL),
                             Return(true)));
   // Saved return address.
   EXPECT_CALL(memory,
-              GetMemoryAtAddress(stack_top + 16, A<u_int64_t *>()))
+              GetMemoryAtAddress(stack_top + 16, A<uint64_t *>()))
       .WillRepeatedly(DoAll(SetArgumentPointee<1>(0xba5ad6d9acce28deULL),
                             Return(true)));
 
diff --git a/src/processor/disassembler_x86.cc b/src/processor/disassembler_x86.cc
index 45a235d..9eba848 100644
--- a/src/processor/disassembler_x86.cc
+++ b/src/processor/disassembler_x86.cc
@@ -31,9 +31,9 @@
 
 namespace google_breakpad {
 
-DisassemblerX86::DisassemblerX86(const u_int8_t *bytecode,
-                                 u_int32_t size,
-                                 u_int32_t virtual_address) :
+DisassemblerX86::DisassemblerX86(const uint8_t *bytecode,
+                                 uint32_t size,
+                                 uint32_t virtual_address) :
                                      bytecode_(bytecode),
                                      size_(size),
                                      virtual_address_(virtual_address),
@@ -54,7 +54,7 @@
   libdis::x86_cleanup();
 }
 
-u_int32_t DisassemblerX86::NextInstruction() {
+uint32_t DisassemblerX86::NextInstruction() {
   if (instr_valid_)
     libdis::x86_oplist_free(&current_instr_);
 
@@ -62,7 +62,7 @@
     instr_valid_ = false;
     return 0;
   }
-  u_int32_t instr_size = 0;
+  uint32_t instr_size = 0;
   instr_size = libdis::x86_disasm((unsigned char *)bytecode_, size_,
                           virtual_address_, current_byte_offset_,
                           &current_instr_);
diff --git a/src/processor/disassembler_x86.h b/src/processor/disassembler_x86.h
index 3bdd558..7106941 100644
--- a/src/processor/disassembler_x86.h
+++ b/src/processor/disassembler_x86.h
@@ -37,6 +37,7 @@
 #define GOOGLE_BREAKPAD_PROCESSOR_DISASSEMBLER_X86_H_
 
 #include <stddef.h>
+#include <sys/types.h>
 
 #include "google_breakpad/common/breakpad_types.h"
 
@@ -62,7 +63,7 @@
     // TODO(cdn): Modify this class to take a MemoryRegion instead of just
     // a raw buffer. This will make it easier to use this on arbitrary
     // minidumps without first copying out the code segment.
-    DisassemblerX86(const u_int8_t *bytecode, u_int32_t, u_int32_t);
+    DisassemblerX86(const uint8_t *bytecode, uint32_t, uint32_t);
     ~DisassemblerX86();
 
     // This walks to the next instruction in the memory region and
@@ -70,7 +71,7 @@
     // including any registers marked as bad through setBadRead()
     // or setBadWrite(). This method can be called in a loop to
     // disassemble until the end of a region.
-    u_int32_t NextInstruction();
+    uint32_t NextInstruction();
 
     // Indicates whether the current disassembled instruction was valid.
     bool currentInstructionValid() { return instr_valid_; }
@@ -90,7 +91,7 @@
     bool endOfBlock() { return end_of_block_; }
 
     // The flags set so far for the disassembly.
-    u_int16_t flags() { return flags_; }
+    uint16_t flags() { return flags_; }
 
     // This sets an indicator that the register used to determine
     // src or dest for the current instruction is tainted. These can
@@ -101,11 +102,11 @@
     bool setBadWrite();
 
   protected:
-    const u_int8_t *bytecode_;
-    u_int32_t size_;
-    u_int32_t virtual_address_;
-    u_int32_t current_byte_offset_;
-    u_int32_t current_inst_offset_;
+    const uint8_t *bytecode_;
+    uint32_t size_;
+    uint32_t virtual_address_;
+    uint32_t current_byte_offset_;
+    uint32_t current_inst_offset_;
 
     bool instr_valid_;
     libdis::x86_insn_t current_instr_;
@@ -118,7 +119,7 @@
     bool pushed_bad_value_;
     bool end_of_block_;
 
-    u_int16_t flags_;
+    uint16_t flags_;
 };
 
 }  // namespace google_breakpad
diff --git a/src/processor/exploitability.cc b/src/processor/exploitability.cc
index 459e7ce..5355b7d 100644
--- a/src/processor/exploitability.cc
+++ b/src/processor/exploitability.cc
@@ -36,12 +36,12 @@
 
 #include <cassert>
 
+#include "common/scoped_ptr.h"
 #include "google_breakpad/processor/exploitability.h"
 #include "google_breakpad/processor/minidump.h"
 #include "google_breakpad/processor/process_state.h"
 #include "processor/exploitability_win.h"
 #include "processor/logging.h"
-#include "processor/scoped_ptr.h"
 
 namespace google_breakpad {
 
@@ -92,9 +92,9 @@
   return platform_exploitability;
 }
 
-bool Exploitability::AddressIsAscii(u_int64_t address) {
+bool Exploitability::AddressIsAscii(uint64_t address) {
   for (int i = 0; i < 8; i++) {
-    u_int8_t byte = (address >> (8*i)) & 0xff;
+    uint8_t byte = (address >> (8*i)) & 0xff;
     if ((byte >= ' ' && byte <= '~') || byte == 0)
       continue;
     return false;
diff --git a/src/processor/exploitability_win.cc b/src/processor/exploitability_win.cc
index 443635f..e20fbdd 100644
--- a/src/processor/exploitability_win.cc
+++ b/src/processor/exploitability_win.cc
@@ -38,11 +38,11 @@
 
 #include "processor/exploitability_win.h"
 
+#include "common/scoped_ptr.h"
 #include "google_breakpad/common/minidump_exception_win32.h"
 #include "google_breakpad/processor/minidump.h"
 #include "processor/disassembler_x86.h"
 #include "processor/logging.h"
-#include "processor/scoped_ptr.h"
 
 #include "third_party/libdisasm/libdis.h"
 
@@ -50,8 +50,8 @@
 
 // The cutoff that we use to judge if and address is likely an offset
 // from various interesting addresses.
-static const u_int64_t kProbableNullOffset = 4096;
-static const u_int64_t kProbableStackOffset = 8192;
+static const uint64_t kProbableNullOffset = 4096;
+static const uint64_t kProbableStackOffset = 8192;
 
 // The various cutoffs for the different ratings.
 static const size_t kHighCutoff        = 100;
@@ -98,14 +98,14 @@
     BPLOG(INFO) << "Minidump memory segments not available.";
     memory_available = false;
   }
-  u_int64_t address = process_state_->crash_address();
-  u_int32_t exception_code = raw_exception->exception_record.exception_code;
+  uint64_t address = process_state_->crash_address();
+  uint32_t exception_code = raw_exception->exception_record.exception_code;
 
-  u_int32_t exploitability_weight = 0;
+  uint32_t exploitability_weight = 0;
 
-  u_int64_t stack_ptr = 0;
-  u_int64_t instruction_ptr = 0;
-  u_int64_t this_ptr = 0;
+  uint64_t stack_ptr = 0;
+  uint64_t instruction_ptr = 0;
+  uint64_t this_ptr = 0;
 
   switch (context->GetContextCPU()) {
     case MD_CONTEXT_X86:
@@ -211,14 +211,14 @@
             context->GetContextCPU() == MD_CONTEXT_X86 &&
             (bad_read || bad_write)) {
           // Perform checks related to memory around instruction pointer.
-          u_int32_t memory_offset =
+          uint32_t memory_offset =
               instruction_ptr - instruction_region->GetBase();
-          u_int32_t available_memory =
+          uint32_t available_memory =
               instruction_region->GetSize() - memory_offset;
           available_memory = available_memory > kDisassembleBytesBeyondPC ?
               kDisassembleBytesBeyondPC : available_memory;
           if (available_memory) {
-            const u_int8_t *raw_memory =
+            const uint8_t *raw_memory =
                 instruction_region->GetMemory() + memory_offset;
             DisassemblerX86 disassembler(raw_memory,
                                          available_memory,
diff --git a/src/processor/fast_source_line_resolver.cc b/src/processor/fast_source_line_resolver.cc
index a7b9933..86073d2 100644
--- a/src/processor/fast_source_line_resolver.cc
+++ b/src/processor/fast_source_line_resolver.cc
@@ -44,9 +44,9 @@
 #include <string>
 #include <utility>
 
+#include "common/scoped_ptr.h"
 #include "common/using_std_string.h"
 #include "processor/module_factory.h"
-#include "processor/scoped_ptr.h"
 
 using std::map;
 using std::make_pair;
@@ -116,15 +116,15 @@
   // The first 8 bytes of int data are unused.
   // They correspond to "StackInfoTypes type_;" and "int valid;"
   // data member of WFI.
-  const u_int32_t *para_uint32 = reinterpret_cast<const u_int32_t*>(
+  const uint32_t *para_uint32 = reinterpret_cast<const uint32_t*>(
       raw + 2 * sizeof(int32_t));
 
-  u_int32_t prolog_size = para_uint32[0];;
-  u_int32_t epilog_size = para_uint32[1];
-  u_int32_t parameter_size = para_uint32[2];
-  u_int32_t saved_register_size = para_uint32[3];
-  u_int32_t local_size = para_uint32[4];
-  u_int32_t max_stack_size = para_uint32[5];
+  uint32_t prolog_size = para_uint32[0];;
+  uint32_t epilog_size = para_uint32[1];
+  uint32_t parameter_size = para_uint32[2];
+  uint32_t saved_register_size = para_uint32[3];
+  uint32_t local_size = para_uint32[4];
+  uint32_t max_stack_size = para_uint32[5];
   const char *boolean = reinterpret_cast<const char*>(para_uint32 + 6);
   bool allocates_base_pointer = (*boolean != 0);
   string program_string = boolean + 1;
@@ -146,7 +146,7 @@
 bool FastSourceLineResolver::Module::LoadMapFromMemory(char *mem_buffer) {
   if (!mem_buffer) return false;
 
-  const u_int32_t *map_sizes = reinterpret_cast<const u_int32_t*>(mem_buffer);
+  const uint32_t *map_sizes = reinterpret_cast<const uint32_t*>(mem_buffer);
 
   unsigned int header_size = kNumberMaps_ * sizeof(unsigned int);
 
diff --git a/src/processor/fast_source_line_resolver_unittest.cc b/src/processor/fast_source_line_resolver_unittest.cc
index c982c54..26982bf 100644
--- a/src/processor/fast_source_line_resolver_unittest.cc
+++ b/src/processor/fast_source_line_resolver_unittest.cc
@@ -71,8 +71,8 @@
   explicit TestCodeModule(string code_file) : code_file_(code_file) {}
   virtual ~TestCodeModule() {}
 
-  virtual u_int64_t base_address() const { return 0; }
-  virtual u_int64_t size() const { return 0xb000; }
+  virtual uint64_t base_address() const { return 0; }
+  virtual uint64_t size() const { return 0xb000; }
   virtual string code_file() const { return code_file_; }
   virtual string code_identifier() const { return ""; }
   virtual string debug_file() const { return ""; }
@@ -88,17 +88,17 @@
 
 // A mock memory region object, for use by the STACK CFI tests.
 class MockMemoryRegion: public MemoryRegion {
-  u_int64_t GetBase() const { return 0x10000; }
-  u_int32_t GetSize() const { return 0x01000; }
-  bool GetMemoryAtAddress(u_int64_t address, u_int8_t *value) const {
+  uint64_t GetBase() const { return 0x10000; }
+  uint32_t GetSize() const { return 0x01000; }
+  bool GetMemoryAtAddress(uint64_t address, uint8_t *value) const {
     *value = address & 0xff;
     return true;
   }
-  bool GetMemoryAtAddress(u_int64_t address, u_int16_t *value) const {
+  bool GetMemoryAtAddress(uint64_t address, uint16_t *value) const {
     *value = address & 0xffff;
     return true;
   }
-  bool GetMemoryAtAddress(u_int64_t address, u_int32_t *value) const {
+  bool GetMemoryAtAddress(uint64_t address, uint32_t *value) const {
     switch (address) {
       case 0x10008: *value = 0x98ecadc3; break;  // saved %ebx
       case 0x1000c: *value = 0x878f7524; break;  // saved %esi
@@ -109,7 +109,7 @@
     }
     return true;
   }
-  bool GetMemoryAtAddress(u_int64_t address, u_int64_t *value) const {
+  bool GetMemoryAtAddress(uint64_t address, uint64_t *value) const {
     *value = address;
     return true;
   }
@@ -121,9 +121,9 @@
 // ".cfa".
 static bool VerifyRegisters(
     const char *file, int line,
-    const CFIFrameInfo::RegisterValueMap<u_int32_t> &expected,
-    const CFIFrameInfo::RegisterValueMap<u_int32_t> &actual) {
-  CFIFrameInfo::RegisterValueMap<u_int32_t>::const_iterator a;
+    const CFIFrameInfo::RegisterValueMap<uint32_t> &expected,
+    const CFIFrameInfo::RegisterValueMap<uint32_t> &actual) {
+  CFIFrameInfo::RegisterValueMap<uint32_t>::const_iterator a;
   a = actual.find(".cfa");
   if (a == actual.end())
     return false;
@@ -131,7 +131,7 @@
   if (a == actual.end())
     return false;
   for (a = actual.begin(); a != actual.end(); a++) {
-    CFIFrameInfo::RegisterValueMap<u_int32_t>::const_iterator e =
+    CFIFrameInfo::RegisterValueMap<uint32_t>::const_iterator e =
       expected.find(a->first);
     if (e == expected.end()) {
       fprintf(stderr, "%s:%d: unexpected register '%s' recovered, value 0x%x\n",
@@ -280,9 +280,9 @@
   cfi_frame_info.reset(fast_resolver.FindCFIFrameInfo(&frame));
   ASSERT_FALSE(cfi_frame_info.get());
 
-  CFIFrameInfo::RegisterValueMap<u_int32_t> current_registers;
-  CFIFrameInfo::RegisterValueMap<u_int32_t> caller_registers;
-  CFIFrameInfo::RegisterValueMap<u_int32_t> expected_caller_registers;
+  CFIFrameInfo::RegisterValueMap<uint32_t> current_registers;
+  CFIFrameInfo::RegisterValueMap<uint32_t> caller_registers;
+  CFIFrameInfo::RegisterValueMap<uint32_t> expected_caller_registers;
   MockMemoryRegion memory;
 
   // Regardless of which instruction evaluation takes place at, it
@@ -305,7 +305,7 @@
   cfi_frame_info.reset(fast_resolver.FindCFIFrameInfo(&frame));
   ASSERT_TRUE(cfi_frame_info.get());
   ASSERT_TRUE(cfi_frame_info.get()
-              ->FindCallerRegs<u_int32_t>(current_registers, memory,
+              ->FindCallerRegs<uint32_t>(current_registers, memory,
                                           &caller_registers));
   ASSERT_TRUE(VerifyRegisters(__FILE__, __LINE__,
                               expected_caller_registers, caller_registers));
@@ -315,7 +315,7 @@
   cfi_frame_info.reset(fast_resolver.FindCFIFrameInfo(&frame));
   ASSERT_TRUE(cfi_frame_info.get());
   ASSERT_TRUE(cfi_frame_info.get()
-              ->FindCallerRegs<u_int32_t>(current_registers, memory,
+              ->FindCallerRegs<uint32_t>(current_registers, memory,
                                           &caller_registers));
   ASSERT_TRUE(VerifyRegisters(__FILE__, __LINE__,
                               expected_caller_registers, caller_registers));
@@ -325,7 +325,7 @@
   cfi_frame_info.reset(fast_resolver.FindCFIFrameInfo(&frame));
   ASSERT_TRUE(cfi_frame_info.get());
   ASSERT_TRUE(cfi_frame_info.get()
-              ->FindCallerRegs<u_int32_t>(current_registers, memory,
+              ->FindCallerRegs<uint32_t>(current_registers, memory,
                                           &caller_registers));
   VerifyRegisters(__FILE__, __LINE__,
                   expected_caller_registers, caller_registers);
@@ -335,7 +335,7 @@
   cfi_frame_info.reset(fast_resolver.FindCFIFrameInfo(&frame));
   ASSERT_TRUE(cfi_frame_info.get());
   ASSERT_TRUE(cfi_frame_info.get()
-              ->FindCallerRegs<u_int32_t>(current_registers, memory,
+              ->FindCallerRegs<uint32_t>(current_registers, memory,
                                           &caller_registers));
   VerifyRegisters(__FILE__, __LINE__,
                   expected_caller_registers, caller_registers);
@@ -345,7 +345,7 @@
   cfi_frame_info.reset(fast_resolver.FindCFIFrameInfo(&frame));
   ASSERT_TRUE(cfi_frame_info.get());
   ASSERT_TRUE(cfi_frame_info.get()
-              ->FindCallerRegs<u_int32_t>(current_registers, memory,
+              ->FindCallerRegs<uint32_t>(current_registers, memory,
                                           &caller_registers));
   VerifyRegisters(__FILE__, __LINE__,
                   expected_caller_registers, caller_registers);
@@ -355,7 +355,7 @@
   cfi_frame_info.reset(fast_resolver.FindCFIFrameInfo(&frame));
   ASSERT_TRUE(cfi_frame_info.get());
   ASSERT_TRUE(cfi_frame_info.get()
-              ->FindCallerRegs<u_int32_t>(current_registers, memory,
+              ->FindCallerRegs<uint32_t>(current_registers, memory,
                                           &caller_registers));
   VerifyRegisters(__FILE__, __LINE__,
                   expected_caller_registers, caller_registers);
diff --git a/src/processor/logging.cc b/src/processor/logging.cc
index a6e15ca..8bb95a6 100644
--- a/src/processor/logging.cc
+++ b/src/processor/logging.cc
@@ -83,13 +83,13 @@
   stream_ << std::endl;
 }
 
-string HexString(u_int32_t number) {
+string HexString(uint32_t number) {
   char buffer[11];
   snprintf(buffer, sizeof(buffer), "0x%x", number);
   return string(buffer);
 }
 
-string HexString(u_int64_t number) {
+string HexString(uint64_t number) {
   char buffer[19];
   snprintf(buffer, sizeof(buffer), "0x%" PRIx64, number);
   return string(buffer);
diff --git a/src/processor/logging.h b/src/processor/logging.h
index 6a964f6..c082242 100644
--- a/src/processor/logging.h
+++ b/src/processor/logging.h
@@ -67,6 +67,18 @@
 #include BP_LOGGING_INCLUDE
 #endif  // BP_LOGGING_INCLUDE
 
+#ifndef THIRD_PARTY_BREAKPAD_GOOGLE_GLUE_LOGGING_H_
+namespace base_logging {
+
+// The open-source copy of logging.h has diverged from Google's internal copy
+// (temporarily, at least).  To support the transition to structured logging
+// a definition for base_logging::LogMessage is needed, which is a ostream-
+// like object for streaming arguments to construct a log message.
+typedef std::ostream LogMessage;
+
+}  // namespace base_logging
+#endif  // THIRD_PARTY_BREAKPAD_GOOGLE_GLUE_LOGGING_H_
+
 namespace google_breakpad {
 
 // These are defined in Microsoft headers.
@@ -115,12 +127,12 @@
 
   // This has to be an operator with a precedence lower than << but higher
   // than ?:
-  void operator&(std::ostream &) {}
+  void operator&(base_logging::LogMessage &) {}
 };
 
 // Returns number formatted as a hexadecimal string, such as "0x7b".
-string HexString(u_int32_t number);
-string HexString(u_int64_t number);
+string HexString(uint32_t number);
+string HexString(uint64_t number);
 string HexString(int number);
 
 // Returns the error code as set in the global errno variable, and sets
diff --git a/src/processor/map_serializers-inl.h b/src/processor/map_serializers-inl.h
index d68e8b9..61c7bbd 100644
--- a/src/processor/map_serializers-inl.h
+++ b/src/processor/map_serializers-inl.h
@@ -55,7 +55,7 @@
 size_t StdMapSerializer<Key, Value>::SizeOf(
     const std::map<Key, Value> &m) const {
   size_t size = 0;
-  size_t header_size = (1 + m.size()) * sizeof(u_int32_t);
+  size_t header_size = (1 + m.size()) * sizeof(uint32_t);
   size += header_size;
 
   typename std::map<Key, Value>::const_iterator iter;
@@ -77,10 +77,10 @@
 
   // Write header:
   // Number of nodes.
-  dest = SimpleSerializer<u_int32_t>::Write(m.size(), dest);
+  dest = SimpleSerializer<uint32_t>::Write(m.size(), dest);
   // Nodes offsets.
-  u_int32_t *offsets = reinterpret_cast<u_int32_t*>(dest);
-  dest += sizeof(u_int32_t) * m.size();
+  uint32_t *offsets = reinterpret_cast<uint32_t*>(dest);
+  dest += sizeof(uint32_t) * m.size();
 
   char *key_address = dest;
   dest += sizeof(Key) * m.size();
@@ -89,7 +89,7 @@
   typename std::map<Key, Value>::const_iterator iter;
   int index = 0;
   for (iter = m.begin(); iter != m.end(); ++iter, ++index) {
-    offsets[index] = static_cast<u_int32_t>(dest - start_address);
+    offsets[index] = static_cast<uint32_t>(dest - start_address);
     key_address = key_serializer_.Write(iter->first, key_address);
     dest = value_serializer_.Write(iter->second, dest);
   }
@@ -119,7 +119,7 @@
 size_t RangeMapSerializer<Address, Entry>::SizeOf(
     const RangeMap<Address, Entry> &m) const {
   size_t size = 0;
-  size_t header_size = (1 + m.map_.size()) * sizeof(u_int32_t);
+  size_t header_size = (1 + m.map_.size()) * sizeof(uint32_t);
   size += header_size;
 
   typename std::map<Address, Range>::const_iterator iter;
@@ -145,10 +145,10 @@
 
   // Write header:
   // Number of nodes.
-  dest = SimpleSerializer<u_int32_t>::Write(m.map_.size(), dest);
+  dest = SimpleSerializer<uint32_t>::Write(m.map_.size(), dest);
   // Nodes offsets.
-  u_int32_t *offsets = reinterpret_cast<u_int32_t*>(dest);
-  dest += sizeof(u_int32_t) * m.map_.size();
+  uint32_t *offsets = reinterpret_cast<uint32_t*>(dest);
+  dest += sizeof(uint32_t) * m.map_.size();
 
   char *key_address = dest;
   dest += sizeof(Address) * m.map_.size();
@@ -157,7 +157,7 @@
   typename std::map<Address, Range>::const_iterator iter;
   int index = 0;
   for (iter = m.map_.begin(); iter != m.map_.end(); ++iter, ++index) {
-    offsets[index] = static_cast<u_int32_t>(dest - start_address);
+    offsets[index] = static_cast<uint32_t>(dest - start_address);
     key_address = address_serializer_.Write(iter->first, key_address);
     dest = address_serializer_.Write(iter->second.base(), dest);
     dest = entry_serializer_.Write(iter->second.entry(), dest);
@@ -192,12 +192,12 @@
   size_t size = 0;
   size_t header_size = addr_serializer_.SizeOf(m->base_)
                        + entry_serializer_.SizeOf(m->entry_)
-                       + sizeof(u_int32_t);
+                       + sizeof(uint32_t);
   size += header_size;
   // In case m.map_ == NULL, we treat it as an empty map:
-  size += sizeof(u_int32_t);
+  size += sizeof(uint32_t);
   if (m->map_) {
-    size += m->map_->size() * sizeof(u_int32_t);
+    size += m->map_->size() * sizeof(uint32_t);
     typename Map::const_iterator iter;
     for (iter = m->map_->begin(); iter != m->map_->end(); ++iter) {
       size += addr_serializer_.SizeOf(iter->first);
@@ -216,18 +216,18 @@
     return NULL;
   }
   dest = addr_serializer_.Write(m->base_, dest);
-  dest = SimpleSerializer<u_int32_t>::Write(entry_serializer_.SizeOf(m->entry_),
+  dest = SimpleSerializer<uint32_t>::Write(entry_serializer_.SizeOf(m->entry_),
                                             dest);
   dest = entry_serializer_.Write(m->entry_, dest);
 
   // Write map<<AddrType, ContainedRangeMap*>:
   char *map_address = dest;
   if (m->map_ == NULL) {
-    dest = SimpleSerializer<u_int32_t>::Write(0, dest);
+    dest = SimpleSerializer<uint32_t>::Write(0, dest);
   } else {
-    dest = SimpleSerializer<u_int32_t>::Write(m->map_->size(), dest);
-    u_int32_t *offsets = reinterpret_cast<u_int32_t*>(dest);
-    dest += sizeof(u_int32_t) * m->map_->size();
+    dest = SimpleSerializer<uint32_t>::Write(m->map_->size(), dest);
+    uint32_t *offsets = reinterpret_cast<uint32_t*>(dest);
+    dest += sizeof(uint32_t) * m->map_->size();
 
     char *key_address = dest;
     dest += sizeof(AddrType) * m->map_->size();
@@ -236,7 +236,7 @@
     typename Map::const_iterator iter;
     int index = 0;
     for (iter = m->map_->begin(); iter != m->map_->end(); ++iter, ++index) {
-      offsets[index] = static_cast<u_int32_t>(dest - map_address);
+      offsets[index] = static_cast<uint32_t>(dest - map_address);
       key_address = addr_serializer_.Write(iter->first, key_address);
       // Recursively write.
       dest = Write(iter->second, dest);
diff --git a/src/processor/map_serializers_unittest.cc b/src/processor/map_serializers_unittest.cc
index abaef97..95d03d0 100644
--- a/src/processor/map_serializers_unittest.cc
+++ b/src/processor/map_serializers_unittest.cc
@@ -64,13 +64,13 @@
 
   std::map<AddrType, EntryType> std_map_;
   google_breakpad::StdMapSerializer<AddrType, EntryType> serializer_;
-  u_int32_t serialized_size_;
+  uint32_t serialized_size_;
   char *serialized_data_;
 };
 
 TEST_F(TestStdMapSerializer, EmptyMapTestCase) {
   const int32_t correct_data[] = { 0 };
-  u_int32_t correct_size = sizeof(correct_data);
+  uint32_t correct_size = sizeof(correct_data);
 
   // std_map_ is empty.
   serialized_data_ = serializer_.Serialize(std_map_, &serialized_size_);
@@ -90,7 +90,7 @@
       // Values
       2, 6
   };
-  u_int32_t correct_size = sizeof(correct_data);
+  uint32_t correct_size = sizeof(correct_data);
 
   std_map_.insert(std::make_pair(1, 2));
   std_map_.insert(std::make_pair(3, 6));
@@ -112,7 +112,7 @@
       // Values
       11, 12, 13, 14, 15
   };
-  u_int32_t correct_size = sizeof(correct_data);
+  uint32_t correct_size = sizeof(correct_data);
 
   for (int i = 1; i < 6; ++i)
     std_map_.insert(std::make_pair(i, 10 + i));
@@ -136,13 +136,13 @@
 
   google_breakpad::AddressMap<AddrType, EntryType> address_map_;
   google_breakpad::AddressMapSerializer<AddrType, EntryType> serializer_;
-  u_int32_t serialized_size_;
+  uint32_t serialized_size_;
   char *serialized_data_;
 };
 
 TEST_F(TestAddressMapSerializer, EmptyMapTestCase) {
   const int32_t correct_data[] = { 0 };
-  u_int32_t correct_size = sizeof(correct_data);
+  uint32_t correct_size = sizeof(correct_data);
 
   // std_map_ is empty.
   serialized_data_ = serializer_.Serialize(address_map_, &serialized_size_);
@@ -162,7 +162,7 @@
       // Values
       2, 6
   };
-  u_int32_t correct_size = sizeof(correct_data);
+  uint32_t correct_size = sizeof(correct_data);
 
   address_map_.Store(1, 2);
   address_map_.Store(3, 6);
@@ -184,7 +184,7 @@
       // Values
       2, 3, 5, 8
   };
-  u_int32_t correct_size = sizeof(correct_data);
+  uint32_t correct_size = sizeof(correct_data);
 
   address_map_.Store(-6, 2);
   address_map_.Store(-4, 3);
@@ -211,13 +211,13 @@
 
   google_breakpad::RangeMap<AddrType, EntryType> range_map_;
   google_breakpad::RangeMapSerializer<AddrType, EntryType> serializer_;
-  u_int32_t serialized_size_;
+  uint32_t serialized_size_;
   char *serialized_data_;
 };
 
 TEST_F(TestRangeMapSerializer, EmptyMapTestCase) {
   const int32_t correct_data[] = { 0 };
-  u_int32_t correct_size = sizeof(correct_data);
+  uint32_t correct_size = sizeof(correct_data);
 
   // range_map_ is empty.
   serialized_data_ = serializer_.Serialize(range_map_, &serialized_size_);
@@ -237,7 +237,7 @@
       // Values: (low address, entry) pairs
       1, 6
   };
-  u_int32_t correct_size = sizeof(correct_data);
+  uint32_t correct_size = sizeof(correct_data);
 
   range_map_.StoreRange(1, 10, 6);
 
@@ -258,7 +258,7 @@
       // Values: (low address, entry) pairs
       2, 1,  6, 2,  10, 3
   };
-  u_int32_t correct_size = sizeof(correct_data);
+  uint32_t correct_size = sizeof(correct_data);
 
   ASSERT_TRUE(range_map_.StoreRange(2, 4, 1));
   ASSERT_TRUE(range_map_.StoreRange(6, 4, 2));
@@ -284,7 +284,7 @@
 
   google_breakpad::ContainedRangeMap<AddrType, EntryType> crm_map_;
   google_breakpad::ContainedRangeMapSerializer<AddrType, EntryType> serializer_;
-  u_int32_t serialized_size_;
+  uint32_t serialized_size_;
   char *serialized_data_;
 };
 
@@ -295,7 +295,7 @@
       0,  // entry stored at root
       0   // empty map stored at root
   };
-  u_int32_t correct_size = sizeof(correct_data);
+  uint32_t correct_size = sizeof(correct_data);
 
   // crm_map_ is empty.
   serialized_data_ = serializer_.Serialize(&crm_map_, &serialized_size_);
@@ -319,7 +319,7 @@
       -1, // entry stored in child CRM
       0   // empty sub-map stored in child CRM
   };
-  u_int32_t correct_size = sizeof(correct_data);
+  uint32_t correct_size = sizeof(correct_data);
 
   crm_map_.StoreRange(3, 7, -1);
 
@@ -361,7 +361,7 @@
         // grandchild3: base, entry_size, entry, empty_map
         16, 4, -1, 0
   };
-  u_int32_t correct_size = sizeof(correct_data);
+  uint32_t correct_size = sizeof(correct_data);
 
   // Store child1.
   ASSERT_TRUE(crm_map_.StoreRange(2, 7, -1));
diff --git a/src/processor/minidump.cc b/src/processor/minidump.cc
old mode 100644
new mode 100755
index 0c13e00..17232b8
--- a/src/processor/minidump.cc
+++ b/src/processor/minidump.cc
@@ -37,13 +37,13 @@
 
 #include <assert.h>
 #include <fcntl.h>
+#include <stddef.h>
 #include <stdio.h>
 #include <string.h>
 #include <time.h>
 
 #ifdef _WIN32
 #include <io.h>
-typedef SSIZE_T ssize_t;
 #define PRIx64 "llx"
 #define PRIx32 "lx"
 #define snprintf _snprintf
@@ -60,10 +60,11 @@
 
 #include "processor/range_map-inl.h"
 
+#include "common/scoped_ptr.h"
 #include "processor/basic_code_module.h"
 #include "processor/basic_code_modules.h"
 #include "processor/logging.h"
-#include "processor/scoped_ptr.h"
+
 
 
 namespace google_breakpad {
@@ -85,9 +86,9 @@
 
 // Swapping an 8-bit quantity is a no-op.  This function is only provided
 // to account for certain templatized operations that require swapping for
-// wider types but handle u_int8_t too
+// wider types but handle uint8_t too
 // (MinidumpMemoryRegion::GetMemoryAtAddressInternal).
-static inline void Swap(u_int8_t* value) {
+static inline void Swap(uint8_t* value) {
 }
 
 
@@ -98,13 +99,13 @@
 // The furthest left shift never needs to be ANDed bitmask.
 
 
-static inline void Swap(u_int16_t* value) {
+static inline void Swap(uint16_t* value) {
   *value = (*value >> 8) |
            (*value << 8);
 }
 
 
-static inline void Swap(u_int32_t* value) {
+static inline void Swap(uint32_t* value) {
   *value =  (*value >> 24) |
            ((*value >> 8)  & 0x0000ff00) |
            ((*value << 8)  & 0x00ff0000) |
@@ -112,11 +113,11 @@
 }
 
 
-static inline void Swap(u_int64_t* value) {
-  u_int32_t* value32 = reinterpret_cast<u_int32_t*>(value);
+static inline void Swap(uint64_t* value) {
+  uint32_t* value32 = reinterpret_cast<uint32_t*>(value);
   Swap(&value32[0]);
   Swap(&value32[1]);
-  u_int32_t temp = value32[0];
+  uint32_t temp = value32[0];
   value32[0] = value32[1];
   value32[1] = temp;
 }
@@ -124,11 +125,11 @@
 
 // Given a pointer to a 128-bit int in the minidump data, set the "low"
 // and "high" fields appropriately.
-static void Normalize128(u_int128_t* value, bool is_big_endian) {
+static void Normalize128(uint128_struct* value, bool is_big_endian) {
   // The struct format is [high, low], so if the format is big-endian,
   // the most significant bytes will already be in the high field.
   if (!is_big_endian) {
-    u_int64_t temp = value->low;
+    uint64_t temp = value->low;
     value->low = value->high;
     value->high = temp;
   }
@@ -136,7 +137,7 @@
 
 // This just swaps each int64 half of the 128-bit value.
 // The value should also be normalized by calling Normalize128().
-static void Swap(u_int128_t* value) {
+static void Swap(uint128_struct* value) {
   Swap(&value->low);
   Swap(&value->high);
 }
@@ -176,7 +177,7 @@
 // parameter, a converter that uses iconv would also need to take the host
 // CPU's endianness into consideration.  It doesn't seems worth the trouble
 // of making it a dependency when we don't care about anything but UTF-16.
-static string* UTF16ToUTF8(const vector<u_int16_t>& in,
+static string* UTF16ToUTF8(const vector<uint16_t>& in,
                            bool                     swap) {
   scoped_ptr<string> out(new string());
 
@@ -185,16 +186,16 @@
   // If the UTF-8 representation is longer, the string will grow dynamically.
   out->reserve(in.size());
 
-  for (vector<u_int16_t>::const_iterator iterator = in.begin();
+  for (vector<uint16_t>::const_iterator iterator = in.begin();
        iterator != in.end();
        ++iterator) {
     // Get a 16-bit value from the input
-    u_int16_t in_word = *iterator;
+    uint16_t in_word = *iterator;
     if (swap)
       Swap(&in_word);
 
     // Convert the input value (in_word) into a Unicode code point (unichar).
-    u_int32_t unichar;
+    uint32_t unichar;
     if (in_word >= 0xdc00 && in_word <= 0xdcff) {
       BPLOG(ERROR) << "UTF16ToUTF8 found low surrogate " <<
                       HexString(in_word) << " without high";
@@ -207,7 +208,7 @@
                         HexString(in_word) << " at end of string";
         return NULL;
       }
-      u_int32_t high_word = in_word;
+      uint32_t high_word = in_word;
       in_word = *iterator;
       if (in_word < 0xdc00 || in_word > 0xdcff) {
         BPLOG(ERROR) << "UTF16ToUTF8 found high surrogate " <<
@@ -250,7 +251,7 @@
 
 // Return the smaller of the number of code units in the UTF-16 string,
 // not including the terminating null word, or maxlen.
-static size_t UTF16codeunits(const u_int16_t *string, size_t maxlen) {
+static size_t UTF16codeunits(const uint16_t *string, size_t maxlen) {
   size_t count = 0;
   while (count < maxlen && string[count] != 0)
     count++;
@@ -286,8 +287,8 @@
 
 MinidumpContext::MinidumpContext(Minidump* minidump)
     : MinidumpStream(minidump),
-      context_flags_(0),
-      context_() {
+      context_(),
+      context_flags_(0) {
 }
 
 
@@ -296,7 +297,7 @@
 }
 
 
-bool MinidumpContext::Read(u_int32_t expected_size) {
+bool MinidumpContext::Read(uint32_t expected_size) {
   valid_ = false;
 
   FreeContext();
@@ -317,7 +318,15 @@
     if (minidump_->swap())
       Swap(&context_amd64->context_flags);
 
-    u_int32_t cpu_type = context_amd64->context_flags & MD_CONTEXT_CPU_MASK;
+    uint32_t cpu_type = context_amd64->context_flags & MD_CONTEXT_CPU_MASK;
+    if (cpu_type == 0) {
+      if (minidump_->GetContextCPUFlagsFromSystemInfo(&cpu_type)) {
+        context_amd64->context_flags |= cpu_type;
+      } else {
+        BPLOG(ERROR) << "Failed to preserve the current stream position";
+        return false;
+      }
+    }
 
     if (cpu_type != MD_CONTEXT_AMD64) {
       //TODO: fall through to switch below?
@@ -400,8 +409,10 @@
 
     context_.amd64 = context_amd64.release();
   }
-  else {
-    u_int32_t context_flags;
+  // |context_flags| of MDRawContextPPC64 is 64 bits, but other MDRawContext
+  // in the else case have 32 bits |context_flags|, so special case it here.
+  else if (expected_size == sizeof(MDRawContextPPC64)) {
+    uint64_t context_flags;
     if (!minidump_->ReadBytes(&context_flags, sizeof(context_flags))) {
       BPLOG(ERROR) << "MinidumpContext could not read context flags";
       return false;
@@ -409,7 +420,77 @@
     if (minidump_->swap())
       Swap(&context_flags);
 
-    u_int32_t cpu_type = context_flags & MD_CONTEXT_CPU_MASK;
+    uint32_t cpu_type = context_flags & MD_CONTEXT_CPU_MASK;
+
+    scoped_ptr<MDRawContextPPC64> context_ppc64(new MDRawContextPPC64());
+
+    // Set the context_flags member, which has already been read, and
+    // read the rest of the structure beginning with the first member
+    // after context_flags.
+    context_ppc64->context_flags = context_flags;
+
+    size_t flags_size = sizeof(context_ppc64->context_flags);
+    uint8_t* context_after_flags =
+          reinterpret_cast<uint8_t*>(context_ppc64.get()) + flags_size;
+    if (!minidump_->ReadBytes(context_after_flags,
+                              sizeof(MDRawContextPPC64) - flags_size)) {
+      BPLOG(ERROR) << "MinidumpContext could not read ppc64 context";
+      return false;
+    }
+
+    // Do this after reading the entire MDRawContext structure because
+    // GetSystemInfo may seek minidump to a new position.
+    if (!CheckAgainstSystemInfo(cpu_type)) {
+      BPLOG(ERROR) << "MinidumpContext ppc64 does not match system info";
+      return false;
+    }
+    if (minidump_->swap()) {
+      // context_ppc64->context_flags was already swapped.
+      Swap(&context_ppc64->srr0);
+      Swap(&context_ppc64->srr1);
+      for (unsigned int gpr_index = 0;
+           gpr_index < MD_CONTEXT_PPC64_GPR_COUNT;
+           ++gpr_index) {
+        Swap(&context_ppc64->gpr[gpr_index]);
+      }
+      Swap(&context_ppc64->cr);
+      Swap(&context_ppc64->xer);
+      Swap(&context_ppc64->lr);
+      Swap(&context_ppc64->ctr);
+      Swap(&context_ppc64->vrsave);
+      for (unsigned int fpr_index = 0;
+           fpr_index < MD_FLOATINGSAVEAREA_PPC_FPR_COUNT;
+           ++fpr_index) {
+        Swap(&context_ppc64->float_save.fpregs[fpr_index]);
+      }
+      // Don't swap context_ppc64->float_save.fpscr_pad because it is only
+      // used for padding.
+      Swap(&context_ppc64->float_save.fpscr);
+      for (unsigned int vr_index = 0;
+           vr_index < MD_VECTORSAVEAREA_PPC_VR_COUNT;
+           ++vr_index) {
+        Normalize128(&context_ppc64->vector_save.save_vr[vr_index], true);
+        Swap(&context_ppc64->vector_save.save_vr[vr_index]);
+      }
+      Swap(&context_ppc64->vector_save.save_vscr);
+      // Don't swap the padding fields in vector_save.
+      Swap(&context_ppc64->vector_save.save_vrvalid);
+    }
+
+    context_flags_ = context_ppc64->context_flags;
+    context_.ppc64 = context_ppc64.release();
+  }
+
+  else {
+    uint32_t context_flags;
+    if (!minidump_->ReadBytes(&context_flags, sizeof(context_flags))) {
+      BPLOG(ERROR) << "MinidumpContext could not read context flags";
+      return false;
+    }
+    if (minidump_->swap())
+      Swap(&context_flags);
+
+    uint32_t cpu_type = context_flags & MD_CONTEXT_CPU_MASK;
     if (cpu_type == 0) {
       // Unfortunately the flag for MD_CONTEXT_ARM that was taken
       // from a Windows CE SDK header conflicts in practice with
@@ -422,6 +503,15 @@
       }
     }
 
+    if (cpu_type == 0) {
+      if (minidump_->GetContextCPUFlagsFromSystemInfo(&cpu_type)) {
+        context_flags |= cpu_type;
+      } else {
+        BPLOG(ERROR) << "Failed to preserve the current stream position";
+        return false;
+      }
+    }
+
     // Allocate the context structure for the correct CPU and fill it.  The
     // casts are slightly unorthodox, but it seems better to do that than to
     // maintain a separate pointer for each type of CPU context structure
@@ -442,8 +532,8 @@
         context_x86->context_flags = context_flags;
 
         size_t flags_size = sizeof(context_x86->context_flags);
-        u_int8_t* context_after_flags =
-          reinterpret_cast<u_int8_t*>(context_x86.get()) + flags_size;
+        uint8_t* context_after_flags =
+          reinterpret_cast<uint8_t*>(context_x86.get()) + flags_size;
         if (!minidump_->ReadBytes(context_after_flags,
                                   sizeof(MDRawContextX86) - flags_size)) {
           BPLOG(ERROR) << "MinidumpContext could not read x86 context";
@@ -515,8 +605,8 @@
         context_ppc->context_flags = context_flags;
 
         size_t flags_size = sizeof(context_ppc->context_flags);
-        u_int8_t* context_after_flags =
-          reinterpret_cast<u_int8_t*>(context_ppc.get()) + flags_size;
+        uint8_t* context_after_flags =
+          reinterpret_cast<uint8_t*>(context_ppc.get()) + flags_size;
         if (!minidump_->ReadBytes(context_after_flags,
                                   sizeof(MDRawContextPPC) - flags_size)) {
           BPLOG(ERROR) << "MinidumpContext could not read ppc context";
@@ -591,8 +681,8 @@
         context_sparc->context_flags = context_flags;
 
         size_t flags_size = sizeof(context_sparc->context_flags);
-        u_int8_t* context_after_flags =
-            reinterpret_cast<u_int8_t*>(context_sparc.get()) + flags_size;
+        uint8_t* context_after_flags =
+            reinterpret_cast<uint8_t*>(context_sparc.get()) + flags_size;
         if (!minidump_->ReadBytes(context_after_flags,
                                   sizeof(MDRawContextSPARC) - flags_size)) {
           BPLOG(ERROR) << "MinidumpContext could not read sparc context";
@@ -647,8 +737,8 @@
         context_arm->context_flags = context_flags;
 
         size_t flags_size = sizeof(context_arm->context_flags);
-        u_int8_t* context_after_flags =
-            reinterpret_cast<u_int8_t*>(context_arm.get()) + flags_size;
+        uint8_t* context_after_flags =
+            reinterpret_cast<uint8_t*>(context_arm.get()) + flags_size;
         if (!minidump_->ReadBytes(context_after_flags,
                                   sizeof(MDRawContextARM) - flags_size)) {
           BPLOG(ERROR) << "MinidumpContext could not read arm context";
@@ -704,7 +794,7 @@
 }
 
 
-u_int32_t MinidumpContext::GetContextCPU() const {
+uint32_t MinidumpContext::GetContextCPU() const {
   if (!valid_) {
     // Don't log a message, GetContextCPU can be legitimately called with
     // valid_ false by FreeContext, which is called by Read.
@@ -714,7 +804,7 @@
   return context_flags_ & MD_CONTEXT_CPU_MASK;
 }
 
-bool MinidumpContext::GetInstructionPointer(u_int64_t* ip) const {
+bool MinidumpContext::GetInstructionPointer(uint64_t* ip) const {
   BPLOG_IF(ERROR, !ip) << "MinidumpContext::GetInstructionPointer "
                           "requires |ip|";
   assert(ip);
@@ -735,6 +825,9 @@
   case MD_CONTEXT_PPC:
     *ip = context_.ppc->srr0;
     break;
+  case MD_CONTEXT_PPC64:
+    *ip = context_.ppc64->srr0;
+    break;
   case MD_CONTEXT_SPARC:
     *ip = context_.ctx_sparc->pc;
     break;
@@ -769,6 +862,15 @@
   return context_.ppc;
 }
 
+const MDRawContextPPC64* MinidumpContext::GetContextPPC64() const {
+  if (GetContextCPU() != MD_CONTEXT_PPC64) {
+    BPLOG(ERROR) << "MinidumpContext cannot get ppc64 context";
+    return NULL;
+  }
+
+  return context_.ppc64;
+}
+
 const MDRawContextAMD64* MinidumpContext::GetContextAMD64() const {
   if (GetContextCPU() != MD_CONTEXT_AMD64) {
     BPLOG(ERROR) << "MinidumpContext cannot get amd64 context";
@@ -806,6 +908,10 @@
       delete context_.ppc;
       break;
 
+    case MD_CONTEXT_PPC64:
+      delete context_.ppc64;
+      break;
+
     case MD_CONTEXT_AMD64:
       delete context_.amd64;
       break;
@@ -830,7 +936,7 @@
 }
 
 
-bool MinidumpContext::CheckAgainstSystemInfo(u_int32_t context_cpu_type) {
+bool MinidumpContext::CheckAgainstSystemInfo(uint32_t context_cpu_type) {
   // It's OK if the minidump doesn't contain an MD_SYSTEM_INFO_STREAM,
   // as this function just implements a sanity check.
   MinidumpSystemInfo* system_info = minidump_->GetSystemInfo();
@@ -868,6 +974,11 @@
         return_value = true;
       break;
 
+    case MD_CONTEXT_PPC64:
+      if (system_info_cpu_type == MD_CPU_ARCHITECTURE_PPC64)
+        return_value = true;
+      break;
+
     case MD_CONTEXT_AMD64:
       if (system_info_cpu_type == MD_CPU_ARCHITECTURE_AMD64)
         return_value = true;
@@ -1002,6 +1113,44 @@
       break;
     }
 
+    case MD_CONTEXT_PPC64: {
+      const MDRawContextPPC64* context_ppc64 = GetContextPPC64();
+      printf("MDRawContextPPC64\n");
+      printf("  context_flags            = 0x%lx\n",
+             context_ppc64->context_flags);
+      printf("  srr0                     = 0x%lx\n", context_ppc64->srr0);
+      printf("  srr1                     = 0x%lx\n", context_ppc64->srr1);
+      for (unsigned int gpr_index = 0;
+           gpr_index < MD_CONTEXT_PPC64_GPR_COUNT;
+           ++gpr_index) {
+        printf("  gpr[%2d]                  = 0x%lx\n",
+               gpr_index, context_ppc64->gpr[gpr_index]);
+      }
+      printf("  cr                       = 0x%lx\n", context_ppc64->cr);
+      printf("  xer                      = 0x%lx\n", context_ppc64->xer);
+      printf("  lr                       = 0x%lx\n", context_ppc64->lr);
+      printf("  ctr                      = 0x%lx\n", context_ppc64->ctr);
+      printf("  vrsave                   = 0x%lx\n", context_ppc64->vrsave);
+      for (unsigned int fpr_index = 0;
+           fpr_index < MD_FLOATINGSAVEAREA_PPC_FPR_COUNT;
+           ++fpr_index) {
+        printf("  float_save.fpregs[%2d]    = 0x%" PRIx64 "\n",
+               fpr_index, context_ppc64->float_save.fpregs[fpr_index]);
+      }
+      printf("  float_save.fpscr         = 0x%x\n",
+             context_ppc64->float_save.fpscr);
+      // TODO(mmentovai): print the 128-bit quantities in
+      // context_ppc64->vector_save.  This isn't done yet because printf
+      // doesn't support 128-bit quantities, and printing them using
+      // PRIx64 as two 64-bit quantities requires knowledge of the CPU's
+      // byte ordering.
+      printf("  vector_save.save_vrvalid = 0x%x\n",
+             context_ppc64->vector_save.save_vrvalid);
+      printf("\n");
+
+      break;
+    }
+
     case MD_CONTEXT_AMD64: {
       const MDRawContextAMD64* context_amd64 = GetContextAMD64();
       printf("MDRawContextAMD64\n");
@@ -1129,7 +1278,7 @@
 //
 
 
-u_int32_t MinidumpMemoryRegion::max_bytes_ = 1024 * 1024;  // 1MB
+uint32_t MinidumpMemoryRegion::max_bytes_ = 1024 * 1024;  // 1MB
 
 
 MinidumpMemoryRegion::MinidumpMemoryRegion(Minidump* minidump)
@@ -1148,12 +1297,12 @@
   descriptor_ = descriptor;
   valid_ = descriptor &&
            descriptor_->memory.data_size <=
-               numeric_limits<u_int64_t>::max() -
+               numeric_limits<uint64_t>::max() -
                descriptor_->start_of_memory_range;
 }
 
 
-const u_int8_t* MinidumpMemoryRegion::GetMemory() const {
+const uint8_t* MinidumpMemoryRegion::GetMemory() const {
   if (!valid_) {
     BPLOG(ERROR) << "Invalid MinidumpMemoryRegion for GetMemory";
     return NULL;
@@ -1177,8 +1326,8 @@
       return NULL;
     }
 
-    scoped_ptr< vector<u_int8_t> > memory(
-        new vector<u_int8_t>(descriptor_->memory.data_size));
+    scoped_ptr< vector<uint8_t> > memory(
+        new vector<uint8_t>(descriptor_->memory.data_size));
 
     if (!minidump_->ReadBytes(&(*memory)[0], descriptor_->memory.data_size)) {
       BPLOG(ERROR) << "MinidumpMemoryRegion could not read memory region";
@@ -1192,17 +1341,17 @@
 }
 
 
-u_int64_t MinidumpMemoryRegion::GetBase() const {
+uint64_t MinidumpMemoryRegion::GetBase() const {
   if (!valid_) {
     BPLOG(ERROR) << "Invalid MinidumpMemoryRegion for GetBase";
-    return static_cast<u_int64_t>(-1);
+    return static_cast<uint64_t>(-1);
   }
 
   return descriptor_->start_of_memory_range;
 }
 
 
-u_int32_t MinidumpMemoryRegion::GetSize() const {
+uint32_t MinidumpMemoryRegion::GetSize() const {
   if (!valid_) {
     BPLOG(ERROR) << "Invalid MinidumpMemoryRegion for GetSize";
     return 0;
@@ -1219,7 +1368,7 @@
 
 
 template<typename T>
-bool MinidumpMemoryRegion::GetMemoryAtAddressInternal(u_int64_t address,
+bool MinidumpMemoryRegion::GetMemoryAtAddressInternal(uint64_t address,
                                                       T*        value) const {
   BPLOG_IF(ERROR, !value) << "MinidumpMemoryRegion::GetMemoryAtAddressInternal "
                              "requires |value|";
@@ -1234,7 +1383,7 @@
 
   // Common failure case
   if (address < descriptor_->start_of_memory_range ||
-      sizeof(T) > numeric_limits<u_int64_t>::max() - address ||
+      sizeof(T) > numeric_limits<uint64_t>::max() - address ||
       address + sizeof(T) > descriptor_->start_of_memory_range +
                             descriptor_->memory.data_size) {
     BPLOG(INFO) << "MinidumpMemoryRegion request out of range: " <<
@@ -1244,7 +1393,7 @@
     return false;
   }
 
-  const u_int8_t* memory = GetMemory();
+  const uint8_t* memory = GetMemory();
   if (!memory) {
     // GetMemory already logged a perfectly good message.
     return false;
@@ -1262,26 +1411,26 @@
 }
 
 
-bool MinidumpMemoryRegion::GetMemoryAtAddress(u_int64_t  address,
-                                              u_int8_t*  value) const {
+bool MinidumpMemoryRegion::GetMemoryAtAddress(uint64_t  address,
+                                              uint8_t*  value) const {
   return GetMemoryAtAddressInternal(address, value);
 }
 
 
-bool MinidumpMemoryRegion::GetMemoryAtAddress(u_int64_t  address,
-                                              u_int16_t* value) const {
+bool MinidumpMemoryRegion::GetMemoryAtAddress(uint64_t  address,
+                                              uint16_t* value) const {
   return GetMemoryAtAddressInternal(address, value);
 }
 
 
-bool MinidumpMemoryRegion::GetMemoryAtAddress(u_int64_t  address,
-                                              u_int32_t* value) const {
+bool MinidumpMemoryRegion::GetMemoryAtAddress(uint64_t  address,
+                                              uint32_t* value) const {
   return GetMemoryAtAddressInternal(address, value);
 }
 
 
-bool MinidumpMemoryRegion::GetMemoryAtAddress(u_int64_t  address,
-                                              u_int64_t* value) const {
+bool MinidumpMemoryRegion::GetMemoryAtAddress(uint64_t  address,
+                                              uint64_t* value) const {
   return GetMemoryAtAddressInternal(address, value);
 }
 
@@ -1292,7 +1441,7 @@
     return;
   }
 
-  const u_int8_t* memory = GetMemory();
+  const uint8_t* memory = GetMemory();
   if (memory) {
     printf("0x");
     for (unsigned int byte_index = 0;
@@ -1352,7 +1501,7 @@
 
   // Check for base + size overflow or undersize.
   if (thread_.stack.memory.data_size == 0 ||
-      thread_.stack.memory.data_size > numeric_limits<u_int64_t>::max() -
+      thread_.stack.memory.data_size > numeric_limits<uint64_t>::max() -
                                        thread_.stack.start_of_memory_range) {
     // This is ok, but log an error anyway.
     BPLOG(ERROR) << "MinidumpThread has a memory region problem, " <<
@@ -1404,7 +1553,7 @@
 }
 
 
-bool MinidumpThread::GetThreadID(u_int32_t *thread_id) const {
+bool MinidumpThread::GetThreadID(uint32_t *thread_id) const {
   BPLOG_IF(ERROR, !thread_id) << "MinidumpThread::GetThreadID requires "
                                  "|thread_id|";
   assert(thread_id);
@@ -1467,7 +1616,7 @@
 //
 
 
-u_int32_t MinidumpThreadList::max_threads_ = 4096;
+uint32_t MinidumpThreadList::max_threads_ = 4096;
 
 
 MinidumpThreadList::MinidumpThreadList(Minidump* minidump)
@@ -1483,7 +1632,7 @@
 }
 
 
-bool MinidumpThreadList::Read(u_int32_t expected_size) {
+bool MinidumpThreadList::Read(uint32_t expected_size) {
   // Invalidate cached data.
   id_to_thread_map_.clear();
   delete threads_;
@@ -1492,7 +1641,7 @@
 
   valid_ = false;
 
-  u_int32_t thread_count;
+  uint32_t thread_count;
   if (expected_size < sizeof(thread_count)) {
     BPLOG(ERROR) << "MinidumpThreadList count size mismatch, " <<
                     expected_size << " < " << sizeof(thread_count);
@@ -1506,7 +1655,7 @@
   if (minidump_->swap())
     Swap(&thread_count);
 
-  if (thread_count > numeric_limits<u_int32_t>::max() / sizeof(MDRawThread)) {
+  if (thread_count > numeric_limits<uint32_t>::max() / sizeof(MDRawThread)) {
     BPLOG(ERROR) << "MinidumpThreadList thread count " << thread_count <<
                     " would cause multiplication overflow";
     return false;
@@ -1517,7 +1666,7 @@
     // may be padded with 4 bytes on 64bit ABIs for alignment
     if (expected_size == sizeof(thread_count) + 4 +
                          thread_count * sizeof(MDRawThread)) {
-      u_int32_t useless;
+      uint32_t useless;
       if (!minidump_->ReadBytes(&useless, 4)) {
         BPLOG(ERROR) << "MinidumpThreadList cannot read threadlist padded bytes";
         return false;
@@ -1553,7 +1702,7 @@
         return false;
       }
 
-      u_int32_t thread_id;
+      uint32_t thread_id;
       if (!thread->GetThreadID(&thread_id)) {
         BPLOG(ERROR) << "MinidumpThreadList cannot get thread ID for thread " <<
                         thread_index << "/" << thread_count;
@@ -1597,7 +1746,7 @@
 }
 
 
-MinidumpThread* MinidumpThreadList::GetThreadByID(u_int32_t thread_id) {
+MinidumpThread* MinidumpThreadList::GetThreadByID(uint32_t thread_id) {
   // Don't check valid_.  Read calls this method before everything is
   // validated.  It is safe to not check valid_ here.
   return id_to_thread_map_[thread_id];
@@ -1629,8 +1778,8 @@
 //
 
 
-u_int32_t MinidumpModule::max_cv_bytes_ = 32768;
-u_int32_t MinidumpModule::max_misc_bytes_ = 32768;
+uint32_t MinidumpModule::max_cv_bytes_ = 32768;
+uint32_t MinidumpModule::max_misc_bytes_ = 32768;
 
 
 MinidumpModule::MinidumpModule(Minidump* minidump)
@@ -1699,7 +1848,7 @@
   // Check for base + size overflow or undersize.
   if (module_.size_of_image == 0 ||
       module_.size_of_image >
-          numeric_limits<u_int64_t>::max() - module_.base_of_image) {
+          numeric_limits<uint64_t>::max() - module_.base_of_image) {
     BPLOG(ERROR) << "MinidumpModule has a module problem, " <<
                     HexString(module_.base_of_image) << "+" <<
                     HexString(module_.size_of_image);
@@ -1874,9 +2023,9 @@
         if (bytes % 2 == 0) {
           unsigned int utf16_words = bytes / 2;
 
-          // UTF16ToUTF8 expects a vector<u_int16_t>, so create a temporary one
+          // UTF16ToUTF8 expects a vector<uint16_t>, so create a temporary one
           // and copy the UTF-16 data into it.
-          vector<u_int16_t> string_utf16(utf16_words);
+          vector<uint16_t> string_utf16(utf16_words);
           if (utf16_words)
             memcpy(&string_utf16[0], &misc_record->data, bytes);
 
@@ -2003,7 +2152,7 @@
 }
 
 
-const u_int8_t* MinidumpModule::GetCVRecord(u_int32_t* size) {
+const uint8_t* MinidumpModule::GetCVRecord(uint32_t* size) {
   if (!module_valid_) {
     BPLOG(ERROR) << "Invalid MinidumpModule for GetCVRecord";
     return NULL;
@@ -2029,21 +2178,21 @@
     }
 
     // Allocating something that will be accessed as MDCVInfoPDB70 or
-    // MDCVInfoPDB20 but is allocated as u_int8_t[] can cause alignment
+    // MDCVInfoPDB20 but is allocated as uint8_t[] can cause alignment
     // problems.  x86 and ppc are able to cope, though.  This allocation
     // style is needed because the MDCVInfoPDB70 or MDCVInfoPDB20 are
     // variable-sized due to their pdb_file_name fields; these structures
     // are not MDCVInfoPDB70_minsize or MDCVInfoPDB20_minsize and treating
     // them as such would result in incomplete structures or overruns.
-    scoped_ptr< vector<u_int8_t> > cv_record(
-        new vector<u_int8_t>(module_.cv_record.data_size));
+    scoped_ptr< vector<uint8_t> > cv_record(
+        new vector<uint8_t>(module_.cv_record.data_size));
 
     if (!minidump_->ReadBytes(&(*cv_record)[0], module_.cv_record.data_size)) {
       BPLOG(ERROR) << "MinidumpModule could not read CodeView record";
       return NULL;
     }
 
-    u_int32_t signature = MD_CVINFOUNKNOWN_SIGNATURE;
+    uint32_t signature = MD_CVINFOUNKNOWN_SIGNATURE;
     if (module_.cv_record.data_size > sizeof(signature)) {
       MDCVInfoPDB70* cv_record_signature =
           reinterpret_cast<MDCVInfoPDB70*>(&(*cv_record)[0]);
@@ -2113,7 +2262,7 @@
     // although byte-swapping can't be done.
 
     // Store the vector type because that's how storage was allocated, but
-    // return it casted to u_int8_t*.
+    // return it casted to uint8_t*.
     cv_record_ = cv_record.release();
     cv_record_signature_ = signature;
   }
@@ -2125,7 +2274,7 @@
 }
 
 
-const MDImageDebugMisc* MinidumpModule::GetMiscRecord(u_int32_t* size) {
+const MDImageDebugMisc* MinidumpModule::GetMiscRecord(uint32_t* size) {
   if (!module_valid_) {
     BPLOG(ERROR) << "Invalid MinidumpModule for GetMiscRecord";
     return NULL;
@@ -2157,13 +2306,13 @@
     }
 
     // Allocating something that will be accessed as MDImageDebugMisc but
-    // is allocated as u_int8_t[] can cause alignment problems.  x86 and
+    // is allocated as uint8_t[] can cause alignment problems.  x86 and
     // ppc are able to cope, though.  This allocation style is needed
     // because the MDImageDebugMisc is variable-sized due to its data field;
     // this structure is not MDImageDebugMisc_minsize and treating it as such
     // would result in an incomplete structure or an overrun.
-    scoped_ptr< vector<u_int8_t> > misc_record_mem(
-        new vector<u_int8_t>(module_.misc_record.data_size));
+    scoped_ptr< vector<uint8_t> > misc_record_mem(
+        new vector<uint8_t>(module_.misc_record.data_size));
     MDImageDebugMisc* misc_record =
         reinterpret_cast<MDImageDebugMisc*>(&(*misc_record_mem)[0]);
 
@@ -2182,7 +2331,7 @@
       if (misc_record->unicode) {
         // There is a potential alignment problem, but shouldn't be a problem
         // in practice due to the layout of MDImageDebugMisc.
-        u_int16_t* data16 = reinterpret_cast<u_int16_t*>(&(misc_record->data));
+        uint16_t* data16 = reinterpret_cast<uint16_t*>(&(misc_record->data));
         unsigned int dataBytes = module_.misc_record.data_size -
                                  MDImageDebugMisc_minsize;
         unsigned int dataLength = dataBytes / 2;
@@ -2266,8 +2415,8 @@
   printf("  (code_identifier)               = \"%s\"\n",
          code_identifier().c_str());
 
-  u_int32_t cv_record_size;
-  const u_int8_t *cv_record = GetCVRecord(&cv_record_size);
+  uint32_t cv_record_size;
+  const uint8_t *cv_record = GetCVRecord(&cv_record_size);
   if (cv_record) {
     if (cv_record_signature_ == MD_CVINFOPDB70_SIGNATURE) {
       const MDCVInfoPDB70* cv_record_70 =
@@ -2352,12 +2501,12 @@
 //
 
 
-u_int32_t MinidumpModuleList::max_modules_ = 1024;
+uint32_t MinidumpModuleList::max_modules_ = 1024;
 
 
 MinidumpModuleList::MinidumpModuleList(Minidump* minidump)
     : MinidumpStream(minidump),
-      range_map_(new RangeMap<u_int64_t, unsigned int>()),
+      range_map_(new RangeMap<uint64_t, unsigned int>()),
       modules_(NULL),
       module_count_(0) {
 }
@@ -2369,7 +2518,7 @@
 }
 
 
-bool MinidumpModuleList::Read(u_int32_t expected_size) {
+bool MinidumpModuleList::Read(uint32_t expected_size) {
   // Invalidate cached data.
   range_map_->Clear();
   delete modules_;
@@ -2378,7 +2527,7 @@
 
   valid_ = false;
 
-  u_int32_t module_count;
+  uint32_t module_count;
   if (expected_size < sizeof(module_count)) {
     BPLOG(ERROR) << "MinidumpModuleList count size mismatch, " <<
                     expected_size << " < " << sizeof(module_count);
@@ -2392,7 +2541,7 @@
   if (minidump_->swap())
     Swap(&module_count);
 
-  if (module_count > numeric_limits<u_int32_t>::max() / MD_MODULE_SIZE) {
+  if (module_count > numeric_limits<uint32_t>::max() / MD_MODULE_SIZE) {
     BPLOG(ERROR) << "MinidumpModuleList module count " << module_count <<
                     " would cause multiplication overflow";
     return false;
@@ -2403,7 +2552,7 @@
     // may be padded with 4 bytes on 64bit ABIs for alignment
     if (expected_size == sizeof(module_count) + 4 +
                          module_count * MD_MODULE_SIZE) {
-      u_int32_t useless;
+      uint32_t useless;
       if (!minidump_->ReadBytes(&useless, 4)) {
         BPLOG(ERROR) << "MinidumpModuleList cannot read modulelist padded bytes";
         return false;
@@ -2464,9 +2613,9 @@
       // It is safe to use module->code_file() after successfully calling
       // module->ReadAuxiliaryData or noting that the module is valid.
 
-      u_int64_t base_address = module->base_address();
-      u_int64_t module_size = module->size();
-      if (base_address == static_cast<u_int64_t>(-1)) {
+      uint64_t base_address = module->base_address();
+      uint64_t module_size = module->size();
+      if (base_address == static_cast<uint64_t>(-1)) {
         BPLOG(ERROR) << "MinidumpModuleList found bad base address "
                         "for module " << module_index << "/" << module_count <<
                         ", " << module->code_file();
@@ -2494,7 +2643,7 @@
 
 
 const MinidumpModule* MinidumpModuleList::GetModuleForAddress(
-    u_int64_t address) const {
+    uint64_t address) const {
   if (!valid_) {
     BPLOG(ERROR) << "Invalid MinidumpModuleList for GetModuleForAddress";
     return NULL;
@@ -2593,12 +2742,12 @@
 //
 
 
-u_int32_t MinidumpMemoryList::max_regions_ = 4096;
+uint32_t MinidumpMemoryList::max_regions_ = 4096;
 
 
 MinidumpMemoryList::MinidumpMemoryList(Minidump* minidump)
     : MinidumpStream(minidump),
-      range_map_(new RangeMap<u_int64_t, unsigned int>()),
+      range_map_(new RangeMap<uint64_t, unsigned int>()),
       descriptors_(NULL),
       regions_(NULL),
       region_count_(0) {
@@ -2612,7 +2761,7 @@
 }
 
 
-bool MinidumpMemoryList::Read(u_int32_t expected_size) {
+bool MinidumpMemoryList::Read(uint32_t expected_size) {
   // Invalidate cached data.
   delete descriptors_;
   descriptors_ = NULL;
@@ -2623,7 +2772,7 @@
 
   valid_ = false;
 
-  u_int32_t region_count;
+  uint32_t region_count;
   if (expected_size < sizeof(region_count)) {
     BPLOG(ERROR) << "MinidumpMemoryList count size mismatch, " <<
                     expected_size << " < " << sizeof(region_count);
@@ -2638,7 +2787,7 @@
     Swap(&region_count);
 
   if (region_count >
-          numeric_limits<u_int32_t>::max() / sizeof(MDMemoryDescriptor)) {
+          numeric_limits<uint32_t>::max() / sizeof(MDMemoryDescriptor)) {
     BPLOG(ERROR) << "MinidumpMemoryList region count " << region_count <<
                     " would cause multiplication overflow";
     return false;
@@ -2649,7 +2798,7 @@
     // may be padded with 4 bytes on 64bit ABIs for alignment
     if (expected_size == sizeof(region_count) + 4 +
                          region_count * sizeof(MDMemoryDescriptor)) {
-      u_int32_t useless;
+      uint32_t useless;
       if (!minidump_->ReadBytes(&useless, 4)) {
         BPLOG(ERROR) << "MinidumpMemoryList cannot read memorylist padded bytes";
         return false;
@@ -2691,12 +2840,12 @@
       if (minidump_->swap())
         Swap(descriptor);
 
-      u_int64_t base_address = descriptor->start_of_memory_range;
-      u_int32_t region_size = descriptor->memory.data_size;
+      uint64_t base_address = descriptor->start_of_memory_range;
+      uint32_t region_size = descriptor->memory.data_size;
 
       // Check for base + size overflow or undersize.
       if (region_size == 0 ||
-          region_size > numeric_limits<u_int64_t>::max() - base_address) {
+          region_size > numeric_limits<uint64_t>::max() - base_address) {
         BPLOG(ERROR) << "MinidumpMemoryList has a memory region problem, " <<
                         " region " << region_index << "/" << region_count <<
                         ", " << HexString(base_address) << "+" <<
@@ -2744,7 +2893,7 @@
 
 
 MinidumpMemoryRegion* MinidumpMemoryList::GetMemoryRegionForAddress(
-    u_int64_t address) {
+    uint64_t address) {
   if (!valid_) {
     BPLOG(ERROR) << "Invalid MinidumpMemoryList for GetMemoryRegionForAddress";
     return NULL;
@@ -2810,7 +2959,7 @@
 }
 
 
-bool MinidumpException::Read(u_int32_t expected_size) {
+bool MinidumpException::Read(uint32_t expected_size) {
   // Invalidate cached data.
   delete context_;
   context_ = NULL;
@@ -2852,7 +3001,7 @@
 }
 
 
-bool MinidumpException::GetThreadID(u_int32_t *thread_id) const {
+bool MinidumpException::GetThreadID(uint32_t *thread_id) const {
   BPLOG_IF(ERROR, !thread_id) << "MinidumpException::GetThreadID requires "
                                  "|thread_id|";
   assert(thread_id);
@@ -2954,7 +3103,7 @@
 }
 
 
-bool MinidumpAssertion::Read(u_int32_t expected_size) {
+bool MinidumpAssertion::Read(uint32_t expected_size) {
   // Invalidate cached data.
   valid_ = false;
 
@@ -2975,11 +3124,11 @@
   // Since we don't have an explicit byte length for each string,
   // we use UTF16codeunits to calculate word length, then derive byte
   // length from that.
-  u_int32_t word_length = UTF16codeunits(assertion_.expression,
+  uint32_t word_length = UTF16codeunits(assertion_.expression,
                                          sizeof(assertion_.expression));
   if (word_length > 0) {
-    u_int32_t byte_length = word_length * 2;
-    vector<u_int16_t> expression_utf16(word_length);
+    uint32_t byte_length = word_length * 2;
+    vector<uint16_t> expression_utf16(word_length);
     memcpy(&expression_utf16[0], &assertion_.expression[0], byte_length);
 
     scoped_ptr<string> new_expression(UTF16ToUTF8(expression_utf16,
@@ -2992,8 +3141,8 @@
   word_length = UTF16codeunits(assertion_.function,
                                sizeof(assertion_.function));
   if (word_length) {
-    u_int32_t byte_length = word_length * 2;
-    vector<u_int16_t> function_utf16(word_length);
+    uint32_t byte_length = word_length * 2;
+    vector<uint16_t> function_utf16(word_length);
     memcpy(&function_utf16[0], &assertion_.function[0], byte_length);
     scoped_ptr<string> new_function(UTF16ToUTF8(function_utf16,
                                                 minidump_->swap()));
@@ -3005,8 +3154,8 @@
   word_length = UTF16codeunits(assertion_.file,
                                sizeof(assertion_.file));
   if (word_length > 0) {
-    u_int32_t byte_length = word_length * 2;
-    vector<u_int16_t> file_utf16(word_length);
+    uint32_t byte_length = word_length * 2;
+    vector<uint16_t> file_utf16(word_length);
     memcpy(&file_utf16[0], &assertion_.file[0], byte_length);
     scoped_ptr<string> new_file(UTF16ToUTF8(file_utf16,
                                             minidump_->swap()));
@@ -3062,7 +3211,7 @@
 }
 
 
-bool MinidumpSystemInfo::Read(u_int32_t expected_size) {
+bool MinidumpSystemInfo::Read(uint32_t expected_size) {
   // Invalidate cached data.
   delete csd_version_;
   csd_version_ = NULL;
@@ -3180,6 +3329,10 @@
       cpu = "ppc";
       break;
 
+    case MD_CPU_ARCHITECTURE_PPC64:
+      cpu = "ppc64";
+      break;
+
     case MD_CPU_ARCHITECTURE_SPARC:
       cpu = "sparc";
       break;
@@ -3314,7 +3467,7 @@
 }
 
 
-bool MinidumpMiscInfo::Read(u_int32_t expected_size) {
+bool MinidumpMiscInfo::Read(uint32_t expected_size) {
   valid_ = false;
 
   if (expected_size != MD_MISCINFO_SIZE &&
@@ -3400,7 +3553,7 @@
 }
 
 
-bool MinidumpBreakpadInfo::Read(u_int32_t expected_size) {
+bool MinidumpBreakpadInfo::Read(uint32_t expected_size) {
   valid_ = false;
 
   if (expected_size != sizeof(breakpad_info_)) {
@@ -3425,7 +3578,7 @@
 }
 
 
-bool MinidumpBreakpadInfo::GetDumpThreadID(u_int32_t *thread_id) const {
+bool MinidumpBreakpadInfo::GetDumpThreadID(uint32_t *thread_id) const {
   BPLOG_IF(ERROR, !thread_id) << "MinidumpBreakpadInfo::GetDumpThreadID "
                                  "requires |thread_id|";
   assert(thread_id);
@@ -3446,7 +3599,7 @@
 }
 
 
-bool MinidumpBreakpadInfo::GetRequestingThreadID(u_int32_t *thread_id)
+bool MinidumpBreakpadInfo::GetRequestingThreadID(uint32_t *thread_id)
     const {
   BPLOG_IF(ERROR, !thread_id) << "MinidumpBreakpadInfo::GetRequestingThreadID "
                                  "requires |thread_id|";
@@ -3507,7 +3660,7 @@
 
 
 bool MinidumpMemoryInfo::IsExecutable() const {
-  u_int32_t protection =
+  uint32_t protection =
       memory_info_.protection & MD_MEMORY_PROTECTION_ACCESS_MASK;
   return protection == MD_MEMORY_PROTECT_EXECUTE ||
       protection == MD_MEMORY_PROTECT_EXECUTE_READ ||
@@ -3516,7 +3669,7 @@
 
 
 bool MinidumpMemoryInfo::IsWritable() const {
-  u_int32_t protection =
+  uint32_t protection =
       memory_info_.protection & MD_MEMORY_PROTECTION_ACCESS_MASK;
   return protection == MD_MEMORY_PROTECT_READWRITE ||
     protection == MD_MEMORY_PROTECT_WRITECOPY ||
@@ -3545,7 +3698,7 @@
 
   // Check for base + size overflow or undersize.
   if (memory_info_.region_size == 0 ||
-      memory_info_.region_size > numeric_limits<u_int64_t>::max() -
+      memory_info_.region_size > numeric_limits<uint64_t>::max() -
                                      memory_info_.base_address) {
     BPLOG(ERROR) << "MinidumpMemoryInfo has a memory region problem, " <<
                     HexString(memory_info_.base_address) << "+" <<
@@ -3585,7 +3738,7 @@
 
 MinidumpMemoryInfoList::MinidumpMemoryInfoList(Minidump* minidump)
     : MinidumpStream(minidump),
-      range_map_(new RangeMap<u_int64_t, unsigned int>()),
+      range_map_(new RangeMap<uint64_t, unsigned int>()),
       infos_(NULL),
       info_count_(0) {
 }
@@ -3597,7 +3750,7 @@
 }
 
 
-bool MinidumpMemoryInfoList::Read(u_int32_t expected_size) {
+bool MinidumpMemoryInfoList::Read(uint32_t expected_size) {
   // Invalidate cached data.
   delete infos_;
   infos_ = NULL;
@@ -3642,7 +3795,7 @@
   }
 
   if (header.number_of_entries >
-          numeric_limits<u_int32_t>::max() / sizeof(MDRawMemoryInfo)) {
+          numeric_limits<uint32_t>::max() / sizeof(MDRawMemoryInfo)) {
     BPLOG(ERROR) << "MinidumpMemoryInfoList info count " <<
                     header.number_of_entries <<
                     " would cause multiplication overflow";
@@ -3674,8 +3827,8 @@
         return false;
       }
 
-      u_int64_t base_address = info->GetBase();
-      u_int32_t region_size = info->GetSize();
+      uint64_t base_address = info->GetBase();
+      uint32_t region_size = info->GetSize();
 
       if (!range_map_->StoreRange(base_address, region_size, index)) {
         BPLOG(ERROR) << "MinidumpMemoryInfoList could not store"
@@ -3715,7 +3868,7 @@
 
 
 const MinidumpMemoryInfo* MinidumpMemoryInfoList::GetMemoryInfoForAddress(
-    u_int64_t address) const {
+    uint64_t address) const {
   if (!valid_) {
     BPLOG(ERROR) << "Invalid MinidumpMemoryInfoList for"
                     " GetMemoryInfoForAddress";
@@ -3758,7 +3911,7 @@
 //
 
 
-u_int32_t Minidump::max_streams_ = 128;
+uint32_t Minidump::max_streams_ = 128;
 unsigned int Minidump::max_string_length_ = 1024;
 
 
@@ -3816,6 +3969,75 @@
   return true;
 }
 
+bool Minidump::GetContextCPUFlagsFromSystemInfo(uint32_t *context_cpu_flags) {
+  // Initialize output parameters
+  *context_cpu_flags = 0;
+
+  // Save the current stream position
+  off_t saved_position = Tell();
+  if (saved_position == -1) {
+    // Failed to save the current stream position.
+    // Returns true because the current position of the stream is preserved.
+    return true;
+  }
+
+  const MDRawSystemInfo* system_info =
+    GetSystemInfo() ? GetSystemInfo()->system_info() : NULL;
+
+  if (system_info != NULL) {
+    switch (system_info->processor_architecture) {
+      case MD_CPU_ARCHITECTURE_X86:
+        *context_cpu_flags = MD_CONTEXT_X86;
+        break;
+      case MD_CPU_ARCHITECTURE_MIPS:
+        *context_cpu_flags = MD_CONTEXT_MIPS;
+        break;
+      case MD_CPU_ARCHITECTURE_ALPHA:
+        *context_cpu_flags = MD_CONTEXT_ALPHA;
+        break;
+      case MD_CPU_ARCHITECTURE_PPC:
+        *context_cpu_flags = MD_CONTEXT_PPC;
+        break;
+      case MD_CPU_ARCHITECTURE_PPC64:
+        *context_cpu_flags = MD_CONTEXT_PPC64;
+        break;
+      case MD_CPU_ARCHITECTURE_SHX:
+        *context_cpu_flags = MD_CONTEXT_SHX;
+        break;
+      case MD_CPU_ARCHITECTURE_ARM:
+        *context_cpu_flags = MD_CONTEXT_ARM;
+        break;
+      case MD_CPU_ARCHITECTURE_IA64:
+        *context_cpu_flags = MD_CONTEXT_IA64;
+        break;
+      case MD_CPU_ARCHITECTURE_ALPHA64:
+        *context_cpu_flags = 0;
+        break;
+      case MD_CPU_ARCHITECTURE_MSIL:
+        *context_cpu_flags = 0;
+        break;
+      case MD_CPU_ARCHITECTURE_AMD64:
+        *context_cpu_flags = MD_CONTEXT_AMD64;
+        break;
+      case MD_CPU_ARCHITECTURE_X86_WIN64:
+        *context_cpu_flags = 0;
+        break;
+      case MD_CPU_ARCHITECTURE_SPARC:
+        *context_cpu_flags = MD_CONTEXT_SPARC;
+        break;
+      case MD_CPU_ARCHITECTURE_UNKNOWN:
+        *context_cpu_flags = 0;
+        break;
+      default:
+        *context_cpu_flags = 0;
+        break;
+    }
+  }
+
+  // Restore position and return
+  return SeekSet(saved_position);
+}
+
 
 bool Minidump::Read() {
   // Invalidate cached data.
@@ -3840,7 +4062,7 @@
     // classes don't know or need to know what CPU (or endianness) the
     // minidump was produced on in order to parse it.  Use the signature as
     // a byte order marker.
-    u_int32_t signature_swapped = header_.signature;
+    uint32_t signature_swapped = header_.signature;
     Swap(&signature_swapped);
     if (signature_swapped != MD_HEADER_SIGNATURE) {
       // This isn't a minidump or a byte-swapped minidump.
@@ -4044,7 +4266,7 @@
   for (MinidumpStreamMap::const_iterator iterator = stream_map_->begin();
        iterator != stream_map_->end();
        ++iterator) {
-    u_int32_t stream_type = iterator->first;
+    uint32_t stream_type = iterator->first;
     MinidumpStreamInfo info = iterator->second;
     printf("  stream type 0x%x at index %d\n", stream_type, info.stream_index);
   }
@@ -4126,7 +4348,7 @@
     return NULL;
   }
 
-  u_int32_t bytes;
+  uint32_t bytes;
   if (!ReadBytes(&bytes, sizeof(bytes))) {
     BPLOG(ERROR) << "ReadString could not read string size at offset " <<
                     offset;
@@ -4149,7 +4371,7 @@
     return NULL;
   }
 
-  vector<u_int16_t> string_utf16(utf16_words);
+  vector<uint16_t> string_utf16(utf16_words);
 
   if (utf16_words) {
     if (!ReadBytes(&string_utf16[0], bytes)) {
@@ -4163,8 +4385,8 @@
 }
 
 
-bool Minidump::SeekToStreamType(u_int32_t  stream_type,
-                                u_int32_t* stream_length) {
+bool Minidump::SeekToStreamType(uint32_t  stream_type,
+                                uint32_t* stream_length) {
   BPLOG_IF(ERROR, !stream_length) << "Minidump::SeekToStreamType requires "
                                      "|stream_length|";
   assert(stream_length);
@@ -4208,7 +4430,7 @@
   // stream is a garbage parameter that's present only to account for C++'s
   // inability to overload a method based solely on its return type.
 
-  const u_int32_t stream_type = T::kStreamType;
+  const uint32_t stream_type = T::kStreamType;
 
   BPLOG_IF(ERROR, !stream) << "Minidump::GetStream type " << stream_type <<
                               " requires |stream|";
@@ -4237,7 +4459,7 @@
     return *stream;
   }
 
-  u_int32_t stream_length;
+  uint32_t stream_length;
   if (!SeekToStreamType(stream_type, &stream_length)) {
     BPLOG(ERROR) << "GetStream could not seek to stream type " << stream_type;
     return NULL;
diff --git a/src/processor/minidump_dump.cc b/src/processor/minidump_dump.cc
index 869a763..343f044 100644
--- a/src/processor/minidump_dump.cc
+++ b/src/processor/minidump_dump.cc
@@ -35,9 +35,9 @@
 #include <stdio.h>
 #include <string.h>
 
+#include "common/scoped_ptr.h"
 #include "google_breakpad/processor/minidump.h"
 #include "processor/logging.h"
-#include "processor/scoped_ptr.h"
 
 namespace {
 
@@ -53,10 +53,10 @@
 using google_breakpad::MinidumpBreakpadInfo;
 
 static void DumpRawStream(Minidump *minidump,
-                          u_int32_t stream_type,
+                          uint32_t stream_type,
                           const char *stream_name,
                           int *errors) {
-  u_int32_t length = 0;
+  uint32_t length = 0;
   if (!minidump->SeekToStreamType(stream_type, &length)) {
     return;
   }
@@ -78,7 +78,7 @@
     size_t remaining = length - current_offset;
     // Printf requires an int and direct casting from size_t results
     // in compatibility warnings.
-    u_int32_t int_remaining = remaining;
+    uint32_t int_remaining = remaining;
     printf("%.*s", int_remaining, &contents[current_offset]);
     char *next_null = reinterpret_cast<char *>(
         memchr(&contents[current_offset], 0, remaining));
diff --git a/src/processor/minidump_processor.cc b/src/processor/minidump_processor.cc
index db5b271..afe15ca 100644
--- a/src/processor/minidump_processor.cc
+++ b/src/processor/minidump_processor.cc
@@ -32,13 +32,13 @@
 #include <assert.h>
 #include <stdio.h>
 
+#include "common/scoped_ptr.h"
 #include "google_breakpad/processor/call_stack.h"
 #include "google_breakpad/processor/minidump.h"
 #include "google_breakpad/processor/process_state.h"
 #include "google_breakpad/processor/exploitability.h"
 #include "google_breakpad/processor/stack_frame_symbolizer.h"
 #include "processor/logging.h"
-#include "processor/scoped_ptr.h"
 #include "processor/stackwalker_x86.h"
 
 namespace google_breakpad {
@@ -87,9 +87,9 @@
   bool has_cpu_info = GetCPUInfo(dump, &process_state->system_info_);
   bool has_os_info = GetOSInfo(dump, &process_state->system_info_);
 
-  u_int32_t dump_thread_id = 0;
+  uint32_t dump_thread_id = 0;
   bool has_dump_thread = false;
-  u_int32_t requesting_thread_id = 0;
+  uint32_t requesting_thread_id = 0;
   bool has_requesting_thread = false;
 
   MinidumpBreakpadInfo *breakpad_info = dump->GetBreakpadInfo();
@@ -156,7 +156,7 @@
       return PROCESS_ERROR_GETTING_THREAD;
     }
 
-    u_int32_t thread_id;
+    uint32_t thread_id;
     if (!thread->GetThreadID(&thread_id)) {
       BPLOG(ERROR) << "Could not get thread ID for " << thread_string;
       return PROCESS_ERROR_GETTING_THREAD_ID;
@@ -227,9 +227,10 @@
 
     scoped_ptr<CallStack> stack(new CallStack());
     if (stackwalker.get()) {
-      if (!stackwalker->Walk(stack.get())) {
-        BPLOG(INFO) << "Stackwalker interrupt (missing symbols?) at " <<
-          thread_string;
+      if (!stackwalker->Walk(stack.get(),
+                             &process_state->modules_without_symbols_)) {
+        BPLOG(INFO) << "Stackwalker interrupt (missing symbols?) at "
+                    << thread_string;
         interrupted = true;
       }
     } else {
@@ -346,6 +347,11 @@
       break;
     }
 
+    case MD_CPU_ARCHITECTURE_PPC64: {
+      info->cpu = "ppc64";
+      break;
+    }
+
     case MD_CPU_ARCHITECTURE_SPARC: {
       info->cpu = "sparc";
       break;
@@ -450,7 +456,7 @@
 }
 
 // static
-string MinidumpProcessor::GetCrashReason(Minidump *dump, u_int64_t *address) {
+string MinidumpProcessor::GetCrashReason(Minidump *dump, uint64_t *address) {
   MinidumpException *exception = dump->GetException();
   if (!exception)
     return "";
@@ -467,8 +473,8 @@
   // map the codes to a string (because there's no system info, or because
   // it's an unrecognized platform, or because it's an unrecognized code.)
   char reason_string[24];
-  u_int32_t exception_code = raw_exception->exception_record.exception_code;
-  u_int32_t exception_flags = raw_exception->exception_record.exception_flags;
+  uint32_t exception_code = raw_exception->exception_record.exception_code;
+  uint32_t exception_flags = raw_exception->exception_record.exception_flags;
   snprintf(reason_string, sizeof(reason_string), "0x%08x / 0x%08x",
            exception_code, exception_flags);
   string reason = reason_string;
diff --git a/src/processor/minidump_processor_unittest.cc b/src/processor/minidump_processor_unittest.cc
index 917caaf..562c0f9 100644
--- a/src/processor/minidump_processor_unittest.cc
+++ b/src/processor/minidump_processor_unittest.cc
@@ -39,6 +39,7 @@
 #include <utility>
 
 #include "breakpad_googletest_includes.h"
+#include "common/scoped_ptr.h"
 #include "common/using_std_string.h"
 #include "google_breakpad/processor/basic_source_line_resolver.h"
 #include "google_breakpad/processor/call_stack.h"
@@ -50,7 +51,6 @@
 #include "google_breakpad/processor/stack_frame.h"
 #include "google_breakpad/processor/symbol_supplier.h"
 #include "processor/logging.h"
-#include "processor/scoped_ptr.h"
 #include "processor/stackwalker_unittest_utils.h"
 
 using std::map;
@@ -84,7 +84,7 @@
  public:
   MockMinidumpThread() : MinidumpThread(NULL) {}
 
-  MOCK_CONST_METHOD1(GetThreadID, bool(u_int32_t*));
+  MOCK_CONST_METHOD1(GetThreadID, bool(uint32_t*));
   MOCK_METHOD0(GetContext, MinidumpContext*());
   MOCK_METHOD0(GetMemory, MinidumpMemoryRegion*());
 };
@@ -93,24 +93,24 @@
 // MinidumpMemoryRegion.
 class MockMinidumpMemoryRegion : public MinidumpMemoryRegion {
  public:
-  MockMinidumpMemoryRegion(u_int64_t base, const string& contents) :
+  MockMinidumpMemoryRegion(uint64_t base, const string& contents) :
       MinidumpMemoryRegion(NULL) {
     region_.Init(base, contents);
   }
 
-  u_int64_t GetBase() const { return region_.GetBase(); }
-  u_int32_t GetSize() const { return region_.GetSize(); }
+  uint64_t GetBase() const { return region_.GetBase(); }
+  uint32_t GetSize() const { return region_.GetSize(); }
 
-  bool GetMemoryAtAddress(u_int64_t address, u_int8_t  *value) const {
+  bool GetMemoryAtAddress(uint64_t address, uint8_t  *value) const {
     return region_.GetMemoryAtAddress(address, value);
   }
-  bool GetMemoryAtAddress(u_int64_t address, u_int16_t *value) const {
+  bool GetMemoryAtAddress(uint64_t address, uint16_t *value) const {
     return region_.GetMemoryAtAddress(address, value);
   }
-  bool GetMemoryAtAddress(u_int64_t address, u_int32_t *value) const {
+  bool GetMemoryAtAddress(uint64_t address, uint32_t *value) const {
     return region_.GetMemoryAtAddress(address, value);
   }
-  bool GetMemoryAtAddress(u_int64_t address, u_int64_t *value) const {
+  bool GetMemoryAtAddress(uint64_t address, uint64_t *value) const {
     return region_.GetMemoryAtAddress(address, value);
   }
 
@@ -475,7 +475,7 @@
   memset(&no_memory_thread_raw_context, 0,
          sizeof(no_memory_thread_raw_context));
   no_memory_thread_raw_context.context_flags = MD_CONTEXT_X86_FULL;
-  const u_int32_t kExpectedEIP = 0xabcd1234;
+  const uint32_t kExpectedEIP = 0xabcd1234;
   no_memory_thread_raw_context.eip = kExpectedEIP;
   TestMinidumpContext no_memory_thread_context(no_memory_thread_raw_context);
   EXPECT_CALL(no_memory_thread, GetContext()).
diff --git a/src/processor/minidump_stackwalk.cc b/src/processor/minidump_stackwalk.cc
index b3137d9..6bf78ac 100644
--- a/src/processor/minidump_stackwalk.cc
+++ b/src/processor/minidump_stackwalk.cc
@@ -39,6 +39,7 @@
 #include <string>
 #include <vector>
 
+#include "common/scoped_ptr.h"
 #include "common/using_std_string.h"
 #include "google_breakpad/processor/basic_source_line_resolver.h"
 #include "google_breakpad/processor/call_stack.h"
@@ -50,7 +51,6 @@
 #include "google_breakpad/processor/stack_frame_cpu.h"
 #include "processor/logging.h"
 #include "processor/pathname_stripper.h"
-#include "processor/scoped_ptr.h"
 #include "processor/simple_symbol_supplier.h"
 
 namespace {
@@ -84,7 +84,7 @@
 // of registers is completely printed, regardless of the number of calls
 // to PrintRegister.
 static const int kMaxWidth = 80;  // optimize for an 80-column terminal
-static int PrintRegister(const char *name, u_int32_t value, int start_col) {
+static int PrintRegister(const char *name, uint32_t value, int start_col) {
   char buffer[64];
   snprintf(buffer, sizeof(buffer), " %5s = 0x%08x", name, value);
 
@@ -98,7 +98,7 @@
 }
 
 // PrintRegister64 does the same thing, but for 64-bit registers.
-static int PrintRegister64(const char *name, u_int64_t value, int start_col) {
+static int PrintRegister64(const char *name, uint64_t value, int start_col) {
   char buffer[64];
   snprintf(buffer, sizeof(buffer), " %5s = 0x%016" PRIx64 , name, value);
 
@@ -144,6 +144,8 @@
     const StackFrame *frame = stack->frames()->at(frame_index);
     printf("%2d  ", frame_index);
 
+    uint64_t instruction_address = frame->ReturnAddress();
+
     if (frame->module) {
       printf("%s", PathnameStripper::File(frame->module->code_file()).c_str());
       if (!frame->function_name.empty()) {
@@ -153,16 +155,16 @@
           printf(" [%s : %d + 0x%" PRIx64 "]",
                  source_file.c_str(),
                  frame->source_line,
-                 frame->instruction - frame->source_line_base);
+                 instruction_address - frame->source_line_base);
         } else {
-          printf(" + 0x%" PRIx64, frame->instruction - frame->function_base);
+          printf(" + 0x%" PRIx64, instruction_address - frame->function_base);
         }
       } else {
         printf(" + 0x%" PRIx64,
-               frame->instruction - frame->module->base_address());
+               instruction_address - frame->module->base_address());
       }
     } else {
-      printf("0x%" PRIx64, frame->instruction);
+      printf("0x%" PRIx64, instruction_address);
     }
     printf("\n ");
 
@@ -231,6 +233,17 @@
       const StackFrameARM *frame_arm =
         reinterpret_cast<const StackFrameARM*>(frame);
 
+      // Argument registers (caller-saves), which will likely only be valid
+      // for the youngest frame.
+      if (frame_arm->context_validity & StackFrameARM::CONTEXT_VALID_R0)
+        sequence = PrintRegister("r0", frame_arm->context.iregs[0], sequence);
+      if (frame_arm->context_validity & StackFrameARM::CONTEXT_VALID_R1)
+        sequence = PrintRegister("r1", frame_arm->context.iregs[1], sequence);
+      if (frame_arm->context_validity & StackFrameARM::CONTEXT_VALID_R2)
+        sequence = PrintRegister("r2", frame_arm->context.iregs[2], sequence);
+      if (frame_arm->context_validity & StackFrameARM::CONTEXT_VALID_R3)
+        sequence = PrintRegister("r3", frame_arm->context.iregs[3], sequence);
+
       // General-purpose callee-saves registers.
       if (frame_arm->context_validity & StackFrameARM::CONTEXT_VALID_R4)
         sequence = PrintRegister("r4", frame_arm->context.iregs[4], sequence);
@@ -275,6 +288,8 @@
     printf("%d%c%d%c", thread_num, kOutputSeparator, frame_index,
            kOutputSeparator);
 
+    uint64_t instruction_address = frame->ReturnAddress();
+
     if (frame->module) {
       assert(!frame->module->code_file().empty());
       printf("%s", StripSeparator(PathnameStripper::File(
@@ -289,13 +304,13 @@
                  kOutputSeparator,
                  frame->source_line,
                  kOutputSeparator,
-                 frame->instruction - frame->source_line_base);
+                 instruction_address - frame->source_line_base);
         } else {
           printf("%c%c%c0x%" PRIx64,
                  kOutputSeparator,  // empty source file
                  kOutputSeparator,  // empty source line
                  kOutputSeparator,
-                 frame->instruction - frame->function_base);
+                 instruction_address - frame->function_base);
         }
       } else {
         printf("%c%c%c%c0x%" PRIx64,
@@ -303,7 +318,7 @@
                kOutputSeparator,  // empty source file
                kOutputSeparator,  // empty source line
                kOutputSeparator,
-               frame->instruction - frame->module->base_address());
+               instruction_address - frame->module->base_address());
       }
     } else {
       // the printf before this prints a trailing separator for module name
@@ -312,20 +327,64 @@
              kOutputSeparator,  // empty source file
              kOutputSeparator,  // empty source line
              kOutputSeparator,
-             frame->instruction);
+             instruction_address);
     }
     printf("\n");
   }
 }
 
-static void PrintModules(const CodeModules *modules) {
+// ContainsModule checks whether a given |module| is in the vector
+// |modules_without_symbols|.
+static bool ContainsModule(
+    const vector<const CodeModule*> *modules,
+    const CodeModule *module) {
+  assert(modules);
+  assert(module);
+  vector<const CodeModule*>::const_iterator iter;
+  for (iter = modules->begin(); iter != modules->end(); ++iter) {
+    if (module->debug_file().compare((*iter)->debug_file()) == 0 &&
+        module->debug_identifier().compare((*iter)->debug_identifier()) == 0) {
+      return true;
+    }
+  }
+  return false;
+}
+
+// PrintModule prints a single |module| to stdout.
+// |modules_without_symbols| should contain the list of modules that were
+// confirmed to be missing their symbols during the stack walk.
+static void PrintModule(
+    const CodeModule *module,
+    const vector<const CodeModule*> *modules_without_symbols,
+    uint64_t main_address) {
+  string missing_symbols;
+  if (ContainsModule(modules_without_symbols, module)) {
+    missing_symbols = "  (WARNING: No symbols, " +
+        PathnameStripper::File(module->debug_file()) + ", " +
+        module->debug_identifier() + ")";
+  }
+  uint64_t base_address = module->base_address();
+  printf("0x%08" PRIx64 " - 0x%08" PRIx64 "  %s  %s%s%s\n",
+         base_address, base_address + module->size() - 1,
+         PathnameStripper::File(module->code_file()).c_str(),
+         module->version().empty() ? "???" : module->version().c_str(),
+         main_address != 0 && base_address == main_address ? "  (main)" : "",
+         missing_symbols.c_str());
+}
+
+// PrintModules prints the list of all loaded |modules| to stdout.
+// |modules_without_symbols| should contain the list of modules that were
+// confirmed to be missing their symbols during the stack walk.
+static void PrintModules(
+    const CodeModules *modules,
+    const vector<const CodeModule*> *modules_without_symbols) {
   if (!modules)
     return;
 
   printf("\n");
   printf("Loaded modules:\n");
 
-  u_int64_t main_address = 0;
+  uint64_t main_address = 0;
   const CodeModule *main_module = modules->GetMainModule();
   if (main_module) {
     main_address = main_module->base_address();
@@ -336,13 +395,7 @@
        module_sequence < module_count;
        ++module_sequence) {
     const CodeModule *module = modules->GetModuleAtSequence(module_sequence);
-    u_int64_t base_address = module->base_address();
-    printf("0x%08" PRIx64 " - 0x%08" PRIx64 "  %s  %s%s\n",
-           base_address, base_address + module->size() - 1,
-           PathnameStripper::File(module->code_file()).c_str(),
-           module->version().empty() ? "???" : module->version().c_str(),
-           main_module != NULL && base_address == main_address ?
-               "  (main)" : "");
+    PrintModule(module, modules_without_symbols, main_address);
   }
 }
 
@@ -355,7 +408,7 @@
   if (!modules)
     return;
 
-  u_int64_t main_address = 0;
+  uint64_t main_address = 0;
   const CodeModule *main_module = modules->GetMainModule();
   if (main_module) {
     main_address = main_module->base_address();
@@ -366,7 +419,7 @@
        module_sequence < module_count;
        ++module_sequence) {
     const CodeModule *module = modules->GetModuleAtSequence(module_sequence);
-    u_int64_t base_address = module->base_address();
+    uint64_t base_address = module->base_address();
     printf("Module%c%s%c%s%c%s%c%s%c0x%08" PRIx64 "%c0x%08" PRIx64 "%c%d\n",
            kOutputSeparator,
            StripSeparator(PathnameStripper::File(module->code_file())).c_str(),
@@ -434,7 +487,8 @@
     }
   }
 
-  PrintModules(process_state.modules());
+  PrintModules(process_state.modules(),
+               process_state.modules_without_symbols());
 }
 
 static void PrintProcessStateMachineReadable(const ProcessState& process_state)
diff --git a/src/processor/minidump_unittest.cc b/src/processor/minidump_unittest.cc
index 1faf169..d16bbc6 100644
--- a/src/processor/minidump_unittest.cc
+++ b/src/processor/minidump_unittest.cc
@@ -89,7 +89,7 @@
   ASSERT_TRUE(minidump.Read());
   const MDRawHeader* header = minidump.header();
   ASSERT_NE(header, (MDRawHeader*)NULL);
-  ASSERT_EQ(header->signature, u_int32_t(MD_HEADER_SIGNATURE));
+  ASSERT_EQ(header->signature, uint32_t(MD_HEADER_SIGNATURE));
   //TODO: add more checks here
 }
 
@@ -115,7 +115,7 @@
   ASSERT_TRUE(minidump.Read());
   const MDRawHeader* header = minidump.header();
   ASSERT_NE(header, (MDRawHeader*)NULL);
-  ASSERT_EQ(header->signature, u_int32_t(MD_HEADER_SIGNATURE));
+  ASSERT_EQ(header->signature, uint32_t(MD_HEADER_SIGNATURE));
   //TODO: add more checks here
 }
 
@@ -159,7 +159,7 @@
   ASSERT_TRUE(dir != NULL);
   EXPECT_EQ(0xfbb7fa2bU, dir->stream_type);
 
-  u_int32_t stream_length;
+  uint32_t stream_length;
   ASSERT_TRUE(minidump.SeekToStreamType(0xfbb7fa2bU, &stream_length));
   ASSERT_EQ(15U, stream_length);
   char stream_contents[15];
@@ -193,7 +193,7 @@
 
   const MDRawDirectory *dir = minidump.GetDirectoryEntryAtIndex(0);
   ASSERT_TRUE(dir != NULL);
-  EXPECT_EQ((u_int32_t) MD_MEMORY_LIST_STREAM, dir->stream_type);
+  EXPECT_EQ((uint32_t) MD_MEMORY_LIST_STREAM, dir->stream_type);
 
   MinidumpMemoryList *memory_list = minidump.GetMemoryList();
   ASSERT_TRUE(memory_list != NULL);
@@ -202,7 +202,7 @@
   MinidumpMemoryRegion *region1 = memory_list->GetMemoryRegionAtIndex(0);
   ASSERT_EQ(0x309d68010bd21b2cULL, region1->GetBase());
   ASSERT_EQ(15U, region1->GetSize());
-  const u_int8_t *region1_bytes = region1->GetMemory();
+  const uint8_t *region1_bytes = region1->GetMemory();
   ASSERT_TRUE(memcmp("memory contents", region1_bytes, 15) == 0);
 }
 
@@ -213,7 +213,7 @@
   stack.Append("stack for thread");
 
   MDRawContextX86 raw_context;
-  const u_int32_t kExpectedEIP = 0x6913f540;
+  const uint32_t kExpectedEIP = 0x6913f540;
   raw_context.context_flags = MD_CONTEXT_X86_INTEGER | MD_CONTEXT_X86_CONTROL;
   raw_context.edi = 0x3ecba80d;
   raw_context.esi = 0x382583b9;
@@ -252,7 +252,7 @@
   MinidumpMemoryRegion *md_region = md_memory_list->GetMemoryRegionAtIndex(0);
   ASSERT_EQ(0x2326a0faU, md_region->GetBase());
   ASSERT_EQ(16U, md_region->GetSize());
-  const u_int8_t *region_bytes = md_region->GetMemory();
+  const uint8_t *region_bytes = md_region->GetMemory();
   ASSERT_TRUE(memcmp("stack for thread", region_bytes, 16) == 0);
 
   MinidumpThreadList *thread_list = minidump.GetThreadList();
@@ -261,27 +261,27 @@
 
   MinidumpThread *md_thread = thread_list->GetThreadAtIndex(0);
   ASSERT_TRUE(md_thread != NULL);
-  u_int32_t thread_id;
+  uint32_t thread_id;
   ASSERT_TRUE(md_thread->GetThreadID(&thread_id));
   ASSERT_EQ(0xa898f11bU, thread_id);
   MinidumpMemoryRegion *md_stack = md_thread->GetMemory();
   ASSERT_TRUE(md_stack != NULL);
   ASSERT_EQ(0x2326a0faU, md_stack->GetBase());
   ASSERT_EQ(16U, md_stack->GetSize());
-  const u_int8_t *md_stack_bytes = md_stack->GetMemory();
+  const uint8_t *md_stack_bytes = md_stack->GetMemory();
   ASSERT_TRUE(memcmp("stack for thread", md_stack_bytes, 16) == 0);
 
   MinidumpContext *md_context = md_thread->GetContext();
   ASSERT_TRUE(md_context != NULL);
-  ASSERT_EQ((u_int32_t) MD_CONTEXT_X86, md_context->GetContextCPU());
+  ASSERT_EQ((uint32_t) MD_CONTEXT_X86, md_context->GetContextCPU());
 
-  u_int64_t eip;
+  uint64_t eip;
   ASSERT_TRUE(md_context->GetInstructionPointer(&eip));
   EXPECT_EQ(kExpectedEIP, eip);
 
   const MDRawContextX86 *md_raw_context = md_context->GetContextX86();
   ASSERT_TRUE(md_raw_context != NULL);
-  ASSERT_EQ((u_int32_t) (MD_CONTEXT_X86_INTEGER | MD_CONTEXT_X86_CONTROL),
+  ASSERT_EQ((uint32_t) (MD_CONTEXT_X86_INTEGER | MD_CONTEXT_X86_CONTROL),
             (md_raw_context->context_flags
              & (MD_CONTEXT_X86_INTEGER | MD_CONTEXT_X86_CONTROL)));
   EXPECT_EQ(0x3ecba80dU, raw_context.edi);
@@ -332,7 +332,7 @@
   MinidumpThread* md_thread = thread_list->GetThreadAtIndex(0);
   ASSERT_TRUE(md_thread != NULL);
 
-  u_int32_t thread_id;
+  uint32_t thread_id;
   ASSERT_TRUE(md_thread->GetThreadID(&thread_id));
   ASSERT_EQ(0xa898f11bU, thread_id);
 
@@ -375,7 +375,7 @@
   MinidumpThread* md_thread = thread_list->GetThreadAtIndex(0);
   ASSERT_TRUE(md_thread != NULL);
 
-  u_int32_t thread_id;
+  uint32_t thread_id;
   ASSERT_TRUE(md_thread->GetThreadID(&thread_id));
   ASSERT_EQ(0xa898f11bU, thread_id);
   MinidumpMemoryRegion* md_stack = md_thread->GetMemory();
@@ -424,7 +424,7 @@
 
   const MDRawDirectory *dir = minidump.GetDirectoryEntryAtIndex(0);
   ASSERT_TRUE(dir != NULL);
-  EXPECT_EQ((u_int32_t) MD_MODULE_LIST_STREAM, dir->stream_type);
+  EXPECT_EQ((uint32_t) MD_MODULE_LIST_STREAM, dir->stream_type);
 
   MinidumpModuleList *md_module_list = minidump.GetModuleList();
   ASSERT_TRUE(md_module_list != NULL);
@@ -462,7 +462,7 @@
 
   const MDRawDirectory *dir = minidump.GetDirectoryEntryAtIndex(0);
   ASSERT_TRUE(dir != NULL);
-  EXPECT_EQ((u_int32_t) MD_SYSTEM_INFO_STREAM, dir->stream_type);
+  EXPECT_EQ((uint32_t) MD_SYSTEM_INFO_STREAM, dir->stream_type);
 
   MinidumpSystemInfo *md_system_info = minidump.GetSystemInfo();
   ASSERT_TRUE(md_system_info != NULL);
@@ -576,7 +576,7 @@
   MinidumpThreadList *thread_list = minidump.GetThreadList();
   ASSERT_TRUE(thread_list != NULL);
   ASSERT_EQ(5U, thread_list->thread_count());
-  u_int32_t thread_id;
+  uint32_t thread_id;
   ASSERT_TRUE(thread_list->GetThreadAtIndex(0)->GetThreadID(&thread_id));
   ASSERT_EQ(0xbbef4432U, thread_id);
   ASSERT_EQ(0x70b9ebfcU,
@@ -634,15 +634,15 @@
   Stream stream(dump, MD_MEMORY_INFO_LIST_STREAM);
 
   // Add the MDRawMemoryInfoList header.
-  const u_int64_t kNumberOfEntries = 1;
+  const uint64_t kNumberOfEntries = 1;
   stream.D32(sizeof(MDRawMemoryInfoList))  // size_of_header
         .D32(sizeof(MDRawMemoryInfo))      // size_of_entry
         .D64(kNumberOfEntries);            // number_of_entries
 
   
   // Now add a MDRawMemoryInfo entry.
-  const u_int64_t kBaseAddress = 0x1000;
-  const u_int64_t kRegionSize = 0x2000;
+  const uint64_t kBaseAddress = 0x1000;
+  const uint64_t kRegionSize = 0x2000;
   stream.D64(kBaseAddress)                         // base_address
         .D64(kBaseAddress)                         // allocation_base
         .D32(MD_MEMORY_PROTECT_EXECUTE_READWRITE)  // allocation_protection
@@ -665,7 +665,7 @@
 
   const MDRawDirectory *dir = minidump.GetDirectoryEntryAtIndex(0);
   ASSERT_TRUE(dir != NULL);
-  EXPECT_EQ((u_int32_t) MD_MEMORY_INFO_LIST_STREAM, dir->stream_type);
+  EXPECT_EQ((uint32_t) MD_MEMORY_INFO_LIST_STREAM, dir->stream_type);
 
   MinidumpMemoryInfoList *info_list = minidump.GetMemoryInfoList();
   ASSERT_TRUE(info_list != NULL);
@@ -724,7 +724,7 @@
   MinidumpException *md_exception = minidump.GetException();
   ASSERT_TRUE(md_exception != NULL);
 
-  u_int32_t thread_id;
+  uint32_t thread_id;
   ASSERT_TRUE(md_exception->GetThreadID(&thread_id));
   ASSERT_EQ(0x1234abcdU, thread_id);
 
@@ -737,10 +737,10 @@
 
   MinidumpContext *md_context = md_exception->GetContext();
   ASSERT_TRUE(md_context != NULL);
-  ASSERT_EQ((u_int32_t) MD_CONTEXT_X86, md_context->GetContextCPU());
+  ASSERT_EQ((uint32_t) MD_CONTEXT_X86, md_context->GetContextCPU());
   const MDRawContextX86 *md_raw_context = md_context->GetContextX86();
   ASSERT_TRUE(md_raw_context != NULL);
-  ASSERT_EQ((u_int32_t) (MD_CONTEXT_X86_INTEGER | MD_CONTEXT_X86_CONTROL),
+  ASSERT_EQ((uint32_t) (MD_CONTEXT_X86_INTEGER | MD_CONTEXT_X86_CONTROL),
             (md_raw_context->context_flags
              & (MD_CONTEXT_X86_INTEGER | MD_CONTEXT_X86_CONTROL)));
   EXPECT_EQ(0x3ecba80dU, raw_context.edi);
@@ -798,7 +798,7 @@
   MinidumpException *md_exception = minidump.GetException();
   ASSERT_TRUE(md_exception != NULL);
 
-  u_int32_t thread_id;
+  uint32_t thread_id;
   ASSERT_TRUE(md_exception->GetThreadID(&thread_id));
   ASSERT_EQ(0x1234abcdU, thread_id);
 
@@ -811,10 +811,10 @@
 
   MinidumpContext *md_context = md_exception->GetContext();
   ASSERT_TRUE(md_context != NULL);
-  ASSERT_EQ((u_int32_t) MD_CONTEXT_X86, md_context->GetContextCPU());
+  ASSERT_EQ((uint32_t) MD_CONTEXT_X86, md_context->GetContextCPU());
   const MDRawContextX86 *md_raw_context = md_context->GetContextX86();
   ASSERT_TRUE(md_raw_context != NULL);
-  ASSERT_EQ((u_int32_t) (MD_CONTEXT_X86_INTEGER | MD_CONTEXT_X86_CONTROL),
+  ASSERT_EQ((uint32_t) (MD_CONTEXT_X86_INTEGER | MD_CONTEXT_X86_CONTROL),
             (md_raw_context->context_flags
              & (MD_CONTEXT_X86_INTEGER | MD_CONTEXT_X86_CONTROL)));
   EXPECT_EQ(0x3ecba80dU, raw_context.edi);
@@ -831,6 +831,158 @@
   EXPECT_EQ(0x2e951ef7U, raw_context.ss);
 }
 
+// Testing that the CPU type can be loaded from a system info stream when
+// the CPU flags are missing from the context_flags of an exception record
+TEST(Dump, OneExceptionX86NoCPUFlags) {
+  Dump dump(0, kLittleEndian);
+
+  MDRawContextX86 raw_context;
+  // Intentionally not setting CPU type in the context_flags
+  raw_context.context_flags = 0;
+  raw_context.edi = 0x3ecba80d;
+  raw_context.esi = 0x382583b9;
+  raw_context.ebx = 0x7fccc03f;
+  raw_context.edx = 0xf62f8ec2;
+  raw_context.ecx = 0x46a6a6a8;
+  raw_context.eax = 0x6a5025e2;
+  raw_context.ebp = 0xd9fabb4a;
+  raw_context.eip = 0x6913f540;
+  raw_context.cs = 0xbffe6eda;
+  raw_context.eflags = 0xb2ce1e2d;
+  raw_context.esp = 0x659caaa4;
+  raw_context.ss = 0x2e951ef7;
+  Context context(dump, raw_context);
+
+  Exception exception(dump, context,
+                      0x1234abcd, // thread id
+                      0xdcba4321, // exception code
+                      0xf0e0d0c0, // exception flags
+                      0x0919a9b9c9d9e9f9ULL); // exception address
+  
+  dump.Add(&context);
+  dump.Add(&exception);
+
+  // Add system info.  This is needed as an alternative source for CPU type
+  // information.  Note, that the CPU flags were intentionally skipped from
+  // the context_flags and this alternative source is required.
+  String csd_version(dump, "Service Pack 2");
+  SystemInfo system_info(dump, SystemInfo::windows_x86, csd_version);
+  dump.Add(&system_info);
+  dump.Add(&csd_version);
+
+  dump.Finish();
+
+  string contents;
+  ASSERT_TRUE(dump.GetContents(&contents));
+
+  istringstream minidump_stream(contents);
+  Minidump minidump(minidump_stream);
+  ASSERT_TRUE(minidump.Read());
+  ASSERT_EQ(2U, minidump.GetDirectoryEntryCount());
+
+  MinidumpException *md_exception = minidump.GetException();
+  ASSERT_TRUE(md_exception != NULL);
+
+  uint32_t thread_id;
+  ASSERT_TRUE(md_exception->GetThreadID(&thread_id));
+  ASSERT_EQ(0x1234abcdU, thread_id);
+
+  const MDRawExceptionStream* raw_exception = md_exception->exception();
+  ASSERT_TRUE(raw_exception != NULL);
+  EXPECT_EQ(0xdcba4321, raw_exception->exception_record.exception_code);
+  EXPECT_EQ(0xf0e0d0c0, raw_exception->exception_record.exception_flags);
+  EXPECT_EQ(0x0919a9b9c9d9e9f9ULL,
+            raw_exception->exception_record.exception_address);
+
+  MinidumpContext *md_context = md_exception->GetContext();
+  ASSERT_TRUE(md_context != NULL);
+
+  ASSERT_EQ((uint32_t) MD_CONTEXT_X86, md_context->GetContextCPU());
+  const MDRawContextX86 *md_raw_context = md_context->GetContextX86();
+  ASSERT_TRUE(md_raw_context != NULL);
+
+  // Even though the CPU flags were missing from the context_flags, the
+  // GetContext call above is expected to load the missing CPU flags from the
+  // system info stream and set the CPU type bits in context_flags.
+  ASSERT_EQ((uint32_t) (MD_CONTEXT_X86), md_raw_context->context_flags);
+
+  EXPECT_EQ(0x3ecba80dU, raw_context.edi);
+  EXPECT_EQ(0x382583b9U, raw_context.esi);
+  EXPECT_EQ(0x7fccc03fU, raw_context.ebx);
+  EXPECT_EQ(0xf62f8ec2U, raw_context.edx);
+  EXPECT_EQ(0x46a6a6a8U, raw_context.ecx);
+  EXPECT_EQ(0x6a5025e2U, raw_context.eax);
+  EXPECT_EQ(0xd9fabb4aU, raw_context.ebp);
+  EXPECT_EQ(0x6913f540U, raw_context.eip);
+  EXPECT_EQ(0xbffe6edaU, raw_context.cs);
+  EXPECT_EQ(0xb2ce1e2dU, raw_context.eflags);
+  EXPECT_EQ(0x659caaa4U, raw_context.esp);
+  EXPECT_EQ(0x2e951ef7U, raw_context.ss);
+}
+
+// This test covers a scenario where a dump contains an exception but the
+// context record of the exception is missing the CPU type information in its
+// context_flags.  The dump has no system info stream so it is imposible to
+// deduce the CPU type, hence the context record is unusable.
+TEST(Dump, OneExceptionX86NoCPUFlagsNoSystemInfo) {
+  Dump dump(0, kLittleEndian);
+
+  MDRawContextX86 raw_context;
+  // Intentionally not setting CPU type in the context_flags
+  raw_context.context_flags = 0;
+  raw_context.edi = 0x3ecba80d;
+  raw_context.esi = 0x382583b9;
+  raw_context.ebx = 0x7fccc03f;
+  raw_context.edx = 0xf62f8ec2;
+  raw_context.ecx = 0x46a6a6a8;
+  raw_context.eax = 0x6a5025e2;
+  raw_context.ebp = 0xd9fabb4a;
+  raw_context.eip = 0x6913f540;
+  raw_context.cs = 0xbffe6eda;
+  raw_context.eflags = 0xb2ce1e2d;
+  raw_context.esp = 0x659caaa4;
+  raw_context.ss = 0x2e951ef7;
+  Context context(dump, raw_context);
+
+  Exception exception(dump, context,
+                      0x1234abcd, // thread id
+                      0xdcba4321, // exception code
+                      0xf0e0d0c0, // exception flags
+                      0x0919a9b9c9d9e9f9ULL); // exception address
+  
+  dump.Add(&context);
+  dump.Add(&exception);
+  dump.Finish();
+
+  string contents;
+  ASSERT_TRUE(dump.GetContents(&contents));
+
+  istringstream minidump_stream(contents);
+  Minidump minidump(minidump_stream);
+  ASSERT_TRUE(minidump.Read());
+  ASSERT_EQ(1U, minidump.GetDirectoryEntryCount());
+
+  MinidumpException *md_exception = minidump.GetException();
+  ASSERT_TRUE(md_exception != NULL);
+
+  uint32_t thread_id;
+  ASSERT_TRUE(md_exception->GetThreadID(&thread_id));
+  ASSERT_EQ(0x1234abcdU, thread_id);
+
+  const MDRawExceptionStream* raw_exception = md_exception->exception();
+  ASSERT_TRUE(raw_exception != NULL);
+  EXPECT_EQ(0xdcba4321, raw_exception->exception_record.exception_code);
+  EXPECT_EQ(0xf0e0d0c0, raw_exception->exception_record.exception_flags);
+  EXPECT_EQ(0x0919a9b9c9d9e9f9ULL,
+            raw_exception->exception_record.exception_address);
+
+  // The context record of the exception is unusable because the context_flags
+  // don't have CPU type information and at the same time the minidump lacks
+  // system info stream so it is impossible to deduce the CPU type.
+  MinidumpContext *md_context = md_exception->GetContext();
+  ASSERT_EQ(NULL, md_context);
+}
+
 TEST(Dump, OneExceptionARM) {
   Dump dump(0, kLittleEndian);
 
@@ -876,7 +1028,7 @@
   MinidumpException *md_exception = minidump.GetException();
   ASSERT_TRUE(md_exception != NULL);
 
-  u_int32_t thread_id;
+  uint32_t thread_id;
   ASSERT_TRUE(md_exception->GetThreadID(&thread_id));
   ASSERT_EQ(0x1234abcdU, thread_id);
 
@@ -889,10 +1041,10 @@
 
   MinidumpContext *md_context = md_exception->GetContext();
   ASSERT_TRUE(md_context != NULL);
-  ASSERT_EQ((u_int32_t) MD_CONTEXT_ARM, md_context->GetContextCPU());
+  ASSERT_EQ((uint32_t) MD_CONTEXT_ARM, md_context->GetContextCPU());
   const MDRawContextARM *md_raw_context = md_context->GetContextARM();
   ASSERT_TRUE(md_raw_context != NULL);
-  ASSERT_EQ((u_int32_t) MD_CONTEXT_ARM_INTEGER,
+  ASSERT_EQ((uint32_t) MD_CONTEXT_ARM_INTEGER,
             (md_raw_context->context_flags
              & MD_CONTEXT_ARM_INTEGER));
   EXPECT_EQ(0x3ecba80dU, raw_context.iregs[0]);
@@ -960,7 +1112,7 @@
   MinidumpException *md_exception = minidump.GetException();
   ASSERT_TRUE(md_exception != NULL);
 
-  u_int32_t thread_id;
+  uint32_t thread_id;
   ASSERT_TRUE(md_exception->GetThreadID(&thread_id));
   ASSERT_EQ(0x1234abcdU, thread_id);
 
@@ -973,10 +1125,10 @@
 
   MinidumpContext *md_context = md_exception->GetContext();
   ASSERT_TRUE(md_context != NULL);
-  ASSERT_EQ((u_int32_t) MD_CONTEXT_ARM, md_context->GetContextCPU());
+  ASSERT_EQ((uint32_t) MD_CONTEXT_ARM, md_context->GetContextCPU());
   const MDRawContextARM *md_raw_context = md_context->GetContextARM();
   ASSERT_TRUE(md_raw_context != NULL);
-  ASSERT_EQ((u_int32_t) MD_CONTEXT_ARM_INTEGER,
+  ASSERT_EQ((uint32_t) MD_CONTEXT_ARM_INTEGER,
             (md_raw_context->context_flags
              & MD_CONTEXT_ARM_INTEGER));
   EXPECT_EQ(0x3ecba80dU, raw_context.iregs[0]);
diff --git a/src/processor/module_comparer.cc b/src/processor/module_comparer.cc
index 09b85e0..ba561ee 100644
--- a/src/processor/module_comparer.cc
+++ b/src/processor/module_comparer.cc
@@ -37,9 +37,9 @@
 #include <map>
 #include <string>
 
+#include "common/scoped_ptr.h"
 #include "processor/basic_code_module.h"
 #include "processor/logging.h"
-#include "processor/scoped_ptr.h"
 
 #define ASSERT_TRUE(condition) \
   if (!(condition)) { \
diff --git a/src/processor/module_serializer.cc b/src/processor/module_serializer.cc
index 5c5ff77..cf64a7e 100644
--- a/src/processor/module_serializer.cc
+++ b/src/processor/module_serializer.cc
@@ -65,7 +65,7 @@
      module.cfi_delta_rules_);
 
   // Header size.
-  total_size_alloc_ = kNumberMaps_ * sizeof(u_int32_t);
+  total_size_alloc_ = kNumberMaps_ * sizeof(uint32_t);
 
   for (int i = 0; i < kNumberMaps_; ++i)
    total_size_alloc_ += map_sizes_[i];
@@ -79,8 +79,8 @@
 char *ModuleSerializer::Write(const BasicSourceLineResolver::Module &module,
                               char *dest) {
   // Write header.
-  memcpy(dest, map_sizes_, kNumberMaps_ * sizeof(u_int32_t));
-  dest += kNumberMaps_ * sizeof(u_int32_t);
+  memcpy(dest, map_sizes_, kNumberMaps_ * sizeof(uint32_t));
+  dest += kNumberMaps_ * sizeof(uint32_t);
   // Write each map.
   dest = files_serializer_.Write(module.files_, dest);
   dest = functions_serializer_.Write(module.functions_, dest);
diff --git a/src/processor/module_serializer.h b/src/processor/module_serializer.h
index 91e913b..effb009 100644
--- a/src/processor/module_serializer.h
+++ b/src/processor/module_serializer.h
@@ -110,7 +110,7 @@
       FastSourceLineResolver::Module::kNumberMaps_;
 
   // Memory sizes required to serialize map components in Module.
-  u_int32_t map_sizes_[kNumberMaps_];
+  uint32_t map_sizes_[kNumberMaps_];
 
   // Serializers for each individual map component in Module class.
   StdMapSerializer<int, string> files_serializer_;
diff --git a/src/processor/postfix_evaluator_unittest.cc b/src/processor/postfix_evaluator_unittest.cc
index 00c8fd8..516be51 100644
--- a/src/processor/postfix_evaluator_unittest.cc
+++ b/src/processor/postfix_evaluator_unittest.cc
@@ -57,21 +57,21 @@
 // the value.
 class FakeMemoryRegion : public MemoryRegion {
  public:
-  virtual u_int64_t GetBase() const { return 0; }
-  virtual u_int32_t GetSize() const { return 0; }
-  virtual bool GetMemoryAtAddress(u_int64_t address, u_int8_t  *value) const {
+  virtual uint64_t GetBase() const { return 0; }
+  virtual uint32_t GetSize() const { return 0; }
+  virtual bool GetMemoryAtAddress(uint64_t address, uint8_t  *value) const {
     *value = address + 1;
     return true;
   }
-  virtual bool GetMemoryAtAddress(u_int64_t address, u_int16_t *value) const {
+  virtual bool GetMemoryAtAddress(uint64_t address, uint16_t *value) const {
     *value = address + 1;
     return true;
   }
-  virtual bool GetMemoryAtAddress(u_int64_t address, u_int32_t *value) const {
+  virtual bool GetMemoryAtAddress(uint64_t address, uint32_t *value) const {
     *value = address + 1;
     return true;
   }
-  virtual bool GetMemoryAtAddress(u_int64_t address, u_int64_t *value) const {
+  virtual bool GetMemoryAtAddress(uint64_t address, uint64_t *value) const {
     *value = address + 1;
     return true;
   }
diff --git a/src/processor/process_state.cc b/src/processor/process_state.cc
index 1d970ba..6c3a656 100644
--- a/src/processor/process_state.cc
+++ b/src/processor/process_state.cc
@@ -57,6 +57,9 @@
   }
   threads_.clear();
   system_info_.Clear();
+  // modules_without_symbols_ DOES NOT owns the underlying CodeModule pointers.
+  // Just clear the vector.
+  modules_without_symbols_.clear();
   delete modules_;
   modules_ = NULL;
 }
diff --git a/src/processor/range_map-inl.h b/src/processor/range_map-inl.h
index 3aa2603..55dae83 100644
--- a/src/processor/range_map-inl.h
+++ b/src/processor/range_map-inl.h
@@ -72,12 +72,18 @@
     // Some other range begins in the space used by this range.  It may be
     // contained within the space used by this range, or it may extend lower.
     // Regardless, it is an error.
-    AddressType other_base = iterator_base->second.base();
-    AddressType other_size = iterator_base->first - other_base + 1;
-    BPLOG(INFO) << "StoreRange failed, an existing range is contained by or "
-                   "extends lower than the new range: new " <<
-                   HexString(base) << "+" << HexString(size) << ", existing " <<
-                   HexString(other_base) << "+" << HexString(other_size);
+    // The processor hits this case too frequently with common symbol files.
+    // This is most appropriate for a DEBUG channel, but since none exists now
+    // simply comment out this logging.
+    //
+    // AddressType other_base = iterator_base->second.base();
+    // AddressType other_size = iterator_base->first - other_base + 1;
+    // BPLOG(INFO) << "StoreRange failed, an existing range is contained by or "
+    //                "extends lower than the new range: new " <<
+    //                 HexString(base) << "+" << HexString(size) <<
+    //                 ", existing " << HexString(other_base) << "+" <<
+    //                 HexString(other_size);
+
     return false;
   }
 
@@ -86,13 +92,17 @@
       // The range above this one overlaps with this one.  It may fully
       // contain this range, or it may begin within this range and extend
       // higher.  Regardless, it's an error.
-      AddressType other_base = iterator_high->second.base();
-      AddressType other_size = iterator_high->first - other_base + 1;
-      BPLOG(INFO) << "StoreRange failed, an existing range contains or "
-                     "extends higher than the new range: new " <<
-                     HexString(base) << "+" << HexString(size) <<
-                     ", existing " <<
-                     HexString(other_base) << "+" << HexString(other_size);
+      // The processor hits this case too frequently with common symbol files.
+      // This is most appropriate for a DEBUG channel, but since none exists now
+      // simply comment out this logging.
+      //
+      // AddressType other_base = iterator_high->second.base();
+      // AddressType other_size = iterator_high->first - other_base + 1;
+      // BPLOG(INFO) << "StoreRange failed, an existing range contains or "
+      //                "extends higher than the new range: new " <<
+      //                HexString(base) << "+" << HexString(size) <<
+      //                ", existing " << HexString(other_base) << "+" <<
+      //                HexString(other_size);
       return false;
     }
   }
diff --git a/src/processor/range_map_unittest.cc b/src/processor/range_map_unittest.cc
index 996ae6d..bf9b727 100644
--- a/src/processor/range_map_unittest.cc
+++ b/src/processor/range_map_unittest.cc
@@ -37,10 +37,9 @@
 
 #include "processor/range_map-inl.h"
 
+#include "common/scoped_ptr.h"
 #include "processor/linked_ptr.h"
 #include "processor/logging.h"
-#include "processor/scoped_ptr.h"
-
 
 namespace {
 
diff --git a/src/processor/simple_serializer-inl.h b/src/processor/simple_serializer-inl.h
index 1faf5ef..6e5fe5d 100644
--- a/src/processor/simple_serializer-inl.h
+++ b/src/processor/simple_serializer-inl.h
@@ -134,12 +134,12 @@
     unsigned int size = 0;
     size += sizeof(int32_t);  // wfi.type_
     size += SimpleSerializer<int32_t>::SizeOf(wfi.valid);
-    size += SimpleSerializer<u_int32_t>::SizeOf(wfi.prolog_size);
-    size += SimpleSerializer<u_int32_t>::SizeOf(wfi.epilog_size);
-    size += SimpleSerializer<u_int32_t>::SizeOf(wfi.parameter_size);
-    size += SimpleSerializer<u_int32_t>::SizeOf(wfi.saved_register_size);
-    size += SimpleSerializer<u_int32_t>::SizeOf(wfi.local_size);
-    size += SimpleSerializer<u_int32_t>::SizeOf(wfi.max_stack_size);
+    size += SimpleSerializer<uint32_t>::SizeOf(wfi.prolog_size);
+    size += SimpleSerializer<uint32_t>::SizeOf(wfi.epilog_size);
+    size += SimpleSerializer<uint32_t>::SizeOf(wfi.parameter_size);
+    size += SimpleSerializer<uint32_t>::SizeOf(wfi.saved_register_size);
+    size += SimpleSerializer<uint32_t>::SizeOf(wfi.local_size);
+    size += SimpleSerializer<uint32_t>::SizeOf(wfi.max_stack_size);
     size += SimpleSerializer<bool>::SizeOf(wfi.allocates_base_pointer);
     size += SimpleSerializer<string>::SizeOf(wfi.program_string);
     return size;
@@ -148,12 +148,12 @@
     dest = SimpleSerializer<int32_t>::Write(
         static_cast<const int32_t>(wfi.type_), dest);
     dest = SimpleSerializer<int32_t>::Write(wfi.valid, dest);
-    dest = SimpleSerializer<u_int32_t>::Write(wfi.prolog_size, dest);
-    dest = SimpleSerializer<u_int32_t>::Write(wfi.epilog_size, dest);
-    dest = SimpleSerializer<u_int32_t>::Write(wfi.parameter_size, dest);
-    dest = SimpleSerializer<u_int32_t>::Write(wfi.saved_register_size, dest);
-    dest = SimpleSerializer<u_int32_t>::Write(wfi.local_size, dest);
-    dest = SimpleSerializer<u_int32_t>::Write(wfi.max_stack_size, dest);
+    dest = SimpleSerializer<uint32_t>::Write(wfi.prolog_size, dest);
+    dest = SimpleSerializer<uint32_t>::Write(wfi.epilog_size, dest);
+    dest = SimpleSerializer<uint32_t>::Write(wfi.parameter_size, dest);
+    dest = SimpleSerializer<uint32_t>::Write(wfi.saved_register_size, dest);
+    dest = SimpleSerializer<uint32_t>::Write(wfi.local_size, dest);
+    dest = SimpleSerializer<uint32_t>::Write(wfi.max_stack_size, dest);
     dest = SimpleSerializer<bool>::Write(wfi.allocates_base_pointer, dest);
     return SimpleSerializer<string>::Write(wfi.program_string, dest);
   }
diff --git a/src/processor/simple_serializer.h b/src/processor/simple_serializer.h
index a1ca4f3..275f51c 100644
--- a/src/processor/simple_serializer.h
+++ b/src/processor/simple_serializer.h
@@ -38,11 +38,11 @@
 #ifndef PROCESSOR_SIMPLE_SERIALIZER_H__
 #define PROCESSOR_SIMPLE_SERIALIZER_H__
 
-#include <sys/types.h>
+#include "google_breakpad/common/breakpad_types.h"
 
 namespace google_breakpad {
 
-typedef u_int64_t MemAddr;
+typedef uint64_t MemAddr;
 
 // Default implementation of SimpleSerializer template.
 // Specializations are defined in "simple_serializer-inl.h".
diff --git a/src/processor/source_line_resolver_base_types.h b/src/processor/source_line_resolver_base_types.h
index 5b099f1..1dc3d62 100644
--- a/src/processor/source_line_resolver_base_types.h
+++ b/src/processor/source_line_resolver_base_types.h
@@ -43,6 +43,7 @@
 #include <map>
 #include <string>
 
+#include "google_breakpad/common/breakpad_types.h"
 #include "google_breakpad/processor/source_line_resolver_base.h"
 #include "google_breakpad/processor/stack_frame.h"
 #include "processor/cfi_frame_info.h"
diff --git a/src/processor/stack_frame_symbolizer.cc b/src/processor/stack_frame_symbolizer.cc
index e12fccb..8e020c9 100644
--- a/src/processor/stack_frame_symbolizer.cc
+++ b/src/processor/stack_frame_symbolizer.cc
@@ -36,6 +36,7 @@
 
 #include <assert.h>
 
+#include "common/scoped_ptr.h"
 #include "google_breakpad/processor/code_module.h"
 #include "google_breakpad/processor/code_modules.h"
 #include "google_breakpad/processor/source_line_resolver_interface.h"
@@ -44,7 +45,6 @@
 #include "google_breakpad/processor/system_info.h"
 #include "processor/linked_ptr.h"
 #include "processor/logging.h"
-#include "processor/scoped_ptr.h"
 
 namespace google_breakpad {
 
@@ -59,27 +59,27 @@
     StackFrame* frame) {
   assert(frame);
 
-  if (!modules) return ERROR;
+  if (!modules) return kError;
   const CodeModule* module = modules->GetModuleForAddress(frame->instruction);
-  if (!module) return ERROR;
+  if (!module) return kError;
   frame->module = module;
 
-  if (!resolver_) return ERROR;  // no resolver.
+  if (!resolver_) return kError;  // no resolver.
   // If module is known to have missing symbol file, return.
   if (no_symbol_modules_.find(module->code_file()) !=
       no_symbol_modules_.end()) {
-    return ERROR;
+    return kError;
   }
 
   // If module is already loaded, go ahead to fill source line info and return.
   if (resolver_->HasModule(frame->module)) {
     resolver_->FillSourceLineInfo(frame);
-    return NO_ERROR;
+    return kNoError;
   }
 
   // Module needs to fetch symbol file. First check to see if supplier exists.
   if (!supplier_) {
-    return ERROR;
+    return kError;
   }
 
   // Start fetching symbol from supplier.
@@ -98,25 +98,26 @@
 
       if (load_success) {
         resolver_->FillSourceLineInfo(frame);
-        return NO_ERROR;
+        return kNoError;
       } else {
         BPLOG(ERROR) << "Failed to load symbol file in resolver.";
         no_symbol_modules_.insert(module->code_file());
-        return ERROR;
+        return kError;
       }
     }
 
     case SymbolSupplier::NOT_FOUND:
       no_symbol_modules_.insert(module->code_file());
-      return ERROR;
+      return kError;
 
     case SymbolSupplier::INTERRUPT:
-      return INTERRUPT;
+      return kInterrupt;
 
     default:
       BPLOG(ERROR) << "Unknown SymbolResult enum: " << symbol_result;
-      return ERROR;
+      return kError;
   }
+  return kError;
 }
 
 WindowsFrameInfo* StackFrameSymbolizer::FindWindowsFrameInfo(
diff --git a/src/processor/stackwalker.cc b/src/processor/stackwalker.cc
index 762c47f..076f2e5 100644
--- a/src/processor/stackwalker.cc
+++ b/src/processor/stackwalker.cc
@@ -37,6 +37,7 @@
 
 #include <assert.h>
 
+#include "common/scoped_ptr.h"
 #include "google_breakpad/processor/call_stack.h"
 #include "google_breakpad/processor/code_module.h"
 #include "google_breakpad/processor/code_modules.h"
@@ -46,8 +47,8 @@
 #include "google_breakpad/processor/system_info.h"
 #include "processor/linked_ptr.h"
 #include "processor/logging.h"
-#include "processor/scoped_ptr.h"
 #include "processor/stackwalker_ppc.h"
+#include "processor/stackwalker_ppc64.h"
 #include "processor/stackwalker_sparc.h"
 #include "processor/stackwalker_x86.h"
 #include "processor/stackwalker_amd64.h"
@@ -55,7 +56,8 @@
 
 namespace google_breakpad {
 
-u_int32_t Stackwalker::max_frames_ = 1024;
+const int Stackwalker::kRASearchWords = 30;
+uint32_t Stackwalker::max_frames_ = 1024;
 
 Stackwalker::Stackwalker(const SystemInfo* system_info,
                          MemoryRegion* memory,
@@ -69,11 +71,16 @@
 }
 
 
-bool Stackwalker::Walk(CallStack* stack) {
+bool Stackwalker::Walk(CallStack* stack,
+                       vector<const CodeModule*>* modules_without_symbols) {
   BPLOG_IF(ERROR, !stack) << "Stackwalker::Walk requires |stack|";
   assert(stack);
   stack->Clear();
 
+  BPLOG_IF(ERROR, !modules_without_symbols) << "Stackwalker::Walk requires "
+                                            << "|modules_without_symbols|";
+  assert(modules_without_symbols);
+
   // Begin with the context frame, and keep getting callers until there are
   // no more.
 
@@ -89,11 +96,32 @@
     StackFrameSymbolizer::SymbolizerResult symbolizer_result =
         frame_symbolizer_->FillSourceLineInfo(modules_, system_info_,
                                              frame.get());
-    if (symbolizer_result == StackFrameSymbolizer::INTERRUPT) {
+    if (symbolizer_result == StackFrameSymbolizer::kInterrupt) {
       BPLOG(INFO) << "Stack walk is interrupted.";
       return false;
     }
 
+    // Keep track of modules that have no symbols.
+    if (symbolizer_result == StackFrameSymbolizer::kError &&
+        frame->module != NULL) {
+      bool found = false;
+      vector<const CodeModule*>::iterator iter;
+      for (iter = modules_without_symbols->begin();
+           iter != modules_without_symbols->end();
+           ++iter) {
+        if (*iter == frame->module) {
+          found = true;
+          break;
+        }
+      }
+      if (!found) {
+        BPLOG(INFO) << "Couldn't load symbols for: "
+                    << frame->module->debug_file() << "|"
+                    << frame->module->debug_identifier();
+        modules_without_symbols->push_back(frame->module);
+      }
+    }
+
     // Add the frame to the call stack.  Relinquish the ownership claim
     // over the frame, because the stack now owns it.
     stack->frames_.push_back(frame.release());
@@ -124,7 +152,7 @@
 
   Stackwalker* cpu_stackwalker = NULL;
 
-  u_int32_t cpu = context->GetContextCPU();
+  uint32_t cpu = context->GetContextCPU();
   switch (cpu) {
     case MD_CONTEXT_X86:
       cpu_stackwalker = new StackwalkerX86(system_info,
@@ -138,6 +166,12 @@
                                            memory, modules, frame_symbolizer);
       break;
 
+    case MD_CONTEXT_PPC64:
+      cpu_stackwalker = new StackwalkerPPC64(system_info,
+                                             context->GetContextPPC64(),
+                                             memory, modules, frame_symbolizer);
+      break;
+
     case MD_CONTEXT_AMD64:
       cpu_stackwalker = new StackwalkerAMD64(system_info,
                                              context->GetContextAMD64(),
@@ -167,7 +201,7 @@
   return cpu_stackwalker;
 }
 
-bool Stackwalker::InstructionAddressSeemsValid(u_int64_t address) {
+bool Stackwalker::InstructionAddressSeemsValid(uint64_t address) {
   StackFrame frame;
   frame.instruction = address;
   StackFrameSymbolizer::SymbolizerResult symbolizer_result =
@@ -184,7 +218,7 @@
     return true;
   }
 
-  if (symbolizer_result != StackFrameSymbolizer::NO_ERROR) {
+  if (symbolizer_result != StackFrameSymbolizer::kNoError) {
     // Some error occurred during symbolization, but the address is within a
     // known module
     return true;
diff --git a/src/processor/stackwalker_amd64.cc b/src/processor/stackwalker_amd64.cc
index b7d3274..656af18 100644
--- a/src/processor/stackwalker_amd64.cc
+++ b/src/processor/stackwalker_amd64.cc
@@ -33,14 +33,15 @@
 //
 // Author: Mark Mentovai, Ted Mielczarek
 
+#include <assert.h>
 
+#include "common/scoped_ptr.h"
 #include "google_breakpad/processor/call_stack.h"
 #include "google_breakpad/processor/memory_region.h"
 #include "google_breakpad/processor/source_line_resolver_interface.h"
 #include "google_breakpad/processor/stack_frame_cpu.h"
 #include "processor/cfi_frame_info.h"
 #include "processor/logging.h"
-#include "processor/scoped_ptr.h"
 #include "processor/stackwalker_amd64.h"
 
 namespace google_breakpad {
@@ -100,6 +101,11 @@
                   (sizeof(cfi_register_map_) / sizeof(cfi_register_map_[0]))) {
 }
 
+uint64_t StackFrameAMD64::ReturnAddress() const
+{
+  assert(context_validity & StackFrameAMD64::CONTEXT_VALID_RIP);
+  return context.rip;   
+}
 
 StackFrame* StackwalkerAMD64::GetContextFrame() {
   if (!context_) {
@@ -144,8 +150,8 @@
 StackFrameAMD64* StackwalkerAMD64::GetCallerByStackScan(
     const vector<StackFrame*> &frames) {
   StackFrameAMD64* last_frame = static_cast<StackFrameAMD64*>(frames.back());
-  u_int64_t last_rsp = last_frame->context.rsp;
-  u_int64_t caller_rip_address, caller_rip;
+  uint64_t last_rsp = last_frame->context.rsp;
+  uint64_t caller_rip_address, caller_rip;
 
   if (!ScanForReturnAddress(last_rsp, &caller_rip_address, &caller_rip)) {
     // No plausible return address was found.
@@ -173,7 +179,7 @@
     // pointing to the first word below the alleged return address, presume
     // that the caller's %rbp is saved there.
     if (caller_rip_address - 8 == last_frame->context.rbp) {
-      u_int64_t caller_rbp = 0;
+      uint64_t caller_rbp = 0;
       if (memory_->GetMemoryAtAddress(last_frame->context.rbp, &caller_rbp) &&
           caller_rbp > caller_rip_address) {
         frame->context.rbp = caller_rbp;
@@ -226,14 +232,11 @@
   if (new_frame->context.rsp <= last_frame->context.rsp)
     return NULL;
 
-  // new_frame->context.rip is the return address, which is one instruction
-  // past the CALL that caused us to arrive at the callee. Set
-  // new_frame->instruction to one less than that. This won't reference the
-  // beginning of the CALL instruction, but it's guaranteed to be within
-  // the CALL, which is sufficient to get the source line information to
-  // match up with the line that contains a function call. Callers that
-  // require the exact return address value may access the context.rip
-  // field of StackFrameAMD64.
+  // new_frame->context.rip is the return address, which is the instruction
+  // after the CALL that caused us to arrive at the callee. Set
+  // new_frame->instruction to one less than that, so it points within the
+  // CALL instruction. See StackFrame::instruction for details, and
+  // StackFrameAMD64::ReturnAddress.
   new_frame->instruction = new_frame->context.rip - 1;
 
   return new_frame.release();
diff --git a/src/processor/stackwalker_amd64.h b/src/processor/stackwalker_amd64.h
index 3e41c12..3f1eaf7 100644
--- a/src/processor/stackwalker_amd64.h
+++ b/src/processor/stackwalker_amd64.h
@@ -64,7 +64,7 @@
 
  private:
   // A STACK CFI-driven frame walker for the AMD64
-  typedef SimpleCFIWalker<u_int64_t, MDRawContextAMD64> CFIWalker;
+  typedef SimpleCFIWalker<uint64_t, MDRawContextAMD64> CFIWalker;
 
   // Implementation of Stackwalker, using amd64 context (stack pointer in %rsp,
   // stack base in %rbp) and stack conventions (saved stack pointer at 0(%rbp))
diff --git a/src/processor/stackwalker_amd64_unittest.cc b/src/processor/stackwalker_amd64_unittest.cc
index 2d679ab..8faf09a 100644
--- a/src/processor/stackwalker_amd64_unittest.cc
+++ b/src/processor/stackwalker_amd64_unittest.cc
@@ -41,6 +41,7 @@
 #include "google_breakpad/common/minidump_format.h"
 #include "google_breakpad/processor/basic_source_line_resolver.h"
 #include "google_breakpad/processor/call_stack.h"
+#include "google_breakpad/processor/code_module.h"
 #include "google_breakpad/processor/source_line_resolver_interface.h"
 #include "google_breakpad/processor/stack_frame_cpu.h"
 #include "processor/stackwalker_unittest_utils.h"
@@ -48,6 +49,7 @@
 
 using google_breakpad::BasicSourceLineResolver;
 using google_breakpad::CallStack;
+using google_breakpad::CodeModule;
 using google_breakpad::StackFrameSymbolizer;
 using google_breakpad::StackFrame;
 using google_breakpad::StackFrameAMD64;
@@ -109,9 +111,9 @@
 
   // Fill RAW_CONTEXT with pseudo-random data, for round-trip checking.
   void BrandContext(MDRawContextAMD64 *raw_context) {
-    u_int8_t x = 173;
+    uint8_t x = 173;
     for (size_t i = 0; i < sizeof(*raw_context); i++)
-      reinterpret_cast<u_int8_t *>(raw_context)[i] = (x += 17);
+      reinterpret_cast<uint8_t *>(raw_context)[i] = (x += 17);
   }
 
   SystemInfo system_info;
@@ -143,7 +145,10 @@
   StackwalkerAMD64 walker(&system_info, &raw_context, &stack_region, &modules,
                           &frame_symbolizer);
   // This should succeed even without a resolver or supplier.
-  ASSERT_TRUE(walker.Walk(&call_stack));
+  vector<const CodeModule*> modules_without_symbols;
+  ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols));
+  ASSERT_EQ(1U, modules_without_symbols.size());
+  ASSERT_EQ("module1", modules_without_symbols[0]->debug_file());
   frames = call_stack.frames();
   ASSERT_GE(1U, frames->size());
   StackFrameAMD64 *frame = static_cast<StackFrameAMD64 *>(frames->at(0));
@@ -163,7 +168,10 @@
   StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
   StackwalkerAMD64 walker(&system_info, &raw_context, &stack_region, &modules,
                           &frame_symbolizer);
-  ASSERT_TRUE(walker.Walk(&call_stack));
+  vector<const CodeModule*> modules_without_symbols;
+  ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols));
+  ASSERT_EQ(1U, modules_without_symbols.size());
+  ASSERT_EQ("module1", modules_without_symbols[0]->debug_file());
   frames = call_stack.frames();
   ASSERT_GE(1U, frames->size());
   StackFrameAMD64 *frame = static_cast<StackFrameAMD64 *>(frames->at(0));
@@ -181,7 +189,10 @@
   StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
   StackwalkerAMD64 walker(&system_info, &raw_context, NULL, &modules,
                           &frame_symbolizer);
-  ASSERT_TRUE(walker.Walk(&call_stack));
+  vector<const CodeModule*> modules_without_symbols;
+  ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols));
+  ASSERT_EQ(1U, modules_without_symbols.size());
+  ASSERT_EQ("module1", modules_without_symbols[0]->debug_file());
   frames = call_stack.frames();
   ASSERT_GE(1U, frames->size());
   StackFrameAMD64 *frame = static_cast<StackFrameAMD64 *>(frames->at(0));
@@ -199,8 +210,8 @@
   // Force scanning through three frames to ensure that the
   // stack pointer is set properly in scan-recovered frames.
   stack_section.start() = 0x8000000080000000ULL;
-  u_int64_t return_address1 = 0x50000000b0000100ULL;
-  u_int64_t return_address2 = 0x50000000b0000900ULL;
+  uint64_t return_address1 = 0x50000000b0000100ULL;
+  uint64_t return_address2 = 0x50000000b0000900ULL;
   Label frame1_sp, frame2_sp, frame1_rbp;
   stack_section
     // frame 0
@@ -236,7 +247,11 @@
   StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
   StackwalkerAMD64 walker(&system_info, &raw_context, &stack_region, &modules,
                           &frame_symbolizer);
-  ASSERT_TRUE(walker.Walk(&call_stack));
+  vector<const CodeModule*> modules_without_symbols;
+  ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols));
+  ASSERT_EQ(2U, modules_without_symbols.size());
+  ASSERT_EQ("module1", modules_without_symbols[0]->debug_file());
+  ASSERT_EQ("module2", modules_without_symbols[1]->debug_file());
   frames = call_stack.frames();
   ASSERT_EQ(3U, frames->size());
 
@@ -270,7 +285,7 @@
   // it is only considered a valid return address if it
   // lies within a function's bounds.
   stack_section.start() = 0x8000000080000000ULL;
-  u_int64_t return_address = 0x50000000b0000110ULL;
+  uint64_t return_address = 0x50000000b0000110ULL;
   Label frame1_sp, frame1_rbp;
 
   stack_section
@@ -304,7 +319,9 @@
   StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
   StackwalkerAMD64 walker(&system_info, &raw_context, &stack_region, &modules,
                           &frame_symbolizer);
-  ASSERT_TRUE(walker.Walk(&call_stack));
+  vector<const CodeModule*> modules_without_symbols;
+  ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols));
+  ASSERT_EQ(0U, modules_without_symbols.size());
   frames = call_stack.frames();
   ASSERT_EQ(2U, frames->size());
 
@@ -333,7 +350,7 @@
   // %rbp directly below the return address, assume that it is indeed the
   // next frame's %rbp.
   stack_section.start() = 0x8000000080000000ULL;
-  u_int64_t return_address = 0x50000000b0000110ULL;
+  uint64_t return_address = 0x50000000b0000110ULL;
   Label frame0_rbp, frame1_sp, frame1_rbp;
 
   stack_section
@@ -369,7 +386,9 @@
   StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
   StackwalkerAMD64 walker(&system_info, &raw_context, &stack_region, &modules,
                           &frame_symbolizer);
-  ASSERT_TRUE(walker.Walk(&call_stack));
+  vector<const CodeModule*> modules_without_symbols;
+  ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols));
+  ASSERT_EQ(0U, modules_without_symbols.size());
   frames = call_stack.frames();
   ASSERT_EQ(2U, frames->size());
 
@@ -445,7 +464,9 @@
     StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
     StackwalkerAMD64 walker(&system_info, &raw_context, &stack_region, &modules,
                             &frame_symbolizer);
-    ASSERT_TRUE(walker.Walk(&call_stack));
+    vector<const CodeModule*> modules_without_symbols;
+    ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols));
+    ASSERT_EQ(0U, modules_without_symbols.size());
     frames = call_stack.frames();
     ASSERT_EQ(2U, frames->size());
 
diff --git a/src/processor/stackwalker_arm.cc b/src/processor/stackwalker_arm.cc
index 2535cd0..a736061 100644
--- a/src/processor/stackwalker_arm.cc
+++ b/src/processor/stackwalker_arm.cc
@@ -35,13 +35,13 @@
 
 #include <vector>
 
+#include "common/scoped_ptr.h"
 #include "google_breakpad/processor/call_stack.h"
 #include "google_breakpad/processor/memory_region.h"
 #include "google_breakpad/processor/source_line_resolver_interface.h"
 #include "google_breakpad/processor/stack_frame_cpu.h"
 #include "processor/cfi_frame_info.h"
 #include "processor/logging.h"
-#include "processor/scoped_ptr.h"
 #include "processor/stackwalker_arm.h"
 
 namespace google_breakpad {
@@ -90,13 +90,13 @@
   };
 
   // Populate a dictionary with the valid register values in last_frame.
-  CFIFrameInfo::RegisterValueMap<u_int32_t> callee_registers;
+  CFIFrameInfo::RegisterValueMap<uint32_t> callee_registers;
   for (int i = 0; register_names[i]; i++)
     if (last_frame->context_validity & StackFrameARM::RegisterValidFlag(i))
       callee_registers[register_names[i]] = last_frame->context.iregs[i];
 
   // Use the STACK CFI data to recover the caller's register values.
-  CFIFrameInfo::RegisterValueMap<u_int32_t> caller_registers;
+  CFIFrameInfo::RegisterValueMap<uint32_t> caller_registers;
   if (!cfi_frame_info->FindCallerRegs(callee_registers, *memory_,
                                       &caller_registers))
     return NULL;
@@ -104,7 +104,7 @@
   // Construct a new stack frame given the values the CFI recovered.
   scoped_ptr<StackFrameARM> frame(new StackFrameARM());
   for (int i = 0; register_names[i]; i++) {
-    CFIFrameInfo::RegisterValueMap<u_int32_t>::iterator entry =
+    CFIFrameInfo::RegisterValueMap<uint32_t>::iterator entry =
       caller_registers.find(register_names[i]);
     if (entry != caller_registers.end()) {
       // We recovered the value of this register; fill the context with the
@@ -123,7 +123,7 @@
   }
   // If the CFI doesn't recover the PC explicitly, then use .ra.
   if (!(frame->context_validity & StackFrameARM::CONTEXT_VALID_PC)) {
-    CFIFrameInfo::RegisterValueMap<u_int32_t>::iterator entry =
+    CFIFrameInfo::RegisterValueMap<uint32_t>::iterator entry =
       caller_registers.find(".ra");
     if (entry != caller_registers.end()) {
       if (fp_register_ == -1) {
@@ -142,7 +142,7 @@
   }
   // If the CFI doesn't recover the SP explicitly, then use .cfa.
   if (!(frame->context_validity & StackFrameARM::CONTEXT_VALID_SP)) {
-    CFIFrameInfo::RegisterValueMap<u_int32_t>::iterator entry =
+    CFIFrameInfo::RegisterValueMap<uint32_t>::iterator entry =
       caller_registers.find(".cfa");
     if (entry != caller_registers.end()) {
       frame->context_validity |= StackFrameARM::CONTEXT_VALID_SP;
@@ -163,10 +163,17 @@
 StackFrameARM* StackwalkerARM::GetCallerByStackScan(
     const vector<StackFrame*> &frames) {
   StackFrameARM* last_frame = static_cast<StackFrameARM*>(frames.back());
-  u_int32_t last_sp = last_frame->context.iregs[MD_CONTEXT_ARM_REG_SP];
-  u_int32_t caller_sp, caller_pc;
+  uint32_t last_sp = last_frame->context.iregs[MD_CONTEXT_ARM_REG_SP];
+  uint32_t caller_sp, caller_pc;
 
-  if (!ScanForReturnAddress(last_sp, &caller_sp, &caller_pc)) {
+  // When searching for the caller of the context frame,
+  // allow the scanner to look farther down the stack.
+  const int kRASearchWords = frames.size() == 1 ?
+    Stackwalker::kRASearchWords * 4 :
+    Stackwalker::kRASearchWords;
+
+  if (!ScanForReturnAddress(last_sp, &caller_sp, &caller_pc,
+                            kRASearchWords)) {
     // No plausible return address was found.
     return NULL;
   }
@@ -199,23 +206,23 @@
     return NULL;
   }
 
-  u_int32_t last_fp = last_frame->context.iregs[fp_register_];
+  uint32_t last_fp = last_frame->context.iregs[fp_register_];
 
-  u_int32_t caller_fp = 0;
+  uint32_t caller_fp = 0;
   if (last_fp && !memory_->GetMemoryAtAddress(last_fp, &caller_fp)) {
     BPLOG(ERROR) << "Unable to read caller_fp from last_fp: 0x"
                  << std::hex << last_fp;
     return NULL;
   }
 
-  u_int32_t caller_lr = 0;
+  uint32_t caller_lr = 0;
   if (last_fp && !memory_->GetMemoryAtAddress(last_fp + 4, &caller_lr)) {
     BPLOG(ERROR) << "Unable to read caller_lr from last_fp + 4: 0x"
                  << std::hex << (last_fp + 4);
     return NULL;
   }
 
-  u_int32_t caller_sp = last_fp ? last_fp + 8 :
+  uint32_t caller_sp = last_fp ? last_fp + 8 :
       last_frame->context.iregs[MD_CONTEXT_ARM_REG_SP];
 
   // Create a new stack frame (ownership will be transferred to the caller)
diff --git a/src/processor/stackwalker_arm_unittest.cc b/src/processor/stackwalker_arm_unittest.cc
index 4c2ca04..588b5c5 100644
--- a/src/processor/stackwalker_arm_unittest.cc
+++ b/src/processor/stackwalker_arm_unittest.cc
@@ -41,6 +41,7 @@
 #include "google_breakpad/common/minidump_format.h"
 #include "google_breakpad/processor/basic_source_line_resolver.h"
 #include "google_breakpad/processor/call_stack.h"
+#include "google_breakpad/processor/code_module.h"
 #include "google_breakpad/processor/source_line_resolver_interface.h"
 #include "google_breakpad/processor/stack_frame_cpu.h"
 #include "processor/stackwalker_unittest_utils.h"
@@ -49,6 +50,7 @@
 
 using google_breakpad::BasicSourceLineResolver;
 using google_breakpad::CallStack;
+using google_breakpad::CodeModule;
 using google_breakpad::StackFrameSymbolizer;
 using google_breakpad::StackFrame;
 using google_breakpad::StackFrameARM;
@@ -111,9 +113,9 @@
 
   // Fill RAW_CONTEXT with pseudo-random data, for round-trip checking.
   void BrandContext(MDRawContextARM *raw_context) {
-    u_int8_t x = 173;
+    uint8_t x = 173;
     for (size_t i = 0; i < sizeof(*raw_context); i++)
-      reinterpret_cast<u_int8_t *>(raw_context)[i] = (x += 17);
+      reinterpret_cast<uint8_t *>(raw_context)[i] = (x += 17);
   }
 
   SystemInfo system_info;
@@ -139,7 +141,9 @@
   StackwalkerARM walker(&system_info, &raw_context, -1, &stack_region, &modules,
                         &frame_symbolizer);
   // This should succeed even without a resolver or supplier.
-  ASSERT_TRUE(walker.Walk(&call_stack));
+  vector<const CodeModule*> modules_without_symbols;
+  ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols));
+  ASSERT_EQ(0U, modules_without_symbols.size());
   frames = call_stack.frames();
   ASSERT_EQ(1U, frames->size());
   StackFrameARM *frame = static_cast<StackFrameARM *>(frames->at(0));
@@ -157,7 +161,9 @@
   StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
   StackwalkerARM walker(&system_info, &raw_context, -1, &stack_region, &modules,
                         &frame_symbolizer);
-  ASSERT_TRUE(walker.Walk(&call_stack));
+  vector<const CodeModule*> modules_without_symbols;
+  ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols));
+  ASSERT_EQ(0U, modules_without_symbols.size());
   frames = call_stack.frames();
   ASSERT_EQ(1U, frames->size());
   StackFrameARM *frame = static_cast<StackFrameARM *>(frames->at(0));
@@ -172,7 +178,9 @@
   StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
   StackwalkerARM walker(&system_info, &raw_context, -1, NULL, &modules,
                         &frame_symbolizer);
-  ASSERT_TRUE(walker.Walk(&call_stack));
+  vector<const CodeModule*> modules_without_symbols;
+  ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols));
+  ASSERT_EQ(0U, modules_without_symbols.size());
   frames = call_stack.frames();
   ASSERT_EQ(1U, frames->size());
   StackFrameARM *frame = static_cast<StackFrameARM *>(frames->at(0));
@@ -190,8 +198,8 @@
   // Force scanning through three frames to ensure that the
   // stack pointer is set properly in scan-recovered frames.
   stack_section.start() = 0x80000000;
-  u_int32_t return_address1 = 0x50000100;
-  u_int32_t return_address2 = 0x50000900;
+  uint32_t return_address1 = 0x50000100;
+  uint32_t return_address2 = 0x50000900;
   Label frame1_sp, frame2_sp;
   stack_section
     // frame 0
@@ -220,7 +228,11 @@
   StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
   StackwalkerARM walker(&system_info, &raw_context, -1, &stack_region, &modules,
                         &frame_symbolizer);
-  ASSERT_TRUE(walker.Walk(&call_stack));
+  vector<const CodeModule*> modules_without_symbols;
+  ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols));
+  ASSERT_EQ(2U, modules_without_symbols.size());
+  ASSERT_EQ("module1", modules_without_symbols[0]->debug_file());
+  ASSERT_EQ("module2", modules_without_symbols[1]->debug_file());
   frames = call_stack.frames();
   ASSERT_EQ(3U, frames->size());
 
@@ -252,7 +264,7 @@
   // it is only considered a valid return address if it
   // lies within a function's bounds.
   stack_section.start() = 0x80000000;
-  u_int32_t return_address = 0x50000200;
+  uint32_t return_address = 0x50000200;
   Label frame1_sp;
 
   stack_section
@@ -284,7 +296,9 @@
   StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
   StackwalkerARM walker(&system_info, &raw_context, -1, &stack_region, &modules,
                         &frame_symbolizer);
-  ASSERT_TRUE(walker.Walk(&call_stack));
+  vector<const CodeModule*> modules_without_symbols;
+  ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols));
+  ASSERT_EQ(0U, modules_without_symbols.size());
   frames = call_stack.frames();
   ASSERT_EQ(2U, frames->size());
 
@@ -306,6 +320,67 @@
   EXPECT_EQ(0x50000100U, frame1->function_base);
 }
 
+TEST_F(GetCallerFrame, ScanFirstFrame) {
+  // If the stackwalker resorts to stack scanning, it will scan much
+  // farther to find the caller of the context frame.
+  stack_section.start() = 0x80000000;
+  uint32_t return_address1 = 0x50000100;
+  uint32_t return_address2 = 0x50000900;
+  Label frame1_sp, frame2_sp;
+  stack_section
+    // frame 0
+    .Append(32, 0)                      // space
+
+    .D32(0x40090000)                    // junk that's not
+    .D32(0x60000000)                    // a return address
+
+    .Append(96, 0)                      // more space
+
+    .D32(return_address1)               // actual return address
+    // frame 1
+    .Mark(&frame1_sp)
+    .Append(32, 0)                      // space
+
+    .D32(0xF0000000)                    // more junk
+    .D32(0x0000000D)
+
+    .Append(96, 0)                      // more space
+
+    .D32(return_address2)               // actual return address
+                                        // (won't be found)
+    // frame 2
+    .Mark(&frame2_sp)
+    .Append(32, 0);                     // end of stack
+  RegionFromSection();
+
+  raw_context.iregs[MD_CONTEXT_ARM_REG_PC] = 0x40005510;
+  raw_context.iregs[MD_CONTEXT_ARM_REG_SP] = stack_section.start().Value();
+
+  StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
+  StackwalkerARM walker(&system_info, &raw_context, -1, &stack_region, &modules,
+                        &frame_symbolizer);
+  vector<const CodeModule*> modules_without_symbols;
+  ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols));
+  ASSERT_EQ(2U, modules_without_symbols.size());
+  ASSERT_EQ("module1", modules_without_symbols[0]->debug_file());
+  ASSERT_EQ("module2", modules_without_symbols[1]->debug_file());
+  frames = call_stack.frames();
+  ASSERT_EQ(2U, frames->size());
+
+  StackFrameARM *frame0 = static_cast<StackFrameARM *>(frames->at(0));
+  EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust);
+  ASSERT_EQ(StackFrameARM::CONTEXT_VALID_ALL, frame0->context_validity);
+  EXPECT_EQ(0, memcmp(&raw_context, &frame0->context, sizeof(raw_context)));
+
+  StackFrameARM *frame1 = static_cast<StackFrameARM *>(frames->at(1));
+  EXPECT_EQ(StackFrame::FRAME_TRUST_SCAN, frame1->trust);
+  ASSERT_EQ((StackFrameARM::CONTEXT_VALID_PC |
+             StackFrameARM::CONTEXT_VALID_SP),
+            frame1->context_validity);
+  EXPECT_EQ(return_address1, frame1->context.iregs[MD_CONTEXT_ARM_REG_PC]);
+  EXPECT_EQ(frame1_sp.Value(), frame1->context.iregs[MD_CONTEXT_ARM_REG_SP]);
+}
+
 struct CFIFixture: public StackwalkerARMFixture {
   CFIFixture() {
     // Provide a bunch of STACK CFI records; we'll walk to the caller
@@ -396,7 +471,9 @@
     StackwalkerARM walker(&system_info, &raw_context, -1, &stack_region,
                           &modules, &frame_symbolizer);
     walker.SetContextFrameValidity(context_frame_validity);
-    ASSERT_TRUE(walker.Walk(&call_stack));
+    vector<const CodeModule*> modules_without_symbols;
+    ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols));
+    ASSERT_EQ(0U, modules_without_symbols.size());
     frames = call_stack.frames();
     ASSERT_EQ(2U, frames->size());
 
@@ -588,7 +665,9 @@
   StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
   StackwalkerARM walker(&system_info, &raw_context, -1, &stack_region, &modules,
                         &frame_symbolizer);
-  ASSERT_TRUE(walker.Walk(&call_stack));
+  vector<const CodeModule*> modules_without_symbols;
+  ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols));
+  ASSERT_EQ(0U, modules_without_symbols.size());
   frames = call_stack.frames();
   ASSERT_EQ(1U, frames->size());
 }
@@ -600,7 +679,9 @@
   StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
   StackwalkerARM walker(&system_info, &raw_context, -1, &stack_region, &modules,
                         &frame_symbolizer);
-  ASSERT_TRUE(walker.Walk(&call_stack));
+  vector<const CodeModule*> modules_without_symbols;
+  ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols));
+  ASSERT_EQ(0U, modules_without_symbols.size());
   frames = call_stack.frames();
   ASSERT_EQ(1U, frames->size());
 }
@@ -617,8 +698,8 @@
 
 TEST_F(GetFramesByFramePointer, OnlyFramePointer) {
   stack_section.start() = 0x80000000;
-  u_int32_t return_address1 = 0x50000100;
-  u_int32_t return_address2 = 0x50000900;
+  uint32_t return_address1 = 0x50000100;
+  uint32_t return_address2 = 0x50000900;
   Label frame1_sp, frame2_sp;
   Label frame1_fp, frame2_fp;
   stack_section
@@ -658,7 +739,11 @@
   StackwalkerARM walker(&system_info, &raw_context, MD_CONTEXT_ARM_REG_IOS_FP,
                         &stack_region, &modules, &frame_symbolizer);
 
-  ASSERT_TRUE(walker.Walk(&call_stack));
+  vector<const CodeModule*> modules_without_symbols;
+  ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols));
+  ASSERT_EQ(2U, modules_without_symbols.size());
+  ASSERT_EQ("module1", modules_without_symbols[0]->debug_file());
+  ASSERT_EQ("module2", modules_without_symbols[1]->debug_file());
   frames = call_stack.frames();
   ASSERT_EQ(3U, frames->size());
 
@@ -707,8 +792,8 @@
                   );
 
   stack_section.start() = 0x80000000;
-  u_int32_t return_address1 = 0x40004010;
-  u_int32_t return_address2 = 0x50000900;
+  uint32_t return_address1 = 0x40004010;
+  uint32_t return_address2 = 0x50000900;
   Label frame1_sp, frame2_sp;
   Label frame1_fp, frame2_fp;
   stack_section
@@ -748,7 +833,10 @@
   StackwalkerARM walker(&system_info, &raw_context, MD_CONTEXT_ARM_REG_IOS_FP,
                         &stack_region, &modules, &frame_symbolizer);
 
-  ASSERT_TRUE(walker.Walk(&call_stack));
+  vector<const CodeModule*> modules_without_symbols;
+  ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols));
+  ASSERT_EQ(1U, modules_without_symbols.size());
+  ASSERT_EQ("module2", modules_without_symbols[0]->debug_file());
   frames = call_stack.frames();
   ASSERT_EQ(3U, frames->size());
 
diff --git a/src/processor/stackwalker_ppc.cc b/src/processor/stackwalker_ppc.cc
index 40bec8d..29015df 100644
--- a/src/processor/stackwalker_ppc.cc
+++ b/src/processor/stackwalker_ppc.cc
@@ -102,7 +102,7 @@
   // A caller frame must reside higher in memory than its callee frames.
   // Anything else is an error, or an indication that we've reached the
   // end of the stack.
-  u_int32_t stack_pointer;
+  uint32_t stack_pointer;
   if (!memory_->GetMemoryAtAddress(last_frame->context.gpr[1],
                                    &stack_pointer) ||
       stack_pointer <= last_frame->context.gpr[1]) {
@@ -114,7 +114,7 @@
   // documentation on this, but 0 or 1 would be bogus return addresses,
   // so check for them here and return false (end of stack) when they're
   // hit to avoid having a phantom frame.
-  u_int32_t instruction;
+  uint32_t instruction;
   if (!memory_->GetMemoryAtAddress(stack_pointer + 8, &instruction) ||
       instruction <= 1) {
     return NULL;
diff --git a/src/processor/stackwalker_ppc64.cc b/src/processor/stackwalker_ppc64.cc
new file mode 100644
index 0000000..fa49ce3
--- /dev/null
+++ b/src/processor/stackwalker_ppc64.cc
@@ -0,0 +1,136 @@
+// 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.
+
+// stackwalker_ppc64.cc: ppc64-specific stackwalker.
+//
+// See stackwalker_ppc64.h for documentation.
+
+
+#include "processor/stackwalker_ppc64.h"
+#include "google_breakpad/processor/call_stack.h"
+#include "google_breakpad/processor/memory_region.h"
+#include "google_breakpad/processor/stack_frame_cpu.h"
+#include "processor/logging.h"
+
+#include <stdio.h>
+
+namespace google_breakpad {
+
+
+StackwalkerPPC64::StackwalkerPPC64(const SystemInfo* system_info,
+                                   const MDRawContextPPC64* context,
+                                   MemoryRegion* memory,
+                                   const CodeModules* modules,
+                                   StackFrameSymbolizer* resolver_helper)
+    : Stackwalker(system_info, memory, modules, resolver_helper),
+      context_(context) {
+}
+
+
+StackFrame* StackwalkerPPC64::GetContextFrame() {
+  if (!context_) {
+    BPLOG(ERROR) << "Can't get context frame without context";
+    return NULL;
+  }
+
+  StackFramePPC64* frame = new StackFramePPC64();
+
+  // The instruction pointer is stored directly in a register, so pull it
+  // straight out of the CPU context structure.
+  frame->context = *context_;
+  frame->context_validity = StackFramePPC64::CONTEXT_VALID_ALL;
+  frame->trust = StackFrame::FRAME_TRUST_CONTEXT;
+  frame->instruction = frame->context.srr0;
+
+  return frame;
+}
+
+
+StackFrame* StackwalkerPPC64::GetCallerFrame(const CallStack* stack) {
+  if (!memory_ || !stack) {
+    BPLOG(ERROR) << "Can't get caller frame without memory or stack";
+    return NULL;
+  }
+
+  // The instruction pointers for previous frames are saved on the stack.
+  // The typical ppc64 calling convention is for the called procedure to store
+  // its return address in the calling procedure's stack frame at 8(%r1),
+  // and to allocate its own stack frame by decrementing %r1 (the stack
+  // pointer) and saving the old value of %r1 at 0(%r1).  Because the ppc64 has
+  // no hardware stack, there is no distinction between the stack pointer and
+  // frame pointer, and what is typically thought of as the frame pointer on
+  // an x86 is usually referred to as the stack pointer on a ppc64.
+
+  StackFramePPC64* last_frame = static_cast<StackFramePPC64*>(
+      stack->frames()->back());
+
+  // A caller frame must reside higher in memory than its callee frames.
+  // Anything else is an error, or an indication that we've reached the
+  // end of the stack.
+  uint64_t stack_pointer;
+  if (!memory_->GetMemoryAtAddress(last_frame->context.gpr[1],
+                                   &stack_pointer) ||
+      stack_pointer <= last_frame->context.gpr[1]) {
+    return NULL;
+  }
+
+  // Mac OS X/Darwin gives 1 as the return address from the bottom-most
+  // frame in a stack (a thread's entry point).  I haven't found any
+  // documentation on this, but 0 or 1 would be bogus return addresses,
+  // so check for them here and return false (end of stack) when they're
+  // hit to avoid having a phantom frame.
+  uint64_t instruction;
+  if (!memory_->GetMemoryAtAddress(stack_pointer + 16, &instruction) ||
+      instruction <= 1) {
+    return NULL;
+  }
+
+  StackFramePPC64* frame = new StackFramePPC64();
+
+  frame->context = last_frame->context;
+  frame->context.srr0 = instruction;
+  frame->context.gpr[1] = stack_pointer;
+  frame->context_validity = StackFramePPC64::CONTEXT_VALID_SRR0 |
+                            StackFramePPC64::CONTEXT_VALID_GPR1;
+  frame->trust = StackFrame::FRAME_TRUST_FP;
+
+  // frame->context.srr0 is the return address, which is one instruction
+  // past the branch that caused us to arrive at the callee.  Set
+  // frame_ppc64->instruction to eight less than that.  Since all ppc64
+  // instructions are 8 bytes wide, this is the address of the branch
+  // instruction.  This allows source line information to match up with the
+  // line that contains a function call.  Callers that require the exact
+  // return address value may access the context.srr0 field of StackFramePPC64.
+  frame->instruction = frame->context.srr0 - 8;
+
+  return frame;
+}
+
+
+}  // namespace google_breakpad
diff --git a/src/processor/stackwalker_ppc64.h b/src/processor/stackwalker_ppc64.h
new file mode 100644
index 0000000..6579db7
--- /dev/null
+++ b/src/processor/stackwalker_ppc64.h
@@ -0,0 +1,76 @@
+// 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.
+
+// stackwalker_ppc64.h: ppc-specific stackwalker.
+//
+// Provides stack frames given ppc64 register context and a memory region
+// corresponding to a ppc64 stack.
+
+
+#ifndef PROCESSOR_STACKWALKER_PPC64_H__
+#define PROCESSOR_STACKWALKER_PPC64_H__
+
+
+#include "google_breakpad/common/breakpad_types.h"
+#include "google_breakpad/common/minidump_format.h"
+#include "google_breakpad/processor/stackwalker.h"
+
+namespace google_breakpad {
+
+class CodeModules;
+
+class StackwalkerPPC64 : public Stackwalker {
+ public:
+  // context is a ppc64 context object that gives access to ppc64-specific
+  // register state corresponding to the innermost called frame to be
+  // included in the stack.  The other arguments are passed directly through
+  // to the base Stackwalker constructor.
+  StackwalkerPPC64(const SystemInfo* system_info,
+                   const MDRawContextPPC64* context,
+                   MemoryRegion* memory,
+                   const CodeModules* modules,
+                   StackFrameSymbolizer* frame_symbolizer);
+
+ private:
+  // Implementation of Stackwalker, using ppc64 context (stack pointer in %r1,
+  // saved program counter in %srr0) and stack conventions (saved stack
+  // pointer at 0(%r1), return address at 8(0(%r1)).
+  virtual StackFrame* GetContextFrame();
+  virtual StackFrame* GetCallerFrame(const CallStack* stack);
+
+  // Stores the CPU context corresponding to the innermost stack frame to
+  // be returned by GetContextFrame.
+  const MDRawContextPPC64* context_;
+};
+
+
+}  // namespace google_breakpad
+
+
+#endif  // PROCESSOR_STACKWALKER_PPC64_H__
diff --git a/src/processor/stackwalker_selftest.cc b/src/processor/stackwalker_selftest.cc
index fdd1527..75d4758 100644
--- a/src/processor/stackwalker_selftest.cc
+++ b/src/processor/stackwalker_selftest.cc
@@ -64,17 +64,19 @@
 
 #include <stdio.h>
 
+#include "common/scoped_ptr.h"
 #include "google_breakpad/common/breakpad_types.h"
 #include "google_breakpad/common/minidump_format.h"
 #include "google_breakpad/processor/basic_source_line_resolver.h"
 #include "google_breakpad/processor/call_stack.h"
+#include "google_breakpad/processor/code_module.h"
 #include "google_breakpad/processor/memory_region.h"
 #include "google_breakpad/processor/stack_frame.h"
 #include "google_breakpad/processor/stack_frame_cpu.h"
-#include "processor/scoped_ptr.h"
 
 using google_breakpad::BasicSourceLineResolver;
 using google_breakpad::CallStack;
+using google_breakpad::CodeModule;
 using google_breakpad::MemoryRegion;
 using google_breakpad::scoped_ptr;
 using google_breakpad::StackFrame;
@@ -100,20 +102,20 @@
 // process' memory space by pointer.
 class SelfMemoryRegion : public MemoryRegion {
  public:
-  virtual u_int64_t GetBase() { return 0; }
-  virtual u_int32_t GetSize() { return 0xffffffff; }
+  virtual uint64_t GetBase() { return 0; }
+  virtual uint32_t GetSize() { return 0xffffffff; }
 
-  bool GetMemoryAtAddress(u_int64_t address, u_int8_t*  value) {
+  bool GetMemoryAtAddress(uint64_t address, uint8_t*  value) {
       return GetMemoryAtAddressInternal(address, value); }
-  bool GetMemoryAtAddress(u_int64_t address, u_int16_t* value) {
+  bool GetMemoryAtAddress(uint64_t address, uint16_t* value) {
       return GetMemoryAtAddressInternal(address, value); }
-  bool GetMemoryAtAddress(u_int64_t address, u_int32_t* value) {
+  bool GetMemoryAtAddress(uint64_t address, uint32_t* value) {
       return GetMemoryAtAddressInternal(address, value); }
-  bool GetMemoryAtAddress(u_int64_t address, u_int64_t* value) {
+  bool GetMemoryAtAddress(uint64_t address, uint64_t* value) {
       return GetMemoryAtAddressInternal(address, value); }
 
  private:
-  template<typename T> bool GetMemoryAtAddressInternal(u_int64_t address,
+  template<typename T> bool GetMemoryAtAddressInternal(uint64_t address,
                                                        T*        value) {
     // Without knowing what addresses are actually mapped, just assume that
     // everything low is not mapped.  This helps the stackwalker catch the
@@ -123,7 +125,7 @@
     if (address < 0x100)
       return false;
 
-    u_int8_t* memory = 0;
+    uint8_t* memory = 0;
     *value = *reinterpret_cast<const T*>(&memory[address]);
     return true;
   }
@@ -142,9 +144,9 @@
 // on the stack (provided frame pointers are not being omitted.)  Because
 // this function depends on the compiler-generated preamble, inlining is
 // disabled.
-static u_int32_t GetEBP() __attribute__((noinline));
-static u_int32_t GetEBP() {
-  u_int32_t ebp;
+static uint32_t GetEBP() __attribute__((noinline));
+static uint32_t GetEBP() {
+  uint32_t ebp;
   __asm__ __volatile__(
     "movl (%%ebp), %0"
     : "=a" (ebp)
@@ -158,9 +160,9 @@
 // The CALL instruction places a 4-byte return address on the stack above
 // the caller's %esp, and this function's prolog will save the caller's %ebp
 // on the stack as well, for another 4 bytes, before storing %esp in %ebp.
-static u_int32_t GetESP() __attribute__((noinline));
-static u_int32_t GetESP() {
-  u_int32_t ebp;
+static uint32_t GetESP() __attribute__((noinline));
+static uint32_t GetESP() {
+  uint32_t ebp;
   __asm__ __volatile__(
     "movl %%ebp, %0"
     : "=a" (ebp)
@@ -179,9 +181,9 @@
 // because GetEBP and stackwalking necessarily depends on access to frame
 // pointers.  Because this function depends on a call instruction and the
 // compiler-generated preamble, inlining is disabled.
-static u_int32_t GetEIP() __attribute__((noinline));
-static u_int32_t GetEIP() {
-  u_int32_t eip;
+static uint32_t GetEIP() __attribute__((noinline));
+static uint32_t GetEIP() {
+  uint32_t eip;
   __asm__ __volatile__(
     "movl 4(%%ebp), %0"
     : "=a" (eip)
@@ -199,9 +201,9 @@
 // pointer.  Dereference %r1 to obtain the caller's stack pointer, which the
 // compiler-generated prolog stored on the stack.  Because this function
 // depends on the compiler-generated prolog, inlining is disabled.
-static u_int32_t GetSP() __attribute__((noinline));
-static u_int32_t GetSP() {
-  u_int32_t sp;
+static uint32_t GetSP() __attribute__((noinline));
+static uint32_t GetSP() {
+  uint32_t sp;
   __asm__ __volatile__(
     "lwz %0, 0(r1)"
     : "=r" (sp)
@@ -215,9 +217,9 @@
 // link register, where it was placed by the branch instruction that called
 // GetPC.  Because this function depends on the caller's use of a branch
 // instruction, inlining is disabled.
-static u_int32_t GetPC() __attribute__((noinline));
-static u_int32_t GetPC() {
-  u_int32_t lr;
+static uint32_t GetPC() __attribute__((noinline));
+static uint32_t GetPC() {
+  uint32_t lr;
   __asm__ __volatile__(
     "mflr %0"
     : "=r" (lr)
@@ -236,9 +238,9 @@
 // pointer, which the compiler-generated prolog stored on the stack.
 // Because this function depends on the compiler-generated prolog, inlining
 // is disabled.
-static u_int32_t GetSP() __attribute__((noinline));
-static u_int32_t GetSP() {
-  u_int32_t sp;
+static uint32_t GetSP() __attribute__((noinline));
+static uint32_t GetSP() {
+  uint32_t sp;
   __asm__ __volatile__(
     "mov %%fp, %0"
     : "=r" (sp)
@@ -253,9 +255,9 @@
 // on the stack (provided frame pointers are not being omitted.)  Because
 // this function depends on the compiler-generated preamble, inlining is
 // disabled.
-static u_int32_t GetFP() __attribute__((noinline));
-static u_int32_t GetFP() {
-  u_int32_t fp;
+static uint32_t GetFP() __attribute__((noinline));
+static uint32_t GetFP() {
+  uint32_t fp;
   __asm__ __volatile__(
     "ld [%%fp+56], %0"
     : "=r" (fp)
@@ -268,9 +270,9 @@
 // link register, where it was placed by the branch instruction that called
 // GetPC.  Because this function depends on the caller's use of a branch
 // instruction, inlining is disabled.
-static u_int32_t GetPC() __attribute__((noinline));
-static u_int32_t GetPC() {
-  u_int32_t pc;
+static uint32_t GetPC() __attribute__((noinline));
+static uint32_t GetPC() {
+  uint32_t pc;
   __asm__ __volatile__(
     "mov %%i7, %0"
     : "=r" (pc)
@@ -284,15 +286,15 @@
 
 #if defined(__i386__)
 extern "C" {
-extern u_int32_t GetEIP();
-extern u_int32_t GetEBP();
-extern u_int32_t GetESP();
+extern uint32_t GetEIP();
+extern uint32_t GetEBP();
+extern uint32_t GetESP();
 }
 #elif defined(__sparc__)
 extern "C" {
-extern u_int32_t GetPC();
-extern u_int32_t GetFP();
-extern u_int32_t GetSP();
+extern uint32_t GetPC();
+extern uint32_t GetFP();
+extern uint32_t GetSP();
 }
 #endif // __i386__ || __sparc__
 
@@ -337,7 +339,8 @@
 #endif  // __i386__ || __ppc__ || __sparc__
 
   CallStack stack;
-  stackwalker.Walk(&stack);
+  vector<const CodeModule*> modules_without_symbols;
+  stackwalker.Walk(&stack, &modules_without_symbols);
 
 #ifdef PRINT_STACKS
   printf("\n");
diff --git a/src/processor/stackwalker_sparc.cc b/src/processor/stackwalker_sparc.cc
index d1d5d23..7c3c520 100644
--- a/src/processor/stackwalker_sparc.cc
+++ b/src/processor/stackwalker_sparc.cc
@@ -93,18 +93,18 @@
   // A caller frame must reside higher in memory than its callee frames.
   // Anything else is an error, or an indication that we've reached the
   // end of the stack.
-  u_int64_t stack_pointer = last_frame->context.g_r[30];
+  uint64_t stack_pointer = last_frame->context.g_r[30];
   if (stack_pointer <= last_frame->context.g_r[14]) {
     return NULL;
   }
 
-  u_int32_t instruction;
+  uint32_t instruction;
   if (!memory_->GetMemoryAtAddress(stack_pointer + 60,
                      &instruction) || instruction <= 1) {
     return NULL;
   }
 
-  u_int32_t stack_base;
+  uint32_t stack_base;
   if (!memory_->GetMemoryAtAddress(stack_pointer + 56,
                      &stack_base) || stack_base <= 1) {
     return NULL;
diff --git a/src/processor/stackwalker_unittest_utils.h b/src/processor/stackwalker_unittest_utils.h
index 5257f81..0763866 100644
--- a/src/processor/stackwalker_unittest_utils.h
+++ b/src/processor/stackwalker_unittest_utils.h
@@ -55,24 +55,24 @@
   // 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(u_int64_t base_address, const string &contents) {
+  void Init(uint64_t base_address, const string &contents) {
     base_address_ = base_address;
     contents_ = contents;
   }
 
-  u_int64_t GetBase() const { return base_address_; }
-  u_int32_t GetSize() const { return contents_.size(); }
+  uint64_t GetBase() const { return base_address_; }
+  uint32_t GetSize() const { return contents_.size(); }
 
-  bool GetMemoryAtAddress(u_int64_t address, u_int8_t  *value) const {
+  bool GetMemoryAtAddress(uint64_t address, uint8_t  *value) const {
     return GetMemoryLittleEndian(address, value);
   }
-  bool GetMemoryAtAddress(u_int64_t address, u_int16_t *value) const {
+  bool GetMemoryAtAddress(uint64_t address, uint16_t *value) const {
     return GetMemoryLittleEndian(address, value);
   }
-  bool GetMemoryAtAddress(u_int64_t address, u_int32_t *value) const {
+  bool GetMemoryAtAddress(uint64_t address, uint32_t *value) const {
     return GetMemoryLittleEndian(address, value);
   }
-  bool GetMemoryAtAddress(u_int64_t address, u_int64_t *value) const {
+  bool GetMemoryAtAddress(uint64_t address, uint64_t *value) const {
     return GetMemoryLittleEndian(address, value);
   }
 
@@ -80,7 +80,7 @@
   // Fetch a little-endian value from ADDRESS in contents_ whose size
   // is BYTES, and store it in *VALUE. Return true on success.
   template<typename ValueType>
-  bool GetMemoryLittleEndian(u_int64_t address, ValueType *value) const {
+  bool GetMemoryLittleEndian(uint64_t address, ValueType *value) const {
     if (address < base_address_ ||
         address - base_address_ + sizeof(ValueType) > contents_.size())
       return false;
@@ -93,18 +93,18 @@
     return true;
   }
 
-  u_int64_t base_address_;
+  uint64_t base_address_;
   string contents_;
 };
 
 class MockCodeModule: public google_breakpad::CodeModule {
  public:
-  MockCodeModule(u_int64_t base_address, u_int64_t size,
+  MockCodeModule(uint64_t base_address, uint64_t size,
                  const string &code_file, const string &version)
       : base_address_(base_address), size_(size), code_file_(code_file) { }
 
-  u_int64_t base_address()       const { return base_address_; }
-  u_int64_t size()               const { return size_; }
+  uint64_t base_address()       const { return base_address_; }
+  uint64_t size()               const { return size_; }
   string code_file()        const { return code_file_; }
   string code_identifier()  const { return code_file_; }
   string debug_file()       const { return code_file_; }
@@ -115,8 +115,8 @@
   }
 
  private:
-  u_int64_t base_address_;
-  u_int64_t size_;
+  uint64_t base_address_;
+  uint64_t size_;
   string code_file_;
   string version_;
 };
@@ -132,7 +132,7 @@
 
   unsigned int module_count() const { return modules_.size(); }
 
-  const CodeModule *GetModuleForAddress(u_int64_t address) const {
+  const CodeModule *GetModuleForAddress(uint64_t address) const {
     for (ModuleVector::const_iterator i = modules_.begin();
          i != modules_.end(); i++) {
       const MockCodeModule *module = *i;
diff --git a/src/processor/stackwalker_x86.cc b/src/processor/stackwalker_x86.cc
index 61d75de..f4de1a4 100644
--- a/src/processor/stackwalker_x86.cc
+++ b/src/processor/stackwalker_x86.cc
@@ -33,8 +33,10 @@
 //
 // Author: Mark Mentovai
 
+#include <assert.h>
 #include <string>
 
+#include "common/scoped_ptr.h"
 #include "google_breakpad/processor/call_stack.h"
 #include "google_breakpad/processor/code_modules.h"
 #include "google_breakpad/processor/memory_region.h"
@@ -42,7 +44,6 @@
 #include "google_breakpad/processor/stack_frame_cpu.h"
 #include "processor/logging.h"
 #include "processor/postfix_evaluator-inl.h"
-#include "processor/scoped_ptr.h"
 #include "processor/stackwalker_x86.h"
 #include "processor/windows_frame_info.h"
 #include "processor/cfi_frame_info.h"
@@ -105,6 +106,12 @@
   cfi_frame_info = NULL;
 }
 
+uint64_t StackFrameX86::ReturnAddress() const
+{
+  assert(context_validity & StackFrameX86::CONTEXT_VALID_EIP);
+  return context.eip;   
+}
+
 StackFrame* StackwalkerX86::GetContextFrame() {
   if (!context_) {
     BPLOG(ERROR) << "Can't get context frame without context";
@@ -172,7 +179,7 @@
   // are unknown, 0 is also used in that case.  When that happens, it should
   // be possible to walk to the next frame without reference to %esp.
 
-  u_int32_t last_frame_callee_parameter_size = 0;
+  uint32_t last_frame_callee_parameter_size = 0;
   int frames_already_walked = frames.size();
   if (frames_already_walked >= 2) {
     const StackFrameX86* last_frame_callee
@@ -190,7 +197,7 @@
   // Set up the dictionary for the PostfixEvaluator.  %ebp and %esp are used
   // in each program string, and their previous values are known, so set them
   // here.
-  PostfixEvaluator<u_int32_t>::DictionaryType dictionary;
+  PostfixEvaluator<uint32_t>::DictionaryType dictionary;
   // Provide the current register values.
   dictionary["$ebp"] = last_frame->context.ebp;
   dictionary["$esp"] = last_frame->context.esp;
@@ -203,13 +210,13 @@
   dictionary[".cbSavedRegs"] = last_frame_info->saved_register_size;
   dictionary[".cbLocals"] = last_frame_info->local_size;
 
-  u_int32_t raSearchStart = last_frame->context.esp +
+  uint32_t raSearchStart = last_frame->context.esp +
                             last_frame_callee_parameter_size +
                             last_frame_info->local_size +
                             last_frame_info->saved_register_size;
 
-  u_int32_t raSearchStartOld = raSearchStart;
-  u_int32_t found = 0;  // dummy value
+  uint32_t raSearchStartOld = raSearchStart;
+  uint32_t found = 0;  // dummy value
   // Scan up to three words above the calculated search value, in case
   // the stack was aligned to a quadword boundary.
   if (ScanForReturnAddress(raSearchStart, &raSearchStart, &found, 3) &&
@@ -319,9 +326,9 @@
 
   // Now crank it out, making sure that the program string set at least the
   // two required variables.
-  PostfixEvaluator<u_int32_t> evaluator =
-      PostfixEvaluator<u_int32_t>(&dictionary, memory_);
-  PostfixEvaluator<u_int32_t>::DictionaryValidityType dictionary_validity;
+  PostfixEvaluator<uint32_t> evaluator =
+      PostfixEvaluator<uint32_t>(&dictionary, memory_);
+  PostfixEvaluator<uint32_t>::DictionaryValidityType dictionary_validity;
   if (!evaluator.Evaluate(program_string, &dictionary_validity) ||
       dictionary_validity.find("$eip") == dictionary_validity.end() ||
       dictionary_validity.find("$esp") == dictionary_validity.end()) {
@@ -331,8 +338,8 @@
     // address. This can happen if the stack is in a module for which
     // we don't have symbols, and that module is compiled without a
     // frame pointer.
-    u_int32_t location_start = last_frame->context.esp;
-    u_int32_t location, eip;
+    uint32_t location_start = last_frame->context.esp;
+    uint32_t location, eip;
     if (!ScanForReturnAddress(location_start, &location, &eip)) {
       // if we can't find an instruction pointer even with stack scanning,
       // give up.
@@ -369,12 +376,12 @@
     // ability, older OSes (pre-XP SP2) and CPUs (pre-P4) don't enforce
     // an independent execute privilege on memory pages.
 
-    u_int32_t eip = dictionary["$eip"];
+    uint32_t eip = dictionary["$eip"];
     if (modules_ && !modules_->GetModuleForAddress(eip)) {
       // The instruction pointer at .raSearchStart was invalid, so start
       // looking one 32-bit word above that location.
-      u_int32_t location_start = dictionary[".raSearchStart"] + 4;
-      u_int32_t location;
+      uint32_t location_start = dictionary[".raSearchStart"] + 4;
+      uint32_t location;
       if (ScanForReturnAddress(location_start, &location, &eip)) {
         // This is a better return address that what program string
         // evaluation found.  Use it, and set %esp to the location above the
@@ -394,7 +401,7 @@
       // stack.  The scan is performed from the highest possible address to
       // the lowest, because the expectation is that the function's prolog
       // would have saved %ebp early.
-      u_int32_t ebp = dictionary["$ebp"];
+      uint32_t ebp = dictionary["$ebp"];
 
       // When a scan for return address is used, it is possible to skip one or
       // more frames (when return address is not in a known module).  One
@@ -403,13 +410,13 @@
       bool has_skipped_frames =
         (trust != StackFrame::FRAME_TRUST_CFI && ebp <= raSearchStart + offset);
 
-      u_int32_t value;  // throwaway variable to check pointer validity
+      uint32_t value;  // throwaway variable to check pointer validity
       if (has_skipped_frames || !memory_->GetMemoryAtAddress(ebp, &value)) {
         int fp_search_bytes = last_frame_info->saved_register_size + offset;
-        u_int32_t location_end = last_frame->context.esp +
+        uint32_t location_end = last_frame->context.esp +
                                  last_frame_callee_parameter_size;
 
-        for (u_int32_t location = location_end + fp_search_bytes;
+        for (uint32_t location = location_end + fp_search_bytes;
              location >= location_end;
              location -= 4) {
           if (!memory_->GetMemoryAtAddress(location, &ebp))
@@ -486,8 +493,8 @@
     const vector<StackFrame*> &frames) {
   StackFrame::FrameTrust trust;
   StackFrameX86* last_frame = static_cast<StackFrameX86*>(frames.back());
-  u_int32_t last_esp = last_frame->context.esp;
-  u_int32_t last_ebp = last_frame->context.ebp;
+  uint32_t last_esp = last_frame->context.esp;
+  uint32_t last_ebp = last_frame->context.ebp;
 
   // Assume that the standard %ebp-using x86 calling convention is in
   // use.
@@ -512,7 +519,7 @@
   // %esp_new = %ebp_old + 8
   // %ebp_new = *(%ebp_old)
 
-  u_int32_t caller_eip, caller_esp, caller_ebp;
+  uint32_t caller_eip, caller_esp, caller_ebp;
 
   if (memory_->GetMemoryAtAddress(last_ebp + 4, &caller_eip) &&
       memory_->GetMemoryAtAddress(last_ebp, &caller_ebp)) {
@@ -597,14 +604,11 @@
   if (new_frame->context.esp <= last_frame->context.esp)
     return NULL;
 
-  // new_frame->context.eip is the return address, which is one instruction
-  // past the CALL that caused us to arrive at the callee. Set
-  // new_frame->instruction to one less than that. This won't reference the
-  // beginning of the CALL instruction, but it's guaranteed to be within
-  // the CALL, which is sufficient to get the source line information to
-  // match up with the line that contains a function call. Callers that
-  // require the exact return address value may access the context.eip
-  // field of StackFrameX86.
+  // new_frame->context.eip is the return address, which is the instruction
+  // after the CALL that caused us to arrive at the callee. Set
+  // new_frame->instruction to one less than that, so it points within the
+  // CALL instruction. See StackFrame::instruction for details, and
+  // StackFrameAMD64::ReturnAddress.
   new_frame->instruction = new_frame->context.eip - 1;
 
   return new_frame.release();
diff --git a/src/processor/stackwalker_x86.h b/src/processor/stackwalker_x86.h
index 410a473..45e9709 100644
--- a/src/processor/stackwalker_x86.h
+++ b/src/processor/stackwalker_x86.h
@@ -67,7 +67,7 @@
 
  private:
   // A STACK CFI-driven frame walker for the X86.
-  typedef SimpleCFIWalker<u_int32_t, MDRawContextX86> CFIWalker;
+  typedef SimpleCFIWalker<uint32_t, MDRawContextX86> CFIWalker;
 
   // Implementation of Stackwalker, using x86 context (%ebp, %esp, %eip) and
   // stack conventions (saved %ebp at [%ebp], saved %eip at 4[%ebp], or
diff --git a/src/processor/stackwalker_x86_unittest.cc b/src/processor/stackwalker_x86_unittest.cc
index 25801a2..caf899e 100644
--- a/src/processor/stackwalker_x86_unittest.cc
+++ b/src/processor/stackwalker_x86_unittest.cc
@@ -40,6 +40,7 @@
 #include "google_breakpad/common/minidump_format.h"
 #include "google_breakpad/processor/basic_source_line_resolver.h"
 #include "google_breakpad/processor/call_stack.h"
+#include "google_breakpad/processor/code_module.h"
 #include "google_breakpad/processor/source_line_resolver_interface.h"
 #include "google_breakpad/processor/stack_frame_cpu.h"
 #include "processor/stackwalker_unittest_utils.h"
@@ -48,6 +49,7 @@
 
 using google_breakpad::BasicSourceLineResolver;
 using google_breakpad::CallStack;
+using google_breakpad::CodeModule;
 using google_breakpad::StackFrameSymbolizer;
 using google_breakpad::StackFrame;
 using google_breakpad::StackFrameX86;
@@ -118,9 +120,9 @@
 
   // Fill RAW_CONTEXT with pseudo-random data, for round-trip checking.
   void BrandContext(MDRawContextX86 *raw_context) {
-    u_int8_t x = 173;
+    uint8_t x = 173;
     for (size_t i = 0; i < sizeof(*raw_context); i++)
-      reinterpret_cast<u_int8_t *>(raw_context)[i] = (x += 17);
+      reinterpret_cast<uint8_t *>(raw_context)[i] = (x += 17);
   }
   
   SystemInfo system_info;
@@ -153,7 +155,10 @@
   StackwalkerX86 walker(&system_info, &raw_context, &stack_region, &modules,
                         &frame_symbolizer);
   // This should succeed, even without a resolver or supplier.
-  ASSERT_TRUE(walker.Walk(&call_stack));
+  vector<const CodeModule*> modules_without_symbols;
+  ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols));
+  ASSERT_EQ(1U, modules_without_symbols.size());
+  ASSERT_EQ("module1", modules_without_symbols[0]->debug_file());
   frames = call_stack.frames();
   StackFrameX86 *frame = static_cast<StackFrameX86 *>(frames->at(0));
   // Check that the values from the original raw context made it
@@ -173,7 +178,10 @@
   StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
   StackwalkerX86 walker(&system_info, &raw_context, &stack_region, &modules,
                         &frame_symbolizer);
-  ASSERT_TRUE(walker.Walk(&call_stack));
+  vector<const CodeModule*> modules_without_symbols;
+  ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols));
+  ASSERT_EQ(1U, modules_without_symbols.size());
+  ASSERT_EQ("module1", modules_without_symbols[0]->debug_file());
   frames = call_stack.frames();
   StackFrameX86 *frame = static_cast<StackFrameX86 *>(frames->at(0));
   // Check that the values from the original raw context made it
@@ -190,7 +198,10 @@
   StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
   StackwalkerX86 walker(&system_info, &raw_context, NULL, &modules,
                         &frame_symbolizer);
-  ASSERT_TRUE(walker.Walk(&call_stack));
+  vector<const CodeModule*> modules_without_symbols;
+  ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols));
+  ASSERT_EQ(1U, modules_without_symbols.size());
+  ASSERT_EQ("module1", modules_without_symbols[0]->debug_file());
   frames = call_stack.frames();
   StackFrameX86 *frame = static_cast<StackFrameX86 *>(frames->at(0));
   // Check that the values from the original raw context made it
@@ -223,7 +234,10 @@
   StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
   StackwalkerX86 walker(&system_info, &raw_context, &stack_region, &modules,
                         &frame_symbolizer);
-  ASSERT_TRUE(walker.Walk(&call_stack));
+  vector<const CodeModule*> modules_without_symbols;
+  ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols));
+  ASSERT_EQ(1U, modules_without_symbols.size());
+  ASSERT_EQ("module1", modules_without_symbols[0]->debug_file());
   frames = call_stack.frames();
   ASSERT_EQ(2U, frames->size());
 
@@ -279,7 +293,10 @@
   StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
   StackwalkerX86 walker(&system_info, &raw_context, &stack_region, &modules,
                         &frame_symbolizer);
-  ASSERT_TRUE(walker.Walk(&call_stack));
+  vector<const CodeModule*> modules_without_symbols;
+  ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols));
+  ASSERT_EQ(1U, modules_without_symbols.size());
+  ASSERT_EQ("module1", modules_without_symbols[0]->debug_file());
   frames = call_stack.frames();
   ASSERT_EQ(2U, frames->size());
 
@@ -341,7 +358,10 @@
   StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
   StackwalkerX86 walker(&system_info, &raw_context, &stack_region, &modules,
                         &frame_symbolizer);
-  ASSERT_TRUE(walker.Walk(&call_stack));
+  vector<const CodeModule*> modules_without_symbols;
+  ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols));
+  ASSERT_EQ(1U, modules_without_symbols.size());
+  ASSERT_EQ("module1", modules_without_symbols[0]->debug_file());
   frames = call_stack.frames();
   ASSERT_EQ(2U, frames->size());
 
@@ -413,7 +433,9 @@
   StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
   StackwalkerX86 walker(&system_info, &raw_context, &stack_region, &modules,
                         &frame_symbolizer);
-  ASSERT_TRUE(walker.Walk(&call_stack));
+  vector<const CodeModule*> modules_without_symbols;
+  ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols));
+  ASSERT_EQ(0U, modules_without_symbols.size());
   frames = call_stack.frames();
   ASSERT_EQ(2U, frames->size());
 
@@ -485,7 +507,10 @@
   StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
   StackwalkerX86 walker(&system_info, &raw_context, &stack_region, &modules,
                         &frame_symbolizer);
-  ASSERT_TRUE(walker.Walk(&call_stack));
+  vector<const CodeModule*> modules_without_symbols;
+  ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols));
+  ASSERT_EQ(1U, modules_without_symbols.size());
+  ASSERT_EQ("module2", modules_without_symbols[0]->debug_file());
   frames = call_stack.frames();
   ASSERT_EQ(2U, frames->size());
 
@@ -568,7 +593,9 @@
   StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
   StackwalkerX86 walker(&system_info, &raw_context, &stack_region, &modules,
                         &frame_symbolizer);
-  ASSERT_TRUE(walker.Walk(&call_stack));
+  vector<const CodeModule*> modules_without_symbols;
+  ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols));
+  ASSERT_EQ(0U, modules_without_symbols.size());
   frames = call_stack.frames();
   ASSERT_EQ(3U, frames->size());
 
@@ -663,7 +690,9 @@
   StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
   StackwalkerX86 walker(&system_info, &raw_context, &stack_region, &modules,
                         &frame_symbolizer);
-  ASSERT_TRUE(walker.Walk(&call_stack));
+  vector<const CodeModule*> modules_without_symbols;
+  ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols));
+  ASSERT_EQ(0U, modules_without_symbols.size());
   frames = call_stack.frames();
   ASSERT_EQ(2U, frames->size());
 
@@ -747,7 +776,9 @@
   StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
   StackwalkerX86 walker(&system_info, &raw_context, &stack_region, &modules,
                         &frame_symbolizer);
-  ASSERT_TRUE(walker.Walk(&call_stack));
+  vector<const CodeModule*> modules_without_symbols;
+  ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols));
+  ASSERT_EQ(0U, modules_without_symbols.size());
   frames = call_stack.frames();
   ASSERT_EQ(2U, frames->size());
 
@@ -815,7 +846,9 @@
   StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
   StackwalkerX86 walker(&system_info, &raw_context, &stack_region, &modules,
                         &frame_symbolizer);
-  ASSERT_TRUE(walker.Walk(&call_stack));
+  vector<const CodeModule*> modules_without_symbols;
+  ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols));
+  ASSERT_EQ(0U, modules_without_symbols.size());
   frames = call_stack.frames();
   ASSERT_EQ(2U, frames->size());
 
@@ -892,7 +925,9 @@
   StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
   StackwalkerX86 walker(&system_info, &raw_context, &stack_region, &modules,
                         &frame_symbolizer);
-  ASSERT_TRUE(walker.Walk(&call_stack));
+  vector<const CodeModule*> modules_without_symbols;
+  ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols));
+  ASSERT_EQ(0U, modules_without_symbols.size());
   frames = call_stack.frames();
   ASSERT_EQ(2U, frames->size());
 
@@ -1030,7 +1065,9 @@
   StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
   StackwalkerX86 walker(&system_info, &raw_context, &stack_region, &modules,
                         &frame_symbolizer);
-  ASSERT_TRUE(walker.Walk(&call_stack));
+  vector<const CodeModule*> modules_without_symbols;
+  ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols));
+  ASSERT_EQ(0U, modules_without_symbols.size());
   frames = call_stack.frames();
 
   ASSERT_EQ(4U, frames->size());
@@ -1238,7 +1275,9 @@
   StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
   StackwalkerX86 walker(&system_info, &raw_context, &stack_region,
                         &local_modules, &frame_symbolizer);
-  ASSERT_TRUE(walker.Walk(&call_stack));
+  vector<const CodeModule*> modules_without_symbols;
+  ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols));
+  ASSERT_EQ(0U, modules_without_symbols.size());
   frames = call_stack.frames();
 
   ASSERT_EQ(3U, frames->size());
@@ -1365,7 +1404,9 @@
     StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
     StackwalkerX86 walker(&system_info, &raw_context, &stack_region, &modules,
                           &frame_symbolizer);
-    ASSERT_TRUE(walker.Walk(&call_stack));
+    vector<const CodeModule*> modules_without_symbols;
+    ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols));
+    ASSERT_EQ(0U, modules_without_symbols.size());
     frames = call_stack.frames();
     ASSERT_EQ(2U, frames->size());
 
diff --git a/src/processor/static_contained_range_map-inl.h b/src/processor/static_contained_range_map-inl.h
index 46f9bbb..777c762 100644
--- a/src/processor/static_contained_range_map-inl.h
+++ b/src/processor/static_contained_range_map-inl.h
@@ -46,7 +46,7 @@
 StaticContainedRangeMap<AddressType, EntryType>::StaticContainedRangeMap(
     const char *base)
     : base_(*(reinterpret_cast<const AddressType*>(base))),
-      entry_size_(*(reinterpret_cast<const u_int32_t*>(base + sizeof(base_)))),
+      entry_size_(*(reinterpret_cast<const uint32_t*>(base + sizeof(base_)))),
       entry_ptr_(reinterpret_cast<const EntryType *>(
           base + sizeof(base_) + sizeof(entry_size_))),
       map_(base + sizeof(base_) + sizeof(entry_size_) + entry_size_) {
diff --git a/src/processor/static_contained_range_map.h b/src/processor/static_contained_range_map.h
index 4d26e63..6a9b8b7 100644
--- a/src/processor/static_contained_range_map.h
+++ b/src/processor/static_contained_range_map.h
@@ -81,7 +81,7 @@
   // actually contain an entry, so its entry_ field is meaningless.  For
   // this reason, the entry_ field should only be accessed on child
   // ContainedRangeMap objects, and never on |this|.
-  u_int32_t entry_size_;
+  uint32_t entry_size_;
   const EntryType *entry_ptr_;
 
   // The map containing child ranges, keyed by each child range's high
diff --git a/src/processor/static_contained_range_map_unittest.cc b/src/processor/static_contained_range_map_unittest.cc
index 4c0c72d..4ee4757 100644
--- a/src/processor/static_contained_range_map_unittest.cc
+++ b/src/processor/static_contained_range_map_unittest.cc
@@ -33,12 +33,11 @@
 // Author: Siyang Xie (lambxsy@google.com)
 
 #include "breakpad_googletest_includes.h"
+#include "common/scoped_ptr.h"
 #include "processor/contained_range_map-inl.h"
 #include "processor/static_contained_range_map-inl.h"
 #include "processor/simple_serializer-inl.h"
 #include "processor/map_serializers-inl.h"
-
-#include "processor/scoped_ptr.h"
 #include "processor/logging.h"
 
 namespace {
diff --git a/src/processor/static_map-inl.h b/src/processor/static_map-inl.h
index 7727052..e6aac6a 100644
--- a/src/processor/static_map-inl.h
+++ b/src/processor/static_map-inl.h
@@ -47,13 +47,13 @@
     : raw_data_(raw_data),
       compare_() {
   // First 4 Bytes store the number of nodes.
-  num_nodes_ = *(reinterpret_cast<const u_int32_t*>(raw_data_));
+  num_nodes_ = *(reinterpret_cast<const uint32_t*>(raw_data_));
 
-  offsets_ = reinterpret_cast<const u_int32_t*>(
+  offsets_ = reinterpret_cast<const uint32_t*>(
       raw_data_ + sizeof(num_nodes_));
 
   keys_ = reinterpret_cast<const Key*>(
-      raw_data_ + (1 + num_nodes_) * sizeof(u_int32_t));
+      raw_data_ + (1 + num_nodes_) * sizeof(uint32_t));
 }
 
 // find(), lower_bound() and upper_bound() implement binary search algorithm.
@@ -132,14 +132,14 @@
 
   int node_index = 0;
   if (num_nodes_) {
-    u_int64_t first_offset = sizeof(int32_t) * (num_nodes_ + 1)
+    uint64_t first_offset = sizeof(int32_t) * (num_nodes_ + 1)
                            + sizeof(Key) * num_nodes_;
     // Num_nodes_ is too large.
     if (first_offset > 0xffffffffUL) {
       BPLOG(INFO) << "StaticMap check failed: size exceeds limit";
       return false;
     }
-    if (offsets_[node_index] != static_cast<u_int32_t>(first_offset)) {
+    if (offsets_[node_index] != static_cast<uint32_t>(first_offset)) {
       BPLOG(INFO) << "StaticMap check failed: first node offset is incorrect";
       return false;
     }
diff --git a/src/processor/static_map.h b/src/processor/static_map.h
index 15a5573..9723ab2 100644
--- a/src/processor/static_map.h
+++ b/src/processor/static_map.h
@@ -131,7 +131,7 @@
   // Array of offset addresses for stored values.
   // For example:
   // address_of_i-th_node_value = raw_data_ + offsets_[i]
-  const u_int32_t* offsets_;
+  const uint32_t* offsets_;
 
   // keys_[i] = key of i_th node
   const Key* keys_;
diff --git a/src/processor/static_map_iterator-inl.h b/src/processor/static_map_iterator-inl.h
index 325046c..7a7db5a 100644
--- a/src/processor/static_map_iterator-inl.h
+++ b/src/processor/static_map_iterator-inl.h
@@ -48,7 +48,7 @@
   // See static_map.h for documentation on
   // bytes format of serialized StaticMap data.
   num_nodes_ = *(reinterpret_cast<const int32_t*>(base_));
-  offsets_ = reinterpret_cast<const u_int32_t*>(base_ + sizeof(num_nodes_));
+  offsets_ = reinterpret_cast<const uint32_t*>(base_ + sizeof(num_nodes_));
   keys_ = reinterpret_cast<const Key*>(
       base_ + (1 + num_nodes_) * sizeof(num_nodes_));
 }
diff --git a/src/processor/static_map_iterator.h b/src/processor/static_map_iterator.h
index 8127667..1af8fff 100644
--- a/src/processor/static_map_iterator.h
+++ b/src/processor/static_map_iterator.h
@@ -39,7 +39,7 @@
 #ifndef PROCESSOR_STATIC_MAP_ITERATOR_H__
 #define PROCESSOR_STATIC_MAP_ITERATOR_H__
 
-#include <sys/types.h>
+#include "google_breakpad/common/breakpad_types.h"
 
 namespace google_breakpad {
 
@@ -101,7 +101,7 @@
   // offsets_ is an array of offset addresses of mapped values.
   // For example:
   // address_of_i-th_node_value = base_ + offsets_[i]
-  const u_int32_t* offsets_;
+  const uint32_t* offsets_;
 
   // keys_[i] = key of i_th node.
   const Key* keys_;
diff --git a/src/processor/static_map_unittest.cc b/src/processor/static_map_unittest.cc
index eb1e135..97b1e61 100644
--- a/src/processor/static_map_unittest.cc
+++ b/src/processor/static_map_unittest.cc
@@ -49,7 +49,7 @@
   static char* Serialize(const std::map<Key, Value> &stdmap,
                    unsigned int* size = NULL) {
     unsigned int size_per_node =
-        sizeof(u_int32_t) + sizeof(Key) + sizeof(Value);
+        sizeof(uint32_t) + sizeof(Key) + sizeof(Value);
     unsigned int memsize = sizeof(int32_t) + size_per_node * stdmap.size();
     if (size) *size = memsize;
 
@@ -58,12 +58,12 @@
     char* address = mem;
 
     // Writer the number of nodes:
-    new (address) u_int32_t(static_cast<u_int32_t>(stdmap.size()));
-    address += sizeof(u_int32_t);
+    new (address) uint32_t(static_cast<uint32_t>(stdmap.size()));
+    address += sizeof(uint32_t);
 
     // Nodes' offset:
-    u_int32_t* offsets = reinterpret_cast<u_int32_t*>(address);
-    address += sizeof(u_int32_t) * stdmap.size();
+    uint32_t* offsets = reinterpret_cast<uint32_t*>(address);
+    address += sizeof(uint32_t) * stdmap.size();
 
     // Keys:
     Key* keys = reinterpret_cast<Key*>(address);
@@ -95,16 +95,16 @@
 };
 
 TEST_F(TestInvalidMap, TestNegativeNumberNodes) {
-  memset(data, 0xff, sizeof(u_int32_t));  // Set the number of nodes = -1
+  memset(data, 0xff, sizeof(uint32_t));  // Set the number of nodes = -1
   test_map = TestMap(data);
   ASSERT_FALSE(test_map.ValidateInMemoryStructure());
 }
 
 TEST_F(TestInvalidMap, TestWrongOffsets) {
-  u_int32_t* header = reinterpret_cast<u_int32_t*>(data);
-  const u_int32_t kNumNodes = 2;
-  const u_int32_t kHeaderOffset =
-        sizeof(u_int32_t) + kNumNodes * (sizeof(u_int32_t) + sizeof(KeyType));
+  uint32_t* header = reinterpret_cast<uint32_t*>(data);
+  const uint32_t kNumNodes = 2;
+  const uint32_t kHeaderOffset =
+        sizeof(uint32_t) + kNumNodes * (sizeof(uint32_t) + sizeof(KeyType));
 
   header[0] = kNumNodes;
   header[1] = kHeaderOffset + 3;   // Wrong offset for first node
@@ -118,16 +118,16 @@
 }
 
 TEST_F(TestInvalidMap, TestUnSortedKeys) {
-  u_int32_t* header = reinterpret_cast<u_int32_t*>(data);
-  const u_int32_t kNumNodes = 2;
-  const u_int32_t kHeaderOffset =
-      sizeof(u_int32_t) + kNumNodes * (sizeof(u_int32_t) + sizeof(KeyType));
+  uint32_t* header = reinterpret_cast<uint32_t*>(data);
+  const uint32_t kNumNodes = 2;
+  const uint32_t kHeaderOffset =
+      sizeof(uint32_t) + kNumNodes * (sizeof(uint32_t) + sizeof(KeyType));
   header[0] = kNumNodes;
   header[1] = kHeaderOffset;
   header[2] = kHeaderOffset + sizeof(ValueType);
 
   KeyType* keys = reinterpret_cast<KeyType*>(
-      data + (kNumNodes + 1) * sizeof(u_int32_t));
+      data + (kNumNodes + 1) * sizeof(uint32_t));
   // Set keys in non-increasing order.
   keys[0] = 10;
   keys[1] = 7;
@@ -171,10 +171,10 @@
 
     // Set correct size of memory allocation for each test case.
     unsigned int size_per_node =
-        sizeof(u_int32_t) + sizeof(KeyType) + sizeof(ValueType);
+        sizeof(uint32_t) + sizeof(KeyType) + sizeof(ValueType);
     for (testcase = 0; testcase < kNumberTestCases; ++testcase) {
       correct_size[testcase] =
-          sizeof(u_int32_t) + std_map[testcase].size() * size_per_node;
+          sizeof(uint32_t) + std_map[testcase].size() * size_per_node;
     }
   }
 
diff --git a/src/processor/static_range_map_unittest.cc b/src/processor/static_range_map_unittest.cc
index 82b2623..2821736 100644
--- a/src/processor/static_range_map_unittest.cc
+++ b/src/processor/static_range_map_unittest.cc
@@ -32,13 +32,13 @@
 // Author: Siyang Xie (lambxsy@google.com)
 
 #include "breakpad_googletest_includes.h"
+#include "common/scoped_ptr.h"
 #include "processor/range_map-inl.h"
 #include "processor/static_range_map-inl.h"
 #include "processor/simple_serializer-inl.h"
 #include "processor/map_serializers-inl.h"
-
 #include "processor/logging.h"
-#include "processor/scoped_ptr.h"
+
 
 namespace {
 // Types used for testing.
diff --git a/src/processor/synth_minidump.cc b/src/processor/synth_minidump.cc
index b207c0d..377368a 100644
--- a/src/processor/synth_minidump.cc
+++ b/src/processor/synth_minidump.cc
@@ -126,7 +126,10 @@
 Context::Context(const Dump &dump, const MDRawContextX86 &context)
   : Section(dump) {
   // The caller should have properly set the CPU type flag.
-  assert(context.context_flags & MD_CONTEXT_X86);
+  // The high 24 bits identify the CPU.  Note that context records with no CPU
+  // type information can be valid (e.g. produced by ::RtlCaptureContext).
+  assert(((context.context_flags & MD_CONTEXT_CPU_MASK) == 0) ||
+         (context.context_flags & MD_CONTEXT_X86));
   // It doesn't make sense to store x86 registers in big-endian form.
   assert(dump.endianness() == kLittleEndian);
   D32(context.context_flags);
@@ -190,9 +193,9 @@
 }
 
 Thread::Thread(const Dump &dump,
-               u_int32_t thread_id, const Memory &stack, const Context &context,
-               u_int32_t suspend_count, u_int32_t priority_class,
-               u_int32_t priority, u_int64_t teb) : Section(dump) {
+               uint32_t thread_id, const Memory &stack, const Context &context,
+               uint32_t suspend_count, uint32_t priority_class,
+               uint32_t priority, uint64_t teb) : Section(dump) {
   D32(thread_id);
   D32(suspend_count);
   D32(priority_class);
@@ -204,11 +207,11 @@
 }
 
 Module::Module(const Dump &dump,
-               u_int64_t base_of_image,
-               u_int32_t size_of_image,
+               uint64_t base_of_image,
+               uint32_t size_of_image,
                const String &name,
-               u_int32_t time_date_stamp,
-               u_int32_t checksum,
+               uint32_t time_date_stamp,
+               uint32_t checksum,
                const MDVSFixedFileInfo &version_info,
                const Section *cv_record,
                const Section *misc_record) : Section(dump) {
@@ -254,10 +257,10 @@
 
 Exception::Exception(const Dump &dump,
                      const Context &context,
-                     u_int32_t thread_id,
-                     u_int32_t exception_code,
-                     u_int32_t exception_flags,
-                     u_int64_t exception_address)
+                     uint32_t thread_id,
+                     uint32_t exception_code,
+                     uint32_t exception_flags,
+                     uint64_t exception_address)
   : Stream(dump, MD_EXCEPTION_STREAM) {
   D32(thread_id);
   D32(0);  // __align
@@ -273,10 +276,10 @@
   assert(Size() == sizeof(MDRawExceptionStream));
 }
 
-Dump::Dump(u_int64_t flags,
+Dump::Dump(uint64_t flags,
            Endianness endianness,
-           u_int32_t version,
-           u_int32_t date_time_stamp)
+           uint32_t version,
+           uint32_t date_time_stamp)
     : test_assembler::Section(endianness),
       file_start_(0),
       stream_directory_(*this),
diff --git a/src/processor/synth_minidump.h b/src/processor/synth_minidump.h
index 17dbc48..fbc1e29 100644
--- a/src/processor/synth_minidump.h
+++ b/src/processor/synth_minidump.h
@@ -166,14 +166,14 @@
  public:
   // Create a stream of type TYPE.  You can append whatever contents
   // you like to this stream using the test_assembler::Section methods.
-  Stream(const Dump &dump, u_int32_t type) : Section(dump), type_(type) { }
+  Stream(const Dump &dump, uint32_t type) : Section(dump), type_(type) { }
 
   // Append an MDRawDirectory referring to this stream to SECTION.
   void CiteStreamIn(test_assembler::Section *section) const;
 
  private:
   // The type of this stream.
-  u_int32_t type_;
+  uint32_t type_;
 };
 
 class SystemInfo: public Stream {
@@ -211,7 +211,7 @@
 // to memory addresses.
 class Memory: public Section {
  public:
-  Memory(const Dump &dump, u_int64_t address)
+  Memory(const Dump &dump, uint64_t address)
       : Section(dump), address_(address) { start() = address; }
 
   // Append an MDMemoryDescriptor referring to this memory range to SECTION.
@@ -220,7 +220,7 @@
  private:
   // The process address from which these memory contents were taken.
   // Shouldn't this be a Label?
-  u_int64_t address_;
+  uint64_t address_;
 };
 
 class Context: public Section {
@@ -238,13 +238,13 @@
   // Create a thread belonging to DUMP with the given values, citing
   // STACK and CONTEXT (which you must Add to the dump separately).
   Thread(const Dump &dump,
-         u_int32_t thread_id,
+         uint32_t thread_id,
          const Memory &stack,
          const Context &context,
-         u_int32_t suspend_count = 0,
-         u_int32_t priority_class = 0,
-         u_int32_t priority = 0,
-         u_int64_t teb = 0);
+         uint32_t suspend_count = 0,
+         uint32_t priority_class = 0,
+         uint32_t priority = 0,
+         uint64_t teb = 0);
 };
 
 class Module: public Section {
@@ -253,11 +253,11 @@
   // MISC_RECORD can be NULL, in which case the corresponding location
   // descriptior in the minidump will have a length of zero.
   Module(const Dump &dump,
-         u_int64_t base_of_image,
-         u_int32_t size_of_image,
+         uint64_t base_of_image,
+         uint32_t size_of_image,
          const String &name,
-         u_int32_t time_date_stamp = 1262805309,
-         u_int32_t checksum = 0,
+         uint32_t time_date_stamp = 1262805309,
+         uint32_t checksum = 0,
          const MDVSFixedFileInfo &version_info = Module::stock_version_info,
          const Section *cv_record = NULL,
          const Section *misc_record = NULL);
@@ -273,10 +273,10 @@
 public:
   Exception(const Dump &dump,
             const Context &context,
-            u_int32_t thread_id = 0,
-            u_int32_t exception_code = 0,
-            u_int32_t exception_flags = 0,
-            u_int64_t exception_address = 0);
+            uint32_t thread_id = 0,
+            uint32_t exception_code = 0,
+            uint32_t exception_flags = 0,
+            uint64_t exception_address = 0);
 };
 
 // A list of entries starting with a 32-bit count, like a memory list
@@ -284,7 +284,7 @@
 template<typename Element>
 class List: public Stream {
  public:
-  List(const Dump &dump, u_int32_t type) : Stream(dump, type), count_(0) {
+  List(const Dump &dump, uint32_t type) : Stream(dump, type), count_(0) {
     D32(count_label_);
   }
 
@@ -317,10 +317,10 @@
   // header uses the given values. ENDIANNESS determines the
   // endianness of the signature; we set this section's default
   // endianness by this.
-  Dump(u_int64_t flags,
+  Dump(uint64_t flags,
        Endianness endianness = kLittleEndian,
-       u_int32_t version = MD_HEADER_VERSION,
-       u_int32_t date_time_stamp = 1262805309);
+       uint32_t version = MD_HEADER_VERSION,
+       uint32_t date_time_stamp = 1262805309);
 
   // The following functions call OBJECT->Finish(), and append the
   // contents of OBJECT to this minidump. They also record OBJECT in
diff --git a/src/processor/synth_minidump_unittest.cc b/src/processor/synth_minidump_unittest.cc
index 4376933..8835b44 100644
--- a/src/processor/synth_minidump_unittest.cc
+++ b/src/processor/synth_minidump_unittest.cc
@@ -147,7 +147,7 @@
 TEST(ContextDeathTest, X86BadFlags) {
   Dump dump(0, kLittleEndian);
   MDRawContextX86 raw;
-  raw.context_flags = 0;
+  raw.context_flags = MD_CONTEXT_AMD64;
   ASSERT_DEATH(Context context(dump, raw);,
                "context\\.context_flags & (0x[0-9a-f]+|MD_CONTEXT_X86)");
 }
@@ -175,7 +175,7 @@
       0xeb2de4be3f29e3e9ULL); // thread environment block
   string contents;
   ASSERT_TRUE(thread.GetContents(&contents));
-  static const u_int8_t expected_bytes[] = {
+  static const uint8_t expected_bytes[] = {
     0x60, 0xc3, 0x7e, 0x3d, // thread id
     0x4d, 0xf4, 0x93, 0x35, // suspend count
     0x82, 0x2b, 0x35, 0xab, // priority class
@@ -203,7 +203,7 @@
                       0x0919a9b9c9d9e9f9ULL); // exception address
   string contents;
   ASSERT_TRUE(exception.GetContents(&contents));
-  static const u_int8_t expected_bytes[] = {
+  static const uint8_t expected_bytes[] = {
     0xcd, 0xab, 0x34, 0x12, // thread id
     0x00, 0x00, 0x00, 0x00, // __align
     0x21, 0x43, 0xba, 0xdc, // exception code
diff --git a/src/processor/synth_minidump_unittest_data.h b/src/processor/synth_minidump_unittest_data.h
index be3bd70..3403372 100644
--- a/src/processor/synth_minidump_unittest_data.h
+++ b/src/processor/synth_minidump_unittest_data.h
@@ -130,7 +130,7 @@
   }
 };
 
-static const u_int8_t x86_expected_contents[] = {
+static const uint8_t x86_expected_contents[] = {
   0x1b, 0xd7, 0xd5, 0xde,
   0x2e, 0x43, 0xdb, 0x9f,
   0x1a, 0xa8, 0xb7, 0x26,
@@ -320,7 +320,7 @@
   }
 };
 
-static const u_int8_t arm_expected_contents[] = {
+static const uint8_t arm_expected_contents[] = {
   0x6a, 0x9e, 0x1b, 0x59,
   0xde, 0x94, 0x15, 0xa2,
   0x25, 0x8a, 0x0d, 0x82,
diff --git a/src/processor/testdata/minidump2.stackwalk.machine_readable.out b/src/processor/testdata/minidump2.stackwalk.machine_readable.out
index 2f3b0f5..60f8af4 100644
--- a/src/processor/testdata/minidump2.stackwalk.machine_readable.out
+++ b/src/processor/testdata/minidump2.stackwalk.machine_readable.out
@@ -16,6 +16,6 @@
 Module|ntdll.dll|5.1.2600.2180|ntdll.pdb|36515FB5D04345E491F672FA2E2878C02|0x7c900000|0x7c9affff|0
 
 0|0|test_app.exe|`anonymous namespace'::CrashFunction|c:\test_app.cc|58|0x3
-0|1|test_app.exe|main|c:\test_app.cc|65|0x4
-0|2|test_app.exe|__tmainCRTStartup|f:\sp\vctools\crt_bld\self_x86\crt\src\crt0.c|327|0x11
-0|3|kernel32.dll|BaseProcessStart|||0x22
+0|1|test_app.exe|main|c:\test_app.cc|65|0x5
+0|2|test_app.exe|__tmainCRTStartup|f:\sp\vctools\crt_bld\self_x86\crt\src\crt0.c|327|0x12
+0|3|kernel32.dll|BaseProcessStart|||0x23
diff --git a/src/processor/testdata/minidump2.stackwalk.out b/src/processor/testdata/minidump2.stackwalk.out
index 5b98867..20d1c4d 100644
--- a/src/processor/testdata/minidump2.stackwalk.out
+++ b/src/processor/testdata/minidump2.stackwalk.out
@@ -13,13 +13,13 @@
     esi = 0x00000002   edi = 0x00000a28   eax = 0x00000045   ecx = 0x0012fe94
     edx = 0x0042bc58   efl = 0x00010246
     Found by: given as instruction pointer in context
- 1  test_app.exe!main [test_app.cc : 65 + 0x4]
+ 1  test_app.exe!main [test_app.cc : 65 + 0x5]
     eip = 0x00404200   esp = 0x0012fe90   ebp = 0x0012ff70
     Found by: call frame info
- 2  test_app.exe!__tmainCRTStartup [crt0.c : 327 + 0x11]
+ 2  test_app.exe!__tmainCRTStartup [crt0.c : 327 + 0x12]
     eip = 0x004053ec   esp = 0x0012ff78   ebp = 0x0012ffc0
     Found by: call frame info
- 3  kernel32.dll!BaseProcessStart + 0x22
+ 3  kernel32.dll!BaseProcessStart + 0x23
     eip = 0x7c816fd7   esp = 0x0012ffc8   ebp = 0x0012fff0
     Found by: call frame info
 
diff --git a/src/processor/tokenize.cc b/src/processor/tokenize.cc
index e398c52..a5b028e 100644
--- a/src/processor/tokenize.cc
+++ b/src/processor/tokenize.cc
@@ -36,6 +36,10 @@
 
 namespace google_breakpad {
 
+#ifdef _WIN32
+#define strtok_r strtok_s
+#endif
+
 using std::vector;
 
 bool Tokenize(char *line,
diff --git a/src/processor/windows_frame_info.h b/src/processor/windows_frame_info.h
index 8af4b3f..c92c610 100644
--- a/src/processor/windows_frame_info.h
+++ b/src/processor/windows_frame_info.h
@@ -51,6 +51,10 @@
 
 namespace google_breakpad {
 
+#ifdef _WIN32
+#define strtoull _strtoui64
+#endif
+
 struct WindowsFrameInfo {
  public:
   enum Validity {
@@ -85,12 +89,12 @@
                      program_string() {}
 
   WindowsFrameInfo(StackInfoTypes type,
-                 u_int32_t set_prolog_size,
-                 u_int32_t set_epilog_size,
-                 u_int32_t set_parameter_size,
-                 u_int32_t set_saved_register_size,
-                 u_int32_t set_local_size,
-                 u_int32_t set_max_stack_size,
+                 uint32_t set_prolog_size,
+                 uint32_t set_epilog_size,
+                 uint32_t set_parameter_size,
+                 uint32_t set_saved_register_size,
+                 uint32_t set_local_size,
+                 uint32_t set_max_stack_size,
                  int set_allocates_base_pointer,
                  const string set_program_string)
       : type_(type),
@@ -110,9 +114,9 @@
   // but not the StackFrameInfo structure, so return them as outparams.
   static WindowsFrameInfo *ParseFromString(const string string,
                                            int &type,
-                                           u_int64_t &rva,
-                                           u_int64_t &code_size) {
-    // The format of a STACK WIN record is documented at: 
+                                           uint64_t &rva,
+                                           uint64_t &code_size) {
+    // The format of a STACK WIN record is documented at:
     //
     // http://code.google.com/p/google-breakpad/wiki/SymbolFiles
 
@@ -128,12 +132,12 @@
 
     rva                           = strtoull(tokens[1],  NULL, 16);
     code_size                     = strtoull(tokens[2],  NULL, 16);
-    u_int32_t prolog_size         =  strtoul(tokens[3],  NULL, 16);
-    u_int32_t epilog_size         =  strtoul(tokens[4],  NULL, 16);
-    u_int32_t parameter_size      =  strtoul(tokens[5],  NULL, 16);
-    u_int32_t saved_register_size =  strtoul(tokens[6],  NULL, 16);
-    u_int32_t local_size          =  strtoul(tokens[7],  NULL, 16);
-    u_int32_t max_stack_size      =  strtoul(tokens[8],  NULL, 16);
+    uint32_t prolog_size          =  strtoul(tokens[3],  NULL, 16);
+    uint32_t epilog_size          =  strtoul(tokens[4],  NULL, 16);
+    uint32_t parameter_size       =  strtoul(tokens[5],  NULL, 16);
+    uint32_t saved_register_size  =  strtoul(tokens[6],  NULL, 16);
+    uint32_t local_size           =  strtoul(tokens[7],  NULL, 16);
+    uint32_t max_stack_size       =  strtoul(tokens[8],  NULL, 16);
     int has_program_string        =  strtoul(tokens[9], NULL, 16);
 
     const char *program_string = "";
@@ -186,12 +190,12 @@
   int valid;
 
   // These values come from IDiaFrameData.
-  u_int32_t prolog_size;
-  u_int32_t epilog_size;
-  u_int32_t parameter_size;
-  u_int32_t saved_register_size;
-  u_int32_t local_size;
-  u_int32_t max_stack_size;
+  uint32_t prolog_size;
+  uint32_t epilog_size;
+  uint32_t parameter_size;
+  uint32_t saved_register_size;
+  uint32_t local_size;
+  uint32_t max_stack_size;
 
   // Only one of allocates_base_pointer or program_string will be valid.
   // If program_string is empty, use allocates_base_pointer.
diff --git a/src/third_party/curl/curlbuild.h b/src/third_party/curl/curlbuild.h
index bab11ac..648cf02 100644
--- a/src/third_party/curl/curlbuild.h
+++ b/src/third_party/curl/curlbuild.h
@@ -154,7 +154,7 @@
 #endif
 
 /* The size of `long', as computed by sizeof. */
-#if defined(_M_X64) || defined(__x86_64__)
+#if defined(_M_X64) || (defined(__x86_64__) && !defined(__ILP32__))
 #define CURL_SIZEOF_LONG 8
 #else
 #define CURL_SIZEOF_LONG 4
@@ -170,7 +170,7 @@
 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__)
+#if defined(_M_X64) || (defined(__x86_64__) && !defined(__ILP32__))
 #define CURL_TYPEOF_CURL_OFF_T long
 #else
 #define CURL_TYPEOF_CURL_OFF_T int64_t
diff --git a/src/tools/linux/dump_syms/dump_syms.cc b/src/tools/linux/dump_syms/dump_syms.cc
index adac216..f58952e 100644
--- a/src/tools/linux/dump_syms/dump_syms.cc
+++ b/src/tools/linux/dump_syms/dump_syms.cc
@@ -32,6 +32,7 @@
 #include <cstring>
 #include <iostream>
 #include <string>
+#include <vector>
 
 #include "common/linux/dump_symbols.h"
 
@@ -39,7 +40,7 @@
 
 int usage(const char* self) {
   fprintf(stderr, "Usage: %s [OPTION] <binary-with-debugging-info> "
-          "[directory-for-debug-file]\n\n", self);
+          "[directories-for-debug-file]\n\n", self);
   fprintf(stderr, "Options:\n");
   fprintf(stderr, "  -c    Do not generate CFI section\n");
   return 1;
@@ -50,24 +51,25 @@
     return usage(argv[0]);
 
   bool cfi = true;
-  if (strcmp("-c", argv[1]) == 0)
+  int binary_index = 1;
+  if (strcmp("-c", argv[1]) == 0) {
     cfi = false;
+    ++binary_index;
+  }
   if (!cfi && argc == 2)
     return usage(argv[0]);
 
   const char *binary;
-  std::string debug_dir;
-  if (cfi) {
-    binary = argv[1];
-    if (argc == 3)
-      debug_dir = argv[2];
-  } else {
-    binary = argv[2];
-    if (argc == 4)
-      debug_dir = argv[3];
+  std::vector<string> debug_dirs;
+  binary = argv[binary_index];
+  for (int debug_dir_index = binary_index + 1;
+       debug_dir_index < argc;
+       ++debug_dir_index) {
+    debug_dirs.push_back(argv[debug_dir_index]);
   }
 
-  if (!WriteSymbolFile(binary, debug_dir, cfi, std::cout)) {
+  SymbolData symbol_data = cfi ? ALL_SYMBOL_DATA : NO_CFI;
+  if (!WriteSymbolFile(binary, debug_dirs, symbol_data, std::cout)) {
     fprintf(stderr, "Failed to write symbol file.\n");
     return 1;
   }
diff --git a/src/tools/linux/md2core/minidump-2-core.cc b/src/tools/linux/md2core/minidump-2-core.cc
index b29d317..93c46aa 100644
--- a/src/tools/linux/md2core/minidump-2-core.cc
+++ b/src/tools/linux/md2core/minidump-2-core.cc
@@ -47,8 +47,8 @@
 #include <vector>
 
 #include "common/linux/memory_mapped_file.h"
+#include "common/scoped_ptr.h"
 #include "google_breakpad/common/minidump_format.h"
-#include "processor/scoped_ptr.h"
 #include "third_party/lss/linux_syscall_support.h"
 #include "tools/linux/md2core/minidump_memory_range.h"
 
@@ -500,9 +500,9 @@
     fputs("MD_LINUX_MAPS:\n", stderr);
     fwrite(range.data(), range.length(), 1, stderr);
   }
-  for (const u_int8_t* ptr = range.data();
+  for (const uint8_t* ptr = range.data();
        ptr < range.data() + range.length();) {
-    const u_int8_t* eol = (u_int8_t*)memchr(ptr, '\n',
+    const uint8_t* eol = (uint8_t*)memchr(ptr, '\n',
                                        range.data() + range.length() - ptr);
     std::string line((const char*)ptr,
                      eol ? eol - ptr : range.data() + range.length() - ptr);
diff --git a/src/tools/linux/md2core/minidump_memory_range.h b/src/tools/linux/md2core/minidump_memory_range.h
index b0d8255..a793e2c 100644
--- a/src/tools/linux/md2core/minidump_memory_range.h
+++ b/src/tools/linux/md2core/minidump_memory_range.h
@@ -75,8 +75,8 @@
     std::string str;
     const MDString* md_str = GetData<MDString>(sub_offset);
     if (md_str) {
-      const u_int16_t* buffer = &md_str->buffer[0];
-      for (u_int32_t i = 0; i < md_str->length && buffer[i]; ++i) {
+      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]);
       }
     }
diff --git a/src/tools/linux/md2core/minidump_memory_range_unittest.cc b/src/tools/linux/md2core/minidump_memory_range_unittest.cc
index f4994fe..fe4ded8 100644
--- a/src/tools/linux/md2core/minidump_memory_range_unittest.cc
+++ b/src/tools/linux/md2core/minidump_memory_range_unittest.cc
@@ -38,9 +38,9 @@
 
 namespace {
 
-const u_int32_t kBuffer[10] = { 0 };
+const uint32_t kBuffer[10] = { 0 };
 const size_t kBufferSize = sizeof(kBuffer);
-const u_int8_t* kBufferPointer = reinterpret_cast<const u_int8_t*>(kBuffer);
+const uint8_t* kBufferPointer = reinterpret_cast<const uint8_t*>(kBuffer);
 
 // Test vectors for verifying Covers, GetData, and Subrange.
 const struct {
@@ -222,7 +222,7 @@
 }
 
 TEST(MinidumpMemoryRangeTest, GetAsciiMDString) {
-  u_int8_t buffer[100] = { 0 };
+  uint8_t buffer[100] = { 0 };
 
   MDString* md_str = reinterpret_cast<MDString*>(buffer);
   md_str->length = 4;
@@ -233,7 +233,7 @@
   md_str->buffer[4] = '\0';
 
   size_t str2_offset =
-      sizeof(MDString) + (md_str->length + 1) * sizeof(u_int16_t);
+      sizeof(MDString) + (md_str->length + 1) * sizeof(uint16_t);
 
   md_str = reinterpret_cast<MDString*>(buffer + str2_offset);
   md_str->length = 9;  // Test length larger than actual string
diff --git a/src/tools/mac/crash_report/crash_report.mm b/src/tools/mac/crash_report/crash_report.mm
index 78eb6f2..b6e3f1c 100644
--- a/src/tools/mac/crash_report/crash_report.mm
+++ b/src/tools/mac/crash_report/crash_report.mm
@@ -39,6 +39,7 @@
 
 #include <Foundation/Foundation.h>
 
+#include "common/scoped_ptr.h"
 #include "google_breakpad/processor/basic_source_line_resolver.h"
 #include "google_breakpad/processor/call_stack.h"
 #include "google_breakpad/processor/code_module.h"
@@ -48,7 +49,6 @@
 #include "google_breakpad/processor/stack_frame_cpu.h"
 #include "google_breakpad/processor/system_info.h"
 #include "processor/pathname_stripper.h"
-#include "processor/scoped_ptr.h"
 #include "processor/simple_symbol_supplier.h"
 
 #include "on_demand_symbol_supplier.h"
diff --git a/src/tools/mac/dump_syms/dump_syms_tool.mm b/src/tools/mac/dump_syms/dump_syms_tool.mm
index 14bbcbb..68321db 100644
--- a/src/tools/mac/dump_syms/dump_syms_tool.mm
+++ b/src/tools/mac/dump_syms/dump_syms_tool.mm
@@ -54,7 +54,7 @@
 
 //=============================================================================
 static bool Start(const Options &options) {
-  DumpSymbols dump_symbols;
+  DumpSymbols dump_symbols(options.cfi ? ALL_SYMBOL_DATA : NO_CFI);
 
   if (!dump_symbols.Read(options.srcPath))
     return false;
@@ -86,7 +86,7 @@
     }
   }
 
-  return dump_symbols.WriteSymbolFile(std::cout, options.cfi);
+  return dump_symbols.WriteSymbolFile(std::cout);
 }
 
 //=============================================================================
diff --git a/src/tools/python/filter_syms.py b/src/tools/python/filter_syms.py
new file mode 100644
index 0000000..738cb3e
--- /dev/null
+++ b/src/tools/python/filter_syms.py
@@ -0,0 +1,204 @@
+#!/usr/bin/env python
+# Copyright (c) 2012 Google Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#     * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+"""Normalizes and de-duplicates paths within Breakpad symbol files.
+
+When using DWARF for storing debug symbols, some file information will be
+stored relative to the current working directory of the current compilation
+unit, and may be further relativized based upon how the file was #included.
+
+This helper can be used to parse the Breakpad symbol file generated from such
+DWARF files and normalize and de-duplicate the FILE records found within,
+updating any references to the FILE records in the other record types.
+"""
+
+import macpath
+import ntpath
+import optparse
+import os
+import posixpath
+import sys
+
+class BreakpadParseError(Exception):
+  """Unsupported Breakpad symbol record exception class."""
+  pass
+
+class SymbolFileParser(object):
+  """Parser for Breakpad symbol files.
+
+  The format of these files is documented at
+  https://code.google.com/p/google-breakpad/wiki/SymbolFiles
+  """
+
+  def __init__(self, input_stream, output_stream, ignored_prefixes=None,
+               path_handler=os.path):
+    """Inits a SymbolFileParser to read symbol records from |input_stream| and
+    write the processed output to |output_stream|.
+    
+    |ignored_prefixes| contains a list of optional path prefixes that
+    should be stripped from the final, normalized path outputs.
+    
+    For example, if the Breakpad symbol file had all paths starting with a
+    common prefix, such as:
+      FILE 1 /b/build/src/foo.cc
+      FILE 2 /b/build/src/bar.cc
+    Then adding "/b/build/src" as an ignored prefix would result in an output
+    file that contained:
+      FILE 1 foo.cc
+      FILE 2 bar.cc
+    
+    Note that |ignored_prefixes| does not necessarily contain file system
+    paths, as the contents of the DWARF DW_AT_comp_dir attribute is dependent
+    upon the host system and compiler, and may contain additional information
+    such as hostname or compiler version.
+    """
+
+    self.unique_files = {}
+    self.duplicate_files = {}
+    self.input_stream = input_stream
+    self.output_stream = output_stream
+    self.ignored_prefixes = ignored_prefixes or []
+    self.path_handler = path_handler
+
+  def Process(self):
+    """Processes the Breakpad symbol file."""
+    for line in self.input_stream:
+      parsed = self._ParseRecord(line.rstrip())
+      if parsed:
+        self.output_stream.write(parsed + '\n')
+
+  def _ParseRecord(self, record):
+    """Parses a single Breakpad symbol record - a single line from the symbol
+    file.
+
+    Returns:
+        The modified string to write to the output file, or None if no line
+        should be written.
+    """
+    record_type = record.partition(' ')[0]
+    if record_type == 'FILE':
+      return self._ParseFileRecord(record)
+    elif self._IsLineRecord(record_type):
+      return self._ParseLineRecord(record)
+    else:
+      # Simply pass the record through unaltered.
+      return record
+
+  def _NormalizePath(self, path):
+    """Normalizes a file path to its canonical form.
+
+    As this may not execute on the machine or file system originally
+    responsible for compilation, it may be necessary to further correct paths
+    for symlinks, junctions, or other such file system indirections.
+
+    Returns:
+        A unique, canonical representation for the the file path.
+    """
+    return self.path_handler.normpath(path)
+
+  def _AdjustPath(self, path):
+    """Adjusts the supplied path after performing path de-duplication.
+
+    This may be used to perform secondary adjustments, such as removing a
+    common prefix, such as "/D/build", or replacing the file system path with
+    information from the version control system.
+
+    Returns:
+        The actual path to use when writing the FILE record.
+    """
+    return path[len(filter(path.startswith,
+                           self.ignored_prefixes + [''])[0]):]
+
+  def _ParseFileRecord(self, file_record):
+    """Parses and corrects a FILE record."""
+    file_info = file_record[5:].split(' ', 3)
+    if len(file_info) > 2:
+      raise BreakpadParseError('Unsupported FILE record: ' + file_record)
+    file_index = int(file_info[0])
+    file_name = self._NormalizePath(file_info[1])
+    existing_file_index = self.unique_files.get(file_name)
+    if existing_file_index is None:
+      self.unique_files[file_name] = file_index
+      file_info[1] = self._AdjustPath(file_name)
+      return 'FILE ' + ' '.join(file_info)
+    else:
+      self.duplicate_files[file_index] = existing_file_index
+      return None
+
+  def _IsLineRecord(self, record_type):
+    """Determines if the current record type is a Line record"""
+    try:
+      line = int(record_type, 16)
+    except (ValueError, TypeError):
+      return False
+    return True
+
+  def _ParseLineRecord(self, line_record):
+    """Parses and corrects a Line record."""
+    line_info = line_record.split(' ', 5)
+    if len(line_info) > 4:
+      raise BreakpadParseError('Unsupported Line record: ' + line_record)
+    file_index = int(line_info[3])
+    line_info[3] = str(self.duplicate_files.get(file_index, file_index))
+    return ' '.join(line_info)
+
+def main():
+  option_parser = optparse.OptionParser()
+  option_parser.add_option("-p", "--prefix",
+                           action="append", dest="prefixes", type="string",
+                           default=[],
+                           help="A path prefix that should be removed from "
+                                "all FILE lines. May be repeated to specify "
+                                "multiple prefixes.")
+  option_parser.add_option("-t", "--path_type",
+                           action="store", type="choice", dest="path_handler",
+                           choices=['win32', 'posix'],
+                           help="Indicates how file paths should be "
+                                "interpreted. The default is to treat paths "
+                                "the same as the OS running Python (eg: "
+                                "os.path)")
+  options, args = option_parser.parse_args()
+  if args:
+    option_parser.error('Unknown argument: %s' % args)
+
+  path_handler = { 'win32': ntpath,
+                   'posix': posixpath }.get(options.path_handler, os.path)
+  try:
+    symbol_parser = SymbolFileParser(sys.stdin, sys.stdout, options.prefixes,
+                                     path_handler)
+    symbol_parser.Process()
+  except BreakpadParseError, e:
+    print >> sys.stderr, 'Got an error while processing symbol file'
+    print >> sys.stderr, str(e)
+    return 1
+  return 0
+
+if __name__ == '__main__':
+  sys.exit(main())
diff --git a/src/tools/python/tests/filter_syms_unittest.py b/src/tools/python/tests/filter_syms_unittest.py
new file mode 100644
index 0000000..b111f34
--- /dev/null
+++ b/src/tools/python/tests/filter_syms_unittest.py
@@ -0,0 +1,138 @@
+#!/usr/bin/env python
+# Copyright (c) 2012 Google Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#     * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+"""Unit tests for filter_syms.py"""
+
+import cStringIO
+import ntpath
+import os
+import StringIO
+import sys
+import unittest
+
+ROOT_DIR = os.path.dirname(os.path.abspath(__file__))
+sys.path.insert(0, os.path.join(ROOT_DIR, '..'))
+
+# In root
+import filter_syms
+
+class FilterSysmsTest(unittest.TestCase):
+  def assertParsed(self, input_data, ignored_prefixes, expected):
+    input_io = cStringIO.StringIO(input_data)
+    output_io = cStringIO.StringIO()
+    parser = filter_syms.SymbolFileParser(input_io, output_io,
+                                          ignored_prefixes, ntpath)
+    parser.Process()
+    self.assertEqual(output_io.getvalue(), expected)
+    
+  def testDuplicateFiles(self):
+    """Tests that duplicate files in FILE records are correctly removed and
+    that Line records are updated."""
+
+    INPUT = \
+"""MODULE windows x86 111111111111111111111111111111111 module1.pdb
+INFO CODE_ID FFFFFFFF module1.exe
+FILE 1 foo/../file1_1.cc
+FILE 2 bar/../file1_1.cc
+FILE 3 baz/../file1_1.cc
+FUNC 1000 c 0 Function1_1
+1000 8 45 2
+1008 4 46 3
+100c 4 44 1
+"""
+    EXPECTED_OUTPUT = \
+"""MODULE windows x86 111111111111111111111111111111111 module1.pdb
+INFO CODE_ID FFFFFFFF module1.exe
+FILE 1 file1_1.cc
+FUNC 1000 c 0 Function1_1
+1000 8 45 1
+1008 4 46 1
+100c 4 44 1
+"""
+    self.assertParsed(INPUT, [], EXPECTED_OUTPUT)
+
+  def testIgnoredPrefix(self):
+    """Tests that prefixes in FILE records are correctly removed."""
+
+    INPUT = \
+"""MODULE windows x86 111111111111111111111111111111111 module1.pdb
+INFO CODE_ID FFFFFFFF module1.exe
+FILE 1 /src/build/foo/../file1_1.cc
+FILE 2 /src/build/bar/../file1_2.cc
+FILE 3 /src/build/baz/../file1_2.cc
+FUNC 1000 c 0 Function1_1
+1000 8 45 2
+1008 4 46 3
+100c 4 44 1
+"""
+    EXPECTED_OUTPUT = \
+"""MODULE windows x86 111111111111111111111111111111111 module1.pdb
+INFO CODE_ID FFFFFFFF module1.exe
+FILE 1 file1_1.cc
+FILE 2 file1_2.cc
+FUNC 1000 c 0 Function1_1
+1000 8 45 2
+1008 4 46 2
+100c 4 44 1
+"""
+    IGNORED_PREFIXES = ['\\src\\build\\']
+    self.assertParsed(INPUT, IGNORED_PREFIXES, EXPECTED_OUTPUT)
+
+  def testIgnoredPrefixesDuplicateFiles(self):
+    """Tests that de-duplication of FILE records happens BEFORE prefixes
+    are removed."""
+
+    INPUT = \
+"""MODULE windows x86 111111111111111111111111111111111 module1.pdb
+INFO CODE_ID FFFFFFFF module1.exe
+FILE 1 /src/build/foo/../file1_1.cc
+FILE 2 /src/build/bar/../file1_2.cc
+FILE 3 D:/src/build2/baz/../file1_2.cc
+FUNC 1000 c 0 Function1_1
+1000 8 45 2
+1008 4 46 3
+100c 4 44 1
+"""
+    EXPECTED_OUTPUT = \
+"""MODULE windows x86 111111111111111111111111111111111 module1.pdb
+INFO CODE_ID FFFFFFFF module1.exe
+FILE 1 file1_1.cc
+FILE 2 file1_2.cc
+FILE 3 file1_2.cc
+FUNC 1000 c 0 Function1_1
+1000 8 45 2
+1008 4 46 3
+100c 4 44 1
+"""
+    IGNORED_PREFIXES = ['\\src\\build\\', 'D:\\src\\build2\\']
+    self.assertParsed(INPUT, IGNORED_PREFIXES, EXPECTED_OUTPUT)
+
+if __name__ == '__main__':
+  unittest.main()
\ No newline at end of file