diff options
Diffstat (limited to 'src/client/linux')
-rw-r--r-- | src/client/linux/handler/exception_handler.cc | 9 | ||||
-rw-r--r-- | src/client/linux/handler/exception_handler.h | 10 | ||||
-rw-r--r-- | src/client/linux/minidump_writer/linux_core_dumper.cc | 4 | ||||
-rw-r--r-- | src/client/linux/minidump_writer/linux_dumper.h | 6 | ||||
-rw-r--r-- | src/client/linux/minidump_writer/linux_ptrace_dumper.cc | 18 | ||||
-rw-r--r-- | src/client/linux/minidump_writer/minidump_writer.cc | 32 |
6 files changed, 68 insertions, 11 deletions
diff --git a/src/client/linux/handler/exception_handler.cc b/src/client/linux/handler/exception_handler.cc index 58fbacbd..9d081ca8 100644 --- a/src/client/linux/handler/exception_handler.cc +++ b/src/client/linux/handler/exception_handler.cc @@ -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); diff --git a/src/client/linux/handler/exception_handler.h b/src/client/linux/handler/exception_handler.h index b57f58d4..2e842d83 100644 --- a/src/client/linux/handler/exception_handler.h +++ b/src/client/linux/handler/exception_handler.h @@ -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]; diff --git a/src/client/linux/minidump_writer/linux_core_dumper.cc b/src/client/linux/minidump_writer/linux_core_dumper.cc index f5b19d10..eb9e3fd0 100644 --- a/src/client/linux/minidump_writer/linux_core_dumper.cc +++ b/src/client/linux/minidump_writer/linux_core_dumper.cc @@ -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." diff --git a/src/client/linux/minidump_writer/linux_dumper.h b/src/client/linux/minidump_writer/linux_dumper.h index 2bb4cac7..335a2ce9 100644 --- a/src/client/linux/minidump_writer/linux_dumper.h +++ b/src/client/linux/minidump_writer/linux_dumper.h @@ -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; diff --git a/src/client/linux/minidump_writer/linux_ptrace_dumper.cc b/src/client/linux/minidump_writer/linux_ptrace_dumper.cc index 8b96037e..5ab59c27 100644 --- a/src/client/linux/minidump_writer/linux_ptrace_dumper.cc +++ b/src/client/linux/minidump_writer/linux_ptrace_dumper.cc @@ -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]); diff --git a/src/client/linux/minidump_writer/minidump_writer.cc b/src/client/linux/minidump_writer/minidump_writer.cc index ee759274..50929f80 100644 --- a/src/client/linux/minidump_writer/minidump_writer.cc +++ b/src/client/linux/minidump_writer/minidump_writer.cc @@ -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 |