Bug 1518947 - Update breakpad to revision 44384d80b32a5bb361c2ec3bee667f7ccee566d7. r=ted a=lizzard
authorGabriele Svelto <gsvelto@mozilla.com>
Thu, 31 Jan 2019 15:50:54 +0000
changeset 515756 c916c1117a67cae04c6808de1e80824ab5cf13fb
parent 515755 373e61d5d56f98a293423d7662a4de7a1534ef68
child 515757 1079d285dd4006cf27fd867d29c7e408a7627365
push id1953
push userffxbld-merge
push dateMon, 11 Mar 2019 12:10:20 +0000
treeherdermozilla-release@9c35dcbaa899 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersted, lizzard
bugs1518947, 1489094, 1511140
milestone66.0
Bug 1518947 - Update breakpad to revision 44384d80b32a5bb361c2ec3bee667f7ccee566d7. r=ted a=lizzard This includes some assorted fixes from upstream plus an adaptation of the patch in b988fa74ec18de6214b18f723e48331d9a7802ae which includes heap memory regions in the minidump. Since our support for that is more extensive than upstream breakpad the resulting change reflects this. Last but not least the fixes for bug 1489094 and bug 1511140 were split out as patches to be applied to the unmodified breakpad sources. They will be reintegrated as soon as we fork breakpad for good. Differential Revision: https://phabricator.services.mozilla.com/D16326
toolkit/crashreporter/breakpad-client/linux/handler/exception_handler.cc
toolkit/crashreporter/breakpad-client/linux/handler/exception_handler.h
toolkit/crashreporter/breakpad-client/linux/handler/exception_handler_unittest.cc
toolkit/crashreporter/breakpad-client/windows/common/minidump_callback.cc
toolkit/crashreporter/breakpad-client/windows/handler/exception_handler.cc
toolkit/crashreporter/breakpad-patches/01-llvm-windows-symbol-fixup.patch
toolkit/crashreporter/breakpad-patches/02-define-print-mach-result.patch
toolkit/crashreporter/breakpad-patches/03-strstr-libc-replacement.patch
toolkit/crashreporter/google-breakpad/GIT-INFO
toolkit/crashreporter/google-breakpad/src/common/dwarf_cu_to_module.cc
toolkit/crashreporter/google-breakpad/src/common/mac/arch_utilities.cc
toolkit/crashreporter/google-breakpad/src/processor/logging.h
toolkit/crashreporter/google-breakpad/src/processor/minidump.cc
toolkit/crashreporter/google-breakpad/src/processor/minidump_processor.cc
toolkit/crashreporter/google-breakpad/src/processor/minidump_processor_unittest.cc
toolkit/crashreporter/google-breakpad/src/tools/mac/dump_syms/dump_syms.xcodeproj/project.pbxproj
toolkit/crashreporter/google-breakpad/src/tools/mac/upload_system_symbols/arch_constants.h
toolkit/crashreporter/google-breakpad/src/tools/mac/upload_system_symbols/arch_reader.go
toolkit/crashreporter/update-breakpad.sh
--- a/toolkit/crashreporter/breakpad-client/linux/handler/exception_handler.cc
+++ b/toolkit/crashreporter/breakpad-client/linux/handler/exception_handler.cc
@@ -211,16 +211,17 @@ pthread_mutex_t g_handler_stack_mutex_ =
 
 // sizeof(CrashContext) can be too big w.r.t the size of alternatate stack
 // for SignalHandler(). Keep the crash context as a .bss field. Exception
 // handlers are serialized by the |g_handler_stack_mutex_| and at most one at a
 // time can use |g_crash_context_|.
 ExceptionHandler::CrashContext g_crash_context_;
 
 FirstChanceHandler g_first_chance_handler_ = nullptr;
+FirstChanceHandlerDeprecated g_first_chance_handler_deprecated_ = nullptr;
 bool g_skip_sigill_ = false;
 }  // namespace
 
 // Runs before crashing: normal context.
 ExceptionHandler::ExceptionHandler(const MinidumpDescriptor& descriptor,
                                    FilterCallback filter,
                                    MinidumpCallback callback,
                                    void* callback_context,
@@ -344,16 +345,21 @@ void ExceptionHandler::SignalHandler(int
   // safety in WebAssembly. This means some signals might be expected if they
   // originate from Wasm code while accessing the guard region. We give V8 the
   // chance to handle and recover from these signals first.
   if (g_first_chance_handler_ != nullptr &&
       g_first_chance_handler_(sig, info, uc)) {
     return;
   }
 
+  if (g_first_chance_handler_deprecated_ != nullptr &&
+      g_first_chance_handler_deprecated_(sig, info, uc)) {
+    return;
+  }
+
   // All the exception signals are blocked at this point.
   pthread_mutex_lock(&g_handler_stack_mutex_);
 
   // Sometimes, Breakpad runs inside a process where some other buggy code
   // saves and restores signal handlers temporarily with 'signal'
   // instead of 'sigaction'. This loses the SA_SIGINFO flag associated
   // with this function. As a consequence, the values of 'info' and 'uc'
   // become totally bogus, generally inducing a crash.
@@ -821,12 +827,18 @@ bool ExceptionHandler::WriteMinidumpForC
                                       child,
                                       child_blamed_thread))
       return false;
 
   return callback ? callback(descriptor, callback_context, true) : true;
 }
 
 void SetFirstChanceExceptionHandler(FirstChanceHandler callback) {
+  g_first_chance_handler_deprecated_ = nullptr;
   g_first_chance_handler_ = callback;
 }
 
+void SetFirstChanceExceptionHandler(FirstChanceHandlerDeprecated callback) {
+  g_first_chance_handler_ = nullptr;
+  g_first_chance_handler_deprecated_ = callback;
+}
+
 }  // namespace google_breakpad
--- a/toolkit/crashreporter/breakpad-client/linux/handler/exception_handler.h
+++ b/toolkit/crashreporter/breakpad-client/linux/handler/exception_handler.h
@@ -268,15 +268,19 @@ class ExceptionHandler {
   // dumper code cannot extract enough information from /proc/<pid>/maps.
   MappingList mapping_list_;
 
   // Callers can request additional memory regions to be included in
   // the dump.
   AppMemoryList app_memory_list_;
 };
 
+typedef bool (*FirstChanceHandler)(int, siginfo_t*, void*);
+void SetFirstChanceExceptionHandler(FirstChanceHandler callback);
 
-typedef bool (*FirstChanceHandler)(int, void*, void*);
-void SetFirstChanceExceptionHandler(FirstChanceHandler callback);
+typedef bool (*FirstChanceHandlerDeprecated)(int, void*, void*);
+// Deprecated. Use SetFirstChanceExceptionHandler(FirstChanceHandler callback)
+// instead.
+void SetFirstChanceExceptionHandler(FirstChanceHandlerDeprecated callback);
 
 }  // namespace google_breakpad
 
 #endif  // CLIENT_LINUX_HANDLER_EXCEPTION_HANDLER_H_
--- a/toolkit/crashreporter/breakpad-client/linux/handler/exception_handler_unittest.cc
+++ b/toolkit/crashreporter/breakpad-client/linux/handler/exception_handler_unittest.cc
@@ -523,21 +523,42 @@ TEST(ExceptionHandlerTest, StackedHandle
                             -1);
     CrashWithCallbacks(NULL, DoneCallbackReturnFalse, temp_dir.path());
   }
   ASSERT_NO_FATAL_FAILURE(WaitForProcessToTerminate(child, SIGKILL));
 }
 
 namespace {
 const int kSimpleFirstChanceReturnStatus = 42;
-bool SimpleFirstChanceHandler(int, void*, void*) {
+bool SimpleFirstChanceHandlerDeprecated(int, void*, void*) {
+  _exit(kSimpleFirstChanceReturnStatus);
+}
+
+bool SimpleFirstChanceHandler(int, siginfo_t*, void*) {
   _exit(kSimpleFirstChanceReturnStatus);
 }
 }
 
+TEST(ExceptionHandlerTest, FirstChanceHandlerRunsDeprecated) {
+  AutoTempDir temp_dir;
+
+  const pid_t child = fork();
+  if (child == 0) {
+    ExceptionHandler handler(
+        MinidumpDescriptor(temp_dir.path()), NULL, NULL, NULL, true, -1);
+    google_breakpad::SetFirstChanceExceptionHandler(
+        SimpleFirstChanceHandlerDeprecated);
+    DoNullPointerDereference();
+  }
+  int status;
+  ASSERT_NE(HANDLE_EINTR(waitpid(child, &status, 0)), -1);
+  ASSERT_TRUE(WIFEXITED(status));
+  ASSERT_EQ(kSimpleFirstChanceReturnStatus, WEXITSTATUS(status));
+}
+
 TEST(ExceptionHandlerTest, FirstChanceHandlerRuns) {
   AutoTempDir temp_dir;
 
   const pid_t child = fork();
   if (child == 0) {
     ExceptionHandler handler(
         MinidumpDescriptor(temp_dir.path()), NULL, NULL, NULL, true, -1);
     google_breakpad::SetFirstChanceExceptionHandler(SimpleFirstChanceHandler);
--- a/toolkit/crashreporter/breakpad-client/windows/common/minidump_callback.cc
+++ b/toolkit/crashreporter/breakpad-client/windows/common/minidump_callback.cc
@@ -207,16 +207,24 @@ void IncludeAppMemoryFromExceptionContex
     heapAddrCandidates[numElements++] = aExceptionContext->R10;
     heapAddrCandidates[numElements++] = aExceptionContext->R11;
     heapAddrCandidates[numElements++] = aExceptionContext->R12;
     heapAddrCandidates[numElements++] = aExceptionContext->R13;
     heapAddrCandidates[numElements++] = aExceptionContext->R14;
     heapAddrCandidates[numElements++] = aExceptionContext->R15;
   }
   heapAddrCandidates[numElements++] = aExceptionContext->Rip;
+#elif defined(_M_ARM64)
+  if (!aInstructionPointerOnly) {
+    for (auto reg : aExceptionContext->X) {
+      heapAddrCandidates[numElements++] = reg;
+    }
+    heapAddrCandidates[numElements++] = aExceptionContext->Sp;
+  }
+  heapAddrCandidates[numElements++] = aExceptionContext->Pc;
 #endif
 
   // Inplace sort the candidates for excluding or merging memory regions.
   auto begin = &heapAddrCandidates[0], end = &heapAddrCandidates[numElements];
   std::make_heap(begin, end);
   std::sort_heap(begin, end);
 
   auto appMemory = FindNextPreallocated(aList, aList.begin());
--- a/toolkit/crashreporter/breakpad-client/windows/handler/exception_handler.cc
+++ b/toolkit/crashreporter/breakpad-client/windows/handler/exception_handler.cc
@@ -380,17 +380,17 @@ bool ExceptionHandler::RequestUpload(DWO
 
 // static
 DWORD ExceptionHandler::ExceptionHandlerThreadMain(void* lpParameter) {
   ExceptionHandler* self = reinterpret_cast<ExceptionHandler *>(lpParameter);
   assert(self);
   assert(self->handler_start_semaphore_ != NULL);
   assert(self->handler_finish_semaphore_ != NULL);
 
-  while (true) {
+  for (;;) {
     if (WaitForSingleObject(self->handler_start_semaphore_, INFINITE) ==
         WAIT_OBJECT_0) {
       // Perform the requested action.
       if (self->is_shutdown_) {
         // The instance of the exception handler is being destroyed.
         break;
       } else {
         self->handler_return_value_ =
new file mode 100644
--- /dev/null
+++ b/toolkit/crashreporter/breakpad-patches/01-llvm-windows-symbol-fixup.patch
@@ -0,0 +1,84 @@
+diff --git a/src/common/windows/pdb_source_line_writer.cc b/src/common/windows/pdb_source_line_writer.cc
+--- a/src/common/windows/pdb_source_line_writer.cc
++++ b/src/common/windows/pdb_source_line_writer.cc
+@@ -1019,34 +1019,50 @@ bool PDBSourceLineWriter::FindPEFile() {
+         }
+       }
+     }
+   }
+ 
+   return false;
+ }
+ 
++static const DWORD kUndecorateOptions =
++    UNDNAME_NO_MS_KEYWORDS | UNDNAME_NO_FUNCTION_RETURNS |
++    UNDNAME_NO_ALLOCATION_MODEL | UNDNAME_NO_ALLOCATION_LANGUAGE |
++    UNDNAME_NO_THISTYPE | UNDNAME_NO_ACCESS_SPECIFIERS |
++    UNDNAME_NO_THROW_SIGNATURES | UNDNAME_NO_MEMBER_TYPE |
++    UNDNAME_NO_RETURN_UDT_MODEL | UNDNAME_NO_ECSU;
++
++static void FixupLlvmUniqueSymbol(BSTR *name) {
++  wchar_t *suffix = wcsstr(*name, L".llvm.");
++
++  if (suffix != nullptr) {
++    *suffix = L'\0';
++
++    const size_t undecorated_len = 1024;
++    wchar_t undecorated[undecorated_len] = {};
++    DWORD res = UnDecorateSymbolNameW(*name, undecorated, undecorated_len,
++                                      kUndecorateOptions);
++    if (res == 0) {
++      fprintf(stderr, "failed to undecorate symbol %S\n", *name);
++    } else {
++      SysFreeString(*name);
++      *name = SysAllocString(undecorated);
++    }
++  }
++}
++
+ // static
+ bool PDBSourceLineWriter::GetSymbolFunctionName(IDiaSymbol *function,
+                                                 BSTR *name,
+                                                 int *stack_param_size) {
+   *stack_param_size = -1;
+-  const DWORD undecorate_options = UNDNAME_NO_MS_KEYWORDS |
+-                                   UNDNAME_NO_FUNCTION_RETURNS |
+-                                   UNDNAME_NO_ALLOCATION_MODEL |
+-                                   UNDNAME_NO_ALLOCATION_LANGUAGE |
+-                                   UNDNAME_NO_THISTYPE |
+-                                   UNDNAME_NO_ACCESS_SPECIFIERS |
+-                                   UNDNAME_NO_THROW_SIGNATURES |
+-                                   UNDNAME_NO_MEMBER_TYPE |
+-                                   UNDNAME_NO_RETURN_UDT_MODEL |
+-                                   UNDNAME_NO_ECSU;
+ 
+   // Use get_undecoratedNameEx to get readable C++ names with arguments.
+-  if (function->get_undecoratedNameEx(undecorate_options, name) != S_OK) {
++  if (function->get_undecoratedNameEx(kUndecorateOptions, name) != S_OK) {
+     if (function->get_name(name) != S_OK) {
+       fprintf(stderr, "failed to get function name\n");
+       return false;
+     }
+ 
+     // It's possible for get_name to return an empty string, so
+     // special-case that.
+     if (wcscmp(*name, L"") == 0) {
+@@ -1060,16 +1076,18 @@ bool PDBSourceLineWriter::GetSymbolFunct
+     // it's already formatted properly to be used as output.  Don't do any
+     // additional processing.
+     //
+     // MSVC7's DIA seems to not undecorate names in as many cases as MSVC8's.
+     // This will result in calling get_name for some C++ symbols, so
+     // all of the parameter and return type information may not be included in
+     // the name string.
+   } else {
++    FixupLlvmUniqueSymbol(name);
++
+     // C++ uses a bogus "void" argument for functions and methods that don't
+     // take any parameters.  Take it out of the undecorated name because it's
+     // ugly and unnecessary.
+     const wchar_t *replace_string = L"(void)";
+     const size_t replace_length = wcslen(replace_string);
+     const wchar_t *replacement_string = L"()";
+     size_t length = wcslen(*name);
+     if (length >= replace_length) {
new file mode 100644
--- /dev/null
+++ b/toolkit/crashreporter/breakpad-patches/02-define-print-mach-result.patch
@@ -0,0 +1,24 @@
+diff --git a/src/common/mac/MachIPC.h b/src/common/mac/MachIPC.h
+--- a/src/common/mac/MachIPC.h
++++ b/src/common/mac/MachIPC.h
+@@ -90,18 +90,20 @@
+ //
+ //    char messageString[] = "Hello server!\n";
+ //    message.SetData(messageString, strlen(messageString)+1);
+ //
+ //    kern_return_t result = sender.SendMessage(message, 1000); // timeout 1000ms
+ //
+ 
+ namespace google_breakpad {
++#ifndef PRINT_MACH_RESULT
+ #define PRINT_MACH_RESULT(result_, message_) \
+   printf(message_" %s (%d)\n", mach_error_string(result_), result_ );
++#endif
+ 
+ //==============================================================================
+ // A wrapper class for mach_msg_port_descriptor_t (with same memory layout)
+ // with convenient constructors and accessors
+ class MachMsgPortDescriptor : public mach_msg_port_descriptor_t {
+  public:
+   // General-purpose constructor
+   MachMsgPortDescriptor(mach_port_t in_name,
new file mode 100644
--- /dev/null
+++ b/toolkit/crashreporter/breakpad-patches/03-strstr-libc-replacement.patch
@@ -0,0 +1,54 @@
+diff --git a/src/common/linux/linux_libc_support.cc b/src/common/linux/linux_libc_support.cc
+--- a/src/common/linux/linux_libc_support.cc
++++ b/src/common/linux/linux_libc_support.cc
+@@ -133,16 +133,27 @@ const char* my_strrchr(const char* hayst
+   while (*haystack) {
+     if (*haystack == needle)
+       ret = haystack;
+     haystack++;
+   }
+   return ret;
+ }
+ 
++const char* my_strstr(const char* haystack, const char* needle) {
++  while (*haystack != 0) {
++    if((*haystack == *needle) &&
++       (my_strncmp(haystack, needle, my_strlen(needle)) == 0)) {
++      return haystack;
++    }
++    haystack++;
++  }
++  return nullptr;
++}
++
+ void* my_memchr(const void* src, int needle, size_t src_len) {
+   const unsigned char* p = (const unsigned char*)src;
+   const unsigned char* p_end = p + src_len;
+   for (; p < p_end; ++p) {
+     if (*p == needle)
+       return (void*)p;
+   }
+   return NULL;
+diff --git a/src/common/linux/linux_libc_support.h b/src/common/linux/linux_libc_support.h
+--- a/src/common/linux/linux_libc_support.h
++++ b/src/common/linux/linux_libc_support.h
+@@ -62,16 +62,18 @@ extern unsigned my_uint_len(uintmax_t i)
+ //   i: the unsigned integer to serialise.
+ //   i_len: the length of the integer in base 10 (see |my_uint_len|).
+ extern void my_uitos(char* output, uintmax_t i, unsigned i_len);
+ 
+ extern const char* my_strchr(const char* haystack, char needle);
+ 
+ extern const char* my_strrchr(const char* haystack, char needle);
+ 
++extern const char *my_strstr(const char *haystack, const char *needle);
++
+ // Read a hex value
+ //   result: (output) the resulting value
+ //   s: a string
+ // Returns a pointer to the first invalid charactor.
+ extern const char* my_read_hex_ptr(uintptr_t* result, const char* s);
+ 
+ extern const char* my_read_decimal_ptr(uintptr_t* result, const char* s);
+ 
+
--- a/toolkit/crashreporter/google-breakpad/GIT-INFO
+++ b/toolkit/crashreporter/google-breakpad/GIT-INFO
@@ -1,1 +1,1 @@
-1459e5df74dd03b7d3d473e6d271413d7aa98a88
+44384d80b32a5bb361c2ec3bee667f7ccee566d7
--- a/toolkit/crashreporter/google-breakpad/src/common/dwarf_cu_to_module.cc
+++ b/toolkit/crashreporter/google-breakpad/src/common/dwarf_cu_to_module.cc
@@ -926,32 +926,35 @@ class FunctionRange {
     function->lines.push_back(line);
   }
 
   Module::Address address;
   Module::Address size;
   Module::Function *function;
 };
 
-// Fills an array of ranges with pointers to the functions which owns them.
-// The array is sorted in ascending order and the ranges are non-overlapping.
+// Fills an array of ranges with pointers to the functions which owns
+// them. The array is sorted in ascending order and the ranges are non
+// empty and non-overlapping.
 
 static void FillSortedFunctionRanges(vector<FunctionRange> &dest_ranges,
                                      vector<Module::Function *> *functions) {
   for (vector<Module::Function *>::const_iterator func_it = functions->cbegin();
        func_it != functions->cend();
        func_it++)
   {
     Module::Function *func = *func_it;
     vector<Module::Range> &ranges = func->ranges;
     for (vector<Module::Range>::const_iterator ranges_it = ranges.cbegin();
          ranges_it != ranges.cend();
          ++ranges_it) {
       FunctionRange range(*ranges_it, func);
-      dest_ranges.push_back(range);
+      if (range.size != 0) {
+          dest_ranges.push_back(range);
+      }
     }
   }
 
   sort(dest_ranges.begin(), dest_ranges.end(),
     [](const FunctionRange &fr1, const FunctionRange &fr2) {
       return fr1.address < fr2.address;
     }
   );
--- a/toolkit/crashreporter/google-breakpad/src/common/mac/arch_utilities.cc
+++ b/toolkit/crashreporter/google-breakpad/src/common/mac/arch_utilities.cc
@@ -41,25 +41,41 @@
 #ifndef CPU_TYPE_ARM64
 #define CPU_TYPE_ARM64 (CPU_TYPE_ARM | CPU_ARCH_ABI64)
 #endif  // CPU_TYPE_ARM64
 
 #ifndef CPU_SUBTYPE_ARM64_ALL
 #define CPU_SUBTYPE_ARM64_ALL (static_cast<cpu_subtype_t>(0))
 #endif  // CPU_SUBTYPE_ARM64_ALL
 
+#ifndef CPU_SUBTYPE_ARM64_E
+#define CPU_SUBTYPE_ARM64_E (static_cast<cpu_subtype_t>(2))
+#endif  // CPU_SUBTYPE_ARM64_E
+
 namespace {
 
-const NXArchInfo* ArchInfo_arm64() {
+const NXArchInfo* ArchInfo_arm64(cpu_subtype_t cpu_subtype) {
+  const char* name = NULL;
+  switch (cpu_subtype) {
+    case CPU_SUBTYPE_ARM64_ALL:
+      name = "arm64";
+      break;
+    case CPU_SUBTYPE_ARM64_E:
+      name = "arm64e";
+      break;
+    default:
+      return NULL;
+  }
+
   NXArchInfo* arm64 = new NXArchInfo;
   *arm64 = *NXGetArchInfoFromCpuType(CPU_TYPE_ARM,
                                      CPU_SUBTYPE_ARM_V7);
-  arm64->name = "arm64";
+  arm64->name = name;
   arm64->cputype = CPU_TYPE_ARM64;
-  arm64->cpusubtype = CPU_SUBTYPE_ARM64_ALL;
+  arm64->cpusubtype = cpu_subtype;
   arm64->description = "arm 64";
   return arm64;
 }
 
 const NXArchInfo* ArchInfo_armv7s() {
   NXArchInfo* armv7s = new NXArchInfo;
   *armv7s = *NXGetArchInfoFromCpuType(CPU_TYPE_ARM,
                                       CPU_SUBTYPE_ARM_V7);
@@ -74,31 +90,40 @@ const NXArchInfo* ArchInfo_armv7s() {
 namespace google_breakpad {
 
 const NXArchInfo* BreakpadGetArchInfoFromName(const char* arch_name) {
   // TODO: Remove this when the OS knows about arm64.
   if (!strcmp("arm64", arch_name))
     return BreakpadGetArchInfoFromCpuType(CPU_TYPE_ARM64,
                                           CPU_SUBTYPE_ARM64_ALL);
 
+  if (!strcmp("arm64e", arch_name))
+    return BreakpadGetArchInfoFromCpuType(CPU_TYPE_ARM64,
+                                          CPU_SUBTYPE_ARM64_E);
+
   // TODO: Remove this when the OS knows about armv7s.
   if (!strcmp("armv7s", arch_name))
     return BreakpadGetArchInfoFromCpuType(CPU_TYPE_ARM, CPU_SUBTYPE_ARM_V7S);
 
   return NXGetArchInfoFromName(arch_name);
 }
 
 const NXArchInfo* BreakpadGetArchInfoFromCpuType(cpu_type_t cpu_type,
                                                  cpu_subtype_t cpu_subtype) {
   // TODO: Remove this when the OS knows about arm64.
   if (cpu_type == CPU_TYPE_ARM64 && cpu_subtype == CPU_SUBTYPE_ARM64_ALL) {
-    static const NXArchInfo* arm64 = ArchInfo_arm64();
+    static const NXArchInfo* arm64 = ArchInfo_arm64(cpu_subtype);
     return arm64;
   }
 
+  if (cpu_type == CPU_TYPE_ARM64 && cpu_subtype == CPU_SUBTYPE_ARM64_E) {
+    static const NXArchInfo* arm64e = ArchInfo_arm64(cpu_subtype);
+    return arm64e;
+  }
+
   // TODO: Remove this when the OS knows about armv7s.
   if (cpu_type == CPU_TYPE_ARM && cpu_subtype == CPU_SUBTYPE_ARM_V7S) {
     static const NXArchInfo* armv7s = ArchInfo_armv7s();
     return armv7s;
   }
 
   return NXGetArchInfoFromCpuType(cpu_type, cpu_subtype);
 }
@@ -109,16 +134,17 @@ const NXArchInfo* BreakpadGetArchInfoFro
 namespace {
 
 enum Architecture {
   kArch_i386 = 0,
   kArch_x86_64,
   kArch_x86_64h,
   kArch_arm,
   kArch_arm64,
+  kArch_arm64e,
   kArch_ppc,
   // This must be last.
   kNumArchitectures
 };
 
 // enum Architecture above and kKnownArchitectures below
 // must be kept in sync.
 const NXArchInfo kKnownArchitectures[] = {
@@ -153,16 +179,23 @@ const NXArchInfo kKnownArchitectures[] =
   {
     "arm64",
     CPU_TYPE_ARM64,
     CPU_SUBTYPE_ARM64_ALL,
     NX_LittleEndian,
     "ARM64"
   },
   {
+    "arm64e",
+    CPU_TYPE_ARM64,
+    CPU_SUBTYPE_ARM64_E,
+    NX_LittleEndian,
+    "ARM64e"
+  },
+  {
     "ppc",
     CPU_TYPE_POWERPC,
     CPU_SUBTYPE_POWERPC_ALL,
     NX_BigEndian,
     "PowerPC"
   }
 };
 
--- a/toolkit/crashreporter/google-breakpad/src/processor/logging.h
+++ b/toolkit/crashreporter/google-breakpad/src/processor/logging.h
@@ -142,19 +142,21 @@ string HexString(int number);
 int ErrnoString(string *error_string);
 
 }  // namespace google_breakpad
 
 #ifndef BPLOG_INIT
 #define BPLOG_INIT(pargc, pargv)
 #endif  // BPLOG_INIT
 
+#ifndef BPLOG_LAZY_STREAM
 #define BPLOG_LAZY_STREAM(stream, condition) \
     !(condition) ? (void) 0 : \
                    google_breakpad::LogMessageVoidify() & (BPLOG_ ## stream)
+#endif
 
 #ifndef BPLOG_MINIMUM_SEVERITY
 #define BPLOG_MINIMUM_SEVERITY SEVERITY_INFO
 #endif
 
 #define BPLOG_LOG_IS_ON(severity) \
     ((google_breakpad::LogStream::SEVERITY_ ## severity) >= \
      (google_breakpad::LogStream::BPLOG_MINIMUM_SEVERITY))
@@ -185,12 +187,14 @@ int ErrnoString(string *error_string);
 #ifndef BPLOG_CRITICAL_STREAM
 #define BPLOG_CRITICAL_STREAM std::cerr
 #endif  // BPLOG_CRITICAL_STREAM
 #define BPLOG_CRITICAL google_breakpad::LogStream(BPLOG_CRITICAL_STREAM, \
                         google_breakpad::LogStream::SEVERITY_CRITICAL, \
                         __FILE__, __LINE__)
 #endif  // BPLOG_CRITICAL
 
+#ifndef BPLOG_IF
 #define BPLOG_IF(severity, condition) \
     BPLOG_LAZY_STREAM(severity, ((condition) && BPLOG_LOG_IS_ON(severity)))
+#endif  // BPLOG_IF
 
 #endif  // PROCESSOR_LOGGING_H__
--- a/toolkit/crashreporter/google-breakpad/src/processor/minidump.cc
+++ b/toolkit/crashreporter/google-breakpad/src/processor/minidump.cc
@@ -2394,17 +2394,21 @@ const uint8_t* MinidumpModule::GetCVReco
     } else if (signature == MD_CVINFOELF_SIGNATURE) {
       // Now that the structure type is known, recheck the size.
       if (MDCVInfoELF_minsize > module_.cv_record.data_size) {
         BPLOG(ERROR) << "MinidumpModule CodeViewELF record size mismatch, " <<
                         MDCVInfoELF_minsize << " > " <<
                         module_.cv_record.data_size;
         return NULL;
       }
-      // There's nothing to swap in CVInfoELF, it's just raw bytes.
+      if (minidump_->swap()) {
+        MDCVInfoELF* cv_record_elf =
+            reinterpret_cast<MDCVInfoELF*>(&(*cv_record)[0]);
+        Swap(&cv_record_elf->cv_signature);
+      }
     }
 
     // If the signature doesn't match something above, it's not something
     // that Breakpad can presently handle directly.  Because some modules in
     // the wild contain such CodeView records as MD_CVINFOCV50_SIGNATURE,
     // don't bail out here - allow the data to be returned to the user,
     // although byte-swapping can't be done.
 
--- a/toolkit/crashreporter/google-breakpad/src/processor/minidump_processor.cc
+++ b/toolkit/crashreporter/google-breakpad/src/processor/minidump_processor.cc
@@ -350,16 +350,36 @@ static const MDRawSystemInfo* GetSystemI
     return NULL;
 
   if (system_info)
     *system_info = minidump_system_info;
 
   return minidump_system_info->system_info();
 }
 
+static uint64_t GetAddressForArchitecture(const MDCPUArchitecture architecture,
+                                          size_t raw_address)
+{
+  switch (architecture) {
+    case MD_CPU_ARCHITECTURE_X86:
+    case MD_CPU_ARCHITECTURE_MIPS:
+    case MD_CPU_ARCHITECTURE_PPC:
+    case MD_CPU_ARCHITECTURE_SHX:
+    case MD_CPU_ARCHITECTURE_ARM:
+    case MD_CPU_ARCHITECTURE_X86_WIN64:
+      // 32-bit architectures, mask the upper bits.
+      return raw_address & 0xffffffffULL;
+
+    default:
+      // All other architectures either have 64-bit pointers or it's impossible
+      // to tell from the minidump (e.g. MSIL or SPARC) so use 64-bits anyway.
+      return raw_address;
+  }
+}
+
 // Extract CPU info string from ARM-specific MDRawSystemInfo structure.
 // raw_info: pointer to source MDRawSystemInfo.
 // cpu_info: address of target string, cpu info text will be appended to it.
 static void GetARMCpuInfo(const MDRawSystemInfo* raw_info,
                           string* cpu_info) {
   assert(raw_info != NULL && cpu_info != NULL);
 
   // Write ARM architecture version.
@@ -530,16 +550,17 @@ bool MinidumpProcessor::GetCPUInfo(Minid
     }
 
     case MD_CPU_ARCHITECTURE_ARM: {
       info->cpu = "arm";
       GetARMCpuInfo(raw_system_info, &info->cpu_info);
       break;
     }
 
+    case MD_CPU_ARCHITECTURE_ARM64:
     case MD_CPU_ARCHITECTURE_ARM64_OLD: {
       info->cpu = "arm64";
       break;
     }
 
     case MD_CPU_ARCHITECTURE_MIPS: {
       info->cpu = "mips";
       break;
@@ -1631,16 +1652,22 @@ string MinidumpProcessor::GetCrashReason
     }
 
     default: {
       BPLOG(INFO) << "Unknown exception reason " << reason;
       break;
     }
   }
 
+  if (address) {
+    *address = GetAddressForArchitecture(
+      static_cast<MDCPUArchitecture>(raw_system_info->processor_architecture),
+      *address);
+  }
+
   return reason;
 }
 
 // static
 string MinidumpProcessor::GetAssertion(Minidump *dump) {
   MinidumpAssertion *assertion = dump->GetAssertion();
   if (!assertion)
     return "";
--- a/toolkit/crashreporter/google-breakpad/src/processor/minidump_processor_unittest.cc
+++ b/toolkit/crashreporter/google-breakpad/src/processor/minidump_processor_unittest.cc
@@ -198,16 +198,22 @@ static const char *kSystemInfoCPUInfo =
 #define ASSERT_TRUE_ABORT(cond) \
   if (!(cond)) {                                                        \
     fprintf(stderr, "FAILED: %s at %s:%d\n", #cond, __FILE__, __LINE__); \
     abort(); \
   }
 
 #define ASSERT_EQ_ABORT(e1, e2) ASSERT_TRUE_ABORT((e1) == (e2))
 
+static string GetTestDataPath() {
+  char *srcdir = getenv("srcdir");
+
+  return string(srcdir ? srcdir : ".") + "/src/processor/testdata/";
+}
+
 class TestSymbolSupplier : public SymbolSupplier {
  public:
   TestSymbolSupplier() : interrupt_(false) {}
 
   virtual SymbolResult GetSymbolFile(const CodeModule *module,
                                      const SystemInfo *system_info,
                                      string *symbol_file);
 
@@ -244,20 +250,18 @@ SymbolSupplier::SymbolResult TestSymbolS
   ASSERT_EQ_ABORT(system_info->os_short, kSystemInfoOSShort);
   ASSERT_EQ_ABORT(system_info->os_version, kSystemInfoOSVersion);
 
   if (interrupt_) {
     return INTERRUPT;
   }
 
   if (module && module->code_file() == "c:\\test_app.exe") {
-      *symbol_file = string(getenv("srcdir") ? getenv("srcdir") : ".") +
-                     "/src/processor/testdata/symbols/test_app.pdb/" +
-                     module->debug_identifier() +
-                     "/test_app.sym";
+      *symbol_file = GetTestDataPath() + "symbols/test_app.pdb/" +
+                     module->debug_identifier() + "/test_app.sym";
     return FOUND;
   }
 
   return NOT_FOUND;
 }
 
 SymbolSupplier::SymbolResult TestSymbolSupplier::GetSymbolFile(
     const CodeModule *module,
@@ -455,18 +459,17 @@ TEST_F(MinidumpProcessorTest, TestCorrup
 
 // This test case verifies that the symbol supplier is only consulted
 // once per minidump per module.
 TEST_F(MinidumpProcessorTest, TestSymbolSupplierLookupCounts) {
   MockSymbolSupplier supplier;
   BasicSourceLineResolver resolver;
   MinidumpProcessor processor(&supplier, &resolver);
 
-  string minidump_file = string(getenv("srcdir") ? getenv("srcdir") : ".") +
-                         "/src/processor/testdata/minidump2.dmp";
+  string minidump_file = GetTestDataPath() + "minidump2.dmp";
   ProcessState state;
   EXPECT_CALL(supplier, GetCStringSymbolData(
       Property(&google_breakpad::CodeModule::code_file,
                "c:\\test_app.exe"),
       _, _, _, _)).WillOnce(Return(SymbolSupplier::NOT_FOUND));
   EXPECT_CALL(supplier, GetCStringSymbolData(
       Property(&google_breakpad::CodeModule::code_file,
                Ne("c:\\test_app.exe")),
@@ -496,18 +499,17 @@ TEST_F(MinidumpProcessorTest, TestSymbol
             google_breakpad::PROCESS_OK);
 }
 
 TEST_F(MinidumpProcessorTest, TestBasicProcessing) {
   TestSymbolSupplier supplier;
   BasicSourceLineResolver resolver;
   MinidumpProcessor processor(&supplier, &resolver);
 
-  string minidump_file = string(getenv("srcdir") ? getenv("srcdir") : ".") +
-                         "/src/processor/testdata/minidump2.dmp";
+  string minidump_file = GetTestDataPath() + "minidump2.dmp";
 
   ProcessState state;
   ASSERT_EQ(processor.Process(minidump_file, &state),
             google_breakpad::PROCESS_OK);
   ASSERT_EQ(state.system_info()->os, kSystemInfoOS);
   ASSERT_EQ(state.system_info()->os_short, kSystemInfoOSShort);
   ASSERT_EQ(state.system_info()->os_version, kSystemInfoOSVersion);
   ASSERT_EQ(state.system_info()->cpu, kSystemInfoCPU);
@@ -734,14 +736,34 @@ TEST_F(MinidumpProcessorTest, TestThread
   EXPECT_EQ(processor.Process(&dump, &state),
             google_breakpad::PROCESS_OK);
 
   // Should have a single thread with zero frames.
   ASSERT_EQ(1U, state.threads()->size());
   ASSERT_EQ(0U, state.threads()->at(0)->frames()->size());
 }
 
+TEST_F(MinidumpProcessorTest, Test32BitCrashingAddress) {
+  TestSymbolSupplier supplier;
+  BasicSourceLineResolver resolver;
+  MinidumpProcessor processor(&supplier, &resolver);
+
+  string minidump_file = GetTestDataPath() + "minidump_32bit_crash_addr.dmp";
+
+  ProcessState state;
+  ASSERT_EQ(processor.Process(minidump_file, &state),
+            google_breakpad::PROCESS_OK);
+  ASSERT_EQ(state.system_info()->os, kSystemInfoOS);
+  ASSERT_EQ(state.system_info()->os_short, kSystemInfoOSShort);
+  ASSERT_EQ(state.system_info()->os_version, kSystemInfoOSVersion);
+  ASSERT_EQ(state.system_info()->cpu, kSystemInfoCPU);
+  ASSERT_EQ(state.system_info()->cpu_info, kSystemInfoCPUInfo);
+  ASSERT_TRUE(state.crashed());
+  ASSERT_EQ(state.crash_reason(), "EXCEPTION_ACCESS_VIOLATION_WRITE");
+  ASSERT_EQ(state.crash_address(), 0x45U);
+}
+
 }  // namespace
 
 int main(int argc, char *argv[]) {
   ::testing::InitGoogleTest(&argc, argv);
   return RUN_ALL_TESTS();
 }
--- a/toolkit/crashreporter/google-breakpad/src/tools/mac/dump_syms/dump_syms.xcodeproj/project.pbxproj
+++ b/toolkit/crashreporter/google-breakpad/src/tools/mac/dump_syms/dump_syms.xcodeproj/project.pbxproj
@@ -31,16 +31,18 @@
 			productName = all_unittests;
 		};
 /* End PBXAggregateTarget section */
 
 /* Begin PBXBuildFile section */
 		162F64FA161C591500CD68D5 /* arch_utilities.cc in Sources */ = {isa = PBXBuildFile; fileRef = 162F64F8161C591500CD68D5 /* arch_utilities.cc */; };
 		162F6500161C5F2200CD68D5 /* arch_utilities.cc in Sources */ = {isa = PBXBuildFile; fileRef = 162F64F8161C591500CD68D5 /* arch_utilities.cc */; };
 		4247E63D2110D4B200482558 /* path_helper.cc in Sources */ = {isa = PBXBuildFile; fileRef = EB06C7511FEBC515000214D9 /* path_helper.cc */; };
+		4262382721AC496F00E5A3A6 /* dwarf_range_list_handler.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4262382521AC496F00E5A3A6 /* dwarf_range_list_handler.cc */; };
+		4262382821AC49A000E5A3A6 /* dwarf_range_list_handler.h in Sources */ = {isa = PBXBuildFile; fileRef = 4262382621AC496F00E5A3A6 /* dwarf_range_list_handler.h */; };
 		4D72CAF513DFBAC2006CABE3 /* md5.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4D72CAF413DFBAC2006CABE3 /* md5.cc */; };
 		8BCAAA4C1CE3A7980046090B /* elf_reader.cc in Sources */ = {isa = PBXBuildFile; fileRef = 8BCAAA4A1CE3A7980046090B /* elf_reader.cc */; };
 		8BCAAA4D1CE3B1260046090B /* elf_reader.cc in Sources */ = {isa = PBXBuildFile; fileRef = 8BCAAA4A1CE3A7980046090B /* elf_reader.cc */; };
 		B84A91F8116CF78F006C210E /* libgtestmockall.a in Frameworks */ = {isa = PBXBuildFile; fileRef = B88FB024116BDFFF00407530 /* libgtestmockall.a */; };
 		B84A91FB116CF7AF006C210E /* module.cc in Sources */ = {isa = PBXBuildFile; fileRef = B88FAE241166603300407530 /* module.cc */; };
 		B84A91FC116CF7AF006C210E /* stabs_to_module.cc in Sources */ = {isa = PBXBuildFile; fileRef = B88FAE3C11666C8900407530 /* stabs_to_module.cc */; };
 		B84A91FD116CF7AF006C210E /* stabs_to_module_unittest.cc in Sources */ = {isa = PBXBuildFile; fileRef = B88FB0D8116CEC0600407530 /* stabs_to_module_unittest.cc */; };
 		B88FAE1911665FE400407530 /* dwarf2diehandler.cc in Sources */ = {isa = PBXBuildFile; fileRef = B88FAE1711665FE400407530 /* dwarf2diehandler.cc */; };
@@ -273,16 +275,18 @@
 		};
 /* End PBXContainerItemProxy section */
 
 /* Begin PBXFileReference section */
 		08FB7796FE84155DC02AAC07 /* dump_syms.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = dump_syms.cc; path = ../../../common/mac/dump_syms.cc; sourceTree = "<group>"; };
 		08FB779EFE84155DC02AAC07 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
 		162F64F8161C591500CD68D5 /* arch_utilities.cc */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = arch_utilities.cc; path = ../../../common/mac/arch_utilities.cc; sourceTree = "<group>"; };
 		162F64F9161C591500CD68D5 /* arch_utilities.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = arch_utilities.h; path = ../../../common/mac/arch_utilities.h; sourceTree = "<group>"; };
+		4262382521AC496F00E5A3A6 /* dwarf_range_list_handler.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = dwarf_range_list_handler.cc; path = ../../../common/dwarf_range_list_handler.cc; sourceTree = "<group>"; };
+		4262382621AC496F00E5A3A6 /* dwarf_range_list_handler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = dwarf_range_list_handler.h; path = ../../../common/dwarf_range_list_handler.h; sourceTree = "<group>"; };
 		4D72CAF413DFBAC2006CABE3 /* md5.cc */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = md5.cc; path = ../../../common/md5.cc; sourceTree = SOURCE_ROOT; };
 		557800890BE1F3AB00EC23E0 /* macho_utilities.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = macho_utilities.cc; path = ../../../common/mac/macho_utilities.cc; sourceTree = SOURCE_ROOT; };
 		5578008A0BE1F3AB00EC23E0 /* macho_utilities.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = macho_utilities.h; path = ../../../common/mac/macho_utilities.h; sourceTree = SOURCE_ROOT; };
 		8B31023E11F0CF1C00FCF3E4 /* Breakpad.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Breakpad.xcconfig; path = ../../../common/mac/Breakpad.xcconfig; sourceTree = SOURCE_ROOT; };
 		8B3102D411F0D60300FCF3E4 /* BreakpadDebug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = BreakpadDebug.xcconfig; path = ../../../common/mac/BreakpadDebug.xcconfig; sourceTree = SOURCE_ROOT; };
 		8B3102D511F0D60300FCF3E4 /* BreakpadRelease.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = BreakpadRelease.xcconfig; path = ../../../common/mac/BreakpadRelease.xcconfig; sourceTree = SOURCE_ROOT; };
 		8BCAAA4A1CE3A7980046090B /* elf_reader.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = elf_reader.cc; path = ../../../common/dwarf/elf_reader.cc; sourceTree = "<group>"; };
 		8BCAAA4B1CE3A7980046090B /* elf_reader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = elf_reader.h; path = ../../../common/dwarf/elf_reader.h; sourceTree = "<group>"; };
@@ -608,16 +612,18 @@
 		};
 		F9F5344B0E7C8FFC0012363F /* DWARF */ = {
 			isa = PBXGroup;
 			children = (
 				B88FAF34116A595400407530 /* cfi_assembler.cc */,
 				B88FAF35116A595400407530 /* cfi_assembler.h */,
 				F95B422E0E0E22D100DBDE83 /* dwarf2enums.h */,
 				F95B422F0E0E22D100DBDE83 /* dwarf2reader.cc */,
+				4262382521AC496F00E5A3A6 /* dwarf_range_list_handler.cc */,
+				4262382621AC496F00E5A3A6 /* dwarf_range_list_handler.h */,
 				F95B42300E0E22D100DBDE83 /* dwarf2reader.h */,
 				B88FAF36116A595400407530 /* dwarf2reader_cfi_unittest.cc */,
 				F95B422D0E0E22D100DBDE83 /* bytereader.h */,
 				F95B422B0E0E22D100DBDE83 /* bytereader-inl.h */,
 				F95B422C0E0E22D100DBDE83 /* bytereader.cc */,
 				B88FB0DA116CEC5800407530 /* bytereader_unittest.cc */,
 				F95B42310E0E22D100DBDE83 /* line_state_machine.h */,
 				B88FAE1711665FE400407530 /* dwarf2diehandler.cc */,
@@ -1080,31 +1086,33 @@
 				B89E0E9A11665A7200DD08C9 /* macho_reader.cc in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
 		B8C5B50E1166531A00D34F4E /* Sources */ = {
 			isa = PBXSourcesBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
+				4262382821AC49A000E5A3A6 /* dwarf_range_list_handler.h in Sources */,
 				162F64FA161C591500CD68D5 /* arch_utilities.cc in Sources */,
 				B88FAE2C1166606200407530 /* macho_reader.cc in Sources */,
 				8BCAAA4C1CE3A7980046090B /* elf_reader.cc in Sources */,
 				B8C5B5171166534700D34F4E /* dwarf2reader.cc in Sources */,
 				EB06C7531FEBC516000214D9 /* path_helper.cc in Sources */,
 				B8C5B5181166534700D34F4E /* bytereader.cc in Sources */,
 				B8C5B5191166534700D34F4E /* macho_utilities.cc in Sources */,
 				B8C5B51A1166534700D34F4E /* file_id.cc in Sources */,
 				B8C5B51B1166534700D34F4E /* macho_id.cc in Sources */,
 				B8C5B51C1166534700D34F4E /* macho_walker.cc in Sources */,
 				B8C5B51D1166534700D34F4E /* dump_syms.cc in Sources */,
 				B8C5B51E1166534700D34F4E /* dump_syms_tool.cc in Sources */,
 				B88FAE1911665FE400407530 /* dwarf2diehandler.cc in Sources */,
 				B88FAE261166603300407530 /* dwarf_cu_to_module.cc in Sources */,
 				B88FAE271166603300407530 /* dwarf_line_to_module.cc in Sources */,
+				4262382721AC496F00E5A3A6 /* dwarf_range_list_handler.cc in Sources */,
 				B88FAE281166603300407530 /* language.cc in Sources */,
 				B88FAE291166603300407530 /* module.cc in Sources */,
 				B88FAE351166673E00407530 /* dwarf_cfi_to_module.cc in Sources */,
 				B88FAE3B11666C6F00407530 /* stabs_reader.cc in Sources */,
 				B88FAE3E11666C8900407530 /* stabs_to_module.cc in Sources */,
 				4D72CAF513DFBAC2006CABE3 /* md5.cc in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
@@ -1238,28 +1246,30 @@
 		};
 /* End PBXTargetDependency section */
 
 /* Begin XCBuildConfiguration section */
 		1DEB927908733DD40010E9CD /* Debug */ = {
 			isa = XCBuildConfiguration;
 			baseConfigurationReference = 8B3102D411F0D60300FCF3E4 /* BreakpadDebug.xcconfig */;
 			buildSettings = {
+				CLANG_CXX_LANGUAGE_STANDARD = "c++0x";
 				HEADER_SEARCH_PATHS = (
 					../../..,
 					../../../common/mac/include/,
 					../../../third_party/musl/include/,
 				);
 			};
 			name = Debug;
 		};
 		1DEB927A08733DD40010E9CD /* Release */ = {
 			isa = XCBuildConfiguration;
 			baseConfigurationReference = 8B3102D511F0D60300FCF3E4 /* BreakpadRelease.xcconfig */;
 			buildSettings = {
+				CLANG_CXX_LANGUAGE_STANDARD = "c++0x";
 				HEADER_SEARCH_PATHS = (
 					../../..,
 					../../../common/mac/include/,
 					../../../third_party/musl/include/,
 				);
 			};
 			name = Release;
 		};
--- a/toolkit/crashreporter/google-breakpad/src/tools/mac/upload_system_symbols/arch_constants.h
+++ b/toolkit/crashreporter/google-breakpad/src/tools/mac/upload_system_symbols/arch_constants.h
@@ -38,20 +38,25 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 #ifndef CPU_TYPE_ARM64
 #define CPU_TYPE_ARM64 (CPU_TYPE_ARM | CPU_ARCH_ABI64)
 #endif
 
 #ifndef CPU_SUBTYPE_ARM64_ALL
 #define CPU_SUBTYPE_ARM64_ALL 0
 #endif
 
+#ifndef CPU_SUBTYPE_ARM64_E
+#define CPU_SUBTYPE_ARM64_E 2
+#endif
+
 const cpu_type_t kCPU_TYPE_ARM = CPU_TYPE_ARM;
 const cpu_type_t kCPU_TYPE_ARM64 = CPU_TYPE_ARM64;
 
 const cpu_subtype_t kCPU_SUBTYPE_ARM64_ALL = CPU_SUBTYPE_ARM64_ALL;
+const cpu_subtype_t kCPU_SUBTYPE_ARM64_E = CPU_SUBTYPE_ARM64_E;
 const cpu_subtype_t kCPU_SUBTYPE_ARM_V7S = CPU_SUBTYPE_ARM_V7S;
 
 const char* GetNXArchInfoName(cpu_type_t cpu_type, cpu_subtype_t cpu_subtype) {
   const NXArchInfo* arch_info = NXGetArchInfoFromCpuType(cpu_type, cpu_subtype);
   if (!arch_info)
     return 0;
   return arch_info->name;
 }
--- a/toolkit/crashreporter/google-breakpad/src/tools/mac/upload_system_symbols/arch_reader.go
+++ b/toolkit/crashreporter/google-breakpad/src/tools/mac/upload_system_symbols/arch_reader.go
@@ -42,16 +42,19 @@ import "C"
 // getArchStringFromHeader takes a MachO FileHeader and returns a string that
 // represents the CPU type and subtype.
 // This function is a Go version of src/common/mac/arch_utilities.cc:BreakpadGetArchInfoFromCpuType().
 func getArchStringFromHeader(header macho.FileHeader) string {
 	// TODO(rsesek): As of 10.9.4, OS X doesn't list these in /usr/include/mach/machine.h.
 	if header.Cpu == C.kCPU_TYPE_ARM64 && header.SubCpu == C.kCPU_SUBTYPE_ARM64_ALL {
 		return "arm64"
 	}
+	if header.Cpu == C.kCPU_TYPE_ARM64 && header.SubCpu == C.kCPU_SUBTYPE_ARM64_E {
+		return "arm64e"
+	}
 	if header.Cpu == C.kCPU_TYPE_ARM && header.SubCpu == C.kCPU_SUBTYPE_ARM_V7S {
 		return "armv7s"
 	}
 
 	cstr := C.GetNXArchInfoName(C.cpu_type_t(header.Cpu), C.cpu_subtype_t(header.SubCpu))
 	if cstr == nil {
 		return ""
 	}
--- a/toolkit/crashreporter/update-breakpad.sh
+++ b/toolkit/crashreporter/update-breakpad.sh
@@ -22,26 +22,27 @@ rev=${2-HEAD}
 # Breakpad uses gclient for externals, so manually export what we need.
 lss_rev=$(cd $breakpad_repo; git show ${rev}:DEPS | python -c "import sys; exec sys.stdin; print deps['src/src/third_party/lss'].split('@')[1]")
 (cd $breakpad_repo/src/third_party/lss; git archive --prefix=toolkit/crashreporter/google-breakpad/src/third_party/lss/ $lss_rev) | (cd $repo; tar xf -)
 
 # remove some extraneous bits
 # We've forked src/client toolkit/crashreporter/breakpad-client.
 rm -rf \
   ${crashreporter_dir}/google-breakpad/appveyor.yml \
+  ${crashreporter_dir}/google-breakpad/autotools/ \
   ${crashreporter_dir}/google-breakpad/docs/ \
-  ${crashreporter_dir}/google-breakpad/autotools/ \
   ${crashreporter_dir}/google-breakpad/m4/ \
   ${crashreporter_dir}/google-breakpad/scripts/ \
   ${crashreporter_dir}/google-breakpad/src/client/ \
+  ${crashreporter_dir}/google-breakpad/src/processor/testdata/ \
+  ${crashreporter_dir}/google-breakpad/src/testing/ \
   ${crashreporter_dir}/google-breakpad/src/third_party/protobuf \
-  ${crashreporter_dir}/google-breakpad/src/testing/ \
   ${crashreporter_dir}/google-breakpad/src/tools/gyp/ \
-  ${crashreporter_dir}/google-breakpad/src/processor/testdata/ \
   ${crashreporter_dir}/google-breakpad/src/tools/windows/dump_syms/testdata/ \
+  ${crashreporter_dir}/google-breakpad/.github/mistaken-pull-closer.yml \
   ${crashreporter_dir}/google-breakpad/.travis.yml
 
 # restore our Makefile.ins
 hg -R ${repo} st -n | grep "Makefile\.in$" | xargs hg revert --no-backup
 # and moz.build files
 hg -R ${repo} st -n | grep "moz\.build$" | xargs hg revert --no-backup
 # and some other makefiles
 hg -R ${repo} st -n | grep "objs\.mozbuild$" | xargs hg revert --no-backup