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 -------------------------------------------------------------------------*/
28 static hTab *bptable = NULL;
29 char userBpPresent = 0;
30 /* call stack can be 1024 deep */
31 STACK_DCL(callStack,function *,1024);
33 /*-----------------------------------------------------------------*/
34 /* setBreakPoint - creates an entry in the break point table */
35 /*-----------------------------------------------------------------*/
36 int setBreakPoint (unsigned addr, char addrType, char bpType,
37 int (*callBack)(unsigned,char,char,int,context *) ,
38 char *fileName, int lineno)
41 static long bpnum = 0;
44 /* allocate & init a new bp */
45 Safe_calloc(1,bp,sizeof(breakp));
47 bp->addrType = addrType;
49 bp->callBack = callBack;
50 bp->bpnum = (bpType == USER ? ++bpnum : 0);
51 bp->filename = fileName;
54 /* if this is an user break point then
55 check if there already exists one for this address */
57 for ( bpl = hTabFirstItemWK(bptable,addr) ; bpl;
58 bpl = hTabNextItemWK(bptable)) {
60 /* if also a user break point then issue Note : */
61 if (bpl->bpType == USER)
62 fprintf(stderr,"Note: breakpoint %d also set at pc 0x%x\n",
63 bpl->bpnum,bpl->addr);
66 fprintf(stderr,"Breakpoint %d at 0x%x: file %s, line %d.\n",
67 bp->bpnum, addr, fileName, lineno);
72 /* if a break point does not already exist then
73 send command to simulator to add one */
74 if (!hTabSearch(bptable,addr))
75 /* send the break command to the simulator */
79 /* now add the break point to list */
80 hTabAddItem(&bptable,addr,bp);
85 /*-----------------------------------------------------------------*/
86 /* deleteSTEPbp - deletes all step break points */
87 /*-----------------------------------------------------------------*/
93 /* for break points delete if they are STEP */
94 for ( bp = hTabFirstItem(bptable,&k); bp ;
95 bp = hTabNextItem(bptable,&k)) {
97 /* if this is a step then delete */
98 if (bp->bpType == STEP) {
99 hTabDeleteItem(&bptable,bp->addr,bp,DELETE_ITEM,NULL);
101 /* if this leaves no other break points then
102 send command to simulator to delete bp from this addr */
103 if (hTabSearch(bptable,bp->addr) == NULL)
104 simClearBP (bp->addr);
112 /*-----------------------------------------------------------------*/
113 /* deleteNEXTbp - deletes all step break points */
114 /*-----------------------------------------------------------------*/
121 /* for break points delete if they are NEXT */
122 for ( bp = hTabFirstItem(bptable,&k); bp ;
123 bp = hTabNextItem(bptable,&k)) {
125 /* if this is a step then delete */
126 if (bp->bpType == NEXT) {
127 hTabDeleteItem(&bptable,bp->addr,bp,DELETE_ITEM,NULL);
129 /* if this leaves no other break points then
130 send command to simulator to delete bp from this addr */
131 if (hTabSearch(bptable,bp->addr) == NULL) {
132 simClearBP(bp->addr);
142 /*-----------------------------------------------------------------*/
143 /* deleteUSERbp - deletes USER break point with number */
144 /*-----------------------------------------------------------------*/
145 void deleteUSERbp (int bpnum)
151 /* for break points delete if they are STEP */
152 for ( bp = hTabFirstItem(bptable,&k); bp ;
153 bp = hTabNextItem(bptable,&k)) {
155 /* if this is a user then delete if break
156 point matches or bpnumber == -1 (meaning delete
157 all user break points */
158 if (bp->bpType == USER && ( bp->bpnum == bpnum || bpnum == -1)) {
159 hTabDeleteItem(&bptable,bp->addr,bp,DELETE_ITEM,NULL);
161 /* if this leaves no other break points then
162 send command to simulator to delete bp from this addr */
163 if (hTabSearch(bptable,bp->addr) == NULL) {
164 simClearBP (bp->addr);
167 fprintf(stdout,"Deleted breakpoint %d\n",
177 if (!bp && bpnum != -1)
178 fprintf(stderr,"No breakpoint number %d.\n",bpnum);
181 /*-----------------------------------------------------------------*/
182 /* listUSERbp - list all user break points */
183 /*-----------------------------------------------------------------*/
189 /* if there are none then say so & return */
190 if (!userBpPresent) {
191 fprintf(stdout,"No breakpoints.\n");
194 fprintf(stdout,"Num Address What\n");
195 for ( bp = hTabFirstItem(bptable,&k) ; bp ;
196 bp = hTabNextItem(bptable,&k)) {
198 if (bp->bpType == USER ) {
199 fprintf(stdout,"%-3d 0x%04x at %s:%d\n",
201 bp->filename,bp->lineno);
207 /*-----------------------------------------------------------------*/
208 /* simStopBPCB - simulator stopped break point */
209 /*-----------------------------------------------------------------*/
210 static int simStopBPCB( unsigned int addr)
212 fprintf(stdout,"Simulator stopped at Address 0x%04x\n",addr);
213 fprintf(stdout,"%s",simResponse());
217 /*-----------------------------------------------------------------*/
218 /* clearUSERbp - deletes USER break point at address */
219 /*-----------------------------------------------------------------*/
220 void clearUSERbp ( unsigned int addr )
225 /* for break points delete if they are STEP */
226 for ( bp = hTabFirstItemWK(bptable,addr); bp ;
227 bp = hTabNextItemWK(bptable)) {
229 /* if this is a step then delete */
230 if (bp->bpType == USER) {
231 hTabDeleteItem(&bptable,bp->addr,bp,DELETE_ITEM,NULL);
233 /* if this leaves no other break points then
234 send command to simulator to delete bp from this addr */
235 if (hTabSearch(bptable,bp->addr) == NULL) {
236 simClearBP(bp->addr);
239 fprintf(stdout,"Deleted breakpoint %d\n",
247 fprintf(stderr,"No breakpoint at address 0x%x.\n",addr);
250 /*-----------------------------------------------------------------*/
251 /* dispatchCB - will lookup the bp table and dispatch the cb funcs */
252 /*-----------------------------------------------------------------*/
253 int dispatchCB (unsigned addr, context *ctxt)
258 /* if no break points set for this address
259 then use a simulator stop break point */
260 if ((bp = hTabFirstItemWK(bptable,addr)) == NULL) {
261 return simStopBPCB(addr);
264 /* dispatch the call back functions */
265 for (; bp; bp = hTabNextItemWK(bptable)) {
267 rv += (*bp->callBack)(addr,bp->addrType,
268 bp->bpType,bp->bpnum,ctxt);
275 /*-----------------------------------------------------------------*/
276 /* fentryCB - callback function for function entry */
277 /*-----------------------------------------------------------------*/
278 BP_CALLBACK(fentryCB)
280 /* add the current function into the call stack */
281 STACK_PUSH(callStack,ctxt->func);
283 /* will have to add code here to get the value of SP
284 which will be used to display the value of local variables
285 and parameters on the stack */
290 /*-----------------------------------------------------------------*/
291 /* fexitCB - call back for function exit */
292 /*-----------------------------------------------------------------*/
295 /* pop the top most from the call stack */
296 STACK_POP(callStack);
299 /*-----------------------------------------------------------------*/
300 /* userBpCB - call back function for user break points */
301 /*-----------------------------------------------------------------*/
302 BP_CALLBACK(userBpCB)
304 if (srcMode == SRC_CMODE) {
305 fprintf(stdout,"Breakpoint %d, %s() at %s:%d\n",
307 ctxt->func->sym->name,
308 ctxt->func->mod->c_name,
310 if (ctxt->func->mod && ctxt->cline > 0)
311 fprintf(stdout,"%d\t%s",ctxt->cline,
312 ctxt->func->mod->cLines[ctxt->cline]->src);
314 fprintf(stdout,"Breakpoint %d, %s() at %s:%d\n",
316 ctxt->func->sym->name,
317 ctxt->func->mod->asm_name,
319 if (ctxt->func->mod && ctxt->asmline > 0)
320 fprintf(stdout,"%d\t%s",ctxt->asmline,
321 ctxt->func->mod->asmLines[ctxt->asmline]->src);
327 /*-----------------------------------------------------------------*/
328 /* stepBpCB - call back function for step break points */
329 /*-----------------------------------------------------------------*/
330 BP_CALLBACK(stepBpCB)
332 static function *lfunc = NULL;
334 if (srcMode == SRC_CMODE) {
335 if ((lfunc && lfunc != ctxt->func) || !lfunc)
336 fprintf(stdout,"%s () at %s:%d\n",
337 ctxt->func->sym->name,
338 ctxt->func->mod->c_name,
341 if (ctxt->func->mod && ctxt->cline > 0) {
342 fprintf(stdout,"%d\t%s",ctxt->cline ,
343 ctxt->func->mod->cLines[ctxt->cline]->src);
346 if ((lfunc && lfunc != ctxt->func) || !lfunc)
347 fprintf(stdout,"%s () at %s:%d\n",
348 ctxt->func->sym->name,
349 ctxt->func->mod->asm_name,
352 if (ctxt->func->mod && ctxt->cline > 0) {
353 fprintf(stdout,"%d\t%s",ctxt->asmline ,
354 ctxt->func->mod->asmLines[ctxt->asmline]->src);
363 /*-----------------------------------------------------------------*/
364 /* nextBpCB - call back function for next break points */
365 /*-----------------------------------------------------------------*/
366 BP_CALLBACK(nextBpCB)
368 static function *lfunc = NULL;
370 if (srcMode == SRC_CMODE) {
371 if ((lfunc && lfunc != ctxt->func) || !lfunc)
372 fprintf(stdout,"%s () at %s:%d\n",
373 ctxt->func->sym->name,
374 ctxt->func->mod->c_name,
377 if (ctxt->func->mod && ctxt->cline > 0)
378 fprintf(stdout,"%d\t%s",ctxt->cline,
379 ctxt->func->mod->cLines[ctxt->cline]->src);
381 if ((lfunc && lfunc != ctxt->func) || !lfunc)
382 fprintf(stdout,"%s () at %s:%d\n",
383 ctxt->func->sym->name,
384 ctxt->func->mod->asm_name,
387 if (ctxt->func->mod && ctxt->asmline > 0)
388 fprintf(stdout,"%d\t%s",ctxt->asmline,
389 ctxt->func->mod->asmLines[ctxt->asmline]->src);