Source code of Windows XP (NT5)
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.

178 lines
7.5 KiB

  1. ;**************************************************************************
  2. ;* STACK2.ASM
  3. ;*
  4. ;* Assembly support code for stack tracing.
  5. ;*
  6. ;**************************************************************************
  7. INCLUDE TOOLPRIV.INC
  8. INCLUDE TDB.INC
  9. ;** External functions
  10. externNP HelperVerifySeg
  11. externNP HelperHandleToSel
  12. ;** Functions
  13. sBegin CODE
  14. assumes CS,CODE
  15. ; StackFrameFirst
  16. ; Returns information about the first stack frame and checks it
  17. ; for validity as much as possible. The first stack frame is found
  18. ; by getting the information from the TDB. If this task is active,
  19. ; or if the task was changed in an unusual way, this information
  20. ; may be incorrect. If it is, the user must set up the first
  21. ; CS, IP, and BP, and BPNext in the user structure, log it as the
  22. ; first stack trace and call StackTraceNext directly.
  23. cProc StackFrameFirst, <NEAR,PUBLIC>, <si,di,ds>
  24. parmD lpStack
  25. parmW hTDB
  26. cBegin
  27. ;** Verify that we have a good TDB first
  28. ;** Start by verifying the selector
  29. mov ax,hTDB ;Get the selector
  30. cCall HelperHandleToSel, <ax> ;Convert it to a selector
  31. push ax ;Save it
  32. mov bx,TDBSize
  33. cCall HelperVerifySeg, <ax,bx>
  34. pop bx ;Get selector back
  35. or ax,ax ;FALSE return?
  36. jnz SHORT SF_SelOk ;Selector's OK
  37. xor ax,ax ;Return FALSE
  38. jmp SHORT SF_End
  39. SF_SelOk:
  40. ;** Verify that the TDB signature matches
  41. mov ds,bx ;Point with DS
  42. cmp ds:[TDB_sig],TDB_SIGNATURE ;Is this really a TDB?
  43. jz SF_SigOk ;Must be
  44. xor ax,ax ;Return FALSE
  45. jmp SHORT SF_End
  46. SF_SigOk:
  47. ;** Get the BP value from the task stack and store in structure
  48. les di,lpStack ;Get a pointer to the user struct
  49. mov ax,ds:[TDB_taskSS] ;Get the SS value
  50. mov bx,ds:[TDB_taskSP] ;Get the max segment offset we need
  51. add bx,Task_CS + 2
  52. cCall HelperVerifySeg, <ax,bx> ;Make sure we can read all this
  53. or ax,ax ;Error?
  54. jz SF_End ;Yes, can't do walk
  55. lds bx,DWORD PTR ds:[TDB_taskSP] ;Get the SS:SP value
  56. mov si,ds:[bx].Task_BP ;Get the BP value from the stack
  57. and si,NOT 1 ;Clear the FAR frame bit, if any
  58. mov es:[di].st_wBP,si ;Store the BP value
  59. mov ax,ds:[bx].Task_IP ;Store initial IP
  60. mov es:[di].st_wIP,ax
  61. mov ax,ds:[bx].Task_CS ;Store the initial CS
  62. mov es:[di].st_wCS,ax
  63. ;** Return as much info as possible about this first frame
  64. mov ax,hTDB ;Get the TDB handle
  65. mov es:[di].st_hTask,ax ;Save in structure
  66. mov es:[di].st_wSS,ds ;Save the SS value
  67. mov es:[di].st_wFlags,FRAME_FAR ;Force a FAR frame this time
  68. ;** Try to verify this stuff
  69. xor ax,ax ;In case we need to exit
  70. or si,si ;End of the line?
  71. jz SF_End ;Nope
  72. cmp si,ds:[0ah] ;Compare against stack top
  73. jb SF_End ;Fine with top
  74. cmp si,ds:[0eh] ;Check against stack bottom
  75. jae SF_End ;OK with bottom too
  76. mov ax,1 ;Return TRUE
  77. SF_End:
  78. cEnd
  79. ; StackFrameNext
  80. ; Returns information in a public structure about the stack frame
  81. ; pointed to by the BP value passed in. Returns TRUE if the
  82. ; information seems valid, or FALSE if information could not be
  83. ; returned.
  84. cProc StackFrameNext, <NEAR,PUBLIC>, <si,di,ds>
  85. parmD lpStack
  86. cBegin
  87. ;** Get pointers to the frame
  88. les di,lpStack ;Get a pointer to the structure
  89. mov ax,es:[di].st_wSS ;Get the stack segment
  90. mov ds,ax ;Point with DS
  91. ;** Get the next stack frame
  92. mov si,es:[di].st_wBP ;Get the current BP value
  93. lea ax,[si + 6] ;Get the max stack probe
  94. cmp ax,si ;No stack wraparound allowed
  95. jb SN_End ;If below, we have wrapped
  96. cCall HelperVerifySeg, <ds,ax> ;Make sure the stack is OK
  97. or ax,ax ;OK?
  98. jnz @F ;Yes.
  99. jmp SHORT SN_End ;Return FALSE
  100. @@: mov dx,ds:[si+4] ;DX:CX is the return address
  101. mov cx,ds:[si+2]
  102. mov bx,ds:[si] ;Get next BP value
  103. ;** Zero BP is end of chain
  104. xor ax,ax ;In case we need to exit
  105. or bx,bx ;End of the line?
  106. jz SN_End ;Nope
  107. ;** If the new BP is higher on the stack than the old, it's invalid
  108. cmp bx,si ;New BP <= Old BP?
  109. jbe SN_End ;OK.
  110. ;** Make sure we're still on the stack (variables from KDATA.ASM)
  111. cmp bx,ds:[0ah] ;Compare against stack top
  112. jb SN_End ;Fine with top
  113. cmp bx,ds:[0eh] ;Check against stack bottom
  114. jae SN_End ;OK with bottom too
  115. ;** Return what we can about the frame
  116. mov es:[di].st_wSS,ds ;Save the SS value
  117. mov es:[di].st_wBP,si ; and the BP value
  118. test bx,1 ;Far or near frame?
  119. jnz SN_FarFrame ;For sure far if BP is odd
  120. ;** Even when BP is not odd, we may have a far frame
  121. mov ax,cs ;Get our RPL bits
  122. and al,3 ;Mask RPL bits
  123. mov ah,dl ;Get frame's RPL bits
  124. and ah,3 ;Mask RPL bits
  125. cmp al,ah ;If CS is a handle, they won't match
  126. jne SN_NearFrame ;Bits don't match
  127. lar ax,dx ;Get the access bits
  128. test ax,800h ;Is this a code segment?
  129. jz SN_NearFrame ;No. MUST be near frame
  130. lsl ax,dx ;Get the limit
  131. cmp ax,cx ;Inside limit?
  132. jbe SN_NearFrame ;No. MUST be near
  133. ;** Otherwise, probably is a far frame. It may not be, of course,
  134. ;** because this may be a code seg parameter
  135. SN_FarFrame:
  136. mov es:[di].st_wIP,cx ;Save the offset
  137. mov es:[di].st_wCS,dx ; and selector value
  138. mov ax,FRAME_FAR ;Tell the user what we did
  139. and bx,NOT 1 ;Clear the far frame bit
  140. jmp SHORT SN_20 ;Skip near section
  141. ;** Must be a near frame
  142. SN_NearFrame:
  143. mov es:[di].st_wIP,cx ;Save the offset
  144. ;Leave the old CS value in
  145. mov ax,FRAME_NEAR ;Tell the user what we did
  146. SN_20: mov es:[di].st_wFlags,ax ;Save in the structure
  147. mov es:[di].st_wBP,bx ;Save BP in the structure
  148. mov ax,1 ;Return TRUE
  149. SN_End:
  150. cEnd
  151. sEnd
  152. END