osbasea.S 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262
  1. /*++
  2. Copyright (c) 2013 Minoca Corp. All Rights Reserved
  3. Module Name:
  4. osbasea.S
  5. Abstract:
  6. This module implements assembly support for the OS Base library.
  7. Author:
  8. Evan Green 25-Feb-2013
  9. Environment:
  10. User Mode
  11. --*/
  12. ##
  13. ## ------------------------------------------------------------------- Includes
  14. ##
  15. #include <minoca/kernel/x86.inc>
  16. ##
  17. ## ---------------------------------------------------------------- Definitions
  18. ##
  19. ##
  20. ## ----------------------------------------------------------------------- Code
  21. ##
  22. ##
  23. ## .text specifies that this code belongs in the executable section.
  24. ##
  25. ## .code32 specifies that this is 32-bit protected mode code.
  26. ##
  27. .text
  28. .code32
  29. ##
  30. ## INTN
  31. ## OspSystemCallFull (
  32. ## ULONG SystemCallNumber,
  33. ## PVOID SystemCallParameter
  34. ## )
  35. ##
  36. /*++
  37. Routine Description:
  38. This routine executes a system call using the traditional "int x" method.
  39. This method is highly compatible, but slow.
  40. Arguments:
  41. SystemCallNumber - Supplies the system call number.
  42. SystemCallParameter - Supplies the system call parameter.
  43. Return Value:
  44. STATUS_SUCCESS or positive integer on success.
  45. Error status code on failure.
  46. --*/
  47. FUNCTION(OspSystemCallFull)
  48. movl 4(%esp), %ecx # Set the system call number.
  49. movl 8(%esp), %edx # Set the system call parameter.
  50. int $0x2F # Perform the system call.
  51. ret # Return.
  52. END_FUNCTION(OspSystemCallFull)
  53. ##
  54. ## INTN
  55. ## OspSysenterSystemCall (
  56. ## ULONG SystemCallNumber,
  57. ## PVOID SystemCallParameter
  58. ## )
  59. ##
  60. /*++
  61. Routine Description:
  62. This routine executes a system call using the sysenter instruction, which
  63. provides a fast jump to kernel mode on mostly-Intel machines.
  64. Arguments:
  65. SystemCallNumber - Supplies the system call number.
  66. SystemCallParameter - Supplies the system call parameter.
  67. Return Value:
  68. STATUS_SUCCESS or positive integer on success.
  69. Error status code on failure.
  70. --*/
  71. FUNCTION(OspSysenterSystemCall)
  72. pushl %ebx # Save EBX.
  73. call OspSysenter # Perform a call to get the return address.
  74. popl %ebx # Restore EBX.
  75. ret # Return.
  76. ##
  77. ## This small fake-ish function is used to be able to get the return address
  78. ## without generating text relocations.
  79. ##
  80. OspSysenter:
  81. popl %edx # Put the return address in EDX for sysenter.
  82. movl 8(%esp), %eax # Move the system call number to EAX.
  83. movl 12(%esp), %ebx # Move the system call parameter to EBX.
  84. movl %esp, %ecx # ECX contains the return stack pointer.
  85. sysenter # Jump to kernel mode.
  86. END_FUNCTION(OspSysenterSystemCall)
  87. ##
  88. ## VOID
  89. ## OspSignalHandler (
  90. ## PSIGNAL_PARAMETERS Parameters,
  91. ## PSIGNAL_CONTEXT Context
  92. ## )
  93. ##
  94. /*++
  95. Routine Description:
  96. This routine is called directly by the kernel when a signal occurs. It
  97. marshals the parameters and calls the C routine for handling the signal.
  98. The parameters are stored on the stack with the signal parameters followed
  99. by the signal context.
  100. Arguments:
  101. Parameters - Supplies a pointer to the signal parameters. Beyond that on
  102. the stack is the restore structure.
  103. Context - Supplies a pointer to the signal context from the kernel.
  104. Return Value:
  105. None.
  106. --*/
  107. FUNCTION(OspSignalHandler)
  108. ##
  109. ## Volatile registers are either saved or don't matter. Non-volatiles will
  110. ## be saved and restored by any C routine called.
  111. ##
  112. movl %esp, %eax # Get a pointer to the signal parameters.
  113. leal SIGNAL_PARAMETERS_SIZE(%eax), %ecx # Get a pointer to the context.
  114. pushl %ecx # Push a pointer to the signal context.
  115. pushl %eax # Push a pointer to the signal parameters.
  116. call OspProcessSignal # Call out to the C routine to handle it.
  117. addl $(SIGNAL_PARAMETERS_SIZE + 8), %esp # Pop arguments + signal params.
  118. pushl %esp # Push system call parameter.
  119. pushl %esp # It's a pointer to a pointer.
  120. pushl $SystemCallRestoreContext # Push system call number.
  121. call OspSystemCallFull # Call the full restore handler.
  122. int $3 # Execution should never get back here.
  123. END_FUNCTION(OspSignalHandler)
  124. ##
  125. ## PTHREAD_CONTROL_BLOCK
  126. ## OspGetThreadControlBlock (
  127. ## VOID
  128. ## )
  129. ##
  130. /*++
  131. Routine Description:
  132. This routine returns a pointer to the thread control block, a structure
  133. unique to each thread.
  134. Arguments:
  135. None.
  136. Return Value:
  137. Returns a pointer to the current thread's control block.
  138. --*/
  139. FUNCTION(OspGetThreadControlBlock)
  140. mov %gs:(0), %eax # Load the Self pointer.
  141. ret # Return.
  142. END_FUNCTION(OspGetThreadControlBlock)
  143. ##
  144. ## VOID
  145. ## OspImArchResolvePltEntry (
  146. ## PLOADED_IMAGE Image,
  147. ## ULONG RelocationOffset
  148. ## )
  149. ##
  150. /*++
  151. Routine Description:
  152. This routine implements the slow path for a Procedure Linkable Table entry
  153. that has not yet been resolved to its target function address. This routine
  154. is only called once for each PLT entry, as subsequent calls jump directly
  155. to the destination function address.
  156. Arguments:
  157. Image - Supplies a pointer to the loaded image whose PLT needs resolution.
  158. This is really whatever pointer is in GOT + 4.
  159. RelocationOffset - Supplies the byte offset from the start of the
  160. relocation section where the relocation for this PLT entry resides.
  161. Return Value:
  162. None. Control jumps directly to the destination function, rather than
  163. returning.
  164. --*/
  165. FUNCTION(OspImArchResolvePltEntry)
  166. pushl %eax # Save eax in case of ___tls_get_addr.
  167. pushl %ecx # Save ecx in case of fastcall.
  168. pushl %edx # Save edx in case of fastcall.
  169. movl 16(%esp), %eax # Get relocation offset argument.
  170. pushl %eax # Push it.
  171. movl 16(%esp), %eax # Get the image pointer.
  172. pushl %eax # Push it.
  173. call OspImResolvePltEntry # Call the C handler
  174. movl %eax, 24(%esp) # Save the address to fake return to later.
  175. movl 8(%esp), %edx # Restore edx.
  176. movl 12(%esp), %ecx # Restore ecx.
  177. movl 16(%esp), %eax # Restore eax.
  178. addl $24, %esp # Pop nearly everything, including parameters.
  179. ret # "Return" to the function destination.
  180. END_FUNCTION(OspImArchResolvePltEntry)