xref: /original-bsd/sys/tahoe/tahoe/kdb_opset.c (revision e59fb703)
1 /*
2  * Copyright (c) 1988 Regents of the University of California.
3  * All rights reserved.  The Berkeley software License Agreement
4  * specifies the terms and conditions for redistribution.
5  *
6  *	@(#)kdb_opset.c	7.7 (Berkeley) 12/16/90
7  */
8 
9 #include "kdb/defs.h"
10 
11 /*
12  * Instruction printing.
13  */
14 
15 REGLIST kdbreglist[] = {
16 	"p2lr",	&kdbpcb.pcb_p2lr,	"p2br",	(int *)&kdbpcb.pcb_p2br,
17 	"p1lr",	&kdbpcb.pcb_p1lr,	"p1br",	(int *)&kdbpcb.pcb_p1br,
18 	"p0lr",	&kdbpcb.pcb_p0lr,	"p0br",	(int *)&kdbpcb.pcb_p0br,
19 	"ksp",	&kdbpcb.pcb_ksp,	"hfs",	&kdbpcb.pcb_hfs,
20 	"psl",	&kdbpcb.pcb_psl,	"pc",	&kdbpcb.pcb_pc,
21 	"ach",	&kdbpcb.pcb_ach,	"acl",	&kdbpcb.pcb_acl,
22 	"usp",	&kdbpcb.pcb_usp,	"fp",	&kdbpcb.pcb_fp,
23 	"r12",	&kdbpcb.pcb_r12,	"r11",	&kdbpcb.pcb_r11,
24 	"r10",	&kdbpcb.pcb_r10,	"r9",	&kdbpcb.pcb_r9,
25 	"r8",	&kdbpcb.pcb_r8,	"r7",	&kdbpcb.pcb_r7,
26 	"r6",	&kdbpcb.pcb_r6,	"r5",	&kdbpcb.pcb_r5,
27 	"r4",	&kdbpcb.pcb_r4,	"r3",	&kdbpcb.pcb_r3,
28 	"r2",	&kdbpcb.pcb_r2,	"r1",	&kdbpcb.pcb_r1,
29 	"r0",	&kdbpcb.pcb_r0,
30 	0
31 };
32 
33 /*
34  * Argument access types
35  */
36 #define ACCA	(8<<3)	/* address only */
37 #define ACCR	(1<<3)	/* read */
38 #define ACCW	(2<<3)	/* write */
39 #define ACCM	(3<<3)	/* modify */
40 #define ACCB	(4<<3)	/* branch displacement */
41 #define ACCI	(5<<3)	/* XFC code */
42 
43 /*
44  * Argument data types
45  */
46 #define TYPB	0	/* byte */
47 #define TYPW	1	/* word */
48 #define TYPL	2	/* long */
49 #define TYPQ	3	/* quad */
50 #define TYPF	4	/* float */
51 #define TYPD	5	/* double */
52 
53 struct optab {
54 	char *iname;
55 	char val;
56 	char nargs;
57 	char argtype[6];
58 };
59 
60 static	struct optab *ioptab[256];	/* index by opcode to optab */
61 static	struct optab optab[] = {	/* opcode table */
62 #define OP(a,b,c,d,e,f,g,h,i) {a,b,c,d,e,f,g,h,i}
63 #include "kdb_instrs"
64 0};
65 static	char *regname[] = {
66 	"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
67 	"r8", "r9", "r10", "r11", "r12", "fp", "sp", "pc"
68 };
69 static	int type, space, incp;
70 
71 /* set up ioptab */
72 kdbsetup()
73 {
74 	register struct optab *p;
75 
76 	for (p = optab; p->iname; p++)
77 		ioptab[p->val&LOBYTE] = p;
78 }
79 
80 static long
81 snarf(nbytes, idsp)
82 {
83 	register long value;
84 
85 	value = (u_int)kdbchkget((off_t)kdbinkdot(incp), idsp);
86 	incp += nbytes;
87 	return(value>>(4-nbytes)*8);
88 }
89 
90 kdbprintins(idsp, ins)
91 	register long ins;
92 {
93 	short argno;		/* argument index */
94 	register mode;		/* mode */
95 	register r;		/* register name */
96 	register long d;	/* assembled byte, word, long or float */
97 	register char *ap;
98 	register struct optab *ip;
99 
100 	type = DSYM;
101 	space = idsp;
102 	ins = byte(ins);
103 	if ((ip = ioptab[ins]) == (struct optab *)0) {
104 		kdbprintf("?%2x%8t", ins);
105 		kdbdotinc = 1;
106 		return;
107 	}
108 	kdbprintf("%s%8t",ip->iname);
109 	incp = 1;
110 	ap = ip->argtype;
111 	for (argno = 0; argno < ip->nargs; argno++, ap++) {
112 		kdbvar[argno] = 0x80000000;
113 		if (argno!=0) kdbprintc(',');
114 	  top:
115 		if (*ap&ACCB)
116 			mode = 0xAF + ((*ap&7)<<5);  /* branch displacement */
117 		else {
118 			mode = kdbbchkget(kdbinkdot(incp),idsp); ++incp;
119 		}
120 		r = mode&0xF;
121 		mode >>= 4;
122 		switch ((int)mode) {
123 			case 0: case 1:
124 			case 2: case 3:	/* short literal */
125 				kdbprintc('$');
126 				d = mode<<4|r;
127 				goto immed;
128 			case 4: /* [r] */
129 				kdbprintf("[%s]", regname[r]);
130 				goto top;
131 			case 5: /* r */
132 				kdbprintf("%s", regname[r]);
133 				break;
134 			case 6: /* (r) */
135 				kdbprintf("(%s)", regname[r]);
136 				break;
137 			case 7: /* -(r) */
138 				kdbprintf("-(%s)", regname[r]);
139 				break;
140 			case 9: /* *(r)+ */
141 				kdbprintc('*');
142 			case 8: /* (r)+ */
143 				if (r == 0xF ||
144 				    mode == 8 && (r == 8 || r == 9)) {
145 					kdbprintc('$');
146 					d = snarf((r&03)+1, idsp);
147 				} else {	/*it's not PC immediate or abs*/
148 					kdbprintf("(%s)+", regname[r]);
149 					break;
150 				}
151 			immed:
152 				if (ins == KCALL && d >= 0 && d < 200) {
153 					kdbprintf("%R", d);
154 					break;
155 				}
156 				goto disp;
157 			case 0xB:	/* byte displacement deferred */
158 			case 0xD:	/* word displacement deferred */
159 			case 0xF:	/* long displacement deferred */
160 				kdbprintc('*');
161 			case 0xA:	/* byte displacement */
162 			case 0xC:	/* word displacement */
163 			case 0xE:	/* long displacement */
164 				d = snarf(1<<((mode>>1&03)-1), idsp);
165 				if (r==0xF) { /* PC offset addressing */
166 					d += kdbdot+incp;
167 					kdbpsymoff(d,type,"");
168 					kdbvar[argno]=d;
169 					break;
170 				}
171 			disp:
172 				if (d >= 0 && d < kdbmaxoff)
173 					kdbprintf("%R", d);
174 				else
175 					kdbpsymoff(d,type,"");
176 				if (mode >= 0xA)
177 					kdbprintf("(%s)", regname[r]);
178 				kdbvar[argno] = d;
179 				break;
180 		}
181 	}
182 	if (ins == CASEL) {
183 		if (kdbinkdot(incp)&01)	/* align */
184 			incp++;
185 		for (argno = 0; argno <= kdbvar[2]; ++argno) {
186 			kdbprintc(EOR);
187 			kdbprintf("    %R:  ", argno+kdbvar[1]);
188 			d = shorten(kdbget(kdbinkdot(incp+argno+argno), idsp));
189 			if (d&0x8000)
190 				d -= 0x10000;
191 			kdbpsymoff(kdbinkdot(incp)+d, type, "");
192 		}
193 		incp += kdbvar[2]+kdbvar[2]+2;
194 	}
195 	kdbdotinc = incp;
196 }
197 ADDR	kdblastframe;
198 ADDR	kdbcallpc;
199 
200 
201 kdbstacktrace(dolocals)
202 	int dolocals;
203 {
204 	register int narg;
205 	register ADDR argp, frame;
206 	int tramp;
207 
208 	if (kdbadrflg) {
209 		frame = kdbadrval;
210 		kdbcallpc = getprevpc(frame);
211 	} else {
212 		frame = kdbpcb.pcb_fp;
213 		kdbcallpc = kdbpcb.pcb_pc;
214 	}
215 	kdblastframe = NOFRAME;
216 	while (kdbcntval-- && frame != NOFRAME) {
217 		char *name;
218 
219 		kdbchkerr();
220 		/* check for pc in pcb (signal trampoline code) */
221 		if (issignalpc(kdbcallpc)) {
222 			tramp = 1;
223 			name = "sigtramp";
224 		} else {
225 			tramp = 0;
226 			(void) kdbfindsym((long)kdbcallpc, ISYM);
227 			if (kdbcursym)
228 				name = kdbcursym->n_un.n_name;
229 			else
230 				name = "?";
231 		}
232 		kdbprintf("%s(", name);
233 		narg = getnargs(frame);
234 		if (narg > 10)
235 			narg = 10;
236 		argp = frame;
237 		if (!tramp)
238 			while (narg) {
239 				kdbprintf("%R",
240 				    kdbget((off_t)(argp = nextarg(argp)),
241 					DSP));
242 				if (--narg != 0)
243 					kdbprintc(',');
244 			}
245 		kdbprintf(") at ");
246 		kdbpsymoff((long)kdbcallpc, ISYM, "\n");
247 
248 		if (dolocals) {
249 			register ADDR word;
250 
251 			while (kdblocalsym((long)frame)) {
252 				word = kdbget((off_t)kdblocalval, DSP);
253 				kdbprintf("%8t%s:%10t",
254 				    kdbcursym->n_un.n_name);
255 				if (kdberrflg) {
256 					kdbprintf("?\n");
257 					kdberrflg = 0;
258 				} else
259 					kdbprintf("%R\n", word);
260 			}
261 		}
262 		if (!tramp) {
263 			kdbcallpc = getprevpc(frame);
264 			kdblastframe = frame;
265 			frame = getprevframe(frame);
266 		} else
267 			kdbcallpc = getsignalpc(kdblastframe);
268 		if (!kdbadrflg && !INSTACK(frame))
269 			break;
270 	}
271 }
272