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;
32 /* call stack can be 1024 deep */
33 STACK_DCL(callStack,function *,1024);
36 char *debug_bp_type_strings[] =
48 /*-----------------------------------------------------------------*/
49 /* setBreakPoint - creates an entry in the break point table */
50 /*-----------------------------------------------------------------*/
51 int setBreakPoint (unsigned addr, char addrType, char bpType,
52 int (*callBack)(unsigned,char,char,int,context *) ,
53 char *fileName, int lineno)
56 static long bpnum = 0;
59 Dprintf(D_break, ("setBreakPoint: addr:%x atype:%s bpType:%s [%s:%d]\n",
61 debug_bp_type_strings[addrType],
62 debug_bp_type_strings[bpType],
65 /* allocate & init a new bp */
66 bp = Safe_calloc(1,sizeof(breakp));
68 bp->addrType = addrType;
70 bp->callBack = callBack;
71 bp->bpnum = (bpType == USER ? ++bpnum : 0);
72 bp->filename = fileName;
75 /* if this is an user break point then
76 check if there already exists one for this address */
79 for ( bpl = hTabFirstItemWK(bptable,addr) ; bpl;
80 bpl = hTabNextItemWK(bptable))
83 /* if also a user break point then issue Note : */
84 if (bpl->bpType == USER)
85 fprintf(stderr,"Note: breakpoint %d also set at pc 0x%x\n",
86 bpl->bpnum,bpl->addr);
89 fprintf(stderr,"Breakpoint %d at 0x%x: file %s, line %d.\n",
90 bp->bpnum, addr, fileName, lineno+1);
95 if (bpType != STEP && bpType != NEXT)
97 /* if a break point does not already exist then
98 send command to simulator to add one */
99 if (!hTabSearch(bptable,addr))
100 /* send the break command to the simulator */
104 /* now add the break point to list */
105 hTabAddItem(&bptable,addr,bp);
110 /*-----------------------------------------------------------------*/
111 /* deleteSTEPbp - deletes all step break points */
112 /*-----------------------------------------------------------------*/
118 Dprintf(D_break, ("break: Deleting all STEP BPs\n"));
119 /* for break points delete if they are STEP */
120 for ( bp = hTabFirstItem(bptable,&k); bp ;
121 bp = hTabNextItem(bptable,&k)) {
123 /* if this is a step then delete */
124 if (bp->bpType == STEP) {
125 hTabDeleteItem(&bptable,bp->addr,bp,DELETE_ITEM,NULL);
128 /* if this leaves no other break points then
129 send command to simulator to delete bp from this addr */
130 if (hTabSearch(bptable,bp->addr) == NULL)
131 simClearBP (bp->addr);
139 /*-----------------------------------------------------------------*/
140 /* deleteNEXTbp - deletes all step break points */
141 /*-----------------------------------------------------------------*/
148 Dprintf(D_break, ("break: Deleting all NEXT BPs\n"));
150 /* for break points delete if they are NEXT */
151 for ( bp = hTabFirstItem(bptable,&k); bp ;
152 bp = hTabNextItem(bptable,&k)) {
154 /* if this is a step then delete */
155 if (bp->bpType == NEXT) {
156 hTabDeleteItem(&bptable,bp->addr,bp,DELETE_ITEM,NULL);
159 /* if this leaves no other break points then
160 send command to simulator to delete bp from this addr */
161 if (hTabSearch(bptable,bp->addr) == NULL) {
162 simClearBP(bp->addr);
172 /*-----------------------------------------------------------------*/
173 /* deleteUSERbp - deletes USER break point with number */
174 /*-----------------------------------------------------------------*/
175 void deleteUSERbp (int bpnum)
181 Dprintf(D_break, ("break: deleteUSERbp %d\n", bpnum));
183 /* for break points delete if they are STEP */
184 for ( bp = hTabFirstItem(bptable,&k); bp ;
185 bp = hTabNextItem(bptable,&k)) {
187 /* if this is a user then delete if break
188 point matches or bpnumber == -1 (meaning delete
189 all user break points */
190 if (bp->bpType == USER && ( bp->bpnum == bpnum || bpnum == -1)) {
191 hTabDeleteItem(&bptable,bp->addr,bp,DELETE_ITEM,NULL);
193 /* if this leaves no other break points then
194 send command to simulator to delete bp from this addr */
195 if (hTabSearch(bptable,bp->addr) == NULL) {
196 simClearBP (bp->addr);
197 Dprintf(D_break, ("break: deleteUSERbp:simClearBP 0x%x\n", bp->addr));
200 fprintf(stdout,"Deleted breakpoint %d\n",
210 if (!bp && bpnum != -1)
211 fprintf(stderr,"No breakpoint number %d.\n",bpnum);
214 /*-----------------------------------------------------------------*/
215 /* listUSERbp - list all user break points */
216 /*-----------------------------------------------------------------*/
222 /* if there are none then say so & return */
223 if (!userBpPresent) {
224 fprintf(stdout,"No breakpoints.\n");
227 fprintf(stdout,"Num Type Disp Enb Address What\n");
228 for ( bp = hTabFirstItem(bptable,&k) ; bp ;
229 bp = hTabNextItem(bptable,&k)) {
231 if (bp->bpType == USER ) {
232 fprintf(stdout,"%-3d breakpoint keep y 0x%08x at %s:%d\n",
234 bp->filename,bp->lineno+1);
240 /*-----------------------------------------------------------------*/
241 /* simStopBPCB - simulator stopped break point */
242 /*-----------------------------------------------------------------*/
243 static int simStopBPCB( unsigned int addr)
245 fprintf(stdout,"Simulator stopped at Address 0x%04x\n",addr);
246 fprintf(stdout,"%s",simResponse());
250 /*-----------------------------------------------------------------*/
251 /* clearUSERbp - deletes USER break point at address */
252 /*-----------------------------------------------------------------*/
253 void clearUSERbp ( unsigned int addr )
258 /* for break points delete if they are STEP */
259 for ( bp = hTabFirstItemWK(bptable,addr); bp ;
260 bp = hTabNextItemWK(bptable)) {
262 /* if this is a step then delete */
263 if (bp->bpType == USER) {
264 hTabDeleteItem(&bptable,bp->addr,bp,DELETE_ITEM,NULL);
266 /* if this leaves no other break points then
267 send command to simulator to delete bp from this addr */
268 if (hTabSearch(bptable,bp->addr) == NULL) {
269 simClearBP(bp->addr);
272 fprintf(stdout,"Deleted breakpoint %d\n",
280 fprintf(stderr,"No breakpoint at address 0x%x.\n",addr);
283 /*-----------------------------------------------------------------*/
284 /* dispatchCB - will lookup the bp table and dispatch the cb funcs */
285 /*-----------------------------------------------------------------*/
286 int dispatchCB (unsigned addr, context *ctxt)
291 Dprintf(D_break, ("break: dispatchCB: addr:0x%x \n", addr));
293 /* if no break points set for this address
294 then use a simulator stop break point */
295 if ((bp = hTabFirstItemWK(bptable,addr)) == NULL) {
296 if ( doingSteps == 2 ) return 1;
297 if ( doingSteps ) return 0;
298 if ( contsim ) return 0;
299 return simStopBPCB(addr);
302 /* dispatch the call back functions */
303 for (; bp; bp = hTabNextItemWK(bptable)) {
305 rv += (*bp->callBack)(addr,bp->addrType,
306 bp->bpType,bp->bpnum,ctxt);
311 Dprintf(D_break, ("break: dispatchCB: WARNING rv==0\n", rv));
317 /*-----------------------------------------------------------------*/
318 /* fentryCB - callback function for function entry */
319 /*-----------------------------------------------------------------*/
320 BP_CALLBACK(fentryCB)
322 Dprintf(D_break, ("break: fentryCB: BP_CALLBACK entry\n"));
324 /* add the current function into the call stack */
325 STACK_PUSH(callStack,ctxt->func);
327 /* will have to add code here to get the value of SP
328 which will be used to display the value of local variables
329 and parameters on the stack */
334 /*-----------------------------------------------------------------*/
335 /* fexitCB - call back for function exit */
336 /*-----------------------------------------------------------------*/
339 Dprintf(D_break, ("break: fexitCB: BP_CALLBACK entry\n"));
341 /* pop the top most from the call stack */
342 STACK_POP(callStack);
345 /*-----------------------------------------------------------------*/
346 /* userBpCB - call back function for user break points */
347 /*-----------------------------------------------------------------*/
348 BP_CALLBACK(userBpCB)
350 Dprintf(D_break, ("break: userBpCB: BP_CALLBACK entry\n"));
352 if (srcMode == SRC_CMODE) {
353 fprintf(stdout,"Breakpoint %d, %s() at %s:%d\n",
355 ctxt->func->sym->name,
356 ctxt->func->mod->c_name,
358 if (ctxt->func->mod && ctxt->cline > 0)
359 fprintf(stdout,"%d\t%s",ctxt->cline+1,
360 ctxt->func->mod->cLines[ctxt->cline]->src);
362 fprintf(stdout,"Breakpoint %d, %s() at %s:%d\n",
364 ctxt->func->sym->name,
365 ctxt->func->mod->asm_name,
367 if (ctxt->func->mod && ctxt->asmline > 0)
368 fprintf(stdout,"%d\t%s",ctxt->asmline+1,
369 ctxt->func->mod->asmLines[ctxt->asmline]->src);
375 /*-----------------------------------------------------------------*/
376 /* stepBpCB - call back function for step break points */
377 /*-----------------------------------------------------------------*/
378 BP_CALLBACK(stepBpCB)
380 static function *lfunc = NULL;
382 Dprintf(D_break, ("break: stepBpCB: BP_CALLBACK entry\n"));
384 if (srcMode == SRC_CMODE) {
385 if ((lfunc && lfunc != ctxt->func) || !lfunc)
386 fprintf(stdout,"%s () at %s:%d\n",
387 ctxt->func->sym->name,
388 ctxt->func->mod->c_name,
391 if (ctxt->func->mod && ctxt->cline > 0) {
392 fprintf(stdout,"%d\t%s",ctxt->cline+1 ,
393 ctxt->func->mod->cLines[ctxt->cline]->src);
396 if ((lfunc && lfunc != ctxt->func) || !lfunc)
397 fprintf(stdout,"%s () at %s:%d\n",
398 ctxt->func->sym->name,
399 ctxt->func->mod->asm_name,
402 if (ctxt->func->mod && ctxt->cline > 0) {
403 fprintf(stdout,"%d\t%s",ctxt->asmline ,
404 ctxt->func->mod->asmLines[ctxt->asmline]->src);
413 /*-----------------------------------------------------------------*/
414 /* nextBpCB - call back function for next break points */
415 /*-----------------------------------------------------------------*/
416 BP_CALLBACK(nextBpCB)
418 static function *lfunc = NULL;
420 Dprintf(D_break, ("break: nextBpCB: BP_CALLBACK entry\n"));
422 if (srcMode == SRC_CMODE) {
423 if ((lfunc && lfunc != ctxt->func) || !lfunc)
424 fprintf(stdout,"%s () at %s:%d\n",
425 ctxt->func->sym->name,
426 ctxt->func->mod->c_name,
429 if (ctxt->func->mod && ctxt->cline > 0)
430 fprintf(stdout,"%d\t%s",ctxt->cline+1,
431 ctxt->func->mod->cLines[ctxt->cline]->src);
433 if ((lfunc && lfunc != ctxt->func) || !lfunc)
434 fprintf(stdout,"%s () at %s:%d\n",
435 ctxt->func->sym->name,
436 ctxt->func->mod->asm_name,
439 if (ctxt->func->mod && ctxt->asmline > 0)
440 fprintf(stdout,"%d\t%s",ctxt->asmline,
441 ctxt->func->mod->asmLines[ctxt->asmline]->src);