#include <lib9.h>#include <bio.h>#include "mach.h"/* * Mips-specific debugger interface */ static char *mipsexcep(Map*, Rgetter);static int mipsfoll(Map*, uvlong, Rgetter, uvlong*);static int mipsinst(Map*, uvlong, char, char*, int);static int mipsdas(Map*, uvlong, char*, int);static int mipsinstlen(Map*, uvlong); /* * Debugger interface */Machdata mipsmach ={ {0, 0, 0, 0xD}, /* break point */ 4, /* break point size */ beswab, /* short to local byte order */ beswal, /* long to local byte order */ beswav, /* vlong to local byte order */ risctrace, /* C traceback */ riscframe, /* Frame finder */ mipsexcep, /* print exception */ 0, /* breakpoint fixup */ beieeesftos, /* single precision float printer */ beieeedftos, /* double precisioin float printer */ mipsfoll, /* following addresses */ mipsinst, /* print instruction */ mipsdas, /* dissembler */ mipsinstlen, /* instruction size */}; Machdata mipsmachle ={ {0, 0, 0, 0xD}, /* break point */ 4, /* break point size */ leswab, /* short to local byte order */ leswal, /* long to local byte order */ leswav, /* vlong to local byte order */ risctrace, /* C traceback */ riscframe, /* Frame finder */ mipsexcep, /* print exception */ 0, /* breakpoint fixup */ leieeesftos, /* single precision float printer */ leieeedftos, /* double precisioin float printer */ mipsfoll, /* following addresses */ mipsinst, /* print instruction */ mipsdas, /* dissembler */ mipsinstlen, /* instruction size */}; /* * mips r4k little-endian */Machdata mipsmach2le ={ {0, 0, 0, 0xD}, /* break point */ 4, /* break point size */ leswab, /* short to local byte order */ leswal, /* long to local byte order */ leswav, /* vlong to local byte order */ risctrace, /* C traceback */ riscframe, /* Frame finder */ mipsexcep, /* print exception */ 0, /* breakpoint fixup */ leieeesftos, /* single precision float printer */ leieeedftos, /* double precisioin float printer */ mipsfoll, /* following addresses */ mipsinst, /* print instruction */ mipsdas, /* dissembler */ mipsinstlen, /* instruction size */}; /* * mips r4k big-endian */Machdata mipsmach2be ={ {0, 0, 0, 0xD}, /* break point */ 4, /* break point size */ beswab, /* short to local byte order */ beswal, /* long to local byte order */ beswav, /* vlong to local byte order */ risctrace, /* C traceback */ riscframe, /* Frame finder */ mipsexcep, /* print exception */ 0, /* breakpoint fixup */ beieeesftos, /* single precision float printer */ beieeedftos, /* double precisioin float printer */ mipsfoll, /* following addresses */ mipsinst, /* print instruction */ mipsdas, /* dissembler */ mipsinstlen, /* instruction size */}; static char *excname[] ={ "external interrupt", "TLB modification", "TLB miss (load or fetch)", "TLB miss (store)", "address error (load or fetch)", "address error (store)", "bus error (fetch)", "bus error (data load or store)", "system call", "breakpoint", "reserved instruction", "coprocessor unusable", "arithmetic overflow", "undefined 13", "undefined 14", "system call", /* the following is made up */ "floating point exception" /* FPEXC */}; static char*mipsexcep(Map *map, Rgetter rget){ int e; long c; c = (*rget)(map, "CAUSE"); if(c & 0x00002000) /* INTR3 */ e = 16; /* Floating point exception */ else e = (c>>2)&0x0F; return excname[e];} /* mips disassembler and related functions */ static char FRAMENAME[] = ".frame"; typedef struct { uvlong addr; uchar op; /* bits 31-26 */ uchar rs; /* bits 25-21 */ uchar rt; /* bits 20-16 */ uchar rd; /* bits 15-11 */ uchar sa; /* bits 10-6 */ uchar function; /* bits 5-0 */ long immediate; /* bits 15-0 */ ulong cofun; /* bits 24-0 */ ulong target; /* bits 25-0 */ long w0; long w1; int size; /* instruction size */ char *curr; /* fill point in buffer */ char *end; /* end of buffer */ char *err; /* error message */} Instr; static Map *mymap; static intdecode(uvlong pc, Instr *i){ ulong w; if (get4(mymap, pc, &w) < 0) { werrstr("can't read instruction: %r"); return -1; } i->addr = pc; i->size = 1; i->op = (w >> 26) & 0x3F; i->rs = (w >> 21) & 0x1F; i->rt = (w >> 16) & 0x1F; i->rd = (w >> 11) & 0x1F; i->sa = (w >> 6) & 0x1F; i->function = w & 0x3F; i->immediate = w & 0x0000FFFF; if (i->immediate & 0x8000) i->immediate |= ~0x0000FFFF; i->cofun = w & 0x01FFFFFF; i->target = w & 0x03FFFFFF; i->w0 = w; return 1;} static intmkinstr(uvlong pc, Instr *i){ Instr x; if (decode(pc, i) < 0) return -1; /* * if it's a LUI followed by an ORI, * it's an immediate load of a large constant. * fix the LUI immediate in any case. */ if (i->op == 0x0F) { if (decode(pc+4, &x) < 0) return 0; i->immediate <<= 16; if (x.op == 0x0D && x.rs == x.rt && x.rt == i->rt) { i->immediate |= (x.immediate & 0xFFFF); i->w1 = x.w0; i->size++; return 1; } } /* * if it's a LWC1 followed by another LWC1 * into an adjacent register, it's a load of * a floating point double. */ else if (i->op == 0x31 && (i->rt & 0x01)) { if (decode(pc+4, &x) < 0) return 0; if (x.op == 0x31 && x.rt == (i->rt - 1) && x.rs == i->rs) { i->rt -= 1; i->w1 = x.w0; i->size++; return 1; } } /* * similarly for double stores */ else if (i->op == 0x39 && (i->rt & 0x01)) { if (decode(pc+4, &x) < 0) return 0; if (x.op == 0x39 && x.rt == (i->rt - 1) && x.rs == i->rs) { i->rt -= 1; i->w1 = x.w0; i->size++; } } return 1;} #pragma varargck argpos bprint 2 static voidbprint(Instr *i, char *fmt, ...){ va_list arg; va_start(arg, fmt); i->curr = vseprint(i->curr, i->end, fmt, arg); va_end(arg);} typedef struct Opcode Opcode; struct Opcode { char *mnemonic; void (*f)(Opcode *, Instr *); char *ken;}; static void format(char *, Instr *, char *); static voidbranch(Opcode *o, Instr *i){ if (i->rs == 0 && i->rt == 0) format("JMP", i, "%b"); else if (i->rs == 0) format(o->mnemonic, i, "R%t,%b"); else if (i->rt < 2) format(o->mnemonic, i, "R%s,%b"); else format(o->mnemonic, i, "R%s,R%t,%b");} static voidaddi(Opcode *o, Instr *i){ if (i->rs == i->rt) format(o->mnemonic, i, "%i,R%t"); else if (i->rs == 0) format("MOVW", i, "%i,R%t"); else if (i->rs == 30) { bprint(i, "MOVW\t$"); i->curr += symoff(i->curr, i->end-i->curr, i->immediate+mach->sb, CANY); bprint(i, "(SB),R%d", i->rt); } else format(o->mnemonic, i, o->ken);} static voidandi(Opcode *o, Instr *i){ if (i->rs == i->rt) format(o->mnemonic, i, "%i,R%t"); else format(o->mnemonic, i, o->ken);} static intplocal(Instr *i, char *m, char r, int store){ int offset; char *reg; Symbol s; if (!findsym(i->addr, CTEXT, &s) || !findlocal(&s, FRAMENAME, &s)) return 0; if (s.value > i->immediate) { if(!getauto(&s, s.value-i->immediate, CAUTO, &s)) return 0; reg = "(SP)"; offset = i->immediate; } else { offset = i->immediate-s.value; if (!getauto(&s, offset-4, CPARAM, &s)) return 0; reg = "(FP)"; } if (store) bprint(i, "%s\t%c%d,%s+%d%s", m, r, i->rt, s.name, offset, reg); else bprint(i, "%s\t%s+%d%s,%c%d", m, s.name, offset, reg, r, i->rt); return 1;} static voidlw(Opcode *o, Instr *i, char r){ char *m; if (r == 'F') { if (i->size == 2) m = "MOVD"; else m = "MOVF"; } else m = o->mnemonic; if (i->rs == 29 && plocal(i, m, r, 0)) return; if (i->rs == 30 && mach->sb) { bprint(i, "%s\t", m); i->curr += symoff(i->curr, i->end-i->curr, i->immediate+mach->sb, CANY); bprint(i, "(SB),%c%d", r, i->rt); return; } if (r == 'F') format(m, i, "%l,F%t"); else format(m, i, o->ken);} static voidload(Opcode *o, Instr *i){ lw(o, i, 'R');} static voidlwc1(Opcode *o, Instr *i){ lw(o, i, 'F');} static voidsw(Opcode *o, Instr *i, char r){ char *m; if (r == 'F') { if (i->size == 2) m = "MOVD"; else m = "MOVF"; } else m = o->mnemonic; if (i->rs == 29 && plocal(i, m, r, 1)) return; if (i->rs == 30 && mach->sb) { bprint(i, "%s\t%c%d,", m, r, i->rt); i->curr += symoff(i->curr, i->end-i->curr, i->immediate+mach->sb, CANY); bprint(i, "(SB)"); return; } if (r == 'F') format(m, i, "F%t,%l"); else format(m, i, o->ken);} static voidstore(Opcode *o, Instr *i){ sw(o, i, 'R');} static voidswc1(Opcode *o, Instr *i){ sw(o, i, 'F');} static voidsll(Opcode *o, Instr *i){ if (i->w0 == 0) bprint(i, "NOOP"); else if (i->rd == i->rt) format(o->mnemonic, i, "$%a,R%d"); else format(o->mnemonic, i, o->ken);} static voidsl32(Opcode *o, Instr *i){ i->sa += 32; if (i->rd == i->rt) format(o->mnemonic, i, "$%a,R%d"); else format(o->mnemonic, i, o->ken);} static voidsllv(Opcode *o, Instr *i){ if (i->rd == i->rt) format(o->mnemonic, i, "R%s,R%d"); else format(o->mnemonic, i, o->ken);} static voidjal(Opcode *o, Instr *i){ if (i->rd == 31) format("JAL", i, "(R%s)"); else format(o->mnemonic, i, o->ken);} static voidadd(Opcode *o, Instr *i){ if (i->rd == i->rs) format(o->mnemonic, i, "R%t,R%d"); else if (i->rd == i->rt) format(o->mnemonic, i, "R%s,R%d"); else format(o->mnemonic, i, o->ken);} static voidsub(Opcode *o, Instr *i){ if (i->rd == i->rs) format(o->mnemonic, i, "R%t,R%d"); else format(o->mnemonic, i, o->ken);} static voidor(Opcode *o, Instr *i){ if (i->rs == 0 && i->rt == 0) format("MOVW", i, "$0,R%d"); else if (i->rs == 0) format("MOVW", i, "R%t,R%d"); else if (i->rt == 0) format("MOVW", i, "R%s,R%d"); else add(o, i);} static voidnor(Opcode *o, Instr *i){ if (i->rs == 0 && i->rt == 0 && i->rd == 0) format("NOP", i, 0); else add(o, i);} static char mipscoload[] = "r%t,%l";static char mipsload[] = "%l,R%t";static char mipsstore[] = "R%t,%l";static char mipsalui[] = "%i,R%s,R%t";static char mipsalu3op[] = "R%t,R%s,R%d";static char mipsrtrs[] = "R%t,R%s";static char mipscorsrt[] = "r%s,r%t";Lines 1–500 of 1165. Load more
#include <lib9.h> #include <bio.h> #include "mach.h" /* * Mips-specific debugger interface */ static char *mipsexcep(Map*, Rgetter); static int mipsfoll(Map*, uvlong, Rgetter, uvlong*); static int mipsinst(Map*, uvlong, char, char*, int); static int mipsdas(Map*, uvlong, char*, int); static int mipsinstlen(Map*, uvlong); /* * Debugger interface */ Machdata mipsmach = { {0, 0, 0, 0xD}, /* break point */ 4, /* break point size */ beswab, /* short to local byte order */ beswal, /* long to local byte order */ beswav, /* vlong to local byte order */ risctrace, /* C traceback */ riscframe, /* Frame finder */ mipsexcep, /* print exception */ 0, /* breakpoint fixup */ beieeesftos, /* single precision float printer */ beieeedftos, /* double precisioin float printer */ mipsfoll, /* following addresses */ mipsinst, /* print instruction */ mipsdas, /* dissembler */ mipsinstlen, /* instruction size */ }; Machdata mipsmachle = { {0, 0, 0, 0xD}, /* break point */ 4, /* break point size */ leswab, /* short to local byte order */ leswal, /* long to local byte order */ leswav, /* vlong to local byte order */ risctrace, /* C traceback */ riscframe, /* Frame finder */ mipsexcep, /* print exception */ 0, /* breakpoint fixup */ leieeesftos, /* single precision float printer */ leieeedftos, /* double precisioin float printer */ mipsfoll, /* following addresses */ mipsinst, /* print instruction */ mipsdas, /* dissembler */ mipsinstlen, /* instruction size */ }; /* * mips r4k little-endian */ Machdata mipsmach2le = { {0, 0, 0, 0xD}, /* break point */ 4, /* break point size */ leswab, /* short to local byte order */ leswal, /* long to local byte order */ leswav, /* vlong to local byte order */ risctrace, /* C traceback */ riscframe, /* Frame finder */ mipsexcep, /* print exception */ 0, /* breakpoint fixup */ leieeesftos, /* single precision float printer */ leieeedftos, /* double precisioin float printer */ mipsfoll, /* following addresses */ mipsinst, /* print instruction */ mipsdas, /* dissembler */ mipsinstlen, /* instruction size */ }; /* * mips r4k big-endian */ Machdata mipsmach2be = { {0, 0, 0, 0xD}, /* break point */ 4, /* break point size */ beswab, /* short to local byte order */ beswal, /* long to local byte order */ beswav, /* vlong to local byte order */ risctrace, /* C traceback */ riscframe, /* Frame finder */ mipsexcep, /* print exception */ 0, /* breakpoint fixup */ beieeesftos, /* single precision float printer */ beieeedftos, /* double precisioin float printer */ mipsfoll, /* following addresses */ mipsinst, /* print instruction */ mipsdas, /* dissembler */ mipsinstlen, /* instruction size */ }; static char *excname[] = { "external interrupt", "TLB modification", "TLB miss (load or fetch)", "TLB miss (store)", "address error (load or fetch)", "address error (store)", "bus error (fetch)", "bus error (data load or store)", "system call", "breakpoint", "reserved instruction", "coprocessor unusable", "arithmetic overflow", "undefined 13", "undefined 14", "system call", /* the following is made up */ "floating point exception" /* FPEXC */ }; static char* mipsexcep(Map *map, Rgetter rget) { int e; long c; c = (*rget)(map, "CAUSE"); if(c & 0x00002000) /* INTR3 */ e = 16; /* Floating point exception */ else e = (c>>2)&0x0F; return excname[e]; } /* mips disassembler and related functions */ static char FRAMENAME[] = ".frame"; typedef struct { uvlong addr; uchar op; /* bits 31-26 */ uchar rs; /* bits 25-21 */ uchar rt; /* bits 20-16 */ uchar rd; /* bits 15-11 */ uchar sa; /* bits 10-6 */ uchar function; /* bits 5-0 */ long immediate; /* bits 15-0 */ ulong cofun; /* bits 24-0 */ ulong target; /* bits 25-0 */ long w0; long w1; int size; /* instruction size */ char *curr; /* fill point in buffer */ char *end; /* end of buffer */ char *err; /* error message */ } Instr; static Map *mymap; static int decode(uvlong pc, Instr *i) { ulong w; if (get4(mymap, pc, &w) < 0) { werrstr("can't read instruction: %r"); return -1; } i->addr = pc; i->size = 1; i->op = (w >> 26) & 0x3F; i->rs = (w >> 21) & 0x1F; i->rt = (w >> 16) & 0x1F; i->rd = (w >> 11) & 0x1F; i->sa = (w >> 6) & 0x1F; i->function = w & 0x3F; i->immediate = w & 0x0000FFFF; if (i->immediate & 0x8000) i->immediate |= ~0x0000FFFF; i->cofun = w & 0x01FFFFFF; i->target = w & 0x03FFFFFF; i->w0 = w; return 1; } static int mkinstr(uvlong pc, Instr *i) { Instr x; if (decode(pc, i) < 0) return -1; /* * if it's a LUI followed by an ORI, * it's an immediate load of a large constant. * fix the LUI immediate in any case. */ if (i->op == 0x0F) { if (decode(pc+4, &x) < 0) return 0; i->immediate <<= 16; if (x.op == 0x0D && x.rs == x.rt && x.rt == i->rt) { i->immediate |= (x.immediate & 0xFFFF); i->w1 = x.w0; i->size++; return 1; } } /* * if it's a LWC1 followed by another LWC1 * into an adjacent register, it's a load of * a floating point double. */ else if (i->op == 0x31 && (i->rt & 0x01)) { if (decode(pc+4, &x) < 0) return 0; if (x.op == 0x31 && x.rt == (i->rt - 1) && x.rs == i->rs) { i->rt -= 1; i->w1 = x.w0; i->size++; return 1; } } /* * similarly for double stores */ else if (i->op == 0x39 && (i->rt & 0x01)) { if (decode(pc+4, &x) < 0) return 0; if (x.op == 0x39 && x.rt == (i->rt - 1) && x.rs == i->rs) { i->rt -= 1; i->w1 = x.w0; i->size++; } } return 1; } #pragma varargck argpos bprint 2 static void bprint(Instr *i, char *fmt, ...) { va_list arg; va_start(arg, fmt); i->curr = vseprint(i->curr, i->end, fmt, arg); va_end(arg); } typedef struct Opcode Opcode; struct Opcode { char *mnemonic; void (*f)(Opcode *, Instr *); char *ken; }; static void format(char *, Instr *, char *); static void branch(Opcode *o, Instr *i) { if (i->rs == 0 && i->rt == 0) format("JMP", i, "%b"); else if (i->rs == 0) format(o->mnemonic, i, "R%t,%b"); else if (i->rt < 2) format(o->mnemonic, i, "R%s,%b"); else format(o->mnemonic, i, "R%s,R%t,%b"); } static void addi(Opcode *o, Instr *i) { if (i->rs == i->rt) format(o->mnemonic, i, "%i,R%t"); else if (i->rs == 0) format("MOVW", i, "%i,R%t"); else if (i->rs == 30) { bprint(i, "MOVW\t$"); i->curr += symoff(i->curr, i->end-i->curr, i->immediate+mach->sb, CANY); bprint(i, "(SB),R%d", i->rt); } else format(o->mnemonic, i, o->ken); } static void andi(Opcode *o, Instr *i) { if (i->rs == i->rt) format(o->mnemonic, i, "%i,R%t"); else format(o->mnemonic, i, o->ken); } static int plocal(Instr *i, char *m, char r, int store) { int offset; char *reg; Symbol s; if (!findsym(i->addr, CTEXT, &s) || !findlocal(&s, FRAMENAME, &s)) return 0; if (s.value > i->immediate) { if(!getauto(&s, s.value-i->immediate, CAUTO, &s)) return 0; reg = "(SP)"; offset = i->immediate; } else { offset = i->immediate-s.value; if (!getauto(&s, offset-4, CPARAM, &s)) return 0; reg = "(FP)"; } if (store) bprint(i, "%s\t%c%d,%s+%d%s", m, r, i->rt, s.name, offset, reg); else bprint(i, "%s\t%s+%d%s,%c%d", m, s.name, offset, reg, r, i->rt); return 1; } static void lw(Opcode *o, Instr *i, char r) { char *m; if (r == 'F') { if (i->size == 2) m = "MOVD"; else m = "MOVF"; } else m = o->mnemonic; if (i->rs == 29 && plocal(i, m, r, 0)) return; if (i->rs == 30 && mach->sb) { bprint(i, "%s\t", m); i->curr += symoff(i->curr, i->end-i->curr, i->immediate+mach->sb, CANY); bprint(i, "(SB),%c%d", r, i->rt); return; } if (r == 'F') format(m, i, "%l,F%t"); else format(m, i, o->ken); } static void load(Opcode *o, Instr *i) { lw(o, i, 'R'); } static void lwc1(Opcode *o, Instr *i) { lw(o, i, 'F'); } static void sw(Opcode *o, Instr *i, char r) { char *m; if (r == 'F') { if (i->size == 2) m = "MOVD"; else m = "MOVF"; } else m = o->mnemonic; if (i->rs == 29 && plocal(i, m, r, 1)) return; if (i->rs == 30 && mach->sb) { bprint(i, "%s\t%c%d,", m, r, i->rt); i->curr += symoff(i->curr, i->end-i->curr, i->immediate+mach->sb, CANY); bprint(i, "(SB)"); return; } if (r == 'F') format(m, i, "F%t,%l"); else format(m, i, o->ken); } static void store(Opcode *o, Instr *i) { sw(o, i, 'R'); } static void swc1(Opcode *o, Instr *i) { sw(o, i, 'F'); } static void sll(Opcode *o, Instr *i) { if (i->w0 == 0) bprint(i, "NOOP"); else if (i->rd == i->rt) format(o->mnemonic, i, "$%a,R%d"); else format(o->mnemonic, i, o->ken); } static void sl32(Opcode *o, Instr *i) { i->sa += 32; if (i->rd == i->rt) format(o->mnemonic, i, "$%a,R%d"); else format(o->mnemonic, i, o->ken); } static void sllv(Opcode *o, Instr *i) { if (i->rd == i->rt) format(o->mnemonic, i, "R%s,R%d"); else format(o->mnemonic, i, o->ken); } static void jal(Opcode *o, Instr *i) { if (i->rd == 31) format("JAL", i, "(R%s)"); else format(o->mnemonic, i, o->ken); } static void add(Opcode *o, Instr *i) { if (i->rd == i->rs) format(o->mnemonic, i, "R%t,R%d"); else if (i->rd == i->rt) format(o->mnemonic, i, "R%s,R%d"); else format(o->mnemonic, i, o->ken); } static void sub(Opcode *o, Instr *i) { if (i->rd == i->rs) format(o->mnemonic, i, "R%t,R%d"); else format(o->mnemonic, i, o->ken); } static void or(Opcode *o, Instr *i) { if (i->rs == 0 && i->rt == 0) format("MOVW", i, "$0,R%d"); else if (i->rs == 0) format("MOVW", i, "R%t,R%d"); else if (i->rt == 0) format("MOVW", i, "R%s,R%d"); else add(o, i); } static void nor(Opcode *o, Instr *i) { if (i->rs == 0 && i->rt == 0 && i->rd == 0) format("NOP", i, 0); else add(o, i); } static char mipscoload[] = "r%t,%l"; static char mipsload[] = "%l,R%t"; static char mipsstore[] = "R%t,%l"; static char mipsalui[] = "%i,R%s,R%t"; static char mipsalu3op[] = "R%t,R%s,R%d"; static char mipsrtrs[] = "R%t,R%s"; static char mipscorsrt[] = "r%s,r%t";