ref: 94443daf8e248e65afc8d3f17f26efea22748b51
dir: /utils/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)+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");