X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=debugger%2Fmcs51%2Fcmd.c;h=fef7d6dc629f1a0e4504dbbe6533ece2384a8e9e;hb=b0f66784a8a6fff0708c7ffd4931bff519869541;hp=da4a2e45214e772659a2d03dadd4fa6834c1e6c1;hpb=ddba1eef4ec147af4bfedb50e6b3bc02ac66f952;p=fw%2Fsdcc diff --git a/debugger/mcs51/cmd.c b/debugger/mcs51/cmd.c index da4a2e45..fef7d6dc 100644 --- a/debugger/mcs51/cmd.c +++ b/debugger/mcs51/cmd.c @@ -7,19 +7,19 @@ under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - + In other words, you are welcome to use, share and improve this program. You are forbidden to forbid anyone else to use, share and improve - what you give them. Help stamp out software-hoarding! + what you give them. Help stamp out software-hoarding! -------------------------------------------------------------------------*/ #include "sdcdb.h" @@ -30,7 +30,8 @@ #include "newalloc.h" /* default number of lines to list out */ -int listLines = 16; +#define LISTLINES 10 +static int listlines = LISTLINES; /* mainly used to retain a reference to the active module being listed. May be used as a general context for other commands if @@ -328,12 +329,14 @@ static char *warranty= #endif static void printTypeInfo(link *); -static void printValAggregates (symbol *,link *,char,unsigned int); -static void setSymValue(symbol *sym, char *val, context *cctxt); +static void printValAggregates (symbol *,link *,char,unsigned int,int); +static int printOrSetSymValue (symbol *sym, context *cctxt, + int flg, int dnum, int fmt, + char *rs, char *val, char cmp); int srcMode = SRC_CMODE ; static set *dispsymbols = NULL ; /* set of displayable symbols */ - +static int currentFrame = 0; /* actual displayed frame */ /*-----------------------------------------------------------------*/ /* funcWithName - returns function with name */ /*-----------------------------------------------------------------*/ @@ -350,49 +353,76 @@ DEFSETFUNC(funcWithName) *funcp = func; return 1; } - + + return 0; +} + +/*-----------------------------------------------------------------*/ +/* symWithAddr - look for symbol with sfr / sbit address */ +/*-----------------------------------------------------------------*/ +DEFSETFUNC(symWithAddr) +{ + symbol *sym = item; + V_ARG(unsigned long,laddr); + V_ARG(int ,laddrspace); + V_ARG(symbol **,rsym); + + if (*rsym) + return 0; + + if ( sym->addr == laddr && + sym->addrspace == laddrspace ) + { + *rsym = sym; + return 1; + } + return 0; } /*-----------------------------------------------------------------*/ /* setBPatModLine - set break point at the line specified for the */ /*-----------------------------------------------------------------*/ -static void setBPatModLine (module *mod, int line) +static void setBPatModLine (module *mod, int line, char bpType ) { - int next_line; + int next_line; /* look for the first executable line after the line - specified & get the break point there */ + specified & get the break point there */ + + if ( line < 0 ) + return; + if (srcMode == SRC_CMODE && line > mod->ncLines) { - fprintf(stderr,"No line %d in file \"%s\".\n", - line,mod->c_name); - return ; + fprintf(stderr,"No line %d in file \"%s\".\n", + line,mod->c_name); + return ; } - + if (srcMode == SRC_AMODE && line > mod->nasmLines) { - fprintf(stderr,"No line %d in file \"%s\".\n", - line,mod->asm_name); - return ; + fprintf(stderr,"No line %d in file \"%s\".\n", + line,mod->asm_name); + return ; } next_line = line; - for ( ; next_line < (srcMode == SRC_CMODE ? mod->ncLines : mod->nasmLines ) ; + for ( ; next_line < (srcMode == SRC_CMODE ? mod->ncLines : mod->nasmLines ) ; next_line++ ) { if (srcMode == SRC_CMODE) { - if (mod->cLines[next_line]->addr) { - setBreakPoint (mod->cLines[next_line]->addr, CODE, USER, + if (mod->cLines[next_line]->addr != INT_MAX) { + setBreakPoint (mod->cLines[next_line]->addr, CODE, bpType, userBpCB, mod->c_name, next_line); return; // break; } } else { - if (mod->asmLines[next_line]->addr) { - setBreakPoint (mod->asmLines[next_line]->addr, CODE, USER, + if (mod->asmLines[next_line]->addr != INT_MAX) { + setBreakPoint (mod->asmLines[next_line]->addr, CODE, bpType, userBpCB, mod->asm_name, next_line); return; // break; - } + } } } @@ -414,23 +444,23 @@ static void clearBPatModLine (module *mod, int line) line,mod->c_name); return ; } - + if (srcMode == SRC_AMODE && line > mod->ncLines) { fprintf(stderr,"No line %d in file \"%s\".\n", line,mod->c_name); return ; - } - - for ( ; line < (srcMode == SRC_CMODE ? mod->ncLines : mod->nasmLines ) ; + } + + for ( ; line < (srcMode == SRC_CMODE ? mod->ncLines : mod->nasmLines ) ; line++ ) { - if (srcMode == SRC_CMODE) + if (srcMode == SRC_CMODE) if (mod->cLines[line]->addr) { - clearUSERbp (mod->cLines[line]->addr); + clearUSERbp (mod->cLines[line]->addr); break; } else if (mod->asmLines[line]->addr) { - clearUSERbp (mod->asmLines[line]->addr); + clearUSERbp (mod->asmLines[line]->addr); break; } } @@ -453,14 +483,22 @@ DEFSETFUNC(moduleLineWithAddr) if (*rmod) return 0; - for (i=0; i < mod->nasmLines; i++ ) + for (i=0; i < mod->nasmLines; i++ ) { if ( mod->asmLines[i]->addr == addr) { *rmod = mod ; if (line ) - *line = mod->ncLines; - return 1; + { + *line = 0; + for ( i=0; i < mod->ncLines; i++ ) + { + if ( mod->cLines[i]->addr > addr) + break; + *line = i; + } + return 1; + } } } @@ -470,7 +508,7 @@ DEFSETFUNC(moduleLineWithAddr) /*-----------------------------------------------------------------*/ /* funcWithNameModule - returns functions with a name module combo */ /*-----------------------------------------------------------------*/ -DEFSETFUNC(funcWithNameModule) +DEFSETFUNC(funcWithNameModule) { function *func = item; V_ARG(char *,fname); @@ -504,12 +542,12 @@ DEFSETFUNC(funcInAddr) /* in the address range */ if (func->sym->addr <= addr && func->sym->eaddr >= addr) { - + *funcp = func; return 1; } - return 0; + return 0; } /*-----------------------------------------------------------------*/ @@ -518,11 +556,11 @@ DEFSETFUNC(funcInAddr) DEFSETFUNC(setStepBp) { function *func = item; - + if (func->sym && func->sym->addr ) { - + /* set the entry break point */ - setBreakPoint (func->sym->addr , CODE , STEP , + setBreakPoint (func->sym->addr , CODE , STEP , stepBpCB ,func->mod->c_name , func->entryline); return 1; @@ -539,8 +577,8 @@ DEFSETFUNC(setStepEPBp) exePoint *ep = item; V_ARG(int,bptype); V_ARG(char *,mname); - - setBreakPoint (ep->addr, CODE, bptype, + + setBreakPoint (ep->addr, CODE, bptype, stepBpCB, mname, ep->line); return 1; } @@ -553,8 +591,8 @@ DEFSETFUNC(setNextEPBp) exePoint *ep = item; V_ARG(int,bptype); V_ARG(char *,mname); - - setBreakPoint (ep->addr, CODE, bptype, + + setBreakPoint (ep->addr, CODE, bptype, nextBpCB, mname, ep->line); return 1; } @@ -581,7 +619,7 @@ DEFSETFUNC(lineAtAddr) } return 0; - + } /*-----------------------------------------------------------------*/ @@ -606,24 +644,23 @@ DEFSETFUNC(lineNearAddr) } return 0; - + } /*-----------------------------------------------------------------*/ /* discoverContext - find out the current context of the bp */ /*-----------------------------------------------------------------*/ -context *discoverContext (unsigned addr) +context *discoverContext (unsigned addr, function *func) { - function *func = NULL; module *mod = NULL; int line = 0; /* find the function we are in */ - if (!applyToSet(functions,funcInAddr,addr,&func)) { - if (!applyToSet(functions,funcWithName,"main") || - !applyToSet(modules,moduleLineWithAddr,addr,&mod,&line)) + if (!func && !applyToSet(functions,funcInAddr,addr,&func)) { + if (!applyToSet(functions,funcWithName,"_main",&func) || + !applyToSet(modules,moduleLineWithAddr,addr,&mod,NULL)) { - fprintf(stderr, "Error?:discoverContext: cannot apply to set!\n"); + fprintf(stderr, "addr 0x%x in no module/function (runtime env?)\n",addr); return NULL; } currCtxt->func = func; @@ -636,22 +673,25 @@ context *discoverContext (unsigned addr) currCtxt->func = func; currCtxt->addr = func->laddr = addr; currCtxt->modName = func->modName; - + /* find the c line number */ - if(applyToSet(func->cfpoints,lineNearAddr,addr, - &line,&currCtxt->block,&currCtxt->level)) + if(applyToSet(func->cfpoints,lineAtAddr,addr, + &line,&currCtxt->block,&currCtxt->level)) + currCtxt->cline = func->lline = line; + else if(applyToSet(func->cfpoints,lineNearAddr,addr, + &line,&currCtxt->block,&currCtxt->level)) currCtxt->cline = func->lline = line; else - currCtxt->cline = func->exitline; - } + currCtxt->cline = -1; + } /* find the asm line number */ line = 0; if (applyToSet(func->afpoints,lineAtAddr,addr, &line,NULL,NULL)) - currCtxt->asmline = line; + currCtxt->asmline = line; else - currCtxt->asmline = -1; - + currCtxt->asmline = -1; + return currCtxt ; } @@ -660,74 +700,109 @@ context *discoverContext (unsigned addr) /* simGo - send 'go' cmd to simulator and wait till a break occurs */ /*-----------------------------------------------------------------*/ void simGo (unsigned int gaddr) -{ +{ unsigned int addr ; context *ctxt; int rv; - static int initial_break_flag = 0; - - top: + stopCommandList(); + top: if ( userinterrupt ) { userinterrupt = 0; return; } + if ( gaddr == 0 ) + { + function *func = NULL;; + if (applyToSet(functions,funcInAddr,gaddr,&func)) + STACK_PUSH(callStack,func); + } addr = simGoTillBp (gaddr); /* got the pc for the break point now first - discover the program context i.e. module, function + discover the program context i.e. module, function linenumber of the source etc, etc etc */ - ctxt = discoverContext (addr); - + currentFrame = 0; + ctxt = discoverContext (addr, NULL); + /* dispatch all the break point call back functions */ - rv = dispatchCB (addr,ctxt); - ret: + rv = dispatchCB (addr,ctxt); /* the dispatch call back function will return non-zero if an user break point has been hit - if not then we continue with the execution + if not then we continue with the execution of the program */ - if (!rv) { - if (!initial_break_flag) { - initial_break_flag = 1; // kludge to stop only at first run - fprintf(stdout, "Stopping at entry. You can now list and set breakpoints\n"); - } - else { - gaddr = -1; - goto top ; - } + if (!rv) + { + if ( gaddr == 0 ) + gaddr = -1; + if ( gaddr == -1 || doingSteps == 1 ) + goto top ; + } -// notes: kpb -// I took this out, after running "run" it would just keep re-running -// even after a lot of break points hit. For some reason above code -// not triggering(dispatchCB). This seems to be by design, startup adds -// a bunch of breakpoints-but they are not USER breakpoints. Perhaps the -// debugger changed with its implementation of "go"("run"). It seems we -// need to add a "next" or "step" followed by a "run"... -// I added a "step" in simi.c when we want a resume function, this seems -// to work. - -// still there is question of how do we stop it initially, since -// it must be started before it can get a context. If so, we would -// want it to just run up to an initial entry point you'd think... -// I don't see why we can't set breakpoints before an initial run, -// this does not seem right to me. - -// line #'s are a bit off too. - -#if 0 - gaddr = -1; - goto top ; -#endif +} + +/*-----------------------------------------------------------------*/ +/* preparePrint - common parse function for set variable, */ +/* output, print and display */ +/*-----------------------------------------------------------------*/ +static char *preparePrint(char *s, context *cctxt, int *fmt, symbol **sym) +{ + char *bp = s+strlen(s) -1; + char save_ch ; + + *fmt = FMT_NON; + *sym = NULL; + + while (isspace(*s)) s++; + if (!*s) + return (char *)0; + + while (isspace(*bp)) bp--; + bp++ ; + *bp = '\0'; + + if ( *s == '/' ) + { + /* format of printout */ + switch ( *++s ) + { + case 'x': + *fmt = FMT_HEX ; + break; + case 'o': + *fmt = FMT_OCT ; + break; + default: + case 'd': + *fmt = FMT_DEZ ; + break; + case 't': + *fmt = FMT_BIN ; + break; + } + s++; + while (isspace(*s)) s++; } - + for ( bp = s; *bp && ( isalnum( *bp ) || *bp == '_' || *bp == '$'); bp++ ); + save_ch = *bp; + if ( *bp ) + *bp = '\0'; + + if ( *s ) + *sym = symLookup(s,cctxt); + *bp = save_ch; + + if ( ! *sym ) + fprintf(stdout,"No symbol \"%s\" in current context.\n", s); + return bp; } -static int printAsmLine( function *func, module *m, long saddr, long eaddr) +static int printAsmLine( function *func, module *m, unsigned saddr, unsigned eaddr) { int i,j,delta; - int symaddr; - int lastaddr = saddr+1; + unsigned symaddr; + unsigned lastaddr = saddr+1; char *symname; if ( func ) @@ -740,7 +815,7 @@ static int printAsmLine( function *func, module *m, long saddr, long eaddr) symaddr = saddr; symname = "" ; } - for (j=0,i=0; i < m->nasmLines; i++ ) + for (j=0,i=0; i < m->nasmLines; i++ ) { if ( saddr >= 0 && m->asmLines[i]->addr < saddr) { @@ -750,12 +825,12 @@ static int printAsmLine( function *func, module *m, long saddr, long eaddr) { continue; } - if ( func && + if ( func && (m->asmLines[i]->addr < func->sym->addr || m->asmLines[i]->addr > func->sym->eaddr )) { continue; - } + } delta = m->asmLines[i]->addr - symaddr; if ( delta >= 0 ) { @@ -763,7 +838,7 @@ static int printAsmLine( function *func, module *m, long saddr, long eaddr) lastaddr = m->asmLines[i]->addr; printf("0x%08x <%s",lastaddr,symname); if (delta > 0) printf("+%d",delta); - printf(">:\t%s",m->asmLines[i]->src); + printf(">:\t%s",m->asmLines[i]->src); } } return lastaddr; @@ -801,7 +876,7 @@ static int cmdDisasm (char *s, context *cctxt, int args) } if ( eaddr == -1 ) - { + { /* no start or only start so dump function */ if ( saddr == -1 ) { @@ -816,7 +891,7 @@ static int cmdDisasm (char *s, context *cctxt, int args) printf("Dump of assembler code for function %s:\n",func->sym->name); printAsmLine(func,func->mod,-1,-1); printf("End of assembler dump.\n"); - return 0; + return 0; } else { @@ -826,7 +901,7 @@ static int cmdDisasm (char *s, context *cctxt, int args) printf("Dump of assembler code:\n"); printAsmLine(NULL,modul,saddr,eaddr); printf("End of assembler dump.\n"); - return 0; + return 0; } } } @@ -856,12 +931,20 @@ static int cmdDisasm (char *s, context *cctxt, int args) { if ( args > 1 ) printf("End of assembler dump.\n"); - return 0; + return 0; } - + } fprintf(stderr,"No function contains specified address.\n"); - return 0; + if( saddr >= 0 ) + { + char lbuf[64]; + sprintf(lbuf,"dis 0x%lx 0 %ld\n",saddr,( eaddr == -1 )?1L:eaddr-saddr); + sendSim(lbuf); + waitForSim(1000, NULL); + fputs(simResponse(),stdout); + } + return 0; } /*-----------------------------------------------------------------*/ /* cmdDisasm1 - disassemble one asm instruction */ @@ -879,14 +962,11 @@ int cmdDisasmF(char *s, context *cctxt) return cmdDisasm( s, cctxt, 2); } -/*-----------------------------------------------------------------*/ -/* cmdSetUserBp - set break point at the user specified location */ -/*-----------------------------------------------------------------*/ -int cmdSetUserBp (char *s, context *cctxt) +static int commonSetUserBp(char *s, context *cctxt, char bpType) { char *bp ; function *func = NULL; - + /* user break point location specification can be of the following forms a) - break point at current location @@ -894,7 +974,7 @@ int cmdSetUserBp (char *s, context *cctxt) c) filename:lineno - line number of the given file e) filename:function- function X in file Y (useful for static functions) f) function - function entry point - g) *addr - break point at address + g) *addr - break point at address */ if (!cctxt) { @@ -903,7 +983,7 @@ int cmdSetUserBp (char *s, context *cctxt) } /* white space skip */ while (*s && isspace(*s)) s++; - + /* null terminate it after stripping trailing blanks*/ bp = s + strlen(s); while (bp != s && isspace(*bp)) bp--; @@ -916,18 +996,19 @@ int cmdSetUserBp (char *s, context *cctxt) /* if current context is known */ if (cctxt->func) { + Dprintf(D_break, ("commonSetUserBp: a) cctxtaddr:%x \n",cctxt->addr)); if (srcMode == SRC_CMODE) /* set the break point */ - setBreakPoint ( cctxt->addr , CODE , USER , userBpCB , + setBreakPoint ( cctxt->addr , CODE , bpType , userBpCB , cctxt->func->mod->c_name, cctxt->cline); else - setBreakPoint ( cctxt->addr , CODE , USER , userBpCB , + setBreakPoint ( cctxt->addr , CODE , bpType , userBpCB , cctxt->func->mod->asm_name, cctxt->asmline); - + } else fprintf(stderr,"No default breakpoint address now.\n"); - + goto ret ; } /* case g) *addr */ @@ -940,11 +1021,12 @@ int cmdSetUserBp (char *s, context *cctxt) module *modul; if (!applyToSet(modules,moduleLineWithAddr,braddr,&modul,&line)) { - fprintf(stderr,"Address 0x%08x not exists in code.\n",braddr); + fprintf(stderr,"Address 0x%08x not exists in code.\n",braddr); } else { - setBreakPoint ( braddr , CODE , USER , userBpCB , + Dprintf(D_break, ("commonSetUserBp: g) addr:%x \n",braddr)); + setBreakPoint ( braddr , CODE , bpType , userBpCB , modul->c_name,line); } goto ret ; @@ -952,47 +1034,54 @@ int cmdSetUserBp (char *s, context *cctxt) else { int line = func->exitline; - applyToSet(func->cfpoints,lineNearAddr,braddr,&line,NULL,NULL); - setBreakPoint ( braddr , CODE , USER , userBpCB , + if ( !applyToSet(func->cfpoints,lineAtAddr,braddr, + &line,NULL,NULL)) + applyToSet(func->cfpoints,lineNearAddr,braddr,&line,NULL,NULL); + setBreakPoint ( braddr , CODE , bpType , userBpCB , func->mod->c_name,line); } goto ret ; } /* case b) lineno */ /* check if line number */ - if (isdigit(*s)) { + if ( !strchr(s,':') && isdigit(*s)) { /* get the lineno */ - int line = atoi(s); - + int line = atoi(s) -1; + Dprintf(D_break, ("commonSetUserBp: b) line:%d \n",line)); + if ( line < 0 ) + { + fprintf(stdout,"linenumber <= 0\n"); + goto ret; + } /* if current context not present then we must get the module which has main & set the break point @ line number provided - of that module : if current context known then set the bp - at the line number given for the current module + of that module : if current context known then set the bp + at the line number given for the current module */ if (cctxt->func) { if (!cctxt->func->mod) { if (!applyToSet(functions,funcWithName,"main")) fprintf(stderr,"Function \"main\" not defined.\n"); - else - setBPatModLine(func->mod,line); - } else - setBPatModLine(cctxt->func->mod,line); + else + setBPatModLine(func->mod,line, bpType); + } else + setBPatModLine(cctxt->func->mod,line, bpType); } else { if (list_mod) { - setBPatModLine(list_mod,line); + setBPatModLine(list_mod,line, bpType); } else { fprintf(stdout,"Sdcdb fails to have module symbol context at %d\n", __LINE__); } } - + goto ret; } if ((bp = strchr(s,':'))) { - + module *mod = NULL; *bp = '\0'; - + if (srcMode == SRC_CMODE) { if (!applyToSet(modules,moduleWithCName,s,&mod)) { fprintf (stderr,"No source file named %s.\n",s); @@ -1004,36 +1093,150 @@ int cmdSetUserBp (char *s, context *cctxt) goto ret; } } - + /* case c) filename:lineno */ - if (isdigit(*(bp +1))) { - - setBPatModLine (mod,atoi(bp+1)); + if (isdigit(*(bp +1))) { + Dprintf(D_break, ("commonSetUserBp: c) line:%d \n",atoi(bp+1))); + setBPatModLine (mod,atoi(bp+1)-1,bpType); goto ret; - + } /* case d) filename:function */ - if (!applyToSet(functions,funcWithNameModule,bp+1,s,&func)) - fprintf(stderr,"Function \"%s\" not defined.\n",bp+1); - else + if (!applyToSet(functions,funcWithNameModule,bp+1,s,&func)) + fprintf(stderr,"Function \"%s\" not defined.\n",bp+1); + else + Dprintf(D_break, ("commonSetUserBp: d) \n")); setBPatModLine (mod, - (srcMode == SRC_CMODE ? + (srcMode == SRC_CMODE ? func->entryline : - func->aentryline)); - + func->aentryline),bpType); + goto ret; } - + /* case e) function */ + Dprintf(D_break, ("commonSetUserBp: e) \n")); if (!applyToSet(functions,funcWithName,s,&func)) - fprintf(stderr,"Function \"%s\" not defined.\n",s); + fprintf(stderr,"Function \"%s\" not defined.\n",s); else setBPatModLine(func->mod, (srcMode == SRC_CMODE ? func->entryline : - func->aentryline)); + func->aentryline),bpType); + + ret: + return 0; +} + +/*-----------------------------------------------------------------*/ +/* cmdSetTmpUserBp - settempory break point at the user specified location */ +/*-----------------------------------------------------------------*/ +int cmdSetTmpUserBp (char *s, context *cctxt) +{ + return commonSetUserBp(s, cctxt, TMPUSER ); +} + +/*-----------------------------------------------------------------*/ +/* cmdSetUserBp - set break point at the user specified location */ +/*-----------------------------------------------------------------*/ +int cmdSetUserBp (char *s, context *cctxt) +{ + return commonSetUserBp(s, cctxt, USER ); +} + +/*-----------------------------------------------------------------*/ +/* cmdJump - set program counter */ +/*-----------------------------------------------------------------*/ +int cmdJump (char *s, context *cctxt) +{ + char *bp ; + function *func = NULL; + if (STACK_EMPTY(callStack)) + { + fprintf(stdout,"The program is not running.\n"); + return 0; + } + + /* white space skip */ + while (*s && isspace(*s)) s++; - ret: + /* null terminate it after stripping trailing blanks*/ + bp = s + strlen(s); + while (bp != s && isspace(*bp)) bp--; + *bp = '\0'; + if (! *s ) + { + fprintf(stdout,"No argument: need line or *addr.\n"); + return 0; + } + if ( *s == '*' && isdigit(*(s+1))) + { + unsigned int addr = atoi(s); + if (cctxt && cctxt->func && + cctxt->func->sym->addr <= addr && + cctxt->func->sym->eaddr >= addr) + { + simSetPC(addr); + return 0; + } + fprintf(stdout,"Warning addr 0x%x outside actual function.\n",addr); + simSetPC(addr); + return 0; + } + if (isdigit(*s)) + { + /* get the lineno */ + int line = atoi(s) -1; + if (!cctxt || !cctxt->func || !cctxt->func->mod) + { + fprintf(stderr,"Function not defined.\n"); + return 0; + } + if (line >= cctxt->func->entryline && + line <= cctxt->func->exitline ) + { + simSetPC(cctxt->func->mod->cLines[line]->addr); + return 0; + } + if (line >= cctxt->func->mod->ncLines ) + { + fprintf(stderr,"line not in module.\n"); + return 0; + } + fprintf(stdout,"Warning line %d outside actual function.\n",line+1); + simSetPC(cctxt->func->mod->cLines[line]->addr); + return 0; + } + if ((bp = strchr(s,':'))) + { + int line; + module *mod = NULL; + *bp++ = '\0'; + if (!applyToSet(modules,moduleWithCName,s,&mod)) + { + fprintf (stderr,"No source file named %s.\n",s); + return 0; + } + if (!isdigit(*bp)) + { + fprintf (stderr,"No line number.\n"); + return 0; + } + line = atoi(bp) -1; + if (line >= mod->ncLines ) + { + fprintf(stderr,"line not in module.\n"); + return 0; + } + if ( mod != cctxt->func->mod || + line < cctxt->func->entryline || + line > cctxt->func->exitline ) + { + fprintf(stdout,"Warning line %d outside actual function.\n", + line+1); + } + simSetPC(mod->cLines[line]->addr); + } return 0; } @@ -1042,12 +1245,15 @@ int cmdSetUserBp (char *s, context *cctxt) /*-----------------------------------------------------------------*/ int cmdListAsm (char *s, context *cctxt) { - if ( cctxt && cctxt->func) + if ( cctxt && cctxt->func) { /* actual line */ - if (printAsmLine(cctxt->func,cctxt->func->mod, + if ( cctxt->addr != INT_MAX ) + { + if (printAsmLine(cctxt->func,cctxt->func->mod, (long)cctxt->addr,(long)cctxt->addr)) - return 0; + return 0; + } } return 0; } @@ -1063,38 +1269,49 @@ int cmdSetOption (char *s, context *cctxt) srcMode = SRC_AMODE; else srcMode = SRC_CMODE; - fprintf(stderr,"source mode set to '%s'\n", + fprintf(stderr,"source mode set to '%s'\n", (srcMode == SRC_CMODE ? "C" : "asm")); return 0; } - if (strncmp(s,"variable ",9) == 0) + if (strncmp(s,"listsize ",9) == 0) + { + listlines = strtol(s+9,0,0); + if ( listlines < LISTLINES ) + listlines = LISTLINES; + return 0; + } + +#ifdef SDCDB_DEBUG + if (strncmp(s,"debug ",6) == 0) + { + sdcdbDebug = strtol(s+6,0,0); + return 0; + } +#endif + if (strncmp(s,"variable ",9) == 0) { symbol *sym ; - char *val; + int fmt; + char *rs; s += 9; - while (isspace(*s)) s++; - if (!*s) return 0; - - val = s; - while (*val && !isspace(*val) && *val != '=') val++; - while (isspace(*val)) *val++ = '\0'; - if (*val) *val++ = '\0'; - if (*val) + if ( !( rs = preparePrint(s, cctxt, &fmt, &sym ))) + return 0; + s = rs; + while (*s && *s != '=') s++; + *s++ = '\0'; + while (isspace(*s)) *s++ = '\0'; + if (*s && sym) { - if ((sym = symLookup(s,cctxt))) - { - setSymValue(sym,val,cctxt); - return 0; - } - fprintf(stdout,"No symbol \"%s\" in current context.\n",s); + printOrSetSymValue(sym,cctxt,0,0,0,rs,s,'\0'); + return 0; } else fprintf(stdout,"No new value for \"%s\".\n",s); - return 0; + return 0; } - + fprintf(stderr,"'set %s' command not yet implemented\n",s); return 0; } @@ -1104,7 +1321,7 @@ int cmdSetOption (char *s, context *cctxt) /*-----------------------------------------------------------------*/ int cmdContinue (char *s, context *cctxt) { - if (!cctxt || !cctxt->func) { + if (STACK_EMPTY(callStack)) { fprintf(stdout,"The program is not being run.\n"); return 0; } @@ -1115,6 +1332,86 @@ int cmdContinue (char *s, context *cctxt) return 0; } +/*-----------------------------------------------------------------*/ +/* cmdIgnore - set ignorecount for breakpoint */ +/*-----------------------------------------------------------------*/ +int cmdIgnore (char *s, context *cctxt) +{ + int bpnum, cnt ; + while (isspace(*s)) s++; + if (!*s ) + { + fprintf(stdout,"Argument required (breakpoint number).\n"); + return 0; + } + bpnum = strtol(s,&s,10); + while (isspace(*s)) s++; + if (!*s ) + { + fprintf(stdout,"Second argument (specified ignore-count) is missing."); + return 0; + } + cnt = strtol(s,0,10); + setUserbpIgnCount(bpnum,cnt); + return 0; +} + +/*-----------------------------------------------------------------*/ +/* cmdCondition - set condition for breakpoint */ +/*-----------------------------------------------------------------*/ +int cmdCondition (char *s, context *cctxt) +{ + int bpnum ; + while (isspace(*s)) s++; + if (!*s ) + { + fprintf(stdout,"Argument required (breakpoint number).\n"); + return 0; + } + bpnum = strtol(s,&s,10); + while (isspace(*s)) s++; + if (*s) + s = Safe_strdup(s); + else + s = NULL; + setUserbpCondition(bpnum,s); + return 0; +} + +/*-----------------------------------------------------------------*/ +/* cmdCommands - set commands for breakpoint */ +/*-----------------------------------------------------------------*/ +int cmdCommands (char *s, context *cctxt) +{ + int bpnum ; + char *cmds,*line; + while (isspace(*s)) s++; + + if (!*s ) + bpnum = getLastBreakptNumber(); + else + bpnum = strtol(s,0,10); + + cmds = NULL; + while ((line = getNextCmdLine())) + { + while (isspace(*line)) line++; + if (!strncmp(line,"end",3)) + break; + if (! cmds ) + { + cmds = Safe_strdup(line); + } + else + { + cmds = Safe_realloc( cmds, strlen(cmds) + 1 + strlen(line)); + strcat(cmds,line); + } + } + setUserbpCommand(bpnum,cmds); + return 0; +} + /*-----------------------------------------------------------------*/ /* cmdDelUserBp - delete user break point */ /*-----------------------------------------------------------------*/ @@ -1122,7 +1419,7 @@ int cmdDelUserBp (char *s, context *cctxt) { int bpnum ; while (isspace(*s)) s++; - + if (!*s ) { if (userBpPresent) { char buffer[10]; @@ -1130,11 +1427,11 @@ int cmdDelUserBp (char *s, context *cctxt) fflush(stdout); fgets(buffer,sizeof(buffer),stdin); if (toupper(buffer[0]) == 'Y') - deleteUSERbp(-1); + deleteUSERbp(-1); } return 0; } - + /* determine the break point number */ if (sscanf(s,"%d",&bpnum) == 1) deleteUSERbp(bpnum); @@ -1143,164 +1440,193 @@ int cmdDelUserBp (char *s, context *cctxt) } /*-----------------------------------------------------------------*/ -/* cmdStep - single step thru C source file */ +/* cmdStepi - single step exactly one instruction */ /*-----------------------------------------------------------------*/ -int cmdStep (char *s, context *cctxt) +int cmdStepi (char *s, context *cctxt) { - function *func = NULL; - - if (!cctxt || !cctxt->func || !cctxt->func->mod) - fprintf(stdout,"The program is not being run.\n"); - else { - int origSrcMode = srcMode; - if ( *s == 'i' ) - srcMode = SRC_AMODE; - /* if we are @ the end of a function then set - break points at execution points of the - function in the call stack... */ - if (cctxt->addr == cctxt->func->sym->eaddr) { - if ((func = STACK_PEEK(callStack))) { - if (srcMode == SRC_CMODE) - applyToSet (func->cfpoints,setStepEPBp,STEP, - func->mod->c_name); - else - applyToSet (func->afpoints,setStepEPBp,STEP, - func->mod->asm_name); - } - } else { - /* set breakpoints at all function entry points - and all exepoints of this functions & for - all functions one up in the call stack */ - - /* all function entry points */ - applyToSet(functions,setStepBp); - - if (srcMode == SRC_CMODE) { - /* for all execution points in this function */ - applyToSet(cctxt->func->cfpoints,setStepEPBp,STEP, - cctxt->func->mod->c_name); - - /* set a break point @ the current function's - exit */ - setBreakPoint (cctxt->func->sym->eaddr, CODE, STEP , - stepBpCB, cctxt->func->mod->c_name, - cctxt->func->exitline); - - /* now break point @ callers execution points */ - if ((func = STACK_PPEEK(callStack))) { - applyToSet (func->cfpoints,setStepEPBp,STEP, - func->mod->c_name); - /* set bp @ callers exit point */ - setBreakPoint (func->sym->eaddr, CODE, STEP , - stepBpCB, func->mod->c_name, - func->exitline); - } - } else { - /* for all execution points in this function */ - applyToSet(cctxt->func->afpoints,setStepEPBp,STEP, - cctxt->func->mod->asm_name); - - /* set a break point @ the current function's - exit */ - setBreakPoint (cctxt->func->sym->eaddr, CODE, STEP , - stepBpCB, cctxt->func->mod->asm_name, - cctxt->func->aexitline); - - /* now break point @ callers execution points */ - if ((func = STACK_PPEEK(callStack))) { - - applyToSet (func->afpoints,setStepEPBp,STEP, - func->mod->asm_name); - - /* set bp @ callers exit point */ - setBreakPoint (func->sym->eaddr, CODE, STEP , - stepBpCB, func->mod->asm_name, - func->aexitline); - } - } - } - srcMode = origSrcMode; - simGo(-1); - showfull = 1; + if (0 /*STACK_EMPTY(callStack)*/) + fprintf(stdout,"The program is not being run.\n"); + else + { + doingSteps = 2; + simGo(2); + doingSteps = 0; + showfull = 1; } return 0; } /*-----------------------------------------------------------------*/ -/* cmdNext - next executable C statement file */ +/* cmdStep - single step thru C source file */ /*-----------------------------------------------------------------*/ -int cmdNext (char *s, context *cctxt) +int cmdStep (char *s, context *cctxt) { function *func = NULL; - /* next is almost the same as step except we don't - we don't set break point for all function entry + + if (STACK_EMPTY(callStack)) + fprintf(stdout,"The program is not being run.\n"); + else { + /* if we are @ the end of a function then set + break points at execution points of the + function in the call stack... */ + if (cctxt->addr == cctxt->func->sym->eaddr) { + if ((func = STACK_PEEK(callStack))) { + if (srcMode == SRC_CMODE) + applyToSet (func->cfpoints,setStepEPBp,STEP, + func->mod->c_name); + else + applyToSet (func->afpoints,setStepEPBp,STEP, + func->mod->asm_name); + } + } else { + /* set breakpoints at all function entry points + and all exepoints of this functions & for + all functions one up in the call stack */ + + /* all function entry points */ + applyToSet(functions,setStepBp); + + if (srcMode == SRC_CMODE) { + /* for all execution points in this function */ + applyToSet(cctxt->func->cfpoints,setStepEPBp,STEP, + cctxt->func->mod->c_name); + + /* set a break point @ the current function's + exit */ + setBreakPoint (cctxt->func->sym->eaddr, CODE, STEP , + stepBpCB, cctxt->func->mod->c_name, + cctxt->func->exitline); + + /* now break point @ callers execution points */ + if ((func = STACK_PPEEK(callStack))) { + applyToSet (func->cfpoints,setStepEPBp,STEP, + func->mod->c_name); + /* set bp @ callers exit point */ + setBreakPoint (func->sym->eaddr, CODE, STEP , + stepBpCB, func->mod->c_name, + func->exitline); + } + } else { + /* for all execution points in this function */ + applyToSet(cctxt->func->afpoints,setStepEPBp,STEP, + cctxt->func->mod->asm_name); + + /* set a break point @ the current function's + exit */ + setBreakPoint (cctxt->func->sym->eaddr, CODE, STEP , + stepBpCB, cctxt->func->mod->asm_name, + cctxt->func->aexitline); + + /* now break point @ callers execution points */ + if ((func = STACK_PPEEK(callStack))) { + + applyToSet (func->afpoints,setStepEPBp,STEP, + func->mod->asm_name); + + /* set bp @ callers exit point */ + setBreakPoint (func->sym->eaddr, CODE, STEP , + stepBpCB, func->mod->asm_name, + func->aexitline); + } + } + } + + doingSteps = 1; + simGo(2); + doingSteps = 0; + showfull = 1; + } + return 0; +} + +/*-----------------------------------------------------------------*/ +/* cmdNexti - next instruction but proceed function call */ +/*-----------------------------------------------------------------*/ +int cmdNexti (char *s, context *cctxt) +{ + if (STACK_EMPTY(callStack)) + fprintf(stdout,"The program is not being run.\n"); + else + { + doingSteps = 2; + simGo(1); + doingSteps = 0; + showfull = 1; + } + return 0; +} + +/*-----------------------------------------------------------------*/ +/* cmdNext - next executable C statement file */ +/*-----------------------------------------------------------------*/ +int cmdNext (char *s, context *cctxt) +{ + function *func = NULL; + /* next is almost the same as step except we don't + we don't set break point for all function entry points */ - if (!cctxt || !cctxt->func || !cctxt->func->mod) - fprintf(stdout,"The program is not being run.\n"); + if (STACK_EMPTY(callStack)) + fprintf(stdout,"The program is not being run.\n"); else { - int origSrcMode = srcMode; - if ( *s == 'i' ) - srcMode = SRC_AMODE; - - /* if we are @ the end of a function then set - break points at execution points of the - function in the call stack... */ - if (cctxt->addr == cctxt->func->sym->eaddr) { - if ((func = STACK_PEEK(callStack))) { - if (srcMode == SRC_CMODE) - applyToSet (func->cfpoints,setStepEPBp,STEP, - func->mod->c_name); - else - applyToSet (func->afpoints,setStepEPBp,STEP, - func->mod->asm_name); - } - } else { - if (srcMode == SRC_CMODE) { - /* for all execution points in this function */ - applyToSet(cctxt->func->cfpoints,setNextEPBp,NEXT, - cctxt->func->mod->c_name); - /* set a break point @ the current function's - exit */ - setBreakPoint (cctxt->func->sym->eaddr, CODE, NEXT , - nextBpCB, cctxt->func->mod->c_name, - cctxt->func->exitline); - - /* now break point @ callers execution points */ - if ((func = STACK_PPEEK(callStack))) { - applyToSet (func->cfpoints,setNextEPBp,NEXT , - func->mod->c_name); - /* set bp @ callers exit point */ - setBreakPoint (func->sym->eaddr, CODE, NEXT , - stepBpCB, func->mod->c_name, - func->exitline); - } - } else { - /* for all execution points in this function */ - applyToSet(cctxt->func->afpoints,setNextEPBp,NEXT, - cctxt->func->mod->asm_name); - /* set a break point @ the current function's - exit */ - setBreakPoint (cctxt->func->sym->eaddr, CODE, NEXT , - nextBpCB, cctxt->func->mod->asm_name, - cctxt->func->aexitline); - - /* now break point @ callers execution points */ - if ((func = STACK_PPEEK(callStack))) { - applyToSet (func->cfpoints,setNextEPBp,NEXT , - func->mod->asm_name); - /* set bp @ callers exit point */ - setBreakPoint (func->sym->eaddr, CODE, NEXT , - stepBpCB, func->mod->asm_name, - func->aexitline); - } - } - srcMode = origSrcMode; - simGo(-1); + /* if we are @ the end of a function then set + break points at execution points of the + function in the call stack... */ + if (cctxt->addr == cctxt->func->sym->eaddr) { + if ((func = STACK_PEEK(callStack))) { + if (srcMode == SRC_CMODE) + applyToSet (func->cfpoints,setStepEPBp,NEXT, + func->mod->c_name); + else + applyToSet (func->afpoints,setStepEPBp,NEXT, + func->mod->asm_name); + } + } else { + if (srcMode == SRC_CMODE) { + /* for all execution points in this function */ + applyToSet(cctxt->func->cfpoints,setNextEPBp,NEXT, + cctxt->func->mod->c_name); + /* set a break point @ the current function's + exit */ + setBreakPoint (cctxt->func->sym->eaddr, CODE, NEXT , + nextBpCB, cctxt->func->mod->c_name, + cctxt->func->exitline); + + /* now break point @ callers execution points */ + if ((func = STACK_PPEEK(callStack))) { + applyToSet (func->cfpoints,setNextEPBp,NEXT , + func->mod->c_name); + /* set bp @ callers exit point */ + setBreakPoint (func->sym->eaddr, CODE, NEXT , + stepBpCB, func->mod->c_name, + func->exitline); + } + } else { + /* for all execution points in this function */ + applyToSet(cctxt->func->afpoints,setNextEPBp,NEXT, + cctxt->func->mod->asm_name); + /* set a break point @ the current function's + exit */ + setBreakPoint (cctxt->func->sym->eaddr, CODE, NEXT , + nextBpCB, cctxt->func->mod->asm_name, + cctxt->func->aexitline); + + /* now break point @ callers execution points */ + if ((func = STACK_PPEEK(callStack))) { + applyToSet (func->cfpoints,setNextEPBp,NEXT , + func->mod->asm_name); + /* set bp @ callers exit point */ + setBreakPoint (func->sym->eaddr, CODE, NEXT , + stepBpCB, func->mod->asm_name, + func->aexitline); + } + } + } + doingSteps = 1; + simGo(1); + doingSteps = 0; showfull = 1; - } - srcMode = origSrcMode; - } + } return 0; } @@ -1310,16 +1636,17 @@ int cmdNext (char *s, context *cctxt) int cmdRun (char *s, context *cctxt) { char buff[10]; - if (!cctxt || !cctxt->func || !cctxt->func->mod) { + if (STACK_EMPTY(callStack)) { fprintf(stdout,"Starting program\n"); if ( ! simactive ) { fprintf(stdout,"No executable file specified.\nUse the \"file\" command.\n"); return 0; } + resetHitCount(); simGo(0); } else { - + fprintf(stdout, "The program being debugged has been started already.\n"); fprintf(stdout,"Start it from the beginning? (y or n) "); @@ -1328,6 +1655,7 @@ int cmdRun (char *s, context *cctxt) fgets(buff,sizeof(buff),stdin); if (toupper(buff[0]) == 'Y') { simReset(); + resetHitCount(); simGo(0); } } @@ -1364,11 +1692,11 @@ int cmdListSymbols (char *s, context *cctxt) sy->name, sy->size, sy->level, sy->block); printf(" isonstack:%d, isfunc:%d, offset:%d addr:%d\n", sy->isonstack, sy->isfunc, sy->offset, sy->addr); - printf(" eaddr:%d, addr_type:%c, type:%x etype:%x\n", + printf(" eaddr:%d, addr_type:%c, type:%p etype:%p\n", sy->eaddr, sy->addr_type, sy->type, sy->etype); printf(" scopetype:%c, sname:%s, rname:%s addrspace:%c\n", sy->scopetype, sy->sname, sy->rname, sy->addrspace); - printf(" next:%x\n", sy->next); + printf(" next:%p\n", sy->next); } ++i; sy = setNextItem(symbols); @@ -1395,19 +1723,17 @@ int cmdListFunctions (char *s, context *cctxt) printf("[functions]\n"); f = setFirstItem(functions); i = 0; - for (;;) { - if (f == NULL) - break; + while (f != NULL) { if (our_verbose) { - printf(" %d) sym:%x, fname:%s, modName:%s, mod:%x\n", i, + printf(" %d) sym:%p, fname:%s, modName:%s, mod:%p\n", i, f->sym, f->sym->name, f->modName, f->mod); printf(" entryline:%d, aentryline:%d, exitline:%d, aexitline:%d\n", f->entryline, f->aentryline, f->exitline, f->aexitline); - printf(" cfpoints:%x, afpoints:%x, laddr:%x, lline:%d\n", + printf(" cfpoints:%p, afpoints:%p, laddr:%x, lline:%d\n", f->cfpoints, f->afpoints, f->laddr, f->lline); } else { - printf("<%s>", f->modName); + printf("<%s>", f->sym->name); } ++i; f = setNextItem(functions); @@ -1417,7 +1743,7 @@ int cmdListFunctions (char *s, context *cctxt) } /*----------------------------------------------------------------- - cmdListModules - list functions. + cmdListModules - list modules. |-----------------------------------------------------------------*/ int cmdListModules (char *s, context *cctxt) { @@ -1444,7 +1770,7 @@ int cmdListModules (char *s, context *cctxt) m->cfullname, m->afullname, m->name); printf(" c_name:%s, asm_name:%s, ncLines:%d, nasmLines:%d\n", m->c_name, m->asm_name, m->ncLines, m->nasmLines); - printf(" cLines:%x, asmLines:%x\n", + printf(" cLines:%p, asmLines:%p\n", m->cLines, m->asmLines); } if (our_verbose >= 2) { @@ -1486,15 +1812,15 @@ static void infoSymbols(context *ctxt) { int our_verbose = 0; - printf("[context:%x] func:%x modName:%s addr:%x\n", + printf("[context:%p] func:%p modName:%s addr:%x\n", ctxt, ctxt->func, ctxt->modName, ctxt->addr); printf(" cline:%d asmline:%d block:%d level:%d\n", - ctxt->cline, ctxt->asmline, ctxt->level); + ctxt->cline, ctxt->asmline, ctxt->block, ctxt->level); - printf("[globals] currCtxt:%x, modules:%x, functions:%x symbols:%x\n", + printf("[globals] currCtxt:%p, modules:%p, functions:%p symbols:%p\n", currCtxt, modules, functions, symbols); - printf(" nStructs:%d, structs:%x, ssdirl:%s\n", + printf(" nStructs:%d, structs:%p, ssdirl:%s\n", nStructs, structs, ssdirl); /**************** modules *******************/ @@ -1512,7 +1838,7 @@ static void infoSymbols(context *ctxt) m->cfullname, m->afullname, m->name); printf(" c_name:%s, asm_name:%s, ncLines:%d, nasmLines:%d\n", m->c_name, m->asm_name, m->ncLines, m->nasmLines); - printf(" cLines:%x, asmLines:%x\n", + printf(" cLines:%p, asmLines:%p\n", m->cLines, m->asmLines); i = 0; if (m->cLines) { @@ -1557,11 +1883,11 @@ static void infoSymbols(context *ctxt) if (f == NULL) break; if (our_verbose) { - printf(" %d) sym:%x, modName:%s, mod:%x\n", i, + printf(" %d) sym:%p, modName:%s, mod:%p\n", i, f->sym, f->modName, f->mod); printf(" entryline:%d, aentryline:%d, exitline:%d, aexitline:%d\n", f->entryline, f->aentryline, f->exitline, f->aexitline); - printf(" cfpoints:%x, afpoints:%x, laddr:%x, lline:%d\n", + printf(" cfpoints:%p, afpoints:%p, laddr:%x, lline:%d\n", f->cfpoints, f->afpoints, f->laddr, f->lline); } ++i; @@ -1586,11 +1912,11 @@ static void infoSymbols(context *ctxt) s->name, s->size, s->level, s->block); printf(" isonstack:%d, isfunc:%d, offset:%d addr:%d\n", s->isonstack, s->isfunc, s->offset, s->addr); - printf(" eaddr:%d, addr_type:%c, type:%x etype:%x\n", + printf(" eaddr:%d, addr_type:%c, type:%p etype:%p\n", s->eaddr, s->addr_type, s->type, s->etype); printf(" scopetype:%c, sname:%s, rname:%s addrspace:%c\n", s->scopetype, s->sname, s->rname, s->addrspace); - printf(" next:%x\n", s->next); + printf(" next:%p\n", s->next); } ++i; s = setNextItem(symbols); @@ -1601,6 +1927,69 @@ static void infoSymbols(context *ctxt) } +/*-----------------------------------------------------------------*/ +/* infoRegisters - print register information */ +/*-----------------------------------------------------------------*/ +static void infoRegisters( int all, context *ctxt) +{ + static int regaddrs[] = {0x81,0x82,0x83,0xb8,0xd0,0xe0,0xf0,0}; + unsigned long val; + int i,j,*r; + + i = simGetValue (0xd0,'I',1); + fprintf(stdout,"IP : 0x%04X RegisterBank %d:\nR0-7:",ctxt->addr,(i>>3)&3); + for ( j = 0; j < 8 ; j++ ) + { + val = simGetValue (j,'R',1); + fprintf(stdout," 0x%02X",val); + } + fprintf(stdout,"\n"); + val = simGetValue (0xe0,'I',1); + fprintf(stdout,"ACC : 0x%02X %d %c\n",val,val,(isprint(val) ? val : '.')); + val = simGetValue (0xf0,'I',1); + fprintf(stdout,"B : 0x%02X %d %c\n",val,val,(isprint(val) ? val : '.')); + val = simGetValue (0x82,'I',2); + fprintf(stdout,"DPTR: 0x%04X %d\n",val,val); + val = simGetValue (0x81,'I',1); + fprintf(stdout,"SP : 0x%02X (0x%04X)\n",val,simGetValue (val-1,'B',2)); + fprintf(stdout,"PSW : 0x%02X | CY : %c | AC : %c | OV : %c | P : %c\n", + i,(i&0x80)?'1':'0',(i&0x40)?'1':'0',(i&4)?'1':'0',(i&1)?'1':'0'); + if ( all ) + { + fprintf(stdout,"Special Function Registers:\n"); + r = regaddrs; + for ( i = 0x80 ; i < 0x100 ; i++ ) + { + symbol *sym = NULL; + if ( *r && *r == i ) + { + /* skip normal registers */ + r++ ; + continue; + } + if (applyToSetFTrue(sfrsymbols,symWithAddr,i,'I',&sym)) + { + val = simGetValue (sym->addr,sym->addrspace,sym->size); + fprintf(stdout,"%s : 0x%02x",sym->name,val); + if ( !(i & 0x07 )) + { + for ( j = 0 ; j < 8 ; j++ ) + { + sym = NULL; + if (applyToSetFTrue(sfrsymbols,symWithAddr,i+j,'J',&sym)) + { + //val = simGetValue (sym->addr,sym->addrspace,sym->size); + fprintf(stdout," %s=%c",sym->name,(val&1)? '1':'0'); + } + val >>= 1; + } + } + fprintf(stdout,"\n"); + } + } + } +} + /*-----------------------------------------------------------------*/ /* infoStack - print call stack information */ /*-----------------------------------------------------------------*/ @@ -1611,12 +2000,14 @@ static void infoStack(context *ctxt) STACK_STARTWALK(callStack) ; while ((func = STACK_WALK(callStack))) { + Dprintf(D_break, ("break: infoStack: %s %p (%p)\n",func->sym->name, w_callStack,p_callStack)); - fprintf(stdout,"#%d 0x%04x %s () at %s:%d\n",i++, + fprintf(stdout,"#%d 0x%08x in %s () at %s:%d\n",i++, func->laddr,func->sym->name, - func->mod->c_name,func->lline); + func->mod->c_name,func->lline+1); } - + if ( !i ) + fprintf(stdout,"no stack.\n"); } /*-----------------------------------------------------------------*/ @@ -1625,25 +2016,9 @@ static void infoStack(context *ctxt) int cmdWhere(char *s, context *cctxt) { infoStack(cctxt); - showfull = 1; - return 0; -} - -/*-----------------------------------------------------------------*/ -/* cmdUp - Up command */ -/*-----------------------------------------------------------------*/ -int cmdUp(char *s, context *cctxt) -{ return 0; } -/*-----------------------------------------------------------------*/ -/* cmdDown - down command */ -/*-----------------------------------------------------------------*/ -int cmdDown(char *s, context *cctxt) -{ - return 0; -} static int infomode = 0; /*-----------------------------------------------------------------*/ @@ -1662,7 +2037,6 @@ int cmdInfo (char *s, context *cctxt) /* info frame same as frame */ if (strcmp(s,"frame") == 0) { cmdFrame (s,cctxt); - showfull = 1; return 0; } @@ -1671,7 +2045,51 @@ int cmdInfo (char *s, context *cctxt) cmdListSrc (s+4,cctxt); return 0; } - + if (strncmp(s,"source",6) == 0) + { + module *m; + if ( s[6] == 's' ) + { + int k = 0; + fprintf(stdout,"Source files for which symbols have been read in:\n\n"); + for (m = setFirstItem(modules); m ; m = setNextItem(modules)) + { + fprintf(stdout,"%s%s, %s",k ? ", ":"",m->cfullname, m->afullname); + k = 1; + } + fprintf(stdout,"\n"); + } + else + { + if (!cctxt || !cctxt->func || !cctxt->func->mod) + { + fprintf(stdout,"No source file loaded\n"); + return 0; + } + m = cctxt->func->mod; + fprintf(stdout,"Current source file is %s\n",m->c_name); + fprintf(stdout,"Located in %s\n",m->cfullname); + fprintf(stdout,"Contains %d lines.\nSource language is c.\n", + m->ncLines); + } + return 0; + } + if (strncmp(s,"functions",7) == 0) + { + function *f; + module *m = NULL; + fprintf(stdout,"All defined functions:\n"); + for ( f = setFirstItem(functions); f ; f = setNextItem(functions)) + { + if ( f->mod != m ) + { + m = f->mod; + fprintf(stdout,"\nFile %s\n", m->c_name); + } + fprintf(stdout,"%s();\n",f->sym->name); + } + return 0; + } /* info stack display call stack */ if (strcmp(s,"stack") == 0) { infoStack(cctxt); @@ -1681,18 +2099,15 @@ int cmdInfo (char *s, context *cctxt) /* info stack display call stack */ if (strcmp(s,"registers") == 0) { - fprintf(stdout,"%s",simRegs()); - return 0; + infoRegisters(0,cctxt); + return 0; } /* info stack display call stack */ - if (strcmp(s,"all-registers") == 0) { - fprintf(stdout,"%s",simRegs()); - fprintf(stdout,"Special Function Registers:\n"); - sendSim("ds 0x80 0x100\n"); - waitForSim(100,NULL); - fprintf(stdout,simResponse()); - return 0; + if (strcmp(s,"all-registers") == 0) + { + infoRegisters(1,cctxt); + return 0; } /* info stack display call stack */ @@ -1719,7 +2134,7 @@ int cmdInfo (char *s, context *cctxt) /* cmdQuit - quit debugging */ /*-----------------------------------------------------------------*/ int cmdQuit (char *s, context *cctxt) -{ +{ if (simactive) closeSimulator(); return 1; @@ -1729,25 +2144,27 @@ int cmdQuit (char *s, context *cctxt) /* cmdListSrc - list src */ /*-----------------------------------------------------------------*/ int cmdListSrc (char *s, context *cctxt) -{ +{ static int currline = 0; int i =0 ; int pline = 0; - int llines = listLines; + int llines = listlines; + function *func = NULL; + while (*s && isspace(*s)) s++; - + /* if the user has spcified line numer then the line number can be of the following formats LINE - just line number FILE:LINE - filename line number + FILE:LINE,LASTLINE + last line FUNCTION - list a function FILE:FUNCTION - function in file */ if (*s) { /* case a) LINE */ if (isdigit(*s)) { - sscanf(s,"%d",&pline); if (!cctxt || !cctxt->func || !cctxt->func->mod) { if (!list_mod) { fprintf(stdout,"Sdcdb fails to have a proper context at %d.\n", __LINE__); @@ -1756,11 +2173,20 @@ int cmdListSrc (char *s, context *cctxt) } else list_mod = cctxt->func->mod; + pline = strtol(s,&s,10) - 1; + if (s && (s = strchr(s,','))) + { + /* LINE,LASTLINE */ + llines = strtol(s+1,0,10); + if ( llines > 0 ) + llines -= pline+1; + else + llines = listlines; + } } else { char *bp; - function *func = NULL; - + /* if ':' present then FILE:LINE || FILE:FUNCTION */ if ((bp = strchr(s,':'))) { *bp = '\0'; @@ -1779,7 +2205,16 @@ int cmdListSrc (char *s, context *cctxt) return 0; } } - sscanf(bp,"%d",&pline); + pline = strtol(bp,&bp,10) - 1; + if (bp && (bp = strchr(bp,','))) + { + /* FILE:LINE,LASTLINE */ + llines = strtol(bp+1,0,10); + if ( llines > 0 ) + llines -= pline+1; + else + llines = listlines; + } } else { /* FILE:FUCTION */ if (!applyToSet(functions,funcWithNameModule,bp,s,&func)) { @@ -1798,18 +2233,28 @@ int cmdListSrc (char *s, context *cctxt) } else { /* FUNCTION */ + if (*s == '\'') + { + /* 'FUNCTION' */ + s++ ; + if ((bp = strrchr(s,'\''))) + { + *bp = '\0'; + } + + } if (!applyToSet(functions,funcWithName,s,&func)) { - fprintf(stderr,"Function \"%s\" not defined.\n",s); + fprintf(stderr,"Function \"%s\" not defined.\n",s); return 0; } else { list_mod = func->mod; if (srcMode == SRC_CMODE) { pline = func->entryline; - llines = func->exitline - func->entryline + 1; + llines = func->exitline - func->entryline + 1; } else { pline = func->aentryline; - llines = func->aexitline - func->aentryline + 1; + llines = func->aexitline - func->aentryline + 1; } } } @@ -1836,14 +2281,42 @@ int cmdListSrc (char *s, context *cctxt) fprintf(stdout,"Sdcdb fails to have a valid module context at %d.\n", __LINE__); return 0; } - - if (llines > listLines) llines = listLines; + if ( pline < 0 ) + return 0; if ( infomode ) { - fprintf(stdout,"Line %d of \"%s\" starts at address 0x%08x.\n",pline, - list_mod->c_name, list_mod->cLines[pline]->addr); + unsigned firstaddr , lastaddr ; + if ( pline >= list_mod->ncLines ) + pline = cctxt->cline; + firstaddr = lastaddr = list_mod->cLines[pline]->addr; + if (!func && cctxt && cctxt->func ) + func = cctxt->func; + fprintf(stdout,"Line %d of \"%s\" starts at address 0x%08x <%s+%d>", + pline+1, + list_mod->c_name, lastaddr, + func ? func->sym->name : "?", + func ? lastaddr -func->sym->addr : 0); + llines = pline +1; + for ( ; pline < list_mod->ncLines; pline++ ) + { + if ( list_mod->cLines[pline]->addr > lastaddr ) + { + lastaddr = list_mod->cLines[pline]->addr -1; + break; + } + } + fprintf(stdout," and ends at 0x%08x <%s+%d>.\n", + lastaddr, + func ? func->sym->name : "?", + func ? lastaddr -func->sym->addr : 0); infomode=0; + if ( func ) + fprintf(stdout,"\032\032%s:%d:1:beg:0x%08x\n", + func->mod->cfullname, + llines,firstaddr); + else + showfull=1; return 0; } for ( i = 0 ; i < llines ; i++ ) { @@ -1863,107 +2336,210 @@ int cmdListSrc (char *s, context *cctxt) return 0; } -static void setValBasic(symbol *sym, char *val) +static unsigned long getValBasic(symbol *sym, link *type, char *val) { - union - { - float f; + char *s; + union + { + float f; unsigned long val; long sval; struct { - short lo; - short hi; + unsigned short lo; + unsigned short hi; } i; unsigned char b[4]; }v; - if (IS_FLOAT(sym->type)) - v.f = strtof(val,NULL); + if (IS_FLOAT(type)) + v.f = strtod(val,NULL); else - if (IS_PTR(sym->type)) - v.sval = strtol(val,NULL,0); + if (IS_PTR(type)) + v.val = strtol(val,NULL,0); else { - if (IS_SPEC(sym->type) && IS_INTEGRAL(sym->type)) + if (IS_INTEGRAL(type)) { - if (IS_CHAR(sym->etype)) - { - v.b[0] = val[0]; + link *etype; + if ( type->next ) + etype = type->next; + else + etype = type; + if (IS_CHAR(etype)) + { + if (( s = strchr(val,'\''))) + { + if ( s[1] == '\\' ) + v.b[0] = strtol(s+2,NULL,8); + else + v.b[0] = s[1]; + } + else + { + v.b[0] = strtol(val,NULL,0); + } } else - if (IS_INT(sym->etype)) - if (IS_LONG(sym->etype)) - if (SPEC_USIGN(sym->etype)) - v.val = strtol(val,NULL,0); - else - v.sval = strtol(val,NULL,0); + if (IS_INT(etype)) + if (IS_LONG(etype)) + v.val = strtol(val,NULL,0); else v.i.lo = strtol(val,NULL,0); else - v.sval = strtol(val,NULL,0); - } + v.val = strtol(val,NULL,0); + } else - v.sval = strtol(val,NULL,0); + v.val = strtol(val,NULL,0); } - simSetValue(sym->addr,sym->addrspace,sym->size,v.sval); + return v.val; +} + +/*-----------------------------------------------------------------*/ +/* printFmtInteger - print value in bin,oct,dez or hex */ +/*-----------------------------------------------------------------*/ +static void printFmtInteger(char *deffmt,int fmt, long val, + int sign, int size) +{ + static char digits[] = + { + '0' , '1' , '2' , '3' , '4' , '5' , + '6' , '7' , '8' , '9' , 'a' , 'b' , + 'c' , 'd' , 'e' , 'f' , 'g' , 'h' + }; + static int radixOfFormat[] = { 0 , 2, 8 ,10, 16 }; + static int olenOfSize[] = { 0 , 3, 6 , 8, 11 }; + char buf[40]; + char negative = 0; + int charPos = 38; + int radix; + + if ( fmt == FMT_NON || fmt == FMT_DEZ ) + { + fprintf(stdout,deffmt,val); + return; + } + radix = radixOfFormat[fmt]; + + /* + if ( sign && val < 0 ) + negative = 1; + */ + + if (!negative) + val = -val; + + buf[39] = '\0'; + while (val <= -radix) + { + buf[charPos--] = digits[-(val % radix)]; + val = val / radix; + } + buf[charPos] = digits[-val]; + + switch ( fmt ) + { + case FMT_OCT: + radix = olenOfSize[size]; + break; + case FMT_HEX: + radix = size << 1; + break; + case FMT_BIN: + radix = size << 3; + break; + } + + while (charPos > 39 - radix ) + { + buf[--charPos] = '0'; + } + switch ( fmt ) + { + case FMT_OCT: + if ( buf[charPos] != '0' ) + buf[--charPos] = '0'; + break; + case FMT_HEX: + buf[--charPos] = 'x'; + buf[--charPos] = '0'; + break; + } + if (negative) { + buf[--charPos] = '-'; + } + fputs(&buf[charPos],stdout); } /*-----------------------------------------------------------------*/ /* printValBasic - print value of basic types */ /*-----------------------------------------------------------------*/ -static void printValBasic(symbol *sym,unsigned addr,char mem, int size) -{ - union { - float f; - unsigned long val; - long sval; - struct { - short lo; - short hi; - } i; - unsigned char b[4]; - }v; +static void printValBasic(symbol *sym, link *type, + char mem, unsigned addr,int size, int fmt) +{ union { - unsigned char b[4]; - }v1; - + float f; + unsigned long val; + long sval; + struct { + unsigned short lo; + unsigned short hi; + } i; + unsigned char b[4]; + }v; + v.val = simGetValue(addr,mem,size); /* if this a floating point number then */ - if (IS_FLOAT(sym->type)) - fprintf(stdout,"%f",v.f); + if (IS_FLOAT(type)) + fprintf(stdout,"%f",v.f); else - if (IS_PTR(sym->type)) - fprintf(stdout,"0x%x",v.val); + if (IS_PTR(type)) + fprintf(stdout,"0x%*x",size<<1,v.val); else - if (IS_SPEC(sym->type) && IS_INTEGRAL(sym->type)) { - if (IS_CHAR(sym->etype)) - { - if ( isprint(v.val)) - fprintf(stdout,"%d 0x%x '%c'",v.val,v.val,v.val); + if (IS_INTEGRAL(type)) + { + link *etype; + if ( type->next ) + etype = type->next; else - fprintf(stdout,"%d 0x%x '\\%o'",v.val,v.val,v.val); - } - else - if (IS_INT(sym->etype)) - if (IS_LONG(sym->etype)) - if (SPEC_USIGN(sym->etype)) - fprintf(stdout,"%d 0x%x",v.val,v.val); - else - fprintf(stdout,"%d 0x%x",v.sval,v.sval); - else - fprintf(stdout,"%d 0x%x",v.i.lo,v.i.lo); - else - fprintf(stdout,"0x%x",v.val); + etype = type; + if (IS_CHAR(etype)) + { + if ( isprint(v.val)) + printFmtInteger((SPEC_USIGN(etype)?"0x%02x":"'%c'"), + fmt,(long)v.val,0,size); + else + printFmtInteger((SPEC_USIGN(etype)?"0x%02x":"'\\%o'"), + fmt,(long)v.val,0,size); + } + else + { + if (IS_INT(etype)) + if (IS_LONG(etype)) + if (SPEC_USIGN(etype)) + printFmtInteger("%u",fmt,(long)v.val,0,size); + else + printFmtInteger("%d",fmt,(long)v.sval,1,size); + else + if (SPEC_USIGN(etype)) + printFmtInteger("%u",fmt,(long)v.i.lo,0,size); + else + printFmtInteger("%d",fmt,(long)v.i.lo,1,size); + else + { + if (IS_BITVAR(etype)) + fprintf(stdout,"%c",(v.val?'1':'0')); + else + fprintf(stdout,"0x%0*x",size<<1,v.val); + } + } } else - fprintf(stdout,"0x%x",v.val); - - + fprintf(stdout,"0x%0*x",size<<1,v.val); } /*-----------------------------------------------------------------*/ /* printValFunc - prints function values */ /*-----------------------------------------------------------------*/ -static void printValFunc (symbol *sym) +static void printValFunc (symbol *sym, int fmt) { fprintf(stdout,"print function not yet implemented"); } @@ -1971,40 +2547,43 @@ static void printValFunc (symbol *sym) /*-----------------------------------------------------------------*/ /* printArrayValue - will print the values of array elements */ /*-----------------------------------------------------------------*/ -static void printArrayValue (symbol *sym, char space, unsigned int addr) +static void printArrayValue (symbol *sym, link *type, + char space, unsigned int addr, int fmt) { - link *elem_type = sym->type->next; + link *elem_type = type->next; int i; - - fprintf(stdout," { "); - for (i = 0 ; i < DCL_ELEM(sym->type) ; i++) { + + fprintf(stdout,"{"); + for (i = 0 ; i < DCL_ELEM(type) ; i++) { if (IS_AGGREGATE(elem_type)) { - printValAggregates(sym,elem_type,space,addr); + printValAggregates(sym,elem_type,space,addr,fmt); } else { - printValBasic(sym,addr,space,getSize(elem_type)); + printValBasic(sym,elem_type,space,addr,getSize(elem_type),fmt); } addr += getSize(elem_type); - if (i != DCL_ELEM(sym->type) -1) + if (i != DCL_ELEM(type) -1) fprintf(stdout,","); } - fprintf(stdout,"}"); + fprintf(stdout,"}"); } /*-----------------------------------------------------------------*/ /* printStructValue - prints structures elements */ /*-----------------------------------------------------------------*/ -static void printStructValue (symbol *sym,link *type, char space, unsigned int addr) +static void printStructValue (symbol *sym, link *type, + char space, unsigned int addr, int fmt) { symbol *fields = SPEC_STRUCT(type)->fields; - + int first = 1; fprintf(stdout," { "); while (fields) { - fprintf(stdout,"%s = ",fields->name); - if (IS_AGGREGATE(fields->type)) { - printValAggregates(fields,fields->type,space, addr); + fprintf(stdout,"%s%s = ",(first ? "": ", "),fields->name); + first = 0; + if (IS_AGGREGATE(fields->type)) { + printValAggregates(fields,fields->type,space, addr, fmt); } else { - printValBasic(fields,addr,space,getSize(fields->type)); + printValBasic(fields,fields->type,space,addr,getSize(fields->type), fmt); } addr += getSize(fields->type); fields = fields->next; @@ -2015,97 +2594,203 @@ static void printStructValue (symbol *sym,link *type, char space, unsigned int a /*-----------------------------------------------------------------*/ /* printValAggregates - print value of aggregates */ /*-----------------------------------------------------------------*/ -static void printValAggregates (symbol *sym, link *type,char space,unsigned int addr) +static void printValAggregates (symbol *sym, link *type, + char space,unsigned int addr, int fmt) { if (IS_ARRAY(type)) { - printArrayValue(sym, space, addr); + printArrayValue(sym, type, space, addr, fmt); return ; } - if (IS_STRUCT(type)) { - printStructValue(sym,sym->type,space, addr); - return; - } + if (IS_STRUCT(type)) { + printStructValue(sym, type, space, addr, fmt); + return; + } } /*-----------------------------------------------------------------*/ -/* setSymValue - set value of a symbol */ +/* printOrSetSymValue - print or set value of a symbol */ /*-----------------------------------------------------------------*/ -static void setSymValue(symbol *sym, char *val, context *cctxt) +static int printOrSetSymValue (symbol *sym, context *cctxt, + int flg, int dnum, int fmt, char *rs, + char *val, char cmp ) { - if (sym->isonstack) + static char fmtChar[] = " todx "; + static int stack = 1; + symbol *fields; + link *type; + unsigned int addr; + int size, n; + char *s, *s2; + char save_ch, save_ch2; + + /* if it is on stack then compute address & fall thru */ + if (sym->isonstack) { symbol *bp = symLookup("bp",cctxt); - if (!bp) + if (!bp) { fprintf(stdout,"cannot determine stack frame\n"); - return ; + return 1; } sym->addr = simGetValue(bp->addr,bp->addrspace,bp->size) - + sym->offset ; - } - /* arrays & structures first */ - if (IS_AGGREGATE(sym->type)) - { - } - else - /* functions */ - if (IS_FUNC(sym->type)) - { + + sym->offset ; } - else - { - setValBasic(sym,val); - } -} - -/*-----------------------------------------------------------------*/ -/* printSymValue - print value of a symbol */ -/*-----------------------------------------------------------------*/ -static void printSymValue (symbol *sym, context *cctxt, int flg, int dnum) -{ - static int stack = 1; - unsigned long val; - /* if it is on stack then compute address & fall thru */ - if (sym->isonstack) { - symbol *bp = symLookup("bp",cctxt); - if (!bp) { - fprintf(stdout,"cannot determine stack frame\n"); - return ; - } - sym->addr = simGetValue(bp->addr,bp->addrspace,bp->size) - + sym->offset ; - } - /* get the value from the simulator and print it */ switch (flg) { - case 0: + case 0: default: break; - case 1: + case 1: fprintf(stdout,"$%d = ",stack++); break; - case 2: - fprintf(stdout,"%d: %s = ",dnum,sym->name); + case 2: + fprintf(stdout,"%d: ", dnum); + if ( fmt != FMT_NON ) + fprintf(stdout,"/%c ",fmtChar[fmt]); + fprintf(stdout,"%s%s = ",sym->name,rs); break; } + + addr = sym->addr; + type = sym->type; + size = sym->size; + + while ( *rs ) + { + if ( *rs == '[' && IS_ARRAY(type)) + { + s = rs+1; + while ( *rs && *rs != ']' ) rs++ ; + save_ch = *rs; + *rs = '\0' ; + if ( ! isdigit(*s )) + { + /* index seems a variable */ + for ( s2 = s; *s2 && ( isalnum( *s2 ) || *s2 == '_'); s2++ ); + save_ch2 = *s2; + if ( *s2 ) + *s2 = '\0'; + fields = symLookup(s,cctxt); + *s2 = save_ch2; + if ( ! fields ) + { + fprintf(stdout,"Unknown variable \"%s\" for index.\n", s); + return 1; + } + /* arrays & structures first */ + if (! IS_INTEGRAL(fields->type)) + { + fprintf(stdout,"Wrong type of variable \"%s\" for index \n", s); + return 1; + } + n = simGetValue(fields->addr,fields->addrspace,getSize(fields->type)); + } + else + { + n = strtol(s,0,0); + } + if ( n < 0 || n >= DCL_ELEM(type)) + { + fprintf(stdout,"Wrong index %d.\n", n); + return 1; + } + type = type->next; + size = getSize(type); + addr += size * n; + *rs++ = save_ch; + } + else if ( *rs == '.' && IS_STRUCT(type)) + { + s = rs+1; + /* search structure element */ + for ( rs = s; *rs && ( isalnum( *rs ) || *rs == '_'); rs++ ); + save_ch = *rs; + if ( *rs ) + *rs = '\0'; + for (fields = SPEC_STRUCT(type)->fields; fields; fields = fields->next) + { + if (!(strcmp(s,fields->name))) + break; + } + *rs = save_ch; + if ( ! fields ) + { + fprintf(stdout,"Unknown field \"%s\" of structure\n", s); + return 1; + } + type = fields->type; + size = getSize(type); + addr += fields->offset; + } + else + break; + } + /* arrays & structures first */ - if (IS_AGGREGATE(sym->type)) - printValAggregates(sym,sym->type,sym->addrspace,sym->addr); + if (IS_AGGREGATE(type)) + { + if ( val ) + { + fprintf(stdout,"Cannot set/compare aggregate variable\n"); + return 1; + } + else + printValAggregates(sym,type,sym->addrspace,addr,fmt); + } else /* functions */ - if (IS_FUNC(sym->type)) - printValFunc(sym); - else - printValBasic(sym,sym->addr,sym->addrspace,sym->size); + if (IS_FUNC(type)) + { + if ( !val ) + printValFunc(sym,fmt); + else + return 1; + } + else + { + if ( val ) + { + unsigned long newval; + newval = getValBasic(sym,type,val); + + if ( cmp ) + { + unsigned long lval; + lval = simGetValue(addr,sym->addrspace,size); + switch ( cmp ) + { + case '<' : return ( lval < newval ? 1:0 ); break; + case '>' : return ( lval > newval ? 1:0 ); break; + case 'l' : return ( lval <= newval ? 1:0 ); break; + case 'g' : return ( lval >= newval ? 1:0 ); break; + case '=' : return ( lval == newval ? 1:0 ); break; + case '!' : return ( lval != newval ? 1:0 ); break; + } + } + else + { + if ( sym->addrspace == 'I' && addr == 0xb8 ) + { + /* Symbol with address of IP */ + if ( cctxt ) cctxt->addr = newval; + simSetPC(cctxt->addr); + } + else + simSetValue(addr,sym->addrspace,size,newval); + return 1; + } + } + else + printValBasic(sym,type,sym->addrspace,addr,size,fmt); + } if ( flg > 0 ) fprintf(stdout,"\n"); - //fprintf(stdout,"(BASIC %x,%c,%d)\n",sym->addr,sym->addrspace,sym->size); - + return 0; } /*-----------------------------------------------------------------*/ @@ -2115,7 +2800,7 @@ static void printStructInfo (structdef *sdef) { symbol *field = sdef->fields ; int i = 0 ; - + while (field) { i += field->offset; field = field->next; @@ -2151,7 +2836,7 @@ static void printTypeInfo(link *p) printTypeInfo (p->next); fprintf(stdout,"[%d]",DCL_ELEM(p)); break; - + case IPOINTER: case PPOINTER: case POINTER: @@ -2168,17 +2853,17 @@ static void printTypeInfo(link *p) printTypeInfo( p->next); fprintf(stdout,"(_code *)"); break; - + case GPOINTER: printTypeInfo( p->next); fprintf(stdout,"(_generic *)"); - break; + break; } } else { switch (SPEC_NOUN(p)) { /* depending on the specifier type */ case V_INT: - (IS_LONG(p) ? fputs("long ",stdout) : - ( IS_SHORT(p) ? fputs("short ",stdout) : + (IS_LONG(p) ? fputs("long ",stdout) : + ( IS_SHORT(p) ? fputs("short ",stdout) : fputs("int ",stdout))) ; break; case V_FLOAT: @@ -2202,32 +2887,62 @@ static void printTypeInfo(link *p) break; case V_BIT: - fprintf(stdout,": %d" ,SPEC_BLEN(p)); + fprintf(stdout,": %d" ,SPEC_BLEN(p)); break; } } } +/*-----------------------------------------------------------------*/ +/* conditionIsTrue - compare variable with constant value */ +/*-----------------------------------------------------------------*/ +int conditionIsTrue( char *s, context *cctxt) +{ + symbol *sym = NULL; + int fmt; + char *rs, *dup, cmp_char; + dup = s = Safe_strdup(s); + if ( !( rs = preparePrint(s, cctxt, &fmt, &sym )) || !sym) + fmt = 1; + else if (!( s = strpbrk(rs,"<>=!"))) + fmt = 1; + else + { + cmp_char = *s; + *s++ = '\0'; + if ( *s == '=' ) + { + /* if <= or >= an other char is used + * == or != not checked in switch + */ + switch( cmp_char ) + { + case '>': cmp_char = 'g' ; break; + case '<': cmp_char = 'l' ; break; + } + s++ ; + } + while (isspace(*s)) *s++ = '\0'; + fmt = printOrSetSymValue(sym,cctxt,0,0,0,rs,s,cmp_char); + } + Safe_free(dup); + return fmt; +} + /*-----------------------------------------------------------------*/ /* cmdPrint - print value of variable */ /*-----------------------------------------------------------------*/ int cmdPrint (char *s, context *cctxt) -{ +{ symbol *sym ; - char *bp = s+strlen(s) -1; - - while (isspace(*s)) s++; - if (!*s) return 0; - while (isspace(*bp)) bp--; - bp++ ; - *bp = '\0'; + int fmt; + char *rs; + if ( !( rs = preparePrint(s, cctxt, &fmt, &sym ))) + return 0; - if ((sym = symLookup(s,cctxt))) { - printSymValue(sym,cctxt,1,0); - } else { - fprintf(stdout, - "No symbol \"%s\" in current context.\n", - s); + if ( sym ) + { + printOrSetSymValue(sym,cctxt,1,0,fmt,rs,NULL,'\0'); } return 0; } @@ -2236,32 +2951,20 @@ int cmdPrint (char *s, context *cctxt) /* cmdOutput - print value of variable without number and newline */ /*-----------------------------------------------------------------*/ int cmdOutput (char *s, context *cctxt) -{ +{ symbol *sym ; - char *bp = s+strlen(s) -1; - - while (isspace(*s)) s++; - if (!*s) return 0; - while (isspace(*bp)) bp--; - bp++ ; - *bp = '\0'; + int fmt; + char *rs; + if ( !( rs = preparePrint(s, cctxt, &fmt, &sym ))) + return 0; - if ((sym = symLookup(s,cctxt))) { - printSymValue(sym,cctxt,0,0); - } else { - fprintf(stdout, - "No symbol \"%s\" in current context.", - s); + if ( sym ) + { + printOrSetSymValue(sym,cctxt,0,0,fmt,rs,NULL,'\0'); } return 0; } -typedef struct _dsymbol -{ - char *name; - int dnum; -} dsymbol; - /** find display entry with this number */ DEFSETFUNC(dsymWithNumber) @@ -2289,10 +2992,11 @@ void displayAll(context *cctxt) return; for (dsym = setFirstItem(dispsymbols); dsym ; - dsym = setNextItem(dispsymbols)) + dsym = setNextItem(dispsymbols)) { if ( (sym = symLookup(dsym->name,cctxt))) - printSymValue(sym,cctxt,2,dsym->dnum); + printOrSetSymValue(sym,cctxt,2,dsym->dnum,dsym->fmt, + dsym->rs,NULL,'\0'); } } @@ -2300,33 +3004,26 @@ void displayAll(context *cctxt) /* cmdDisplay - display value of variable */ /*-----------------------------------------------------------------*/ int cmdDisplay (char *s, context *cctxt) -{ - symbol *sym ; - char *bp = s+strlen(s) -1; +{ static int dnum = 1; - - while (isspace(*s)) s++; - if (!*s) + symbol *sym ; + int fmt; + char *rs; + if ( !( rs = preparePrint(s, cctxt, &fmt, &sym ))) { displayAll(cctxt); return 0; } - while (isspace(*bp)) bp--; - bp++ ; - *bp = '\0'; - if ((sym = symLookup(s,cctxt))) + if ( sym ) { dsymbol *dsym = (dsymbol *)Safe_calloc(1,sizeof(dsymbol)); dsym->dnum = dnum++ ; dsym->name = sym->name; + dsym->fmt = fmt; + dsym->rs = gc_strdup(rs); addSetHead(&dispsymbols,dsym); } - else - { - fprintf(stdout,"No symbol \"%s\" in current context.\n", - s); - } return 0; } @@ -2334,26 +3031,35 @@ int cmdDisplay (char *s, context *cctxt) /* cmdUnDisplay - undisplay value of variable */ /*-----------------------------------------------------------------*/ int cmdUnDisplay (char *s, context *cctxt) -{ +{ dsymbol *dsym; int dnum; while (isspace(*s)) s++; if (!*s) { + for (dsym = setFirstItem(dispsymbols); + dsym; + dsym = setNextItem(dispsymbols)) + { + Safe_free(dsym->rs); + Safe_free(dsym); + } deleteSet(&dispsymbols); return 0; } while ( s && *s ) { dnum = strtol(s,&s,10); - if (applyToSetFTrue(dispsymbols,dsymWithNumber,dnum,&dsym)) + if (applyToSetFTrue(dispsymbols,dsymWithNumber,dnum,&dsym)) { deleteSetItem(&dispsymbols,dsym); - } + Safe_free(dsym->rs); + Safe_free(dsym); + } else { - fprintf(stdout,"Arguments must be display numbers.\n"); + fprintf(stdout,"Arguments must be display numbers.\n"); } } return 0; @@ -2363,7 +3069,7 @@ int cmdUnDisplay (char *s, context *cctxt) /* cmdPrintType - print type of a variable */ /*-----------------------------------------------------------------*/ int cmdPrintType (char *s, context *cctxt) -{ +{ symbol *sym ; char *bp = s+strlen(s) -1; @@ -2381,17 +3087,17 @@ int cmdPrintType (char *s, context *cctxt) "No symbol \"%s\" in current context.\n", s); } - return 0; + return 0; } /*-----------------------------------------------------------------*/ /* cmdClrUserBp - clear user break point */ /*-----------------------------------------------------------------*/ int cmdClrUserBp (char *s, context *cctxt) -{ - char *bp ; +{ + char *bp ; function *func = NULL; - + /* clear break point location specification can be of the following forms a) - break point at current location @@ -2408,7 +3114,7 @@ int cmdClrUserBp (char *s, context *cctxt) /* white space skip */ while (*s && isspace(*s)) s++; - + /* null terminate it after stripping trailing blanks*/ bp = s + strlen(s); while (bp != s && isspace(*bp)) bp--; @@ -2420,12 +3126,12 @@ int cmdClrUserBp (char *s, context *cctxt) if (! *s ) { /* if current context is known */ - if (cctxt->func) + if (cctxt->func) /* clear the break point @ current location */ clearUSERbp (cctxt->addr); else fprintf(stderr,"No default breakpoint address now.\n"); - + goto ret ; } @@ -2437,64 +3143,63 @@ int cmdClrUserBp (char *s, context *cctxt) /* if current context not present then we must get the module which has main & set the break point @ line number provided - of that module : if current context known then set the bp - at the line number given for the current module + of that module : if current context known then set the bp + at the line number given for the current module */ if (cctxt->func) { if (!cctxt->func->mod) { if (!applyToSet(functions,funcWithName,"main")) fprintf(stderr,"Function \"main\" not defined.\n"); - else + else clearBPatModLine(func->mod,line); - } else - clearBPatModLine(cctxt->func->mod,line); + } else + clearBPatModLine(cctxt->func->mod,line); } - + goto ret; } if ((bp = strchr(s,':'))) { - + module *mod = NULL; *bp = '\0'; - + if (!applyToSet(modules,moduleWithCName,s,&mod)) { fprintf (stderr,"No source file named %s.\n",s); goto ret; } /* case c) filename:lineno */ - if (isdigit(*(bp +1))) { - - clearBPatModLine (mod,atoi(bp+1)); + if (isdigit(*(bp +1))) { + + clearBPatModLine (mod,atoi(bp+1)); goto ret; - + } /* case d) filename:function */ - if (!applyToSet(functions,funcWithNameModule,bp+1,s,&func)) - fprintf(stderr,"Function \"%s\" not defined.\n",bp+1); + if (!applyToSet(functions,funcWithNameModule,bp+1,s,&func)) + fprintf(stderr,"Function \"%s\" not defined.\n",bp+1); else clearBPatModLine (mod,func->entryline); - + goto ret; } - + /* case e) function */ if (!applyToSet(functions,funcWithName,s,&func)) - fprintf(stderr,"Function \"%s\" not defined.\n",s); + fprintf(stderr,"Function \"%s\" not defined.\n",s); else clearBPatModLine(func->mod,func->entryline); - ret: - return 0; + ret: + return 0; } - /*-----------------------------------------------------------------*/ /* cmdSimulator - send command to simulator */ /*-----------------------------------------------------------------*/ int cmdSimulator (char *s, context *cctxt) -{ +{ char tmpstr[82]; if (strlen(s) > 80) { @@ -2509,23 +3214,103 @@ int cmdSimulator (char *s, context *cctxt) return 0; } +void setMainContext() +{ + function *func = NULL; + currentFrame = 0; + if (!applyToSet(functions,funcWithName,"_main",&func) && + !applyToSet(functions,funcWithName,"main",&func)) + return; + + discoverContext (func->sym->addr, func); +} + +function *needExtraMainFunction() +{ + function *func = NULL; + if (!applyToSet(functions,funcWithName,"_main",&func)) + { + if (applyToSet(functions,funcWithName,"main",&func)) + { + return func; + } + } + return NULL; +} + +static void printFrame() +{ + int i; + function *func = NULL; + function *lastfunc = NULL; + + if ( currentFrame < 0 ) + { + currentFrame = 0; + fprintf(stdout,"Bottom (i.e., innermost) frame selected; you cannot go down.\n"); + return; + } + STACK_STARTWALK(callStack) ; + for ( i = 0; i <= currentFrame ; i++ ) + { + func = STACK_WALK(callStack); + if ( !func ) + { + currentFrame = i-1; + fprintf(stdout,"Initial frame selected; you cannot go up.\n"); + return; + } + } + fprintf(stdout,"#%d 0x%08x in %s () at %s:%d\n", + currentFrame,func->laddr,func->sym->name,func->mod->c_name,func->lline+1); + fprintf(stdout,"\032\032%s:%d:1:beg:0x%08x\n", + func->mod->cfullname,func->lline+1,func->laddr); + + discoverContext (func->laddr, func); +} + + +/*-----------------------------------------------------------------*/ +/* cmdUp - Up command */ +/*-----------------------------------------------------------------*/ +int cmdUp(char *s, context *cctxt) +{ + while (isspace(*s)) s++; + if ( *s ) + currentFrame += strtol(s,0,10); + else + currentFrame++ ; + + printFrame(); + return 0; +} + +/*-----------------------------------------------------------------*/ +/* cmdDown - down command */ +/*-----------------------------------------------------------------*/ +int cmdDown(char *s, context *cctxt) +{ + while (isspace(*s)) s++; + if ( *s ) + currentFrame -= strtol(s,0,10); + else + currentFrame-- ; + + printFrame(); + return 0; +} /*-----------------------------------------------------------------*/ /* cmdFrame - Frame command */ /*-----------------------------------------------------------------*/ int cmdFrame (char *s, context *cctxt) -{ - function *func ; - - if ((func = STACK_PEEK(callStack))) { - fprintf(stdout,"#0 %s () at %s:%d\n", - func->sym->name,func->mod->c_name,cctxt->cline); +{ + function *func = NULL; + int framenr = 0; - if (cctxt->cline < func->mod->ncLines) - fprintf(stdout,"%d\t%s", - cctxt->cline, - func->mod->cLines[cctxt->cline]->src); - } else - fprintf(stdout,"No stack.\n"); + while (isspace(*s)) s++; + if ( *s ) + currentFrame = strtol(s,0,10); + printFrame(); return 0; } @@ -2534,24 +3319,25 @@ int cmdFrame (char *s, context *cctxt) /*-----------------------------------------------------------------*/ int cmdFinish (char *s, context *ctxt) { - if (!ctxt || ! ctxt->func) { + if (STACK_EMPTY(callStack)) { fprintf(stdout,"The program is not running.\n"); return 0; } if (srcMode == SRC_CMODE) { - setBreakPoint (ctxt->func->sym->eaddr, CODE, STEP, - stepBpCB, ctxt->func->mod->c_name, + setBreakPoint (ctxt->func->sym->eaddr, CODE, STEP, + stepBpCB, ctxt->func->mod->c_name, ctxt->func->exitline); } else { - setBreakPoint (ctxt->func->sym->eaddr, CODE, STEP, - stepBpCB, ctxt->func->mod->asm_name, + setBreakPoint (ctxt->func->sym->eaddr, CODE, STEP, + stepBpCB, ctxt->func->mod->asm_name, ctxt->func->aexitline); } simGo(-1); + showfull = 1; return 0; - + } @@ -2567,7 +3353,7 @@ int cmdShow (char *s, context *cctxt) fputs(copying,stdout); return 0; } - + if (strcmp(s,"warranty") == 0) { fputs(warranty,stdout); return 0;