aboutsummaryrefslogtreecommitdiff
path: root/src/client/mac
diff options
context:
space:
mode:
authorqsr@chromium.org <qsr@chromium.org@4c0a9323-5329-0410-9bdc-e9ce6186880e>2011-10-07 15:57:23 +0000
committerqsr@chromium.org <qsr@chromium.org@4c0a9323-5329-0410-9bdc-e9ce6186880e>2011-10-07 15:57:23 +0000
commit9525fcd6338ac1697f26306216f579fa60cba657 (patch)
tree43b69333262270f3b4373c0e562206cb8c807430 /src/client/mac
parent10.4 SDK fix (diff)
downloadbreakpad-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.cc22
-rw-r--r--src/client/mac/handler/dynamic_images.h2
-rw-r--r--src/client/mac/handler/exception_handler.cc13
-rw-r--r--src/client/mac/handler/exception_handler.h12
-rw-r--r--src/client/mac/handler/minidump_generator.cc101
-rw-r--r--src/client/mac/handler/minidump_generator.h19
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 &);