⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cli.c

📁 mips架构的bootloader,99左右的版本 但源代码现在没人更新了
💻 C
字号:
/************************************************************* * File: mon/cli.c * Purpose: Command line interface for MON * Author: Phil Bunce (pjb@carmel.com) * Revision History: *	970216	Start of revision history *	970216	Switched over to using addCmdRec() *	970303	trace_mode removed. *	970409	Switched over to using addEnvRec() *	971007	Removed %s from printf on break in gotintr *	980420	Added ifndef around flush_target for NON_CACHED build *	980602	Added shrc_needed to delay execution of shrc cmds. *	980715	Added arg to shrc() call. *	980717	Always flush D then I for copyback D caches. *	980725	Added compare command. */#include <setjmp.h>#include <signal.h>#include <string.h>#include <mon.h>#include <termio.h>#include <stdio.h>#define PREGS		/* enable pseudo regs */jmp_buf intrbuf;int xvwmode;             /* crossview mode */int noecho;char prnbuf[LINESZ];char line[LINESZ];CmdRec *cmdChain;extern int clilst,*curlst;extern int shrc_needed;int gotintr();char *badhexsym = "%s: neither hex value nor symbol\n";Optdesc sh_opts[] = {	{"","The command shell"},	{"^P","recall previous cmd"},	{"^N","recall next cmd"},	{"^F","move cursor right"},	{"^B","move cursor left"},	{"^A","move cursor far left"},	{"^E","move cursor far right"},	{"^D","delete char at cursor"},	{"^H","delete char before cursor"},	{"",""},	{"!!","repeat last cmd"},	{"!str","recall and execute cmd str"},	{"!num","recall and execute cmd num"},	{"",""},	{"+-*/()","operators"},	{"^addr","contents of address"},	{"@name","contents of register"},	{"&name","value of symbol"},	{"0xnum","hex number"},	{"0onum","octal number"},	{"0tnum","decimal number"},	{0}};int do_vers();char full_vers_info[80];Optdesc vers_opts[] = {	{"[-a]","display version info"},	{"-a","display all version info"},	{0}};#ifdef CROSSVIEWint do_cp(),do_echo(),do_sc(),do_gc(),do_sr(),do_mr();int gmx(),smx(),do_init(),do_lo();#endifextern Optdesc ab_opts[];int ab_cmd();CmdRec moncmds[] = {	{"h",h_opts,help},	{"hi",hi_opts,dohi},	{"m",m_opts,modify},	{"r",r_opts,registers},	{"d",d_opts,dump},	{"l",l_opts,dis},	{"copy",copy_opts,copy},	{"fill",fill_opts,fill},	{"search",search_opts,search},	{"compare",compare_opts,compare_cmd},	{"when",w_opts,when},	{"g",g_opts,go},	{"c",c_opts,cont},	{"t",t_opts,trace},	{"to",to_opts,trace},	{"b",b_opts,setbp},	{"db",db_opts,clrbp},	{"sym",sym_opts,do_sym},	{"ls",ls_opts,do_ls},	{"set",set_opts,do_set},	{"vers",vers_opts,do_vers},	{"sh",sh_opts,no_cmd},	{"more",more_opts,no_cmd},#ifdef GDB_SUPPORT	{"debug",debug_opts,debug},#endif	{"ab",ab_opts,ab_cmd},	/* access (data) bpts */#ifdef CROSSVIEW	{"xvw",crossview_opts,no_cmd},	{"cp",0,do_cp},		/* copy memory range */	{"echo",0,do_echo}, 	/* echo args */	{"sc",0,do_sc},	 	/* set config */	{"gc",0,do_gc},	 	/* get config */	{"sr",0,do_sr},	 	/* set register */	{"mr",0,do_mr},	 	/* display modified regs */	{"gmb",0,gmx},		/* get memory as bytes */	{"smb",0,smx},		/* set memory as bytes */	{"gmh",0,gmx},		/* get memory as half-words */	{"smh",0,smx},		/* set memory as half-words */	{"gmw",0,gmx},		/* get memory as words */	{"smw",0,smx},		/* set memory as words */	{"lo",0,do_lo},		/* binary download */	{"init",0,do_init},	/* warm (cold) reboot */#endif	{0}};/**************************************************************  moninit()*/moninit(){int i;for (i=0;moncmds[i].name;i++) addCmdRec(&moncmds[i]);histinit();envinit();ioctl_setup(STDIN);c0regNames = regs_hw;c2cRegNames = regs_hw;c2dRegNames = regs_hw;if (!matchenv("regstyle")) regnames = regs_hw;else regnames = regs_sw;}/**************************************************************  monmain()*	Called after moninit has been executed*	o  Prompts for commands and calls do_cmd to execute them*	o  The setjmp is used to pass control back here if a ^C is typed*/monmain(){int i,t1,rptcmd;char prompt[20],tmp[8],*p,*t;char buf[100];Ulong adr;#ifdef PMCCioctl(STDIN,SETINTR,intrbuf);if (setjmp(intrbuf) == 1) { /* on INTR */	if (curlst == &clilst && regChain) { /* 970826 */		adr = getPc();		disasm(buf,adr,read_target(XT_MEM,adr,4));		printf("break!\n%s\n",buf); /* 971007 */		}	else printf("break!\n"); /* 971007 */	}#elsesetjmp(intrbuf);if (signal(SIGINT,SIG_IGN) != SIG_IGN) signal(SIGINT,gotintr);#endifdisableints();swlst(1);if (bptTmpId != -1) {	clrbpt(bptTmpId);	bptTmpId = -1;	}if (shrc_needed) {	shrc_needed = 0;	shrc(1);	}while (1) {	ioctl_restore(STDIN); /* in case it has been left in a funny state */#ifndef NON_CACHED	flush_target(DCACHE);	flush_target(ICACHE);#endif	if (!*line) { /* line is empty */		/* don't hang if the env var is bad */		if (getMonEnv("prompt")) strcpy(prompt,getMonEnv("prompt"));		else strcpy(prompt,"BAD> ");					if (p = strchr(prompt,'!')) {			strdchr(p); /* delete the bang */			sprintf(tmp,"%d",histno);			stristr(p,tmp);			}		printf("%s",prompt);		get_cmd(line);		if (!*line || strempty(line)) { /* blank */			rptcmd = matchenv("rptcmd");			if (rptcmd) { /* repeat requested */				t = gethistn(histno-1);				if (rptcmd == 1) strcpy(line,t); /* all cmds */				else if (rptcmd == 2) { /* trace only */					if (wordsz(t) > 10) continue;					getword(tmp,t);					if (strequ(tmp,"t")||strequ(tmp,"to")) 						strcpy(line,tmp);					else 	continue;					}				else {					printf("bad rptcmd value [%s]\n",							getMonEnv("rptcmd"));					continue;					}				}			else continue;			}		}	do_cmd(line);	}}#if 0/**************************************************************  gotintr()*/gotintr(){char buf[100];Ulong adr;signal(SIGINT,gotintr);if (curlst == &clilst && regChain) { /* 970826 */	adr = getPc();	disasm(buf,adr,read_target(XT_MEM,adr,4));	printf("break!\n%s\n",buf); /* 971007 */	}else printf("break!\n"); /* 971007 */longjmp(intrbuf,0);}#endif/**************************************************************  do_cmd(p)*	execute a command, the string pointed to by p.*	warning: p does get written to*	o  Commands are invoked as if executed from a standard command*	   shell. i.e. they are passed an argc/argv argument list.*/do_cmd(cmd)char *cmd;{char *av[MAX_AC];	/* argument holder */int ac;			/* # of arguments */char *t,tmp[200];int i,c,r;CmdRec *p;for (;*cmd;) {	/* look for ';' that is not enclosed within "" or '' */	for (t=cmd;*t;) {		c = *t;		if(c == '\'' || c == '"') {			t++;			while(*t && *t != c) ++t;			if(*t) t++;			}		else if (c == ';') break;		else t++;		}	/* copy the 1st cmd into tmp, and then remove it from cmd */	strNcpy(tmp,cmd,t-cmd);	if (c == ';') i = (t-cmd)+1;	else i = t-cmd;	for (;i>0;i--) strdchr(cmd);	/* find and then execute the command specified in tmp */	ac = argvize(av,tmp);	if(ac > 0) {		if (strequ(av[0],"stop")) return(1);		for (p=cmdChain;p;p=p->next)			if (strequ(p->name,av[0])) break;		if (p) (p->func)(ac,av,p);		else printf("%s: Command not found.\n",av[0]);		}	}return(0);}Optdesc h_opts[] = {	{"[*|cmd..]","The help command"},	{0}};/**************************************************************  help(ac,av)*	the 'help' command*/help(ac,av)int ac;char *av[];{int i,j,namemax,optsmax,descmax,len;int ln,siz;CmdRec *p;namemax = optsmax = descmax = 0;for (p=cmdChain;p;p=p->next) {	len = strlen(p->name);	if (len > namemax) namemax = len;	if (p->opts) {		if (p->opts->name) {			len = strlen(p->opts->name);			if (len > optsmax) optsmax = len;			}		if (p->opts->desc) {			len = strlen(p->opts->desc);			if (len > descmax) descmax = len;			}		}	}if (!atob(&siz,getMonEnv("moresz"),10)) {	printf("%s: bad moresz value\n",getMonEnv("moresz"));	return(1);	}ioctl_cbreak(0L);ln = siz;if (ac >= 2) { /* extended help */	if (strequ(av[1],"*")) { /* all commands */		for (p=cmdChain;p;p=p->next) {			if (prhelp(p,&ln,siz,namemax,optsmax)) break;			}		}	else { /* specific commands */		for (j=1;j<ac;j++) {			for (p=cmdChain;p;p=p->next) {				if (strequ(p->name,av[j])) break;				}			if (p) {				if (prhelp(p,&ln,siz,namemax,optsmax)) break;				}			else printf("%s: Command not found\n",av[j]);			}		}	}else { /* general help only */	for (p=cmdChain,i=0;p;p=p->next) {		if (!p->opts) continue;		printf("%*s  %-*s",namemax,p->name,descmax,p->opts->desc);		if (i%2 != 0) printf("\n");		else printf("   ");		i++;		}	if (i%2 != 0) printf("\n");	}return(0);}/**************************************************************  prhelp(n,lnp,siz,namemax,optsmax)*/prhelp(p,lnp,siz,namemax,optsmax)int *lnp,siz,namemax,optsmax;CmdRec *p;{Optdesc *o;int i;if (!p->opts) return(0);sprintf(prnbuf,"%*s  %-*s    %s",namemax,p->name,optsmax, p->opts->name,					p->opts->desc);if (more(prnbuf,lnp,siz)) return(1);o = p->opts;if (o) {	for (i=1;o[i].name;i++) {		sprintf(prnbuf,"%*s  %15s    %s",namemax,"",					o[i].name,o[i].desc);		if (more(prnbuf,lnp,siz)) return(1);		}	}return(0);}/**************************************************************  no_cmd(ac,av)*/no_cmd(ac,av)int ac;char *av[];{printf("The %s command cannot be invoked by name.\n",av[0]);return(0);}/**************************************************************  printfb(fmt,a1,a2,a3,a4)*	A buffered printf used for printing the PMON banner.*/printfb(fmt,a1,a2,a3,a4)char *fmt;Ulong a1,a2,a3,a4;{char tmp[80];int len,islf;islf = 0;sprintf(tmp,fmt,a1,a2,a3,a4);len = strlen(tmp);if (len == 0) return(0);if (!strcmp(fmt,"\n")) islf = 1;if ((strlen(prnbuf)+len) > 70 || islf) {	printf("\n");	*prnbuf = 0;	}if (strlen(prnbuf)) strcat(prnbuf," ");strcat(prnbuf,tmp);printf("%s ",tmp);}/**************************************************************  get_rsa(vp,p)*	Get Register/Symbol/Address*	This function evaluates expressions on the command line*	using recursive decent. It understands expressions*	containing any combination of register names, symbols,*	constants, perens, and the operators +-* /. In addition*	it also permits the '^' operator to dereference any*	address.*/get_rsa(vp,p)unsigned long *vp;char *p;{int r,inbase,inalpha;unsigned long v1,v2;char *q,subexpr[LINESZ];/* strip enclosing parens */while (*p == '(' && strbalp(p) == p+strlen(p)-1) {	strdchr(p);	p[strlen(p)-1] = 0;	}if (q=strrpset(p,"+-")) { /* is compound */	strNcpy(subexpr,p,q-p);	r = get_rsa(&v1,subexpr);	if (r == 0) return(r);	r = get_rsa(&v2,q+1);	if (r == 0) return(r);	if (*q == '+') *vp = v1 + v2;	else *vp = v1 - v2;	return(1);	}if (q=strrpset(p,"*/")) { 	strNcpy(subexpr,p,q-p);	r = get_rsa(&v1,subexpr);	if (r == 0) return(r);	r = get_rsa(&v2,q+1);	if (r == 0) return(r);	if (*q == '*') *vp = v1 * v2;	else *vp = v1 / v2;	return(1);	}if (*p == '^') {	r = get_rsa(&v2,p+1);	if (r == 0) return(r);	*vp = read_target(XT_MEM,v2,4);	return(1);	}if (*p == '@') {#ifdef PREGS /* preg */	if (ispreg(&p[1])) {		*vp = getPreg(p[1]-'a');		r = 1;		}	else {		r = getreg(vp,&p[1]);		if (r == 0) printf("%s: bad register name\n",&p[1]);		}#else	r = getreg(vp,&p[1]);	if (r == 0) printf("%s: bad register name\n",&p[1]);#endif	}else if (strequ(p,".")) {	r = getreg(vp,"pc");	if (r == 0) printf("%s: bad register name\n",&p[1]);	}else if (*p == '&') {	r = sym2adr(vp,&p[1]);	if (r == 0) printf("%s: bad symbol name\n",&p[1]);	}else if (isdigit(*p)) {	inbase = matchenv("inbase");	if (inbase == IB_TEN) r = atob(vp,p,10);	else if (inbase == IB_SIXTEEN) r = atob(vp,p,16);	else if (inbase == IB_EIGHT) r = atob(vp,p,8);	else if (inbase == IB_AUTO) r = atob(vp,p,0);	else {		printf("%s: bad inbase value\n",getMonEnv("inbase"));		return(0);		}	if (r == 0) {		r = atob(vp,p,0);		if (r == 0) printf("%s: bad base %s value\n",						p,getMonEnv("inbase"));		}	}else if (isxdigit(*p)) {	inalpha = matchenv("inalpha");	if (inalpha == IA_HEX) {		r = atob(vp,p,16);		if (r == 0) {			r = sym2adr(vp,p);			if (r == 0) printf(badhexsym,p);			}		}	else if (inalpha == IA_SYMBOL) {		r = sym2adr(vp,p);		if (r == 0) {			r = atob(vp,p,16);			if (r == 0) printf(badhexsym,p);			}		}	else {		printf("%s: bad inalpha value\n",getMonEnv("inalpha"));		return(0);		}	}else {	r = sym2adr(vp,p);	if (r == 0) printf("%s: bad symbol name\n",p);	}return(r);}/**************************************************************  stop(cmdstr)*/stop(cmdstr)char *cmdstr;{char cmd[LINESZ];#ifdef CROSSVIEWif (xvwmode) longjmp(intrbuf,2);#endifif (cmdstr) strcpy(cmd,cmdstr);else strcpy(cmd,getMonEnv("brkcmd"));do_cmd(cmd);longjmp(intrbuf,2);}/**************************************************************  addCmdRec(p)*	add a CmdRec to the cmdChain*/addCmdRec(p)CmdRec *p;{CmdRec *q;p->next = 0;if (!cmdChain) { /* empty */	cmdChain = p;	}else {	for (q=cmdChain;q->next;q=q->next) ; /* find end of chain */	q->next = p;	}}/**************************************************************  do_vers(ac,av)*	display version number*/do_vers(ac,av)int ac;char *av[];{if (ac == 1) printf("%s\n",vers);else printf("%s\n",full_vers_info);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -