1 /*
2 * @(#)kdb_opset.c 7.4 (Berkeley) 5/1/89
3 */
4
5 #include "kdb/defs.h"
6
7 #include "../include/frame.h"
8
9 ADDR kdbcallpc;
10 ADDR kdblastframe;
11
12 /*
13 * Instruction printing.
14 */
15 REGLIST kdbreglist [] = {
16 "p1lr", &kdbpcb.pcb_p1lr, "p1br", (int *)&kdbpcb.pcb_p1br,
17 "p0lr", &kdbpcb.pcb_p0lr, "p0br", (int *)&kdbpcb.pcb_p0br,
18 "ksp", &kdbpcb.pcb_ksp, "esp", &kdbpcb.pcb_esp,
19 "ssp", &kdbpcb.pcb_ssp, "psl", &kdbpcb.pcb_psl,
20 "pc", &kdbpcb.pcb_pc, "usp", &kdbpcb.pcb_usp,
21 "fp", &kdbpcb.pcb_fp, "ap", &kdbpcb.pcb_ap,
22 "r11", &kdbpcb.pcb_r11, "r10", &kdbpcb.pcb_r10,
23 "r9", &kdbpcb.pcb_r9, "r8", &kdbpcb.pcb_r8,
24 "r7", &kdbpcb.pcb_r7, "r6", &kdbpcb.pcb_r6,
25 "r5", &kdbpcb.pcb_r5, "r4", &kdbpcb.pcb_r4,
26 "r3", &kdbpcb.pcb_r3, "r2", &kdbpcb.pcb_r2,
27 "r1", &kdbpcb.pcb_r1, "r0", &kdbpcb.pcb_r0,
28 0
29 };
30
31 /*
32 * Argument data types
33 *
34 * If you change these definitions, you must also change the tables
35 * in assizetab.c
36 */
37 #define TYPB 000 /* byte integer */
38 #define TYPW 001 /* word integer */
39 #define TYPL 002 /* long integer */
40 #define TYPQ 003 /* quad integer */
41 #define TYPO 004 /* octa integer */
42 #define TYPF 005 /* F float */
43 #define TYPD 006 /* D float */
44 #define TYPG 007 /* G float */
45 #define TYPH 010 /* H float */
46 #define TYPUNPACKED 011 /* when unpacked into mantissa & exponent */
47 #define TYPNONE 012 /* when nothing */
48 #define TYPLG 4 /* number of bits the above take up */
49
50 #define TYPMASK ((1<<TYPLG)-1) /* the mask (assumes 2's comp arith) */
51 /*
52 * Constructors and extractors for argument access kinds and types
53 */
54 #define A_CONS(access, type) ((access) | (type))
55 #define A_ACCEXT(consed) ((consed) & (TYPMASK << TYPLG))
56 #define A_TYPEXT(consed) ((consed) & TYPMASK)
57
58 /*
59 * Argument access types used to test validity of operands to operators
60 */
61 #define ACCR (1<<TYPLG) /* read */
62 #define ACCW (2<<TYPLG) /* write */
63 #define ACCB (4<<TYPLG) /* branch displacement */
64 #define ACCA (8<<TYPLG) /* address only */
65 #define ACCV (8<<TYPLG) /* address only */
66 #define ACCM (ACCR | ACCW) /* modify */
67 #define ACCI (ACCB | ACCR) /* XFC code */
68
69 #define ACCESSMASK (ACCA | ACCR | ACCW | ACCB) /* the mask */
70
71 /*
72 * Construction of TYPX and ACCX, to make the instrs table
73 * easy to use and read.
74 */
75 /*
76 * For real memory address
77 */
78 #define A_AB A_CONS(ACCA, TYPB)
79 #define A_AW A_CONS(ACCA, TYPW)
80 #define A_AL A_CONS(ACCA, TYPL)
81 #define A_AQ A_CONS(ACCA, TYPQ)
82 #define A_AO A_CONS(ACCA, TYPO)
83 #define A_AF A_CONS(ACCA, TYPF)
84 #define A_AD A_CONS(ACCA, TYPD)
85 #define A_AG A_CONS(ACCA, TYPG)
86 #define A_AH A_CONS(ACCA, TYPH)
87 /*
88 * For real memory addresses, or register addresses [sic]
89 *
90 * CHEAT! we just call these read access, since
91 * registers are allowed. All field instruction, except insv,
92 * are are read access fields.
93 */
94 #define A_VB A_CONS(ACCR, TYPB)
95 #define A_VW A_CONS(ACCR, TYPW)
96 #define A_VL A_CONS(ACCR, TYPL)
97 #define A_VQ A_CONS(ACCR, TYPQ)
98 #define A_VO A_CONS(ACCR, TYPO)
99 #define A_VF A_CONS(ACCR, TYPF)
100 #define A_VD A_CONS(ACCR, TYPD)
101 #define A_VG A_CONS(ACCR, TYPG)
102 #define A_VH A_CONS(ACCR, TYPH)
103 /*
104 * For branch displacement
105 */
106 #define A_BB A_CONS(ACCB, TYPB)
107 #define A_BW A_CONS(ACCB, TYPW)
108 /*
109 * For modification
110 */
111 #define A_MB A_CONS(ACCM, TYPB)
112 #define A_MW A_CONS(ACCM, TYPW)
113 #define A_ML A_CONS(ACCM, TYPL)
114 #define A_MF A_CONS(ACCM, TYPF)
115 #define A_MD A_CONS(ACCM, TYPD)
116 #define A_MG A_CONS(ACCM, TYPG)
117 #define A_MH A_CONS(ACCM, TYPH)
118 /*
119 * For reading
120 */
121 #define A_RB A_CONS(ACCR, TYPB)
122 #define A_RW A_CONS(ACCR, TYPW)
123 #define A_RL A_CONS(ACCR, TYPL)
124 #define A_RQ A_CONS(ACCR, TYPQ)
125 #define A_RO A_CONS(ACCR, TYPO)
126 #define A_RF A_CONS(ACCR, TYPF)
127 #define A_RD A_CONS(ACCR, TYPD)
128 #define A_RG A_CONS(ACCR, TYPG)
129 #define A_RH A_CONS(ACCR, TYPH)
130 /*
131 * For writing
132 */
133 #define A_WB A_CONS(ACCW, TYPB)
134 #define A_WW A_CONS(ACCW, TYPW)
135 #define A_WL A_CONS(ACCW, TYPL)
136 #define A_WQ A_CONS(ACCW, TYPQ)
137 #define A_WO A_CONS(ACCW, TYPO)
138 #define A_WF A_CONS(ACCW, TYPF)
139 #define A_WD A_CONS(ACCW, TYPD)
140 #define A_WG A_CONS(ACCW, TYPG)
141 #define A_WH A_CONS(ACCW, TYPH)
142
143 struct insttab {
144 char *iname;
145 u_char eopcode;
146 u_char popcode;
147 char nargs;
148 u_char argtype[6];
149 };
150
151 #define OP(name,eopcode,popdcode,nargs,a1,a2,a3,a4,a5,a6) \
152 {name,eopcode,popdcode,nargs,a1,a2,a3,a4,a5,a6}
153 /*
154 * Definitions for the escape bytes
155 */
156 #define CORE 0
157 #define NEW 1
158 #define ESCD 0xfd
159 #define ESCF 0xff
160 #define mapescbyte(b) ((b) == ESCD ? 1 : (b) == ESCF ? 2 : 0)
161
162 static struct insttab insttab[] = {
163 #include "../vax/kdb_instrs"
164 0};
165
166 /*
167 * Convert TYP[BWLQOFDGH] into {1 if relocation not OK}
168 */
169 int ty_NORELOC[] = {
170 0, /* TYPB */
171 0, /* TYPW */
172 0, /* TYPL */
173 1, /* TYPQ */
174 1, /* TYPO */
175 1, /* TYPF */
176 1, /* TYPD */
177 1, /* TYPG */
178 1, /* TYPH */
179 1 /* TYPNONE */
180 };
181
182 /*
183 * Convert TYP[BWLQOFDGH] into {1 ... 16}
184 */
185 int ty_nbyte[] = {
186 1, /* TYPB */
187 2, /* TYPW */
188 4, /* TYPL */
189 8, /* TYPQ */
190 16, /* TYPO */
191 4, /* TYPF */
192 8, /* TYPD */
193 8, /* TYPG */
194 16, /* TYPH */
195 0 /* TYPNONE */
196 };
197
198 static char *regname[] = {
199 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
200 "r8", "r9", "r10","r11","ap", "fp", "sp", "pc"
201 };
202 static char *fltimm[] = {
203 "0.5", "0.5625", "0.625", "0.6875", "0.75", "0.8125", "0.875", "0.9375",
204 "1.0", "1.125", "1.25", "1.375", "1.5", "1.625", "1.75", "1.875",
205 "2.0", "2.25", "2.5", "2.75", "3.0", "3.25", "3.5", "3.75",
206 "4.0", "4.5", "5.0", "5.5", "6.0", "6.5", "7.0", "7.5",
207 "8.0", "9.0", "10.0", "11.0", "12.0", "13.0", "14.0", "15.0",
208 "16.0", "18.0", "20.0", "22.0", "24.0", "26.0", "28.0", "30.0",
209 "32.0", "36.0", "40.0", "44.0", "48.0", "52.0", "56.0", "60.0",
210 "64.0", "72.0", "80.0", "88.0", "96.0", "104.0", "112.0", "120.0"
211 };
212
213 static int type, space, incp;
214 static long insoutvar[36];
215 /*
216 * Definitions for registers and for operand classes
217 */
218 static char *insregname(); /* how to print a register */
219
220 #define R_PC 0xF
221
222 #define OC_IMM0 0x0
223 #define OC_IMM1 0x1
224 #define OC_IMM2 0x2
225 #define OC_IMM3 0x3
226 #define OC_INDEX 0x4
227 #define OC_REG 0x5
228 #define OC_DREG 0x6
229 #define OC_ADREG 0x7
230 #define OC_AIREG 0x8
231 #define OC_DAIREG 0x9
232
233 #define OC_BDISP 0xA
234 #define OC_DBDISP 0xB
235 #define OC_WDISP 0xC
236 #define OC_DWDISP 0xD
237 #define OC_LDISP 0xE
238 #define OC_DLDISP 0xF
239
240 #define OC_SHIFT 4
241 #define OC_CONS(oc,reg) (((oc & 0xF) << OC_SHIFT) | (reg & 0xF))
242 #define OC_AMEXT(x) (((x) >> OC_SHIFT) & 0xF)
243 #define OC_REGEXT(x) ((x) & 0xF)
244
245 /*
246 * Definitions for large numbers
247 */
248 #include "../vax/asnumber.h"
249 typedef struct as_number *numberp;
250 static numberp snarf();
251 static numberp snarfreloc();
252 /*
253 * Definitions for special instructions
254 */
255 #define CASEB 0x8F
256 #define CASEW 0xAF
257 #define CASEL 0xCF
258
259 /* two level 1-based index by opcode into insttab */
260 static short ioptab[3][256];
261
kdbsetup()262 kdbsetup()
263 {
264 register struct insttab *p;
265 int mapchar;
266
267 for(p = insttab; p->iname; p++){
268 mapchar = mapescbyte(p->eopcode);
269 if (ioptab[mapchar][p->popcode])
270 continue;
271 ioptab[mapchar][p->popcode] = (p - insttab) + 1;
272 }
273 }
274
275 static u_char snarfuchar();
276 /*
277 * Global variables for communicating with the minions and printins
278 */
279 static int idsp;
280 static short argno; /* which argument one is working on */
281 static char insoutfmt[2]; /* how to format the relocated symbols */
282
savevar(val)283 static savevar(val)
284 long val;
285 {
286 kdbvar[argno] = val;
287 insoutvar[argno] = val;
288 }
289
290 /* ARGSUSED */
kdbprintins(Idsp,ins)291 kdbprintins(Idsp, ins)
292 u_char ins;
293 int Idsp;
294 {
295 u_char mode; /* mode */
296 u_char ins2;
297 char *indexreg; /* print of which register indexes */
298 char *indexed; /* we indexed */
299 char *operandout();
300 register u_char *ap;
301 register struct insttab *ip;
302 u_char optype;
303 int mapchar;
304
305 idsp = Idsp;
306 type = DSYM;
307 space = idsp;
308 insoutfmt[0] = 0;
309
310 incp = 1;
311 if ((mapchar = mapescbyte(ins)) != 0){
312 ins2 = snarfuchar();
313 if (ioptab[mapchar][ins2] == 0){
314 /*
315 * Oops; not a defined instruction;
316 * back over this escape byte.
317 */
318 incp -= 1;
319 mapchar = 0;
320 } else {
321 ins = ins2;
322 }
323 }
324 if (ioptab[mapchar][ins] == 0){
325 kdbprintf("<undefined operator byte>: %x", ins);
326 goto ret;
327 }
328 ip = &insttab[ioptab[mapchar][ins] - 1];
329 kdbprintf("%s\t", ip->iname);
330
331 for (ap = ip->argtype, argno = 0; argno < ip->nargs; argno++, ap++) {
332 savevar(0x80000000); /* an illegal symbol */
333 optype = *ap;
334 if (argno != 0)
335 kdbprintc(',');
336 indexreg = 0;
337 indexed = 0;
338 do{
339 if (A_ACCEXT(optype) & ACCB){
340 switch(A_TYPEXT(optype)){
341 case TYPB:
342 mode = OC_CONS(OC_BDISP, R_PC);
343 break;
344 case TYPW:
345 mode = OC_CONS(OC_WDISP, R_PC);
346 break;
347 }
348 } else {
349 mode = snarfuchar();
350 }
351 indexreg = operandout(mode, optype);
352 if (indexed)
353 kdbprintf("[%s]", indexed);
354 indexed = indexreg;
355 } while(indexed);
356 }
357 if (mapchar == 0){
358 switch(ins){
359 case CASEB:
360 case CASEW:
361 case CASEL:
362 casebody(insoutvar[1], insoutvar[2]);
363 break;
364 default:
365 break;
366 }
367 }
368 ret: ;
369
370 kdbdotinc = incp;
371 }
372
casebody(base,limit)373 casebody(base, limit)
374 long base;
375 long limit;
376 {
377 int i;
378 u_int baseincp;
379 u_int advincp;
380 struct as_number *valuep;
381 #define OSIZE (sizeof(short))
382 argno = 0;
383 baseincp = incp;
384 for (i = 0; i <= limit; i++) {
385 kdbprintc(EOR);
386 kdbprintf(" %R: ", i + base);
387 valuep = snarfreloc(OSIZE, 0);
388 advincp = incp;
389 incp = baseincp;
390 dispaddress(valuep, OC_CONS(OC_WDISP, R_PC));
391 incp = advincp;
392 }
393 }
394
395 /*
396 * magic values to mung an offset to a register into
397 * something that psymoff can understand.. all magic
398 */
399 /* 0 1 2 3 4 */
400 static long magic_masks[5] = {0, 0x80, 0x8000, 0, 0};
401 static long magic_compl[5] = {0, 0x100, 0x10000,0, 0};
402 /*
403 * Snarf up some bytes, and put in the magic relocation flags
404 */
snarfreloc(nbytes)405 static numberp snarfreloc(nbytes)
406 int nbytes;
407 {
408 numberp back;
409 back = snarf(nbytes);
410 if (back->num_ulong[0] & magic_masks[nbytes])
411 back->num_ulong[0] -= magic_compl[nbytes];
412 return(back);
413 }
414 /*
415 * The following code is NOT portable from the PDP 11 to the VAX
416 * because of the byte ordering problem.
417 */
snarf(nbytes)418 static numberp snarf(nbytes)
419 int nbytes;
420 {
421 register int i;
422
423 static struct as_number backnumber;
424 static struct as_number znumber; /* init'ed to 0 */
425
426 backnumber = znumber;
427 for (i = 0; i < nbytes; i++)
428 backnumber.num_uchar[i] = snarfuchar();
429 return(&backnumber);
430 }
431
432 /*
433 * Read one single character, and advance the dot
434 */
435 static u_char
snarfuchar()436 snarfuchar()
437 {
438 u_char back;
439 /*
440 * assert: bchkget and inkdot don't have side effects
441 */
442 back = (u_char)kdbbchkget(kdbinkdot(incp), idsp);
443 incp += 1;
444 return(back);
445 }
446
447 /*
448 * normal operand; return non zero pointer to register
449 * name if this is an index instruction.
450 */
operandout(mode,optype)451 char *operandout(mode, optype)
452 u_char mode;
453 u_char optype;
454 {
455 char *r;
456 int regnumber;
457 int nbytes;
458
459 regnumber = OC_REGEXT(mode);
460 r = insregname(regnumber);
461 switch (OC_AMEXT(mode)){
462 case OC_IMM0:
463 case OC_IMM1:
464 case OC_IMM2:
465 case OC_IMM3:
466 shortliteral(mode, optype);
467 return(0);
468 case OC_INDEX:
469 return(r); /* will be printed later */
470 case OC_REG:
471 kdbprintf("%s", r);
472 return(0);
473 case OC_DREG:
474 kdbprintf("(%s)", r);
475 return(0);
476 case OC_ADREG:
477 kdbprintf("-(%s)", r);
478 return(0);
479 case OC_DAIREG:
480 kdbprintc('*');
481 case OC_AIREG:
482 if (regnumber == R_PC){
483 pcimmediate(mode, optype);
484 } else {
485 kdbprintf("(%s)+", r);
486 }
487 return(0);
488 case OC_DBDISP:
489 kdbprintc('*');
490 case OC_BDISP:
491 nbytes = 1;
492 break;
493 case OC_DWDISP:
494 kdbprintc('*');
495 case OC_WDISP:
496 nbytes = 2;
497 break;
498 case OC_DLDISP:
499 kdbprintc('*');
500 case OC_LDISP:
501 nbytes = 4;
502 break;
503 }
504 dispaddress(snarfreloc(nbytes), mode);
505 return(0);
506 }
507
dispaddress(valuep,mode)508 dispaddress(valuep, mode)
509 numberp valuep;
510 u_char mode;
511 {
512 int regnumber = OC_REGEXT(mode);
513
514 switch(OC_AMEXT(mode)){
515 case OC_BDISP:
516 case OC_DBDISP:
517 case OC_WDISP:
518 case OC_DWDISP:
519 case OC_LDISP:
520 case OC_DLDISP:
521 if (regnumber == R_PC){
522 /* PC offset addressing */
523 valuep->num_ulong[0] += kdbinkdot(incp);
524 }
525 }
526 if (regnumber == R_PC)
527 kdbpsymoff(valuep->num_ulong[0], type, &insoutfmt[0]);
528 else { /* } */
529 kdbprintf(LPRMODE, valuep->num_ulong[0]);
530 kdbprintf(insoutfmt);
531 kdbprintf("(%s)", insregname(regnumber));
532 }
533 savevar((long)valuep->num_ulong[0]);
534 }
535
536 /*
537 * get a register name
538 */
539 static char *
insregname(regnumber)540 insregname(regnumber)
541 int regnumber;
542 {
543 char *r;
544 r = regname[regnumber];
545 return(r);
546 }
547
548 /*
549 * print out a short literal
550 */
shortliteral(mode,optype)551 shortliteral(mode, optype)
552 u_char mode;
553 u_char optype;
554 {
555 savevar((long)mode);
556 switch(A_TYPEXT(optype)){
557 case TYPF:
558 case TYPD:
559 case TYPG:
560 case TYPH:
561 kdbprintf("$%s", fltimm[mode]);
562 break;
563 default:
564 kdbprintf("$%r", mode);
565 break;
566 }
567 }
568
pcimmediate(mode,optype)569 pcimmediate(mode, optype)
570 u_char mode;
571 u_char optype;
572 {
573 int nbytes;
574
575 kdbprintc('$');
576 if (mode == OC_CONS(OC_DAIREG, R_PC)){ /* PC absolute, always 4 bytes*/
577 dispaddress(snarfreloc(4), mode);
578 return;
579 }
580 nbytes = ty_nbyte[A_TYPEXT(optype)];
581 if (! ty_NORELOC[A_TYPEXT(optype)]){
582 dispaddress(snarfreloc(nbytes), mode);
583 return;
584 }
585 bignumprint(nbytes, optype);
586 }
587
bignumprint(nbytes,optype)588 bignumprint(nbytes, optype)
589 int nbytes;
590 u_char optype;
591 {
592 numberp valuep;
593 int leading_zero = 1;
594 register int bindex;
595 register int nindex;
596 register int ch;
597
598 valuep = snarf(nbytes);
599 switch(A_TYPEXT(optype)){
600 case TYPF:
601 kdbprintf("0f%f", valuep->num_num.numFf_float.Ff_value);
602 break;
603 case TYPD:
604 kdbprintf("0d%f", valuep->num_num.numFd_float.Fd_value);
605 break;
606 case TYPG:
607 kdbprintf("0g::"); goto qprint;
608 case TYPH:
609 kdbprintf("0h::"); goto qprint;
610 case TYPQ:
611 case TYPO:
612 qprint:
613 for (bindex = nbytes - 1; bindex >= 0; --bindex){
614 for (nindex = 4; nindex >= 0; nindex -= 4){
615 ch = (valuep->num_uchar[bindex] >> nindex);
616 ch &= 0x0F;
617 if ( ! (leading_zero &= (ch == 0) ) ){
618 if (ch <= 0x09)
619 kdbprintc(ch + '0');
620 else
621 kdbprintc(ch - 0x0A + 'a');
622 }
623 }
624 }
625 break;
626 }
627 }
628
kdbstacktrace(dolocals)629 kdbstacktrace(dolocals)
630 int dolocals;
631 {
632 register ADDR ap, fp;
633 register int i, narg, tramp;
634 struct frame fr;
635
636 if (kdbadrflg) {
637 /*
638 * Can only find args if called via `calls' (not callg).
639 * The horrible expression below reads the second
640 * longword of the given frame address; this contains
641 * fr_s and fr_spa, plus the register save mask. The
642 * memory layout is
643 * fp+0x00: call frame structure
644 * fp+0x14: saved registers
645 * fp+0xMM: stack alignment bytes
646 * fp+0xNN: arguments
647 */
648 fp = kdbadrval;
649 ((int *)&fr)[1] = kdbget((off_t)fp + 4, DSP);
650 if (fr.fr_s) {
651 ap = fp + sizeof(fr) + fr.fr_spa;
652 for (i = fr.fr_mask; i != 0; i >>= 1)
653 if (i & 1)
654 ap += 4;
655 } else
656 ap = 0;
657 kdbcallpc = getprevpc(fp);
658 } else {
659 fp = kdbpcb.pcb_fp;
660 ap = kdbpcb.pcb_ap;
661 kdbcallpc = kdbpcb.pcb_pc;
662 }
663
664 kdblastframe = NOFRAME;
665 while (kdbcntval-- && fp != NOFRAME) {
666 char *name;
667
668 kdbchkerr();
669 /* check for pc in pcb (signal trampoline code) */
670 if (issignalpc(kdbcallpc)) {
671 tramp = 1;
672 name = "sigtramp";
673 } else {
674 tramp = 0;
675 (void) kdbfindsym((long)kdbcallpc, ISYM);
676 if (kdbcursym)
677 name = kdbcursym->n_un.n_name;
678 else
679 name = "?";
680 }
681 kdbprintf("%s(", name);
682 if (ap) {
683 /* byte at ap tells how many arguments */
684 narg = kdbget((off_t)ap, DSP) & 0xff;
685 for (i = narg > 10 ? 10 : narg; i;) {
686 ap += 4;
687 kdbprintf("%R", kdbget((off_t)ap, DSP));
688 if (--i != 0)
689 kdbprintc(',');
690 }
691 } else
692 kdbprintc('?');
693 kdbprintf(") at ");
694 kdbpsymoff((long)kdbcallpc, ISYM, "\n");
695
696 if (dolocals) {
697 register ADDR word;
698
699 while (kdblocalsym((long)fp)) {
700 word = kdbget((off_t)kdblocalval, DSP);
701 kdbprintf("%8t%s:%10t",
702 kdbcursym->n_un.n_name);
703 if (kdberrflg) {
704 kdbprintf("?\n");
705 kdberrflg = 0;
706 } else
707 kdbprintf("%R\n", word);
708 }
709 }
710 if (!tramp) {
711 kdbcallpc = getprevpc(fp);
712 kdblastframe = fp;
713 /* 8 below == offsetof(struct frame, fr_savap) */
714 ap = kdbget((off_t)fp + 8, DSP);
715 fp = getprevframe(fp);
716 } else {
717 kdbcallpc = getsignalpc(kdblastframe);
718 /* ??? WHAT ABOUT ap AND fp ??? */
719 }
720 if (!kdbadrflg && !INSTACK(fp))
721 break;
722 }
723 }
724