| 1 | static char sccsid[] = "@(#)xeq.c 4.3 %G%"; |
| 2 | #include "head.h" |
| 3 | #include <a.out.h> |
| 4 | #include <stab.h> |
| 5 | struct user u; |
| 6 | #include <stdio.h> |
| 7 | INT signo; |
| 8 | INT adrflg; |
| 9 | INT pid; |
| 10 | ADDR userpc; |
| 11 | L_INT cntval; |
| 12 | |
| 13 | |
| 14 | /* service routines for sub process control */ |
| 15 | |
| 16 | |
| 17 | /* |
| 18 | * single step until loc with descriptor format d is modified |
| 19 | * return its new value. |
| 20 | */ |
| 21 | monex(loc, d) |
| 22 | ADDR loc; char d; { |
| 23 | register ADDR oldval; |
| 24 | |
| 25 | oldval = getval(loc, d, DSP); |
| 26 | do { |
| 27 | subpcs('s'); |
| 28 | } while (oldval == getval(loc, d, DSP)); |
| 29 | return(getval(loc, d, DSP)); |
| 30 | } |
| 31 | |
| 32 | /* single step count source stmts */ |
| 33 | singstep(count, cmd) |
| 34 | char cmd; { |
| 35 | register int thisline, curline; |
| 36 | register struct proct *thisproc; |
| 37 | |
| 38 | if (sdbttym.sg_flags != userttym.sg_flags) |
| 39 | stty(2, &userttym); |
| 40 | dot = *(ADDR *) (((ADDR) &u) + PC); |
| 41 | thisproc = adrtoprocp(dot); |
| 42 | thisline = adrtolineno(dot); |
| 43 | if (count == 0) count = 1; |
| 44 | for(; count; count--) { |
| 45 | do { |
| 46 | if (cmd == 'S') { /* MACHINE DEPENDENT */ |
| 47 | dot = *(ADDR *) (((ADDR) &u) + PC); |
| 48 | if ((get(dot,ISP) & 0xff) == 0xfb){ /* calls */ |
| 49 | int retaddr; |
| 50 | subpcs('s'); |
| 51 | retaddr = |
| 52 | *(ADDR *) (((ADDR) &u) + USP) + 16; |
| 53 | retaddr = dot = get(retaddr, DSP); |
| 54 | subpcs('b'); |
| 55 | subpcs('c'); |
| 56 | dot = retaddr; |
| 57 | subpcs('d'); |
| 58 | dot = *(ADDR *) (((ADDR) &u) + PC); |
| 59 | if (retaddr != dot && signo == 0) { |
| 60 | gtty(2, &userttym); |
| 61 | if (sdbttym.sg_flags != |
| 62 | userttym.sg_flags) |
| 63 | stty(2, &sdbttym); |
| 64 | printf("Breakpoint at \n"); |
| 65 | return; |
| 66 | } |
| 67 | continue; |
| 68 | } |
| 69 | } |
| 70 | |
| 71 | subpcs('s'); |
| 72 | dot = *(ADDR *) (((ADDR) &u) + PC); |
| 73 | curline = adrtolineno(dot); |
| 74 | } while (!signo && |
| 75 | ((thisproc == adrtoprocp(dot) && thisline == curline) || |
| 76 | curline == -1)); |
| 77 | gtty(2, &userttym); |
| 78 | if (sdbttym.sg_flags != userttym.sg_flags) |
| 79 | stty(2, &sdbttym); |
| 80 | if (signo) return; |
| 81 | } |
| 82 | } |
| 83 | |
| 84 | doscall() { |
| 85 | int subargs[NUMARGS]; |
| 86 | /* subargs[0] = address, |
| 87 | * subargs[1] = number of arguments |
| 88 | * subargs[2:NUMARGS] = actual arguments |
| 89 | */ |
| 90 | union { |
| 91 | int w[128-NUMARGS]; |
| 92 | char c[4*(128-NUMARGS)]; |
| 93 | }substr; |
| 94 | |
| 95 | register int i, numchars, *subargp; |
| 96 | register char ch; |
| 97 | ADDR straddr, adr, praddr; |
| 98 | ADDR j; |
| 99 | |
| 100 | praddr = extaddr(proc); |
| 101 | if (praddr == -1) { |
| 102 | printf("Cannot find %s\n", proc); |
| 103 | return; |
| 104 | } |
| 105 | straddr = extaddr("_dbargs"); |
| 106 | if (straddr == -1) { |
| 107 | error("Program not loaded with -lg"); |
| 108 | return; |
| 109 | } |
| 110 | |
| 111 | numchars = 0; |
| 112 | subargp = subargs; |
| 113 | argsp++; |
| 114 | *subargp++ = praddr; |
| 115 | subargp++; |
| 116 | |
| 117 | for (i=0; i<NUMARGS - 2; i++) { /* process an argument */ |
| 118 | ch = *argsp; |
| 119 | if (ch == '\'') { |
| 120 | *subargp++ = *(argsp+1); |
| 121 | argsp += 2; |
| 122 | } else if (ch == '"') { |
| 123 | *subargp++ = straddr + sizeof subargs + numchars; |
| 124 | argsp++; |
| 125 | for (;;) { |
| 126 | ch = *argsp++; |
| 127 | if (ch == '\\') { |
| 128 | switch(ch = *argsp++) { |
| 129 | case 'r': |
| 130 | ch = '\015'; |
| 131 | break; |
| 132 | case 'n': |
| 133 | ch = '\012'; |
| 134 | break; |
| 135 | case '\\': |
| 136 | ch = '\\'; |
| 137 | break; |
| 138 | } |
| 139 | } |
| 140 | substr.c[numchars++] = ch; |
| 141 | if (ch == '"') { |
| 142 | substr.c[numchars-1] = '\0'; |
| 143 | break; |
| 144 | } |
| 145 | if (ch == '\0') { |
| 146 | error("Unterminated string constant"); |
| 147 | return; |
| 148 | } |
| 149 | if (numchars > sizeof substr.c) { |
| 150 | error("Too many string constants"); |
| 151 | return; |
| 152 | } |
| 153 | } |
| 154 | } else if ((ch >= '0' && ch <= '9') || ch == '-') { |
| 155 | *subargp++ = readint(&argsp); |
| 156 | } else if ((ch >= 'a' && ch <= 'z') || |
| 157 | (ch >= 'A' && ch <= 'Z') || ch == '_') { |
| 158 | cpname(var, argsp); |
| 159 | j = varaddr(curproc()->pname, var); |
| 160 | if (j == -1) { |
| 161 | return; |
| 162 | } |
| 163 | *subargp++ = |
| 164 | sl_class == N_RSYM ? |
| 165 | *(ADDR *)(((ADDR) &u) + R0 + (WORDSIZE)*j) : |
| 166 | getval(j, typetodesc(sl_type, 0)[0], DSP); |
| 167 | do { |
| 168 | argsp++; |
| 169 | } while (varchar(*argsp) || number(*argsp)); |
| 170 | } else if (ch != ')') { |
| 171 | printf("Unexpected character %c\n", ch); |
| 172 | return; |
| 173 | } |
| 174 | |
| 175 | do { |
| 176 | ch = *argsp++; |
| 177 | } while(ch == ' '); |
| 178 | if (ch == ')') { |
| 179 | if (scallx == 0) { |
| 180 | scallx = 1; |
| 181 | pcs = *(ADDR *)(((ADDR)&u)+PC); |
| 182 | fps = *(ADDR *)(((ADDR)&u)+FP); |
| 183 | aps = *(ADDR *)(((ADDR)&u)+AP); |
| 184 | if (bkpts = scanbkpt(userpc)) { |
| 185 | if (flagss = bkpts->flag) { |
| 186 | bkpts->flag = BKPTSET; |
| 187 | } |
| 188 | } |
| 189 | } |
| 190 | dot = *(ADDR *)(((ADDR)&u)+PC) = extaddr("_dbsubc"); |
| 191 | if (dot == -1) { |
| 192 | error("Internal error - cannot find _dbsubc"); |
| 193 | return; |
| 194 | } |
| 195 | adrflg = 1; |
| 196 | cntval = 1; |
| 197 | if (pid == 0 || signo) subpcs('r'); |
| 198 | subargs[1] = (subargp - subargs) - 2; |
| 199 | adr = straddr; |
| 200 | for (j=0; j<=(subargp-subargs); j++) { |
| 201 | put(adr, DSP, subargs[j]); |
| 202 | adr += WORDSIZE; |
| 203 | } |
| 204 | adr = straddr + sizeof subargs; |
| 205 | for (j=0; j<(numchars+WORDSIZE-1)/WORDSIZE; j++) { |
| 206 | put(adr, DSP, substr.w[j]); |
| 207 | adr += WORDSIZE; |
| 208 | } |
| 209 | dschar = *argsp++; |
| 210 | errflg = 0; |
| 211 | dopcs('c'); |
| 212 | if (!signo) printf("Breakpoint"); |
| 213 | printf(" at\n"); |
| 214 | return; |
| 215 | } |
| 216 | while (*argsp == ' ' || *argsp == ',') |
| 217 | argsp++; |
| 218 | } |
| 219 | |
| 220 | error ("Too many arguments"); |
| 221 | |
| 222 | } |
| 223 | |
| 224 | |
| 225 | /* get arguments from core file, place them in args */ |
| 226 | getargs() { |
| 227 | struct proct *procp; |
| 228 | ADDR p, av; |
| 229 | int ac, i; |
| 230 | char *argsp = args; |
| 231 | union { |
| 232 | char c[WORDSIZE]; |
| 233 | int w; |
| 234 | float f; |
| 235 | } word; |
| 236 | |
| 237 | if ((procp = initframe()) == badproc) goto old1; |
| 238 | do { |
| 239 | if (eqstr("main", procp->pname)) |
| 240 | goto fnd; |
| 241 | } while ((procp = nextframe()) != badproc); |
| 242 | |
| 243 | old1: cpstr(args, oldargs); |
| 244 | printf("%s %s\n", symfil, args); |
| 245 | return; |
| 246 | |
| 247 | fnd: ac = get(argp, DSP); |
| 248 | if ((ac == 0) || (ac & 0xff)) goto old1; |
| 249 | ac = get(argp+4, DSP); |
| 250 | av = (ADDR) get(argp+8, DSP); |
| 251 | |
| 252 | av += WORDSIZE; |
| 253 | ac--; |
| 254 | |
| 255 | for (; ac; ac--) { |
| 256 | p = (ADDR) get(av, DSP); |
| 257 | av += WORDSIZE; |
| 258 | for (;;) { |
| 259 | word.w = get(p, DSP); |
| 260 | for (i=0; i<WORDSIZE; i++) { |
| 261 | if (word.c[i] == '\0') goto l1; |
| 262 | *argsp++ = word.c[i]; |
| 263 | } |
| 264 | p += WORDSIZE; |
| 265 | } |
| 266 | l1: *argsp++ = ' '; |
| 267 | } |
| 268 | *argsp == '\0'; |
| 269 | printf("%s %s\n", symfil, args); |
| 270 | return; |
| 271 | |
| 272 | |
| 273 | } |
| 274 | |
| 275 | dopcs(c) |
| 276 | char c; { |
| 277 | if (c != 'r' && c != 'R' && sdbttym.sg_flags != userttym.sg_flags) |
| 278 | stty(2, &userttym); |
| 279 | subpcs(c); |
| 280 | gtty(2, &userttym); |
| 281 | if (sdbttym.sg_flags != userttym.sg_flags) |
| 282 | stty(2, &sdbttym); |
| 283 | |
| 284 | if (eqany(c, "cCsS") && |
| 285 | *(ADDR *)(((ADDR)&u)+PC) == extaddr("_dbsubn")) { |
| 286 | if (dschar == '/') { |
| 287 | dispf((ADDR) 0, *argsp ? argsp : "d", N_RSYM, 0, 0, DSP); |
| 288 | } |
| 289 | else |
| 290 | printf("Procedure returned normally\n"); |
| 291 | userpc = dot = *(ADDR *)(((ADDR)&u)+PC) = pcs; |
| 292 | *(ADDR *)(((ADDR)&u)+FP) = fps; |
| 293 | *(ADDR *)(((ADDR)&u)+AP) = aps; |
| 294 | if (bkpts) |
| 295 | bkpts->flag = flagss; |
| 296 | scallx = 0; |
| 297 | longjmp(env, 0); |
| 298 | } |
| 299 | } |
| 300 | |
| 301 | /* execute commands from a breakpoint */ |
| 302 | acommand(cmds) |
| 303 | char *cmds; { |
| 304 | char *p = cmds; |
| 305 | int endflg = 0; |
| 306 | |
| 307 | setcur(0); |
| 308 | do { /* process a command */ |
| 309 | for (;;) { |
| 310 | if (*p == ';') { |
| 311 | *p = '\n'; |
| 312 | break; |
| 313 | } |
| 314 | if (*p == '\n') { |
| 315 | endflg++; |
| 316 | break; |
| 317 | } |
| 318 | p++; |
| 319 | } |
| 320 | if (decode(cmds) == 1) { |
| 321 | printf("Bad command: "); |
| 322 | do { |
| 323 | printf("%c", *cmds); |
| 324 | } while (*cmds++ != '\n'); |
| 325 | return; |
| 326 | } |
| 327 | docommand(); |
| 328 | if (!endflg) |
| 329 | *p = ';'; |
| 330 | p = cmds = p + 1; |
| 331 | } while (!endflg); |
| 332 | } |