Add Arm64 version of breakpad_getcontext for Android.

This CL adds breakpad_getcontext support for Arm64 to Android. The assembly
is based on getcontext.S in glibc.

BUG=354405,335641
R=mark@chromium.org

Review URL: https://breakpad.appspot.com/1384002

git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@1302 4c0a9323-5329-0410-9bdc-e9ce6186880e
This commit is contained in:
rmcilroy@chromium.org 2014-04-03 13:15:37 +00:00
parent 83b9a28cf9
commit 410b7024e3
6 changed files with 140 additions and 25 deletions

View file

@ -398,8 +398,15 @@ bool ExceptionHandler::HandleSignal(int sig, siginfo_t* info, void* uc) {
CrashContext context;
memcpy(&context.siginfo, info, sizeof(siginfo_t));
memcpy(&context.context, uc, sizeof(struct ucontext));
#if !defined(__ARM_EABI__) && !defined(__aarch64__) && !defined(__mips__)
// FP state is not part of user ABI on ARM or ARM64 Linux.
#if defined(__aarch64__)
struct ucontext *uc_ptr = (struct ucontext*)uc;
struct fpsimd_context *fp_ptr =
(struct fpsimd_context*)&uc_ptr->uc_mcontext.__reserved;
if (fp_ptr->head.magic == FPSIMD_MAGIC) {
memcpy(&context.float_state, fp_ptr, sizeof(context.float_state));
}
#elif !defined(__ARM_EABI__) && !defined(__mips__)
// FP state is not part of user ABI on ARM Linux.
// In case of MIPS Linux FP state is already part of struct ucontext
// and 'float_state' is not a member of CrashContext.
struct ucontext *uc_ptr = (struct ucontext*)uc;

View file

@ -190,11 +190,11 @@ class ExceptionHandler {
siginfo_t siginfo;
pid_t tid; // the crashing thread.
struct ucontext context;
#if !defined(__ARM_EABI__) && !defined(__aarch64__) && !defined(__mips__)
// #ifdef this out because FP state is not part of user ABI for Linux ARM
// or ARM64. In case of MIPS Linux FP state is already part of struct
#if !defined(__ARM_EABI__) && !defined(__mips__)
// #ifdef this out because FP state is not part of user ABI for Linux ARM.
// In case of MIPS Linux FP state is already part of struct
// ucontext so 'float_state' is not required.
struct _libc_fpstate float_state;
fpstate_t float_state;
#endif
};

View file

@ -344,8 +344,7 @@ void CPUFillFromThreadInfo(MDRawContextARM* out,
#endif
}
void CPUFillFromUContext(MDRawContextARM* out, const ucontext* uc,
const struct _libc_fpstate* fpregs) {
void CPUFillFromUContext(MDRawContextARM* out, const ucontext* uc) {
out->context_flags = MD_CONTEXT_ARM_FULL;
out->iregs[0] = uc->uc_mcontext.arm_r0;
@ -383,7 +382,7 @@ void CPUFillFromThreadInfo(MDRawContextARM64* out,
}
void CPUFillFromUContext(MDRawContextARM64* out, const ucontext* uc,
const struct _libc_fpstate* fpregs) {
const struct fpsimd_context* fpregs) {
// TODO(rmcilroy): Implement for arm64.
}
@ -418,8 +417,7 @@ static void CPUFillFromThreadInfo(MDRawContextMIPS* out,
out->float_save.fir = info.fpregs.fir;
}
static void CPUFillFromUContext(MDRawContextMIPS* out, const ucontext* uc,
const struct _libc_fpstate* fpregs) {
static void CPUFillFromUContext(MDRawContextMIPS* out, const ucontext* uc) {
out->context_flags = MD_CONTEXT_MIPS_FULL;
for (int i = 0; i < MD_CONTEXT_MIPS_GPR_COUNT; ++i)
@ -483,11 +481,8 @@ class MinidumpWriter {
: fd_(minidump_fd),
path_(minidump_path),
ucontext_(context ? &context->context : NULL),
#if !defined(__ARM_EABI__) && !defined(__mips__) && !defined(__aarch64__)
#if !defined(__ARM_EABI__) && !defined(__mips__)
float_state_(context ? &context->float_state : NULL),
#else
// TODO: fix this after fixing ExceptionHandler
float_state_(NULL),
#endif
dumper_(dumper),
minidump_size_limit_(-1),
@ -848,7 +843,11 @@ class MinidumpWriter {
if (!cpu.Allocate())
return false;
my_memset(cpu.get(), 0, sizeof(RawContextCPU));
#if !defined(__ARM_EABI__) && !defined(__mips__)
CPUFillFromUContext(cpu.get(), ucontext_, float_state_);
#else
CPUFillFromUContext(cpu.get(), ucontext_);
#endif
if (stack_copy)
PopSeccompStackFrame(cpu.get(), thread, stack_copy);
thread.thread_context = cpu.location();
@ -1756,7 +1755,9 @@ class MinidumpWriter {
const char* path_; // Path to the file where the minidum should be written.
const struct ucontext* const ucontext_; // also from the signal handler
const struct _libc_fpstate* const float_state_; // ditto
#if !defined(__ARM_EABI__) && !defined(__mips__)
const google_breakpad::fpstate_t* const float_state_; // ditto
#endif
LinuxDumper* dumper_;
MinidumpFileWriter minidump_writer_;
off_t minidump_size_limit_;

View file

@ -32,6 +32,7 @@
#include <stdint.h>
#include <sys/types.h>
#include <sys/ucontext.h>
#include <unistd.h>
#include <list>
@ -52,6 +53,12 @@ struct MappingEntry {
// A list of <MappingInfo, GUID>
typedef std::list<MappingEntry> MappingList;
#if defined(__aarch64__)
typedef struct fpsimd_context fpstate_t;
#elif !defined(__ARM_EABI__) && !defined(__mips__)
typedef struct _libc_fpstate fpstate_t;
#endif
// These entries store a list of memory regions that the client wants included
// in the minidump.
struct AppMemory {