1 /*-------------------------------------------------------------------------
2 break.c - Source file for break point management
3 Written By - Sandeep Dutta . sandeep.dutta@usa.net (1999)
5 This program is free software; you can redistribute it and/or modify it
6 under the terms of the GNU General Public License as published by the
7 Free Software Foundation; either version 2, or (at your option) any
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 In other words, you are welcome to use, share and improve this program.
20 You are forbidden to forbid anyone else to use, share and improve
21 what you give them. Help stamp out software-hoarding!
22 -------------------------------------------------------------------------*/
32 char userBpPresent = 0;
35 char *debug_bp_type_strings[] =
44 "FEXIT", "TMPUSER", ""};
47 static long bpnum = 0;
49 long getLastBreakptNumber()
58 for ( bp = hTabFirstItem(bptable,&k); bp ;
59 bp = hTabNextItem(bptable,&k))
66 /*-----------------------------------------------------------------*/
67 /* setBreakPoint - creates an entry in the break point table */
68 /*-----------------------------------------------------------------*/
69 int setBreakPoint (unsigned addr, char addrType, char bpType,
70 int (*callBack)(unsigned,breakp *,context *) ,
71 char *fileName, int lineno)
75 Dprintf(D_break, ("setBreakPoint: addr:%x atype:%s bpType:%s [%s:%d]\n",
77 debug_bp_type_strings[addrType],
78 debug_bp_type_strings[bpType],
81 /* allocate & init a new bp */
82 bp = Safe_calloc(1,sizeof(breakp));
84 bp->addrType = addrType;
86 bp->callBack = callBack;
87 bp->bpnum = ((bpType == USER || bpType == TMPUSER)? ++bpnum : 0);
88 bp->filename = fileName;
91 /* if this is an user break point then
92 check if there already exists one for this address */
93 if (bpType == USER || bpType == TMPUSER)
95 for ( bpl = hTabFirstItemWK(bptable,addr) ; bpl;
96 bpl = hTabNextItemWK(bptable))
99 /* if also a user break point then issue Note : */
100 if (bpl->bpType == USER || bpType == TMPUSER)
101 fprintf(stderr,"Note: breakpoint %d also set at pc 0x%x\n",
102 bpl->bpnum,bpl->addr);
105 fprintf(stderr,"Breakpoint %d at 0x%x: file %s, line %d.\n",
106 bp->bpnum, addr, fileName, lineno+1);
111 /* if a break point does not already exist then
112 send command to simulator to add one */
113 if (!hTabSearch(bptable,addr))
114 /* send the break command to the simulator */
117 /* now add the break point to list */
118 hTabAddItem(&bptable,addr,bp);
123 /*-----------------------------------------------------------------*/
124 /* deleteSTEPbp - deletes all step break points */
125 /*-----------------------------------------------------------------*/
131 Dprintf(D_break, ("break: Deleting all STEP BPs\n"));
132 /* for break points delete if they are STEP */
133 for ( bp = hTabFirstItem(bptable,&k); bp ;
134 bp = hTabNextItem(bptable,&k))
137 /* if this is a step then delete */
138 if (bp->bpType == STEP)
140 simClearBP(bp->addr);
141 hTabDeleteItem(&bptable,bp->addr,bp,DELETE_ITEM,NULL);
148 /*-----------------------------------------------------------------*/
149 /* deleteNEXTbp - deletes all step break points */
150 /*-----------------------------------------------------------------*/
156 Dprintf(D_break, ("break: Deleting all NEXT BPs\n"));
158 /* for break points delete if they are NEXT */
159 for ( bp = hTabFirstItem(bptable,&k); bp ;
160 bp = hTabNextItem(bptable,&k))
163 /* if this is a step then delete */
164 if (bp->bpType == NEXT)
166 hTabDeleteItem(&bptable,bp->addr,bp,DELETE_ITEM,NULL);
173 static void freeUSERbp(breakp *bp)
176 Safe_free(bp->commands);
178 Safe_free(bp->condition);
182 /*-----------------------------------------------------------------*/
183 /* deleteUSERbp - deletes USER break point with number */
184 /*-----------------------------------------------------------------*/
185 void deleteUSERbp (int bpnum)
190 Dprintf(D_break, ("break: deleteUSERbp %d\n", bpnum));
192 /* for break points delete if they are STEP */
193 for ( bp = hTabFirstItem(bptable,&k); bp ;
194 bp = hTabNextItem(bptable,&k)) {
196 /* if this is a user then delete if break
197 point matches or bpnumber == -1 (meaning delete
198 all user break points */
199 if ((bp->bpType == USER || bp->bpType == TMPUSER )
200 && ( bp->bpnum == bpnum || bpnum == -1))
202 hTabDeleteItem(&bptable,bp->addr,bp,DELETE_ITEM,NULL);
204 /* if this leaves no other break points then
205 send command to simulator to delete bp from this addr */
206 if (hTabSearch(bptable,bp->addr) == NULL) {
207 simClearBP (bp->addr);
208 Dprintf(D_break, ("break: deleteUSERbp:simClearBP 0x%x\n", bp->addr));
211 fprintf(stdout,"Deleted breakpoint %d\n",bp->bpnum);
221 if (!bp && bpnum != -1)
222 fprintf(stderr,"No breakpoint number %d.\n",bpnum);
225 /*-----------------------------------------------------------------*/
226 /* setUserbpCommand - set commandstring for breakpoint */
227 /*-----------------------------------------------------------------*/
228 void setUserbpCommand (int bpnum, char *cmds)
232 Dprintf(D_break, ("break: setUserbpCommand %d: commands:\n%send\n",
235 for ( bp = hTabFirstItem(bptable,&k); bp ;
236 bp = hTabNextItem(bptable,&k))
238 if ((bp->bpType == USER || bp->bpType == TMPUSER )
239 && ( bp->bpnum == bpnum ))
242 Safe_free(bp->commands);
247 fprintf(stderr,"No breakpoint number %d.\n",bpnum);
250 /*-----------------------------------------------------------------*/
251 /* setUserbpCondition - set condition string for breakpoint */
252 /*-----------------------------------------------------------------*/
253 void setUserbpCondition (int bpnum, char *cond)
257 Dprintf(D_break, ("break: setUserbpCondition %d: condition:'%s'\n",
258 bpnum, cond?cond:""));
260 for ( bp = hTabFirstItem(bptable,&k); bp ;
261 bp = hTabNextItem(bptable,&k))
263 if ((bp->bpType == USER || bp->bpType == TMPUSER )
264 && ( bp->bpnum == bpnum ))
267 Safe_free(bp->condition);
268 bp->condition = cond;
272 fprintf(stderr,"No breakpoint number %d.\n",bpnum);
275 /*-----------------------------------------------------------------*/
276 /* setUserbpIgnCount - set ignorecount for breakpoint */
277 /*-----------------------------------------------------------------*/
278 void setUserbpIgnCount (int bpnum, int ignorecnt )
282 Dprintf(D_break, ("break: setUserbpIgnCount %d: ignorecnt=%d\n",
285 for ( bp = hTabFirstItem(bptable,&k); bp ;
286 bp = hTabNextItem(bptable,&k))
288 if ((bp->bpType == USER || bp->bpType == TMPUSER )
289 && ( bp->bpnum == bpnum ))
291 bp->ignoreCnt = bp->hitCnt + ignorecnt;
295 fprintf(stderr,"No breakpoint number %d.\n",bpnum);
298 /*-----------------------------------------------------------------*/
299 /* listUSERbp - list all user break points */
300 /*-----------------------------------------------------------------*/
306 /* if there are none then say so & return */
307 if (!userBpPresent) {
308 fprintf(stdout,"No breakpoints.\n");
311 fprintf(stdout,"Num Type Disp Enb Address What\n");
312 for ( bp = hTabFirstItem(bptable,&k) ; bp ;
313 bp = hTabNextItem(bptable,&k)) {
316 if (bp->bpType == USER ) {
317 fprintf(stdout,"%-3d breakpoint keep y 0x%08x at %s:%d\n",
319 bp->filename,bp->lineno+1);
322 else if (bp->bpType == TMPUSER ) {
323 fprintf(stdout,"%-3d breakpoint del y 0x%08x at %s:%d\n",
325 bp->filename,bp->lineno+1);
330 if ( bp->ignoreCnt > bp->hitCnt )
331 fprintf(stdout,"\tignore next %d hits\n",
332 bp->ignoreCnt - bp->hitCnt );
334 fprintf(stdout,"\tstop only if %s\n",bp->condition );
335 if ( bp->hitCnt > 0 )
336 fprintf(stdout,"\tbreakpoint already hit %d time%s\n",
337 bp->hitCnt,bp->hitCnt>1?"s":"" );
343 /*-----------------------------------------------------------------*/
344 /* simStopBPCB - simulator stopped break point */
345 /*-----------------------------------------------------------------*/
346 static int simStopBPCB( unsigned int addr)
348 fprintf(stdout,"Simulator stopped at Address 0x%04x\n",addr);
349 fprintf(stdout,"%s",simResponse());
353 /*-----------------------------------------------------------------*/
354 /* clearUSERbp - deletes USER break point at address */
355 /*-----------------------------------------------------------------*/
356 void clearUSERbp ( unsigned int addr )
360 /* for break points delete if they are STEP */
361 for ( bp = hTabFirstItemWK(bptable,addr); bp ;
362 bp = hTabNextItemWK(bptable)) {
364 /* if this is a step then delete */
365 if (bp->bpType == USER || bp->bpType == TMPUSER)
367 hTabDeleteItem(&bptable,bp->addr,bp,DELETE_ITEM,NULL);
369 /* if this leaves no other break points then
370 send command to simulator to delete bp from this addr */
371 if (hTabSearch(bptable,bp->addr) == NULL)
373 simClearBP(bp->addr);
375 fprintf(stdout,"Deleted breakpoint %d\n",
384 fprintf(stderr,"No breakpoint at address 0x%x.\n",addr);
387 /*-----------------------------------------------------------------*/
388 /* dispatchCB - will lookup the bp table and dispatch the cb funcs */
389 /*-----------------------------------------------------------------*/
390 int dispatchCB (unsigned addr, context *ctxt)
395 Dprintf(D_break, ("break: dispatchCB: addr:0x%x \n", addr));
397 /* if no break points set for this address
398 then use a simulator stop break point */
399 if ((bp = hTabFirstItemWK(bptable,addr)) == NULL) {
400 if ( doingSteps == 2 ) return 1;
401 if ( doingSteps ) return 0;
402 if ( contsim ) return 0;
403 return simStopBPCB(addr);
406 /* dispatch the call back functions */
407 for (; bp; bp = hTabNextItemWK(bptable))
409 rv += (*bp->callBack)(addr,bp,ctxt);
413 Dprintf(D_break, ("break: dispatchCB: WARNING rv==0\n", rv));
419 /*-----------------------------------------------------------------*/
420 /* userBpCB - call back function for user break points */
421 /*-----------------------------------------------------------------*/
422 BP_CALLBACK(userBpCB)
425 Dprintf(D_break, ("break: userBpCB: BP_CALLBACK entry hit=%d ignor=%d\n",
426 bp->hitCnt, bp->ignoreCnt));
428 if ( bp->ignoreCnt > bp->hitCnt )
433 if (! conditionIsTrue( bp->condition, ctxt ))
439 Dprintf(D_break, ("break: userBpCB: commands:%p\n", bp->commands));
440 setCmdLine(bp->commands);
443 if (srcMode == SRC_CMODE) {
444 fprintf(stdout,"Breakpoint %d, %s() at %s:%d\n",
446 ctxt->func->sym->name,
447 ctxt->func->mod->c_name,
449 if (ctxt->func->mod && ctxt->cline > 0)
450 fprintf(stdout,"%d\t%s",ctxt->cline+1,
451 ctxt->func->mod->cLines[ctxt->cline]->src);
453 fprintf(stdout,"Breakpoint %d, %s() at %s:%d\n",
455 ctxt->func->sym->name,
456 ctxt->func->mod->asm_name,
458 if (ctxt->func->mod && ctxt->asmline > 0)
459 fprintf(stdout,"%d\t%s",ctxt->asmline+1,
460 ctxt->func->mod->asmLines[ctxt->asmline]->src);
463 if ( bp->bpType == TMPUSER && bp->bpnum > 0 )
465 hTabDeleteItem(&bptable,bp->addr,bp,DELETE_ITEM,NULL);
467 /* if this leaves no other break points then
468 send command to simulator to delete bp from this addr */
469 if (hTabSearch(bptable,bp->addr) == NULL)
471 simClearBP (bp->addr);
472 Dprintf(D_break, ("break: simClearBP 0x%x\n", bp->addr));
481 /*-----------------------------------------------------------------*/
482 /* stepBpCB - call back function for step break points */
483 /*-----------------------------------------------------------------*/
484 BP_CALLBACK(stepBpCB)
486 static function *lfunc = NULL;
488 Dprintf(D_break, ("break: stepBpCB: BP_CALLBACK entry\n"));
490 if (srcMode == SRC_CMODE) {
491 if ((lfunc && lfunc != ctxt->func) || !lfunc)
492 fprintf(stdout,"%s () at %s:%d\n",
493 ctxt->func->sym->name,
494 ctxt->func->mod->c_name,
497 if (ctxt->func->mod && ctxt->cline > 0) {
498 fprintf(stdout,"%d\t%s",ctxt->cline+1 ,
499 ctxt->func->mod->cLines[ctxt->cline]->src);
502 if ((lfunc && lfunc != ctxt->func) || !lfunc)
503 fprintf(stdout,"%s () at %s:%d\n",
504 ctxt->func->sym->name,
505 ctxt->func->mod->asm_name,
508 if (ctxt->func->mod && ctxt->cline > 0) {
509 fprintf(stdout,"%d\t%s",ctxt->asmline ,
510 ctxt->func->mod->asmLines[ctxt->asmline]->src);
519 /*-----------------------------------------------------------------*/
520 /* nextBpCB - call back function for next break points */
521 /*-----------------------------------------------------------------*/
522 BP_CALLBACK(nextBpCB)
524 static function *lfunc = NULL;
526 Dprintf(D_break, ("break: nextBpCB: BP_CALLBACK entry\n"));
528 if (srcMode == SRC_CMODE) {
529 if ((lfunc && lfunc != ctxt->func) || !lfunc)
530 fprintf(stdout,"%s () at %s:%d\n",
531 ctxt->func->sym->name,
532 ctxt->func->mod->c_name,
535 if (ctxt->func->mod && ctxt->cline > 0)
536 fprintf(stdout,"%d\t%s",ctxt->cline+1,
537 ctxt->func->mod->cLines[ctxt->cline]->src);
539 if ((lfunc && lfunc != ctxt->func) || !lfunc)
540 fprintf(stdout,"%s () at %s:%d\n",
541 ctxt->func->sym->name,
542 ctxt->func->mod->asm_name,
545 if (ctxt->func->mod && ctxt->asmline > 0)
546 fprintf(stdout,"%d\t%s",ctxt->asmline,
547 ctxt->func->mod->asmLines[ctxt->asmline]->src);