1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/toolkit/crashreporter/google-breakpad/src/common/android/breakpad_getcontext.S Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,145 @@ 1.4 +// Copyright (c) 2012, Google Inc. 1.5 +// All rights reserved. 1.6 +// 1.7 +// Redistribution and use in source and binary forms, with or without 1.8 +// modification, are permitted provided that the following conditions are 1.9 +// met: 1.10 +// 1.11 +// * Redistributions of source code must retain the above copyright 1.12 +// notice, this list of conditions and the following disclaimer. 1.13 +// * Redistributions in binary form must reproduce the above 1.14 +// copyright notice, this list of conditions and the following disclaimer 1.15 +// in the documentation and/or other materials provided with the 1.16 +// distribution. 1.17 +// * Neither the name of Google Inc. nor the names of its 1.18 +// contributors may be used to endorse or promote products derived from 1.19 +// this software without specific prior written permission. 1.20 +// 1.21 +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1.22 +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1.23 +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1.24 +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 1.25 +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 1.26 +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 1.27 +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 1.28 +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 1.29 +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 1.30 +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 1.31 +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 1.32 + 1.33 +// A minimalistic implementation of getcontext() to be used by 1.34 +// Google Breakpad on Android. 1.35 + 1.36 +#include "common/android/ucontext_constants.h" 1.37 + 1.38 +/* int getcontext (ucontext_t *ucp) */ 1.39 + 1.40 +#ifdef __arm__ 1.41 + 1.42 + .text 1.43 + .global breakpad_getcontext 1.44 + .hidden breakpad_getcontext 1.45 + .type breakpad_getcontext, #function 1.46 + .align 0 1.47 + .fnstart 1.48 +breakpad_getcontext: 1.49 + 1.50 + /* First, save r4-r11 */ 1.51 + add r1, r0, #(MCONTEXT_GREGS_OFFSET + 4*4) 1.52 + stm r1, {r4-r11} 1.53 + 1.54 + /* r12 is a scratch register, don't save it */ 1.55 + 1.56 + /* Save sp and lr explicitely. */ 1.57 + /* - sp can't be stored with stmia in Thumb-2 */ 1.58 + /* - STM instructions that store sp and pc are deprecated in ARM */ 1.59 + str sp, [r0, #(MCONTEXT_GREGS_OFFSET + 13*4)] 1.60 + str lr, [r0, #(MCONTEXT_GREGS_OFFSET + 14*4)] 1.61 + 1.62 + /* Save the caller's address in 'pc' */ 1.63 + str lr, [r0, #(MCONTEXT_GREGS_OFFSET + 15*4)] 1.64 + 1.65 + /* Save ucontext_t* pointer accross next call */ 1.66 + mov r4, r0 1.67 + 1.68 + /* Call sigprocmask(SIG_BLOCK, NULL, &(ucontext->uc_sigmask)) */ 1.69 + mov r0, #0 /* SIG_BLOCK */ 1.70 + mov r1, #0 /* NULL */ 1.71 + add r2, r4, #UCONTEXT_SIGMASK_OFFSET 1.72 + bl sigprocmask(PLT) 1.73 + 1.74 + /* Intentionally do not save the FPU state here. This is because on 1.75 + * Linux/ARM, one should instead use ptrace(PTRACE_GETFPREGS) or 1.76 + * ptrace(PTRACE_GETVFPREGS) to get it. 1.77 + * 1.78 + * Note that a real implementation of getcontext() would need to save 1.79 + * this here to allow setcontext()/swapcontext() to work correctly. 1.80 + */ 1.81 + 1.82 + /* Restore the values of r4 and lr */ 1.83 + mov r0, r4 1.84 + ldr lr, [r0, #(MCONTEXT_GREGS_OFFSET + 14*4)] 1.85 + ldr r4, [r0, #(MCONTEXT_GREGS_OFFSET + 4*4)] 1.86 + 1.87 + /* Return 0 */ 1.88 + mov r0, #0 1.89 + bx lr 1.90 + 1.91 + .fnend 1.92 + .size breakpad_getcontext, . - breakpad_getcontext 1.93 + 1.94 +#elif defined(__i386__) 1.95 + 1.96 + .text 1.97 + .global breakpad_getcontext 1.98 + .hidden breakpad_getcontext 1.99 + .align 4 1.100 + .type breakpad_getcontext, @function 1.101 + 1.102 +breakpad_getcontext: 1.103 + 1.104 + movl 4(%esp), %eax /* eax = uc */ 1.105 + 1.106 + /* Save register values */ 1.107 + movl %ecx, MCONTEXT_ECX_OFFSET(%eax) 1.108 + movl %edx, MCONTEXT_EDX_OFFSET(%eax) 1.109 + movl %ebx, MCONTEXT_EBX_OFFSET(%eax) 1.110 + movl %edi, MCONTEXT_EDI_OFFSET(%eax) 1.111 + movl %esi, MCONTEXT_ESI_OFFSET(%eax) 1.112 + movl %ebp, MCONTEXT_EBP_OFFSET(%eax) 1.113 + 1.114 + movl (%esp), %edx /* return address */ 1.115 + lea 4(%esp), %ecx /* exclude return address from stack */ 1.116 + mov %edx, MCONTEXT_EIP_OFFSET(%eax) 1.117 + mov %ecx, MCONTEXT_ESP_OFFSET(%eax) 1.118 + 1.119 + xorl %ecx, %ecx 1.120 + movw %fs, %cx 1.121 + mov %ecx, MCONTEXT_FS_OFFSET(%eax) 1.122 + 1.123 + movl $0, MCONTEXT_EAX_OFFSET(%eax) 1.124 + 1.125 + /* Save floating point state to fpregstate, then update 1.126 + * the fpregs pointer to point to it */ 1.127 + leal UCONTEXT_FPREGS_MEM_OFFSET(%eax), %ecx 1.128 + fnstenv (%ecx) 1.129 + fldenv (%ecx) 1.130 + mov %ecx, UCONTEXT_FPREGS_OFFSET(%eax) 1.131 + 1.132 + /* Save signal mask: sigprocmask(SIGBLOCK, NULL, &uc->uc_sigmask) */ 1.133 + leal UCONTEXT_SIGMASK_OFFSET(%eax), %edx 1.134 + xorl %ecx, %ecx 1.135 + push %edx /* &uc->uc_sigmask */ 1.136 + push %ecx /* NULL */ 1.137 + push %ecx /* SIGBLOCK == 0 on i386 */ 1.138 + call sigprocmask@PLT 1.139 + addl $12, %esp 1.140 + 1.141 + movl $0, %eax 1.142 + ret 1.143 + 1.144 + .size breakpad_getcontext, . - breakpad_getcontext 1.145 + 1.146 +#else 1.147 +#error "This file has not been ported for your CPU!" 1.148 +#endif