URI:
       tprint.c - 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
       ---
       tprint.c (6525B)
       ---
            1 /*
            2  *
            3  *        debugger
            4  *
            5  */
            6 #include "defs.h"
            7 #include "fns.h"
            8 
            9 #define ptrace dbptrace
           10 
           11 extern        int        infile;
           12 extern        int        outfile;
           13 extern        int        maxpos;
           14 
           15 /* general printing routines ($) */
           16 
           17 char        *Ipath = INCDIR;
           18 static        int        tracetype;
           19 static void        printfp(Map*, int);
           20 
           21 /*
           22  *        callback on stack trace
           23  */
           24 static int
           25 ptrace(Map *map, Regs *regs, u64int pc, u64int nextpc, Symbol *sym, int depth)
           26 {
           27         char buf[512];
           28 
           29         USED(map);
           30         if(sym){
           31                 dprint("%s(", sym->name);
           32                 printparams(sym, regs);
           33                 dprint(") ");
           34         }else
           35                 dprint("%#lux ", pc);
           36         printsource(pc);
           37 
           38         dprint(" called from ");
           39         symoff(buf, 512, nextpc, CTEXT);
           40         dprint("%s ", buf);
           41 /*        printsource(nextpc); */
           42         dprint("\n");
           43         if(tracetype == 'C' && sym)
           44                 printlocals(sym, regs);
           45         return depth<40;
           46 }
           47 
           48 static ulong *adrregvals;
           49 
           50 static int
           51 adrrw(Regs *regs, char *name, u64int *val, int isr)
           52 {
           53         int i;
           54 
           55         if((i = windindex(name)) == -1)
           56                 return correg->rw(correg, name, val, isr);
           57         if(isr){
           58                 *val = adrregvals[i];
           59                 return 0;
           60         }
           61         werrstr("saved registers are immutable");
           62         return -1;
           63 }
           64 
           65 Regs*
           66 adrregs(void)
           67 {
           68         int i;
           69         static Regs r;
           70         static u32int x;
           71 
           72         if(adrregvals== nil){
           73                 adrregvals = malloc(mach->nwindreg*sizeof(adrregvals[0]));
           74                 if(adrregvals == nil)
           75                         error("%r");
           76         }
           77         for(i=0; i<mach->nwindreg; i++){
           78                 if(get4(cormap, adrval+4*i, &x) < 0)
           79                         error("%r");
           80                 adrregvals[i] = x;
           81         }
           82         r.rw = adrrw;
           83         return &r;
           84 }
           85 
           86 void
           87 printdollar(int modif)
           88 {
           89         int        i;
           90         u32int u4;
           91         BKPT *bk;
           92         Symbol s;
           93         int        stack;
           94         char        *fname;
           95         char buf[512];
           96         Regs *r;
           97 
           98         if (cntflg==0)
           99                 cntval = -1;
          100         switch (modif) {
          101 
          102         case '<':
          103                 if (cntval == 0) {
          104                         while (readchar() != EOR)
          105                                 ;
          106                         reread();
          107                         break;
          108                 }
          109                 if (rdc() == '<')
          110                         stack = 1;
          111                 else {
          112                         stack = 0;
          113                         reread();
          114                 }
          115                 fname = getfname();
          116                 redirin(stack, fname);
          117                 break;
          118 
          119         case '>':
          120                 fname = getfname();
          121                 redirout(fname);
          122                 break;
          123 
          124         case 'a':
          125                 attachprocess();
          126                 break;
          127 
          128 /* maybe use this for lwpids?
          129         case 'A':
          130                 attachpthread();
          131                 break;
          132 */
          133         case 'k':
          134                 kmsys();
          135                 break;
          136 
          137         case 'q':
          138         case 'Q':
          139                 done();
          140 
          141         case 'w':
          142                 maxpos=(adrflg?adrval:MAXPOS);
          143                 break;
          144 
          145         case 'S':
          146                 printsym();
          147                 break;
          148 
          149         case 's':
          150                 maxoff=(adrflg?adrval:MAXOFF);
          151                 break;
          152 
          153         case 'm':
          154                 printmap("? map", symmap);
          155                 printmap("/ map", cormap);
          156                 break;
          157 
          158         case 0:
          159         case '?':
          160                 if (pid)
          161                         dprint("pid = %d\n",pid);
          162                 else
          163                         prints("no process\n");
          164                 flushbuf();
          165 
          166         case 'r':
          167         case 'R':
          168                 printregs(modif);
          169                 return;
          170 
          171         case 'f':
          172         case 'F':
          173                 printfp(cormap, modif);
          174                 return;
          175 
          176         case 'c':
          177         case 'C':
          178                 tracetype = modif;
          179                 if (adrflg)
          180                         r = adrregs();
          181                 else
          182                         r = correg;
          183                 if(stacktrace(cormap, correg, ptrace) <= 0)
          184                         error("no stack frame");
          185                 break;
          186 
          187                 /*print externals*/
          188         case 'e':
          189                 for (i = 0; indexsym(i, &s)>=0; i++) {
          190                         if (s.class==CDATA)
          191                         if (s.loc.type==LADDR)
          192                         if (get4(cormap, s.loc.addr, &u4) > 0)
          193                                 dprint("%s/%12t%#lux\n", s.name, (ulong)u4);
          194                 }
          195                 break;
          196 
          197                 /*print breakpoints*/
          198         case 'b':
          199         case 'B':
          200                 for (bk=bkpthead; bk; bk=bk->nxtbkpt)
          201                         if (bk->flag) {
          202                                 symoff(buf, 512, (WORD)bk->loc, CTEXT);
          203                                 dprint(buf);
          204                                 if (bk->count != 1)
          205                                         dprint(",%d", bk->count);
          206                                 dprint(":%c %s", bk->flag == BKPTTMP ? 'B' : 'b', bk->comm);
          207                         }
          208                 break;
          209 
          210         case 'M':
          211                 fname = getfname();
          212                 if (machbyname(fname) == 0)
          213                         dprint("unknown name\n");;
          214                 break;
          215         default:
          216                 error("bad `$' command");
          217         }
          218         USED(r);
          219 
          220 }
          221 
          222 char *
          223 getfname(void)
          224 {
          225         static char fname[ARB];
          226         char *p;
          227 
          228         if (rdc() == EOR) {
          229                 reread();
          230                 return (0);
          231         }
          232         p = fname;
          233         do {
          234                 *p++ = lastc;
          235                 if (p >= &fname[ARB-1])
          236                         error("filename too long");
          237         } while (rdc() != EOR);
          238         *p = 0;
          239         reread();
          240         return (fname);
          241 }
          242 
          243 static void
          244 printfp(Map *map, int modif)
          245 {
          246         Regdesc *rp;
          247         int i;
          248         int ret;
          249         char buf[512];
          250 
          251         for (i = 0, rp = mach->reglist; rp->name; rp += ret) {
          252                 ret = 1;
          253                 if (!(rp->flags&RFLT))
          254                         continue;
          255                 ret = fpformat(map, rp, buf, sizeof(buf), modif);
          256                 if (ret < 0) {
          257                         werrstr("Register %s: %r", rp->name);
          258                         error("%r");
          259                 }
          260                         /* double column print */
          261                 if (i&0x01)
          262                         dprint("%40t%-8s%-12s\n", rp->name, buf);
          263                 else
          264                         dprint("\t%-8s%-12s", rp->name, buf);
          265                 i++;
          266         }
          267 }
          268 
          269 void
          270 redirin(int stack, char *file)
          271 {
          272         char pfile[ARB];
          273 
          274         if (file == 0) {
          275                 iclose(-1, 0);
          276                 return;
          277         }
          278         iclose(stack, 0);
          279         if ((infile = open(file, 0)) < 0) {
          280                 strcpy(pfile, Ipath);
          281                 strcat(pfile, "/");
          282                 strcat(pfile, file);
          283                 if ((infile = open(pfile, 0)) < 0) {
          284                         infile = STDIN;
          285                         error("cannot open");
          286                 }
          287         }
          288 }
          289 
          290 void
          291 printmap(char *s, Map *map)
          292 {
          293         int i;
          294 
          295         if (!map)
          296                 return;
          297         if (map == symmap)
          298                 dprint("%s%12t`%s'\n", s, symfil==nil ? "-" : symfil);
          299         else if (map == cormap)
          300                 dprint("%s%12t`%s'\n", s, corfil==nil ? "-" : corfil);
          301         else
          302                 dprint("%s\n", s);
          303         for (i = 0; i < map->nseg; i++) {
          304                 dprint("%s%8t%-16#lux %-16#lux %-16#lux %s\n", map->seg[i].name,
          305                         map->seg[i].base, map->seg[i].base+map->seg[i].size, map->seg[i].offset,
          306                         map->seg[i].file ? map->seg[i].file : "");
          307         }
          308 }
          309 
          310 /*
          311  *        dump the raw symbol table
          312  */
          313 void
          314 printsym(void)
          315 {
          316         int i;
          317         Symbol *sp, s;
          318 
          319         for (i=0; indexsym(i, &s)>=0; i++){
          320                 sp = &s;
          321                 switch(sp->type) {
          322                 case 't':
          323                 case 'l':
          324                         dprint("%8#lux t %s\n", sp->loc.addr, sp->name);
          325                         break;
          326                 case 'T':
          327                 case 'L':
          328                         dprint("%8#lux T %s\n", sp->loc.addr, sp->name);
          329                         break;
          330                 case 'D':
          331                 case 'd':
          332                 case 'B':
          333                 case 'b':
          334                 case 'a':
          335                 case 'p':
          336                 case 'm':
          337                         dprint("%8#lux %c %s\n", sp->loc.addr, sp->type, sp->name);
          338                         break;
          339                 default:
          340                         break;
          341                 }
          342         }
          343 }
          344 
          345 #define        STRINGSZ        128
          346 
          347 /*
          348  *        print the value of dot as file:line
          349  */
          350 void
          351 printsource(long dot)
          352 {
          353         char str[STRINGSZ];
          354 
          355         if (fileline(dot, str, STRINGSZ) >= 0)
          356                 dprint("%s", str);
          357 }
          358 
          359 void
          360 printpc(void)
          361 {
          362         char buf[512];
          363         u64int u;
          364 
          365         if(rget(correg, mach->pc, &u) < 0)
          366                 error("%r");
          367         dot = u;
          368         if(dot){
          369                 printsource((long)dot);
          370                 printc(' ');
          371                 symoff(buf, sizeof(buf), (long)dot, CTEXT);
          372                 dprint("%s/", buf);
          373                 if (mach->das(cormap, dot, 'i', buf, sizeof(buf)) < 0)
          374                         error("%r");
          375                 dprint("%16t%s\n", buf);
          376         }
          377 }
          378 
          379 void
          380 printlocals(Symbol *fn, Regs *regs)
          381 {
          382         int i;
          383         u32int v;
          384         Symbol s;
          385 
          386         for (i = 0; indexlsym(fn, i, &s)>=0; i++) {
          387                 if (s.class != CAUTO)
          388                         continue;
          389                 if(lget4(cormap, regs, s.loc, &v) >= 0)
          390                         dprint("%8t%s.%s/%10t%#lux\n", fn->name, s.name, v);
          391                 else
          392                         dprint("%8t%s.%s/%10t?\n", fn->name, s.name);
          393         }
          394 }
          395 
          396 void
          397 printparams(Symbol *fn, Regs *regs)
          398 {
          399         int i;
          400         Symbol s;
          401         u32int v;
          402         int first = 0;
          403 
          404         for (i = 0; indexlsym(fn, i, &s)>=0; i++) {
          405                 if (s.class != CPARAM)
          406                         continue;
          407                 if (first++)
          408                         dprint(", ");
          409                 if(lget4(cormap, regs, s.loc, &v) >= 0)
          410                         dprint("%s=%#lux", s.name, v);
          411                 else
          412                         dprint("%s=?", s.name);
          413         }
          414 }