00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #define _MAIN_MDB
00031 #include "mdb.h"
00032
00033 #include <minix/type.h>
00034
00035 #include <stdio.h>
00036 #include <signal.h>
00037 #include <string.h>
00038 #include <stdlib.h>
00039 #include <unistd.h>
00040 #include <ctype.h>
00041 #include <errno.h>
00042 #include <sys/wait.h>
00043 #define ptrace mdbtrace
00044 #include <sys/ptrace.h>
00045 #include <setjmp.h>
00046 #include "proto.h"
00047
00048 #include <kernel/const.h>
00049 #include <kernel/type.h>
00050 #include <kernel/proc.h>
00051
00052
00053 extern struct proc *prc;
00054
00055 #define MAXLINE 128
00056 #define MAXARG 20
00057
00058 PRIVATE unsigned long lastexp = 0L;
00059 PRIVATE int lastseg = NOSEG;
00060 PRIVATE char *prog;
00061 PRIVATE char sbuf[MAXLINE];
00062 PRIVATE char cbuf[MAXLINE];
00063 PRIVATE char *cmd;
00064 PRIVATE char *cmdstart;
00065 PRIVATE jmp_buf mainlp;
00066
00067
00068 struct b_pnt {
00069 struct b_pnt *nxt, *prv;
00070 long addr;
00071 long oldval;
00072 char cmd[1];
00073 } *b_head, *curpnt;
00074
00075 _PROTOTYPE( void main , (int argc, char *argv[]));
00076
00077 FORWARD _PROTOTYPE( void cleanup , (void));
00078 FORWARD _PROTOTYPE( void freepnt , (struct b_pnt *pnt ));
00079 FORWARD _PROTOTYPE( void findbpnt , (int verbose ));
00080 FORWARD _PROTOTYPE( int exebpnt , (int restart ));
00081 FORWARD _PROTOTYPE( void catch , (int sig ));
00082 FORWARD _PROTOTYPE( int run , (char *name , char *argstr , int tflg ));
00083 FORWARD _PROTOTYPE( int dowait , (void));
00084 FORWARD _PROTOTYPE( void backtrace , (int all ));
00085 FORWARD _PROTOTYPE( void modify , (long addr , int cnt , int verbose , int size ));
00086 FORWARD _PROTOTYPE( void display , (long addr , int req ));
00087 FORWARD _PROTOTYPE( void fill , (long addr , int req ));
00088 FORWARD _PROTOTYPE( void dorun , (char *cmd ));
00089 FORWARD _PROTOTYPE( void not_for_core , (void));
00090 FORWARD _PROTOTYPE( void command , (void));
00091
00092
00093 PRIVATE void cleanup()
00094 {
00095 curpid = 0;
00096 curpnt = NULL;
00097 while (b_head) freepnt(b_head);
00098 }
00099
00100 PRIVATE void findbpnt(verbose)
00101 int verbose;
00102 {
00103 for (curpnt = b_head; curpnt; curpnt = curpnt->nxt) {
00104 if (curpnt->addr == PC_MEMBER(prc) - BREAKPOINT_ADVANCE) {
00105 ptrace(T_SETINS, curpid, curpnt->addr, curpnt->oldval);
00106 ptrace(T_SETUSER, curpid, PC_OFF, curpnt->addr);
00107 #if SYSCALLS_SUPPORT
00108 if( syscalls )
00109 do_syscall(curpnt->addr);
00110 else if (curpnt->cmd[0] != '\n')
00111 #else
00112 if (curpnt->cmd[0] != '\n')
00113 #endif
00114 cmd = strcpy(cbuf, curpnt->cmd);
00115 else if (verbose)
00116 Printf("Breakpoint hit.\n");
00117 return;
00118 }
00119 }
00120 if (verbose) Printf("Unknown breakpoint hit.\n");
00121 }
00122
00123 PRIVATE int exebpnt(restart)
00124 int restart;
00125 {
00126 ptrace(T_STEP, curpid, 0L, (long) restart);
00127 if (dowait() == 0) return TRUE;
00128 ptrace(T_SETINS, curpid, curpnt->addr, BREAK(curpnt->oldval));
00129 curpnt = NULL;
00130 return FALSE;
00131 }
00132
00133
00134 PRIVATE void freepnt(pnt)
00135 struct b_pnt *pnt;
00136 {
00137 if (pnt->prv)
00138 pnt->prv->nxt = pnt->nxt;
00139 else
00140 b_head = pnt->nxt;
00141 if (pnt->nxt) pnt->nxt->prv = pnt->prv;
00142 if (curpid > 0) ptrace(T_SETINS, curpid, pnt->addr, pnt->oldval);
00143 free(pnt);
00144 if (pnt == curpnt) curpnt = NULL;
00145 }
00146
00147
00148 PUBLIC long breakpt(addr, cmd)
00149 long addr;
00150 char *cmd;
00151 {
00152 struct b_pnt *new;
00153
00154 if (curpid <= 0) {
00155 Printf("No active process.\n");
00156 return 0L;
00157 }
00158 for (new = b_head; new; new = new->nxt)
00159 if (new->addr == addr) {
00160 Printf("Breakpoint already exists here.\n");
00161 return 0L;
00162 }
00163 new = (struct b_pnt *) malloc(sizeof(struct b_pnt) + strlen(cmd));
00164 if (new == NULL) {
00165 Printf("No room for new breakpoint.\n");
00166 return 0L;
00167 }
00168 new->nxt = b_head;
00169 new->prv = 0;
00170 if (b_head) b_head->prv = new;
00171 b_head = new;
00172 new->addr = addr;
00173 strcpy(new->cmd, cmd);
00174 new->oldval = ptrace(T_GETINS, curpid, addr, 0L);
00175 ptrace(T_SETINS, curpid, addr, BREAK(new->oldval));
00176 if (ptrace(T_GETINS, curpid, addr, 0L) != BREAK(new->oldval)) {
00177 do_error("Can't set breakpoint");
00178 freepnt(new);
00179 return 0L;
00180 }
00181 return new->oldval;
00182 }
00183
00184 PRIVATE void catch(sig)
00185 int sig;
00186 {
00187 signal(sig, catch);
00188 if (sig == SIGINT || sig == SIGQUIT) return;
00189 tstart(T_EXIT, 0, sig, 0);
00190 exit(0);
00191 }
00192
00193
00194 PRIVATE int dowait()
00195 {
00196 int stat;
00197
00198 if (corepid > 0) return cursig = 0;
00199 while (wait(&stat) != curpid) {};
00200 if ( WIFEXITED(stat) ) {
00201 if (WEXITSTATUS(stat) != 127)
00202 Printf("child exited with status %d\n", WEXITSTATUS(stat));
00203 cleanup();
00204 return 0;
00205 }
00206 if ( WIFSIGNALED(stat) ) {
00207 Printf("child terminated by signal %d\n", WTERMSIG(stat) );
00208 if (_LOW(stat) & 0x80) Printf("(core dumped)\n");
00209 cleanup();
00210 return 0;
00211 }
00212 return cursig = WSTOPSIG(stat);
00213 }
00214
00215
00216
00217 PUBLIC void tstart(req, verbose, val, cnt)
00218 int req, verbose, val, cnt;
00219 {
00220 if (curpid == 0) {
00221 if (verbose) Printf("No active process.\n");
00222 return;
00223 }
00224 if (req == T_EXIT) {
00225 ptrace(T_EXIT, curpid, 0L, (long) val);
00226 dowait();
00227 return;
00228 }
00229 if (cnt == 0) cnt = 1;
00230 do {
00231 if (curpnt) {
00232 if (exebpnt(val)) return;
00233 if (req == T_RESUME) cnt++;
00234 val = 0;
00235 } else {
00236 ptrace(req, curpid, 0L, (long) val);
00237 if (dowait() == 0) return;
00238 val = 0;
00239 switch (cursig) {
00240 case SIGEMT:
00241 update();
00242 findbpnt(cnt <= 1);
00243 break;
00244 case SIGTRAP:
00245 if (req == T_STEP) break;
00246 default:
00247 val = cursig;
00248 break;
00249 }
00250 }
00251 }
00252 while (--cnt > 0);
00253 update();
00254 if ( verbose ) dasm((long) PC_MEMBER(prc), 1, 1);
00255 }
00256
00257 PRIVATE int run(name, argstr, tflg)
00258 char *name, *argstr;
00259 int tflg;
00260 {
00261 int procid;
00262 char *argv[MAXARG], *inf = NULL, *outf = NULL;
00263 int argc;
00264
00265 if ((procid = fork()) == 0) {
00266
00267 if (tflg) ptrace(T_OK, 0, 0L, 0L);
00268 argv[0] = name;
00269 for (argc = 1;;) {
00270 argstr = skip(argstr);
00271 if (*argstr == '\n' || *argstr == ';') {
00272 argv[argc] = 0;
00273 if (inf) freopen(inf, "r", stdin);
00274 if (outf) freopen(outf, "w", stdout);
00275 if (tflg) {
00276 execv(name, argv);
00277 do_error("execv");
00278 } else {
00279 execvp(name, argv);
00280 do_error("execvp");
00281 }
00282 exit(127);
00283 }
00284 if (*argstr == '<')
00285 inf = argstr + 1;
00286 else if (*argstr == '>')
00287 outf = argstr + 1;
00288 else if (argc == MAXARG) {
00289 Printf("Too many arguments.\n");
00290 exit(127);
00291 } else
00292 argv[argc++] = argstr;
00293 while (!isspace(*argstr)) argstr++;
00294 if (*argstr == '\n') argstr[1] = '\n', argstr[2] = 0;
00295 *argstr++ = 0;
00296 }
00297 }
00298 if (procid < 0) do_error("Fork failed.\n");
00299 return procid;
00300 }
00301
00302
00303 PRIVATE void dorun(cmd)
00304 char *cmd;
00305 {
00306 if (curpid = run(prog, cmd, 1)) {
00307 if (dowait()) {
00308 ptrace(T_SETUSER, curpid, BP_OFF, 0L);
00309 update();
00310 Printf("Process stopped.\n");
00311 }
00312 }
00313 }
00314
00315
00316
00317
00318 PRIVATE void backtrace(all)
00319 int all;
00320 {
00321 unsigned long pc, bp, off, val, obp;
00322
00323 if (curpid <= 0) {
00324 Printf("No process.\n");
00325 return;
00326 }
00327 pc = get_reg(curpid,PC_OFF);
00328 bp = get_reg(curpid,BP_OFF);
00329 if (bp == 0) {
00330 Printf("No active frame.\n");
00331 return;
00332 }
00333 errno = 0;
00334 do {
00335 symbolic(pc, '(');
00336 pc = (ptrace(T_GETDATA, curpid, bp + ADDRSIZE, 0L)
00337 >> SHIFT(ADDRSIZE)) & MASK(ADDRSIZE);
00338 off = ptrace(T_GETINS, curpid, pc, 0L);
00339 #ifdef DEBUG
00340 if(debug)
00341 Printf("Return address %lx Value %lx\n",pc,off);
00342 #endif
00343 obp = bp;
00344 bp += 2 * ADDRSIZE;
00345
00346
00347
00348
00349
00350
00351 if (ADDQ(off)) off = ADDQ_CNT(off) + bp;
00352 #ifdef __mc68000__
00353 else if (LEA(off))
00354 off = LEA_DISP(off) + bp;
00355 #endif
00356 else if (ADDA(off))
00357 off = ADDA_CNT(ptrace(T_GETINS, curpid, pc + 2, 0L)) + bp;
00358 #if (CHIP == INTEL)
00359 else if (INCSP2(off))
00360 off = bp + 2*INTSIZE;
00361 else if (POPBX2(off))
00362 off = bp + 2*INTSIZE;
00363 else if (POPCX2(off))
00364 off = bp + 2*INTSIZE;
00365 else if (POPBX(off))
00366 off = bp + INTSIZE;
00367 else if (POPCX(off))
00368 off = bp + INTSIZE;
00369 #endif
00370 else
00371 goto skiplp;
00372
00373 #ifdef DEBUG
00374 if (debug)
00375 Printf("Number of arguments: %d\n",(off-bp)/INTSIZE);
00376 #endif
00377
00378 for (;;) {
00379 if (errno) return;
00380 val = (ptrace(T_GETDATA, curpid, bp, 0L)
00381 >> SHIFT(INTSIZE)) & MASK(INTSIZE);
00382 Printf("0x%0*lx", 2 * INTSIZE, val);
00383 bp += INTSIZE;
00384 if (bp >= off) break;
00385 Printf(",");
00386 }
00387
00388 skiplp:
00389 Printf(")\n");
00390 bp = (long) ( (reg_t) ptrace(T_GETDATA, curpid, obp, 0L) );
00391 #ifdef DEBUG
00392 if(debug)
00393 Printf("Old BP %lx New %lx\n",obp,bp);
00394 #endif
00395 }
00396 while (all && (reg_t) bp);
00397 }
00398
00399 PRIVATE void modify(addr, cnt, verbose, size)
00400 long addr;
00401 int cnt, verbose, size;
00402 {
00403 long curval, off;
00404
00405 if (curpid == 0) {
00406 Printf("No active process.\n");
00407 return;
00408 }
00409 curval = ptrace(T_GETDATA, curpid, addr, 0L) & MASK(size);
00410 do {
00411 if (cursig == SIGTRAP) cursig = 0;
00412 if (verbose) {
00413 off = get_reg(curpid, PC_OFF);
00414 dasm(off, 1, 0);
00415 }
00416 if (curpnt && exebpnt(cursig))
00417 return;
00418 else {
00419 ptrace(T_STEP, curpid, addr, 0L);
00420 switch (dowait()) {
00421 case 0:
00422 return;
00423 case SIGEMT:
00424 update();
00425 findbpnt(0);
00426 break;
00427 }
00428 }
00429 if (curval != ptrace(T_GETDATA, curpid, addr, 0L) & MASK(size)) {
00430 Printf("Modification detected\n");
00431 break;
00432 }
00433 }
00434 while (--cnt);
00435 update();
00436 dasm((long) PC_MEMBER(prc), 1, 1);
00437 return;
00438 }
00439
00440 PRIVATE void display(addr, req)
00441 long addr;
00442 int req;
00443 {
00444 int count, size, out, shift;
00445 long val, msk;
00446 char fmt;
00447
00448 if (curpid == 0) {
00449 Printf("No active process\n");
00450 return;
00451 }
00452 if (req == T_GETDATA && seg == T) req = T_GETINS;
00453 count = strtol(cmd, &cmd, 0);
00454 if (count == 0) count = 1;
00455 cmd = skip(cmd);
00456 if (*cmd == 'i' || *cmd == 'I') {
00457 dasm(addr, count, *cmd == 'i');
00458 return;
00459 }
00460 if (*cmd == 'y') {
00461 symbolic(addr, '\n');
00462 return;
00463 }
00464 switch (*cmd++) {
00465 case 'b': size = sizeof(char); break;
00466 case 'h': size = sizeof(short); break;
00467 case 'l': size = sizeof(long); break;
00468 default:
00469 size = sizeof(int);
00470 --cmd;
00471 break;
00472 }
00473 switch (fmt = *cmd) {
00474 case 'X':
00475 case 'D':
00476 size = sizeof(long);
00477 break;
00478 case 's':
00479 addr = ptrace(req, curpid, addr, 0L);
00480 req = T_GETDATA;
00481
00482 case 'a':
00483 case 'c':
00484 size = sizeof(char);
00485 break;
00486 }
00487 out = 0;
00488 msk = MASK(size);
00489 shift = SHIFT(size);
00490 do {
00491 val = (ptrace(req, curpid, addr, 0L) >> shift) & msk;
00492 if (out == 0) Printf("\n0x%0*lx: ", 2 * ADDRSIZE,
00493 (addr >> SHIFT(ADDRSIZE)) & MASK(ADDRSIZE));
00494 switch (fmt) {
00495 case 'c':
00496 Printf(isprint((int) (UCHAR(val))) ? " %c " : "\\%03o ",
00497 (int) (UCHAR(val)));
00498 if (++out == 8) out = 0;
00499 break;
00500 case 'u':
00501 Printf("%12lu ", val);
00502 if (++out == 4) out = 0;
00503 break;
00504 case 'x':
00505 case 'X':
00506 Printf("%*lx ", 2 * size, val);
00507 if (++out == (size == 4 ? 4 : 8)) out = 0;
00508 break;
00509 case 'o':
00510 Printf("%*lo ", 3 * size, val);
00511 if (++out == (size == 4 ? 4 : 8)) out = 0;
00512 break;
00513 case 's':
00514 case 'a':
00515 if (val)
00516 Printf("%c",val);
00517 else
00518 goto exitlp;
00519 if (++out == 64) out = 0;
00520 break;
00521 default:
00522 case 'd':
00523 case 'D':
00524 Printf("%12ld ", val);
00525 if (++out == 4) out = 0;
00526 break;
00527 }
00528 addr += size;
00529 }
00530 while (--count > 0 || fmt == 's' || fmt == 'a');
00531 exitlp:
00532 Printf("\n");
00533 }
00534
00535 PRIVATE void fill(addr, req)
00536 long addr;
00537 int req;
00538 {
00539 int count, size, shift;
00540 long val, msk, nval;
00541
00542 if (curpid == 0) {
00543 Printf("No active process\n");
00544 return;
00545 }
00546
00547 if (req == T_GETDATA && seg == T) {
00548 req = T_GETINS;
00549 Printf("mdb: warning - modifying text\n");
00550 }
00551 count = strtol(cmd, &cmd, 0);
00552 if ( count == 0 ) count = 1;
00553 switch (*cmd++) {
00554 case 'b': size = sizeof(char); break;
00555 case 'h': size = sizeof(short); break;
00556 case 'l': size = sizeof(long); break;
00557 default:
00558 size = sizeof(int);
00559 --cmd;
00560 break;
00561 }
00562 shift = SHIFT(size);
00563 msk = MASK(size);
00564 cmd = getexp(cmd, &nval, &seg);
00565
00566 #ifdef DEBUG
00567 if (debug)
00568 Printf("Filling for Count=%d Size=%d val=%lx\n",count,size,nval);
00569 #endif
00570
00571 nval <<= shift;
00572 do {
00573 val = ptrace(req, curpid, addr, 0L) | (nval & msk);
00574 val &= (nval | ~msk);
00575 ptrace(req + 3, curpid, addr, val);
00576 addr += size;
00577 }
00578 while (--count > 0);
00579 }
00580
00581 PRIVATE void not_for_core()
00582 {
00583 if (corepid > 0)
00584 mdb_error("Illegal command for 'core' file\n");
00585 }
00586
00587 PRIVATE void command()
00588 {
00589 char c, *p;
00590 int i;
00591 int size;
00592 int stat;
00593 long exp, lj, lk;
00594 struct b_pnt *bp;
00595
00596 seg = NOSEG;
00597 cmdstart = cmd = skip(cmd);
00598 cmd = getexp(cmd, &exp, &seg);
00599
00600 if (cmd == cmdstart) {
00601
00602 if (corepid < 0) {
00603 seg = T;
00604 exp = PC_MEMBER(prc);
00605 } else {
00606 seg = lastseg;
00607 exp = lastexp;
00608 }
00609
00610
00611 cmd = skip(cmd+1);
00612 if (*cmd == '?') {
00613 help_on(*cmdstart);
00614 *cmd = '\n';
00615 return;
00616 }
00617 else
00618 cmd = cmdstart;
00619 }
00620
00621 if (seg == NOSEG) seg = T;
00622 lastexp = exp;
00623 lastseg = seg;
00624 #ifdef DEBUG
00625 if(debug)
00626 Printf("Current address 0x%0*lx and segment %d\n", 2 * ADDRSIZE, exp, seg);
00627
00628 #endif
00629
00630
00631 switch (c = *cmd++) {
00632 case 'r':
00633 case 'R':
00634 case 'k':
00635 case 'B':
00636 case 'd':
00637 case 'D': not_for_core();
00638 break;
00639
00640 case 'b':
00641 case 'c':
00642 case 'C':
00643 case 'm':
00644 case 'M':
00645 #if SYSCALLS_SUPPORT
00646 case 'z':
00647 #endif
00648 case 'i':
00649 case 'I': not_for_core();
00650 if (curpid <= 0) dorun("\n");
00651 break;
00652
00653 case 's': if (curpid <= 0) dorun("\n");
00654 break;
00655
00656 default: break;
00657 }
00658
00659 switch (c) {
00660 case '!':
00661 if (cmd == cmdstart + 1) {
00662 cmd = skip(cmd);
00663 if (*cmd == '\n' || *cmd == ';') {
00664 i = run("/bin/sh", "\n", 0);
00665 } else {
00666 for (p = cmd + 1; *p && !isspace(*p); p++) {
00667 };
00668 *p++ = 0;
00669 i = run(cmd, *p ? p : "\n", 0);
00670 }
00671 if (i > 0) while (wait(&stat) != i) {};
00672 break;
00673 }
00674 if (corepid > 0) longjmp(mainlp, 0);
00675 break;
00676 case 'T':
00677 backtrace(0);
00678 break;
00679 case 't':
00680 backtrace(1);
00681 break;
00682 case '/':
00683 display(exp, T_GETDATA);
00684 break;
00685 case 'x':
00686 if (disp_regs()) break;
00687
00688 case 'X':
00689 lj = strtol(cmd, &cmd, 0);
00690 lk = 0;
00691 if (*cmd != '\0')
00692 lk = strtol(++cmd, &cmd, 0);
00693 if (curpid > 0)
00694 dasm(exp + lk, lj ? lj : 1, 1);
00695 else
00696 Printf("No active process.\n");
00697 break;
00698 case 'R':
00699 case 'r':
00700 tstart(T_EXIT, 0, 0, 0);
00701 if (c == 'r') {
00702 cmd = skip(cmd);
00703 if (*cmd == '\n' || *cmd == ';')
00704 cmd = sbuf;
00705 else
00706 strcpy(sbuf, cmd);
00707 } else {
00708 cmd = "\n";
00709 }
00710 dorun(cmd);
00711 break;
00712 case 'c':
00713 cursig = 0;
00714 case 'C':
00715 i = 0;
00716 if (seg == T && curpnt == 0 && cmd != cmdstart + 1) {
00717 breakpt(exp, "\n");
00718 curpnt = b_head;
00719 ptrace(T_SETINS, curpid, curpnt->addr, curpnt->oldval);
00720 i = 1;
00721 }
00722 tstart(T_RESUME, 1, cursig, (int) strtol(cmd, &cmd, 0));
00723
00724 if (i) freepnt(b_head);
00725 if (cursig == SIGEMT) return;
00726 if (curpid) Printf("Process stopped by signal %d\n", cursig);
00727 break;
00728 case 'i':
00729 tstart(T_STEP, 1, 0, (int) strtol(cmd, &cmd, 0));
00730 break;
00731 case 'I':
00732 tstart(T_STEP, 1, cursig, (int) strtol(cmd, &cmd, 0));
00733 break;
00734 case 'm':
00735 case 'M':
00736 cmd = skip(cmd);
00737 switch (*cmd++) {
00738 case 'b': size = sizeof(char); break;
00739 case 'h': size = sizeof(short); break;
00740 case 'l': size = sizeof(long); break;
00741 default:
00742 size = sizeof(int);
00743 --cmd;
00744 break;
00745 }
00746 modify(exp, (int) strtol(cmd, &cmd, 0), c == 'M', size);
00747 break;
00748 case 'k':
00749 tstart(T_EXIT, 1, 0, 0);
00750 break;
00751 case 'b':
00752 #ifdef MINIX_PC
00753 if (seg != T || exp > end_addr ) {
00754 #else
00755 if (seg != T || exp < st_addr || exp > et_addr ) {
00756 #endif
00757 Printf("Address not in text space.\n");
00758 return;
00759 }
00760 breakpt(exp, skip(cmd));
00761 cmd = "\n";
00762 return;
00763 case 'B':
00764 for (i = 1, bp = b_head; bp; bp = bp->nxt, i++) {
00765 Printf("%2d: ", i);
00766 symbolic((long) bp->addr, '\t');
00767 Printf("(0x%lx)\t- %s", bp->addr, bp->cmd);
00768 }
00769 break;
00770 case 'd':
00771 if (seg == T) {
00772 for (bp = b_head; bp && bp->addr != exp; bp = bp->nxt);
00773 if (bp) {
00774 freepnt(bp);
00775 break;
00776 }
00777 }
00778 Printf("No such breakpoint.\n");
00779 break;
00780 case 'D':
00781 while (b_head) freepnt(b_head);
00782 break;
00783 case 's':
00784 dump_stack( strtol(cmd, &cmd, 0) );
00785 break;
00786 case 'P':
00787 paging = !paging;
00788 if (paging) Printf("Paging is ON\n");
00789 break;
00790 case 'l':
00791 case 'L':
00792 logging(c,skip(cmd));
00793 break;
00794 #if SYSCALLS_SUPPORT
00795 case 'z':
00796 start_syscall( strtol(cmd, &cmd, 0) );
00797 if ( syscalls )
00798 Printf("Break point set - use the 'c n' command\n");
00799 break;
00800 #endif
00801 case 'q':
00802 tstart(T_EXIT, 0, 0, 0);
00803 logging(c,cmd);
00804 case 'Q':
00805 exit(0);
00806 break;
00807 case '\n':
00808 case ';':
00809 if (isdigit(*cmdstart))
00810 symbolic(exp, '\n');
00811 else
00812 Printf("0x%0*lx\n", 2 * ADDRSIZE, exp);
00813 --cmd;
00814 break;
00815 #ifdef DEBUG
00816 case 'v':
00817 debug = !debug;
00818 if (debug) Printf("Debug flag ON\n");
00819 break;
00820 #endif
00821 case 'e':
00822 listsym(cmd);
00823 break;
00824 case 'y':
00825 prtmap();
00826 break;
00827 case '?':
00828 help_page();
00829 break;
00830 case 'V':
00831 version_info();
00832 break;
00833 case '@':
00834 cmd = skip(cmd);
00835 openin(cmd);
00836 *cmd = '\n';
00837 return;
00838 case '#':
00839 cmd = skip(cmd + 1);
00840 if (*cmd == '$') {
00841 cmd++;
00842 i = reg_addr(cmd);
00843 set_reg(curpid, i, strtol(cmd+2, &cmd, 0) );
00844 update();
00845 break;
00846 }
00847 cmd = getexp(cmd, &exp, &seg);
00848 fill(exp, T_GETDATA);
00849 break;
00850 default:
00851 help_page();
00852 break;
00853 }
00854 while (*cmd != '\n' && *cmd != ';') ++cmd;
00855 if (*cmd == ';') cmd = skip(cmd + 1);
00856 }
00857
00858 PUBLIC void mdb_error(s)
00859 char *s;
00860 {
00861 Printf("%s",s);
00862 longjmp(mainlp, 0);
00863 }
00864
00865 PUBLIC void main(argc, argv)
00866 int argc;
00867 char *argv[];
00868 {
00869 int i, c;
00870 char *p, *q, *r;
00871 int opt_c = FALSE;
00872 int opt_f = FALSE;
00873 int opt_l = FALSE;
00874 int opt_L = FALSE;
00875
00876
00877 prc = (struct proc *) lbuf;
00878 strcpy(sbuf, "\n");
00879 corepid = -1;
00880 prog = p = q = r = NULL;
00881
00882 if ( argc == 1 )
00883 {
00884 help_page();
00885 exit(0);
00886 }
00887
00888
00889
00890
00891
00892
00893
00894
00895
00896
00897
00898
00899
00900
00901
00902
00903
00904
00905
00906
00907
00908
00909 if (strcmp(argv[1], "core") == 0) {
00910 for (i = argc ; i > 1 ; i--)
00911 argv[i] = argv[i - 1];
00912 argv[i] = "-c";
00913 argc++;
00914 }
00915
00916
00917 opterr = 0;
00918 while ((i = getopt(argc, argv, "c:f:L:l:x:")) != EOF) {
00919 switch (i & 0377) {
00920 case 'c':
00921 if (opt_c == TRUE || opt_f == TRUE) {
00922 help_page();
00923 exit(1);
00924 }
00925 p = optarg;
00926 opt_c = TRUE;
00927 break;
00928 case 'f':
00929 if (opt_c == TRUE || opt_f == TRUE) {
00930 help_page();
00931 exit(1);
00932 }
00933 p = optarg;
00934 opt_f = TRUE;
00935 break;
00936 case 'l':
00937 if (opt_l == TRUE || opt_L == TRUE) {
00938 help_page();
00939 exit(1);
00940 }
00941 opt_l = TRUE;
00942 logging(i, optarg);
00943 break;
00944 case 'L':
00945 if (opt_l == TRUE || opt_L == TRUE) {
00946 help_page();
00947 exit(1);
00948 }
00949 opt_L = TRUE;
00950 logging(i, optarg);
00951 break;
00952 #ifdef DEBUG
00953 case 'x':
00954 debug = atoi(optarg);
00955 break;
00956 #endif
00957 case '?':
00958 default:
00959 help_page();
00960 exit(1);
00961 }
00962 }
00963
00964
00965 if (!opt_c && !opt_f && optind >= argc) {
00966 help_page();
00967 exit(1);
00968 }
00969
00970
00971 for (i = optind ; i < argc ; i++) {
00972 if (*argv[i] == '@') {
00973 if (r == NULL) r = argv[i] + 1;
00974 }
00975
00976 else if (!opt_c && !opt_f && p == NULL) p = argv[i];
00977 else if (q == NULL) q = argv[i];
00978 }
00979
00980
00981 coreonly = opt_c;
00982 fileonly = opt_f;
00983
00984 if (!opt_c && !opt_f) {
00985 prog = p;
00986 syminit(prog);
00987 }
00988
00989
00990
00991
00992
00993
00994
00995
00996
00997
00998
00999
01000
01001
01002
01003
01004
01005
01006
01007
01008
01009 if (opt_c) lastexp = core_init(p);
01010 if (opt_f) lastexp = file_init(p);
01011 if (q != NULL) lastexp = core_init(q);
01012 if (r != NULL) openin(r);
01013 for (i = 1; i < _NSIG; i++) signal(i, catch);
01014
01015 setjmp(mainlp);
01016
01017 while (get_cmd( cbuf, MAXLINE ) != NULL) {
01018 if (strlen(cbuf) == sizeof(cbuf) - 1) {
01019 Printf("Command line too long.\n");
01020 continue;
01021 }
01022 cmd = cbuf;
01023 command();
01024 while (*cmd != '\n') command();
01025 }
01026 tstart(T_EXIT, 0, 0, 0);
01027 exit(0);
01028 }