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;
30 char userBpPresent = 0;
31 /* call stack can be 1024 deep */
32 STACK_DCL(callStack,function *,1024);
35 char *debug_bp_type_strings[] =
47 /*-----------------------------------------------------------------*/
48 /* setBreakPoint - creates an entry in the break point table */
49 /*-----------------------------------------------------------------*/
50 int setBreakPoint (unsigned addr, char addrType, char bpType,
51 int (*callBack)(unsigned,char,char,int,context *) ,
52 char *fileName, int lineno)
55 static long bpnum = 0;
58 Dprintf(D_break, ("setBreakPoint: addr:%x atype:%s bpType:%s [%s:%d]\n",
60 debug_bp_type_strings[addrType],
61 debug_bp_type_strings[bpType],
64 /* allocate & init a new bp */
65 bp = Safe_calloc(1,sizeof(breakp));
67 bp->addrType = addrType;
69 bp->callBack = callBack;
70 bp->bpnum = (bpType == USER ? ++bpnum : 0);
71 bp->filename = fileName;
74 /* if this is an user break point then
75 check if there already exists one for this address */
77 for ( bpl = hTabFirstItemWK(bptable,addr) ; bpl;
78 bpl = hTabNextItemWK(bptable)) {
80 /* if also a user break point then issue Note : */
81 if (bpl->bpType == USER)
82 fprintf(stderr,"Note: breakpoint %d also set at pc 0x%x\n",
83 bpl->bpnum,bpl->addr);
86 fprintf(stderr,"Breakpoint %d at 0x%x: file %s, line %d.\n",
87 bp->bpnum, addr, fileName, lineno);
92 /* if a break point does not already exist then
93 send command to simulator to add one */
94 if (!hTabSearch(bptable,addr))
95 /* send the break command to the simulator */
99 /* now add the break point to list */
100 hTabAddItem(&bptable,addr,bp);
105 /*-----------------------------------------------------------------*/
106 /* deleteSTEPbp - deletes all step break points */
107 /*-----------------------------------------------------------------*/
113 Dprintf(D_break, ("Deleting all STEP BPs\n"));
114 /* for break points delete if they are STEP */
115 for ( bp = hTabFirstItem(bptable,&k); bp ;
116 bp = hTabNextItem(bptable,&k)) {
118 /* if this is a step then delete */
119 if (bp->bpType == STEP) {
120 hTabDeleteItem(&bptable,bp->addr,bp,DELETE_ITEM,NULL);
122 /* if this leaves no other break points then
123 send command to simulator to delete bp from this addr */
124 if (hTabSearch(bptable,bp->addr) == NULL)
125 simClearBP (bp->addr);
133 /*-----------------------------------------------------------------*/
134 /* deleteNEXTbp - deletes all step break points */
135 /*-----------------------------------------------------------------*/
142 Dprintf(D_break, ("Deleting all NEXT BPs\n"));
144 /* for break points delete if they are NEXT */
145 for ( bp = hTabFirstItem(bptable,&k); bp ;
146 bp = hTabNextItem(bptable,&k)) {
148 /* if this is a step then delete */
149 if (bp->bpType == NEXT) {
150 hTabDeleteItem(&bptable,bp->addr,bp,DELETE_ITEM,NULL);
152 /* if this leaves no other break points then
153 send command to simulator to delete bp from this addr */
154 if (hTabSearch(bptable,bp->addr) == NULL) {
155 simClearBP(bp->addr);
165 /*-----------------------------------------------------------------*/
166 /* deleteUSERbp - deletes USER break point with number */
167 /*-----------------------------------------------------------------*/
168 void deleteUSERbp (int bpnum)
174 Dprintf(D_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->bpnum == bpnum || bpnum == -1)) {
184 hTabDeleteItem(&bptable,bp->addr,bp,DELETE_ITEM,NULL);
186 /* if this leaves no other break points then
187 send command to simulator to delete bp from this addr */
188 if (hTabSearch(bptable,bp->addr) == NULL) {
189 simClearBP (bp->addr);
190 Dprintf(D_break, ("deleteUSERbp:simClearBP 0x%x\n", bp->addr));
193 fprintf(stdout,"Deleted breakpoint %d\n",
203 if (!bp && bpnum != -1)
204 fprintf(stderr,"No breakpoint number %d.\n",bpnum);
207 /*-----------------------------------------------------------------*/
208 /* listUSERbp - list all user break points */
209 /*-----------------------------------------------------------------*/
215 /* if there are none then say so & return */
216 if (!userBpPresent) {
217 fprintf(stdout,"No breakpoints.\n");
220 fprintf(stdout,"Num Address What\n");
221 for ( bp = hTabFirstItem(bptable,&k) ; bp ;
222 bp = hTabNextItem(bptable,&k)) {
224 if (bp->bpType == USER ) {
225 fprintf(stdout,"%-3d 0x%04x at %s:%d\n",
227 bp->filename,bp->lineno);
233 /*-----------------------------------------------------------------*/
234 /* simStopBPCB - simulator stopped break point */
235 /*-----------------------------------------------------------------*/
236 static int simStopBPCB( unsigned int addr)
238 fprintf(stdout,"Simulator stopped at Address 0x%04x\n",addr);
239 fprintf(stdout,"%s",simResponse());
243 /*-----------------------------------------------------------------*/
244 /* clearUSERbp - deletes USER break point at address */
245 /*-----------------------------------------------------------------*/
246 void clearUSERbp ( unsigned int addr )
251 /* for break points delete if they are STEP */
252 for ( bp = hTabFirstItemWK(bptable,addr); bp ;
253 bp = hTabNextItemWK(bptable)) {
255 /* if this is a step then delete */
256 if (bp->bpType == USER) {
257 hTabDeleteItem(&bptable,bp->addr,bp,DELETE_ITEM,NULL);
259 /* if this leaves no other break points then
260 send command to simulator to delete bp from this addr */
261 if (hTabSearch(bptable,bp->addr) == NULL) {
262 simClearBP(bp->addr);
265 fprintf(stdout,"Deleted breakpoint %d\n",
273 fprintf(stderr,"No breakpoint at address 0x%x.\n",addr);
276 /*-----------------------------------------------------------------*/
277 /* dispatchCB - will lookup the bp table and dispatch the cb funcs */
278 /*-----------------------------------------------------------------*/
279 int dispatchCB (unsigned addr, context *ctxt)
284 Dprintf(D_break, ("dispatchCB: addr:0x%x \n", addr));
286 /* if no break points set for this address
287 then use a simulator stop break point */
288 if ((bp = hTabFirstItemWK(bptable,addr)) == NULL) {
289 return simStopBPCB(addr);
292 /* dispatch the call back functions */
293 for (; bp; bp = hTabNextItemWK(bptable)) {
295 rv += (*bp->callBack)(addr,bp->addrType,
296 bp->bpType,bp->bpnum,ctxt);
301 Dprintf(D_break, ("dispatchCB: WARNING rv==0\n", rv));
307 /*-----------------------------------------------------------------*/
308 /* fentryCB - callback function for function entry */
309 /*-----------------------------------------------------------------*/
310 BP_CALLBACK(fentryCB)
312 Dprintf(D_break, ("fentryCB: BP_CALLBACK entry\n"));
314 /* add the current function into the call stack */
315 STACK_PUSH(callStack,ctxt->func);
317 /* will have to add code here to get the value of SP
318 which will be used to display the value of local variables
319 and parameters on the stack */
324 /*-----------------------------------------------------------------*/
325 /* fexitCB - call back for function exit */
326 /*-----------------------------------------------------------------*/
329 Dprintf(D_break, ("fexitCB: BP_CALLBACK entry\n"));
331 /* pop the top most from the call stack */
332 STACK_POP(callStack);
335 /*-----------------------------------------------------------------*/
336 /* userBpCB - call back function for user break points */
337 /*-----------------------------------------------------------------*/
338 BP_CALLBACK(userBpCB)
340 Dprintf(D_break, ("userBpCB: BP_CALLBACK entry\n"));
342 if (srcMode == SRC_CMODE) {
343 fprintf(stdout,"Breakpoint %d, %s() at %s:%d\n",
345 ctxt->func->sym->name,
346 ctxt->func->mod->c_name,
348 if (ctxt->func->mod && ctxt->cline > 0)
349 fprintf(stdout,"%d\t%s",ctxt->cline,
350 ctxt->func->mod->cLines[ctxt->cline]->src);
352 fprintf(stdout,"Breakpoint %d, %s() at %s:%d\n",
354 ctxt->func->sym->name,
355 ctxt->func->mod->asm_name,
357 if (ctxt->func->mod && ctxt->asmline > 0)
358 fprintf(stdout,"%d\t%s",ctxt->asmline,
359 ctxt->func->mod->asmLines[ctxt->asmline]->src);
365 /*-----------------------------------------------------------------*/
366 /* stepBpCB - call back function for step break points */
367 /*-----------------------------------------------------------------*/
368 BP_CALLBACK(stepBpCB)
370 static function *lfunc = NULL;
372 Dprintf(D_break, ("stepBpCB: BP_CALLBACK entry\n"));
374 if (srcMode == SRC_CMODE) {
375 if ((lfunc && lfunc != ctxt->func) || !lfunc)
376 fprintf(stdout,"%s () at %s:%d\n",
377 ctxt->func->sym->name,
378 ctxt->func->mod->c_name,
381 if (ctxt->func->mod && ctxt->cline > 0) {
382 fprintf(stdout,"%d\t%s",ctxt->cline ,
383 ctxt->func->mod->cLines[ctxt->cline]->src);
386 if ((lfunc && lfunc != ctxt->func) || !lfunc)
387 fprintf(stdout,"%s () at %s:%d\n",
388 ctxt->func->sym->name,
389 ctxt->func->mod->asm_name,
392 if (ctxt->func->mod && ctxt->cline > 0) {
393 fprintf(stdout,"%d\t%s",ctxt->asmline ,
394 ctxt->func->mod->asmLines[ctxt->asmline]->src);
403 /*-----------------------------------------------------------------*/
404 /* nextBpCB - call back function for next break points */
405 /*-----------------------------------------------------------------*/
406 BP_CALLBACK(nextBpCB)
408 static function *lfunc = NULL;
410 Dprintf(D_break, ("nextBpCB: BP_CALLBACK entry\n"));
412 if (srcMode == SRC_CMODE) {
413 if ((lfunc && lfunc != ctxt->func) || !lfunc)
414 fprintf(stdout,"%s () at %s:%d\n",
415 ctxt->func->sym->name,
416 ctxt->func->mod->c_name,
419 if (ctxt->func->mod && ctxt->cline > 0)
420 fprintf(stdout,"%d\t%s",ctxt->cline,
421 ctxt->func->mod->cLines[ctxt->cline]->src);
423 if ((lfunc && lfunc != ctxt->func) || !lfunc)
424 fprintf(stdout,"%s () at %s:%d\n",
425 ctxt->func->sym->name,
426 ctxt->func->mod->asm_name,
429 if (ctxt->func->mod && ctxt->asmline > 0)
430 fprintf(stdout,"%d\t%s",ctxt->asmline,
431 ctxt->func->mod->asmLines[ctxt->asmline]->src);