From 9cd2bae5ab23e17918f0b68dd1bd86ab07af712a Mon Sep 17 00:00:00 2001 From: Joshua Peraza Date: Wed, 1 Aug 2018 08:42:27 -0700 Subject: [PATCH] Use Microsoft's ARM64 context layout Change-Id: Ic92447e99474f9b24197375acfc324cca4899222 Reviewed-on: https://chromium-review.googlesource.com/1157286 Reviewed-by: Mark Mentovai Commit-Queue: Joshua Peraza --- minidump/minidump_context.h | 54 ++++++++++++++++----- minidump/minidump_context_writer.cc | 27 +++++++---- minidump/test/minidump_context_test_util.cc | 4 +- 3 files changed, 62 insertions(+), 23 deletions(-) diff --git a/minidump/minidump_context.h b/minidump/minidump_context.h index 6f51b5a4..3a3e603c 100644 --- a/minidump/minidump_context.h +++ b/minidump/minidump_context.h @@ -389,11 +389,16 @@ struct MinidumpContextARM { //! \brief 64-bit ARM-specifc flags for MinidumpContextARM64::context_flags. enum MinidumpContextARM64Flags : uint32_t { //! \brief Identifies the context structure as 64-bit ARM. - kMinidumpContextARM64 = 0x80000000, + kMinidumpContextARM64 = 0x00400000, + + //! \brief Indicates the validity of control registers. + //! + //! Registers `fp`, `lr`, `sp`, `pc`, and `cpsr`. + kMinidumpContextARM64Control = kMinidumpContextARM64 | 0x00000001, //! \brief Indicates the validty of integer registers. //! - //! Registers `x0`-`x31`, `pc`, and `cpsr`. + //! Registers `x0`-`x28`. kMinidumpContextARM64Integer = kMinidumpContextARM64 | 0x00000002, //! \brief Indicates the validity of fpsimd registers. @@ -401,17 +406,37 @@ enum MinidumpContextARM64Flags : uint32_t { //! Registers `v0`-`v31`, `fpsr`, and `fpcr` are valid. kMinidumpContextARM64Fpsimd = kMinidumpContextARM64 | 0x00000004, + //! \brief Indicates the validity of debug registers. + //! + //! `bcr`, `bvr`, `wcr`, and `wvr` are valid. + kMinidumpContextARM64Debug = kMinidumpContextARM64 | 0x00000008, + + //! \brief Indicates the validity of control, integer and floating point + //! registers. + kMinidumpContextARM64Full = kMinidumpContextARM64Control | + kMinidumpContextARM64Integer | + kMinidumpContextARM64Fpsimd, + //! \brief Indicates the validity of all registers. kMinidumpContextARM64All = - kMinidumpContextARM64Integer | kMinidumpContextARM64Fpsimd, + kMinidumpContextARM64Full | kMinidumpContextARM64Debug, }; //! \brief A 64-bit ARM CPU context (register state) carried in a minidump file. struct MinidumpContextARM64 { - uint64_t context_flags; + uint32_t context_flags; - //! \brief General-purpose registers `x0`-`x30`. - uint64_t regs[31]; + //! \brief Current program status register. + uint32_t cpsr; + + //! \brief General-purpose registers `x0`-`x28`. + uint64_t regs[29]; + + //! \brief Frame pointer or `x29`. + uint64_t fp; + + //! \brief Link register or `x30`. + uint64_t lr; //! \brief Stack pointer or `x31`. uint64_t sp; @@ -419,17 +444,20 @@ struct MinidumpContextARM64 { //! \brief Program counter. uint64_t pc; - //! \brief Current program status register. - uint32_t cpsr; - - //! \brief Floating-point status register. - uint32_t fpsr; + //! \brief NEON registers `v0`-`v31`. + uint128_struct fpsimd[32]; //! \brief Floating-point control register. uint32_t fpcr; - //! \brief NEON registers `v0`-`v31`. - uint128_struct fpsimd[32]; + //! \brief Floating-point status register. + uint32_t fpsr; + + //! \brief Debug registers. + uint32_t bcr[8]; + uint64_t bvr[8]; + uint32_t wcr[2]; + uint64_t wvr[2]; }; //! \brief 32bit MIPS-specifc flags for MinidumpContextMIPS::context_flags. diff --git a/minidump/minidump_context_writer.cc b/minidump/minidump_context_writer.cc index 20adbf3f..b67e2bfe 100644 --- a/minidump/minidump_context_writer.cc +++ b/minidump/minidump_context_writer.cc @@ -321,13 +321,7 @@ void MinidumpContextARM64Writer::InitializeFromSnapshot( DCHECK_EQ(state(), kStateMutable); DCHECK_EQ(context_.context_flags, kMinidumpContextARM64); - context_.context_flags = kMinidumpContextARM64All; - - static_assert(sizeof(context_.regs) == sizeof(context_snapshot->regs), - "GPRs size mismatch"); - memcpy(context_.regs, context_snapshot->regs, sizeof(context_.regs)); - context_.sp = context_snapshot->sp; - context_.pc = context_snapshot->pc; + context_.context_flags = kMinidumpContextARM64Full; if (context_snapshot->pstate > std::numeric_limits::max()) { @@ -336,11 +330,26 @@ void MinidumpContextARM64Writer::InitializeFromSnapshot( context_.cpsr = static_cast(context_snapshot->pstate); - context_.fpsr = context_snapshot->fpsr; - context_.fpcr = context_snapshot->fpcr; + static_assert( + sizeof(context_.regs) == sizeof(context_snapshot->regs) - + 2 * sizeof(context_snapshot->regs[0]), + "GPRs size mismatch"); + memcpy(context_.regs, context_snapshot->regs, sizeof(context_.regs)); + context_.fp = context_snapshot->regs[29]; + context_.lr = context_snapshot->regs[30]; + context_.sp = context_snapshot->sp; + context_.pc = context_snapshot->pc; + static_assert(sizeof(context_.fpsimd) == sizeof(context_snapshot->fpsimd), "FPSIMD size mismatch"); memcpy(context_.fpsimd, context_snapshot->fpsimd, sizeof(context_.fpsimd)); + context_.fpcr = context_snapshot->fpcr; + context_.fpsr = context_snapshot->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)); } bool MinidumpContextARM64Writer::WriteObject(FileWriterInterface* file_writer) { diff --git a/minidump/test/minidump_context_test_util.cc b/minidump/test/minidump_context_test_util.cc index 28f94106..318b3fc9 100644 --- a/minidump/test/minidump_context_test_util.cc +++ b/minidump/test/minidump_context_test_util.cc @@ -176,13 +176,15 @@ void InitializeMinidumpContextARM64(MinidumpContextARM64* context, return; } - context->context_flags = kMinidumpContextARM64All; + context->context_flags = kMinidumpContextARM64Full; uint32_t value = seed; for (size_t index = 0; index < arraysize(context->regs); ++index) { context->regs[index] = value++; } + context->fp = value++; + context->lr = value++; context->sp = value++; context->pc = value++; context->cpsr = value++;