📄 debug.c
字号:
*seq = ch - '@';for (i=0;i<len;i++) { ch = readc(fd,msg); csum += ch; if (msg) msg[i] = ch; }if (msg) msg[i] = 0;rsum = readc(fd,msg) - '@';rsum = (rsum<<6) + (readc(fd,msg) - '@');rsum = (rsum<<6) + (readc(fd,msg) - '@');if (Vflag) fprintf(dfp,"GetPkt: fd=%d seq=%d msg=%s\n",fd,*seq,msg);if (rsum != csum) { if (vflag) fprintf(dfp,"error: csum expected %x actual %x\n",rsum,csum); return(-1); }return(type);}/************************************************************** static readc(fd,msg)*/static readc(fd,msg)int fd;char *msg;{char ch;int n,i;for (i=0;;i++) { if (msg) break; /* it's not an ACK */ if (i > TIMEOUT) { if (vflag) fprintf(dfp,"timeout\n"); longjmp(timeout,1); } n = ioctl_fionread(fd); if (n > 0) break; } read(fd,&ch,1);if (ch == CNTRL('V')) longjmp(pktstart,1);return(ch);}/************************************************************** static void do_req(fd,ac,av) handle a dbx request* av[0]=pid av[1]=req av[2]=addr av[3]=data*/static void do_req(fd,ac,av)int fd,ac;char *av[];{Ulong adr,adr2,dat,val;RegRec *rp;int i,code,rtn;char msg[80],*rname;if (ac < 4 || ac > 5) { fprintf(dfp,"ac=%d: "); for (i=0;i<ac;i++) fprintf(dfp,"av[%d]=%s ",i,av[i]); fprintf(dfp,"\n"); return; }if (strlen(av[1]) != 1) { fprintf(dfp,"unknown request type %s\n",av[1]); return; }atob(&adr,av[2],0);atob(&dat,av[3],0); switch (av[1][0]) { case 'i' : /* read Ispace */ case 'd' : /* read Dspace */ val = read_target(XT_MEM,adr,4); sprintf(msg,"%s %s 0x0 0x%x",av[0],av[1],val); putmsg(fd,&myseq,msg); break; case 'h' : /* read half-word */ val = read_target(XT_MEM,adr,2); sprintf(msg,"%s %s 0x0 0x%x",av[0],av[1],val); putmsg(fd,&myseq,msg); break; case 'p' : /* read byte */ val = read_target(XT_MEM,adr,1); sprintf(msg,"%s %s 0x0 0x%x",av[0],av[1],val); putmsg(fd,&myseq,msg); break; case 'r' : /* read reg */ if (adr <= 31) val = getGpr(adr); else if (adr <= 63) val = 0; else { switch (adr) { case 96 : rname="pc"; break; case 97 : rname="cause"; break; case 98 : rname="hi"; break; case 99 : rname="lo"; break; case 100 : rname="0"; break; /* fcsr */ case 101 : rname="0"; break; /* feir */ default : rname="0"; break; } val = getRegVal(findRegRec(rname,0)); } sprintf(msg,"%s %s 0x0 0x%x",av[0],av[1],val); putmsg(fd,&myseq,msg); break; case 'g' : /* read multiple regs */ for (i=0;i<32;i++) { if (adr&1) val = getGpr(i); else continue; sprintf(msg,"%s %s 0x0 0x%x",av[0],av[1],val); putmsg(fd,&myseq,msg); adr >>= 1; } break; case 'I' : /* write Ispace */ case 'D' : /* write Dspace */ val = read_target(XT_MEM,adr,4); write_target(XT_MEM,adr,dat,4); sprintf(msg,"%s %s 0x0 0x%x",av[0],av[1],val); putmsg(fd,&myseq,msg);#if 0 /* it would be nice. But gdb only uses 'D' */ if (av[1][0] == 'I') flush_target(ICACHE);#else flush_target(ICACHE);#endif break; case 'H' : /* write half-word */ val = read_target(XT_MEM,adr,2); write_target(XT_MEM,adr,dat,2); sprintf(msg,"%s %s 0x0 0x%x",av[0],av[1],val); putmsg(fd,&myseq,msg); break; case 'P' : /* write byte */ val = read_target(XT_MEM,adr,1); write_target(XT_MEM,adr,dat,1); sprintf(msg,"%s %s 0x0 0x%x",av[0],av[1],val); putmsg(fd,&myseq,msg); break; case 'R' : /* write reg */ if (adr <= 31) { val = getGpr(adr); putGpr(adr,dat); } else if (adr <= 63) val = 0; /* Fpr */ else { switch (adr) { case 96 : rname="pc"; break; case 97 : rname="cause"; break; case 98 : rname="hi"; break; case 99 : rname="lo"; break; case 100 : rname="0"; break; /* fcsr */ case 101 : rname="0"; break; /* feir */ default : rname="0"; break; } rp = findRegRec(rname,0); val = getRegVal(rp); putRegVal(rp,dat); } sprintf(msg,"%s %s 0x0 0x%x",av[0],av[1],val); putmsg(fd,&myseq,msg); break; case 's' : /* step */ /* optional addr */ if (adr != 1) putPc(adr); run_target(4,0,1); break; case 'c' : /* continue */ /* optional addr */ if (adr != 1) putPc(adr); run_target(3,0); break; case 'x' : /* exit */ gdbmode = 0; close(hostfd); /* 990304 */ if (verbose) fprintf(dfp,"exiting debug mode\n"); printf(" break!\n"); longjmp(intrbuf,2); break; /* addr */ case 'B' : /* <addr> set ibpt */ code = 0; rtn = setbp_target(-1,BPTYPE_PC,adr,0,0); if (rtn < 0) { code = 0-rtn; val = 0; } else {val = rtn&0xffff; code = rtn>>16;} sprintf(msg,"%s %s 0x%x 0x%x",av[0],av[1],val,code); putmsg(fd,&myseq,msg); break; case 'b' : /* <bptn> 0x0 clear bpt */ clrbp_target(adr); code = 0; sprintf(msg,"%s %s 0x0 0x%x",av[0],av[1],code); putmsg(fd,&myseq,msg); break; case 'A' : /* set daccess bpt */ /* <addr1> <type> [<addr2> [<value>]] */ /* adr dat av[4] av[5] */ if (ac >= 5) atob(&adr2,av[4],0); else adr2 = 0; if (ac >= 6) { atob(&val,av[5],0); dat |= 4; } dat <<= 4; rtn = setbp_target(-1,dat|BPTYPE_DATA,adr,adr2,val); if (rtn < 0) { code = 0-rtn; val = 0; } else {val = rtn&0xffff; code = rtn>>16;} sprintf(msg,"%s %s 0x%x 0x%x",av[0],av[1],val,code); putmsg(fd,&myseq,msg); break; default : fprintf(dfp,"unknown request type '%s %s %s %s'\n", av[0],av[1],av[2],av[3]); }}#if 0 Hardware Breakpoint Support ---------------------------Hardware breakpoint support uses three new commands: 'B', 'A', and 'b',which are used for setting instruction breakpoints, setting databreakpoints (Access bpts), or clearing breakpoints respectively.Set Instruction Breakpoint--------------------------gdb should use the following command whenever an instruction breakpointis to be set. The underlying monitor (eg. PMON) will be responsible forfiguring out what actual breakpoint mechanism to use. Sometimes it willuse a software breakpoint mechanism, sometimes a icache locking mechanism,and sometimes an actual hardware breakpoint register.<pid> 'B' <addr> 0x0reply:<pid> 'B' <bptn> <code>The reply returns two values: bptn - a breakpoint number, which is a small integer with possible values of zero through 255. code - an error return code, a value of zero indicates a succesful completion, other values indicate various errors and warnings.Possible return codes: OK, W_QAL, E_QAL, E_OUT, E_NONSet Data Breakpoint-------------------gdb should use the following command whenever a data breakpointis to be set. The underlying monitor (eg. PMON) will be responsible forfiguring out what actual breakpoint mechanism to use. <pid> 'A' <addr1> <type> [<addr2> [<value>]] where: type= "0x1" = read "0x2" = write "0x3" = access (read or write)For example, 0x1 'A' 0x80020004 0x1 any read from address 0x1 'A' 0x80032140 0x2 any write to address 0x1 'A' 0x80032140 0x3 any access to address 0x1 'A' 0x80042160 0x2 0x0 0x12345678 write of value to address. -- the 0x0 is a placeholder for addr2 not used here 0x1 'A' 0x80050000 0x3 0x8006ffff any access within rangeEach of these commands would return a message of the following format. <pid> 'A' <bptn> <code>Where: bptn - a breakpoint number, which is a small integer with possible values of zero through 255. code - an error return code, a value of zero indicates a succesful completion, other values indicate various errors and warnings.Possible return codes: OK, W_MSK, W_VAL, W_QAL, E_RGE, E_QAL, E_OUT, E_NONClear Breakpoint----------------gdb should use the following command whenever a breakpointis to be deleted. This command uses the "Breakpoint Number" returned byeither the 'B' or 'A' commands.<pid> 'b' <bptn> 0x0reply:<pid> 'b' 0x0 <code>Possible return codes: OK, E_BPTReturn codes:-------------Note that it is possible to get more than one warning value. For example,a return value of 0x103 would indicate that "Range feature is supported via mask" and "Value check is not supported in hardware".OK 0 -- OKW_MSK 0x101 -- warning: Range feature is supported via maskW_VAL 0x102 -- warning: Value check is not supported in hardwareW_QAL 0x104 -- warning: Requested qualifiers are not supported in hardwareE_BPT 0x200 -- error: No such breakpoint numberE_RGE 0x201 -- error: Range is not supportedE_QAL 0x202 -- error: The requested qualifiers can not be usedE_OUT 0x203 -- error: Out of hardware resourcesE_NON 0x204 -- error: Hardware breakpoint not supportedE_VAL 0x205 -- error: value feature not supportedE_ERR 0x206 -- error: requested bpt can not be set#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -