syscallas.S 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. /* Copyright (C) 2014 Stony Brook University
  2. This file is part of Graphene Library OS.
  3. Graphene Library OS is free software: you can redistribute it and/or
  4. modify it under the terms of the GNU Lesser General Public License
  5. as published by the Free Software Foundation, either version 3 of the
  6. License, or (at your option) any later version.
  7. Graphene Library OS is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU Lesser General Public License for more details.
  11. You should have received a copy of the GNU Lesser General Public License
  12. along with this program. If not, see <http://www.gnu.org/licenses/>. */
  13. /*
  14. * syscallas.S
  15. *
  16. * This file contains the entry point of system call table in library OS.
  17. */
  18. #include <shim_defs.h>
  19. #include <shim_unistd_defs.h>
  20. #include "asm-offsets.h"
  21. .global syscalldb
  22. .type syscalldb, @function
  23. .extern shim_table, debug_unsupp
  24. .global syscall_wrapper
  25. .type syscall_wrapper, @function
  26. .global syscall_wrapper_after_syscalldb
  27. .type syscall_wrapper_after_syscalldb, @function
  28. syscalldb:
  29. .cfi_startproc
  30. # Create shim_regs struct on the stack.
  31. pushfq
  32. # Under GDB, single-stepping sets Trap Flag (TP) of EFLAGS,
  33. # thus TP=1 is stored on pushfq above. Upon consequent popfq,
  34. # TP is 1, resulting in spurious trap. Reset TP here.
  35. andq $~0x100, (%rsp)
  36. cld
  37. pushq %rbp
  38. pushq %rbx
  39. pushq %rdi
  40. pushq %rsi
  41. pushq %rdx
  42. pushq %rcx
  43. pushq %r8
  44. pushq %r9
  45. pushq %r10
  46. pushq %r11
  47. pushq %r12
  48. pushq %r13
  49. pushq %r14
  50. pushq %r15
  51. leaq SHIM_REGS_SIZE - SHIM_REGS_R15(%rsp), %rbx
  52. pushq %rbx
  53. pushq %rax
  54. # shim_regs struct ends here.
  55. movq %rsp, %rbp
  56. .cfi_def_cfa_offset SHIM_REGS_SIZE
  57. .cfi_offset %rbp, -3 * 8 # saved_rbp is at CFA-24 (saved_rflags + saved_rbp)
  58. .cfi_def_cfa_register %rbp # %rbp
  59. cmp $LIBOS_SYSCALL_BOUND, %rax
  60. jae isundef
  61. movq shim_table@GOTPCREL(%rip), %rbx
  62. movq (%rbx,%rax,8), %rbx
  63. cmp $0, %rbx
  64. je isundef
  65. movq %rbp, %gs:(SHIM_TCB_OFFSET + TCB_REGS)
  66. /* Translating x86_64 kernel calling convention to user-space
  67. * calling convention */
  68. movq %r10, %rcx
  69. andq $~0xF, %rsp # Required by System V AMD64 ABI.
  70. call *%rbx
  71. movq $0, %gs:(SHIM_TCB_OFFSET + TCB_REGS)
  72. ret:
  73. movq %rbp, %rsp
  74. addq $2 * 8, %rsp # skip orig_rax and rsp
  75. popq %r15
  76. popq %r14
  77. popq %r13
  78. popq %r12
  79. popq %r11
  80. popq %r10
  81. popq %r9
  82. popq %r8
  83. popq %rcx
  84. popq %rdx
  85. popq %rsi
  86. popq %rdi
  87. popq %rbx
  88. popq %rbp
  89. .cfi_def_cfa %rsp, 2 * 8 # +8 for ret_addr, +8 for saved_rflags
  90. popfq
  91. .cfi_def_cfa_offset 8 # +8 for ret_addr
  92. retq
  93. isundef:
  94. #ifdef DEBUG
  95. mov %rax, %rdi
  96. andq $~0xF, %rsp # Required by System V AMD64 ABI.
  97. call *debug_unsupp@GOTPCREL(%rip)
  98. #endif
  99. movq $-38, %rax # ENOSYS
  100. jmp ret
  101. .cfi_endproc
  102. .size syscalldb, .-syscalldb
  103. /*
  104. * syscall_wrapper: emulate syscall instruction
  105. * prohibited in e.g. Linux-SGX PAL which raises a SIGILL exception
  106. * See illegal_upcall() @ shim_signal.c and
  107. * fixup_child_context() @ shim_clone.c
  108. *
  109. * input:
  110. * %rcx: Instruction address to continue app execution after trapped
  111. * syscall instruction
  112. * %r11: rflags on entering syscall
  113. */
  114. syscall_wrapper:
  115. .cfi_startproc
  116. .cfi_def_cfa %rsp, 0
  117. # %rcx is used as input for returning %rip
  118. .cfi_register %rip, %rcx
  119. # %r11 is used as input to keep %rflags
  120. .cfi_register %rflags, %r11
  121. subq $RED_ZONE_SIZE, %rsp
  122. .cfi_adjust_cfa_offset RED_ZONE_SIZE
  123. callq *syscalldb@GOTPCREL(%rip)
  124. syscall_wrapper_after_syscalldb:
  125. addq $RED_ZONE_SIZE, %rsp
  126. .cfi_adjust_cfa_offset -RED_ZONE_SIZE
  127. # restore %rflags for syscall abi compatibility.
  128. # This must be done after "addq $RED_ZONE_SIZE, %rsp" above
  129. # which destroys %rflags
  130. xchg %r11, (%rsp)
  131. .cfi_offset %rflags, 0
  132. popfq
  133. .cfi_adjust_cfa_offset -8
  134. .cfi_same_value %rflags
  135. pushq %r11
  136. .cfi_adjust_cfa_offset 8
  137. jmp *%rcx
  138. .cfi_endproc
  139. .size syscall_wrapper, .-syscall_wrapper