mirror of
https://git.suyu.dev/suyu/breakpad.git
synced 2026-03-10 14:02:56 +00:00
Generate minidumps for 64-bit ARM apps on iOS.
Adds an ARM64-specific definition of MDRawContext and support for writing out a minidump when running on ARM64. Additionally, extends the iOS minidump generator for NSExceptions to work on ARM64 as well as ARM. Patch by Colin Blundell <blundell@chromium.org> BUG=542 Review URL: https://breakpad.appspot.com/664002/ git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@1235 4c0a9323-5329-0410-9bdc-e9ce6186880e
This commit is contained in:
@@ -42,7 +42,7 @@
|
||||
|
||||
#include "client/mac/handler/minidump_generator.h"
|
||||
|
||||
#ifdef HAS_ARM_SUPPORT
|
||||
#if defined(HAS_ARM_SUPPORT) || defined(HAS_ARM64_SUPPORT)
|
||||
#include <mach/arm/thread_status.h>
|
||||
#endif
|
||||
#ifdef HAS_PPC_SUPPORT
|
||||
@@ -171,7 +171,7 @@ void MinidumpGenerator::GatherSystemInformation() {
|
||||
os_build_number_ = IntegerValueAtIndex(product_str, 2);
|
||||
}
|
||||
|
||||
void MinidumpGenerator::SetTaskContext(ucontext_t *task_context) {
|
||||
void MinidumpGenerator::SetTaskContext(breakpad_ucontext_t *task_context) {
|
||||
task_context_ = task_context;
|
||||
}
|
||||
|
||||
@@ -369,6 +369,10 @@ bool MinidumpGenerator::WriteStack(breakpad_thread_state_data_t state,
|
||||
case CPU_TYPE_ARM:
|
||||
return WriteStackARM(state, stack_location);
|
||||
#endif
|
||||
#ifdef HAS_ARM64_SUPPORT
|
||||
case CPU_TYPE_ARM64:
|
||||
return WriteStackARM64(state, stack_location);
|
||||
#endif
|
||||
#ifdef HAS_PPC_SUPPORT
|
||||
case CPU_TYPE_POWERPC:
|
||||
return WriteStackPPC(state, stack_location);
|
||||
@@ -393,6 +397,10 @@ bool MinidumpGenerator::WriteContext(breakpad_thread_state_data_t state,
|
||||
case CPU_TYPE_ARM:
|
||||
return WriteContextARM(state, register_location);
|
||||
#endif
|
||||
#ifdef HAS_ARM64_SUPPORT
|
||||
case CPU_TYPE_ARM64:
|
||||
return WriteContextARM64(state, register_location);
|
||||
#endif
|
||||
#ifdef HAS_PPC_SUPPORT
|
||||
case CPU_TYPE_POWERPC:
|
||||
return WriteContextPPC(state, register_location);
|
||||
@@ -417,6 +425,10 @@ uint64_t MinidumpGenerator::CurrentPCForStack(
|
||||
case CPU_TYPE_ARM:
|
||||
return CurrentPCForStackARM(state);
|
||||
#endif
|
||||
#ifdef HAS_ARM64_SUPPORT
|
||||
case CPU_TYPE_ARM64:
|
||||
return CurrentPCForStackARM64(state);
|
||||
#endif
|
||||
#ifdef HAS_PPC_SUPPORT
|
||||
case CPU_TYPE_POWERPC:
|
||||
return CurrentPCForStackPPC(state);
|
||||
@@ -486,7 +498,82 @@ bool MinidumpGenerator::WriteContextARM(breakpad_thread_state_data_t state,
|
||||
AddGPR(10);
|
||||
AddGPR(11);
|
||||
AddGPR(12);
|
||||
#undef AddReg
|
||||
#undef AddGPR
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAS_ARM64_SUPPORT
|
||||
bool MinidumpGenerator::WriteStackARM64(breakpad_thread_state_data_t state,
|
||||
MDMemoryDescriptor *stack_location) {
|
||||
arm_thread_state64_t *machine_state =
|
||||
reinterpret_cast<arm_thread_state64_t *>(state);
|
||||
mach_vm_address_t start_addr = REGISTER_FROM_THREADSTATE(machine_state, sp);
|
||||
return WriteStackFromStartAddress(start_addr, stack_location);
|
||||
}
|
||||
|
||||
uint64_t
|
||||
MinidumpGenerator::CurrentPCForStackARM64(breakpad_thread_state_data_t state) {
|
||||
arm_thread_state64_t *machine_state =
|
||||
reinterpret_cast<arm_thread_state64_t *>(state);
|
||||
|
||||
return REGISTER_FROM_THREADSTATE(machine_state, pc);
|
||||
}
|
||||
|
||||
bool
|
||||
MinidumpGenerator::WriteContextARM64(breakpad_thread_state_data_t state,
|
||||
MDLocationDescriptor *register_location)
|
||||
{
|
||||
TypedMDRVA<MDRawContextARM64> context(&writer_);
|
||||
arm_thread_state64_t *machine_state =
|
||||
reinterpret_cast<arm_thread_state64_t *>(state);
|
||||
|
||||
if (!context.Allocate())
|
||||
return false;
|
||||
|
||||
*register_location = context.location();
|
||||
MDRawContextARM64 *context_ptr = context.get();
|
||||
context_ptr->context_flags = MD_CONTEXT_ARM64_FULL;
|
||||
|
||||
#define AddGPR(a) context_ptr->iregs[a] = \
|
||||
REGISTER_FROM_THREADSTATE(machine_state, x[a])
|
||||
|
||||
context_ptr->iregs[29] = REGISTER_FROM_THREADSTATE(machine_state, fp);
|
||||
context_ptr->iregs[30] = REGISTER_FROM_THREADSTATE(machine_state, lr);
|
||||
context_ptr->iregs[31] = REGISTER_FROM_THREADSTATE(machine_state, sp);
|
||||
context_ptr->iregs[32] = REGISTER_FROM_THREADSTATE(machine_state, pc);
|
||||
context_ptr->cpsr = REGISTER_FROM_THREADSTATE(machine_state, cpsr);
|
||||
|
||||
AddGPR(0);
|
||||
AddGPR(1);
|
||||
AddGPR(2);
|
||||
AddGPR(3);
|
||||
AddGPR(4);
|
||||
AddGPR(5);
|
||||
AddGPR(6);
|
||||
AddGPR(7);
|
||||
AddGPR(8);
|
||||
AddGPR(9);
|
||||
AddGPR(10);
|
||||
AddGPR(11);
|
||||
AddGPR(12);
|
||||
AddGPR(13);
|
||||
AddGPR(14);
|
||||
AddGPR(15);
|
||||
AddGPR(16);
|
||||
AddGPR(17);
|
||||
AddGPR(18);
|
||||
AddGPR(19);
|
||||
AddGPR(20);
|
||||
AddGPR(21);
|
||||
AddGPR(22);
|
||||
AddGPR(23);
|
||||
AddGPR(24);
|
||||
AddGPR(25);
|
||||
AddGPR(26);
|
||||
AddGPR(27);
|
||||
AddGPR(28);
|
||||
#undef AddGPR
|
||||
|
||||
return true;
|
||||
@@ -780,10 +867,18 @@ bool MinidumpGenerator::GetThreadState(thread_act_t target_thread,
|
||||
if (task_context_ && target_thread == mach_thread_self()) {
|
||||
switch (cpu_type_) {
|
||||
#ifdef HAS_ARM_SUPPORT
|
||||
case CPU_TYPE_ARM: {
|
||||
case CPU_TYPE_ARM:
|
||||
size_t final_size =
|
||||
std::min(static_cast<size_t>(*count), sizeof(arm_thread_state_t));
|
||||
memcpy(state, &task_context_->uc_mcontext->__ss, final_size);
|
||||
memcpy(state, &task_context_->breakpad_uc_mcontext->__ss, final_size);
|
||||
*count = final_size;
|
||||
return true;
|
||||
#endif
|
||||
#ifdef HAS_ARM64_SUPPORT
|
||||
case CPU_TYPE_ARM64: {
|
||||
size_t final_size =
|
||||
std::min(static_cast<size_t>(*count), sizeof(arm_thread_state64_t));
|
||||
memcpy(state, &task_context_->breakpad_uc_mcontext->__ss, final_size);
|
||||
*count = final_size;
|
||||
return true;
|
||||
}
|
||||
@@ -795,7 +890,7 @@ bool MinidumpGenerator::GetThreadState(thread_act_t target_thread,
|
||||
sizeof(i386_thread_state_t) : sizeof(x86_thread_state64_t);
|
||||
size_t final_size =
|
||||
std::min(static_cast<size_t>(*count), state_size);
|
||||
memcpy(state, &task_context_->uc_mcontext->__ss, final_size);
|
||||
memcpy(state, &task_context_->breakpad_uc_mcontext->__ss, final_size);
|
||||
*count = final_size;
|
||||
return true;
|
||||
}
|
||||
@@ -810,6 +905,11 @@ bool MinidumpGenerator::GetThreadState(thread_act_t target_thread,
|
||||
flavor = ARM_THREAD_STATE;
|
||||
break;
|
||||
#endif
|
||||
#ifdef HAS_ARM64_SUPPORT
|
||||
case CPU_TYPE_ARM64:
|
||||
flavor = ARM_THREAD_STATE64;
|
||||
break;
|
||||
#endif
|
||||
#ifdef HAS_PPC_SUPPORT
|
||||
case CPU_TYPE_POWERPC:
|
||||
flavor = PPC_THREAD_STATE;
|
||||
@@ -1060,6 +1160,11 @@ bool MinidumpGenerator::WriteSystemInfoStream(
|
||||
info_ptr->processor_architecture = MD_CPU_ARCHITECTURE_ARM;
|
||||
break;
|
||||
#endif
|
||||
#ifdef HAS_ARM64_SUPPORT
|
||||
case CPU_TYPE_ARM64:
|
||||
info_ptr->processor_architecture = MD_CPU_ARCHITECTURE_ARM64;
|
||||
break;
|
||||
#endif
|
||||
#ifdef HAS_PPC_SUPPORT
|
||||
case CPU_TYPE_POWERPC:
|
||||
case CPU_TYPE_POWERPC64:
|
||||
|
||||
Reference in New Issue
Block a user