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.

714 lines
24 KiB

  1. //----------------------------------------------------------------------------
  2. //
  3. // VDM debugging support.
  4. //
  5. // Copyright (C) Microsoft Corporation, 1997-2001.
  6. //
  7. //----------------------------------------------------------------------------
  8. #include "ntsdp.hpp"
  9. BOOL fVDMInitDone;
  10. BOOL fVDMActive;
  11. VDMPROCESSEXCEPTIONPROC pfnVDMProcessException;
  12. VDMGETTHREADSELECTORENTRYPROC pfnVDMGetThreadSelectorEntry;
  13. VDMGETPOINTERPROC pfnVDMGetPointer;
  14. VDMGETCONTEXTPROC pfnVDMGetContext;
  15. VDMSETCONTEXTPROC pfnVDMSetContext;
  16. VDMGETSELECTORMODULEPROC pfnVDMGetSelectorModule;
  17. #define SEGTYPE_AVAILABLE 0
  18. #define SEGTYPE_V86 1
  19. #define SEGTYPE_PROT 2
  20. #define MAXSEGENTRY 1024
  21. SEGENTRY segtable[MAXSEGENTRY];
  22. VOID VDMRegCmd(
  23. LPSTR achInput,
  24. X86_NT5_CONTEXT *pvc
  25. )
  26. {
  27. DWORD dwVal;
  28. if ( _stricmp(achInput,"rp") == 0 )
  29. {
  30. g_X86Machine.OutputAll(g_X86Machine.m_AllMask,
  31. DEBUG_OUTPUT_NORMAL);
  32. return;
  33. }
  34. if (achInput[1] != 'e') {
  35. dprintf("VDM R: can only operate on 32-bit registers\n");
  36. return;
  37. }
  38. if (strlen(achInput) < 6) {
  39. dprintf("VDM R: Missing value\n");
  40. return;
  41. }
  42. dwVal = strtoul(&achInput[5], NULL, 16);
  43. if ( _strnicmp(&achInput[2],"ax", 2) == 0 ) {
  44. pvc->Eax = dwVal;
  45. } else if ( _strnicmp(&achInput[2],"bx", 2) == 0 ) {
  46. pvc->Ebx = dwVal;
  47. } else if ( _strnicmp(&achInput[2],"cx", 2) == 0 ) {
  48. pvc->Ecx = dwVal;
  49. } else if ( _strnicmp(&achInput[2],"dx", 2) == 0 ) {
  50. pvc->Edx = dwVal;
  51. } else if ( _strnicmp(&achInput[2],"si", 2) == 0 ) {
  52. pvc->Esi = dwVal;
  53. } else if ( _strnicmp(&achInput[2],"di", 2) == 0 ) {
  54. pvc->Edi = dwVal;
  55. } else if ( _strnicmp(&achInput[2],"ip", 2) == 0 ) {
  56. pvc->Eip = dwVal;
  57. } else if ( _strnicmp(&achInput[2],"sp", 2) == 0 ) {
  58. pvc->Esp = dwVal;
  59. } else if ( _strnicmp(&achInput[2],"bp", 2) == 0 ) {
  60. pvc->Ebp = dwVal;
  61. } else if ( _strnicmp(&achInput[2],"fl", 2) == 0 ) {
  62. pvc->EFlags = dwVal;
  63. } else {
  64. dprintf("Invalid register\n");
  65. return;
  66. }
  67. dprintf("%.8X will be flushed to '%3.3s'. Use 'rp' to display pending values\n",
  68. dwVal,
  69. &achInput[1]);
  70. }
  71. void
  72. DebugEvent64To(LPDEBUG_EVENT64 Event64,
  73. LPDEBUG_EVENT Event)
  74. {
  75. Event->dwDebugEventCode = Event64->dwDebugEventCode;
  76. Event->dwProcessId = Event64->dwProcessId;
  77. Event->dwThreadId = Event64->dwThreadId;
  78. switch(Event64->dwDebugEventCode)
  79. {
  80. case EXCEPTION_DEBUG_EVENT:
  81. ExceptionRecord64To(&Event64->u.Exception.ExceptionRecord,
  82. &Event->u.Exception.ExceptionRecord);
  83. Event->u.Exception.dwFirstChance =
  84. Event64->u.Exception.dwFirstChance;
  85. break;
  86. case CREATE_THREAD_DEBUG_EVENT:
  87. Event->u.CreateThread.hThread =
  88. (PVOID)(ULONG_PTR)(Event64->u.CreateThread.hThread);
  89. Event->u.CreateThread.lpThreadLocalBase =
  90. (PVOID)(ULONG_PTR)(Event64->u.CreateThread.lpThreadLocalBase);
  91. Event->u.CreateThread.lpStartAddress =
  92. (LPTHREAD_START_ROUTINE)(ULONG_PTR)(Event64->u.CreateThread.lpStartAddress);
  93. break;
  94. case CREATE_PROCESS_DEBUG_EVENT:
  95. Event->u.CreateProcessInfo.hFile =
  96. (PVOID)(ULONG_PTR)(Event64->u.CreateProcessInfo.hFile);
  97. Event->u.CreateProcessInfo.hProcess =
  98. (PVOID)(ULONG_PTR)(Event64->u.CreateProcessInfo.hProcess);
  99. Event->u.CreateProcessInfo.hThread =
  100. (PVOID)(ULONG_PTR)(Event64->u.CreateProcessInfo.hThread);
  101. Event->u.CreateProcessInfo.lpBaseOfImage =
  102. (PVOID)(ULONG_PTR)(Event64->u.CreateProcessInfo.lpBaseOfImage);
  103. Event->u.CreateProcessInfo.dwDebugInfoFileOffset =
  104. Event64->u.CreateProcessInfo.dwDebugInfoFileOffset;
  105. Event->u.CreateProcessInfo.nDebugInfoSize =
  106. Event64->u.CreateProcessInfo.nDebugInfoSize;
  107. Event->u.CreateProcessInfo.lpThreadLocalBase =
  108. (PVOID)(ULONG_PTR)(Event64->u.CreateProcessInfo.lpThreadLocalBase);
  109. Event->u.CreateProcessInfo.lpStartAddress =
  110. (LPTHREAD_START_ROUTINE)(ULONG_PTR)(Event64->u.CreateProcessInfo.lpStartAddress);
  111. Event->u.CreateProcessInfo.lpImageName =
  112. (PVOID)(ULONG_PTR)(Event64->u.CreateProcessInfo.lpImageName);
  113. Event->u.CreateProcessInfo.fUnicode =
  114. Event64->u.CreateProcessInfo.fUnicode;
  115. break;
  116. case EXIT_THREAD_DEBUG_EVENT:
  117. Event->u.ExitThread.dwExitCode =
  118. Event64->u.ExitThread.dwExitCode;
  119. break;
  120. case EXIT_PROCESS_DEBUG_EVENT:
  121. Event->u.ExitProcess.dwExitCode =
  122. Event64->u.ExitProcess.dwExitCode;
  123. break;
  124. case LOAD_DLL_DEBUG_EVENT:
  125. Event->u.LoadDll.hFile =
  126. (PVOID)(ULONG_PTR)(Event64->u.LoadDll.hFile);
  127. Event->u.LoadDll.lpBaseOfDll =
  128. (PVOID)(ULONG_PTR)(Event64->u.LoadDll.lpBaseOfDll);
  129. Event->u.LoadDll.dwDebugInfoFileOffset =
  130. Event64->u.LoadDll.dwDebugInfoFileOffset;
  131. Event->u.LoadDll.nDebugInfoSize =
  132. Event64->u.LoadDll.nDebugInfoSize;
  133. Event->u.LoadDll.lpImageName =
  134. (PVOID)(ULONG_PTR)(Event64->u.LoadDll.lpImageName);
  135. Event->u.LoadDll.fUnicode =
  136. Event64->u.LoadDll.fUnicode;
  137. break;
  138. case UNLOAD_DLL_DEBUG_EVENT:
  139. Event->u.UnloadDll.lpBaseOfDll =
  140. (PVOID)(ULONG_PTR)(Event64->u.UnloadDll.lpBaseOfDll);
  141. break;
  142. case OUTPUT_DEBUG_STRING_EVENT:
  143. Event->u.DebugString.lpDebugStringData =
  144. (LPSTR)(ULONG_PTR)(Event64->u.DebugString.lpDebugStringData);
  145. Event->u.DebugString.fUnicode =
  146. Event64->u.DebugString.fUnicode;
  147. Event->u.DebugString.nDebugStringLength =
  148. Event64->u.DebugString.nDebugStringLength;
  149. break;
  150. case RIP_EVENT:
  151. Event->u.RipInfo.dwError =
  152. Event64->u.RipInfo.dwError;
  153. Event->u.RipInfo.dwType =
  154. Event64->u.RipInfo.dwType;
  155. break;
  156. }
  157. }
  158. ULONG
  159. VDMEvent(DEBUG_EVENT64* pDebugEvent)
  160. /*
  161. returns - 0, if exception not handled
  162. STATUS_VDM_EVENT, if exception handled
  163. otherwise, the return value is the translated event status,
  164. for example STATUS_BREAKPOINT
  165. */
  166. {
  167. LPSTR Str;
  168. LPSTR pFileName;
  169. BOOL b;
  170. ULONG lpNumberOfBytesRead;
  171. UINT_PTR address;
  172. PULONG_PTR lpdw;
  173. int segslot;
  174. int mode;
  175. BOOL fData;
  176. WORD selector;
  177. WORD segment;
  178. WORD newselect;
  179. BOOL fStop;
  180. DWORD ImgLen;
  181. ULONG ulRet;
  182. BOOL fNeedSegTableEdit;
  183. BOOL fNeedInteractive;
  184. BOOL fVerbose;
  185. CHAR achInput[_MAX_PATH];
  186. PSTR pTemp;
  187. BOOL fProcess;
  188. SEGMENT_NOTE se;
  189. IMAGE_NOTE im;
  190. BOOL bProtectMode;
  191. WORD EventFlags;
  192. ulRet = VDMEVENT_HANDLED;
  193. if (!fVDMInitDone) {
  194. fVDMInitDone = TRUE;
  195. HINSTANCE hmodVDM = NULL;
  196. const char* c_szVDMFailed = NULL;
  197. fVDMActive = (
  198. (hmodVDM = LoadLibrary("VDMDBG.DLL")) &&
  199. (pfnVDMProcessException = (VDMPROCESSEXCEPTIONPROC)
  200. GetProcAddress(hmodVDM, c_szVDMFailed = "VDMProcessException")
  201. ) &&
  202. (pfnVDMGetPointer = (VDMGETPOINTERPROC)
  203. GetProcAddress(hmodVDM, c_szVDMFailed = "VDMGetPointer")
  204. ) &&
  205. (pfnVDMGetThreadSelectorEntry = (VDMGETTHREADSELECTORENTRYPROC)
  206. GetProcAddress(hmodVDM, c_szVDMFailed = "VDMGetThreadSelectorEntry")
  207. ) &&
  208. (pfnVDMGetContext = (VDMGETCONTEXTPROC)
  209. GetProcAddress(hmodVDM, c_szVDMFailed = "VDMGetContext")
  210. ) &&
  211. (pfnVDMSetContext = (VDMSETCONTEXTPROC)
  212. GetProcAddress( hmodVDM, c_szVDMFailed = "VDMSetContext")
  213. ) &&
  214. (pfnVDMGetSelectorModule = (VDMGETSELECTORMODULEPROC)
  215. GetProcAddress( hmodVDM, c_szVDMFailed = "VDMGetSelectorModule")
  216. )
  217. ); // fVDMActive
  218. if (!fVDMActive) { // display error on first time...
  219. if (!hmodVDM) {
  220. dprintf("LoadLibrary(VDMDBG.DLL) failed\n");
  221. }
  222. else if (c_szVDMFailed && *c_szVDMFailed) { // is valid printable string
  223. dprintf("%s can not be found in VDMDBG.DLL\n", c_szVDMFailed);
  224. }
  225. else {
  226. dprintf("Unknown failure while initializing VDMDBG.DLL\n");
  227. } // iff
  228. } // if
  229. } // if
  230. if (!fVDMActive) return VDMEVENT_NOT_HANDLED;
  231. DEBUG_EVENT Event;
  232. DebugEvent64To(pDebugEvent, &Event);
  233. lpdw = &(Event.u.Exception.ExceptionRecord.ExceptionInformation[0]);
  234. fProcess = (*pfnVDMProcessException)(&Event);
  235. fNeedSegTableEdit = FALSE;
  236. fNeedInteractive = FALSE;
  237. fVerbose = FALSE;
  238. mode = LOWORD(lpdw[0]);
  239. EventFlags = HIWORD(lpdw[0]);
  240. bProtectMode = (BOOL) (EventFlags & VDMEVENT_PE);
  241. // Has the caller explicitly asked for interaction?
  242. if (EventFlags & VDMEVENT_NEEDS_INTERACTIVE) {
  243. fNeedInteractive = TRUE;
  244. }
  245. if (EventFlags & VDMEVENT_VERBOSE) {
  246. fVerbose = TRUE;
  247. }
  248. switch( mode ) {
  249. case DBG_SEGLOAD:
  250. case DBG_SEGMOVE:
  251. case DBG_SEGFREE:
  252. case DBG_MODLOAD:
  253. case DBG_MODFREE:
  254. address = lpdw[2];
  255. b = g_Target->ReadVirtual(EXTEND64(address),
  256. &se, sizeof(se),
  257. &lpNumberOfBytesRead ) == S_OK;
  258. if ( !b || lpNumberOfBytesRead != sizeof(se) ) {
  259. return( VDMEVENT_NOT_HANDLED );
  260. }
  261. break;
  262. case DBG_DLLSTART:
  263. case DBG_DLLSTOP:
  264. case DBG_TASKSTART:
  265. case DBG_TASKSTOP:
  266. address = lpdw[2];
  267. b = g_Target->ReadVirtual(EXTEND64(address),
  268. &im, sizeof(im),
  269. &lpNumberOfBytesRead ) == S_OK;
  270. if ( !b || lpNumberOfBytesRead != sizeof(im) ) {
  271. return( VDMEVENT_NOT_HANDLED );
  272. }
  273. break;
  274. }
  275. switch( mode ) {
  276. default:
  277. ulRet = VDMEVENT_NOT_HANDLED;
  278. break;
  279. case DBG_SEGLOAD:
  280. fNeedSegTableEdit = TRUE;
  281. selector = se.Selector1;
  282. segment = se.Segment;
  283. fData = (BOOL)se.Type;
  284. segslot = 0;
  285. while ( segslot < MAXSEGENTRY ) {
  286. if ( segtable[segslot].type != SEGTYPE_AVAILABLE ) {
  287. if ( _stricmp(segtable[segslot].path_name, se.FileName) == 0 ) {
  288. break;
  289. }
  290. }
  291. segslot++;
  292. }
  293. if ( segslot == MAXSEGENTRY ) {
  294. if ( strlen(se.FileName) != 0 ) {
  295. dprintf("Loading [%s]\n", se.FileName );
  296. }
  297. }
  298. if (fVerbose) {
  299. dprintf("VDM SegLoad: %s(%d) %s => %x\n",
  300. se.FileName,
  301. segment,
  302. fData ? "Data" : "Code",
  303. selector);
  304. }
  305. break;
  306. case DBG_SEGMOVE:
  307. fNeedSegTableEdit = TRUE;
  308. segment = se.Segment;
  309. selector = se.Selector1;
  310. newselect = se.Selector2;
  311. if ( newselect == 0 ) {
  312. mode = DBG_SEGFREE;
  313. } else if (segment > 1) {
  314. //
  315. // real mode module is getting split up into different
  316. // segments, so create a new segtable entry
  317. //
  318. segslot = 0;
  319. while ( segslot < MAXSEGENTRY ) {
  320. if (( segtable[segslot].type != SEGTYPE_AVAILABLE ) &&
  321. ( segtable[segslot].selector == selector )) {
  322. mode = DBG_MODLOAD;
  323. segment--; //make it zero-based
  324. selector = newselect;
  325. pFileName = segtable[segslot].path_name;
  326. // Don't have the image length here so
  327. // just choose one.
  328. ImgLen = segtable[segslot].ImgLen;
  329. break;
  330. }
  331. segslot++;
  332. }
  333. }
  334. if (fVerbose) {
  335. dprintf("VDM SegMove: (%d) %x => %x\n",
  336. segment, selector, newselect);
  337. }
  338. break;
  339. case DBG_SEGFREE:
  340. fNeedSegTableEdit = TRUE;
  341. selector = se.Selector1;
  342. if (fVerbose) {
  343. dprintf("VDM SegFree: %x\n",selector);
  344. }
  345. break;
  346. case DBG_MODFREE:
  347. fNeedSegTableEdit = TRUE;
  348. if ( strlen(se.FileName) != 0 ) {
  349. dprintf("Freeing [%s]\n", se.FileName );
  350. } else if (fVerbose) {
  351. dprintf("VDM ModFree: unknown module\n");
  352. }
  353. break;
  354. case DBG_MODLOAD:
  355. fNeedSegTableEdit = TRUE;
  356. selector = se.Selector1;
  357. ImgLen = se.Length;
  358. segment = 0;
  359. pFileName = se.FileName;
  360. segslot = 0;
  361. while ( segslot < MAXSEGENTRY ) {
  362. if ( segtable[segslot].type != SEGTYPE_AVAILABLE ) {
  363. if ( _stricmp(segtable[segslot].path_name, se.FileName) == 0 ) {
  364. break;
  365. }
  366. }
  367. segslot++;
  368. }
  369. if ( segslot == MAXSEGENTRY ) {
  370. if ( strlen(se.FileName) != 0 ) {
  371. dprintf("Loading [%s]\n", se.FileName );
  372. }
  373. }
  374. if (fVerbose) {
  375. dprintf("VDM ModLoad: %s => %x, len=%x\n",
  376. se.FileName,
  377. selector,
  378. ImgLen);
  379. }
  380. break;
  381. case DBG_SINGLESTEP:
  382. if (g_TargetMachineType == IMAGE_FILE_MACHINE_I386) {
  383. fNeedInteractive = FALSE;
  384. ulRet = STATUS_SINGLE_STEP;
  385. } else {
  386. fNeedInteractive = TRUE;
  387. }
  388. break;
  389. case DBG_BREAK:
  390. if (g_TargetMachineType == IMAGE_FILE_MACHINE_I386) {
  391. fNeedInteractive = FALSE;
  392. ulRet = STATUS_BREAKPOINT;
  393. } else {
  394. fNeedInteractive = TRUE;
  395. }
  396. break;
  397. case DBG_GPFAULT:
  398. dprintf(" GP Fault in VDM\n");
  399. if (g_TargetMachineType == IMAGE_FILE_MACHINE_I386) {
  400. fNeedInteractive = FALSE;
  401. ulRet = STATUS_ACCESS_VIOLATION;
  402. } else {
  403. fNeedInteractive = TRUE;
  404. }
  405. break;
  406. case DBG_GPFAULT2:
  407. dprintf("GP Fault in VDM\n");
  408. dprintf("!!! second chance !!!\n");
  409. fNeedInteractive = TRUE;
  410. break;
  411. case DBG_INSTRFAULT:
  412. dprintf("invalid opcode fault in VDM\n");
  413. fNeedInteractive = TRUE;
  414. break;
  415. case DBG_DIVOVERFLOW:
  416. dprintf("divide overflow in VDM\n");
  417. fNeedInteractive = TRUE;
  418. break;
  419. case DBG_STACKFAULT:
  420. dprintf("stack fault in VDM\n");
  421. if (g_TargetMachineType == IMAGE_FILE_MACHINE_I386) {
  422. fNeedInteractive = FALSE;
  423. ulRet = STATUS_ACCESS_VIOLATION;
  424. } else {
  425. fNeedInteractive = TRUE;
  426. }
  427. break;
  428. case DBG_TASKSTART:
  429. if ( fNeedInteractive || fVerbose ) {
  430. dprintf("VDM Start Task <%s:%s>\n",
  431. im.Module,
  432. im.FileName );
  433. }
  434. break;
  435. case DBG_DLLSTART:
  436. if ( fNeedInteractive || fVerbose ) {
  437. dprintf("VDM Start Dll <%s:%s>\n", im.Module, im.FileName );
  438. }
  439. break;
  440. case DBG_TASKSTOP:
  441. fNeedInteractive = FALSE;
  442. break;
  443. case DBG_DLLSTOP:
  444. fNeedInteractive = FALSE;
  445. break;
  446. }
  447. /*
  448. ** Temporary code to emulate a 16-bit debugger. Eventually I will make
  449. ** NTSD understand these events and call ProcessStateChange to allow
  450. ** real 16-bit debugging and other activities on the other 32-bit threads.
  451. ** -BobDay
  452. */
  453. if ( fNeedInteractive ) {
  454. char text[MAX_DISASM_LEN];
  455. char path[128];
  456. UINT cSeg;
  457. ADDR addr;
  458. X86_NT5_CONTEXT vc;
  459. g_X86Machine.m_Context.X86Nt5Context.ContextFlags = VDMCONTEXT_FULL;
  460. (*pfnVDMGetContext)(g_EventProcess->Handle, OS_HANDLE(g_EventThread->Handle),
  461. (LPVDMCONTEXT)&g_X86Machine.m_Context);
  462. g_X86Machine.m_Context.X86Nt5Context.EFlags &= ~V86FLAGS_TRACE;
  463. vc = g_X86Machine.m_Context.X86Nt5Context;
  464. // Dump a simulated context
  465. g_X86Machine.OutputAll(g_X86Machine.m_AllMask,
  466. DEBUG_OUTPUT_PROMPT_REGISTERS);
  467. b = (*pfnVDMGetSelectorModule)(g_EventProcess->Handle, OS_HANDLE(g_EventThread->Handle),
  468. (WORD)g_X86Machine.m_Context.X86Nt5Context.SegCs, &cSeg, text, 128, path, 128 );
  469. if ( b ) {
  470. dprintf("%s:%d!%04x:\n", text, cSeg, (WORD)g_X86Machine.m_Context.X86Nt5Context.Eip );
  471. }
  472. addr.seg = (WORD)g_X86Machine.m_Context.X86Nt5Context.SegCs;
  473. addr.off = g_X86Machine.m_Context.X86Nt5Context.Eip;
  474. if ( !bProtectMode ) {
  475. addr.type = ADDR_V86 | FLAT_COMPUTED;
  476. addr.flat = (*pfnVDMGetPointer)(
  477. g_EventProcess->Handle,
  478. OS_HANDLE(g_EventThread->Handle),
  479. addr.seg,
  480. (ULONG)addr.off,
  481. FALSE
  482. );
  483. } else {
  484. addr.type = ADDR_16 | FLAT_COMPUTED;
  485. addr.flat = (*pfnVDMGetPointer)(
  486. g_EventProcess->Handle,
  487. OS_HANDLE(g_EventThread->Handle),
  488. addr.seg,
  489. (ULONG)addr.off,
  490. TRUE
  491. );
  492. }
  493. if ( Flat(addr) == 0 ) {
  494. dprintf("Unable to disassemble failing code\n");
  495. } else {
  496. g_X86Machine.Disassemble( &addr, text, TRUE );
  497. dprintf("%s", text );
  498. }
  499. AddExtensionDll("vdmexts", TRUE, NULL);
  500. while ( TRUE ) {
  501. GetInput("VDM>", achInput, sizeof(achInput));
  502. if ( _stricmp(achInput,"gh") == 0 || _stricmp(achInput,"g") == 0 ) {
  503. ulRet = VDMEVENT_HANDLED;
  504. break;
  505. }
  506. if ( _stricmp(achInput,"gn") == 0 ) {
  507. ulRet = VDMEVENT_NOT_HANDLED;
  508. break;
  509. }
  510. if ( _stricmp(achInput, "t") == 0 ) {
  511. ulRet = VDMEVENT_HANDLED;
  512. vc.EFlags |= V86FLAGS_TRACE;
  513. break;
  514. }
  515. if ((achInput[0] == 'r') && (_stricmp(achInput, "r") != 0)) {
  516. VDMRegCmd(achInput, &vc);
  517. g_X86Machine.m_Context.X86Nt5Context = vc;
  518. continue;
  519. }
  520. if (achInput[0] == '!') {
  521. fnBangCmd(NULL, &achInput[1], &pTemp, FALSE);
  522. continue;
  523. }
  524. if (achInput[0] == '.') {
  525. g_CurCmd = &achInput[1];
  526. g_CommandStart = g_CurCmd;
  527. ProcessCommandsAndCatch(NULL);
  528. continue;
  529. }
  530. if ( _stricmp(achInput,"?") == 0 ) {
  531. dprintf("\n---------- NTVDM Monitor Help ------------\n\n");
  532. dprintf("g - Go\n");
  533. dprintf("gh - Go : Exception handled\n");
  534. dprintf("gn - Go : Exception not handled\n");
  535. dprintf("help - Display extension help\n");
  536. dprintf("r<reg> <val> - reg=[eax|ebx|ecx|edx|eip|esp|ebp|efl]\n");
  537. dprintf("rp - display pending register set\n");
  538. dprintf("t - Trace 1 instruction\n");
  539. dprintf("!<cmd> - Execute extension command\n");
  540. dprintf(".<cmd> - Execute native NTSD command\n");
  541. dprintf("\nAnything else is interpreted as a VDMEXTS extension command\n\n");
  542. continue;
  543. }
  544. fnBangCmd(NULL, achInput, &pTemp, FALSE);
  545. }
  546. g_X86Machine.m_Context.X86Nt5Context = vc;
  547. (*pfnVDMSetContext)(g_EventProcess->Handle, OS_HANDLE(g_EventThread->Handle),
  548. (LPVDMCONTEXT)&g_X86Machine.m_Context);
  549. }
  550. /*
  551. ** End of temporary code
  552. */
  553. if ( fNeedSegTableEdit ) {
  554. segslot = 0;
  555. fStop = FALSE;
  556. while ( segslot < MAXSEGENTRY ) {
  557. switch( mode ) {
  558. case DBG_SEGLOAD:
  559. if ( segtable[segslot].type == SEGTYPE_AVAILABLE ) {
  560. segtable[segslot].segment = segment;
  561. segtable[segslot].selector = selector;
  562. // This notification message is used only by wow in prot
  563. // It could be determined from the current mode to be
  564. // correct
  565. segtable[segslot].type = SEGTYPE_PROT;
  566. Str = (PSTR)calloc(1,strlen(se.FileName)+1);
  567. if ( !Str ) {
  568. return( VDMEVENT_NOT_HANDLED );
  569. }
  570. strcpy( Str, se.FileName );
  571. segtable[segslot].path_name = Str;
  572. segtable[segslot].ImgLen = 0;
  573. fStop = TRUE;
  574. }
  575. break;
  576. case DBG_SEGMOVE:
  577. if (( segtable[segslot].type != SEGTYPE_AVAILABLE ) &&
  578. ( segtable[segslot].selector == selector )) {
  579. segtable[segslot].selector = newselect;
  580. fStop = TRUE;
  581. }
  582. break;
  583. case DBG_SEGFREE:
  584. if ( segtable[segslot].selector == selector ) {
  585. fStop = TRUE;
  586. segtable[segslot].type = SEGTYPE_AVAILABLE;
  587. free(segtable[segslot].path_name);
  588. segtable[segslot].path_name = NULL;
  589. }
  590. break;
  591. case DBG_MODFREE:
  592. if ( segtable[segslot].type != SEGTYPE_AVAILABLE ) {
  593. if ( _stricmp(segtable[segslot].path_name,se.FileName) == 0 ) {
  594. segtable[segslot].type = SEGTYPE_AVAILABLE;
  595. free(segtable[segslot].path_name);
  596. segtable[segslot].path_name = NULL;
  597. }
  598. }
  599. break;
  600. case DBG_MODLOAD:
  601. if ( segtable[segslot].type == SEGTYPE_AVAILABLE ) {
  602. segtable[segslot].segment = segment;
  603. segtable[segslot].selector = selector;
  604. // This notification message is used only by v86 dos
  605. // It could be determined from the current mode to be
  606. // correct
  607. segtable[segslot].type = SEGTYPE_V86;
  608. Str = (PSTR)calloc(1,strlen(pFileName)+1);
  609. if ( !Str ) {
  610. return( VDMEVENT_NOT_HANDLED );
  611. }
  612. strcpy( Str, pFileName );
  613. segtable[segslot].path_name = Str;
  614. segtable[segslot].ImgLen = ImgLen;
  615. fStop = TRUE;
  616. }
  617. break;
  618. }
  619. if ( fStop ) {
  620. break;
  621. }
  622. segslot++;
  623. }
  624. if ( segslot == MAXSEGENTRY ) {
  625. if ( mode == DBG_SEGLOAD ) {
  626. dprintf("Warning - adding selector %04X for segment %d, segtable full\n",
  627. selector, segment );
  628. }
  629. }
  630. }
  631. pDebugEvent->u.Exception.ExceptionRecord.ExceptionCode = ulRet;
  632. return( ulRet );
  633. }