diff options
Diffstat (limited to 'utils/acid/port')
| -rw-r--r-- | utils/acid/port | 547 |
1 files changed, 547 insertions, 0 deletions
diff --git a/utils/acid/port b/utils/acid/port new file mode 100644 index 00000000..a348eb9c --- /dev/null +++ b/utils/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)+Labpcoff, *l+Labspoff, 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 = curpc(); + 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("/sys/lib/acid/port"); |
