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, ulong pc, ulong 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 ulong pc, sp, link; 46 long v; 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) { /* trace from jmpbuf for multi-threaded code */ 131 if (get4(cormap, adrval, (long*)&sp) < 0 || 132 get4(cormap, adrval+4, (long*)&pc) < 0) 133 error("%r"); 134 } else { 135 sp = rget(cormap, mach->sp); 136 pc = rget(cormap, mach->pc); 137 } 138 if(mach->link) 139 link = rget(cormap, mach->link); 140 else 141 link = 0; 142 if (machdata->ctrace(cormap, pc, sp, link, ptrace) <= 0) 143 error("no stack frame"); 144 } 145 break; 146 147 /*print externals*/ 148 case 'e': 149 for (i = 0; globalsym(&s, i); i++) { 150 if (get4(cormap, s.value, &v) > 0) 151 dprint("%s/%12t%#lux\n", s.name, v); 152 } 153 break; 154 155 /*print breakpoints*/ 156 case 'b': 157 case 'B': 158 for (bk=bkpthead; bk; bk=bk->nxtbkpt) 159 if (bk->flag) { 160 symoff(buf, 512, (WORD)bk->loc, CTEXT); 161 dprint(buf); 162 if (bk->count != 1) 163 dprint(",%d", bk->count); 164 dprint(":%c %s", bk->flag == BKPTTMP ? 'B' : 'b', bk->comm); 165 } 166 break; 167 168 case 'M': 169 fname = getfname(); 170 if (machbyname(fname) == 0) 171 dprint("unknown name\n");; 172 break; 173 default: 174 error("bad `$' command"); 175 } 176 177 } 178 179 char * 180 getfname(void) 181 { 182 static char fname[ARB]; 183 char *p; 184 185 if (rdc() == EOR) { 186 reread(); 187 return (0); 188 } 189 p = fname; 190 do { 191 *p++ = lastc; 192 if (p >= &fname[ARB-1]) 193 error("filename too long"); 194 } while (rdc() != EOR); 195 *p = 0; 196 reread(); 197 return (fname); 198 } 199 200 static void 201 printfp(Map *map, int modif) 202 { 203 Reglist *rp; 204 int i; 205 int ret; 206 char buf[512]; 207 208 for (i = 0, rp = mach->reglist; rp->rname; rp += ret) { 209 ret = 1; 210 if (!(rp->rflags&RFLT)) 211 continue; 212 ret = fpformat(map, rp, buf, sizeof(buf), modif); 213 if (ret < 0) { 214 werrstr("Register %s: %r", rp->rname); 215 error("%r"); 216 } 217 /* double column print */ 218 if (i&0x01) 219 dprint("%40t%-8s%-12s\n", rp->rname, buf); 220 else 221 dprint("\t%-8s%-12s", rp->rname, buf); 222 i++; 223 } 224 } 225 226 void 227 redirin(int stack, char *file) 228 { 229 char pfile[ARB]; 230 231 if (file == 0) { 232 iclose(-1, 0); 233 return; 234 } 235 iclose(stack, 0); 236 if ((infile = open(file, 0)) < 0) { 237 strcpy(pfile, Ipath); 238 strcat(pfile, "/"); 239 strcat(pfile, file); 240 if ((infile = open(pfile, 0)) < 0) { 241 infile = STDIN; 242 error("cannot open"); 243 } 244 } 245 } 246 247 void 248 printmap(char *s, Map *map) 249 { 250 int i; 251 252 if (!map) 253 return; 254 if (map == symmap) 255 dprint("%s%12t`%s'\n", s, fsym < 0 ? "-" : symfil); 256 else if (map == cormap) 257 dprint("%s%12t`%s'\n", s, fcor < 0 ? "-" : corfil); 258 else 259 dprint("%s\n", s); 260 for (i = 0; i < map->nsegs; i++) { 261 if (map->seg[i].inuse) 262 dprint("%s%8t%-16#lux %-16#lux %-16#lux\n", map->seg[i].name, 263 map->seg[i].b, map->seg[i].e, map->seg[i].f); 264 } 265 } 266 267 /* 268 * dump the raw symbol table 269 */ 270 void 271 printsym(void) 272 { 273 int i; 274 Sym *sp; 275 276 for (i = 0; sp = getsym(i); i++) { 277 switch(sp->type) { 278 case 't': 279 case 'l': 280 dprint("%8#lux t %s\n", sp->value, sp->name); 281 break; 282 case 'T': 283 case 'L': 284 dprint("%8#lux T %s\n", sp->value, sp->name); 285 break; 286 case 'D': 287 case 'd': 288 case 'B': 289 case 'b': 290 case 'a': 291 case 'p': 292 case 'm': 293 dprint("%8#lux %c %s\n", sp->value, sp->type, sp->name); 294 break; 295 default: 296 break; 297 } 298 } 299 } 300 301 #define STRINGSZ 128 302 303 /* 304 * print the value of dot as file:line 305 */ 306 void 307 printsource(long dot) 308 { 309 char str[STRINGSZ]; 310 311 if (fileline(str, STRINGSZ, dot)) 312 dprint("%s", str); 313 } 314 315 void 316 printpc(void) 317 { 318 char buf[512]; 319 320 dot = (ulong)rget(cormap, mach->pc); 321 if(dot){ 322 printsource((long)dot); 323 printc(' '); 324 symoff(buf, sizeof(buf), (long)dot, CTEXT); 325 dprint("%s/", buf); 326 if (machdata->das(cormap, dot, 'i', buf, sizeof(buf)) < 0) 327 error("%r"); 328 dprint("%16t%s\n", buf); 329 } 330 } 331 332 void 333 printlocals(Symbol *fn, ADDR fp) 334 { 335 int i; 336 long val; 337 Symbol s; 338 339 s = *fn; 340 for (i = 0; localsym(&s, i); i++) { 341 if (s.class != CAUTO) 342 continue; 343 if (get4(cormap, fp-s.value, &val) > 0) 344 dprint("%8t%s.%s/%10t%#lux\n", fn->name, s.name, val); 345 else 346 dprint("%8t%s.%s/%10t?\n", fn->name, s.name); 347 } 348 } 349 350 void 351 printparams(Symbol *fn, ADDR fp) 352 { 353 int i; 354 Symbol s; 355 long v; 356 int first = 0; 357 358 fp += mach->szaddr; /* skip saved pc */ 359 s = *fn; 360 for (i = 0; localsym(&s, i); i++) { 361 if (s.class != CPARAM) 362 continue; 363 if (first++) 364 dprint(", "); 365 if (get4(cormap, fp+s.value, &v) > 0) 366 dprint("%s=%#lux", s.name, v); 367 } 368 } 369