123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146 |
- #include "asan_mapping.h"
- #include "sanitizer_common/sanitizer_asm.h"
- #if defined(__x86_64__)
- #include "sanitizer_common/sanitizer_platform.h"
- .section .text
- .file "asan_rtl_x86_64.S"
- #define NAME(n, reg, op, s, i) n##_##op##_##i##_##s##_##reg
- #define FNAME(reg, op, s, i) NAME(__asan_check, reg, op, s, i)
- #define RLABEL(reg, op, s, i) NAME(.return, reg, op, s, i)
- #define CLABEL(reg, op, s, i) NAME(.check, reg, op, s, i)
- #define FLABEL(reg, op, s, i) NAME(.fail, reg, op, s, i)
- #define BEGINF(reg, op, s, i) \
- .globl FNAME(reg, op, s, i) ;\
- .hidden FNAME(reg, op, s, i) ;\
- ASM_TYPE_FUNCTION(FNAME(reg, op, s, i)) ;\
- .cfi_startproc ;\
- FNAME(reg, op, s, i): ;\
- #define ENDF .cfi_endproc ;\
- // Access check functions for 1,2 and 4 byte types, which require extra checks.
- #define ASAN_MEMORY_ACCESS_INITIAL_CHECK_ADD(reg, op, s) \
- mov %##reg,%r10 ;\
- shr $0x3,%r10 ;\
- movsbl ASAN_SHADOW_OFFSET_CONST(%r10),%r10d ;\
- test %r10d,%r10d ;\
- jne CLABEL(reg, op, s, add) ;\
- RLABEL(reg, op, s, add): ;\
- retq ;\
- #define ASAN_MEMORY_ACCESS_EXTRA_CHECK_1(reg, op, i) \
- CLABEL(reg, op, 1, i): ;\
- push %rcx ;\
- mov %##reg,%rcx ;\
- and $0x7,%ecx ;\
- cmp %r10d,%ecx ;\
- pop %rcx ;\
- jl RLABEL(reg, op, 1, i);\
- mov %##reg,%rdi ;\
- jmp __asan_report_##op##1@PLT ;\
- #define ASAN_MEMORY_ACCESS_EXTRA_CHECK_2(reg, op, i) \
- CLABEL(reg, op, 2, i): ;\
- push %rcx ;\
- mov %##reg,%rcx ;\
- and $0x7,%ecx ;\
- add $0x1,%ecx ;\
- cmp %r10d,%ecx ;\
- pop %rcx ;\
- jl RLABEL(reg, op, 2, i);\
- mov %##reg,%rdi ;\
- jmp __asan_report_##op##2@PLT ;\
- #define ASAN_MEMORY_ACCESS_EXTRA_CHECK_4(reg, op, i) \
- CLABEL(reg, op, 4, i): ;\
- push %rcx ;\
- mov %##reg,%rcx ;\
- and $0x7,%ecx ;\
- add $0x3,%ecx ;\
- cmp %r10d,%ecx ;\
- pop %rcx ;\
- jl RLABEL(reg, op, 4, i);\
- mov %##reg,%rdi ;\
- jmp __asan_report_##op##4@PLT ;\
- #define ASAN_MEMORY_ACCESS_CALLBACK_ADD_1(reg, op) \
- BEGINF(reg, op, 1, add) ;\
- ASAN_MEMORY_ACCESS_INITIAL_CHECK_ADD(reg, op, 1) ;\
- ASAN_MEMORY_ACCESS_EXTRA_CHECK_1(reg, op, add) ;\
- ENDF
- #define ASAN_MEMORY_ACCESS_CALLBACK_ADD_2(reg, op) \
- BEGINF(reg, op, 2, add) ;\
- ASAN_MEMORY_ACCESS_INITIAL_CHECK_ADD(reg, op, 2) ;\
- ASAN_MEMORY_ACCESS_EXTRA_CHECK_2(reg, op, add) ;\
- ENDF
- #define ASAN_MEMORY_ACCESS_CALLBACK_ADD_4(reg, op) \
- BEGINF(reg, op, 4, add) ;\
- ASAN_MEMORY_ACCESS_INITIAL_CHECK_ADD(reg, op, 4) ;\
- ASAN_MEMORY_ACCESS_EXTRA_CHECK_4(reg, op, add) ;\
- ENDF
- // Access check functions for 8 and 16 byte types: no extra checks required.
- #define ASAN_MEMORY_ACCESS_CHECK_ADD(reg, op, s, c) \
- mov %##reg,%r10 ;\
- shr $0x3,%r10 ;\
- ##c $0x0,ASAN_SHADOW_OFFSET_CONST(%r10) ;\
- jne FLABEL(reg, op, s, add) ;\
- retq ;\
- #define ASAN_MEMORY_ACCESS_FAIL(reg, op, s, i) \
- FLABEL(reg, op, s, i): ;\
- mov %##reg,%rdi ;\
- jmp __asan_report_##op##s@PLT;\
- #define ASAN_MEMORY_ACCESS_CALLBACK_ADD_8(reg, op) \
- BEGINF(reg, op, 8, add) ;\
- ASAN_MEMORY_ACCESS_CHECK_ADD(reg, op, 8, cmpb) ;\
- ASAN_MEMORY_ACCESS_FAIL(reg, op, 8, add) ;\
- ENDF
- #define ASAN_MEMORY_ACCESS_CALLBACK_ADD_16(reg, op) \
- BEGINF(reg, op, 16, add) ;\
- ASAN_MEMORY_ACCESS_CHECK_ADD(reg, op, 16, cmpw) ;\
- ASAN_MEMORY_ACCESS_FAIL(reg, op, 16, add) ;\
- ENDF
- #define ASAN_MEMORY_ACCESS_CALLBACKS_ADD(reg) \
- ASAN_MEMORY_ACCESS_CALLBACK_ADD_1(reg, load) \
- ASAN_MEMORY_ACCESS_CALLBACK_ADD_1(reg, store) \
- ASAN_MEMORY_ACCESS_CALLBACK_ADD_2(reg, load) \
- ASAN_MEMORY_ACCESS_CALLBACK_ADD_2(reg, store) \
- ASAN_MEMORY_ACCESS_CALLBACK_ADD_4(reg, load) \
- ASAN_MEMORY_ACCESS_CALLBACK_ADD_4(reg, store) \
- ASAN_MEMORY_ACCESS_CALLBACK_ADD_8(reg, load) \
- ASAN_MEMORY_ACCESS_CALLBACK_ADD_8(reg, store) \
- ASAN_MEMORY_ACCESS_CALLBACK_ADD_16(reg, load) \
- ASAN_MEMORY_ACCESS_CALLBACK_ADD_16(reg, store) \
- // Instantiate all but R10 and R11 callbacks. We are using PLTSafe class with
- // the intrinsic, which guarantees that the code generation will never emit
- // R10 or R11 callback.
- ASAN_MEMORY_ACCESS_CALLBACKS_ADD(RAX)
- ASAN_MEMORY_ACCESS_CALLBACKS_ADD(RBX)
- ASAN_MEMORY_ACCESS_CALLBACKS_ADD(RCX)
- ASAN_MEMORY_ACCESS_CALLBACKS_ADD(RDX)
- ASAN_MEMORY_ACCESS_CALLBACKS_ADD(RSI)
- ASAN_MEMORY_ACCESS_CALLBACKS_ADD(RDI)
- ASAN_MEMORY_ACCESS_CALLBACKS_ADD(RBP)
- ASAN_MEMORY_ACCESS_CALLBACKS_ADD(R8)
- ASAN_MEMORY_ACCESS_CALLBACKS_ADD(R9)
- ASAN_MEMORY_ACCESS_CALLBACKS_ADD(R12)
- ASAN_MEMORY_ACCESS_CALLBACKS_ADD(R13)
- ASAN_MEMORY_ACCESS_CALLBACKS_ADD(R14)
- ASAN_MEMORY_ACCESS_CALLBACKS_ADD(R15)
- #endif
- NO_EXEC_STACK_DIRECTIVE
|