:pserver:cvsanon@mok.lvcm.com:/CVS/ReactOS reactos
[reactos.git] / 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 }