You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

210 lines
6.0 KiB

  1. #!/usr/bin/env perl
  2. # Copyright (c) 2019, Google Inc.
  3. #
  4. # Permission to use, copy, modify, and/or distribute this software for any
  5. # purpose with or without fee is hereby granted, provided that the above
  6. # copyright notice and this permission notice appear in all copies.
  7. #
  8. # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  9. # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  10. # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
  11. # SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  12. # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
  13. # OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
  14. # CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  15. # This file defines helper functions for crypto/test/abi_test.h on aarch64. See
  16. # that header for details on how to use this.
  17. #
  18. # For convenience, this file is linked into libcrypto, where consuming builds
  19. # already support architecture-specific sources. The static linker should drop
  20. # this code in non-test binaries. This includes a shared library build of
  21. # libcrypto, provided --gc-sections (ELF), -dead_strip (iOS), or equivalent is
  22. # used.
  23. #
  24. # References:
  25. #
  26. # AAPCS64: http://infocenter.arm.com/help/topic/com.arm.doc.ihi0055b/IHI0055B_aapcs64.pdf
  27. # iOS ARM64: https://developer.apple.com/library/archive/documentation/Xcode/Conceptual/iPhoneOSABIReference/Articles/ARM64FunctionCallingConventions.html
  28. use strict;
  29. my $flavour = shift;
  30. my $output = shift;
  31. if ($flavour =~ /\./) { $output = $flavour; undef $flavour; }
  32. $0 =~ m/(.*[\/\\])[^\/\\]+$/;
  33. my $dir = $1;
  34. my $xlate;
  35. ( $xlate="${dir}arm-xlate.pl" and -f $xlate ) or
  36. ( $xlate="${dir}../../perlasm/arm-xlate.pl" and -f $xlate) or
  37. die "can't locate arm-xlate.pl";
  38. open OUT, "| \"$^X\" \"$xlate\" $flavour \"$output\"";
  39. *STDOUT = *OUT;
  40. my ($func, $state, $argv, $argc) = ("x0", "x1", "x2", "x3");
  41. my $code = <<____;
  42. .text
  43. // abi_test_trampoline loads callee-saved registers from |state|, calls |func|
  44. // with |argv|, then saves the callee-saved registers into |state|. It returns
  45. // the result of |func|. The |unwind| argument is unused.
  46. // uint64_t abi_test_trampoline(void (*func)(...), CallerState *state,
  47. // const uint64_t *argv, size_t argc,
  48. // uint64_t unwind);
  49. .type abi_test_trampoline, %function
  50. .globl abi_test_trampoline
  51. .align 4
  52. abi_test_trampoline:
  53. .Labi_test_trampoline_begin:
  54. // Stack layout (low to high addresses)
  55. // x29,x30 (16 bytes)
  56. // d8-d15 (64 bytes)
  57. // x19-x28 (80 bytes)
  58. // $state (8 bytes)
  59. // padding (8 bytes)
  60. stp x29, x30, [sp, #-176]!
  61. mov x29, sp
  62. // Saved callee-saved registers and |state|.
  63. stp d8, d9, [sp, #16]
  64. stp d10, d11, [sp, #32]
  65. stp d12, d13, [sp, #48]
  66. stp d14, d15, [sp, #64]
  67. stp x19, x20, [sp, #80]
  68. stp x21, x22, [sp, #96]
  69. stp x23, x24, [sp, #112]
  70. stp x25, x26, [sp, #128]
  71. stp x27, x28, [sp, #144]
  72. str $state, [sp, #160]
  73. // Load registers from |state|, with the exception of x29. x29 is the
  74. // frame pointer and also callee-saved, but AAPCS64 allows platforms to
  75. // mandate that x29 always point to a frame. iOS64 does so, which means
  76. // we cannot fill x29 with entropy without violating ABI rules
  77. // ourselves. x29 is tested separately below.
  78. ldp d8, d9, [$state], #16
  79. ldp d10, d11, [$state], #16
  80. ldp d12, d13, [$state], #16
  81. ldp d14, d15, [$state], #16
  82. ldp x19, x20, [$state], #16
  83. ldp x21, x22, [$state], #16
  84. ldp x23, x24, [$state], #16
  85. ldp x25, x26, [$state], #16
  86. ldp x27, x28, [$state], #16
  87. // Move parameters into temporary registers.
  88. mov x9, $func
  89. mov x10, $argv
  90. mov x11, $argc
  91. // Load parameters into registers.
  92. cbz x11, .Largs_done
  93. ldr x0, [x10], #8
  94. subs x11, x11, #1
  95. b.eq .Largs_done
  96. ldr x1, [x10], #8
  97. subs x11, x11, #1
  98. b.eq .Largs_done
  99. ldr x2, [x10], #8
  100. subs x11, x11, #1
  101. b.eq .Largs_done
  102. ldr x3, [x10], #8
  103. subs x11, x11, #1
  104. b.eq .Largs_done
  105. ldr x4, [x10], #8
  106. subs x11, x11, #1
  107. b.eq .Largs_done
  108. ldr x5, [x10], #8
  109. subs x11, x11, #1
  110. b.eq .Largs_done
  111. ldr x6, [x10], #8
  112. subs x11, x11, #1
  113. b.eq .Largs_done
  114. ldr x7, [x10], #8
  115. .Largs_done:
  116. blr x9
  117. // Reload |state| and store registers.
  118. ldr $state, [sp, #160]
  119. stp d8, d9, [$state], #16
  120. stp d10, d11, [$state], #16
  121. stp d12, d13, [$state], #16
  122. stp d14, d15, [$state], #16
  123. stp x19, x20, [$state], #16
  124. stp x21, x22, [$state], #16
  125. stp x23, x24, [$state], #16
  126. stp x25, x26, [$state], #16
  127. stp x27, x28, [$state], #16
  128. // |func| is required to preserve x29, the frame pointer. We cannot load
  129. // random values into x29 (see comment above), so compare it against the
  130. // expected value and zero the field of |state| if corrupted.
  131. mov x9, sp
  132. cmp x29, x9
  133. b.eq .Lx29_ok
  134. str xzr, [$state]
  135. .Lx29_ok:
  136. // Restore callee-saved registers.
  137. ldp d8, d9, [sp, #16]
  138. ldp d10, d11, [sp, #32]
  139. ldp d12, d13, [sp, #48]
  140. ldp d14, d15, [sp, #64]
  141. ldp x19, x20, [sp, #80]
  142. ldp x21, x22, [sp, #96]
  143. ldp x23, x24, [sp, #112]
  144. ldp x25, x26, [sp, #128]
  145. ldp x27, x28, [sp, #144]
  146. ldp x29, x30, [sp], #176
  147. ret
  148. .size abi_test_trampoline,.-abi_test_trampoline
  149. ____
  150. # abi_test_clobber_* zeros the corresponding register. These are used to test
  151. # the ABI-testing framework.
  152. foreach (0..29) {
  153. # x18 is the platform register and off limits.
  154. next if ($_ == 18);
  155. $code .= <<____;
  156. .type abi_test_clobber_x$_, %function
  157. .globl abi_test_clobber_x$_
  158. .align 4
  159. abi_test_clobber_x$_:
  160. mov x$_, xzr
  161. ret
  162. .size abi_test_clobber_x$_,.-abi_test_clobber_x$_
  163. ____
  164. }
  165. foreach (0..31) {
  166. $code .= <<____;
  167. .type abi_test_clobber_d$_, %function
  168. .globl abi_test_clobber_d$_
  169. .align 4
  170. abi_test_clobber_d$_:
  171. fmov d$_, xzr
  172. ret
  173. .size abi_test_clobber_d$_,.-abi_test_clobber_d$_
  174. ____
  175. }
  176. # abi_test_clobber_v*_upper clobbers only the upper half of v*. AAPCS64 only
  177. # requires the lower half (d*) be preserved.
  178. foreach (8..15) {
  179. $code .= <<____;
  180. .type abi_test_clobber_v${_}_upper, %function
  181. .globl abi_test_clobber_v${_}_upper
  182. .align 4
  183. abi_test_clobber_v${_}_upper:
  184. fmov v${_}.d[1], xzr
  185. ret
  186. .size abi_test_clobber_v${_}_upper,.-abi_test_clobber_v${_}_upper
  187. ____
  188. }
  189. print $code;
  190. close STDOUT;