1*c0909341SAndroid Build Coastguard Worker/****************************************************************************** 2*c0909341SAndroid Build Coastguard Worker * Copyright © 2018, VideoLAN and dav1d authors 3*c0909341SAndroid Build Coastguard Worker * Copyright © 2015 Martin Storsjo 4*c0909341SAndroid Build Coastguard Worker * Copyright © 2015 Janne Grunau 5*c0909341SAndroid Build Coastguard Worker * All rights reserved. 6*c0909341SAndroid Build Coastguard Worker * 7*c0909341SAndroid Build Coastguard Worker * Redistribution and use in source and binary forms, with or without 8*c0909341SAndroid Build Coastguard Worker * modification, are permitted provided that the following conditions are met: 9*c0909341SAndroid Build Coastguard Worker * 10*c0909341SAndroid Build Coastguard Worker * 1. Redistributions of source code must retain the above copyright notice, this 11*c0909341SAndroid Build Coastguard Worker * list of conditions and the following disclaimer. 12*c0909341SAndroid Build Coastguard Worker * 13*c0909341SAndroid Build Coastguard Worker * 2. Redistributions in binary form must reproduce the above copyright notice, 14*c0909341SAndroid Build Coastguard Worker * this list of conditions and the following disclaimer in the documentation 15*c0909341SAndroid Build Coastguard Worker * and/or other materials provided with the distribution. 16*c0909341SAndroid Build Coastguard Worker * 17*c0909341SAndroid Build Coastguard Worker * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 18*c0909341SAndroid Build Coastguard Worker * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19*c0909341SAndroid Build Coastguard Worker * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20*c0909341SAndroid Build Coastguard Worker * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 21*c0909341SAndroid Build Coastguard Worker * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 22*c0909341SAndroid Build Coastguard Worker * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 23*c0909341SAndroid Build Coastguard Worker * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 24*c0909341SAndroid Build Coastguard Worker * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25*c0909341SAndroid Build Coastguard Worker * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 26*c0909341SAndroid Build Coastguard Worker * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27*c0909341SAndroid Build Coastguard Worker *****************************************************************************/ 28*c0909341SAndroid Build Coastguard Worker 29*c0909341SAndroid Build Coastguard Worker#define PRIVATE_PREFIX checkasm_ 30*c0909341SAndroid Build Coastguard Worker 31*c0909341SAndroid Build Coastguard Worker#include "src/arm/asm.S" 32*c0909341SAndroid Build Coastguard Worker#include "src/arm/32/util.S" 33*c0909341SAndroid Build Coastguard Worker 34*c0909341SAndroid Build Coastguard Workerconst register_init, align=3 35*c0909341SAndroid Build Coastguard Worker .quad 0x21f86d66c8ca00ce 36*c0909341SAndroid Build Coastguard Worker .quad 0x75b6ba21077c48ad 37*c0909341SAndroid Build Coastguard Worker .quad 0xed56bb2dcb3c7736 38*c0909341SAndroid Build Coastguard Worker .quad 0x8bda43d3fd1a7e06 39*c0909341SAndroid Build Coastguard Worker .quad 0xb64a9c9e5d318408 40*c0909341SAndroid Build Coastguard Worker .quad 0xdf9a54b303f1d3a3 41*c0909341SAndroid Build Coastguard Worker .quad 0x4a75479abd64e097 42*c0909341SAndroid Build Coastguard Worker .quad 0x249214109d5d1c88 43*c0909341SAndroid Build Coastguard Workerendconst 44*c0909341SAndroid Build Coastguard Worker 45*c0909341SAndroid Build Coastguard Workerconst error_message_fpscr 46*c0909341SAndroid Build Coastguard Worker .asciz "failed to preserve register FPSCR, changed bits: %x" 47*c0909341SAndroid Build Coastguard Workererror_message_gpr: 48*c0909341SAndroid Build Coastguard Worker .asciz "failed to preserve register r%d" 49*c0909341SAndroid Build Coastguard Workererror_message_vfp: 50*c0909341SAndroid Build Coastguard Worker .asciz "failed to preserve register d%d" 51*c0909341SAndroid Build Coastguard Workererror_message_stack: 52*c0909341SAndroid Build Coastguard Worker .asciz "failed to preserve stack" 53*c0909341SAndroid Build Coastguard Workerendconst 54*c0909341SAndroid Build Coastguard Worker 55*c0909341SAndroid Build Coastguard Worker@ max number of args used by any asm function. 56*c0909341SAndroid Build Coastguard Worker#define MAX_ARGS 15 57*c0909341SAndroid Build Coastguard Worker 58*c0909341SAndroid Build Coastguard Worker#define ARG_STACK 4*(MAX_ARGS - 4) 59*c0909341SAndroid Build Coastguard Worker 60*c0909341SAndroid Build Coastguard Worker@ Align the used stack space to 8 to preserve the stack alignment. 61*c0909341SAndroid Build Coastguard Worker@ +8 for stack canary reference. 62*c0909341SAndroid Build Coastguard Worker#define ARG_STACK_A (((ARG_STACK + pushed + 7) & ~7) - pushed + 8) 63*c0909341SAndroid Build Coastguard Worker 64*c0909341SAndroid Build Coastguard Worker.macro clobbercheck variant 65*c0909341SAndroid Build Coastguard Worker.equ pushed, 4*9 66*c0909341SAndroid Build Coastguard Workerfunction checked_call_\variant, export=1 67*c0909341SAndroid Build Coastguard Worker push {r4-r11, lr} 68*c0909341SAndroid Build Coastguard Worker.ifc \variant, vfp 69*c0909341SAndroid Build Coastguard Worker vpush {d8-d15} 70*c0909341SAndroid Build Coastguard Worker fmrx r4, FPSCR 71*c0909341SAndroid Build Coastguard Worker push {r4} 72*c0909341SAndroid Build Coastguard Worker.equ pushed, pushed + 16*4 + 4 73*c0909341SAndroid Build Coastguard Worker.endif 74*c0909341SAndroid Build Coastguard Worker 75*c0909341SAndroid Build Coastguard Worker movrel r12, register_init 76*c0909341SAndroid Build Coastguard Worker.ifc \variant, vfp 77*c0909341SAndroid Build Coastguard Worker vldm r12, {d8-d15} 78*c0909341SAndroid Build Coastguard Worker.endif 79*c0909341SAndroid Build Coastguard Worker ldm r12, {r4-r11} 80*c0909341SAndroid Build Coastguard Worker 81*c0909341SAndroid Build Coastguard Worker sub sp, sp, #ARG_STACK_A 82*c0909341SAndroid Build Coastguard Worker.equ pos, 0 83*c0909341SAndroid Build Coastguard Worker.rept MAX_ARGS-4 84*c0909341SAndroid Build Coastguard Worker ldr r12, [sp, #ARG_STACK_A + pushed + 8 + pos] 85*c0909341SAndroid Build Coastguard Worker str r12, [sp, #pos] 86*c0909341SAndroid Build Coastguard Worker.equ pos, pos + 4 87*c0909341SAndroid Build Coastguard Worker.endr 88*c0909341SAndroid Build Coastguard Worker 89*c0909341SAndroid Build Coastguard Worker @ For stack overflows, the callee is free to overwrite the parameters 90*c0909341SAndroid Build Coastguard Worker @ that were passed on the stack (if any), so we can only check after 91*c0909341SAndroid Build Coastguard Worker @ that point. First figure out how many parameters the function 92*c0909341SAndroid Build Coastguard Worker @ really took on the stack: 93*c0909341SAndroid Build Coastguard Worker ldr r12, [sp, #ARG_STACK_A + pushed + 8 + 4*(MAX_ARGS-4)] 94*c0909341SAndroid Build Coastguard Worker @ Load the first non-parameter value from the stack, that should be 95*c0909341SAndroid Build Coastguard Worker @ left untouched by the function. Store a copy of it inverted, so that 96*c0909341SAndroid Build Coastguard Worker @ e.g. overwriting everything with zero would be noticed. 97*c0909341SAndroid Build Coastguard Worker ldr r12, [sp, r12, lsl #2] 98*c0909341SAndroid Build Coastguard Worker mvn r12, r12 99*c0909341SAndroid Build Coastguard Worker str r12, [sp, #ARG_STACK_A - 4] 100*c0909341SAndroid Build Coastguard Worker 101*c0909341SAndroid Build Coastguard Worker mov r12, r0 102*c0909341SAndroid Build Coastguard Worker mov r0, r2 103*c0909341SAndroid Build Coastguard Worker mov r1, r3 104*c0909341SAndroid Build Coastguard Worker ldr r2, [sp, #ARG_STACK_A + pushed] 105*c0909341SAndroid Build Coastguard Worker ldr r3, [sp, #ARG_STACK_A + pushed + 4] 106*c0909341SAndroid Build Coastguard Worker @ Call the target function 107*c0909341SAndroid Build Coastguard Worker v4blx r12 108*c0909341SAndroid Build Coastguard Worker 109*c0909341SAndroid Build Coastguard Worker @ Load the number of stack parameters, stack canary and its reference 110*c0909341SAndroid Build Coastguard Worker ldr r12, [sp, #ARG_STACK_A + pushed + 8 + 4*(MAX_ARGS-4)] 111*c0909341SAndroid Build Coastguard Worker ldr r2, [sp, r12, lsl #2] 112*c0909341SAndroid Build Coastguard Worker ldr r3, [sp, #ARG_STACK_A - 4] 113*c0909341SAndroid Build Coastguard Worker 114*c0909341SAndroid Build Coastguard Worker add sp, sp, #ARG_STACK_A 115*c0909341SAndroid Build Coastguard Worker push {r0, r1} 116*c0909341SAndroid Build Coastguard Worker 117*c0909341SAndroid Build Coastguard Worker mvn r3, r3 118*c0909341SAndroid Build Coastguard Worker cmp r2, r3 119*c0909341SAndroid Build Coastguard Worker bne 5f 120*c0909341SAndroid Build Coastguard Worker 121*c0909341SAndroid Build Coastguard Worker movrel r12, register_init 122*c0909341SAndroid Build Coastguard Worker.ifc \variant, vfp 123*c0909341SAndroid Build Coastguard Worker.macro check_reg_vfp, dreg, offset 124*c0909341SAndroid Build Coastguard Worker ldr r2, [r12, #(8 * (\offset))] 125*c0909341SAndroid Build Coastguard Worker ldr r3, [r12, #(8 * (\offset)) + 4] 126*c0909341SAndroid Build Coastguard Worker vmov r0, lr, \dreg 127*c0909341SAndroid Build Coastguard Worker eor r2, r2, r0 128*c0909341SAndroid Build Coastguard Worker eor r3, r3, lr 129*c0909341SAndroid Build Coastguard Worker orrs r2, r2, r3 130*c0909341SAndroid Build Coastguard Worker bne 4f 131*c0909341SAndroid Build Coastguard Worker.endm 132*c0909341SAndroid Build Coastguard Worker 133*c0909341SAndroid Build Coastguard Worker.irp n, 8, 9, 10, 11, 12, 13, 14, 15 134*c0909341SAndroid Build Coastguard Worker @ keep track of the checked double/SIMD register 135*c0909341SAndroid Build Coastguard Worker mov r1, #\n 136*c0909341SAndroid Build Coastguard Worker check_reg_vfp d\n, \n-8 137*c0909341SAndroid Build Coastguard Worker.endr 138*c0909341SAndroid Build Coastguard Worker.purgem check_reg_vfp 139*c0909341SAndroid Build Coastguard Worker 140*c0909341SAndroid Build Coastguard Worker fmrx r1, FPSCR 141*c0909341SAndroid Build Coastguard Worker ldr r3, [sp, #8] 142*c0909341SAndroid Build Coastguard Worker eor r1, r1, r3 143*c0909341SAndroid Build Coastguard Worker @ Ignore changes in bits 0-4 and 7 144*c0909341SAndroid Build Coastguard Worker bic r1, r1, #0x9f 145*c0909341SAndroid Build Coastguard Worker @ Ignore changes in the topmost 5 bits 146*c0909341SAndroid Build Coastguard Worker bics r1, r1, #0xf8000000 147*c0909341SAndroid Build Coastguard Worker bne 3f 148*c0909341SAndroid Build Coastguard Worker.endif 149*c0909341SAndroid Build Coastguard Worker 150*c0909341SAndroid Build Coastguard Worker @ keep track of the checked GPR 151*c0909341SAndroid Build Coastguard Worker mov r1, #4 152*c0909341SAndroid Build Coastguard Worker.macro check_reg reg1, reg2= 153*c0909341SAndroid Build Coastguard Worker ldr r2, [r12], #4 154*c0909341SAndroid Build Coastguard Worker ldr r3, [r12], #4 155*c0909341SAndroid Build Coastguard Worker eors r2, r2, \reg1 156*c0909341SAndroid Build Coastguard Worker bne 2f 157*c0909341SAndroid Build Coastguard Worker add r1, r1, #1 158*c0909341SAndroid Build Coastguard Worker.ifnb \reg2 159*c0909341SAndroid Build Coastguard Worker eors r3, r3, \reg2 160*c0909341SAndroid Build Coastguard Worker bne 2f 161*c0909341SAndroid Build Coastguard Worker.endif 162*c0909341SAndroid Build Coastguard Worker add r1, r1, #1 163*c0909341SAndroid Build Coastguard Worker.endm 164*c0909341SAndroid Build Coastguard Worker check_reg r4, r5 165*c0909341SAndroid Build Coastguard Worker check_reg r6, r7 166*c0909341SAndroid Build Coastguard Worker@ r9 is a volatile register in the ios ABI 167*c0909341SAndroid Build Coastguard Worker#ifdef __APPLE__ 168*c0909341SAndroid Build Coastguard Worker check_reg r8 169*c0909341SAndroid Build Coastguard Worker#else 170*c0909341SAndroid Build Coastguard Worker check_reg r8, r9 171*c0909341SAndroid Build Coastguard Worker#endif 172*c0909341SAndroid Build Coastguard Worker check_reg r10, r11 173*c0909341SAndroid Build Coastguard Worker.purgem check_reg 174*c0909341SAndroid Build Coastguard Worker 175*c0909341SAndroid Build Coastguard Worker b 0f 176*c0909341SAndroid Build Coastguard Worker5: 177*c0909341SAndroid Build Coastguard Worker movrel r0, error_message_stack 178*c0909341SAndroid Build Coastguard Worker b 1f 179*c0909341SAndroid Build Coastguard Worker4: 180*c0909341SAndroid Build Coastguard Worker movrel r0, error_message_vfp 181*c0909341SAndroid Build Coastguard Worker b 1f 182*c0909341SAndroid Build Coastguard Worker3: 183*c0909341SAndroid Build Coastguard Worker movrel r0, error_message_fpscr 184*c0909341SAndroid Build Coastguard Worker b 1f 185*c0909341SAndroid Build Coastguard Worker2: 186*c0909341SAndroid Build Coastguard Worker movrel r0, error_message_gpr 187*c0909341SAndroid Build Coastguard Worker1: 188*c0909341SAndroid Build Coastguard Worker#ifdef PREFIX 189*c0909341SAndroid Build Coastguard Worker bl _checkasm_fail_func 190*c0909341SAndroid Build Coastguard Worker#else 191*c0909341SAndroid Build Coastguard Worker bl checkasm_fail_func 192*c0909341SAndroid Build Coastguard Worker#endif 193*c0909341SAndroid Build Coastguard Worker0: 194*c0909341SAndroid Build Coastguard Worker pop {r0, r1} 195*c0909341SAndroid Build Coastguard Worker.ifc \variant, vfp 196*c0909341SAndroid Build Coastguard Worker pop {r2} 197*c0909341SAndroid Build Coastguard Worker fmxr FPSCR, r2 198*c0909341SAndroid Build Coastguard Worker vpop {d8-d15} 199*c0909341SAndroid Build Coastguard Worker.endif 200*c0909341SAndroid Build Coastguard Worker pop {r4-r11, pc} 201*c0909341SAndroid Build Coastguard Workerendfunc 202*c0909341SAndroid Build Coastguard Worker.endm 203*c0909341SAndroid Build Coastguard Worker 204*c0909341SAndroid Build Coastguard Workerclobbercheck novfp 205*c0909341SAndroid Build Coastguard Workerclobbercheck vfp 206