1// portable acid for all architectures 2 3defn pfl(addr) 4{ 5 print(pcfile(addr), ":", pcline(addr), "\n"); 6} 7 8defn 9notestk(addr) 10{ 11 local pc, sp; 12 complex Ureg addr; 13 14 pc = addr.pc\X; 15 sp = addr.sp\X; 16 17 print("Note pc:", pc, " sp:", sp, " ", fmt(pc, 'a'), " "); 18 pfl(pc); 19 _stk(pc, sp, linkreg(addr), 1); 20} 21 22defn labstk(l) // trace from a label 23{ 24 _stk(*(l+4), *l, linkreg(0), 0); 25} 26 27defn params(param) 28{ 29 while param do { 30 sym = head param; 31 print(sym[0], "=", sym[1]); 32 param = tail param; 33 if param then 34 print (","); 35 } 36} 37 38defn locals(l) 39{ 40 local sym; 41 42 while l do { 43 sym = head l; 44 print("\t", sym[0], "=", sym[1], "\n"); 45 l = tail l; 46 } 47} 48 49defn _stk(pc, sp, link, dolocals) 50{ 51 local stk; 52 53 print("At pc:", pc, ":", fmt(pc, 'a'), " "); 54 pfl(pc); 55 56 stk = strace(pc, sp, link); 57 58 while stk do { 59 frame = head stk; 60 print(fmt(frame[0], 'a'), "("); 61 params(frame[2]); 62 print(") ", pcfile(frame[0]), ":", pcline(frame[0])); 63 print("\n\tcalled from ", fmt(frame[1], 'a'), " "); 64 pfl(frame[1]); 65 stk = tail stk; 66 if dolocals then 67 locals(frame[3]); 68 } 69} 70 71defn findsrc(file) 72{ 73 local lst, src; 74 75 if file[0] == '/' then { 76 src = file(file); 77 if src != {} then { 78 srcfiles = append srcfiles, file; 79 srctext = append srctext, src; 80 return src; 81 } 82 return {}; 83 } 84 85 lst = srcpath; 86 while head lst do { 87 src = file(head lst+file); 88 if src != {} then { 89 srcfiles = append srcfiles, file; 90 srctext = append srctext, src; 91 return src; 92 } 93 lst = tail lst; 94 } 95} 96 97defn line(addr) 98{ 99 local src, file; 100 101 file = pcfile(addr); 102 src = match(file, srcfiles); 103 104 if src >= 0 then 105 src = srctext[src]; 106 else 107 src = findsrc(file); 108 109 if src == {} then { 110 print("no source for ", file, "\n"); 111 return {}; 112 } 113 line = pcline(addr)-1; 114 print(file, ":", src[line], "\n"); 115} 116 117defn addsrcdir(dir) 118{ 119 dir = dir+"/"; 120 121 if match(dir, srcpath) >= 0 then { 122 print("already in srcpath\n"); 123 return {}; 124 } 125 126 srcpath = {dir}+srcpath; 127} 128 129defn source() 130{ 131 local l; 132 133 l = srcpath; 134 while l do { 135 print(head l, "\n"); 136 l = tail l; 137 } 138 l = srcfiles; 139 140 while l do { 141 print("\t", head l, "\n"); 142 l = tail l; 143 } 144} 145 146defn Bsrc(addr) 147{ 148 local lst; 149 150 lst = srcpath; 151 file = pcfile(addr); 152 if file[0] == '/' && access(file) then { 153 rc("B "+itoa(-pcline(addr))+" "+file); 154 return {}; 155 } 156 while head lst do { 157 name = head lst+file; 158 if access(name) then { 159 rc("B "+itoa(-pcline(addr))+" "+name); 160 return {}; 161 } 162 lst = tail lst; 163 } 164 print("no source for ", file, "\n"); 165} 166 167defn src(addr) 168{ 169 local src, file, line, cline, text; 170 171 file = pcfile(addr); 172 src = match(file, srcfiles); 173 174 if src >= 0 then 175 src = srctext[src]; 176 else 177 src = findsrc(file); 178 179 if src == {} then { 180 print("no source for ", file, "\n"); 181 return {}; 182 } 183 184 cline = pcline(addr)-1; 185 print(file, ":", cline, "\n"); 186 line = cline-5; 187 loop 0,10 do { 188 if line >= 0 then { 189 if line == cline then 190 print(">"); 191 else 192 print(" "); 193 text = src[line]; 194 if text == {} then 195 return {}; 196 print(line, "\t", text, "\n"); 197 } 198 line = line+1; 199 } 200} 201 202defn stopped(pid) // called from acid when a process changes state 203{ 204 pstop(pid); // stub so this is easy to replace 205} 206 207defn procs() // print status of processes 208{ 209 local c, lst, cpid; 210 211 cpid = pid; 212 lst = proclist; 213 while lst do { 214 np = head lst; 215 setproc(np); 216 if np == cpid then 217 c = '>'; 218 else 219 c = ' '; 220 print(fmt(c, 'c'), np, ": ", status(np), " at ", fmt(*PC, 'a'), " setproc(", np, ")\n"); 221 lst = tail lst; 222 } 223 pid = cpid; 224 if pid != 0 then 225 setproc(pid); 226} 227 228defn asm(addr) 229{ 230 local bound; 231 232 bound = fnbound(addr); 233 234 addr = fmt(addr, 'i'); 235 loop 1,30 do { 236 print(fmt(addr, 'a'), " ", fmt(addr, 'X')); 237 print("\t", @addr++, "\n"); 238 if bound != {} && addr > bound[1] then { 239 lasmaddr = addr; 240 return {}; 241 } 242 } 243 lasmaddr = addr; 244} 245 246defn casm() 247{ 248 asm(lasmaddr); 249} 250 251defn new() 252{ 253 bplist = {}; 254 newproc(progargs); 255 // Dont miss the delay slot calls 256 bpset(follow(main)[0]); 257 cont(); 258 bpdel(*PC); 259} 260 261defn stmnt() // step one statement 262{ 263 local line; 264 265 line = pcline(*PC); 266 while 1 do { 267 step(); 268 if line != pcline(*PC) then { 269 src(*PC); 270 return {}; 271 } 272 } 273} 274 275defn func() // step until we leave the current function 276{ 277 local bound, end, start, pc; 278 279 bound = fnbound(*PC); 280 if bound == {} then { 281 print("cannot locate text symbol\n"); 282 return {}; 283 } 284 285 pc = *PC; 286 start = bound[0]; 287 end = bound[1]; 288 while pc >= start && pc < end do { 289 step(); 290 pc = *PC; 291 } 292} 293 294defn next() 295{ 296 local sp, bound; 297 298 sp = *SP; 299 bound = fnbound(*PC); 300 stmnt(); 301 pc = *PC; 302 if pc >= bound[0] && pc < bound[1] then 303 return {}; 304 305 while (pc < bound[0] || pc > bound[1]) && sp >= *SP do { 306 step(); 307 pc = *PC; 308 } 309 src(*PC); 310} 311 312defn dump(addr, n, fmt) 313{ 314 loop 0, n do { 315 print(fmt(addr, 'X'), ": "); 316 addr = mem(addr, fmt); 317 } 318} 319 320defn mem(addr, fmt) 321{ 322 323 local i, c, n; 324 325 i = 0; 326 while fmt[i] != 0 do { 327 c = fmt[i]; 328 n = 0; 329 while '0' <= fmt[i] && fmt[i] <= '9' do { 330 n = 10*n + fmt[i]-'0'; 331 i = i+1; 332 } 333 if n <= 0 then n = 1; 334 addr = fmt(addr, fmt[i]); 335 while n > 0 do { 336 print(*addr++, " "); 337 n = n-1; 338 } 339 i = i+1; 340 } 341 print("\n"); 342 return addr; 343} 344 345defn symbols(pattern) 346{ 347 local l, s; 348 349 l = symbols; 350 while l do { 351 s = head l; 352 if regexp(pattern, s[0]) then 353 print(s[0], "\t", s[1], "\t", s[2], "\n"); 354 l = tail l; 355 } 356} 357 358defn spsrch(len) 359{ 360 local addr, a, s, e; 361 362 addr = *SP; 363 s = origin & 0x7fffffff; 364 e = etext & 0x7fffffff; 365 loop 1, len do { 366 a = *addr++; 367 c = a & 0x7fffffff; 368 if c > s && c < e then { 369 print("src(", a, ")\n"); 370 pfl(a); 371 } 372 } 373} 374 375defn bppush(val) 376{ 377 return {"p", val}; 378} 379 380defn bpderef() 381{ 382 return {"*", 0}; 383} 384 385defn bpmask() 386{ 387 return {"&", 0}; 388} 389 390defn bpeq() 391{ 392 return {"=", 0}; 393} 394 395defn bpneq() 396{ 397 return {"!", 0}; 398} 399 400defn bpand() 401{ 402 return {"a", 0}; 403} 404 405defn bpor() 406{ 407 return {"o", 0}; 408} 409 410defn bpcondset(pid, addr, conds) 411{ 412 local l; 413 local id; 414 local found; 415 416 if status(pid) != "Stopped" then { 417 print("Waiting...\n"); 418 stop(pid); 419 } 420 421 id = 0; 422 found = 0; 423 424 while !found && id <= 255 do { 425 l = bpl; 426 while l && head head l != id do { 427 l = tail l; 428 } 429 430 if !l then 431 found = 1; 432 else 433 id = id + 1; 434 } 435 436 if !found then { 437 print("error: no breakpoints available\n"); 438 return -1; 439 } 440 441 bpl = append bpl, {id\d, pid\d, addr\X, conds}; 442 443 _bpcondset(id, pid, addr, conds); 444 445 return id; 446} 447 448defn bpconddel(id) 449{ 450 local i; 451 local l; 452 453 l = bpl; 454 i = 0; 455 while l do { 456 if id == head head l then { 457 bpl = delete bpl, i; 458 _bpconddel(id); 459 if id == bpid then 460 bpid = -1; 461 return {}; 462 } 463 i = i + 1; 464 l = tail l; 465 } 466 print("no breakpoint with id ", id\d, ".\n"); 467} 468 469defn bpprint(b) 470{ 471 local l; 472 473 print(b[0], "\t", b[1], "\t", fmt(b[2], 'a'), " ", b[2]); 474 print("\t{"); 475 l = b[3]; 476 while l do { 477 print("\n\t\t\t\t\t", head l); 478 l = tail l; 479 } 480 print(" }\n"); 481} 482 483defn bptab() 484{ 485 local l; 486 487 l = bpl; 488 print("ID PID ADDR CONDITIONS\n"); 489 while l do { 490 bpprint(head l); 491 l = tail l; 492 } 493} 494 495defn cont() 496{ 497 local b, c, l, found; 498 499 l = bpl; 500 found = 0; 501 c = *PC; 502 while !found && l do { 503 b = head l; 504 if b[2] == c then { 505 nopstop = 1; 506 step(); 507 nopstop = 0; 508 found = 1; 509 } else { 510 l = tail l; 511 } 512 } 513 514 return startstop(pid); 515} 516 517defn bpset(addr) // set a breakpoint 518{ 519 return bpcondset(pid, addr, {}); 520} 521 522defn bpdel(id) 523{ 524 bpconddel(id); 525} 526 527defn bpaddr(id) 528{ 529 local i; 530 local l; 531 local b; 532 533 l = bpl; 534 i = 0; 535 while l do { 536 b = head l; 537 if id == b[0] then 538 return b[2]; 539 i = i + 1; 540 l = tail l; 541 } 542 print("bpaddr(", id\d, "): no match\n"); 543 return {}; 544} 545 546progargs=""; 547print("$ROOT/lib/acid/port"); 548