1/****************************************************************************** 2 * Copyright © 2018, VideoLAN and dav1d authors 3 * Copyright © 2015 Martin Storsjo 4 * Copyright © 2015 Janne Grunau 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions are met: 9 * 10 * 1. Redistributions of source code must retain the above copyright notice, this 11 * list of conditions and the following disclaimer. 12 * 13 * 2. Redistributions in binary form must reproduce the above copyright notice, 14 * this list of conditions and the following disclaimer in the documentation 15 * and/or other materials provided with the distribution. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 21 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 22 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 23 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 24 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 26 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 *****************************************************************************/ 28 29#define PRIVATE_PREFIX checkasm_ 30 31#include "src/arm/asm.S" 32#include "src/arm/64/util.S" 33 34const register_init, align=4 35 .quad 0x21f86d66c8ca00ce 36 .quad 0x75b6ba21077c48ad 37 .quad 0xed56bb2dcb3c7736 38 .quad 0x8bda43d3fd1a7e06 39 .quad 0xb64a9c9e5d318408 40 .quad 0xdf9a54b303f1d3a3 41 .quad 0x4a75479abd64e097 42 .quad 0x249214109d5d1c88 43 .quad 0x1a1b2550a612b48c 44 .quad 0x79445c159ce79064 45 .quad 0x2eed899d5a28ddcd 46 .quad 0x86b2536fcd8cf636 47 .quad 0xb0856806085e7943 48 .quad 0x3f2bf84fc0fcca4e 49 .quad 0xacbd382dcf5b8de2 50 .quad 0xd229e1f5b281303f 51 .quad 0x71aeaff20b095fd9 52 .quad 0xab63e2e11fa38ed9 53endconst 54 55 56const error_message_register 57 .asciz "failed to preserve register" 58error_message_stack: 59 .asciz "stack clobbered" 60endconst 61 62 63// max number of args used by any asm function. 64#define MAX_ARGS 15 65 66#define CLOBBER_STACK ((8*MAX_ARGS + 15) & ~15) 67 68function stack_clobber, export=1 69 mov x3, sp 70 mov x2, #CLOBBER_STACK 711: 72 stp x0, x1, [sp, #-16]! 73 subs x2, x2, #16 74 b.gt 1b 75 mov sp, x3 76 ret 77endfunc 78 79// + 16 for stack canary reference 80#define ARG_STACK ((8*(MAX_ARGS - 8) + 15) & ~15 + 16) 81 82function checked_call, export=1 83 stp x29, x30, [sp, #-16]! 84 mov x29, sp 85 stp x19, x20, [sp, #-16]! 86 stp x21, x22, [sp, #-16]! 87 stp x23, x24, [sp, #-16]! 88 stp x25, x26, [sp, #-16]! 89 stp x27, x28, [sp, #-16]! 90 stp d8, d9, [sp, #-16]! 91 stp d10, d11, [sp, #-16]! 92 stp d12, d13, [sp, #-16]! 93 stp d14, d15, [sp, #-16]! 94 95 movrel x9, register_init 96 ldp d8, d9, [x9], #16 97 ldp d10, d11, [x9], #16 98 ldp d12, d13, [x9], #16 99 ldp d14, d15, [x9], #16 100 ldp x19, x20, [x9], #16 101 ldp x21, x22, [x9], #16 102 ldp x23, x24, [x9], #16 103 ldp x25, x26, [x9], #16 104 ldp x27, x28, [x9], #16 105 106 sub sp, sp, #ARG_STACK 107.equ pos, 0 108.rept MAX_ARGS-8 109 // Skip the first 8 args, that are loaded into registers 110 ldr x9, [x29, #16 + 8*8 + pos] 111 str x9, [sp, #pos] 112.equ pos, pos + 8 113.endr 114 115 // Fill x8-x17 with garbage. This doesn't have to be preserved, 116 // but avoids relying on them having any particular value. 117 movrel x9, register_init 118 ldp x10, x11, [x9], #32 119 ldp x12, x13, [x9], #32 120 ldp x14, x15, [x9], #32 121 ldp x16, x17, [x9], #32 122 ldp x8, x9, [x9] 123 124 // For stack overflows, the callee is free to overwrite the parameters 125 // that were passed on the stack (if any), so we can only check after 126 // that point. First figure out how many parameters the function 127 // really took on the stack: 128 ldr w2, [x29, #16 + 8*8 + (MAX_ARGS-8)*8] 129 // Load the first non-parameter value from the stack, that should be 130 // left untouched by the function. Store a copy of it inverted, so that 131 // e.g. overwriting everything with zero would be noticed. 132 ldr x2, [sp, x2, lsl #3] 133 mvn x2, x2 134 str x2, [sp, #ARG_STACK-8] 135 136 // Load the in-register arguments 137 mov x12, x0 138 ldp x0, x1, [x29, #16] 139 ldp x2, x3, [x29, #32] 140 ldp x4, x5, [x29, #48] 141 ldp x6, x7, [x29, #64] 142 // Call the target function 143 blr x12 144 145 // Load the number of stack parameters, stack canary and its reference 146 ldr w2, [x29, #16 + 8*8 + (MAX_ARGS-8)*8] 147 ldr x2, [sp, x2, lsl #3] 148 ldr x3, [sp, #ARG_STACK-8] 149 150 add sp, sp, #ARG_STACK 151 stp x0, x1, [sp, #-16]! 152 153 mvn x3, x3 154 cmp x2, x3 155 b.ne 2f 156 157 movrel x9, register_init 158 movi v3.8h, #0 159 160.macro check_reg_neon reg1, reg2 161 ldr q1, [x9], #16 162 uzp1 v2.2d, v\reg1\().2d, v\reg2\().2d 163 eor v1.16b, v1.16b, v2.16b 164 orr v3.16b, v3.16b, v1.16b 165.endm 166 check_reg_neon 8, 9 167 check_reg_neon 10, 11 168 check_reg_neon 12, 13 169 check_reg_neon 14, 15 170 uqxtn v3.8b, v3.8h 171 umov x3, v3.d[0] 172 173.macro check_reg reg1, reg2 174 ldp x0, x1, [x9], #16 175 eor x0, x0, \reg1 176 eor x1, x1, \reg2 177 orr x3, x3, x0 178 orr x3, x3, x1 179.endm 180 check_reg x19, x20 181 check_reg x21, x22 182 check_reg x23, x24 183 check_reg x25, x26 184 check_reg x27, x28 185 186 cbz x3, 0f 187 188 movrel x0, error_message_register 189 b 1f 1902: 191 movrel x0, error_message_stack 1921: 193#ifdef PREFIX 194 bl _checkasm_fail_func 195#else 196 bl checkasm_fail_func 197#endif 1980: 199 ldp x0, x1, [sp], #16 200 ldp d14, d15, [sp], #16 201 ldp d12, d13, [sp], #16 202 ldp d10, d11, [sp], #16 203 ldp d8, d9, [sp], #16 204 ldp x27, x28, [sp], #16 205 ldp x25, x26, [sp], #16 206 ldp x23, x24, [sp], #16 207 ldp x21, x22, [sp], #16 208 ldp x19, x20, [sp], #16 209 ldp x29, x30, [sp], #16 210 ret 211endfunc 212 213#if HAVE_SVE 214ENABLE_SVE 215function sve_length, export=1 216 cntb x0 217 lsl x0, x0, #3 218 ret 219endfunc 220DISABLE_SVE 221#endif 222