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 -------------------------------------------------------------------------*/
29 static hTab *bptable = NULL;
31 char userBpPresent = 0;
33 /* call stack can be 1024 deep */
34 STACK_DCL(callStack,function *,1024);
37 char *debug_bp_type_strings[] =
46 "FEXIT", "TMPUSER", ""};
49 static long bpnum = 0;
51 long getLastBreakptNumber()
56 /*-----------------------------------------------------------------*/
57 /* setBreakPoint - creates an entry in the break point table */
58 /*-----------------------------------------------------------------*/
59 int setBreakPoint (unsigned addr, char addrType, char bpType,
60 int (*callBack)(unsigned,char,char,int,context *) ,
61 char *fileName, int lineno)
66 Dprintf(D_break, ("setBreakPoint: addr:%x atype:%s bpType:%s [%s:%d]\n",
68 debug_bp_type_strings[addrType],
69 debug_bp_type_strings[bpType],
72 /* allocate & init a new bp */
73 bp = Safe_calloc(1,sizeof(breakp));
75 bp->addrType = addrType;
77 bp->callBack = callBack;
78 bp->bpnum = ((bpType == USER || bpType == TMPUSER)? ++bpnum : 0);
79 bp->filename = fileName;
82 /* if this is an user break point then
83 check if there already exists one for this address */
84 if (bpType == USER || bpType == TMPUSER)
86 for ( bpl = hTabFirstItemWK(bptable,addr) ; bpl;
87 bpl = hTabNextItemWK(bptable))
90 /* if also a user break point then issue Note : */
91 if (bpl->bpType == USER || bpType == TMPUSER)
92 fprintf(stderr,"Note: breakpoint %d also set at pc 0x%x\n",
93 bpl->bpnum,bpl->addr);
96 fprintf(stderr,"Breakpoint %d at 0x%x: file %s, line %d.\n",
97 bp->bpnum, addr, fileName, lineno+1);
102 if (bpType != STEP && bpType != NEXT)
104 /* if a break point does not already exist then
105 send command to simulator to add one */
106 if (!hTabSearch(bptable,addr))
107 /* send the break command to the simulator */
111 /* now add the break point to list */
112 hTabAddItem(&bptable,addr,bp);
117 /*-----------------------------------------------------------------*/
118 /* deleteSTEPbp - deletes all step break points */
119 /*-----------------------------------------------------------------*/
125 Dprintf(D_break, ("break: Deleting all STEP BPs\n"));
126 /* for break points delete if they are STEP */
127 for ( bp = hTabFirstItem(bptable,&k); bp ;
128 bp = hTabNextItem(bptable,&k)) {
130 /* if this is a step then delete */
131 if (bp->bpType == STEP) {
132 hTabDeleteItem(&bptable,bp->addr,bp,DELETE_ITEM,NULL);
140 /*-----------------------------------------------------------------*/
141 /* deleteNEXTbp - deletes all step break points */
142 /*-----------------------------------------------------------------*/
149 Dprintf(D_break, ("break: Deleting all NEXT BPs\n"));
151 /* for break points delete if they are NEXT */
152 for ( bp = hTabFirstItem(bptable,&k); bp ;
153 bp = hTabNextItem(bptable,&k)) {
155 /* if this is a step then delete */
156 if (bp->bpType == NEXT) {
157 hTabDeleteItem(&bptable,bp->addr,bp,DELETE_ITEM,NULL);
165 /*-----------------------------------------------------------------*/
166 /* deleteUSERbp - deletes USER break point with number */
167 /*-----------------------------------------------------------------*/
168 void deleteUSERbp (int bpnum)
174 Dprintf(D_break, ("break: deleteUSERbp %d\n", bpnum));
176 /* for break points delete if they are STEP */
177 for ( bp = hTabFirstItem(bptable,&k); bp ;
178 bp = hTabNextItem(bptable,&k)) {
180 /* if this is a user then delete if break
181 point matches or bpnumber == -1 (meaning delete
182 all user break points */
183 if ((bp->bpType == USER || bp->bpType == TMPUSER )
184 && ( bp->bpnum == bpnum || bpnum == -1)) {
185 hTabDeleteItem(&bptable,bp->addr,bp,DELETE_ITEM,NULL);
187 /* if this leaves no other break points then
188 send command to simulator to delete bp from this addr */
189 if (hTabSearch(bptable,bp->addr) == NULL) {
190 simClearBP (bp->addr);
191 Dprintf(D_break, ("break: deleteUSERbp:simClearBP 0x%x\n", bp->addr));
194 fprintf(stdout,"Deleted breakpoint %d\n",
204 if (!bp && bpnum != -1)
205 fprintf(stderr,"No breakpoint number %d.\n",bpnum);
208 /*-----------------------------------------------------------------*/
209 /* setUserbpCommand - set commandstring for breakpoint */
210 /*-----------------------------------------------------------------*/
211 void setUserbpCommand (int bpnum, char *cmds)
215 Dprintf(D_break, ("break: setUserbpCommand %d: commands:\n%send\n",
218 for ( bp = hTabFirstItem(bptable,&k); bp ;
219 bp = hTabNextItem(bptable,&k))
221 if ((bp->bpType == USER || bp->bpType == TMPUSER )
222 && ( bp->bpnum == bpnum ))
225 Safe_free(bp->commands);
230 fprintf(stderr,"No breakpoint number %d.\n",bpnum);
233 /*-----------------------------------------------------------------*/
234 /* listUSERbp - list all user break points */
235 /*-----------------------------------------------------------------*/
241 /* if there are none then say so & return */
242 if (!userBpPresent) {
243 fprintf(stdout,"No breakpoints.\n");
246 fprintf(stdout,"Num Type Disp Enb Address What\n");
247 for ( bp = hTabFirstItem(bptable,&k) ; bp ;
248 bp = hTabNextItem(bptable,&k)) {
250 if (bp->bpType == USER ) {
251 fprintf(stdout,"%-3d breakpoint keep y 0x%08x at %s:%d\n",
253 bp->filename,bp->lineno+1);
256 else if (bp->bpType == TMPUSER ) {
257 fprintf(stdout,"%-3d breakpoint del y 0x%08x at %s:%d\n",
259 bp->filename,bp->lineno+1);
265 /*-----------------------------------------------------------------*/
266 /* simStopBPCB - simulator stopped break point */
267 /*-----------------------------------------------------------------*/
268 static int simStopBPCB( unsigned int addr)
270 fprintf(stdout,"Simulator stopped at Address 0x%04x\n",addr);
271 fprintf(stdout,"%s",simResponse());
275 /*-----------------------------------------------------------------*/
276 /* clearUSERbp - deletes USER break point at address */
277 /*-----------------------------------------------------------------*/
278 void clearUSERbp ( unsigned int addr )
283 /* for break points delete if they are STEP */
284 for ( bp = hTabFirstItemWK(bptable,addr); bp ;
285 bp = hTabNextItemWK(bptable)) {
287 /* if this is a step then delete */
288 if (bp->bpType == USER || bp->bpType == TMPUSER) {
289 hTabDeleteItem(&bptable,bp->addr,bp,DELETE_ITEM,NULL);
291 /* if this leaves no other break points then
292 send command to simulator to delete bp from this addr */
293 if (hTabSearch(bptable,bp->addr) == NULL) {
294 simClearBP(bp->addr);
297 fprintf(stdout,"Deleted breakpoint %d\n",
305 fprintf(stderr,"No breakpoint at address 0x%x.\n",addr);
308 /*-----------------------------------------------------------------*/
309 /* dispatchCB - will lookup the bp table and dispatch the cb funcs */
310 /*-----------------------------------------------------------------*/
311 int dispatchCB (unsigned addr, context *ctxt)
316 Dprintf(D_break, ("break: dispatchCB: addr:0x%x \n", addr));
318 /* if no break points set for this address
319 then use a simulator stop break point */
320 if ((bp = hTabFirstItemWK(bptable,addr)) == NULL) {
321 if ( doingSteps == 2 ) return 1;
322 if ( doingSteps ) return 0;
323 if ( contsim ) return 0;
324 return simStopBPCB(addr);
327 /* dispatch the call back functions */
328 for (; bp; bp = hTabNextItemWK(bptable))
333 Dprintf(D_break, ("break: dispatchCB: commands:\n%send\n", bp->commands));
334 setCmdLine(bp->commands);
337 rv += (*bp->callBack)(addr,bp->addrType,
338 bp->bpType,bp->bpnum,ctxt);
342 Dprintf(D_break, ("break: dispatchCB: WARNING rv==0\n", rv));
348 /*-----------------------------------------------------------------*/
349 /* fentryCB - callback function for function entry */
350 /*-----------------------------------------------------------------*/
351 BP_CALLBACK(fentryCB)
355 /* we save the value of SP
356 which will be used to display the value of local variables
357 and parameters on the stack */
358 ctxt->func->stkaddr = simGetValue (0x81,'I',1);
360 Dprintf(D_break, ("break: fentryCB: BP_CALLBACK entry %s sp=0x%02x %p\n",
361 ctxt->func->sym->name,
362 ctxt->func->stkaddr, p_callStack));
364 /* and set laddr of calling function to return addr from stack */
365 if ((func = STACK_PEEK(callStack)))
367 /* extern stack ?? 'A' */
368 func->laddr = simGetValue (ctxt->func->stkaddr-1,'B',2);
370 /* add the current function into the call stack */
371 STACK_PUSH(callStack,ctxt->func);
376 /*-----------------------------------------------------------------*/
377 /* fexitCB - call back for function exit */
378 /*-----------------------------------------------------------------*/
382 /* pop the top most from the call stack */
383 func = STACK_POP(callStack);
385 Dprintf(D_break, ("break: fexitCB: BP_CALLBACK entry %s %p\n",func->sym->name, p_callStack));
387 /* check main function */
388 if ( STACK_EMPTY(callStack))
390 fprintf(stdout,"Program exited with code %d.\n",simGetValue (0x82,'I',2));
395 /*-----------------------------------------------------------------*/
396 /* userBpCB - call back function for user break points */
397 /*-----------------------------------------------------------------*/
398 BP_CALLBACK(userBpCB)
400 Dprintf(D_break, ("break: userBpCB: BP_CALLBACK entry\n"));
402 if (srcMode == SRC_CMODE) {
403 fprintf(stdout,"Breakpoint %d, %s() at %s:%d\n",
405 ctxt->func->sym->name,
406 ctxt->func->mod->c_name,
408 if (ctxt->func->mod && ctxt->cline > 0)
409 fprintf(stdout,"%d\t%s",ctxt->cline+1,
410 ctxt->func->mod->cLines[ctxt->cline]->src);
412 fprintf(stdout,"Breakpoint %d, %s() at %s:%d\n",
414 ctxt->func->sym->name,
415 ctxt->func->mod->asm_name,
417 if (ctxt->func->mod && ctxt->asmline > 0)
418 fprintf(stdout,"%d\t%s",ctxt->asmline+1,
419 ctxt->func->mod->asmLines[ctxt->asmline]->src);
422 if ( bpType == TMPUSER && bpnum > 0 )
423 deleteUSERbp (bpnum);
427 /*-----------------------------------------------------------------*/
428 /* stepBpCB - call back function for step break points */
429 /*-----------------------------------------------------------------*/
430 BP_CALLBACK(stepBpCB)
432 static function *lfunc = NULL;
434 Dprintf(D_break, ("break: stepBpCB: BP_CALLBACK entry\n"));
436 if (srcMode == SRC_CMODE) {
437 if ((lfunc && lfunc != ctxt->func) || !lfunc)
438 fprintf(stdout,"%s () at %s:%d\n",
439 ctxt->func->sym->name,
440 ctxt->func->mod->c_name,
443 if (ctxt->func->mod && ctxt->cline > 0) {
444 fprintf(stdout,"%d\t%s",ctxt->cline+1 ,
445 ctxt->func->mod->cLines[ctxt->cline]->src);
448 if ((lfunc && lfunc != ctxt->func) || !lfunc)
449 fprintf(stdout,"%s () at %s:%d\n",
450 ctxt->func->sym->name,
451 ctxt->func->mod->asm_name,
454 if (ctxt->func->mod && ctxt->cline > 0) {
455 fprintf(stdout,"%d\t%s",ctxt->asmline ,
456 ctxt->func->mod->asmLines[ctxt->asmline]->src);
465 /*-----------------------------------------------------------------*/
466 /* nextBpCB - call back function for next break points */
467 /*-----------------------------------------------------------------*/
468 BP_CALLBACK(nextBpCB)
470 static function *lfunc = NULL;
472 Dprintf(D_break, ("break: nextBpCB: BP_CALLBACK entry\n"));
474 if (srcMode == SRC_CMODE) {
475 if ((lfunc && lfunc != ctxt->func) || !lfunc)
476 fprintf(stdout,"%s () at %s:%d\n",
477 ctxt->func->sym->name,
478 ctxt->func->mod->c_name,
481 if (ctxt->func->mod && ctxt->cline > 0)
482 fprintf(stdout,"%d\t%s",ctxt->cline+1,
483 ctxt->func->mod->cLines[ctxt->cline]->src);
485 if ((lfunc && lfunc != ctxt->func) || !lfunc)
486 fprintf(stdout,"%s () at %s:%d\n",
487 ctxt->func->sym->name,
488 ctxt->func->mod->asm_name,
491 if (ctxt->func->mod && ctxt->asmline > 0)
492 fprintf(stdout,"%d\t%s",ctxt->asmline,
493 ctxt->func->mod->asmLines[ctxt->asmline]->src);