URI: 
       tport - plan9port - [fork] Plan 9 from user space
  HTML git clone git://src.adamsgaard.dk/plan9port
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
       tport (10931B)
       ---
            1 // portable acid for all architectures
            2 
            3 defn pfl(addr)
            4 {
            5         print(pcfile(addr), ":", pcline(addr), "\n");
            6 }
            7 
            8 defn
            9 notestk(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", pc, "SP", sp, linkreg(addr)}, 1);
           20 }
           21 
           22 defn
           23 notelstk(addr)
           24 {
           25         local pc, sp;
           26         complex Ureg addr;
           27 
           28         pc = addr.pc\X;
           29         sp = addr.sp\X;
           30 
           31         print("Note pc:", pc, " sp:", sp, " ", fmt(pc, 'a'), " ");
           32         pfl(pc);
           33         _stk({"PC", pc, "SP", sp, linkreg(addr)}, 1);
           34 }
           35 
           36 defn params(param)
           37 {
           38         while param do {
           39                 sym = head param;
           40                 print(sym[0], "=", itoa(sym[1], "%#ux"));
           41                 param = tail param;
           42                 if param then
           43                         print (",");
           44         }        
           45 }
           46 
           47 stkprefix = "";
           48 stkignore = {};
           49 stkend = 0;
           50 
           51 defn locals(l)
           52 {
           53         local sym;
           54 
           55         while l do {
           56                 sym = head l;
           57                 print(stkprefix, "\t", sym[0], "=", itoa(sym[1], "%#ux"), "\n");
           58                 l = tail l;
           59         }        
           60 }
           61 
           62 defn _stkign(frame)
           63 {
           64         local file;
           65 
           66         file = pcfile(frame[0]);
           67         s = stkignore;
           68         while s do {
           69                 if regexp(head s, file) then
           70                         return 1;
           71                 s = tail s;
           72         }
           73         return 0;
           74 }
           75 
           76 // print a stack trace
           77 //
           78 // in a run of leading frames in files matched by regexps in stkignore,
           79 // only print the last one.
           80 defn _stk(regs, dolocals)
           81 {
           82         local stk, frame, pc, fn, done, callerpc, paramlist, locallist;
           83 
           84         stk = strace(regs);
           85         if stkignore then {
           86                 while stk && tail stk && _stkign(head tail stk) do
           87                         stk = tail stk;
           88         }
           89 
           90         callerpc = 0;
           91         done = 0;
           92         while stk && !done do {
           93                 frame = head stk;
           94                 stk = tail stk;
           95                 fn = frame[0];
           96                 pc = frame[1];
           97                 callerpc = frame[2];
           98                 paramlist = frame[3];
           99                 locallist = frame[4];
          100 
          101                 print(stkprefix, fmt(fn, 'a'), "(");
          102                 params(paramlist);
          103                 print(")");
          104                 if pc != fn then
          105                         print("+", itoa(pc-fn, "%#ux"));
          106                 print(" ");
          107                 pfl(pc);
          108                 if dolocals then
          109                         locals(locallist);
          110                 if fn == var("threadmain") || fn == var("p9main") then
          111                         done=1;
          112                 if fn == var("threadstart") || fn == var("scheduler") then
          113                         done=1;
          114                 if callerpc == 0 then
          115                         done=1;
          116         }
          117         if callerpc && !done then {
          118                 print(stkprefix, fmt(callerpc, 'a'), " ");
          119                 pfl(callerpc);
          120         }
          121 }
          122 
          123 defn findsrc(file)
          124 {
          125         local lst, src;
          126 
          127         if file[0] == '/' then {
          128                 src = file(file);
          129                 if src != {} then {
          130                         srcfiles = append srcfiles, file;
          131                         srctext = append srctext, src;
          132                         return src;
          133                 }
          134                 return {};
          135         }
          136 
          137         lst = srcpath;
          138         while head lst do {
          139                 src = file(head lst+file);
          140                 if src != {} then {
          141                         srcfiles = append srcfiles, file;
          142                         srctext = append srctext, src;
          143                         return src;
          144                 }
          145                 lst = tail lst;
          146         }
          147 }
          148 
          149 defn line(addr)
          150 {
          151         local src, file;
          152 
          153         file = pcfile(addr);
          154         src = match(file, srcfiles);
          155 
          156         if src >= 0 then
          157                 src = srctext[src];
          158         else
          159                 src = findsrc(file);
          160 
          161         if src == {} then {
          162                 print("no source for ", file, "\n");
          163                 return {};
          164         }
          165         line = pcline(addr)-1;
          166         print(file, ":", src[line], "\n");
          167 }
          168 
          169 defn addsrcdir(dir)
          170 {
          171         dir = dir+"/";
          172 
          173         if match(dir, srcpath) >= 0 then {
          174                 print("already in srcpath\n");
          175                 return {};
          176         }
          177 
          178         srcpath = {dir}+srcpath;
          179 }
          180 
          181 defn source()
          182 {
          183         local l;
          184 
          185         l = srcpath;
          186         while l do {
          187                 print(head l, "\n");
          188                 l = tail l;
          189         }
          190         l = srcfiles;
          191 
          192         while l do {
          193                 print("\t", head l, "\n");
          194                 l = tail l;
          195         }
          196 }
          197 
          198 defn Bsrc(addr)
          199 {
          200         local lst;
          201 
          202         lst = srcpath;
          203         file = pcfile(addr);
          204         if file[0] == '/' && access(file) then {
          205                 rc("B "+file+":"+itoa(pcline(addr)));
          206                 return {};
          207         }
          208         while head lst do {
          209                 name = head lst+file;
          210                 if access(name) then {
          211                         rc("B "+name+":"+itoa(pcline(addr)));
          212                         return {};
          213                 }
          214                 lst = tail lst;
          215         }
          216         print("no source for ", file, "\n");
          217 }
          218 
          219 defn srcline(addr)
          220 {
          221         local text, cline, line, file, src;
          222         file = pcfile(addr);
          223         src = match(file,srcfiles);
          224         if (src>=0) then
          225                 src = srctext[src];
          226         else
          227                 src = findsrc(file);
          228         if (src=={}) then
          229         {
          230                 return "(no source)";
          231         }
          232         return src[pcline(addr)-1];
          233 }
          234 
          235 defn src(addr)
          236 {
          237         local src, file, line, cline, text;
          238 
          239         file = pcfile(addr);
          240         src = match(file, srcfiles);
          241 
          242         if src >= 0 then
          243                 src = srctext[src];
          244         else
          245                 src = findsrc(file);
          246 
          247         if src == {} then {
          248                 print("no source for ", file, "\n");
          249                 return {};
          250         }
          251 
          252         cline = pcline(addr)-1;
          253         print(file, ":", cline+1, "\n");
          254         line = cline-5;
          255         loop 0,10 do {
          256                 if line >= 0 then {
          257                         if line == cline then
          258                                 print(">");
          259                         else
          260                                 print(" ");
          261                         text = src[line];
          262                         if text == {} then
          263                                 return {};
          264                         print(line+1, "\t", text, "\n");
          265                 }
          266                 line = line+1;
          267         }        
          268 }
          269 
          270 defn step()                                        // single step the process
          271 {
          272         local lst, lpl, addr, bput;
          273 
          274         bput = 0;
          275         if match(*PC, bplist) >= 0 then {        // Sitting on a breakpoint
          276                 bput = fmt(*PC, bpfmt);
          277                 *bput = @bput;
          278         }
          279 
          280         lst = follow(*PC);
          281 
          282         lpl = lst;
          283         while lpl do {                                // place break points
          284                 *(head lpl) = bpinst;
          285                 lpl = tail lpl;
          286         }
          287 
          288         startstop(pid);                                // do the step
          289 
          290         while lst do {                                // remove the breakpoints
          291                 addr = fmt(head lst, bpfmt);
          292                 *addr = @addr;
          293                 lst = tail lst;
          294         }
          295         if bput != 0 then
          296                 *bput = bpinst;
          297 }
          298 
          299 defn bpset(addr)                                // set a breakpoint
          300 {
          301         if status(pid) != "Stopped" then {
          302                 print("Waiting...\n");
          303                 stop(pid);
          304         }
          305         if match(addr, bplist) >= 0 then
          306                 print("breakpoint already set at ", fmt(addr, 'a'), "\n");
          307         else {
          308                 *fmt(addr, bpfmt) = bpinst;
          309                 bplist = append bplist, addr;
          310         }
          311 }
          312 
          313 defn bptab()                                        // print a table of breakpoints
          314 {
          315         local lst, addr;
          316 
          317         lst = bplist;
          318         while lst do {
          319                 addr = head lst;
          320                 print("\t", fmt(addr, 'X'), " ", fmt(addr, 'a'), "  ", fmt(addr, 'i'), "\n");
          321                 lst = tail lst;
          322         }
          323 }
          324 
          325 defn bpdel(addr)                                // delete a breakpoint
          326 {
          327         local n, pc, nbplist;
          328 
          329         if addr == 0 then {
          330                 while bplist do {
          331                         pc = head bplist;
          332                         pc = fmt(pc, bpfmt);
          333                         *pc = @pc;
          334                         bplist = tail bplist;
          335                 }
          336                 return {};
          337         }
          338 
          339         n = match(addr, bplist);
          340         if n < 0  then {
          341                 print("no breakpoint at ", fmt(addr, 'a'), "\n");
          342                 return {};
          343         }
          344 
          345         addr = fmt(addr, bpfmt);
          346         *addr = @addr;
          347 
          348         nbplist = {};                                // delete from list
          349         while bplist do {
          350                 pc = head bplist;
          351                 if pc != addr then
          352                         nbplist = append nbplist, pc;
          353                 bplist = tail bplist;
          354         }
          355         bplist = nbplist;                        // delete from memory
          356 }
          357 
          358 defn cont()                                        // continue execution
          359 {
          360         local addr;
          361 
          362         addr = fmt(*PC, bpfmt);
          363         if match(addr, bplist) >= 0 then {        // Sitting on a breakpoint
          364                 *addr = @addr;
          365                 step();                                // Step over
          366                 *addr = bpinst;
          367         }
          368         startstop(pid);                                // Run
          369 }
          370 
          371 defn stopped(pid)                // called from acid when a process changes state
          372 {
          373         pfixstop(pid);
          374         pstop(pid);                // stub so this is easy to replace
          375 }
          376 
          377 defn procs()                        // print status of processes
          378 {
          379         local c, lst, cpid;
          380 
          381         cpid = pid;
          382         lst = proclist;
          383         while lst do {
          384                 np = head lst;
          385                 setproc(np);
          386                 if np == cpid then
          387                         c = '>';
          388                 else
          389                         c = ' ';
          390                 print(fmt(c, 'c'), np, ": ", status(np), " at ", fmt(*PC, 'a'), " setproc(", np, ")\n");
          391                 lst = tail lst;
          392         }
          393         pid = cpid;
          394         if pid != 0 then
          395                 setproc(pid);
          396 }
          397 
          398 _asmlines = 30;
          399 
          400 defn asm(addr)
          401 {
          402         local bound;
          403 
          404         bound = fnbound(addr);
          405 
          406         addr = fmt(addr, 'i');
          407         loop 1,_asmlines do {
          408                 print(fmt(addr, 'a'), " ", fmt(addr, 'X'));
          409                 print("\t", @addr++, "\n");
          410                 if bound != {} && addr > bound[1] then {
          411                         lasmaddr = addr;
          412                         return {};
          413                 }
          414         }
          415         lasmaddr = addr;
          416 }
          417 
          418 defn casm()
          419 {
          420         asm(lasmaddr);
          421 }
          422 
          423 defn xasm(addr)
          424 {
          425         local bound;
          426 
          427         bound = fnbound(addr);
          428 
          429         addr = fmt(addr, 'i');
          430         loop 1,_asmlines do {
          431                 print(fmt(addr, 'a'), " ", fmt(addr, 'X'));
          432                 print("\t", *addr++, "\n");
          433                 if bound != {} && addr > bound[1] then {
          434                         lasmaddr = addr;
          435                         return {};
          436                 }
          437         }
          438         lasmaddr = addr;
          439 }
          440 
          441 defn xcasm()
          442 {
          443         xasm(lasmaddr);
          444 }
          445 
          446 defn win()
          447 {
          448         local npid, estr;
          449 
          450         bplist = {};
          451         notes = {};
          452 
          453         estr = "/sys/lib/acid/window '0 0 600 400' "+textfile;
          454         if progargs != "" then
          455                 estr = estr+" "+progargs;
          456 
          457         npid = rc(estr);
          458         npid = atoi(npid);
          459         if npid == 0 then
          460                 error("win failed to create process");
          461 
          462         setproc(npid);
          463         stopped(npid);
          464 }
          465 
          466 defn win2()
          467 {
          468         local npid, estr;
          469 
          470         bplist = {};
          471         notes = {};
          472 
          473         estr = "/sys/lib/acid/transcript '0 0 600 400' '100 100 700 500' "+textfile;
          474         if progargs != "" then
          475                 estr = estr+" "+progargs;
          476 
          477         npid = rc(estr);
          478         npid = atoi(npid);
          479         if npid == 0 then
          480                 error("win failed to create process");
          481 
          482         setproc(npid);
          483         stopped(npid);
          484 }
          485 
          486 printstopped = 1;
          487 defn new()
          488 {
          489         local a;
          490         
          491         bplist = {};
          492         newproc(progargs);
          493         a = var("p9main");
          494         if a == {} then
          495                 a = var("main");
          496         if a == {} then
          497                 return {};
          498         bpset(a);
          499         while *PC != a do
          500                 cont();
          501         bpdel(a);
          502 }
          503 
          504 defn stmnt()                        // step one statement
          505 {
          506         local line;
          507 
          508         line = pcline(*PC);
          509         while 1 do {
          510                 step();
          511                 if line != pcline(*PC) then {
          512                         src(*PC);
          513                         return {};
          514                 }
          515         }
          516 }
          517 
          518 defn func()                        // step until we leave the current function
          519 {
          520         local bound, end, start, pc;
          521 
          522         bound = fnbound(*PC);
          523         if bound == {} then {
          524                 print("cannot locate text symbol\n");
          525                 return {};
          526         }
          527 
          528         pc = *PC;
          529         start = bound[0];
          530         end = bound[1];
          531         while pc >= start && pc < end do {
          532                 step();
          533                 pc = *PC;
          534         }
          535 }
          536 
          537 defn next()
          538 {
          539         local sp, bound, pc;
          540 
          541         sp = *SP;
          542         bound = fnbound(*PC);
          543         if bound == {} then {
          544                 print("cannot locate text symbol\n");
          545                 return {};
          546         }
          547         stmnt();
          548         pc = *PC;
          549         if pc >= bound[0] && pc < bound[1] then
          550                 return {};
          551 
          552         while (pc < bound[0] || pc > bound[1]) && sp >= *SP do {
          553                 step();
          554                 pc = *PC;
          555         }
          556         src(*PC);
          557 }
          558 
          559 defn maps()
          560 {
          561         local m, mm;
          562 
          563         m = map();
          564         while m != {} do {
          565                 mm = head m;
          566                 m = tail m;
          567                 print(mm[2]\X, " ", mm[3]\X, " ", mm[4]\X, " ", mm[0], " ", mm[1], "\n");
          568         }
          569 }
          570 
          571 defn dump(addr, n, fmt)
          572 {
          573         loop 0, n do {
          574                 print(fmt(addr, 'X'), ": ");
          575                 addr = mem(addr, fmt);
          576         }
          577 }
          578 
          579 defn mem(addr, fmt)
          580 {
          581 
          582         local i, c, n;
          583 
          584         i = 0;
          585         while fmt[i] != 0 do {
          586                 c = fmt[i];
          587                 n = 0;
          588                 while '0' <= fmt[i] && fmt[i] <= '9' do {
          589                         n = 10*n + fmt[i]-'0';
          590                         i = i+1;
          591                 }
          592                 if n <= 0 then n = 1;
          593                 addr = fmt(addr, fmt[i]);
          594                 while n > 0 do {
          595                         print(*addr++, " ");
          596                         n = n-1;
          597                 }
          598                 i = i+1;
          599         }
          600         print("\n");
          601         return addr;
          602 }
          603 
          604 defn symbols(pattern)
          605 {
          606         local l, s, name;
          607         
          608         l = symbols;
          609         while l do {
          610                 s = head l;
          611                 if regexp(pattern, s[0]) then {
          612                         name = s[4];
          613                         if name == {} then
          614                                 name = "";
          615                         print(s[0], "\t", s[1], "\t", s[2], "\t", s[3], "\t", name, "\n");
          616                 }
          617                 l = tail l;
          618         }
          619 }
          620 
          621 defn havesymbol(name)
          622 {
          623         local l, s;
          624 
          625         l = symbols;
          626         while l do {
          627                 s = head l;
          628                 l = tail l;
          629                 if s[0] == name then
          630                         return 1;
          631         }
          632         return 0;
          633 }
          634 
          635 defn spsrch(len)
          636 {
          637         local addr, a, s, e;
          638 
          639         addr = *SP;
          640         s = origin & 0x7fffffff;
          641         e = etext & 0x7fffffff;
          642         loop 1, len do {
          643                 a = *addr++;
          644                 c = a & 0x7fffffff;
          645                 if c > s && c < e then {
          646                         print("src(", a, ")\n");
          647                         pfl(a);
          648                 }                        
          649         }
          650 }
          651 
          652 defn acidtypes()
          653 {
          654         local syms;
          655         local l;
          656 
          657         l = textfile();
          658         if l != {} then {
          659                 syms = "acidtypes";
          660                 while l != {} do {
          661                         syms = syms + " " + ((head l)[0]);
          662                         l = tail l;
          663                 }
          664                 includepipe(syms);
          665         }
          666 }
          667 
          668 defn getregs()
          669 {
          670         local regs, l;
          671 
          672         regs = {};
          673         l = registers;
          674         while l != {} do {
          675                 regs = append regs, var(l[0]);
          676                 l = tail l;
          677         }
          678         return regs;
          679 }
          680 
          681 defn setregs(regs)
          682 {
          683         local l;
          684 
          685         l = registers;
          686         while l != {} do {
          687                 var(l[0]) = regs[0];
          688                 l = tail l;
          689                 regs = tail regs;
          690         }
          691         return regs;
          692 }
          693 
          694 defn resetregs()
          695 {
          696         local l;
          697 
          698         l = registers;
          699         while l != {} do {
          700                 var(l[0]) = register(l[0]);
          701                 l = tail l;
          702         }
          703 }
          704 
          705 defn clearregs()
          706 {
          707         local l;
          708 
          709         l = registers;
          710         while l != {} do {
          711                 var(l[0]) = refconst(~0);
          712                 l = tail l;
          713         }
          714 }
          715 
          716 progargs="";
          717 print(acidfile);
          718