summaryrefslogtreecommitdiffstats
path: root/toolkit/crashreporter/google-breakpad/src/common/android/breakpad_getcontext.S
diff options
context:
space:
mode:
Diffstat (limited to 'toolkit/crashreporter/google-breakpad/src/common/android/breakpad_getcontext.S')
-rw-r--r--toolkit/crashreporter/google-breakpad/src/common/android/breakpad_getcontext.S489
1 files changed, 0 insertions, 489 deletions
diff --git a/toolkit/crashreporter/google-breakpad/src/common/android/breakpad_getcontext.S b/toolkit/crashreporter/google-breakpad/src/common/android/breakpad_getcontext.S
deleted file mode 100644
index fd6326adf..000000000
--- a/toolkit/crashreporter/google-breakpad/src/common/android/breakpad_getcontext.S
+++ /dev/null
@@ -1,489 +0,0 @@
-// Copyright (c) 2012, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// A minimalistic implementation of getcontext() to be used by
-// Google Breakpad on Android.
-
-#include "common/android/ucontext_constants.h"
-
-/* int getcontext (ucontext_t *ucp) */
-
-#if defined(__arm__)
-
- .text
- .global breakpad_getcontext
- .hidden breakpad_getcontext
- .type breakpad_getcontext, #function
- .align 0
- .fnstart
-breakpad_getcontext:
-
- /* First, save r4-r11 */
- add r1, r0, #(MCONTEXT_GREGS_OFFSET + 4*4)
- stm r1, {r4-r11}
-
- /* r12 is a scratch register, don't save it */
-
- /* Save sp and lr explicitly. */
- /* - sp can't be stored with stmia in Thumb-2 */
- /* - STM instructions that store sp and pc are deprecated in ARM */
- str sp, [r0, #(MCONTEXT_GREGS_OFFSET + 13*4)]
- str lr, [r0, #(MCONTEXT_GREGS_OFFSET + 14*4)]
-
- /* Save the caller's address in 'pc' */
- str lr, [r0, #(MCONTEXT_GREGS_OFFSET + 15*4)]
-
- /* Save ucontext_t* pointer across next call */
- mov r4, r0
-
- /* Call sigprocmask(SIG_BLOCK, NULL, &(ucontext->uc_sigmask)) */
- mov r0, #0 /* SIG_BLOCK */
- mov r1, #0 /* NULL */
- add r2, r4, #UCONTEXT_SIGMASK_OFFSET
- bl sigprocmask(PLT)
-
- /* Intentionally do not save the FPU state here. This is because on
- * Linux/ARM, one should instead use ptrace(PTRACE_GETFPREGS) or
- * ptrace(PTRACE_GETVFPREGS) to get it.
- *
- * Note that a real implementation of getcontext() would need to save
- * this here to allow setcontext()/swapcontext() to work correctly.
- */
-
- /* Restore the values of r4 and lr */
- mov r0, r4
- ldr lr, [r0, #(MCONTEXT_GREGS_OFFSET + 14*4)]
- ldr r4, [r0, #(MCONTEXT_GREGS_OFFSET + 4*4)]
-
- /* Return 0 */
- mov r0, #0
- bx lr
-
- .fnend
- .size breakpad_getcontext, . - breakpad_getcontext
-
-#elif defined(__aarch64__)
-
-#define _NSIG 64
-#define __NR_rt_sigprocmask 135
-
- .text
- .global breakpad_getcontext
- .hidden breakpad_getcontext
- .type breakpad_getcontext, #function
- .align 4
- .cfi_startproc
-breakpad_getcontext:
-
- /* The saved context will return to the getcontext() call point
- with a return value of 0 */
- str xzr, [x0, MCONTEXT_GREGS_OFFSET + 0 * REGISTER_SIZE]
-
- stp x18, x19, [x0, MCONTEXT_GREGS_OFFSET + 18 * REGISTER_SIZE]
- stp x20, x21, [x0, MCONTEXT_GREGS_OFFSET + 20 * REGISTER_SIZE]
- stp x22, x23, [x0, MCONTEXT_GREGS_OFFSET + 22 * REGISTER_SIZE]
- stp x24, x25, [x0, MCONTEXT_GREGS_OFFSET + 24 * REGISTER_SIZE]
- stp x26, x27, [x0, MCONTEXT_GREGS_OFFSET + 26 * REGISTER_SIZE]
- stp x28, x29, [x0, MCONTEXT_GREGS_OFFSET + 28 * REGISTER_SIZE]
- str x30, [x0, MCONTEXT_GREGS_OFFSET + 30 * REGISTER_SIZE]
-
- /* Place LR into the saved PC, this will ensure that when
- switching to this saved context with setcontext() control
- will pass back to the caller of getcontext(), we have
- already arranged to return the appropriate return value in x0
- above. */
- str x30, [x0, MCONTEXT_PC_OFFSET]
-
- /* Save the current SP */
- mov x2, sp
- str x2, [x0, MCONTEXT_SP_OFFSET]
-
- /* Initialize the pstate. */
- str xzr, [x0, MCONTEXT_PSTATE_OFFSET]
-
- /* Figure out where to place the first context extension
- block. */
- add x2, x0, #MCONTEXT_EXTENSION_OFFSET
-
- /* Write the context extension fpsimd header. */
- mov w3, #(FPSIMD_MAGIC & 0xffff)
- movk w3, #(FPSIMD_MAGIC >> 16), lsl #16
- str w3, [x2, #FPSIMD_CONTEXT_MAGIC_OFFSET]
- mov w3, #FPSIMD_CONTEXT_SIZE
- str w3, [x2, #FPSIMD_CONTEXT_SIZE_OFFSET]
-
- /* Fill in the FP SIMD context. */
- add x3, x2, #(FPSIMD_CONTEXT_VREGS_OFFSET + 8 * SIMD_REGISTER_SIZE)
- stp d8, d9, [x3], #(2 * SIMD_REGISTER_SIZE)
- stp d10, d11, [x3], #(2 * SIMD_REGISTER_SIZE)
- stp d12, d13, [x3], #(2 * SIMD_REGISTER_SIZE)
- stp d14, d15, [x3], #(2 * SIMD_REGISTER_SIZE)
-
- add x3, x2, FPSIMD_CONTEXT_FPSR_OFFSET
-
- mrs x4, fpsr
- str w4, [x3]
-
- mrs x4, fpcr
- str w4, [x3, FPSIMD_CONTEXT_FPCR_OFFSET - FPSIMD_CONTEXT_FPSR_OFFSET]
-
- /* Write the termination context extension header. */
- add x2, x2, #FPSIMD_CONTEXT_SIZE
-
- str xzr, [x2, #FPSIMD_CONTEXT_MAGIC_OFFSET]
- str xzr, [x2, #FPSIMD_CONTEXT_SIZE_OFFSET]
-
- /* Grab the signal mask */
- /* rt_sigprocmask (SIG_BLOCK, NULL, &ucp->uc_sigmask, _NSIG8) */
- add x2, x0, #UCONTEXT_SIGMASK_OFFSET
- mov x0, #0 /* SIG_BLOCK */
- mov x1, #0 /* NULL */
- mov x3, #(_NSIG / 8)
- mov x8, #__NR_rt_sigprocmask
- svc 0
-
- /* Return x0 for success */
- mov x0, 0
- ret
-
- .cfi_endproc
- .size breakpad_getcontext, . - breakpad_getcontext
-
-#elif defined(__i386__)
-
- .text
- .global breakpad_getcontext
- .hidden breakpad_getcontext
- .align 4
- .type breakpad_getcontext, @function
-
-breakpad_getcontext:
-
- movl 4(%esp), %eax /* eax = uc */
-
- /* Save register values */
- movl %ecx, MCONTEXT_ECX_OFFSET(%eax)
- movl %edx, MCONTEXT_EDX_OFFSET(%eax)
- movl %ebx, MCONTEXT_EBX_OFFSET(%eax)
- movl %edi, MCONTEXT_EDI_OFFSET(%eax)
- movl %esi, MCONTEXT_ESI_OFFSET(%eax)
- movl %ebp, MCONTEXT_EBP_OFFSET(%eax)
-
- movl (%esp), %edx /* return address */
- lea 4(%esp), %ecx /* exclude return address from stack */
- mov %edx, MCONTEXT_EIP_OFFSET(%eax)
- mov %ecx, MCONTEXT_ESP_OFFSET(%eax)
-
- xorl %ecx, %ecx
- movw %fs, %cx
- mov %ecx, MCONTEXT_FS_OFFSET(%eax)
-
- movl $0, MCONTEXT_EAX_OFFSET(%eax)
-
- /* Save floating point state to fpregstate, then update
- * the fpregs pointer to point to it */
- leal UCONTEXT_FPREGS_MEM_OFFSET(%eax), %ecx
- fnstenv (%ecx)
- fldenv (%ecx)
- mov %ecx, UCONTEXT_FPREGS_OFFSET(%eax)
-
- /* Save signal mask: sigprocmask(SIGBLOCK, NULL, &uc->uc_sigmask) */
- leal UCONTEXT_SIGMASK_OFFSET(%eax), %edx
- xorl %ecx, %ecx
- push %edx /* &uc->uc_sigmask */
- push %ecx /* NULL */
- push %ecx /* SIGBLOCK == 0 on i386 */
- call sigprocmask@PLT
- addl $12, %esp
-
- movl $0, %eax
- ret
-
- .size breakpad_getcontext, . - breakpad_getcontext
-
-#elif defined(__mips__)
-
-// This implementation is inspired by implementation of getcontext in glibc.
-#if _MIPS_SIM == _ABIO32
-#include <asm/asm.h>
-#include <asm/regdef.h>
-#include <asm/fpregdef.h>
-#else
-#include <machine/asm.h>
-#include <machine/regdef.h>
-#endif
-
-// from asm/asm.h
-#if _MIPS_SIM == _ABIO32
-#define ALSZ 7
-#define ALMASK ~7
-#define SZREG 4
-#else // _MIPS_SIM != _ABIO32
-#define ALSZ 15
-#define ALMASK ~15
-#define SZREG 8
-#endif
-
-#include <asm/unistd.h> // for __NR_rt_sigprocmask
-
-#define _NSIG8 128 / 8
-#define SIG_BLOCK 1
-
-
- .text
-LOCALS_NUM = 1 // save gp on stack
-FRAME_SIZE = ((LOCALS_NUM * SZREG) + ALSZ) & ALMASK
-
-GP_FRAME_OFFSET = FRAME_SIZE - (1 * SZREG)
-MCONTEXT_REG_SIZE = 8
-
-#if _MIPS_SIM == _ABIO32
-
-NESTED (breakpad_getcontext, FRAME_SIZE, ra)
- .mask 0x00000000, 0
- .fmask 0x00000000, 0
-
- .set noreorder
- .cpload t9
- .set reorder
-
- move a2, sp
-#define _SP a2
-
- addiu sp, -FRAME_SIZE
- .cprestore GP_FRAME_OFFSET
-
- sw s0, (16 * MCONTEXT_REG_SIZE + MCONTEXT_GREGS_OFFSET)(a0)
- sw s1, (17 * MCONTEXT_REG_SIZE + MCONTEXT_GREGS_OFFSET)(a0)
- sw s2, (18 * MCONTEXT_REG_SIZE + MCONTEXT_GREGS_OFFSET)(a0)
- sw s3, (19 * MCONTEXT_REG_SIZE + MCONTEXT_GREGS_OFFSET)(a0)
- sw s4, (20 * MCONTEXT_REG_SIZE + MCONTEXT_GREGS_OFFSET)(a0)
- sw s5, (21 * MCONTEXT_REG_SIZE + MCONTEXT_GREGS_OFFSET)(a0)
- sw s6, (22 * MCONTEXT_REG_SIZE + MCONTEXT_GREGS_OFFSET)(a0)
- sw s7, (23 * MCONTEXT_REG_SIZE + MCONTEXT_GREGS_OFFSET)(a0)
- sw _SP, (29 * MCONTEXT_REG_SIZE + MCONTEXT_GREGS_OFFSET)(a0)
- sw fp, (30 * MCONTEXT_REG_SIZE + MCONTEXT_GREGS_OFFSET)(a0)
- sw ra, (31 * MCONTEXT_REG_SIZE + MCONTEXT_GREGS_OFFSET)(a0)
- sw ra, MCONTEXT_PC_OFFSET(a0)
-
-#ifdef __mips_hard_float
- s.d fs0, (20 * MCONTEXT_REG_SIZE + MCONTEXT_FPREGS_OFFSET)(a0)
- s.d fs1, (22 * MCONTEXT_REG_SIZE + MCONTEXT_FPREGS_OFFSET)(a0)
- s.d fs2, (24 * MCONTEXT_REG_SIZE + MCONTEXT_FPREGS_OFFSET)(a0)
- s.d fs3, (26 * MCONTEXT_REG_SIZE + MCONTEXT_FPREGS_OFFSET)(a0)
- s.d fs4, (28 * MCONTEXT_REG_SIZE + MCONTEXT_FPREGS_OFFSET)(a0)
- s.d fs5, (30 * MCONTEXT_REG_SIZE + MCONTEXT_FPREGS_OFFSET)(a0)
-
- cfc1 v1, fcr31
- sw v1, MCONTEXT_FPC_CSR(a0)
-#endif // __mips_hard_float
-
- /* rt_sigprocmask (SIG_BLOCK, NULL, &ucp->uc_sigmask, _NSIG8) */
- li a3, _NSIG8
- addu a2, a0, UCONTEXT_SIGMASK_OFFSET
- move a1, zero
- li a0, SIG_BLOCK
- li v0, __NR_rt_sigprocmask
- syscall
-
- addiu sp, FRAME_SIZE
- jr ra
-
-END (breakpad_getcontext)
-#else
-
-#ifndef NESTED
-/*
- * NESTED - declare nested routine entry point
- */
-#define NESTED(symbol, framesize, rpc) \
- .globl symbol; \
- .align 2; \
- .type symbol,@function; \
- .ent symbol,0; \
-symbol: .frame sp, framesize, rpc;
-#endif
-
-/*
- * END - mark end of function
- */
-#ifndef END
-# define END(function) \
- .end function; \
- .size function,.-function
-#endif
-
-/* int getcontext (ucontext_t *ucp) */
-
-NESTED (breakpad_getcontext, FRAME_SIZE, ra)
- .mask 0x10000000, 0
- .fmask 0x00000000, 0
-
- move a2, sp
-#define _SP a2
- move a3, gp
-#define _GP a3
-
- daddiu sp, -FRAME_SIZE
- .cpsetup $25, GP_FRAME_OFFSET, breakpad_getcontext
-
- /* Store a magic flag. */
- li v1, 1
- sd v1, (0 * MCONTEXT_REG_SIZE + MCONTEXT_GREGS_OFFSET)(a0) /* zero */
-
- sd s0, (16 * MCONTEXT_REG_SIZE + MCONTEXT_GREGS_OFFSET)(a0)
- sd s1, (17 * MCONTEXT_REG_SIZE + MCONTEXT_GREGS_OFFSET)(a0)
- sd s2, (18 * MCONTEXT_REG_SIZE + MCONTEXT_GREGS_OFFSET)(a0)
- sd s3, (19 * MCONTEXT_REG_SIZE + MCONTEXT_GREGS_OFFSET)(a0)
- sd s4, (20 * MCONTEXT_REG_SIZE + MCONTEXT_GREGS_OFFSET)(a0)
- sd s5, (21 * MCONTEXT_REG_SIZE + MCONTEXT_GREGS_OFFSET)(a0)
- sd s6, (22 * MCONTEXT_REG_SIZE + MCONTEXT_GREGS_OFFSET)(a0)
- sd s7, (23 * MCONTEXT_REG_SIZE + MCONTEXT_GREGS_OFFSET)(a0)
- sd _GP, (28 * MCONTEXT_REG_SIZE + MCONTEXT_GREGS_OFFSET)(a0)
- sd _SP, (29 * MCONTEXT_REG_SIZE + MCONTEXT_GREGS_OFFSET)(a0)
- sd s8, (30 * MCONTEXT_REG_SIZE + MCONTEXT_GREGS_OFFSET)(a0)
- sd ra, (31 * MCONTEXT_REG_SIZE + MCONTEXT_GREGS_OFFSET)(a0)
- sd ra, MCONTEXT_PC_OFFSET(a0)
-
-#ifdef __mips_hard_float
- s.d $f24, (24 * MCONTEXT_REG_SIZE + MCONTEXT_FPREGS_OFFSET)(a0)
- s.d $f25, (25 * MCONTEXT_REG_SIZE + MCONTEXT_FPREGS_OFFSET)(a0)
- s.d $f26, (26 * MCONTEXT_REG_SIZE + MCONTEXT_FPREGS_OFFSET)(a0)
- s.d $f27, (27 * MCONTEXT_REG_SIZE + MCONTEXT_FPREGS_OFFSET)(a0)
- s.d $f28, (28 * MCONTEXT_REG_SIZE + MCONTEXT_FPREGS_OFFSET)(a0)
- s.d $f29, (29 * MCONTEXT_REG_SIZE + MCONTEXT_FPREGS_OFFSET)(a0)
- s.d $f30, (30 * MCONTEXT_REG_SIZE + MCONTEXT_FPREGS_OFFSET)(a0)
- s.d $f31, (31 * MCONTEXT_REG_SIZE + MCONTEXT_FPREGS_OFFSET)(a0)
-
- cfc1 v1, $31
- sw v1, MCONTEXT_FPC_CSR(a0)
-#endif /* __mips_hard_float */
-
-/* rt_sigprocmask (SIG_BLOCK, NULL, &ucp->uc_sigmask, _NSIG8) */
- li a3, _NSIG8
- daddu a2, a0, UCONTEXT_SIGMASK_OFFSET
- move a1, zero
- li a0, SIG_BLOCK
-
- li v0, __NR_rt_sigprocmask
- syscall
-
- .cpreturn
- daddiu sp, FRAME_SIZE
- move v0, zero
- jr ra
-
-END (breakpad_getcontext)
-#endif // _MIPS_SIM == _ABIO32
-
-#elif defined(__x86_64__)
-/* The x64 implementation of breakpad_getcontext was derived in part
- from the implementation of libunwind which requires the following
- notice. */
-/* libunwind - a platform-independent unwind library
- Copyright (C) 2008 Google, Inc
- Contributed by Paul Pluzhnikov <ppluzhnikov@google.com>
- Copyright (C) 2010 Konstantin Belousov <kib@freebsd.org>
-
-This file is part of libunwind.
-
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files (the
-"Software"), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-
- .text
- .global breakpad_getcontext
- .hidden breakpad_getcontext
- .align 4
- .type breakpad_getcontext, @function
-
-breakpad_getcontext:
- .cfi_startproc
-
- /* Callee saved: RBX, RBP, R12-R15 */
- movq %r12, MCONTEXT_GREGS_R12(%rdi)
- movq %r13, MCONTEXT_GREGS_R13(%rdi)
- movq %r14, MCONTEXT_GREGS_R14(%rdi)
- movq %r15, MCONTEXT_GREGS_R15(%rdi)
- movq %rbp, MCONTEXT_GREGS_RBP(%rdi)
- movq %rbx, MCONTEXT_GREGS_RBX(%rdi)
-
- /* Save argument registers (not strictly needed, but setcontext
- restores them, so don't restore garbage). */
- movq %r8, MCONTEXT_GREGS_R8(%rdi)
- movq %r9, MCONTEXT_GREGS_R9(%rdi)
- movq %rdi, MCONTEXT_GREGS_RDI(%rdi)
- movq %rsi, MCONTEXT_GREGS_RSI(%rdi)
- movq %rdx, MCONTEXT_GREGS_RDX(%rdi)
- movq %rax, MCONTEXT_GREGS_RAX(%rdi)
- movq %rcx, MCONTEXT_GREGS_RCX(%rdi)
-
- /* Save fp state (not needed, except for setcontext not
- restoring garbage). */
- leaq MCONTEXT_FPREGS_MEM(%rdi),%r8
- movq %r8, MCONTEXT_FPREGS_PTR(%rdi)
- fnstenv (%r8)
- stmxcsr FPREGS_OFFSET_MXCSR(%r8)
-
- leaq 8(%rsp), %rax /* exclude this call. */
- movq %rax, MCONTEXT_GREGS_RSP(%rdi)
-
- movq 0(%rsp), %rax
- movq %rax, MCONTEXT_GREGS_RIP(%rdi)
-
- /* Save signal mask: sigprocmask(SIGBLOCK, NULL, &uc->uc_sigmask) */
- leaq UCONTEXT_SIGMASK_OFFSET(%rdi), %rdx // arg3
- xorq %rsi, %rsi // arg2 NULL
- xorq %rdi, %rdi // arg1 SIGBLOCK == 0
- call sigprocmask@PLT
-
- /* Always return 0 for success, even if sigprocmask failed. */
- xorl %eax, %eax
- ret
- .cfi_endproc
- .size breakpad_getcontext, . - breakpad_getcontext
-
-#else
-#error "This file has not been ported for your CPU!"
-#endif