Print this page
9210 remove KMDB branch debugging support
9211 ::crregs could do with cr2/cr3 support
9209 ::ttrace should be able to filter by thread
Reviewed by: Patrick Mooney <patrick.mooney@joyent.com>
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/cmd/mdb/sparc/kmdb/kvm_isadep.c
+++ new/usr/src/cmd/mdb/sparc/kmdb/kvm_isadep.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License, Version 1.0 only
6 6 * (the "License"). You may not use this file except in compliance
7 7 * with the License.
8 8 *
9 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 10 * or http://www.opensolaris.org/os/licensing.
11 11 * See the License for the specific language governing permissions
12 12 * and limitations under the License.
13 13 *
14 14 * When distributing Covered Code, include this CDDL HEADER in each
↓ open down ↓ |
14 lines elided |
↑ open up ↑ |
15 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 16 * If applicable, add the following below this CDDL HEADER, with the
17 17 * fields enclosed by brackets "[]" replaced with your own identifying
18 18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 19 *
20 20 * CDDL HEADER END
21 21 */
22 22 /*
23 23 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
24 24 * Use is subject to license terms.
25 + *
26 + * Copyright 2018 Joyent, Inc.
25 27 */
26 28
27 -#pragma ident "%Z%%M% %I% %E% SMI"
28 -
29 29 /*
30 30 * isa-dependent portions of the kmdb target
31 31 */
32 32
33 33 #include <mdb/mdb_kreg_impl.h>
34 34 #include <mdb/mdb_debug.h>
35 35 #include <mdb/mdb_modapi.h>
36 36 #include <mdb/mdb_v9util.h>
37 37 #include <mdb/mdb_target_impl.h>
38 38 #include <mdb/mdb_err.h>
39 39 #include <mdb/mdb_umem.h>
40 40 #include <kmdb/kmdb_kdi.h>
41 41 #include <kmdb/kmdb_dpi.h>
42 42 #include <kmdb/kmdb_promif.h>
43 43 #include <kmdb/kmdb_asmutil.h>
44 44 #include <kmdb/kvm.h>
45 45 #include <mdb/mdb.h>
46 46
47 47 #include <sys/types.h>
48 48 #include <sys/stack.h>
49 49 #include <sys/regset.h>
50 50 #include <sys/sysmacros.h>
51 51 #include <sys/bitmap.h>
52 52 #include <sys/machtrap.h>
53 53 #include <sys/trap.h>
54 54
55 55 /* Higher than the highest trap number for which we have a specific specifier */
56 56 #define KMT_MAXTRAPNO 0x1ff
57 57
58 58 #define OP(x) ((x) >> 30)
59 59 #define OP3(x) (((x) >> 19) & 0x3f)
60 60 #define RD(x) (((x) >> 25) & 0x1f)
61 61 #define RS1(x) (((x) >> 14) & 0x1f)
62 62 #define RS2(x) ((x) & 0x1f)
63 63
64 64 #define OP_ARITH 0x2
65 65
66 66 #define OP3_OR 0x02
67 67 #define OP3_SAVE 0x3c
68 68 #define OP3_RESTORE 0x3d
69 69
70 70 static int
71 71 kmt_stack_iter(mdb_tgt_t *t, const mdb_tgt_gregset_t *gsp,
72 72 mdb_tgt_stack_f *func, void *arg, int cpuid)
73 73 {
74 74 const mdb_tgt_gregset_t *grp;
75 75 mdb_tgt_gregset_t gregs;
76 76 kreg_t *kregs = &gregs.kregs[0];
77 77 long nwin, stopwin, canrestore, wp, i, sp;
78 78 long argv[6];
79 79
80 80 /*
81 81 * If gsp isn't null, we were asked to dump a trace from a
82 82 * specific location. The normal iterator can handle that.
83 83 */
84 84 if (gsp != NULL) {
85 85 if (cpuid != DPI_MASTER_CPUID)
86 86 warn("register set provided - ignoring cpu argument\n");
87 87 return (mdb_kvm_v9stack_iter(t, gsp, func, arg));
88 88 }
89 89
90 90 if (kmdb_dpi_get_cpu_state(cpuid) < 0) {
91 91 warn("failed to iterate through stack for cpu %u", cpuid);
92 92 return (DCMD_ERR);
93 93 }
94 94
95 95 /*
96 96 * We're being asked to dump the trace for the current CPU.
97 97 * To do that, we need to iterate first through the saved
98 98 * register windors. If there's more to the trace than that,
99 99 * we'll hand off to the normal iterator.
100 100 */
101 101 if ((grp = kmdb_dpi_get_gregs(cpuid)) == NULL) {
102 102 warn("failed to retrieve registers for cpu %d", cpuid);
103 103 return (DCMD_ERR);
104 104 }
105 105
106 106 bcopy(grp, &gregs, sizeof (mdb_tgt_gregset_t));
107 107
108 108 wp = kregs[KREG_CWP];
109 109 canrestore = kregs[KREG_CANRESTORE];
110 110 nwin = kmdb_dpi_get_nwin(cpuid);
111 111 stopwin = ((wp + nwin) - canrestore - 1) % nwin;
112 112
113 113 mdb_dprintf(MDB_DBG_KMOD, "dumping cwp = %lu, canrestore = %lu, "
114 114 "stopwin = %lu\n", wp, canrestore, stopwin);
115 115
116 116 for (;;) {
117 117 struct rwindow rwin;
118 118
119 119 for (i = 0; i < 6; i++)
120 120 argv[i] = kregs[KREG_I0 + i];
121 121
122 122 if (kregs[KREG_PC] != 0 &&
123 123 func(arg, kregs[KREG_PC], 6, argv, &gregs) != 0)
124 124 return (0);
125 125
126 126 kregs[KREG_PC] = kregs[KREG_I7];
127 127 kregs[KREG_NPC] = kregs[KREG_PC] + 4;
128 128
129 129 if ((sp = kregs[KREG_FP] + STACK_BIAS) == STACK_BIAS || sp == 0)
130 130 return (0); /* Stop if we're at the end of stack */
131 131
132 132 if (sp & (STACK_ALIGN - 1))
133 133 return (set_errno(EMDB_STKALIGN));
134 134
135 135 wp = (wp + nwin - 1) % nwin;
136 136
137 137 if (wp == stopwin)
138 138 break;
139 139
140 140 bcopy(&kregs[KREG_I0], &kregs[KREG_O0], 8 * sizeof (kreg_t));
141 141
142 142 if (kmdb_dpi_get_rwin(cpuid, wp, &rwin) < 0) {
143 143 warn("unable to get registers from window %ld\n", wp);
144 144 return (-1);
145 145 }
146 146
147 147 for (i = 0; i < 8; i++)
148 148 kregs[KREG_L0 + i] = (uintptr_t)rwin.rw_local[i];
149 149 for (i = 0; i < 8; i++)
150 150 kregs[KREG_I0 + i] = (uintptr_t)rwin.rw_in[i];
151 151 }
152 152
153 153 mdb_dprintf(MDB_DBG_KMOD, "dumping wp %ld and beyond normally\n", wp);
154 154
155 155 /*
156 156 * hack - if we null out pc here, iterator won't print the frame
157 157 * that corresponds to the current set of registers. That's what we
158 158 * want because we just printed them above.
159 159 */
160 160 kregs[KREG_PC] = 0;
161 161 return (mdb_kvm_v9stack_iter(t, &gregs, func, arg));
162 162 }
163 163
164 164 void
165 165 kmt_printregs(const mdb_tgt_gregset_t *gregs)
166 166 {
167 167 mdb_v9printregs(gregs);
168 168 }
169 169
170 170 static int
171 171 kmt_stack_common(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv,
172 172 int cpuid, mdb_tgt_stack_f *func, kreg_t saved_pc)
173 173 {
174 174 mdb_tgt_gregset_t *grp = NULL;
175 175 mdb_tgt_gregset_t gregs;
176 176 void *arg = (void *)(uintptr_t)mdb.m_nargs;
177 177
178 178 if (flags & DCMD_ADDRSPEC) {
179 179 bzero(&gregs, sizeof (gregs));
180 180 gregs.kregs[KREG_FP] = addr;
181 181 gregs.kregs[KREG_I7] = saved_pc;
182 182 grp = &gregs;
183 183 }
184 184
185 185 if (argc != 0) {
186 186 if (argv->a_type == MDB_TYPE_CHAR || argc > 1)
187 187 return (DCMD_USAGE);
188 188
189 189 if (argv->a_type == MDB_TYPE_STRING)
190 190 arg = (void *)(uintptr_t)(uint_t)
191 191 mdb_strtoull(argv->a_un.a_str);
192 192 else
193 193 arg = (void *)(uintptr_t)(uint_t)argv->a_un.a_val;
194 194 }
195 195
196 196 (void) kmt_stack_iter(mdb.m_target, grp, func, arg, cpuid);
197 197
198 198 return (DCMD_OK);
199 199 }
200 200
201 201 int
202 202 kmt_cpustack(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv,
203 203 int cpuid, int verbose)
204 204 {
205 205 return (kmt_stack_common(addr, flags, argc, argv, cpuid,
206 206 (verbose ? mdb_kvm_v9framev : mdb_kvm_v9frame), 0));
207 207 }
208 208
209 209 int
210 210 kmt_stack(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
211 211 {
212 212 return (kmt_stack_common(addr, flags, argc, argv, DPI_MASTER_CPUID,
213 213 mdb_kvm_v9frame, 0));
214 214 }
215 215
216 216 int
217 217 kmt_stackv(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
218 218 {
219 219 return (kmt_stack_common(addr, flags, argc, argv, DPI_MASTER_CPUID,
220 220 mdb_kvm_v9framev, 0));
221 221 }
222 222
223 223 int
224 224 kmt_stackr(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
225 225 {
226 226 /*
227 227 * Force printing of the first register window by setting the saved
228 228 * pc (%i7) to PC_FAKE.
229 229 */
230 230 return (kmt_stack_common(addr, flags, argc, argv, DPI_MASTER_CPUID,
231 231 mdb_kvm_v9framer, PC_FAKE));
232 232 }
233 233
234 234 ssize_t
235 235 kmt_write_page(mdb_tgt_t *t, const void *buf, size_t nbytes, uintptr_t addr)
236 236 {
237 237 jmp_buf *oldpcb = NULL;
238 238 jmp_buf pcb;
239 239 physaddr_t pa;
240 240
241 241 /*
242 242 * Can we write to this page?
243 243 */
244 244 if (!(t->t_flags & MDB_TGT_F_ALLOWIO) &&
245 245 (nbytes = kmdb_kdi_range_is_nontoxic(addr, nbytes, 1)) == 0)
246 246 return (set_errno(EMDB_NOMAP));
247 247
248 248 /*
249 249 * The OBP va>pa call returns a protection value that's right only some
250 250 * of the time. We can, however, tell if we failed a write due to a
251 251 * protection violation. If we get such an error, we'll retry the
252 252 * write using pwrite.
253 253 */
254 254 if (setjmp(pcb) != 0) {
255 255 /* We failed the write */
256 256 kmdb_dpi_restore_fault_hdlr(oldpcb);
257 257
258 258 if (errno == EACCES && kmdb_prom_vtop(addr, &pa) == 0)
259 259 return (kmt_pwrite(t, buf, nbytes, pa));
260 260 return (-1); /* errno is set for us */
261 261 }
262 262
263 263 mdb_dprintf(MDB_DBG_KMOD, "copying %lu bytes from %p to %p\n", nbytes,
264 264 buf, (void *)addr);
265 265
266 266 oldpcb = kmdb_dpi_set_fault_hdlr(&pcb);
267 267 (void) kmt_writer((void *)buf, nbytes, addr);
268 268 kmdb_dpi_restore_fault_hdlr(oldpcb);
269 269
270 270 return (nbytes);
271 271 }
272 272
273 273 /*ARGSUSED*/
274 274 ssize_t
275 275 kmt_write(mdb_tgt_t *t, const void *buf, size_t nbytes, uintptr_t addr)
276 276 {
277 277 size_t ntowrite, nwritten, n;
278 278 int rc;
279 279
280 280 kmdb_prom_check_interrupt();
281 281
282 282 if (nbytes == 0)
283 283 return (0);
284 284
285 285 /*
286 286 * Break the writes up into page-sized chunks. First, the leading page
287 287 * fragment (if any), then the subsequent pages.
288 288 */
289 289
290 290 if ((n = (addr & (mdb.m_pagesize - 1))) != 0) {
291 291 ntowrite = MIN(mdb.m_pagesize - n, nbytes);
292 292
293 293 if ((rc = kmt_write_page(t, buf, ntowrite, addr)) != ntowrite)
294 294 return (rc);
295 295
296 296 addr = roundup(addr, mdb.m_pagesize);
297 297 nbytes -= ntowrite;
298 298 nwritten = ntowrite;
299 299 buf = ((caddr_t)buf + ntowrite);
300 300 }
301 301
302 302 while (nbytes > 0) {
303 303 ntowrite = MIN(mdb.m_pagesize, nbytes);
304 304
305 305 if ((rc = kmt_write_page(t, buf, ntowrite, addr)) != ntowrite)
306 306 return (rc < 0 ? rc : rc + nwritten);
307 307
308 308 addr += mdb.m_pagesize;
309 309 nbytes -= ntowrite;
310 310 nwritten += ntowrite;
311 311 buf = ((caddr_t)buf + ntowrite);
312 312 }
313 313
314 314 return (rc);
315 315 }
316 316
317 317 /*ARGSUSED*/
318 318 ssize_t
319 319 kmt_ioread(mdb_tgt_t *t, void *buf, size_t nbytes, uintptr_t addr)
320 320 {
321 321 return (set_errno(EMDB_TGTHWNOTSUP));
322 322 }
323 323
324 324 /*ARGSUSED*/
325 325 ssize_t
326 326 kmt_iowrite(mdb_tgt_t *t, const void *buf, size_t nbytes, uintptr_t addr)
327 327 {
328 328 return (set_errno(EMDB_TGTHWNOTSUP));
329 329 }
330 330
331 331 const char *
332 332 kmt_def_dismode(void)
333 333 {
334 334 #ifdef __sparcv9
335 335 return ("v9plus");
336 336 #else
337 337 return ("v8");
338 338 #endif
339 339 }
340 340
341 341 /*
342 342 * If we are stopped on a save instruction or at the first instruction of a
343 343 * known function, return %o7 as the step-out address; otherwise return the
344 344 * current frame's return address (%i7). Significantly better handling of
345 345 * step out in leaf routines could be accomplished by implementing more
346 346 * complex decoding of the current function and our current state.
347 347 */
348 348 int
349 349 kmt_step_out(mdb_tgt_t *t, uintptr_t *p)
350 350 {
351 351 kreg_t pc, i7, o7;
352 352 GElf_Sym func;
353 353
354 354 (void) kmdb_dpi_get_register("pc", &pc);
355 355 (void) kmdb_dpi_get_register("i7", &i7);
356 356 (void) kmdb_dpi_get_register("o7", &o7);
357 357
358 358 if (mdb_tgt_lookup_by_addr(t, pc, MDB_TGT_SYM_FUZZY, NULL, 0,
359 359 &func, NULL) == 0 && func.st_value == pc)
360 360 *p = o7 + 2 * sizeof (mdb_instr_t);
361 361 else {
362 362 mdb_instr_t instr;
363 363
364 364 if (mdb_tgt_vread(t, &instr, sizeof (instr), pc) !=
365 365 sizeof (instr)) {
366 366 warn("failed to read instruction at %p for step out",
367 367 (void *)pc);
368 368 return (-1);
369 369 }
↓ open down ↓ |
331 lines elided |
↑ open up ↑ |
370 370
371 371 if (OP(instr) == OP_ARITH && OP3(instr) == OP3_SAVE)
372 372 *p = o7 + 2 * sizeof (mdb_instr_t);
373 373 else
374 374 *p = i7 + 2 * sizeof (mdb_instr_t);
375 375 }
376 376
377 377 return (0);
378 378 }
379 379
380 -/*ARGSUSED*/
381 -int
382 -kmt_step_branch(mdb_tgt_t *t)
383 -{
384 - return (set_errno(EMDB_TGTHWNOTSUP));
385 -}
386 -
387 380 static const char *
388 381 regno2name(int idx)
389 382 {
390 383 const mdb_tgt_regdesc_t *rd;
391 384
392 385 for (rd = mdb_sparcv9_kregs; rd->rd_name != NULL; rd++) {
393 386 if (idx == rd->rd_num)
394 387 return (rd->rd_name);
395 388 }
396 389
397 390 ASSERT(rd->rd_name != NULL);
398 391
399 392 return ("unknown");
400 393 }
401 394
402 395 /*
403 396 * Step over call and jmpl by returning the address of the position where a
404 397 * temporary breakpoint can be set to catch return from the control transfer.
405 398 * This function does not currently provide advanced decoding of DCTI couples
406 399 * or any other complex special case; we just fall back to single-step.
407 400 */
408 401 int
409 402 kmt_next(mdb_tgt_t *t, uintptr_t *p)
410 403 {
411 404 kreg_t pc, npc;
412 405 GElf_Sym func;
413 406
414 407 (void) kmdb_dpi_get_register("pc", &pc);
415 408 (void) kmdb_dpi_get_register("npc", &npc);
416 409
417 410 if (mdb_tgt_lookup_by_addr(t, pc, MDB_TGT_SYM_FUZZY, NULL, 0,
418 411 &func, NULL) != 0)
419 412 return (-1);
420 413
421 414 if (npc < func.st_value || func.st_value + func.st_size <= npc) {
422 415 mdb_instr_t instr;
423 416 kreg_t reg;
424 417
425 418 /*
426 419 * We're about to transfer control outside this function, so we
427 420 * want to stop when control returns from the other function.
428 421 * Normally the return address will be in %o7, tail-calls being
429 422 * the exception. We try to discover if this is a tail-call and
430 423 * compute the return address in that case.
431 424 */
432 425 if (mdb_tgt_vread(t, &instr, sizeof (instr), pc) !=
433 426 sizeof (instr)) {
434 427 warn("failed to read instruction at %p for next",
435 428 (void *)pc);
436 429 return (-1);
437 430 }
438 431
439 432 if (OP(instr) == OP_ARITH && OP3(instr) == OP3_RESTORE) {
440 433 (void) kmdb_dpi_get_register("i7", ®);
441 434 } else if (OP(instr) == OP_ARITH && OP3(instr) == OP3_OR &&
442 435 RD(instr) == KREG_O7) {
443 436 if (RS1(instr) == KREG_G0)
444 437 return (set_errno(EAGAIN));
445 438
446 439 (void) kmdb_dpi_get_register(regno2name(RS2(instr)),
447 440 ®);
448 441 } else
449 442 (void) kmdb_dpi_get_register("o7", ®);
450 443
451 444 *p = reg + 2 * sizeof (mdb_instr_t);
452 445
453 446 return (0);
454 447 }
455 448
456 449 return (set_errno(EAGAIN));
457 450 }
458 451
459 452 const char *
460 453 kmt_trapname(int trapnum)
461 454 {
462 455 static char trapname[11];
463 456
464 457 switch (trapnum) {
465 458 case T_INSTR_EXCEPTION:
466 459 return ("instruction access error trap");
467 460 case T_ALIGNMENT:
468 461 return ("improper alignment trap");
469 462 case T_UNIMP_INSTR:
470 463 return ("illegal instruction trap");
471 464 case T_IDIV0:
472 465 return ("division by zero trap");
473 466 case T_FAST_INSTR_MMU_MISS:
474 467 return ("instruction access MMU miss trap");
475 468 case T_FAST_DATA_MMU_MISS:
476 469 return ("data access MMU miss trap");
477 470 case ST_KMDB_TRAP|T_SOFTWARE_TRAP:
478 471 return ("debugger entry trap");
479 472 case ST_KMDB_BREAKPOINT|T_SOFTWARE_TRAP:
480 473 return ("breakpoint trap");
481 474 default:
482 475 (void) mdb_snprintf(trapname, sizeof (trapname), "trap %#x",
483 476 trapnum);
484 477 return (trapname);
485 478 }
486 479 }
487 480
488 481 void
489 482 kmt_init_isadep(mdb_tgt_t *t)
490 483 {
491 484 kmt_data_t *kmt = t->t_data;
492 485
493 486 kmt->kmt_rds = mdb_sparcv9_kregs;
494 487
495 488 kmt->kmt_trapmax = KMT_MAXTRAPNO;
496 489 kmt->kmt_trapmap = mdb_zalloc(BT_SIZEOFMAP(kmt->kmt_trapmax), UM_SLEEP);
497 490
498 491 /* Traps for which we want to provide an explicit message */
499 492 (void) mdb_tgt_add_fault(t, T_INSTR_EXCEPTION, MDB_TGT_SPEC_INTERNAL,
500 493 no_se_f, NULL);
501 494 (void) mdb_tgt_add_fault(t, T_ALIGNMENT, MDB_TGT_SPEC_INTERNAL,
502 495 no_se_f, NULL);
503 496 (void) mdb_tgt_add_fault(t, T_UNIMP_INSTR, MDB_TGT_SPEC_INTERNAL,
504 497 no_se_f, NULL);
505 498 (void) mdb_tgt_add_fault(t, T_IDIV0, MDB_TGT_SPEC_INTERNAL,
506 499 no_se_f, NULL);
507 500 (void) mdb_tgt_add_fault(t, T_FAST_INSTR_MMU_MISS,
508 501 MDB_TGT_SPEC_INTERNAL, no_se_f, NULL);
509 502 (void) mdb_tgt_add_fault(t, T_FAST_DATA_MMU_MISS, MDB_TGT_SPEC_INTERNAL,
510 503 no_se_f, NULL);
511 504
512 505 /*
513 506 * Traps which will be handled elsewhere, and which therefore don't
514 507 * need the trap-based message.
515 508 */
516 509 BT_SET(kmt->kmt_trapmap, ST_KMDB_TRAP|T_SOFTWARE_TRAP);
517 510 BT_SET(kmt->kmt_trapmap, ST_KMDB_BREAKPOINT|T_SOFTWARE_TRAP);
518 511 BT_SET(kmt->kmt_trapmap, T_PA_WATCHPOINT);
519 512 BT_SET(kmt->kmt_trapmap, T_VA_WATCHPOINT);
520 513
521 514 /* Catch-all for traps not explicitly listed here */
522 515 (void) mdb_tgt_add_fault(t, KMT_TRAP_NOTENUM, MDB_TGT_SPEC_INTERNAL,
523 516 no_se_f, NULL);
524 517 }
525 518
526 519 /*ARGSUSED*/
527 520 void
528 521 kmt_startup_isadep(mdb_tgt_t *t)
529 522 {
530 523 }
↓ open down ↓ |
134 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX