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