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.

2274 lines
47 KiB

  1. TITLE LDDEBUG - Debugger interface procedures
  2. include kernel.inc
  3. include newexe.inc
  4. include tdb.inc
  5. include protect.inc
  6. include wow.inc
  7. include dbgsvc.inc
  8. include bop.inc
  9. ifdef WOW
  10. include vint.inc
  11. endif
  12. ;.386p
  13. HEAPDUMP = 0
  14. DEBUGOFFSET equ 000FBH
  15. INTOFFSET equ 4*3+2
  16. DEBUGCALL MACRO
  17. call MyDebugCall
  18. ENDM
  19. DataBegin
  20. externW winVer
  21. externW wDefRip
  22. externB Kernel_Flags
  23. externB Kernel_InDOS
  24. externB fDW_Int21h
  25. externW pGlobalHeap
  26. externW hGlobalHeap
  27. externD ptrace_dll_entry
  28. externD lpfnToolHelpProc
  29. externD pKeyboardSysReq
  30. externW curTDB
  31. externW wExitingTDB
  32. externW <Win_PDB, topPDB>
  33. ifdef WOW
  34. externD FastBop
  35. externW DebugWOW
  36. externW hExeHead
  37. if PMODE32
  38. externW gdtdsc
  39. endif; PMODE32
  40. endif; WOW
  41. debugseg dw 0
  42. IF KDEBUG
  43. externB fKTraceOut
  44. ENDIF
  45. DataEnd
  46. ifdef WOW
  47. externFP GetModuleFileName
  48. externFP GetModuleHandle
  49. externFP WOWOutputDebugString
  50. externFP WOWNotifyTHHOOK
  51. endif
  52. ifdef FE_SB
  53. ; _TEXT code segment is over flow with debug 386 version
  54. ; GetOwnerName moves to _MISCTEXT from _TEXT segment with DBCS flag
  55. externFP FarGetOwner
  56. endif ; FE_SB
  57. sBegin CODE
  58. assumes CS,CODE
  59. if pmode32
  60. externNP get_arena_pointer32
  61. else
  62. externNP get_arena_pointer
  63. endif
  64. externNP GetOwner
  65. externNP genter
  66. externNP get_physical_address
  67. externNP ValidatePointer
  68. sEnd CODE
  69. sBegin INITCODE
  70. assumes CS,CODE
  71. assumes DS,NOTHING
  72. assumes ES,NOTHING
  73. ;-----------------------------------------------------------------------;
  74. ; debuginit ;
  75. ; ;
  76. ; Returns a non zero value in AX if debugger is resident. ;
  77. ; If the debugger is present a distinquished string of "SEGDEBUG",0 ;
  78. ; will be found at 100H off of the interrupt vector segment (int 3). ;
  79. ; ;
  80. ; Arguments: ;
  81. ; None. ;
  82. ; ;
  83. ; Returns: ;
  84. ; AX =! 0 if debugger resident. ;
  85. ; ;
  86. ; Error Returns: ;
  87. ; ;
  88. ; Registers Preserved: ;
  89. ; ;
  90. ; Registers Destroyed: ;
  91. ; ;
  92. ; Calls: ;
  93. ; ;
  94. ; History: ;
  95. ; ;
  96. ; Thu Nov 13, 1986 02:03:51p -by- David N. Weise [davidw] ;
  97. ; Added this nifty comment block. ;
  98. ;-----------------------------------------------------------------------;
  99. assumes ds,nothing
  100. assumes es,nothing
  101. cProc DebugInit,<PUBLIC,NEAR>,<es,si,di>
  102. cBegin
  103. CheckKernelDS
  104. ReSetKernelDS
  105. DebInt 4fh
  106. cmp ax, 0F386h
  107. jne short no_debugger
  108. inc debugseg
  109. or Kernel_flags[2],KF2_SYMDEB
  110. no_debugger:
  111. cEnd
  112. ;-----------------------------------------------------------------------;
  113. ; DebugDebug
  114. ;
  115. ;
  116. ; Entry:
  117. ;
  118. ; Returns:
  119. ;
  120. ; Registers Destroyed:
  121. ;
  122. ; History:
  123. ; Tue 21-Jun-1988 13:10:41 -by- David N. Weise [davidw]
  124. ;
  125. ;-----------------------------------------------------------------------;
  126. assumes ds,nothing
  127. assumes es,nothing
  128. cProc DebugDebug,<PUBLIC,NEAR>
  129. cBegin nogen
  130. push ds
  131. SetKernelDS
  132. ifdef WOW
  133. call WOWNotifyTHHOOK
  134. ; Tell the debugger where it can poke around for kernel data structure info
  135. mov cx, hGlobalHeap
  136. mov dx, hExeHead
  137. push DBG_WOWINIT
  138. FBOP BOP_DEBUGGER,,FastBop
  139. add sp,+2
  140. else
  141. test Kernel_Flags[2],KF2_SYMDEB or KF2_PTRACE
  142. jz short dd_done
  143. ; Tell the debugger where it can poke around for kernel data structure info
  144. push ax
  145. push bx
  146. push cx
  147. push dx
  148. mov bx,winVer
  149. mov cx,dataOffset hGlobalHeap
  150. mov dx,ds
  151. DebInt 5ah
  152. pop dx
  153. pop cx
  154. pop bx
  155. pop ax
  156. UnSetKernelDS
  157. dd_done:
  158. endif
  159. pop ds
  160. ret
  161. cEnd nogen
  162. ;-----------------------------------------------------------------------;
  163. ; DebugSysReq
  164. ;
  165. ; tell the keyboard driver to pass sys req through
  166. ;
  167. ; Entry:
  168. ;
  169. ; Returns:
  170. ;
  171. ; Registers Destroyed:
  172. ;
  173. ; History:
  174. ; Tue 19-Sep-1989 21:42:02 -by- David N. Weise [davidw]
  175. ; Wrote it!
  176. ;-----------------------------------------------------------------------;
  177. assumes ds,nothing
  178. assumes es,nothing
  179. cProc DebugSysReq,<PUBLIC,NEAR>
  180. cBegin nogen
  181. CheckKernelDS
  182. ReSetKernelDS
  183. mov ax,debugseg
  184. or ax,ax
  185. jz short dwr_ret
  186. cmp pKeyboardSysReq.sel,0 ; is there a keyboard driver?
  187. jz short dwr_ret
  188. mov ax,1 ; use int 2
  189. cCall pKeyboardSysReq,<ax>
  190. dwr_ret:
  191. ret
  192. cEnd nogen
  193. sEnd INITCODE
  194. ifdef FE_SB
  195. sBegin MISCCODE
  196. assumes CS,MISCCODE
  197. else ; !FE_SB
  198. sBegin CODE
  199. assumes CS,CODE
  200. endif ; !FE_SB
  201. assumes DS,NOTHING
  202. assumes ES,NOTHING
  203. ; Copyright (c) Microsoft Coropration 1989-1990. All Rights Reserved.
  204. ;
  205. ; Stolen from DOSX\DXBUG.ASM
  206. ;
  207. ; -------------------------------------------------------
  208. ; GENERAL SYMBOL DEFINITIONS
  209. ; -------------------------------------------------------
  210. Debug_Serv_Int equ 41h ;WDEB386 service codes
  211. DS_Out_Char equ 0
  212. DS_Out_Symbol equ 0fh
  213. ; Find owner of 'sel', copy name to buffer, zero terminate name
  214. ; return count of chars copied, or 0.
  215. cProc GetOwnerName,<PUBLIC,FAR>,<ds, si, di>
  216. parmW obj
  217. parmD buf
  218. parmW buflen
  219. cBegin
  220. push [obj]
  221. ifdef FE_SB
  222. call FarGetOwner
  223. else ; !FE_SB
  224. call GetOwner
  225. endif ; !FE_SB
  226. or ax, ax
  227. jz gon_exit
  228. mov ds, ax ; DS:SI points to name
  229. xor ax, ax
  230. cmp word ptr ds:[0], NEMAGIC
  231. jnz gon_exit
  232. mov si, ds:[ne_restab]
  233. lodsb ; get length
  234. cmp ax, [buflen] ; name must be smaller than buf
  235. jb @F
  236. mov ax, [buflen]
  237. dec ax
  238. @@: mov cx, ax
  239. cld
  240. les di, [buf]
  241. rep movsb
  242. mov byte ptr es:[di], 0
  243. gon_exit:
  244. cEnd
  245. ifdef FE_SB
  246. sEnd MISCCODE
  247. sBegin CODE
  248. assumes CS,CODE
  249. assumes DS,NOTHING
  250. assumes ES,NOTHING
  251. endif ; FE_SB
  252. ;******************************************************************************
  253. ;
  254. ; KOutputDebugStr
  255. ;
  256. ; Basically stolen from Windows/386 code by Ralph Lipe -- hacked up for
  257. ; 286 instead of 386. Here in RalphL's own words is the description:
  258. ;
  259. ; DESCRIPTION:
  260. ; The following code is not pretty but it does what it needs to. It will
  261. ; only be included in DEBUG versions of Kernel. It accepts an ASCIIZ
  262. ; string which it will output to the COM1 serial port. If the string
  263. ; contains #(Register) (for example #AX) then the value of that register
  264. ; will be output. It will not work for segment registers.
  265. ;
  266. ; If the string contains ?(Register)[:(Register)] (for example ?AX or
  267. ; ?AX:BX) then the value of the register(s) is passed to the debugger
  268. ; to display the label nearest to the given address. (It, also, will
  269. ; not work with segment registers. If ?AX is given, then the segment is
  270. ; assumed to be the DS data segment.
  271. ;
  272. ; Lower case register forces skip leading zeros.
  273. ;
  274. ; ENTRY:
  275. ; DS:SI -> ASCIIZ string
  276. ;
  277. ; EXIT:
  278. ; All registers and flags trashed
  279. ;
  280. ; ASSUMES:
  281. ; This procedure was called by the Trace_Out macro. It assumes that
  282. ; the stack is a pusha followed by a FAR call to this procedure.
  283. ;
  284. ;------------------------------------------------------------------------------
  285. Reg_Offset_Table LABEL WORD ; Order of PUSHA
  286. dw "DI"
  287. dw "SI"
  288. dw "BP"
  289. dw "SP"
  290. dw "BX"
  291. dw "DX"
  292. dw "CX"
  293. dw "AX"
  294. dw "SS"
  295. dw "ES"
  296. dw "DS"
  297. dw "CS"
  298. OSC1_ModName:
  299. pop ax
  300. OSC1_ModName1:
  301. push es
  302. mov es, ax
  303. cmp word ptr es:[0], NEMAGIC
  304. jz @F
  305. pop es
  306. jmps is_pdb
  307. @@: mov cx, es:[ne_restab]
  308. inc cx ; skip length byte
  309. pop es
  310. jmp Show_String ; AX:CX -> string to print
  311. OSC1_FileName:
  312. pop ax
  313. push es
  314. mov es, ax
  315. mov cx, word ptr es:[ne_crc+2]
  316. add cx, 8
  317. pop es
  318. jmp Show_String
  319. szUnk db 'Unknown',0
  320. OSC1_OwnerName:
  321. pop ax
  322. push ds
  323. push ax
  324. cCall GetOwner ; seg value already on stack
  325. pop ds
  326. or ax, ax
  327. jnz OSC1_ModName1
  328. is_pdb: mov ax, cs
  329. mov cx, CodeOffset szUnk
  330. jmp Show_String
  331. OSC1_Custom:
  332. call Get_Register
  333. jnc short OSC1_not_special
  334. or ax, ax
  335. jz short OSC1_not_special
  336. push ax
  337. lodsb
  338. cmp al, '0'
  339. jz short OSC1_ModName
  340. cmp al, '1'
  341. jz short OSC1_FileName
  342. cmp al, '2'
  343. jz short OSC1_OwnerName
  344. pop ax
  345. jmps OSC1_not_special
  346. public KOutDebugStr
  347. KOutDebugStr proc far
  348. push bp
  349. mov bp, sp ; Assumes BP+6 = Pusha
  350. sub sp, 84 ; local 80 char line + count
  351. odslen equ word ptr [bp-2]
  352. odsbuf equ byte ptr [bp-82]
  353. odszero equ word ptr [bp-84] ; flag - true if skip leading zero
  354. odsflag equ word ptr [bp-86] ; last local var - from pushf
  355. mov odslen, 0
  356. pushf
  357. push es
  358. push cs ; Address our own data seg
  359. pop es
  360. assumes ds,NOTHING
  361. assumes es,code
  362. cld
  363. FCLI
  364. OSC1_Loop:
  365. lodsb ; Get the next character
  366. test al, al ; Q: End of string?
  367. jz short OSC1_Done ; Y: Return
  368. push codeoffset OSC1_Loop
  369. cmp al, "#" ; N: Q: Special register out?
  370. je SHORT OSC1_Hex ; Y: Find out which one
  371. cmp al, "?" ; Q: special label out?
  372. je short OSC1_Label ; Y: find out which one
  373. cmp al, "@" ; Q: special string out?
  374. je short OSC1_Str
  375. cmp al, "%" ; Custom value?
  376. je short OSC1_Custom
  377. OSC1_out:
  378. xor ah, ah ; N: Send char to COM
  379. jmp Out_Debug_Chr
  380. OSC1_Hex:
  381. call Get_Register
  382. jnc short OSC1_not_special
  383. or bh, bh ; Q: Word output?
  384. jz SHORT OSC1_Out_Byte ; N: display byte
  385. OSC1_Out_Word:
  386. jmp Out_Hex_4_test ; Display AX in hex
  387. OSC1_Out_Byte:
  388. xchg al, ah ; swap bytes to print just
  389. jmp Out_Hex_2_test ; the low one!
  390. OSC1_Label:
  391. call Get_Register
  392. jc short show_label
  393. OSC1_not_special:
  394. lodsb ; Get special char again
  395. jmp OSC1_out ; display it, and continue
  396. show_label:
  397. mov cx, ax ; save first value
  398. cmp byte ptr [si], ':' ;Q: selector separator?
  399. jne short flat_offset ; N:
  400. lodsb ; Y: eat the ':'
  401. call Get_Register ; and attempt to get the selector
  402. jc short sel_offset
  403. flat_offset:
  404. mov ax, cs ; default selector value
  405. sel_offset:
  406. jmp Show_Near_Label
  407. OSC1_Str:
  408. call Get_Register
  409. jnc short OSC1_not_special
  410. mov cx,ax
  411. cmp byte ptr [si],':'
  412. jne short no_selector
  413. lodsb
  414. push cx
  415. call Get_Register
  416. pop cx
  417. xchg ax,cx
  418. jc short got_sel_off
  419. mov cx,ax
  420. no_selector:
  421. mov ax,ds ; default selector for strings
  422. got_sel_off:
  423. jmp Show_String
  424. OSC1_Done: ; The end
  425. xor ax, ax ; flush buffer
  426. call Out_Debug_Chr
  427. pop es
  428. if pmode32
  429. test odsflag, 200h
  430. jz short @F
  431. FSTI
  432. @@:
  433. endif
  434. popf
  435. leave
  436. ret
  437. KOutDebugStr endp
  438. ;******************************************************************************
  439. ;
  440. ; Get_Register
  441. ;
  442. ; DESCRIPTION:
  443. ;
  444. ; ENTRY:
  445. ;
  446. ; EXIT: Carry set if register value found
  447. ; AX = register value
  448. ; BL = value size (1, 2, 4) (no longer true - donc)
  449. ;
  450. ; USES:
  451. ;
  452. ;==============================================================================
  453. Get_Register proc near
  454. lodsw ; get next pair of letters
  455. mov bx, ax
  456. and bx, 2020h
  457. mov [odszero], bx
  458. and ax, 0dfdfh ; to upper case
  459. xchg ah, al ; normal order (or change table?)
  460. or bx, -1 ; BH = -1
  461. cmp al, 'L' ; Q: "L" (ie AL, BL, etc)?
  462. jne short @F ; N: word reg
  463. mov al, 'X' ; Y: change to X for pos match
  464. inc bh ; BH now 0 - will clear AH below
  465. @@:
  466. xor di, di ; DI = 0
  467. mov cx, 12 ; Size of a pusha + 4 seg regs
  468. OSC1_Special_Loop:
  469. cmp ax, Reg_Offset_Table[di] ; Q: Is this the register?
  470. je SHORT OSC1_Out_Reg ; Y: Output it
  471. add di, 2 ; N: Try the next one
  472. loop OSC1_Special_Loop ; until CX = 0
  473. sub si, 3 ; restore pointer, clear carry
  474. ret
  475. OSC1_Out_Reg:
  476. mov ax, SS:[bp.6][di] ; AX = Value to output
  477. and ah, bh ; if xL, zero out high byte
  478. stc
  479. ret
  480. Get_Register endp
  481. ;******************************************************************************
  482. ;
  483. ; Out_Hex_Word
  484. ;
  485. ; Outputs the value in AX to the COM port in hexadecimal.
  486. ;
  487. ;------------------------------------------------------------------------------
  488. Out_Hex_2_test: ; Write two chars
  489. xor ah, ah
  490. cmp [odszero], 0 ; skip leading 0's?
  491. je Out_Hex_2 ; no, show 2 chars
  492. ; yes, fall through
  493. Out_Hex_4_test:
  494. cmp [odszero], 0
  495. je Out_Hex_4
  496. test ax, 0fff0h
  497. jz Out_Hex_1
  498. test ah, 0f0h
  499. jnz Out_Hex_4
  500. test ah, 0fh
  501. jz Out_Hex_2
  502. Out_Hex_3:
  503. xchg al, ah
  504. call Out_Hex_1
  505. xchg al, ah
  506. jmps Out_Hex_2
  507. Out_Hex_4:
  508. xchg al, ah
  509. call Out_Hex_2
  510. xchg al, ah
  511. Out_Hex_2:
  512. push ax
  513. shr ax, 4
  514. call Out_Hex_1
  515. pop ax
  516. Out_Hex_1:
  517. push ax
  518. and al, 0fh
  519. cmp al, 10
  520. jb @F
  521. add al, '@'-'9'
  522. @@: add al, '0'
  523. call Out_Debug_Chr
  524. pop ax
  525. ret
  526. ;******************************************************************************
  527. ;
  528. ; Out_Debug_Chr
  529. ;
  530. ; DESCRIPTION:
  531. ;
  532. ; ENTRY:
  533. ; AL contains character to output
  534. ;
  535. ; EXIT:
  536. ;
  537. ; USES:
  538. ; Nothing
  539. ;
  540. ;==============================================================================
  541. Out_Debug_Chr proc near
  542. push di
  543. mov di, odslen
  544. mov odsbuf[di], al ; store in buffer (in stack)
  545. or al, al
  546. jz short odc_flushit ; if null, flush buffer
  547. inc odslen
  548. cmp di, 79 ; if full, flush buffer
  549. jnz short odc_ret
  550. odc_flushit:
  551. mov odsbuf[di], 0 ; null terminate string
  552. lea di, odsbuf
  553. ifdef WOW
  554. cCall <far ptr DebugWrite>,<ssdi,odslen>
  555. else
  556. cCall DebugWrite,<ssdi,odslen>
  557. endif
  558. mov odslen, 0
  559. odc_ret:
  560. pop di
  561. ret
  562. Out_Debug_Chr endp
  563. ;******************************************************************************
  564. ;
  565. ; Show_Near_Label
  566. ;
  567. ; DESCRIPTION: call the debugger to display a label less than or equal
  568. ; to the given address
  569. ;
  570. ; ENTRY: AX is selector, CX is offset of address to try to find
  571. ; a symbol for
  572. ; ES selector to DOSX data segment
  573. ; EXIT:
  574. ;
  575. ; USES:
  576. ;
  577. ;==============================================================================
  578. Show_Near_Label proc near
  579. push ax ;on a 286, use 16 bit regs
  580. push bx
  581. push cx
  582. mov bx,cx
  583. mov cx,ax
  584. mov ax,DS_Out_Symbol
  585. int Debug_Serv_Int
  586. pop cx
  587. pop bx
  588. pop ax
  589. ret
  590. Show_Near_Label endp
  591. ;******************************************************************************
  592. ;
  593. ; Show_String
  594. ;
  595. ; DESCRIPTION: Display an asciiz string
  596. ;
  597. ; ENTRY: AX is selector, CX is offset of address to find string
  598. ;
  599. ; EXIT:
  600. ;
  601. ; USES:
  602. ;
  603. ;==============================================================================
  604. Show_String proc near
  605. push ax
  606. push ds
  607. push si
  608. mov ds,ax
  609. mov si,cx
  610. xor ax,ax
  611. cmp byte ptr ds:[si], ' '
  612. jbe pascal_show_string
  613. @@:
  614. lodsb
  615. or al,al
  616. jz short @f
  617. call Out_Debug_Chr
  618. jmp short @b
  619. @@:
  620. pop si
  621. pop ds
  622. pop ax
  623. ret
  624. pascal_show_string:
  625. push cx
  626. lodsb
  627. mov cl, al
  628. xor ch, ch
  629. pss_1: lodsb
  630. call Out_Debug_Chr
  631. loop pss_1
  632. pop cx
  633. jmps @B
  634. Show_String endp
  635. ; END OF DXBUG STUFF
  636. ;-----------------------------------------------------------------------;
  637. ; CVWBreak
  638. ;
  639. ; This is part of the tortuous path from a Ctrl-Alt-SysReq to
  640. ; CVW. In RegisterPtrace we tell the keyboard driver to jump
  641. ; here if Ctrl-Alt_SysReq is done.
  642. ;
  643. ; Entry:
  644. ; none
  645. ;
  646. ; Returns:
  647. ;
  648. ; Registers Destroyed:
  649. ; none
  650. ;
  651. ; History:
  652. ; Mon 17-Jul-1989 14:34:21 -by- David N. Weise [davidw]
  653. ; Wrote it!
  654. ;-----------------------------------------------------------------------;
  655. assumes ds,nothing
  656. assumes es,nothing
  657. cProc CVWBreak,<PUBLIC,FAR>
  658. cBegin nogen
  659. push ax
  660. push di
  661. push ds
  662. SetKernelDS
  663. test Kernel_flags[2],KF2_PTRACE
  664. jz short call_WDEB
  665. cmp Kernel_InDOS,0 ; not in DOS we don't
  666. jnz short TVC15_exit
  667. if pmode32
  668. .386p
  669. push fs ; save current FS for debuggers
  670. .286p
  671. endif
  672. call genter ; sets FS to kernel data seg
  673. UnSetKernelDS
  674. if pmode32
  675. .386p
  676. pop fs
  677. .286p
  678. endif
  679. dec [di].gi_lrulock
  680. jz short call_PTrace
  681. or [di].gi_flags,GIF_INT2
  682. jmps TVC15_exit
  683. call_PTrace:
  684. SetKernelDS
  685. cmp ptrace_DLL_entry.sel,0
  686. jnz short yes_CVW
  687. ;** This is the only case where WINDEBUG gets first dibs something.
  688. ;* Since we have no way of knowing if TOOLHELP wants the
  689. ;** CtlAltSysRq, we always give it to CVW if it's there.
  690. test Kernel_Flags[2],KF2_TOOLHELP
  691. jz SHORT call_WDEB
  692. mov ax,SDM_INT2 ;Notification number
  693. call lpfnToolHelpProc ;Give it to TOOLHELP
  694. jmp SHORT TVC15_exit
  695. ;** Give it to the kernel debugger
  696. call_WDEB:
  697. pop ds
  698. UnSetKernelDS
  699. pop di
  700. pop ax
  701. int 1
  702. iret
  703. ;** Give it to CVW
  704. yes_CVW:
  705. ReSetKernelDS
  706. mov ax,SDM_INT2
  707. call ptrace_DLL_entry
  708. TVC15_exit:
  709. pop ds
  710. UnSetKernelDS
  711. pop di
  712. pop ax
  713. iret
  714. cEnd nogen
  715. ;-----------------------------------------------------------------------;
  716. ; DebugDefineSegment ;
  717. ; ;
  718. ; Informs debugger of physical address and type of a segment for the ;
  719. ; named module, that is informed of segment index and corresponding ;
  720. ; name and physical segment. ;
  721. ; ;
  722. ; Arguments: ;
  723. ; ModName - Long pointer to module name. ;
  724. ; SegNumber - zero based segment index ;
  725. ; LoadedSeg - Physical seg address assigned by user to index. ;
  726. ; InstanceNumber - Windows instance number bound to physical seg.;
  727. ; DataOrCodeFlag - Whether segment is code or data. ;
  728. ; ;
  729. ; Returns: ;
  730. ; None. ;
  731. ; ;
  732. ; Error Returns: ;
  733. ; ;
  734. ; Registers Preserved: ;
  735. ; ;
  736. ; Registers Destroyed: ;
  737. ; ;
  738. ; Calls: ;
  739. ; ;
  740. ; History: ;
  741. ; ;
  742. ; Thu Nov 13, 1986 02:20:52p -by- David N. Weise [davidw] ;
  743. ; Added this nifty comment block. ;
  744. ;-----------------------------------------------------------------------;
  745. assumes ds,nothing
  746. assumes es,nothing
  747. default_buf_size equ 130
  748. cProc DebugDefineSegment,<PUBLIC,NEAR>,<es>
  749. Parmd ModName
  750. Parmw SegNumber
  751. Parmw LoadedSeg
  752. Parmw InstanceNumber
  753. Parmw DataOrCodeFlag
  754. localV modBuf,default_buf_size
  755. localV nameBuf,default_buf_size
  756. cBegin
  757. SetKernelDS es
  758. test Kernel_Flags[2],KF2_SYMDEB or KF2_PTRACE
  759. jz short setdone
  760. push bx
  761. push cx
  762. push dx
  763. push si
  764. push di
  765. les di, ModName
  766. UnSetKernelDS es
  767. mov bx, SegNumber
  768. mov cx, LoadedSeg
  769. mov dx, InstanceNumber
  770. mov si, DataOrCodeFlag
  771. mov ax,SDM_LOADSEG
  772. DEBUGCALL
  773. pop di
  774. pop si
  775. pop dx
  776. pop cx
  777. pop bx
  778. setdone:
  779. ifdef WOW
  780. SetKernelDS es
  781. test es:DebugWOW,DW_DEBUG
  782. jnz @f
  783. jmp dd_no_wdebug
  784. UnSetKernelDS es
  785. @@:
  786. push ds
  787. push bx
  788. push cx
  789. push dx
  790. push si
  791. push di
  792. lds si, ModName
  793. mov cx,ds:[ne_magic]
  794. cmp cx,NEMAGIC
  795. jz @f
  796. jmp not_yet
  797. @@: mov cx,ss
  798. mov es,cx
  799. lea di,modBuf
  800. xor cx,cx
  801. mov cl,byte ptr [si-1] ; Get length byte
  802. cmp cx,default_buf_size
  803. jl @f
  804. mov cx,default_buf_size-1
  805. @@:
  806. rep movsb ; Copy the string
  807. xor ax,ax
  808. stosb
  809. mov si,ds:[ne_pfileinfo]
  810. mov cl,ds:[si].opLen
  811. sub cx,opFile
  812. lea si,[si].opFile
  813. lea di,nameBuf
  814. cmp cx,default_buf_size
  815. jl @f
  816. mov cx,default_buf_size-1
  817. @@:
  818. rep movsb ; Copy the string
  819. stosb
  820. SetKernelDS es
  821. push DataOrCodeFlag
  822. lea si,nameBuf
  823. push ss
  824. push si
  825. lea si,modBuf
  826. push ss
  827. push si
  828. push SegNumber
  829. push LoadedSeg
  830. push DBG_SEGLOAD
  831. IFE PMODE
  832. BOP BOP_DEBUGGER
  833. ELSE
  834. FBOP BOP_DEBUGGER,,FastBop
  835. ENDIF
  836. add sp,+16
  837. not_yet:
  838. pop di
  839. pop si
  840. pop dx
  841. pop cx
  842. pop bx
  843. pop ds
  844. UnSetKernelDS
  845. dd_no_wdebug:
  846. endif
  847. cEnd
  848. ;-----------------------------------------------------------------------;
  849. ; DebugMovedSegment ;
  850. ; ;
  851. ; Informs debugger of the old and new values for a physical segment. ;
  852. ; ;
  853. ; Arguments: ;
  854. ; SourceSeg - Original segment value. ;
  855. ; DestSeg - New segment value. ;
  856. ; ;
  857. ; Returns: ;
  858. ; None. ;
  859. ; ;
  860. ; Error Returns: ;
  861. ; ;
  862. ; Registers Preserved: ;
  863. ; ;
  864. ; Registers Destroyed: ;
  865. ; ;
  866. ; Calls: ;
  867. ; ;
  868. ; History: ;
  869. ; ;
  870. ; Thu Nov 13, 1986 02:29:15p -by- David N. Weise [davidw] ;
  871. ; Wrote it. ;
  872. ;-----------------------------------------------------------------------;
  873. cProc DebugMovedSegment,<PUBLIC,NEAR>
  874. ParmW SourceSeg
  875. ParmW DestSeg
  876. cBegin
  877. cEnd
  878. ;-----------------------------------------------------------------------;
  879. ; DebugFreeSegment ;
  880. ; ;
  881. ; Informs debugger that a segment is being returned to the global ;
  882. ; memory pool and is no longer code or data. ;
  883. ; ;
  884. ; Arguments: ;
  885. ; SegAddr - segment being freed ;
  886. ; fRelBP - flag indicating if breakpoints should be released, ;
  887. ; -1 means yes ;
  888. ; ;
  889. ; Returns: ;
  890. ; None. ;
  891. ; ;
  892. ; Error Returns: ;
  893. ; ;
  894. ; Registers Preserved: ;
  895. ; ;
  896. ; Registers Destroyed: ;
  897. ; ;
  898. ; Calls: ;
  899. ; ;
  900. ; History: ;
  901. ; ;
  902. ; Thu Nov 13, 1986 02:34:13p -by- David N. Weise [davidw] ;
  903. ; Added this nifty comment block. ;
  904. ;-----------------------------------------------------------------------;
  905. cProc DebugFreeSegment,<PUBLIC,NEAR>,<es>
  906. Parmw SegAddr
  907. parmW fRelBP
  908. cBegin
  909. push ds
  910. SetKernelDS
  911. ifdef WOW
  912. test DebugWOW,DW_DEBUG
  913. jz df_no_wdebug
  914. push SegAddr ; Notify the Win32 debugger that
  915. push fRelBP
  916. mov ax,DBG_SEGFREE ; the selector number needs to be freed
  917. push ax
  918. IFE PMODE
  919. BOP BOP_DEBUGGER
  920. ELSE
  921. FBOP BOP_DEBUGGER,,FastBop
  922. ENDIF
  923. add sp,+6
  924. df_no_wdebug:
  925. endif
  926. test Kernel_Flags[2],KF2_SYMDEB or KF2_PTRACE
  927. pop ds
  928. UnSetKernelDS
  929. jz short killdone
  930. mov bx, SegAddr
  931. mov ax, SDM_FREESEG
  932. inc fRelBP
  933. jnz short @f
  934. mov ax, SDM_RELEASESEG ;free but pulls out breakpoints 1st
  935. @@:
  936. DEBUGCALL
  937. killdone:
  938. cEnd
  939. ;-----------------------------------------------------------------------;
  940. ; DebugWrite ;
  941. ; ;
  942. ; Prints the given string of the given length. If a debugger is ;
  943. ; present tells the debugger to print the message. Otherwise uses ;
  944. ; DOS Function 40h to the con device. ;
  945. ; ;
  946. ; Arguments: ;
  947. ; lpBuf long pointer to string to write ;
  948. ; nBytes # of bytes in string ;
  949. ; ;
  950. ; Returns: ;
  951. ; None. ;
  952. ; ;
  953. ; Error Returns: ;
  954. ; ;
  955. ; Registers Preserved: ;
  956. ; ;
  957. ; Registers Destroyed: ;
  958. ; ;
  959. ; Calls: ;
  960. ; ;
  961. ; History: ;
  962. ; ;
  963. ; Thu Nov 13, 1986 02:53:08p -by- David N. Weise [davidw] ;
  964. ; Added this nifty comment block. ;
  965. ;-----------------------------------------------------------------------;
  966. ifdef WOW
  967. cProc DebugWrite,<PUBLIC,FAR>,<ds,si>
  968. else
  969. cProc DebugWrite,<PUBLIC,NEAR>,<ds,si>
  970. endif
  971. parmD lpBuf
  972. parmW nBytes
  973. localW wHandled
  974. localW SavePDB
  975. cBegin
  976. ;** Validate the pointer and number of bytes
  977. mov ax,WORD PTR lpBuf[0]
  978. add ax,nBytes
  979. jnc SHORT @F
  980. jmp DW_End ;Overflow: error
  981. @@:
  982. if pmode32
  983. .386
  984. push eax ; 32 bit ValidatePointer destroys top half
  985. push ecx ; of eax, ecx which isn't nice in debug outs
  986. .286
  987. endif
  988. push WORD PTR lpBuf[2]
  989. push ax
  990. call ValidatePointer ;Make sure pointer is OK
  991. or ax,ax
  992. if pmode32
  993. .386
  994. pop ecx
  995. pop eax
  996. .286
  997. endif
  998. jnz SHORT @F
  999. jmp DW_End ;Bogus pointer: just return.
  1000. @@: mov cx,nBytes
  1001. lds dx,lpBuf ;DS:DX points to string
  1002. or cx,cx ;Zero length requires computing
  1003. jnz SHORT DW_GoodLen
  1004. ;** Compute string length if a valid length not passed in
  1005. mov si,dx
  1006. cld
  1007. DW_LenLoop:
  1008. lodsb
  1009. or al,al
  1010. jnz short DW_LenLoop
  1011. mov cx,si
  1012. sub cx,dx
  1013. dec cx
  1014. DW_GoodLen:
  1015. ;** Set up for the Int 41h, PTrace, and TOOLHELP interfaces
  1016. mov wHandled,0 ;Flag that we haven't handled yet
  1017. mov si,dx ;Point to string with DS:SI
  1018. push ds ; and ES:SI
  1019. pop es
  1020. ;** Decide which debugger (if any) to send string to
  1021. push ds
  1022. SetKernelDS
  1023. test Kernel_Flags[2],KF2_SYMDEB ;WDEB386 loaded?
  1024. pop ds
  1025. UnSetKernelDS
  1026. jz SHORT DW_TryToolHelp ;No, now try TOOLHELP
  1027. ;** Send to WDEB386
  1028. push si
  1029. DebInt SDM_CONWRITE
  1030. pop si
  1031. mov wHandled,1 ;Assume that WDEB386 handled it
  1032. ;** Send it to TOOLHELP if it is there
  1033. DW_TryToolHelp:
  1034. push ds
  1035. SetKernelDS
  1036. test Kernel_Flags[2],KF2_TOOLHELP ;ToolHelp around?
  1037. pop ds
  1038. UnSetKernelDS
  1039. jz SHORT DW_TryPTrace ;Nope, now try PTrace
  1040. push ds
  1041. SetKernelDS
  1042. push Win_PDB ;Save current PDB
  1043. cmp curTDB,0
  1044. jz @F
  1045. push es ; and set to current task's PDB
  1046. mov es,curTDB ; for toolhelp call.
  1047. push es:[TDB_PDB]
  1048. pop ds:Win_PDB
  1049. pop es
  1050. @@:
  1051. mov ax,SDM_CONWRITE ;Notification ID
  1052. call lpfnToolHelpProc ;String in ES:SI for TOOLHELP
  1053. pop Win_PDB ;Restore current PDB
  1054. or ax,ax ;TOOLHELP client say to pass it on?
  1055. pop ds
  1056. UnSetKernelDS
  1057. jnz SHORT DW_End ;No, we're done
  1058. ;** Handle PTrace
  1059. DW_TryPTrace:
  1060. SetKernelDS es
  1061. cmp WORD PTR es:ptrace_dll_entry[2],0 ;WINDEBUG.DLL lurking around?
  1062. jz SHORT DW_WriteToCOM ;No, try COM port
  1063. ;** If we're exiting a task, don't send the debug write to PTrace.
  1064. ;** This is a gross hack for QCWin who chokes on these. These
  1065. ;** were being sent because of parameter validation errors.
  1066. push ax ;Temp reg
  1067. mov ax,es:curTDB
  1068. cmp ax,es:wExitingTDB
  1069. pop ax
  1070. je DW_WriteToCOM ;Write out directly
  1071. IF KDEBUG
  1072. ;** If we're sending a KERNEL trace out, we don't want to send this
  1073. ;** to PTrace, either
  1074. cmp fKTraceOut, 0 ;Are we doing a KERNEL trace out?
  1075. jne DW_WriteToCOM ;Yes, don't call PTrace
  1076. ENDIF
  1077. ;** Now send to PTrace
  1078. mov wHandled,1 ;Assume WINDEBUG handles if present
  1079. push ax ;Save regs PTrace might trash
  1080. push si
  1081. push dx
  1082. push ds
  1083. push es
  1084. mov ax,SDM_CONWRITE ;Notification ID
  1085. call es:ptrace_DLL_entry ;Do the PTrace thing
  1086. pop es
  1087. pop ds
  1088. pop dx
  1089. pop si
  1090. pop ax
  1091. ;** Write string to debug terminal
  1092. DW_WriteToCOM:
  1093. cmp wHandled,0 ;Handled?
  1094. jnz SHORT DW_End ;Yes
  1095. inc es:fDW_Int21h ; Skip it if user has canceled
  1096. jnz SHORT DW_Skip_Write ; a crit error on this before
  1097. mov ax, es:topPDB
  1098. xchg es:Win_PDB, ax ; Switch to Kernel's PDB,
  1099. mov SavePDB, ax ; saving current PDB
  1100. ifdef WOW
  1101. cCall WOWOutputDebugString,<lpBuf>
  1102. else
  1103. mov bx,3 ;Send to DOS AUX port
  1104. mov ah,40h
  1105. int 21h
  1106. endif; WOW
  1107. mov ax, SavePDB
  1108. mov es:Win_PDB, ax ; restore app pdb
  1109. DW_Skip_Write:
  1110. dec es:fDW_Int21h
  1111. DW_End:
  1112. UnSetKernelDS
  1113. UnSetKernelDS es
  1114. cEnd
  1115. ;-----------------------------------------------------------------------;
  1116. ; OutputDebugString ;
  1117. ; ;
  1118. ; A routine callable from anywhere since it is exported. It calls ;
  1119. ; DebugWrite to do its dirty work. ;
  1120. ; ;
  1121. ; Arguments: ;
  1122. ; lpStr long pointer to null terminated string ;
  1123. ; ;
  1124. ; Returns: ;
  1125. ; none ;
  1126. ; ;
  1127. ; Error Returns: ;
  1128. ; ;
  1129. ; Registers Preserved: ;
  1130. ; all ;
  1131. ; ;
  1132. ; Registers Destroyed: ;
  1133. ; ;
  1134. ; Calls: ;
  1135. ; ;
  1136. ; History: ;
  1137. ; ;
  1138. ; Tue June 28, 1988 -by- Ken Shirriff [t-kens] ;
  1139. ; Made it save all the registers. ;
  1140. ; ;
  1141. ; Thu Nov 13, 1986 02:54:36p -by- David N. Weise [davidw] ;
  1142. ; Added this nifty comment block. ;
  1143. ;-----------------------------------------------------------------------;
  1144. cProc OutputDebugString,<PUBLIC,FAR,NODATA>,<es>
  1145. parmD lpStr
  1146. cBegin
  1147. pusha
  1148. ifdef WOW
  1149. cCall <far ptr DebugWrite>,<lpStr, 0>
  1150. else
  1151. cCall DebugWrite,<lpStr, 0>
  1152. endif
  1153. popa
  1154. cEnd
  1155. ;-----------------------------------------------------------------------;
  1156. ; DebugRead ;
  1157. ; ;
  1158. ; Gets a character from either the debugger (if one is present) or ;
  1159. ; from the AUX. ;
  1160. ; ;
  1161. ; Arguments: ;
  1162. ; none ;
  1163. ; ;
  1164. ; Returns: ;
  1165. ; AL = character ;
  1166. ; ;
  1167. ; Error Returns: ;
  1168. ; ;
  1169. ; Registers Preserved: ;
  1170. ; ;
  1171. ; Registers Destroyed: ;
  1172. ; ;
  1173. ; Calls: ;
  1174. ; ;
  1175. ; History: ;
  1176. ; ;
  1177. ; Thu Nov 13, 1986 02:55:09p -by- David N. Weise [davidw] ;
  1178. ; Added this nifty comment block. ;
  1179. ;-----------------------------------------------------------------------;
  1180. cProc DebugRead,<PUBLIC,NEAR>
  1181. cBegin nogen
  1182. push ds
  1183. SetKernelDS
  1184. ;** Send it to the debugger(s) FIRST
  1185. mov ax,SDM_CONREAD ;Get the notification ID
  1186. ; This sure is weird! Goal is to ask if WDEB386 has a char
  1187. ; available. If so, return.
  1188. ; We do the check here because MyDebugCall assumes INT41
  1189. ; doesn't modify registers, but the CONREAD call does.
  1190. ; This was hosing TOOLHELP, since we were passing a different
  1191. ; function to TOOLHELP based on what char a user was pressing.
  1192. test Kernel_Flags[2],KF2_SYMDEB ; WDEB386 loaded?
  1193. jz short dr_symdeb ; no - MyDebugCall
  1194. DebInt ; Yes - read CON
  1195. cmp ax, SDM_CONREAD
  1196. jnz @F ; got a response - continue.
  1197. dr_symdeb:
  1198. DEBUGCALL
  1199. @@:
  1200. ;** See if we should still hand it to the AUX port
  1201. cmp al,SDM_CONREAD ;If not changed, we didn't get a character
  1202. jne SHORT DR_End
  1203. mov ax, wDefRIP ;Do we have a default value to use?
  1204. or ax, ax
  1205. jnz DR_End
  1206. xor cx,cx ;Allocate WORD to read into
  1207. push cx
  1208. mov dx,sp ;Point with DS:DX
  1209. push ss
  1210. pop ds
  1211. inc cx ;Get one byte
  1212. DR_ConLoop:
  1213. ifdef WOW
  1214. int 3 ; BUGBUG mattfe 29-mar-92, should be thunked to 32 bit side.
  1215. endif
  1216. mov bx,3 ;Use AUX
  1217. mov ah,3fh ;Read device
  1218. int 21h ;Call DOS
  1219. cmp ax,cx ;Did we get a byte?
  1220. jne SHORT DR_ConLoop ;No, try again
  1221. pop ax ;Get the byte read
  1222. DR_End:
  1223. pop ds
  1224. ret
  1225. cEnd nogen
  1226. ;-----------------------------------------------------------------------;
  1227. ; DebugDefineLine ;
  1228. ; ;
  1229. ; Notifies debugger of the location of The Line. ;
  1230. ; ;
  1231. ; Arguments: ;
  1232. ; None ;
  1233. ; ;
  1234. ; Returns: ;
  1235. ; None ;
  1236. ; ;
  1237. ; Registers Destroyed: ;
  1238. ; ;
  1239. ; History: ;
  1240. ; Mon 20-Jun-1988 13:17:41 -by- David N. Weise [davidw] ;
  1241. ; Moved it here. ;
  1242. ;-----------------------------------------------------------------------;
  1243. ;
  1244. ; assumes ds,nothing
  1245. ; assumes es,nothing
  1246. ;
  1247. ;cProc DebugDefineLine,<PUBLIC,NEAR>
  1248. ;
  1249. ;cBegin nogen
  1250. ; ret
  1251. ;cEnd nogen
  1252. ;
  1253. ;cProc FarDebugNewTask,<PUBLIC,FAR>
  1254. ;
  1255. ;cBegin nogen
  1256. ; call DebugNewTask
  1257. ; ret
  1258. ;cEnd nogen
  1259. ;
  1260. ;
  1261. ;-----------------------------------------------------------------------;
  1262. ; DebugNewTask ;
  1263. ; ;
  1264. ; ;
  1265. ; Arguments: ;
  1266. ; AX = EMS PID ;
  1267. ; ;
  1268. ; Returns: ;
  1269. ; None ;
  1270. ; ;
  1271. ; Error Returns: ;
  1272. ; ;
  1273. ; Registers Preserved: ;
  1274. ; ;
  1275. ; Registers Destroyed: ;
  1276. ; ;
  1277. ; Calls: ;
  1278. ; ;
  1279. ; History: ;
  1280. ; ;
  1281. ;-----------------------------------------------------------------------;
  1282. ;
  1283. ;cProc DebugNewTask,<PUBLIC,NEAR>
  1284. ;
  1285. ;cBegin nogen
  1286. ; ret
  1287. ;cEnd nogen
  1288. ;
  1289. ;cProc FarDebugFlushTask,<PUBLIC,FAR>
  1290. ;
  1291. ;cBegin nogen
  1292. ; call DebugFlushTask
  1293. ; ret
  1294. ;cEnd nogen
  1295. ;
  1296. ;-----------------------------------------------------------------------;
  1297. ; DebugFlushTask ;
  1298. ; ;
  1299. ; ;
  1300. ; Arguments: ;
  1301. ; AX = EMS PID ;
  1302. ; ;
  1303. ; Returns: ;
  1304. ; None ;
  1305. ; ;
  1306. ; Error Returns: ;
  1307. ; ;
  1308. ; Registers Preserved: ;
  1309. ; ;
  1310. ; Registers Destroyed: ;
  1311. ; ;
  1312. ; Calls: ;
  1313. ; ;
  1314. ; History: ;
  1315. ; ;
  1316. ;-----------------------------------------------------------------------;
  1317. ;
  1318. ;cProc DebugFlushTask,<PUBLIC,NEAR>
  1319. ;
  1320. ;cBegin nogen
  1321. ; ret
  1322. ;cEnd nogen
  1323. ;-----------------------------------------------------------------------;
  1324. ; DebugSwitchOut ;
  1325. ; ;
  1326. ; ;
  1327. ; Arguments: ;
  1328. ; DS = TDB ;
  1329. ; ;
  1330. ; Returns: ;
  1331. ; None ;
  1332. ; ;
  1333. ; Error Returns: ;
  1334. ; ;
  1335. ; Registers Preserved: ;
  1336. ; All ;
  1337. ; ;
  1338. ; Registers Destroyed: ;
  1339. ; ;
  1340. ; Calls: ;
  1341. ; ;
  1342. ; History: ;
  1343. ; ;
  1344. ;-----------------------------------------------------------------------;
  1345. cProc DebugSwitchOut,<PUBLIC,NEAR>
  1346. cBegin nogen
  1347. push ds
  1348. SetKernelDS
  1349. test Kernel_Flags[2],KF2_PTRACE
  1350. pop ds
  1351. UnSetKernelDS
  1352. jz short dso_done
  1353. push ax
  1354. mov ax,SDM_SWITCHOUT
  1355. DEBUGCALL
  1356. pop ax
  1357. dso_done:
  1358. ret
  1359. cEnd nogen
  1360. ;-----------------------------------------------------------------------;
  1361. ; DebugSwitchIn ;
  1362. ; ;
  1363. ; ;
  1364. ; Arguments: ;
  1365. ; DS = TDB ;
  1366. ; ;
  1367. ; Returns: ;
  1368. ; None ;
  1369. ; ;
  1370. ; Error Returns: ;
  1371. ; ;
  1372. ; Registers Preserved: ;
  1373. ; All ;
  1374. ; ;
  1375. ; Registers Destroyed: ;
  1376. ; ;
  1377. ; Calls: ;
  1378. ; ;
  1379. ; History: ;
  1380. ; ;
  1381. ;-----------------------------------------------------------------------;
  1382. cProc DebugSwitchIn,<PUBLIC,NEAR>
  1383. cBegin nogen
  1384. push ds
  1385. SetKernelDS
  1386. test Kernel_Flags[2],KF2_PTRACE
  1387. pop ds
  1388. UnSetKernelDS
  1389. jz short dsi_done
  1390. push ax
  1391. mov ax,SDM_SWITCHIN
  1392. DEBUGCALL
  1393. pop ax
  1394. dsi_done:
  1395. ret
  1396. cEnd nogen
  1397. ;-----------------------------------------------------------------------;
  1398. ; DebugExitCall
  1399. ;
  1400. ; Notifies the debugger than an app is quitting. This gets
  1401. ; called at the top of ExitCall.
  1402. ;
  1403. ; Entry:
  1404. ;
  1405. ; Returns:
  1406. ;
  1407. ; Registers Preserved:
  1408. ; all
  1409. ;
  1410. ; History:
  1411. ; Thu 11-May-1989 08:58:40 -by- David N. Weise [davidw]
  1412. ; Wrote it!
  1413. ;-----------------------------------------------------------------------;
  1414. assumes ds,nothing
  1415. assumes es,nothing
  1416. cProc DebugExitCall,<PUBLIC,NEAR>
  1417. cBegin nogen
  1418. ;
  1419. ; Windebug knows where this is. See MyDebugCall() comment.
  1420. ;
  1421. ifdef WOW
  1422. push ds
  1423. SetKernelDS
  1424. test DebugWOW,DW_DEBUG
  1425. jz de_no_wdebug
  1426. push ax
  1427. push es
  1428. mov es,bx ; Get the current TDB
  1429. push es ; hTask
  1430. mov ax,es:[TDB_pModule] ; Get the module handle
  1431. mov es,ax
  1432. push es ; hModule
  1433. push es ; Pointer to module name
  1434. push es:ne_restab
  1435. push es ; Pointer to module path
  1436. push word ptr es:ne_crc+2
  1437. mov ax,DBG_TASKSTOP ; the selector number needs to be freed
  1438. push ax
  1439. FBOP BOP_DEBUGGER,,FastBop
  1440. add sp,+14
  1441. pop es ; Restore original ES
  1442. pop ax
  1443. de_no_wdebug:
  1444. pop ds
  1445. UnSetKernelDS
  1446. endif
  1447. push ax
  1448. mov bl,al ;Exit code in BL
  1449. mov ax,SDM_EXITCALL
  1450. DEBUGCALL
  1451. pop ax
  1452. ret
  1453. cEnd nogen
  1454. ;-----------------------------------------------------------------------;
  1455. ; FarDebugDelModule
  1456. ;
  1457. ; Notifies the debugger than a module is being deleted. This gets
  1458. ; called at the top of ExitCall.
  1459. ;
  1460. ; Entry:
  1461. ; ES = module handle
  1462. ;
  1463. ; Returns:
  1464. ;
  1465. ; Registers Reserved:
  1466. ; all
  1467. ;
  1468. ; History:
  1469. ; Mon 11-Sep-1989 18:34:06 -by- David N. Weise [davidw]
  1470. ; Wrote it!
  1471. ;-----------------------------------------------------------------------;
  1472. assumes ds,nothing
  1473. assumes es,nothing
  1474. cProc FarDebugDelModule,<PUBLIC,FAR>
  1475. ifdef WOW
  1476. localV nameBuf,130
  1477. localV ModName,64
  1478. endif
  1479. cBegin nogen
  1480. push es
  1481. ifdef WOW
  1482. push ds
  1483. push es
  1484. SetKernelDS
  1485. test DebugWOW,DW_DEBUG
  1486. jnz @f
  1487. jmp fdd_no_wdebug
  1488. @@: push di
  1489. push si
  1490. push cx
  1491. xor cx,cx
  1492. mov ax,es
  1493. mov ds,ax
  1494. mov si,es:[ne_restab]
  1495. mov cl,[si]
  1496. inc si
  1497. cmp cl,64
  1498. jb @f
  1499. mov cl,63
  1500. @@:
  1501. mov ax,ss
  1502. mov es,ax
  1503. lea di,ModName
  1504. rep movsb ; Copy module name from resource
  1505. mov byte ptr es:[di],0 ; table and null terminate it
  1506. mov ax,ds
  1507. mov es,ax
  1508. lea di,nameBuf
  1509. push ax
  1510. push ss
  1511. push di
  1512. mov ax, 130
  1513. push ax
  1514. call GetModuleFileName
  1515. SetKernelDS
  1516. lea di,nameBuf
  1517. push ss
  1518. push di
  1519. lea di,ModName
  1520. push ss
  1521. push di
  1522. push DBG_MODFREE
  1523. IFE PMODE
  1524. BOP BOP_DEBUGGER
  1525. ELSE
  1526. FBOP BOP_DEBUGGER,,FastBop
  1527. ENDIF
  1528. add sp,+10
  1529. pop cx
  1530. pop si
  1531. pop di
  1532. fdd_no_wdebug:
  1533. pop es
  1534. pop ds
  1535. UnSetKernelDS
  1536. endif; WOW
  1537. mov ax,SDM_DELMODULE
  1538. DEBUGCALL
  1539. add sp,2
  1540. ret
  1541. cEnd nogen
  1542. ;-----------------------------------------------------------------------;
  1543. ; void DebugLogError(WORD err, VOID FAR* lpInfo);
  1544. ;
  1545. ; Notifies debugger of a LogError() call.
  1546. ;
  1547. ;-----------------------------------------------------------------------;
  1548. assumes ds,nothing
  1549. assumes es,nothing
  1550. cProc DebugLogError,<PUBLIC,NEAR>
  1551. ;ParmW err
  1552. cBegin nogen
  1553. pop ax
  1554. pop bx ; dx:bx = lpInfo
  1555. pop dx
  1556. pop cx ; cx = error code
  1557. push ax
  1558. mov ax,SDM_LOGERROR
  1559. jmp short MyDebugCall
  1560. cEnd nogen
  1561. ;-----------------------------------------------------------------------;
  1562. ; void DebugLogParamError(VOID FAR* param, FARPROC lpfn, WORD err);
  1563. ;
  1564. ; Notifies debugger of a LogParamError() call.
  1565. ;
  1566. ; NOTE: the parameters are passed in the REVERSE order than expected,
  1567. ; so that the stack layout is natural when we do the DebugCall.
  1568. ;
  1569. ;-----------------------------------------------------------------------;
  1570. assumes ds,nothing
  1571. assumes es,nothing
  1572. cProc DebugLogParamError,<PUBLIC,NEAR>
  1573. ;ParmD param
  1574. ;ParmD lpfn
  1575. ;ParmW err
  1576. cBegin nogen
  1577. ;
  1578. ; es:bx = pointer to struct containing args
  1579. ;
  1580. mov bx,sp
  1581. add bx,2 ; point past return addr.
  1582. push ss
  1583. pop es
  1584. mov ax,SDM_LOGPARAMERROR
  1585. call MyDebugCall
  1586. ret 2+4+4
  1587. cEnd nogen
  1588. ;------------------------------------------------------------------------
  1589. ;
  1590. ; MyDebugCall
  1591. ;
  1592. ; Call the debugger interface. Created to reduce references to kernel
  1593. ; data segment.
  1594. ;
  1595. ;------------------------------------------------------------------------
  1596. assumes ds,nothing
  1597. assumes es,nothing
  1598. cProc MyFarDebugCall, <FAR,PUBLIC>
  1599. cBegin nogen
  1600. cCall MyDebugCall
  1601. retf
  1602. cEnd nogen
  1603. cProc MyDebugCall,<NEAR,PUBLIC>
  1604. cBegin nogen
  1605. push ds
  1606. SetKernelDS
  1607. test Kernel_Flags[2],KF2_SYMDEB
  1608. jz short no_symdeb
  1609. cmp ax,SDM_SWITCHOUT ; Don't give these to WDEB.
  1610. je no_symdeb
  1611. cmp ax,SDM_SWITCHIN
  1612. je no_symdeb
  1613. pop ds ; Too bad some Int 41h services
  1614. UnSetKernelDS ; require segment reg params
  1615. DebInt
  1616. push ds
  1617. SetKernelDS
  1618. no_symdeb:
  1619. ;** Check for TOOLHELP's hook. We always send it here first
  1620. ;** This callback does NOT depend on what's on the stack.
  1621. test Kernel_Flags[2],KF2_TOOLHELP ;TOOLHELP hook?
  1622. jz SHORT MDC_NoToolHelp ;No
  1623. push ax
  1624. push Win_PDB ; Preserve Win_TDB across ToolHelp call
  1625. cmp curTDB,0
  1626. jz @F
  1627. push es
  1628. mov es,curTDB
  1629. push es:[TDB_PDB]
  1630. pop ds:Win_PDB
  1631. pop es
  1632. @@:
  1633. ;** Just call the TOOLHELP callback. It preserves all registers
  1634. ;** except AX where it returns nonzero if the notification
  1635. ;** was handled.
  1636. call lpfnToolHelpProc ;Do it
  1637. pop Win_PDB ; Restore Win_TDB
  1638. or ax,ax ;Did the TOOLHELP client say to
  1639. ; pass it on?
  1640. jz SHORT @F ;Yes
  1641. add sp,2 ;No, so return TOOLHELP's return value
  1642. jmp SHORT no_ptrace
  1643. @@: pop ax ;Restore notification ID
  1644. MDC_NoToolHelp:
  1645. ;** Make sure we don't have a new notification. If it's newer than
  1646. ;* CVW, CVW chokes on it so we can't send new notifications
  1647. ;** through PTrace.
  1648. cmp ax,SDM_DELMODULE ;Last old notification
  1649. ja short no_ptrace ;Don't send new notification
  1650. MDC_PTraceOk:
  1651. cmp WORD PTR ptrace_dll_entry[2],0 ;WINDEBUG.DLL lurking around?
  1652. jz SHORT no_ptrace
  1653. ; !!!!!!!!!!!!!! HACK ALERT !!!!!!!!!!!!!!
  1654. ;
  1655. ; Windebug.DLL for Windows 3.0 knows exactly what is on the stack
  1656. ; when Kernel makes a PTrace callout. For this reason, we cannot
  1657. ; change what is on the stack when we make one of these calls.
  1658. ; This stuff below fakes a FAR return to our NEAR caller, and jumps
  1659. ; to the PTrace DLL entry with all registers intact.
  1660. ;
  1661. ; SP -> DS RET
  1662. sub sp,8
  1663. push bp
  1664. mov bp,sp
  1665. ; BP -> BP xx xx xx xx DS KERNEL_RET
  1666. mov [bp+2],ax ; save AX
  1667. mov ax,[bp+10] ; move saved DS
  1668. mov [bp+4],ax
  1669. mov ax,[bp+12] ; convert near RET to far
  1670. mov [bp+10],ax
  1671. mov [bp+12],cs
  1672. mov ax,word ptr ptrace_dll_entry[2] ; CS of Routine to invoke
  1673. mov [bp+8],ax
  1674. mov ax,word ptr ptrace_dll_entry ; IP of Routine to invoke
  1675. mov [bp+6],ax
  1676. ; SP -> BP AX DS PTRACE_IP PTRACE_CS KERNEL_RET KERNEL_CS
  1677. pop bp
  1678. pop ax
  1679. pop ds
  1680. UnSetKernelDS
  1681. retf
  1682. no_ptrace:
  1683. pop ds
  1684. UnSetKernelDS
  1685. ret
  1686. cEnd nogen
  1687. if KDEBUG
  1688. dout macro var
  1689. mov byte ptr ss:[si],var
  1690. inc si
  1691. endm
  1692. ;-----------------------------------------------------------------------;
  1693. ; hex ;
  1694. ; ;
  1695. ; Outputs byte in AL as two hex digits. ;
  1696. ; ;
  1697. ; Arguments: ;
  1698. ; AL = 8-bit value to be output ;
  1699. ; SS:SI = where it's to be put ;
  1700. ; ;
  1701. ; Returns: ;
  1702. ; ;
  1703. ; Error Returns: ;
  1704. ; ;
  1705. ; Registers Preserved: ;
  1706. ; ;
  1707. ; Registers Destroyed: ;
  1708. ; ;
  1709. ; Calls: ;
  1710. ; ;
  1711. ; History: ;
  1712. ; ;
  1713. ; Fri Nov 14, 1986 02:32:15p -by- David N. Weise [davidw] ;
  1714. ; Modified it from symdeb\debug.asm. ;
  1715. ;-----------------------------------------------------------------------;
  1716. ifndef WOW
  1717. cProc hex,<NEAR>
  1718. cBegin nogen
  1719. mov ah,al ; save for second digit
  1720. ; shift high digit into low 4 bits
  1721. mov cl,4
  1722. shr al,cl
  1723. and al,0Fh ; mask to 4 bits
  1724. add al,90h
  1725. daa
  1726. adc al,40h
  1727. daa
  1728. dout al
  1729. mov al,ah ; now do digit saved in ah
  1730. and al,0Fh ; mask to 4 bits
  1731. add al,90h
  1732. daa
  1733. adc al,40h
  1734. daa
  1735. dout al
  1736. ret
  1737. cEnd nogen
  1738. ;-----------------------------------------------------------------------;
  1739. ; pdref_norip ;
  1740. ; ;
  1741. ; Dereferences the given global handle, i.e. gives back abs. address. ;
  1742. ; ;
  1743. ; Arguments: ;
  1744. ; DX = selector ;
  1745. ; DS:DI = BURGERMASTER ;
  1746. ; ;
  1747. ; Returns: ;
  1748. ; FS:ESI = address of arena header ;
  1749. ; AX = address of client data ;
  1750. ; CH = lock count or 0 for fixed objects ;
  1751. ; CL = flags ;
  1752. ; DX = handle, 0 for fixed objects ;
  1753. ; ;
  1754. ; Error Returns: ;
  1755. ; ZF = 1 if invalid or discarded ;
  1756. ; AX = 0 ;
  1757. ; BX = owner of discarded object ;
  1758. ; SI = handle of discarded object ;
  1759. ; ;
  1760. ; Registers Preserved: ;
  1761. ; ;
  1762. ; Registers Destroyed: ;
  1763. ; ;
  1764. ; Calls: ;
  1765. ; ghdref ;
  1766. ; ;
  1767. ; History: ;
  1768. ; ;
  1769. ;-----------------------------------------------------------------------;
  1770. if pmode32
  1771. .386p
  1772. assumes ds,nothing
  1773. assumes es,nothing
  1774. cProc pdref_norip,<PUBLIC,NEAR>
  1775. cBegin nogen
  1776. ; DPMI - no LDT access
  1777. mov si, dx
  1778. sel_check si
  1779. or si, si ; Null handle?
  1780. jnz short OK1
  1781. mov ax, si ; yes, return 0
  1782. jmps pd_exit
  1783. OK1:
  1784. lar eax, edx
  1785. jnz short pd_totally_bogus
  1786. shr eax, 8
  1787. ; We should beef up the check for a valid discarded sel.
  1788. xor cx,cx
  1789. test ah, DSC_DISCARDABLE
  1790. jz short pd_not_discardable
  1791. or cl, GA_DISCARDABLE
  1792. ; Discardable, is it code?
  1793. test al, DSC_CODE_BIT
  1794. jz short pd_not_code
  1795. or cl,GA_DISCCODE
  1796. pd_not_code:
  1797. pd_not_discardable:
  1798. test al, DSC_PRESENT
  1799. jnz short pd_not_discarded
  1800. ; object discarded
  1801. or cl,HE_DISCARDED
  1802. if PMODE32
  1803. ; On WOW we don't copy the owner to the real LDT since it is slow to call
  1804. ; the NT Kernel, so we read our copy of it directly.
  1805. ; see set_discarded_sel_owner mattfe mar 23 93
  1806. mov ax,es ; save es
  1807. mov bx,dx
  1808. mov es,cs:gdtdsc
  1809. and bl, not 7
  1810. mov bx,es:[bx].dsc_owner
  1811. mov es,ax ; restore
  1812. else
  1813. lsl bx, dx ; get the owner
  1814. endif
  1815. or si, SEG_RING-1 ; Handles are RING 2
  1816. xor ax,ax
  1817. jmps pd_exit
  1818. pd_not_discarded:
  1819. cCall get_arena_pointer32,<dx>
  1820. mov esi, eax
  1821. mov ax, dx
  1822. or esi, esi ; Unknown selector
  1823. jz short pd_maybe_alias
  1824. mov dx, ds:[esi].pga_handle
  1825. cmp dx, ax ; Quick check - handle in header
  1826. je short pd_match ; matches what we were given?
  1827. test al, 1 ; NOW, we MUST have been given
  1828. jz short pd_totally_bogus ; a selector address.
  1829. push ax
  1830. StoH ax ; Turn into handle
  1831. cmp dx, ax
  1832. pop ax
  1833. jne short pd_nomatch
  1834. pd_match:
  1835. or cl, ds:[esi].pga_flags
  1836. and cl, NOT HE_DISCARDED ; same as GA_NOTIFY!!
  1837. mov ax, dx ; Get address in AX
  1838. test dl, GA_FIXED ; DX contains handle
  1839. jnz short pd_fixed ; Does handle need derefencing?
  1840. mov ch, ds:[esi].pga_count
  1841. HtoS ax ; Dereference moveable handle
  1842. jmps pd_exit
  1843. pd_totally_bogus:
  1844. xor ax,ax
  1845. pd_maybe_alias:
  1846. pd_nomatch: ; Handle did not match...
  1847. xor dx, dx
  1848. pd_fixed:
  1849. pd_exit:
  1850. or ax,ax
  1851. ret
  1852. cEnd nogen
  1853. .286p
  1854. endif
  1855. ;-----------------------------------------------------------------------;
  1856. ; xhandle_norip ;
  1857. ; ;
  1858. ; Returns the handle for a global segment. ;
  1859. ; ;
  1860. ; Arguments: ;
  1861. ; Stack = sp -> near return return address ;
  1862. ; sp+2 -> far return return address of caller ;
  1863. ; sp+6 -> segment address parameter ;
  1864. ; ;
  1865. ; Returns: ;
  1866. ; Old DS,DI have been pushed on the stack ;
  1867. ; ;
  1868. ; ZF= 1 if fixed segment. ;
  1869. ; AX = handle ;
  1870. ; ;
  1871. ; ZF = 0 ;
  1872. ; AX = handle ;
  1873. ; BX = pointer to handle table entry ;
  1874. ; CX = flags and count word from handle table ;
  1875. ; DX = segment address ;
  1876. ; ES:DI = arena header of object ;
  1877. ; DS:DI = master object segment address ;
  1878. ; ;
  1879. ; Error Returns: ;
  1880. ; AX = 0 if invalid segment address ;
  1881. ; ZF = 1 ;
  1882. ; ;
  1883. ; Registers Preserved: ;
  1884. ; ;
  1885. ; Registers Destroyed: ;
  1886. ; ;
  1887. ; Calls: ;
  1888. ; ;
  1889. ; History: ;
  1890. ; ;
  1891. ; Thu Oct 16, 1986 02:40:08p -by- David N. Weise [davidw] ;
  1892. ; Added this nifty comment block. ;
  1893. ;-----------------------------------------------------------------------;
  1894. if pmode32
  1895. .386p
  1896. cProc xhandle_norip,<PUBLIC,NEAR>
  1897. cBegin nogen
  1898. pop dx ; Get near return address
  1899. mov bx,sp ; Get seg parameter from stack
  1900. mov ax,ss:[bx+4]
  1901. cmp ax,-1 ; Is it -1?
  1902. jnz short xh1
  1903. mov ax,ds ; Yes, use callers DS
  1904. xh1: inc bp
  1905. push bp
  1906. mov bp,sp
  1907. push ds ; Save DS:DI
  1908. push edi
  1909. push esi
  1910. SetKernelDS
  1911. mov ds, pGlobalHeap ; Point to master object
  1912. UnSetKernelDS
  1913. xor edi,edi
  1914. inc [di].gi_lrulock
  1915. push dx
  1916. mov dx,ax
  1917. call pdref_norip
  1918. xchg dx,ax ; get seg address in DX
  1919. jz short xhandle_ret ; invalid or discarded handle
  1920. test al, GA_FIXED
  1921. jnz short xhandle_fixed
  1922. or ax, ax
  1923. jmps xhandle_ret
  1924. xhandle_fixed:
  1925. xor bx, bx ; Set ZF
  1926. xhandle_ret:
  1927. ret
  1928. cEnd nogen
  1929. .286p
  1930. else ; !pmode32
  1931. cProc xhandle_norip,<PUBLIC,NEAR>
  1932. cBegin nogen
  1933. pop dx ; Get near return address
  1934. mov bx,sp ; Get seg parameter from stack
  1935. mov ax,ss:[bx+4]
  1936. cmp ax,-1 ; Is it -1?
  1937. jnz xh1
  1938. mov ax,ds ; Yes, use callers DS
  1939. xh1: inc bp
  1940. push bp
  1941. mov bp,sp
  1942. push ds ; Save DS:DI
  1943. push di
  1944. call genter
  1945. push dx
  1946. mov dx,ax
  1947. push si
  1948. externNP pdref
  1949. call pdref
  1950. xchg dx,ax ; get seg address in DX
  1951. jz xhandle_ret ; invalid or discarded handle
  1952. mov bx,si
  1953. or si,si
  1954. jz xhandle_ret
  1955. mov ax,si
  1956. xhandle_ret:
  1957. pop si
  1958. ret
  1959. cEnd nogen
  1960. endif ; !pmode32
  1961. endif ;ifndef WOW
  1962. endif ;KDEBUG
  1963. cProc ReplaceInst,<PUBLIC,FAR>
  1964. ;; parmD bpaddress
  1965. ;; parmW instruct
  1966. cBegin nogen
  1967. ret 6
  1968. cEnd nogen
  1969. sEnd CODE
  1970. end