Release 970305
[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     unsigned int seg2;
212     BYTE *p;
213
214     DBG_FIX_ADDR_SEG( &addr, CS_reg(&DEBUG_context) );
215
216     if( addr.type != NULL && addr.type == DEBUG_TypeIntConst )
217       {
218         /*
219          * We know that we have the actual offset stored somewhere
220          * else in 32-bit space.  Grab it, and we
221          * should be all set.
222          */
223         seg2 = addr.seg;
224         addr.seg = 0;
225         addr.off = DEBUG_GetExprValue(&addr, NULL);
226         addr.seg = seg2;
227       }
228
229     if (next_bp < MAX_BREAKPOINTS)
230         num = next_bp++;
231     else  /* try to find an empty slot */  
232     {
233         for (num = 1; num < MAX_BREAKPOINTS; num++)
234             if (!breakpoints[num].in_use) break;
235         if (num >= MAX_BREAKPOINTS)
236         {
237             fprintf( stderr, "Too many breakpoints. Please delete some.\n" );
238             return;
239         }
240     }
241     if (!DBG_CHECK_READ_PTR( &addr, 1 )) return;
242     p = DBG_ADDR_TO_LIN( &addr );
243     breakpoints[num].addr    = addr;
244     breakpoints[num].addrlen = !addr.seg ? 32 :
245                          (GET_SEL_FLAGS(addr.seg) & LDT_FLAGS_32BIT) ? 32 : 16;
246     breakpoints[num].opcode  = *p;
247     breakpoints[num].enabled = TRUE;
248     breakpoints[num].in_use  = TRUE;
249     breakpoints[num].skipcount = 0;
250     fprintf( stderr, "Breakpoint %d at ", num );
251     DEBUG_PrintAddress( &breakpoints[num].addr, breakpoints[num].addrlen,
252                         TRUE );
253     fprintf( stderr, "\n" );
254 }
255
256
257 /***********************************************************************
258  *           DEBUG_DelBreakpoint
259  *
260  * Delete a breakpoint.
261  */
262 void DEBUG_DelBreakpoint( int num )
263 {
264     if ((num <= 0) || (num >= next_bp) || !breakpoints[num].in_use)
265     {
266         fprintf( stderr, "Invalid breakpoint number %d\n", num );
267         return;
268     }
269
270     if( breakpoints[num].condition != NULL )
271       {
272         DEBUG_FreeExpr(breakpoints[num].condition);
273         breakpoints[num].condition = NULL;
274       }
275
276     breakpoints[num].enabled = FALSE;
277     breakpoints[num].in_use  = FALSE;
278     breakpoints[num].skipcount = 0;
279 }
280
281
282 /***********************************************************************
283  *           DEBUG_EnableBreakpoint
284  *
285  * Enable or disable a break point.
286  */
287 void DEBUG_EnableBreakpoint( int num, BOOL32 enable )
288 {
289     if ((num <= 0) || (num >= next_bp) || !breakpoints[num].in_use)
290     {
291         fprintf( stderr, "Invalid breakpoint number %d\n", num );
292         return;
293     }
294     breakpoints[num].enabled = enable;
295     breakpoints[num].skipcount = 0;
296 }
297
298
299 /***********************************************************************
300  *           DEBUG_InfoBreakpoints
301  *
302  * Display break points information.
303  */
304 void DEBUG_InfoBreakpoints(void)
305 {
306     int i;
307
308     fprintf( stderr, "Breakpoints:\n" );
309     for (i = 1; i < next_bp; i++)
310     {
311         if (breakpoints[i].in_use)
312         {
313             fprintf( stderr, "%d: %c ", i, breakpoints[i].enabled ? 'y' : 'n');
314             DEBUG_PrintAddress( &breakpoints[i].addr, breakpoints[i].addrlen,
315                                 TRUE);
316             fprintf( stderr, "\n" );
317             if( breakpoints[i].condition != NULL )
318               {
319                 fprintf(stderr, "\t\tstop when  ");
320                 DEBUG_DisplayExpr(breakpoints[i].condition);
321                 fprintf(stderr, "\n");
322               }
323         }
324     }
325 }
326
327
328 /***********************************************************************
329  *           DEBUG_ShouldContinue
330  *
331  * Determine if we should continue execution after a SIGTRAP signal when
332  * executing in the given mode.
333  */
334 BOOL32 DEBUG_ShouldContinue( enum exec_mode mode, int * count )
335 {
336     DBG_ADDR addr;
337     DBG_ADDR cond_addr;
338     int bpnum;
339     struct list_id list;
340
341       /* If not single-stepping, back up over the int3 instruction */
342     if (!(EFL_reg(&DEBUG_context) & STEP_FLAG)) EIP_reg(&DEBUG_context)--;
343
344     addr.seg = (CS_reg(&DEBUG_context) == WINE_CODE_SELECTOR) ? 
345                 0 : CS_reg(&DEBUG_context);
346     addr.off = EIP_reg(&DEBUG_context);
347         
348     bpnum = DEBUG_FindBreakpoint( &addr );
349     breakpoints[0].enabled = 0;  /* disable the step-over breakpoint */
350
351     if ((bpnum != 0) && (bpnum != -1))
352     {
353         if( breakpoints[bpnum].condition != NULL )
354           {
355             cond_addr = DEBUG_EvalExpr(breakpoints[bpnum].condition);
356             if( cond_addr.type == NULL )
357               {
358                 /*
359                  * Something wrong - unable to evaluate this expression.
360                  */
361                 fprintf(stderr, "Unable to evaluate expression ");
362                 DEBUG_DisplayExpr(breakpoints[bpnum].condition);
363                 fprintf(stderr, "\nTurning off condition\n");
364                 DEBUG_AddBPCondition(bpnum, NULL);
365               }
366             else if( ! DEBUG_GetExprValue( &cond_addr, NULL) )
367               {
368                 return TRUE;
369               }
370           }
371
372         if( breakpoints[bpnum].skipcount > 0 )
373           {
374             breakpoints[bpnum].skipcount--;
375             if( breakpoints[bpnum].skipcount > 0 )
376               {
377                 return TRUE;
378               }
379           }
380         fprintf( stderr, "Stopped on breakpoint %d at ", bpnum );
381         DEBUG_PrintAddress( &breakpoints[bpnum].addr,
382                             breakpoints[bpnum].addrlen, TRUE );
383         fprintf( stderr, "\n" );
384         
385         /*
386          * See if there is a source file for this bp.  If so,
387          * then dig it out and display one line.
388          */
389         DEBUG_FindNearestSymbol( &addr, TRUE, NULL, 0, &list);
390         if( list.sourcefile != NULL )
391           {
392             DEBUG_List(&list, NULL, 0);
393           }
394         return FALSE;
395     }
396
397     /*
398      * If our mode indicates that we are stepping line numbers,
399      * get the current function, and figure out if we are exactly
400      * on a line number or not.
401      */
402     if( mode == EXEC_STEP_OVER 
403         || mode == EXEC_STEP_INSTR )
404       {
405         if( DEBUG_CheckLinenoStatus(&addr) == AT_LINENUMBER )
406           {
407             (*count)--;
408           }
409       }
410     else if( mode == EXEC_STEPI_OVER 
411         || mode == EXEC_STEPI_INSTR )
412
413       {
414         (*count)--;
415       }
416
417     if( *count > 0 || mode == EXEC_FINISH )
418       {
419         /*
420          * We still need to execute more instructions.
421          */
422         return TRUE;
423       }
424     
425     /*
426      * If we are about to stop, then print out the source line if we
427      * have it.
428      */
429     if( (mode != EXEC_CONT && mode != EXEC_FINISH) )
430       {
431         DEBUG_FindNearestSymbol( &addr, TRUE, NULL, 0, &list);
432         if( list.sourcefile != NULL )
433           {
434             DEBUG_List(&list, NULL, 0);
435           }
436       }
437
438     /* If there's no breakpoint and we are not single-stepping, then we     */
439     /* must have encountered an int3 in the Windows program; let's skip it. */
440     if ((bpnum == -1) && !(EFL_reg(&DEBUG_context) & STEP_FLAG))
441         EIP_reg(&DEBUG_context)++;
442
443       /* no breakpoint, continue if in continuous mode */
444     return (mode == EXEC_CONT || mode == EXEC_FINISH);
445 }
446
447
448 /***********************************************************************
449  *           DEBUG_RestartExecution
450  *
451  * Set the breakpoints to the correct state to restart execution
452  * in the given mode.
453  */
454 enum exec_mode DEBUG_RestartExecution( enum exec_mode mode, int count )
455 {
456     DBG_ADDR addr;
457     DBG_ADDR addr2;
458     int bp;
459     int delta;
460     int status;
461     unsigned int * value;
462     enum exec_mode ret_mode;
463     BYTE *instr;
464
465     addr.seg = (CS_reg(&DEBUG_context) == WINE_CODE_SELECTOR) ?
466                 0 : CS_reg(&DEBUG_context);
467     addr.off = EIP_reg(&DEBUG_context);
468
469     /*
470      * This is the mode we will be running in after we finish.  We would like
471      * to be able to modify this in certain cases.
472      */
473     ret_mode = mode;
474
475     bp = DEBUG_FindBreakpoint( &addr ); 
476     if ( bp != -1 && bp != 0)
477       {
478         /*
479          * If we have set a new value, then save it in the BP number.
480          */
481         if( count != 0 && mode == EXEC_CONT )
482           {
483             breakpoints[bp].skipcount = count;
484           }
485         mode = EXEC_STEPI_INSTR;  /* If there's a breakpoint, skip it */
486       }
487     else
488       {
489         if( mode == EXEC_CONT && count > 1 )
490           {
491             fprintf(stderr,"Not stopped at any breakpoint; argument ignored.\n");
492           }
493       }
494     
495     if( mode == EXEC_FINISH && DEBUG_IsFctReturn() )
496       {
497         mode = ret_mode = EXEC_STEPI_INSTR;
498       }
499
500     instr = (BYTE *)PTR_SEG_OFF_TO_LIN( CS_reg(&DEBUG_context),
501                                         EIP_reg(&DEBUG_context) );
502     /*
503      * See if the function we are stepping into has debug info
504      * and line numbers.  If not, then we step over it instead.
505      * FIXME - we need to check for things like thunks or trampolines,
506      * as the actual function may in fact have debug info.
507      */
508     if( *instr == 0xe8 )
509       {
510         delta = *(unsigned int*) (instr + 1);
511         addr2 = addr;
512         DEBUG_Disasm(&addr2, FALSE);
513         addr2.off += delta;
514         
515         status = DEBUG_CheckLinenoStatus(&addr2);
516         /*
517          * Anytime we have a trampoline, step over it.
518          */
519         if( ((mode == EXEC_STEP_OVER) || (mode == EXEC_STEPI_OVER))
520             && status == FUNC_IS_TRAMPOLINE )
521           {
522 #if 0
523             fprintf(stderr, "Not stepping into trampoline at %x (no lines)\n",
524                     addr2.off);
525 #endif
526             mode = EXEC_STEP_OVER_TRAMPOLINE;
527           }
528         
529         if( mode == EXEC_STEP_INSTR && status == FUNC_HAS_NO_LINES )
530           {
531 #if 0
532             fprintf(stderr, "Not stepping into function at %x (no lines)\n",
533                     addr2.off);
534 #endif
535             mode = EXEC_STEP_OVER;
536           }
537       }
538
539
540     if( mode == EXEC_STEP_INSTR )
541       {
542         if( DEBUG_CheckLinenoStatus(&addr) == FUNC_HAS_NO_LINES )
543           {
544             fprintf(stderr, "Single stepping until exit from function, \n");
545             fprintf(stderr, "which has no line number information.\n");
546             
547             ret_mode = mode = EXEC_FINISH;
548           }
549       }
550
551     switch(mode)
552     {
553     case EXEC_CONT: /* Continuous execution */
554         EFL_reg(&DEBUG_context) &= ~STEP_FLAG;
555         DEBUG_SetBreakpoints( TRUE );
556         break;
557
558     case EXEC_STEP_OVER_TRAMPOLINE:
559       /*
560        * This is the means by which we step over our conversion stubs
561        * in callfrom*.s and callto*.s.  We dig the appropriate address
562        * off the stack, and we set the breakpoint there instead of the
563        * address just after the call.
564        */
565       value = (unsigned int *) ESP_reg(&DEBUG_context) + 2;
566       addr.off = *value;
567       EFL_reg(&DEBUG_context) &= ~STEP_FLAG;
568       breakpoints[0].addr    = addr;
569       breakpoints[0].enabled = TRUE;
570       breakpoints[0].in_use  = TRUE;
571       breakpoints[0].skipcount = 0;
572       breakpoints[0].opcode  = *(BYTE *)DBG_ADDR_TO_LIN( &addr );
573       DEBUG_SetBreakpoints( TRUE );
574       break;
575
576     case EXEC_FINISH:
577     case EXEC_STEPI_OVER:  /* Stepping over a call */
578     case EXEC_STEP_OVER:  /* Stepping over a call */
579         if (DEBUG_IsStepOverInstr())
580         {
581             EFL_reg(&DEBUG_context) &= ~STEP_FLAG;
582             DEBUG_Disasm(&addr, FALSE);
583             breakpoints[0].addr    = addr;
584             breakpoints[0].enabled = TRUE;
585             breakpoints[0].in_use  = TRUE;
586             breakpoints[0].skipcount = 0;
587             breakpoints[0].opcode  = *(BYTE *)DBG_ADDR_TO_LIN( &addr );
588             DEBUG_SetBreakpoints( TRUE );
589             break;
590         }
591         /* else fall through to single-stepping */
592
593     case EXEC_STEP_INSTR: /* Single-stepping an instruction */
594     case EXEC_STEPI_INSTR: /* Single-stepping an instruction */
595         EFL_reg(&DEBUG_context) |= STEP_FLAG;
596         break;
597     }
598     return ret_mode;
599 }
600
601 int
602 DEBUG_AddBPCondition(int num, struct expr * exp)
603 {
604     if ((num <= 0) || (num >= next_bp) || !breakpoints[num].in_use)
605     {
606         fprintf( stderr, "Invalid breakpoint number %d\n", num );
607         return FALSE;
608     }
609
610     if( breakpoints[num].condition != NULL )
611       {
612         DEBUG_FreeExpr(breakpoints[num].condition);
613         breakpoints[num].condition = NULL;
614       }
615
616     if( exp != NULL )
617       {
618         breakpoints[num].condition = DEBUG_CloneExpr(exp);
619       }
620
621    return TRUE;
622 }