manual page first distributed with 4.3BSD
[unix-history] / usr / src / old / dbx / vax.c
index cf86815..f98ad05 100644 (file)
@@ -1,6 +1,8 @@
 /* Copyright (c) 1982 Regents of the University of California */
 
 /* Copyright (c) 1982 Regents of the University of California */
 
-static char sccsid[] = "@(#)vax.c 1.3 %G%";
+static char sccsid[] = "@(#)vax.c      1.13 (Berkeley) %G%";
+
+static char rcsid[] = "$Header: machine.c,v 1.5 84/12/26 10:40:05 linton Exp $";
 
 /*
  * Target machine dependent stuff.
 
 /*
  * Target machine dependent stuff.
@@ -9,12 +11,14 @@ static char sccsid[] = "@(#)vax.c 1.3 %G%";
 #include "defs.h"
 #include "machine.h"
 #include "process.h"
 #include "defs.h"
 #include "machine.h"
 #include "process.h"
+#include "runtime.h"
 #include "events.h"
 #include "main.h"
 #include "symbols.h"
 #include "source.h"
 #include "mappings.h"
 #include "object.h"
 #include "events.h"
 #include "main.h"
 #include "symbols.h"
 #include "source.h"
 #include "mappings.h"
 #include "object.h"
+#include "keywords.h"
 #include "ops.h"
 #include <signal.h>
 
 #include "ops.h"
 #include <signal.h>
 
@@ -260,6 +264,7 @@ int mode;
     char byte;
     short hword;
     int argval;
     char byte;
     short hword;
     int argval;
+    Symbol f;
 
     switch (nbytes) {
        case 1:
 
     switch (nbytes) {
        case 1:
@@ -280,9 +285,22 @@ int mode;
        argval += addr + nbytes;
     }
     if (reg == regname[PROGCTR]) {
        argval += addr + nbytes;
     }
     if (reg == regname[PROGCTR]) {
-       printf("%x", argval);
+       f = whatblock((Address) argval + 2);
+       if (codeloc(f) == argval + 2) {
+           printf("%s", symname(f));
+       } else {
+           printf("%x", argval);
+       }
     } else {
     } else {
-       printf("%d(%s)", argval, reg);
+       if (varIsSet("$hexoffsets")) {
+           if (argval < 0) {
+               printf("-%x(%s)", -(argval), reg);
+           } else {
+               printf("%x(%s)", argval, reg);
+           }
+       } else {
+           printf("%d(%s)", argval, reg);
+       }
     }
     return argval;
 }
     }
     return argval;
 }
@@ -308,11 +326,26 @@ private Format fmt[] = {
     { "b", " \\%o", sizeof(char) },
     { "c", " '%c'", sizeof(char) },
     { "s", "%c", sizeof(char) },
     { "b", " \\%o", sizeof(char) },
     { "c", " '%c'", sizeof(char) },
     { "s", "%c", sizeof(char) },
-    { "f", " %f", sizeof(double) },
+    { "f", " %f", sizeof(float) },
     { "g", " %g", sizeof(double) },
     { nil, nil, 0 }
 };
 
     { "g", " %g", sizeof(double) },
     { nil, nil, 0 }
 };
 
+private Format *findformat(s)
+String s;
+{
+    register Format *f;
+
+    f = &fmt[0];
+    while (f->name != nil and not streq(f->name, s)) {
+       ++f;
+    }
+    if (f->name == nil) {
+       error("bad print format \"%s\"", s);
+    }
+    return f;
+}
+
 public Address printdata(lowaddr, highaddr, format)
 Address lowaddr;
 Address highaddr;
 public Address printdata(lowaddr, highaddr, format)
 Address lowaddr;
 Address highaddr;
@@ -326,13 +359,7 @@ String format;
     if (lowaddr > highaddr) {
        error("first address larger than second");
     }
     if (lowaddr > highaddr) {
        error("first address larger than second");
     }
-    f = &fmt[0];
-    while (f->name != nil and not streq(f->name, format)) {
-       ++f;
-    }
-    if (f->name == nil) {
-       error("bad print format \"%s\"", format);
-    }
+    f = findformat(format);
     n = 0;
     value = 0;
     for (addr = lowaddr; addr <= highaddr; addr += f->length) {
     n = 0;
     value = 0;
     for (addr = lowaddr; addr <= highaddr; addr += f->length) {
@@ -367,33 +394,34 @@ String format;
     register Address addr;
     register Format *f;
     register Boolean isstring;
     register Address addr;
     register Format *f;
     register Boolean isstring;
-    int value;
+    char c;
+    union {
+       char charv;
+       short shortv;
+       int intv;
+       float floatv;
+       double doublev;
+    } value;
 
     if (count <= 0) {
        error("non-positive repetition count");
     }
 
     if (count <= 0) {
        error("non-positive repetition count");
     }
-    f = &fmt[0];
-    while (f->name != nil and not streq(f->name, format)) {
-       ++f;
-    }
-    if (f->name == nil) {
-       error("bad print format \"%s\"", format);
-    }
+    f = findformat(format);
     isstring = (Boolean) streq(f->name, "s");
     n = 0;
     addr = startaddr;
     isstring = (Boolean) streq(f->name, "s");
     n = 0;
     addr = startaddr;
-    value = 0;
+    value.intv = 0;
     for (i = 0; i < count; i++) {
        if (n == 0) {
            printf("%08x: ", addr);
        }
        if (isstring) {
            putchar('"');
     for (i = 0; i < count; i++) {
        if (n == 0) {
            printf("%08x: ", addr);
        }
        if (isstring) {
            putchar('"');
-           dread(&value, addr, sizeof(char));
-           while (value != '\0') {
-               printchar((char) value);
+           dread(&c, addr, sizeof(char));
+           while (c != '\0') {
+               printchar(c);
                ++addr;
                ++addr;
-               dread(&value, addr, sizeof(char));
+               dread(&c, addr, sizeof(char));
            }
            putchar('"');
            putchar('\n');
            }
            putchar('"');
            putchar('\n');
@@ -416,8 +444,36 @@ String format;
     prtaddr = addr;
 }
 
     prtaddr = addr;
 }
 
+/*
+ * Print out a value according to the given format.
+ */
+
+public printvalue(v, format)
+long v;
+String format;
+{
+    Format *f;
+    char *p, *q;
+
+    f = findformat(format);
+    if (streq(f->name, "s")) {
+       putchar('"');
+       p = (char *) &v;
+       q = p + sizeof(v);
+       while (p < q) {
+           printchar(*p);
+           ++p;
+       }
+       putchar('"');
+    } else {
+       printf(f->printfstring, v);
+    }
+    putchar('\n');
+}
+
 /*
  * Print out an execution time error.
 /*
  * Print out an execution time error.
+ * Assumes the source position of the error has been calculated.
  *
  * Have to check if the -r option was specified; if so then
  * the object file information hasn't been read in yet.
  *
  * Have to check if the -r option was specified; if so then
  * the object file information hasn't been read in yet.
@@ -427,37 +483,28 @@ public printerror()
 {
     extern Integer sys_nsig;
     extern String sys_siglist[];
 {
     extern Integer sys_nsig;
     extern String sys_siglist[];
-    String filename;
-    Integer err;
+    integer err;
 
     if (isfinished(process)) {
 
     if (isfinished(process)) {
-       printf("\"%s\" exits with code %d\n", objname, exitcode(process));
+       err = exitcode(process);
+       if (err == 0) {
+           printf("\"%s\" terminated normally\n", objname);
+       } else {
+           printf("\"%s\" terminated abnormally (exit code %d)\n",
+               objname, err
+           );
+       }
        erecover();
     }
     if (runfirst) {
        erecover();
     }
     if (runfirst) {
-       fprintf(stderr, "Entering debugger ...");
+       fprintf(stderr, "Entering debugger ...\n");
        init();
        init();
-       fprintf(stderr, " type 'help' for help\n");
     }
     }
-    curline = srcline(pc);
-    curfunc = whatblock(pc);
-    filename = srcfilename(pc);
-    setsource(filename);
     err = errnum(process);
     err = errnum(process);
-    if (err == SIGINT) {
-       printf("\n\ninterrupt ");
-       printloc();
-    } else if (err == SIGTRAP) {
-       printf("\nerror ");
-       printloc();
-    } else {
-       if (err < 0 or err > sys_nsig) {
-           printf("\nsignal %d ", err);
-       } else {
-           printf("\n%s ", sys_siglist[err]);
-       }
-       printloc();
-    }
+    putchar('\n');
+    printsig(err);
+    putchar(' ');
+    printloc();
     putchar('\n');
     if (curline > 0) {
        printlines(curline, curline);
     putchar('\n');
     if (curline > 0) {
        printlines(curline, curline);
@@ -467,18 +514,49 @@ public printerror()
     erecover();
 }
 
     erecover();
 }
 
-private printloc()
+/*
+ * Print out a signal.
+ */
+
+private String illinames[] = {
+    "reserved addressing fault",
+    "priviliged instruction fault",
+    "reserved operand fault"
+};
+
+private String fpenames[] = {
+    nil,
+    "integer overflow trap",
+    "integer divide by zero trap",
+    "floating overflow trap",
+    "floating/decimal divide by zero trap",
+    "floating underflow trap",
+    "decimal overflow trap",
+    "subscript out of range trap",
+    "floating overflow fault",
+    "floating divide by zero fault",
+    "floating undeflow fault"
+};
+
+public printsig (signo)
+integer signo;
 {
 {
-    if (curline > 0) {
-       if (nlhdr.nfiles > 1) {
-           printf("at line %d in file %s", curline, cursource);
-       } else {
-           printf("at line %d", curline);
-       }
+    integer code;
+
+    if (signo < 0 or signo > sys_nsig) {
+       printf("[signal %d]", signo);
     } else {
     } else {
-       printf("in ");
-       printname(stdout, curfunc);
-       printf(" at 0x%x", pc);
+       printf("%s", sys_siglist[signo]);
+    }
+    code = errcode(process);
+    if (signo == SIGILL) {
+       if (code >= 0 and code < sizeof(illinames) / sizeof(illinames[0])) {
+           printf(" (%s)", illinames[code]);
+       }
+    } else if (signo == SIGFPE) {
+       if (code > 0 and code < sizeof(fpenames) / sizeof(fpenames[0])) {
+           printf(" (%s)", fpenames[code]);
+       }
     }
 }
 
     }
 }
 
@@ -496,14 +574,18 @@ public endprogram()
     stepto(nextaddr(pc, true));
     printnews();
     exitcode = argn(1, nil);
     stepto(nextaddr(pc, true));
     printnews();
     exitcode = argn(1, nil);
-    printf("\nexecution completed, exit code is %d\n", exitcode);
+    if (exitcode != 0) {
+       printf("\nexecution completed (exit code %d)\n", exitcode);
+    } else {
+       printf("\nexecution completed\n");
+    }
     getsrcpos();
     erecover();
 }
 
 /*
  * Single step the machine a source line (or instruction if "inst_tracing"
     getsrcpos();
     erecover();
 }
 
 /*
  * Single step the machine a source line (or instruction if "inst_tracing"
- * is true.  If "isnext" is true, skip over procedure calls.
+ * is true).  If "isnext" is true, skip over procedure calls.
  */
 
 private Address getcall();
  */
 
 private Address getcall();
@@ -514,17 +596,21 @@ Boolean isnext;
     register Address addr;
     register Lineno line;
     String filename;
     register Address addr;
     register Lineno line;
     String filename;
+    Address startaddr;
 
 
+    startaddr = pc;
     addr = nextaddr(pc, isnext);
     addr = nextaddr(pc, isnext);
-    if (not inst_tracing) {
+    if (not inst_tracing and nlhdr.nlines != 0) {
        line = linelookup(addr);
        while (line == 0) {
            addr = nextaddr(addr, isnext);
            line = linelookup(addr);
        }
        line = linelookup(addr);
        while (line == 0) {
            addr = nextaddr(addr, isnext);
            line = linelookup(addr);
        }
+       curline = line;
+    } else {
+       curline = 0;
     }
     stepto(addr);
     }
     stepto(addr);
-    curline = line;
     filename = srcfilename(addr);
     setsource(filename);
 }
     filename = srcfilename(addr);
     setsource(filename);
 }
@@ -541,8 +627,44 @@ Boolean isnext;
  * that branches is the branch address (or relative offset).
  */
 
  * that branches is the branch address (or relative offset).
  */
 
+private Address findnextaddr();
+
 public Address nextaddr(startaddr, isnext)
 Address startaddr;
 public Address nextaddr(startaddr, isnext)
 Address startaddr;
+boolean isnext;
+{
+    Address addr;
+
+    addr = usignal(process);
+    if (addr == 0 or addr == 1) {
+       addr = findnextaddr(startaddr, isnext);
+    }
+    return addr;
+}
+
+/*
+ * Determine if it's ok to skip function f entered by instruction ins.
+ * If so, we're going to compute the return address and step to it.
+ * Therefore we cannot skip over a function entered by a jsb or bsb,
+ * since the return address is not easily computed for them.
+ */
+
+private boolean skipfunc (ins, f)
+VaxOpcode ins;
+Symbol f;
+{
+    boolean b;
+
+    b = (boolean) (
+       ins != O_JSB and ins != O_BSBB and ins != O_BSBW and
+       not inst_tracing and nlhdr.nlines != 0 and
+       nosource(curfunc) and canskip(curfunc)
+    );
+    return b;
+}
+
+private Address findnextaddr(startaddr, isnext)
+Address startaddr;
 Boolean isnext;
 {
     register Address addr;
 Boolean isnext;
 {
     register Address addr;
@@ -559,42 +681,65 @@ Boolean isnext;
     addr = startaddr;
     iread(&ins, addr, sizeof(ins));
     switch (ins) {
     addr = startaddr;
     iread(&ins, addr, sizeof(ins));
     switch (ins) {
+       /*
+        * It used to be that unconditional jumps and branches were handled
+        * by taking their destination address as the next address.  While
+        * saving the cost of starting up the process, this approach
+        * doesn't work when jumping indirect (since the value in the
+        * register might not yet have been set).
+        *
+        * So unconditional jumps and branches are now handled the same way
+        * as conditional jumps and branches.
+        *
        case O_BRB:
        case O_BRW:
        case O_BRB:
        case O_BRW:
-       case O_JMP:
            addrstatus = BRANCH;
            break;
            addrstatus = BRANCH;
            break;
+        *
+        */
            
        case O_BSBB:
        case O_BSBW:
        case O_JSB:
        case O_CALLG:
        case O_CALLS:
            
        case O_BSBB:
        case O_BSBW:
        case O_JSB:
        case O_CALLG:
        case O_CALLS:
-           if (isnext) {
-               addrstatus = SEQUENTIAL;
-           } else {
+           addrstatus = KNOWN;
+           stepto(addr);
+           pstep(process, DEFSIG);
+           addr = reg(PROGCTR);
+           pc = addr;
+           setcurfunc(whatblock(pc));
+           if (not isbperr()) {
+               printstatus();
+               /* NOTREACHED */
+           }
+           bpact();
+           if (isnext or skipfunc(ins, curfunc)) {
                addrstatus = KNOWN;
                addrstatus = KNOWN;
+               addr = return_addr();
                stepto(addr);
                stepto(addr);
-               pstep(process);
-               addr = reg(PROGCTR);
-               pc = addr;
+               bpact();
+           } else {
                callnews(/* iscall = */ true);
                callnews(/* iscall = */ true);
-               if (not isbperr()) {
-                   printstatus();
-               } else {
-                   bpact();
-               }
            }
            break;
 
        case O_RSB:
        case O_RET:
            addrstatus = KNOWN;
            }
            break;
 
        case O_RSB:
        case O_RET:
            addrstatus = KNOWN;
-           callnews(/* iscall = */ false);
-           addr = return_addr();
            stepto(addr);
            stepto(addr);
+           callnews(/* iscall = */ false);
+           pstep(process, DEFSIG);
+           addr = reg(PROGCTR);
+           pc = addr;
+           if (not isbperr()) {
+               printstatus();
+           }
+           bpact();
            break;
 
            break;
 
+       case O_BRB: case O_BRW:
+       case O_JMP: /* because it may be jmp (r1) */
        case O_BNEQ: case O_BEQL: case O_BGTR:
        case O_BLEQ: case O_BGEQ: case O_BLSS:
        case O_BGTRU: case O_BLEQU: case O_BVC:
        case O_BNEQ: case O_BEQL: case O_BGTR:
        case O_BLEQ: case O_BGEQ: case O_BLSS:
        case O_BGTRU: case O_BLEQU: case O_BVC:
@@ -607,7 +752,7 @@ Boolean isnext;
        case O_SOBGEQ: case O_SOBGTR:
            addrstatus = KNOWN;
            stepto(addr);
        case O_SOBGEQ: case O_SOBGTR:
            addrstatus = KNOWN;
            stepto(addr);
-           pstep(process);
+           pstep(process, DEFSIG);
            addr = reg(PROGCTR);
            pc = addr;
            if (not isbperr()) {
            addr = reg(PROGCTR);
            pc = addr;
            if (not isbperr()) {
@@ -795,7 +940,7 @@ Address addr;
            return;
        }
     }
            return;
        }
     }
-    iread(&save, addr, sizeof(addr));
+    iread(&save, addr, sizeof(save));
     newsave = new(Savelist);
     newsave->location = addr;
     newsave->save = save;
     newsave = new(Savelist);
     newsave->location = addr;
     newsave->save = save;
@@ -837,16 +982,6 @@ Address addr;
     panic("unsetbp: couldn't find address %d", addr);
 }
 
     panic("unsetbp: couldn't find address %d", addr);
 }
 
-/*
- * Predicate to test if the reason the process stopped was because
- * of a breakpoint.
- */
-
-public Boolean isbperr()
-{
-    return (Boolean) (not isfinished(process) and errnum(process) == SIGTRAP);
-}
-
 /*
  * Enter a procedure by creating and executing a call instruction.
  */
 /*
  * Enter a procedure by creating and executing a call instruction.
  */
@@ -875,7 +1010,7 @@ Integer argc;
     mov(&dest, call.addr, sizeof(call.addr));
     iwrite(&call, pc, sizeof(call));
     setreg(PROGCTR, pc);
     mov(&dest, call.addr, sizeof(call.addr));
     iwrite(&call, pc, sizeof(call));
     setreg(PROGCTR, pc);
-    pstep(process);
+    pstep(process, DEFSIG);
     iwrite(save, pc, sizeof(save));
     pc = reg(PROGCTR);
     if (not isbperr()) {
     iwrite(save, pc, sizeof(save));
     pc = reg(PROGCTR);
     if (not isbperr()) {