ref: bd6c2aad586814b091ce5aca9d41cf2c51adb37b
dir: /lib/acid/port/
// 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");