Release 970112
[wine] / debugger / break.c
1 /*
2  * Debugger break-points handling
3  *
4  * Copyright 1994 Martin von Loewis
5  * Copyright 1995 Alexandre Julliard
6  */
7
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <sys/types.h>
11 #include <sys/mman.h>
12 #include "windows.h"
13 #include "debugger.h"
14
15 #define INT3          0xcc   /* int 3 opcode */
16
17 #define MAX_BREAKPOINTS 100
18
19 typedef struct
20 {
21     DBG_ADDR      addr;
22     BYTE          addrlen;
23     BYTE          opcode;
24     BOOL16        enabled;
25     WORD          skipcount;
26     BOOL16        in_use;
27     struct expr * condition;
28 } BREAKPOINT;
29
30 static BREAKPOINT breakpoints[MAX_BREAKPOINTS];
31
32 static int next_bp = 1;  /* breakpoint 0 is reserved for step-over */
33
34
35 /***********************************************************************
36  *           DEBUG_ChangeOpcode
37  *
38  * Change the opcode at segment:addr.
39  */
40 static void DEBUG_SetOpcode( const DBG_ADDR *addr, BYTE op )
41 {
42     BYTE *ptr;
43
44     if (addr->seg) ptr = (BYTE *)PTR_SEG_OFF_TO_LIN( addr->seg, addr->off );
45     else ptr = (BYTE *)addr->off;
46
47     /* There are a couple of problems with this. On Linux prior to
48        1.1.62, this call fails (ENOACCESS) due to a bug in fs/exec.c.
49        This code is currently not tested at all on BSD.
50        How do I get the old protection in order to restore it later on?
51        */
52     if (mprotect((caddr_t)((int)ptr & (~4095)), 4096,
53                  PROT_READ | PROT_WRITE | PROT_EXEC) == -1)
54     {
55         perror( "Can't set break point" );
56         return;
57     }
58     *ptr = op;
59     /* mprotect((caddr_t)(addr->off & ~4095), 4096,
60        PROT_READ | PROT_EXEC ); */
61 }
62
63
64 /***********************************************************************
65  *           DEBUG_IsStepOverInstr
66  *
67  * Determine if the instruction at CS:EIP is an instruction that
68  * we need to step over (like a call or a repetitive string move).
69  */
70 static BOOL32 DEBUG_IsStepOverInstr()
71 {
72     BYTE *instr = (BYTE *)PTR_SEG_OFF_TO_LIN( CS_reg(&DEBUG_context),
73                                               EIP_reg(&DEBUG_context) );
74
75     for (;;)
76     {
77         switch(*instr)
78         {
79           /* Skip all prefixes */
80
81         case 0x2e:  /* cs: */
82         case 0x36:  /* ss: */
83         case 0x3e:  /* ds: */
84         case 0x26:  /* es: */
85         case 0x64:  /* fs: */
86         case 0x65:  /* gs: */
87         case 0x66:  /* opcode size prefix */
88         case 0x67:  /* addr size prefix */
89         case 0xf0:  /* lock */
90         case 0xf2:  /* repne */
91         case 0xf3:  /* repe */
92             instr++;
93             continue;
94
95           /* Handle call instructions */
96
97         case 0xe8:  /* call <offset> */
98         case 0x9a:  /* lcall <seg>:<off> */
99             return TRUE;
100
101         case 0xff:  /* call <regmodrm> */
102             return (((instr[1] & 0x38) == 0x10) ||
103                     ((instr[1] & 0x38) == 0x18));
104
105           /* Handle string instructions */
106
107         case 0x6c:  /* insb */
108         case 0x6d:  /* insw */
109         case 0x6e:  /* outsb */
110         case 0x6f:  /* outsw */
111         case 0xa4:  /* movsb */
112         case 0xa5:  /* movsw */
113         case 0xa6:  /* cmpsb */
114         case 0xa7:  /* cmpsw */
115         case 0xaa:  /* stosb */
116         case 0xab:  /* stosw */
117         case 0xac:  /* lodsb */
118         case 0xad:  /* lodsw */
119         case 0xae:  /* scasb */
120         case 0xaf:  /* scasw */
121             return TRUE;
122
123         default:
124             return FALSE;
125         }
126     }
127 }
128
129
130 /***********************************************************************
131  *           DEBUG_IsFctReturn
132  *
133  * Determine if the instruction at CS:EIP is an instruction that
134  * is a function return.
135  */
136 BOOL32 DEBUG_IsFctReturn(void)
137 {
138     BYTE *instr = (BYTE *)PTR_SEG_OFF_TO_LIN( CS_reg(&DEBUG_context),
139                                               EIP_reg(&DEBUG_context) );
140
141     for (;;)
142     {
143         switch(*instr)
144         {
145         case 0xc2:
146         case 0xc3:
147           return TRUE;
148         default:
149             return FALSE;
150         }
151     }
152 }
153
154
155 /***********************************************************************
156  *           DEBUG_SetBreakpoints
157  *
158  * Set or remove all the breakpoints.
159  */
160 void DEBUG_SetBreakpoints( BOOL32 set )
161 {
162     int i;
163
164     for (i = 0; i < MAX_BREAKPOINTS; i++)
165     {
166         if (breakpoints[i].in_use && breakpoints[i].enabled)
167         {
168             /* Note: we check for read here, because if reading is allowed */
169             /*       writing permission will be forced in DEBUG_SetOpcode. */
170             if (DEBUG_IsBadReadPtr( &breakpoints[i].addr, 1 ))
171             {
172                 fprintf( stderr, "Invalid address for breakpoint %d, disabling it\n", i );
173                 breakpoints[i].enabled = FALSE;
174             }
175             else DEBUG_SetOpcode( &breakpoints[i].addr,
176                                   set ? INT3 : breakpoints[i].opcode );
177         }
178     }
179 }
180
181
182 /***********************************************************************
183  *           DEBUG_FindBreakpoint
184  *
185  * Find the breakpoint for a given address. Return the breakpoint
186  * number or -1 if none.
187  */
188 int DEBUG_FindBreakpoint( const DBG_ADDR *addr )
189 {
190     int i;
191
192     for (i = 0; i < MAX_BREAKPOINTS; i++)
193     {
194         if (breakpoints[i].in_use && breakpoints[i].enabled &&
195             breakpoints[i].addr.seg == addr->seg &&
196             breakpoints[i].addr.off == addr->off) return i;
197     }
198     return -1;
199 }
200
201
202 /***********************************************************************
203  *           DEBUG_AddBreakpoint
204  *
205  * Add a breakpoint.
206  */
207 void DEBUG_AddBreakpoint( const DBG_ADDR *address )
208 {
209     DBG_ADDR addr = *address;
210     int num;
211     BYTE *p;
212
213     DBG_FIX_ADDR_SEG( &addr, CS_reg(&DEBUG_context) );
214
215     if (next_bp < MAX_BREAKPOINTS)
216         num = next_bp++;
217     else  /* try to find an empty slot */  
218     {
219         for (num = 1; num < MAX_BREAKPOINTS; num++)
220             if (!breakpoints[num].in_use) break;
221         if (num >= MAX_BREAKPOINTS)
222         {
223             fprintf( stderr, "Too many breakpoints. Please delete some.\n" );
224             return;
225         }
226     }
227     if (!DBG_CHECK_READ_PTR( &addr, 1 )) return;
228     p = DBG_ADDR_TO_LIN( &addr );
229     breakpoints[num].addr    = addr;
230     breakpoints[num].addrlen = !addr.seg ? 32 :
231                          (GET_SEL_FLAGS(addr.seg) & LDT_FLAGS_32BIT) ? 32 : 16;
232     breakpoints[num].opcode  = *p;
233     breakpoints[num].enabled = TRUE;
234     breakpoints[num].in_use  = TRUE;
235     breakpoints[num].skipcount = 0;
236     fprintf( stderr, "Breakpoint %d at ", num );
237     DEBUG_PrintAddress( &breakpoints[num].addr, breakpoints[num].addrlen,
238                         TRUE );
239     fprintf( stderr, "\n" );
240 }
241
242
243 /***********************************************************************
244  *           DEBUG_DelBreakpoint
245  *
246  * Delete a breakpoint.
247  */
248 void DEBUG_DelBreakpoint( int num )
249 {
250     if ((num <= 0) || (num >= next_bp) || !breakpoints[num].in_use)
251     {
252         fprintf( stderr, "Invalid breakpoint number %d\n", num );
253         return;
254     }
255     breakpoints[num].enabled = FALSE;
256     breakpoints[num].in_use  = FALSE;
257     breakpoints[num].skipcount = 0;
258 }
259
260
261 /***********************************************************************
262  *           DEBUG_EnableBreakpoint
263  *
264  * Enable or disable a break point.
265  */
266 void DEBUG_EnableBreakpoint( int num, BOOL32 enable )
267 {
268     if ((num <= 0) || (num >= next_bp) || !breakpoints[num].in_use)
269     {
270         fprintf( stderr, "Invalid breakpoint number %d\n", num );
271         return;
272     }
273     breakpoints[num].enabled = enable;
274     breakpoints[num].skipcount = 0;
275 }
276
277
278 /***********************************************************************
279  *           DEBUG_InfoBreakpoints
280  *
281  * Display break points information.
282  */
283 void DEBUG_InfoBreakpoints(void)
284 {
285     int i;
286
287     fprintf( stderr, "Breakpoints:\n" );
288     for (i = 1; i < next_bp; i++)
289     {
290         if (breakpoints[i].in_use)
291         {
292             fprintf( stderr, "%d: %c ", i, breakpoints[i].enabled ? 'y' : 'n');
293             DEBUG_PrintAddress( &breakpoints[i].addr, breakpoints[i].addrlen,
294                                 TRUE);
295             fprintf( stderr, "\n" );
296             if( breakpoints[i].condition != NULL )
297               {
298                 fprintf(stderr, "\t\tstop when  ");
299                 DEBUG_DisplayExpr(breakpoints[i].condition);
300                 fprintf(stderr, "\n");
301               }
302         }
303     }
304 }
305
306
307 /***********************************************************************
308  *           DEBUG_ShouldContinue
309  *
310  * Determine if we should continue execution after a SIGTRAP signal when
311  * executing in the given mode.
312  */
313 BOOL32 DEBUG_ShouldContinue( enum exec_mode mode, int * count )
314 {
315     DBG_ADDR addr;
316     DBG_ADDR cond_addr;
317     int bpnum;
318     struct list_id list;
319
320       /* If not single-stepping, back up over the int3 instruction */
321     if (!(EFL_reg(&DEBUG_context) & STEP_FLAG)) EIP_reg(&DEBUG_context)--;
322
323     addr.seg = (CS_reg(&DEBUG_context) == WINE_CODE_SELECTOR) ? 
324                 0 : CS_reg(&DEBUG_context);
325     addr.off = EIP_reg(&DEBUG_context);
326         
327     bpnum = DEBUG_FindBreakpoint( &addr );
328     breakpoints[0].enabled = 0;  /* disable the step-over breakpoint */
329
330     if ((bpnum != 0) && (bpnum != -1))
331     {
332         if( breakpoints[bpnum].condition != NULL )
333           {
334             cond_addr = DEBUG_EvalExpr(breakpoints[bpnum].condition);
335             if( cond_addr.type == NULL )
336               {
337                 /*
338                  * Something wrong - unable to evaluate this expression.
339                  */
340                 fprintf(stderr, "Unable to evaluate expression ");
341                 DEBUG_DisplayExpr(breakpoints[bpnum].condition);
342                 fprintf(stderr, "\nTurning off condition\n");
343                 DEBUG_AddBPCondition(bpnum, NULL);
344               }
345             else if( ! DEBUG_GetExprValue( &cond_addr, NULL) )
346               {
347                 return TRUE;
348               }
349           }
350
351         if( breakpoints[bpnum].skipcount > 0 )
352           {
353             breakpoints[bpnum].skipcount--;
354             if( breakpoints[bpnum].skipcount > 0 )
355               {
356                 return TRUE;
357               }
358           }
359         fprintf( stderr, "Stopped on breakpoint %d at ", bpnum );
360         DEBUG_PrintAddress( &breakpoints[bpnum].addr,
361                             breakpoints[bpnum].addrlen, TRUE );
362         fprintf( stderr, "\n" );
363         
364         /*
365          * See if there is a source file for this bp.  If so,
366          * then dig it out and display one line.
367          */
368         DEBUG_FindNearestSymbol( &addr, TRUE, NULL, 0, &list);
369         if( list.sourcefile != NULL )
370           {
371             DEBUG_List(&list, NULL, 0);
372           }
373         return FALSE;
374     }
375
376     /*
377      * If our mode indicates that we are stepping line numbers,
378      * get the current function, and figure out if we are exactly
379      * on a line number or not.
380      */
381     if( mode == EXEC_STEP_OVER 
382         || mode == EXEC_STEP_INSTR )
383       {
384         if( DEBUG_CheckLinenoStatus(&addr) == AT_LINENUMBER )
385           {
386             (*count)--;
387           }
388       }
389     else if( mode == EXEC_STEPI_OVER 
390         || mode == EXEC_STEPI_INSTR )
391
392       {
393         (*count)--;
394       }
395
396     if( *count > 0 || mode == EXEC_FINISH )
397       {
398         /*
399          * We still need to execute more instructions.
400          */
401         return TRUE;
402       }
403     
404     /*
405      * If we are about to stop, then print out the source line if we
406      * have it.
407      */
408     if( (mode != EXEC_CONT && mode != EXEC_FINISH) )
409       {
410         DEBUG_FindNearestSymbol( &addr, TRUE, NULL, 0, &list);
411         if( list.sourcefile != NULL )
412           {
413             DEBUG_List(&list, NULL, 0);
414           }
415       }
416
417     /* If there's no breakpoint and we are not single-stepping, then we     */
418     /* must have encountered an int3 in the Windows program; let's skip it. */
419     if ((bpnum == -1) && !(EFL_reg(&DEBUG_context) & STEP_FLAG))
420         EIP_reg(&DEBUG_context)++;
421
422       /* no breakpoint, continue if in continuous mode */
423     return (mode == EXEC_CONT || mode == EXEC_FINISH);
424 }
425
426
427 /***********************************************************************
428  *           DEBUG_RestartExecution
429  *
430  * Set the breakpoints to the correct state to restart execution
431  * in the given mode.
432  */
433 enum exec_mode DEBUG_RestartExecution( enum exec_mode mode, int count )
434 {
435     DBG_ADDR addr;
436     DBG_ADDR addr2;
437     int bp;
438     int delta;
439     int status;
440     unsigned int * value;
441     enum exec_mode ret_mode;
442     BYTE *instr;
443
444     addr.seg = (CS_reg(&DEBUG_context) == WINE_CODE_SELECTOR) ?
445                 0 : CS_reg(&DEBUG_context);
446     addr.off = EIP_reg(&DEBUG_context);
447
448     /*
449      * This is the mode we will be running in after we finish.  We would like
450      * to be able to modify this in certain cases.
451      */
452     ret_mode = mode;
453
454     bp = DEBUG_FindBreakpoint( &addr ); 
455     if ( bp != -1 && bp != 0)
456       {
457         /*
458          * If we have set a new value, then save it in the BP number.
459          */
460         if( count != 0 && mode == EXEC_CONT )
461           {
462             breakpoints[bp].skipcount = count;
463           }
464         mode = EXEC_STEPI_INSTR;  /* If there's a breakpoint, skip it */
465       }
466     else
467       {
468         if( mode == EXEC_CONT && count > 1 )
469           {
470             fprintf(stderr,"Not stopped at any breakpoint; argument ignored.\n");
471           }
472       }
473     
474     if( mode == EXEC_FINISH && DEBUG_IsFctReturn() )
475       {
476         mode = ret_mode = EXEC_STEPI_INSTR;
477       }
478
479     instr = (BYTE *)PTR_SEG_OFF_TO_LIN( CS_reg(&DEBUG_context),
480                                         EIP_reg(&DEBUG_context) );
481     /*
482      * See if the function we are stepping into has debug info
483      * and line numbers.  If not, then we step over it instead.
484      * FIXME - we need to check for things like thunks or trampolines,
485      * as the actual function may in fact have debug info.
486      */
487     if( *instr == 0xe8 )
488       {
489         delta = *(unsigned int*) (instr + 1);
490         addr2 = addr;
491         DEBUG_Disasm(&addr2, FALSE);
492         addr2.off += delta;
493         
494         status = DEBUG_CheckLinenoStatus(&addr2);
495         /*
496          * Anytime we have a trampoline, step over it.
497          */
498         if( ((mode == EXEC_STEP_OVER) || (mode == EXEC_STEPI_OVER))
499             && status == FUNC_IS_TRAMPOLINE )
500           {
501 #if 0
502             fprintf(stderr, "Not stepping into trampoline at %x (no lines)\n",
503                     addr2.off);
504 #endif
505             mode = EXEC_STEP_OVER_TRAMPOLINE;
506           }
507         
508         if( mode == EXEC_STEP_INSTR && status == FUNC_HAS_NO_LINES )
509           {
510 #if 0
511             fprintf(stderr, "Not stepping into function at %x (no lines)\n",
512                     addr2.off);
513 #endif
514             mode = EXEC_STEP_OVER;
515           }
516       }
517
518
519     if( mode == EXEC_STEP_INSTR )
520       {
521         if( DEBUG_CheckLinenoStatus(&addr) == FUNC_HAS_NO_LINES )
522           {
523             fprintf(stderr, "Single stepping until exit from function, \n");
524             fprintf(stderr, "which has no line number information.\n");
525             
526             ret_mode = mode = EXEC_FINISH;
527           }
528       }
529
530     switch(mode)
531     {
532     case EXEC_CONT: /* Continuous execution */
533         EFL_reg(&DEBUG_context) &= ~STEP_FLAG;
534         DEBUG_SetBreakpoints( TRUE );
535         break;
536
537     case EXEC_STEP_OVER_TRAMPOLINE:
538       /*
539        * This is the means by which we step over our conversion stubs
540        * in callfrom*.s and callto*.s.  We dig the appropriate address
541        * off the stack, and we set the breakpoint there instead of the
542        * address just after the call.
543        */
544       value = (unsigned int *) ESP_reg(&DEBUG_context) + 2;
545       addr.off = *value;
546       EFL_reg(&DEBUG_context) &= ~STEP_FLAG;
547       breakpoints[0].addr    = addr;
548       breakpoints[0].enabled = TRUE;
549       breakpoints[0].in_use  = TRUE;
550       breakpoints[0].skipcount = 0;
551       breakpoints[0].opcode  = *(BYTE *)DBG_ADDR_TO_LIN( &addr );
552       DEBUG_SetBreakpoints( TRUE );
553       break;
554
555     case EXEC_FINISH:
556     case EXEC_STEPI_OVER:  /* Stepping over a call */
557     case EXEC_STEP_OVER:  /* Stepping over a call */
558         if (DEBUG_IsStepOverInstr())
559         {
560             EFL_reg(&DEBUG_context) &= ~STEP_FLAG;
561             DEBUG_Disasm(&addr, FALSE);
562             breakpoints[0].addr    = addr;
563             breakpoints[0].enabled = TRUE;
564             breakpoints[0].in_use  = TRUE;
565             breakpoints[0].skipcount = 0;
566             breakpoints[0].opcode  = *(BYTE *)DBG_ADDR_TO_LIN( &addr );
567             DEBUG_SetBreakpoints( TRUE );
568             break;
569         }
570         /* else fall through to single-stepping */
571
572     case EXEC_STEP_INSTR: /* Single-stepping an instruction */
573     case EXEC_STEPI_INSTR: /* Single-stepping an instruction */
574         EFL_reg(&DEBUG_context) |= STEP_FLAG;
575         break;
576     }
577     return ret_mode;
578 }
579
580 int
581 DEBUG_AddBPCondition(int num, struct expr * exp)
582 {
583     if ((num <= 0) || (num >= next_bp) || !breakpoints[num].in_use)
584     {
585         fprintf( stderr, "Invalid breakpoint number %d\n", num );
586         return FALSE;
587     }
588
589     if( breakpoints[num].condition != NULL )
590       {
591         DEBUG_FreeExpr(breakpoints[num].condition);
592         breakpoints[num].condition = NULL;
593       }
594
595     if( exp != NULL )
596       {
597         breakpoints[num].condition = DEBUG_CloneExpr(exp);
598       }
599
600    return TRUE;
601 }