checkasm.S 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. /****************************************************************************
  2. * Assembly testing and benchmarking tool
  3. * Copyright (c) 2015 Martin Storsjo
  4. * Copyright (c) 2015 Janne Grunau
  5. *
  6. * This file is part of FFmpeg.
  7. *
  8. * FFmpeg is free software; you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License as published by
  10. * the Free Software Foundation; either version 2 of the License, or
  11. * (at your option) any later version.
  12. *
  13. * FFmpeg is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program; if not, write to the Free Software
  20. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111, USA.
  21. *****************************************************************************/
  22. #include "libavutil/aarch64/asm.S"
  23. const register_init, align=4
  24. .quad 0x21f86d66c8ca00ce
  25. .quad 0x75b6ba21077c48ad
  26. .quad 0xed56bb2dcb3c7736
  27. .quad 0x8bda43d3fd1a7e06
  28. .quad 0xb64a9c9e5d318408
  29. .quad 0xdf9a54b303f1d3a3
  30. .quad 0x4a75479abd64e097
  31. .quad 0x249214109d5d1c88
  32. .quad 0x1a1b2550a612b48c
  33. .quad 0x79445c159ce79064
  34. .quad 0x2eed899d5a28ddcd
  35. .quad 0x86b2536fcd8cf636
  36. .quad 0xb0856806085e7943
  37. .quad 0x3f2bf84fc0fcca4e
  38. .quad 0xacbd382dcf5b8de2
  39. .quad 0xd229e1f5b281303f
  40. .quad 0x71aeaff20b095fd9
  41. .quad 0xab63e2e11fa38ed9
  42. endconst
  43. const error_message_register
  44. .asciz "failed to preserve register"
  45. error_message_stack:
  46. .asciz "stack clobbered"
  47. endconst
  48. // max number of args used by any asm function.
  49. #define MAX_ARGS 15
  50. #define CLOBBER_STACK ((8*MAX_ARGS + 15) & ~15)
  51. function checkasm_stack_clobber, export=1
  52. mov x3, sp
  53. mov x2, #CLOBBER_STACK
  54. 1:
  55. stp x0, x1, [sp, #-16]!
  56. subs x2, x2, #16
  57. b.gt 1b
  58. mov sp, x3
  59. ret
  60. endfunc
  61. // + 16 for stack canary reference
  62. #define ARG_STACK ((8*(MAX_ARGS - 8) + 15) & ~15 + 16)
  63. function checkasm_checked_call, export=1
  64. stp x29, x30, [sp, #-16]!
  65. mov x29, sp
  66. stp x19, x20, [sp, #-16]!
  67. stp x21, x22, [sp, #-16]!
  68. stp x23, x24, [sp, #-16]!
  69. stp x25, x26, [sp, #-16]!
  70. stp x27, x28, [sp, #-16]!
  71. stp d8, d9, [sp, #-16]!
  72. stp d10, d11, [sp, #-16]!
  73. stp d12, d13, [sp, #-16]!
  74. stp d14, d15, [sp, #-16]!
  75. movrel x9, register_init
  76. ldp d8, d9, [x9], #16
  77. ldp d10, d11, [x9], #16
  78. ldp d12, d13, [x9], #16
  79. ldp d14, d15, [x9], #16
  80. ldp x19, x20, [x9], #16
  81. ldp x21, x22, [x9], #16
  82. ldp x23, x24, [x9], #16
  83. ldp x25, x26, [x9], #16
  84. ldp x27, x28, [x9], #16
  85. sub sp, sp, #ARG_STACK
  86. .equ pos, 0
  87. .rept MAX_ARGS-8
  88. // Skip the first 8 args, that are loaded into registers
  89. ldr x9, [x29, #16 + 8*8 + pos]
  90. str x9, [sp, #pos]
  91. .equ pos, pos + 8
  92. .endr
  93. // Fill x8-x17 with garbage. This doesn't have to be preserved,
  94. // but avoids relying on them having any particular value.
  95. movrel x9, register_init
  96. ldp x10, x11, [x9], #32
  97. ldp x12, x13, [x9], #32
  98. ldp x14, x15, [x9], #32
  99. ldp x16, x17, [x9], #32
  100. ldp x8, x9, [x9]
  101. // For stack overflows, the callee is free to overwrite the parameters
  102. // that were passed on the stack (if any), so we can only check after
  103. // that point. First figure out how many parameters the function
  104. // really took on the stack:
  105. ldr w2, [x29, #16 + 8*8 + (MAX_ARGS-8)*8]
  106. // Load the first non-parameter value from the stack, that should be
  107. // left untouched by the function. Store a copy of it inverted, so that
  108. // e.g. overwriting everything with zero would be noticed.
  109. ldr x2, [sp, x2, lsl #3]
  110. mvn x2, x2
  111. str x2, [sp, #ARG_STACK-8]
  112. // Load the in-register arguments
  113. mov x12, x0
  114. ldp x0, x1, [x29, #16]
  115. ldp x2, x3, [x29, #32]
  116. ldp x4, x5, [x29, #48]
  117. ldp x6, x7, [x29, #64]
  118. // Call the target function
  119. blr x12
  120. // Load the number of stack parameters, stack canary and its reference
  121. ldr w2, [x29, #16 + 8*8 + (MAX_ARGS-8)*8]
  122. ldr x2, [sp, x2, lsl #3]
  123. ldr x3, [sp, #ARG_STACK-8]
  124. add sp, sp, #ARG_STACK
  125. stp x0, x1, [sp, #-16]!
  126. mvn x3, x3
  127. cmp x2, x3
  128. b.ne 2f
  129. movrel x9, register_init
  130. movi v3.8h, #0
  131. .macro check_reg_neon reg1, reg2
  132. ldr q1, [x9], #16
  133. uzp1 v2.2d, v\reg1\().2d, v\reg2\().2d
  134. eor v1.16b, v1.16b, v2.16b
  135. orr v3.16b, v3.16b, v1.16b
  136. .endm
  137. check_reg_neon 8, 9
  138. check_reg_neon 10, 11
  139. check_reg_neon 12, 13
  140. check_reg_neon 14, 15
  141. uqxtn v3.8b, v3.8h
  142. umov x3, v3.d[0]
  143. .macro check_reg reg1, reg2
  144. ldp x0, x1, [x9], #16
  145. eor x0, x0, \reg1
  146. eor x1, x1, \reg2
  147. orr x3, x3, x0
  148. orr x3, x3, x1
  149. .endm
  150. check_reg x19, x20
  151. check_reg x21, x22
  152. check_reg x23, x24
  153. check_reg x25, x26
  154. check_reg x27, x28
  155. cbz x3, 0f
  156. movrel x0, error_message_register
  157. b 1f
  158. 2:
  159. movrel x0, error_message_stack
  160. 1:
  161. bl X(checkasm_fail_func)
  162. 0:
  163. ldp x0, x1, [sp], #16
  164. ldp d14, d15, [sp], #16
  165. ldp d12, d13, [sp], #16
  166. ldp d10, d11, [sp], #16
  167. ldp d8, d9, [sp], #16
  168. ldp x27, x28, [sp], #16
  169. ldp x25, x26, [sp], #16
  170. ldp x23, x24, [sp], #16
  171. ldp x21, x22, [sp], #16
  172. ldp x19, x20, [sp], #16
  173. ldp x29, x30, [sp], #16
  174. ret
  175. endfunc