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