4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
23 * Copyright (c) 2013 by Delphix. All rights reserved.
24 */
25
26 #include <kmdb/kmdb_kvm.h>
27 #include <kmdb/kvm.h>
28 #include <kmdb/kmdb_kdi.h>
29 #include <kmdb/kmdb_promif.h>
30 #include <kmdb/kmdb_module.h>
31 #include <kmdb/kmdb_asmutil.h>
32 #include <mdb/mdb_types.h>
33 #include <mdb/mdb_conf.h>
34 #include <mdb/mdb_err.h>
35 #include <mdb/mdb_modapi.h>
36 #include <mdb/mdb_target_impl.h>
37 #include <mdb/mdb_debug.h>
38 #include <mdb/mdb_string.h>
39 #include <mdb/mdb_ctf.h>
40 #include <mdb/mdb_kreg_impl.h>
41 #include <mdb/mdb_ks.h>
42 #include <mdb/mdb.h>
43
532 if (msg != NULL) {
533 if (first) {
534 mdb_printf(msg, NULL);
535 first = 0;
536 }
537
538 mdb_printf(" %s", kmc->kmc_modname);
539 }
540 }
541
542 if (!first && msg != NULL)
543 mdb_printf("\n");
544
545 return (n);
546 }
547
548 /*ARGSUSED*/
549 static int
550 kmt_status_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
551 {
552 kmt_data_t *kmt = mdb.m_target->t_data;
553 struct utsname uts;
554 char uuid[37];
555 kreg_t tt;
556
557 if (mdb_tgt_readsym(mdb.m_target, MDB_TGT_AS_VIRT, &uts, sizeof (uts),
558 "unix", "utsname") != sizeof (uts)) {
559 warn("failed to read 'utsname' struct from kernel\n");
560 bzero(&uts, sizeof (uts));
561 (void) strcpy(uts.nodename, "unknown machine");
562 }
563
564 mdb_printf("debugging live kernel (%d-bit) on %s\n",
565 (int)(sizeof (void *) * NBBY),
566 (*uts.nodename == '\0' ? "(not set)" : uts.nodename));
567 mdb_printf("operating system: %s %s (%s)\n",
568 uts.release, uts.version, uts.machine);
569
570 if (mdb_tgt_readsym(mdb.m_target, MDB_TGT_AS_VIRT, uuid, sizeof (uuid),
571 "genunix", "dump_osimage_uuid") != sizeof (uuid)) {
572 warn("failed to read 'dump_osimage_uuid' string from kernel\n");
573 (void) strcpy(uuid, "(error)");
574 } else if (*uuid == '\0') {
575 (void) strcpy(uuid, "(not set)");
576 } else if (uuid[36] != '\0') {
577 (void) strcpy(uuid, "(invalid)");
578 }
579 mdb_printf("image uuid: %s\n", uuid);
580
581 if (kmt->kmt_cpu != NULL) {
582 mdb_printf("CPU-specific support: %s\n",
583 kmt_cpu_name(kmt->kmt_cpu));
584 }
585
586 mdb_printf("DTrace state: %s\n", (kmdb_kdi_dtrace_get_state() ==
587 KDI_DTSTATE_DTRACE_ACTIVE ? "active (debugger breakpoints cannot "
588 "be armed)" : "inactive"));
589
590 (void) kmdb_dpi_get_register("tt", &tt);
591 mdb_printf("stopped on: %s\n", kmt_trapname(tt));
592
593 (void) kmt_dmod_status("pending dmod loads:", KMDB_MC_STATE_LOADING);
594 (void) kmt_dmod_status("pending dmod unloads:",
595 KMDB_MC_STATE_UNLOADING);
596
597 return (DCMD_OK);
598 }
599
600 /*ARGSUSED*/
601 static int
602 kmt_switch(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
603 {
604 if (!(flags & DCMD_ADDRSPEC) || argc != 0)
605 return (DCMD_USAGE);
2375 }
2376
2377 static void
2378 kmt_destroy(mdb_tgt_t *t)
2379 {
2380 kmt_data_t *kmt = t->t_data;
2381 kmt_module_t *km, *pkm;
2382
2383 mdb_nv_destroy(&kmt->kmt_modules);
2384 for (km = mdb_list_prev(&kmt->kmt_modlist); km != NULL; km = pkm) {
2385 pkm = mdb_list_prev(km);
2386 mdb_free(km, sizeof (kmt_module_t));
2387 }
2388
2389 if (!kmt_defbp_lock)
2390 kmt_defbp_destroy_all();
2391
2392 if (kmt->kmt_trapmap != NULL)
2393 mdb_free(kmt->kmt_trapmap, BT_SIZEOFMAP(kmt->kmt_trapmax));
2394
2395 if (kmt->kmt_cpu != NULL)
2396 kmt_cpu_destroy(kmt->kmt_cpu);
2397
2398 if (kmt != NULL)
2399 mdb_free(kmt, sizeof (kmt_data_t));
2400 }
2401
2402 static const mdb_tgt_ops_t kmt_ops = {
2403 kmt_setflags, /* t_setflags */
2404 (int (*)()) mdb_tgt_notsup, /* t_setcontext */
2405 kmt_activate, /* t_activate */
2406 (void (*)()) mdb_tgt_nop, /* t_deactivate */
2407 kmt_periodic, /* t_periodic */
2408 kmt_destroy, /* t_destroy */
2409 kmt_name, /* t_name */
2410 (const char *(*)()) mdb_conf_isa, /* t_isa */
2411 kmt_platform, /* t_platform */
2412 kmt_uname, /* t_uname */
2413 kmt_dmodel, /* t_dmodel */
2414 (ssize_t (*)()) mdb_tgt_notsup, /* t_aread */
2415 (ssize_t (*)()) mdb_tgt_notsup, /* t_awrite */
2416 kmt_read, /* t_vread */
2417 kmt_write, /* t_vwrite */
2418 kmt_pread, /* t_pread */
2419 kmt_pwrite, /* t_pwrite */
2420 kmt_read, /* t_fread */
2421 kmt_write, /* t_fwrite */
2422 kmt_ioread, /* t_ioread */
2423 kmt_iowrite, /* t_iowrite */
2424 kmt_vtop, /* t_vtop */
2425 kmt_lookup_by_name, /* t_lookup_by_name */
2426 kmt_lookup_by_addr, /* t_lookup_by_addr */
2427 kmt_symbol_iter, /* t_symbol_iter */
2428 kmt_mapping_iter, /* t_mapping_iter */
2429 kmt_object_iter, /* t_object_iter */
2430 kmt_addr_to_map, /* t_addr_to_map */
2431 kmt_name_to_map, /* t_name_to_map */
2432 kmt_addr_to_ctf, /* t_addr_to_ctf */
2433 kmt_name_to_ctf, /* t_name_to_ctf */
2434 kmt_status, /* t_status */
2435 (int (*)()) mdb_tgt_notsup, /* t_run */
2436 kmt_step, /* t_step */
2437 kmt_step_out, /* t_step_out */
2438 kmt_step_branch, /* t_step_branch */
2439 kmt_next, /* t_next */
2440 kmt_continue, /* t_cont */
2441 (int (*)()) mdb_tgt_notsup, /* t_signal */
2442 kmt_add_vbrkpt, /* t_add_vbrkpt */
2443 kmt_add_sbrkpt, /* t_add_sbrkpt */
2444 kmt_add_pwapt, /* t_add_pwapt */
2445 kmt_add_vwapt, /* t_add_vwapt */
2446 kmt_add_iowapt, /* t_add_iowapt */
2447 (int (*)()) mdb_tgt_null, /* t_add_sysenter */
2448 (int (*)()) mdb_tgt_null, /* t_add_sysexit */
2449 (int (*)()) mdb_tgt_null, /* t_add_signal */
2450 kmt_add_trap, /* t_add_fault */
2451 kmt_getareg, /* t_getareg */
2452 kmt_putareg, /* t_putareg */
2453 (int (*)()) mdb_tgt_nop, /* XXX t_stack_iter */
2454 (int (*)()) mdb_tgt_notsup /* t_auxv */
2455 };
2456
2457 /*
2458 * Called immediately upon resumption of the system after a step or continue.
2487 kmt->kmt_symavail = TRUE;
2488
2489 mdb_dprintf(MDB_DBG_KMOD, "synchronization complete\n");
2490
2491 kmt_defbp_prune();
2492
2493 if (kmt_defbp_num > 0 && kmt_defbp_bpspec == 0 &&
2494 kmdb_kdi_dtrace_get_state() != KDI_DTSTATE_DTRACE_ACTIVE) {
2495 /*
2496 * Deferred breakpoints were created while DTrace was active,
2497 * and consequently the deferred breakpoint enabling mechanism
2498 * wasn't activated. Activate it now, and then try to activate
2499 * the deferred breakpoints. We do this so that we can catch
2500 * the ones which may apply to modules that have been loaded
2501 * while they were waiting for DTrace to deactivate.
2502 */
2503 (void) kmt_defbp_activate(t);
2504 (void) mdb_tgt_sespec_activate_all(t);
2505 }
2506
2507 if (kmt->kmt_cpu_retry && ((kmt->kmt_cpu = kmt_cpu_create(t)) !=
2508 NULL || errno != EAGAIN))
2509 kmt->kmt_cpu_retry = FALSE;
2510
2511 (void) mdb_tgt_status(t, &t->t_status);
2512 }
2513
2514 /*
2515 * This routine executes while the kernel is running.
2516 */
2517 /*ARGSUSED*/
2518 int
2519 kmdb_kvm_create(mdb_tgt_t *t, int argc, const char *argv[])
2520 {
2521 kmt_data_t *kmt;
2522
2523 if (argc != 0)
2524 return (set_errno(EINVAL));
2525
2526 kmt = mdb_zalloc(sizeof (kmt_data_t), UM_SLEEP);
2527 t->t_data = kmt;
2528 t->t_ops = &kmt_ops;
2529 t->t_flags |= MDB_TGT_F_RDWR; /* kmdb is always r/w */
2530
2531 (void) mdb_nv_insert(&mdb.m_nv, "cpuid", &kmt_cpuid_disc, 0,
2532 MDB_NV_PERSIST | MDB_NV_RDONLY);
2533
2534 (void) mdb_nv_create(&kmt->kmt_modules, UM_SLEEP);
2535
2536 kmt_init_isadep(t);
2537
2538 kmt->kmt_symavail = FALSE;
2539 kmt->kmt_cpu_retry = TRUE;
2540
2541 bzero(&kmt_defbp_list, sizeof (mdb_list_t));
2542
2543 return (0);
2544
2545 create_err:
2546 kmt_destroy(t);
2547
2548 return (-1);
2549 }
2550
2551 /*
2552 * This routine is called once, when kmdb first has control of the world.
2553 */
2554 void
2555 kmdb_kvm_startup(void)
2556 {
2557 kmt_data_t *kmt = mdb.m_target->t_data;
2558
2559 mdb_dprintf(MDB_DBG_KMOD, "kmdb_kvm startup\n");
|
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
23 * Copyright (c) 2013 by Delphix. All rights reserved.
24 *
25 * Copyright 2018 Joyent, Inc.
26 */
27
28 #include <kmdb/kmdb_kvm.h>
29 #include <kmdb/kvm.h>
30 #include <kmdb/kmdb_kdi.h>
31 #include <kmdb/kmdb_promif.h>
32 #include <kmdb/kmdb_module.h>
33 #include <kmdb/kmdb_asmutil.h>
34 #include <mdb/mdb_types.h>
35 #include <mdb/mdb_conf.h>
36 #include <mdb/mdb_err.h>
37 #include <mdb/mdb_modapi.h>
38 #include <mdb/mdb_target_impl.h>
39 #include <mdb/mdb_debug.h>
40 #include <mdb/mdb_string.h>
41 #include <mdb/mdb_ctf.h>
42 #include <mdb/mdb_kreg_impl.h>
43 #include <mdb/mdb_ks.h>
44 #include <mdb/mdb.h>
45
534 if (msg != NULL) {
535 if (first) {
536 mdb_printf(msg, NULL);
537 first = 0;
538 }
539
540 mdb_printf(" %s", kmc->kmc_modname);
541 }
542 }
543
544 if (!first && msg != NULL)
545 mdb_printf("\n");
546
547 return (n);
548 }
549
550 /*ARGSUSED*/
551 static int
552 kmt_status_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
553 {
554 struct utsname uts;
555 char uuid[37];
556 kreg_t tt;
557
558 if (mdb_tgt_readsym(mdb.m_target, MDB_TGT_AS_VIRT, &uts, sizeof (uts),
559 "unix", "utsname") != sizeof (uts)) {
560 warn("failed to read 'utsname' struct from kernel\n");
561 bzero(&uts, sizeof (uts));
562 (void) strcpy(uts.nodename, "unknown machine");
563 }
564
565 mdb_printf("debugging live kernel (%d-bit) on %s\n",
566 (int)(sizeof (void *) * NBBY),
567 (*uts.nodename == '\0' ? "(not set)" : uts.nodename));
568 mdb_printf("operating system: %s %s (%s)\n",
569 uts.release, uts.version, uts.machine);
570
571 if (mdb_tgt_readsym(mdb.m_target, MDB_TGT_AS_VIRT, uuid, sizeof (uuid),
572 "genunix", "dump_osimage_uuid") != sizeof (uuid)) {
573 warn("failed to read 'dump_osimage_uuid' string from kernel\n");
574 (void) strcpy(uuid, "(error)");
575 } else if (*uuid == '\0') {
576 (void) strcpy(uuid, "(not set)");
577 } else if (uuid[36] != '\0') {
578 (void) strcpy(uuid, "(invalid)");
579 }
580 mdb_printf("image uuid: %s\n", uuid);
581
582 mdb_printf("DTrace state: %s\n", (kmdb_kdi_dtrace_get_state() ==
583 KDI_DTSTATE_DTRACE_ACTIVE ? "active (debugger breakpoints cannot "
584 "be armed)" : "inactive"));
585
586 (void) kmdb_dpi_get_register("tt", &tt);
587 mdb_printf("stopped on: %s\n", kmt_trapname(tt));
588
589 (void) kmt_dmod_status("pending dmod loads:", KMDB_MC_STATE_LOADING);
590 (void) kmt_dmod_status("pending dmod unloads:",
591 KMDB_MC_STATE_UNLOADING);
592
593 return (DCMD_OK);
594 }
595
596 /*ARGSUSED*/
597 static int
598 kmt_switch(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
599 {
600 if (!(flags & DCMD_ADDRSPEC) || argc != 0)
601 return (DCMD_USAGE);
2371 }
2372
2373 static void
2374 kmt_destroy(mdb_tgt_t *t)
2375 {
2376 kmt_data_t *kmt = t->t_data;
2377 kmt_module_t *km, *pkm;
2378
2379 mdb_nv_destroy(&kmt->kmt_modules);
2380 for (km = mdb_list_prev(&kmt->kmt_modlist); km != NULL; km = pkm) {
2381 pkm = mdb_list_prev(km);
2382 mdb_free(km, sizeof (kmt_module_t));
2383 }
2384
2385 if (!kmt_defbp_lock)
2386 kmt_defbp_destroy_all();
2387
2388 if (kmt->kmt_trapmap != NULL)
2389 mdb_free(kmt->kmt_trapmap, BT_SIZEOFMAP(kmt->kmt_trapmax));
2390
2391 if (kmt != NULL)
2392 mdb_free(kmt, sizeof (kmt_data_t));
2393 }
2394
2395 static const mdb_tgt_ops_t kmt_ops = {
2396 kmt_setflags, /* t_setflags */
2397 (int (*)()) mdb_tgt_notsup, /* t_setcontext */
2398 kmt_activate, /* t_activate */
2399 (void (*)()) mdb_tgt_nop, /* t_deactivate */
2400 kmt_periodic, /* t_periodic */
2401 kmt_destroy, /* t_destroy */
2402 kmt_name, /* t_name */
2403 (const char *(*)()) mdb_conf_isa, /* t_isa */
2404 kmt_platform, /* t_platform */
2405 kmt_uname, /* t_uname */
2406 kmt_dmodel, /* t_dmodel */
2407 (ssize_t (*)()) mdb_tgt_notsup, /* t_aread */
2408 (ssize_t (*)()) mdb_tgt_notsup, /* t_awrite */
2409 kmt_read, /* t_vread */
2410 kmt_write, /* t_vwrite */
2411 kmt_pread, /* t_pread */
2412 kmt_pwrite, /* t_pwrite */
2413 kmt_read, /* t_fread */
2414 kmt_write, /* t_fwrite */
2415 kmt_ioread, /* t_ioread */
2416 kmt_iowrite, /* t_iowrite */
2417 kmt_vtop, /* t_vtop */
2418 kmt_lookup_by_name, /* t_lookup_by_name */
2419 kmt_lookup_by_addr, /* t_lookup_by_addr */
2420 kmt_symbol_iter, /* t_symbol_iter */
2421 kmt_mapping_iter, /* t_mapping_iter */
2422 kmt_object_iter, /* t_object_iter */
2423 kmt_addr_to_map, /* t_addr_to_map */
2424 kmt_name_to_map, /* t_name_to_map */
2425 kmt_addr_to_ctf, /* t_addr_to_ctf */
2426 kmt_name_to_ctf, /* t_name_to_ctf */
2427 kmt_status, /* t_status */
2428 (int (*)()) mdb_tgt_notsup, /* t_run */
2429 kmt_step, /* t_step */
2430 kmt_step_out, /* t_step_out */
2431 kmt_next, /* t_next */
2432 kmt_continue, /* t_cont */
2433 (int (*)()) mdb_tgt_notsup, /* t_signal */
2434 kmt_add_vbrkpt, /* t_add_vbrkpt */
2435 kmt_add_sbrkpt, /* t_add_sbrkpt */
2436 kmt_add_pwapt, /* t_add_pwapt */
2437 kmt_add_vwapt, /* t_add_vwapt */
2438 kmt_add_iowapt, /* t_add_iowapt */
2439 (int (*)()) mdb_tgt_null, /* t_add_sysenter */
2440 (int (*)()) mdb_tgt_null, /* t_add_sysexit */
2441 (int (*)()) mdb_tgt_null, /* t_add_signal */
2442 kmt_add_trap, /* t_add_fault */
2443 kmt_getareg, /* t_getareg */
2444 kmt_putareg, /* t_putareg */
2445 (int (*)()) mdb_tgt_nop, /* XXX t_stack_iter */
2446 (int (*)()) mdb_tgt_notsup /* t_auxv */
2447 };
2448
2449 /*
2450 * Called immediately upon resumption of the system after a step or continue.
2479 kmt->kmt_symavail = TRUE;
2480
2481 mdb_dprintf(MDB_DBG_KMOD, "synchronization complete\n");
2482
2483 kmt_defbp_prune();
2484
2485 if (kmt_defbp_num > 0 && kmt_defbp_bpspec == 0 &&
2486 kmdb_kdi_dtrace_get_state() != KDI_DTSTATE_DTRACE_ACTIVE) {
2487 /*
2488 * Deferred breakpoints were created while DTrace was active,
2489 * and consequently the deferred breakpoint enabling mechanism
2490 * wasn't activated. Activate it now, and then try to activate
2491 * the deferred breakpoints. We do this so that we can catch
2492 * the ones which may apply to modules that have been loaded
2493 * while they were waiting for DTrace to deactivate.
2494 */
2495 (void) kmt_defbp_activate(t);
2496 (void) mdb_tgt_sespec_activate_all(t);
2497 }
2498
2499 (void) mdb_tgt_status(t, &t->t_status);
2500 }
2501
2502 /*
2503 * This routine executes while the kernel is running.
2504 */
2505 /*ARGSUSED*/
2506 int
2507 kmdb_kvm_create(mdb_tgt_t *t, int argc, const char *argv[])
2508 {
2509 kmt_data_t *kmt;
2510
2511 if (argc != 0)
2512 return (set_errno(EINVAL));
2513
2514 kmt = mdb_zalloc(sizeof (kmt_data_t), UM_SLEEP);
2515 t->t_data = kmt;
2516 t->t_ops = &kmt_ops;
2517 t->t_flags |= MDB_TGT_F_RDWR; /* kmdb is always r/w */
2518
2519 (void) mdb_nv_insert(&mdb.m_nv, "cpuid", &kmt_cpuid_disc, 0,
2520 MDB_NV_PERSIST | MDB_NV_RDONLY);
2521
2522 (void) mdb_nv_create(&kmt->kmt_modules, UM_SLEEP);
2523
2524 kmt_init_isadep(t);
2525
2526 kmt->kmt_symavail = FALSE;
2527
2528 bzero(&kmt_defbp_list, sizeof (mdb_list_t));
2529
2530 return (0);
2531
2532 create_err:
2533 kmt_destroy(t);
2534
2535 return (-1);
2536 }
2537
2538 /*
2539 * This routine is called once, when kmdb first has control of the world.
2540 */
2541 void
2542 kmdb_kvm_startup(void)
2543 {
2544 kmt_data_t *kmt = mdb.m_target->t_data;
2545
2546 mdb_dprintf(MDB_DBG_KMOD, "kmdb_kvm startup\n");
|