mirror of
https://git.suyu.dev/suyu/breakpad.git
synced 2026-01-10 00:18:27 +01:00
First cut at adding arm64 Linux / Android support to Breakpad.
This is an initial attempt to add Arm64 (aarch64) support to Breakpad for Linux / Android platforms. This CL adds the Arm64 data structures, but does not yet implement the Android getcontext support or CPUFillFromThreadInfo / CPUFillFromUContext. BUG=354405,335641 R=mark@chromium.org Review URL: https://breakpad.appspot.com/1354002 git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@1301 4c0a9323-5329-0410-9bdc-e9ce6186880e
This commit is contained in:
parent
46aba5a43a
commit
83b9a28cf9
16 changed files with 118 additions and 19 deletions
|
|
@ -398,8 +398,8 @@ 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(__mips__)
|
||||
// FP state is not part of user ABI on ARM Linux.
|
||||
#if !defined(__ARM_EABI__) && !defined(__aarch64__) && !defined(__mips__)
|
||||
// FP state is not part of user ABI on ARM or ARM64 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;
|
||||
|
|
@ -608,7 +608,7 @@ bool ExceptionHandler::WriteMinidump() {
|
|||
}
|
||||
#endif
|
||||
|
||||
#if !defined(__ARM_EABI__) && !defined(__mips__)
|
||||
#if !defined(__ARM_EABI__) && !defined(__aarch64__) && !defined(__mips__)
|
||||
// FPU state is not part of ARM EABI ucontext_t.
|
||||
memcpy(&context.float_state, context.context.uc_mcontext.fpregs,
|
||||
sizeof(context.float_state));
|
||||
|
|
@ -627,6 +627,9 @@ bool ExceptionHandler::WriteMinidump() {
|
|||
#elif defined(__arm__)
|
||||
context.siginfo.si_addr =
|
||||
reinterpret_cast<void*>(context.context.uc_mcontext.arm_pc);
|
||||
#elif defined(__aarch64__)
|
||||
context.siginfo.si_addr =
|
||||
reinterpret_cast<void*>(context.context.uc_mcontext.pc);
|
||||
#elif defined(__mips__)
|
||||
context.siginfo.si_addr =
|
||||
reinterpret_cast<void*>(context.context.uc_mcontext.pc);
|
||||
|
|
|
|||
|
|
@ -190,10 +190,10 @@ class ExceptionHandler {
|
|||
siginfo_t siginfo;
|
||||
pid_t tid; // the crashing thread.
|
||||
struct ucontext context;
|
||||
#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.
|
||||
#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
|
||||
// ucontext so 'float_state' is not required.
|
||||
struct _libc_fpstate float_state;
|
||||
#endif
|
||||
};
|
||||
|
|
@ -259,7 +259,7 @@ class ExceptionHandler {
|
|||
// We need to explicitly enable ptrace of parent processes on some
|
||||
// kernels, but we need to know the PID of the cloned process before we
|
||||
// can do this. We create a pipe which we can use to block the
|
||||
// cloned process after creating it, until we have explicitly enabled
|
||||
// cloned process after creating it, until we have explicitly enabled
|
||||
// ptrace. This is used to store the file descriptors for the pipe
|
||||
int fdes[2];
|
||||
|
||||
|
|
|
|||
|
|
@ -99,8 +99,10 @@ bool LinuxCoreDumper::GetThreadInfoByIndex(size_t index, ThreadInfo* info) {
|
|||
memcpy(&stack_pointer, &info->regs.rsp, sizeof(info->regs.rsp));
|
||||
#elif defined(__ARM_EABI__)
|
||||
memcpy(&stack_pointer, &info->regs.ARM_sp, sizeof(info->regs.ARM_sp));
|
||||
#elif defined(__aarch64__)
|
||||
memcpy(&stack_pointer, &info->regs.sp, sizeof(info->regs.sp));
|
||||
#elif defined(__mips__)
|
||||
stack_pointer =
|
||||
stack_pointer =
|
||||
reinterpret_cast<uint8_t*>(info->regs.regs[MD_CONTEXT_MIPS_REG_SP]);
|
||||
#else
|
||||
#error "This code hasn't been ported to your platform yet."
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ typedef typeof(((struct user*) 0)->u_debugreg[0]) debugreg_t;
|
|||
// Typedef for our parsing of the auxv variables in /proc/pid/auxv.
|
||||
#if defined(__i386) || defined(__ARM_EABI__) || defined(__mips__)
|
||||
typedef Elf32_auxv_t elf_aux_entry;
|
||||
#elif defined(__x86_64)
|
||||
#elif defined(__x86_64) || defined(__aarch64__)
|
||||
typedef Elf64_auxv_t elf_aux_entry;
|
||||
#endif
|
||||
|
||||
|
|
@ -88,6 +88,10 @@ struct ThreadInfo {
|
|||
// Mimicking how strace does this(see syscall.c, search for GETREGS)
|
||||
struct user_regs regs;
|
||||
struct user_fpregs fpregs;
|
||||
#elif defined(__aarch64__)
|
||||
// Use the structures defined in <asm/ptrace.h>
|
||||
struct user_pt_regs regs;
|
||||
struct user_fpsimd_state fpregs;
|
||||
#elif defined(__mips__)
|
||||
user_regs_struct regs;
|
||||
user_fpregs_struct fpregs;
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/ptrace.h>
|
||||
#include <sys/uio.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
#if defined(__i386)
|
||||
|
|
@ -186,6 +187,20 @@ bool LinuxPtraceDumper::GetThreadInfoByIndex(size_t index, ThreadInfo* info) {
|
|||
if (info->ppid == -1 || info->tgid == -1)
|
||||
return false;
|
||||
|
||||
#ifdef PTRACE_GETREGSET
|
||||
struct iovec io;
|
||||
io.iov_base = &info->regs;
|
||||
io.iov_len = sizeof(info->regs);
|
||||
if (sys_ptrace(PTRACE_GETREGSET, tid, (void*)NT_PRSTATUS, (void*)&io) == -1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
io.iov_base = &info->fpregs;
|
||||
io.iov_len = sizeof(info->fpregs);
|
||||
if (sys_ptrace(PTRACE_GETREGSET, tid, (void*)NT_FPREGSET, (void*)&io) == -1) {
|
||||
return false;
|
||||
}
|
||||
#else
|
||||
if (sys_ptrace(PTRACE_GETREGS, tid, NULL, &info->regs) == -1) {
|
||||
return false;
|
||||
}
|
||||
|
|
@ -193,6 +208,7 @@ bool LinuxPtraceDumper::GetThreadInfoByIndex(size_t index, ThreadInfo* info) {
|
|||
if (sys_ptrace(PTRACE_GETFPREGS, tid, NULL, &info->fpregs) == -1) {
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(__i386)
|
||||
#if !defined(bit_FXSAVE) // e.g. Clang
|
||||
|
|
@ -241,6 +257,8 @@ bool LinuxPtraceDumper::GetThreadInfoByIndex(size_t index, ThreadInfo* info) {
|
|||
my_memcpy(&stack_pointer, &info->regs.rsp, sizeof(info->regs.rsp));
|
||||
#elif defined(__ARM_EABI__)
|
||||
my_memcpy(&stack_pointer, &info->regs.ARM_sp, sizeof(info->regs.ARM_sp));
|
||||
#elif defined(__aarch64__)
|
||||
my_memcpy(&stack_pointer, &info->regs.sp, sizeof(info->regs.sp));
|
||||
#elif defined(__mips__)
|
||||
stack_pointer =
|
||||
reinterpret_cast<uint8_t*>(info->regs.regs[MD_CONTEXT_MIPS_REG_SP]);
|
||||
|
|
|
|||
|
|
@ -374,6 +374,19 @@ void CPUFillFromUContext(MDRawContextARM* out, const ucontext* uc,
|
|||
my_memset(&out->float_save.extra, 0, sizeof(out->float_save.extra));
|
||||
}
|
||||
|
||||
#elif defined(__aarch64__)
|
||||
typedef MDRawContextARM64 RawContextCPU;
|
||||
|
||||
void CPUFillFromThreadInfo(MDRawContextARM64* out,
|
||||
const google_breakpad::ThreadInfo& info) {
|
||||
// TODO(rmcilroy): Implement for arm64.
|
||||
}
|
||||
|
||||
void CPUFillFromUContext(MDRawContextARM64* out, const ucontext* uc,
|
||||
const struct _libc_fpstate* fpregs) {
|
||||
// TODO(rmcilroy): Implement for arm64.
|
||||
}
|
||||
|
||||
#elif defined(__mips__)
|
||||
typedef MDRawContextMIPS RawContextCPU;
|
||||
|
||||
|
|
@ -470,7 +483,7 @@ class MinidumpWriter {
|
|||
: fd_(minidump_fd),
|
||||
path_(minidump_path),
|
||||
ucontext_(context ? &context->context : NULL),
|
||||
#if !defined(__ARM_EABI__) && !defined(__mips__)
|
||||
#if !defined(__ARM_EABI__) && !defined(__mips__) && !defined(__aarch64__)
|
||||
float_state_(context ? &context->float_state : NULL),
|
||||
#else
|
||||
// TODO: fix this after fixing ExceptionHandler
|
||||
|
|
@ -1271,6 +1284,18 @@ class MinidumpWriter {
|
|||
uintptr_t GetInstructionPointer(const ThreadInfo& info) {
|
||||
return info.regs.uregs[15];
|
||||
}
|
||||
#elif defined(__aarch64__)
|
||||
uintptr_t GetStackPointer() {
|
||||
return ucontext_->uc_mcontext.sp;
|
||||
}
|
||||
|
||||
uintptr_t GetInstructionPointer() {
|
||||
return ucontext_->uc_mcontext.pc;
|
||||
}
|
||||
|
||||
uintptr_t GetInstructionPointer(const ThreadInfo& info) {
|
||||
return info.regs.pc;
|
||||
}
|
||||
#elif defined(__mips__)
|
||||
uintptr_t GetStackPointer() {
|
||||
return ucontext_->uc_mcontext.gregs[MD_CONTEXT_MIPS_REG_SP];
|
||||
|
|
@ -1581,6 +1606,11 @@ class MinidumpWriter {
|
|||
|
||||
return true;
|
||||
}
|
||||
#elif defined(__aarch64__)
|
||||
bool WriteCPUInformation(MDRawSystemInfo* sys_info) {
|
||||
// TODO(rmcilroy): Implement for arm64.
|
||||
return false;
|
||||
}
|
||||
#else
|
||||
# error "Unsupported CPU"
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue