1#include "asan_mapping.h" 2#include "sanitizer_common/sanitizer_asm.h" 3 4#if defined(__x86_64__) 5#include "sanitizer_common/sanitizer_platform.h" 6 7.file "asan_rtl_x86_64.S" 8 9#define NAME(n, reg, op, s, i) n##_##op##_##i##_##s##_##reg 10 11#define FNAME(reg, op, s, i) NAME(__asan_check, reg, op, s, i) 12#define RLABEL(reg, op, s, i) NAME(.return, reg, op, s, i) 13#define CLABEL(reg, op, s, i) NAME(.check, reg, op, s, i) 14#define FLABEL(reg, op, s, i) NAME(.fail, reg, op, s, i) 15 16#define BEGINF(reg, op, s, i) \ 17.section .text.FNAME(reg, op, s, i),"ax",@progbits ;\ 18.globl FNAME(reg, op, s, i) ;\ 19.hidden FNAME(reg, op, s, i) ;\ 20ASM_TYPE_FUNCTION(FNAME(reg, op, s, i)) ;\ 21.cfi_startproc ;\ 22FNAME(reg, op, s, i): ;\ 23 24#define ENDF .cfi_endproc ;\ 25 26// Access check functions for 1,2 and 4 byte types, which require extra checks. 27#define ASAN_MEMORY_ACCESS_INITIAL_CHECK_ADD(reg, op, s) \ 28 mov %##reg,%r10 ;\ 29 shr $0x3,%r10 ;\ 30 .if ASAN_SHADOW_OFFSET_CONST < 0x80000000 ;\ 31 movsbl ASAN_SHADOW_OFFSET_CONST(%r10),%r10d ;\ 32 .else ;\ 33 movabsq $ASAN_SHADOW_OFFSET_CONST,%r11 ;\ 34 movsbl (%r10,%r11),%r10d ;\ 35 .endif ;\ 36 test %r10d,%r10d ;\ 37 jne CLABEL(reg, op, s, add) ;\ 38RLABEL(reg, op, s, add): ;\ 39 retq ;\ 40 41#define ASAN_MEMORY_ACCESS_EXTRA_CHECK_1(reg, op, i) \ 42CLABEL(reg, op, 1, i): ;\ 43 mov %##reg,%r11 ;\ 44 and $0x7,%r11d ;\ 45 cmp %r10d,%r11d ;\ 46 jl RLABEL(reg, op, 1, i);\ 47 mov %##reg,%rdi ;\ 48 jmp __asan_report_##op##1_asm ;\ 49 50#define ASAN_MEMORY_ACCESS_EXTRA_CHECK_2(reg, op, i) \ 51CLABEL(reg, op, 2, i): ;\ 52 mov %##reg,%r11 ;\ 53 and $0x7,%r11d ;\ 54 add $0x1,%r11d ;\ 55 cmp %r10d,%r11d ;\ 56 jl RLABEL(reg, op, 2, i);\ 57 mov %##reg,%rdi ;\ 58 jmp __asan_report_##op##2_asm ;\ 59 60#define ASAN_MEMORY_ACCESS_EXTRA_CHECK_4(reg, op, i) \ 61CLABEL(reg, op, 4, i): ;\ 62 mov %##reg,%r11 ;\ 63 and $0x7,%r11d ;\ 64 add $0x3,%r11d ;\ 65 cmp %r10d,%r11d ;\ 66 jl RLABEL(reg, op, 4, i);\ 67 mov %##reg,%rdi ;\ 68 jmp __asan_report_##op##4_asm ;\ 69 70#define ASAN_MEMORY_ACCESS_CALLBACK_ADD_1(reg, op) \ 71BEGINF(reg, op, 1, add) ;\ 72 ASAN_MEMORY_ACCESS_INITIAL_CHECK_ADD(reg, op, 1) ;\ 73 ASAN_MEMORY_ACCESS_EXTRA_CHECK_1(reg, op, add) ;\ 74ENDF 75 76#define ASAN_MEMORY_ACCESS_CALLBACK_ADD_2(reg, op) \ 77BEGINF(reg, op, 2, add) ;\ 78 ASAN_MEMORY_ACCESS_INITIAL_CHECK_ADD(reg, op, 2) ;\ 79 ASAN_MEMORY_ACCESS_EXTRA_CHECK_2(reg, op, add) ;\ 80ENDF 81 82#define ASAN_MEMORY_ACCESS_CALLBACK_ADD_4(reg, op) \ 83BEGINF(reg, op, 4, add) ;\ 84 ASAN_MEMORY_ACCESS_INITIAL_CHECK_ADD(reg, op, 4) ;\ 85 ASAN_MEMORY_ACCESS_EXTRA_CHECK_4(reg, op, add) ;\ 86ENDF 87 88// Access check functions for 8 and 16 byte types: no extra checks required. 89#define ASAN_MEMORY_ACCESS_CHECK_ADD(reg, op, s, c) \ 90 mov %##reg,%r10 ;\ 91 shr $0x3,%r10 ;\ 92 .if ASAN_SHADOW_OFFSET_CONST < 0x80000000 ;\ 93 ##c $0x0,ASAN_SHADOW_OFFSET_CONST(%r10) ;\ 94 .else ;\ 95 movabsq $ASAN_SHADOW_OFFSET_CONST,%r11 ;\ 96 ##c $0x0,(%r10,%r11) ;\ 97 .endif ;\ 98 jne FLABEL(reg, op, s, add) ;\ 99 retq ;\ 100 101#define ASAN_MEMORY_ACCESS_FAIL(reg, op, s, i) \ 102FLABEL(reg, op, s, i): ;\ 103 mov %##reg,%rdi ;\ 104 jmp __asan_report_##op##s##_asm;\ 105 106#define ASAN_MEMORY_ACCESS_CALLBACK_ADD_8(reg, op) \ 107BEGINF(reg, op, 8, add) ;\ 108 ASAN_MEMORY_ACCESS_CHECK_ADD(reg, op, 8, cmpb) ;\ 109 ASAN_MEMORY_ACCESS_FAIL(reg, op, 8, add) ;\ 110ENDF 111 112#define ASAN_MEMORY_ACCESS_CALLBACK_ADD_16(reg, op) \ 113BEGINF(reg, op, 16, add) ;\ 114 ASAN_MEMORY_ACCESS_CHECK_ADD(reg, op, 16, cmpw) ;\ 115 ASAN_MEMORY_ACCESS_FAIL(reg, op, 16, add) ;\ 116ENDF 117 118#define ASAN_MEMORY_ACCESS_CALLBACKS_ADD(reg) \ 119ASAN_MEMORY_ACCESS_CALLBACK_ADD_1(reg, load) \ 120ASAN_MEMORY_ACCESS_CALLBACK_ADD_1(reg, store) \ 121ASAN_MEMORY_ACCESS_CALLBACK_ADD_2(reg, load) \ 122ASAN_MEMORY_ACCESS_CALLBACK_ADD_2(reg, store) \ 123ASAN_MEMORY_ACCESS_CALLBACK_ADD_4(reg, load) \ 124ASAN_MEMORY_ACCESS_CALLBACK_ADD_4(reg, store) \ 125ASAN_MEMORY_ACCESS_CALLBACK_ADD_8(reg, load) \ 126ASAN_MEMORY_ACCESS_CALLBACK_ADD_8(reg, store) \ 127ASAN_MEMORY_ACCESS_CALLBACK_ADD_16(reg, load) \ 128ASAN_MEMORY_ACCESS_CALLBACK_ADD_16(reg, store) \ 129 130 131// Instantiate all but R10 and R11 callbacks. We are using PLTSafe class with 132// the intrinsic, which guarantees that the code generation will never emit 133// R10 or R11 callback. 134ASAN_MEMORY_ACCESS_CALLBACKS_ADD(RAX) 135ASAN_MEMORY_ACCESS_CALLBACKS_ADD(RBX) 136ASAN_MEMORY_ACCESS_CALLBACKS_ADD(RCX) 137ASAN_MEMORY_ACCESS_CALLBACKS_ADD(RDX) 138ASAN_MEMORY_ACCESS_CALLBACKS_ADD(RSI) 139ASAN_MEMORY_ACCESS_CALLBACKS_ADD(RDI) 140ASAN_MEMORY_ACCESS_CALLBACKS_ADD(RBP) 141ASAN_MEMORY_ACCESS_CALLBACKS_ADD(R8) 142ASAN_MEMORY_ACCESS_CALLBACKS_ADD(R9) 143ASAN_MEMORY_ACCESS_CALLBACKS_ADD(R12) 144ASAN_MEMORY_ACCESS_CALLBACKS_ADD(R13) 145ASAN_MEMORY_ACCESS_CALLBACKS_ADD(R14) 146ASAN_MEMORY_ACCESS_CALLBACKS_ADD(R15) 147 148#endif 149 150NO_EXEC_STACK_DIRECTIVE 151