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