|
|
From 8c24c695052d156fd1322d6dacfab117b92cb175 Mon Sep 17 00:00:00 2001
|
|
|
From: Shawn Anastasio <sanastasio@raptorengineering.com>
|
|
|
Date: Thu, 30 Aug 2018 17:32:05 -0500
|
|
|
Subject: [PATCH] Implement support for PPC64 on Linux
|
|
|
|
|
|
This patch implements support for the PPC64 architecture on Linux hosts.
|
|
|
---
|
|
|
CONTRIBUTORS | 1 +
|
|
|
minidump/minidump_context.h | 64 ++++++
|
|
|
minidump/minidump_context_writer.cc | 50 +++++
|
|
|
minidump/minidump_context_writer.h | 39 ++++
|
|
|
minidump/minidump_context_writer_test.cc | 15 ++
|
|
|
minidump/minidump_misc_info_writer.cc | 2 +
|
|
|
minidump/test/minidump_context_test_util.cc | 67 ++++++
|
|
|
minidump/test/minidump_context_test_util.h | 3 +
|
|
|
snapshot/capture_memory.cc | 5 +
|
|
|
snapshot/cpu_architecture.h | 5 +-
|
|
|
snapshot/cpu_context.cc | 5 +
|
|
|
snapshot/cpu_context.h | 19 ++
|
|
|
snapshot/linux/cpu_context_linux.h | 73 ++++++
|
|
|
snapshot/linux/debug_rendezvous_test.cc | 4 +-
|
|
|
snapshot/linux/exception_snapshot_linux.cc | 63 ++++++
|
|
|
snapshot/linux/exception_snapshot_linux.h | 2 +
|
|
|
.../linux/exception_snapshot_linux_test.cc | 21 ++
|
|
|
snapshot/linux/process_reader_linux.cc | 2 +
|
|
|
snapshot/linux/signal_context.h | 83 +++++++
|
|
|
snapshot/linux/system_snapshot_linux.cc | 11 +
|
|
|
snapshot/linux/thread_snapshot_linux.cc | 8 +
|
|
|
snapshot/linux/thread_snapshot_linux.h | 2 +
|
|
|
snapshot/test/test_cpu_context.cc | 33 +++
|
|
|
snapshot/test/test_cpu_context.h | 1 +
|
|
|
test/linux/get_tls.cc | 2 +
|
|
|
test/multiprocess_posix.cc | 3 +-
|
|
|
util/linux/auxiliary_vector.cc | 5 +
|
|
|
util/linux/ptracer.cc | 61 +++++
|
|
|
util/linux/thread_info.h | 55 +++++
|
|
|
util/misc/capture_context.h | 1 +
|
|
|
util/misc/capture_context_linux.S | 212 +++++++++++++++++-
|
|
|
util/misc/capture_context_test.cc | 3 +-
|
|
|
util/misc/capture_context_test_util_linux.cc | 6 +
|
|
|
36 files changed, 932 insertions(+), 12 deletions(-)
|
|
|
|
|
|
Index: chromium-120.0.6099.71/third_party/crashpad/crashpad/CONTRIBUTORS
|
|
|
===================================================================
|
|
|
--- chromium-120.0.6099.71.orig/third_party/crashpad/crashpad/CONTRIBUTORS
|
|
|
+++ chromium-120.0.6099.71/third_party/crashpad/crashpad/CONTRIBUTORS
|
|
|
@@ -13,3 +13,5 @@ Mark Mentovai <mark@chromium.org>
|
|
|
Robert Sesek <rsesek@chromium.org>
|
|
|
Scott Graham <scottmg@chromium.org>
|
|
|
Joshua Peraza <jperaza@chromium.org>
|
|
|
+Shawn Anastasio <sanastasio@raptorengineering.com>
|
|
|
+Timothy Pearson <tpearson@raptorengineering.com>
|
|
|
Index: chromium-120.0.6099.71/third_party/crashpad/crashpad/minidump/minidump_context.h
|
|
|
===================================================================
|
|
|
--- chromium-120.0.6099.71.orig/third_party/crashpad/crashpad/minidump/minidump_context.h
|
|
|
+++ chromium-120.0.6099.71/third_party/crashpad/crashpad/minidump/minidump_context.h
|
|
|
@@ -687,6 +687,70 @@ struct MinidumpContextRISCV64 {
|
|
|
uint32_t fcsr;
|
|
|
};
|
|
|
|
|
|
+//! \brief ppc64-specific flags for MinidumpPPC64::context_flags
|
|
|
+//! Based on minidump_cpu_ppc64.h from breakpad
|
|
|
+enum MinidumpContextPPC64Flags : uint32_t {
|
|
|
+ //! \brief Identifies the context as PPC64.
|
|
|
+ kMinidumpContextPPC64 = 0x01000000,
|
|
|
+
|
|
|
+ //! \brief Indicates the validity of general purpose registers.
|
|
|
+ //!
|
|
|
+ //! Registers `r0`-`r31`, `nip`, `msr`, `lr`, etc. are valid.
|
|
|
+ kMinidumpContextPPC64Base = kMinidumpContextPPC64 | 0x00000001,
|
|
|
+
|
|
|
+ //! \brief Indicates the validity of floating point registers.
|
|
|
+ //!
|
|
|
+ //! Registers `fp0`-`fp31`, `fpscr` are valid.
|
|
|
+ kMinidumpContextPPC64Floating = kMinidumpContextPPC64 | 0x00000008,
|
|
|
+
|
|
|
+ //! \brief Indicates the validity of Altivec/VMX registers.
|
|
|
+ //!
|
|
|
+ //! Registers `v0`-`v31`, `vscr`, `vrsave`.
|
|
|
+ kMinidumpContextPPC64Vector = kMinidumpContextPPC64 | 0x00000020,
|
|
|
+
|
|
|
+ //! \brief Indicates the validity of all registers
|
|
|
+ kMinidumpContextPPC64All = kMinidumpContextPPC64Base |
|
|
|
+ kMinidumpContextPPC64Floating |
|
|
|
+ kMinidumpContextPPC64Vector
|
|
|
+};
|
|
|
+
|
|
|
+//! \brief A PPC64 CPU context carried in a minidump file.
|
|
|
+//! Based on minidump_cpu_ppc64.h from breakpad.
|
|
|
+struct MinidumpContextPPC64 {
|
|
|
+ uint64_t context_flags;
|
|
|
+
|
|
|
+ //! \brief General purpose registers.
|
|
|
+ uint64_t nip;
|
|
|
+ uint64_t msr;
|
|
|
+ uint64_t regs[32];
|
|
|
+ uint64_t ccr;
|
|
|
+ uint64_t xer;
|
|
|
+ uint64_t lnk;
|
|
|
+ uint64_t ctr;
|
|
|
+
|
|
|
+ //! \brief Floating point registers.
|
|
|
+ double fpregs[32];
|
|
|
+
|
|
|
+ //! \brief FPU status register.
|
|
|
+ double fpscr;
|
|
|
+
|
|
|
+ //! \brief Altivec/VMX vector registers.
|
|
|
+ struct {
|
|
|
+ //! \brief Vector registers are 128bits.
|
|
|
+ uint128_struct save_vr[32];
|
|
|
+ uint128_struct save_vscr;
|
|
|
+
|
|
|
+ //! \brief Padding included for breakpad compatibiltiy.
|
|
|
+ uint32_t save_pad5[4];
|
|
|
+
|
|
|
+ //! \brief VRSAVE register.
|
|
|
+ uint32_t save_vrsave;
|
|
|
+
|
|
|
+ //! \brief Padding included for breakpad compatibiltiy.
|
|
|
+ uint32_t save_pad6[7];
|
|
|
+ } vregs;
|
|
|
+};
|
|
|
+
|
|
|
} // namespace crashpad
|
|
|
|
|
|
#endif // CRASHPAD_MINIDUMP_MINIDUMP_CONTEXT_H_
|
|
|
Index: chromium-120.0.6099.71/third_party/crashpad/crashpad/minidump/minidump_context_writer.cc
|
|
|
===================================================================
|
|
|
--- chromium-120.0.6099.71.orig/third_party/crashpad/crashpad/minidump/minidump_context_writer.cc
|
|
|
+++ chromium-120.0.6099.71/third_party/crashpad/crashpad/minidump/minidump_context_writer.cc
|
|
|
@@ -110,6 +110,13 @@ MinidumpContextWriter::CreateFromSnapsho
|
|
|
break;
|
|
|
}
|
|
|
|
|
|
+ case kCPUArchitecturePPC64: {
|
|
|
+ context = std::make_unique<MinidumpContextPPC64Writer>();
|
|
|
+ reinterpret_cast<MinidumpContextPPC64Writer*>(context.get())
|
|
|
+ ->InitializeFromSnapshot(context_snapshot->ppc64);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
default: {
|
|
|
LOG(ERROR) << "unknown context architecture "
|
|
|
<< context_snapshot->architecture;
|
|
|
@@ -601,5 +608,48 @@ size_t MinidumpContextRISCV64Writer::Con
|
|
|
DCHECK_GE(state(), kStateFrozen);
|
|
|
return sizeof(context_);
|
|
|
}
|
|
|
+
|
|
|
+MinidumpContextPPC64Writer::MinidumpContextPPC64Writer()
|
|
|
+ : MinidumpContextWriter(), context_() {
|
|
|
+ context_.context_flags = kMinidumpContextPPC64;
|
|
|
+}
|
|
|
+
|
|
|
+MinidumpContextPPC64Writer::~MinidumpContextPPC64Writer() = default;
|
|
|
+
|
|
|
+void MinidumpContextPPC64Writer::InitializeFromSnapshot(
|
|
|
+ const CPUContextPPC64* context_snapshot) {
|
|
|
+ DCHECK_EQ(state(), kStateMutable);
|
|
|
+ DCHECK_EQ(context_.context_flags, kMinidumpContextPPC64);
|
|
|
+
|
|
|
+ context_.context_flags = kMinidumpContextPPC64All;
|
|
|
+
|
|
|
+ memcpy(context_.regs, context_snapshot->regs, sizeof(context_.regs));
|
|
|
+ context_.nip = context_snapshot->nip;
|
|
|
+ context_.msr = context_snapshot->msr;
|
|
|
+ context_.ccr = context_snapshot->ccr;
|
|
|
+ context_.xer = context_snapshot->xer;
|
|
|
+ context_.lnk = context_snapshot->lnk;
|
|
|
+ context_.ctr = context_snapshot->ctr;
|
|
|
+
|
|
|
+ memcpy(context_.fpregs, context_snapshot->fpregs, sizeof(context_.fpregs));
|
|
|
+ context_.fpscr = context_snapshot->fpscr;
|
|
|
+
|
|
|
+ memcpy(context_.vregs.save_vr, context_snapshot->vregs.save_vr,
|
|
|
+ sizeof(context_.vregs.save_vr));
|
|
|
+ memcpy(&context_.vregs.save_vscr, &context_snapshot->vregs.save_vscr,
|
|
|
+ sizeof(context_.vregs.save_vscr));
|
|
|
+ context_.vregs.save_vrsave = context_snapshot->vregs.save_vrsave;
|
|
|
+}
|
|
|
+
|
|
|
+bool MinidumpContextPPC64Writer::WriteObject(
|
|
|
+ FileWriterInterface* file_writer) {
|
|
|
+ DCHECK_EQ(state(), kStateWritable);
|
|
|
+ return file_writer->Write(&context_, sizeof(context_));
|
|
|
+}
|
|
|
+
|
|
|
+size_t MinidumpContextPPC64Writer::ContextSize() const {
|
|
|
+ DCHECK_GE(state(), kStateFrozen);
|
|
|
+ return sizeof(context_);
|
|
|
+}
|
|
|
|
|
|
} // namespace crashpad
|
|
|
Index: chromium-120.0.6099.71/third_party/crashpad/crashpad/minidump/minidump_context_writer.h
|
|
|
===================================================================
|
|
|
--- chromium-120.0.6099.71.orig/third_party/crashpad/crashpad/minidump/minidump_context_writer.h
|
|
|
+++ chromium-120.0.6099.71/third_party/crashpad/crashpad/minidump/minidump_context_writer.h
|
|
|
@@ -413,6 +413,49 @@ class MinidumpContextRISCV64Writer final
|
|
|
MinidumpContextRISCV64 context_;
|
|
|
};
|
|
|
|
|
|
+//! \brief The writer for a MinidumpContextPPC64 structure in a minidump file.
|
|
|
+class MinidumpContextPPC64Writer final : public MinidumpContextWriter {
|
|
|
+ public:
|
|
|
+ MinidumpContextPPC64Writer();
|
|
|
+
|
|
|
+ MinidumpContextPPC64Writer(const MinidumpContextPPC64Writer&) = delete;
|
|
|
+ MinidumpContextPPC64Writer& operator=(const MinidumpContextPPC64Writer&) =
|
|
|
+ delete;
|
|
|
+
|
|
|
+ ~MinidumpContextPPC64Writer() override;
|
|
|
+
|
|
|
+ //! \brief Initializes the MinidumpContextPPC based on \a context_snapshot.
|
|
|
+ //!
|
|
|
+ //! \param[in] context_snapshot The context snapshot to use as source data.
|
|
|
+ //!
|
|
|
+ //! \note Valid in #kStateMutable. No mutation of context() may be done before
|
|
|
+ //! calling this method, and it is not normally necessary to alter
|
|
|
+ //! context() after calling this method.
|
|
|
+ void InitializeFromSnapshot(const CPUContextPPC64* context_snapshot);
|
|
|
+
|
|
|
+ //! \brief Returns a pointer to the context structure that this object will
|
|
|
+ //! write.
|
|
|
+ //!
|
|
|
+ //! \attention This returns a non-`const` pointer to this object’s private
|
|
|
+ //! data so that a caller can populate the context structure directly.
|
|
|
+ //! This is done because providing setter interfaces to each field in the
|
|
|
+ //! context structure would be unwieldy and cumbersome. Care must be taken
|
|
|
+ //! to populate the context structure correctly. The context structure
|
|
|
+ //! must only be modified while this object is in the #kStateMutable
|
|
|
+ //! state.
|
|
|
+ MinidumpContextPPC64* context() { return &context_; }
|
|
|
+
|
|
|
+ protected:
|
|
|
+ // MinidumpWritable:
|
|
|
+ bool WriteObject(FileWriterInterface* file_writer) override;
|
|
|
+
|
|
|
+ // MinidumpContextWriter:
|
|
|
+ size_t ContextSize() const override;
|
|
|
+
|
|
|
+ private:
|
|
|
+ MinidumpContextPPC64 context_;
|
|
|
+};
|
|
|
+
|
|
|
} // namespace crashpad
|
|
|
|
|
|
#endif // CRASHPAD_MINIDUMP_MINIDUMP_CONTEXT_WRITER_H_
|
|
|
Index: chromium-120.0.6099.71/third_party/crashpad/crashpad/minidump/minidump_context_writer_test.cc
|
|
|
===================================================================
|
|
|
--- chromium-120.0.6099.71.orig/third_party/crashpad/crashpad/minidump/minidump_context_writer_test.cc
|
|
|
+++ chromium-120.0.6099.71/third_party/crashpad/crashpad/minidump/minidump_context_writer_test.cc
|
|
|
@@ -328,6 +328,21 @@ TYPED_TEST(MinidumpContextWriter, RISCV6
|
|
|
TypeParam>(context, ExpectMinidumpContextRISCV64, kSeed);
|
|
|
}
|
|
|
|
|
|
+TEST(MinidumpContextWriter, PPC64_Zeros) {
|
|
|
+ EmptyContextTest<MinidumpContextPPC64Writer, MinidumpContextPPC64>(
|
|
|
+ ExpectMinidumpContextPPC64);
|
|
|
+}
|
|
|
+
|
|
|
+TEST(MinidumpContextWriter, PPC64_FromSnapshot) {
|
|
|
+ constexpr uint32_t kSeed = 64;
|
|
|
+ CPUContextPPC64 context_ppc64;
|
|
|
+ CPUContext context;
|
|
|
+ context.ppc64 = &context_ppc64;
|
|
|
+ InitializeCPUContextPPC64(&context, kSeed);
|
|
|
+ FromSnapshotTest<MinidumpContextPPC64Writer, MinidumpContextPPC64>(
|
|
|
+ context, ExpectMinidumpContextPPC64, kSeed);
|
|
|
+}
|
|
|
+
|
|
|
} // namespace
|
|
|
} // namespace test
|
|
|
} // namespace crashpad
|
|
|
Index: chromium-120.0.6099.71/third_party/crashpad/crashpad/minidump/minidump_misc_info_writer.cc
|
|
|
===================================================================
|
|
|
--- chromium-120.0.6099.71.orig/third_party/crashpad/crashpad/minidump/minidump_misc_info_writer.cc
|
|
|
+++ chromium-120.0.6099.71/third_party/crashpad/crashpad/minidump/minidump_misc_info_writer.cc
|
|
|
@@ -177,6 +177,8 @@ std::string MinidumpMiscInfoDebugBuildSt
|
|
|
static constexpr char kCPU[] = "mips64";
|
|
|
#elif defined(ARCH_CPU_RISCV64)
|
|
|
static constexpr char kCPU[] = "riscv64";
|
|
|
+#elif defined(ARCH_CPU_PPC64)
|
|
|
+ static constexpr char kCPU[] = "ppc64";
|
|
|
#else
|
|
|
#error define kCPU for this CPU
|
|
|
#endif
|
|
|
Index: chromium-120.0.6099.71/third_party/crashpad/crashpad/minidump/test/minidump_context_test_util.cc
|
|
|
===================================================================
|
|
|
--- chromium-120.0.6099.71.orig/third_party/crashpad/crashpad/minidump/test/minidump_context_test_util.cc
|
|
|
+++ chromium-120.0.6099.71/third_party/crashpad/crashpad/minidump/test/minidump_context_test_util.cc
|
|
|
@@ -297,6 +297,40 @@ void InitializeMinidumpContextRISCV64(Mi
|
|
|
context->fcsr = value++;
|
|
|
}
|
|
|
|
|
|
+void InitializeMinidumpContextPPC64(MinidumpContextPPC64* context,
|
|
|
+ uint32_t seed) {
|
|
|
+ if (seed == 0) {
|
|
|
+ memset(context, 0, sizeof(*context));
|
|
|
+ context->context_flags = kMinidumpContextPPC64;
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ context->context_flags = kMinidumpContextPPC64All;
|
|
|
+
|
|
|
+ uint64_t value = seed;
|
|
|
+ for (size_t i = 0; i < base::size(context->regs); ++i) {
|
|
|
+ context->regs[i] = value++;
|
|
|
+ }
|
|
|
+
|
|
|
+ context->nip = value++;
|
|
|
+ context->msr = value++;
|
|
|
+ context->ccr = value++;
|
|
|
+ context->xer = value++;
|
|
|
+ context->lnk = value++;
|
|
|
+ context->ctr = value++;
|
|
|
+
|
|
|
+ for (size_t i = 0; i < base::size(context->fpregs); ++i) {
|
|
|
+ context->fpregs[i] = static_cast<double>(i);
|
|
|
+ }
|
|
|
+ context->fpscr = value++;
|
|
|
+
|
|
|
+ for (size_t i = 0; i < base::size(context->vregs.save_vr); ++i) {
|
|
|
+ context->vregs.save_vr[i] = {value++, value++};
|
|
|
+ }
|
|
|
+ context->vregs.save_vscr = {value++, value++};
|
|
|
+ context->vregs.save_vrsave = value++;
|
|
|
+}
|
|
|
+
|
|
|
namespace {
|
|
|
|
|
|
// Using Google Test assertions, compares |expected| to |observed|. This is
|
|
|
@@ -645,5 +679,38 @@ void ExpectMinidumpContextRISCV64(uint32
|
|
|
EXPECT_EQ(observed->fcsr, expected.fcsr);
|
|
|
}
|
|
|
|
|
|
+void ExpectMinidumpContextPPC64(uint32_t expect_seed,
|
|
|
+ const MinidumpContextPPC64* observed,
|
|
|
+ bool snapshot) {
|
|
|
+ MinidumpContextPPC64 expected;
|
|
|
+ InitializeMinidumpContextPPC64(&expected, expect_seed);
|
|
|
+
|
|
|
+ EXPECT_EQ(observed->context_flags, expected.context_flags);
|
|
|
+
|
|
|
+ for (size_t i = 0; i < base::size(expected.regs); ++i) {
|
|
|
+ EXPECT_EQ(observed->regs[i], expected.regs[i]);
|
|
|
+ }
|
|
|
+
|
|
|
+ EXPECT_EQ(observed->nip, expected.nip);
|
|
|
+ EXPECT_EQ(observed->msr, expected.msr);
|
|
|
+ EXPECT_EQ(observed->ccr, expected.ccr);
|
|
|
+ EXPECT_EQ(observed->xer, expected.xer);
|
|
|
+ EXPECT_EQ(observed->lnk, expected.lnk);
|
|
|
+ EXPECT_EQ(observed->ctr, expected.ctr);
|
|
|
+
|
|
|
+ for (size_t i = 0; i < base::size(expected.fpregs); ++i) {
|
|
|
+ EXPECT_EQ(observed->fpregs[i], expected.fpregs[i]);
|
|
|
+ }
|
|
|
+ EXPECT_EQ(observed->fpscr, expected.fpscr);
|
|
|
+
|
|
|
+ for (size_t i = 0; i < base::size(expected.vregs.save_vr); ++ i) {
|
|
|
+ EXPECT_EQ(observed->vregs.save_vr[i].lo, expected.vregs.save_vr[i].lo);
|
|
|
+ EXPECT_EQ(observed->vregs.save_vr[i].hi, expected.vregs.save_vr[i].hi);
|
|
|
+ }
|
|
|
+ EXPECT_EQ(observed->vregs.save_vscr.lo, expected.vregs.save_vscr.lo);
|
|
|
+ EXPECT_EQ(observed->vregs.save_vscr.hi, expected.vregs.save_vscr.hi);
|
|
|
+ EXPECT_EQ(observed->vregs.save_vrsave, expected.vregs.save_vrsave);
|
|
|
+}
|
|
|
+
|
|
|
} // namespace test
|
|
|
} // namespace crashpad
|
|
|
Index: chromium-120.0.6099.71/third_party/crashpad/crashpad/minidump/test/minidump_context_test_util.h
|
|
|
===================================================================
|
|
|
--- chromium-120.0.6099.71.orig/third_party/crashpad/crashpad/minidump/test/minidump_context_test_util.h
|
|
|
+++ chromium-120.0.6099.71/third_party/crashpad/crashpad/minidump/test/minidump_context_test_util.h
|
|
|
@@ -90,6 +90,9 @@ void ExpectMinidumpContextMIPS64(uint32_
|
|
|
void ExpectMinidumpContextRISCV64(uint32_t expect_seed,
|
|
|
const MinidumpContextRISCV64* observed,
|
|
|
bool snapshot);
|
|
|
+void ExpectMinidumpContextPPC64(uint32_t expect_seed,
|
|
|
+ const MinidumpContextPPC64* observed,
|
|
|
+ bool snapshot);
|
|
|
//! \}
|
|
|
|
|
|
} // namespace test
|
|
|
Index: chromium-120.0.6099.71/third_party/crashpad/crashpad/snapshot/capture_memory.cc
|
|
|
===================================================================
|
|
|
--- chromium-120.0.6099.71.orig/third_party/crashpad/crashpad/snapshot/capture_memory.cc
|
|
|
+++ chromium-120.0.6099.71/third_party/crashpad/crashpad/snapshot/capture_memory.cc
|
|
|
@@ -122,6 +122,11 @@ void CaptureMemory::PointedToByContext(c
|
|
|
for (size_t i = 0; i < std::size(context.riscv64->regs); ++i) {
|
|
|
MaybeCaptureMemoryAround(delegate, context.riscv64->regs[i]);
|
|
|
}
|
|
|
+#elif defined(ARCH_CPU_PPC64_FAMILY)
|
|
|
+ MaybeCaptureMemoryAround(delegate, context.ppc64->nip);
|
|
|
+ for (size_t i = 0; i < std::size(context.ppc64->regs); ++i) {
|
|
|
+ MaybeCaptureMemoryAround(delegate, context.ppc64->regs[i]);
|
|
|
+ }
|
|
|
#else
|
|
|
#error Port.
|
|
|
#endif
|
|
|
Index: chromium-120.0.6099.71/third_party/crashpad/crashpad/snapshot/cpu_architecture.h
|
|
|
===================================================================
|
|
|
--- chromium-120.0.6099.71.orig/third_party/crashpad/crashpad/snapshot/cpu_architecture.h
|
|
|
+++ chromium-120.0.6099.71/third_party/crashpad/crashpad/snapshot/cpu_architecture.h
|
|
|
@@ -47,6 +47,9 @@ enum CPUArchitecture {
|
|
|
|
|
|
//! \brief 64-bit RISC-V.
|
|
|
kCPUArchitectureRISCV64,
|
|
|
+
|
|
|
+ //! \brief 64-bit PPC64.
|
|
|
+ kCPUArchitecturePPC64
|
|
|
};
|
|
|
|
|
|
} // namespace crashpad
|
|
|
Index: chromium-120.0.6099.71/third_party/crashpad/crashpad/snapshot/cpu_context.cc
|
|
|
===================================================================
|
|
|
--- chromium-120.0.6099.71.orig/third_party/crashpad/crashpad/snapshot/cpu_context.cc
|
|
|
+++ chromium-120.0.6099.71/third_party/crashpad/crashpad/snapshot/cpu_context.cc
|
|
|
@@ -173,6 +173,8 @@ uint64_t CPUContext::InstructionPointer(
|
|
|
return arm64->pc;
|
|
|
case kCPUArchitectureRISCV64:
|
|
|
return riscv64->pc;
|
|
|
+ case kCPUArchitecturePPC64:
|
|
|
+ return ppc64->nip;
|
|
|
default:
|
|
|
NOTREACHED();
|
|
|
return ~0ull;
|
|
|
@@ -191,6 +193,8 @@ uint64_t CPUContext::StackPointer() cons
|
|
|
return arm64->sp;
|
|
|
case kCPUArchitectureRISCV64:
|
|
|
return riscv64->regs[1];
|
|
|
+ case kCPUArchitecturePPC64:
|
|
|
+ return ppc64->regs[1];
|
|
|
default:
|
|
|
NOTREACHED();
|
|
|
return ~0ull;
|
|
|
@@ -231,6 +235,7 @@ bool CPUContext::Is64Bit() const {
|
|
|
case kCPUArchitectureX86_64:
|
|
|
case kCPUArchitectureARM64:
|
|
|
case kCPUArchitectureMIPS64EL:
|
|
|
+ case kCPUArchitecturePPC64:
|
|
|
case kCPUArchitectureRISCV64:
|
|
|
return true;
|
|
|
case kCPUArchitectureX86:
|
|
|
Index: chromium-120.0.6099.71/third_party/crashpad/crashpad/snapshot/cpu_context.h
|
|
|
===================================================================
|
|
|
--- chromium-120.0.6099.71.orig/third_party/crashpad/crashpad/snapshot/cpu_context.h
|
|
|
+++ chromium-120.0.6099.71/third_party/crashpad/crashpad/snapshot/cpu_context.h
|
|
|
@@ -371,6 +371,24 @@ struct CPUContextRISCV64 {
|
|
|
uint32_t fcsr;
|
|
|
};
|
|
|
|
|
|
+//! \brief A context structure carrying PPC64 CPU state.
|
|
|
+struct CPUContextPPC64 {
|
|
|
+ uint64_t nip;
|
|
|
+ uint64_t msr;
|
|
|
+ uint64_t regs[32];
|
|
|
+ uint64_t ccr;
|
|
|
+ uint64_t xer;
|
|
|
+ uint64_t lnk;
|
|
|
+ uint64_t ctr;
|
|
|
+ double fpregs[32];
|
|
|
+ double fpscr;
|
|
|
+ struct {
|
|
|
+ uint128_struct save_vr[32];
|
|
|
+ uint128_struct save_vscr;
|
|
|
+ uint32_t save_vrsave;
|
|
|
+ } vregs;
|
|
|
+};
|
|
|
+
|
|
|
//! \brief A context structure capable of carrying the context of any supported
|
|
|
//! CPU architecture.
|
|
|
struct CPUContext {
|
|
|
@@ -412,6 +430,7 @@ struct CPUContext {
|
|
|
CPUContextMIPS* mipsel;
|
|
|
CPUContextMIPS64* mips64;
|
|
|
CPUContextRISCV64* riscv64;
|
|
|
+ CPUContextPPC64* ppc64;
|
|
|
};
|
|
|
};
|
|
|
|
|
|
Index: chromium-120.0.6099.71/third_party/crashpad/crashpad/snapshot/linux/cpu_context_linux.h
|
|
|
===================================================================
|
|
|
--- chromium-120.0.6099.71.orig/third_party/crashpad/crashpad/snapshot/linux/cpu_context_linux.h
|
|
|
+++ chromium-120.0.6099.71/third_party/crashpad/crashpad/snapshot/linux/cpu_context_linux.h
|
|
|
@@ -15,6 +15,7 @@
|
|
|
#ifndef CRASHPAD_SNAPSHOT_LINUX_CPU_CONTEXT_LINUX_H_
|
|
|
#define CRASHPAD_SNAPSHOT_LINUX_CPU_CONTEXT_LINUX_H_
|
|
|
|
|
|
+#include <cstring>
|
|
|
#include "build/build_config.h"
|
|
|
#include "snapshot/cpu_context.h"
|
|
|
#include "snapshot/linux/signal_context.h"
|
|
|
@@ -188,6 +189,78 @@ void InitializeCPUContextRISCV64(const T
|
|
|
|
|
|
#endif // ARCH_CPU_RISCV64 || DOXYGEN
|
|
|
|
|
|
+#if defined(ARCH_CPU_PPC64_FAMILY) || DOXYGEN
|
|
|
+
|
|
|
+//! \brief Initializes a CPUContextPPC64 structure from native context
|
|
|
+//! structures on Linux.
|
|
|
+//!
|
|
|
+//! \param[in] thread_context The native thread context.
|
|
|
+//! \param[in] float_context The native float context.
|
|
|
+//! \param[in] vector_context The native vector context.
|
|
|
+//! \param[out] context The CPUContextPPC64 structure to initialize.
|
|
|
+template <typename Traits>
|
|
|
+void InitializeCPUContextPPC64(
|
|
|
+ const ThreadContext::t64_t& thread_context,
|
|
|
+ const FloatContext::f64_t& float_context,
|
|
|
+ const VectorContext::v64_t& vector_context,
|
|
|
+ typename Traits::CPUContext* context) {
|
|
|
+
|
|
|
+ memcpy(context->regs, thread_context.gpr, sizeof(context->regs));
|
|
|
+ context->nip = thread_context.nip;
|
|
|
+ context->msr = thread_context.msr;
|
|
|
+ context->ccr = thread_context.ccr;
|
|
|
+ context->xer = thread_context.xer;
|
|
|
+ context->lnk = thread_context.lnk;
|
|
|
+ context->ctr = thread_context.ctr;
|
|
|
+
|
|
|
+ memcpy(context->fpregs, float_context.fpregs, sizeof(context->fpregs));
|
|
|
+ context->fpscr = float_context.fpscr;
|
|
|
+
|
|
|
+ for (uint8_t i = 0; i < 32; i++) {
|
|
|
+ context->vregs.save_vr[i] = {
|
|
|
+ (((uint64_t)vector_context.vrregs[i][0]) << 32) |
|
|
|
+ vector_context.vrregs[i][1],
|
|
|
+ (((uint64_t)vector_context.vrregs[i][2]) << 32) |
|
|
|
+ vector_context.vrregs[i][3]
|
|
|
+ };
|
|
|
+ }
|
|
|
+ context->vregs.save_vrsave = vector_context.vrsave;
|
|
|
+ context->vregs.save_vscr = {0, (uint64_t)vector_context.vscr.vscr_word};
|
|
|
+}
|
|
|
+
|
|
|
+template <typename Traits>
|
|
|
+void InitializeCPUContextPPC64(
|
|
|
+ const SignalThreadContext64 &thread_context,
|
|
|
+ const SignalFloatContext64 &float_context,
|
|
|
+ const SignalVectorContext64 &vector_context,
|
|
|
+ typename Traits::CPUContext* context) {
|
|
|
+
|
|
|
+ memcpy(context->regs, thread_context.regs, sizeof(context->regs));
|
|
|
+ context->nip = thread_context.nip;
|
|
|
+ context->msr = thread_context.msr;
|
|
|
+ context->ccr = thread_context.ccr;
|
|
|
+ context->xer = thread_context.xer;
|
|
|
+ context->lnk = thread_context.lnk;
|
|
|
+ context->ctr = thread_context.ctr;
|
|
|
+
|
|
|
+ memcpy(context->fpregs, float_context.regs, sizeof(context->fpregs));
|
|
|
+ context->fpscr = float_context.fpscr;
|
|
|
+
|
|
|
+ for (uint8_t i = 0; i < 32; i++) {
|
|
|
+ context->vregs.save_vr[i] = {
|
|
|
+ (((uint64_t)vector_context.vrregs[i][0]) << 32) |
|
|
|
+ vector_context.vrregs[i][1],
|
|
|
+ (((uint64_t)vector_context.vrregs[i][2]) << 32) |
|
|
|
+ vector_context.vrregs[i][3]
|
|
|
+ };
|
|
|
+ }
|
|
|
+ context->vregs.save_vrsave = vector_context.vrsave;
|
|
|
+ context->vregs.save_vscr = {0, (uint64_t)vector_context.vscr.vscr_word};
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+#endif
|
|
|
+
|
|
|
} // namespace internal
|
|
|
} // namespace crashpad
|
|
|
|
|
|
Index: chromium-120.0.6099.71/third_party/crashpad/crashpad/snapshot/linux/debug_rendezvous_test.cc
|
|
|
===================================================================
|
|
|
--- chromium-120.0.6099.71.orig/third_party/crashpad/crashpad/snapshot/linux/debug_rendezvous_test.cc
|
|
|
+++ chromium-120.0.6099.71/third_party/crashpad/crashpad/snapshot/linux/debug_rendezvous_test.cc
|
|
|
@@ -195,12 +195,15 @@ void TestAgainstTarget(PtraceConnection*
|
|
|
device == 0 && inode == 0 && mapping_name == "[vdso]";
|
|
|
#if defined(ARCH_CPU_X86)
|
|
|
static constexpr char kPrefix[] = "linux-gate.so.";
|
|
|
+ static constexpr char kPrefix64[] = "linux-gate.so.";
|
|
|
#else
|
|
|
static constexpr char kPrefix[] = "linux-vdso.so.";
|
|
|
+ static constexpr char kPrefix64[] = "linux-vdso64.so.";
|
|
|
#endif
|
|
|
return is_vdso_mapping ==
|
|
|
(module_name.empty() ||
|
|
|
- module_name.compare(0, strlen(kPrefix), kPrefix) == 0);
|
|
|
+ module_name.compare(0, strlen(kPrefix), kPrefix) == 0) ||
|
|
|
+ module_name.compare(0, strlen(kPrefix64), kPrefix64) == 0);
|
|
|
},
|
|
|
module_mapping->name,
|
|
|
module_mapping->device,
|
|
|
Index: chromium-120.0.6099.71/third_party/crashpad/crashpad/snapshot/linux/exception_snapshot_linux.cc
|
|
|
===================================================================
|
|
|
--- chromium-120.0.6099.71.orig/third_party/crashpad/crashpad/snapshot/linux/exception_snapshot_linux.cc
|
|
|
+++ chromium-120.0.6099.71/third_party/crashpad/crashpad/snapshot/linux/exception_snapshot_linux.cc
|
|
|
@@ -367,6 +367,69 @@ bool ExceptionSnapshotLinux::ReadContext
|
|
|
return internal::ReadContext(reader, context_address, context_.riscv64);
|
|
|
}
|
|
|
|
|
|
+#elif defined(ARCH_CPU_PPC64_FAMILY)
|
|
|
+
|
|
|
+template <typename Traits>
|
|
|
+static bool ReadContext(ProcessReaderLinux* reader,
|
|
|
+ LinuxVMAddress context_address,
|
|
|
+ typename Traits::CPUContext* dest_context) {
|
|
|
+ const ProcessMemory* memory = reader->Memory();
|
|
|
+
|
|
|
+ LinuxVMAddress gp_regs_address = context_address +
|
|
|
+ offsetof(UContext, mcontext) +
|
|
|
+ offsetof(typename Traits::MContext, gp_regs);
|
|
|
+
|
|
|
+ typename Traits::SignalThreadContext thread_context;
|
|
|
+ if (!memory->Read(gp_regs_address, sizeof(thread_context), &thread_context)) {
|
|
|
+ LOG(ERROR) << "Couldn't read gp_regs!";
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ LinuxVMAddress fp_regs_address = context_address +
|
|
|
+ offsetof(UContext, mcontext) +
|
|
|
+ offsetof(typename Traits::MContext, fp_regs);
|
|
|
+
|
|
|
+ typename Traits::SignalFloatContext fp_context;
|
|
|
+ if (!memory->Read(fp_regs_address, sizeof(fp_context), &fp_context)) {
|
|
|
+ LOG(ERROR) << "Couldn't read fp_regs!";
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ LinuxVMAddress v_regs_ptr_address = context_address +
|
|
|
+ offsetof(UContext, mcontext) +
|
|
|
+ offsetof(typename Traits::MContext, vmx_reserve) + 8;
|
|
|
+
|
|
|
+ typename Traits::SignalVectorContext v_context;
|
|
|
+ if (!memory->Read(v_regs_ptr_address, sizeof(v_context), &v_context)) {
|
|
|
+ LOG(ERROR) << "Couldn't read v_regs!";
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ InitializeCPUContextPPC64<ContextTraits64>(thread_context, fp_context,
|
|
|
+ v_context, dest_context);
|
|
|
+
|
|
|
+ return true;
|
|
|
+}
|
|
|
+
|
|
|
+template<>
|
|
|
+bool ExceptionSnapshotLinux::ReadContext<ContextTraits64>(
|
|
|
+ ProcessReaderLinux* reader,
|
|
|
+ LinuxVMAddress context_address) {
|
|
|
+ context_.architecture = kCPUArchitecturePPC64;
|
|
|
+ context_.ppc64 = &context_union_.ppc64;
|
|
|
+
|
|
|
+ return internal::ReadContext<ContextTraits64>(
|
|
|
+ reader, context_address, context_.ppc64);
|
|
|
+}
|
|
|
+
|
|
|
+template<>
|
|
|
+bool ExceptionSnapshotLinux::ReadContext<ContextTraits32>(
|
|
|
+ ProcessReaderLinux* reader,
|
|
|
+ LinuxVMAddress context_address) {
|
|
|
+ // PPC64 is 64-bit
|
|
|
+ return false;
|
|
|
+}
|
|
|
+
|
|
|
#endif // ARCH_CPU_X86_FAMILY
|
|
|
|
|
|
bool ExceptionSnapshotLinux::Initialize(
|
|
|
Index: chromium-120.0.6099.71/third_party/crashpad/crashpad/snapshot/linux/exception_snapshot_linux.h
|
|
|
===================================================================
|
|
|
--- chromium-120.0.6099.71.orig/third_party/crashpad/crashpad/snapshot/linux/exception_snapshot_linux.h
|
|
|
+++ chromium-120.0.6099.71/third_party/crashpad/crashpad/snapshot/linux/exception_snapshot_linux.h
|
|
|
@@ -91,6 +91,8 @@ class ExceptionSnapshotLinux final : pub
|
|
|
CPUContextMIPS64 mips64;
|
|
|
#elif defined(ARCH_CPU_RISCV64)
|
|
|
CPUContextRISCV64 riscv64;
|
|
|
+#elif defined(ARCH_CPU_PPC64_FAMILY)
|
|
|
+ CPUContextPPC64 ppc64;
|
|
|
#endif
|
|
|
} context_union_;
|
|
|
CPUContext context_;
|
|
|
Index: chromium-120.0.6099.71/third_party/crashpad/crashpad/snapshot/linux/exception_snapshot_linux_test.cc
|
|
|
===================================================================
|
|
|
--- chromium-120.0.6099.71.orig/third_party/crashpad/crashpad/snapshot/linux/exception_snapshot_linux_test.cc
|
|
|
+++ chromium-120.0.6099.71/third_party/crashpad/crashpad/snapshot/linux/exception_snapshot_linux_test.cc
|
|
|
@@ -325,7 +325,28 @@ void ExpectContext(const CPUContext& act
|
|
|
sizeof(actual.riscv64->fpregs)),
|
|
|
0);
|
|
|
}
|
|
|
+#elif defined(ARCH_CPU_PPC64_FAMILY)
|
|
|
+using NativeCPUContext = ucontext_t;
|
|
|
|
|
|
+void InitializeContext(NativeCPUContext* context) {
|
|
|
+ for (size_t reg = 0; reg < 32; ++reg) {
|
|
|
+ context->uc_mcontext.gp_regs[reg] = reg;
|
|
|
+ }
|
|
|
+
|
|
|
+ memset(&context->uc_mcontext.fp_regs, 44,
|
|
|
+ sizeof(context->uc_mcontext.fp_regs));
|
|
|
+}
|
|
|
+
|
|
|
+void ExpectContext(const CPUContext& actual, const NativeCPUContext& expected) {
|
|
|
+ EXPECT_EQ(actual.architecture, kCPUArchitecturePPC64);
|
|
|
+
|
|
|
+ for (size_t reg = 0; reg < 32; ++reg) {
|
|
|
+ EXPECT_EQ(actual.ppc64->regs[reg], expected.uc_mcontext.gp_regs[reg]);
|
|
|
+ }
|
|
|
+
|
|
|
+ EXPECT_EQ(memcmp(actual.ppc64->fpregs, expected.uc_mcontext.fp_regs,
|
|
|
+ sizeof(actual.ppc64->fpregs)), 0);
|
|
|
+}
|
|
|
#else
|
|
|
#error Port.
|
|
|
#endif
|
|
|
Index: chromium-120.0.6099.71/third_party/crashpad/crashpad/snapshot/linux/process_reader_linux.cc
|
|
|
===================================================================
|
|
|
--- chromium-120.0.6099.71.orig/third_party/crashpad/crashpad/snapshot/linux/process_reader_linux.cc
|
|
|
+++ chromium-120.0.6099.71/third_party/crashpad/crashpad/snapshot/linux/process_reader_linux.cc
|
|
|
@@ -129,6 +129,8 @@ void ProcessReaderLinux::Thread::Initial
|
|
|
: thread_info.thread_context.t32.regs[29];
|
|
|
#elif defined(ARCH_CPU_RISCV64)
|
|
|
stack_pointer = thread_info.thread_context.t64.regs[1];
|
|
|
+#elif defined(ARCH_CPU_PPC64_FAMILY)
|
|
|
+ stack_pointer = thread_info.thread_context.t64.gpr[1];
|
|
|
#else
|
|
|
#error Port.
|
|
|
#endif
|
|
|
Index: chromium-120.0.6099.71/third_party/crashpad/crashpad/snapshot/linux/signal_context.h
|
|
|
===================================================================
|
|
|
--- chromium-120.0.6099.71.orig/third_party/crashpad/crashpad/snapshot/linux/signal_context.h
|
|
|
+++ chromium-120.0.6099.71/third_party/crashpad/crashpad/snapshot/linux/signal_context.h
|
|
|
@@ -456,6 +456,89 @@ static_assert(offsetof(UContext<ContextT
|
|
|
offsetof(ucontext_t, uc_mcontext.__fpregs),
|
|
|
"context offset mismatch");
|
|
|
|
|
|
+#elif defined(ARCH_CPU_PPC64_FAMILY)
|
|
|
+
|
|
|
+struct SignalThreadContext64 {
|
|
|
+ uint64_t regs[32];
|
|
|
+ uint64_t nip;
|
|
|
+ uint64_t msr;
|
|
|
+ uint64_t orig_r3;
|
|
|
+ uint64_t ctr;
|
|
|
+ uint64_t lnk;
|
|
|
+ uint64_t xer;
|
|
|
+ uint64_t ccr;
|
|
|
+ uint64_t softe;
|
|
|
+ uint64_t trap;
|
|
|
+ uint64_t dar;
|
|
|
+ uint64_t dsisr;
|
|
|
+ uint64_t result;
|
|
|
+ uint64_t dscr;
|
|
|
+ uint64_t fpr0[3];
|
|
|
+};
|
|
|
+
|
|
|
+struct SignalFloatContext64 {
|
|
|
+ double regs[32];
|
|
|
+ double fpscr;
|
|
|
+};
|
|
|
+
|
|
|
+struct SignalVectorContext64 {
|
|
|
+ int32_t vrregs[32][4];
|
|
|
+ struct {
|
|
|
+ int32_t __pad[3];
|
|
|
+ int32_t vscr_word;
|
|
|
+ } vscr;
|
|
|
+ int32_t vrsave;
|
|
|
+ int32_t __pad[3];
|
|
|
+} __attribute__((__aligned__(16)));
|
|
|
+
|
|
|
+
|
|
|
+#pragma pack(pop)
|
|
|
+struct MContext64 {
|
|
|
+ uint64_t reserved[4];
|
|
|
+ int32_t signal;
|
|
|
+ int32_t __pad0;
|
|
|
+ uint64_t handler;
|
|
|
+ uint64_t oldmask;
|
|
|
+ uint64_t pt_regs_ptr;
|
|
|
+ SignalThreadContext64 gp_regs;
|
|
|
+ SignalFloatContext64 fp_regs;
|
|
|
+ SignalVectorContext64 *v_regs;
|
|
|
+ int64_t vmx_reserve[69];
|
|
|
+};
|
|
|
+
|
|
|
+struct ContextTraits64 : public Traits64 {
|
|
|
+ using MContext = MContext64;
|
|
|
+ using SignalThreadContext = SignalThreadContext64;
|
|
|
+ using SignalFloatContext = SignalFloatContext64;
|
|
|
+ using SignalVectorContext = SignalVectorContext64;
|
|
|
+ using CPUContext = CPUContextPPC64;
|
|
|
+};
|
|
|
+
|
|
|
+struct ContextTraits32 : public Traits32 {};
|
|
|
+
|
|
|
+struct UContext {
|
|
|
+ uint64_t flags;
|
|
|
+ uint64_t link;
|
|
|
+ SignalStack<ContextTraits64> stack;
|
|
|
+ Sigset<ContextTraits64> sigmask;
|
|
|
+ MContext64 mcontext;
|
|
|
+};
|
|
|
+#pragma pack(push, 1)
|
|
|
+
|
|
|
+static_assert(sizeof(UContext) == sizeof(ucontext_t),
|
|
|
+ "ucontext_t size mismatch");
|
|
|
+static_assert(sizeof(MContext64) == sizeof(mcontext_t),
|
|
|
+ "mcontext_t size mismatch");
|
|
|
+static_assert(sizeof(SignalThreadContext64) == sizeof(gregset_t),
|
|
|
+ "gregset_t size mismatch");
|
|
|
+static_assert(sizeof(SignalFloatContext64) == sizeof(fpregset_t),
|
|
|
+ "fpregset_t size mismatch");
|
|
|
+static_assert(sizeof(SignalVectorContext64) == sizeof(_libc_vrstate),
|
|
|
+ "vrstate size mismatch");
|
|
|
+static_assert(offsetof(UContext, mcontext) ==
|
|
|
+ offsetof(ucontext_t, uc_mcontext), "mcontext offset mismatch");
|
|
|
+static_assert(offsetof(MContext64, gp_regs) ==
|
|
|
+ offsetof(mcontext_t, gp_regs), "gp_regs offset mismatch");
|
|
|
#else
|
|
|
#error Port.
|
|
|
#endif // ARCH_CPU_X86_FAMILY
|
|
|
Index: chromium-120.0.6099.71/third_party/crashpad/crashpad/snapshot/linux/system_snapshot_linux.cc
|
|
|
===================================================================
|
|
|
--- chromium-120.0.6099.71.orig/third_party/crashpad/crashpad/snapshot/linux/system_snapshot_linux.cc
|
|
|
+++ chromium-120.0.6099.71/third_party/crashpad/crashpad/snapshot/linux/system_snapshot_linux.cc
|
|
|
@@ -208,6 +208,8 @@ CPUArchitecture SystemSnapshotLinux::Get
|
|
|
: kCPUArchitectureMIPSEL;
|
|
|
#elif defined(ARCH_CPU_RISCV64)
|
|
|
return kCPUArchitectureRISCV64;
|
|
|
+#elif defined(ARCH_CPU_PPC64_FAMILY)
|
|
|
+ return kCPUArchitecturePPC64;
|
|
|
#else
|
|
|
#error port to your architecture
|
|
|
#endif
|
|
|
@@ -226,6 +228,9 @@ uint32_t SystemSnapshotLinux::CPURevisio
|
|
|
#elif defined(ARCH_CPU_RISCV64)
|
|
|
// Not implemented
|
|
|
return 0;
|
|
|
+#elif defined(ARCH_CPU_PPC64_FAMILY)
|
|
|
+ // Not yet implemented on PPC64
|
|
|
+ return 0;
|
|
|
#else
|
|
|
#error port to your architecture
|
|
|
#endif
|
|
|
@@ -249,6 +254,9 @@ std::string SystemSnapshotLinux::CPUVend
|
|
|
#elif defined(ARCH_CPU_RISCV64)
|
|
|
// Not implemented
|
|
|
return std::string();
|
|
|
+#elif defined(ARCH_CPU_PPC64_FAMILY)
|
|
|
+ // Not yet implemented on PPC64
|
|
|
+ return std::string();
|
|
|
#else
|
|
|
#error port to your architecture
|
|
|
#endif
|
|
|
@@ -385,6 +393,9 @@ bool SystemSnapshotLinux::NXEnabled() co
|
|
|
#elif defined(ARCH_CPU_RISCV64)
|
|
|
// Not implemented
|
|
|
return false;
|
|
|
+#elif defined(ARCH_CPU_PPC64_FAMILY)
|
|
|
+ // Not yet implemented on PPC64
|
|
|
+ return false;
|
|
|
#else
|
|
|
#error Port.
|
|
|
#endif // ARCH_CPU_X86_FAMILY
|
|
|
Index: chromium-120.0.6099.71/third_party/crashpad/crashpad/snapshot/linux/thread_snapshot_linux.cc
|
|
|
===================================================================
|
|
|
--- chromium-120.0.6099.71.orig/third_party/crashpad/crashpad/snapshot/linux/thread_snapshot_linux.cc
|
|
|
+++ chromium-120.0.6099.71/third_party/crashpad/crashpad/snapshot/linux/thread_snapshot_linux.cc
|
|
|
@@ -196,6 +196,14 @@ bool ThreadSnapshotLinux::Initialize(
|
|
|
InitializeCPUContextRISCV64(thread.thread_info.thread_context.t64,
|
|
|
thread.thread_info.float_context.f64,
|
|
|
context_.riscv64);
|
|
|
+#elif defined(ARCH_CPU_PPC64_FAMILY)
|
|
|
+ context_.architecture = kCPUArchitecturePPC64;
|
|
|
+ context_.ppc64 = &context_union_.ppc64;
|
|
|
+ InitializeCPUContextPPC64<ContextTraits64>(
|
|
|
+ thread.thread_info.thread_context.t64,
|
|
|
+ thread.thread_info.float_context.f64,
|
|
|
+ thread.thread_info.vector_context.v64,
|
|
|
+ context_.ppc64);
|
|
|
#else
|
|
|
#error Port.
|
|
|
#endif
|
|
|
Index: chromium-120.0.6099.71/third_party/crashpad/crashpad/snapshot/linux/thread_snapshot_linux.h
|
|
|
===================================================================
|
|
|
--- chromium-120.0.6099.71.orig/third_party/crashpad/crashpad/snapshot/linux/thread_snapshot_linux.h
|
|
|
+++ chromium-120.0.6099.71/third_party/crashpad/crashpad/snapshot/linux/thread_snapshot_linux.h
|
|
|
@@ -76,6 +76,8 @@ class ThreadSnapshotLinux final : public
|
|
|
CPUContextMIPS64 mips64;
|
|
|
#elif defined(ARCH_CPU_RISCV64)
|
|
|
CPUContextRISCV64 riscv64;
|
|
|
+#elif defined(ARCH_CPU_PPC64_FAMILY)
|
|
|
+ CPUContextPPC64 ppc64;
|
|
|
#else
|
|
|
#error Port.
|
|
|
#endif // ARCH_CPU_X86_FAMILY
|
|
|
Index: chromium-120.0.6099.71/third_party/crashpad/crashpad/snapshot/test/test_cpu_context.cc
|
|
|
===================================================================
|
|
|
--- chromium-120.0.6099.71.orig/third_party/crashpad/crashpad/snapshot/test/test_cpu_context.cc
|
|
|
+++ chromium-120.0.6099.71/third_party/crashpad/crashpad/snapshot/test/test_cpu_context.cc
|
|
|
@@ -317,5 +317,38 @@ void InitializeCPUContextRISCV64(CPUCont
|
|
|
riscv64->fcsr = value++;
|
|
|
}
|
|
|
|
|
|
+void InitializeCPUContextPPC64(CPUContext* context, uint32_t seed) {
|
|
|
+ context->architecture = kCPUArchitecturePPC64;
|
|
|
+ CPUContextPPC64* ppc64 = context->ppc64;
|
|
|
+
|
|
|
+ if (seed == 0) {
|
|
|
+ memset(ppc64, 0, sizeof(*ppc64));
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ uint64_t value = seed;
|
|
|
+ for (size_t i = 0; i < base::size(ppc64->regs); ++i) {
|
|
|
+ ppc64->regs[i] = value++;
|
|
|
+ }
|
|
|
+
|
|
|
+ ppc64->nip = value++;
|
|
|
+ ppc64->msr = value++;
|
|
|
+ ppc64->ccr = value++;
|
|
|
+ ppc64->xer = value++;
|
|
|
+ ppc64->lnk = value++;
|
|
|
+ ppc64->ctr = value++;
|
|
|
+
|
|
|
+ for (size_t i = 0; i < base::size(ppc64->fpregs); ++i) {
|
|
|
+ ppc64->fpregs[i] = static_cast<double>(i);
|
|
|
+ }
|
|
|
+ ppc64->fpscr = value++;
|
|
|
+
|
|
|
+ for (size_t i = 0; i < base::size(ppc64->vregs.save_vr); ++i) {
|
|
|
+ ppc64->vregs.save_vr[i] = {value++, value++};
|
|
|
+ }
|
|
|
+ ppc64->vregs.save_vscr = {value++, value++};
|
|
|
+ ppc64->vregs.save_vrsave = value++;
|
|
|
+}
|
|
|
+
|
|
|
} // namespace test
|
|
|
} // namespace crashpad
|
|
|
Index: chromium-120.0.6099.71/third_party/crashpad/crashpad/snapshot/test/test_cpu_context.h
|
|
|
===================================================================
|
|
|
--- chromium-120.0.6099.71.orig/third_party/crashpad/crashpad/snapshot/test/test_cpu_context.h
|
|
|
+++ chromium-120.0.6099.71/third_party/crashpad/crashpad/snapshot/test/test_cpu_context.h
|
|
|
@@ -64,6 +64,7 @@ void InitializeCPUContextARM64(CPUContex
|
|
|
void InitializeCPUContextMIPS(CPUContext* context, uint32_t seed);
|
|
|
void InitializeCPUContextMIPS64(CPUContext* context, uint32_t seed);
|
|
|
void InitializeCPUContextRISCV64(CPUContext* context, uint32_t seed);
|
|
|
+void InitializeCPUContextPPC64(CPUContext* context, uint32_t seed);
|
|
|
//! \}
|
|
|
|
|
|
} // namespace test
|
|
|
Index: chromium-120.0.6099.71/third_party/crashpad/crashpad/test/linux/get_tls.cc
|
|
|
===================================================================
|
|
|
--- chromium-120.0.6099.71.orig/third_party/crashpad/crashpad/test/linux/get_tls.cc
|
|
|
+++ chromium-120.0.6099.71/third_party/crashpad/crashpad/test/linux/get_tls.cc
|
|
|
@@ -51,6 +51,8 @@ LinuxVMAddress GetTLS() {
|
|
|
: "$3");
|
|
|
#elif defined(ARCH_CPU_RISCV64)
|
|
|
asm("mv %0, tp" : "=r"(tls));
|
|
|
+#elif defined(ARCH_CPU_PPC64)
|
|
|
+ asm("mr %0, 13": "=r"(tls));
|
|
|
#else
|
|
|
#error Port.
|
|
|
#endif // ARCH_CPU_ARMEL
|
|
|
Index: chromium-120.0.6099.71/third_party/crashpad/crashpad/test/multiprocess_posix.cc
|
|
|
===================================================================
|
|
|
--- chromium-120.0.6099.71.orig/third_party/crashpad/crashpad/test/multiprocess_posix.cc
|
|
|
+++ chromium-120.0.6099.71/third_party/crashpad/crashpad/test/multiprocess_posix.cc
|
|
|
@@ -162,7 +162,8 @@ void Multiprocess::SetExpectedChildTermi
|
|
|
}
|
|
|
|
|
|
void Multiprocess::SetExpectedChildTerminationBuiltinTrap() {
|
|
|
-#if defined(ARCH_CPU_ARM64) || defined(ARCH_CPU_MIPS_FAMILY)
|
|
|
+#if defined(ARCH_CPU_ARM64) || defined(ARCH_CPU_MIPS_FAMILY) || \
|
|
|
+ defined(ARCH_CPU_PPC64_FAMILY)
|
|
|
SetExpectedChildTermination(kTerminationSignal, SIGTRAP);
|
|
|
#else
|
|
|
SetExpectedChildTermination(kTerminationSignal, SIGILL);
|
|
|
Index: chromium-120.0.6099.71/third_party/crashpad/crashpad/util/linux/auxiliary_vector.cc
|
|
|
===================================================================
|
|
|
--- chromium-120.0.6099.71.orig/third_party/crashpad/crashpad/util/linux/auxiliary_vector.cc
|
|
|
+++ chromium-120.0.6099.71/third_party/crashpad/crashpad/util/linux/auxiliary_vector.cc
|
|
|
@@ -56,6 +56,11 @@ bool AuxiliaryVector::Read(PtraceConnect
|
|
|
if (type == AT_IGNORE) {
|
|
|
continue;
|
|
|
}
|
|
|
+#if defined(ARCH_CPU_PPC64_FAMILY)
|
|
|
+ if (type == AT_IGNOREPPC) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+#endif
|
|
|
if (!MapInsertOrReplace(&values_, type, value, nullptr)) {
|
|
|
LOG(ERROR) << "duplicate auxv entry";
|
|
|
return false;
|
|
|
Index: chromium-120.0.6099.71/third_party/crashpad/crashpad/util/linux/ptracer.cc
|
|
|
===================================================================
|
|
|
--- chromium-120.0.6099.71.orig/third_party/crashpad/crashpad/util/linux/ptracer.cc
|
|
|
+++ chromium-120.0.6099.71/third_party/crashpad/crashpad/util/linux/ptracer.cc
|
|
|
@@ -430,6 +430,64 @@ bool GetThreadArea64(pid_t tid,
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
+#elif defined(ARCH_CPU_PPC64_FAMILY)
|
|
|
+// PPC64 has had HAVE_ARCH_TRACEHOOK set since 2.6.27 (even before x86 had it).
|
|
|
+// That means we can simply use PTRACE_GETREGESET.
|
|
|
+
|
|
|
+template <typename Destination>
|
|
|
+bool GetRegisterSet(pid_t tid, int set, Destination* dest, bool can_log) {
|
|
|
+ iovec iov;
|
|
|
+ iov.iov_base = reinterpret_cast<void*>(dest);
|
|
|
+ iov.iov_len = sizeof(*dest);
|
|
|
+ if (ptrace(PTRACE_GETREGSET, tid, reinterpret_cast<void*>(set), &iov) != 0) {
|
|
|
+ PLOG_IF(ERROR, can_log) << "ptrace";
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ if (iov.iov_len != sizeof(*dest)) {
|
|
|
+ LOG_IF(ERROR, can_log) << "Unexpected registers size";
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ return true;
|
|
|
+}
|
|
|
+
|
|
|
+bool GetVectorRegisters64(pid_t tid,
|
|
|
+ VectorContext* context,
|
|
|
+ bool can_log) {
|
|
|
+ return GetRegisterSet(tid, NT_PPC_VMX, &context->v64, can_log);
|
|
|
+}
|
|
|
+
|
|
|
+bool GetFloatingPointRegisters64(pid_t tid,
|
|
|
+ FloatContext* context,
|
|
|
+ bool can_log) {
|
|
|
+ return GetRegisterSet(tid, NT_PRFPREG, &context->f64, can_log);
|
|
|
+}
|
|
|
+
|
|
|
+bool GetThreadArea64(pid_t tid,
|
|
|
+ const ThreadContext& context,
|
|
|
+ LinuxVMAddress* address,
|
|
|
+ bool can_log) {
|
|
|
+ // PPC64 doesn't have PTRACE_GET_THREAD_AREA since the thread pointer
|
|
|
+ // is stored in GPR 13.
|
|
|
+ ThreadContext::t64_t tc;
|
|
|
+ if (!GetRegisterSet(tid, NT_PRSTATUS, &tc, can_log)) {
|
|
|
+ LOG_IF(ERROR, can_log) << "Unable to get thread pointer!";
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ *address = tc.gpr[13];
|
|
|
+
|
|
|
+ return true;
|
|
|
+}
|
|
|
+
|
|
|
+// Stubs for 32-bit functions not applicable on PPC64
|
|
|
+bool GetFloatingPointRegisters32(pid_t tid,
|
|
|
+ FloatContext* context,
|
|
|
+ bool can_log) { return false; }
|
|
|
+bool GetThreadArea32(pid_t tid,
|
|
|
+ const ThreadContext &context,
|
|
|
+ LinuxVMAddress *address,
|
|
|
+ bool can_log) { return false; }
|
|
|
+
|
|
|
#else
|
|
|
#error Port.
|
|
|
#endif // ARCH_CPU_X86_FAMILY
|
|
|
@@ -528,6 +586,9 @@ bool Ptracer::GetThreadInfo(pid_t tid, T
|
|
|
if (is_64_bit_) {
|
|
|
return GetGeneralPurposeRegisters64(tid, &info->thread_context, can_log_) &&
|
|
|
GetFloatingPointRegisters64(tid, &info->float_context, can_log_) &&
|
|
|
+#if defined(ARCH_CPU_PPC64_FAMILY)
|
|
|
+ GetVectorRegisters64(tid, &info->vector_context, can_log_) &&
|
|
|
+#endif
|
|
|
GetThreadArea64(tid,
|
|
|
info->thread_context,
|
|
|
&info->thread_specific_data_address,
|
|
|
Index: chromium-120.0.6099.71/third_party/crashpad/crashpad/util/linux/thread_info.h
|
|
|
===================================================================
|
|
|
--- chromium-120.0.6099.71.orig/third_party/crashpad/crashpad/util/linux/thread_info.h
|
|
|
+++ chromium-120.0.6099.71/third_party/crashpad/crashpad/util/linux/thread_info.h
|
|
|
@@ -34,6 +34,10 @@
|
|
|
#include <asm/ptrace.h>
|
|
|
#endif
|
|
|
|
|
|
+#if defined(ARCH_CPU_PPC64_FAMILY)
|
|
|
+#include <sys/ucontext.h>
|
|
|
+#endif
|
|
|
+
|
|
|
namespace crashpad {
|
|
|
|
|
|
//! \brief The set of general purpose registers for an architecture family.
|
|
|
@@ -87,6 +91,8 @@ union ThreadContext {
|
|
|
uint32_t padding1_;
|
|
|
#elif defined(ARCH_CPU_RISCV64)
|
|
|
// 32 bit RISC-V not supported
|
|
|
+#elif defined(ARCH_CPU_PPC64_FAMILY)
|
|
|
+ // PPC64 is 64-bit
|
|
|
#else
|
|
|
#error Port.
|
|
|
#endif // ARCH_CPU_X86_FAMILY
|
|
|
@@ -144,6 +150,21 @@ union ThreadContext {
|
|
|
// Reflects user_regs_struct in asm/ptrace.h.
|
|
|
uint64_t pc;
|
|
|
uint64_t regs[31];
|
|
|
+#elif defined(ARCH_CPU_PPC64_FAMILY)
|
|
|
+ // Reflects struct pt_regs in asm/ptrace.h.
|
|
|
+ uint64_t gpr[32];
|
|
|
+ uint64_t nip;
|
|
|
+ uint64_t msr;
|
|
|
+ uint64_t orig_gpr3;
|
|
|
+ uint64_t ctr;
|
|
|
+ uint64_t lnk;
|
|
|
+ uint64_t xer;
|
|
|
+ uint64_t ccr;
|
|
|
+ uint64_t softe;
|
|
|
+ uint64_t trap;
|
|
|
+ uint64_t dar;
|
|
|
+ uint64_t dsisr;
|
|
|
+ uint64_t result;
|
|
|
#else
|
|
|
#error Port.
|
|
|
#endif // ARCH_CPU_X86_FAMILY
|
|
|
@@ -156,6 +177,8 @@ union ThreadContext {
|
|
|
using NativeThreadContext = user_regs;
|
|
|
#elif defined(ARCH_CPU_MIPS_FAMILY)
|
|
|
// No appropriate NativeThreadsContext type available for MIPS
|
|
|
+#elif defined(ARCH_CPU_PPC64_FAMILY)
|
|
|
+ using NativeThreadContext = struct pt_regs;
|
|
|
#else
|
|
|
#error Port.
|
|
|
#endif // ARCH_CPU_X86_FAMILY || ARCH_CPU_ARM64 || ARCH_CPU_RISCV64
|
|
|
@@ -233,6 +256,9 @@ union FloatContext {
|
|
|
uint32_t fpu_id;
|
|
|
#elif defined(ARCH_CPU_RISCV64)
|
|
|
// 32 bit RISC-V not supported
|
|
|
+#elif defined(ARCH_CPU_PPC64_FAMILY)
|
|
|
+ // Crashpad's PPC support is 64-bit only, so this
|
|
|
+ // 32bit-only struct is declared as empty.
|
|
|
#else
|
|
|
#error Port.
|
|
|
#endif // ARCH_CPU_X86_FAMILY
|
|
|
@@ -271,6 +297,10 @@ union FloatContext {
|
|
|
// Reflects __riscv_d_ext_state in asm/ptrace.h
|
|
|
uint64_t fpregs[32];
|
|
|
uint64_t fcsr;
|
|
|
+#elif defined(ARCH_CPU_PPC64_FAMILY)
|
|
|
+ // Reflects fpregset_t in sys/ucontext.h
|
|
|
+ double fpregs[32];
|
|
|
+ double fpscr;
|
|
|
#else
|
|
|
#error Port.
|
|
|
#endif // ARCH_CPU_X86_FAMILY
|
|
|
@@ -302,6 +332,8 @@ union FloatContext {
|
|
|
// No appropriate floating point context native type for available MIPS.
|
|
|
#elif defined(ARCH_CPU_RISCV64)
|
|
|
static_assert(sizeof(f64) == sizeof(__riscv_d_ext_state), "Size mismatch");
|
|
|
+#elif defined(ARCH_CPU_PPC64_FAMILY)
|
|
|
+ static_assert(sizeof(f64) == sizeof(fpregset_t), "Size mismatch");
|
|
|
#else
|
|
|
#error Port.
|
|
|
#endif // ARCH_CPU_X86
|
|
|
@@ -309,6 +341,26 @@ union FloatContext {
|
|
|
static_assert(std::is_standard_layout<FloatContext>::value,
|
|
|
"Not standard layout");
|
|
|
|
|
|
+//! \brief The vector registers used for an architecture family
|
|
|
+union VectorContext {
|
|
|
+ struct v32_t {} v32;
|
|
|
+#if defined(ARCH_CPU_PPC64_FAMILY)
|
|
|
+ __attribute__((__aligned__(16))) // Vector context must be doubleword aligned.
|
|
|
+#endif
|
|
|
+ struct v64_t {
|
|
|
+#if defined(ARCH_CPU_PPC64_FAMILY)
|
|
|
+ // Reflects vrregset_t in sys/ucontext.h
|
|
|
+ uint32_t vrregs[32][4];
|
|
|
+ struct {
|
|
|
+ uint32_t __pad[3];
|
|
|
+ uint32_t vscr_word;
|
|
|
+ } vscr;
|
|
|
+ uint32_t vrsave;
|
|
|
+ uint32_t __pad[3];
|
|
|
+#endif
|
|
|
+ } v64;
|
|
|
+};
|
|
|
+
|
|
|
//! \brief A collection of `ptrace`-able information about a thread.
|
|
|
struct ThreadInfo {
|
|
|
ThreadInfo();
|
|
|
@@ -320,6 +372,9 @@ struct ThreadInfo {
|
|
|
//! \brief The floating point registers for the thread.
|
|
|
FloatContext float_context;
|
|
|
|
|
|
+ //! \brief (Optional) The vector registers used for the thread.
|
|
|
+ VectorContext vector_context;
|
|
|
+
|
|
|
//! \brief The thread-local storage address for the thread.
|
|
|
LinuxVMAddress thread_specific_data_address;
|
|
|
};
|
|
|
Index: chromium-120.0.6099.71/third_party/crashpad/crashpad/util/misc/capture_context.h
|
|
|
===================================================================
|
|
|
--- chromium-120.0.6099.71.orig/third_party/crashpad/crashpad/util/misc/capture_context.h
|
|
|
+++ chromium-120.0.6099.71/third_party/crashpad/crashpad/util/misc/capture_context.h
|
|
|
@@ -70,6 +70,7 @@ using NativeCPUContext = ucontext_t;
|
|
|
//! Linux | ARM/ARM64 | `r0`/`x0`
|
|
|
//! Linux | MIPS/MIPS64 | `$a0`
|
|
|
//! Linux | RISCV64 | `a0`
|
|
|
+//! Linux | PPC64 | `r3`
|
|
|
//!
|
|
|
//! Additionally, the value `LR` on ARM/ARM64 will be the return address of
|
|
|
//! this function.
|
|
|
Index: chromium-120.0.6099.71/third_party/crashpad/crashpad/util/misc/capture_context_linux.S
|
|
|
===================================================================
|
|
|
--- chromium-120.0.6099.71.orig/third_party/crashpad/crashpad/util/misc/capture_context_linux.S
|
|
|
+++ chromium-120.0.6099.71/third_party/crashpad/crashpad/util/misc/capture_context_linux.S
|
|
|
@@ -30,7 +30,7 @@
|
|
|
.globl CAPTURECONTEXT_SYMBOL2
|
|
|
#if defined(__i386__) || defined(__x86_64__)
|
|
|
.balign 16, 0x90
|
|
|
-#elif defined(__arm__) || defined(__aarch64__)
|
|
|
+#elif defined(__arm__) || defined(__aarch64__) || defined(__powerpc64__)
|
|
|
.balign 4, 0x0
|
|
|
.type CAPTURECONTEXT_SYMBOL, %function
|
|
|
.type CAPTURECONTEXT_SYMBOL2, %function
|
|
|
@@ -430,6 +430,216 @@ CAPTURECONTEXT_SYMBOL2:
|
|
|
|
|
|
.set at
|
|
|
|
|
|
+#elif defined(__powerpc64__)
|
|
|
+ // Store r0-r31
|
|
|
+ std 0, 0xe8(3) // context->uc_mcontext.gp_regs[0]
|
|
|
+ std 1, 0xf0(3) // context->uc_mcontext.gp_regs[1]
|
|
|
+ std 2, 0xf8(3) // context->uc_mcontext.gp_regs[2]
|
|
|
+ // note that r3's original value was lost
|
|
|
+ std 3, 0x100(3) // context->uc_mcontext.gp_regs[3]
|
|
|
+ std 4, 0x108(3) // context->uc_mcontext.gp_regs[4]
|
|
|
+ std 5, 0x110(3) // context->uc_mcontext.gp_regs[5]
|
|
|
+ std 6, 0x118(3) // context->uc_mcontext.gp_regs[6]
|
|
|
+ std 7, 0x120(3) // context->uc_mcontext.gp_regs[7]
|
|
|
+ std 8, 0x128(3) // context->uc_mcontext.gp_regs[8]
|
|
|
+ std 9, 0x130(3) // context->uc_mcontext.gp_regs[9]
|
|
|
+ std 10, 0x138(3) // context->uc_mcontext.gp_regs[10]
|
|
|
+ std 11, 0x140(3) // context->uc_mcontext.gp_regs[11]
|
|
|
+ std 12, 0x148(3) // context->uc_mcontext.gp_regs[12]
|
|
|
+ std 13, 0x150(3) // context->uc_mcontext.gp_regs[13]
|
|
|
+ std 14, 0x158(3) // context->uc_mcontext.gp_regs[14]
|
|
|
+ std 15, 0x160(3) // context->uc_mcontext.gp_regs[15]
|
|
|
+ std 16, 0x168(3) // context->uc_mcontext.gp_regs[16]
|
|
|
+ std 17, 0x170(3) // context->uc_mcontext.gp_regs[17]
|
|
|
+ std 18, 0x178(3) // context->uc_mcontext.gp_regs[18]
|
|
|
+ std 19, 0x180(3) // context->uc_mcontext.gp_regs[19]
|
|
|
+ std 20, 0x188(3) // context->uc_mcontext.gp_regs[20]
|
|
|
+ std 21, 0x190(3) // context->uc_mcontext.gp_regs[21]
|
|
|
+ std 22, 0x198(3) // context->uc_mcontext.gp_regs[22]
|
|
|
+ std 23, 0x1a0(3) // context->uc_mcontext.gp_regs[23]
|
|
|
+ std 24, 0x1a8(3) // context->uc_mcontext.gp_regs[24]
|
|
|
+ std 25, 0x1b0(3) // context->uc_mcontext.gp_regs[25]
|
|
|
+ std 26, 0x1b8(3) // context->uc_mcontext.gp_regs[26]
|
|
|
+ std 27, 0x1c0(3) // context->uc_mcontext.gp_regs[27]
|
|
|
+ std 28, 0x1c8(3) // context->uc_mcontext.gp_regs[28]
|
|
|
+ std 29, 0x1d0(3) // context->uc_mcontext.gp_regs[29]
|
|
|
+ std 30, 0x1d8(3) // context->uc_mcontext.gp_regs[30]
|
|
|
+ std 31, 0x1e0(3) // context->uc_mcontext.gp_regs[31]
|
|
|
+
|
|
|
+ // For NIP, we can use the value in the link register
|
|
|
+ mflr 0
|
|
|
+ std 0, 0x1e8(3) // context->uc_mcontext.gp_regs[PT_NIP]
|
|
|
+
|
|
|
+ // CTR
|
|
|
+ mfctr 0
|
|
|
+ std 0, 0x200(3) // context->uc_mcontext.gp_regs[PT_CTR]
|
|
|
+
|
|
|
+ // For LNK, we'll use the caller's LR save area (2 stack frames up).
|
|
|
+ // r4 can be used as a scratch register since it has already been saved.
|
|
|
+ ld 4, 0(1)
|
|
|
+ ld 4, 16(4)
|
|
|
+ std 4, 0x208(3) // context->uc_mcontext.gp_regs[PT_LNK]
|
|
|
+
|
|
|
+ // XER
|
|
|
+ mfxer 0
|
|
|
+ std 0, 0x210(3) // context->uc_mcontext.gp_regs[PT_XER]
|
|
|
+
|
|
|
+ // CCR
|
|
|
+ mfcr 0
|
|
|
+ std 0, 0x218(3) // context->uc_mcontext.gp_regs[PT_CCR]
|
|
|
+
|
|
|
+ // MSR, orig_r3, MQ, TRAP, DAR, DSISR, RESULT, DSCR,
|
|
|
+ // not used or not relevant, zero them out.
|
|
|
+ li 4, 0
|
|
|
+ std 4, 0x1f0(3) // context->uc_mcontext.gp_regs[PT_MSR]
|
|
|
+ std 4, 0x1f8(3) // context->uc_mcontext.gp_regs[PT_ORIG_R3]
|
|
|
+ std 4, 0x220(3) // context->uc_mcontext.gp_regs[PT_MQ]
|
|
|
+ std 4, 0x228(3) // context->uc_mcontext.gp_regs[PT_TRAP]
|
|
|
+ std 4, 0x230(3) // context->uc_mcontext.gp_regs[PT_DAR]
|
|
|
+ std 4, 0x238(3) // context->uc_mcontext.gp_regs[PT_DSISR]
|
|
|
+ std 4, 0x240(3) // context->uc_mcontext.gp_regs[PT_RESULT]
|
|
|
+ std 4, 0x248(3) // context->uc_mcontext.gp_regs[PT_DSCR]
|
|
|
+
|
|
|
+ // Update context->uc_mcontext.regs to point to gp_regs
|
|
|
+ addi 0, 3, 0xe8
|
|
|
+ std 0, 0xe0(3)
|
|
|
+
|
|
|
+ // Save floating point registers 0-31
|
|
|
+ stfd 0, 0x268(3) // context->uc_mcontext.fp_regs[0]
|
|
|
+ stfd 1, 0x270(3) // context->uc_mcontext.fp_regs[1]
|
|
|
+ stfd 2, 0x278(3) // context->uc_mcontext.fp_regs[2]
|
|
|
+ stfd 3, 0x280(3) // context->uc_mcontext.fp_regs[3]
|
|
|
+ stfd 4, 0x288(3) // context->uc_mcontext.fp_regs[4]
|
|
|
+ stfd 5, 0x290(3) // context->uc_mcontext.fp_regs[5]
|
|
|
+ stfd 6, 0x298(3) // context->uc_mcontext.fp_regs[6]
|
|
|
+ stfd 7, 0x2a0(3) // context->uc_mcontext.fp_regs[7]
|
|
|
+ stfd 8, 0x2a8(3) // context->uc_mcontext.fp_regs[8]
|
|
|
+ stfd 9, 0x2b0(3) // context->uc_mcontext.fp_regs[9]
|
|
|
+ stfd 10, 0x2b8(3) // context->uc_mcontext.fp_regs[10]
|
|
|
+ stfd 11, 0x2c0(3) // context->uc_mcontext.fp_regs[11]
|
|
|
+ stfd 12, 0x2c8(3) // context->uc_mcontext.fp_regs[12]
|
|
|
+ stfd 13, 0x2d0(3) // context->uc_mcontext.fp_regs[13]
|
|
|
+ stfd 14, 0x2d8(3) // context->uc_mcontext.fp_regs[14]
|
|
|
+ stfd 15, 0x2e0(3) // context->uc_mcontext.fp_regs[15]
|
|
|
+ stfd 16, 0x2e8(3) // context->uc_mcontext.fp_regs[16]
|
|
|
+ stfd 17, 0x2f0(3) // context->uc_mcontext.fp_regs[17]
|
|
|
+ stfd 18, 0x2f8(3) // context->uc_mcontext.fp_regs[18]
|
|
|
+ stfd 19, 0x300(3) // context->uc_mcontext.fp_regs[19]
|
|
|
+ stfd 20, 0x308(3) // context->uc_mcontext.fp_regs[20]
|
|
|
+ stfd 21, 0x310(3) // context->uc_mcontext.fp_regs[21]
|
|
|
+ stfd 22, 0x318(3) // context->uc_mcontext.fp_regs[22]
|
|
|
+ stfd 23, 0x320(3) // context->uc_mcontext.fp_regs[23]
|
|
|
+ stfd 24, 0x328(3) // context->uc_mcontext.fp_regs[24]
|
|
|
+ stfd 25, 0x330(3) // context->uc_mcontext.fp_regs[25]
|
|
|
+ stfd 26, 0x338(3) // context->uc_mcontext.fp_regs[26]
|
|
|
+ stfd 27, 0x340(3) // context->uc_mcontext.fp_regs[27]
|
|
|
+ stfd 28, 0x348(3) // context->uc_mcontext.fp_regs[28]
|
|
|
+ stfd 29, 0x350(3) // context->uc_mcontext.fp_regs[29]
|
|
|
+ stfd 30, 0x358(3) // context->uc_mcontext.fp_regs[30]
|
|
|
+ stfd 31, 0x360(3) // context->uc_mcontext.fp_regs[31]
|
|
|
+
|
|
|
+ // FPSCR
|
|
|
+ mffs 0
|
|
|
+ stfd 0, 0x368(3) // context->uc_mcontext.fp_regs[32]
|
|
|
+
|
|
|
+ // Save VMX Vector registers
|
|
|
+ // Update r4 to contain the base address of vmx_reserve
|
|
|
+ addi 4, 3, 0x378
|
|
|
+ // Ensure that it is quadword aligned
|
|
|
+ andi. 5, 4, 0xF
|
|
|
+ beq 1f // No alignment is necessary
|
|
|
+ // Address is doubleword aligned and not quadword aligned, add 8
|
|
|
+ addi 4, 4, 8
|
|
|
+
|
|
|
+1:
|
|
|
+ // Store VMX registers 0-31
|
|
|
+ // r4 will contain the base address
|
|
|
+ // r5 will contain the index
|
|
|
+ li 5, 0
|
|
|
+ stvx 0, 4, 5 // context->uc_mcontext.vmx_reserve[(align) + 0]
|
|
|
+ addi 5, 5, 16
|
|
|
+ stvx 1, 4, 5 // context->uc_mcontext.vmx_reserve[(align) + 1]
|
|
|
+ addi 5, 5, 16
|
|
|
+ stvx 2, 4, 5 // context->uc_mcontext.vmx_reserve[(align) + 2]
|
|
|
+ addi 5, 5, 16
|
|
|
+ stvx 3, 4, 5 // context->uc_mcontext.vmx_reserve[(align) + 3]
|
|
|
+ addi 5, 5, 16
|
|
|
+ stvx 4, 4, 5 // context->uc_mcontext.vmx_reserve[(align) + 4]
|
|
|
+ addi 5, 5, 16
|
|
|
+ stvx 5, 4, 5 // context->uc_mcontext.vmx_reserve[(align) + 5]
|
|
|
+ addi 5, 5, 16
|
|
|
+ stvx 6, 4, 5 // context->uc_mcontext.vmx_reserve[(align) + 6]
|
|
|
+ addi 5, 5, 16
|
|
|
+ stvx 7, 4, 5 // context->uc_mcontext.vmx_reserve[(align) + 7]
|
|
|
+ addi 5, 5, 16
|
|
|
+ stvx 8, 4, 5 // context->uc_mcontext.vmx_reserve[(align) + 8]
|
|
|
+ addi 5, 5, 16
|
|
|
+ stvx 9, 4, 5 // context->uc_mcontext.vmx_reserve[(align) + 9]
|
|
|
+ addi 5, 5, 16
|
|
|
+ stvx 10, 4, 5 // context->uc_mcontext.vmx_reserve[(align) + 10]
|
|
|
+ addi 5, 5, 16
|
|
|
+ stvx 11, 4, 5 // context->uc_mcontext.vmx_reserve[(align) + 11]
|
|
|
+ addi 5, 5, 16
|
|
|
+ stvx 12, 4, 5 // context->uc_mcontext.vmx_reserve[(align) + 12]
|
|
|
+ addi 5, 5, 16
|
|
|
+ stvx 13, 4, 5 // context->uc_mcontext.vmx_reserve[(align) + 13]
|
|
|
+ addi 5, 5, 16
|
|
|
+ stvx 14, 4, 5 // context->uc_mcontext.vmx_reserve[(align) + 14]
|
|
|
+ addi 5, 5, 16
|
|
|
+ stvx 15, 4, 5 // context->uc_mcontext.vmx_reserve[(align) + 15]
|
|
|
+ addi 5, 5, 16
|
|
|
+ stvx 16, 4, 5 // context->uc_mcontext.vmx_reserve[(align) + 16]
|
|
|
+ addi 5, 5, 16
|
|
|
+ stvx 17, 4, 5 // context->uc_mcontext.vmx_reserve[(align) + 17]
|
|
|
+ addi 5, 5, 16
|
|
|
+ stvx 18, 4, 5 // context->uc_mcontext.vmx_reserve[(align) + 18]
|
|
|
+ addi 5, 5, 16
|
|
|
+ stvx 19, 4, 5 // context->uc_mcontext.vmx_reserve[(align) + 19]
|
|
|
+ addi 5, 5, 16
|
|
|
+ stvx 20, 4, 5 // context->uc_mcontext.vmx_reserve[(align) + 20]
|
|
|
+ addi 5, 5, 16
|
|
|
+ stvx 21, 4, 5 // context->uc_mcontext.vmx_reserve[(align) + 21]
|
|
|
+ addi 5, 5, 16
|
|
|
+ stvx 22, 4, 5 // context->uc_mcontext.vmx_reserve[(align) + 22]
|
|
|
+ addi 5, 5, 16
|
|
|
+ stvx 23, 4, 5 // context->uc_mcontext.vmx_reserve[(align) + 23]
|
|
|
+ addi 5, 5, 16
|
|
|
+ stvx 24, 4, 5 // context->uc_mcontext.vmx_reserve[(align) + 24]
|
|
|
+ addi 5, 5, 16
|
|
|
+ stvx 25, 4, 5 // context->uc_mcontext.vmx_reserve[(align) + 25]
|
|
|
+ addi 5, 5, 16
|
|
|
+ stvx 26, 4, 5 // context->uc_mcontext.vmx_reserve[(align) + 26]
|
|
|
+ addi 5, 5, 16
|
|
|
+ stvx 27, 4, 5 // context->uc_mcontext.vmx_reserve[(align) + 27]
|
|
|
+ addi 5, 5, 16
|
|
|
+ stvx 28, 4, 5 // context->uc_mcontext.vmx_reserve[(align) + 28]
|
|
|
+ addi 5, 5, 16
|
|
|
+ stvx 29, 4, 5 // context->uc_mcontext.vmx_reserve[(align) + 29]
|
|
|
+ addi 5, 5, 16
|
|
|
+ stvx 30, 4, 5 // context->uc_mcontext.vmx_reserve[(align) + 30]
|
|
|
+ addi 5, 5, 16
|
|
|
+ stvx 31, 4, 5 // context->uc_mcontext.vmx_reserve[(align) + 31]
|
|
|
+ addi 5, 5, 16
|
|
|
+
|
|
|
+ // VSCR
|
|
|
+ mfvscr 0
|
|
|
+ stvx 0, 4, 5
|
|
|
+ addi 5, 5, 16
|
|
|
+
|
|
|
+ // VRSAVE
|
|
|
+ mfvrsave 0
|
|
|
+ stwx 0, 4, 5
|
|
|
+
|
|
|
+ // Update context->uc_mcontext.v_regs to point to vmx_reserve + alignment.
|
|
|
+ std 4, 0x370(3)
|
|
|
+
|
|
|
+ // Zero out all unused fields
|
|
|
+ li 4, 0
|
|
|
+ std 4, 0xc8(3) // context->uc_mcontext.signal
|
|
|
+ std 4, 0xd0(3) // context->uc_mcontext.handler
|
|
|
+ std 4, 0xd8(3) // context->uc_mcontext.oldmask
|
|
|
+
|
|
|
+ blr
|
|
|
#elif defined(__riscv)
|
|
|
|
|
|
#define MCONTEXT_GREGS_OFFSET 176
|
|
|
Index: chromium-120.0.6099.71/third_party/crashpad/crashpad/util/misc/capture_context_test.cc
|
|
|
===================================================================
|
|
|
--- chromium-120.0.6099.71.orig/third_party/crashpad/crashpad/util/misc/capture_context_test.cc
|
|
|
+++ chromium-120.0.6099.71/third_party/crashpad/crashpad/util/misc/capture_context_test.cc
|
|
|
@@ -48,7 +48,7 @@ void TestCaptureContext() {
|
|
|
uintptr_t pc = ProgramCounterFromContext(context_1);
|
|
|
|
|
|
#if !defined(ADDRESS_SANITIZER) && !defined(ARCH_CPU_MIPS_FAMILY) && \
|
|
|
- !defined(MEMORY_SANITIZER)
|
|
|
+ !defined(MEMORY_SANITIZER) && !defined(ARCH_CPU_PPC64_FAMILY)
|
|
|
// Sanitizers can cause enough code bloat that the “nearby” check would
|
|
|
// likely fail.
|
|
|
const uintptr_t kReferencePC =
|
|
|
Index: chromium-120.0.6099.71/third_party/crashpad/crashpad/util/misc/capture_context_test_util_linux.cc
|
|
|
===================================================================
|
|
|
--- chromium-120.0.6099.71.orig/third_party/crashpad/crashpad/util/misc/capture_context_test_util_linux.cc
|
|
|
+++ chromium-120.0.6099.71/third_party/crashpad/crashpad/util/misc/capture_context_test_util_linux.cc
|
|
|
@@ -38,6 +38,8 @@ void SanityCheckContext(const NativeCPUC
|
|
|
#elif defined(ARCH_CPU_RISCV64)
|
|
|
EXPECT_EQ(context.uc_mcontext.__gregs[10],
|
|
|
FromPointerCast<uintptr_t>(&context));
|
|
|
+#elif defined(ARCH_CPU_PPC64_FAMILY)
|
|
|
+ EXPECT_EQ(context.uc_mcontext.gp_regs[3], FromPointerCast<uintptr_t>(&context));
|
|
|
#endif
|
|
|
}
|
|
|
|
|
|
@@ -54,6 +56,8 @@ uintptr_t ProgramCounterFromContext(cons
|
|
|
return context.uc_mcontext.pc;
|
|
|
#elif defined(ARCH_CPU_RISCV64)
|
|
|
return context.uc_mcontext.__gregs[0];
|
|
|
+#elif defined(ARCH_CPU_PPC64_FAMILY)
|
|
|
+ return context.uc_mcontext.gp_regs[PT_NIP];
|
|
|
#endif
|
|
|
}
|
|
|
|
|
|
@@ -70,6 +74,8 @@ uintptr_t StackPointerFromContext(const
|
|
|
return context.uc_mcontext.gregs[29];
|
|
|
#elif defined(ARCH_CPU_RISCV64)
|
|
|
return context.uc_mcontext.__gregs[2];
|
|
|
+#elif defined(ARCH_CPU_PPC64_FAMILY)
|
|
|
+ return context.uc_mcontext.gp_regs[1];
|
|
|
#endif
|
|
|
}
|
|
|
|