1/* 2 * Copyright (c) 2024 CISPA Helmholtz Center for Information Security 3 * 4 * SPDX-License-Identifier: Apache-2.0 5 */ 6 7#include <zephyr/toolchain.h> 8 9GTEXT(_riscv_edge_case_cb_trigger_backward) 10 11/* 12 * Tests that jumping 256 bytes (the maximum) backwards 13 * using CB-type instruction is feasible 14 */ 15SECTION_FUNC(TEXT, _riscv_edge_case_cb_trigger_backward) 16 /* 17 * tentative fail 18 * this needs precise alignment - need explicit compressed instructions 19 */ 20 addi a0, zero, 0 21 c.j _do_jump 22 23_backward_jump_target: 24 25 /* 26 * we need to force RISC-V compressed instructions for alignment 27 * this directive is standard in RISC-V, i.e., not toolchain-specific 28 */ 29 .option push 30 .option rvc 31 32 /* we made it to the correct target - success, return true */ 33 c.addi a0, 0x1 34 /* explicit compressed return */ 35 c.jr ra 36 37 38 /* 39 * we need a distance of 256 bytes between _do_jump and _backward_jump_target to trigger 40 * the edge case (max jump distance for c.beqz) 41 * _backward_jump_target itself needs 4 bytes (two compressed instructions) 42 * so we need to insert 252 additional padding bytes 43 * we pad with return instructions here, causing the test to return 0 (failure) 44 */ 45 .rept 126 46 /* explicit compressed return - 2 bytes */ 47 c.jr ra 48 .endr 49 50_do_jump: 51 /* jump precisely 256 bytes, the maximum distance, backwards */ 52 c.beqz a0, _backward_jump_target 53 54 /* 55 * in case we erroneously jump FORWARD instead of backwards, 56 * the jump ends in the following return sled and we return 0 57 * this indicates test failure 58 * note that maximum distance for jump forwards is 254 bytes, 59 * which is also the size of this sled 60 */ 61 .rept 127 62 /* explicit compressed return - 2 bytes */ 63 c.jr ra 64 .endr 65 66 /* assembler can decide whether to emit compressed instructions */ 67 .option pop 68 69GTEXT(_riscv_edge_case_cb_trigger_forward) 70 71/* 72 * Tests that jumping 256 bytes (the maximum) forwards 73 * using CB-type instruction is feasible 74 */ 75SECTION_FUNC(TEXT, _riscv_edge_case_cb_trigger_forward) 76 j _test_start 77 78 /* we need to force RISC-V compressed instructions for alignment */ 79 .option push 80 .option rvc 81 82 /* 83 * in case the relocation is incorrect and the c.beqz jumps BACKWARDS, 84 * e.g., after arithmetic overflow, we jump into the following return sled 85 * the return sled is 256 bytes long, covering the maximum backward jump 86 */ 87 .rept 128 88 /* explicit compressed return - 2 bytes */ 89 c.jr ra 90 .endr 91 92_test_start: 93 /* tentative fail */ 94 addi a0, zero, 0 95 96 /* 97 * jump precisely 254 bytes, the maximum distance, forwards 98 * in case the relocation is applied incorrectly, we jump into the padding bytes 99 * this causes test failure 100 * we cannot jump too far forwards, 254 bytes is the maximum distance 101 */ 102 c.beqz a0, _forward_jump_target 103 104 /* 105 * need to insert 252 padding bytes to pad to 254 byte jump 106 * we pad with return instructions here, causing the test to return 0 (failure) 107 */ 108 .rept 126 109 /* explicit compressed return - 2 bytes */ 110 c.jr ra 111 .endr 112 113 /* assembler can decide whether to emit compressed instructions */ 114 .option pop 115 116_forward_jump_target: 117 /* we made it to the correct target - success, return true */ 118 li a0, 1 119 /* should not be reached - causes return false */ 120 ret 121