We now have ICC_LINK_CLASS.
[wine] / programs / winedbg / 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 #include "wine/debug.h"
26
27 WINE_DEFAULT_DEBUG_CHANNEL(winedbg);
28
29 /***********************************************************************
30  *           is_at_func_return
31  *
32  * Determine if the instruction at current PC is an instruction that
33  * is a function return.
34  */
35 static BOOL is_at_func_return(void)
36 {
37     ADDRESS     addr;
38
39     memory_get_current_pc(&addr);
40     return be_cpu->is_function_return(memory_to_linear_addr(&addr));
41 }
42
43 /***********************************************************************
44  *           break_set_xpoints
45  *
46  * Set or remove all the breakpoints & watchpoints
47  */
48 void  break_set_xpoints(BOOL set)
49 {
50     static BOOL                 last; /* = 0 = FALSE */
51
52     unsigned int                i, ret, size;
53     void*                       addr;
54     struct dbg_breakpoint*      bp = dbg_curr_process->bp;
55
56     if (set == last) return;
57     last = set;
58
59     for (i = 0; i < dbg_curr_process->next_bp; i++)
60     {
61         if (!bp[i].refcount || !bp[i].enabled) continue;
62
63         if (bp[i].xpoint_type == be_xpoint_break)
64             size = 0;
65         else
66             size = bp[i].w.len + 1;
67         addr = (void*)memory_to_linear_addr(&bp[i].addr);
68
69         if (set)
70             ret = be_cpu->insert_Xpoint(dbg_curr_process->handle, &dbg_context, 
71                                         bp[i].xpoint_type, addr,
72                                         &bp[i].info, size);
73         else
74             ret = be_cpu->remove_Xpoint(dbg_curr_process->handle, &dbg_context, 
75                                         bp[i].xpoint_type, addr,
76                                         bp[i].info, size);
77         if (!ret)
78         {
79             dbg_printf("Invalid address (");
80             print_address(&bp[i].addr, FALSE);
81             dbg_printf(") for breakpoint %d, disabling it\n", i);
82             bp[i].enabled = FALSE;
83         }
84     }
85 }
86
87 /***********************************************************************
88  *           find_xpoint
89  *
90  * Find the breakpoint for a given address. Return the breakpoint
91  * number or -1 if none.
92  */
93 static int find_xpoint(const ADDRESS* addr, enum be_xpoint_type type)
94 {
95     int                         i;
96     void*                       lin = memory_to_linear_addr(addr);
97     struct dbg_breakpoint*      bp = dbg_curr_process->bp;
98
99     for (i = 0; i < dbg_curr_process->next_bp; i++)
100     {
101         if (bp[i].refcount && bp[i].enabled && bp[i].xpoint_type == type &&
102             memory_to_linear_addr(&bp[i].addr) == lin)
103             return i;
104     }
105     return -1;
106 }
107
108 /***********************************************************************
109  *           init_xpoint
110  *
111  * Find an empty slot in BP table to add a new break/watch point
112  */
113 static  int init_xpoint(int type, const ADDRESS* addr)
114 {
115     int                         num;
116     struct dbg_breakpoint*      bp = dbg_curr_process->bp;
117
118     for (num = (dbg_curr_process->next_bp < MAX_BREAKPOINTS) ? 
119              dbg_curr_process->next_bp++ : 1;
120          num < MAX_BREAKPOINTS; num++)
121     {
122         if (bp[num].refcount == 0)
123         {
124             bp[num].refcount    = 1;
125             bp[num].enabled     = TRUE;
126             bp[num].xpoint_type = type;
127             bp[num].skipcount   = 0;
128             bp[num].addr        = *addr;
129             return num;
130         }
131     }
132
133     dbg_printf("Too many bp. Please delete some.\n");
134     return -1;
135 }
136
137 /***********************************************************************
138  *           get_watched_value
139  *
140  * Returns the value watched by watch point 'num'.
141  */
142 static  BOOL    get_watched_value(int num, LPDWORD val)
143 {
144     BYTE        buf[4];
145
146     if (!dbg_read_memory(memory_to_linear_addr(&dbg_curr_process->bp[num].addr),
147                          buf, dbg_curr_process->bp[num].w.len + 1))
148         return FALSE;
149
150     switch (dbg_curr_process->bp[num].w.len + 1)
151     {
152     case 4:     *val = *(DWORD*)buf;    break;
153     case 2:     *val = *(WORD*)buf;     break;
154     case 1:     *val = *(BYTE*)buf;     break;
155     default: RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
156     }
157     return TRUE;
158 }
159
160 /***********************************************************************
161  *           break_add_break
162  *
163  * Add a breakpoint.
164  */
165 BOOL break_add_break(const ADDRESS* addr, BOOL verbose)
166 {
167     int                         num;
168     BYTE                        ch;
169     struct dbg_breakpoint*      bp = dbg_curr_process->bp;
170
171     if ((num = find_xpoint(addr, be_xpoint_break)) >= 1)
172     {
173         bp[num].refcount++;
174         dbg_printf("Breakpoint %d at ", num);
175         print_address(&bp[num].addr, TRUE);
176         dbg_printf(" (refcount=%d)\n", bp[num].refcount);
177         return TRUE;
178     }
179
180     if (!dbg_read_memory(memory_to_linear_addr(addr), &ch, sizeof(ch)))
181     {
182         if (verbose)
183         {
184             dbg_printf("Invalid address ");
185             print_bare_address(addr);
186             dbg_printf(", can't set breakpoint\n");
187         }
188         return FALSE;
189     }
190
191     if ((num = init_xpoint(be_xpoint_break, addr)) == -1)
192         return FALSE;
193
194     dbg_printf("Breakpoint %d at ", num);
195     print_address(&bp[num].addr, TRUE);
196     dbg_printf("\n");
197
198     return TRUE;
199 }
200
201 /***********************************************************************
202  *           break_add_break_from_lvalue
203  *
204  * Add a breakpoint.
205  */
206 BOOL break_add_break_from_lvalue(const struct dbg_lvalue* lvalue)
207 {
208     ADDRESS     addr;
209
210     addr.Mode = AddrModeFlat;
211     addr.Offset = types_extract_as_integer(lvalue);
212
213     if (!break_add_break(&addr, TRUE))
214     {
215         if (!DBG_IVAR(CanDeferOnBPByAddr))
216         {
217             dbg_printf("Invalid address, can't set breakpoint\n"
218                        "You can turn on deferring bp by address by setting $CanDeferOnBPByAddr to 1\n");
219             return FALSE;
220         }
221         dbg_printf("Unable to add breakpoint, will check again any time a new DLL is loaded\n");
222         dbg_curr_process->delayed_bp = 
223             dbg_heap_realloc(dbg_curr_process->delayed_bp,
224                              sizeof(struct dbg_delayed_bp) * ++dbg_curr_process->num_delayed_bp);
225
226         dbg_curr_process->delayed_bp[dbg_curr_process->num_delayed_bp - 1].is_symbol = FALSE;
227         dbg_curr_process->delayed_bp[dbg_curr_process->num_delayed_bp - 1].u.addr    = addr;
228         return TRUE;
229     }
230     return FALSE;
231 }
232
233 /***********************************************************************
234  *           break_add_break_from_id
235  *
236  * Add a breakpoint from a function name (and eventually a line #)
237  */
238 void    break_add_break_from_id(const char *name, int lineno)
239 {
240     struct dbg_lvalue   lvalue;
241     int                 i;
242
243     switch (symbol_get_lvalue(name, lineno, &lvalue, TRUE))
244     {
245     case sglv_found:
246         break_add_break(&lvalue.addr, TRUE);
247         return;
248     case sglv_unknown:
249         break;
250     case sglv_aborted: /* user aborted symbol lookup */
251         return;
252     }
253
254     dbg_printf("Unable to add breakpoint, will check again when a new DLL is loaded\n");
255     for (i = 0; i < dbg_curr_process->num_delayed_bp; i++)
256     {
257         if (dbg_curr_process->delayed_bp[i].is_symbol &&
258             !strcmp(name, dbg_curr_process->delayed_bp[i].u.symbol.name) &&
259             lineno == dbg_curr_process->delayed_bp[i].u.symbol.lineno)
260             return;
261     }
262     dbg_curr_process->delayed_bp = dbg_heap_realloc(dbg_curr_process->delayed_bp,
263                                                     sizeof(struct dbg_delayed_bp) * ++dbg_curr_process->num_delayed_bp);
264
265     dbg_curr_process->delayed_bp[dbg_curr_process->num_delayed_bp - 1].is_symbol = TRUE;
266     dbg_curr_process->delayed_bp[dbg_curr_process->num_delayed_bp - 1].u.symbol.name = strcpy(HeapAlloc(GetProcessHeap(), 0, strlen(name) + 1), name);
267     dbg_curr_process->delayed_bp[dbg_curr_process->num_delayed_bp - 1].u.symbol.lineno = lineno;
268 }
269
270 /***********************************************************************
271  *           break_add_break_from_lineno
272  *
273  * Add a breakpoint from a line number in current file
274  */
275 void    break_add_break_from_lineno(int lineno)
276 {
277     ADDRESS             addr;
278
279     memory_get_current_pc(&addr);
280
281     if (lineno != -1)
282     {
283         IMAGEHLP_LINE   il;
284         IMAGEHLP_LINE   iil;
285         BOOL            found = FALSE;
286
287         il.SizeOfStruct = sizeof(il);
288         if (!SymGetLineFromAddr(dbg_curr_process->handle, 
289                                 (DWORD)memory_to_linear_addr(&addr), NULL, &il))
290         {
291             dbg_printf("Unable to add breakpoint (unknown address)\n");
292             return;
293         }
294
295         iil = il;
296         while (SymGetLinePrev(dbg_curr_process->handle, &iil))
297         {
298             if (lineno == iil.LineNumber && !strcmp(il.FileName, iil.FileName))
299             {
300                 addr.Mode = AddrModeFlat;
301                 addr.Offset = iil.Address;
302                 found = TRUE;
303                 break;
304             }
305         }
306         iil = il;
307         if (!found) while (SymGetLineNext(dbg_curr_process->handle, &iil))
308         {
309             if (lineno == iil.LineNumber && !strcmp(il.FileName, iil.FileName))
310             {
311                 addr.Mode = AddrModeFlat;
312                 addr.Offset = iil.Address;
313                 found = TRUE;
314                 break;
315             }
316         }
317         if (!found)
318         {
319             dbg_printf("Unknown line number\n"
320                        "(either out of file, or no code at given line number)\n");
321             return;
322         }
323     }
324
325     break_add_break(&addr, TRUE);
326 }
327
328 /***********************************************************************
329  *           break_check_delayed_bp
330  *
331  * Check is a registered delayed BP is now available.
332  */
333 void break_check_delayed_bp(void)
334 {
335     struct dbg_lvalue           lvalue;
336     int                         i;
337     struct dbg_delayed_bp*      dbp = dbg_curr_process->delayed_bp;
338
339     for (i = 0; i < dbg_curr_process->num_delayed_bp; i++)
340     {
341         if (dbp[i].is_symbol)
342         {
343             if (symbol_get_lvalue(dbp[i].u.symbol.name, dbp[i].u.symbol.lineno,
344                                   &lvalue, TRUE) != sglv_found)
345                 continue;
346             if (lvalue.cookie != DLV_TARGET) continue;
347         }
348         else
349             lvalue.addr = dbp[i].u.addr;
350         WINE_TRACE("trying to add delayed %s-bp\n", dbp[i].is_symbol ? "S" : "A");
351         if (!dbp[i].is_symbol)
352             WINE_TRACE("\t%04x:%08lx\n", 
353                        dbp[i].u.addr.Segment, dbp[i].u.addr.Offset);
354         else
355             WINE_TRACE("\t'%s' @ %d\n", 
356                        dbp[i].u.symbol.name, dbp[i].u.symbol.lineno);
357
358         if (break_add_break(&lvalue.addr, FALSE))
359             memmove(&dbp[i], &dbp[i+1], (--dbg_curr_process->num_delayed_bp - i) * sizeof(*dbp));
360     }
361 }
362
363 /***********************************************************************
364  *           break_add_watch
365  *
366  * Add a watchpoint.
367  */
368 void break_add_watch(const struct dbg_lvalue* lvalue, BOOL is_write)
369 {
370     int         num;
371     DWORD       l = 4;
372
373     num = init_xpoint((is_write) ? be_xpoint_watch_write : be_xpoint_watch_read,
374                       &lvalue->addr);
375     if (num == -1) return;
376
377     if (lvalue->type.id != dbg_itype_none)
378     {
379         if (types_get_info(&lvalue->type, TI_GET_LENGTH, &l))
380         {
381             switch (l)
382             {
383             case 4: case 2: case 1: break;
384             default:
385                 dbg_printf("Unsupported length (%lu) for watch-points, defaulting to 4\n", l);
386                 break;
387             }
388         }
389         else dbg_printf("Cannot get watch size, defaulting to 4\n");
390     }
391     dbg_curr_process->bp[num].w.len = l - 1;
392
393     if (!get_watched_value(num, &dbg_curr_process->bp[num].w.oldval))
394     {
395         dbg_printf("Bad address. Watchpoint not set\n");
396         dbg_curr_process->bp[num].refcount = 0;
397         return;
398     }
399     dbg_printf("Watchpoint %d at ", num);
400     print_address(&dbg_curr_process->bp[num].addr, TRUE);
401     dbg_printf("\n");
402 }
403
404 /***********************************************************************
405  *           break_add_watch_from_id
406  *
407  * Add a watchpoint from a symbol name (and eventually a line #)
408  */
409 void    break_add_watch_from_id(const char *name)
410 {
411     struct dbg_lvalue    lvalue;
412
413     switch (symbol_get_lvalue(name, -1, &lvalue, TRUE))
414     {
415     case sglv_found:
416         break_add_watch(&lvalue, 1);
417         break;
418     case sglv_unknown:
419         dbg_printf("Unable to add watchpoint\n");
420         break;
421     case sglv_aborted: /* user aborted symbol lookup */
422         break;
423     }
424 }
425
426 /***********************************************************************
427  *           break_delete_xpoint
428  *
429  * Delete a breakpoint.
430  */
431 void break_delete_xpoint(int num)
432 {
433     struct dbg_breakpoint*      bp = dbg_curr_process->bp;
434
435     if ((num <= 0) || (num >= dbg_curr_process->next_bp) ||
436         bp[num].refcount == 0)
437     {
438         dbg_printf("Invalid breakpoint number %d\n", num);
439         return;
440     }
441
442     if (--bp[num].refcount > 0)
443         return;
444
445     if (bp[num].condition != NULL)
446     {
447         expr_free(bp[num].condition);
448         bp[num].condition = NULL;
449     }
450
451     bp[num].enabled = FALSE;
452     bp[num].refcount = 0;
453     bp[num].skipcount = 0;
454 }
455
456 static inline BOOL module_is_container(const IMAGEHLP_MODULE* wmod_cntnr,
457                                      const IMAGEHLP_MODULE* wmod_child)
458 {
459     return wmod_cntnr->BaseOfImage <= wmod_child->BaseOfImage &&
460         (DWORD)wmod_cntnr->BaseOfImage + wmod_cntnr->ImageSize >=
461         (DWORD)wmod_child->BaseOfImage + wmod_child->ImageSize;
462 }
463
464 /******************************************************************
465  *              break_delete_xpoints_from_module
466  *
467  * Remove all Xpoints from module which base is 'base'
468  */
469 void break_delete_xpoints_from_module(unsigned long base)
470 {
471     IMAGEHLP_MODULE             im, im_elf;
472     int                         i;
473     DWORD                       linear;
474     struct dbg_breakpoint*      bp = dbg_curr_process->bp;
475
476     /* FIXME: should do it also on the ELF sibbling if any */
477     im.SizeOfStruct = sizeof(im);
478     im_elf.SizeOfStruct = sizeof(im_elf);
479     if (!SymGetModuleInfo(dbg_curr_process->handle, base, &im)) return;
480
481     /* try to get in fact the underlying ELF module (if any) */
482     if (SymGetModuleInfo(dbg_curr_process->handle, im.BaseOfImage - 1, &im_elf) &&
483         im_elf.BaseOfImage <= im.BaseOfImage &&
484         (DWORD)im_elf.BaseOfImage + im_elf.ImageSize >= (DWORD)im.BaseOfImage + im.ImageSize)
485         im = im_elf;
486
487     for (i = 0; i < dbg_curr_process->next_bp; i++)
488     {
489         linear = (DWORD)memory_to_linear_addr(&bp[i].addr);
490         if (bp[i].refcount && bp[i].enabled &&
491             im.BaseOfImage <= linear && linear < im.BaseOfImage + im.ImageSize)
492         {
493             break_delete_xpoint(i);
494         }
495     }
496 }
497
498 /***********************************************************************
499  *           break_enable_xpoint
500  *
501  * Enable or disable a break point.
502  */
503 void break_enable_xpoint(int num, BOOL enable)
504 {
505     if ((num <= 0) || (num >= dbg_curr_process->next_bp) || 
506         dbg_curr_process->bp[num].refcount == 0)
507     {
508         dbg_printf("Invalid breakpoint number %d\n", num);
509         return;
510     }
511     dbg_curr_process->bp[num].enabled = (enable) ? TRUE : FALSE;
512     dbg_curr_process->bp[num].skipcount = 0;
513 }
514
515
516 /***********************************************************************
517  *           find_triggered_watch
518  *
519  * Lookup the watchpoints to see if one has been triggered
520  * Return >= (watch point index) if one is found and *oldval is set to
521  *      the value watched before the TRAP
522  * Return -1 if none found (*oldval is undetermined)
523  *
524  * Unfortunately, Linux does *NOT* (A REAL PITA) report with ptrace
525  * the DR6 register value, so we have to look with our own need the
526  * cause of the TRAP.
527  * -EP
528  */
529 static int find_triggered_watch(LPDWORD oldval)
530 {
531     int                         found = -1;
532     int                         i;
533     struct dbg_breakpoint*      bp = dbg_curr_process->bp;
534
535     /* Method 1 => get triggered watchpoint from context (doesn't work on Linux
536      * 2.2.x). This should be fixed in >= 2.2.16
537      */
538     for (i = 0; i < dbg_curr_process->next_bp; i++)
539     {
540         DWORD val = 0;
541
542         if (bp[i].refcount && bp[i].enabled && bp[i].xpoint_type != be_xpoint_break &&
543             (be_cpu->is_watchpoint_set(&dbg_context, bp[i].info)))
544         {
545             be_cpu->clear_watchpoint(&dbg_context, bp[i].info);
546
547             *oldval = bp[i].w.oldval;
548             if (get_watched_value(i, &val))
549             {
550                 bp[i].w.oldval = val;
551                 return i;
552             }
553         }
554     }
555
556     /* Method 1 failed, trying method 2 */
557
558     /* Method 2 => check if value has changed among registered watchpoints
559      * this really sucks, but this is how gdb 4.18 works on my linux box
560      * -EP
561      */
562     for (i = 0; i < dbg_curr_process->next_bp; i++)
563     {
564         DWORD val = 0;
565
566         if (bp[i].refcount && bp[i].enabled && bp[i].xpoint_type != be_xpoint_break &&
567             get_watched_value(i, &val))
568         {
569             *oldval = bp[i].w.oldval;
570             if (val != *oldval)
571             {
572                 be_cpu->clear_watchpoint(&dbg_context, bp[i].info);
573                 bp[i].w.oldval = val;
574                 found = i;
575                 /* cannot break, because two watch points may have been triggered on
576                  * the same access
577                  * only one will be reported to the user (FIXME ?)
578                  */
579             }
580         }
581     }
582     return found;
583 }
584
585 /***********************************************************************
586  *           break_info
587  *
588  * Display break & watch points information.
589  */
590 void break_info(void)
591 {
592     int                         i;
593     int                         nbp = 0, nwp = 0;
594     struct dbg_delayed_bp*      dbp = dbg_curr_process->delayed_bp;
595     struct dbg_breakpoint*      bp = dbg_curr_process->bp;
596
597     for (i = 1; i < dbg_curr_process->next_bp; i++)
598     {
599         if (bp[i].refcount)
600         {
601             if (bp[i].xpoint_type == be_xpoint_break) nbp++; else nwp++;
602         }
603     }
604
605     if (nbp)
606     {
607         dbg_printf("Breakpoints:\n");
608         for (i = 1; i < dbg_curr_process->next_bp; i++)
609         {
610             if (!bp[i].refcount || bp[i].xpoint_type != be_xpoint_break)
611                 continue;
612             dbg_printf("%d: %c ", i, bp[i].enabled ? 'y' : 'n');
613             print_address(&bp[i].addr, TRUE);
614             dbg_printf(" (%u)\n", bp[i].refcount);
615             if (bp[i].condition != NULL)
616             {
617                 dbg_printf("\t\tstop when  ");
618                 expr_print(bp[i].condition);
619                 dbg_printf("\n");
620             }
621         }
622     }
623     else dbg_printf("No breakpoints\n");
624     if (nwp)
625     {
626         dbg_printf("Watchpoints:\n");
627         for (i = 1; i < dbg_curr_process->next_bp; i++)
628         {
629             if (!bp[i].refcount || bp[i].xpoint_type == be_xpoint_break)
630                 continue;
631             dbg_printf("%d: %c ", i, bp[i].enabled ? 'y' : 'n');
632             print_address(&bp[i].addr, TRUE);
633             dbg_printf(" on %d byte%s (%c)\n",
634                        bp[i].w.len + 1, bp[i].w.len > 0 ? "s" : "",
635                        bp[i].xpoint_type == be_xpoint_watch_write ? 'W' : 'R');
636             if (bp[i].condition != NULL)
637             {
638                 dbg_printf("\t\tstop when ");
639                 expr_print(bp[i].condition);
640                 dbg_printf("\n");
641             }
642         }
643     }
644     else dbg_printf("No watchpoints\n");
645     if (dbg_curr_process->num_delayed_bp)
646     {
647         dbg_printf("Delayed breakpoints:\n");
648         for (i = 0; i < dbg_curr_process->num_delayed_bp; i++)
649         {
650             if (dbp[i].is_symbol)
651             {
652                 dbg_printf("%d: %s", i, dbp[i].u.symbol.name);
653                 if (dbp[i].u.symbol.lineno != -1)
654                     dbg_printf(" at line %u", dbp[i].u.symbol.lineno);
655             }
656             else
657             {
658                 dbg_printf("%d: ", i);
659                 print_address(&dbp[i].u.addr, FALSE);
660             }
661             dbg_printf("\n");
662         }
663     }
664 }
665
666 /***********************************************************************
667  *           should_stop
668  *
669  * Check whether or not the condition (bp / skipcount) of a break/watch
670  * point are met.
671  */
672 static  BOOL should_stop(int bpnum)
673 {
674     struct dbg_breakpoint*      bp = &dbg_curr_process->bp[bpnum];
675
676     if (bp->condition != NULL)
677     {
678         struct dbg_lvalue lvalue = expr_eval(bp->condition);
679
680         if (lvalue.type.id == dbg_itype_none)
681         {
682             /*
683              * Something wrong - unable to evaluate this expression.
684              */
685             dbg_printf("Unable to evaluate expression ");
686             expr_print(bp->condition);
687             dbg_printf("\nTurning off condition\n");
688             break_add_condition(bpnum, NULL);
689         }
690         else if (!types_extract_as_integer(&lvalue))
691         {
692             return FALSE;
693         }
694     }
695
696     if (bp->skipcount > 0) bp->skipcount--;
697     return bp->skipcount == 0;
698 }
699
700 /***********************************************************************
701  *           break_should_continue
702  *
703  * Determine if we should continue execution after a SIGTRAP signal when
704  * executing in the given mode.
705  */
706 BOOL break_should_continue(ADDRESS* addr, DWORD code, int* count)
707 {
708     int                 bpnum;
709     DWORD               oldval;
710     int                 wpnum;
711     enum dbg_exec_mode  mode = dbg_curr_thread->exec_mode;
712
713     /* If not single-stepping, back up to the break instruction */
714     if (code == EXCEPTION_BREAKPOINT)
715         addr->Offset += be_cpu->adjust_pc_for_break(&dbg_context, TRUE);
716
717     bpnum = find_xpoint(addr, be_xpoint_break);
718     dbg_curr_process->bp[0].enabled = FALSE;  /* disable the step-over breakpoint */
719
720     if (bpnum > 0)
721     {
722         if (!should_stop(bpnum)) return TRUE;
723
724         dbg_printf("Stopped on breakpoint %d at ", bpnum);
725         print_address(&dbg_curr_process->bp[bpnum].addr, TRUE);
726         dbg_printf("\n");
727         source_list_from_addr(addr, 0);
728         return FALSE;
729     }
730
731     wpnum = find_triggered_watch(&oldval);
732     if (wpnum > 0)
733     {
734         /* If not single-stepping, do not back up over the break instruction */
735         if (code == EXCEPTION_BREAKPOINT)
736             addr->Offset += be_cpu->adjust_pc_for_break(&dbg_context, FALSE);
737
738         if (!should_stop(wpnum)) return TRUE;
739
740         dbg_printf("Stopped on watchpoint %d at ", wpnum);
741         print_address(addr, TRUE);
742         dbg_printf(" values: old=%lu new=%lu\n",
743                      oldval, dbg_curr_process->bp[wpnum].w.oldval);
744         source_list_from_addr(addr, 0);
745         return FALSE;
746     }
747
748     /*
749      * If our mode indicates that we are stepping line numbers,
750      * get the current function, and figure out if we are exactly
751      * on a line number or not.
752      */
753     if (mode == dbg_exec_step_over_line || mode == dbg_exec_step_into_line)
754     {
755         if (symbol_get_function_line_status(addr) == dbg_on_a_line_number)
756         {
757             (*count)--;
758         }
759     }
760     else if (mode == dbg_exec_step_over_insn || mode == dbg_exec_step_into_insn)
761     {
762         (*count)--;
763     }
764
765     if (*count > 0 || mode == dbg_exec_finish)
766     {
767         /*
768          * We still need to execute more instructions.
769          */
770         return TRUE;
771     }
772
773     /*
774      * If we are about to stop, then print out the source line if we
775      * have it.
776      */
777     if (mode != dbg_exec_cont && mode != dbg_exec_finish)
778         source_list_from_addr(addr, 0);
779
780     /* If there's no breakpoint and we are not single-stepping, then
781      * either we must have encountered a break insn in the Windows program
782      * or someone is trying to stop us
783      */
784     if (bpnum == -1 && code == EXCEPTION_BREAKPOINT)
785     {
786         addr->Offset += be_cpu->adjust_pc_for_break(&dbg_context, FALSE);
787         return FALSE;
788     }
789
790     /* no breakpoint, continue if in continuous mode */
791     return mode == dbg_exec_cont || mode == dbg_exec_finish;
792 }
793
794 /***********************************************************************
795  *           break_suspend_execution
796  *
797  * Remove all bp before entering the debug loop
798  */
799 void    break_suspend_execution(void)
800 {
801     break_set_xpoints(FALSE);
802     dbg_curr_process->bp[0] = dbg_curr_thread->step_over_bp;
803 }
804
805 /***********************************************************************
806  *           break_restart_execution
807  *
808  * Set the bp to the correct state to restart execution
809  * in the given mode.
810  */
811 void break_restart_execution(int count)
812 {
813     ADDRESS                     addr;
814     int                         bp;
815     enum dbg_line_status        status;
816     enum dbg_exec_mode          mode, ret_mode;
817     ADDRESS                     callee;
818
819     memory_get_current_pc(&addr);
820
821     /*
822      * This is the mode we will be running in after we finish.  We would like
823      * to be able to modify this in certain cases.
824      */
825     ret_mode = mode = dbg_curr_thread->exec_mode;
826
827     bp = find_xpoint(&addr, be_xpoint_break);
828     if (bp != -1 && bp != 0)
829     {
830         /*
831          * If we have set a new value, then save it in the BP number.
832          */
833         if (count != 0 && mode == dbg_exec_cont)
834         {
835             dbg_curr_process->bp[bp].skipcount = count;
836         }
837         mode = dbg_exec_step_into_insn;  /* If there's a breakpoint, skip it */
838     }
839     else if (mode == dbg_exec_cont && count > 1)
840     {
841         dbg_printf("Not stopped at any breakpoint; argument ignored.\n");
842     }
843
844     if (mode == dbg_exec_finish && is_at_func_return())
845     {
846         mode = ret_mode = dbg_exec_step_into_insn;
847     }
848
849     /*
850      * See if the function we are stepping into has debug info
851      * and line numbers.  If not, then we step over it instead.
852      * FIXME - we need to check for things like thunks or trampolines,
853      * as the actual function may in fact have debug info.
854      */
855     if (be_cpu->is_function_call(memory_to_linear_addr(&addr), &callee))
856     {
857         status = symbol_get_function_line_status(&callee);
858 #if 0
859         /* FIXME: we need to get the thunk type */
860         /*
861          * Anytime we have a trampoline, step over it.
862          */
863         if ((mode == EXEC_STEP_OVER || mode == EXEC_STEPI_OVER)
864             && status == dbg_in_a_thunk)
865         {
866             WINE_WARN("Not stepping into trampoline at %p (no lines)\n", 
867                       memory_to_linear_addr(&callee));
868             mode = EXEC_STEP_OVER_TRAMPOLINE;
869         }
870 #endif
871         if (mode == dbg_exec_step_into_line && status == dbg_no_line_info)
872         {
873             WINE_WARN("Not stepping into function at %p (no lines)\n",
874                       memory_to_linear_addr(&callee));
875             mode = dbg_exec_step_over_line;
876         }
877     }
878
879     if (mode == dbg_exec_step_into_line && 
880         symbol_get_function_line_status(&addr) == dbg_no_line_info)
881     {
882         dbg_printf("Single stepping until exit from function, \n"
883                    "which has no line number information.\n");
884         ret_mode = mode = dbg_exec_finish;
885     }
886
887     switch (mode)
888     {
889     case dbg_exec_cont: /* Continuous execution */
890         be_cpu->single_step(&dbg_context, FALSE);
891         break_set_xpoints(TRUE);
892         break;
893
894 #if 0
895     case EXEC_STEP_OVER_TRAMPOLINE:
896         /*
897          * This is the means by which we step over our conversion stubs
898          * in callfrom*.s and callto*.s.  We dig the appropriate address
899          * off the stack, and we set the breakpoint there instead of the
900          * address just after the call.
901          */
902         be_cpu->get_addr(dbg_curr_thread->handle, &dbg_context,
903                          be_cpu_addr_stack, &addr);
904         /* FIXME: we assume stack grows as on a i386 */
905         addr.Offset += 2 * sizeof(unsigned int);
906         dbg_read_memory(memory_to_linear_addr(&addr),
907                         &addr.Offset, sizeof(addr.Offset));
908         dbg_curr_process->bp[0].addr = addr;
909         dbg_curr_process->bp[0].enabled = TRUE;
910         dbg_curr_process->bp[0].refcount = 1;
911         dbg_curr_process->bp[0].skipcount = 0;
912         be_cpu->single_step(&dbg_context, FALSE);
913         break_set_xpoints(TRUE);
914         break;
915 #endif
916
917     case dbg_exec_finish:
918     case dbg_exec_step_over_insn:  /* Stepping over a call */
919     case dbg_exec_step_over_line:  /* Stepping over a call */
920         if (be_cpu->is_step_over_insn(memory_to_linear_addr(&addr)))
921         {
922             be_cpu->single_step(&dbg_context, FALSE);
923             be_cpu->disasm_one_insn(&addr, FALSE);
924             dbg_curr_process->bp[0].addr = addr;
925             dbg_curr_process->bp[0].enabled = TRUE;
926             dbg_curr_process->bp[0].refcount = 1;
927             dbg_curr_process->bp[0].skipcount = 0;
928             be_cpu->single_step(&dbg_context, FALSE);
929             break_set_xpoints(TRUE);
930             break;
931         }
932         /* else fall through to single-stepping */
933
934     case dbg_exec_step_into_line: /* Single-stepping a line */
935     case dbg_exec_step_into_insn: /* Single-stepping an instruction */
936         be_cpu->single_step(&dbg_context, TRUE);
937         break;
938     default: RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
939     }
940     dbg_curr_thread->step_over_bp = dbg_curr_process->bp[0];
941     dbg_curr_thread->exec_mode = ret_mode;
942 }
943
944 int break_add_condition(int num, struct expr* exp)
945 {
946     if (num <= 0 || num >= dbg_curr_process->next_bp || 
947         !dbg_curr_process->bp[num].refcount)
948     {
949         dbg_printf("Invalid breakpoint number %d\n", num);
950         return FALSE;
951     }
952
953     if (dbg_curr_process->bp[num].condition != NULL)
954     {
955         expr_free(dbg_curr_process->bp[num].condition);
956         dbg_curr_process->bp[num].condition = NULL;
957     }
958
959     if (exp != NULL) dbg_curr_process->bp[num].condition = expr_clone(exp);
960
961     return TRUE;
962 }