Added support for DirectDraw overlays using the XVideo extension.
[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           switch (DEBUG_GetSelectorType( addr->seg ))
278           {
279           case MODE_32:
280               breakpoints[num].is32 = 1;
281               break;
282           case MODE_VM86:
283           case MODE_16:
284               breakpoints[num].is32 = 0;
285               break;
286           default:
287               RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
288           }
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     BYTE ch;
330
331     if( value.type != NULL && value.type == DEBUG_TypeIntConst )
332     {
333         /*
334          * We know that we have the actual offset stored somewhere
335          * else in 32-bit space.  Grab it, and we
336          * should be all set.
337          */
338         unsigned int seg2 = value.addr.seg;
339         value.addr.seg = 0;
340         value.addr.off = DEBUG_GetExprValue(&value, NULL);
341         value.addr.seg = seg2;
342     }
343
344     if ((num = DEBUG_FindBreakpoint(&value.addr, DBG_BREAK)) >= 1) 
345     {
346        breakpoints[num].refcount++;
347        return;
348     }
349
350     if (!DEBUG_READ_MEM_VERBOSE((void*)DEBUG_ToLinear( &value.addr ), &ch, sizeof(ch)))
351     {
352        DEBUG_Printf( DBG_CHN_MESG, "Invalid address, can't set breakpoint\n");
353        return;
354     }
355
356     if ((num = DEBUG_InitXPoint(DBG_BREAK, &value.addr)) == -1)
357        return;
358
359     breakpoints[num].u.b.opcode = ch;
360     breakpoints[num].u.b.func = func;
361
362     DEBUG_Printf( DBG_CHN_MESG, "Breakpoint %d at ", num );
363     DEBUG_PrintAddress( &breakpoints[num].addr, breakpoints[num].is32 ? MODE_32 : MODE_16,
364                         TRUE );
365     DEBUG_Printf( DBG_CHN_MESG, "\n" );
366 }
367
368 /***********************************************************************
369  *           DEBUG_AddBreakpointFromId
370  *
371  * Add a breakpoint from a function name (and eventually a line #)
372  */
373 void    DEBUG_AddBreakpointFromId(const char *name, int lineno)
374 {
375    DBG_VALUE value;
376    
377    if (DEBUG_GetSymbolValue(name, lineno, &value, TRUE))
378       DEBUG_AddBreakpoint(&value, NULL);
379    else
380       DEBUG_Printf(DBG_CHN_MESG, "Unable to add breakpoint\n");
381 }
382
383 /***********************************************************************
384  *           DEBUG_AddBreakpointFromLineno
385  *
386  * Add a breakpoint from a line number in current file
387  */
388 void    DEBUG_AddBreakpointFromLineno(int lineno)
389 {
390    DBG_VALUE                    value;
391    
392    DEBUG_GetCurrentAddress(&value.addr);
393    
394    if (lineno != -1) {
395       struct name_hash* nh;
396       
397       DEBUG_FindNearestSymbol(&value.addr, TRUE, &nh, 0, NULL);
398       if (nh == NULL) {
399          DEBUG_Printf(DBG_CHN_MESG,"Unable to add breakpoint\n");
400          return;
401       }
402       DEBUG_GetLineNumberAddr(nh, lineno, &value.addr, TRUE);
403    }
404    
405    value.type = NULL;
406    value.cookie = DV_TARGET;
407    DEBUG_AddBreakpoint( &value, NULL );
408 }
409
410  /***********************************************************************
411  *           DEBUG_AddWatchpoint
412  *
413  * Add a watchpoint.
414  */
415 void DEBUG_AddWatchpoint( const DBG_VALUE *_value, BOOL is_write )
416 {
417    DBG_VALUE    value = *_value;
418    int          num, reg = -1;
419    unsigned     seg2;
420    DWORD        mask = 0;
421    
422    assert(_value->cookie == DV_TARGET || _value->cookie == DV_HOST);
423
424 #ifdef __i386__
425    DEBUG_FixAddress( &value.addr, DEBUG_context.SegCs );
426 #endif
427    
428    if ( value.type != NULL && value.type == DEBUG_TypeIntConst )
429    {
430       /*
431        * We know that we have the actual offset stored somewhere
432        * else in 32-bit space.  Grab it, and we
433        * should be all set.
434        */
435       seg2 = value.addr.seg;
436       value.addr.seg = 0;
437       value.addr.off = DEBUG_GetExprValue(&value, NULL);
438       value.addr.seg = seg2;
439    }
440    
441    for (num = 1; num < next_bp; num++) 
442    {
443       if (breakpoints[num].refcount && breakpoints[num].enabled && 
444           breakpoints[num].type == DBG_WATCH) {
445          mask |= (1 << breakpoints[num].u.w.reg);
446       }
447    }
448 #ifdef __i386__
449    for (reg = 0; reg < 4 && (mask & (1 << reg)); reg++);
450    if (reg == 4)
451    {
452       DEBUG_Printf(DBG_CHN_MESG, "All i386 hardware watchpoints have been set. Delete some\n");
453       return;
454    }
455 #endif
456
457    if ((num = DEBUG_InitXPoint(DBG_WATCH, &value.addr)) == -1)
458       return;
459    
460    breakpoints[num].u.w.len = 4 - 1;
461    if (_value->type && DEBUG_GetObjectSize(_value->type) < 4)
462       breakpoints[num].u.w.len = 2 - 1;
463    
464    if (!DEBUG_GetWatchedValue( num, &breakpoints[num].u.w.oldval)) 
465    {
466       DEBUG_Printf(DBG_CHN_MESG, "Bad address. Watchpoint not set\n");
467       breakpoints[num].refcount = 0;
468    }
469    else
470    {
471       breakpoints[num].u.w.rw = (is_write) ? TRUE : FALSE;
472       breakpoints[reg].u.w.reg = reg;
473    
474       DEBUG_Printf( DBG_CHN_MESG, "Watchpoint %d at ", num );
475       DEBUG_PrintAddress( &breakpoints[num].addr, breakpoints[num].is32 ? MODE_32 : MODE_16, TRUE );
476       DEBUG_Printf( DBG_CHN_MESG, "\n" );
477    }
478 }
479
480 /***********************************************************************
481  *           DEBUG_AddWathpointFromId
482  *
483  * Add a watchpoint from a symbol name (and eventually a line #)
484  */
485 void    DEBUG_AddWatchpointFromId(const char *name, int lineno)
486 {
487    DBG_VALUE value;
488    
489    if( DEBUG_GetSymbolValue(name, lineno, &value, TRUE) )
490       DEBUG_AddWatchpoint( &value, 1 );
491    else
492       DEBUG_Printf(DBG_CHN_MESG, "Unable to add watchpoint\n");
493 }
494
495 /***********************************************************************
496  *           DEBUG_DelBreakpoint
497  *
498  * Delete a breakpoint.
499  */
500 void DEBUG_DelBreakpoint( int num )
501 {
502     if ((num <= 0) || (num >= next_bp) || breakpoints[num].refcount == 0)
503     {
504         DEBUG_Printf( DBG_CHN_MESG, "Invalid breakpoint number %d\n", num );
505         return;
506     }
507
508     if (--breakpoints[num].refcount > 0)
509        return;
510
511     if( breakpoints[num].condition != NULL )
512     {
513        DEBUG_FreeExpr(breakpoints[num].condition);
514        breakpoints[num].condition = NULL;
515     }
516
517     breakpoints[num].enabled = FALSE;
518     breakpoints[num].refcount = 0;
519     breakpoints[num].skipcount = 0;
520 }
521
522 /***********************************************************************
523  *           DEBUG_EnableBreakpoint
524  *
525  * Enable or disable a break point.
526  */
527 void DEBUG_EnableBreakpoint( int num, BOOL enable )
528 {
529     if ((num <= 0) || (num >= next_bp) || breakpoints[num].refcount == 0)
530     {
531         DEBUG_Printf( DBG_CHN_MESG, "Invalid breakpoint number %d\n", num );
532         return;
533     }
534     breakpoints[num].enabled = (enable) ? TRUE : FALSE;
535     breakpoints[num].skipcount = 0;
536 }
537
538
539 /***********************************************************************
540  *           DEBUG_FindTriggeredWatchpoint
541  *
542  * Lookup the watchpoints to see if one has been triggered
543  * Return >= (watch point index) if one is found and *oldval is set to
544  *      the value watched before the TRAP
545  * Return -1 if none found (*oldval is undetermined)
546  *
547  * Unfortunately, Linux does *NOT* (A REAL PITA) report with ptrace 
548  * the DR6 register value, so we have to look with our own need the
549  * cause of the TRAP.
550  * -EP
551  */
552 static int DEBUG_FindTriggeredWatchpoint(LPDWORD oldval)
553 {
554    int                          found = -1;
555 #ifdef __i386__
556    int                          i;
557    
558    /* Method 1 => get triggered watchpoint from context (doesn't work on Linux
559     * 2.2.x). This should be fixed in >= 2.2.16
560     */
561    for (i = 0; i < next_bp; i++) 
562    {
563       DWORD val = 0;
564
565       if (breakpoints[i].refcount && breakpoints[i].enabled && 
566           breakpoints[i].type == DBG_WATCH &&
567           (DEBUG_context.Dr6 & (1 << breakpoints[i].u.w.reg)))
568       {
569          DEBUG_context.Dr6 &= ~(1 << breakpoints[i].u.w.reg);
570          
571          *oldval = breakpoints[i].u.w.oldval;
572          if (DEBUG_GetWatchedValue(i, &val)) {
573             breakpoints[i].u.w.oldval = val;
574             return i;
575          }
576       }
577    }
578    
579    /* Method 1 failed, trying method 2 */
580    
581    /* Method 2 => check if value has changed among registered watchpoints
582     * this really sucks, but this is how gdb 4.18 works on my linux box
583     * -EP
584     */
585    for (i = 0; i < next_bp; i++) 
586    {
587       DWORD val = 0;
588
589       if (breakpoints[i].refcount && breakpoints[i].enabled && 
590           breakpoints[i].type == DBG_WATCH && 
591           DEBUG_GetWatchedValue(i, &val)) 
592       {
593          *oldval = breakpoints[i].u.w.oldval;
594          if (val != *oldval) 
595          {
596             DEBUG_context.Dr6 &= ~(1 << breakpoints[i].u.w.reg);
597             breakpoints[i].u.w.oldval = val;
598             found = i;
599             /* cannot break, because two watch points may have been triggered on
600              * the same access
601              * only one will be reported to the user (FIXME ?)
602              */
603          }
604       }
605    }
606 #endif
607    return found;
608 }
609
610 /***********************************************************************
611  *           DEBUG_InfoBreakpoints
612  *
613  * Display break points information.
614  */
615 void DEBUG_InfoBreakpoints(void)
616 {
617     int i;
618
619     DEBUG_Printf( DBG_CHN_MESG, "Breakpoints:\n" );
620     for (i = 1; i < next_bp; i++)
621     {
622         if (breakpoints[i].refcount && breakpoints[i].type == DBG_BREAK)
623         {
624             DEBUG_Printf( DBG_CHN_MESG, "%d: %c ", i, breakpoints[i].enabled ? 'y' : 'n');
625             DEBUG_PrintAddress( &breakpoints[i].addr, 
626                                 breakpoints[i].is32 ? MODE_32 : MODE_16, TRUE);
627             DEBUG_Printf( DBG_CHN_MESG, " (%u)\n", breakpoints[i].refcount );
628             if( breakpoints[i].condition != NULL )
629             {
630                 DEBUG_Printf(DBG_CHN_MESG, "\t\tstop when  ");
631                 DEBUG_DisplayExpr(breakpoints[i].condition);
632                 DEBUG_Printf(DBG_CHN_MESG, "\n");
633             }
634         }
635     }
636     DEBUG_Printf( DBG_CHN_MESG, "Watchpoints:\n" );
637     for (i = 1; i < next_bp; i++)
638     {
639         if (breakpoints[i].refcount && breakpoints[i].type == DBG_WATCH)
640         {
641             DEBUG_Printf( DBG_CHN_MESG, "%d: %c ", i, breakpoints[i].enabled ? 'y' : 'n');
642             DEBUG_PrintAddress( &breakpoints[i].addr, 
643                                 breakpoints[i].is32 ? MODE_32 : MODE_16, TRUE);
644             DEBUG_Printf( DBG_CHN_MESG, " on %d byte%s (%c)\n", 
645                      breakpoints[i].u.w.len + 1, 
646                      breakpoints[i].u.w.len > 0 ? "s" : "",
647                      breakpoints[i].u.w.rw ? 'W' : 'R');
648             if( breakpoints[i].condition != NULL )
649             {
650                 DEBUG_Printf(DBG_CHN_MESG, "\t\tstop when  ");
651                 DEBUG_DisplayExpr(breakpoints[i].condition);
652                 DEBUG_Printf(DBG_CHN_MESG, "\n");
653             }
654         }
655     }
656 }
657
658 /***********************************************************************
659  *           DEBUG_ShallBreak
660  *
661  * Check whether or not the condition (bp / skipcount) of a break/watch
662  * point are met.
663  */
664 static  BOOL DEBUG_ShallBreak( int bpnum )
665 {
666     if ( breakpoints[bpnum].condition != NULL )
667     {
668         DBG_VALUE value = DEBUG_EvalExpr(breakpoints[bpnum].condition);
669
670         if ( value.type == NULL )
671         {
672             /*
673              * Something wrong - unable to evaluate this expression.
674              */
675             DEBUG_Printf(DBG_CHN_MESG, "Unable to evaluate expression ");
676             DEBUG_DisplayExpr(breakpoints[bpnum].condition);
677             DEBUG_Printf(DBG_CHN_MESG, "\nTurning off condition\n");
678             DEBUG_AddBPCondition(bpnum, NULL);
679         }
680         else if( !DEBUG_GetExprValue( &value, NULL) )
681         {
682             return FALSE;
683         }
684     }
685    
686     if ( breakpoints[bpnum].skipcount > 0 && --breakpoints[bpnum].skipcount > 0 )
687         return FALSE;
688
689    if ((breakpoints[bpnum].type == DBG_BREAK) && breakpoints[bpnum].u.b.func)
690        return breakpoints[bpnum].u.b.func();
691    return TRUE;
692 }
693
694 /***********************************************************************
695  *           DEBUG_ShouldContinue
696  *
697  * Determine if we should continue execution after a SIGTRAP signal when
698  * executing in the given mode.
699  */
700 BOOL DEBUG_ShouldContinue( DBG_ADDR *addr, DWORD code, enum exec_mode mode, int * count )
701 {
702     int         bpnum;
703     DWORD       oldval;
704     int         wpnum;
705     enum dbg_mode addr_mode;
706     struct symbol_info syminfo;
707
708 #ifdef __i386__
709     /* If not single-stepping, back up over the int3 instruction */
710     if (code == EXCEPTION_BREAKPOINT)
711     {
712        DEBUG_context.Eip--;
713        addr->off--;
714     }
715 #endif
716
717     bpnum = DEBUG_FindBreakpoint( addr, DBG_BREAK );
718     breakpoints[0].enabled = FALSE;  /* disable the step-over breakpoint */
719
720     if ((bpnum != 0) && (bpnum != -1))
721     {
722         if (!DEBUG_ShallBreak(bpnum)) return TRUE;
723
724         DEBUG_Printf( DBG_CHN_MESG, "Stopped on breakpoint %d at ", bpnum );
725         syminfo = DEBUG_PrintAddress( &breakpoints[bpnum].addr,
726                                       breakpoints[bpnum].is32 ? MODE_32 : MODE_16, TRUE );
727         DEBUG_Printf( DBG_CHN_MESG, "\n" );
728         
729         if( syminfo.list.sourcefile != NULL )
730             DEBUG_List(&syminfo.list, NULL, 0);
731         return FALSE;
732     }
733
734     wpnum = DEBUG_FindTriggeredWatchpoint(&oldval);
735     if ((wpnum != 0) && (wpnum != -1))
736     {
737        /* If not single-stepping, do not back up over the int3 instruction */
738        if (code == EXCEPTION_BREAKPOINT) 
739        {
740 #ifdef __i386__
741            DEBUG_context.Eip++;
742            addr->off++;
743 #endif
744        }
745        if (!DEBUG_ShallBreak(wpnum)) return TRUE;
746        
747        addr_mode = DEBUG_GetSelectorType( addr->seg );
748        DEBUG_Printf(DBG_CHN_MESG, "Stopped on watchpoint %d at ", wpnum);
749        syminfo = DEBUG_PrintAddress( addr, addr_mode, TRUE );
750        
751        DEBUG_Printf(DBG_CHN_MESG, " values: old=%lu new=%lu\n", 
752                oldval, breakpoints[wpnum].u.w.oldval);
753        if (syminfo.list.sourcefile != NULL)
754           DEBUG_List(&syminfo.list, NULL, 0);
755        return FALSE;
756     }
757
758     /*
759      * If our mode indicates that we are stepping line numbers,
760      * get the current function, and figure out if we are exactly
761      * on a line number or not.
762      */
763     if( mode == EXEC_STEP_OVER || mode == EXEC_STEP_INSTR )
764     {
765         if( DEBUG_CheckLinenoStatus(addr) == AT_LINENUMBER )
766         {
767             (*count)--;
768         }
769     }
770     else if( mode == EXEC_STEPI_OVER || mode == EXEC_STEPI_INSTR )
771     {
772         (*count)--;
773     }
774
775     if( *count > 0 || mode == EXEC_FINISH )
776     {
777         /*
778          * We still need to execute more instructions.
779          */
780         return TRUE;
781     }
782     
783     /*
784      * If we are about to stop, then print out the source line if we
785      * have it.
786      */
787     if (mode != EXEC_CONT && mode != EXEC_PASS && mode != EXEC_FINISH)
788     {
789         DEBUG_FindNearestSymbol( addr, TRUE, NULL, 0, &syminfo.list);
790         if( syminfo.list.sourcefile != NULL )
791         {
792             DEBUG_List(&syminfo.list, NULL, 0);
793         }
794     }
795
796 #ifdef __i386__
797     /* If there's no breakpoint and we are not single-stepping, then we     */
798     /* must have encountered an int3 in the Windows program; let's skip it. */
799     if ((bpnum == -1) && code == EXCEPTION_BREAKPOINT)
800     {
801         DEBUG_context.Eip++;
802         addr->off++;
803     }
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 }