📄 machine.c
字号:
/*#@(#)machine.c 4.1 Ultrix 7/17/90*//* Copyright (c) 1982 Regents of the University of California */static char sccsid[] = "@(#)machine.c 1.9 8/5/83";static char rcsid[] = "$Header: machine.c,v 1.3 84/03/27 10:21:26 linton Exp $";/* * Target machine dependent stuff. */#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 "ops.h"#include <signal.h>#ifndef publictypedef unsigned int Address;typedef unsigned char Byte;typedef unsigned int Word;#define NREG 16#define ARGP 12#define FRP 13#define STKP 14#define PROGCTR 15#define BITSPERBYTE 8#define BITSPERWORD (BITSPERBYTE * sizeof(Word))#define nargspassed(frame) argn(0, frame)#include "source.h"#include "symbols.h"Address pc;Address prtaddr;#endifprivate Address printop();/* * Decode and print the instructions within the given address range. */public printinst(lowaddr, highaddr)Address lowaddr;Address highaddr;{ register Address addr; for (addr = lowaddr; addr <= highaddr; ) { addr = printop(addr); } prtaddr = addr;}/* * Another approach: print n instructions starting at the given address. */public printninst(count, addr)int count;Address addr;{ register Integer i; register Address newaddr; if (count <= 0) { error("non-positive repetition count"); } else { newaddr = addr; for (i = 0; i < count; i++) { newaddr = printop(newaddr); } prtaddr = newaddr; }}/* * Hacked version of adb's VAX instruction decoder. */private Address printop(addr)Address addr;{ Optab op; VaxOpcode ins; unsigned char mode; int argtype, amode, argno, argval; String reg; Boolean indexf; short offset; argval = 0; indexf = false; printf("%08x ", addr); iread(&ins, addr, sizeof(ins)); addr += 1; op = optab[ins]; printf("%s", op.iname); for (argno = 0; argno < op.numargs; argno++) { if (indexf == true) { indexf = false; } else if (argno == 0) { printf("\t"); } else { printf(","); } argtype = op.argtype[argno]; if (is_branch_disp(argtype)) { mode = 0xAF + (typelen(argtype) << 5); } else { iread(&mode, addr, sizeof(mode)); addr += 1; } reg = regname[regnm(mode)]; amode = addrmode(mode); switch (amode) { case LITSHORT: case LITUPTO31: case LITUPTO47: case LITUPTO63: if (typelen(argtype) == TYPF || typelen(argtype) ==TYPD) printf("$%s", fltimm[mode]); else printf("$%x", mode); argval = mode; break; case INDEX: printf("[%s]", reg); indexf = true; argno--; break; case REG: printf("%s", reg); break; case REGDEF: printf("(%s)", reg); break; case AUTODEC: printf("-(%s)", reg); break; case AUTOINC: if (reg != regname[PROGCTR]) { printf("(%s)+", reg); } else { printf("$"); switch (typelen(argtype)) { case TYPB: argval = printdisp(addr, 1, reg, amode); addr += 1; break; case TYPW: argval = printdisp(addr, 2, reg, amode); addr += 2; break; case TYPL: argval = printdisp(addr, 4, reg, amode); addr += 4; break; case TYPF: iread(&argval, addr, sizeof(argval)); printf("%06x", argval); addr += 4; break; case TYPQ: case TYPD: iread(&argval, addr, sizeof(argval)); printf("%06x", argval); iread(&argval, addr+4, sizeof(argval)); printf("%06x", argval); addr += 8; break; } } break; case AUTOINCDEF: if (reg == regname[PROGCTR]) { printf("*$"); argval = printdisp(addr, 4, reg, amode); addr += 4; } else { printf("*(%s)+", reg); } break; case BYTEDISP: argval = printdisp(addr, 1, reg, amode); addr += 1; break; case BYTEDISPDEF: printf("*"); argval = printdisp(addr, 1, reg, amode); addr += 1; break; case WORDDISP: argval = printdisp(addr, 2, reg, amode); addr += 2; break; case WORDDISPDEF: printf("*"); argval = printdisp(addr, 2, reg, amode); addr += 2; break; case LONGDISP: argval = printdisp(addr, 4, reg, amode); addr += 4; break; case LONGDISPDEF: printf("*"); argval = printdisp(addr, 4, reg, amode); addr += 4; break; } } if (ins == O_CASEB || ins == O_CASEW || ins == O_CASEL) { for (argno = 0; argno <= argval; argno++) { iread(&offset, addr, sizeof(offset)); printf("\n\t\t%d", offset); addr += 2; } } printf("\n"); return addr;}/* * Print the displacement of an instruction that uses displacement * addressing. */private int printdisp(addr, nbytes, reg, mode)Address addr;int nbytes;char *reg;int mode;{ char byte; short hword; int argval; Symbol f; switch (nbytes) { case 1: iread(&byte, addr, sizeof(byte)); argval = byte; break; case 2: iread(&hword, addr, sizeof(hword)); argval = hword; break; case 4: iread(&argval, addr, sizeof(argval)); break; } if (reg == regname[PROGCTR] && mode >= BYTEDISP) { argval += addr + nbytes; } if (reg == regname[PROGCTR]) { f = whatblock((Address) argval + 2); if (codeloc(f) == argval + 2) { printf("%s", symname(f)); } else { printf("%x", argval); } } else { printf("%d(%s)", argval, reg); } return argval;}/* * Print the contents of the addresses within the given range * according to the given format. */typedef struct { String name; String printfstring; int length;} Format;private Format fmt[] = { { "d", " %d", sizeof(short) }, { "D", " %ld", sizeof(long) }, { "o", " %o", sizeof(short) }, { "O", " %lo", sizeof(long) }, { "x", " %04x", sizeof(short) }, { "X", " %08x", sizeof(long) }, { "b", " \\%o", sizeof(char) }, { "c", " '%c'", sizeof(char) }, { "s", "%c", sizeof(char) }, { "f", " %f", sizeof(float) }, { "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;String format;{ register int n; register Address addr; register Format *f; int value; if (lowaddr > highaddr) { error("first address larger than second"); } f = findformat(format); n = 0; value = 0; for (addr = lowaddr; addr <= highaddr; addr += f->length) { if (n == 0) { printf("%08x: ", addr); } dread(&value, addr, f->length); printf(f->printfstring, value); ++n; if (n >= (16 div f->length)) { putchar('\n'); n = 0; } } if (n != 0) { putchar('\n'); } prtaddr = addr; return addr;}/* * The other approach is to print n items starting with a given address. */public printndata(count, startaddr, format)int count;Address startaddr;String format;{ register int i, n; register Address addr; register Format *f; register Boolean isstring; char c; union { char charv; short shortv; int intv; float floatv; double doublev; } value; if (count <= 0) { error("non-positive repetition count"); } f = findformat(format); isstring = (Boolean) streq(f->name, "s"); n = 0; addr = startaddr; value.intv = 0; for (i = 0; i < count; i++) { if (n == 0) { printf("%08x: ", addr); } if (isstring) { putchar('"'); dread(&c, addr, sizeof(char)); while (c != '\0') { printchar(c); ++addr; dread(&c, addr, sizeof(char)); } putchar('"'); putchar('\n'); n = 0; addr += sizeof(String); } else { dread(&value, addr, f->length); printf(f->printfstring, value); ++n; if (n >= (16 div f->length)) { putchar('\n'); n = 0; } addr += f->length; } } if (n != 0) { putchar('\n'); } 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. * 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. */public printerror(){ extern Integer sys_nsig;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -