minor corrections by M.Taguchi
[reactos.git] / reactos / apps / utils / pice / module / bp.c
1 /*++
2
3 Copyright (c) 1998-2001 Klaus P. Gerlicher
4
5 Module Name:
6
7 bp.c
8
9 Abstract:
10
11 setting, listing and removing breakpoints
12
13 Environment:
14
15 LINUX 2.2.X
16 Kernel mode only
17
18 Author:
19
20 Klaus P. Gerlicher
21
22 Revision History:
23
24 13-Nov-1999: created
25 15-Nov-2000: general cleanup of source files
26
27 Copyright notice:
28
29 This file may be distributed under the terms of the GNU Public License.
30
31 --*/
32
33 ////////////////////////////////////////////////////
34 // INCLUDES
35 ////
36 #include "remods.h"
37 #include "precomp.h"
38
39 ////////////////////////////////////////////////////
40 // GLOBALS
41 ////
42 char tempBp[1024];
43
44 ULONG OldInt3Handler=0;
45
46 SW_BP aSwBreakpoints[64]={{0,0,0,0},};
47
48 //*************************************************************************
49 // FindSwBp()
50 //
51 //*************************************************************************
52 PSW_BP FindSwBp(ULONG ulAddress)
53 {
54 ULONG i;
55
56 for(i=0;i<DIM(aSwBreakpoints);i++)
57 {
58 if(aSwBreakpoints[i].ulAddress == ulAddress && aSwBreakpoints[i].bUsed==TRUE && aSwBreakpoints[i].bVirtual==FALSE)
59 return &aSwBreakpoints[i];
60 }
61
62 return NULL;
63 }
64
65 //*************************************************************************
66 // FindEmptySwBpSlot()
67 //
68 //*************************************************************************
69 PSW_BP FindEmptySwBpSlot(void)
70 {
71 ULONG i;
72
73 for(i=0;i<(sizeof(aSwBreakpoints)/sizeof(SW_BP));i++)
74 {
75 if(aSwBreakpoints[i].bUsed == FALSE)
76 {
77 return &aSwBreakpoints[i];
78 }
79 }
80
81 return NULL;
82 }
83
84 //*************************************************************************
85 // FindVirtualSwBp()
86 //
87 //*************************************************************************
88 PSW_BP FindVirtualSwBp(LPSTR ModName,LPSTR szFunctionName)
89 {
90 ULONG i;
91 PSW_BP p;
92
93 for(i=0;i<(sizeof(aSwBreakpoints)/sizeof(SW_BP));i++)
94 {
95 p = &aSwBreakpoints[i];
96
97 if(p->bUsed == TRUE &&
98 p->bVirtual == TRUE &&
99 PICE_strcmpi(p->szModName,ModName)==0 &&
100 PICE_strcmpi(p->szFunctionName,szFunctionName)==0)
101 {
102 return p;
103 }
104 }
105
106 return NULL;
107 }
108
109 //*************************************************************************
110 // IsSwBpAtAddressInstalled()
111 //
112 //*************************************************************************
113 BOOLEAN IsSwBpAtAddressInstalled(ULONG ulAddress)
114 {
115 ULONG i;
116
117 for(i=0;i<DIM(aSwBreakpoints);i++)
118 {
119 if(aSwBreakpoints[i].ulAddress == ulAddress &&
120 aSwBreakpoints[i].bUsed == TRUE &&
121 aSwBreakpoints[i].bInstalled &&
122 aSwBreakpoints[i].bVirtual == FALSE)
123 return TRUE;
124 }
125
126 return FALSE;
127 }
128
129 //*************************************************************************
130 // IsSwBpAtAddress()
131 //
132 //*************************************************************************
133 BOOLEAN IsSwBpAtAddress(ULONG ulAddress)
134 {
135 ULONG i;
136
137 for(i=0;i<DIM(aSwBreakpoints);i++)
138 {
139 if(aSwBreakpoints[i].ulAddress == ulAddress && aSwBreakpoints[i].bUsed==TRUE && aSwBreakpoints[i].bVirtual==FALSE)
140 return TRUE;
141 }
142
143 return FALSE;
144 }
145
146 //*************************************************************************
147 // NeedToReInstallSWBreakpoints()
148 //
149 //*************************************************************************
150 BOOLEAN NeedToReInstallSWBreakpoints(ULONG ulAddress,BOOLEAN bUseAddress)
151 {
152 PSW_BP p;
153 BOOLEAN bResult = FALSE;
154 ULONG i;
155
156 ENTER_FUNC();
157 DPRINT((0,"NeedToReInstallSWBreakpoint() for %x (bUseAddress = %s)\n",ulAddress,bUseAddress?"TRUE":"FALSE"));
158
159 for(i=0;i<(sizeof(aSwBreakpoints)/sizeof(SW_BP));i++)
160 {
161 p = &aSwBreakpoints[i];
162 if(bUseAddress)
163 {
164 if(p->bUsed == TRUE && p->bInstalled == FALSE && p->ulAddress==ulAddress && p->bVirtual==FALSE)
165 {
166 if(IsAddressValid(p->ulAddress))
167 {
168 DPRINT((0,"NeedToReInstallSWBreakpoint(): [1] found BP\n"));
169 bResult = TRUE;
170 break;
171 }
172 }
173 }
174 else
175 {
176 if(p->bUsed == TRUE && p->bInstalled == FALSE && p->bVirtual == FALSE)
177 {
178 if(IsAddressValid(p->ulAddress))
179 {
180 DPRINT((0,"NeedToReInstallSWBreakpoint(): [2] found BP\n"));
181 bResult = TRUE;
182 break;
183 }
184 }
185 }
186 }
187
188 LEAVE_FUNC();
189
190 return bResult;
191 }
192
193 //*************************************************************************
194 // ReInstallSWBreakpoint()
195 //
196 //*************************************************************************
197 BOOLEAN ReInstallSWBreakpoint(ULONG ulAddress)
198 {
199 PSW_BP p;
200 BOOLEAN bResult = FALSE;
201 ULONG i;
202
203 ENTER_FUNC();
204 DPRINT((0,"ReInstallSWBreakpoint()\n"));
205
206 for(i=0;i<(sizeof(aSwBreakpoints)/sizeof(SW_BP));i++)
207 {
208 p = &aSwBreakpoints[i];
209 if(p->bUsed == TRUE && p->bInstalled == FALSE && p->ulAddress == ulAddress && p->bVirtual == FALSE)
210 {
211 if(IsAddressValid(p->ulAddress))
212 {
213 BOOLEAN isWriteable;
214
215 if( !( isWriteable = IsAddressWriteable(p->ulAddress) ) )
216 SetAddressWriteable(p->ulAddress,TRUE);
217 *(PUCHAR)(p->ulAddress) = 0xCC;
218 if( !isWriteable )
219 SetAddressWriteable(p->ulAddress,FALSE);
220 p->bInstalled = TRUE;
221 bResult = TRUE;
222 }
223 }
224 }
225
226 LEAVE_FUNC();
227
228 return bResult;
229 }
230
231
232 //*************************************************************************
233 // InstallSWBreakpoint()
234 //
235 //*************************************************************************
236 BOOLEAN InstallSWBreakpoint(ULONG ulAddress,BOOLEAN bPermanent,void (*SWBreakpointCallback)(void))
237 {
238 PSW_BP p;
239 BOOLEAN bResult = FALSE;
240
241 ENTER_FUNC();
242 DPRINT((0,"InstallSWBreakpoint()\n"));
243
244 // check if page is present
245 // TODO: must also check if it's a writable page
246 if(IsAddressValid(ulAddress) )
247 {
248 DPRINT((0,"InstallSWBreakpoint(): %.8X is valid, writable? %d\n",ulAddress,IsAddressWriteable(ulAddress)));
249 DPRINT((0,"pde: %x, pte: %x\n", *(ADDR_TO_PDE(ulAddress)), *(ADDR_TO_PTE(ulAddress))));
250 if((p = FindSwBp(ulAddress))==NULL)
251 {
252 DPRINT((0,"InstallSWBreakpoint(): %.8X is free\n",ulAddress));
253 if( (p=FindEmptySwBpSlot()) )
254 {
255 BOOLEAN isWriteable;
256 DPRINT((0,"InstallSWBreakpoint(): found empty slot\n"));
257 DPRINT((0,"InstallSWBreakpoint(): %x value: %x", ulAddress, *(PUCHAR)ulAddress));
258 p->ucOriginalOpcode = *(PUCHAR)ulAddress;
259 //allow writing to page
260 if( !( isWriteable = IsAddressWriteable(ulAddress) ) )
261 SetAddressWriteable(ulAddress,TRUE);
262 DPRINT((0,"writing breakpoint\n"));
263 *(PUCHAR)ulAddress = 0xCC;
264 DPRINT((0,"restoring page access\n"));
265 if( !isWriteable )
266 SetAddressWriteable(ulAddress,FALSE);
267 p->bUsed = TRUE;
268 p->bInstalled = TRUE;
269 // find next address
270 p->ulAddress = ulAddress;
271 Disasm(&ulAddress,(PUCHAR)&tempBp);
272 p->ulNextInstr = ulAddress;
273 p->bPermanent = bPermanent;
274 if(bPermanent)
275 p->Callback = SWBreakpointCallback;
276 else
277 p->Callback = NULL;
278 bResult = TRUE;
279 }
280 }
281 else
282 {
283 DPRINT((0,"InstallSWBreakpoint(): %.8X is already used\n",ulAddress));
284 if(p->bPermanent)
285 {
286 DPRINT((0,"InstallSWBreakpoint(): %.8X is a permanent breakpoint\n",ulAddress));
287 }
288 }
289 }
290
291 LEAVE_FUNC();
292
293 return bResult;
294 }
295
296 //*************************************************************************
297 // InstallVirtualSWBreakpoint()
298 //
299 //*************************************************************************
300 BOOLEAN InstallVirtualSWBreakpoint(LPSTR ModName,LPSTR FunctionName)
301 {
302 PSW_BP p;
303 BOOLEAN bResult = FALSE;
304
305 ENTER_FUNC();
306 DPRINT((0,"InstallVirtualSWBreakpoint(%s!%s)\n",ModName,FunctionName));
307
308 if( (p=FindEmptySwBpSlot()) )
309 {
310 DPRINT((0,"InstallVirtualSWBreakpoint(): found empty slot\n"));
311
312 p->bUsed = TRUE;
313 p->bInstalled = TRUE;
314 p->bVirtual = TRUE;
315 p->Callback = NULL;
316 PICE_strcpy(p->szModName,ModName);
317 PICE_strcpy(p->szFunctionName,FunctionName);
318
319 bResult = TRUE;
320 }
321
322 LEAVE_FUNC();
323
324 return bResult;
325 }
326
327 //*************************************************************************
328 // TryToInstallVirtualSWBreakpoints()
329 //
330 //*************************************************************************
331 void TryToInstallVirtualSWBreakpoints(void)
332 {
333 ULONG i,ulAddress;
334 PDEBUG_MODULE pMod;
335 PSW_BP p;
336
337 DPRINT((0,"TryToInstallVirtualSWBreakpoints()\n"));
338
339 for(i=0;i<(sizeof(aSwBreakpoints)/sizeof(SW_BP));i++)
340 {
341 p = &aSwBreakpoints[i];
342 if(p->bUsed == TRUE && p->bVirtual)
343 {
344 if((pMod = IsModuleLoaded(p->szModName)))
345 {
346 if((ulAddress = FindFunctionInModuleByName(p->szFunctionName,pMod)))
347 {
348 if((p = FindVirtualSwBp(p->szModName,p->szFunctionName)))
349 {
350 ULONG ulAddressWithOffset = ulAddress+p->ulAddress;
351 DPRINT((0,"TryToInstallVirtualSWBreakpoints(): ulAddressWithOffset = %x (offset = %x)\n",ulAddressWithOffset,p->ulAddress));
352
353 if(IsAddressValid(ulAddressWithOffset))
354 {
355 BOOLEAN isWriteable;
356 DPRINT((0,"TryToInstallVirtualSWBreakpoints(): installing...\n"));
357 p->ucOriginalOpcode = *(PUCHAR)ulAddressWithOffset;
358 //allow writing to page
359 if( !( isWriteable = IsAddressWriteable(ulAddressWithOffset) ) )
360 SetAddressWriteable(ulAddressWithOffset,TRUE);
361 *(PUCHAR)ulAddressWithOffset = 0xCC;
362 if( !isWriteable )
363 SetAddressWriteable(ulAddressWithOffset,FALSE);
364 p->bUsed = TRUE;
365 p->bInstalled = TRUE;
366 p->bVirtual = FALSE;
367 // find next address
368 p->ulAddress = ulAddressWithOffset;
369 Disasm(&ulAddressWithOffset,(PUCHAR)&tempBp);
370 p->ulNextInstr = ulAddressWithOffset;
371 p->bPermanent = FALSE;
372 p->Callback = NULL;
373 }
374 else
375 {
376 DPRINT((0,"TryToInstallVirtualSWBreakpoints(): not valid address\n"));
377 PICE_memset(p,0,sizeof(*p));
378 }
379 }
380
381 }
382 }
383 }
384 }
385 }
386
387 //*************************************************************************
388 // RemoveSWBreakpoint()
389 //
390 // removes breakpoint from breakpoint list
391 //*************************************************************************
392 BOOLEAN RemoveSWBreakpoint(ULONG ulAddress)
393 {
394 PSW_BP p;
395 BOOLEAN bResult = FALSE;
396
397 ENTER_FUNC();
398 DPRINT((0,"RemoveSWBreakpoint()\n"));
399
400 if( (p = FindSwBp(ulAddress)) )
401 {
402 if(IsAddressValid(ulAddress) && p->bInstalled == TRUE && p->bVirtual==FALSE)
403 {
404 BOOLEAN isWriteable;
405 if( !( isWriteable = IsAddressWriteable(ulAddress) ) )
406 SetAddressWriteable(ulAddress,TRUE);
407 // restore original opcode
408 *(PUCHAR)(p->ulAddress) = p->ucOriginalOpcode;
409 if( !isWriteable )
410 SetAddressWriteable(ulAddress,FALSE);
411 }
412
413 PICE_memset(p,0,sizeof(*p));
414
415 bResult = TRUE;
416 }
417
418 LEAVE_FUNC();
419
420 return bResult;
421 }
422
423
424 //*************************************************************************
425 // DeInstallSWBreakpoint()
426 //
427 //*************************************************************************
428 BOOLEAN DeInstallSWBreakpoint(ULONG ulAddress)
429 {
430 PSW_BP p;
431 BOOLEAN bResult = FALSE;
432
433 ENTER_FUNC();
434 DPRINT((0,"DeInstallSWBreakpoint()\n"));
435
436 if( (p = FindSwBp(ulAddress)) )
437 {
438 if(IsAddressValid(ulAddress) && p->bInstalled == TRUE && p->bVirtual==FALSE)
439 {
440 BOOLEAN isWriteable;
441 if( !( isWriteable = IsAddressWriteable(ulAddress) ) )
442 SetAddressWriteable(ulAddress,TRUE);
443 // restore original opcode
444 *(PUCHAR)(p->ulAddress) = p->ucOriginalOpcode;
445 if( !isWriteable )
446 SetAddressWriteable(ulAddress,FALSE);
447 }
448
449 p->bInstalled = FALSE;
450
451 bResult = TRUE;
452 }
453
454 LEAVE_FUNC();
455
456 return bResult;
457 }
458
459 //*************************************************************************
460 // RemoveAllSWBreakpoints()
461 //
462 //*************************************************************************
463 BOOLEAN RemoveAllSWBreakpoints(BOOLEAN bEvenPermanents)
464 {
465 PSW_BP p;
466 BOOLEAN bResult = FALSE;
467 ULONG i;
468
469 ENTER_FUNC();
470 DPRINT((0,"RemoveAllSWBreakpoint()\n"));
471
472 for(i=0;i<(sizeof(aSwBreakpoints)/sizeof(SW_BP));i++)
473 {
474 p = &aSwBreakpoints[i];
475 if(p->bUsed == TRUE)
476 {
477 if(bEvenPermanents)
478 {
479 if(IsAddressValid(p->ulAddress) && p->bVirtual==FALSE)
480 {
481 BOOLEAN isWriteable;
482 if( !( isWriteable = IsAddressWriteable(p->ulAddress) ) )
483 SetAddressWriteable(p->ulAddress,TRUE);
484 *(PUCHAR)(p->ulAddress) = p->ucOriginalOpcode;
485 if( !isWriteable )
486 SetAddressWriteable(p->ulAddress,FALSE);
487 bResult = TRUE;
488 }
489 PICE_memset(p,0,sizeof(*p));
490 }
491 else
492 {
493 if(!p->bPermanent)
494 {
495 if(IsAddressValid(p->ulAddress) && p->bVirtual==FALSE)
496 {
497 BOOLEAN isWriteable;
498 if( !( isWriteable = IsAddressWriteable(p->ulAddress) ) )
499 SetAddressWriteable(p->ulAddress,TRUE);
500 *(PUCHAR)(p->ulAddress) = p->ucOriginalOpcode;
501 if( !isWriteable )
502 SetAddressWriteable(p->ulAddress,FALSE);
503 bResult = TRUE;
504 }
505 PICE_memset(p,0,sizeof(*p));
506 }
507 }
508 }
509 }
510
511 LEAVE_FUNC();
512
513 return bResult;
514 }
515
516 //*************************************************************************
517 // IsPermanentSWBreakpoint()
518 //
519 //*************************************************************************
520 PSW_BP IsPermanentSWBreakpoint(ULONG ulAddress)
521 {
522 PSW_BP p;
523 ULONG i;
524
525 ENTER_FUNC();
526 DPRINT((0,"IsPermanentSWBreakpoint(%.8X)\n",ulAddress));
527
528 for(i=0;i<(sizeof(aSwBreakpoints)/sizeof(aSwBreakpoints[0]));i++)
529 {
530 p = &aSwBreakpoints[i];
531 if(p->ulAddress == ulAddress &&
532 p->bUsed == TRUE &&
533 p->bPermanent == TRUE)
534 {
535 LEAVE_FUNC();
536 return p;
537 }
538 }
539
540 LEAVE_FUNC();
541
542 return NULL;
543 }
544
545 //*************************************************************************
546 // ListSWBreakpoints()
547 //
548 //*************************************************************************
549 void ListSWBreakpoints(void)
550 {
551 PSW_BP p;
552 ULONG i;
553 LPSTR pSymbolName;
554 PDEBUG_MODULE pMod;
555
556 ENTER_FUNC();
557 DPRINT((0,"ListSWBreakpoints()\n"));
558
559 for(i=0;i<(sizeof(aSwBreakpoints)/sizeof(SW_BP));i++)
560 {
561 p = &aSwBreakpoints[i];
562 if(p->bUsed == TRUE && p->bVirtual == FALSE)
563 {
564 if((pSymbolName = FindFunctionByAddress(p->ulAddress,NULL,NULL)) )
565 {
566 pMod = FindModuleFromAddress(p->ulAddress);
567 PICE_sprintf(tempBp,"[%u] %.8X (%S!%s) %s\n",i,p->ulAddress,pMod->name,pSymbolName,p->bPermanent?"PERMANENT":"");
568 }
569 else
570 {
571 if(ScanExportsByAddress(&pSymbolName,p->ulAddress))
572 PICE_sprintf(tempBp,"[%u] %.8X (%s) %s\n",i,p->ulAddress,pSymbolName,p->bPermanent?"PERMANENT":"");
573 else
574 PICE_sprintf(tempBp,"[%u] %.8X (no symbol) %s\n",i,p->ulAddress,p->bPermanent?"PERMANENT":"");
575 }
576 Print(OUTPUT_WINDOW,tempBp);
577 }
578 else if(p->bUsed == TRUE)
579 {
580 PICE_sprintf(tempBp,"[%u] xxxxxxxx (%s!%s) VIRTUAL\n",i,p->szModName,p->szFunctionName);
581 Print(OUTPUT_WINDOW,tempBp);
582 }
583 }
584
585 LEAVE_FUNC();
586 }
587
588 //*************************************************************************
589 // RevirtualizeBreakpointsForModule()
590 //
591 //*************************************************************************
592 void RevirtualizeBreakpointsForModule(PDEBUG_MODULE pMod)
593 {
594 ULONG i,start,end;
595 PSW_BP p;
596 char temp[DEBUG_MODULE_NAME_LEN];
597
598 DPRINT((0,"RevirtualizeBreakpointsForModule(%x)\n",(ULONG)pMod));
599
600 if(IsRangeValid((ULONG)pMod,sizeof(DEBUG_MODULE)) )
601 {
602 start = (ULONG)pMod->BaseAddress;
603 end = (ULONG)pMod->BaseAddress+pMod->size;
604
605 DPRINT((0,"RevirtualizeBreakpointsForModule(): module %x (%x-%x)\n",(ULONG)pMod,start,end));
606 // go through all breakpoints
607 for(i=0;i<(sizeof(aSwBreakpoints)/sizeof(SW_BP));i++)
608 {
609 p = &aSwBreakpoints[i];
610 // if it's used and installed and not virtual
611 if(p->bUsed && p->bInstalled && p->bVirtual == FALSE)
612 {
613 // make sure we're in module's bound
614 if(p->ulAddress>=start && p->ulAddress<end)
615 {
616 LPSTR pFind;
617 ULONG ulFunctionAddress;
618
619 DPRINT((0,"RevirtualizeBreakpointsForModule(): module breakpoint %u\n",i));
620 // find the function in which this breakpoint resides
621 if(ScanExportsByAddress(&pFind,p->ulAddress))
622 {
623 // from now on it's virtual again
624 p->bVirtual = TRUE;
625 if(IsAddressValid(p->ulAddress) )
626 {
627 BOOLEAN isWriteable;
628 if( !( isWriteable = IsAddressWriteable(p->ulAddress) ) )
629 SetAddressWriteable(p->ulAddress,TRUE);
630 DPRINT((0,"RevirtualizeBreakpointsForModule(): restoring original opcode @ %x\n",p->ulAddress));
631 *(PUCHAR)(p->ulAddress) = p->ucOriginalOpcode;
632 if( !isWriteable )
633 SetAddressWriteable(p->ulAddress,FALSE);
634 }
635 else
636 {
637 DPRINT((0,"RevirtualizeBreakpointsForModule(): could not restore original opcode @ %x\n",p->ulAddress));
638 }
639 // skip past the module separator
640 while(*pFind!='!')pFind++;
641 pFind++;
642 // remember the function and the module for reinstallation
643 CopyWideToAnsi(temp,pMod->name);
644 PICE_strcpy(p->szModName,temp);
645 PICE_strcpy(p->szFunctionName,pFind);
646 DPRINT((0,"RevirtualizeBreakpointsForModule(): %s!%s\n",p->szModName,p->szFunctionName));
647 // if function name contains a '+' it's an offset
648 pFind = p->szFunctionName;
649 while(*pFind!=0)
650 {
651 DPRINT((0,"RevirtualizeBreakpointsForModule(): [1] %s\n",pFind));
652 // found any offset to function
653 if(*pFind=='+')
654 {
655 *pFind=0;
656 break;
657 }
658 pFind++;
659 }
660
661 DPRINT((0,"RevirtualizeBreakpointsForModule(): [2] %s\n",p->szFunctionName));
662 if(ScanExports(p->szFunctionName,&ulFunctionAddress))
663 {
664 p->ulAddress -= ulFunctionAddress;
665 DPRINT((0,"RevirtualizeBreakpointsForModule(): [1] function @ %x offset = %x\n",ulFunctionAddress,p->ulAddress));
666 }
667 else
668 {
669 if((ulFunctionAddress = FindFunctionInModuleByName(p->szFunctionName,pMod)) )
670 {
671 p->ulAddress -= ulFunctionAddress;
672 DPRINT((0,"RevirtualizeBreakpointsForModule(): [2] function @ %x offset = %x\n",ulFunctionAddress,p->ulAddress));
673 }
674 else
675 {
676 DPRINT((0,"RevirtualizeBreakpointsForModule(): Breakpoint %u could not be virtualized properly!\n",i));
677 PICE_sprintf(tempBp,"Breakpoint %u could not be virtualized properly!\n",i);
678 Print(OUTPUT_WINDOW,tempBp);
679 }
680 }
681 }
682 else
683 {
684 DPRINT((0,"RevirtualizeBreakpointsForModule(): function for %x not found!\n",p->ulAddress));
685 PICE_memset(p,0,sizeof(*p));
686 }
687 }
688 }
689 }
690 }
691 }
692
693 //*************************************************************************
694 // NewInt3Handler()
695 //
696 //*************************************************************************
697 __asm__ ("\n\t \
698 NewInt3Handler:\n\t \
699 pushl $" STR(REASON_INT3) "\n\t \
700 // call debugger loop\n\t \
701 jmp NewInt31Handler\n\t \
702 ");
703
704
705 //*************************************************************************
706 // InstallInt3Hook()
707 //
708 //*************************************************************************
709 void InstallInt3Hook(void)
710 {
711 ULONG LocalInt3Handler;
712
713 ENTER_FUNC();
714 DPRINT((0,"enter InstallInt3Hook()...\n"));
715
716 MaskIrqs();
717 if(!OldInt3Handler)
718 {
719 PICE_memset(aSwBreakpoints,0,sizeof(aSwBreakpoints));
720 __asm__("mov $NewInt3Handler,%0"
721 :"=r" (LocalInt3Handler)
722 :
723 :"eax");
724 OldInt3Handler=SetGlobalInt(0x03,(ULONG)LocalInt3Handler);
725 }
726 UnmaskIrqs();
727
728 DPRINT((0,"leave InstallInt3Hook()...\n"));
729 LEAVE_FUNC();
730 }
731
732 //*************************************************************************
733 // DeInstallInt3Hook()
734 //
735 //*************************************************************************
736 void DeInstallInt3Hook(void)
737 {
738 ENTER_FUNC();
739 DPRINT((0,"enter DeInstallInt3Hook()...\n"));
740
741 MaskIrqs();
742 if(OldInt3Handler)
743 {
744 RemoveAllSWBreakpoints(TRUE);
745 SetGlobalInt(0x03,(ULONG)OldInt3Handler);
746 OldInt3Handler=0;
747 }
748 UnmaskIrqs();
749
750 DPRINT((0,"leave DeInstallInt3Hook()...\n"));
751 LEAVE_FUNC();
752 }