1*344aa361SAndroid Build Coastguard Worker/* 2*344aa361SAndroid Build Coastguard Worker * Copyright (c) 2022, Google Inc. All rights reserved 3*344aa361SAndroid Build Coastguard Worker * 4*344aa361SAndroid Build Coastguard Worker * Permission is hereby granted, free of charge, to any person obtaining 5*344aa361SAndroid Build Coastguard Worker * a copy of this software and associated documentation files 6*344aa361SAndroid Build Coastguard Worker * (the "Software"), to deal in the Software without restriction, 7*344aa361SAndroid Build Coastguard Worker * including without limitation the rights to use, copy, modify, merge, 8*344aa361SAndroid Build Coastguard Worker * publish, distribute, sublicense, and/or sell copies of the Software, 9*344aa361SAndroid Build Coastguard Worker * and to permit persons to whom the Software is furnished to do so, 10*344aa361SAndroid Build Coastguard Worker * subject to the following conditions: 11*344aa361SAndroid Build Coastguard Worker * 12*344aa361SAndroid Build Coastguard Worker * The above copyright notice and this permission notice shall be 13*344aa361SAndroid Build Coastguard Worker * included in all copies or substantial portions of the Software. 14*344aa361SAndroid Build Coastguard Worker * 15*344aa361SAndroid Build Coastguard Worker * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16*344aa361SAndroid Build Coastguard Worker * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17*344aa361SAndroid Build Coastguard Worker * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 18*344aa361SAndroid Build Coastguard Worker * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 19*344aa361SAndroid Build Coastguard Worker * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 20*344aa361SAndroid Build Coastguard Worker * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 21*344aa361SAndroid Build Coastguard Worker * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22*344aa361SAndroid Build Coastguard Worker */ 23*344aa361SAndroid Build Coastguard Worker 24*344aa361SAndroid Build Coastguard Worker#include <asm.h> 25*344aa361SAndroid Build Coastguard Worker#include <arch/asm_macros.h> 26*344aa361SAndroid Build Coastguard Worker#include <err.h> 27*344aa361SAndroid Build Coastguard Worker#include "btitest.h" 28*344aa361SAndroid Build Coastguard Worker 29*344aa361SAndroid Build Coastguard Worker.section .text 30*344aa361SAndroid Build Coastguard Worker 31*344aa361SAndroid Build Coastguard Worker/* Fault handler to return where BTI calls fail. 32*344aa361SAndroid Build Coastguard Worker * On return from the caught Branch Target exception, PSTATE.BTYPE will still 33*344aa361SAndroid Build Coastguard Worker * be set according to the last branch taken. Therefore we need to land on a 34*344aa361SAndroid Build Coastguard Worker * BTI jc to be compatible with all callers - and avoid another immediate 35*344aa361SAndroid Build Coastguard Worker * Branch Target exception. 36*344aa361SAndroid Build Coastguard Worker */ 37*344aa361SAndroid Build Coastguard Worker.Lbtitest_callee_fault: 38*344aa361SAndroid Build Coastguard Worker bti jc 39*344aa361SAndroid Build Coastguard Worker mov x0, #ERR_FAULT 40*344aa361SAndroid Build Coastguard Worker ret 41*344aa361SAndroid Build Coastguard Worker 42*344aa361SAndroid Build Coastguard Worker/** 43*344aa361SAndroid Build Coastguard Worker * int btitest_bl(void) - Use bl to call each of the test functions 44*344aa361SAndroid Build Coastguard Worker * 45*344aa361SAndroid Build Coastguard Worker * This calls each of the test functions using bl and a relative offset, 46*344aa361SAndroid Build Coastguard Worker * which should always be allowed. The functions are expected to all return 0. 47*344aa361SAndroid Build Coastguard Worker * 48*344aa361SAndroid Build Coastguard Worker * Returns The first non-zero return code, or 0 if all functions pass. 49*344aa361SAndroid Build Coastguard Worker */ 50*344aa361SAndroid Build Coastguard WorkerFUNCTION(btitest_bl) 51*344aa361SAndroid Build Coastguard Worker push lr, xzr 52*344aa361SAndroid Build Coastguard Worker bl btitest_callee_nop 53*344aa361SAndroid Build Coastguard Worker cbnz x0, .Lerror 54*344aa361SAndroid Build Coastguard Worker bl btitest_callee_bti 55*344aa361SAndroid Build Coastguard Worker cbnz x0, .Lerror 56*344aa361SAndroid Build Coastguard Worker bl btitest_callee_bti_c 57*344aa361SAndroid Build Coastguard Worker cbnz x0, .Lerror 58*344aa361SAndroid Build Coastguard Worker bl btitest_callee_bti_j 59*344aa361SAndroid Build Coastguard Worker cbnz x0, .Lerror 60*344aa361SAndroid Build Coastguard Worker bl btitest_callee_bti_jc 61*344aa361SAndroid Build Coastguard Worker cbnz x0, .Lerror 62*344aa361SAndroid Build Coastguard Worker bl btitest_callee_paciasp 63*344aa361SAndroid Build Coastguard Worker cbnz x0, .Lerror 64*344aa361SAndroid Build Coastguard Worker bl btitest_callee_pacibsp 65*344aa361SAndroid Build Coastguard Worker.Lerror: 66*344aa361SAndroid Build Coastguard Worker pop lr, xzr 67*344aa361SAndroid Build Coastguard Worker ret 68*344aa361SAndroid Build Coastguard Worker 69*344aa361SAndroid Build Coastguard Worker/** 70*344aa361SAndroid Build Coastguard Worker * int btitest_blr(int) - Use blr to call the passed function 71*344aa361SAndroid Build Coastguard Worker * 72*344aa361SAndroid Build Coastguard Worker * Returns The called function's return value 73*344aa361SAndroid Build Coastguard Worker */ 74*344aa361SAndroid Build Coastguard WorkerFUNCTION(btitest_blr) 75*344aa361SAndroid Build Coastguard Worker push lr, xzr 76*344aa361SAndroid Build Coastguard Worker bl get_callee 77*344aa361SAndroid Build Coastguard Worker blr x0 78*344aa361SAndroid Build Coastguard Worker pop lr, xzr 79*344aa361SAndroid Build Coastguard Worker ret 80*344aa361SAndroid Build Coastguard Worker 81*344aa361SAndroid Build Coastguard Worker/** 82*344aa361SAndroid Build Coastguard Worker * int btitest_br(int) - Use br to call the passed function via the x0 register 83*344aa361SAndroid Build Coastguard Worker * 84*344aa361SAndroid Build Coastguard Worker * Returns The called function's return value 85*344aa361SAndroid Build Coastguard Worker */ 86*344aa361SAndroid Build Coastguard WorkerFUNCTION(btitest_br) 87*344aa361SAndroid Build Coastguard Worker push lr, xzr 88*344aa361SAndroid Build Coastguard Worker bl get_callee 89*344aa361SAndroid Build Coastguard Worker pop lr, xzr 90*344aa361SAndroid Build Coastguard Worker br x0 91*344aa361SAndroid Build Coastguard Worker 92*344aa361SAndroid Build Coastguard Worker/** 93*344aa361SAndroid Build Coastguard Worker * int btitest_br_x16(int) - Use br to call the passed function via the x16 94*344aa361SAndroid Build Coastguard Worker * register 95*344aa361SAndroid Build Coastguard Worker * 96*344aa361SAndroid Build Coastguard Worker * Returns The called function's return value 97*344aa361SAndroid Build Coastguard Worker */ 98*344aa361SAndroid Build Coastguard WorkerFUNCTION(btitest_br_x16) 99*344aa361SAndroid Build Coastguard Worker push lr, xzr 100*344aa361SAndroid Build Coastguard Worker bl get_callee 101*344aa361SAndroid Build Coastguard Worker pop lr, xzr 102*344aa361SAndroid Build Coastguard Worker mov x16, x0 103*344aa361SAndroid Build Coastguard Worker br x16 104*344aa361SAndroid Build Coastguard Worker 105*344aa361SAndroid Build Coastguard Worker/** 106*344aa361SAndroid Build Coastguard Worker * int btitest_br_x17(int) - Use br to call the passed function via the x17 107*344aa361SAndroid Build Coastguard Worker * register 108*344aa361SAndroid Build Coastguard Worker * 109*344aa361SAndroid Build Coastguard Worker * Returns The called function's return value 110*344aa361SAndroid Build Coastguard Worker */ 111*344aa361SAndroid Build Coastguard WorkerFUNCTION(btitest_br_x17) 112*344aa361SAndroid Build Coastguard Worker push lr, xzr 113*344aa361SAndroid Build Coastguard Worker bl get_callee 114*344aa361SAndroid Build Coastguard Worker pop lr, xzr 115*344aa361SAndroid Build Coastguard Worker mov x17, x0 116*344aa361SAndroid Build Coastguard Worker br x17 117*344aa361SAndroid Build Coastguard Worker 118*344aa361SAndroid Build Coastguard Worker/** 119*344aa361SAndroid Build Coastguard Worker * int btitest_callee_nop(void) - Function with nop instruction 120*344aa361SAndroid Build Coastguard Worker * 121*344aa361SAndroid Build Coastguard Worker * Returns ERR_FAULT if the BTI check fails. 122*344aa361SAndroid Build Coastguard Worker * Return 0 if the BTI check passes. 123*344aa361SAndroid Build Coastguard Worker */ 124*344aa361SAndroid Build Coastguard WorkerLOCAL_FUNCTION(btitest_callee_nop) 125*344aa361SAndroid Build Coastguard Worker set_fault_handler .Lbtitest_callee_fault 126*344aa361SAndroid Build Coastguard Worker nop 127*344aa361SAndroid Build Coastguard Worker mov x0, #0 128*344aa361SAndroid Build Coastguard Worker ret 129*344aa361SAndroid Build Coastguard Worker 130*344aa361SAndroid Build Coastguard Worker/** 131*344aa361SAndroid Build Coastguard Worker * int btitest_callee_bti(void) - Function with bti instruction 132*344aa361SAndroid Build Coastguard Worker * 133*344aa361SAndroid Build Coastguard Worker * Returns ERR_FAULT if the BTI check fails. 134*344aa361SAndroid Build Coastguard Worker * Return 0 if the BTI check passes. 135*344aa361SAndroid Build Coastguard Worker */ 136*344aa361SAndroid Build Coastguard WorkerLOCAL_FUNCTION(btitest_callee_bti) 137*344aa361SAndroid Build Coastguard Worker set_fault_handler .Lbtitest_callee_fault 138*344aa361SAndroid Build Coastguard Worker bti 139*344aa361SAndroid Build Coastguard Worker mov x0, #0 140*344aa361SAndroid Build Coastguard Worker ret 141*344aa361SAndroid Build Coastguard Worker 142*344aa361SAndroid Build Coastguard Worker/** 143*344aa361SAndroid Build Coastguard Worker * int btitest_callee_bti_c(void) - Function with bti c instruction 144*344aa361SAndroid Build Coastguard Worker * 145*344aa361SAndroid Build Coastguard Worker * Returns ERR_FAULT if the BTI check fails. 146*344aa361SAndroid Build Coastguard Worker * Return 0 if the BTI check passes. 147*344aa361SAndroid Build Coastguard Worker */ 148*344aa361SAndroid Build Coastguard WorkerLOCAL_FUNCTION(btitest_callee_bti_c) 149*344aa361SAndroid Build Coastguard Worker set_fault_handler .Lbtitest_callee_fault 150*344aa361SAndroid Build Coastguard Worker bti c 151*344aa361SAndroid Build Coastguard Worker mov x0, #0 152*344aa361SAndroid Build Coastguard Worker ret 153*344aa361SAndroid Build Coastguard Worker 154*344aa361SAndroid Build Coastguard Worker/** 155*344aa361SAndroid Build Coastguard Worker * int btitest_callee_bti_j(void) - Function with bti j instruction 156*344aa361SAndroid Build Coastguard Worker * 157*344aa361SAndroid Build Coastguard Worker * Returns ERR_FAULT if the BTI check fails. 158*344aa361SAndroid Build Coastguard Worker * Return 0 if the BTI check passes. 159*344aa361SAndroid Build Coastguard Worker */ 160*344aa361SAndroid Build Coastguard WorkerLOCAL_FUNCTION(btitest_callee_bti_j) 161*344aa361SAndroid Build Coastguard Worker set_fault_handler .Lbtitest_callee_fault 162*344aa361SAndroid Build Coastguard Worker bti j 163*344aa361SAndroid Build Coastguard Worker mov x0, #0 164*344aa361SAndroid Build Coastguard Worker ret 165*344aa361SAndroid Build Coastguard Worker 166*344aa361SAndroid Build Coastguard Worker/** 167*344aa361SAndroid Build Coastguard Worker * int btitest_callee_bti_jc(void) - Function with bti jc instruction 168*344aa361SAndroid Build Coastguard Worker * 169*344aa361SAndroid Build Coastguard Worker * Returns ERR_FAULT if the BTI check fails. 170*344aa361SAndroid Build Coastguard Worker * Return 0 if the BTI check passes. 171*344aa361SAndroid Build Coastguard Worker */ 172*344aa361SAndroid Build Coastguard WorkerLOCAL_FUNCTION(btitest_callee_bti_jc) 173*344aa361SAndroid Build Coastguard Worker set_fault_handler .Lbtitest_callee_fault 174*344aa361SAndroid Build Coastguard Worker bti jc 175*344aa361SAndroid Build Coastguard Worker mov x0, #0 176*344aa361SAndroid Build Coastguard Worker ret 177*344aa361SAndroid Build Coastguard Worker 178*344aa361SAndroid Build Coastguard Worker/** 179*344aa361SAndroid Build Coastguard Worker * int btitest_callee_paciasp(void) - Function with paciasp instruction 180*344aa361SAndroid Build Coastguard Worker * 181*344aa361SAndroid Build Coastguard Worker * Returns ERR_FAULT if the BTI check fails. 182*344aa361SAndroid Build Coastguard Worker * Return 0 if the BTI check passes. 183*344aa361SAndroid Build Coastguard Worker */ 184*344aa361SAndroid Build Coastguard WorkerLOCAL_FUNCTION(btitest_callee_paciasp) 185*344aa361SAndroid Build Coastguard Worker set_fault_handler .Lbtitest_callee_fault 186*344aa361SAndroid Build Coastguard Worker paciasp 187*344aa361SAndroid Build Coastguard Worker mov x0, #0 188*344aa361SAndroid Build Coastguard Worker autiasp 189*344aa361SAndroid Build Coastguard Worker ret 190*344aa361SAndroid Build Coastguard Worker 191*344aa361SAndroid Build Coastguard Worker/** 192*344aa361SAndroid Build Coastguard Worker * int btitest_callee_pacibsp(void) - Function with pacibsp instruction 193*344aa361SAndroid Build Coastguard Worker * 194*344aa361SAndroid Build Coastguard Worker * Returns ERR_FAULT if the BTI check fails. 195*344aa361SAndroid Build Coastguard Worker * Return 0 if the BTI check passes. 196*344aa361SAndroid Build Coastguard Worker */ 197*344aa361SAndroid Build Coastguard WorkerLOCAL_FUNCTION(btitest_callee_pacibsp) 198*344aa361SAndroid Build Coastguard Worker set_fault_handler .Lbtitest_callee_fault 199*344aa361SAndroid Build Coastguard Worker pacibsp 200*344aa361SAndroid Build Coastguard Worker mov x0, #0 201*344aa361SAndroid Build Coastguard Worker autibsp 202*344aa361SAndroid Build Coastguard Worker ret 203*344aa361SAndroid Build Coastguard Worker 204*344aa361SAndroid Build Coastguard Worker/** 205*344aa361SAndroid Build Coastguard Worker * int btitest_callee_error(void) - Error function which always fails 206*344aa361SAndroid Build Coastguard Worker * 207*344aa361SAndroid Build Coastguard Worker * This is valid as any jump target. 208*344aa361SAndroid Build Coastguard Worker * 209*344aa361SAndroid Build Coastguard Worker * Returns ERR_INVALID_ARGS unconditionally. 210*344aa361SAndroid Build Coastguard Worker */ 211*344aa361SAndroid Build Coastguard WorkerLOCAL_FUNCTION(btitest_callee_error) 212*344aa361SAndroid Build Coastguard Worker bti jc 213*344aa361SAndroid Build Coastguard Worker mov x0, #ERR_INVALID_ARGS 214*344aa361SAndroid Build Coastguard Worker ret 215*344aa361SAndroid Build Coastguard Worker 216*344aa361SAndroid Build Coastguard Worker/** 217*344aa361SAndroid Build Coastguard Worker * get_callee(int) - Get the address of the callee function. 218*344aa361SAndroid Build Coastguard Worker * 219*344aa361SAndroid Build Coastguard Worker * Converts the passed function index into the function address. 220*344aa361SAndroid Build Coastguard Worker * This is done here to avoid using the C compiler to get function addresses - 221*344aa361SAndroid Build Coastguard Worker * the compiler may insert veneers or indirection under some situations (e.g. 222*344aa361SAndroid Build Coastguard Worker * for CFI) and break the specific landing pad instructions needed to test BTI. 223*344aa361SAndroid Build Coastguard Worker * 224*344aa361SAndroid Build Coastguard Worker * Return 0 if the index is not recognised, otherwise the function address. 225*344aa361SAndroid Build Coastguard Worker */ 226*344aa361SAndroid Build Coastguard WorkerLOCAL_FUNCTION(get_callee) 227*344aa361SAndroid Build Coastguard Worker cmp w0, #BTITEST_CALLEE_NOP 228*344aa361SAndroid Build Coastguard Worker bne .Ltry_bti 229*344aa361SAndroid Build Coastguard Worker adr x0, btitest_callee_nop 230*344aa361SAndroid Build Coastguard Worker ret 231*344aa361SAndroid Build Coastguard Worker.Ltry_bti: 232*344aa361SAndroid Build Coastguard Worker cmp w0, #BTITEST_CALLEE_BTI 233*344aa361SAndroid Build Coastguard Worker bne .Ltry_bti_c 234*344aa361SAndroid Build Coastguard Worker adr x0, btitest_callee_bti 235*344aa361SAndroid Build Coastguard Worker ret 236*344aa361SAndroid Build Coastguard Worker.Ltry_bti_c: 237*344aa361SAndroid Build Coastguard Worker cmp w0, #BTITEST_CALLEE_BTI_C 238*344aa361SAndroid Build Coastguard Worker bne .Ltry_bti_j 239*344aa361SAndroid Build Coastguard Worker adr x0, btitest_callee_bti_c 240*344aa361SAndroid Build Coastguard Worker ret 241*344aa361SAndroid Build Coastguard Worker.Ltry_bti_j: 242*344aa361SAndroid Build Coastguard Worker cmp w0, #BTITEST_CALLEE_BTI_J 243*344aa361SAndroid Build Coastguard Worker bne .Ltry_bti_jc 244*344aa361SAndroid Build Coastguard Worker adr x0, btitest_callee_bti_j 245*344aa361SAndroid Build Coastguard Worker ret 246*344aa361SAndroid Build Coastguard Worker.Ltry_bti_jc: 247*344aa361SAndroid Build Coastguard Worker cmp w0, #BTITEST_CALLEE_BTI_JC 248*344aa361SAndroid Build Coastguard Worker bne .Ltry_paciasp 249*344aa361SAndroid Build Coastguard Worker adr x0, btitest_callee_bti_jc 250*344aa361SAndroid Build Coastguard Worker ret 251*344aa361SAndroid Build Coastguard Worker.Ltry_paciasp: 252*344aa361SAndroid Build Coastguard Worker cmp w0, #BTITEST_CALLEE_PACIASP 253*344aa361SAndroid Build Coastguard Worker bne .Ltry_pacibsp 254*344aa361SAndroid Build Coastguard Worker adr x0, btitest_callee_paciasp 255*344aa361SAndroid Build Coastguard Worker ret 256*344aa361SAndroid Build Coastguard Worker.Ltry_pacibsp: 257*344aa361SAndroid Build Coastguard Worker cmp w0, #BTITEST_CALLEE_PACIBSP 258*344aa361SAndroid Build Coastguard Worker bne .Lunknown 259*344aa361SAndroid Build Coastguard Worker adr x0, btitest_callee_pacibsp 260*344aa361SAndroid Build Coastguard Worker ret 261*344aa361SAndroid Build Coastguard Worker.Lunknown: 262*344aa361SAndroid Build Coastguard Worker /* Return error function which unconditionally fails any test */ 263*344aa361SAndroid Build Coastguard Worker adr x0, btitest_callee_error 264*344aa361SAndroid Build Coastguard Worker ret 265