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);
34 /*-----------------------------------------------------------------*/
35 /* setBreakPoint - creates an entry in the break point table */
36 /*-----------------------------------------------------------------*/
37 int setBreakPoint (unsigned addr, char addrType, char bpType,
38 int (*callBack)(unsigned,char,char,int,context *) ,
39 char *fileName, int lineno)
42 static long bpnum = 0;
45 /* allocate & init a new bp */
46 bp = Safe_calloc(1,sizeof(breakp));
48 bp->addrType = addrType;
50 bp->callBack = callBack;
51 bp->bpnum = (bpType == USER ? ++bpnum : 0);
52 bp->filename = fileName;
55 /* if this is an user break point then
56 check if there already exists one for this address */
58 for ( bpl = hTabFirstItemWK(bptable,addr) ; bpl;
59 bpl = hTabNextItemWK(bptable)) {
61 /* if also a user break point then issue Note : */
62 if (bpl->bpType == USER)
63 fprintf(stderr,"Note: breakpoint %d also set at pc 0x%x\n",
64 bpl->bpnum,bpl->addr);
67 fprintf(stderr,"Breakpoint %d at 0x%x: file %s, line %d.\n",
68 bp->bpnum, addr, fileName, lineno);
73 /* if a break point does not already exist then
74 send command to simulator to add one */
75 if (!hTabSearch(bptable,addr))
76 /* send the break command to the simulator */
80 /* now add the break point to list */
81 hTabAddItem(&bptable,addr,bp);
86 /*-----------------------------------------------------------------*/
87 /* deleteSTEPbp - deletes all step break points */
88 /*-----------------------------------------------------------------*/
94 /* for break points delete if they are STEP */
95 for ( bp = hTabFirstItem(bptable,&k); bp ;
96 bp = hTabNextItem(bptable,&k)) {
98 /* if this is a step then delete */
99 if (bp->bpType == STEP) {
100 hTabDeleteItem(&bptable,bp->addr,bp,DELETE_ITEM,NULL);
102 /* if this leaves no other break points then
103 send command to simulator to delete bp from this addr */
104 if (hTabSearch(bptable,bp->addr) == NULL)
105 simClearBP (bp->addr);
113 /*-----------------------------------------------------------------*/
114 /* deleteNEXTbp - deletes all step break points */
115 /*-----------------------------------------------------------------*/
122 /* for break points delete if they are NEXT */
123 for ( bp = hTabFirstItem(bptable,&k); bp ;
124 bp = hTabNextItem(bptable,&k)) {
126 /* if this is a step then delete */
127 if (bp->bpType == NEXT) {
128 hTabDeleteItem(&bptable,bp->addr,bp,DELETE_ITEM,NULL);
130 /* if this leaves no other break points then
131 send command to simulator to delete bp from this addr */
132 if (hTabSearch(bptable,bp->addr) == NULL) {
133 simClearBP(bp->addr);
143 /*-----------------------------------------------------------------*/
144 /* deleteUSERbp - deletes USER break point with number */
145 /*-----------------------------------------------------------------*/
146 void deleteUSERbp (int bpnum)
152 /* for break points delete if they are STEP */
153 for ( bp = hTabFirstItem(bptable,&k); bp ;
154 bp = hTabNextItem(bptable,&k)) {
156 /* if this is a user then delete if break
157 point matches or bpnumber == -1 (meaning delete
158 all user break points */
159 if (bp->bpType == USER && ( bp->bpnum == bpnum || bpnum == -1)) {
160 hTabDeleteItem(&bptable,bp->addr,bp,DELETE_ITEM,NULL);
162 /* if this leaves no other break points then
163 send command to simulator to delete bp from this addr */
164 if (hTabSearch(bptable,bp->addr) == NULL) {
165 simClearBP (bp->addr);
168 fprintf(stdout,"Deleted breakpoint %d\n",
178 if (!bp && bpnum != -1)
179 fprintf(stderr,"No breakpoint number %d.\n",bpnum);
182 /*-----------------------------------------------------------------*/
183 /* listUSERbp - list all user break points */
184 /*-----------------------------------------------------------------*/
190 /* if there are none then say so & return */
191 if (!userBpPresent) {
192 fprintf(stdout,"No breakpoints.\n");
195 fprintf(stdout,"Num Address What\n");
196 for ( bp = hTabFirstItem(bptable,&k) ; bp ;
197 bp = hTabNextItem(bptable,&k)) {
199 if (bp->bpType == USER ) {
200 fprintf(stdout,"%-3d 0x%04x at %s:%d\n",
202 bp->filename,bp->lineno);
208 /*-----------------------------------------------------------------*/
209 /* simStopBPCB - simulator stopped break point */
210 /*-----------------------------------------------------------------*/
211 static int simStopBPCB( unsigned int addr)
213 fprintf(stdout,"Simulator stopped at Address 0x%04x\n",addr);
214 fprintf(stdout,"%s",simResponse());
218 /*-----------------------------------------------------------------*/
219 /* clearUSERbp - deletes USER break point at address */
220 /*-----------------------------------------------------------------*/
221 void clearUSERbp ( unsigned int addr )
226 /* for break points delete if they are STEP */
227 for ( bp = hTabFirstItemWK(bptable,addr); bp ;
228 bp = hTabNextItemWK(bptable)) {
230 /* if this is a step then delete */
231 if (bp->bpType == USER) {
232 hTabDeleteItem(&bptable,bp->addr,bp,DELETE_ITEM,NULL);
234 /* if this leaves no other break points then
235 send command to simulator to delete bp from this addr */
236 if (hTabSearch(bptable,bp->addr) == NULL) {
237 simClearBP(bp->addr);
240 fprintf(stdout,"Deleted breakpoint %d\n",
248 fprintf(stderr,"No breakpoint at address 0x%x.\n",addr);
251 /*-----------------------------------------------------------------*/
252 /* dispatchCB - will lookup the bp table and dispatch the cb funcs */
253 /*-----------------------------------------------------------------*/
254 int dispatchCB (unsigned addr, context *ctxt)
259 /* if no break points set for this address
260 then use a simulator stop break point */
261 if ((bp = hTabFirstItemWK(bptable,addr)) == NULL) {
262 return simStopBPCB(addr);
265 /* dispatch the call back functions */
266 for (; bp; bp = hTabNextItemWK(bptable)) {
268 rv += (*bp->callBack)(addr,bp->addrType,
269 bp->bpType,bp->bpnum,ctxt);
276 /*-----------------------------------------------------------------*/
277 /* fentryCB - callback function for function entry */
278 /*-----------------------------------------------------------------*/
279 BP_CALLBACK(fentryCB)
281 /* add the current function into the call stack */
282 STACK_PUSH(callStack,ctxt->func);
284 /* will have to add code here to get the value of SP
285 which will be used to display the value of local variables
286 and parameters on the stack */
291 /*-----------------------------------------------------------------*/
292 /* fexitCB - call back for function exit */
293 /*-----------------------------------------------------------------*/
296 /* pop the top most from the call stack */
297 STACK_POP(callStack);
300 /*-----------------------------------------------------------------*/
301 /* userBpCB - call back function for user break points */
302 /*-----------------------------------------------------------------*/
303 BP_CALLBACK(userBpCB)
305 if (srcMode == SRC_CMODE) {
306 fprintf(stdout,"Breakpoint %d, %s() at %s:%d\n",
308 ctxt->func->sym->name,
309 ctxt->func->mod->c_name,
311 if (ctxt->func->mod && ctxt->cline > 0)
312 fprintf(stdout,"%d\t%s",ctxt->cline,
313 ctxt->func->mod->cLines[ctxt->cline]->src);
315 fprintf(stdout,"Breakpoint %d, %s() at %s:%d\n",
317 ctxt->func->sym->name,
318 ctxt->func->mod->asm_name,
320 if (ctxt->func->mod && ctxt->asmline > 0)
321 fprintf(stdout,"%d\t%s",ctxt->asmline,
322 ctxt->func->mod->asmLines[ctxt->asmline]->src);
328 /*-----------------------------------------------------------------*/
329 /* stepBpCB - call back function for step break points */
330 /*-----------------------------------------------------------------*/
331 BP_CALLBACK(stepBpCB)
333 static function *lfunc = NULL;
335 if (srcMode == SRC_CMODE) {
336 if ((lfunc && lfunc != ctxt->func) || !lfunc)
337 fprintf(stdout,"%s () at %s:%d\n",
338 ctxt->func->sym->name,
339 ctxt->func->mod->c_name,
342 if (ctxt->func->mod && ctxt->cline > 0) {
343 fprintf(stdout,"%d\t%s",ctxt->cline ,
344 ctxt->func->mod->cLines[ctxt->cline]->src);
347 if ((lfunc && lfunc != ctxt->func) || !lfunc)
348 fprintf(stdout,"%s () at %s:%d\n",
349 ctxt->func->sym->name,
350 ctxt->func->mod->asm_name,
353 if (ctxt->func->mod && ctxt->cline > 0) {
354 fprintf(stdout,"%d\t%s",ctxt->asmline ,
355 ctxt->func->mod->asmLines[ctxt->asmline]->src);
364 /*-----------------------------------------------------------------*/
365 /* nextBpCB - call back function for next break points */
366 /*-----------------------------------------------------------------*/
367 BP_CALLBACK(nextBpCB)
369 static function *lfunc = NULL;
371 if (srcMode == SRC_CMODE) {
372 if ((lfunc && lfunc != ctxt->func) || !lfunc)
373 fprintf(stdout,"%s () at %s:%d\n",
374 ctxt->func->sym->name,
375 ctxt->func->mod->c_name,
378 if (ctxt->func->mod && ctxt->cline > 0)
379 fprintf(stdout,"%d\t%s",ctxt->cline,
380 ctxt->func->mod->cLines[ctxt->cline]->src);
382 if ((lfunc && lfunc != ctxt->func) || !lfunc)
383 fprintf(stdout,"%s () at %s:%d\n",
384 ctxt->func->sym->name,
385 ctxt->func->mod->asm_name,
388 if (ctxt->func->mod && ctxt->asmline > 0)
389 fprintf(stdout,"%d\t%s",ctxt->asmline,
390 ctxt->func->mod->asmLines[ctxt->asmline]->src);