xref: /openbsd/sys/arch/m88k/m88k/db_trace.c (revision 949c1c4e)
1 /*	$OpenBSD: db_trace.c,v 1.21 2024/11/07 16:02:29 miod Exp $	*/
2 /*
3  * Mach Operating System
4  * Copyright (c) 1993-1991 Carnegie Mellon University
5  * Copyright (c) 1991 OMRON Corporation
6  * All Rights Reserved.
7  *
8  * Permission to use, copy, modify and distribute this software and its
9  * documentation is hereby granted, provided that both the copyright
10  * notice and this permission notice appear in all copies of the
11  * software, derivative works or modified versions, and any portions
12  * thereof, and that both notices appear in supporting documentation.
13  *
14  * CARNEGIE MELLON AND OMRON ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS IS"
15  * CONDITION.  CARNEGIE MELLON AND OMRON DISCLAIM ANY LIABILITY OF ANY KIND
16  * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
17  *
18  * Carnegie Mellon requests users of this software to return to
19  *
20  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
21  *  School of Computer Science
22  *  Carnegie Mellon University
23  *  Pittsburgh PA 15213-3890
24  *
25  * any improvements or extensions that they make and grant Carnegie the
26  * rights to redistribute these changes.
27  */
28 
29 #include <sys/param.h>
30 #include <sys/systm.h>
31 
32 #include <machine/cpu.h>
33 #include <machine/db_machdep.h>
34 
35 #include <ddb/db_variables.h>	/* db_variable, DB_VAR_GET, etc.  */
36 #include <ddb/db_output.h>	/* db_printf                      */
37 #include <ddb/db_sym.h>		/* DB_STGY_PROC, etc.             */
38 #include <ddb/db_command.h>	/* db_recover                     */
39 #include <ddb/db_access.h>
40 #include <ddb/db_interface.h>
41 
42 #ifdef DEBUG
43 #define	DPRINTF(stmt) printf stmt
44 #else
45 #define	DPRINTF(stmt) do { } while (0)
46 #endif
47 
48 static inline u_int
br_dest(vaddr_t addr,u_int inst)49 br_dest(vaddr_t addr, u_int inst)
50 {
51 	inst = (inst & 0x03ffffff) << 2;
52 	/* check if sign extension is needed */
53 	if (inst & 0x08000000)
54 		inst |= 0xf0000000;
55 	return (addr + inst);
56 }
57 
58 int frame_is_sane(db_regs_t *regs, int);
59 const char *m88k_exception_name(u_int vector);
60 u_int db_trace_get_val(vaddr_t addr, u_int *ptr);
61 
62 /*
63  * Some macros to tell if the given text is the instruction.
64  */
65 #define JMPN_R1(I)		((I) == 0xf400c401)	/* jmp.n r1 */
66 #define JMP_R1(I)		((I) == 0xf400c001)	/* jmp r1 */
67 
68 /* gets the IMM16 value from an instruction */
69 #define IMM16VAL(I)		((I) & 0x0000ffff)
70 
71 /* subu r31, r31, IMM */
72 #define SUBU_R31_R31_IMM(I)	(((I) & 0xffff0000) == 0x67ff0000U)
73 
74 /* st r30, r31, IMM */
75 #define ST_R30_R31_IMM(I)	(((I) & 0xffff0000) == 0x27df0000U)
76 
77 extern label_t *db_recover;
78 
79 /*
80  * m88k trace/register state interface for ddb.
81  */
82 
83 #define N(s, x)  {s, (long *)&ddb_regs.x, FCN_NULL}
84 
85 struct db_variable db_regs[] = {
86 	N("r1", r[1]),     N("r2", r[2]),    N("r3", r[3]),    N("r4", r[4]),
87 	N("r5", r[5]),     N("r6", r[6]),    N("r7", r[7]),    N("r8", r[8]),
88 	N("r9", r[9]),     N("r10", r[10]),  N("r11", r[11]),  N("r12", r[12]),
89 	N("r13", r[13]),   N("r14", r[14]),  N("r15", r[15]),  N("r16", r[16]),
90 	N("r17", r[17]),   N("r18", r[18]),  N("r19", r[19]),  N("r20", r[20]),
91 	N("r21", r[21]),   N("r22", r[22]),  N("r23", r[23]),  N("r24", r[24]),
92 	N("r25", r[25]),   N("r26", r[26]),  N("r27", r[27]),  N("r28", r[28]),
93 	N("r29", r[29]),   N("r30", r[30]),  N("r31", r[31]),  N("epsr", epsr),
94 	N("sxip", sxip),   N("snip", snip),  N("sfip", sfip),  N("ssbr", ssbr),
95 	N("dmt0", dmt0),   N("dmd0", dmd0),  N("dma0", dma0),  N("dmt1", dmt1),
96 	N("dmd1", dmd1),   N("dma1", dma1),  N("dmt2", dmt2),  N("dmd2", dmd2),
97 	N("dma2", dma2),   N("fpecr", fpecr),N("fphs1", fphs1),N("fpls1", fpls1),
98 	N("fphs2", fphs2), N("fpls2", fpls2),N("fppt", fppt),  N("fprh", fprh),
99 	N("fprl", fprl),   N("fpit", fpit),  N("fpsr", fpsr),  N("fpcr", fpcr),
100 };
101 #undef N
102 
103 struct db_variable *db_eregs = db_regs + nitems(db_regs);
104 
105 #define TRASHES    0x001	/* clobbers instruction field D */
106 #define STORE      0x002	/* does a store to S1+IMM16 */
107 #define LOAD       0x004	/* does a load from S1+IMM16 */
108 #define DOUBLE     0x008	/* double-register */
109 #define FLOW_CTRL  0x010	/* flow-control instruction */
110 #define DELAYED    0x020	/* delayed flow control */
111 #define JSR	   0x040	/* flow-control is a jsr[.n] */
112 #define BSR	   0x080	/* flow-control is a bsr[.n] */
113 
114 /*
115  * Given a word of instruction text, return some flags about that
116  * instruction (flags defined above).
117  */
118 static u_int
m88k_instruction_info(u_int32_t instruction)119 m88k_instruction_info(u_int32_t instruction)
120 {
121 	static const struct {
122 		u_int32_t mask, value;
123 		u_int flags;
124 	} *ptr, control[] = {
125 		/* runs in the same order as 2nd Ed 88100 manual Table 3-14 */
126 		{ 0xf0000000U, 0x00000000U, /* xmem */     TRASHES | STORE | LOAD},
127 		{ 0xec000000U, 0x00000000U, /* ld.d */     TRASHES | LOAD | DOUBLE},
128 		{ 0xe0000000U, 0x00000000U, /* load */     TRASHES | LOAD},
129 		{ 0xfc000000U, 0x20000000U, /* st.d */     STORE | DOUBLE},
130 		{ 0xf0000000U, 0x20000000U, /* store */    STORE},
131 		{ 0xc0000000U, 0x40000000U, /* arith */    TRASHES},
132 		{ 0xfc004000U, 0x80004000U, /* ld cr */    TRASHES},
133 		{ 0xfc004000U, 0x80000000U, /* st cr */    0},
134 		{ 0xfc008060U, 0x84000000U, /* f */        TRASHES},
135 		{ 0xfc008060U, 0x84000020U, /* f.d */      TRASHES | DOUBLE},
136 		{ 0xfc000000U, 0xcc000000U, /* bsr.n */    FLOW_CTRL | DELAYED | BSR},
137 		{ 0xfc000000U, 0xc8000000U, /* bsr */      FLOW_CTRL | BSR},
138 		{ 0xe4000000U, 0xc4000000U, /* br/bb.n */  FLOW_CTRL | DELAYED},
139 		{ 0xe4000000U, 0xc0000000U, /* br/bb */    FLOW_CTRL},
140 		{ 0xfc000000U, 0xec000000U, /* bcnd.n */   FLOW_CTRL | DELAYED},
141 		{ 0xfc000000U, 0xe8000000U, /* bcnd */     FLOW_CTRL},
142 		{ 0xfc00c000U, 0xf0008000U, /* bits */     TRASHES},
143 		{ 0xfc00c000U, 0xf000c000U, /* trap */     0},
144 		{ 0xfc00f0e0U, 0xf4002000U, /* st */       0},
145 		{ 0xfc00cce0U, 0xf4000000U, /* ld.d */     TRASHES | DOUBLE},
146 		{ 0xfc00c0e0U, 0xf4000000U, /* ld */       TRASHES},
147 		{ 0xfc00c0e0U, 0xf4004000U, /* arith */    TRASHES},
148 		{ 0xfc00c3e0U, 0xf4008000U, /* bits */     TRASHES},
149 		{ 0xfc00ffe0U, 0xf400cc00U, /* jsr.n */    FLOW_CTRL | DELAYED | JSR},
150 		{ 0xfc00ffe0U, 0xf400c800U, /* jsr */      FLOW_CTRL | JSR},
151 		{ 0xfc00ffe0U, 0xf400c400U, /* jmp.n */    FLOW_CTRL | DELAYED},
152 		{ 0xfc00ffe0U, 0xf400c000U, /* jmp */      FLOW_CTRL},
153 		{ 0xfc00fbe0U, 0xf400e800U, /* ff */       TRASHES},
154 		{ 0xfc00ffe0U, 0xf400f800U, /* tbnd */     0},
155 		{ 0xfc00ffe0U, 0xf400fc00U, /* rte */      FLOW_CTRL},
156 		{ 0xfc000000U, 0xf8000000U, /* tbnd */     0},
157 	};
158 
159 	for (ptr = &control[0]; ptr < &control[nitems(control)]; ptr++)
160 		if ((instruction & ptr->mask) == ptr->value)
161 			return ptr->flags;
162 	return 0;
163 }
164 
165 static int
hex_value_needs_0x(u_int value)166 hex_value_needs_0x(u_int value)
167 {
168 	int c;
169 	int have_a_hex_digit = 0;
170 
171 	if (value <= 9)
172 		return (0);
173 
174 	while (value != 0) {
175 		c = value & 0xf;
176 		value >>= 4;
177 		if (c > 9)
178 			have_a_hex_digit = 1;
179 	}
180 	if (have_a_hex_digit == 0)	/* has no letter, thus needs 0x */
181 		return (1);
182 	if (c > 9)		/* starts with a letter, thus needs 0x */
183 		return (1);
184 	return (0);
185 }
186 
187 /*
188  * returns
189  *   1 if regs seems to be a reasonable kernel exception frame.
190  *   2 if regs seems to be a reasonable user exception frame
191  * 	(in the current task).
192  *   0 if this looks like neither.
193  */
194 int
frame_is_sane(db_regs_t * regs,int quiet)195 frame_is_sane(db_regs_t *regs, int quiet)
196 {
197 	/* no good if we can't read the whole frame */
198 	if (badaddr((vaddr_t)regs, 4) || badaddr((vaddr_t)&regs->fpit, 4)) {
199 		if (quiet == 0)
200 			db_printf("[WARNING: frame at %p : unreadable]\n", regs);
201 		return 0;
202 	}
203 
204 	/* r0 must be 0 (obviously) */
205 	if (regs->r[0] != 0) {
206 		if (quiet == 0)
207 			db_printf("[WARNING: frame at %p : r[0] != 0]\n", regs);
208 		return 0;
209 	}
210 
211 	/* stack sanity ... r31 must be nonzero, and must be word aligned */
212 	if (regs->r[31] == 0 || (regs->r[31] & 3) != 0) {
213 		if (quiet == 0)
214 			db_printf("[WARNING: frame at %p : r[31] == 0 or not word aligned]\n", regs);
215 		return 0;
216 	}
217 
218 #ifdef M88100
219 	if (CPU_IS88100) {
220 		/* sxip is reasonable */
221 #if 0
222 		if ((regs->sxip & XIP_E) != 0)
223 			goto out;
224 #endif
225 		/* snip is reasonable */
226 		if ((regs->snip & ~NIP_ADDR) != NIP_V)
227 			goto out;
228 		/* sfip is reasonable */
229 		if ((regs->sfip & ~FIP_ADDR) != FIP_V)
230 			goto out;
231 	}
232 #endif
233 
234 	/* epsr sanity */
235 	if (regs->epsr & PSR_BO)
236 		goto out;
237 
238 	return ((regs->epsr & PSR_MODE) ? 1 : 2);
239 
240 out:
241 	if (quiet == 0)
242 		db_printf("[WARNING: not an exception frame?]\n");
243 	return (0);
244 }
245 
246 const char *
m88k_exception_name(u_int vector)247 m88k_exception_name(u_int vector)
248 {
249 	switch (vector) {
250 	default:
251 	case   0: return "Reset";
252 	case   1: return "Interrupt";
253 	case   2: return "Instruction Access Exception";
254 	case   3: return "Data Access Exception";
255 	case   4: return "Misaligned Access Exception";
256 	case   5: return "Unimplemented Opcode Exception";
257 	case   6: return "Privilege Violation";
258 	case   7: return "Bounds Check";
259 	case   8: return "Integer Divide Exception";
260 	case   9: return "Integer Overflow Exception";
261 	case  10: return "Error Exception";
262 	case  11: return "Non Maskable Interrupt";
263 	case 114: return "FPU precise";
264 	case 115: return "FPU imprecise";
265 	case DDB_ENTRY_BKPT_NO:
266 		return "ddb break";
267 	case DDB_ENTRY_TRACE_NO:
268 		return "ddb trace";
269 	case DDB_ENTRY_TRAP_NO:
270 		return "ddb trap";
271 	case 451: return "Syscall";
272 	}
273 }
274 
275 /*
276  * Read a word at address addr.
277  * Return 1 if was able to read, 0 otherwise.
278  */
279 u_int
db_trace_get_val(vaddr_t addr,u_int * ptr)280 db_trace_get_val(vaddr_t addr, u_int *ptr)
281 {
282 	label_t db_jmpbuf;
283 	label_t *prev = db_recover;
284 
285 	if (setjmp((db_recover = &db_jmpbuf)) != 0) {
286 		db_recover = prev;
287 		return 0;
288 	} else {
289 		db_read_bytes(addr, 4, (char *)ptr);
290 		db_recover = prev;
291 		return 1;
292 	}
293 }
294 
295 #define	FIRST_CALLPRESERVED_REG	14
296 #define	LAST_CALLPRESERVED_REG	29
297 #define	FIRST_ARG_REG		2
298 #define	LAST_ARG_REG		9
299 #define	RETURN_VAL_REG		1
300 
301 static u_int global_saved_list = 0x0; /* one bit per register */
302 static u_int local_saved_list  = 0x0; /* one bit per register */
303 static u_int trashed_list      = 0x0; /* one bit per register */
304 static u_int saved_reg[32];		 /* one value per register */
305 
306 #define	reg_bit(reg)	1 << (reg)
307 
308 static void
save_reg(int reg,u_int value)309 save_reg(int reg, u_int value)
310 {
311 	reg &= 0x1f;
312 	if (trashed_list & reg_bit(reg))
313 		return;	/* don't save trashed registers */
314 
315 	saved_reg[reg] = value;
316 	global_saved_list |= reg_bit(reg);
317 	local_saved_list |= reg_bit(reg);
318 }
319 
320 #define	mark_reg_trashed(reg)	trashed_list |= reg_bit((reg) & 0x1f)
321 
322 #define	have_global_reg(reg)	(global_saved_list & reg_bit(reg))
323 #define	have_local_reg(reg)	(local_saved_list & reg_bit(reg))
324 
325 #define	clear_local_saved_regs()	local_saved_list = trashed_list = 0
326 #define	clear_global_saved_regs()	local_saved_list = global_saved_list = 0
327 
328 #define	saved_reg_value(reg)	saved_reg[(reg)]
329 
330 /*
331  * Show any arguments that we might have been able to determine.
332  */
333 static void
print_args(void)334 print_args(void)
335 {
336 	int reg, last_arg;
337 
338 	/* find the highest argument register saved */
339 	for (last_arg = LAST_ARG_REG; last_arg >= FIRST_ARG_REG; last_arg--)
340 		if (have_local_reg(last_arg))
341 			break;
342 	if (last_arg < FIRST_ARG_REG)
343 		return;	/* none were saved */
344 
345 	db_printf("(");
346 
347 	/* print each one, up to the highest */
348 	for (reg = FIRST_ARG_REG; /*nothing */; reg++) {
349 		if (!have_local_reg(reg))
350 			db_printf("?");
351 		else {
352 			u_int value = saved_reg_value(reg);
353 			db_printf("%s%x", hex_value_needs_0x(value) ?
354 				  "0x" : "", value);
355 		}
356 		if (reg == last_arg)
357 			break;
358 		else
359 			db_printf(", ");
360 	}
361 	db_printf(")");
362 }
363 
364 #define JUMP_SOURCE_IS_BAD		0
365 #define JUMP_SOURCE_IS_OK		1
366 #define JUMP_SOURCE_IS_UNLIKELY		2
367 
368 /*
369  * Give an address to where we return, and an address to where we'd jumped,
370  * Decided if it all makes sense.
371  *
372  * Gcc sometimes optimized something like
373  *	if (condition)
374  *		func1();
375  *	else
376  *		OtherStuff...
377  * to
378  *	bcnd	!condition, mark
379  *	bsr.n	func1
380  *	 or	r1, r0, mark2
381  *    mark:
382  *	OtherStuff...
383  *    mark2:
384  *
385  * So RETURN_TO will be mark2, even though we really did branch via
386  * 'bsr.n func1', so this makes it difficult to be certain about being
387  * wrong.
388  */
389 static int
is_jump_source_ok(vaddr_t return_to,vaddr_t jump_to)390 is_jump_source_ok(vaddr_t return_to, vaddr_t jump_to)
391 {
392 	u_int flags;
393 	uint32_t instruction;
394 
395 	/*
396 	 * Delayed branches are the most common... look two instructions before
397 	 * where we were going to return to to see if it's a delayed branch.
398 	 */
399 	if (!db_trace_get_val(return_to - 8, &instruction))
400 		return JUMP_SOURCE_IS_BAD;
401 
402 	flags = m88k_instruction_info(instruction);
403 	if ((flags & (FLOW_CTRL | DELAYED)) == (FLOW_CTRL | DELAYED) &&
404 	    (flags & (JSR | BSR)) != 0) {
405 		if ((flags & JSR) != 0)
406 			return JUMP_SOURCE_IS_OK; /* have to assume it's correct */
407 		/* calculate the offset */
408 		if (br_dest(return_to - 8, instruction) == jump_to)
409 			return JUMP_SOURCE_IS_OK; /* exactamundo! */
410 		else
411 			return JUMP_SOURCE_IS_UNLIKELY;	/* seems wrong */
412 	}
413 
414 	/*
415 	 * Try again, looking for a non-delayed jump one instruction back.
416 	 */
417 	if (!db_trace_get_val(return_to - 4, &instruction))
418 		return JUMP_SOURCE_IS_BAD;
419 
420 	flags = m88k_instruction_info(instruction);
421 	if ((flags & (FLOW_CTRL | DELAYED)) == FLOW_CTRL &&
422 	    (flags & (JSR | BSR)) != 0) {
423 		if ((flags & JSR) != 0)
424 			return JUMP_SOURCE_IS_OK; /* have to assume it's correct */
425 		/* calculate the offset */
426 		if (br_dest(return_to - 4, instruction) == jump_to)
427 			return JUMP_SOURCE_IS_OK; /* exactamundo! */
428 		else
429 			return JUMP_SOURCE_IS_UNLIKELY;	/* seems wrong */
430 	}
431 
432 	return JUMP_SOURCE_IS_UNLIKELY;
433 }
434 
435 static int next_address_likely_wrong = 0;
436 
437 /* How much slop we expect in the stack trace */
438 #define FRAME_PLAY 8
439 
440 /*
441  *  Stack decode -
442  *	vaddr_t addr;    program counter
443  *	vaddr_t *stack; IN/OUT stack pointer
444  *
445  * 	given an address within a function and a stack pointer,
446  *	try to find the function from which this one was called
447  *	and the stack pointer for that function.
448  *
449  *	The return value is zero if we get confused or
450  *	we determine that the return address has not yet
451  *	been saved (early in the function prologue). Otherwise
452  *	the return value is the address from which this function
453  *	was called.
454  *
455  *	Note that even is zero is returned (the second case) the
456  *	stack pointer can be adjusted.
457  */
458 static vaddr_t
stack_decode(vaddr_t addr,vaddr_t * stack,int (* pr)(const char *,...))459 stack_decode(vaddr_t addr, vaddr_t *stack, int (*pr)(const char *, ...))
460 {
461 	Elf_Sym *proc;
462 	db_expr_t offset_from_proc;
463 	uint instructions_to_search;
464 	vaddr_t check_addr;
465 	vaddr_t function_addr;    /* start of function */
466 	uint32_t r31;
467 	uint32_t inst;
468 	vaddr_t ret_addr;	    /* address to which we return */
469 	u_int tried_to_save_r1 = 0;
470 	vaddr_t str30_addr = 0;
471 	vaddr_t last_subu_addr = 0;
472 
473 	/* get what we hope will be the symbol for the function name */
474 	proc = db_search_symbol(addr, DB_STGY_PROC, &offset_from_proc);
475 	if (offset_from_proc == addr) /* i.e. no symbol found */
476 		proc = NULL;
477 
478 	/*
479 	 * Try and find the start of this function, and its stack usage.
480 	 * If we do not have symbols available, we will need to
481 	 * look back in memory for a prologue pattern.
482 	 */
483 	if (proc != NULL) {
484 		const char *names = NULL;
485 		db_symbol_values(proc, &names, &function_addr);
486 		if (names == NULL)
487 			return 0;
488 	} else {
489 		/*
490 		 * Unable to find symbol. Search back looking for a function
491 		 * prolog.
492 		 *
493 		 * This is a difficult game because of the compiler
494 		 * optimizations. However, we can rely upon the first two
495 		 * instructions of the function being:
496 		 *	subu	r31, r31, imm16
497 		 *	st	r30, r31, imm16
498 		 * unless the function did not need a frame, in which case
499 		 * the store of r30 is missing...
500 		 */
501 		instructions_to_search = 400;
502 		for (check_addr = addr; instructions_to_search-- != 0;
503 		    check_addr -= 4) {
504 			if (!db_trace_get_val(check_addr, &inst))
505 				break;
506 
507 			if (ST_R30_R31_IMM(inst)) {
508 				DPRINTF(("{st r30 found at %p}\n",
509 				    check_addr));
510 				str30_addr = (vaddr_t)check_addr;
511 			} else if (SUBU_R31_R31_IMM(inst)) {
512 				DPRINTF(("{subu r31 found at %p}\n",
513 				    check_addr));
514 				if (str30_addr == (vaddr_t)check_addr + 4)
515 					break;	/* success */
516 				else
517 					last_subu_addr = (vaddr_t)check_addr;
518 			}
519 
520 			/*
521 			 * if we come across a [jmp r1] or [jmp.n r1] assume
522 			 * we have hit the previous functions epilogue and
523 			 * stop our search.
524 			 * Since we know we would have hit the "subu r31, r31"
525 			 * if it was right in front of us, we know this doesn't
526 			 * have one so we just return failure....
527 			 */
528 			if (JMP_R1(inst) || JMPN_R1(inst)) {
529 				if (last_subu_addr != 0) {
530 					check_addr = last_subu_addr;
531 					break;
532 				} else
533 					return 0;
534 			}
535 		}
536 		if (instructions_to_search == 0)
537 			return 0; /* bummer, couldn't find it */
538 		function_addr = check_addr;
539 	}
540 
541 	DPRINTF(("{start of function at %p}\n", function_addr));
542 	/*
543 	 * We now know the start of the function (function_addr).
544 	 * If we're stopped right there, or if it's not a
545 	 *		subu r31, r31, imm16
546 	 * then we're done.
547 	 */
548 	if (addr == function_addr)
549 		return 0;
550 	if (!db_trace_get_val(function_addr, &inst))
551 		return 0;
552 	if (!SUBU_R31_R31_IMM(inst))
553 		return 0;
554 
555  	/*
556 	 * Unfortunately for us, functions with variable number of
557 	 * arguments will further alter r31 in va_start(), through the
558 	 * use of __builtin_alloca(). Since panic() is one such
559 	 * function, we need to take this into account to be able to
560 	 * backtrack further.
561 	 *
562 	 * So we need to look for further addu/subu r31 sequences after the
563 	 * prologue.
564 	 *
565 	 * Of course, control flow may cause execution to NOT pass
566 	 * through the __builtin_alloca() expansion...
567 	 */
568 	DPRINTF(("{orig r31 is %p}\n", *stack));
569 	*stack += IMM16VAL(inst);
570 
571 	if (function_addr == (vaddr_t)&panic) /* XXX others? */ {
572 		check_addr = function_addr + 4;
573 		instructions_to_search = (addr - check_addr) / 4;
574 		while (instructions_to_search-- != 0) {
575 			if (!db_trace_get_val(check_addr, &inst))
576 				break;
577 			if (SUBU_R31_R31_IMM(inst)) {
578 				DPRINTF(("{variadic subu r31 found at %p}\n",
579 				    check_addr));
580 				*stack += IMM16VAL(inst);
581 			}
582 			check_addr += 4;
583 		}
584 	}
585 
586 	/*
587 	 * Search from the beginning of the function (function_addr) to where
588 	 * we are in the function (addr) looking to see what kind of registers
589 	 * have been saved on the stack.
590 	 *
591 	 * We'll stop looking before we get to addr if we hit a branch.
592 	 */
593 	clear_local_saved_regs();
594 	check_addr = function_addr;
595 	r31 = *stack;
596 	DPRINTF(("{entry r31 would be %p}\n", r31));
597 	for (instructions_to_search = (addr - check_addr) / sizeof(uint32_t);
598 	    instructions_to_search-- != 0; check_addr += 4) {
599 		uint32_t s1, d;
600 		uint flags;
601 
602 		/* read the instruction */
603 		if (!db_trace_get_val(check_addr, &inst))
604 			break;
605 
606 		if (SUBU_R31_R31_IMM(inst)) {
607 			r31 -= IMM16VAL(inst);
608 			DPRINTF(("{adjust r31 to %p at %p}\n",
609 			    r31, check_addr));
610 		}
611 
612 		/* find out the particulars about this instruction */
613 		flags = m88k_instruction_info(inst);
614 
615 		/* split the instruction in its diatic components anyway */
616 		s1 = (inst >> 16) & 0x1f;
617 		d = (inst >> 21) & 0x1f;
618 
619 		/* if a store to something off the stack pointer, note the value */
620 		if ((flags & STORE) && s1 == 31 /*stack pointer*/) {
621 			u_int value;
622 			if (!have_local_reg(d)) {
623 				if (d == 1)
624 					tried_to_save_r1 = r31 + IMM16VAL(inst);
625 				DPRINTF(("{r%d saved at %p to %p}\n",
626 				    d, check_addr, r31 + IMM16VAL(inst)));
627 				if (db_trace_get_val(r31 + IMM16VAL(inst),
628 				    &value))
629 					save_reg(d, value);
630 			}
631 			if ((flags & DOUBLE) && !have_local_reg(d + 1)) {
632 				if (d == 0)
633 					tried_to_save_r1 = r31 +
634 					    IMM16VAL(inst) + 4;
635 				DPRINTF(("{r%d saved at %p to %p}\n",
636 				    d + 1, check_addr, r31 + IMM16VAL(inst)));
637 				if (db_trace_get_val(r31 + IMM16VAL(inst) + 4,
638 				    &value))
639 					save_reg(d + 1, value);
640 			}
641 		}
642 
643 		/* if an inst that kills D (and maybe D+1), note that */
644 		if (flags & TRASHES) {
645 			mark_reg_trashed(d);
646 			if (flags & DOUBLE)
647 				mark_reg_trashed(d + 1);
648 		}
649 
650 		/* if a flow control instruction, stop now (or next if delayed) */
651 		if ((flags & FLOW_CTRL) && instructions_to_search != 0)
652 			instructions_to_search = (flags & DELAYED) ? 1 : 0;
653 	}
654 
655 	/*
656 	 * If we didn't save r1 at some point, we're hosed.
657 	 */
658 	if (!have_local_reg(1)) {
659 		if (tried_to_save_r1 != 0) {
660 			(*pr)("    <return value of next fcn unreadable in %08x>\n",
661 				  tried_to_save_r1);
662 		}
663 		return 0;
664 	}
665 
666 	ret_addr = saved_reg_value(1);
667 
668 	if (ret_addr != 0) {
669 		switch (is_jump_source_ok(ret_addr, function_addr)) {
670 		case JUMP_SOURCE_IS_OK:
671 			break; /* excellent */
672 
673 		case JUMP_SOURCE_IS_BAD:
674 			return 0; /* bummer */
675 
676 		case JUMP_SOURCE_IS_UNLIKELY:
677 			next_address_likely_wrong = 1;
678 			break;
679 		}
680 	}
681 
682 	return ret_addr;
683 }
684 
685 static void
db_stack_trace_cmd2(db_regs_t * regs,int (* pr)(const char *,...))686 db_stack_trace_cmd2(db_regs_t *regs, int (*pr)(const char *, ...))
687 {
688 	vaddr_t stack;
689 	u_int depth=1;
690 	vaddr_t where;
691 	u_int ft;
692 	u_int pair[2];
693 	int i;
694 
695 	/*
696 	 * Frame_is_sane returns:
697 	 *   1 if regs seems to be a reasonable kernel exception frame.
698 	 *   2 if regs seems to be a reasonable user exception frame
699 	 *      (in the current task).
700 	 *   0 if this looks like neither.
701 	 */
702 	if ((ft = frame_is_sane(regs, 1)) == 0) {
703 		(*pr)("Register frame 0x%x is suspicious; skipping trace\n", regs);
704 		return;
705 	}
706 
707 	/* if user space and no user space trace specified, puke */
708 	if (ft == 2)
709 		return;
710 
711 	/* fetch address */
712 	where = PC_REGS(regs);
713 	stack = regs->r[31];
714 	(*pr)("stack base = 0x%x\n", stack);
715 	(*pr)("(0) "); /* depth of trace */
716 	db_printsym(where, DB_STGY_PROC, pr);
717 	clear_global_saved_regs();
718 
719 	/* see if this routine had a stack frame */
720 	if ((where = stack_decode(where, &stack, pr)) == 0) {
721 		where = regs->r[1];
722 		(*pr)("(stackless)");
723 	} else
724 		print_args();
725 	(*pr)("\n");
726 
727 	do {
728 		/*
729 		 * If requested, show preserved registers at the time
730 		 * the next-shown call was made. Only registers known to have
731 		 * changed from the last exception frame are shown, as others
732 		 * can be gotten at by looking at the exception frame.
733 		 */
734 		(*pr)("(%d)%c", depth++, next_address_likely_wrong ? '?' : ' ');
735 		next_address_likely_wrong = 0;
736 
737 		db_printsym(where, DB_STGY_PROC, pr);
738 		where = stack_decode(where, &stack, pr);
739 		print_args();
740 		(*pr)("\n");
741 	} while (where);
742 
743 	/* try to trace back over trap/exception */
744 
745 	stack &= ~7; /* double word aligned */
746 	/* take last top of stack, and try to find an exception frame near it */
747 
748 	i = FRAME_PLAY;
749 	while (i) {
750 		/*
751 		 * On the stack, a pointer to the exception frame is written
752 		 * in two adjacent words. In the case of a fault from the kernel,
753 		 * this should point to the frame right above them:
754 		 *
755 		 * Exception Frame Top
756 		 * ..
757 		 * Exception Frame Bottom  <-- frame addr
758 		 * frame addr
759 		 * frame addr		<-- stack pointer
760 		 *
761 		 * In the case of a fault from user mode, the top of stack
762 		 * will just have the address of the frame
763 		 * replicated twice.
764 		 *
765 		 * frame addr		<-- top of stack
766 		 * frame addr
767 		 *
768 		 * Here we are just looking for kernel exception frames.
769 		 */
770 
771 		if (badaddr((vaddr_t)stack, 4) ||
772 		    badaddr((vaddr_t)(stack + 4), 4))
773 			break;
774 
775 		db_read_bytes((vaddr_t)stack, 2 * sizeof(int), (char *)pair);
776 
777 		/* the pairs should match and equal stack+8 */
778 		if (pair[0] == pair[1]) {
779 			if (pair[0] != stack+8) {
780 #if 0
781 				if (!badaddr((vaddr_t)pair[0], 4) &&
782 				    pair[0] != 0)
783 					(*pr)("stack_trace:found pair 0x%x but != to stack+8\n",
784 					    pair[0]);
785 #endif
786 			} else if (frame_is_sane((db_regs_t*)pair[0], 1) != 0) {
787 				struct trapframe *frame =
788 				    (struct trapframe *)pair[0];
789 
790 				(*pr)("-------------- %s [EF: 0x%x] -------------\n",
791 				    m88k_exception_name(frame->tf_vector),
792 				    frame);
793 				db_stack_trace_cmd2(&frame->tf_regs, pr);
794 				return;
795 			}
796 		}
797 		stack += 8;
798 		i--;
799 	}
800 }
801 
802 /*
803  * stack trace - needs a pointer to a m88k saved state.
804  *
805  * If argument f is given, the stack pointer of each call frame is
806  * printed.
807  */
808 void
db_stack_trace_print(db_expr_t addr,int have_addr,db_expr_t count,char * modif,int (* pr)(const char *,...))809 db_stack_trace_print(db_expr_t addr, int have_addr, db_expr_t count,
810     char *modif, int (*pr)(const char *, ...))
811 {
812 	enum {
813 		Default, Stack, Frame
814 	} style = Default;
815 	db_regs_t frame;
816 	db_regs_t *regs;
817 	union {
818 		db_regs_t *frame;
819 		db_expr_t num;
820 	} arg;
821 
822 	arg.num = addr;
823 
824 	while (modif && *modif) {
825 		switch (*modif++) {
826 		case 's': style = Stack  ; break;
827 		case 'f': style = Frame  ; break;
828 		default:
829 			(*pr)("unknown trace modifier [%c]\n", modif[-1]);
830 			/*FALLTHROUGH*/
831 		case 'h':
832 			(*pr)("usage: trace/[MODIFIER]  [ARG]\n");
833 			(*pr)("  s = ARG is a stack pointer\n");
834 			(*pr)("  f = ARG is a frame pointer\n");
835 			return;
836 		}
837 	}
838 
839 	if (!have_addr && style != Default) {
840 		(*pr)("expecting argument with /s or /f\n");
841 		return;
842 	}
843 	if (have_addr && style == Default)
844 		style = Frame;
845 
846 	switch (style) {
847 	case Default:
848 		regs = &ddb_regs;
849 		break;
850 	case Frame:
851 		regs = arg.frame;
852 		break;
853 	case Stack:
854 	    {
855 		u_int val1, val2, sxip;
856 		u_int ptr;
857 		bzero((void *)&frame, sizeof(frame));
858 #define REASONABLE_FRAME_DISTANCE 2048
859 
860 		/*
861 		 * We've got to find the top of a stack frame so we can get both
862 		 * a PC and a real SP.
863 		 */
864 		for (ptr = arg.num;/**/; ptr += 4) {
865 			/* Read a word from the named stack */
866 			if (db_trace_get_val(ptr, &val1) == 0) {
867 				(*pr)("can't read from %x, aborting.\n", ptr);
868 				return;
869 			}
870 
871 			/*
872 			 * See if it's a frame pointer.... if so it will be larger than
873 			 * the address it was taken from (i.e. point back up the stack)
874 			 * and we'll be able to read where it points.
875 			 */
876 			if (val1 <= ptr ||
877 			    (val1 & 3)  ||
878 			    val1 > (ptr + REASONABLE_FRAME_DISTANCE))
879 				continue;
880 
881 			/* peek at the next word to see if it could be a return address */
882 			if (db_trace_get_val(ptr, &sxip) == 0) {
883 				(*pr)("can't read from %x, aborting.\n", ptr);
884 				return;
885 			}
886 			if (sxip == 0 || !db_trace_get_val(sxip, &val2))
887 				continue;
888 
889 			if (db_trace_get_val(val1, &val2) == 0) {
890 				(*pr)("can't read from %x, aborting.\n", val1);
891 				continue;
892 			}
893 
894 			/*
895 			 * The value we've just read will be either
896 			 * another frame pointer, or the start of
897 			 * another exception frame.
898 			 */
899 			if (val2 == 0x12345678 &&
900 			    db_trace_get_val(val1 - 4, &val2) &&
901 			    val2 == val1 &&
902 			    db_trace_get_val(val1 - 8, &val2) &&
903 			    val2 == val1) {
904 				/* we've found a frame, so the stack
905 				   must have been good */
906 				(*pr)("%x looks like a frame, accepting %x\n",val1,ptr);
907 				break;
908 			}
909 
910 			if (val2 > val1 && (val2 & 3) == 0) {
911 				/* well, looks close enough to be another frame pointer */
912 				(*pr)("*%x = %x looks like a stack frame pointer, accepting %x\n", val1, val2, ptr);
913 				break;
914 			}
915 		}
916 		frame.r[31] = ptr;
917 		frame.epsr = 0x800003f0U;
918 #ifdef M88100
919 		if (CPU_IS88100) {
920 			frame.sxip = sxip | XIP_V;
921 			frame.snip = frame.sxip + 4;
922 			frame.sfip = frame.snip + 4;
923 		}
924 #endif
925 		(*pr)("[r31=%x, %sxip=%x]\n", frame.r[31],
926 		    CPU_IS88110 ? "e" : "s", frame.sxip);
927 		regs = &frame;
928 	    }
929 		break;
930 	}
931 	db_stack_trace_cmd2(regs, pr);
932 }
933