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