diff options
Diffstat (limited to 'lib/acid')
| -rw-r--r-- | lib/acid/386 | 205 | ||||
| -rw-r--r-- | lib/acid/arm | 84 | ||||
| -rw-r--r-- | lib/acid/gpa | 88 | ||||
| -rw-r--r-- | lib/acid/inferno | 63 | ||||
| -rw-r--r-- | lib/acid/mips | 217 | ||||
| -rw-r--r-- | lib/acid/port | 547 | ||||
| -rw-r--r-- | lib/acid/power | 233 | ||||
| -rw-r--r-- | lib/acid/rdebug | 116 | ||||
| -rw-r--r-- | lib/acid/sparc | 218 |
9 files changed, 1771 insertions, 0 deletions
diff --git a/lib/acid/386 b/lib/acid/386 new file mode 100644 index 00000000..ee65a3fd --- /dev/null +++ b/lib/acid/386 @@ -0,0 +1,205 @@ +// 386 support + +defn acidinit() // Called after all the init modules are loaded +{ + bpl = {}; + bpid = -1; + bpfmt = 'b'; + + srcpath = { + "./", + }; + + nopstop = 0; + srcfiles = {}; // list of loaded files + srctext = {}; // the text of the files + Labspoff = 4; // adjustment to Label's sp + Labpcoff = 0; // adjustment to Label's pc +} + +defn linkreg(addr) +{ + return 0; +} + +defn stk() // trace +{ + _stk(*PC, *SP, 0, 0); +} + +defn lstk() // trace with locals +{ + _stk(*PC, *SP, 0, 1); +} + +defn kstk() // kernel stack, PC and SP point to kernel +{ + _stk(*PC, *SP, 0, 0); +} + +defn lkstk() // kernel stack and locals, PC and SP are kernel's +{ + _stk(*PC, *SP, 0, 1); +} +defn gpr() // print general(hah hah!) purpose registers +{ + print("AX\t", *AX, " BX\t", *BX, " CX\t", *CX, " DX\t", *DX, "\n"); + print("DI\t", *DI, " SI\t", *SI, " BP\t", *BP, "\n"); +} + +defn spr() // print special processor registers +{ + local pc; + local cause; + + pc = *PC; + print("PC\t", pc, " ", fmt(pc, 'a'), " "); + pfl(pc); + print("SP\t", *SP, " ECODE ", *ECODE, " EFLAG ", *EFLAGS, "\n"); + print("CS\t", *CS, " DS\t ", *DS, " SS\t", *SS, "\n"); + print("GS\t", *GS, " FS\t ", *FS, " ES\t", *ES, "\n"); + + cause = *TRAP; + print("TRAP\t", cause, " ", reason(cause), "\n"); +} + +defn regs() // print all registers +{ + spr(); + gpr(); +} + +defn step() +{ + local ur; + local addrs; + local id; + local l; + local b; + local bl; + local sl; + local pc; + + complex Proc proc; + ur = proc.dbgreg; + if ur == 0 then + error("step: process not in breakpoint trap"); + complex Ureg ur; + + // + // stop all kprocs that could potentially hit this breakpoint + // make a list of all the breakpoints at this address + // + bl = {}; + sl = {}; + l = bpl; + + while l do { + b = head l; + if ((b[2] & *PC) == b[2]) then { + if status(b[1]) != "Stopped" then { + stop(b[1]); + sl = append sl, b[1]; + } + bl = append bl, b; + } + l = tail l; + } + + // + // delete all the breakpoints at this address + // + if bl then { + l = bl; + while l do { + b = head l; + _bpconddel(b[0]); + l = tail l; + } + } + + // + // single step to the following address + // + addrs = follow(*PC); + id = bpset(addrs[0]); + startstop(pid); + bpdel(id); + + // + // restore all the breakpoints at this address + // + if bl then { + l = bl; + while l do { + b = head l; + _bpcondset(b[0], b[1], b[2], b[3]); + l = tail l; + } + } + + // + // restart all kprocs that could potentially hit this breakpoint + // + if sl then { + l = sl; + while l do { + start(head l); + l = tail l; + } + } +} + +aggr Ureg +{ + 'X' 0 di; + 'X' 4 si; + 'X' 8 bp; + 'X' 12 nsp; + 'X' 16 bx; + 'X' 20 dx; + 'X' 24 cx; + 'X' 28 ax; + 'X' 32 gs; + 'X' 36 fs; + 'X' 40 es; + 'X' 44 ds; + 'X' 48 trap; + 'X' 52 ecode; + 'X' 56 pc; + 'X' 60 cs; + 'X' 64 flags; + { + 'X' 68 usp; + 'X' 68 sp; + }; + 'X' 72 ss; +}; + + +defn +Ureg(addr) { + complex Ureg addr; + print(" di ", addr.di, "\n"); + print(" si ", addr.si, "\n"); + print(" bp ", addr.bp, "\n"); + print(" nsp ", addr.nsp, "\n"); + print(" bx ", addr.bx, "\n"); + print(" dx ", addr.dx, "\n"); + print(" cx ", addr.cx, "\n"); + print(" ax ", addr.ax, "\n"); + print(" gs ", addr.gs, "\n"); + print(" fs ", addr.fs, "\n"); + print(" es ", addr.es, "\n"); + print(" ds ", addr.ds, "\n"); + print(" trap ", addr.trap, "\n"); + print(" ecode ", addr.ecode, "\n"); + print(" pc ", addr.pc, "\n"); + print(" cs ", addr.cs, "\n"); + print(" flags ", addr.flags, "\n"); + print(" sp ", addr.sp, "\n"); + print("}\n"); + print(" ss ", addr.ss, "\n"); +}; + +print("/sys/lib/acid/386"); diff --git a/lib/acid/arm b/lib/acid/arm new file mode 100644 index 00000000..8f054af5 --- /dev/null +++ b/lib/acid/arm @@ -0,0 +1,84 @@ +// ARM support + +defn acidinit() // Called after all the init modules are loaded +{ + bpl = {}; + bpid = -1; + bpfmt = 'X'; + nopstop = 0; + + srcpath = { + "./", + }; + + srcfiles = {}; // list of loaded files + srctext = {}; // the text of the files +} + +defn linkreg(addr) +{ + return 0; +} + +defn stk() // trace +{ + _stk(*PC, *SP, linkreg(0), 0); +} + +defn lstk() // trace with locals +{ + _stk(*PC, *SP, linkreg(0), 1); +} + +defn kstk() +{ + local lab; + complex Proc proc; + lab = proc.sched; + complex Label lab; + _stk(lab.pc\X, lab.sp\X, linkreg(0), 0); +} + +defn lkstk() +{ + local lab; + complex Proc proc; + lab = proc.sched; + complex Label lab; + _stk(lab.pc\X, lab.sp\X, linkreg(0), 1); +} + +defn gpr() // print general purpose registers +{ + print("R0\t", *R0, " R1\t", *R1, " R2\t", *R2, " R3\t", *R3, "\n"); + print("R4\t", *R4, " R5\t", *R5, " R6\t", *R6, " R7\t", *R7, "\n"); + print("R8\t", *R8, " R9\t", *R9, " R10\t", *R10, " R11\t", *R11, "\n"); + print("R12\t", *R12, "\n"); + return 0; +} + +defn spr() // print special processor registers +{ + local pc; + local cause; + local lr; + + pc = *PC; + lr = *LINK; + print("PC\t", pc, " ", fmt(pc, 'a'), " "); + pfl(pc); + print("LINK\t", lr, " ", fmt(lr, 'a'), " "); + pfl(lr); + print("TYPE: ", reason(*TYPE), "\n"); + print("SP\t", *SP, "\n"); + + return 0; +} + +defn regs() // print all registers +{ + spr(); + gpr(); +} + +print("$ROOT/lib/acid/arm"); diff --git a/lib/acid/gpa b/lib/acid/gpa new file mode 100644 index 00000000..8a08393f --- /dev/null +++ b/lib/acid/gpa @@ -0,0 +1,88 @@ +// +// generate ``General Purpose Ascii'' file for HP logic analyser +// +// usage: gpa() +// note: output has to be postprocessed with "sed 's/0x//g' "... +// + +defn functions(start, end) +{ + print("[FUNCTIONS]\n"); + pc = start; + while pc < end do { + bnd = fnbound(pc); + print(pc\a, "\t", bnd[0], "..", bnd[1]-1, "\n"); + pc = bnd[1]; + } + print("\n"); +} + +defn variables(start, end) +{ + print("[VARIABLES]\n"); + // TODO: how do we get this one? + print("\n"); +} + +defn sourcelines(start, end) +{ + local pc, curfile, curline, newfile, newline; + + print("[SOURCE LINES]\n"); + pc = txtstart; + curfile = "<no-file>"; + curline = -1; + while pc < txtend do { + newfile = pcfile(pc); + newline = pcline(pc); + if newfile != curfile then { + if curline != -1 then + print("\n"); + print("File: ", newfile, "\n"); + curfile = newfile; + } + if newline != curline then { + print(newline, "\t", pc, "\n"); + curline = newline; + } + pc++; + } + print("\n"); +} + +defn gpa() +{ + local l, ent, txtstart, txtend, datastart, dataend, pc, bnd; + + print("[SECTIONS]\n"); + l = map(); + while l do { + ent = head l; + if ent[0] == "text" || ent[0] == "data" then { + if ent[0] == "text" then { + txtstart = ent[1]; + txtend = ent[2]; + } + else { + datastart = ent[1]; + dataend = ent[2]; + } + print(ent[0], "\t", ent[1], "..", ent[2]-1, "\n"); + } + l = tail l; + } + print("\n"); + + functions(txtstart, txtend); +// variables(datastart, dataend); + sourcelines(datastart, dataend); + + print("[START ADDRESS]\n"); + print(txtstart, "\n"); + print("\n"); +} + +defn acidinit() +{ + gpa(); +} diff --git a/lib/acid/inferno b/lib/acid/inferno new file mode 100644 index 00000000..31769019 --- /dev/null +++ b/lib/acid/inferno @@ -0,0 +1,63 @@ +// +// experimental acid functions for Inferno (common to native and emu) +// +// problems arise because of unnamed substructures having to be +// named in emu, for instance Ref. We cheat by ``knowing'' that Ref +// is first in the structure, to keep this code portable between native +// and emu. +// + +// +// ps() - Process Listing +// +complex Ref pidalloc; + +defn +ps() +{ + local i; + local n; + local done; + local p; + local curpid; + + i = 0; + done = 0; + n = pidalloc.ref; + curpid = pid; + p = procalloc.arena; + + if n > conf.nproc then + n = conf.nproc; + + print("PID PC PRI STATE NAME\n"); + while n > 0 && i < conf.nproc do { + complex Proc p; + if p.state != 0 then { + print(p.pid, "\t", p.pc\X, "\t", p.pri, "\t", status(p.pid), "\t"); + mem(p.text, "s"); + n = n - 1; + } + i = i + 1; + p = p + sizeofProc; + } +} + +defn labels() +{ + local n; + local l; + complex Proc proc; + + n = proc.nerrlab; + l = proc.errlab; + while n > 0 do { + complex Label l; + print(l.pc\a, " "); + pfl(l.pc); + l = l + sizeofLabel; + n = n - 1; + } +} + +print("$ROOT/lib/acid/inferno"); diff --git a/lib/acid/mips b/lib/acid/mips new file mode 100644 index 00000000..5c267d1f --- /dev/null +++ b/lib/acid/mips @@ -0,0 +1,217 @@ +// Mips support + +defn acidinit() // Called after all the init modules are loaded +{ + bplist = {}; + bpfmt = 'X'; + + srcpath = { + "./", + "/sys/src/libc/port/", + "/sys/src/libc/9sys/", + "/sys/src/libc/mips/" + }; + + srcfiles = {}; // list of loaded files + srctext = {}; // the text of the files +} + +defn stk() // trace +{ + _stk(*PC, *SP, linkreg(0), 0); +} + +defn lstk() // trace with locals +{ + _stk(*PC, *SP, linkreg(0), 1); +} + +defn gpr() // print general purpose registers +{ + print("R1\t", *R1, " R2\t", *R2, " R3\t", *R3, "\n"); + print("R4\t", *R4, " R5\t", *R5, " R6\t", *R6, "\n"); + print("R7\t", *R7, " R8\t", *R8, " R9\t", *R9, "\n"); + print("R10\t", *R10, " R11\t", *R11, " R12\t", *R12, "\n"); + print("R13\t", *R13, " R14\t", *R14, " R15\t", *R15, "\n"); + print("R16\t", *R16, " R17\t", *R17, " R18\t", *R18, "\n"); + print("R19\t", *R19, " R20\t", *R20, " R21\t", *R21, "\n"); + print("R22\t", *R22, " R23\t", *R23, " R24\t", *R24, "\n"); + print("R25\t", *R25, " R26\t", *R26, " R27\t", *R27, "\n"); + print("R28\t", *R28, " R29\t", *SP, " R30\t", *R30, "\n"); + print("R31\t", *R31, "\n"); +} + +defn Fpr() +{ + print("F0\t", *fmt(F0, 'G'), "\tF2\t", *fmt(F2, 'G'), "\n"); + print("F4\t", *fmt(F4, 'G'), "\tF6\t", *fmt(F6, 'G'), "\n"); + print("F8\t", *fmt(F8, 'G'), "\tF10\t", *fmt(F10, 'G'), "\n"); + print("F12\t", *fmt(F12, 'G'), "\tF14\t", *fmt(F14, 'G'), "\n"); + print("F16\t", *fmt(F16, 'G'), "\tF18\t", *fmt(F18, 'G'), "\n"); + print("F20\t", *fmt(F20, 'G'), "\tF22\t", *fmt(F22, 'G'), "\n"); + print("F24\t", *fmt(F24, 'G'), "\tF26\t", *fmt(F26, 'G'), "\n"); + print("F28\t", *fmt(F28, 'G'), "\tF30\t", *fmt(F30, 'G'), "\n"); +} + +defn fpr() +{ + print("F0\t", *fmt(F0, 'g'), "\tF1\t", *fmt(F1, 'g'), "\n"); + print("F2\t", *fmt(F2, 'g'), "\tF3\t", *fmt(F3, 'g'), "\n"); + print("F4\t", *fmt(F4, 'g'), "\tF5\t", *fmt(F5, 'g'), "\n"); + print("F6\t", *fmt(F6, 'g'), "\tF7\t", *fmt(F7, 'g'), "\n"); + print("F8\t", *fmt(F8, 'g'), "\tF9\t", *fmt(F9, 'g'), "\n"); + print("F10\t", *fmt(F10, 'g'), "\tF11\t", *fmt(F11, 'g'), "\n"); + print("F12\t", *fmt(F12, 'g'), "\tF13\t", *fmt(F13, 'g'), "\n"); + print("F14\t", *fmt(F14, 'g'), "\tF15\t", *fmt(F15, 'g'), "\n"); + print("F16\t", *fmt(F16, 'g'), "\tF17\t", *fmt(F17, 'g'), "\n"); + print("F18\t", *fmt(F18, 'g'), "\tF19\t", *fmt(F19, 'g'), "\n"); + print("F20\t", *fmt(F20, 'g'), "\tF21\t", *fmt(F21, 'g'), "\n"); + print("F22\t", *fmt(F22, 'g'), "\tF23\t", *fmt(F23, 'g'), "\n"); + print("F24\t", *fmt(F24, 'g'), "\tF25\t", *fmt(F25, 'g'), "\n"); + print("F26\t", *fmt(F26, 'g'), "\tF27\t", *fmt(F27, 'g'), "\n"); + print("F28\t", *fmt(F28, 'g'), "\tF29\t", *fmt(F29, 'g'), "\n"); + print("F30\t", *fmt(F30, 'g'), "\tF31\t", *fmt(F31, 'g'), "\n"); +} + +defn spr() // print special processor registers +{ + local pc, link, cause; + + pc = *PC; + print("PC\t", pc, " ", fmt(pc, 'a'), " "); + pfl(pc); + + link = *R31; + print("SP\t", *SP, "\tLINK\t", link, " ", fmt(link, 'a'), " "); + pfl(link); + + cause = *CAUSE; + print("STATUS\t", *STATUS, "\tCAUSE\t", cause, " ", reason(cause), "\n"); + print("TLBVIR\t", *TLBVIRT, "\tBADVADR\t", *BADVADDR, "\n"); + + print("HI\t", *HI, "\tLO\t", *LO, "\n"); +} + +defn regs() // print all registers +{ + spr(); + gpr(); +} + +defn pstop(pid) +{ + local l, pc; + + pc = *PC; + + print(pid,": ", reason(*CAUSE), "\t"); + print(fmt(pc, 'a'), "\t", fmt(pc, 'i'), "\n"); + + if notes then { + if notes[0] != "sys: breakpoint" then { + print("Notes pending:\n"); + l = notes; + while l do { + print("\t", head l, "\n"); + l = tail l; + } + } + } +} + +sizeofUreg = 152; +aggr Ureg +{ + 'X' 0 status; + 'X' 4 pc; + { + 'X' 8 sp; + 'X' 8 usp; + }; + 'X' 12 cause; + 'X' 16 badvaddr; + 'X' 20 tlbvirt; + 'X' 24 hi; + 'X' 28 lo; + 'X' 32 r31; + 'X' 36 r30; + 'X' 40 r28; + 'X' 44 r27; + 'X' 48 r26; + 'X' 52 r25; + 'X' 56 r24; + 'X' 60 r23; + 'X' 64 r22; + 'X' 68 r21; + 'X' 72 r20; + 'X' 76 r19; + 'X' 80 r18; + 'X' 84 r17; + 'X' 88 r16; + 'X' 92 r15; + 'X' 96 r14; + 'X' 100 r13; + 'X' 104 r12; + 'X' 108 r11; + 'X' 112 r10; + 'X' 116 r9; + 'X' 120 r8; + 'X' 124 r7; + 'X' 128 r6; + 'X' 132 r5; + 'X' 136 r4; + 'X' 140 r3; + 'X' 144 r2; + 'X' 148 r1; +}; + +defn +Ureg(addr) { + complex Ureg addr; + print(" status ", addr.status, "\n"); + print(" pc ", addr.pc, "\n"); + print(" sp ", addr.sp, "\n"); + print(" cause ", addr.cause, "\n"); + print(" badvaddr ", addr.badvaddr, "\n"); + print(" tlbvirt ", addr.tlbvirt, "\n"); + print(" hi ", addr.hi, "\n"); + print(" lo ", addr.lo, "\n"); + print(" r31 ", addr.r31, "\n"); + print(" r30 ", addr.r30, "\n"); + print(" r28 ", addr.r28, "\n"); + print(" r27 ", addr.r27, "\n"); + print(" r26 ", addr.r26, "\n"); + print(" r25 ", addr.r25, "\n"); + print(" r24 ", addr.r24, "\n"); + print(" r23 ", addr.r23, "\n"); + print(" r22 ", addr.r22, "\n"); + print(" r21 ", addr.r21, "\n"); + print(" r20 ", addr.r20, "\n"); + print(" r19 ", addr.r19, "\n"); + print(" r18 ", addr.r18, "\n"); + print(" r17 ", addr.r17, "\n"); + print(" r16 ", addr.r16, "\n"); + print(" r15 ", addr.r15, "\n"); + print(" r14 ", addr.r14, "\n"); + print(" r13 ", addr.r13, "\n"); + print(" r12 ", addr.r12, "\n"); + print(" r11 ", addr.r11, "\n"); + print(" r10 ", addr.r10, "\n"); + print(" r9 ", addr.r9, "\n"); + print(" r8 ", addr.r8, "\n"); + print(" r7 ", addr.r7, "\n"); + print(" r6 ", addr.r6, "\n"); + print(" r5 ", addr.r5, "\n"); + print(" r4 ", addr.r4, "\n"); + print(" r3 ", addr.r3, "\n"); + print(" r2 ", addr.r2, "\n"); + print(" r1 ", addr.r1, "\n"); +}; + +defn linkreg(addr) +{ + complex Ureg addr; + return addr.r31\X; +} + +print("/sys/lib/acid/mips"); diff --git a/lib/acid/port b/lib/acid/port new file mode 100644 index 00000000..52d9871a --- /dev/null +++ b/lib/acid/port @@ -0,0 +1,547 @@ +// portable acid for all architectures + +defn pfl(addr) +{ + print(pcfile(addr), ":", pcline(addr), "\n"); +} + +defn +notestk(addr) +{ + local pc, sp; + complex Ureg addr; + + pc = addr.pc\X; + sp = addr.sp\X; + + print("Note pc:", pc, " sp:", sp, " ", fmt(pc, 'a'), " "); + pfl(pc); + _stk(pc, sp, linkreg(addr), 1); +} + +defn labstk(l) // trace from a label +{ + _stk(*(l+4), *l, linkreg(0), 0); +} + +defn params(param) +{ + while param do { + sym = head param; + print(sym[0], "=", sym[1]); + param = tail param; + if param then + print (","); + } +} + +defn locals(l) +{ + local sym; + + while l do { + sym = head l; + print("\t", sym[0], "=", sym[1], "\n"); + l = tail l; + } +} + +defn _stk(pc, sp, link, dolocals) +{ + local stk; + + print("At pc:", pc, ":", fmt(pc, 'a'), " "); + pfl(pc); + + stk = strace(pc, sp, link); + + while stk do { + frame = head stk; + print(fmt(frame[0], 'a'), "("); + params(frame[2]); + print(") ", pcfile(frame[0]), ":", pcline(frame[0])); + print("\n\tcalled from ", fmt(frame[1], 'a'), " "); + pfl(frame[1]); + stk = tail stk; + if dolocals then + locals(frame[3]); + } +} + +defn findsrc(file) +{ + local lst, src; + + if file[0] == '/' then { + src = file(file); + if src != {} then { + srcfiles = append srcfiles, file; + srctext = append srctext, src; + return src; + } + return {}; + } + + lst = srcpath; + while head lst do { + src = file(head lst+file); + if src != {} then { + srcfiles = append srcfiles, file; + srctext = append srctext, src; + return src; + } + lst = tail lst; + } +} + +defn line(addr) +{ + local src, file; + + file = pcfile(addr); + src = match(file, srcfiles); + + if src >= 0 then + src = srctext[src]; + else + src = findsrc(file); + + if src == {} then { + print("no source for ", file, "\n"); + return {}; + } + line = pcline(addr)-1; + print(file, ":", src[line], "\n"); +} + +defn addsrcdir(dir) +{ + dir = dir+"/"; + + if match(dir, srcpath) >= 0 then { + print("already in srcpath\n"); + return {}; + } + + srcpath = {dir}+srcpath; +} + +defn source() +{ + local l; + + l = srcpath; + while l do { + print(head l, "\n"); + l = tail l; + } + l = srcfiles; + + while l do { + print("\t", head l, "\n"); + l = tail l; + } +} + +defn Bsrc(addr) +{ + local lst; + + lst = srcpath; + file = pcfile(addr); + if file[0] == '/' && access(file) then { + rc("B "+itoa(-pcline(addr))+" "+file); + return {}; + } + while head lst do { + name = head lst+file; + if access(name) then { + rc("B "+itoa(-pcline(addr))+" "+name); + return {}; + } + lst = tail lst; + } + print("no source for ", file, "\n"); +} + +defn src(addr) +{ + local src, file, line, cline, text; + + file = pcfile(addr); + src = match(file, srcfiles); + + if src >= 0 then + src = srctext[src]; + else + src = findsrc(file); + + if src == {} then { + print("no source for ", file, "\n"); + return {}; + } + + cline = pcline(addr)-1; + print(file, ":", cline, "\n"); + line = cline-5; + loop 0,10 do { + if line >= 0 then { + if line == cline then + print(">"); + else + print(" "); + text = src[line]; + if text == {} then + return {}; + print(line, "\t", text, "\n"); + } + line = line+1; + } +} + +defn stopped(pid) // called from acid when a process changes state +{ + pstop(pid); // stub so this is easy to replace +} + +defn procs() // print status of processes +{ + local c, lst, cpid; + + cpid = pid; + lst = proclist; + while lst do { + np = head lst; + setproc(np); + if np == cpid then + c = '>'; + else + c = ' '; + print(fmt(c, 'c'), np, ": ", status(np), " at ", fmt(*PC, 'a'), " setproc(", np, ")\n"); + lst = tail lst; + } + pid = cpid; + if pid != 0 then + setproc(pid); +} + +defn asm(addr) +{ + local bound; + + bound = fnbound(addr); + + addr = fmt(addr, 'i'); + loop 1,30 do { + print(fmt(addr, 'a'), " ", fmt(addr, 'X')); + print("\t", @addr++, "\n"); + if bound != {} && addr > bound[1] then { + lasmaddr = addr; + return {}; + } + } + lasmaddr = addr; +} + +defn casm() +{ + asm(lasmaddr); +} + +defn new() +{ + bplist = {}; + newproc(progargs); + // Dont miss the delay slot calls + bpset(follow(main)[0]); + cont(); + bpdel(*PC); +} + +defn stmnt() // step one statement +{ + local line; + + line = pcline(*PC); + while 1 do { + step(); + if line != pcline(*PC) then { + src(*PC); + return {}; + } + } +} + +defn func() // step until we leave the current function +{ + local bound, end, start, pc; + + bound = fnbound(*PC); + if bound == {} then { + print("cannot locate text symbol\n"); + return {}; + } + + pc = *PC; + start = bound[0]; + end = bound[1]; + while pc >= start && pc < end do { + step(); + pc = *PC; + } +} + +defn next() +{ + local sp, bound; + + sp = *SP; + bound = fnbound(*PC); + stmnt(); + pc = *PC; + if pc >= bound[0] && pc < bound[1] then + return {}; + + while (pc < bound[0] || pc > bound[1]) && sp >= *SP do { + step(); + pc = *PC; + } + src(*PC); +} + +defn dump(addr, n, fmt) +{ + loop 0, n do { + print(fmt(addr, 'X'), ": "); + addr = mem(addr, fmt); + } +} + +defn mem(addr, fmt) +{ + + local i, c, n; + + i = 0; + while fmt[i] != 0 do { + c = fmt[i]; + n = 0; + while '0' <= fmt[i] && fmt[i] <= '9' do { + n = 10*n + fmt[i]-'0'; + i = i+1; + } + if n <= 0 then n = 1; + addr = fmt(addr, fmt[i]); + while n > 0 do { + print(*addr++, " "); + n = n-1; + } + i = i+1; + } + print("\n"); + return addr; +} + +defn symbols(pattern) +{ + local l, s; + + l = symbols; + while l do { + s = head l; + if regexp(pattern, s[0]) then + print(s[0], "\t", s[1], "\t", s[2], "\n"); + l = tail l; + } +} + +defn spsrch(len) +{ + local addr, a, s, e; + + addr = *SP; + s = origin & 0x7fffffff; + e = etext & 0x7fffffff; + loop 1, len do { + a = *addr++; + c = a & 0x7fffffff; + if c > s && c < e then { + print("src(", a, ")\n"); + pfl(a); + } + } +} + +defn bppush(val) +{ + return {"p", val}; +} + +defn bpderef() +{ + return {"*", 0}; +} + +defn bpmask() +{ + return {"&", 0}; +} + +defn bpeq() +{ + return {"=", 0}; +} + +defn bpneq() +{ + return {"!", 0}; +} + +defn bpand() +{ + return {"a", 0}; +} + +defn bpor() +{ + return {"o", 0}; +} + +defn bpcondset(pid, addr, conds) +{ + local l; + local id; + local found; + + if status(pid) != "Stopped" then { + print("Waiting...\n"); + stop(pid); + } + + id = 0; + found = 0; + + while !found && id <= 255 do { + l = bpl; + while l && head head l != id do { + l = tail l; + } + + if !l then + found = 1; + else + id = id + 1; + } + + if !found then { + print("error: no breakpoints available\n"); + return -1; + } + + bpl = append bpl, {id\d, pid\d, addr\X, conds}; + + _bpcondset(id, pid, addr, conds); + + return id; +} + +defn bpconddel(id) +{ + local i; + local l; + + l = bpl; + i = 0; + while l do { + if id == head head l then { + bpl = delete bpl, i; + _bpconddel(id); + if id == bpid then + bpid = -1; + return {}; + } + i = i + 1; + l = tail l; + } + print("no breakpoint with id ", id\d, ".\n"); +} + +defn bpprint(b) +{ + local l; + + print(b[0], "\t", b[1], "\t", fmt(b[2], 'a'), " ", b[2]); + print("\t{"); + l = b[3]; + while l do { + print("\n\t\t\t\t\t", head l); + l = tail l; + } + print(" }\n"); +} + +defn bptab() +{ + local l; + + l = bpl; + print("ID PID ADDR CONDITIONS\n"); + while l do { + bpprint(head l); + l = tail l; + } +} + +defn cont() +{ + local b, c, l, found; + + l = bpl; + found = 0; + c = *PC; + while !found && l do { + b = head l; + if b[2] == c then { + nopstop = 1; + step(); + nopstop = 0; + found = 1; + } else { + l = tail l; + } + } + + return startstop(pid); +} + +defn bpset(addr) // set a breakpoint +{ + return bpcondset(pid, addr, {}); +} + +defn bpdel(id) +{ + bpconddel(id); +} + +defn bpaddr(id) +{ + local i; + local l; + local b; + + l = bpl; + i = 0; + while l do { + b = head l; + if id == b[0] then + return b[2]; + i = i + 1; + l = tail l; + } + print("bpaddr(", id\d, "): no match\n"); + return {}; +} + +progargs=""; +print("$ROOT/lib/acid/port"); diff --git a/lib/acid/power b/lib/acid/power new file mode 100644 index 00000000..0691e243 --- /dev/null +++ b/lib/acid/power @@ -0,0 +1,233 @@ +// Power PC support + +defn acidinit() // Called after all the init modules are loaded +{ + bpl = {}; + bpid = -1; + bpfmt = 'X'; + nopstop = 0; + bplist = {}; + + srcpath = { + "./", + "/sys/src/libc/port/", + "/sys/src/libc/9sys/", + "/sys/src/libc/power/" + }; + + srcfiles = {}; // list of loaded files + srctext = {}; // the text of the files +} + +// defn stk() // trace +// { +// _stk(*PC, *SP, linkreg(0), 0); +// } + +// defn lstk() // trace with locals +// { +// _stk(*PC, *SP, linkreg(0), 1); +// } + +defn ustk(ur) +{ + complex Ureg ur; + _stk(ur.pc, ur.sp, 0, 0); +} + +defn lustk(ur) +{ + complex Ureg ur; + _stk(ur.pc, ur.sp, 0, 1); +} + +defn stk() +{ + ustk(0); +} + +defn lstk() +{ + lustk(0); +} + +defn kstk() +{ + local lab; + complex Proc proc; + lab = proc.sched; + complex Label lab; + _stk(lab.pc\X, lab.sp\X, 0, 0); +} + +defn lkstk() +{ + local lab; + complex Proc proc; + lab = proc.sched; + complex Label lab; + _stk(lab.pc\X, lab.sp\X, 0, 1); +} + +defn gpr() // print general purpose registers +{ + print("SP\t", *SP, " R2\t", *R2, " R3\t", *R3, "\n"); + print("R4\t", *R4, " R5\t", *R5, " R6\t", *R6, "\n"); + print("R7\t", *R7, " R8\t", *R8, " R9\t", *R9, "\n"); + print("R10\t", *R10, " R11\t", *R11, " R12\t", *R12, "\n"); + print("R13\t", *R13, " R14\t", *R14, " R15\t", *R15, "\n"); + print("R16\t", *R16, " R17\t", *R17, " R18\t", *R18, "\n"); + print("R19\t", *R19, " R20\t", *R20, " R21\t", *R21, "\n"); + print("R22\t", *R22, " R23\t", *R23, " R24\t", *R24, "\n"); + print("R25\t", *R25, " R26\t", *R26, " R27\t", *R27, "\n"); + print("R28\t", *R28, " R29\t", *R29, " R30\t", *R30, "\n"); + print("R31\t", *R31, "\n"); +} + +defn Fpr() +{ + fpr(); +} + +defn fpr() +{ + print("F0\t", *fmt(F0, 'G'), "\tF1\t", *fmt(F1, 'G'), "\n"); + print("F2\t", *fmt(F2, 'G'), "\tF3\t", *fmt(F3, 'G'), "\n"); + print("F4\t", *fmt(F4, 'G'), "\tF5\t", *fmt(F5, 'G'), "\n"); + print("F6\t", *fmt(F6, 'G'), "\tF7\t", *fmt(F7, 'G'), "\n"); + print("F8\t", *fmt(F8, 'G'), "\tF9\t", *fmt(F9, 'G'), "\n"); + print("F10\t", *fmt(F10, 'G'), "\tF11\t", *fmt(F11, 'G'), "\n"); + print("F12\t", *fmt(F12, 'G'), "\tF13\t", *fmt(F13, 'G'), "\n"); + print("F14\t", *fmt(F14, 'G'), "\tF15\t", *fmt(F15, 'G'), "\n"); + print("F16\t", *fmt(F16, 'G'), "\tF17\t", *fmt(F17, 'G'), "\n"); + print("F18\t", *fmt(F18, 'G'), "\tF19\t", *fmt(F19, 'G'), "\n"); + print("F20\t", *fmt(F20, 'G'), "\tF21\t", *fmt(F21, 'G'), "\n"); + print("F22\t", *fmt(F22, 'G'), "\tF23\t", *fmt(F23, 'G'), "\n"); + print("F24\t", *fmt(F24, 'G'), "\tF25\t", *fmt(F25, 'G'), "\n"); + print("F26\t", *fmt(F26, 'G'), "\tF27\t", *fmt(F27, 'G'), "\n"); + print("F28\t", *fmt(F28, 'G'), "\tF29\t", *fmt(F29, 'G'), "\n"); + print("F30\t", *fmt(F30, 'G'), "\tF31\t", *fmt(F31, 'G'), "\n"); +} + +defn spr() // print special processor registers +{ + local pc, link, cause; + + pc = *PC; + print("PC\t", pc, " ", fmt(pc, 'a'), " "); + pfl(pc); + + link = *R31; + print("SP\t", *SP, "\tLINK\t", link, " ", fmt(link, 'a'), " "); + pfl(link); + + cause = *CAUSE; + print("SRR1\t", *SRR1, "\tCAUSE\t", cause, " ", reason(cause), "\n"); + print("LR\t", *LR, "\tCR\t", *CR, "\n"); + + print("XER\t", *XER, "\tCTR\t", *CTR, "\n"); +} + +defn regs() // print all registers +{ + spr(); + gpr(); +} + + +defn linkreg(addr) +{ + return *LR; +} + +sizeofUreg = 160; +aggr Ureg +{ + 'U' 0 cause; + 'U' 4 status; + 'U' 8 pc; + 'U' 12 pad; + 'U' 16 lr; + 'U' 20 cr; + 'U' 24 xer; + 'U' 28 ctr; + 'U' 32 r0; + 'U' 36 sp; + 'U' 40 r2; + 'U' 44 r3; + 'U' 48 r4; + 'U' 52 r5; + 'U' 56 r6; + 'U' 60 r7; + 'U' 64 r8; + 'U' 68 r9; + 'U' 72 r10; + 'U' 76 r11; + 'U' 80 r12; + 'U' 84 r13; + 'U' 88 r14; + 'U' 92 r15; + 'U' 96 r16; + 'U' 100 r17; + 'U' 104 r18; + 'U' 108 r19; + 'U' 112 r20; + 'U' 116 r21; + 'U' 120 r22; + 'U' 124 r23; + 'U' 128 r24; + 'U' 132 r25; + 'U' 136 r26; + 'U' 140 r27; + 'U' 144 r28; + 'U' 148 r29; + 'U' 152 r30; + 'U' 156 r31; +}; + +defn +Ureg(addr) { + complex Ureg addr; + print(" cause ", addr.cause, "\n"); + print(" status ", addr.status, "\n"); + print(" pc ", addr.pc, "\n"); + print(" pad ", addr.pad, "\n"); + print(" lr ", addr.lr, "\n"); + print(" cr ", addr.cr, "\n"); + print(" xer ", addr.xer, "\n"); + print(" ctr ", addr.ctr, "\n"); + print(" r0 ", addr.r0, "\n"); + print(" sp ", addr.sp, "\n"); + print(" r2 ", addr.r2, "\n"); + print(" r3 ", addr.r3, "\n"); + print(" r4 ", addr.r4, "\n"); + print(" r5 ", addr.r5, "\n"); + print(" r6 ", addr.r6, "\n"); + print(" r7 ", addr.r7, "\n"); + print(" r8 ", addr.r8, "\n"); + print(" r9 ", addr.r9, "\n"); + print(" r10 ", addr.r10, "\n"); + print(" r11 ", addr.r11, "\n"); + print(" r12 ", addr.r12, "\n"); + print(" r13 ", addr.r13, "\n"); + print(" r14 ", addr.r14, "\n"); + print(" r15 ", addr.r15, "\n"); + print(" r16 ", addr.r16, "\n"); + print(" r17 ", addr.r17, "\n"); + print(" r18 ", addr.r18, "\n"); + print(" r19 ", addr.r19, "\n"); + print(" r20 ", addr.r20, "\n"); + print(" r21 ", addr.r21, "\n"); + print(" r22 ", addr.r22, "\n"); + print(" r23 ", addr.r23, "\n"); + print(" r24 ", addr.r24, "\n"); + print(" r25 ", addr.r25, "\n"); + print(" r26 ", addr.r26, "\n"); + print(" r27 ", addr.r27, "\n"); + print(" r28 ", addr.r28, "\n"); + print(" r29 ", addr.r29, "\n"); + print(" r30 ", addr.r30, "\n"); + print(" r31 ", addr.r31, "\n"); +}; + +print("/sys/lib/acid/power"); diff --git a/lib/acid/rdebug b/lib/acid/rdebug new file mode 100644 index 00000000..be8c45f9 --- /dev/null +++ b/lib/acid/rdebug @@ -0,0 +1,116 @@ +// Acid remote debug (using devdbg.c) + +defn step() +{ + local ur; + local addrs; + local id; + local l; + local b; + local bl; + local sl; + + complex Proc proc; + ur = proc.dbgreg; + if ur == 0 then + error("step: process not in breakpoint trap"); + complex Ureg ur; + + // + // stop all kprocs that could potentially hit this breakpoint + // make a list of all the breakpoints at this address + // + bl = {}; + sl = {}; + l = bpl; + while l do { + b = head l; + if b[2] == ur.pc then { + if status(b[1]) != "Stopped" then { + stop(b[1]); + sl = append sl, b[1]; + } + bl = append bl, b; + } + l = tail l; + } + + // + // delete all the breakpoints at this address + // + if bl then { + l = bl; + while l do { + b = head l; + _bpconddel(b[0]); + l = tail l; + } + } + + // + // single step to the following address + // + addrs = follow(ur.pc); + id = bpset(addrs[0]); + startstop(pid); + bpdel(id); + + // + // restore all the breakpoints at this address + // + if bl then { + l = bl; + while l do { + b = head l; + _bpcondset(b[0], b[1], b[2], b[3]); + l = tail l; + } + } + + // + // restart all kprocs that could potentially hit this breakpoint + // + if sl then { + l = sl; + while l do { + start(head l); + l = tail l; + } + } +} + +defn pstop(pid) +{ + local l; + local pc; + local ur; + + if nopstop then + return {}; + + complex Proc proc; + ur = proc.dbgreg; + complex Ureg ur; + pc = ur.pc; + + if _breakid != -1 then { + print("break ", _breakid\d, ": pid "); + _breakid = -1; + } + print(pid,": ", status(pid), "\t"); + + print(fmt(pc, 'a'), "\t", fmt(pc, 'i'), "\n"); + + if notes then { + if notes[0] != "sys: breakpoint" then { + print("Notes pending:\n"); + l = notes; + while l do { + print("\t", head l, "\n"); + l = tail l; + } + } + } +} + +print("$ROOT/lib/acid/rdebug"); diff --git a/lib/acid/sparc b/lib/acid/sparc new file mode 100644 index 00000000..76a1eba3 --- /dev/null +++ b/lib/acid/sparc @@ -0,0 +1,218 @@ +// Sparc support + +defn acidinit() // Called after all the init modules are loaded +{ + bplist = {}; + bpfmt = 'X'; + + srcpath = { + "./", + "/sys/src/libc/port/", + "/sys/src/libc/9sys/", + "/sys/src/libc/sparc/" + }; + + srcfiles = {}; // list of loaded files + srctext = {}; // the text of the files +} + +defn stk() // trace +{ + _stk(*PC, *R1, linkreg(0), 0); +} + +defn lstk() // trace with locals +{ + _stk(*PC, *R1, linkreg(0), 1); +} + +defn gpr() // print general purpose registers +{ + print("R1\t", *R1, "R2\t", *R2, "R3\t", *R3, "\n"); + print("R4\t", *R4, "R5\t", *R5, "R6\t", *R6, "\n"); + print("R7\t", *R7, "R8\t", *R8, "R9\t", *R9, "\n"); + print("R10\t", *R10, "R11\t", *R11, "R12\t", *R12, "\n"); + print("R13\t", *R13, "R14\t", *R14, "R15\t", *R15, "\n"); + print("R16\t", *R16, "R17\t", *R17, "R18\t", *R18, "\n"); + print("R19\t", *R19, "R20\t", *R20, "R21\t", *R21, "\n"); + print("R22\t", *R22, "R23\t", *R23, "R24\t", *R24, "\n"); + print("R25\t", *R25, "R26\t", *R26, "R27\t", *R27, "\n"); + print("R28\t", *R28, "R29\t", *R29, "R30\t", *R30, "\n"); + print("R31\t", *R31, "\n"); +} + +defn spr() // print special processor registers +{ + local pc; + local link; + local cause; + + pc = *PC; + print("PC\t", pc, " ", fmt(pc, 'a'), " "); + pfl(pc); + print("PSR\t", *PSR, "\n"); + + link = *R15; + print("SP\t", *R1, "\tLINK\t\t", link, " ", fmt(link, 'a')); + pfl(link); + + cause = *TBR; + print("Y\t", *Y, "\tCAUSE\t", *Y, cause, " ", reason(cause), "\n"); +} + +defn Fpr() +{ + print("F0\t", *fmt(F0, 'G'), "\tF2\t", *fmt(F2, 'G'), "\n"); + print("F4\t", *fmt(F4, 'G'), "\tF6\t", *fmt(F6, 'G'), "\n"); + print("F8\t", *fmt(F8, 'G'), "\tF10\t", *fmt(F10, 'G'), "\n"); + print("F12\t", *fmt(F12, 'G'), "\tF14\t", *fmt(F14, 'G'), "\n"); + print("F16\t", *fmt(F16, 'G'), "\tF18\t", *fmt(F18, 'G'), "\n"); + print("F20\t", *fmt(F20, 'G'), "\tF22\t", *fmt(F22, 'G'), "\n"); + print("F24\t", *fmt(F24, 'G'), "\tF26\t", *fmt(F26, 'G'), "\n"); + print("F28\t", *fmt(F28, 'G'), "\tF30\t", *fmt(F30, 'G'), "\n"); +} + +defn fpr() +{ + print("F0\t", *fmt(F0, 'g'), "\tF1\t", *fmt(F1, 'g'), "\n"); + print("F2\t", *fmt(F2, 'g'), "\tF3\t", *fmt(F3, 'g'), "\n"); + print("F4\t", *fmt(F4, 'g'), "\tF5\t", *fmt(F5, 'g'), "\n"); + print("F6\t", *fmt(F6, 'g'), "\tF7\t", *fmt(F7, 'g'), "\n"); + print("F8\t", *fmt(F8, 'g'), "\tF9\t", *fmt(F9, 'g'), "\n"); + print("F10\t", *fmt(F10, 'g'), "\tF11\t", *fmt(F11, 'g'), "\n"); + print("F12\t", *fmt(F12, 'g'), "\tF13\t", *fmt(F13, 'g'), "\n"); + print("F14\t", *fmt(F14, 'g'), "\tF15\t", *fmt(F15, 'g'), "\n"); + print("F16\t", *fmt(F16, 'g'), "\tF17\t", *fmt(F17, 'g'), "\n"); + print("F18\t", *fmt(F18, 'g'), "\tF19\t", *fmt(F19, 'g'), "\n"); + print("F20\t", *fmt(F20, 'g'), "\tF21\t", *fmt(F21, 'g'), "\n"); + print("F22\t", *fmt(F22, 'g'), "\tF23\t", *fmt(F23, 'g'), "\n"); + print("F24\t", *fmt(F24, 'g'), "\tF25\t", *fmt(F25, 'g'), "\n"); + print("F26\t", *fmt(F26, 'g'), "\tF27\t", *fmt(F27, 'g'), "\n"); + print("F28\t", *fmt(F28, 'g'), "\tF29\t", *fmt(F29, 'g'), "\n"); + print("F30\t", *fmt(F30, 'g'), "\tF31\t", *fmt(F31, 'g'), "\n"); +} + +defn regs() // print all registers +{ + spr(); + gpr(); +} + +defn pstop(pid) +{ + local l; + local pc; + + pc = *PC; + + print(pid,": ", reason(*TBR), "\t"); + print(fmt(pc, 'a'), "\t", fmt(pc, 'i'), "\n"); + + if notes then { + if notes[0] != "sys: breakpoint" then { + print("Notes pending:\n"); + l = notes; + while l do { + print("\t", head l, "\n"); + l = tail l; + } + } + } +} + +aggr Ureg +{ + 'U' 0 r0; + { + 'U' 4 sp; + 'U' 4 usp; + 'U' 4 r1; + }; + 'U' 8 r2; + 'U' 12 r3; + 'U' 16 r4; + 'U' 20 r5; + 'U' 24 r6; + 'U' 28 r7; + 'U' 32 r8; + 'U' 36 r9; + 'U' 40 r10; + 'U' 44 r11; + 'U' 48 r12; + 'U' 52 r13; + 'U' 56 r14; + 'U' 60 r15; + 'U' 64 r16; + 'U' 68 r17; + 'U' 72 r18; + 'U' 76 r19; + 'U' 80 r20; + 'U' 84 r21; + 'U' 88 r22; + 'U' 92 r23; + 'U' 96 r24; + 'U' 100 r25; + 'U' 104 r26; + 'U' 108 r27; + 'U' 112 r28; + 'U' 116 r29; + 'U' 120 r30; + 'U' 124 r31; + 'U' 128 y; + 'U' 132 tbr; + 'U' 136 psr; + 'U' 140 npc; + 'U' 144 pc; + 'U' 148 pad; +}; + +defn +Ureg(addr) { + complex Ureg addr; + print(" r0 ", addr.r0, "\n"); + print(" sp ", addr.sp, "\n"); + print(" r2 ", addr.r2, "\n"); + print(" r3 ", addr.r3, "\n"); + print(" r4 ", addr.r4, "\n"); + print(" r5 ", addr.r5, "\n"); + print(" r6 ", addr.r6, "\n"); + print(" r7 ", addr.r7, "\n"); + print(" r8 ", addr.r8, "\n"); + print(" r9 ", addr.r9, "\n"); + print(" r10 ", addr.r10, "\n"); + print(" r11 ", addr.r11, "\n"); + print(" r12 ", addr.r12, "\n"); + print(" r13 ", addr.r13, "\n"); + print(" r14 ", addr.r14, "\n"); + print(" r15 ", addr.r15, "\n"); + print(" r16 ", addr.r16, "\n"); + print(" r17 ", addr.r17, "\n"); + print(" r18 ", addr.r18, "\n"); + print(" r19 ", addr.r19, "\n"); + print(" r20 ", addr.r20, "\n"); + print(" r21 ", addr.r21, "\n"); + print(" r22 ", addr.r22, "\n"); + print(" r23 ", addr.r23, "\n"); + print(" r24 ", addr.r24, "\n"); + print(" r25 ", addr.r25, "\n"); + print(" r26 ", addr.r26, "\n"); + print(" r27 ", addr.r27, "\n"); + print(" r28 ", addr.r28, "\n"); + print(" r29 ", addr.r29, "\n"); + print(" r30 ", addr.r30, "\n"); + print(" r31 ", addr.r31, "\n"); + print(" y ", addr.y, "\n"); + print(" tbr ", addr.tbr, "\n"); + print(" psr ", addr.psr, "\n"); + print(" npc ", addr.npc, "\n"); + print(" pc ", addr.pc, "\n"); + print(" pad ", addr.pad, "\n"); +}; + +defn linkreg(addr) +{ + complex Ureg addr; + return addr.r15\X; +} + +print("/sys/lib/acid/sparc"); |
