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.

1533 lines
31 KiB

  1. TITLE LDINT - Loader interrupt procedure
  2. .xlist
  3. include kernel.inc
  4. include newexe.inc
  5. include tdb.inc
  6. include protect.inc
  7. include dbgsvc.inc
  8. include bop.inc
  9. include kdos.inc
  10. include gpcont.inc ; SHERLOCK
  11. ifdef WOW
  12. include vint.inc
  13. include softpc.inc
  14. endif
  15. NOTEXT = 1
  16. NOGDICAPMASKS = 1
  17. NOMB = 1
  18. NOVK = 1
  19. NOWH = 1
  20. NOMST = 1
  21. NORASTOPS = 1
  22. NOMETAFILE = 1
  23. NOMDI = 1
  24. NOWINMESSAGES = 1
  25. NOSYSMETRICS = 1
  26. NOCOLOR = 1
  27. NOCOMM = 1
  28. NOKERNEL = 1
  29. include windows.inc ; YIKES!!!
  30. .list
  31. FAULTSTACKFRAME struc
  32. fsf_BP dw ? ; Saved BP
  33. fsf_msg dw ? ; Near pointer to message describing fault
  34. fsf_prev_IP dw ? ; IP of previous fault handler
  35. fsf_prev_CS dw ? ; CS of previous fault handler
  36. fsf_ret_IP dw ? ; DPMI fault handler frame follows
  37. fsf_ret_CS dw ?
  38. fsf_err_code dw ?
  39. fsf_faulting_IP dw ?
  40. fsf_faulting_CS dw ?
  41. fsf_flags dw ?
  42. fsf_SP dw ?
  43. fsf_SS dw ?
  44. FAULTSTACKFRAME ends
  45. fsf_OFFSET = fsf_ret_IP - fsf_msg
  46. UAE_STRING_LEN equ 192d
  47. MIN_SP equ 256d
  48. externFP ExitKernel
  49. DataBegin
  50. ;externB syserr
  51. externB szAbort
  52. externB szAbortCaption
  53. externB szNukeApp
  54. externB szWillClose
  55. externB szBlame
  56. externB szSnoozer
  57. externB szInModule
  58. externB szAt
  59. externB szII
  60. externB szGP
  61. externB szSF
  62. externB szNP
  63. externB szLoad
  64. ;externB szDiscard
  65. externB szPF
  66. externB Kernel_Flags
  67. externB fBooting
  68. externW curTDB
  69. ;externW pGlobalHeap
  70. externW DemandLoadSel
  71. externD pSErrProc
  72. externD pUserGetFocus
  73. externD pUserGetWinTask
  74. externD pUserIsWindow
  75. externD lpGPChain
  76. if kdebug
  77. globalw wFaultSegNo,0
  78. endif
  79. if ROM
  80. externD prevIntx6proc
  81. externD prevInt0Cproc
  82. externD prevInt0Dproc
  83. externD prevInt0Eproc
  84. externD prevInt3Fproc
  85. endif
  86. if KDEBUG
  87. staticW INT3Fcs,0
  88. endif
  89. globalW FaultHandler,<codeOffset HandleFault>
  90. externD pPostMessage
  91. ifdef WOW
  92. externD FastBop
  93. externD prevInt01proc
  94. externD prevInt03proc
  95. externD oldInt00proc
  96. externW DebugWOW
  97. externW gdtdsc
  98. endif
  99. DataEnd
  100. sBegin DATA
  101. externW gmove_stack
  102. externW TraceOff
  103. sEnd DATA
  104. sBegin CODE
  105. assumes CS,CODE
  106. if SHERLOCK
  107. externNP GPContinue
  108. endif
  109. ife ROM
  110. externD prevIntx6proc
  111. externD prevInt0Cproc
  112. externD prevInt0Dproc
  113. externD prevInt0Eproc
  114. externD prevInt3Fproc
  115. endif
  116. externNP LoadSegment
  117. ;externNP MyLock
  118. ifndef WOW
  119. externNP htoa
  120. endif
  121. externNP GetOwner
  122. externNP GetPureName
  123. externNP TextMode
  124. externNP Int21Handler
  125. ;externNP DebugPostLoadMessage
  126. externFP GlobalLRUNewest
  127. externFP GlobalHandleNorip
  128. externFP HasGPHandler
  129. externFP AllocSelector
  130. externFP IFreeSelector
  131. assumes ds, nothing
  132. assumes es, nothing
  133. ifdef WOW
  134. Entry macro name
  135. public name
  136. align 2
  137. name&:
  138. endm
  139. endif
  140. ;-----------------------------------------------------------------------;
  141. ; Display_Box_of_Doom -- Display the Unrecoverable Application Error
  142. ; box that everyone seems to dislike so much.
  143. ;
  144. ; Entry:
  145. ; Action Reserved, must be zero
  146. ; lpText String to display, NULL for default
  147. ;
  148. ; Returns:
  149. ; AX = 1 Cancel
  150. ; AX = 2 OK
  151. ;
  152. ; Registers Destroyed:
  153. ; AX, BX, CX, DX, SI, DI
  154. ;
  155. ; History:
  156. ; Thu 16-May-1991 -by- Earle R. Horton
  157. ;
  158. ;-----------------------------------------------------------------------;
  159. assumes ds,nothing
  160. assumes es,nothing
  161. cProc Display_Box_of_Doom,<PUBLIC,NEAR>
  162. parmW action
  163. parmD lpText
  164. cBegin
  165. SetKernelDS
  166. if KDEBUG
  167. xor bx,bx
  168. or action,bx
  169. jz @F
  170. kerror 00FFh,<Action not 0 in FatalAppExit>,bx,bx
  171. @@:
  172. endif
  173. push es ; added 10 feb 1990
  174. mov es,curTDB ; did app disable exception
  175. test es:[TDB_ErrMode],02h ; message box?
  176. pop es
  177. jnz nf_dont_ask
  178. cmp pSErrProc.sel, 0 ; Can we put up message box?
  179. jnz short nf_ask ; yes, do it
  180. ; no, have debugger?
  181. nf_dont_ask:
  182. mov ax,1
  183. test Kernel_Flags[2],KF2_SYMDEB
  184. jnz nf_ret ; yes, call debugger
  185. inc ax
  186. jmps nf_ret ; no, have to nuke the app
  187. nf_ask:
  188. push es
  189. mov ax,lpText.sel
  190. or ax,ax
  191. jz nf_default_string
  192. push ax
  193. push lpText.off
  194. jmps nf_pushed_string
  195. nf_default_string:
  196. push ds
  197. mov ax,dataOffset szAbort ; lpText
  198. push ax
  199. nf_pushed_string:
  200. push ds ; lpCaption
  201. mov ax, dataOffset szAbortCaption
  202. push ax
  203. xor ax,ax ; Assume no debugger, blank first button
  204. mov cx,ax
  205. test Kernel_Flags[2],KF2_SYMDEB ; Debugger?
  206. jz @F ; No
  207. mov cx,SEB_CANCEL ; Yes, use Cancel button
  208. @@:
  209. push cx
  210. ; push SEB_OK+SEB_DEFBUTTON
  211. push SEB_CLOSE + SEB_DEFBUTTON
  212. push ax
  213. call ds:[pSErrProc] ; Put up the system error message
  214. pop es
  215. nf_ret:
  216. cEnd
  217. ;-----------------------------------------------------------------------;
  218. ; FatalAppExit -- Called by apps. to request an application error
  219. ; message box.
  220. ;
  221. ; Entry:
  222. ; Action Reserved, must be zero
  223. ; lpText String to display, NULL for default
  224. ;
  225. ; Returns:
  226. ; Returns to caller if Cancel button pressed
  227. ;
  228. ; Registers Destroyed:
  229. ;
  230. ; History:
  231. ; Sun 22-Oct-1989 15:18:57 -by- David N. Weise [davidw]
  232. ; Tonyg wrote it!
  233. ; Fri 24-May-1991 EarleH totally rewrote it, so there!
  234. ;
  235. ;-----------------------------------------------------------------------;
  236. assumes ds,nothing
  237. assumes es,nothing
  238. cProc IFatalAppExit,<PUBLIC,FAR>
  239. parmW action
  240. parmD lpText
  241. cBegin
  242. cmp seg_lpText,0
  243. jne fae_string
  244. mov off_lpText,offset szAbort
  245. mov seg_lpText,seg szAbort
  246. fae_string:
  247. cCall Display_Box_of_Doom,<action,lpText>
  248. cmp ax,1 ; Cancel pressed?
  249. je fae_ret
  250. jmp KillApp
  251. fae_ret:
  252. cEnd
  253. ; ------------------------------------------------------------------
  254. ;
  255. ; FormatFaultString -- Special purpose "sprintf()"
  256. ; Only used for the Box of Doom
  257. ;
  258. ; ------------------------------------------------------------------
  259. cProc FormatFaultString,<PUBLIC,NEAR>,<si,di,ds,es>
  260. parmD lpstr
  261. parmW pStr ; Assumed in Kernel's DS
  262. parmD csip
  263. cBegin
  264. SetKernelDS
  265. cld
  266. les di, lpstr ; Form string in ES:DI
  267. call CurApName
  268. lea si, szSnoozer ; " has caused an error in Windows"
  269. call strcpy
  270. mov si, pStr ; Copy the fault string
  271. call strcpy
  272. lea si, szInModule ; "in Module: <unknown>"
  273. call strcpy
  274. push es
  275. push di
  276. cCall GetOwner,<seg_csip> ; Can we find a module to blame?
  277. or ax, ax
  278. jz NoOwner
  279. mov es, ax
  280. cmp es:[ne_magic], NEMAGIC
  281. jne NoOwner
  282. mov bx, seg_csip ; Have the module, can we get the
  283. and bl, not SEG_RING ; segment number?
  284. mov di,es:[ne_segtab]
  285. mov ax,1
  286. mov cx, es:[ne_cseg]
  287. getsegno:
  288. mov dx, es:[di].ns_handle
  289. and dl, not SEG_RING
  290. cmp dx, bx
  291. jz gotsegno
  292. add di,SIZE NEW_SEG1
  293. inc ax
  294. loop getsegno
  295. jmps nosegno ; No, report the selector instead
  296. gotsegno:
  297. mov seg_csip, ax ; Print Segment #
  298. nosegno:
  299. mov di, es:[ne_pfileinfo] ; Now blame the module
  300. add di, opFile
  301. call GetPureName
  302. mov si, di
  303. smov ds, es
  304. UnSetKernelDS
  305. pop di
  306. pop es
  307. ifdef FE_SB
  308. find_space:
  309. cmp byte ptr es:[di-1],' ' ; prepare space before mod name
  310. jz copy_name
  311. dec di
  312. jmps find_space
  313. copy_name:
  314. else ; !FE_SB
  315. sub di, 9 ; Get rid of <unknown>
  316. endif ; !FE_SB
  317. call strcpy
  318. SetKernelDS
  319. jmps GotOwner
  320. NoOwner:
  321. pop di
  322. pop es
  323. GotOwner:
  324. lea si, szAt
  325. call strcpy
  326. ifdef WOW
  327. cCall <far ptr Far_htoa>,<es,di,seg_csip>
  328. else
  329. cCall htoa,<es,di,seg_csip>
  330. endif
  331. mov di, ax
  332. mov es, dx
  333. mov byte ptr es:[di], ':'
  334. inc di
  335. ifdef WOW
  336. cCall <far ptr Far_htoa>,<es,di,off_csip>
  337. else
  338. cCall htoa,<es,di,off_csip>
  339. endif
  340. mov es, dx
  341. mov di, ax
  342. lea si, szNukeApp
  343. call strcpy
  344. call CurApName
  345. lea si, szWillClose
  346. call strcpy
  347. cEnd
  348. CurApName proc near
  349. SetKernelDS
  350. lea si, szBlame ; Default task to blame
  351. cmp curTDB, 0 ; Have a task to blame?
  352. je DefaultCaption ; nope, use default
  353. mov ds, curTDB
  354. UnSetKernelDS
  355. mov si, TDB_ModName
  356. DefaultCaption:
  357. mov cx, 8
  358. copy_appname:
  359. lodsb
  360. stosb
  361. or al, al ; Null padded in TDB
  362. loopne copy_appname
  363. jne no_null
  364. dec di ; Toss extra space
  365. no_null:
  366. SetKernelDS
  367. ret
  368. CurApName endp
  369. public strcpy
  370. strcpy proc near
  371. lodsb
  372. stosb
  373. or al, al
  374. jnz strcpy
  375. dec di ; Ignore Null
  376. ret
  377. strcpy endp
  378. ;-----------------------------------------------------------------------;
  379. ;
  380. ; KillApp -- Calls USER to tell it that the application is going away,
  381. ; then tells DOS to kill it.
  382. ;
  383. ; ENTRY: None
  384. ; EXIT: None, doesn't
  385. ;
  386. ; Registers modified: Huh?
  387. ;
  388. ;-----------------------------------------------------------------------;
  389. KillApp proc near
  390. SetKernelDS
  391. test fBooting, 1
  392. jz @F
  393. mov ax, 1
  394. cCall ExitKernel,<ax>
  395. @@: mov ax,4CFFH ; They said OK to Nuke app.
  396. DOSCALL
  397. UnSetKernelDS
  398. KillApp endp
  399. ;-----------------------------------------------------------------------;
  400. ; FaultFilter -- Called by HandleFault, NestedFault, and routines that
  401. ; use the same stack frame. Look at the faulting CS:IP on the exception
  402. ; handler frame, and make sure that CS is Ring 3, LDT. If it is not
  403. ; pop the near return address from the stack and chain the exception
  404. ; to the next handler. This will be the DPMI server, which will crash
  405. ; Windows back to DOS. We ought to try to close up a few things first.
  406. ;-----------------------------------------------------------------------;
  407. ReSetKernelDS
  408. public FaultFilter
  409. FaultFilter proc near
  410. mov al,byte ptr [bp].fsf_faulting_CS
  411. and al, SEG_RING_MASK ; Check it was Ring 3, LDT
  412. cmp al, SEG_RING
  413. je @F
  414. ;
  415. ; The faulting CS's ring bits do not match up. We will not handle
  416. ; this fault, because we assume it happened in the DPMI provider,
  417. ; and is a Real Bad one. Since the default handler is going to
  418. ; abort here, it would be nice to let the user down real easy.
  419. ; Restoring the display to text mode would be nice, at the very
  420. ; minimum.
  421. ;
  422. cCall TextMode
  423. ret ; Hypocrite!
  424. @@:
  425. ;
  426. ; Check for faults on POP FS and POP GS. If found, fix them up. We need to
  427. ; fix up faults in the register restoration of both KRNL386 (WOW16Return) and
  428. ; MMSYSTEM (MULTI_MEDIA_ISR386). Monty Pythons Complete Waste of Time is an app
  429. ; which frees selectors in FS across message boundries.
  430. ;
  431. ifdef WOW
  432. push ds
  433. mov ax, word ptr [bp].fsf_faulting_CS
  434. mov ds, ax
  435. mov si, word ptr [bp].fsf_faulting_IP
  436. cmp word ptr [si], 0A10Fh ; pop fs
  437. je HandFSGSflt
  438. cmp word ptr [si], 0A90Fh ; pop gs
  439. je HandFSGSflt
  440. jmp short NoFSGSflt
  441. HandFSGSflt:
  442. if KDEBUG
  443. Trace_Out "POP GS/FS fault fixed up!"
  444. endif
  445. mov ds, [bp].fsf_SS
  446. mov si, [bp].fsf_SP
  447. mov word ptr [si], 0
  448. pop ds ; restore kernel DS
  449. pop ax ; don't do EH_Chain
  450. push codeOffset EH_ret ; use "handled it" return instead
  451. ret
  452. NoFSGSflt:
  453. pop ds
  454. endif
  455. pop ax ; toss chain return
  456. push codeOffset EH_ret ; use "handled it" return
  457. mov si,word ptr FaultHandler ; SI = Handler
  458. push si
  459. mov word ptr FaultHandler,codeOffset NestedFault
  460. if KDEBUG
  461. test byte ptr [bp].fsf_flags+1,2 ; IF set in faulting frame?
  462. jnz @F
  463. Trace_Out "Fault with interrupts disabled!"
  464. @@:
  465. endif
  466. cmp [bp].fsf_SP,128d
  467. jb ff_stack
  468. cCall HasGPHandler, <[bp].fsf_faulting_CS, [bp].fsf_faulting_IP>
  469. or ax, ax
  470. jz ff_real_fault
  471. mov ds, [bp].fsf_SS
  472. mov bx, [bp].fsf_SP
  473. sub [bp].fsf_SP, 4
  474. mov cx, [bp].fsf_err_code ; put error code on stack
  475. mov [bx-2],cx
  476. mov dx, [bp].fsf_faulting_IP
  477. mov [bx-4],dx ; and faulting IP
  478. mov [bp].fsf_faulting_IP, ax ; continue at gp fault handler
  479. jmps ff_ret
  480. ff_real_fault:
  481. ifdef WOW
  482. test DebugWOW,DW_DEBUG
  483. jz ff_no_wdebug
  484. xor ax,ax ; 0 in AX defaults to not handled
  485. push DBG_GPFAULT2
  486. FBOP BOP_DEBUGGER,,FastBop
  487. add sp,+2
  488. or ax, ax
  489. jnz ff_ret ; Alright! they handled the exception!
  490. ; Get us back to the app please!
  491. ; Otherwise, they chose to continue the exception
  492. ff_no_wdebug:
  493. endif
  494. if SHERLOCK
  495. cCall GPContinue ; We know BP points to
  496. or ax, ax ; the fault frame!
  497. jnz ff_ret
  498. endif
  499. ff_stack:
  500. call si ; call our fault handler
  501. ff_ret:
  502. SetKernelDS
  503. pop FaultHandler
  504. ret
  505. FaultFilter endp
  506. ifdef WOW
  507. ;-----------------------------------------------------------------------;
  508. ;
  509. ; single_step
  510. ;
  511. ;-----------------------------------------------------------------------;
  512. Entry single_step
  513. push ds
  514. SetKernelDS ds
  515. push ax
  516. ; QCWIN traces through code which it has no source code for. This means
  517. ; its ends up tracing through the 16-bit to 32-bit transition code and
  518. ; when it traces on the call fword instruction, it cause 32-bit trace
  519. ; interrupt which breaks into the kd> On a retail build with no
  520. ; debugger attached, it might work.
  521. ; To work around the problem we turn off the TraceFlag here if wow16cal
  522. ; has requested it.
  523. test TraceOff,1h
  524. jnz ss_turn_off_trace_flag
  525. test DebugWOW,DW_DEBUG
  526. jz ss_no_wdebug
  527. xor ax,ax ; 0 in AX defaults to not handled
  528. push DBG_SINGLESTEP
  529. FBOP BOP_DEBUGGER,,FastBop
  530. add sp,+2
  531. or ax, ax
  532. jnz ss_ret ; Alright! they handled the exception!
  533. ; Get us back to the app please!
  534. ss_no_wdebug:
  535. ; Otherwise, they chose to continue the exception
  536. pop ax
  537. pop ds
  538. jmp cs:[prevInt01proc]
  539. ; Tell api code (wow16cal) to turn on trace flag at end of next api
  540. ss_turn_off_trace_flag:
  541. sub sp,2 ; Make it look like "normalized" fault frame
  542. push bp
  543. mov bp,sp
  544. or TraceOff,2h
  545. and [bp].fsf_flags,NOT FLG_TRAP ; turn off the trap flag
  546. pop bp
  547. add sp,2
  548. ss_ret:
  549. pop ax
  550. pop ds
  551. UnSetKernelDS ds
  552. retf
  553. ;-----------------------------------------------------------------------;
  554. ;
  555. ; breakpoint
  556. ;
  557. ;-----------------------------------------------------------------------;
  558. Entry breakpoint
  559. push ds
  560. SetKernelDS ds
  561. push ax
  562. test DebugWOW,DW_DEBUG
  563. jz br_no_wdebug
  564. xor ax,ax ; 0 in AX defaults to not handled
  565. push DBG_BREAK
  566. FBOP BOP_DEBUGGER,,FastBop
  567. add sp,+2
  568. or ax, ax
  569. jnz bp_ret ; Alright! they handled the exception!
  570. ; Get us back to the app please!
  571. br_no_wdebug:
  572. ; Otherwise, they chose to continue the exception
  573. pop ax
  574. pop ds
  575. jmp cs:[prevInt03proc]
  576. bp_ret:
  577. pop ax
  578. pop ds
  579. UnSetKernelDS ds
  580. retf
  581. ;-----------------------------------------------------------------------;
  582. ;
  583. ; divide_overflow
  584. ;
  585. ;-----------------------------------------------------------------------;
  586. Entry divide_overflow
  587. push ds
  588. SetKernelDS ds
  589. push ax
  590. test DebugWOW,DW_DEBUG
  591. jz di_no_wdebug
  592. xor ax,ax ; 0 in AX defaults to not handled
  593. push DBG_DIVOVERFLOW
  594. FBOP BOP_DEBUGGER,,FastBop
  595. .286p
  596. add sp,+2
  597. or ax, ax
  598. jnz do_ret ; Alright! they handled the exception!
  599. ; Get us back to the app please!
  600. di_no_wdebug:
  601. ; Otherwise, they chose to continue the exception
  602. pop ax
  603. pop ds
  604. jmp cs:[oldInt00proc]
  605. do_ret:
  606. pop ax
  607. pop ds
  608. UnSetKernelDS ds
  609. retf
  610. endif
  611. ;-----------------------------------------------------------------------;
  612. ;
  613. ; Set_GO_BP
  614. ;
  615. ;-----------------------------------------------------------------------;
  616. public Set_GO_BP
  617. Set_GO_BP proc near
  618. mov cx, [bp].fsf_faulting_CS ; Faulting CS
  619. mov bx, [bp].fsf_faulting_IP ; Faulting IP
  620. DebInt 40h
  621. ; mov ax, 40h ; 16 bit forced go command
  622. ; int 41h ; Call debugger
  623. ;ifdef JAPAN
  624. ; INT41SIGNATURE
  625. ;endif
  626. ret
  627. Set_GO_BP endp
  628. ;-----------------------------------------------------------------------;
  629. ;
  630. ; ExitFault -- Fault at Exit Time!!!
  631. ;
  632. ; ENTRY: BP points to fault frame described above
  633. ;
  634. ; EXIT: Returns to DPMI.
  635. ;
  636. ; Registers Modified: None
  637. ;
  638. ;-----------------------------------------------------------------------;
  639. ReSetKernelDS
  640. public ExitFault
  641. ExitFault proc near
  642. if KDEBUG
  643. Trace_Out "Fault at Exit Time!!!"
  644. endif
  645. ;
  646. ; If a kernel debugger is loaded, pop out at the nested fault, and
  647. ; take no prisoners.
  648. ;
  649. test Kernel_Flags[2],KF2_SYMDEB ; Debugger?
  650. jz @F
  651. jmp Set_GO_BP
  652. @@:
  653. jmps HandleFault
  654. ExitFault endp
  655. public BUNNY_351
  656. BUNNY_351 proc far
  657. push ds
  658. SetKernelDS
  659. mov FaultHandler,codeOffset ExitFault
  660. pop ds
  661. ret
  662. BUNNY_351 endp
  663. ;-----------------------------------------------------------------------;
  664. ;
  665. ; MY_RETF -- Executes a far return.
  666. ;
  667. ;-----------------------------------------------------------------------;
  668. MY_RETF proc near
  669. retf
  670. MY_RETF endp
  671. ;-----------------------------------------------------------------------;
  672. ;
  673. ; NestedFault -- Called when a fault handler Faults!!!
  674. ;
  675. ; ENTRY: BP points to fault frame described above
  676. ;
  677. ; EXIT: Returns to DPMI.
  678. ;
  679. ; Registers Modified: None
  680. ;
  681. ;-----------------------------------------------------------------------;
  682. ReSetKernelDS
  683. public NestedFault
  684. NestedFault proc near
  685. if KDEBUG
  686. Trace_Out "Nested Fault!!!"
  687. endif
  688. ;
  689. ; If a kernel debugger is loaded, pop out at the nested fault, and
  690. ; take no prisoners.
  691. ;
  692. test Kernel_Flags[2],KF2_SYMDEB ; Debugger?
  693. jz @F
  694. jmp Set_GO_BP
  695. @@:
  696. jmps HandleFault
  697. NestedFault endp
  698. ;-----------------------------------------------------------------------;
  699. ;
  700. ; HandleFault -- Puts up the System Error box for a Fault. Terminates
  701. ; the application or enters the debugger.
  702. ;
  703. ; ENTRY: BP points to fault frame described above
  704. ;
  705. ; EXIT: Returns to DPMI. If Cancel is pressed, we tell
  706. ; WDEB to set a GO breakpoint at the faulting instruction
  707. ; first. If OK is pressed, then the CS:IP on the DPMI
  708. ; fault frame is modified to point to KillApp, and the
  709. ; SS:SP points to a temp. stack owned by Kernel.
  710. ;
  711. ; Registers Modified: None
  712. ;
  713. ;-----------------------------------------------------------------------;
  714. ReSetKernelDS
  715. public HandleFault
  716. HandleFault proc near
  717. mov ax, lpGPChain.sel ; Do we have a private GP handler?
  718. mov lpGPChain.sel, 0 ; Prevent re-entrancy
  719. cmp ax, [bp].fsf_SS
  720. jnz We_Can_Handle_It
  721. test Kernel_Flags[2],KF2_SYMDEB ; Debugger?
  722. jz @F
  723. mov lpGPChain.sel,ax
  724. jmp Set_GO_BP
  725. @@:
  726. ; If we want to chain back for any
  727. mov bx, lpGPChain.off ; faults, then set up the stack of
  728. mov [bp].fsf_SP, bx ; the handler, and continue execution
  729. mov [bp].fsf_faulting_CS, cs ; at a RETF in Kernel
  730. mov [bp].fsf_faulting_IP, offset MY_RETF
  731. cmp [pPostMessage.sel],0 ; is there a USER around yet?
  732. je @F
  733. pusha
  734. push es
  735. cCall [pPostMessage],<-1,WM_SYSTEMERROR,1,0,0>
  736. pop es
  737. popa
  738. @@:
  739. if kdebug
  740. mov es, ax
  741. mov ax, es:[bx+2]
  742. mov bx, es:[bx]
  743. krDebugOut DEB_ERROR, "Fault detected - handled by %AX2 #AX:#BX"
  744. endif
  745. jmp HandleFault_Exit
  746. We_Can_Handle_It:
  747. sub sp, UAE_STRING_LEN ; Room for string
  748. mov si, sp
  749. cCall FormatFaultString,<ss,si,[bp].fsf_msg,[bp].fsf_faulting_CS,[bp].fsf_faulting_IP>
  750. push bp
  751. xor bp,bp ; Some people are picky...
  752. cCall Display_Box_of_Doom,<0,ss,si>
  753. pop bp
  754. add sp, UAE_STRING_LEN
  755. or ax, ax
  756. jne @F
  757. INT3_DEBUG ; Failed call - no USER
  758. @@:
  759. cmp ax, 1 ; Button 1 (Cancel) pressed?
  760. jne @F
  761. jmp Set_GO_BP
  762. @@:
  763. test fBooting, 1 ; No, they said to Nuke app.
  764. jnz no_signal_proc
  765. mov ds, curTDB
  766. UnSetKernelDS
  767. cmp ds:[TDB_USignalProc].sel,0
  768. jz no_signal_proc
  769. mov bx,0666h
  770. mov di, -1
  771. cCall ds:[TDB_USignalProc],<ds,bx,di,ds:[TDB_Module],ds:[TDB_Queue]>
  772. ;
  773. ; Since we are on a nice big fat juicy fault handler stack now, we can call
  774. ; Windows to clean up after the task.
  775. ;
  776. mov bx,SG_EXIT
  777. cCall ds:[TDB_USignalProc],<ds,bx,di,ds:[TDB_Module],ds:[TDB_Queue]>
  778. mov ds:[TDB_USignalProc].sel,0
  779. no_signal_proc:
  780. mov [bp].fsf_SP,dataOffset gmove_stack
  781. mov [bp].fsf_SS,seg gmove_stack
  782. mov [bp].fsf_faulting_CS,cs
  783. lea ax,KillApp
  784. mov [bp].fsf_faulting_IP,ax
  785. HandleFault_Exit:
  786. ret
  787. HandleFault endp
  788. ; ------------------------------------------------------------------
  789. ;
  790. ; ExceptionHandlerProc -- Common entry point for exception handlers
  791. ;
  792. ; ------------------------------------------------------------------
  793. public ExceptionHandlerProc
  794. ExceptionHandlerProc proc far
  795. push bp
  796. mov bp,sp
  797. pusha
  798. push ds
  799. SetKernelDS
  800. push es
  801. EH_Popup:
  802. call FaultFilter
  803. EH_Chain:
  804. pop es
  805. pop ds
  806. UnsetKernelDS
  807. popa
  808. pop bp
  809. add sp,2 ; remove message from stack
  810. retf ; chain to prev handler
  811. EH_ret:
  812. pop es
  813. pop ds
  814. popa
  815. pop bp
  816. add sp,fsf_OFFSET
  817. retf
  818. ExceptionHandlerProc endp
  819. ; ------------------------------------------------------------------
  820. ;
  821. ; This macro sets up the stack frame for entry to the generic
  822. ; exception handler.
  823. ;
  824. ; ------------------------------------------------------------------
  825. ExceptionHandlerPrologue macro name,msg,chain
  826. public name
  827. name:
  828. if ROM
  829. sub sp,6
  830. push bp
  831. push ds
  832. push ax
  833. mov bp,sp
  834. SetKernelDS
  835. mov word ptr [bp+6],offset msg
  836. mov ax, word ptr [chain][0]
  837. mov [bp+8],ax
  838. mov ax, word ptr [chain][2]
  839. mov [bp+10],ax
  840. UnsetKernelDS
  841. pop ax
  842. pop ds
  843. pop bp
  844. else
  845. push word ptr chain + 2
  846. push word ptr chain
  847. push offset msg
  848. endif
  849. endm
  850. ; ------------------------------------------------------------------
  851. ;
  852. ; This macro sets up the stack frame, then jumps to the generic
  853. ; exception handler.
  854. ;
  855. ; ------------------------------------------------------------------
  856. ExceptionHandler macro name,msg,chain
  857. ExceptionHandlerPrologue name,msg,chain
  858. jmp ExceptionHandlerProc
  859. assumes ds, nothing
  860. assumes es, nothing
  861. endm
  862. ; ------------------------------------------------------------------
  863. ;
  864. ; Four fatal ones.
  865. ;
  866. ; ------------------------------------------------------------------
  867. ExceptionHandler StackFault,szSF,prevInt0Cproc
  868. ExceptionHandler GPFault,szGP,prevInt0Dproc
  869. ExceptionHandler invalid_op_code_exception,szII,prevIntx6proc
  870. ExceptionHandler page_fault,szPF,prevInt0Eproc
  871. ExceptionHandler LoadSegFailed,szLoad,prevInt3Fproc
  872. ; ------------------------------------------------------------------
  873. ;
  874. ; The not present fault is used to demand-load segments from newexe
  875. ; files. If we find out that something bogus has happened, then
  876. ; we just jump into the fault handler.
  877. ;
  878. ; ------------------------------------------------------------------
  879. ExceptionHandlerPrologue SegmentNotPresentFault,szNP,prevInt3Fproc
  880. push bp
  881. mov bp,sp
  882. pusha
  883. push ds
  884. SetKernelDS
  885. push es
  886. mov al,byte ptr [bp].fsf_faulting_CS
  887. and al, SEG_RING_MASK ; Check it was Ring 1, LDT
  888. cmp al, SEG_RING
  889. je @F
  890. jmp EH_Chain
  891. @@:
  892. mov al,byte ptr [bp].fsf_err_code
  893. test al, SEL_LDT ; Check it was LDT
  894. jne @F
  895. jmp EH_Chain
  896. @@:
  897. if KDEBUG
  898. test byte ptr [bp].fsf_flags+1,2 ; IF set in faulting frame?
  899. jnz @F
  900. Trace_Out "Segment not present fault with interrupts disabled!"
  901. @@:
  902. endif
  903. FSTI
  904. ;
  905. ; Don't discard the segment that we have to return to!!!
  906. ;
  907. cCall GlobalHandleNorip,<[bp].fsf_faulting_CS>
  908. test cl,GA_DISCARDABLE
  909. jz @F
  910. cCall GlobalLRUNewest,<ax>
  911. @@:
  912. mov bx,[bp].fsf_err_code
  913. seg_reload:
  914. and bx, NOT 7h ; get the not present selector
  915. or bl, SEG_RING ; Correct RING bits
  916. if KDEBUG
  917. mov INT3Fcs, bx ; Save in case of error
  918. endif
  919. if PMODE32
  920. ; On WOW we don't copy the owner to the real LDT since it is slow to call
  921. ; the NT Kernel, so we read our copy of it directly.
  922. ; see set_discarded_sel_owner mattfe mar 23 93
  923. mov es,cs:gdtdsc
  924. mov cx,bx ; save bx
  925. and bl, not 7
  926. mov es,es:[bx].dsc_owner
  927. mov bx,cx ; restore
  928. else
  929. lsl cx, bx ; mov es,[bx].he_owner
  930. mov es, cx
  931. endif
  932. StoH bl ; Need handle
  933. cmp es:[ne_magic],NEMAGIC ; If owner is not a module
  934. jnz bad_seg_load ; (i.e., an instance or garbage)
  935. ; get out of here.
  936. mov di,es:[ne_segtab]
  937. mov ax,1
  938. mov cx, es:[ne_cseg]
  939. jcxz bad_seg_load
  940. dorten:
  941. cmp es:[di].ns_handle,bx
  942. jz got_seg_no
  943. add di,SIZE NEW_SEG1
  944. inc ax
  945. loop dorten
  946. ; program has referenced garbage...
  947. bad_seg_load:
  948. jmp EH_Popup
  949. got_seg_no:
  950. ;
  951. ; If we already are on the exception handler stack, then we want to make
  952. ; sure that we don't overwrite the original stack frame. Copy our
  953. ; stack frame variables down by the difference between SP and SP before
  954. ; we got called.
  955. ;
  956. push ax
  957. mov ax,ss
  958. cmp ax,word ptr [bp].fsf_SS
  959. pop ax
  960. jne stack_OK
  961. push ax
  962. push bx
  963. push bp
  964. lea bp,word ptr [bp].fsf_SS
  965. mov ax,sp
  966. dec ax
  967. dec ax
  968. @@:
  969. push word ptr [bp]
  970. dec bp
  971. dec bp
  972. cmp bp,ax
  973. jne @B
  974. pop bp
  975. pop bx
  976. pop ax
  977. ;
  978. ; Figured out what this was supposed to be by tracing up to here
  979. ; in the debugger.
  980. ;
  981. sub bp,32h
  982. stack_OK:
  983. push es
  984. mov bx,ax
  985. UnsetKernelDS
  986. mov ax,ss
  987. mov ds,ax
  988. les di,dword ptr [bp].fsf_SP
  989. dec di
  990. dec di
  991. std
  992. ;
  993. ; Push an IRET frame on the faulting stack.
  994. ;
  995. lea si,[bp].fsf_flags
  996. mov cx,3
  997. rep movsw
  998. ;
  999. ; Push our saved registers on the faulting stack.
  1000. ;
  1001. lea si,[bp]
  1002. mov cx,11 ; BP + PUSHA + ES + DS
  1003. rep movsw
  1004. pop ax
  1005. ;
  1006. ; Push arguments to LoadSegment on the faulting stack.
  1007. ;
  1008. stosw ; hExe
  1009. mov ax,bx
  1010. stosw ; segno
  1011. mov ax,-1
  1012. stosw
  1013. stosw
  1014. inc di
  1015. inc di
  1016. ;
  1017. ; Point the faulting stack at the new location.
  1018. ;
  1019. mov [bp].fsf_SP,di
  1020. ;
  1021. ; Tell DPMI to return to us instead of the faulting code.
  1022. ;
  1023. mov [bp].fsf_faulting_CS,cs
  1024. mov [bp].fsf_faulting_IP,offset let_them_do_it
  1025. lea sp,[bp].fsf_ret_IP
  1026. if kdebug
  1027. SetKernelDS
  1028. mov wFaultSegNo, bx
  1029. UnSetKernelDS
  1030. endif
  1031. retf
  1032. let_them_do_it:
  1033. SetKernelDS
  1034. xor cx, cx ; we try to keep a selector reserved
  1035. xchg cx, DemandLoadSel ; for scratch use while demand
  1036. jcxz @f ; loading segments--free it to make
  1037. cCall IFreeSelector,<cx> ; it available now
  1038. @@:
  1039. cCall LoadSegment
  1040. push ax ; reserve a selector for the next
  1041. cCall AllocSelector,<0> ; time we demand load a segment
  1042. mov DemandLoadSel, ax
  1043. pop cx ; LoadSegment result
  1044. jcxz SegLoaderFailure
  1045. if kdebug
  1046. push bx
  1047. mov bx, wFaultSegNo
  1048. krDebugOut <DEB_TRACE or DEB_krLoadSeg>, "Demand load %CX2(#bx) on %SS2"
  1049. pop bx
  1050. endif
  1051. pop es
  1052. pop ds
  1053. UnsetKernelDS
  1054. popa
  1055. pop bp
  1056. ;** Check to see if we're about to restart an instruction in
  1057. ;** a not present segment. This would only occur if the
  1058. ;** segment was discarded because of the segment load we
  1059. ;** just did.
  1060. IF KDEBUG
  1061. push bp ;Make a stack frame
  1062. mov bp,sp
  1063. push ax
  1064. mov bp,[bp + 4] ;Get the CS
  1065. lar ax,bp ;See if the CS is valid
  1066. test ax,8000h ;Is it present?
  1067. jnz @F ;Yes, don't complain
  1068. mov ax,bp
  1069. Trace_Out <'LDINT: Trying to restart discarded caller (#AX)'>
  1070. @@:
  1071. pop ax
  1072. pop bp
  1073. ENDIF
  1074. iret
  1075. public SegLoaderFailure
  1076. SegLoaderFailure proc near
  1077. ;
  1078. ; segment loader was unable to load the segment!!!
  1079. ; Restore all the registers, create a fake DPMI frame, then
  1080. ; complain about the problem. Lets the user break into the
  1081. ; debugger, if installed, on Cancel. Creating and destroying
  1082. ; the fake DPMI frame is inconvenient and messy, but it lets
  1083. ; us handle the problem in common fault code.
  1084. ;
  1085. pop es
  1086. pop ds
  1087. UnsetKernelDS
  1088. popa
  1089. sub sp,4
  1090. mov bp,sp ; BP -> xx xx BP IP CS FL
  1091. push word ptr [bp+4] ; push app's BP
  1092. push ax ; get a temporary register
  1093. mov ax,[bp+6] ; IP
  1094. mov [bp+2],ax
  1095. mov ax,[bp+8] ; CS
  1096. mov [bp+4],ax
  1097. mov ax,[bp+10] ; Flags
  1098. mov [bp+6],ax
  1099. mov [bp+10],ss
  1100. lea ax,[bp+12]
  1101. mov [bp+8],ax
  1102. pop ax
  1103. pop bp
  1104. call far ptr LoadSegFailed ; BP -> RETIP RETCS EC IP CS FL SP SS
  1105. push bp
  1106. mov bp,sp ; BP -> BP EC IP CS FL SP SS
  1107. mov [bp+2],ax
  1108. mov ax,[bp+8] ; Flags
  1109. mov [bp+12],ax
  1110. mov ax,[bp+6] ; CS
  1111. mov [bp+10],ax
  1112. mov ax,[bp+4] ; IP
  1113. mov [bp+8],ax
  1114. pop bp
  1115. pop ax
  1116. add sp,4
  1117. iret
  1118. SegLoaderFailure endp
  1119. ;ENDIF
  1120. ;-----------------------------------------------------------------------;
  1121. ; default_sig_handler
  1122. ;
  1123. ;
  1124. ; Entry:
  1125. ;
  1126. ; Returns:
  1127. ;
  1128. ; Registers Destroyed:
  1129. ;
  1130. ; History:
  1131. ; Wed 10-Jan-1990 22:32:34 -by- David N. Weise [davidw]
  1132. ; Wrote it!
  1133. ;-----------------------------------------------------------------------;
  1134. assumes ds,nothing
  1135. assumes es,nothing
  1136. cProc default_sig_handler,<PUBLIC,FAR>
  1137. cBegin nogen
  1138. ret
  1139. cEnd nogen
  1140. ;-----------------------------------------------------------------------;
  1141. ;
  1142. ; Panic -- Called by ToolHelp when it gets a bad stack fault or any
  1143. ; other fault with SP suspiciously low.
  1144. ;
  1145. ;-----------------------------------------------------------------------;
  1146. assumes ds,nothing
  1147. assumes es,nothing
  1148. cProc Panic,<PUBLIC,NEAR>
  1149. cBegin
  1150. if KDEBUG
  1151. Trace_Out "KERNEL: Panic called!!!"
  1152. endif
  1153. int 1
  1154. jmp KillApp
  1155. cEnd
  1156. ;-----------------------------------------------------------------------;
  1157. ; DoSignal
  1158. ;
  1159. ;
  1160. ; Entry:
  1161. ;
  1162. ; Returns:
  1163. ;
  1164. ; Registers Destroyed:
  1165. ;
  1166. ; History:
  1167. ; Wed 10-Jan-1990 22:52:52 -by- David N. Weise [davidw]
  1168. ; Wrote it!
  1169. ;-----------------------------------------------------------------------;
  1170. assumes ds,nothing
  1171. assumes es,nothing
  1172. cProc DoSignal,<PUBLIC,FAR>,<ax,bx,cx,dx,di,si,es>
  1173. cBegin
  1174. SetKernelDS
  1175. cmp pUserGetFocus.sel,0 ; is there a USER yet?
  1176. jz ds_exit
  1177. call pUserGetFocus
  1178. or ax,ax
  1179. jz ds_exit
  1180. mov si,ax
  1181. cCall pUserIsWindow,<ax>
  1182. or ax,ax
  1183. jz ds_exit
  1184. cCall pUserGetWinTask,<si>
  1185. mov ds,ax
  1186. TDB_check_DS
  1187. cmp ds:[TDB_SigAction],2 ; send it on?
  1188. jnz ds_exit
  1189. mov ax,1
  1190. xor bx,bx
  1191. cCall ds:[bx].TDB_ASignalProc,<bx,ax>
  1192. ds_exit:
  1193. cEnd
  1194. sEnd CODE
  1195. sBegin MISCCODE
  1196. assumes cs, misccode
  1197. assumes ds, nothing
  1198. assumes es, nothing
  1199. externNP MISCMapDStoDATA
  1200. ifdef WOW
  1201. externFP htoa
  1202. assumes ds,nothing
  1203. assumes es,nothing
  1204. ;-----------------------------------------------------------------------;
  1205. ; allows htoa to be called from _TEXT code segment
  1206. cProc Far_htoa,<PUBLIC,FAR>
  1207. parmD lpstr
  1208. parmW val
  1209. cBegin
  1210. push [bp+10]
  1211. push [bp+8]
  1212. push [bp+6]
  1213. call far ptr htoa
  1214. cEnd
  1215. endif ;; WOW
  1216. ;-----------------------------------------------------------------------;
  1217. ; SetSigHandler
  1218. ;
  1219. ; SetSigHandler notifies Windows of a handler for a signal.
  1220. ; It may also be used to ignore a signal or install a default
  1221. ; action for a signal.
  1222. ;
  1223. ; Entry:
  1224. ; parmD lpprocRoutine Signal handler
  1225. ; parmD lpDPrevAddress Previous handler (returned)
  1226. ; parmD lpWPrevAction Previous action (returned)
  1227. ; parmW Action Indicate request type
  1228. ; parmW SigNumber Signal number of interest
  1229. ;
  1230. ; Returns:
  1231. ;
  1232. ; Registers Destroyed:
  1233. ;
  1234. ; History:
  1235. ; Mon 25-Dec-1989 00:36:01 -by- David N. Weise [davidw]
  1236. ; Wrote it!
  1237. ;-----------------------------------------------------------------------;
  1238. assumes ds,nothing
  1239. assumes es,nothing
  1240. cProc SetSigHandler,<PUBLIC,FAR>,<di,si,ds>
  1241. parmD lpprocRoutine
  1242. parmD lpDPrevAddress
  1243. parmD lpWPrevAction
  1244. parmW Action
  1245. parmW SigNumber
  1246. cBegin
  1247. call MISCMapDStoDATA
  1248. ReSetKernelDS
  1249. cmp SigNumber,1 ; is it SIGINTR?
  1250. jnz dssh_return_success ; ignore if not
  1251. cmp Action,4 ; is it reset Signal?
  1252. jz @F
  1253. push ds
  1254. mov ds,curTDB
  1255. assumes ds,nothing
  1256. mov ax,Action
  1257. xchg ax,ds:[TDB_SigAction]
  1258. les bx,lpWPrevAction
  1259. mov cx,es
  1260. or cx,bx
  1261. jz @F
  1262. mov es:[bx],ax
  1263. @@:
  1264. mov dx,lpprocRoutine.sel
  1265. mov ax,lpprocRoutine.off
  1266. cmp Action,0 ; put in default handler?
  1267. jnz ssg_stick_it_in
  1268. mov dx,SEG default_sig_handler
  1269. mov ax,codeOffset default_sig_handler
  1270. ssg_stick_it_in:
  1271. xchg dx,ds:[TDB_ASignalProc].sel
  1272. xchg ax,ds:[TDB_ASignalProc].off
  1273. cmp Action,4 ; is it reset Signal?
  1274. jz @F
  1275. les bx,lpDPrevAddress
  1276. mov cx,es
  1277. or cx,bx
  1278. jz @F
  1279. mov es:[bx].sel,dx
  1280. mov es:[bx].off,ax
  1281. pop ds
  1282. @@:
  1283. dssh_return_success:
  1284. xor ax,ax ; return success
  1285. dssh_exit:
  1286. cEnd
  1287. ;----------------------------------------------------------------------------
  1288. ;
  1289. ; SwapRecording(Flag)
  1290. ;
  1291. ; Flag = 0 => Stop recording
  1292. ; = 1 => Start recording only Swaps, Discards and Returns
  1293. ; = 2 => Start recording Calls in addition to Swaps, Discards and
  1294. ; returns.
  1295. ; Destroys AL register
  1296. ;----------------------------------------------------------------------------
  1297. ; Retail Version
  1298. cProc ISwapRecording,<PUBLIC, FAR>
  1299. ; parmW Flag
  1300. cBegin nogen
  1301. retf 2
  1302. cEnd nogen
  1303. sEnd MISCCODE
  1304. end