vdso.S 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. /*
  2. * arm linux replacement vdso.
  3. *
  4. * Copyright 2023 Linaro, Ltd.
  5. *
  6. * SPDX-License-Identifier: GPL-2.0-or-later
  7. */
  8. #include <asm/unistd.h>
  9. #include "vdso-asmoffset.h"
  10. /*
  11. * All supported cpus have T16 instructions: at least arm4t.
  12. *
  13. * We support user-user with m-profile cpus as an extension, because it
  14. * is useful for testing gcc, which requires we avoid A32 instructions.
  15. */
  16. .thumb
  17. .arch armv4t
  18. .eabi_attribute Tag_FP_arch, 0
  19. .eabi_attribute Tag_ARM_ISA_use, 0
  20. .text
  21. .macro raw_syscall n
  22. .ifne \n < 0x100
  23. mov r7, #\n
  24. .elseif \n < 0x1ff
  25. mov r7, #0xff
  26. add r7, #(\n - 0xff)
  27. .else
  28. .err
  29. .endif
  30. swi #0
  31. .endm
  32. .macro fdpic_thunk ofs
  33. ldr r3, [sp, #\ofs]
  34. ldmia r2, {r2, r3}
  35. mov r9, r3
  36. bx r2
  37. .endm
  38. .macro endf name
  39. .globl \name
  40. .type \name, %function
  41. .size \name, . - \name
  42. .endm
  43. /*
  44. * We must save/restore r7 for the EABI syscall number.
  45. * While we're doing that, we might as well save LR to get a free return,
  46. * and a branch that is interworking back to ARMv5.
  47. */
  48. .macro SYSCALL name, nr
  49. \name:
  50. .cfi_startproc
  51. push {r7, lr}
  52. .cfi_adjust_cfa_offset 8
  53. .cfi_offset r7, -8
  54. .cfi_offset lr, -4
  55. raw_syscall \nr
  56. pop {r7, pc}
  57. .cfi_endproc
  58. endf \name
  59. .endm
  60. SYSCALL __vdso_clock_gettime, __NR_clock_gettime
  61. SYSCALL __vdso_clock_gettime64, __NR_clock_gettime64
  62. SYSCALL __vdso_clock_getres, __NR_clock_getres
  63. SYSCALL __vdso_gettimeofday, __NR_gettimeofday
  64. /*
  65. * We, like the real kernel, use a table of sigreturn trampolines.
  66. * Unlike the real kernel, we do not attempt to pack this into as
  67. * few bytes as possible -- simply use 8 bytes per slot.
  68. *
  69. * Within each slot, use the exact same code sequence as the kernel,
  70. * lest we trip up someone doing code inspection.
  71. */
  72. .macro slot n
  73. .balign 8
  74. .org sigreturn_codes + 8 * \n
  75. .endm
  76. .macro cfi_fdpic_r9 ofs
  77. /*
  78. * fd = *(r13 + ofs)
  79. * r9 = *(fd + 4)
  80. *
  81. * DW_CFA_expression r9, length (7),
  82. * DW_OP_breg13, ofs, DW_OP_deref,
  83. * DW_OP_plus_uconst, 4, DW_OP_deref
  84. */
  85. .cfi_escape 0x10, 9, 7, 0x7d, (\ofs & 0x7f) + 0x80, (\ofs >> 7), 0x06, 0x23, 4, 0x06
  86. .endm
  87. .macro cfi_fdpic_pc ofs
  88. /*
  89. * fd = *(r13 + ofs)
  90. * pc = *fd
  91. *
  92. * DW_CFA_expression lr (14), length (5),
  93. * DW_OP_breg13, ofs, DW_OP_deref, DW_OP_deref
  94. */
  95. .cfi_escape 0x10, 14, 5, 0x7d, (\ofs & 0x7f) + 0x80, (\ofs >> 7), 0x06, 0x06
  96. .endm
  97. /*
  98. * Start the unwind info at least one instruction before the signal
  99. * trampoline, because the unwinder will assume we are returning
  100. * after a call site.
  101. */
  102. .cfi_startproc simple
  103. .cfi_signal_frame
  104. .cfi_return_column 15
  105. .cfi_def_cfa sp, 32 + 64
  106. .cfi_offset r0, -16 * 4
  107. .cfi_offset r1, -15 * 4
  108. .cfi_offset r2, -14 * 4
  109. .cfi_offset r3, -13 * 4
  110. .cfi_offset r4, -12 * 4
  111. .cfi_offset r5, -11 * 4
  112. .cfi_offset r6, -10 * 4
  113. .cfi_offset r7, -9 * 4
  114. .cfi_offset r8, -8 * 4
  115. .cfi_offset r9, -7 * 4
  116. .cfi_offset r10, -6 * 4
  117. .cfi_offset r11, -5 * 4
  118. .cfi_offset r12, -4 * 4
  119. .cfi_offset r13, -3 * 4
  120. .cfi_offset r14, -2 * 4
  121. .cfi_offset r15, -1 * 4
  122. nop
  123. .balign 16
  124. sigreturn_codes:
  125. /* [EO]ABI sigreturn */
  126. slot 0
  127. raw_syscall __NR_sigreturn
  128. .cfi_def_cfa_offset 160 + 64
  129. /* [EO]ABI rt_sigreturn */
  130. slot 1
  131. raw_syscall __NR_rt_sigreturn
  132. .cfi_endproc
  133. /* FDPIC sigreturn */
  134. .cfi_startproc
  135. cfi_fdpic_pc SIGFRAME_RC3_OFFSET
  136. cfi_fdpic_r9 SIGFRAME_RC3_OFFSET
  137. slot 2
  138. fdpic_thunk SIGFRAME_RC3_OFFSET
  139. .cfi_endproc
  140. /* FDPIC rt_sigreturn */
  141. .cfi_startproc
  142. cfi_fdpic_pc RT_SIGFRAME_RC3_OFFSET
  143. cfi_fdpic_r9 RT_SIGFRAME_RC3_OFFSET
  144. slot 3
  145. fdpic_thunk RT_SIGFRAME_RC3_OFFSET
  146. .cfi_endproc
  147. .balign 16
  148. endf sigreturn_codes