Team Fortress 2 Source Code as on 22/4/2020
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.

175 lines
5.3 KiB

  1. option casemap:none
  2. .CODE
  3. ; import Coroutine_Finish with its mangled Microsoft Visual C++ name
  4. ?Coroutine_Finish@@YAXXZ PROTO
  5. ; extern "C" void SaveNonVolatileRegs( uintptr_t regs[8] );
  6. ; incoming parameter is rcs
  7. SaveNonVolatileRegs PROC FRAME
  8. .endprolog
  9. mov qword ptr[rcx], rbx
  10. mov qword ptr[rcx+8], rbp
  11. mov qword ptr[rcx+16], rsi
  12. mov qword ptr[rcx+24], rdi
  13. mov qword ptr[rcx+32], r12
  14. mov qword ptr[rcx+40], r13
  15. mov qword ptr[rcx+48], r14
  16. mov qword ptr[rcx+56], r15
  17. ret
  18. SaveNonVolatileRegs ENDP
  19. ; extern "C" void NORETURN Coroutine_Launch_ASM( byte **ppStackHigh, uintptr_t **ppLaunchParentFramePtr, void (*pfnExec)( void* ), void *pvParam )
  20. ; Per Win64 ABI, incoming params are rcx, rdx, r8, r9. initial stack pointer is half-aligned due to return address
  21. Coroutine_Launch_ASM PROC FRAME
  22. ; x64 prolog and prolog description macros:
  23. ; save caller's nonvolatile registers (pushed in reverse order to match SaveNonVolatileRegs)
  24. ; so that we can slam new values in later to trick the x64 callstack unwind procedure
  25. push r15
  26. .pushreg r15
  27. push r14
  28. .pushreg r14
  29. push r13
  30. .pushreg r13
  31. push r12
  32. .pushreg r12
  33. push rdi
  34. .pushreg rdi
  35. push rsi
  36. .pushreg rsi
  37. push rbp
  38. .pushreg rbp
  39. push rbx
  40. .pushreg rbx
  41. ; stack-allocate Win64 function call shadow space for calls to pfnExec and Coroutine_Finish,
  42. ; plus 8 additional bytes to align the stack frame properly (comes in off by 8)
  43. sub rsp, 28h
  44. .allocstack 28h
  45. .endprolog
  46. ; compute top of stack for coroutine: 40 bytes for stack, 64 for saved regs, 8 for return address
  47. ; (we do not bother including the additional unused 32 byte shadow space we own above that)
  48. lea rax, [rsp+70h]
  49. mov qword ptr [rcx], rax
  50. ; save off the address of our saved regs so that we can memcpy over them later and trick
  51. ; the x64 stack unwind logic into walking up to a different Internal_Coroutine_Continue
  52. lea rax, [rsp+28h]
  53. mov qword ptr [rdx], rax
  54. ; call pfnExec(pvParam)
  55. mov rcx, r9
  56. call r8
  57. ; call Coroutine_Finish - does not return
  58. call ?Coroutine_Finish@@YAXXZ
  59. Coroutine_Launch_ASM ENDP
  60. ; Needs to match definition found in setjmp.h
  61. _JUMP_BUFFER STRUCT
  62. m_Frame QWORD ?
  63. m_Rbx QWORD ?
  64. m_Rsp QWORD ?
  65. m_Rbp QWORD ?
  66. m_Rsi QWORD ?
  67. m_Rdi QWORD ?
  68. m_R12 QWORD ?
  69. m_R13 QWORD ?
  70. m_R14 QWORD ?
  71. m_R15 QWORD ?
  72. m_Rip QWORD ?
  73. m_MxCsr DWORD ?
  74. m_FpCsr WORD ?
  75. m_Spare WORD ?
  76. m_Xmm6 XMMWORD ?
  77. m_Xmm7 XMMWORD ?
  78. m_Xmm8 XMMWORD ?
  79. m_Xmm9 XMMWORD ?
  80. m_Xmm10 XMMWORD ?
  81. m_Xmm11 XMMWORD ?
  82. m_Xmm12 XMMWORD ?
  83. m_Xmm13 XMMWORD ?
  84. m_Xmm14 XMMWORD ?
  85. m_Xmm15 XMMWORD ?
  86. _JUMP_BUFFER ENDS
  87. ;This is the reference asm for __intrinsic_setjmp() in VS2015
  88. ;mov qword ptr [rcx],rdx ; intrinsic call site does "mov rdx,rbp" followed by "add rdx,0FFFFFFFFFFFFFFC0h", looks like a nonstandard abi
  89. ;mov qword ptr [rcx+8],rbx
  90. ;mov qword ptr [rcx+18h],rbp
  91. ;mov qword ptr [rcx+20h],rsi
  92. ;mov qword ptr [rcx+28h],rdi
  93. ;mov qword ptr [rcx+30h],r12
  94. ;mov qword ptr [rcx+38h],r13
  95. ;mov qword ptr [rcx+40h],r14
  96. ;mov qword ptr [rcx+48h],r15
  97. ;lea r8,[rsp+8] ; rsp set to post-return address
  98. ;mov qword ptr [rcx+10h],r8
  99. ;mov r8,qword ptr [rsp]
  100. ;mov qword ptr [rcx+50h],r8
  101. ;stmxcsr dword ptr [rcx+58h]
  102. ;fnstcw word ptr [rcx+5Ch]
  103. ;movdqa xmmword ptr [rcx+60h],xmm6
  104. ;ovdqa xmmword ptr [rcx+70h],xmm7
  105. ;movdqa xmmword ptr [rcx+80h],xmm8
  106. ;movdqa xmmword ptr [rcx+90h],xmm9
  107. ;movdqa xmmword ptr [rcx+0A0h],xmm10
  108. ;movdqa xmmword ptr [rcx+0B0h],xmm11
  109. ;movdqa xmmword ptr [rcx+0C0h],xmm12
  110. ;movdqa xmmword ptr [rcx+0D0h],xmm13
  111. ;movdqa xmmword ptr [rcx+0E0h],xmm14
  112. ;movdqa xmmword ptr [rcx+0F0h],xmm15
  113. ;xor eax,eax
  114. ;ret
  115. ; extern "C" void NORETURN Coroutine_LongJmp_UnChecked( jmp_buf buf, int nResult )
  116. ; Per Win64 ABI, incoming params are rcx, rdx, r8, r9. initial stack pointer is half-aligned due to return address
  117. Coroutine_LongJmp_Unchecked PROC
  118. ;load nResult into result from initial setjmp()
  119. xor rax, rax
  120. mov eax, edx
  121. ;restore to setjmp() caller state
  122. mov rdx, [rcx]._JUMP_BUFFER.m_Frame ; appears to be an error checking value of (_JUMP_BUFFER.m_Rbp + 0FFFFFFFFFFFFFFC0h) passed non-standardly through rdx to setjmp()
  123. mov rbx, [rcx]._JUMP_BUFFER.m_Rbx
  124. mov rsp, [rcx]._JUMP_BUFFER.m_Rsp
  125. mov rbp, [rcx]._JUMP_BUFFER.m_Rbp
  126. mov rsi, [rcx]._JUMP_BUFFER.m_Rsi
  127. mov rdi, [rcx]._JUMP_BUFFER.m_Rdi
  128. mov r12, [rcx]._JUMP_BUFFER.m_R12
  129. mov r13, [rcx]._JUMP_BUFFER.m_R13
  130. mov r14, [rcx]._JUMP_BUFFER.m_R14
  131. mov r15, [rcx]._JUMP_BUFFER.m_R15
  132. mov r10, [rcx]._JUMP_BUFFER.m_Rip ; store return address in r10 for return
  133. ldmxcsr [rcx]._JUMP_BUFFER.m_MxCsr
  134. fldcw [rcx]._JUMP_BUFFER.m_FpCsr
  135. ;[rcx]._JUMP_BUFFER.m_Spare
  136. movaps xmm6, [rcx]._JUMP_BUFFER.m_Xmm6
  137. movaps xmm7, [rcx]._JUMP_BUFFER.m_Xmm7
  138. movaps xmm8, [rcx]._JUMP_BUFFER.m_Xmm8
  139. movaps xmm9, [rcx]._JUMP_BUFFER.m_Xmm9
  140. movaps xmm10, [rcx]._JUMP_BUFFER.m_Xmm10
  141. movaps xmm11, [rcx]._JUMP_BUFFER.m_Xmm11
  142. movaps xmm12, [rcx]._JUMP_BUFFER.m_Xmm12
  143. movaps xmm13, [rcx]._JUMP_BUFFER.m_Xmm13
  144. movaps xmm14, [rcx]._JUMP_BUFFER.m_Xmm14
  145. movaps xmm15, [rcx]._JUMP_BUFFER.m_Xmm15
  146. ;jmp instead of ret to _JUMP_BUFFER.m_Rip because setjmp() already set the _JUMP_BUFFER.m_Rsp to the post-return state
  147. db 048h ; emit a REX prefix on the jmp to ensure it's a full qword
  148. jmp qword ptr r10
  149. Coroutine_LongJmp_Unchecked ENDP
  150. _TEXT ENDS
  151. END