Fixed WinMain's signature.
[wine] / debugger / break.c
1 /*
2  * Debugger break-points handling
3  *
4  * Copyright 1994 Martin von Loewis
5  * Copyright 1995 Alexandre Julliard
6  * Copyright 1999,2000 Eric Pouech
7  */
8
9 #include "config.h"
10 #include "debugger.h"
11
12 #ifdef __i386__
13 #define DR7_CONTROL_SHIFT       16
14 #define DR7_CONTROL_SIZE        4
15
16 #define DR7_RW_EXECUTE          (0x0)
17 #define DR7_RW_WRITE            (0x1)
18 #define DR7_RW_READ             (0x3)
19
20 #define DR7_LEN_1               (0x0)
21 #define DR7_LEN_2               (0x4)
22 #define DR7_LEN_4               (0xC)
23
24 #define DR7_LOCAL_ENABLE_SHIFT  0
25 #define DR7_GLOBAL_ENABLE_SHIFT 1
26 #define DR7_ENABLE_SIZE         2
27
28 #define DR7_LOCAL_ENABLE_MASK   (0x55)
29 #define DR7_GLOBAL_ENABLE_MASK  (0xAA)
30
31 #define DR7_CONTROL_RESERVED    (0xFC00)
32 #define DR7_LOCAL_SLOWDOWN      (0x100)
33 #define DR7_GLOBAL_SLOWDOWN     (0x200)
34
35 #define DR7_ENABLE_MASK(dr)     (1<<(DR7_LOCAL_ENABLE_SHIFT+DR7_ENABLE_SIZE*(dr)))
36 #define IS_DR7_SET(ctrl,dr)     ((ctrl)&DR7_ENABLE_MASK(dr))
37 #define INT3          0xcc   /* int 3 opcode */
38 #endif
39
40 #define MAX_BREAKPOINTS 100
41
42 static DBG_BREAKPOINT breakpoints[MAX_BREAKPOINTS];
43
44 static int next_bp = 1;  /* breakpoint 0 is reserved for step-over */
45
46 /***********************************************************************
47  *           DEBUG_IsStepOverInstr
48  *
49  * Determine if the instruction at CS:EIP is an instruction that
50  * we need to step over (like a call or a repetitive string move).
51  */
52 static BOOL DEBUG_IsStepOverInstr(void)
53 {
54 #ifdef __i386__
55     BYTE*       instr;
56     BYTE        ch;
57     DBG_ADDR    addr;
58
59     addr.seg = DEBUG_context.SegCs;
60     addr.off = DEBUG_context.Eip;
61     /* FIXME: old code was using V86BASE(DEBUG_context)
62      * instead of passing thru DOSMEM_MemoryBase
63      */
64     instr = (BYTE*)DEBUG_ToLinear(&addr);
65
66     for (;;)
67     {
68         if (!DEBUG_READ_MEM(instr, &ch, sizeof(ch)))
69             return FALSE;
70
71         switch (ch)
72         {
73           /* Skip all prefixes */
74
75         case 0x2e:  /* cs: */
76         case 0x36:  /* ss: */
77         case 0x3e:  /* ds: */
78         case 0x26:  /* es: */
79         case 0x64:  /* fs: */
80         case 0x65:  /* gs: */
81         case 0x66:  /* opcode size prefix */
82         case 0x67:  /* addr size prefix */
83         case 0xf0:  /* lock */
84         case 0xf2:  /* repne */
85         case 0xf3:  /* repe */
86             instr++;
87             continue;
88
89           /* Handle call instructions */
90
91         case 0xcd:  /* int <intno> */
92         case 0xe8:  /* call <offset> */
93         case 0x9a:  /* lcall <seg>:<off> */
94             return TRUE;
95
96         case 0xff:  /* call <regmodrm> */
97             if (!DEBUG_READ_MEM(instr + 1, &ch, sizeof(ch)))
98                 return FALSE;
99             return (((ch & 0x38) == 0x10) || ((ch & 0x38) == 0x18));
100
101           /* Handle string instructions */
102
103         case 0x6c:  /* insb */
104         case 0x6d:  /* insw */
105         case 0x6e:  /* outsb */
106         case 0x6f:  /* outsw */
107         case 0xa4:  /* movsb */
108         case 0xa5:  /* movsw */
109         case 0xa6:  /* cmpsb */
110         case 0xa7:  /* cmpsw */
111         case 0xaa:  /* stosb */
112         case 0xab:  /* stosw */
113         case 0xac:  /* lodsb */
114         case 0xad:  /* lodsw */
115         case 0xae:  /* scasb */
116         case 0xaf:  /* scasw */
117             return TRUE;
118
119         default:
120             return FALSE;
121         }
122     }
123 #else
124     return FALSE;
125 #endif
126 }
127
128
129 /***********************************************************************
130  *           DEBUG_IsFctReturn
131  *
132  * Determine if the instruction at CS:EIP is an instruction that
133  * is a function return.
134  */
135 BOOL DEBUG_IsFctReturn(void)
136 {
137 #ifdef __i386__
138     BYTE*       instr;
139     BYTE        ch;
140     DBG_ADDR    addr;
141
142     addr.seg = DEBUG_context.SegCs;
143     addr.off = DEBUG_context.Eip;
144     /* FIXME: old code was using V86BASE(DEBUG_context)
145      * instead of passing thru DOSMEM_MemoryBase
146      */
147     instr = (BYTE*)DEBUG_ToLinear(&addr);
148
149     if (!DEBUG_READ_MEM(instr, &ch, sizeof(ch)))
150         return FALSE;
151
152     return (ch == 0xc2) || (ch == 0xc3);
153 #else
154     return FALSE;
155 #endif
156 }
157
158
159 /***********************************************************************
160  *           DEBUG_SetBreakpoints
161  *
162  * Set or remove all the breakpoints.
163  */
164 void DEBUG_SetBreakpoints( BOOL set )
165 {
166    int          i;
167    
168 #ifdef __i386__
169    DEBUG_context.Dr7 &= ~DR7_LOCAL_ENABLE_MASK;
170 #endif
171    
172    for (i = 0; i < next_bp; i++)
173    {
174       if (!(breakpoints[i].refcount && breakpoints[i].enabled))
175          continue;
176       
177       switch (breakpoints[i].type) {
178       case DBG_BREAK:
179          {
180 #ifdef __i386__
181             char ch = set ? INT3 : breakpoints[i].u.b.opcode;
182             
183             if (!DEBUG_WRITE_MEM( (void*)DEBUG_ToLinear(&breakpoints[i].addr), 
184                                   &ch, sizeof(ch) ))
185             {
186                DEBUG_Printf(DBG_CHN_MESG, "Invalid address for breakpoint %d, disabling it\n", i);
187                breakpoints[i].enabled = FALSE;
188             }
189 #endif
190          }
191          break;
192       case DBG_WATCH:
193          if (set) 
194          {
195 #ifdef __i386__
196             DWORD       bits;
197             int         reg = breakpoints[i].u.w.reg;
198             LPDWORD     lpdr = NULL;
199
200             switch (reg) 
201             {
202                case 0: lpdr = &DEBUG_context.Dr0; break;
203                case 1: lpdr = &DEBUG_context.Dr1; break;
204                case 2: lpdr = &DEBUG_context.Dr2; break;
205                case 3: lpdr = &DEBUG_context.Dr3; break;
206                default: RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
207             }
208             
209             *lpdr = DEBUG_ToLinear(&breakpoints[i].addr);
210             bits = (breakpoints[i].u.w.rw) ? DR7_RW_WRITE : DR7_RW_READ;
211             switch (breakpoints[i].u.w.len + 1)
212             {
213                case 4: bits |= DR7_LEN_4;       break;
214                case 2: bits |= DR7_LEN_2;       break;
215                case 1: bits |= DR7_LEN_1;       break;
216                default: RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
217             }
218             
219             DEBUG_context.Dr7 &= ~(0x0F << (DR7_CONTROL_SHIFT + DR7_CONTROL_SIZE * reg));
220             DEBUG_context.Dr7 |= bits << (DR7_CONTROL_SHIFT + DR7_CONTROL_SIZE * reg);
221             DEBUG_context.Dr7 |= DR7_ENABLE_MASK(reg) | DR7_LOCAL_SLOWDOWN;
222 #endif
223          }
224          break;
225       }
226    }
227 }
228
229 /***********************************************************************
230  *           DEBUG_FindBreakpoint
231  *
232  * Find the breakpoint for a given address. Return the breakpoint
233  * number or -1 if none.
234  * If type is DBG_BREAKPOINT, addr is a complete addr
235  * If type is DBG_WATCHPOINT, only addr.off is meaningful and contains 
236  * linear address
237  */
238 static int DEBUG_FindBreakpoint( const DBG_ADDR *addr, int type )
239 {
240    int i;
241    
242    for (i = 0; i < next_bp; i++)
243    {
244       if (breakpoints[i].refcount && breakpoints[i].enabled &&
245           breakpoints[i].type == type )
246       {
247          if ((type == DBG_BREAK && 
248               breakpoints[i].addr.seg == addr->seg &&
249               breakpoints[i].addr.off == addr->off) ||
250              (type == DBG_WATCH && 
251               DEBUG_ToLinear(&breakpoints[i].addr) == addr->off))
252             return i;
253       }
254    }
255    return -1;
256 }
257
258 /***********************************************************************
259  *           DEBUG_InitXPoint
260  *
261  * Find an empty slot in BP table to add a new break/watch point
262  */
263 static  int     DEBUG_InitXPoint(int type, DBG_ADDR* addr)
264 {
265    int  num;
266    
267    for (num = (next_bp < MAX_BREAKPOINTS) ? next_bp++ : 1; 
268         num < MAX_BREAKPOINTS; num++) 
269    {
270       if (breakpoints[num].refcount == 0) 
271       {
272          breakpoints[num].refcount = 1;
273          breakpoints[num].enabled = TRUE;
274          breakpoints[num].type    = type;
275          breakpoints[num].skipcount = 0;
276          breakpoints[num].addr = *addr;
277          breakpoints[num].is32 = 1;
278 #ifdef __i386__
279          if (addr->seg) 
280          {
281             switch (DEBUG_GetSelectorType( addr->seg )) 
282             {
283                case 32: break;
284                case 16: breakpoints[num].is32 = 0; break;
285                default: RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
286             }
287          }
288 #endif
289          return num;
290       }
291    }
292    
293    DEBUG_Printf( DBG_CHN_MESG, "Too many breakpoints. Please delete some.\n" );
294    return -1;
295 }
296
297 /***********************************************************************
298  *           DEBUG_GetWatchedValue
299  *
300  * Returns the value watched by watch point 'num'.
301  */
302 static  BOOL    DEBUG_GetWatchedValue( int num, LPDWORD val )
303 {
304    BYTE         buf[4];
305    
306    if (!DEBUG_READ_MEM((void*)DEBUG_ToLinear(&breakpoints[num].addr), 
307                        buf, breakpoints[num].u.w.len + 1))
308       return FALSE;
309    
310    switch (breakpoints[num].u.w.len + 1) 
311    {
312       case 4:   *val = *(DWORD*)buf;    break;
313       case 2:   *val = *(WORD*)buf;     break;
314       case 1:   *val = *(BYTE*)buf;     break;
315       default: RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
316    }
317    return TRUE;
318 }
319
320 /***********************************************************************
321  *           DEBUG_AddBreakpoint
322  *
323  * Add a breakpoint.
324  */
325 void DEBUG_AddBreakpoint( const DBG_VALUE *_value, BOOL (*func)(void) )
326 {
327     DBG_VALUE value = *_value;
328     int num;
329     unsigned int seg2;
330     BYTE ch;
331
332     assert(_value->cookie == DV_TARGET || _value->cookie == DV_HOST);
333
334 #ifdef __i386__
335     DEBUG_FixAddress( &value.addr, DEBUG_context.SegCs );
336 #endif
337
338     if( value.type != NULL && value.type == DEBUG_TypeIntConst )
339     {
340        /*
341         * We know that we have the actual offset stored somewhere
342         * else in 32-bit space.  Grab it, and we
343         * should be all set.
344         */
345        seg2 = value.addr.seg;
346        value.addr.seg = 0;
347        value.addr.off = DEBUG_GetExprValue(&value, NULL);
348        value.addr.seg = seg2;
349     }
350
351     if ((num = DEBUG_FindBreakpoint(&value.addr, DBG_BREAK)) >= 1) 
352     {
353        breakpoints[num].refcount++;
354        return;
355     }
356
357     if (!DEBUG_READ_MEM_VERBOSE((void*)DEBUG_ToLinear( &value.addr ), &ch, sizeof(ch)))
358         return;
359
360     if ((num = DEBUG_InitXPoint(DBG_BREAK, &value.addr)) == -1)
361        return;
362
363     breakpoints[num].u.b.opcode = ch;
364     breakpoints[num].u.b.func = func;
365
366     DEBUG_Printf( DBG_CHN_MESG, "Breakpoint %d at ", num );
367     DEBUG_PrintAddress( &breakpoints[num].addr, breakpoints[num].is32 ? 32 : 16,
368                         TRUE );
369     DEBUG_Printf( DBG_CHN_MESG, "\n" );
370 }
371
372 /***********************************************************************
373  *           DEBUG_AddBreakpointFromId
374  *
375  * Add a breakpoint from a function name (and eventually a line #)
376  */
377 void    DEBUG_AddBreakpointFromId(const char *name, int lineno)
378 {
379    DBG_VALUE value;
380    
381    if (DEBUG_GetSymbolValue(name, lineno, &value, TRUE))
382       DEBUG_AddBreakpoint(&value, NULL);
383    else
384       DEBUG_Printf(DBG_CHN_MESG, "Unable to add breakpoint\n");
385 }
386
387 /***********************************************************************
388  *           DEBUG_AddBreakpointFromLineno
389  *
390  * Add a breakpoint from a line number in current file
391  */
392 void    DEBUG_AddBreakpointFromLineno(int lineno)
393 {
394    DBG_VALUE                    value;
395    
396    DEBUG_GetCurrentAddress(&value.addr);
397    
398    if (lineno != -1) {
399       struct name_hash* nh;
400       
401       DEBUG_FindNearestSymbol(&value.addr, TRUE, &nh, 0, NULL);
402       if (nh == NULL) {
403          DEBUG_Printf(DBG_CHN_MESG,"Unable to add breakpoint\n");
404          return;
405       }
406       DEBUG_GetLineNumberAddr(nh, lineno, &value.addr, TRUE);
407    }
408    
409    value.type = NULL;
410    value.cookie = DV_TARGET;
411    DEBUG_AddBreakpoint( &value, NULL );
412 }
413
414  /***********************************************************************
415  *           DEBUG_AddWatchpoint
416  *
417  * Add a watchpoint.
418  */
419 void DEBUG_AddWatchpoint( const DBG_VALUE *_value, BOOL is_write )
420 {
421    DBG_VALUE    value = *_value;
422    int          num, reg = -1;
423    unsigned     seg2;
424    DWORD        mask = 0;
425    
426    assert(_value->cookie == DV_TARGET || _value->cookie == DV_HOST);
427
428 #ifdef __i386__
429    DEBUG_FixAddress( &value.addr, DEBUG_context.SegCs );
430 #endif
431    
432    if ( value.type != NULL && value.type == DEBUG_TypeIntConst )
433    {
434       /*
435        * We know that we have the actual offset stored somewhere
436        * else in 32-bit space.  Grab it, and we
437        * should be all set.
438        */
439       seg2 = value.addr.seg;
440       value.addr.seg = 0;
441       value.addr.off = DEBUG_GetExprValue(&value, NULL);
442       value.addr.seg = seg2;
443    }
444    
445    for (num = 1; num < next_bp; num++) 
446    {
447       if (breakpoints[num].refcount && breakpoints[num].enabled && 
448           breakpoints[num].type == DBG_WATCH) {
449          mask |= (1 << breakpoints[num].u.w.reg);
450       }
451    }
452 #ifdef __i386__
453    for (reg = 0; reg < 4 && (mask & (1 << reg)); reg++);
454    if (reg == 4)
455    {
456       DEBUG_Printf(DBG_CHN_MESG, "All i386 hardware watchpoints have been set. Delete some\n");
457       return;
458    }
459 #endif
460
461    if ((num = DEBUG_InitXPoint(DBG_WATCH, &value.addr)) == -1)
462       return;
463    
464    breakpoints[num].u.w.len = 4 - 1;
465    if (_value->type && DEBUG_GetObjectSize(_value->type) < 4)
466       breakpoints[num].u.w.len = 2 - 1;
467    
468    if (!DEBUG_GetWatchedValue( num, &breakpoints[num].u.w.oldval)) 
469    {
470       DEBUG_Printf(DBG_CHN_MESG, "Bad address. Watchpoint not set\n");
471       breakpoints[num].refcount = 0;
472    }
473    
474    breakpoints[num].u.w.rw = (is_write) ? TRUE : FALSE;
475    breakpoints[reg].u.w.reg = reg;
476    
477    DEBUG_Printf( DBG_CHN_MESG, "Watchpoint %d at ", num );
478    DEBUG_PrintAddress( &breakpoints[num].addr, breakpoints[num].is32 ? 32:16, TRUE );
479    DEBUG_Printf( DBG_CHN_MESG, "\n" );
480 }
481
482 /***********************************************************************
483  *           DEBUG_AddWathpointFromId
484  *
485  * Add a watchpoint from a symbol name (and eventually a line #)
486  */
487 void    DEBUG_AddWatchpointFromId(const char *name, int lineno)
488 {
489    DBG_VALUE value;
490    
491    if( DEBUG_GetSymbolValue(name, lineno, &value, TRUE) )
492       DEBUG_AddWatchpoint( &value, 1 );
493    else
494       DEBUG_Printf(DBG_CHN_MESG, "Unable to add watchpoint\n");
495 }
496
497 /***********************************************************************
498  *           DEBUG_DelBreakpoint
499  *
500  * Delete a breakpoint.
501  */
502 void DEBUG_DelBreakpoint( int num )
503 {
504     if ((num <= 0) || (num >= next_bp) || breakpoints[num].refcount == 0)
505     {
506         DEBUG_Printf( DBG_CHN_MESG, "Invalid breakpoint number %d\n", num );
507         return;
508     }
509
510     if (--breakpoints[num].refcount > 0)
511        return;
512
513     if( breakpoints[num].condition != NULL )
514     {
515        DEBUG_FreeExpr(breakpoints[num].condition);
516        breakpoints[num].condition = NULL;
517     }
518
519     breakpoints[num].enabled = FALSE;
520     breakpoints[num].refcount = 0;
521     breakpoints[num].skipcount = 0;
522 }
523
524 /***********************************************************************
525  *           DEBUG_EnableBreakpoint
526  *
527  * Enable or disable a break point.
528  */
529 void DEBUG_EnableBreakpoint( int num, BOOL enable )
530 {
531     if ((num <= 0) || (num >= next_bp) || breakpoints[num].refcount == 0)
532     {
533         DEBUG_Printf( DBG_CHN_MESG, "Invalid breakpoint number %d\n", num );
534         return;
535     }
536     breakpoints[num].enabled = (enable) ? TRUE : FALSE;
537     breakpoints[num].skipcount = 0;
538 }
539
540
541 /***********************************************************************
542  *           DEBUG_FindTriggeredWatchpoint
543  *
544  * Lookup the watchpoints to see if one has been triggered
545  * Return >= (watch point index) if one is found and *oldval is set to
546  *      the value watched before the TRAP
547  * Return -1 if none found (*oldval is undetermined)
548  *
549  * Unfortunately, Linux does *NOT* (A REAL PITA) report with ptrace 
550  * the DR6 register value, so we have to look with our own need the
551  * cause of the TRAP.
552  * -EP
553  */
554 static int DEBUG_FindTriggeredWatchpoint(LPDWORD oldval)
555 {
556    int                          found = -1;
557 #ifdef __i386__
558    int                          i;
559    
560    /* Method 1 => get triggered watchpoint from context (doesn't work on Linux
561     * 2.2.x)
562     */
563    for (i = 0; i < next_bp; i++) 
564    {
565       DWORD val = 0;
566
567       if (breakpoints[i].refcount && breakpoints[i].enabled && 
568           breakpoints[i].type == DBG_WATCH &&
569           (DEBUG_context.Dr6 & (1 << breakpoints[i].u.w.reg)))
570       {
571          DEBUG_context.Dr6 &= ~(1 << breakpoints[i].u.w.reg);
572          
573          *oldval = breakpoints[i].u.w.oldval;
574          if (DEBUG_GetWatchedValue(i, &val)) {
575             breakpoints[i].u.w.oldval = val;
576             return i;
577          }
578       }
579    }
580    
581    /* Method 1 failed, trying method 2 */
582    
583    /* Method 2 => check if value has changed among registered watchpoints
584     * this really sucks, but this is how gdb 4.18 works on my linux box
585     * -EP
586     */
587    for (i = 0; i < next_bp; i++) 
588    {
589       DWORD val = 0;
590
591       if (breakpoints[i].refcount && breakpoints[i].enabled && 
592           breakpoints[i].type == DBG_WATCH && 
593           DEBUG_GetWatchedValue(i, &val)) 
594       {
595          *oldval = breakpoints[i].u.w.oldval;
596          if (val != *oldval) 
597          {
598             DEBUG_context.Dr6 &= ~(1 << breakpoints[i].u.w.reg);
599             breakpoints[i].u.w.oldval = val;
600             found = i;
601             /* cannot break, because two watch points may have been triggered on
602              * the same access
603              * only one will be reported to the user (FIXME ?)
604              */
605          }
606       }
607    }
608 #endif
609    return found;
610 }
611
612 /***********************************************************************
613  *           DEBUG_InfoBreakpoints
614  *
615  * Display break points information.
616  */
617 void DEBUG_InfoBreakpoints(void)
618 {
619     int i;
620
621     DEBUG_Printf( DBG_CHN_MESG, "Breakpoints:\n" );
622     for (i = 1; i < next_bp; i++)
623     {
624         if (breakpoints[i].refcount && breakpoints[i].type == DBG_BREAK)
625         {
626             DEBUG_Printf( DBG_CHN_MESG, "%d: %c ", i, breakpoints[i].enabled ? 'y' : 'n');
627             DEBUG_PrintAddress( &breakpoints[i].addr, 
628                                 breakpoints[i].is32 ? 32 : 16, TRUE);
629             DEBUG_Printf( DBG_CHN_MESG, " (%u)\n", breakpoints[i].refcount );
630             if( breakpoints[i].condition != NULL )
631             {
632                 DEBUG_Printf(DBG_CHN_MESG, "\t\tstop when  ");
633                 DEBUG_DisplayExpr(breakpoints[i].condition);
634                 DEBUG_Printf(DBG_CHN_MESG, "\n");
635             }
636         }
637     }
638     DEBUG_Printf( DBG_CHN_MESG, "Watchpoints:\n" );
639     for (i = 1; i < next_bp; i++)
640     {
641         if (breakpoints[i].refcount && breakpoints[i].type == DBG_WATCH)
642         {
643             DEBUG_Printf( DBG_CHN_MESG, "%d: %c ", i, breakpoints[i].enabled ? 'y' : 'n');
644             DEBUG_PrintAddress( &breakpoints[i].addr, 
645                                 breakpoints[i].is32 ? 32 : 16, TRUE);
646             DEBUG_Printf( DBG_CHN_MESG, " on %d byte%s (%c)\n", 
647                      breakpoints[i].u.w.len + 1, 
648                      breakpoints[i].u.w.len > 0 ? "s" : "",
649                      breakpoints[i].u.w.rw ? 'W' : 'R');
650             if( breakpoints[i].condition != NULL )
651             {
652                 DEBUG_Printf(DBG_CHN_MESG, "\t\tstop when  ");
653                 DEBUG_DisplayExpr(breakpoints[i].condition);
654                 DEBUG_Printf(DBG_CHN_MESG, "\n");
655             }
656         }
657     }
658 }
659
660 /***********************************************************************
661  *           DEBUG_ShallBreak
662  *
663  * Check whether or not the condition (bp / skipcount) of a break/watch
664  * point are met.
665  */
666 static  BOOL DEBUG_ShallBreak( int bpnum )
667 {
668     if ( breakpoints[bpnum].condition != NULL )
669     {
670         DBG_VALUE value = DEBUG_EvalExpr(breakpoints[bpnum].condition);
671
672         if ( value.type == NULL )
673         {
674             /*
675              * Something wrong - unable to evaluate this expression.
676              */
677             DEBUG_Printf(DBG_CHN_MESG, "Unable to evaluate expression ");
678             DEBUG_DisplayExpr(breakpoints[bpnum].condition);
679             DEBUG_Printf(DBG_CHN_MESG, "\nTurning off condition\n");
680             DEBUG_AddBPCondition(bpnum, NULL);
681         }
682         else if( !DEBUG_GetExprValue( &value, NULL) )
683         {
684             return FALSE;
685         }
686     }
687    
688     if ( breakpoints[bpnum].skipcount > 0 && --breakpoints[bpnum].skipcount > 0 )
689         return FALSE;
690
691    if ((breakpoints[bpnum].type == DBG_BREAK) && breakpoints[bpnum].u.b.func)
692        return breakpoints[bpnum].u.b.func();
693    return TRUE;
694 }
695
696 /***********************************************************************
697  *           DEBUG_ShouldContinue
698  *
699  * Determine if we should continue execution after a SIGTRAP signal when
700  * executing in the given mode.
701  */
702 BOOL DEBUG_ShouldContinue( DWORD code, enum exec_mode mode, int * count )
703 {
704     DBG_ADDR    addr;
705     int         bpnum;
706     DWORD       oldval;
707     int         wpnum;
708     int         addrlen = 32;
709     struct symbol_info syminfo;
710
711 #ifdef __i386__
712     /* If not single-stepping, back up over the int3 instruction */
713     if (code == EXCEPTION_BREAKPOINT) 
714        DEBUG_context.Eip--;
715 #endif
716
717     DEBUG_GetCurrentAddress( &addr );
718     bpnum = DEBUG_FindBreakpoint( &addr, DBG_BREAK );
719     breakpoints[0].enabled = FALSE;  /* disable the step-over breakpoint */
720
721     if ((bpnum != 0) && (bpnum != -1))
722     {
723         if (!DEBUG_ShallBreak(bpnum)) return TRUE;
724
725         DEBUG_Printf( DBG_CHN_MESG, "Stopped on breakpoint %d at ", bpnum );
726         syminfo = DEBUG_PrintAddress( &breakpoints[bpnum].addr,
727                                       breakpoints[bpnum].is32 ? 32 : 16, TRUE );
728         DEBUG_Printf( DBG_CHN_MESG, "\n" );
729         
730         if( syminfo.list.sourcefile != NULL )
731             DEBUG_List(&syminfo.list, NULL, 0);
732         return FALSE;
733     }
734
735     wpnum = DEBUG_FindTriggeredWatchpoint(&oldval);
736     if ((wpnum != 0) && (wpnum != -1))
737     {
738        /* If not single-stepping, do not back up over the int3 instruction */
739        if (code == EXCEPTION_BREAKPOINT) 
740        {
741 #ifdef __i386__
742            DEBUG_context.Eip++;
743            addr.off++;
744 #endif
745        }
746        if (!DEBUG_ShallBreak(wpnum)) return TRUE;
747        
748 #ifdef __i386__
749        addrlen = !addr.seg? 32 : DEBUG_GetSelectorType( addr.seg );
750 #endif
751        DEBUG_Printf(DBG_CHN_MESG, "Stopped on watchpoint %d at ", wpnum);
752        syminfo = DEBUG_PrintAddress( &addr, addrlen, TRUE );
753        
754        DEBUG_Printf(DBG_CHN_MESG, " values: old=%lu new=%lu\n", 
755                oldval, breakpoints[wpnum].u.w.oldval);
756        if (syminfo.list.sourcefile != NULL)
757           DEBUG_List(&syminfo.list, NULL, 0);
758        return FALSE;
759     }
760
761     /*
762      * If our mode indicates that we are stepping line numbers,
763      * get the current function, and figure out if we are exactly
764      * on a line number or not.
765      */
766     if( mode == EXEC_STEP_OVER || mode == EXEC_STEP_INSTR )
767     {
768         if( DEBUG_CheckLinenoStatus(&addr) == AT_LINENUMBER )
769         {
770             (*count)--;
771         }
772     }
773     else if( mode == EXEC_STEPI_OVER || mode == EXEC_STEPI_INSTR )
774     {
775         (*count)--;
776     }
777
778     if( *count > 0 || mode == EXEC_FINISH )
779     {
780         /*
781          * We still need to execute more instructions.
782          */
783         return TRUE;
784     }
785     
786     /*
787      * If we are about to stop, then print out the source line if we
788      * have it.
789      */
790     if (mode != EXEC_CONT && mode != EXEC_PASS && mode != EXEC_FINISH)
791     {
792         DEBUG_FindNearestSymbol( &addr, TRUE, NULL, 0, &syminfo.list);
793         if( syminfo.list.sourcefile != NULL )
794         {
795             DEBUG_List(&syminfo.list, NULL, 0);
796         }
797     }
798
799 #ifdef __i386__
800     /* If there's no breakpoint and we are not single-stepping, then we     */
801     /* must have encountered an int3 in the Windows program; let's skip it. */
802     if ((bpnum == -1) && code == EXCEPTION_BREAKPOINT)
803         DEBUG_context.Eip++;
804 #endif
805
806     /* no breakpoint, continue if in continuous mode */
807     return (mode == EXEC_CONT || mode == EXEC_PASS || mode == EXEC_FINISH);
808 }
809
810 /***********************************************************************
811  *           DEBUG_SuspendExecution
812  *
813  * Remove all breakpoints before entering the debug loop
814  */
815 void    DEBUG_SuspendExecution( void )
816 {
817    DEBUG_SetBreakpoints( FALSE );
818    breakpoints[0] = DEBUG_CurrThread->stepOverBP;
819 }
820
821 /***********************************************************************
822  *           DEBUG_RestartExecution
823  *
824  * Set the breakpoints to the correct state to restart execution
825  * in the given mode.
826  */
827 enum exec_mode DEBUG_RestartExecution( enum exec_mode mode, int count )
828 {
829     DBG_ADDR addr;
830     DBG_ADDR addr2;
831     int bp;
832     int delta;
833     int status;
834     enum exec_mode ret_mode;
835     DWORD instr;
836     unsigned char ch;
837
838     DEBUG_GetCurrentAddress( &addr );
839
840     /*
841      * This is the mode we will be running in after we finish.  We would like
842      * to be able to modify this in certain cases.
843      */
844     ret_mode = mode;
845
846     bp = DEBUG_FindBreakpoint( &addr, DBG_BREAK ); 
847     if ( bp != -1 && bp != 0)
848       {
849         /*
850          * If we have set a new value, then save it in the BP number.
851          */
852         if( count != 0 && mode == EXEC_CONT )
853           {
854             breakpoints[bp].skipcount = count;
855           }
856         mode = EXEC_STEPI_INSTR;  /* If there's a breakpoint, skip it */
857       }
858     else
859       {
860         if( mode == EXEC_CONT && count > 1 )
861           {
862             DEBUG_Printf(DBG_CHN_MESG, "Not stopped at any breakpoint; argument ignored.\n");
863           }
864       }
865     
866     if( mode == EXEC_FINISH && DEBUG_IsFctReturn() )
867       {
868         mode = ret_mode = EXEC_STEPI_INSTR;
869       }
870
871     instr = DEBUG_ToLinear( &addr );
872     DEBUG_READ_MEM((void*)instr, &ch, sizeof(ch));
873     /*
874      * See if the function we are stepping into has debug info
875      * and line numbers.  If not, then we step over it instead.
876      * FIXME - we need to check for things like thunks or trampolines,
877      * as the actual function may in fact have debug info.
878      */
879     if( ch == 0xe8 )
880       {
881         DEBUG_READ_MEM((void*)(instr + 1), &delta, sizeof(delta));
882         addr2 = addr;
883         DEBUG_Disasm(&addr2, FALSE);
884         addr2.off += delta;
885         
886         status = DEBUG_CheckLinenoStatus(&addr2);
887         /*
888          * Anytime we have a trampoline, step over it.
889          */
890         if( ((mode == EXEC_STEP_OVER) || (mode == EXEC_STEPI_OVER))
891             && status == FUNC_IS_TRAMPOLINE )
892           {
893 #if 0
894             DEBUG_Printf(DBG_CHN_MESG, "Not stepping into trampoline at %x (no lines)\n",
895                     addr2.off);
896 #endif
897             mode = EXEC_STEP_OVER_TRAMPOLINE;
898           }
899         
900         if( mode == EXEC_STEP_INSTR && status == FUNC_HAS_NO_LINES )
901           {
902 #if 0
903             DEBUG_Printf(DBG_CHN_MESG, "Not stepping into function at %x (no lines)\n",
904                     addr2.off);
905 #endif
906             mode = EXEC_STEP_OVER;
907           }
908       }
909
910
911     if( mode == EXEC_STEP_INSTR )
912       {
913         if( DEBUG_CheckLinenoStatus(&addr) == FUNC_HAS_NO_LINES )
914           {
915             DEBUG_Printf(DBG_CHN_MESG, "Single stepping until exit from function, \n");
916             DEBUG_Printf(DBG_CHN_MESG, "which has no line number information.\n");
917             
918             ret_mode = mode = EXEC_FINISH;
919           }
920       }
921
922     switch(mode)
923     {
924     case EXEC_CONT: /* Continuous execution */
925     case EXEC_PASS: /* Continue, passing exception */
926 #ifdef __i386__
927         DEBUG_context.EFlags &= ~STEP_FLAG;
928 #endif
929         DEBUG_SetBreakpoints( TRUE );
930         break;
931
932     case EXEC_STEP_OVER_TRAMPOLINE:
933       /*
934        * This is the means by which we step over our conversion stubs
935        * in callfrom*.s and callto*.s.  We dig the appropriate address
936        * off the stack, and we set the breakpoint there instead of the
937        * address just after the call.
938        */
939 #ifdef __i386__
940       DEBUG_READ_MEM((void*)(DEBUG_context.Esp + 
941                              2 * sizeof(unsigned int)), 
942                      &addr.off, sizeof(addr.off));
943       DEBUG_context.EFlags &= ~STEP_FLAG;
944 #endif
945       breakpoints[0].addr    = addr;
946       breakpoints[0].enabled = TRUE;
947       breakpoints[0].refcount = 1;
948       breakpoints[0].skipcount = 0;
949       DEBUG_READ_MEM((void*)DEBUG_ToLinear( &addr ), &breakpoints[0].u.b.opcode, 
950                      sizeof(char));
951       DEBUG_SetBreakpoints( TRUE );
952       break;
953
954     case EXEC_FINISH:
955     case EXEC_STEPI_OVER:  /* Stepping over a call */
956     case EXEC_STEP_OVER:  /* Stepping over a call */
957         if (DEBUG_IsStepOverInstr())
958         {
959 #ifdef __i386__
960             DEBUG_context.EFlags &= ~STEP_FLAG;
961 #endif
962             DEBUG_Disasm(&addr, FALSE);
963             breakpoints[0].addr    = addr;
964             breakpoints[0].enabled = TRUE;
965             breakpoints[0].refcount = 1;
966             breakpoints[0].skipcount = 0;
967             DEBUG_READ_MEM((void*)DEBUG_ToLinear( &addr ), &breakpoints[0].u.b.opcode,
968                            sizeof(char));
969             DEBUG_SetBreakpoints( TRUE );
970             break;
971         }
972         /* else fall through to single-stepping */
973
974     case EXEC_STEP_INSTR: /* Single-stepping an instruction */
975     case EXEC_STEPI_INSTR: /* Single-stepping an instruction */
976 #ifdef __i386__
977         DEBUG_context.EFlags |= STEP_FLAG;
978 #endif
979         break;
980     default:
981         RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
982     }
983     DEBUG_CurrThread->stepOverBP = breakpoints[0];
984     return ret_mode;
985 }
986
987 int
988 DEBUG_AddBPCondition(int num, struct expr * exp)
989 {
990     if ((num <= 0) || (num >= next_bp) || !breakpoints[num].refcount)
991     {
992         DEBUG_Printf( DBG_CHN_MESG, "Invalid breakpoint number %d\n", num );
993         return FALSE;
994     }
995
996     if( breakpoints[num].condition != NULL )
997       {
998         DEBUG_FreeExpr(breakpoints[num].condition);
999         breakpoints[num].condition = NULL;
1000       }
1001
1002     if( exp != NULL )
1003       {
1004         breakpoints[num].condition = DEBUG_CloneExpr(exp);
1005       }
1006
1007    return TRUE;
1008 }