📄 go.c
字号:
/************************************************************* * File: mon/go.c * Purpose: code for execution control * Author: Phil Bunce (pjb@carmel.com) * Revision History: * 970216 Changed type name Cmd to CmdRec. * 970227 setTrigger: Added cleanup code on setbp error. * 970331 Used BPTYPE_ codes for setbp_target * 970822 Added clrhndlrs() to go. * 980802 Added count=0 to constReduc(). * 981023 cont() updated to support -w for imon95. */#include <stdio.h>#include <string.h>#include <malloc.h>#include <mon.h>#define PREGS /* enable pseudo regs */char clientcmd[LINESZ];extern int clkdat;int bptTmpId = -1;Bps Bpt[MAX_BPT]; /* user break points */int bptCount;#define PCHISTSZ 200unsigned long pchist_d[PCHISTSZ+1];int pchist_ip,pchist_op;WhenRec *when_list,*when_ptr;char *oprs[] = {"&&","||","==","!=",">=","<=",">","<", "+","-","*","/","&","|",0};Optdesc g_opts[] = { {"[-st] [adr [bptadr]] [-c args]","start execution (go)"}, {"-s","don't set client sp"}, {"-t","time execution"}, {"<adr>","start address"}, {"<bptadr>","temporary breakpoint"}, {"-c <args>","args to be passed to client"}, {0}};Optdesc t_opts[] = { {"[-v] [cnt]","trace (single-step)"}, {"-v","verbose, list each step"}, {"<cnt>","execute <cnt> instructions"}, {0}};Optdesc to_opts[] = { {"[-v] [cnt]","trace over (single-step)"}, {"-v","verbose, list each step"}, {"<cnt>","execute <cnt> instructions"}, {0}};Optdesc b_opts[] = { {"[[-s cmdstr]brkadr]..","set breakpoint at address"}, {"-s <cmdstr>","execute command string when bpt is encountered"}, {"<brkadr>","stop when PC is <brkadr>"}, {"-d","display detailed break info"}, {"-T","TinyRISC address"}, {0}};Optdesc w_opts[] = { {"<cond> <action>","complex breakpoint"}, {"<cond>","expression defining condition"}, {"<action>","a command string defining the action"}, {0}};Optdesc db_opts[] = { {"[numb|*]..","delete breakpoint"}, {0}};/************************************************************** go(ac,av,info), the 'g' command*/go(ac,av,info)int ac;char *av[];CmdRec *info;{Ulong adr;int i,j,n,flags,tbpt;char *p,tmp[16];n = flags = 0;bptTmpId = -1;strcpy(clientcmd,av[0]);strcat(clientcmd," ");if (!regChain) { printf("Target Description Driver not loaded\n"); return(1); }for (i=1;i<ac;i++) { if (av[i][0] == '-') { for (j=1;av[i][j] != 0;j++) { if (av[i][j] == 's') flags |= T_SP; else if (av[i][j] == 't') clientcmd[0] = 't'; else if (av[i][j] == 'c') { for (i++;i<ac;i++) { strcat(clientcmd,av[i]); strcat(clientcmd," "); } break; } else { printf("%c: unknown option\n",av[i][j]); printf("usage: %s %s\n",info->name,info->opts); return(1); } } } else { if (n == 0) { n++; if(!get_rsa(&adr,av[i])) return(1); if (adr != getPc()) putPc(adr); } else if (n == 1) { n++; if(!get_rsa(&adr,av[i])) return(1); tbpt = setbp_target(-1,BPTYPE_ITMP,adr,0,0); if (tbpt < 0) { printf("error: unable to set bpt\n"); return(1); } tbpt &= 0xff; /* 970520 mask out warnings */ } else { if (tbpt != -1) clrbp_target(tbpt); printf("Too many arguments.\n"); printf("usage: %s %s\n",info->name,info->opts); return(1); } } }clrhndlrs(); /* 970822 */swlst(2); /* switch to clilst */run_target(0,flags,clientcmd);}Optdesc c_opts[] = { {"[-w][bptadr]","continue execution"}, {"bptadr","a temporary breakpoint"}, {"-w","Don't wait (imon95 and imon only)"}, {0}};/************************************************************** cont(ac,av,info) * The continue command* 981023 Updated to support -w for imon95.*/cont(ac,av,info)int ac;char *av[];CmdRec *info;{Ulong adr;char *p,tmp[16];int i,n,tbpt,flags;if (!regChain) { printf("Target Description Driver not loaded\n"); return(1); }n = flags = 0;for (i=1;i<ac;i++) { if (strequ(av[i],"-w")) flags |= T_W; else if (n==0) { if(!get_rsa(&adr,av[i])) return(1); n++; } else { printf("Too many arguments.\n"); printf("usage: %s %s\n",info->name,info->opts); return(1); } }bptTmpId = -1;if (n == 1) { tbpt = setbp_target(-1,BPTYPE_ITMP,adr,0,0); if (tbpt < 0) { printf("error: unable to set bpt\n"); return(1); } tbpt &= 0xff; /* 970520 mask out warnings */ }swlst(2); /* switch to clilst */run_target(1,flags);}/************************************************************** setTrigger(char *cond,char *action)* This function sets up a trigger event.* It converts cond from a string to an RPN expression.* It does this by calling parseCond(). parseCond() is* called twice, once to set the when_ptr which indicates* the amount of storage required, and once to generate the actual* expression. The expression is placed in the array pointed* to be when_list. when_list and when_ptr are then saved in the* cond and csz members of a Bps structure. The string that* describes the condition is saved in the member cstr.* The action string (if specified) is placed in the member* cmdstr. The function setbp_target() is called in order to* set the actual breakpoint. Only this target dependent routine* 'knows' how this might best be achieved for a given set of* hardware.* 970227 Added cleanup code on setbp error.*/setTrigger(cond,action)char *cond,*action;{char *p;int j,r;Ulong v;/* find an empty slot */for(j=0;j < MAX_BPT && Bpt[j].cond;j++) ;if(j >= MAX_BPT) { printf("too many breakpoints\n"); return(-1); }when_list = when_ptr = 0;p = strdup(cond);parseCond(p);strcpy(p,cond);when_list = (WhenRec *)malloc((unsigned int)when_ptr);when_ptr = when_list;parseCond(p);free(p);constReduc();Bpt[j].cond = when_list;Bpt[j].csz = when_ptr;Bpt[j].cstr = strdup(cond);if (action) Bpt[j].cmdstr = strdup(action);else Bpt[j].cmdstr = 0;bptCount++;if ((v=pcBpt(Bpt[j].cond,Bpt[j].csz)) != -1) { /* @pc CONST == bpc */ /* @pc CONST == ......... && bpc */ r = setbp_target(j,BPTYPE_PC,v,0,0); /* instr */ }else if ((v=singleDref(Bpt[j].cond,Bpt[j].csz)) != -1) { /* ADDR CONST OPR bda */ /* ADDR CONST OPR ........... && bda */ r = setbp_target(j,0x20|BPTYPE_DATA,v,0,0); /* data */ /* 0x20 is brk on write only */ }else { /* ...................... || nonrt */ r = setbp_target(j,BPTYPE_NONRT,0,0,0); /* nonrt execution */ }if (r >= 0) return(j); /* all ok *//* 970227 error case */Bpt[j].cond = 0;free(Bpt[j].cstr);if (Bpt[j].cmdstr) free(Bpt[j].cmdstr);if (when_list) free(when_list);return(-1);}#if 1/**************************************************************/setHwdbpt(atype,addr,mask)int atype;Ulong addr,mask;{char *p,buf[100];int j;char *cmd = "(@cause&0x3c)==0x1c"; /* look for a DBE exception *//* find an empty slot */for(j=0;j < MAX_BPT && Bpt[j].cond;j++) ;if(j >= MAX_BPT) { printf("too many breakpoints\n"); return(-1); }when_list = when_ptr = 0;p = strdup(cmd);parseCond(p);strcpy(p,cmd);when_list = (WhenRec *)malloc((unsigned int)when_ptr);when_ptr = when_list;parseCond(p);free(p);constReduc();Bpt[j].cond = when_list;Bpt[j].csz = when_ptr;sprintf(buf,"ab -%s%s %08x %08x", (atype&1)?"r":"", (atype&2)?"w":"", addr,mask);Bpt[j].cstr = strdup(buf);Bpt[j].cmdstr = strdup("stop");bptCount++;atype |= 8; /* indicate that addr2 is a mask value */atype <<= 4;if (setbp_target(j,atype|BPTYPE_DATA,addr,mask,0) >= 0) { printf("Bpt%d has been set (%s)\n",j,Bpt[j].cstr); return(j); /* ok */ }/* 970227 error case */printf("Unable to set Bpt%d\n",j);Bpt[j].cond = 0;free(Bpt[j].cstr);if (Bpt[j].cmdstr) free(Bpt[j].cmdstr);if (when_list) free(when_list);return(-1);}Optdesc ab_opts[] = { {"[-rw] addr1 [mask]","set access (data) bpt"}, {"addr1","start address"}, {"mask","address mask"}, {"-r","break on read operations only"}, {"-w","break on write operations only"}, {0}};/**************************************************************/int ab_cmd(ac,av)int ac;char *av[];{int got_addr1,got_mask,mode;Ulong addr1,mask;int i,j,rtn,n;char *cstr;got_addr1 = got_mask = mode = 0;for (i=1;i<ac;i++) { if (av[i][0] == '-') { for (j=1;av[i][j];j++) { if (av[i][j] == 'r') mode |= 1; else if (av[i][j] == 'w') mode |= 2; else { printf("%c: bad option\n",av[i][j]); return(0); } } } else if (!got_addr1) { if (!get_rsa(&addr1,av[i])) return(0); got_addr1 = 1; } else if (!got_mask) { if (!get_rsa(&mask,av[i])) return(0); got_mask = 1; } else { printf("%s: too many args.\n",av[i]); return(0); } }if (!mode) mode = 3;if (!got_addr1) { printf("Requires at least one address.\n"); return(0); }if (!got_mask) mask = 0xffffffff;setHwdbpt(mode,addr1,mask);}#endif/************************************************************** pcBpt(cond,csz)* @pc CONST ==* @pc CONST == ...... &&* If this a PC-only breakpoint, return the bpt addr; else return -1.*/pcBpt(cond,csz)WhenRec *cond,*csz;{if (cond[0].tag == WHEN_REG && strequ(((RegRec *)cond[0].val)->name,"PC") && cond[1].tag == WHEN_CONST && cond[2].tag == WHEN_OPR && cond[2].val == WHEN_OPR_EQ) { if (csz-cond == 3) return(cond[1].val); else if (csz[-1].tag == WHEN_OPR && csz[-1].val == WHEN_OPR_LAND) return(cond[1].val); }return(-1);}/************************************************************** singleDref(cond,csz)* If this a singleDref breakpoint, return the bpt addr; else return -1.*/singleDref(cond,csz)WhenRec *cond,*csz;{if (cond[0].tag == WHEN_CONST && cond[1].tag == WHEN_MEM && cond[2].tag == WHEN_CONST && cond[3].tag == WHEN_OPR) { if (csz-cond == 4) return(cond[0].val); else if (csz[-1].tag == WHEN_OPR && csz[-1].val == WHEN_OPR_LAND) return(cond[0].val); }return(-1);}/************************************************************** when(ac,av,info)* The 'when' (set trigger event) command.*/when(ac,av,info)int ac;char *av[];CmdRec *info;{int j;char tmp[LINESZ];if (!regChain) { printf("Target Description Driver not loaded\n"); return(1); }if (ac != 3) { printf("usage: %s %s\n",info->name,info->opts); return(1); }strnspc(av[1]); /* remove whitespace */j = setTrigger(av[1],av[2]);if (j != -1) { sprintf(prnbuf,"Bpt %2d: when '%s' ",j,Bpt[j].cstr); if (Bpt[j].cmdstr) { sprintf(tmp," \"%s\"",Bpt[j].cmdstr); strcat(prnbuf,tmp); } printf("%s\n",prnbuf); }else printf("Unable to set specified breakpoint.\n");}/************************************************************** trace(ac,av) * The 't' and 'to' (single-step) commands*/trace(ac,av)int ac;char *av[];{int i,j,n,flags,count;Ulong target;unsigned long adr,val;if (!regChain) { printf("Target Description Driver not loaded\n"); return(1); }flags = 0;if (strequ(av[0],"to")) flags |= T_O;n = 0;count = 1;for (i=1;i<ac;i++) { if (av[i][0] == '-') { for (j=1;av[i][j] != 0;j++) { if (av[i][j] == 'v') flags |= (T_V|T_M); else if (av[i][j] == 'b') flags |= T_B; else if (av[i][j] == 'c') flags |= T_C; else if (av[i][j] == 'i') flags |= (T_I|T_M); else { printf("%c: unrecognized option\n",av[i][j]); return(1); } } } else { if (n == 0) { if (!get_rsa(&count,av[i])) return(1); flags |= T_M; } else { printf("%s: unrecognized argument\n",av[i]); return(1); } n++; } }clrpchist();swlst(2); /* switch to clilst */run_target(2,flags,count);}/************************************************************** setbp(ac,av) * The 'b' (set breakpoint) command.* Set one or more breakpoint(s).* When invoked without args, this command displays a list* of all breakpoints currently set.*/setbp(ac,av)int ac;char *av[];{Ulong adr,msk,i,j,w;char *str,*p,tmp[LINESZ];int Tflag;int flag = 0;if (!regChain) { printf("Target Description Driver not loaded\n"); return(1); }if(ac == 1) { dspbpts(); return(0); }w = 0; str = 0; Tflag = 0;for(i=1;i<ac;i++) { if (av[i][0] == '-') { if (av[i][1] == 's') { i++; if (i >= ac) { printf("bad arg count\n"); return(1); } str = av[i]; } else if (av[i][1] == 'T') Tflag = 1; else if (av[i][1] == 'd') { for (j=0;j<MAX_BPT;j++) { if (Bpt[j].cond==0) continue; printf("Bpt %d:\n",j); printOps(Bpt[j].cond,Bpt[j].csz); } return(0); } else { printf("%s: unrecognized option\n",av[i]); return(1); } } else { flag = 1; if(!get_rsa(&adr,av[i])) return(1); if (!str) str = "stop"; if (Tflag) adr |= 1; /* set LSB */ sprintf(tmp,"@pc==0x%08x",adr); j = setTrigger(tmp,str); if (j != -1) { sprintf(prnbuf,"Bpt %2d: when (%s) ",j,Bpt[j].cstr); if (Bpt[j].cmdstr) { sprintf(tmp," \"%s\"",Bpt[j].cmdstr); strcat(prnbuf,tmp); } printf("%s\n",prnbuf); } else printf("Unable to set specified breakpoint.\n"); } }if (!flag) printf("break address not specified\n");return(0);}/************************************************************** int getBpid(void)* Returns the breakpoint id of a breakpoint that requests a stop* or -1 if none.*/getBpid(){int i,j,n;char *p;n = -1;for (i=0;i<MAX_BPT;i++) { if (Bpt[i].cond == 0) continue; if (evalBpt(Bpt[i].cond,Bpt[i].csz)) { p = strdup(Bpt[i].cmdstr); printf("brkpt %d \"%s\"\n",i,p); if (do_cmd(p)) { if (n == -1) n = i; } free(p); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -