mirror of
https://github.com/yuzu-emu/breakpad.git
synced 2025-07-19 11:57:38 +00:00
#ifdef cpu specific code.
Review URL: http://breakpad.appspot.com/307002 git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@848 4c0a9323-5329-0410-9bdc-e9ce6186880e
This commit is contained in:
parent
be368a3d4a
commit
9525fcd633
|
@ -35,19 +35,23 @@ extern "C" { // needed to compile on Leopard
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
}
|
}
|
||||||
|
|
||||||
#include "breakpad_nlist_64.h"
|
|
||||||
#include <AvailabilityMacros.h>
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <CoreServices/CoreServices.h>
|
#include <AvailabilityMacros.h>
|
||||||
#include <dlfcn.h>
|
#include <dlfcn.h>
|
||||||
#include <mach/mach_vm.h>
|
#include <mach/mach_vm.h>
|
||||||
#include <mach/task_info.h>
|
#include <mach/task_info.h>
|
||||||
#include <sys/sysctl.h>
|
#include <sys/sysctl.h>
|
||||||
|
#include <TargetConditionals.h>
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include "breakpad_nlist_64.h"
|
||||||
|
|
||||||
|
#if !TARGET_OS_IPHONE
|
||||||
|
#include <CoreServices/CoreServices.h>
|
||||||
|
|
||||||
#ifndef MAC_OS_X_VERSION_10_6
|
#ifndef MAC_OS_X_VERSION_10_6
|
||||||
#define MAC_OS_X_VERSION_10_6 1060
|
#define MAC_OS_X_VERSION_10_6 1060
|
||||||
#endif
|
#endif
|
||||||
|
@ -67,6 +71,8 @@ typedef struct task_dyld_info *task_dyld_info_t;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#endif // !TARGET_OS_IPHONE
|
||||||
|
|
||||||
namespace google_breakpad {
|
namespace google_breakpad {
|
||||||
|
|
||||||
using std::string;
|
using std::string;
|
||||||
|
@ -358,6 +364,11 @@ static uint64_t LookupSymbol(const char* symbol_name,
|
||||||
return list.n_value;
|
return list.n_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if TARGET_OS_IPHONE
|
||||||
|
static bool HasTaskDyldInfo() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
#else
|
||||||
static SInt32 GetOSVersionInternal() {
|
static SInt32 GetOSVersionInternal() {
|
||||||
SInt32 os_version = 0;
|
SInt32 os_version = 0;
|
||||||
Gestalt(gestaltSystemVersion, &os_version);
|
Gestalt(gestaltSystemVersion, &os_version);
|
||||||
|
@ -369,16 +380,17 @@ static SInt32 GetOSVersion() {
|
||||||
return os_version;
|
return os_version;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool IsSnowLeopardOrLater() {
|
static bool HasTaskDyldInfo() {
|
||||||
#if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_6
|
#if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_6
|
||||||
return true;
|
return true;
|
||||||
#else
|
#else
|
||||||
return GetOSVersion() >= 0x1060;
|
return GetOSVersion() >= 0x1060;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
#endif // TARGET_OS_IPHONE
|
||||||
|
|
||||||
uint64_t DynamicImages::GetDyldAllImageInfosPointer() {
|
uint64_t DynamicImages::GetDyldAllImageInfosPointer() {
|
||||||
if (IsSnowLeopardOrLater()) {
|
if (HasTaskDyldInfo()) {
|
||||||
task_dyld_info_data_t task_dyld_info;
|
task_dyld_info_data_t task_dyld_info;
|
||||||
mach_msg_type_number_t count = TASK_DYLD_INFO_COUNT;
|
mach_msg_type_number_t count = TASK_DYLD_INFO_COUNT;
|
||||||
if (task_info(task_, TASK_DYLD_INFO, (task_info_t)&task_dyld_info,
|
if (task_info(task_, TASK_DYLD_INFO, (task_info_t)&task_dyld_info,
|
||||||
|
|
|
@ -281,6 +281,8 @@ class DynamicImages {
|
||||||
return CPU_TYPE_POWERPC;
|
return CPU_TYPE_POWERPC;
|
||||||
#elif defined(__ppc64__)
|
#elif defined(__ppc64__)
|
||||||
return CPU_TYPE_POWERPC64;
|
return CPU_TYPE_POWERPC64;
|
||||||
|
#elif defined(__arm__)
|
||||||
|
return CPU_TYPE_ARM;
|
||||||
#else
|
#else
|
||||||
#error "GetNativeCPUType not implemented for this architecture"
|
#error "GetNativeCPUType not implemented for this architecture"
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
|
#include <TargetConditionals.h>
|
||||||
|
|
||||||
#include "client/mac/handler/exception_handler.h"
|
#include "client/mac/handler/exception_handler.h"
|
||||||
#include "client/mac/handler/minidump_generator.h"
|
#include "client/mac/handler/minidump_generator.h"
|
||||||
|
@ -36,8 +37,12 @@
|
||||||
#include "common/mac/scoped_task_suspend-inl.h"
|
#include "common/mac/scoped_task_suspend-inl.h"
|
||||||
|
|
||||||
#ifndef USE_PROTECTED_ALLOCATIONS
|
#ifndef USE_PROTECTED_ALLOCATIONS
|
||||||
|
#if TARGET_OS_IPHONE
|
||||||
|
#define USE_PROTECTED_ALLOCATIONS 1
|
||||||
|
#else
|
||||||
#define USE_PROTECTED_ALLOCATIONS 0
|
#define USE_PROTECTED_ALLOCATIONS 0
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
// If USE_PROTECTED_ALLOCATIONS is activated then the
|
// If USE_PROTECTED_ALLOCATIONS is activated then the
|
||||||
// gBreakpadAllocator needs to be setup in other code
|
// gBreakpadAllocator needs to be setup in other code
|
||||||
|
@ -239,8 +244,10 @@ ExceptionHandler::ExceptionHandler(const string &dump_path,
|
||||||
// This will update to the ID and C-string pointers
|
// This will update to the ID and C-string pointers
|
||||||
set_dump_path(dump_path);
|
set_dump_path(dump_path);
|
||||||
MinidumpGenerator::GatherSystemInformation();
|
MinidumpGenerator::GatherSystemInformation();
|
||||||
|
#if !TARGET_OS_IPHONE
|
||||||
if (port_name)
|
if (port_name)
|
||||||
crash_generation_client_.reset(new CrashGenerationClient(port_name));
|
crash_generation_client_.reset(new CrashGenerationClient(port_name));
|
||||||
|
#endif
|
||||||
Setup(install_handler);
|
Setup(install_handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -322,6 +329,8 @@ bool ExceptionHandler::WriteMinidumpForChild(mach_port_t child,
|
||||||
EXC_I386_BPT,
|
EXC_I386_BPT,
|
||||||
#elif defined (__ppc__) || defined (__ppc64__)
|
#elif defined (__ppc__) || defined (__ppc64__)
|
||||||
EXC_PPC_BREAKPOINT,
|
EXC_PPC_BREAKPOINT,
|
||||||
|
#elif defined (__arm__)
|
||||||
|
EXC_ARM_BREAKPOINT,
|
||||||
#else
|
#else
|
||||||
#error architecture not supported
|
#error architecture not supported
|
||||||
#endif
|
#endif
|
||||||
|
@ -352,6 +361,7 @@ bool ExceptionHandler::WriteMinidumpWithException(int exception_type,
|
||||||
if (exit_after_write)
|
if (exit_after_write)
|
||||||
_exit(exception_type);
|
_exit(exception_type);
|
||||||
}
|
}
|
||||||
|
#if !TARGET_OS_IPHONE
|
||||||
} else if (IsOutOfProcess()) {
|
} else if (IsOutOfProcess()) {
|
||||||
if (exception_type && exception_code) {
|
if (exception_type && exception_code) {
|
||||||
// If this is a real exception, give the filter (if any) a chance to
|
// If this is a real exception, give the filter (if any) a chance to
|
||||||
|
@ -364,6 +374,7 @@ bool ExceptionHandler::WriteMinidumpWithException(int exception_type,
|
||||||
exception_subcode,
|
exception_subcode,
|
||||||
thread_name);
|
thread_name);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
} else {
|
} else {
|
||||||
string minidump_id;
|
string minidump_id;
|
||||||
|
|
||||||
|
@ -548,6 +559,8 @@ void *ExceptionHandler::WaitForMessage(void *exception_handler_class) {
|
||||||
exception_code = EXC_I386_BPT;
|
exception_code = EXC_I386_BPT;
|
||||||
#elif defined (__ppc__) || defined (__ppc64__)
|
#elif defined (__ppc__) || defined (__ppc64__)
|
||||||
exception_code = EXC_PPC_BREAKPOINT;
|
exception_code = EXC_PPC_BREAKPOINT;
|
||||||
|
#elif defined (__arm__)
|
||||||
|
exception_code = EXC_ARM_BREAKPOINT;
|
||||||
#else
|
#else
|
||||||
#error architecture not supported
|
#error architecture not supported
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -37,12 +37,16 @@
|
||||||
#define CLIENT_MAC_HANDLER_EXCEPTION_HANDLER_H__
|
#define CLIENT_MAC_HANDLER_EXCEPTION_HANDLER_H__
|
||||||
|
|
||||||
#include <mach/mach.h>
|
#include <mach/mach.h>
|
||||||
|
#include <TargetConditionals.h>
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "client/mac/crash_generation/crash_generation_client.h"
|
|
||||||
#include "processor/scoped_ptr.h"
|
#include "processor/scoped_ptr.h"
|
||||||
|
|
||||||
|
#if !TARGET_OS_IPHONE
|
||||||
|
#include "client/mac/crash_generation/crash_generation_client.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace google_breakpad {
|
namespace google_breakpad {
|
||||||
|
|
||||||
using std::string;
|
using std::string;
|
||||||
|
@ -152,7 +156,11 @@ class ExceptionHandler {
|
||||||
|
|
||||||
// Returns whether out-of-process dump generation is used or not.
|
// Returns whether out-of-process dump generation is used or not.
|
||||||
bool IsOutOfProcess() const {
|
bool IsOutOfProcess() const {
|
||||||
|
#if TARGET_OS_IPHONE
|
||||||
|
return false;
|
||||||
|
#else
|
||||||
return crash_generation_client_.get() != NULL;
|
return crash_generation_client_.get() != NULL;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -250,8 +258,10 @@ class ExceptionHandler {
|
||||||
// True, if we're using the mutext to indicate when mindump writing occurs
|
// True, if we're using the mutext to indicate when mindump writing occurs
|
||||||
bool use_minidump_write_mutex_;
|
bool use_minidump_write_mutex_;
|
||||||
|
|
||||||
|
#if !TARGET_OS_IPHONE
|
||||||
// Client for out-of-process dump generation.
|
// Client for out-of-process dump generation.
|
||||||
scoped_ptr<CrashGenerationClient> crash_generation_client_;
|
scoped_ptr<CrashGenerationClient> crash_generation_client_;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace google_breakpad
|
} // namespace google_breakpad
|
||||||
|
|
|
@ -31,7 +31,6 @@
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
|
|
||||||
#include <mach/host_info.h>
|
#include <mach/host_info.h>
|
||||||
#include <mach/i386/thread_status.h>
|
|
||||||
#include <mach/mach_vm.h>
|
#include <mach/mach_vm.h>
|
||||||
#include <mach/vm_statistics.h>
|
#include <mach/vm_statistics.h>
|
||||||
#include <mach-o/dyld.h>
|
#include <mach-o/dyld.h>
|
||||||
|
@ -43,9 +42,15 @@
|
||||||
|
|
||||||
#include "client/mac/handler/minidump_generator.h"
|
#include "client/mac/handler/minidump_generator.h"
|
||||||
|
|
||||||
|
#ifdef HAS_ARM_SUPPORT
|
||||||
|
#include <mach/arm/thread_status.h>
|
||||||
|
#endif
|
||||||
#ifdef HAS_PPC_SUPPORT
|
#ifdef HAS_PPC_SUPPORT
|
||||||
#include <mach/ppc/thread_status.h>
|
#include <mach/ppc/thread_status.h>
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef HAS_X86_SUPPORT
|
||||||
|
#include <mach/i386/thread_status.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "client/minidump_file_writer-inl.h"
|
#include "client/minidump_file_writer-inl.h"
|
||||||
#include "common/mac/file_id.h"
|
#include "common/mac/file_id.h"
|
||||||
|
@ -348,16 +353,22 @@ bool MinidumpGenerator::WriteStackFromStartAddress(
|
||||||
bool MinidumpGenerator::WriteStack(breakpad_thread_state_data_t state,
|
bool MinidumpGenerator::WriteStack(breakpad_thread_state_data_t state,
|
||||||
MDMemoryDescriptor *stack_location) {
|
MDMemoryDescriptor *stack_location) {
|
||||||
switch (cpu_type_) {
|
switch (cpu_type_) {
|
||||||
|
#ifdef HAS_ARM_SUPPORT
|
||||||
|
case CPU_TYPE_ARM:
|
||||||
|
return WriteStackARM(state, stack_location);
|
||||||
|
#endif
|
||||||
#ifdef HAS_PPC_SUPPORT
|
#ifdef HAS_PPC_SUPPORT
|
||||||
case CPU_TYPE_POWERPC:
|
case CPU_TYPE_POWERPC:
|
||||||
return WriteStackPPC(state, stack_location);
|
return WriteStackPPC(state, stack_location);
|
||||||
case CPU_TYPE_POWERPC64:
|
case CPU_TYPE_POWERPC64:
|
||||||
return WriteStackPPC64(state, stack_location);
|
return WriteStackPPC64(state, stack_location);
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef HAS_X86_SUPPORT
|
||||||
case CPU_TYPE_I386:
|
case CPU_TYPE_I386:
|
||||||
return WriteStackX86(state, stack_location);
|
return WriteStackX86(state, stack_location);
|
||||||
case CPU_TYPE_X86_64:
|
case CPU_TYPE_X86_64:
|
||||||
return WriteStackX86_64(state, stack_location);
|
return WriteStackX86_64(state, stack_location);
|
||||||
|
#endif
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -366,16 +377,22 @@ bool MinidumpGenerator::WriteStack(breakpad_thread_state_data_t state,
|
||||||
bool MinidumpGenerator::WriteContext(breakpad_thread_state_data_t state,
|
bool MinidumpGenerator::WriteContext(breakpad_thread_state_data_t state,
|
||||||
MDLocationDescriptor *register_location) {
|
MDLocationDescriptor *register_location) {
|
||||||
switch (cpu_type_) {
|
switch (cpu_type_) {
|
||||||
|
#ifdef HAS_ARM_SUPPORT
|
||||||
|
case CPU_TYPE_ARM:
|
||||||
|
return WriteContextARM(state, register_location);
|
||||||
|
#endif
|
||||||
#ifdef HAS_PPC_SUPPORT
|
#ifdef HAS_PPC_SUPPORT
|
||||||
case CPU_TYPE_POWERPC:
|
case CPU_TYPE_POWERPC:
|
||||||
return WriteContextPPC(state, register_location);
|
return WriteContextPPC(state, register_location);
|
||||||
case CPU_TYPE_POWERPC64:
|
case CPU_TYPE_POWERPC64:
|
||||||
return WriteContextPPC64(state, register_location);
|
return WriteContextPPC64(state, register_location);
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef HAS_X86_SUPPORT
|
||||||
case CPU_TYPE_I386:
|
case CPU_TYPE_I386:
|
||||||
return WriteContextX86(state, register_location);
|
return WriteContextX86(state, register_location);
|
||||||
case CPU_TYPE_X86_64:
|
case CPU_TYPE_X86_64:
|
||||||
return WriteContextX86_64(state, register_location);
|
return WriteContextX86_64(state, register_location);
|
||||||
|
#endif
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -384,22 +401,86 @@ bool MinidumpGenerator::WriteContext(breakpad_thread_state_data_t state,
|
||||||
u_int64_t MinidumpGenerator::CurrentPCForStack(
|
u_int64_t MinidumpGenerator::CurrentPCForStack(
|
||||||
breakpad_thread_state_data_t state) {
|
breakpad_thread_state_data_t state) {
|
||||||
switch (cpu_type_) {
|
switch (cpu_type_) {
|
||||||
|
#ifdef HAS_ARM_SUPPORT
|
||||||
|
case CPU_TYPE_ARM:
|
||||||
|
return CurrentPCForStackARM(state);
|
||||||
|
#endif
|
||||||
#ifdef HAS_PPC_SUPPORT
|
#ifdef HAS_PPC_SUPPORT
|
||||||
case CPU_TYPE_POWERPC:
|
case CPU_TYPE_POWERPC:
|
||||||
return CurrentPCForStackPPC(state);
|
return CurrentPCForStackPPC(state);
|
||||||
case CPU_TYPE_POWERPC64:
|
case CPU_TYPE_POWERPC64:
|
||||||
return CurrentPCForStackPPC64(state);
|
return CurrentPCForStackPPC64(state);
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef HAS_X86_SUPPORT
|
||||||
case CPU_TYPE_I386:
|
case CPU_TYPE_I386:
|
||||||
return CurrentPCForStackX86(state);
|
return CurrentPCForStackX86(state);
|
||||||
case CPU_TYPE_X86_64:
|
case CPU_TYPE_X86_64:
|
||||||
return CurrentPCForStackX86_64(state);
|
return CurrentPCForStackX86_64(state);
|
||||||
|
#endif
|
||||||
default:
|
default:
|
||||||
assert("Unknown CPU type!");
|
assert("Unknown CPU type!");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef HAS_ARM_SUPPORT
|
||||||
|
bool MinidumpGenerator::WriteStackARM(breakpad_thread_state_data_t state,
|
||||||
|
MDMemoryDescriptor *stack_location) {
|
||||||
|
arm_thread_state_t *machine_state =
|
||||||
|
reinterpret_cast<arm_thread_state_t *>(state);
|
||||||
|
mach_vm_address_t start_addr = REGISTER_FROM_THREADSTATE(machine_state, sp);
|
||||||
|
return WriteStackFromStartAddress(start_addr, stack_location);
|
||||||
|
}
|
||||||
|
|
||||||
|
u_int64_t
|
||||||
|
MinidumpGenerator::CurrentPCForStackARM(breakpad_thread_state_data_t state) {
|
||||||
|
arm_thread_state_t *machine_state =
|
||||||
|
reinterpret_cast<arm_thread_state_t *>(state);
|
||||||
|
|
||||||
|
return REGISTER_FROM_THREADSTATE(machine_state, pc);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MinidumpGenerator::WriteContextARM(breakpad_thread_state_data_t state,
|
||||||
|
MDLocationDescriptor *register_location)
|
||||||
|
{
|
||||||
|
TypedMDRVA<MDRawContextARM> context(&writer_);
|
||||||
|
arm_thread_state_t *machine_state =
|
||||||
|
reinterpret_cast<arm_thread_state_t *>(state);
|
||||||
|
|
||||||
|
if (!context.Allocate())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
*register_location = context.location();
|
||||||
|
MDRawContextARM *context_ptr = context.get();
|
||||||
|
context_ptr->context_flags = MD_CONTEXT_ARM_FULL;
|
||||||
|
|
||||||
|
#define AddGPR(a) context_ptr->iregs[a] = REGISTER_FROM_THREADSTATE(machine_state, r[a])
|
||||||
|
|
||||||
|
context_ptr->iregs[13] = REGISTER_FROM_THREADSTATE(machine_state, sp);
|
||||||
|
context_ptr->iregs[14] = REGISTER_FROM_THREADSTATE(machine_state, lr);
|
||||||
|
context_ptr->iregs[15] = 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);
|
||||||
|
#undef AddReg
|
||||||
|
#undef AddGPR
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef HAS_PCC_SUPPORT
|
#ifdef HAS_PCC_SUPPORT
|
||||||
bool MinidumpGenerator::WriteStackPPC(breakpad_thread_state_data_t state,
|
bool MinidumpGenerator::WriteStackPPC(breakpad_thread_state_data_t state,
|
||||||
MDMemoryDescriptor *stack_location) {
|
MDMemoryDescriptor *stack_location) {
|
||||||
|
@ -560,6 +641,7 @@ bool MinidumpGenerator::WriteContextPPC64(
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAS_X86_SUPPORT
|
||||||
bool MinidumpGenerator::WriteStackX86(breakpad_thread_state_data_t state,
|
bool MinidumpGenerator::WriteStackX86(breakpad_thread_state_data_t state,
|
||||||
MDMemoryDescriptor *stack_location) {
|
MDMemoryDescriptor *stack_location) {
|
||||||
i386_thread_state_t *machine_state =
|
i386_thread_state_t *machine_state =
|
||||||
|
@ -678,12 +760,18 @@ bool MinidumpGenerator::WriteContextX86_64(
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
bool MinidumpGenerator::GetThreadState(thread_act_t target_thread,
|
bool MinidumpGenerator::GetThreadState(thread_act_t target_thread,
|
||||||
thread_state_t state,
|
thread_state_t state,
|
||||||
mach_msg_type_number_t *count) {
|
mach_msg_type_number_t *count) {
|
||||||
thread_state_flavor_t flavor;
|
thread_state_flavor_t flavor;
|
||||||
switch (cpu_type_) {
|
switch (cpu_type_) {
|
||||||
|
#ifdef HAS_ARM_SUPPORT
|
||||||
|
case CPU_TYPE_ARM:
|
||||||
|
flavor = ARM_THREAD_STATE;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
#ifdef HAS_PPC_SUPPORT
|
#ifdef HAS_PPC_SUPPORT
|
||||||
case CPU_TYPE_POWERPC:
|
case CPU_TYPE_POWERPC:
|
||||||
flavor = PPC_THREAD_STATE;
|
flavor = PPC_THREAD_STATE;
|
||||||
|
@ -692,12 +780,14 @@ bool MinidumpGenerator::GetThreadState(thread_act_t target_thread,
|
||||||
flavor = PPC_THREAD_STATE64;
|
flavor = PPC_THREAD_STATE64;
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef HAS_X86_SUPPORT
|
||||||
case CPU_TYPE_I386:
|
case CPU_TYPE_I386:
|
||||||
flavor = i386_THREAD_STATE;
|
flavor = i386_THREAD_STATE;
|
||||||
break;
|
break;
|
||||||
case CPU_TYPE_X86_64:
|
case CPU_TYPE_X86_64:
|
||||||
flavor = x86_THREAD_STATE64;
|
flavor = x86_THREAD_STATE64;
|
||||||
break;
|
break;
|
||||||
|
#endif
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -927,10 +1017,18 @@ bool MinidumpGenerator::WriteSystemInfoStream(
|
||||||
MDRawSystemInfo *info_ptr = info.get();
|
MDRawSystemInfo *info_ptr = info.get();
|
||||||
|
|
||||||
switch (cpu_type_) {
|
switch (cpu_type_) {
|
||||||
|
#ifdef HAS_ARM_SUPPORT
|
||||||
|
case CPU_TYPE_ARM:
|
||||||
|
info_ptr->processor_architecture = MD_CPU_ARCHITECTURE_ARM;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
#ifdef HAS_PPC_SUPPORT
|
||||||
case CPU_TYPE_POWERPC:
|
case CPU_TYPE_POWERPC:
|
||||||
case CPU_TYPE_POWERPC64:
|
case CPU_TYPE_POWERPC64:
|
||||||
info_ptr->processor_architecture = MD_CPU_ARCHITECTURE_PPC;
|
info_ptr->processor_architecture = MD_CPU_ARCHITECTURE_PPC;
|
||||||
break;
|
break;
|
||||||
|
#endif
|
||||||
|
#ifdef HAS_X86_SUPPORT
|
||||||
case CPU_TYPE_I386:
|
case CPU_TYPE_I386:
|
||||||
case CPU_TYPE_X86_64:
|
case CPU_TYPE_X86_64:
|
||||||
if (cpu_type_ == CPU_TYPE_I386)
|
if (cpu_type_ == CPU_TYPE_I386)
|
||||||
|
@ -994,6 +1092,7 @@ bool MinidumpGenerator::WriteSystemInfoStream(
|
||||||
|
|
||||||
#endif // __i386__ || __x86_64_
|
#endif // __i386__ || __x86_64_
|
||||||
break;
|
break;
|
||||||
|
#endif // HAS_X86_SUPPORT
|
||||||
default:
|
default:
|
||||||
info_ptr->processor_architecture = MD_CPU_ARCHITECTURE_UNKNOWN;
|
info_ptr->processor_architecture = MD_CPU_ARCHITECTURE_UNKNOWN;
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -33,6 +33,7 @@
|
||||||
#define CLIENT_MAC_GENERATOR_MINIDUMP_GENERATOR_H__
|
#define CLIENT_MAC_GENERATOR_MINIDUMP_GENERATOR_H__
|
||||||
|
|
||||||
#include <mach/mach.h>
|
#include <mach/mach.h>
|
||||||
|
#include <TargetConditionals.h>
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
@ -43,9 +44,14 @@
|
||||||
|
|
||||||
#include "dynamic_images.h"
|
#include "dynamic_images.h"
|
||||||
|
|
||||||
#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_7
|
#if !TARGET_OS_IPHONE && (MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_7)
|
||||||
#define HAS_PPC_SUPPORT
|
#define HAS_PPC_SUPPORT
|
||||||
#endif
|
#endif
|
||||||
|
#if defined(__arm__)
|
||||||
|
#define HAS_ARM_SUPPORT
|
||||||
|
#elif defined(__i386__) || defined(__x86_64__)
|
||||||
|
#define HAS_X86_SUPPORT
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace google_breakpad {
|
namespace google_breakpad {
|
||||||
|
|
||||||
|
@ -53,7 +59,7 @@ using std::string;
|
||||||
|
|
||||||
// Use the REGISTER_FROM_THREADSTATE to access a register name from the
|
// Use the REGISTER_FROM_THREADSTATE to access a register name from the
|
||||||
// breakpad_thread_state_t structure.
|
// breakpad_thread_state_t structure.
|
||||||
#if __DARWIN_UNIX03 || TARGET_CPU_X86_64 || TARGET_CPU_PPC64
|
#if __DARWIN_UNIX03 || TARGET_CPU_X86_64 || TARGET_CPU_PPC64 || TARGET_CPU_ARM
|
||||||
// In The 10.5 SDK Headers Apple prepended __ to the variable names in the
|
// In The 10.5 SDK Headers Apple prepended __ to the variable names in the
|
||||||
// i386_thread_state_t structure. There's no good way to tell what version of
|
// i386_thread_state_t structure. There's no good way to tell what version of
|
||||||
// the SDK we're compiling against so we just toggle on the same preprocessor
|
// the SDK we're compiling against so we just toggle on the same preprocessor
|
||||||
|
@ -129,6 +135,13 @@ class MinidumpGenerator {
|
||||||
int FindExecutableModule();
|
int FindExecutableModule();
|
||||||
|
|
||||||
// Per-CPU implementations of these methods
|
// Per-CPU implementations of these methods
|
||||||
|
#ifdef HAS_ARM_SUPPORT
|
||||||
|
bool WriteStackARM(breakpad_thread_state_data_t state,
|
||||||
|
MDMemoryDescriptor *stack_location);
|
||||||
|
bool WriteContextARM(breakpad_thread_state_data_t state,
|
||||||
|
MDLocationDescriptor *register_location);
|
||||||
|
u_int64_t CurrentPCForStackARM(breakpad_thread_state_data_t state);
|
||||||
|
#endif
|
||||||
#ifdef HAS_PPC_SUPPORT
|
#ifdef HAS_PPC_SUPPORT
|
||||||
bool WriteStackPPC(breakpad_thread_state_data_t state,
|
bool WriteStackPPC(breakpad_thread_state_data_t state,
|
||||||
MDMemoryDescriptor *stack_location);
|
MDMemoryDescriptor *stack_location);
|
||||||
|
@ -141,6 +154,7 @@ class MinidumpGenerator {
|
||||||
MDLocationDescriptor *register_location);
|
MDLocationDescriptor *register_location);
|
||||||
u_int64_t CurrentPCForStackPPC64(breakpad_thread_state_data_t state);
|
u_int64_t CurrentPCForStackPPC64(breakpad_thread_state_data_t state);
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef HAS_X86_SUPPORT
|
||||||
bool WriteStackX86(breakpad_thread_state_data_t state,
|
bool WriteStackX86(breakpad_thread_state_data_t state,
|
||||||
MDMemoryDescriptor *stack_location);
|
MDMemoryDescriptor *stack_location);
|
||||||
bool WriteContextX86(breakpad_thread_state_data_t state,
|
bool WriteContextX86(breakpad_thread_state_data_t state,
|
||||||
|
@ -151,6 +165,7 @@ class MinidumpGenerator {
|
||||||
bool WriteContextX86_64(breakpad_thread_state_data_t state,
|
bool WriteContextX86_64(breakpad_thread_state_data_t state,
|
||||||
MDLocationDescriptor *register_location);
|
MDLocationDescriptor *register_location);
|
||||||
u_int64_t CurrentPCForStackX86_64(breakpad_thread_state_data_t state);
|
u_int64_t CurrentPCForStackX86_64(breakpad_thread_state_data_t state);
|
||||||
|
#endif
|
||||||
|
|
||||||
// disallow copy ctor and operator=
|
// disallow copy ctor and operator=
|
||||||
explicit MinidumpGenerator(const MinidumpGenerator &);
|
explicit MinidumpGenerator(const MinidumpGenerator &);
|
||||||
|
|
Loading…
Reference in a new issue