diff options
author | qsr@chromium.org <qsr@chromium.org@4c0a9323-5329-0410-9bdc-e9ce6186880e> | 2011-10-07 15:57:23 +0000 |
---|---|---|
committer | qsr@chromium.org <qsr@chromium.org@4c0a9323-5329-0410-9bdc-e9ce6186880e> | 2011-10-07 15:57:23 +0000 |
commit | 9525fcd6338ac1697f26306216f579fa60cba657 (patch) | |
tree | 43b69333262270f3b4373c0e562206cb8c807430 /src/client/mac | |
parent | 10.4 SDK fix (diff) | |
download | breakpad-9525fcd6338ac1697f26306216f579fa60cba657.tar.xz |
#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
Diffstat (limited to 'src/client/mac')
-rw-r--r-- | src/client/mac/handler/dynamic_images.cc | 22 | ||||
-rw-r--r-- | src/client/mac/handler/dynamic_images.h | 2 | ||||
-rw-r--r-- | src/client/mac/handler/exception_handler.cc | 13 | ||||
-rw-r--r-- | src/client/mac/handler/exception_handler.h | 12 | ||||
-rw-r--r-- | src/client/mac/handler/minidump_generator.cc | 101 | ||||
-rw-r--r-- | src/client/mac/handler/minidump_generator.h | 19 |
6 files changed, 160 insertions, 9 deletions
diff --git a/src/client/mac/handler/dynamic_images.cc b/src/client/mac/handler/dynamic_images.cc index c6499e68..11f4e95d 100644 --- a/src/client/mac/handler/dynamic_images.cc +++ b/src/client/mac/handler/dynamic_images.cc @@ -35,19 +35,23 @@ extern "C" { // needed to compile on Leopard #include <stdio.h> } -#include "breakpad_nlist_64.h" -#include <AvailabilityMacros.h> #include <assert.h> -#include <CoreServices/CoreServices.h> +#include <AvailabilityMacros.h> #include <dlfcn.h> #include <mach/mach_vm.h> #include <mach/task_info.h> #include <sys/sysctl.h> +#include <TargetConditionals.h> #include <algorithm> #include <string> #include <vector> +#include "breakpad_nlist_64.h" + +#if !TARGET_OS_IPHONE +#include <CoreServices/CoreServices.h> + #ifndef MAC_OS_X_VERSION_10_6 #define MAC_OS_X_VERSION_10_6 1060 #endif @@ -67,6 +71,8 @@ typedef struct task_dyld_info *task_dyld_info_t; #endif +#endif // !TARGET_OS_IPHONE + namespace google_breakpad { using std::string; @@ -358,6 +364,11 @@ static uint64_t LookupSymbol(const char* symbol_name, return list.n_value; } +#if TARGET_OS_IPHONE +static bool HasTaskDyldInfo() { + return true; +} +#else static SInt32 GetOSVersionInternal() { SInt32 os_version = 0; Gestalt(gestaltSystemVersion, &os_version); @@ -369,16 +380,17 @@ static SInt32 GetOSVersion() { return os_version; } -static bool IsSnowLeopardOrLater() { +static bool HasTaskDyldInfo() { #if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_6 return true; #else return GetOSVersion() >= 0x1060; #endif } +#endif // TARGET_OS_IPHONE uint64_t DynamicImages::GetDyldAllImageInfosPointer() { - if (IsSnowLeopardOrLater()) { + if (HasTaskDyldInfo()) { task_dyld_info_data_t task_dyld_info; mach_msg_type_number_t count = TASK_DYLD_INFO_COUNT; if (task_info(task_, TASK_DYLD_INFO, (task_info_t)&task_dyld_info, diff --git a/src/client/mac/handler/dynamic_images.h b/src/client/mac/handler/dynamic_images.h index 63816bf3..d4062ea6 100644 --- a/src/client/mac/handler/dynamic_images.h +++ b/src/client/mac/handler/dynamic_images.h @@ -281,6 +281,8 @@ class DynamicImages { return CPU_TYPE_POWERPC; #elif defined(__ppc64__) return CPU_TYPE_POWERPC64; +#elif defined(__arm__) + return CPU_TYPE_ARM; #else #error "GetNativeCPUType not implemented for this architecture" #endif diff --git a/src/client/mac/handler/exception_handler.cc b/src/client/mac/handler/exception_handler.cc index d4cd43d5..54eb409d 100644 --- a/src/client/mac/handler/exception_handler.cc +++ b/src/client/mac/handler/exception_handler.cc @@ -29,6 +29,7 @@ #include <map> #include <pthread.h> +#include <TargetConditionals.h> #include "client/mac/handler/exception_handler.h" #include "client/mac/handler/minidump_generator.h" @@ -36,8 +37,12 @@ #include "common/mac/scoped_task_suspend-inl.h" #ifndef USE_PROTECTED_ALLOCATIONS +#if TARGET_OS_IPHONE +#define USE_PROTECTED_ALLOCATIONS 1 +#else #define USE_PROTECTED_ALLOCATIONS 0 #endif +#endif // If USE_PROTECTED_ALLOCATIONS is activated then the // 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 set_dump_path(dump_path); MinidumpGenerator::GatherSystemInformation(); +#if !TARGET_OS_IPHONE if (port_name) crash_generation_client_.reset(new CrashGenerationClient(port_name)); +#endif Setup(install_handler); } @@ -322,6 +329,8 @@ bool ExceptionHandler::WriteMinidumpForChild(mach_port_t child, EXC_I386_BPT, #elif defined (__ppc__) || defined (__ppc64__) EXC_PPC_BREAKPOINT, +#elif defined (__arm__) + EXC_ARM_BREAKPOINT, #else #error architecture not supported #endif @@ -352,6 +361,7 @@ bool ExceptionHandler::WriteMinidumpWithException(int exception_type, if (exit_after_write) _exit(exception_type); } +#if !TARGET_OS_IPHONE } else if (IsOutOfProcess()) { if (exception_type && exception_code) { // 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, thread_name); } +#endif } else { string minidump_id; @@ -548,6 +559,8 @@ void *ExceptionHandler::WaitForMessage(void *exception_handler_class) { exception_code = EXC_I386_BPT; #elif defined (__ppc__) || defined (__ppc64__) exception_code = EXC_PPC_BREAKPOINT; +#elif defined (__arm__) + exception_code = EXC_ARM_BREAKPOINT; #else #error architecture not supported #endif diff --git a/src/client/mac/handler/exception_handler.h b/src/client/mac/handler/exception_handler.h index 172dc358..4689e3af 100644 --- a/src/client/mac/handler/exception_handler.h +++ b/src/client/mac/handler/exception_handler.h @@ -37,12 +37,16 @@ #define CLIENT_MAC_HANDLER_EXCEPTION_HANDLER_H__ #include <mach/mach.h> +#include <TargetConditionals.h> #include <string> -#include "client/mac/crash_generation/crash_generation_client.h" #include "processor/scoped_ptr.h" +#if !TARGET_OS_IPHONE +#include "client/mac/crash_generation/crash_generation_client.h" +#endif + namespace google_breakpad { using std::string; @@ -152,7 +156,11 @@ class ExceptionHandler { // Returns whether out-of-process dump generation is used or not. bool IsOutOfProcess() const { +#if TARGET_OS_IPHONE + return false; +#else return crash_generation_client_.get() != NULL; +#endif } private: @@ -250,8 +258,10 @@ class ExceptionHandler { // True, if we're using the mutext to indicate when mindump writing occurs bool use_minidump_write_mutex_; +#if !TARGET_OS_IPHONE // Client for out-of-process dump generation. scoped_ptr<CrashGenerationClient> crash_generation_client_; +#endif }; } // namespace google_breakpad diff --git a/src/client/mac/handler/minidump_generator.cc b/src/client/mac/handler/minidump_generator.cc index a37e73c5..b0eb7b7c 100644 --- a/src/client/mac/handler/minidump_generator.cc +++ b/src/client/mac/handler/minidump_generator.cc @@ -31,7 +31,6 @@ #include <cstdio> #include <mach/host_info.h> -#include <mach/i386/thread_status.h> #include <mach/mach_vm.h> #include <mach/vm_statistics.h> #include <mach-o/dyld.h> @@ -43,9 +42,15 @@ #include "client/mac/handler/minidump_generator.h" +#ifdef HAS_ARM_SUPPORT +#include <mach/arm/thread_status.h> +#endif #ifdef HAS_PPC_SUPPORT #include <mach/ppc/thread_status.h> #endif +#ifdef HAS_X86_SUPPORT +#include <mach/i386/thread_status.h> +#endif #include "client/minidump_file_writer-inl.h" #include "common/mac/file_id.h" @@ -348,16 +353,22 @@ bool MinidumpGenerator::WriteStackFromStartAddress( bool MinidumpGenerator::WriteStack(breakpad_thread_state_data_t state, MDMemoryDescriptor *stack_location) { switch (cpu_type_) { +#ifdef HAS_ARM_SUPPORT + case CPU_TYPE_ARM: + return WriteStackARM(state, stack_location); +#endif #ifdef HAS_PPC_SUPPORT case CPU_TYPE_POWERPC: return WriteStackPPC(state, stack_location); case CPU_TYPE_POWERPC64: return WriteStackPPC64(state, stack_location); #endif +#ifdef HAS_X86_SUPPORT case CPU_TYPE_I386: return WriteStackX86(state, stack_location); case CPU_TYPE_X86_64: return WriteStackX86_64(state, stack_location); +#endif default: return false; } @@ -366,16 +377,22 @@ bool MinidumpGenerator::WriteStack(breakpad_thread_state_data_t state, bool MinidumpGenerator::WriteContext(breakpad_thread_state_data_t state, MDLocationDescriptor *register_location) { switch (cpu_type_) { +#ifdef HAS_ARM_SUPPORT + case CPU_TYPE_ARM: + return WriteContextARM(state, register_location); +#endif #ifdef HAS_PPC_SUPPORT case CPU_TYPE_POWERPC: return WriteContextPPC(state, register_location); case CPU_TYPE_POWERPC64: return WriteContextPPC64(state, register_location); #endif +#ifdef HAS_X86_SUPPORT case CPU_TYPE_I386: return WriteContextX86(state, register_location); case CPU_TYPE_X86_64: return WriteContextX86_64(state, register_location); +#endif default: return false; } @@ -384,22 +401,86 @@ bool MinidumpGenerator::WriteContext(breakpad_thread_state_data_t state, u_int64_t MinidumpGenerator::CurrentPCForStack( breakpad_thread_state_data_t state) { switch (cpu_type_) { +#ifdef HAS_ARM_SUPPORT + case CPU_TYPE_ARM: + return CurrentPCForStackARM(state); +#endif #ifdef HAS_PPC_SUPPORT case CPU_TYPE_POWERPC: return CurrentPCForStackPPC(state); case CPU_TYPE_POWERPC64: return CurrentPCForStackPPC64(state); #endif +#ifdef HAS_X86_SUPPORT case CPU_TYPE_I386: return CurrentPCForStackX86(state); case CPU_TYPE_X86_64: return CurrentPCForStackX86_64(state); +#endif default: assert("Unknown CPU type!"); 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 bool MinidumpGenerator::WriteStackPPC(breakpad_thread_state_data_t state, MDMemoryDescriptor *stack_location) { @@ -560,6 +641,7 @@ bool MinidumpGenerator::WriteContextPPC64( #endif +#ifdef HAS_X86_SUPPORT bool MinidumpGenerator::WriteStackX86(breakpad_thread_state_data_t state, MDMemoryDescriptor *stack_location) { i386_thread_state_t *machine_state = @@ -678,12 +760,18 @@ bool MinidumpGenerator::WriteContextX86_64( return true; } +#endif bool MinidumpGenerator::GetThreadState(thread_act_t target_thread, thread_state_t state, mach_msg_type_number_t *count) { thread_state_flavor_t flavor; switch (cpu_type_) { +#ifdef HAS_ARM_SUPPORT + case CPU_TYPE_ARM: + flavor = ARM_THREAD_STATE; + break; +#endif #ifdef HAS_PPC_SUPPORT case CPU_TYPE_POWERPC: flavor = PPC_THREAD_STATE; @@ -692,12 +780,14 @@ bool MinidumpGenerator::GetThreadState(thread_act_t target_thread, flavor = PPC_THREAD_STATE64; break; #endif +#ifdef HAS_X86_SUPPORT case CPU_TYPE_I386: flavor = i386_THREAD_STATE; break; case CPU_TYPE_X86_64: flavor = x86_THREAD_STATE64; break; +#endif default: return false; } @@ -927,10 +1017,18 @@ bool MinidumpGenerator::WriteSystemInfoStream( MDRawSystemInfo *info_ptr = info.get(); 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_POWERPC64: info_ptr->processor_architecture = MD_CPU_ARCHITECTURE_PPC; break; +#endif +#ifdef HAS_X86_SUPPORT case CPU_TYPE_I386: case CPU_TYPE_X86_64: if (cpu_type_ == CPU_TYPE_I386) @@ -994,6 +1092,7 @@ bool MinidumpGenerator::WriteSystemInfoStream( #endif // __i386__ || __x86_64_ break; +#endif // HAS_X86_SUPPORT default: info_ptr->processor_architecture = MD_CPU_ARCHITECTURE_UNKNOWN; break; diff --git a/src/client/mac/handler/minidump_generator.h b/src/client/mac/handler/minidump_generator.h index 6f9fe8f7..3ceb95be 100644 --- a/src/client/mac/handler/minidump_generator.h +++ b/src/client/mac/handler/minidump_generator.h @@ -33,6 +33,7 @@ #define CLIENT_MAC_GENERATOR_MINIDUMP_GENERATOR_H__ #include <mach/mach.h> +#include <TargetConditionals.h> #include <string> @@ -43,9 +44,14 @@ #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 #endif +#if defined(__arm__) + #define HAS_ARM_SUPPORT +#elif defined(__i386__) || defined(__x86_64__) + #define HAS_X86_SUPPORT +#endif namespace google_breakpad { @@ -53,7 +59,7 @@ using std::string; // Use the REGISTER_FROM_THREADSTATE to access a register name from the // 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 // 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 @@ -129,6 +135,13 @@ class MinidumpGenerator { int FindExecutableModule(); // 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 bool WriteStackPPC(breakpad_thread_state_data_t state, MDMemoryDescriptor *stack_location); @@ -141,6 +154,7 @@ class MinidumpGenerator { MDLocationDescriptor *register_location); u_int64_t CurrentPCForStackPPC64(breakpad_thread_state_data_t state); #endif +#ifdef HAS_X86_SUPPORT bool WriteStackX86(breakpad_thread_state_data_t state, MDMemoryDescriptor *stack_location); bool WriteContextX86(breakpad_thread_state_data_t state, @@ -151,6 +165,7 @@ class MinidumpGenerator { bool WriteContextX86_64(breakpad_thread_state_data_t state, MDLocationDescriptor *register_location); u_int64_t CurrentPCForStackX86_64(breakpad_thread_state_data_t state); +#endif // disallow copy ctor and operator= explicit MinidumpGenerator(const MinidumpGenerator &); |