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 return simStopBPCB(addr);
301 /* dispatch the call back functions */
302 for (; bp; bp = hTabNextItemWK(bptable)) {
304 rv += (*bp->callBack)(addr,bp->addrType,
305 bp->bpType,bp->bpnum,ctxt);
310 Dprintf(D_break, ("break: dispatchCB: WARNING rv==0\n", rv));
316 /*-----------------------------------------------------------------*/
317 /* fentryCB - callback function for function entry */
318 /*-----------------------------------------------------------------*/
319 BP_CALLBACK(fentryCB)
321 Dprintf(D_break, ("break: fentryCB: BP_CALLBACK entry\n"));
323 /* add the current function into the call stack */
324 STACK_PUSH(callStack,ctxt->func);
326 /* will have to add code here to get the value of SP
327 which will be used to display the value of local variables
328 and parameters on the stack */
333 /*-----------------------------------------------------------------*/
334 /* fexitCB - call back for function exit */
335 /*-----------------------------------------------------------------*/
338 Dprintf(D_break, ("break: fexitCB: BP_CALLBACK entry\n"));
340 /* pop the top most from the call stack */
341 STACK_POP(callStack);
344 /*-----------------------------------------------------------------*/
345 /* userBpCB - call back function for user break points */
346 /*-----------------------------------------------------------------*/
347 BP_CALLBACK(userBpCB)
349 Dprintf(D_break, ("break: userBpCB: BP_CALLBACK entry\n"));
351 if (srcMode == SRC_CMODE) {
352 fprintf(stdout,"Breakpoint %d, %s() at %s:%d\n",
354 ctxt->func->sym->name,
355 ctxt->func->mod->c_name,
357 if (ctxt->func->mod && ctxt->cline > 0)
358 fprintf(stdout,"%d\t%s",ctxt->cline+1,
359 ctxt->func->mod->cLines[ctxt->cline]->src);
361 fprintf(stdout,"Breakpoint %d, %s() at %s:%d\n",
363 ctxt->func->sym->name,
364 ctxt->func->mod->asm_name,
366 if (ctxt->func->mod && ctxt->asmline > 0)
367 fprintf(stdout,"%d\t%s",ctxt->asmline+1,
368 ctxt->func->mod->asmLines[ctxt->asmline]->src);
374 /*-----------------------------------------------------------------*/
375 /* stepBpCB - call back function for step break points */
376 /*-----------------------------------------------------------------*/
377 BP_CALLBACK(stepBpCB)
379 static function *lfunc = NULL;
381 Dprintf(D_break, ("break: stepBpCB: BP_CALLBACK entry\n"));
383 if (srcMode == SRC_CMODE) {
384 if ((lfunc && lfunc != ctxt->func) || !lfunc)
385 fprintf(stdout,"%s () at %s:%d\n",
386 ctxt->func->sym->name,
387 ctxt->func->mod->c_name,
390 if (ctxt->func->mod && ctxt->cline > 0) {
391 fprintf(stdout,"%d\t%s",ctxt->cline+1 ,
392 ctxt->func->mod->cLines[ctxt->cline]->src);
395 if ((lfunc && lfunc != ctxt->func) || !lfunc)
396 fprintf(stdout,"%s () at %s:%d\n",
397 ctxt->func->sym->name,
398 ctxt->func->mod->asm_name,
401 if (ctxt->func->mod && ctxt->cline > 0) {
402 fprintf(stdout,"%d\t%s",ctxt->asmline ,
403 ctxt->func->mod->asmLines[ctxt->asmline]->src);
412 /*-----------------------------------------------------------------*/
413 /* nextBpCB - call back function for next break points */
414 /*-----------------------------------------------------------------*/
415 BP_CALLBACK(nextBpCB)
417 static function *lfunc = NULL;
419 Dprintf(D_break, ("break: nextBpCB: BP_CALLBACK entry\n"));
421 if (srcMode == SRC_CMODE) {
422 if ((lfunc && lfunc != ctxt->func) || !lfunc)
423 fprintf(stdout,"%s () at %s:%d\n",
424 ctxt->func->sym->name,
425 ctxt->func->mod->c_name,
428 if (ctxt->func->mod && ctxt->cline > 0)
429 fprintf(stdout,"%d\t%s",ctxt->cline+1,
430 ctxt->func->mod->cLines[ctxt->cline]->src);
432 if ((lfunc && lfunc != ctxt->func) || !lfunc)
433 fprintf(stdout,"%s () at %s:%d\n",
434 ctxt->func->sym->name,
435 ctxt->func->mod->asm_name,
438 if (ctxt->func->mod && ctxt->asmline > 0)
439 fprintf(stdout,"%d\t%s",ctxt->asmline,
440 ctxt->func->mod->asmLines[ctxt->asmline]->src);