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