mirror of
https://github.com/chromium/crashpad.git
synced 2024-12-27 15:32:10 +08:00
Add Windows ARM64 support to Chromium crashpad
Bug: chromium:893460 Change-Id: Ifbeb6f937a6b96c77b02dcf8afe492c5bc617435 Reviewed-on: https://chromium-review.googlesource.com/c/1347773 Reviewed-by: Mark Mentovai <mark@chromium.org> Commit-Queue: Mark Mentovai <mark@chromium.org>
This commit is contained in:
parent
9b6dde9101
commit
761c6fe8be
@ -36,6 +36,7 @@
|
||||
#include "util/misc/random_string.h"
|
||||
#include "util/win/address_types.h"
|
||||
#include "util/win/command_line.h"
|
||||
#include "util/win/context_wrappers.h"
|
||||
#include "util/win/critical_section_with_debug_info.h"
|
||||
#include "util/win/get_function.h"
|
||||
#include "util/win/handle.h"
|
||||
@ -187,11 +188,7 @@ void HandleAbortSignal(int signum) {
|
||||
EXCEPTION_RECORD record = {};
|
||||
record.ExceptionCode = STATUS_FATAL_APP_EXIT;
|
||||
record.ExceptionFlags = EXCEPTION_NONCONTINUABLE;
|
||||
#if defined(ARCH_CPU_64_BITS)
|
||||
record.ExceptionAddress = reinterpret_cast<void*>(context.Rip);
|
||||
#else
|
||||
record.ExceptionAddress = reinterpret_cast<void*>(context.Eip);
|
||||
#endif // ARCH_CPU_64_BITS
|
||||
record.ExceptionAddress = ProgramCounterFromCONTEXT(&context);
|
||||
|
||||
EXCEPTION_POINTERS exception_pointers;
|
||||
exception_pointers.ContextRecord = &context;
|
||||
@ -773,11 +770,7 @@ void CrashpadClient::DumpWithoutCrash(const CONTEXT& context) {
|
||||
constexpr uint32_t kSimulatedExceptionCode = 0x517a7ed;
|
||||
EXCEPTION_RECORD record = {};
|
||||
record.ExceptionCode = kSimulatedExceptionCode;
|
||||
#if defined(ARCH_CPU_64_BITS)
|
||||
record.ExceptionAddress = reinterpret_cast<void*>(context.Rip);
|
||||
#else
|
||||
record.ExceptionAddress = reinterpret_cast<void*>(context.Eip);
|
||||
#endif // ARCH_CPU_64_BITS
|
||||
record.ExceptionAddress = ProgramCounterFromCONTEXT(&context);
|
||||
|
||||
exception_pointers.ExceptionRecord = &record;
|
||||
|
||||
|
@ -126,7 +126,13 @@ void CommonInitializeX86Context(const T& context, CPUContextX86* out) {
|
||||
|
||||
} // namespace
|
||||
|
||||
#if defined(ARCH_CPU_64_BITS)
|
||||
#if defined(ARCH_CPU_X86)
|
||||
|
||||
void InitializeX86Context(const CONTEXT& context, CPUContextX86* out) {
|
||||
CommonInitializeX86Context(context, out);
|
||||
}
|
||||
|
||||
#elif defined(ARCH_CPU_X86_64)
|
||||
|
||||
void InitializeX86Context(const WOW64_CONTEXT& context, CPUContextX86* out) {
|
||||
CommonInitializeX86Context(context, out);
|
||||
@ -192,12 +198,36 @@ void InitializeX64Context(const CONTEXT& context, CPUContextX86_64* out) {
|
||||
}
|
||||
}
|
||||
|
||||
#else // ARCH_CPU_64_BITS
|
||||
#elif defined(ARCH_CPU_ARM64)
|
||||
|
||||
void InitializeX86Context(const CONTEXT& context, CPUContextX86* out) {
|
||||
CommonInitializeX86Context(context, out);
|
||||
void InitializeARM64Context(const CONTEXT& context, CPUContextARM64* out) {
|
||||
memset(out, 0, sizeof(*out));
|
||||
|
||||
LOG_IF(ERROR, !HasContextPart(context, CONTEXT_ARM64)) << "non-arm64 context";
|
||||
|
||||
if (HasContextPart(context, CONTEXT_CONTROL)) {
|
||||
out->spsr = context.Cpsr;
|
||||
out->pc = context.Pc;
|
||||
out->regs[30] = context.Lr;
|
||||
out->sp = context.Sp;
|
||||
out->regs[29] = context.Fp;
|
||||
}
|
||||
|
||||
if (HasContextPart(context, CONTEXT_INTEGER)) {
|
||||
memcpy(&out->regs[0], &context.X0, 18 * sizeof(context.X0));
|
||||
// Don't copy x18 which is reserved as platform register.
|
||||
memcpy(&out->regs[19], &context.X19, 10 * sizeof(context.X0));
|
||||
}
|
||||
|
||||
if (HasContextPart(context, CONTEXT_FLOATING_POINT)) {
|
||||
static_assert(sizeof(out->fpsimd) == sizeof(context.V),
|
||||
"types must be equivalent");
|
||||
memcpy(&out->fpsimd, &context.V, sizeof(out->fpsimd));
|
||||
}
|
||||
}
|
||||
|
||||
#endif // ARCH_CPU_64_BITS
|
||||
#else
|
||||
#error Unsupported Windows Arch
|
||||
#endif // ARCH_CPU_X86
|
||||
|
||||
} // namespace crashpad
|
||||
|
@ -23,8 +23,17 @@ namespace crashpad {
|
||||
|
||||
struct CPUContextX86;
|
||||
struct CPUContextX86_64;
|
||||
struct CPUContextARM64;
|
||||
|
||||
#if defined(ARCH_CPU_64_BITS) || DOXYGEN
|
||||
#if defined(ARCH_CPU_X86) || DOXYGEN
|
||||
|
||||
//! \brief Initializes a CPUContextX86 structure from a native context structure
|
||||
//! on Windows.
|
||||
void InitializeX86Context(const CONTEXT& context, CPUContextX86* out);
|
||||
|
||||
#endif // ARCH_CPU_X86
|
||||
|
||||
#if defined(ARCH_CPU_X86_64) || DOXYGEN
|
||||
|
||||
//! \brief Initializes a CPUContextX86 structure from a native context structure
|
||||
//! on Windows.
|
||||
@ -34,13 +43,15 @@ void InitializeX86Context(const WOW64_CONTEXT& context, CPUContextX86* out);
|
||||
//! structure on Windows.
|
||||
void InitializeX64Context(const CONTEXT& context, CPUContextX86_64* out);
|
||||
|
||||
#else // ARCH_CPU_64_BITS
|
||||
#endif // ARCH_CPU_X86_64
|
||||
|
||||
//! \brief Initializes a CPUContextX86 structure from a native context structure
|
||||
//! on Windows.
|
||||
void InitializeX86Context(const CONTEXT& context, CPUContextX86* out);
|
||||
#if defined(ARCH_CPU_ARM64) || DOXYGEN
|
||||
|
||||
#endif // ARCH_CPU_64_BITS
|
||||
//! \brief Initializes a CPUContextARM64 structure from a native context
|
||||
//! structure on Windows.
|
||||
void InitializeARM64Context(const CONTEXT& context, CPUContextARM64* out);
|
||||
|
||||
#endif // ARCH_CPU_ARM64
|
||||
|
||||
} // namespace crashpad
|
||||
|
||||
|
@ -16,10 +16,10 @@
|
||||
#include <windows.h>
|
||||
|
||||
#include "base/logging.h"
|
||||
#include "build/build_config.h"
|
||||
#include "client/crashpad_client.h"
|
||||
#include "util/misc/capture_context.h"
|
||||
#include "util/win/address_types.h"
|
||||
#include "util/win/context_wrappers.h"
|
||||
|
||||
int wmain(int argc, wchar_t* argv[]) {
|
||||
CHECK_EQ(argc, 2);
|
||||
@ -32,11 +32,9 @@ int wmain(int argc, wchar_t* argv[]) {
|
||||
|
||||
CONTEXT context;
|
||||
crashpad::CaptureContext(&context);
|
||||
#if defined(ARCH_CPU_64_BITS)
|
||||
crashpad::WinVMAddress break_address = context.Rip;
|
||||
#else
|
||||
crashpad::WinVMAddress break_address = context.Eip;
|
||||
#endif
|
||||
crashpad::WinVMAddress break_address =
|
||||
reinterpret_cast<crashpad::WinVMAddress>(
|
||||
crashpad::ProgramCounterFromCONTEXT(&context));
|
||||
|
||||
// This does not used CheckedWriteFile() because at high optimization
|
||||
// settings, a lot of logging code can be inlined, causing there to be a large
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include "client/simulate_crash.h"
|
||||
#include "util/misc/capture_context.h"
|
||||
#include "util/win/address_types.h"
|
||||
#include "util/win/context_wrappers.h"
|
||||
|
||||
int wmain(int argc, wchar_t* argv[]) {
|
||||
CHECK_EQ(argc, 2);
|
||||
@ -32,11 +33,9 @@ int wmain(int argc, wchar_t* argv[]) {
|
||||
|
||||
CONTEXT context;
|
||||
crashpad::CaptureContext(&context);
|
||||
#if defined(ARCH_CPU_64_BITS)
|
||||
crashpad::WinVMAddress break_address = context.Rip;
|
||||
#else
|
||||
crashpad::WinVMAddress break_address = context.Eip;
|
||||
#endif
|
||||
crashpad::WinVMAddress break_address =
|
||||
reinterpret_cast<crashpad::WinVMAddress>(
|
||||
crashpad::ProgramCounterFromCONTEXT(&context));
|
||||
|
||||
// This does not used CheckedWriteFile() because at high optimization
|
||||
// settings, a lot of logging code can be inlined, causing there to be a large
|
||||
|
@ -28,22 +28,13 @@ namespace internal {
|
||||
|
||||
namespace {
|
||||
|
||||
#if defined(ARCH_CPU_X86_FAMILY)
|
||||
#if defined(ARCH_CPU_32_BITS)
|
||||
using Context32 = CONTEXT;
|
||||
#elif defined(ARCH_CPU_64_BITS)
|
||||
using Context32 = WOW64_CONTEXT;
|
||||
#endif
|
||||
|
||||
#if defined(ARCH_CPU_64_BITS)
|
||||
void NativeContextToCPUContext64(const CONTEXT& context_record,
|
||||
CPUContext* context,
|
||||
CPUContextUnion* context_union) {
|
||||
context->architecture = kCPUArchitectureX86_64;
|
||||
context->x86_64 = &context_union->x86_64;
|
||||
InitializeX64Context(context_record, context->x86_64);
|
||||
}
|
||||
#endif
|
||||
|
||||
void NativeContextToCPUContext32(const Context32& context_record,
|
||||
CPUContext* context,
|
||||
CPUContextUnion* context_union) {
|
||||
@ -51,6 +42,25 @@ void NativeContextToCPUContext32(const Context32& context_record,
|
||||
context->x86 = &context_union->x86;
|
||||
InitializeX86Context(context_record, context->x86);
|
||||
}
|
||||
#endif // ARCH_CPU_X86_FAMILY
|
||||
|
||||
#if defined(ARCH_CPU_64_BITS)
|
||||
void NativeContextToCPUContext64(const CONTEXT& context_record,
|
||||
CPUContext* context,
|
||||
CPUContextUnion* context_union) {
|
||||
#if defined(ARCH_CPU_X86_64)
|
||||
context->architecture = kCPUArchitectureX86_64;
|
||||
context->x86_64 = &context_union->x86_64;
|
||||
InitializeX64Context(context_record, context->x86_64);
|
||||
#elif defined(ARCH_CPU_ARM64)
|
||||
context->architecture = kCPUArchitectureARM64;
|
||||
context->arm64 = &context_union->arm64;
|
||||
InitializeARM64Context(context_record, context->arm64);
|
||||
#else
|
||||
#error Unsupported Windows 64-bit Arch
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace
|
||||
|
||||
@ -106,6 +116,8 @@ bool ExceptionSnapshotWin::Initialize(
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !defined(ARCH_CPU_ARM64)
|
||||
if (!is_64_bit) {
|
||||
if (!InitializeFromExceptionPointers<EXCEPTION_RECORD32,
|
||||
process_types::EXCEPTION_POINTERS32>(
|
||||
@ -116,6 +128,7 @@ bool ExceptionSnapshotWin::Initialize(
|
||||
return false;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
CaptureMemoryDelegateWin capture_memory_delegate(
|
||||
process_reader, *thread, &extra_memory_, nullptr);
|
||||
|
@ -38,12 +38,14 @@ namespace internal {
|
||||
|
||||
class MemorySnapshotWin;
|
||||
|
||||
#if defined(ARCH_CPU_X86_FAMILY)
|
||||
union CPUContextUnion {
|
||||
#if defined(ARCH_CPU_X86_FAMILY)
|
||||
CPUContextX86 x86;
|
||||
CPUContextX86_64 x86_64;
|
||||
};
|
||||
#elif defined(ARCH_CPU_ARM64)
|
||||
CPUContextARM64 arm64;
|
||||
#endif
|
||||
};
|
||||
|
||||
class ExceptionSnapshotWin final : public ExceptionSnapshot {
|
||||
public:
|
||||
@ -91,9 +93,7 @@ class ExceptionSnapshotWin final : public ExceptionSnapshot {
|
||||
CPUContext* context,
|
||||
CPUContextUnion* context_union));
|
||||
|
||||
#if defined(ARCH_CPU_X86_FAMILY)
|
||||
CPUContextUnion context_union_;
|
||||
#endif
|
||||
CPUContext context_;
|
||||
std::vector<uint64_t> codes_;
|
||||
std::vector<std::unique_ptr<internal::MemorySnapshotWin>> extra_memory_;
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include "util/misc/from_pointer_cast.h"
|
||||
#include "util/synchronization/semaphore.h"
|
||||
#include "util/thread/thread.h"
|
||||
#include "util/win/context_wrappers.h"
|
||||
#include "util/win/scoped_process_suspend.h"
|
||||
|
||||
namespace crashpad {
|
||||
@ -106,12 +107,7 @@ TEST(ProcessReaderWin, SelfOneThread) {
|
||||
ASSERT_GE(threads.size(), 1u);
|
||||
|
||||
EXPECT_EQ(threads[0].id, GetCurrentThreadId());
|
||||
#if defined(ARCH_CPU_64_BITS)
|
||||
EXPECT_NE(threads[0].context.native.Rip, 0u);
|
||||
#else
|
||||
EXPECT_NE(threads[0].context.native.Eip, 0u);
|
||||
#endif
|
||||
|
||||
EXPECT_NE(ProgramCounterFromCONTEXT(&threads[0].context.native), nullptr);
|
||||
EXPECT_EQ(threads[0].suspend_count, 0u);
|
||||
}
|
||||
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include "base/logging.h"
|
||||
#include "base/numerics/safe_conversions.h"
|
||||
#include "base/strings/utf_string_conversions.h"
|
||||
#include "build/build_config.h"
|
||||
#include "util/misc/from_pointer_cast.h"
|
||||
#include "util/misc/time.h"
|
||||
#include "util/win/nt_internals.h"
|
||||
@ -276,7 +277,7 @@ void ProcessSnapshotWin::InitializeUnloadedModules() {
|
||||
// and 32-reading-32, so at the moment, we simply do not retrieve unloaded
|
||||
// modules for 64-reading-32. See https://crashpad.chromium.org/bug/89.
|
||||
|
||||
#if defined(ARCH_CPU_X86_64)
|
||||
#if defined(ARCH_CPU_X86_64) || defined(ARCH_CPU_ARM64)
|
||||
if (!process_reader_.Is64Bit()) {
|
||||
LOG(ERROR)
|
||||
<< "reading unloaded modules across bitness not currently supported";
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include "base/numerics/safe_conversions.h"
|
||||
#include "base/strings/stringprintf.h"
|
||||
#include "base/strings/utf_string_conversions.h"
|
||||
#include "build/build_config.h"
|
||||
#include "util/win/module_version.h"
|
||||
|
||||
namespace crashpad {
|
||||
@ -125,13 +126,20 @@ void SystemSnapshotWin::Initialize(ProcessReaderWin* process_reader) {
|
||||
CPUArchitecture SystemSnapshotWin::GetCPUArchitecture() const {
|
||||
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
|
||||
|
||||
#if defined(ARCH_CPU_X86_FAMILY)
|
||||
return process_reader_->Is64Bit() ? kCPUArchitectureX86_64
|
||||
: kCPUArchitectureX86;
|
||||
#elif defined(ARCH_CPU_ARM64)
|
||||
return kCPUArchitectureARM64;
|
||||
#else
|
||||
#error Unsupported Windows Arch
|
||||
#endif
|
||||
}
|
||||
|
||||
uint32_t SystemSnapshotWin::CPURevision() const {
|
||||
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
|
||||
|
||||
#if defined(ARCH_CPU_X86_FAMILY)
|
||||
uint32_t raw = CPUX86Signature();
|
||||
uint8_t stepping = raw & 0xf;
|
||||
uint8_t model = (raw & 0xf0) >> 4;
|
||||
@ -149,6 +157,13 @@ uint32_t SystemSnapshotWin::CPURevision() const {
|
||||
uint16_t adjusted_family = family + extended_family;
|
||||
uint8_t adjusted_model = model + (extended_model << 4);
|
||||
return (adjusted_family << 16) | (adjusted_model << 8) | stepping;
|
||||
#elif defined(ARCH_CPU_ARM64)
|
||||
// TODO(jperaza): do this. https://crashpad.chromium.org/bug/30
|
||||
// This is the same as SystemSnapshotLinux::CPURevision.
|
||||
return 0;
|
||||
#else
|
||||
#error Unsupported Windows Arch
|
||||
#endif
|
||||
}
|
||||
|
||||
uint8_t SystemSnapshotWin::CPUCount() const {
|
||||
@ -166,6 +181,7 @@ uint8_t SystemSnapshotWin::CPUCount() const {
|
||||
std::string SystemSnapshotWin::CPUVendor() const {
|
||||
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
|
||||
|
||||
#if defined(ARCH_CPU_X86_FAMILY)
|
||||
int cpu_info[4];
|
||||
__cpuid(cpu_info, 0);
|
||||
char vendor[12];
|
||||
@ -173,6 +189,13 @@ std::string SystemSnapshotWin::CPUVendor() const {
|
||||
*reinterpret_cast<int*>(vendor + 4) = cpu_info[3];
|
||||
*reinterpret_cast<int*>(vendor + 8) = cpu_info[2];
|
||||
return std::string(vendor, sizeof(vendor));
|
||||
#elif defined(ARCH_CPU_ARM64)
|
||||
// TODO(jperaza): do this. https://crashpad.chromium.org/bug/30
|
||||
// This is the same as SystemSnapshotLinux::CPURevision.
|
||||
return std::string();
|
||||
#else
|
||||
#error Unsupported Windows Arch
|
||||
#endif
|
||||
}
|
||||
|
||||
void SystemSnapshotWin::CPUFrequency(uint64_t* current_hz,
|
||||
@ -212,36 +235,52 @@ void SystemSnapshotWin::CPUFrequency(uint64_t* current_hz,
|
||||
uint32_t SystemSnapshotWin::CPUX86Signature() const {
|
||||
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
|
||||
|
||||
#if defined(ARCH_CPU_X86_FAMILY)
|
||||
int cpu_info[4];
|
||||
// We will never run on any processors that don't support at least function 1.
|
||||
__cpuid(cpu_info, 1);
|
||||
return cpu_info[0];
|
||||
#else
|
||||
NOTREACHED();
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
uint64_t SystemSnapshotWin::CPUX86Features() const {
|
||||
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
|
||||
|
||||
#if defined(ARCH_CPU_X86_FAMILY)
|
||||
int cpu_info[4];
|
||||
// We will never run on any processors that don't support at least function 1.
|
||||
__cpuid(cpu_info, 1);
|
||||
return (static_cast<uint64_t>(cpu_info[2]) << 32) |
|
||||
static_cast<uint64_t>(cpu_info[3]);
|
||||
#else
|
||||
NOTREACHED();
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
uint64_t SystemSnapshotWin::CPUX86ExtendedFeatures() const {
|
||||
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
|
||||
|
||||
#if defined(ARCH_CPU_X86_FAMILY)
|
||||
int cpu_info[4];
|
||||
// We will never run on any processors that don't support at least extended
|
||||
// function 1.
|
||||
__cpuid(cpu_info, 0x80000001);
|
||||
return (static_cast<uint64_t>(cpu_info[2]) << 32) |
|
||||
static_cast<uint64_t>(cpu_info[3]);
|
||||
#else
|
||||
NOTREACHED();
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
uint32_t SystemSnapshotWin::CPUX86Leaf7Features() const {
|
||||
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
|
||||
|
||||
#if defined(ARCH_CPU_X86_FAMILY)
|
||||
int cpu_info[4];
|
||||
|
||||
// Make sure leaf 7 can be called.
|
||||
@ -251,11 +290,16 @@ uint32_t SystemSnapshotWin::CPUX86Leaf7Features() const {
|
||||
|
||||
__cpuidex(cpu_info, 7, 0);
|
||||
return cpu_info[1];
|
||||
#else
|
||||
NOTREACHED();
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool SystemSnapshotWin::CPUX86SupportsDAZ() const {
|
||||
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
|
||||
|
||||
#if defined(ARCH_CPU_X86_FAMILY)
|
||||
// The correct way to check for denormals-as-zeros (DAZ) support is to examine
|
||||
// mxcsr mask, which can be done with fxsave. See Intel Software Developer's
|
||||
// Manual, Volume 1: Basic Architecture (253665-051), 11.6.3 "Checking for the
|
||||
@ -277,6 +321,10 @@ bool SystemSnapshotWin::CPUX86SupportsDAZ() const {
|
||||
|
||||
// Test the DAZ bit.
|
||||
return (mxcsr_mask & (1 << 6)) != 0;
|
||||
#else
|
||||
NOTREACHED();
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
SystemSnapshot::OperatingSystem SystemSnapshotWin::GetOperatingSystem() const {
|
||||
|
@ -60,6 +60,10 @@ TEST_F(SystemSnapshotWinTest, GetCPUArchitecture) {
|
||||
EXPECT_EQ(cpu_architecture, kCPUArchitectureX86);
|
||||
#elif defined(ARCH_CPU_X86_64)
|
||||
EXPECT_EQ(cpu_architecture, kCPUArchitectureX86_64);
|
||||
#elif defined(ARCH_CPU_ARM64)
|
||||
EXPECT_EQ(cpu_architecture, kCPUArchitectureARM64);
|
||||
#else
|
||||
#error Unsupported Windows Arch
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -63,7 +63,11 @@ bool ThreadSnapshotWin::Initialize(
|
||||
teb_.Initialize(process_reader, 0, 0);
|
||||
}
|
||||
|
||||
#if defined(ARCH_CPU_X86_64)
|
||||
#if defined(ARCH_CPU_X86)
|
||||
context_.architecture = kCPUArchitectureX86;
|
||||
context_.x86 = &context_union_.x86;
|
||||
InitializeX86Context(process_reader_thread.context.native, context_.x86);
|
||||
#elif defined(ARCH_CPU_X86_64)
|
||||
if (process_reader->Is64Bit()) {
|
||||
context_.architecture = kCPUArchitectureX86_64;
|
||||
context_.x86_64 = &context_union_.x86_64;
|
||||
@ -73,11 +77,13 @@ bool ThreadSnapshotWin::Initialize(
|
||||
context_.x86 = &context_union_.x86;
|
||||
InitializeX86Context(process_reader_thread.context.wow64, context_.x86);
|
||||
}
|
||||
#elif defined(ARCH_CPU_ARM64)
|
||||
context_.architecture = kCPUArchitectureARM64;
|
||||
context_.arm64 = &context_union_.arm64;
|
||||
InitializeARM64Context(process_reader_thread.context.native, context_.arm64);
|
||||
#else
|
||||
context_.architecture = kCPUArchitectureX86;
|
||||
context_.x86 = &context_union_.x86;
|
||||
InitializeX86Context(process_reader_thread.context.native, context_.x86);
|
||||
#endif // ARCH_CPU_X86_64
|
||||
#error Unsupported Windows Arch
|
||||
#endif // ARCH_CPU_X86
|
||||
|
||||
CaptureMemoryDelegateWin capture_memory_delegate(
|
||||
process_reader,
|
||||
|
@ -71,12 +71,16 @@ class ThreadSnapshotWin final : public ThreadSnapshot {
|
||||
std::vector<const MemorySnapshot*> ExtraMemory() const override;
|
||||
|
||||
private:
|
||||
#if defined(ARCH_CPU_X86_FAMILY)
|
||||
union {
|
||||
#if defined(ARCH_CPU_X86_FAMILY)
|
||||
CPUContextX86 x86;
|
||||
CPUContextX86_64 x86_64;
|
||||
} context_union_;
|
||||
#elif defined(ARCH_CPU_ARM64)
|
||||
CPUContextARM64 arm64;
|
||||
#else
|
||||
#error Unsupported Windows Arch
|
||||
#endif
|
||||
} context_union_;
|
||||
CPUContext context_;
|
||||
MemorySnapshotWin stack_;
|
||||
MemorySnapshotWin teb_;
|
||||
|
6
third_party/zlib/BUILD.gn
vendored
6
third_party/zlib/BUILD.gn
vendored
@ -91,6 +91,12 @@ if (zlib_source == "external") {
|
||||
"/wd4324", # structure was padded due to alignment specifier
|
||||
"/wd4702", # unreachable code
|
||||
]
|
||||
if (current_cpu == "arm64" && !crashpad_is_clang) {
|
||||
# Select code path for clang in zlib to avoid using MSVC x86/x64
|
||||
# intrinsics for Windows ARM64.
|
||||
# TODO: https://crashpad.chromium.org/bug/267
|
||||
defines += [ "__clang__" ]
|
||||
}
|
||||
} else {
|
||||
defines += [
|
||||
"HAVE_HIDDEN",
|
||||
|
@ -341,6 +341,7 @@ static_library("util") {
|
||||
"win/checked_win_address_range.h",
|
||||
"win/command_line.cc",
|
||||
"win/command_line.h",
|
||||
"win/context_wrappers.h",
|
||||
"win/critical_section_with_debug_info.cc",
|
||||
"win/critical_section_with_debug_info.h",
|
||||
"win/exception_handler_server.cc",
|
||||
@ -390,10 +391,15 @@ static_library("util") {
|
||||
# TODO(thakis): Use the .asm file in cross builds somehow,
|
||||
# https://crbug.com/762167.
|
||||
if (host_os == "win") {
|
||||
sources += [
|
||||
"misc/capture_context_win.asm",
|
||||
"win/safe_terminate_process.asm",
|
||||
]
|
||||
if (current_cpu != "arm64") {
|
||||
sources += [
|
||||
"misc/capture_context_win.asm",
|
||||
"win/safe_terminate_process.asm",
|
||||
]
|
||||
} else {
|
||||
# TODO: Add assembly code of CaptureContext for Windows ARM64.
|
||||
sources += [ "misc/capture_context_broken.cc" ]
|
||||
}
|
||||
} else {
|
||||
sources += [
|
||||
"misc/capture_context_broken.cc",
|
||||
|
@ -13,6 +13,7 @@
|
||||
// limitations under the License.
|
||||
|
||||
#include "util/misc/capture_context_test_util.h"
|
||||
#include "util/win/context_wrappers.h"
|
||||
|
||||
#include "base/macros.h"
|
||||
#include "gtest/gtest.h"
|
||||
@ -95,11 +96,7 @@ void SanityCheckContext(const NativeCPUContext& context) {
|
||||
}
|
||||
|
||||
uintptr_t ProgramCounterFromContext(const NativeCPUContext& context) {
|
||||
#if defined(ARCH_CPU_X86)
|
||||
return context.Eip;
|
||||
#elif defined(ARCH_CPU_X86_64)
|
||||
return context.Rip;
|
||||
#endif
|
||||
return reinterpret_cast<uintptr_t>(ProgramCounterFromCONTEXT(&context));
|
||||
}
|
||||
|
||||
uintptr_t StackPointerFromContext(const NativeCPUContext& context) {
|
||||
@ -107,6 +104,8 @@ uintptr_t StackPointerFromContext(const NativeCPUContext& context) {
|
||||
return context.Esp;
|
||||
#elif defined(ARCH_CPU_X86_64)
|
||||
return context.Rsp;
|
||||
#elif defined(ARCH_CPU_ARM64)
|
||||
return context.Sp;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -65,6 +65,8 @@ std::string UserAgent() {
|
||||
user_agent.append("x86");
|
||||
#elif defined(ARCH_CPU_X86_64)
|
||||
user_agent.append("x64");
|
||||
#elif defined(ARCH_CPU_ARM64)
|
||||
user_agent.append("arm64");
|
||||
#else
|
||||
#error Port
|
||||
#endif
|
||||
|
@ -246,6 +246,7 @@
|
||||
'win/checked_win_address_range.h',
|
||||
'win/command_line.cc',
|
||||
'win/command_line.h',
|
||||
'win/context_wrappers.h',
|
||||
'win/critical_section_with_debug_info.cc',
|
||||
'win/critical_section_with_debug_info.h',
|
||||
'win/exception_handler_server.cc',
|
||||
|
40
util/win/context_wrappers.h
Normal file
40
util/win/context_wrappers.h
Normal file
@ -0,0 +1,40 @@
|
||||
// Copyright 2018 The Crashpad Authors. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef CRASHPAD_UTIL_WIN_CONTEXT_WRAPPERS_H_
|
||||
#define CRASHPAD_UTIL_WIN_CONTEXT_WRAPPERS_H_
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include "build/build_config.h"
|
||||
|
||||
namespace crashpad {
|
||||
|
||||
//! \brief Retrieve program counter from `CONTEXT` structure for different
|
||||
//! architectures supported by Windows.
|
||||
inline void* ProgramCounterFromCONTEXT(const CONTEXT* context) {
|
||||
#if defined(ARCH_CPU_X86)
|
||||
return reinterpret_cast<void*>(context->Eip);
|
||||
#elif defined(ARCH_CPU_X86_64)
|
||||
return reinterpret_cast<void*>(context->Rip);
|
||||
#elif defined(ARCH_CPU_ARM64)
|
||||
return reinterpret_cast<void*>(context->Pc);
|
||||
#else
|
||||
#error Unsupported Windows Arch
|
||||
#endif // ARCH_CPU_X86
|
||||
}
|
||||
|
||||
} // namespace crashpad
|
||||
|
||||
#endif // CRASHPAD_UTIL_WIN_CONTEXT_WRAPPERS_H_
|
@ -91,6 +91,8 @@ class ScopedExecutablePatch {
|
||||
DISALLOW_COPY_AND_ASSIGN(ScopedExecutablePatch);
|
||||
};
|
||||
|
||||
// SafeTerminateProcess is calling convention specific only for x86.
|
||||
#if defined(ARCH_CPU_X86_FAMILY)
|
||||
TEST(SafeTerminateProcess, PatchBadly) {
|
||||
// This is a test of SafeTerminateProcess(), but it doesn’t actually terminate
|
||||
// anything. Instead, it works with a process handle for the current process
|
||||
@ -161,6 +163,7 @@ TEST(SafeTerminateProcess, PatchBadly) {
|
||||
EXPECT_FALSE(SafeTerminateProcess(process, 0));
|
||||
EXPECT_EQ(GetLastError(), static_cast<DWORD>(ERROR_ACCESS_DENIED));
|
||||
}
|
||||
#endif // ARCH_CPU_X86_FAMILY
|
||||
|
||||
TEST(SafeTerminateProcess, TerminateChild) {
|
||||
base::FilePath child_executable =
|
||||
|
Loading…
x
Reference in New Issue
Block a user