// 386 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/hobbit/" }; srcfiles = {}; // list of loaded files srctext = {}; // the text of the files } defn stk() // trace { _stk(*PC, *SP, 0); } defn lstk() // trace with locals { _stk(*PC, *SP, 1); } defn gpr() // print general purpose registers { sp = fmt(*SP, 'X'); print("R0\t", *sp++, "R4\t", *sp++, "R8\t", *sp++, "R12\t", *sp++, "\n"); print("R16\t", *sp++, "R20\t", *sp++, "R24\t", *sp++, "R28\t", *sp++, "\n"); print("R32\t", *sp++, "R36\t", *sp++, "R40\t", *sp++, "R44\t", *sp++, "\n"); print("R48\t", *sp++, "R52\t", *sp++, "R56\t", *sp++, "R60\t", *sp++, "\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, "MSP\t", *MSP, "\n"); print("PSW\t", *PSW, "FAULT\t", *FAULT, "\n"); cause = *CAUSE; print("ID\t", *ID, "CAUSE ", cause, reason(cause), "\n"); } defn regs() // print all registers { spr(); gpr(); } defn next() { local lst; local addr; lst = follow(*PC); while lst do { addr = head lst; print(fmt(addr, 'a'),"\t", fmt(addr, 'i'), "\n"); lst = tail lst; } } defn pstop(pid) { local l; local 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; } } } } defn step() // single step the process { local lst; local lpl; local addr; local bput; lst = follow(*PC); lpl = lst; while lpl do { // place break points *((head lpl)^0x02) = bpinst; lpl = tail lpl; } bput = 0; if match(*PC, bplist) >= 0 then { // Sitting on a breakpoint bput = fmt(*PC^0x02, bpfmt); *bput = @bput; } startstop(pid); // do the step while lst do { // remove the breakpoints addr = fmt((head lst)^0x02, bpfmt); *addr = @addr; lst = tail lst; } if bput != 0 then *bput = bpinst; } defn bpset(addr) // set a breakpoint { if match(addr, bplist) >= 0 then print("breakpoint already set at ", fmt(addr, 'a'), "\n"); else { *fmt(addr^0x02, bpfmt) = bpinst; bplist = append bplist, addr; } } defn bpdel(addr) // delete a breakpoint { local n; local pc; local ra; local nbplist; n = match(addr, bplist); if n < 0 then print("no breakpoint at ", fmt(addr, 'a'), "\n"); else { ra = fmt(addr^0x02, bpfmt); *ra = @ra; nbplist = {}; // delete from list while bplist do { pc = head bplist; if pc != addr then nbplist = append nbplist, pc; bplist = tail bplist; } bplist = nbplist; // delete from memory } } defn cont() // continue execution { local addr; addr = fmt(*PC, bpfmt); if match(addr, bplist) >= 0 then { // Sitting on a breakpoint addr = addr^0x02; *addr = @addr; step(); // Step over *addr = bpinst; } startstop(pid); // Run } print("/lib/acid/hobbit");