asan_rtl_x86_64.S 5.1 KB

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