1#include "sanitizer_common/sanitizer_asm.h" 2 3// The content of this file is RISCV64-only: 4#if defined(__riscv) && (__riscv_xlen == 64) 5 6// The responsibility of the HWASan entry point in compiler-rt is to primarily 7// readjust the stack from the callee and save the current register values to 8// the stack. 9// This entry point function should be called from a __hwasan_check_* symbol. 10// These are generated during a lowering pass in the backend, and are found in 11// RISCVAsmPrinter::EmitHwasanMemaccessSymbols(). Please look there for 12// further information. 13// The __hwasan_check_* caller of this function should have expanded the stack 14// and saved the previous values of x10(arg0), x11(arg1), x1(ra), and x8(fp). 15// This function will "consume" these saved values and treats it as part of its 16// own stack frame. In this sense, the __hwasan_check_* callee and this function 17// "share" a stack frame. This allows us to omit having unwinding information 18// (.cfi_*) present in every __hwasan_check_* function, therefore reducing binary size. 19// This is particularly important as hwasan_check_* instances are duplicated in every 20// translation unit where HWASan is enabled. 21// This function calls HwasanTagMismatch to step back into the C++ code that 22// completes the stack unwinding and error printing. This function is is not 23// permitted to return. 24 25 26// | ... | 27// | ... | 28// | Previous stack frames... | 29// +=================================+ 30// | ... | 31// | | 32// | Stack frame space for x12 - x31.| 33// | | 34// | ... | 35// +---------------------------------+ <-- [SP + 96] 36// | Saved x11(arg1), as | 37// | __hwasan_check_* clobbers it. | 38// +---------------------------------+ <-- [SP + 88] 39// | Saved x10(arg0), as | 40// | __hwasan_check_* clobbers it. | 41// +---------------------------------+ <-- [SP + 80] 42// | | 43// | Stack frame space for x9. | 44// +---------------------------------+ <-- [SP + 72] 45// | | 46// | Saved x8(fp), as | 47// | __hwasan_check_* clobbers it. | 48// +---------------------------------+ <-- [SP + 64] 49// | ... | 50// | | 51// | Stack frame space for x2 - x7. | 52// | | 53// | ... | 54// +---------------------------------+ <-- [SP + 16] 55// | Return address (x1) for caller | 56// | of __hwasan_check_*. | 57// +---------------------------------+ <-- [SP + 8] 58// | Reserved place for x0, possibly | 59// | junk, since we don't save it. | 60// +---------------------------------+ <-- [x2 / SP] 61 62// This function takes two arguments: 63// * x10/a0: The data address. 64// * x11/a1: The encoded access info for the failing access. 65 66.section .text 67.file "hwasan_tag_mismatch_riscv64.S" 68 69.global __hwasan_tag_mismatch_v2 70ASM_TYPE_FUNCTION(__hwasan_tag_mismatch_v2) 71__hwasan_tag_mismatch_v2: 72 CFI_STARTPROC 73 74 // Set the CFA to be the return address for caller of __hwasan_check_*. Note 75 // that we do not emit CFI predicates to describe the contents of this stack 76 // frame, as this proxy entry point should never be debugged. The contents 77 // are static and are handled by the unwinder after calling 78 // __hwasan_tag_mismatch. The frame pointer is already correctly setup 79 // by __hwasan_check_*. 80 addi fp, sp, 256 81 CFI_DEF_CFA(fp, 0) 82 CFI_OFFSET(ra, -248) 83 CFI_OFFSET(fp, -192) 84 85 // Save the rest of the registers into the preallocated space left by 86 // __hwasan_check. 87 sd x31, 248(sp) 88 sd x30, 240(sp) 89 sd x29, 232(sp) 90 sd x28, 224(sp) 91 sd x27, 216(sp) 92 sd x26, 208(sp) 93 sd x25, 200(sp) 94 sd x24, 192(sp) 95 sd x23, 184(sp) 96 sd x22, 176(sp) 97 sd x21, 168(sp) 98 sd x20, 160(sp) 99 sd x19, 152(sp) 100 sd x18, 144(sp) 101 sd x17, 136(sp) 102 sd x16, 128(sp) 103 sd x15, 120(sp) 104 sd x14, 112(sp) 105 sd x13, 104(sp) 106 sd x12, 96(sp) 107 // sd x11, 88(sp) ; already saved 108 // sd x10, 80(sp) ; already saved 109 sd x9, 72(sp) 110 // sd x8, 64(sp) ; already saved 111 sd x7, 56(sp) 112 sd x6, 48(sp) 113 sd x5, 40(sp) 114 sd x4, 32(sp) 115 sd x3, 24(sp) 116 sd x2, 16(sp) 117 // sd x1, 8(sp) ; already saved 118 // sd x0, 0(sp) ; don't store zero register 119 120 // Pass the address of the frame to __hwasan_tag_mismatch4, so that it can 121 // extract the saved registers from this frame without having to worry about 122 // finding this frame. 123 mv x12, sp 124 125 call __hwasan_tag_mismatch4 126 CFI_ENDPROC 127ASM_SIZE(__hwasan_tag_mismatch_v2) 128 129#endif // defined(__riscv) && (__riscv_xlen == 64) 130 131// We do not need executable stack. 132NO_EXEC_STACK_DIRECTIVE 133