]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/mips/mips/db_trace.c
Update lldb to trunk r290819 and resolve conflicts.
[FreeBSD/FreeBSD.git] / sys / mips / mips / db_trace.c
1 /*-
2  * Copyright (c) 2004-2005, Juniper Networks, Inc.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24  * SUCH DAMAGE.
25  *
26  *      JNPR: db_trace.c,v 1.8 2007/08/09 11:23:32 katta
27  */
28
29 #include <sys/cdefs.h>
30 __FBSDID("$FreeBSD$");
31
32 #include <sys/param.h>
33 #include <sys/systm.h>
34 #include <sys/kdb.h>
35 #include <sys/proc.h>
36 #include <sys/stack.h>
37 #include <sys/sysent.h>
38
39 #include <machine/asm.h>
40 #include <machine/db_machdep.h>
41 #include <machine/md_var.h>
42 #include <machine/mips_opcode.h>
43 #include <machine/pcb.h>
44 #include <machine/trap.h>
45
46 #include <ddb/ddb.h>
47 #include <ddb/db_sym.h>
48
49 extern char _locore[];
50 extern char _locoreEnd[];
51 extern char edata[];
52
53 /*
54  * A function using a stack frame has the following instruction as the first
55  * one: [d]addiu sp,sp,-<frame_size>
56  *
57  * We make use of this to detect starting address of a function. This works
58  * better than using 'j ra' instruction to signify end of the previous
59  * function (for e.g. functions like boot() or panic() do not actually
60  * emit a 'j ra' instruction).
61  *
62  * XXX the abi does not require that the addiu instruction be the first one.
63  */
64 #define MIPS_START_OF_FUNCTION(ins)     ((((ins) & 0xffff8000) == 0x27bd8000) \
65         || (((ins) & 0xffff8000) == 0x67bd8000))
66
67 /*
68  * MIPS ABI 3.0 requires that all functions return using the 'j ra' instruction
69  *
70  * XXX gcc doesn't do this for functions with __noreturn__ attribute.
71  */
72 #define MIPS_END_OF_FUNCTION(ins)       ((ins) == 0x03e00008)
73
74 #if defined(__mips_n64)
75 #       define  MIPS_IS_VALID_KERNELADDR(reg)   ((((reg) & 3) == 0) && \
76                                         ((vm_offset_t)(reg) >= MIPS_XKPHYS_START))
77 #else
78 #       define  MIPS_IS_VALID_KERNELADDR(reg)   ((((reg) & 3) == 0) && \
79                                         ((vm_offset_t)(reg) >= MIPS_KSEG0_START))
80 #endif
81
82 /*
83  * Functions ``special'' enough to print by name
84  */
85 #ifdef __STDC__
86 #define Name(_fn)  { (void*)_fn, # _fn }
87 #else
88 #define Name(_fn) { _fn, "_fn"}
89 #endif
90 static struct {
91         void *addr;
92         char *name;
93 }      names[] = {
94
95         Name(trap),
96         Name(MipsKernGenException),
97         Name(MipsUserGenException),
98         Name(MipsKernIntr),
99         Name(MipsUserIntr),
100         Name(cpu_switch),
101         {
102                 0, 0
103         }
104 };
105
106 /*
107  * Map a function address to a string name, if known; or a hex string.
108  */
109 static const char *
110 fn_name(uintptr_t addr)
111 {
112         static char buf[17];
113         int i = 0;
114
115         db_expr_t diff;
116         c_db_sym_t sym;
117         const char *symname;
118
119         diff = 0;
120         symname = NULL;
121         sym = db_search_symbol((db_addr_t)addr, DB_STGY_ANY, &diff);
122         db_symbol_values(sym, &symname, NULL);
123         if (symname && diff == 0)
124                 return (symname);
125
126         for (i = 0; names[i].name; i++)
127                 if (names[i].addr == (void *)addr)
128                         return (names[i].name);
129         sprintf(buf, "%jx", (uintmax_t)addr);
130         return (buf);
131 }
132
133 void
134 stacktrace_subr(register_t pc, register_t sp, register_t ra,
135         int (*printfn) (const char *,...))
136 {
137         InstFmt i;
138         /*
139          * Arrays for a0..a3 registers and flags if content
140          * of these registers is valid, e.g. obtained from the stack
141          */
142         int valid_args[4];
143         register_t args[4];
144         register_t va, subr;
145         unsigned instr, mask;
146         unsigned int frames = 0;
147         int more, stksize, j;
148         register_t      next_ra;
149
150 /* Jump here when done with a frame, to start a new one */
151 loop:
152
153         /*
154          * Invalidate arguments values
155          */
156         valid_args[0] = 0;
157         valid_args[1] = 0;
158         valid_args[2] = 0;
159         valid_args[3] = 0;
160         next_ra = 0;
161         stksize = 0;
162         subr = 0;
163         if (frames++ > 100) {
164                 (*printfn) ("\nstackframe count exceeded\n");
165                 /* return breaks stackframe-size heuristics with gcc -O2 */
166                 goto finish;    /* XXX */
167         }
168         /* check for bad SP: could foul up next frame */
169         /*XXX MIPS64 bad: this hard-coded SP is lame */
170         if (!MIPS_IS_VALID_KERNELADDR(sp)) {
171                 (*printfn) ("SP 0x%jx: not in kernel\n", sp);
172                 ra = 0;
173                 subr = 0;
174                 goto done;
175         }
176 #define Between(x, y, z) \
177                 ( ((x) <= (y)) && ((y) < (z)) )
178 #define pcBetween(a,b) \
179                 Between((uintptr_t)a, pc, (uintptr_t)b)
180
181         /*
182          * Check for current PC in  exception handler code that don't have a
183          * preceding "j ra" at the tail of the preceding function. Depends
184          * on relative ordering of functions in exception.S, swtch.S.
185          */
186         if (pcBetween(MipsKernGenException, MipsUserGenException))
187                 subr = (uintptr_t)MipsKernGenException;
188         else if (pcBetween(MipsUserGenException, MipsKernIntr))
189                 subr = (uintptr_t)MipsUserGenException;
190         else if (pcBetween(MipsKernIntr, MipsUserIntr))
191                 subr = (uintptr_t)MipsKernIntr;
192         else if (pcBetween(MipsUserIntr, MipsTLBInvalidException))
193                 subr = (uintptr_t)MipsUserIntr;
194         else if (pcBetween(MipsTLBInvalidException, MipsTLBMissException))
195                 subr = (uintptr_t)MipsTLBInvalidException;
196         else if (pcBetween(fork_trampoline, savectx))
197                 subr = (uintptr_t)fork_trampoline;
198         else if (pcBetween(savectx, cpu_throw))
199                 subr = (uintptr_t)savectx;
200         else if (pcBetween(cpu_throw, cpu_switch))
201                 subr = (uintptr_t)cpu_throw;
202         else if (pcBetween(cpu_switch, MipsSwitchFPState))
203                 subr = (uintptr_t)cpu_switch;
204         else if (pcBetween(_locore, _locoreEnd)) {
205                 subr = (uintptr_t)_locore;
206                 ra = 0;
207                 goto done;
208         }
209         /* check for bad PC */
210         /*XXX MIPS64 bad: These hard coded constants are lame */
211         if (!MIPS_IS_VALID_KERNELADDR(pc)) {
212                 (*printfn) ("PC 0x%jx: not in kernel\n", pc);
213                 ra = 0;
214                 goto done;
215         }
216
217         /*
218          * For a kernel stack overflow, skip to the output and
219          * afterwards pull the previous registers out of the trapframe
220          * instead of decoding the function prologue.
221          */
222         if (pc == (uintptr_t)MipsKStackOverflow)
223                 goto done;
224
225         /*
226          * Find the beginning of the current subroutine by scanning
227          * backwards from the current PC for the end of the previous
228          * subroutine.
229          */
230         if (!subr) {
231                 va = pc - sizeof(int);
232                 while (1) {
233                         instr = kdbpeek((int *)va);
234
235                         if (MIPS_START_OF_FUNCTION(instr))
236                                 break;
237
238                         if (MIPS_END_OF_FUNCTION(instr)) {
239                                 /* skip over branch-delay slot instruction */
240                                 va += 2 * sizeof(int);
241                                 break;
242                         }
243
244                         va -= sizeof(int);
245                 }
246
247                 /* skip over nulls which might separate .o files */
248                 while ((instr = kdbpeek((int *)va)) == 0)
249                         va += sizeof(int);
250                 subr = va;
251         }
252         /* scan forwards to find stack size and any saved registers */
253         stksize = 0;
254         more = 3;
255         mask = 0;
256         for (va = subr; more; va += sizeof(int),
257             more = (more == 3) ? 3 : more - 1) {
258                 /* stop if hit our current position */
259                 if (va >= pc)
260                         break;
261                 instr = kdbpeek((int *)va);
262                 i.word = instr;
263                 switch (i.JType.op) {
264                 case OP_SPECIAL:
265                         switch (i.RType.func) {
266                         case OP_JR:
267                         case OP_JALR:
268                                 more = 2;       /* stop after next instruction */
269                                 break;
270
271                         case OP_SYSCALL:
272                         case OP_BREAK:
273                                 more = 1;       /* stop now */
274                         }
275                         break;
276
277                 case OP_BCOND:
278                 case OP_J:
279                 case OP_JAL:
280                 case OP_BEQ:
281                 case OP_BNE:
282                 case OP_BLEZ:
283                 case OP_BGTZ:
284                         more = 2;       /* stop after next instruction */
285                         break;
286
287                 case OP_COP0:
288                 case OP_COP1:
289                 case OP_COP2:
290                 case OP_COP3:
291                         switch (i.RType.rs) {
292                         case OP_BCx:
293                         case OP_BCy:
294                                 more = 2;       /* stop after next instruction */
295                         }
296                         break;
297
298                 case OP_SW:
299                         /* look for saved registers on the stack */
300                         if (i.IType.rs != 29)
301                                 break;
302                         /*
303                          * only restore the first one except RA for
304                          * MipsKernGenException case
305                          */
306                         if (mask & (1 << i.IType.rt)) {
307                                 if (subr == (uintptr_t)MipsKernGenException &&
308                                     i.IType.rt == 31)
309                                         next_ra = kdbpeek((int *)(sp +
310                                             (short)i.IType.imm));
311                                 break;
312                         }
313                         mask |= (1 << i.IType.rt);
314                         switch (i.IType.rt) {
315                         case 4:/* a0 */
316                                 args[0] = kdbpeek((int *)(sp + (short)i.IType.imm));
317                                 valid_args[0] = 1;
318                                 break;
319
320                         case 5:/* a1 */
321                                 args[1] = kdbpeek((int *)(sp + (short)i.IType.imm));
322                                 valid_args[1] = 1;
323                                 break;
324
325                         case 6:/* a2 */
326                                 args[2] = kdbpeek((int *)(sp + (short)i.IType.imm));
327                                 valid_args[2] = 1;
328                                 break;
329
330                         case 7:/* a3 */
331                                 args[3] = kdbpeek((int *)(sp + (short)i.IType.imm));
332                                 valid_args[3] = 1;
333                                 break;
334
335                         case 31:        /* ra */
336                                 ra = kdbpeek((int *)(sp + (short)i.IType.imm));
337                         }
338                         break;
339
340                 case OP_SD:
341                         /* look for saved registers on the stack */
342                         if (i.IType.rs != 29)
343                                 break;
344                         /* only restore the first one */
345                         if (mask & (1 << i.IType.rt))
346                                 break;
347                         mask |= (1 << i.IType.rt);
348                         switch (i.IType.rt) {
349                         case 4:/* a0 */
350                                 args[0] = kdbpeekd((int *)(sp + (short)i.IType.imm));
351                                 valid_args[0] = 1;
352                                 break;
353
354                         case 5:/* a1 */
355                                 args[1] = kdbpeekd((int *)(sp + (short)i.IType.imm));
356                                 valid_args[1] = 1;
357                                 break;
358
359                         case 6:/* a2 */
360                                 args[2] = kdbpeekd((int *)(sp + (short)i.IType.imm));
361                                 valid_args[2] = 1;
362                                 break;
363
364                         case 7:/* a3 */
365                                 args[3] = kdbpeekd((int *)(sp + (short)i.IType.imm));
366                                 valid_args[3] = 1;
367                                 break;
368
369                         case 31:        /* ra */
370                                 ra = kdbpeekd((int *)(sp + (short)i.IType.imm));
371                         }
372                         break;
373
374                 case OP_ADDI:
375                 case OP_ADDIU:
376                 case OP_DADDI:
377                 case OP_DADDIU:
378                         /* look for stack pointer adjustment */
379                         if (i.IType.rs != 29 || i.IType.rt != 29)
380                                 break;
381                         stksize = -((short)i.IType.imm);
382                 }
383         }
384
385 done:
386         (*printfn) ("%s+%x (", fn_name(subr), pc - subr);
387         for (j = 0; j < 4; j ++) {
388                 if (j > 0)
389                         (*printfn)(",");
390                 if (valid_args[j])
391                         (*printfn)("%jx", (uintmax_t)(u_register_t)args[j]);
392                 else
393                         (*printfn)("?");
394         }
395
396         (*printfn) (") ra %jx sp %jx sz %d\n",
397             (uintmax_t)(u_register_t) ra,
398             (uintmax_t)(u_register_t) sp,
399             stksize);
400
401         if (pc == (uintptr_t)MipsKStackOverflow) {
402 #define TF_REG(base, reg)       ((base) + CALLFRAME_SIZ + ((reg) * SZREG))
403 #if defined(__mips_n64) || defined(__mips_n32)
404                 pc = kdbpeekd((int *)TF_REG(sp, PC));
405                 ra = kdbpeekd((int *)TF_REG(sp, RA));
406                 sp = kdbpeekd((int *)TF_REG(sp, SP));
407 #else
408                 pc = kdbpeek((int *)TF_REG(sp, PC));
409                 ra = kdbpeek((int *)TF_REG(sp, RA));
410                 sp = kdbpeek((int *)TF_REG(sp, SP));
411 #endif
412 #undef TF_REG
413                 (*printfn) ("--- Kernel Stack Overflow ---\n");
414                 goto loop;
415         } else if (ra) {
416                 if (pc == ra && stksize == 0)
417                         (*printfn) ("stacktrace: loop!\n");
418                 else {
419                         pc = ra;
420                         sp += stksize;
421                         ra = next_ra;
422                         goto loop;
423                 }
424         } else {
425 finish:
426                 if (curproc)
427                         (*printfn) ("pid %d\n", curproc->p_pid);
428                 else
429                         (*printfn) ("curproc NULL\n");
430         }
431 }
432
433
434 int
435 db_md_set_watchpoint(db_expr_t addr, db_expr_t size)
436 {
437
438         return(0);
439 }
440
441
442 int
443 db_md_clr_watchpoint(db_expr_t addr, db_expr_t size)
444 {
445
446         return(0);
447 }
448
449
450 void
451 db_md_list_watchpoints()
452 {
453 }
454
455 void
456 db_trace_self(void)
457 {
458         register_t pc, ra, sp;
459
460         sp = (register_t)(intptr_t)__builtin_frame_address(0);
461         ra = (register_t)(intptr_t)__builtin_return_address(0);
462
463         __asm __volatile(
464                 "jal 99f\n"
465                 "nop\n"
466                 "99:\n"
467                  "move %0, $31\n" /* get ra */
468                  "move $31, %1\n" /* restore ra */
469                  : "=r" (pc)
470                  : "r" (ra));
471         stacktrace_subr(pc, sp, ra, db_printf);
472         return;
473 }
474
475 int
476 db_trace_thread(struct thread *thr, int count)
477 {
478         register_t pc, ra, sp;
479         struct pcb *ctx;
480
481         ctx = kdb_thr_ctx(thr);
482         sp = (register_t)ctx->pcb_context[PCB_REG_SP];
483         pc = (register_t)ctx->pcb_context[PCB_REG_PC];
484         ra = (register_t)ctx->pcb_context[PCB_REG_RA];
485         stacktrace_subr(pc, sp, ra, db_printf);
486
487         return (0);
488 }
489
490 void
491 db_show_mdpcpu(struct pcpu *pc)
492 {
493
494         db_printf("ipis         = 0x%x\n", pc->pc_pending_ipis);
495         db_printf("next ASID    = %d\n", pc->pc_next_asid);
496         db_printf("GENID        = %d\n", pc->pc_asid_generation);
497         return;
498 }