port 8.7 KB

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