| 1 | #include "head.h" |
| 2 | #include <a.out.h> |
| 3 | #include "cdefs.h" |
| 4 | struct user u; |
| 5 | BKPTR bkpthead; |
| 6 | STRING errflg; |
| 7 | |
| 8 | /* |
| 9 | * outvar(): |
| 10 | * Prints named variable, recursing once for each structure member or |
| 11 | * subscript. |
| 12 | * proc:var: variable name |
| 13 | * fmt: print format |
| 14 | * metaflag: set iff var contains metacharacters * or ? |
| 15 | * addr: partial address of variable, initally 0 |
| 16 | * class: type class of variable |
| 17 | * subflag: number of levels of subscript indirection |
| 18 | * prnamep: pointer to end of partially formed print name of variable |
| 19 | * comblk: name of common block containing variable, if any |
| 20 | * prflag: as in findvar |
| 21 | * |
| 22 | * Here and elsewhere we assume that -1 is an invalid address, and |
| 23 | * its is used to indicate error. |
| 24 | */ |
| 25 | outvar(proc, var, fmt, metaflag, addr, class, subflag, prnamep, comblk, prflag) |
| 26 | ADDR addr; char *proc, *var, *fmt, class, *prnamep, *comblk; { |
| 27 | char *p, *q, *r, *oldpr; |
| 28 | register int match; |
| 29 | long soffset, goffset; |
| 30 | register ADDR newaddr = -1, arrowaddr; |
| 31 | register enum {INIT, ARROW, DOT} typeflag; |
| 32 | |
| 33 | switch (var[0]) { |
| 34 | case '\0': |
| 35 | if (prflag == 0) return(addr); |
| 36 | if (metaflag) { |
| 37 | if (comblk[0] && !(eqstr(comblk, "*"))) |
| 38 | printf("%.8s:%.8s", comblk, prname); |
| 39 | else if (proc[0]) |
| 40 | printf("%.8s:%.8s", proc, prname); |
| 41 | else |
| 42 | printf("%s", prname); |
| 43 | if (prflag == 1) |
| 44 | printf("/ "); |
| 45 | else |
| 46 | printf("= "); |
| 47 | } |
| 48 | if (prflag == 1) |
| 49 | dispf(addr, fmt, class, sl_type, sl_size, subflag); |
| 50 | else |
| 51 | dispf(addr, fmt, 0, -1, 0, 0); |
| 52 | return(addr); |
| 53 | |
| 54 | case '[': |
| 55 | *prnamep++ = *var++; |
| 56 | p = var; |
| 57 | for (;;) { |
| 58 | *prnamep++ = *var; |
| 59 | if (*var == '\0' || *var == ']') break; |
| 60 | var++; |
| 61 | } |
| 62 | newaddr = getindir(class, addr, sl_type); |
| 63 | newaddr += typetosize(sl_type, sl_size) * readint(&p); |
| 64 | return(outvar(proc, var+1, fmt, metaflag, newaddr, N_GSYM, |
| 65 | subflag+1, prnamep, comblk, prflag)); |
| 66 | |
| 67 | case '-': |
| 68 | case '>': |
| 69 | typeflag = ARROW; |
| 70 | while (eqany(*var, "->")) |
| 71 | *prnamep++ = *var++; |
| 72 | subflag++; |
| 73 | arrowaddr = getindir(class, addr, sl_type); |
| 74 | if (errflg) { |
| 75 | printf("%s\n", errflg); |
| 76 | errflg = 0; |
| 77 | return(0); |
| 78 | } |
| 79 | class = N_GSYM; |
| 80 | if (var[0] == '\0') { |
| 81 | p = var; |
| 82 | goto recurse; |
| 83 | } |
| 84 | break; |
| 85 | |
| 86 | case '.': |
| 87 | typeflag = DOT; |
| 88 | if (class == N_RSYM) { |
| 89 | error("Not with a register variable"); |
| 90 | return(0); |
| 91 | } |
| 92 | *prnamep++ = *var++; |
| 93 | subflag = 0; |
| 94 | break; |
| 95 | |
| 96 | default: |
| 97 | typeflag = INIT; |
| 98 | break; |
| 99 | } |
| 100 | |
| 101 | if (typeflag == INIT) { |
| 102 | soffset = proc[0] ? adrtostoffset(callpc-1) : -1; |
| 103 | goffset = proc[0] ? -1 : findfile(curfile)->stf_offset; |
| 104 | } else { |
| 105 | soffset = proc[0] ? adrtostoffset(callpc-1) : -1; |
| 106 | goffset = findfile(curfile)->stf_offset; |
| 107 | } |
| 108 | |
| 109 | p = var; |
| 110 | oldpr = prnamep; |
| 111 | while (!eqany(*p, "->.[") && *p != '\0') |
| 112 | *prnamep++ = *p++; |
| 113 | *prnamep = '\0'; |
| 114 | |
| 115 | match = 0; |
| 116 | slookinit(); |
| 117 | |
| 118 | for (;;) { |
| 119 | if (soffset != -1) |
| 120 | if ((soffset = slooknext(var, soffset, typeflag!=INIT, |
| 121 | comblk)) != -1) |
| 122 | goto found; |
| 123 | if (goffset != -1) |
| 124 | if ((goffset = globallookup(var, goffset, |
| 125 | typeflag!=INIT)) != -1) |
| 126 | goto found; |
| 127 | return(newaddr); |
| 128 | |
| 129 | found: |
| 130 | r = sl_name; |
| 131 | q = oldpr; |
| 132 | while (*r) *q++ = *r++; |
| 133 | *q ='\0'; |
| 134 | |
| 135 | switch(typeflag) { |
| 136 | case INIT: |
| 137 | class = sl_class & STABMASK; |
| 138 | if (!varclass(class) || class == N_SSYM) |
| 139 | goto l; |
| 140 | newaddr = (class == N_LSYM) ? -sl_addr : sl_addr; |
| 141 | newaddr = formaddr(class, newaddr); |
| 142 | break; |
| 143 | |
| 144 | case ARROW: |
| 145 | class = sl_class & STABMASK; |
| 146 | if (!varclass(class) || class != N_SSYM) |
| 147 | goto l; |
| 148 | newaddr = arrowaddr + sl_addr; |
| 149 | break; |
| 150 | |
| 151 | case DOT: |
| 152 | class = sl_class & STABMASK; |
| 153 | if (!varclass(class) || class != N_SSYM) |
| 154 | goto l; |
| 155 | newaddr = addr + sl_addr; |
| 156 | break; |
| 157 | } |
| 158 | |
| 159 | recurse: |
| 160 | newaddr = outvar(proc, p, fmt, metaflag, newaddr, |
| 161 | class, subflag, prnamep, comblk, prflag); |
| 162 | |
| 163 | if (!metaflag) |
| 164 | return(newaddr); |
| 165 | l:; } |
| 166 | } |
| 167 | |
| 168 | prdebug() { |
| 169 | register struct proct *procp; |
| 170 | register struct filet *filep; |
| 171 | |
| 172 | printf("dot=%d\n", dot); |
| 173 | printf("extstart = %d\n", extstart); |
| 174 | for(filep=files;filep->sfilename[0];filep++) |
| 175 | printf("%s offs %d @ %d flag %d addr 0x%x\n", filep->sfilename, filep->stf_offset, filep, filep->lineflag, filep->faddr); |
| 176 | for(procp=procs;procp->pname[0];procp++) { |
| 177 | printf("%8.8s addr 0x%x; offs %d; sfptr %d; line %d", |
| 178 | procp->pname, procp->paddr, procp->st_offset, |
| 179 | procp->sfptr, procp->lineno); |
| 180 | if (procp->entrypt) printf(" entrypoint"); |
| 181 | printf("\n"); |
| 182 | } |
| 183 | } |
| 184 | |
| 185 | /* display addr using format desc or class s */ |
| 186 | dispf(addr, desc, class, type, size, subflag) |
| 187 | char *desc; short type; ADDR addr; { |
| 188 | dispx(addr, desc, class, type, size, subflag); |
| 189 | printf("\n"); |
| 190 | } |
| 191 | |
| 192 | char pd[] = "%x"; |
| 193 | dispx(addr, desc, class, type, size, subflag) |
| 194 | char *desc; short type; ADDR addr; { |
| 195 | int i, sflag; |
| 196 | char *p; |
| 197 | char dlen, dfmt; |
| 198 | long value; |
| 199 | union { |
| 200 | struct { |
| 201 | char c[WORDSIZE]; |
| 202 | }; |
| 203 | struct { |
| 204 | int w; |
| 205 | }; |
| 206 | struct { |
| 207 | float f; |
| 208 | } |
| 209 | } word; |
| 210 | union { |
| 211 | struct{ |
| 212 | int w1, w2; |
| 213 | }; |
| 214 | struct { |
| 215 | double d; |
| 216 | }; |
| 217 | } dbl; |
| 218 | |
| 219 | class &= STABMASK; |
| 220 | if (desc[0] == '\0') desc = typetodesc(type, subflag); |
| 221 | cpstr(odesc, desc); |
| 222 | otype = type; |
| 223 | oclass = class; |
| 224 | oaddr = addr; |
| 225 | oincr = 0; |
| 226 | if (debug) printf("dispf(%d,%s,0%o,0%o)\n", addr,desc,class,type); |
| 227 | pd[1] = dfmt = 'd'; |
| 228 | dlen = '\0'; |
| 229 | for (p = desc; *p; p++) { |
| 230 | if (*p>= '0' && *p<'9') { |
| 231 | size = readint(&p); |
| 232 | p--; |
| 233 | } else switch (*p) { |
| 234 | case 'l': |
| 235 | case 'h': |
| 236 | case 'b': |
| 237 | dlen = *p; |
| 238 | break; |
| 239 | |
| 240 | case 'a': |
| 241 | case 'c': |
| 242 | case 'd': |
| 243 | case 'f': |
| 244 | case 'g': |
| 245 | case 'o': |
| 246 | case 'p': |
| 247 | case 's': |
| 248 | case 'u': |
| 249 | case 'x': |
| 250 | pd[1] = dfmt = *p; |
| 251 | break; |
| 252 | |
| 253 | default: |
| 254 | printf("Illegal descriptor: %c\n", *p); |
| 255 | return; |
| 256 | } |
| 257 | } |
| 258 | |
| 259 | if (type == -1) |
| 260 | value = addr; |
| 261 | else if (class == N_RSYM && addr < 16) { |
| 262 | /* MACHINE DEPENDENT */ |
| 263 | if ((addr > 0 && addr < 6) || addr > 11) { |
| 264 | printf("Bad register var %d\n", addr); |
| 265 | return; |
| 266 | } |
| 267 | value = *(ADDR *)(((ADDR) &u) + R0 + (WORDSIZE)*addr); |
| 268 | } |
| 269 | else { |
| 270 | value = getval(addr, dfmt == 'g' ? 'd' : dfmt); |
| 271 | } |
| 272 | |
| 273 | if (errflg) { |
| 274 | printf("%s", errflg); |
| 275 | errflg = 0; |
| 276 | return; |
| 277 | } |
| 278 | |
| 279 | switch (dfmt) { |
| 280 | default: |
| 281 | switch (dfmt) { |
| 282 | case 'u': |
| 283 | case 'x': |
| 284 | case 'o': |
| 285 | switch (dlen) { |
| 286 | case 'h': |
| 287 | value = (unsigned short) value; |
| 288 | oincr = 2; |
| 289 | break; |
| 290 | case 'b': |
| 291 | value = (unsigned char) value; |
| 292 | oincr = 1; |
| 293 | break; |
| 294 | case 'l': |
| 295 | value = (unsigned long) value; |
| 296 | oincr = 4; |
| 297 | break; |
| 298 | } |
| 299 | break; |
| 300 | |
| 301 | default: |
| 302 | switch (dlen) { |
| 303 | case 'h': |
| 304 | value = (short) value; |
| 305 | oincr = 2; |
| 306 | break; |
| 307 | case 'b': |
| 308 | value = (char) value; |
| 309 | oincr = 1; |
| 310 | break; |
| 311 | case 'l': |
| 312 | value = (long) value; |
| 313 | oincr = 4; |
| 314 | break; |
| 315 | } |
| 316 | } |
| 317 | if (value > 0) { |
| 318 | if (value > 9 && dfmt == 'x') |
| 319 | printf("0x"); |
| 320 | else if (value > 7 && dfmt == 'o') |
| 321 | printf("0"); |
| 322 | } |
| 323 | printf(pd, value); |
| 324 | return; |
| 325 | |
| 326 | case 'f': |
| 327 | pd[1] = 'g'; |
| 328 | word.w = value; |
| 329 | printf(pd, word.f); |
| 330 | return; |
| 331 | |
| 332 | case 'g': |
| 333 | dbl.w1 = value; |
| 334 | dbl.w2 = (class == (char) N_RSYM) ? |
| 335 | *(ADDR *)(((ADDR) &u)+R0+(WORDSIZE)*(addr+1)) : |
| 336 | getval(addr+WORDSIZE, 'd'); |
| 337 | printf("%.13g", dbl.d); |
| 338 | return; |
| 339 | |
| 340 | case 'p': |
| 341 | printf("%s:%d", adrtoprocp(value)->pname, |
| 342 | adrtolineno(value)); |
| 343 | return; |
| 344 | |
| 345 | case 's': |
| 346 | addr = getindir(class, addr, type); |
| 347 | goto aa; |
| 348 | |
| 349 | case 'c': |
| 350 | if (size <= 1) { |
| 351 | oincr = 1; |
| 352 | printchar(value); |
| 353 | return; |
| 354 | } else |
| 355 | goto aa; |
| 356 | |
| 357 | case 'a': |
| 358 | aa: sflag = size == 0; |
| 359 | if (sflag) |
| 360 | size = 128; /* maximum length for s and a */ |
| 361 | else |
| 362 | oincr = size; |
| 363 | for (;;) { |
| 364 | word.w = getval(addr, 'd'); |
| 365 | for (i=0; i<WORDSIZE; i++) { |
| 366 | if (sflag && word.c[i] == 0) |
| 367 | return; |
| 368 | if (size-- == 0) |
| 369 | return; |
| 370 | printchar(word.c[i]); |
| 371 | } |
| 372 | addr += WORDSIZE; |
| 373 | } |
| 374 | |
| 375 | } |
| 376 | } |
| 377 | |
| 378 | printchar(c) { |
| 379 | if ((c & 0177) < ' ') |
| 380 | printf("^%c", c + ('A' - 1)); |
| 381 | else if ((c & 0177) == 0177) |
| 382 | printf("^?"); |
| 383 | else |
| 384 | printf("%c", c); |
| 385 | } |
| 386 | |