aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/client/mac/Breakpad.xcodeproj/project.pbxproj10
-rw-r--r--src/google_breakpad/common/minidump_cpu_arm64.h56
-rw-r--r--src/google_breakpad/common/minidump_format.h1
-rw-r--r--src/google_breakpad/processor/dump_context.h6
-rw-r--r--src/google_breakpad/processor/microdump.h2
-rw-r--r--src/google_breakpad/processor/minidump.h5
-rw-r--r--src/google_breakpad/processor/stack_frame_cpu.h2
-rw-r--r--src/processor/convert_old_arm64_context.cc67
-rw-r--r--src/processor/convert_old_arm64_context.h42
-rw-r--r--src/processor/dump_context.cc25
-rw-r--r--src/processor/microdump.cc22
-rw-r--r--src/processor/minidump.cc83
-rw-r--r--src/processor/processor.gyp2
-rw-r--r--src/processor/stackwalker.cc2
-rw-r--r--src/processor/stackwalker_arm64.cc2
-rw-r--r--src/processor/stackwalker_arm64.h4
-rw-r--r--src/processor/stackwalker_arm64_unittest.cc6
-rw-r--r--src/tools/linux/md2core/minidump-2-core.cc33
-rw-r--r--src/tools/mac/crash_report/crash_report.xcodeproj/project.pbxproj6
19 files changed, 325 insertions, 51 deletions
diff --git a/src/client/mac/Breakpad.xcodeproj/project.pbxproj b/src/client/mac/Breakpad.xcodeproj/project.pbxproj
index 57e0d1ab..2d30ed6c 100644
--- a/src/client/mac/Breakpad.xcodeproj/project.pbxproj
+++ b/src/client/mac/Breakpad.xcodeproj/project.pbxproj
@@ -52,6 +52,9 @@
3329D4ED0FA16D820007BBC5 /* Breakpad.xib in Resources */ = {isa = PBXBuildFile; fileRef = 3329D4EC0FA16D820007BBC5 /* Breakpad.xib */; };
33880C800F9E097100817F82 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 33880C7E0F9E097100817F82 /* InfoPlist.strings */; };
4084699D0F5D9CF900FDCA37 /* crash_report_sender.icns in Resources */ = {isa = PBXBuildFile; fileRef = 4084699C0F5D9CF900FDCA37 /* crash_report_sender.icns */; };
+ 421BC5BC21110C0300B8042E /* convert_old_arm64_context.cc in Sources */ = {isa = PBXBuildFile; fileRef = 421BC5AD21110C0300B8042E /* convert_old_arm64_context.cc */; };
+ 421BC5BD21110C0300B8042E /* convert_old_arm64_context.h in Headers */ = {isa = PBXBuildFile; fileRef = 421BC5BB21110C0300B8042E /* convert_old_arm64_context.h */; };
+ 421BC5BE21110C1000B8042E /* convert_old_arm64_context.cc in Sources */ = {isa = PBXBuildFile; fileRef = 421BC5AD21110C0300B8042E /* convert_old_arm64_context.cc */; };
4247E6412110D7A300482558 /* memory_allocator_unittest.cc in Sources */ = {isa = PBXBuildFile; fileRef = D244540A12439BA0009BBCE0 /* memory_allocator_unittest.cc */; };
4D61A25F14F43CFC002D5862 /* bootstrap_compat.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4D61A25D14F43CFC002D5862 /* bootstrap_compat.cc */; };
4D61A26B14F43D3C002D5862 /* bootstrap_compat.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4D61A25D14F43CFC002D5862 /* bootstrap_compat.cc */; };
@@ -577,6 +580,8 @@
3329D4EC0FA16D820007BBC5 /* Breakpad.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Breakpad.xib; path = sender/Breakpad.xib; sourceTree = "<group>"; };
33880C7F0F9E097100817F82 /* English */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = English; path = sender/English.lproj/InfoPlist.strings; sourceTree = "<group>"; };
4084699C0F5D9CF900FDCA37 /* crash_report_sender.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; name = crash_report_sender.icns; path = sender/crash_report_sender.icns; sourceTree = "<group>"; };
+ 421BC5AD21110C0300B8042E /* convert_old_arm64_context.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = convert_old_arm64_context.cc; path = ../../processor/convert_old_arm64_context.cc; sourceTree = "<group>"; };
+ 421BC5BB21110C0300B8042E /* convert_old_arm64_context.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = convert_old_arm64_context.h; path = ../../processor/convert_old_arm64_context.h; sourceTree = "<group>"; };
4D61A25D14F43CFC002D5862 /* bootstrap_compat.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = bootstrap_compat.cc; path = ../../common/mac/bootstrap_compat.cc; sourceTree = SOURCE_ROOT; };
4D61A25E14F43CFC002D5862 /* bootstrap_compat.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = bootstrap_compat.h; path = ../../common/mac/bootstrap_compat.h; sourceTree = SOURCE_ROOT; };
4D72CA0D13DFAD5C006CABE3 /* md5.cc */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = md5.cc; path = ../../common/md5.cc; sourceTree = SOURCE_ROOT; };
@@ -896,6 +901,8 @@
D244536912426EE7009BBCE0 /* processor */ = {
isa = PBXGroup;
children = (
+ 421BC5AD21110C0300B8042E /* convert_old_arm64_context.cc */,
+ 421BC5BB21110C0300B8042E /* convert_old_arm64_context.h */,
D244535112426EBB009BBCE0 /* logging.cc */,
D244535212426EBB009BBCE0 /* minidump.cc */,
D244535312426EBB009BBCE0 /* pathname_stripper.cc */,
@@ -1154,6 +1161,7 @@
D2F9A4CC121336C7002747C1 /* crash_generation_server.h in Headers */,
163201D61443019E00C4DBF5 /* ConfigFile.h in Headers */,
16C7C918147D45AE00776EAD /* BreakpadDefines.h in Headers */,
+ 421BC5BD21110C0300B8042E /* convert_old_arm64_context.h in Headers */,
162F64F3161C577500CD68D5 /* arch_utilities.h in Headers */,
F4DAB1DE19F1027100A5A838 /* launch_reporter.h in Headers */,
1EEEB6241720829E00F7E689 /* simple_string_dictionary.h in Headers */,
@@ -1686,6 +1694,7 @@
163201D71443019E00C4DBF5 /* ConfigFile.mm in Sources */,
162F64F2161C577500CD68D5 /* arch_utilities.cc in Sources */,
1EEEB6231720829E00F7E689 /* simple_string_dictionary.cc in Sources */,
+ 421BC5BC21110C0300B8042E /* convert_old_arm64_context.cc in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -1844,6 +1853,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
+ 421BC5BE21110C1000B8042E /* convert_old_arm64_context.cc in Sources */,
4247E6412110D7A300482558 /* memory_allocator_unittest.cc in Sources */,
D244536A12426F00009BBCE0 /* logging.cc in Sources */,
D244536B12426F00009BBCE0 /* minidump.cc in Sources */,
diff --git a/src/google_breakpad/common/minidump_cpu_arm64.h b/src/google_breakpad/common/minidump_cpu_arm64.h
index e146ec99..0411bebb 100644
--- a/src/google_breakpad/common/minidump_cpu_arm64.h
+++ b/src/google_breakpad/common/minidump_cpu_arm64.h
@@ -66,7 +66,61 @@
#ifndef GOOGLE_BREAKPAD_COMMON_MINIDUMP_CPU_ARM64_H__
#define GOOGLE_BREAKPAD_COMMON_MINIDUMP_CPU_ARM64_H__
+#include "google_breakpad/common/breakpad_types.h"
+
#define MD_FLOATINGSAVEAREA_ARM64_FPR_COUNT 32
+#define MD_CONTEXT_ARM64_GPR_COUNT 33
+
+typedef struct {
+ /* 32 128-bit floating point registers, d0 .. d31. */
+ uint128_struct regs[MD_FLOATINGSAVEAREA_ARM64_FPR_COUNT];
+
+ uint32_t fpcr; /* FPU control register */
+ uint32_t fpsr; /* FPU status register */
+} MDFloatingSaveAreaARM64;
+
+/* For (MDRawContextARM64).context_flags. These values indicate the type of
+ * context stored in the structure. */
+#define MD_CONTEXT_ARM64 0x00400000
+#define MD_CONTEXT_ARM64_CONTROL (MD_CONTEXT_ARM64 | 0x00000001)
+#define MD_CONTEXT_ARM64_INTEGER (MD_CONTEXT_ARM64 | 0x00000002)
+#define MD_CONTEXT_ARM64_FLOATING_POINT (MD_CONTEXT_ARM64 | 0x00000004)
+#define MD_CONTEXT_ARM64_DEBUG (MD_CONTEXT_ARM64 | 0x00000008)
+#define MD_CONTEXT_ARM64_FULL (MD_CONTEXT_ARM64_CONTROL | \
+ MD_CONTEXT_ARM64_INTEGER | \
+ MD_CONTEXT_ARM64_FLOATING_POINT)
+#define MD_CONTEXT_ARM64_ALL (MD_CONTEXT_ARM64_FULL | MD_CONTEXT_ARM64_DEBUG)
+
+typedef struct {
+ /* Determines which fields of this struct are populated */
+ uint32_t context_flags;
+
+ /* CPSR (flags, basically): 32 bits:
+ bit 31 - N (negative)
+ bit 30 - Z (zero)
+ bit 29 - C (carry)
+ bit 28 - V (overflow)
+ bit 27 - Q (saturation flag, sticky)
+ All other fields -- ignore */
+ uint32_t cpsr;
+
+ /* 33 64-bit integer registers, x0 .. x31 + the PC
+ * Note the following fixed uses:
+ * x29 is the frame pointer
+ * x30 is the link register
+ * x31 is the stack pointer
+ * The PC is effectively x32.
+ */
+ uint64_t iregs[MD_CONTEXT_ARM64_GPR_COUNT];
+
+ /* The next field is included with MD_CONTEXT64_ARM_FLOATING_POINT */
+ MDFloatingSaveAreaARM64 float_save;
+
+ uint32_t bcr[8];
+ uint64_t bvr[8];
+ uint32_t wcr[2];
+ uint64_t wvr[2];
+} MDRawContextARM64;
typedef struct {
uint32_t fpsr; /* FPU status register */
@@ -76,8 +130,6 @@ typedef struct {
uint128_struct regs[MD_FLOATINGSAVEAREA_ARM64_FPR_COUNT];
} MDFloatingSaveAreaARM64_Old;
-#define MD_CONTEXT_ARM64_GPR_COUNT 33
-
/* Use the same 32-bit alignment when accessing this structure from 64-bit code
* as is used natively in 32-bit code. */
#pragma pack(push, 4)
diff --git a/src/google_breakpad/common/minidump_format.h b/src/google_breakpad/common/minidump_format.h
index 9db7049a..04c94cd3 100644
--- a/src/google_breakpad/common/minidump_format.h
+++ b/src/google_breakpad/common/minidump_format.h
@@ -654,6 +654,7 @@ typedef enum {
MD_CPU_ARCHITECTURE_AMD64 = 9, /* PROCESSOR_ARCHITECTURE_AMD64 */
MD_CPU_ARCHITECTURE_X86_WIN64 = 10,
/* PROCESSOR_ARCHITECTURE_IA32_ON_WIN64 (WoW64) */
+ MD_CPU_ARCHITECTURE_ARM64 = 12, /* PROCESSOR_ARCHITECTURE_ARM64 */
MD_CPU_ARCHITECTURE_SPARC = 0x8001, /* Breakpad-defined value for SPARC */
MD_CPU_ARCHITECTURE_PPC64 = 0x8002, /* Breakpad-defined value for PPC64 */
MD_CPU_ARCHITECTURE_ARM64_OLD = 0x8003, /* Breakpad-defined value for ARM64 */
diff --git a/src/google_breakpad/processor/dump_context.h b/src/google_breakpad/processor/dump_context.h
index 455115e5..df80bf7e 100644
--- a/src/google_breakpad/processor/dump_context.h
+++ b/src/google_breakpad/processor/dump_context.h
@@ -56,7 +56,7 @@ class DumpContext : public DumpObject {
// context data does not match the CPU type or does not exist, returns NULL.
const MDRawContextAMD64* GetContextAMD64() const;
const MDRawContextARM* GetContextARM() const;
- const MDRawContextARM64_Old* GetContextARM64() const;
+ const MDRawContextARM64* GetContextARM64() const;
const MDRawContextMIPS* GetContextMIPS() const;
const MDRawContextPPC* GetContextPPC() const;
const MDRawContextPPC64* GetContextPPC64() const;
@@ -85,7 +85,7 @@ class DumpContext : public DumpObject {
void SetContextAMD64(MDRawContextAMD64* amd64);
void SetContextSPARC(MDRawContextSPARC* ctx_sparc);
void SetContextARM(MDRawContextARM* arm);
- void SetContextARM64(MDRawContextARM64_Old* arm64);
+ void SetContextARM64(MDRawContextARM64* arm64);
void SetContextMIPS(MDRawContextMIPS* ctx_mips);
// Free the CPU-specific context structure.
@@ -103,7 +103,7 @@ class DumpContext : public DumpObject {
// so variables can NOT be named as sparc
MDRawContextSPARC* ctx_sparc;
MDRawContextARM* arm;
- MDRawContextARM64_Old* arm64_old;
+ MDRawContextARM64* arm64;
MDRawContextMIPS* ctx_mips;
} context_;
diff --git a/src/google_breakpad/processor/microdump.h b/src/google_breakpad/processor/microdump.h
index 496f83ce..02ebdcd7 100644
--- a/src/google_breakpad/processor/microdump.h
+++ b/src/google_breakpad/processor/microdump.h
@@ -68,7 +68,7 @@ class MicrodumpModules : public BasicCodeModules {
class MicrodumpContext : public DumpContext {
public:
virtual void SetContextARM(MDRawContextARM* arm);
- virtual void SetContextARM64(MDRawContextARM64_Old* arm64);
+ virtual void SetContextARM64(MDRawContextARM64* arm64);
virtual void SetContextX86(MDRawContextX86* x86);
virtual void SetContextMIPS(MDRawContextMIPS* mips32);
virtual void SetContextMIPS64(MDRawContextMIPS* mips64);
diff --git a/src/google_breakpad/processor/minidump.h b/src/google_breakpad/processor/minidump.h
index 1ad513df..febdaeb7 100644
--- a/src/google_breakpad/processor/minidump.h
+++ b/src/google_breakpad/processor/minidump.h
@@ -1260,6 +1260,8 @@ class Minidump {
bool swap() const { return valid_ ? swap_ : false; }
+ bool is_big_endian() const { return valid_ ? is_big_endian_ : false; }
+
// Print a human-readable representation of the object to stdout.
void Print();
@@ -1325,6 +1327,9 @@ class Minidump {
// same-endian, this will be false.
bool swap_;
+ // true if the minidump was produced by a big-endian cpu.
+ bool is_big_endian_;
+
// Validity of the Minidump structure, false immediately after
// construction or after a failed Read(); true following a successful
// Read().
diff --git a/src/google_breakpad/processor/stack_frame_cpu.h b/src/google_breakpad/processor/stack_frame_cpu.h
index 3b2551b5..dc5d8ae6 100644
--- a/src/google_breakpad/processor/stack_frame_cpu.h
+++ b/src/google_breakpad/processor/stack_frame_cpu.h
@@ -327,7 +327,7 @@ struct StackFrameARM64 : public StackFrame {
// stack. In other frames, the values of nonvolatile registers may be
// present, given sufficient debugging information. Refer to
// context_validity.
- MDRawContextARM64_Old context;
+ MDRawContextARM64 context;
// For each register in context whose value has been recovered, we set
// the corresponding CONTEXT_VALID_ bit in context_validity.
diff --git a/src/processor/convert_old_arm64_context.cc b/src/processor/convert_old_arm64_context.cc
new file mode 100644
index 00000000..d4b749e7
--- /dev/null
+++ b/src/processor/convert_old_arm64_context.cc
@@ -0,0 +1,67 @@
+// Copyright (c) 2018, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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/convert_old_arm64_context.h"
+
+#include <string.h>
+
+namespace google_breakpad {
+
+void ConvertOldARM64Context(const MDRawContextARM64_Old& old,
+ MDRawContextARM64* context) {
+ context->context_flags = MD_CONTEXT_ARM64;
+ if (old.context_flags & MD_CONTEXT_ARM64_INTEGER_OLD) {
+ context->context_flags |=
+ MD_CONTEXT_ARM64_INTEGER | MD_CONTEXT_ARM64_CONTROL;
+ }
+ if (old.context_flags & MD_CONTEXT_ARM64_FLOATING_POINT_OLD) {
+ context->context_flags |= MD_CONTEXT_ARM64_FLOATING_POINT;
+ }
+
+ context->cpsr = old.cpsr;
+
+ static_assert(sizeof(old.iregs) == sizeof(context->iregs),
+ "iregs size mismatch");
+ memcpy(context->iregs, old.iregs, sizeof(context->iregs));
+
+ static_assert(sizeof(old.float_save.regs) == sizeof(context->float_save.regs),
+ "float_save.regs size mismatch");
+ memcpy(context->float_save.regs,
+ old.float_save.regs,
+ sizeof(context->float_save.regs));
+ context->float_save.fpcr = old.float_save.fpcr;
+ context->float_save.fpsr = old.float_save.fpsr;
+
+ memset(context->bcr, 0, sizeof(context->bcr));
+ memset(context->bvr, 0, sizeof(context->bvr));
+ memset(context->wcr, 0, sizeof(context->wcr));
+ memset(context->wvr, 0, sizeof(context->wvr));
+}
+
+} // namespace google_breakpad
diff --git a/src/processor/convert_old_arm64_context.h b/src/processor/convert_old_arm64_context.h
new file mode 100644
index 00000000..8c0dfe90
--- /dev/null
+++ b/src/processor/convert_old_arm64_context.h
@@ -0,0 +1,42 @@
+// Copyright (c) 2018, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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 PROCESSOR_CONVERT_OLD_ARM64_CONTEXT_H__
+#define PROCESSOR_CONVERT_OLD_ARM64_CONTEXT_H__
+
+#include "google_breakpad/common/minidump_cpu_arm64.h"
+
+namespace google_breakpad {
+
+void ConvertOldARM64Context(const MDRawContextARM64_Old& old,
+ MDRawContextARM64* context);
+
+} // namespace google_breakpad
+
+#endif // PROCESSOR_CONVERT_OLD_ARM64_CONTEXT_H__
diff --git a/src/processor/dump_context.cc b/src/processor/dump_context.cc
index 198b9501..63ccf4ab 100644
--- a/src/processor/dump_context.cc
+++ b/src/processor/dump_context.cc
@@ -121,13 +121,13 @@ const MDRawContextARM* DumpContext::GetContextARM() const {
return context_.arm;
}
-const MDRawContextARM64_Old* DumpContext::GetContextARM64() const {
- if (GetContextCPU() != MD_CONTEXT_ARM64_OLD) {
+const MDRawContextARM64* DumpContext::GetContextARM64() const {
+ if (GetContextCPU() != MD_CONTEXT_ARM64) {
BPLOG(ERROR) << "DumpContext cannot get arm64 context";
return NULL;
}
- return context_.arm64_old;
+ return context_.arm64;
}
const MDRawContextMIPS* DumpContext::GetContextMIPS() const {
@@ -157,7 +157,7 @@ bool DumpContext::GetInstructionPointer(uint64_t* ip) const {
case MD_CONTEXT_ARM:
*ip = GetContextARM()->iregs[MD_CONTEXT_ARM_REG_PC];
break;
- case MD_CONTEXT_ARM64_OLD:
+ case MD_CONTEXT_ARM64:
*ip = GetContextARM64()->iregs[MD_CONTEXT_ARM64_REG_PC];
break;
case MD_CONTEXT_PPC:
@@ -201,7 +201,7 @@ bool DumpContext::GetStackPointer(uint64_t* sp) const {
case MD_CONTEXT_ARM:
*sp = GetContextARM()->iregs[MD_CONTEXT_ARM_REG_SP];
break;
- case MD_CONTEXT_ARM64_OLD:
+ case MD_CONTEXT_ARM64:
*sp = GetContextARM64()->iregs[MD_CONTEXT_ARM64_REG_SP];
break;
case MD_CONTEXT_PPC:
@@ -256,8 +256,8 @@ void DumpContext::SetContextARM(MDRawContextARM* arm) {
context_.arm = arm;
}
-void DumpContext::SetContextARM64(MDRawContextARM64_Old* arm64) {
- context_.arm64_old = arm64;
+void DumpContext::SetContextARM64(MDRawContextARM64* arm64) {
+ context_.arm64 = arm64;
}
void DumpContext::SetContextMIPS(MDRawContextMIPS* ctx_mips) {
@@ -290,10 +290,6 @@ void DumpContext::FreeContext() {
delete context_.arm;
break;
- case MD_CONTEXT_ARM64_OLD:
- delete context_.arm64_old;
- break;
-
case MD_CONTEXT_MIPS:
case MD_CONTEXT_MIPS64:
delete context_.ctx_mips;
@@ -581,10 +577,10 @@ void DumpContext::Print() {
break;
}
- case MD_CONTEXT_ARM64_OLD: {
- const MDRawContextARM64_Old* context_arm64 = GetContextARM64();
+ case MD_CONTEXT_ARM64: {
+ const MDRawContextARM64* context_arm64 = GetContextARM64();
printf("MDRawContextARM64\n");
- printf(" context_flags = 0x%" PRIx64 "\n",
+ printf(" context_flags = 0x%x\n",
context_arm64->context_flags);
for (unsigned int ireg_index = 0;
ireg_index < MD_CONTEXT_ARM64_GPR_COUNT;
@@ -603,6 +599,7 @@ void DumpContext::Print() {
printf(" float_save.regs[%2d] = 0x%" PRIx64 "%" PRIx64 "\n",
freg_index, fp_value.high, fp_value.low);
}
+
break;
}
diff --git a/src/processor/microdump.cc b/src/processor/microdump.cc
index b100f765..13e261b4 100644
--- a/src/processor/microdump.cc
+++ b/src/processor/microdump.cc
@@ -44,6 +44,7 @@
#include "google_breakpad/common/minidump_cpu_arm.h"
#include "google_breakpad/processor/code_module.h"
#include "processor/basic_code_module.h"
+#include "processor/convert_old_arm64_context.h"
#include "processor/linked_ptr.h"
#include "processor/logging.h"
#include "processor/range_map-inl.h"
@@ -125,8 +126,8 @@ void MicrodumpContext::SetContextARM(MDRawContextARM* arm) {
valid_ = true;
}
-void MicrodumpContext::SetContextARM64(MDRawContextARM64_Old* arm64) {
- DumpContext::SetContextFlags(MD_CONTEXT_ARM64_OLD);
+void MicrodumpContext::SetContextARM64(MDRawContextARM64* arm64) {
+ DumpContext::SetContextFlags(MD_CONTEXT_ARM64);
DumpContext::SetContextARM64(arm64);
valid_ = true;
}
@@ -311,15 +312,22 @@ Microdump::Microdump(const string& contents)
memcpy(arm, &cpu_state_raw[0], cpu_state_raw.size());
context_->SetContextARM(arm);
} else if (strcmp(arch.c_str(), kArm64Architecture) == 0) {
- if (cpu_state_raw.size() != sizeof(MDRawContextARM64_Old)) {
+ if (cpu_state_raw.size() == sizeof(MDRawContextARM64)) {
+ MDRawContextARM64* arm = new MDRawContextARM64();
+ memcpy(arm, &cpu_state_raw[0], cpu_state_raw.size());
+ context_->SetContextARM64(arm);
+ } else if (cpu_state_raw.size() == sizeof(MDRawContextARM64_Old)) {
+ MDRawContextARM64_Old old_arm;
+ memcpy(&old_arm, &cpu_state_raw[0], cpu_state_raw.size());
+ MDRawContextARM64* new_arm = new MDRawContextARM64();
+ ConvertOldARM64Context(old_arm, new_arm);
+ context_->SetContextARM64(new_arm);
+ } else {
std::cerr << "Malformed CPU context. Got " << cpu_state_raw.size()
- << " bytes instead of " << sizeof(MDRawContextARM64_Old)
+ << " bytes instead of " << sizeof(MDRawContextARM64)
<< std::endl;
continue;
}
- MDRawContextARM64_Old* arm = new MDRawContextARM64_Old();
- memcpy(arm, &cpu_state_raw[0], cpu_state_raw.size());
- context_->SetContextARM64(arm);
} else if (strcmp(arch.c_str(), kX86Architecture) == 0) {
if (cpu_state_raw.size() != sizeof(MDRawContextX86)) {
std::cerr << "Malformed CPU context. Got " << cpu_state_raw.size()
diff --git a/src/processor/minidump.cc b/src/processor/minidump.cc
index 020b95d3..c86a813f 100644
--- a/src/processor/minidump.cc
+++ b/src/processor/minidump.cc
@@ -59,6 +59,7 @@
#include "google_breakpad/processor/dump_context.h"
#include "processor/basic_code_module.h"
#include "processor/basic_code_modules.h"
+#include "processor/convert_old_arm64_context.h"
#include "processor/logging.h"
// All intentional fallthroughs in breakpad are in this file, so define
@@ -104,6 +105,8 @@ bool IsContextSizeUnique(uint32_t context_size) {
num_matching_contexts++;
if (context_size == sizeof(MDRawContextARM))
num_matching_contexts++;
+ if (context_size == sizeof(MDRawContextARM64))
+ num_matching_contexts++;
if (context_size == sizeof(MDRawContextARM64_Old))
num_matching_contexts++;
if (context_size == sizeof(MDRawContextMIPS))
@@ -745,10 +748,8 @@ bool MinidumpContext::Read(uint32_t expected_size) {
for (unsigned int fpr_index = 0;
fpr_index < MD_FLOATINGSAVEAREA_ARM64_FPR_COUNT;
++fpr_index) {
- // While ARM64 is bi-endian, iOS (currently the only platform
- // for which ARM64 support has been brought up) uses ARM64 exclusively
- // in little-endian mode.
- Normalize128(&context_arm64->float_save.regs[fpr_index], false);
+ Normalize128(&context_arm64->float_save.regs[fpr_index],
+ minidump_->is_big_endian());
Swap(&context_arm64->float_save.regs[fpr_index]);
}
}
@@ -762,7 +763,9 @@ bool MinidumpContext::Read(uint32_t expected_size) {
return false;
}
- SetContextARM64(context_arm64.release());
+ scoped_ptr<MDRawContextARM64> new_context(new MDRawContextARM64());
+ ConvertOldARM64Context(*context_arm64.get(), new_context.get());
+ SetContextARM64(new_context.release());
} else {
uint32_t context_flags;
if (!minidump_->ReadBytes(&context_flags, sizeof(context_flags))) {
@@ -1059,6 +1062,58 @@ bool MinidumpContext::Read(uint32_t expected_size) {
break;
}
+ case MD_CONTEXT_ARM64: {
+ if (expected_size != sizeof(MDRawContextARM64)) {
+ BPLOG(ERROR) << "MinidumpContext arm64 size mismatch, " <<
+ expected_size << " != " << sizeof(MDRawContextARM64);
+ return false;
+ }
+
+ scoped_ptr<MDRawContextARM64> context_arm64(new MDRawContextARM64());
+
+ // 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_arm64->context_flags = context_flags;
+
+ size_t flags_size = sizeof(context_arm64->context_flags);
+ uint8_t* context_after_flags =
+ reinterpret_cast<uint8_t*>(context_arm64.get()) + flags_size;
+ if (!minidump_->ReadBytes(context_after_flags,
+ sizeof(*context_arm64) - flags_size)) {
+ BPLOG(ERROR) << "MinidumpContext could not read arm64 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 arm does not match system info";
+ return false;
+ }
+
+ if (minidump_->swap()) {
+ // context_arm64->context_flags was already swapped.
+ for (unsigned int ireg_index = 0;
+ ireg_index < MD_CONTEXT_ARM64_GPR_COUNT;
+ ++ireg_index) {
+ Swap(&context_arm64->iregs[ireg_index]);
+ }
+ Swap(&context_arm64->cpsr);
+ Swap(&context_arm64->float_save.fpsr);
+ Swap(&context_arm64->float_save.fpcr);
+ for (unsigned int fpr_index = 0;
+ fpr_index < MD_FLOATINGSAVEAREA_ARM64_FPR_COUNT;
+ ++fpr_index) {
+ Normalize128(&context_arm64->float_save.regs[fpr_index],
+ minidump_->is_big_endian());
+ Swap(&context_arm64->float_save.regs[fpr_index]);
+ }
+ }
+ SetContextARM64(context_arm64.release());
+ break;
+ }
+
case MD_CONTEXT_MIPS:
case MD_CONTEXT_MIPS64: {
if (expected_size != sizeof(MDRawContextMIPS)) {
@@ -1199,6 +1254,11 @@ bool MinidumpContext::CheckAgainstSystemInfo(uint32_t context_cpu_type) {
return_value = true;
break;
+ case MD_CONTEXT_ARM64:
+ if (system_info_cpu_type == MD_CPU_ARCHITECTURE_ARM64)
+ return_value = true;
+ break;
+
case MD_CONTEXT_ARM64_OLD:
if (system_info_cpu_type == MD_CPU_ARCHITECTURE_ARM64_OLD)
return_value = true;
@@ -3487,6 +3547,7 @@ string MinidumpSystemInfo::GetCPU() {
cpu = "arm";
break;
+ case MD_CPU_ARCHITECTURE_ARM64:
case MD_CPU_ARCHITECTURE_ARM64_OLD:
cpu = "arm64";
break;
@@ -4994,6 +5055,7 @@ Minidump::Minidump(const string& path, bool hexdump, unsigned int hexdump_width)
path_(path),
stream_(NULL),
swap_(false),
+ is_big_endian_(false),
valid_(false),
hexdump_(hexdump),
hexdump_width_(hexdump_width) {
@@ -5006,6 +5068,7 @@ Minidump::Minidump(istream& stream)
path_(),
stream_(&stream),
swap_(false),
+ is_big_endian_(false),
valid_(false),
hexdump_(false),
hexdump_width_(0) {
@@ -5086,6 +5149,9 @@ bool Minidump::GetContextCPUFlagsFromSystemInfo(uint32_t *context_cpu_flags) {
case MD_CPU_ARCHITECTURE_ARM:
*context_cpu_flags = MD_CONTEXT_ARM;
break;
+ case MD_CPU_ARCHITECTURE_ARM64:
+ *context_cpu_flags = MD_CONTEXT_ARM64;
+ break;
case MD_CPU_ARCHITECTURE_ARM64_OLD:
*context_cpu_flags = MD_CONTEXT_ARM64_OLD;
break;
@@ -5161,6 +5227,13 @@ bool Minidump::Read() {
swap_ = false;
}
+#if defined(__BIG_ENDIAN__) || \
+ (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
+ is_big_endian_ = !swap_;
+#else
+ is_big_endian_ = swap_;
+#endif
+
BPLOG(INFO) << "Minidump " << (swap_ ? "" : "not ") <<
"byte-swapping minidump";
diff --git a/src/processor/processor.gyp b/src/processor/processor.gyp
index d09a8953..feec7443 100644
--- a/src/processor/processor.gyp
+++ b/src/processor/processor.gyp
@@ -49,6 +49,8 @@
'cfi_frame_info.h',
'contained_range_map-inl.h',
'contained_range_map.h',
+ 'convert_old_arm64_context.cc',
+ 'convert_old_arm64_context.h',
'disassembler_x86.cc',
'disassembler_x86.h',
'dump_context.cc',
diff --git a/src/processor/stackwalker.cc b/src/processor/stackwalker.cc
index c7634ff0..4988ef1e 100644
--- a/src/processor/stackwalker.cc
+++ b/src/processor/stackwalker.cc
@@ -259,7 +259,7 @@ Stackwalker* Stackwalker::StackwalkerForCPU(
break;
}
- case MD_CONTEXT_ARM64_OLD:
+ case MD_CONTEXT_ARM64:
cpu_stackwalker = new StackwalkerARM64(system_info,
context->GetContextARM64(),
memory, modules,
diff --git a/src/processor/stackwalker_arm64.cc b/src/processor/stackwalker_arm64.cc
index 042fd089..f9660112 100644
--- a/src/processor/stackwalker_arm64.cc
+++ b/src/processor/stackwalker_arm64.cc
@@ -48,7 +48,7 @@ namespace google_breakpad {
StackwalkerARM64::StackwalkerARM64(const SystemInfo* system_info,
- const MDRawContextARM64_Old* context,
+ const MDRawContextARM64* context,
MemoryRegion* memory,
const CodeModules* modules,
StackFrameSymbolizer* resolver_helper)
diff --git a/src/processor/stackwalker_arm64.h b/src/processor/stackwalker_arm64.h
index 1b01f21e..121e8246 100644
--- a/src/processor/stackwalker_arm64.h
+++ b/src/processor/stackwalker_arm64.h
@@ -55,7 +55,7 @@ class StackwalkerARM64 : public Stackwalker {
// included in the stack. The other arguments are passed directly through
// to the base Stackwalker constructor.
StackwalkerARM64(const SystemInfo* system_info,
- const MDRawContextARM64_Old* context,
+ const MDRawContextARM64* context,
MemoryRegion* memory,
const CodeModules* modules,
StackFrameSymbolizer* frame_symbolizer);
@@ -89,7 +89,7 @@ class StackwalkerARM64 : public Stackwalker {
// Stores the CPU context corresponding to the youngest stack frame, to
// be returned by GetContextFrame.
- const MDRawContextARM64_Old* context_;
+ const MDRawContextARM64* context_;
// Validity mask for youngest stack frame. This is always
// CONTEXT_VALID_ALL in real use; it is only changeable for the sake of
diff --git a/src/processor/stackwalker_arm64_unittest.cc b/src/processor/stackwalker_arm64_unittest.cc
index fff70744..f9d18cea 100644
--- a/src/processor/stackwalker_arm64_unittest.cc
+++ b/src/processor/stackwalker_arm64_unittest.cc
@@ -122,14 +122,14 @@ class StackwalkerARM64Fixture {
}
// Fill RAW_CONTEXT with pseudo-random data, for round-trip checking.
- void BrandContext(MDRawContextARM64_Old *raw_context) {
+ void BrandContext(MDRawContextARM64 *raw_context) {
uint8_t x = 173;
for (size_t i = 0; i < sizeof(*raw_context); i++)
reinterpret_cast<uint8_t *>(raw_context)[i] = (x += 17);
}
SystemInfo system_info;
- MDRawContextARM64_Old raw_context;
+ MDRawContextARM64 raw_context;
Section stack_section;
MockMemoryRegion stack_region;
MockCodeModule module1;
@@ -688,7 +688,7 @@ struct CFIFixture: public StackwalkerARM64Fixture {
}
// The values we expect to find for the caller's registers.
- MDRawContextARM64_Old expected;
+ MDRawContextARM64 expected;
// The validity mask for expected.
uint64_t expected_validity;
diff --git a/src/tools/linux/md2core/minidump-2-core.cc b/src/tools/linux/md2core/minidump-2-core.cc
index cf9648f6..941586e9 100644
--- a/src/tools/linux/md2core/minidump-2-core.cc
+++ b/src/tools/linux/md2core/minidump-2-core.cc
@@ -480,17 +480,28 @@ ParseThreadRegisters(CrashedProcess::Thread* thread,
static void
ParseThreadRegisters(CrashedProcess::Thread* thread,
const MinidumpMemoryRange& range) {
- const MDRawContextARM64_Old* rawregs = range.GetData<MDRawContextARM64_Old>(0);
-
- for (int i = 0; i < 31; ++i)
- thread->regs.regs[i] = rawregs->iregs[i];
- thread->regs.sp = rawregs->iregs[MD_CONTEXT_ARM64_REG_SP];
- thread->regs.pc = rawregs->iregs[MD_CONTEXT_ARM64_REG_PC];
- thread->regs.pstate = rawregs->cpsr;
-
- memcpy(thread->fpregs.vregs, rawregs->float_save.regs, 8 * 32);
- thread->fpregs.fpsr = rawregs->float_save.fpsr;
- thread->fpregs.fpcr = rawregs->float_save.fpcr;
+#define COPY_REGS(rawregs) \
+ do { \
+ for (int i = 0; i < 31; ++i) \
+ thread->regs.regs[i] = rawregs->iregs[i]; \
+ thread->regs.sp = rawregs->iregs[MD_CONTEXT_ARM64_REG_SP]; \
+ thread->regs.pc = rawregs->iregs[MD_CONTEXT_ARM64_REG_PC]; \
+ thread->regs.pstate = rawregs->cpsr; \
+ \
+ memcpy(thread->fpregs.vregs, rawregs->float_save.regs, 8 * 32); \
+ thread->fpregs.fpsr = rawregs->float_save.fpsr; \
+ thread->fpregs.fpcr = rawregs->float_save.fpcr; \
+ } while (false)
+
+ if (range.length() == sizeof(MDRawContextARM64_Old)) {
+ const MDRawContextARM64_Old* rawregs =
+ range.GetData<MDRawContextARM64_Old>(0);
+ COPY_REGS(rawregs);
+ } else {
+ const MDRawContextARM64* rawregs = range.GetData<MDRawContextARM64>(0);
+ COPY_REGS(rawregs);
+ }
+#undef COPY_REGS
}
#elif defined(__mips__)
static void
diff --git a/src/tools/mac/crash_report/crash_report.xcodeproj/project.pbxproj b/src/tools/mac/crash_report/crash_report.xcodeproj/project.pbxproj
index ff5eadc0..33204f7e 100644
--- a/src/tools/mac/crash_report/crash_report.xcodeproj/project.pbxproj
+++ b/src/tools/mac/crash_report/crash_report.xcodeproj/project.pbxproj
@@ -8,6 +8,7 @@
/* Begin PBXBuildFile section */
162F64FE161C5ECB00CD68D5 /* arch_utilities.cc in Sources */ = {isa = PBXBuildFile; fileRef = 162F64FC161C5ECB00CD68D5 /* arch_utilities.cc */; };
+ 4214B800211109A600B769FA /* convert_old_arm64_context.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4214B7FE211109A600B769FA /* convert_old_arm64_context.cc */; };
4247E6402110D5A500482558 /* path_helper.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4247E63F2110D5A500482558 /* path_helper.cc */; };
4D2C721B126F9ACC00B43EAF /* source_line_resolver_base.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4D2C721A126F9ACC00B43EAF /* source_line_resolver_base.cc */; };
4D2C721F126F9ADE00B43EAF /* exploitability.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4D2C721E126F9ADE00B43EAF /* exploitability.cc */; };
@@ -82,6 +83,8 @@
08FB779EFE84155DC02AAC07 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
162F64FC161C5ECB00CD68D5 /* arch_utilities.cc */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = arch_utilities.cc; path = ../../../common/mac/arch_utilities.cc; sourceTree = "<group>"; };
162F64FD161C5ECB00CD68D5 /* arch_utilities.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = arch_utilities.h; path = ../../../common/mac/arch_utilities.h; sourceTree = "<group>"; };
+ 4214B7FE211109A600B769FA /* convert_old_arm64_context.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = convert_old_arm64_context.cc; path = ../../../processor/convert_old_arm64_context.cc; sourceTree = "<group>"; };
+ 4214B7FF211109A600B769FA /* convert_old_arm64_context.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = convert_old_arm64_context.h; path = ../../../processor/convert_old_arm64_context.h; sourceTree = "<group>"; };
4247E63E2110D5A500482558 /* path_helper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = path_helper.h; path = ../../../common/path_helper.h; sourceTree = "<group>"; };
4247E63F2110D5A500482558 /* path_helper.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = path_helper.cc; path = ../../../common/path_helper.cc; sourceTree = "<group>"; };
4D2C721A126F9ACC00B43EAF /* source_line_resolver_base.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = source_line_resolver_base.cc; path = ../../../processor/source_line_resolver_base.cc; sourceTree = SOURCE_ROOT; };
@@ -218,6 +221,8 @@
08FB7794FE84155DC02AAC07 /* crash_report */ = {
isa = PBXGroup;
children = (
+ 4214B7FE211109A600B769FA /* convert_old_arm64_context.cc */,
+ 4214B7FF211109A600B769FA /* convert_old_arm64_context.h */,
4247E63F2110D5A500482558 /* path_helper.cc */,
4247E63E2110D5A500482558 /* path_helper.h */,
8B31025311F0D2D400FCF3E4 /* Breakpad.xcconfig */,
@@ -525,6 +530,7 @@
4D2C7223126F9AF900B43EAF /* exploitability_win.cc in Sources */,
4D2C7227126F9B0F00B43EAF /* disassembler_x86.cc in Sources */,
F407DC48185773C10064622B /* exploitability_linux.cc in Sources */,
+ 4214B800211109A600B769FA /* convert_old_arm64_context.cc in Sources */,
4D2C722B126F9B5A00B43EAF /* x86_disasm.c in Sources */,
4D2C722D126F9B6E00B43EAF /* x86_misc.c in Sources */,
4D2C722F126F9B8300B43EAF /* x86_operand_list.c in Sources */,