1 /*-
2 * Mach Operating System
3 * Copyright (c) 1991,1990 Carnegie Mellon University
4 * All Rights Reserved.
5 *
6 * Permission to use, copy, modify and distribute this software and its
7 * documentation is hereby granted, provided that both the copyright
8 * notice and this permission notice appear in all copies of the
9 * software, derivative works or modified versions, and any portions
10 * thereof, and that both notices appear in supporting documentation.
11 *
12 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS
13 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
14 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
15 *
16 * Carnegie Mellon requests users of this software to return to
17 *
18 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
19 * School of Computer Science
20 * Carnegie Mellon University
21 * Pittsburgh PA 15213-3890
22 *
23 * any improvements or extensions that they make and grant Carnegie the
24 * rights to redistribute these changes.
25 */
26
27 #include <sys/param.h>
28 #include <sys/systm.h>
29 #include <sys/kdb.h>
30 #include <sys/proc.h>
31 #include <sys/reg.h>
32
33 #include <machine/cpu.h>
34 #include <machine/frame.h>
35 #include <machine/md_var.h>
36 #include <machine/pcb.h>
37 #include <machine/stack.h>
38
39 #include <vm/vm.h>
40 #include <vm/vm_param.h>
41 #include <vm/pmap.h>
42
43 #include <ddb/ddb.h>
44 #include <ddb/db_access.h>
45 #include <ddb/db_sym.h>
46 #include <ddb/db_variables.h>
47
48 static db_varfcn_t db_esp;
49 static db_varfcn_t db_frame;
50 static db_varfcn_t db_frame_seg;
51 static db_varfcn_t db_gs;
52 static db_varfcn_t db_ss;
53
54 /*
55 * Machine register set.
56 */
57 #define DB_OFFSET(x) (db_expr_t *)offsetof(struct trapframe, x)
58 struct db_variable db_regs[] = {
59 { "cs", DB_OFFSET(tf_cs), db_frame_seg },
60 { "ds", DB_OFFSET(tf_ds), db_frame_seg },
61 { "es", DB_OFFSET(tf_es), db_frame_seg },
62 { "fs", DB_OFFSET(tf_fs), db_frame_seg },
63 { "gs", NULL, db_gs },
64 { "ss", NULL, db_ss },
65 { "eax", DB_OFFSET(tf_eax), db_frame },
66 { "ecx", DB_OFFSET(tf_ecx), db_frame },
67 { "edx", DB_OFFSET(tf_edx), db_frame },
68 { "ebx", DB_OFFSET(tf_ebx), db_frame },
69 { "esp", NULL, db_esp },
70 { "ebp", DB_OFFSET(tf_ebp), db_frame },
71 { "esi", DB_OFFSET(tf_esi), db_frame },
72 { "edi", DB_OFFSET(tf_edi), db_frame },
73 { "eip", DB_OFFSET(tf_eip), db_frame },
74 { "efl", DB_OFFSET(tf_eflags), db_frame },
75 };
76 struct db_variable *db_eregs = db_regs + nitems(db_regs);
77
78 static __inline int
get_esp(struct trapframe * tf)79 get_esp(struct trapframe *tf)
80 {
81 return (TF_HAS_STACKREGS(tf) ? tf->tf_esp : (intptr_t)&tf->tf_esp);
82 }
83
84 static int
db_frame(struct db_variable * vp,db_expr_t * valuep,int op)85 db_frame(struct db_variable *vp, db_expr_t *valuep, int op)
86 {
87 int *reg;
88
89 if (kdb_frame == NULL)
90 return (0);
91
92 reg = (int *)((uintptr_t)kdb_frame + (db_expr_t)vp->valuep);
93 if (op == DB_VAR_GET)
94 *valuep = *reg;
95 else
96 *reg = *valuep;
97 return (1);
98 }
99
100 static int
db_frame_seg(struct db_variable * vp,db_expr_t * valuep,int op)101 db_frame_seg(struct db_variable *vp, db_expr_t *valuep, int op)
102 {
103 struct trapframe_vm86 *tfp;
104 int off;
105 uint16_t *reg;
106
107 if (kdb_frame == NULL)
108 return (0);
109
110 off = (intptr_t)vp->valuep;
111 if (kdb_frame->tf_eflags & PSL_VM) {
112 tfp = (void *)kdb_frame;
113 switch ((intptr_t)vp->valuep) {
114 case (intptr_t)DB_OFFSET(tf_cs):
115 reg = (uint16_t *)&tfp->tf_cs;
116 break;
117 case (intptr_t)DB_OFFSET(tf_ds):
118 reg = (uint16_t *)&tfp->tf_vm86_ds;
119 break;
120 case (intptr_t)DB_OFFSET(tf_es):
121 reg = (uint16_t *)&tfp->tf_vm86_es;
122 break;
123 case (intptr_t)DB_OFFSET(tf_fs):
124 reg = (uint16_t *)&tfp->tf_vm86_fs;
125 break;
126 }
127 } else
128 reg = (uint16_t *)((uintptr_t)kdb_frame + off);
129 if (op == DB_VAR_GET)
130 *valuep = *reg;
131 else
132 *reg = *valuep;
133 return (1);
134 }
135
136 static int
db_esp(struct db_variable * vp,db_expr_t * valuep,int op)137 db_esp(struct db_variable *vp, db_expr_t *valuep, int op)
138 {
139
140 if (kdb_frame == NULL)
141 return (0);
142
143 if (op == DB_VAR_GET)
144 *valuep = get_esp(kdb_frame);
145 else if (TF_HAS_STACKREGS(kdb_frame))
146 kdb_frame->tf_esp = *valuep;
147 return (1);
148 }
149
150 static int
db_gs(struct db_variable * vp,db_expr_t * valuep,int op)151 db_gs(struct db_variable *vp, db_expr_t *valuep, int op)
152 {
153 struct trapframe_vm86 *tfp;
154
155 if (kdb_frame != NULL && kdb_frame->tf_eflags & PSL_VM) {
156 tfp = (void *)kdb_frame;
157 if (op == DB_VAR_GET)
158 *valuep = tfp->tf_vm86_gs;
159 else
160 tfp->tf_vm86_gs = *valuep;
161 return (1);
162 }
163 if (op == DB_VAR_GET)
164 *valuep = rgs();
165 else
166 load_gs(*valuep);
167 return (1);
168 }
169
170 static int
db_ss(struct db_variable * vp,db_expr_t * valuep,int op)171 db_ss(struct db_variable *vp, db_expr_t *valuep, int op)
172 {
173
174 if (kdb_frame == NULL)
175 return (0);
176
177 if (op == DB_VAR_GET)
178 *valuep = TF_HAS_STACKREGS(kdb_frame) ? kdb_frame->tf_ss :
179 rss();
180 else if (TF_HAS_STACKREGS(kdb_frame))
181 kdb_frame->tf_ss = *valuep;
182 return (1);
183 }
184
185 #define NORMAL 0
186 #define TRAP 1
187 #define INTERRUPT 2
188 #define SYSCALL 3
189 #define DOUBLE_FAULT 4
190
191 static void db_nextframe(struct i386_frame **, db_addr_t *, struct thread *);
192 static int db_numargs(struct i386_frame *);
193 static void db_print_stack_entry(const char *, int, char **, int *, db_addr_t,
194 void *);
195
196 /*
197 * Figure out how many arguments were passed into the frame at "fp".
198 */
199 static int
db_numargs(struct i386_frame * fp)200 db_numargs(struct i386_frame *fp)
201 {
202 char *argp;
203 int inst;
204 int args;
205
206 argp = (char *)db_get_value((int)&fp->f_retaddr, 4, false);
207 /*
208 * XXX etext is wrong for LKMs. We should attempt to interpret
209 * the instruction at the return address in all cases. This
210 * may require better fault handling.
211 */
212 if (argp < btext || argp >= etext) {
213 args = -1;
214 } else {
215 retry:
216 inst = db_get_value((int)argp, 4, false);
217 if ((inst & 0xff) == 0x59) /* popl %ecx */
218 args = 1;
219 else if ((inst & 0xffff) == 0xc483) /* addl $Ibs, %esp */
220 args = ((inst >> 16) & 0xff) / 4;
221 else if ((inst & 0xf8ff) == 0xc089) { /* movl %eax, %Reg */
222 argp += 2;
223 goto retry;
224 } else
225 args = -1;
226 }
227 return (args);
228 }
229
230 static void
db_print_stack_entry(const char * name,int narg,char ** argnp,int * argp,db_addr_t callpc,void * frame)231 db_print_stack_entry(const char *name, int narg, char **argnp, int *argp,
232 db_addr_t callpc, void *frame)
233 {
234 int n = narg >= 0 ? narg : 5;
235
236 db_printf("%s(", name);
237 while (n) {
238 if (argnp)
239 db_printf("%s=", *argnp++);
240 db_printf("%r", db_get_value((int)argp, 4, false));
241 argp++;
242 if (--n != 0)
243 db_printf(",");
244 }
245 if (narg < 0)
246 db_printf(",...");
247 db_printf(") at ");
248 db_printsym(callpc, DB_STGY_PROC);
249 if (frame != NULL)
250 db_printf("/frame 0x%r", (register_t)frame);
251 db_printf("\n");
252 }
253
254 /*
255 * Figure out the next frame up in the call stack.
256 */
257 static void
db_nextframe(struct i386_frame ** fp,db_addr_t * ip,struct thread * td)258 db_nextframe(struct i386_frame **fp, db_addr_t *ip, struct thread *td)
259 {
260 struct trapframe *tf;
261 int frame_type;
262 int eip, esp, ebp;
263 db_expr_t offset;
264 c_db_sym_t sym;
265 const char *name;
266
267 eip = db_get_value((int) &(*fp)->f_retaddr, 4, false);
268 ebp = db_get_value((int) &(*fp)->f_frame, 4, false);
269
270 /*
271 * Figure out frame type. We look at the address just before
272 * the saved instruction pointer as the saved EIP is after the
273 * call function, and if the function being called is marked as
274 * dead (such as panic() at the end of dblfault_handler()), then
275 * the instruction at the saved EIP will be part of a different
276 * function (syscall() in this example) rather than the one that
277 * actually made the call.
278 */
279 frame_type = NORMAL;
280
281 if (eip >= PMAP_TRM_MIN_ADDRESS) {
282 sym = db_search_symbol(eip - 1 - setidt_disp, DB_STGY_ANY,
283 &offset);
284 } else {
285 sym = db_search_symbol(eip - 1, DB_STGY_ANY, &offset);
286 }
287 db_symbol_values(sym, &name, NULL);
288 if (name != NULL) {
289 if (strcmp(name, "calltrap") == 0 ||
290 strcmp(name, "fork_trampoline") == 0)
291 frame_type = TRAP;
292 else if (strncmp(name, "Xatpic_intr", 11) == 0 ||
293 strncmp(name, "Xapic_isr", 9) == 0) {
294 frame_type = INTERRUPT;
295 } else if (strcmp(name, "Xlcall_syscall") == 0 ||
296 strcmp(name, "Xint0x80_syscall") == 0)
297 frame_type = SYSCALL;
298 else if (strcmp(name, "dblfault_handler") == 0)
299 frame_type = DOUBLE_FAULT;
300 else if (strcmp(name, "Xtimerint") == 0 ||
301 strcmp(name, "Xxen_intr_upcall") == 0)
302 frame_type = INTERRUPT;
303 else if (strcmp(name, "Xcpustop") == 0 ||
304 strcmp(name, "Xrendezvous") == 0 ||
305 strcmp(name, "Xipi_intr_bitmap_handler") == 0) {
306 /* No arguments. */
307 frame_type = INTERRUPT;
308 }
309 }
310
311 /*
312 * Normal frames need no special processing.
313 */
314 if (frame_type == NORMAL) {
315 *ip = (db_addr_t) eip;
316 *fp = (struct i386_frame *) ebp;
317 return;
318 }
319
320 db_print_stack_entry(name, 0, 0, 0, eip, &(*fp)->f_frame);
321
322 /*
323 * For a double fault, we have to snag the values from the
324 * previous TSS since a double fault uses a task gate to
325 * switch to a known good state.
326 */
327 if (frame_type == DOUBLE_FAULT) {
328 esp = PCPU_GET(common_tssp)->tss_esp;
329 eip = PCPU_GET(common_tssp)->tss_eip;
330 ebp = PCPU_GET(common_tssp)->tss_ebp;
331 db_printf(
332 "--- trap 0x17, eip = %#r, esp = %#r, ebp = %#r ---\n",
333 eip, esp, ebp);
334 *ip = (db_addr_t) eip;
335 *fp = (struct i386_frame *) ebp;
336 return;
337 }
338
339 /*
340 * Point to base of trapframe which is just above the current
341 * frame. Pointer to it was put into %ebp by the kernel entry
342 * code.
343 */
344 tf = (struct trapframe *)(*fp)->f_frame;
345
346 /*
347 * This can be the case for e.g. fork_trampoline, last frame
348 * of a kernel thread stack.
349 */
350 if (tf == NULL) {
351 *ip = 0;
352 *fp = 0;
353 db_printf("--- kthread start\n");
354 return;
355 }
356
357 esp = get_esp(tf);
358 eip = tf->tf_eip;
359 ebp = tf->tf_ebp;
360 switch (frame_type) {
361 case TRAP:
362 db_printf("--- trap %#r", tf->tf_trapno);
363 break;
364 case SYSCALL:
365 db_printf("--- syscall");
366 db_decode_syscall(td, tf->tf_eax);
367 break;
368 case INTERRUPT:
369 db_printf("--- interrupt");
370 break;
371 default:
372 panic("The moon has moved again.");
373 }
374 db_printf(", eip = %#r, esp = %#r, ebp = %#r ---\n", eip, esp, ebp);
375
376 /*
377 * Detect the last (trap) frame on the kernel stack, where we
378 * entered kernel from usermode. Terminate tracing in this
379 * case.
380 */
381 switch (frame_type) {
382 case TRAP:
383 case INTERRUPT:
384 if (!TRAPF_USERMODE(tf))
385 break;
386 /* FALLTHROUGH */
387 case SYSCALL:
388 ebp = 0;
389 eip = 0;
390 break;
391 }
392
393 *ip = (db_addr_t) eip;
394 *fp = (struct i386_frame *) ebp;
395 }
396
397 static int
db_backtrace(struct thread * td,struct trapframe * tf,struct i386_frame * frame,db_addr_t pc,register_t sp,int count)398 db_backtrace(struct thread *td, struct trapframe *tf, struct i386_frame *frame,
399 db_addr_t pc, register_t sp, int count)
400 {
401 struct i386_frame *actframe;
402 #define MAXNARG 16
403 char *argnames[MAXNARG], **argnp = NULL;
404 const char *name;
405 int *argp;
406 db_expr_t offset;
407 c_db_sym_t sym;
408 int instr, narg;
409 bool first;
410
411 if (db_segsize(tf) == 16) {
412 db_printf(
413 "--- 16-bit%s, cs:eip = %#x:%#x, ss:esp = %#x:%#x, ebp = %#x, tf = %p ---\n",
414 (tf->tf_eflags & PSL_VM) ? " (vm86)" : "",
415 tf->tf_cs, tf->tf_eip,
416 TF_HAS_STACKREGS(tf) ? tf->tf_ss : rss(),
417 TF_HAS_STACKREGS(tf) ? tf->tf_esp : (intptr_t)&tf->tf_esp,
418 tf->tf_ebp, tf);
419 return (0);
420 }
421
422 /* 'frame' can be null initially. Just print the pc then. */
423 if (frame == NULL)
424 goto out;
425
426 /*
427 * If an indirect call via an invalid pointer caused a trap,
428 * %pc contains the invalid address while the return address
429 * of the unlucky caller has been saved by CPU on the stack
430 * just before the trap frame. In this case, try to recover
431 * the caller's address so that the first frame is assigned
432 * to the right spot in the right function, for that is where
433 * the failure actually happened.
434 *
435 * This trick depends on the fault address stashed in tf_err
436 * by trap_fatal() before entering KDB.
437 */
438 if (kdb_frame && pc == kdb_frame->tf_err) {
439 /*
440 * Find where the trap frame actually ends.
441 * It won't contain tf_esp or tf_ss unless crossing rings.
442 */
443 if (TF_HAS_STACKREGS(kdb_frame))
444 instr = (int)(kdb_frame + 1);
445 else
446 instr = (int)&kdb_frame->tf_esp;
447 pc = db_get_value(instr, 4, false);
448 }
449
450 if (count == -1)
451 count = 1024;
452
453 first = true;
454 while (count-- && !db_pager_quit) {
455 sym = db_search_symbol(pc, DB_STGY_ANY, &offset);
456 db_symbol_values(sym, &name, NULL);
457
458 /*
459 * Attempt to determine a (possibly fake) frame that gives
460 * the caller's pc. It may differ from `frame' if the
461 * current function never sets up a standard frame or hasn't
462 * set one up yet or has just discarded one. The last two
463 * cases can be guessed fairly reliably for code generated
464 * by gcc. The first case is too much trouble to handle in
465 * general because the amount of junk on the stack depends
466 * on the pc (the special handling of "calltrap", etc. in
467 * db_nextframe() works because the `next' pc is special).
468 */
469 actframe = frame;
470 if (first) {
471 first = false;
472 if (sym == C_DB_SYM_NULL && sp != 0) {
473 /*
474 * If a symbol couldn't be found, we've probably
475 * jumped to a bogus location, so try and use
476 * the return address to find our caller.
477 */
478 db_print_stack_entry(name, 0, 0, 0, pc,
479 NULL);
480 pc = db_get_value(sp, 4, false);
481 if (db_search_symbol(pc, DB_STGY_PROC,
482 &offset) == C_DB_SYM_NULL)
483 break;
484 continue;
485 } else if (tf != NULL) {
486 instr = db_get_value(pc, 4, false);
487 if ((instr & 0xffffff) == 0x00e58955) {
488 /* pushl %ebp; movl %esp, %ebp */
489 actframe = (void *)(get_esp(tf) - 4);
490 } else if ((instr & 0xffff) == 0x0000e589) {
491 /* movl %esp, %ebp */
492 actframe = (void *)get_esp(tf);
493 if (tf->tf_ebp == 0) {
494 /* Fake frame better. */
495 frame = actframe;
496 }
497 } else if ((instr & 0xff) == 0x000000c3) {
498 /* ret */
499 actframe = (void *)(get_esp(tf) - 4);
500 } else if (offset == 0) {
501 /* Probably an assembler symbol. */
502 actframe = (void *)(get_esp(tf) - 4);
503 }
504 } else if (strcmp(name, "fork_trampoline") == 0) {
505 /*
506 * Don't try to walk back on a stack for a
507 * process that hasn't actually been run yet.
508 */
509 db_print_stack_entry(name, 0, 0, 0, pc,
510 actframe);
511 break;
512 }
513 }
514
515 argp = &actframe->f_arg0;
516 narg = MAXNARG;
517 if (sym != NULL && db_sym_numargs(sym, &narg, argnames)) {
518 argnp = argnames;
519 } else {
520 narg = db_numargs(frame);
521 }
522
523 db_print_stack_entry(name, narg, argnp, argp, pc, actframe);
524
525 if (actframe != frame) {
526 /* `frame' belongs to caller. */
527 pc = (db_addr_t)
528 db_get_value((int)&actframe->f_retaddr, 4, false);
529 continue;
530 }
531
532 db_nextframe(&frame, &pc, td);
533
534 out:
535 /*
536 * 'frame' can be null here, either because it was initially
537 * null or because db_nextframe() found no frame.
538 * db_nextframe() may also have found a non-kernel frame.
539 * !INKERNEL() classifies both. Stop tracing if either,
540 * after printing the pc if it is the kernel.
541 */
542 if (frame == NULL || frame <= actframe) {
543 if (pc != 0) {
544 sym = db_search_symbol(pc, DB_STGY_ANY,
545 &offset);
546 db_symbol_values(sym, &name, NULL);
547 db_print_stack_entry(name, 0, 0, 0, pc, frame);
548 }
549 break;
550 }
551 }
552
553 return (0);
554 }
555
556 void
db_trace_self(void)557 db_trace_self(void)
558 {
559 struct i386_frame *frame;
560 db_addr_t callpc;
561 register_t ebp;
562
563 __asm __volatile("movl %%ebp,%0" : "=r" (ebp));
564 frame = (struct i386_frame *)ebp;
565 callpc = (db_addr_t)db_get_value((int)&frame->f_retaddr, 4, false);
566 frame = frame->f_frame;
567 db_backtrace(curthread, NULL, frame, callpc, 0, -1);
568 }
569
570 int
db_trace_thread(struct thread * thr,int count)571 db_trace_thread(struct thread *thr, int count)
572 {
573 struct pcb *ctx;
574 struct trapframe *tf;
575
576 ctx = kdb_thr_ctx(thr);
577 tf = thr == kdb_thread ? kdb_frame : NULL;
578 return (db_backtrace(thr, tf, (struct i386_frame *)ctx->pcb_ebp,
579 ctx->pcb_eip, ctx->pcb_esp, count));
580 }
581
582 void
db_md_list_watchpoints(void)583 db_md_list_watchpoints(void)
584 {
585
586 dbreg_list_watchpoints();
587 }
588