Print this page
11626 introduce /etc/versions/build
11627 clean up UUID code for ::status


   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) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
  23  */
  24 
  25 /*
  26  * Copyright (c) 2013, Joyent, Inc.  All rights reserved.
  27  */
  28 
  29 /*
  30  * Libkvm Kernel Target
  31  *
  32  * The libkvm kernel target provides access to both crash dumps and live
  33  * kernels through /dev/ksyms and /dev/kmem, using the facilities provided by
  34  * the libkvm.so library.  The target-specific data structures are shared
  35  * between this file (common code) and the ISA-dependent parts of the target,
  36  * and so they are defined in the mdb_kvm.h header.  The target processes an
  37  * "executable" (/dev/ksyms or the unix.X file) which contains a primary
  38  * .symtab and .dynsym, and then also iterates over the krtld module chain in
  39  * the kernel in order to obtain a list of loaded modules and per-module symbol
  40  * tables.  To improve startup performance, the per-module symbol tables are
  41  * instantiated on-the-fly whenever an address lookup falls within the text
  42  * section of a given module.  The target also relies on services from the
  43  * mdb_ks (kernel support) module, which contains pieces of the implementation
  44  * that must be compiled against the kernel implementation.
  45  */
  46 
  47 #include <sys/modctl.h>
  48 #include <sys/kobj.h>
  49 #include <sys/kobj_impl.h>
  50 #include <sys/utsname.h>
  51 #include <sys/panic.h>
  52 #include <sys/dumphdr.h>
  53 #include <sys/dumpadm.h>

  54 
  55 #include <dlfcn.h>
  56 #include <libctf.h>
  57 #include <string.h>
  58 #include <fcntl.h>
  59 #include <errno.h>
  60 
  61 #include <mdb/mdb_target_impl.h>
  62 #include <mdb/mdb_err.h>
  63 #include <mdb/mdb_debug.h>
  64 #include <mdb/mdb_string.h>
  65 #include <mdb/mdb_modapi.h>
  66 #include <mdb/mdb_io_impl.h>
  67 #include <mdb/mdb_ctf.h>
  68 #include <mdb/mdb_kvm.h>
  69 #include <mdb/mdb_module.h>
  70 #include <mdb/mdb_kb.h>

  71 #include <mdb/mdb.h>
  72 
  73 #define KT_RELOC_BUF(buf, obase, nbase) \
  74         ((uintptr_t)(buf) - (uintptr_t)(obase) + (uintptr_t)(nbase))
  75 
  76 #define KT_BAD_BUF(buf, base, size) \
  77         ((uintptr_t)(buf) < (uintptr_t)(base) || \
  78         ((uintptr_t)(buf) >= (uintptr_t)(base) + (uintptr_t)(size)))
  79 
  80 typedef struct kt_symarg {
  81         mdb_tgt_sym_f *sym_cb;          /* Caller's callback function */
  82         void *sym_data;                 /* Callback function argument */
  83         uint_t sym_type;                /* Symbol type/binding filter */
  84         mdb_syminfo_t sym_info;         /* Symbol id and table id */
  85         const char *sym_obj;            /* Containing object */
  86 } kt_symarg_t;
  87 
  88 typedef struct kt_maparg {
  89         mdb_tgt_t *map_target;          /* Target used for mapping iter */
  90         mdb_tgt_map_f *map_cb;          /* Caller's callback function */
  91         void *map_data;                 /* Callback function argument */
  92 } kt_maparg_t;
  93 
  94 static const char KT_MODULE[] = "mdb_ks";
  95 static const char KT_CTFPARENT[] = "genunix";
  96 


  97 static void
  98 kt_load_module(kt_data_t *kt, mdb_tgt_t *t, kt_module_t *km)
  99 {
 100         km->km_data = mdb_alloc(km->km_datasz, UM_SLEEP);
 101 
 102         (void) mdb_tgt_vread(t, km->km_data, km->km_datasz, km->km_symspace_va);
 103 
 104         km->km_symbuf = (void *)
 105             KT_RELOC_BUF(km->km_symtab_va, km->km_symspace_va, km->km_data);
 106 
 107         km->km_strtab = (char *)
 108             KT_RELOC_BUF(km->km_strtab_va, km->km_symspace_va, km->km_data);
 109 
 110         km->km_symtab = mdb_gelf_symtab_create_raw(&kt->k_file->gf_ehdr,
 111             &km->km_symtab_hdr, km->km_symbuf,
 112             &km->km_strtab_hdr, km->km_strtab, MDB_TGT_SYMTAB);
 113 }
 114 
 115 static void
 116 kt_load_modules(kt_data_t *kt, mdb_tgt_t *t)


 468 {
 469         kt_data_t *kt = mdb.m_target->t_data;
 470         struct utsname uts;
 471 
 472         bzero(&uts, sizeof (uts));
 473         (void) strcpy(uts.nodename, "unknown machine");
 474         (void) kt_uname(mdb.m_target, &uts);
 475 
 476         if (mdb_prop_postmortem) {
 477                 mdb_printf("debugging %scrash dump %s (%d-bit) from %s\n",
 478                     kt->k_xpv_domu ? "domain " : "", kt->k_kvmfile,
 479                     (int)(sizeof (void *) * NBBY), uts.nodename);
 480         } else {
 481                 mdb_printf("debugging live kernel (%d-bit) on %s\n",
 482                     (int)(sizeof (void *) * NBBY), uts.nodename);
 483         }
 484 
 485         mdb_printf("operating system: %s %s (%s)\n",
 486             uts.release, uts.version, uts.machine);
 487 



 488         if (kt->k_dumphdr) {
 489                 dumphdr_t *dh = kt->k_dumphdr;
 490 
 491                 mdb_printf("image uuid: %s\n", dh->dump_uuid[0] != '\0' ?
 492                     dh->dump_uuid : "(not set)");
 493                 mdb_printf("panic message: %s\n", dh->dump_panicstring);
 494 
 495                 kt->k_dump_print_content(dh, kt->k_dumpcontent);
 496         } else {
 497                 char uuid[37];
 498 
 499                 if (mdb_readsym(uuid, 37, "dump_osimage_uuid") == 37 &&
 500                     uuid[36] == '\0') {
 501                         mdb_printf("image uuid: %s\n", uuid);


 502                 }
 503         }
 504 
 505         return (DCMD_OK);
 506 }
 507 
 508 static const mdb_dcmd_t kt_dcmds[] = {
 509         { "$c", "?[cnt]", "print stack backtrace", kt_stack },
 510         { "$C", "?[cnt]", "print stack backtrace", kt_stackv },
 511         { "$r", NULL, "print general-purpose registers", kt_regs },
 512         { "$?", NULL, "print status and registers", kt_regs },
 513         { "regs", NULL, "print general-purpose registers", kt_regs },
 514         { "stack", "?[cnt]", "print stack backtrace", kt_stack },
 515         { "stackregs", "?", "print stack backtrace and registers", kt_stackr },
 516 #ifdef __x86
 517         { "cpustack", "?[-v] [-c cpuid] [cnt]", "print stack backtrace for a "
 518             "specific CPU", kt_cpustack },
 519         { "cpuregs", "?[-c cpuid]", "print general-purpose registers for a "
 520             "specific CPU", kt_cpuregs },
 521 #endif


 565                 /*
 566                  * If we're examining a crash dump, root is /, and uname(2)
 567                  * does not match the utsname in the dump, issue a warning.
 568                  * Note that we are assuming that the modules and macros in
 569                  * /usr/lib are compiled against the kernel from uname -rv.
 570                  */
 571                 if (mdb_prop_postmortem && strcmp(mdb.m_root, "/") == 0 &&
 572                     uname(&u1) >= 0 && kt_uname(t, &u2) >= 0 &&
 573                     (strcmp(u1.release, u2.release) ||
 574                     strcmp(u1.version, u2.version))) {
 575                         mdb_warn("warning: dump is from %s %s %s; dcmds and "
 576                             "macros may not match kernel implementation\n",
 577                             u2.sysname, u2.release, u2.version);
 578                 }
 579 
 580                 if (mdb_module_load(KT_MODULE, MDB_MOD_GLOBAL) < 0) {
 581                         warn("failed to load kernel support module -- "
 582                             "some modules may not load\n");
 583                 }
 584 



 585                 if (mdb_prop_postmortem && kt->k_dumphdr != NULL) {
 586                         sym = dlsym(RTLD_NEXT, "mdb_dump_print_content");
 587                         if (sym != NULL)
 588                                 kt->k_dump_print_content = (void (*)())sym;
 589 
 590                         sym = dlsym(RTLD_NEXT, "mdb_dump_find_curproc");
 591                         if (sym != NULL)
 592                                 kt->k_dump_find_curproc = (int (*)())sym;
 593 
 594                         kt->k_dumpcontent = kt_find_dump_contents(kt);
 595                 }
 596 
 597                 if (t->t_flags & MDB_TGT_F_PRELOAD) {
 598                         oflag = mdb_iob_getflags(mdb.m_out) & MDB_IOB_PGENABLE;
 599 
 600                         mdb_iob_clrflags(mdb.m_out, oflag);
 601                         mdb_iob_puts(mdb.m_out, "Preloading module symbols: [");
 602                         mdb_iob_flush(mdb.m_out);
 603                 }
 604 




   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) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
  23  */
  24 
  25 /*
  26  * Copyright 2019 Joyent, Inc.
  27  */
  28 
  29 /*
  30  * Libkvm Kernel Target
  31  *
  32  * The libkvm kernel target provides access to both crash dumps and live
  33  * kernels through /dev/ksyms and /dev/kmem, using the facilities provided by
  34  * the libkvm.so library.  The target-specific data structures are shared
  35  * between this file (common code) and the ISA-dependent parts of the target,
  36  * and so they are defined in the mdb_kvm.h header.  The target processes an
  37  * "executable" (/dev/ksyms or the unix.X file) which contains a primary
  38  * .symtab and .dynsym, and then also iterates over the krtld module chain in
  39  * the kernel in order to obtain a list of loaded modules and per-module symbol
  40  * tables.  To improve startup performance, the per-module symbol tables are
  41  * instantiated on-the-fly whenever an address lookup falls within the text
  42  * section of a given module.  The target also relies on services from the
  43  * mdb_ks (kernel support) module, which contains pieces of the implementation
  44  * that must be compiled against the kernel implementation.
  45  */
  46 
  47 #include <sys/modctl.h>
  48 #include <sys/kobj.h>
  49 #include <sys/kobj_impl.h>
  50 #include <sys/utsname.h>
  51 #include <sys/panic.h>
  52 #include <sys/dumphdr.h>
  53 #include <sys/dumpadm.h>
  54 #include <sys/uuid.h>
  55 
  56 #include <dlfcn.h>
  57 #include <libctf.h>
  58 #include <string.h>
  59 #include <fcntl.h>
  60 #include <errno.h>
  61 
  62 #include <mdb/mdb_target_impl.h>
  63 #include <mdb/mdb_err.h>
  64 #include <mdb/mdb_debug.h>
  65 #include <mdb/mdb_string.h>
  66 #include <mdb/mdb_modapi.h>
  67 #include <mdb/mdb_io_impl.h>
  68 #include <mdb/mdb_ctf.h>
  69 #include <mdb/mdb_kvm.h>
  70 #include <mdb/mdb_module.h>
  71 #include <mdb/mdb_kb.h>
  72 #include <mdb/mdb_ks.h>
  73 #include <mdb/mdb.h>
  74 
  75 #define KT_RELOC_BUF(buf, obase, nbase) \
  76         ((uintptr_t)(buf) - (uintptr_t)(obase) + (uintptr_t)(nbase))
  77 
  78 #define KT_BAD_BUF(buf, base, size) \
  79         ((uintptr_t)(buf) < (uintptr_t)(base) || \
  80         ((uintptr_t)(buf) >= (uintptr_t)(base) + (uintptr_t)(size)))
  81 
  82 typedef struct kt_symarg {
  83         mdb_tgt_sym_f *sym_cb;          /* Caller's callback function */
  84         void *sym_data;                 /* Callback function argument */
  85         uint_t sym_type;                /* Symbol type/binding filter */
  86         mdb_syminfo_t sym_info;         /* Symbol id and table id */
  87         const char *sym_obj;            /* Containing object */
  88 } kt_symarg_t;
  89 
  90 typedef struct kt_maparg {
  91         mdb_tgt_t *map_target;          /* Target used for mapping iter */
  92         mdb_tgt_map_f *map_cb;          /* Caller's callback function */
  93         void *map_data;                 /* Callback function argument */
  94 } kt_maparg_t;
  95 
  96 static const char KT_MODULE[] = "mdb_ks";
  97 static const char KT_CTFPARENT[] = "genunix";
  98 
  99 static void (*print_buildversion)(void);
 100 
 101 static void
 102 kt_load_module(kt_data_t *kt, mdb_tgt_t *t, kt_module_t *km)
 103 {
 104         km->km_data = mdb_alloc(km->km_datasz, UM_SLEEP);
 105 
 106         (void) mdb_tgt_vread(t, km->km_data, km->km_datasz, km->km_symspace_va);
 107 
 108         km->km_symbuf = (void *)
 109             KT_RELOC_BUF(km->km_symtab_va, km->km_symspace_va, km->km_data);
 110 
 111         km->km_strtab = (char *)
 112             KT_RELOC_BUF(km->km_strtab_va, km->km_symspace_va, km->km_data);
 113 
 114         km->km_symtab = mdb_gelf_symtab_create_raw(&kt->k_file->gf_ehdr,
 115             &km->km_symtab_hdr, km->km_symbuf,
 116             &km->km_strtab_hdr, km->km_strtab, MDB_TGT_SYMTAB);
 117 }
 118 
 119 static void
 120 kt_load_modules(kt_data_t *kt, mdb_tgt_t *t)


 472 {
 473         kt_data_t *kt = mdb.m_target->t_data;
 474         struct utsname uts;
 475 
 476         bzero(&uts, sizeof (uts));
 477         (void) strcpy(uts.nodename, "unknown machine");
 478         (void) kt_uname(mdb.m_target, &uts);
 479 
 480         if (mdb_prop_postmortem) {
 481                 mdb_printf("debugging %scrash dump %s (%d-bit) from %s\n",
 482                     kt->k_xpv_domu ? "domain " : "", kt->k_kvmfile,
 483                     (int)(sizeof (void *) * NBBY), uts.nodename);
 484         } else {
 485                 mdb_printf("debugging live kernel (%d-bit) on %s\n",
 486                     (int)(sizeof (void *) * NBBY), uts.nodename);
 487         }
 488 
 489         mdb_printf("operating system: %s %s (%s)\n",
 490             uts.release, uts.version, uts.machine);
 491 
 492         if (print_buildversion != NULL)
 493                 print_buildversion();
 494 
 495         if (kt->k_dumphdr) {
 496                 dumphdr_t *dh = kt->k_dumphdr;
 497 
 498                 mdb_printf("image uuid: %s\n", dh->dump_uuid[0] != '\0' ?
 499                     dh->dump_uuid : "(not set)");
 500                 mdb_printf("panic message: %s\n", dh->dump_panicstring);
 501 
 502                 kt->k_dump_print_content(dh, kt->k_dumpcontent);
 503         } else {
 504                 char uuid[UUID_PRINTABLE_STRING_LENGTH];
 505 
 506                 if (mdb_readsym(uuid, sizeof (uuid),
 507                     "dump_osimage_uuid") == sizeof (uuid) &&
 508                     uuid[sizeof (uuid) - 1] == '\0') {
 509                         mdb_printf("image uuid: %s\n", uuid[0] != '\0' ?
 510                             uuid : "(not set)");
 511                 }
 512         }
 513 
 514         return (DCMD_OK);
 515 }
 516 
 517 static const mdb_dcmd_t kt_dcmds[] = {
 518         { "$c", "?[cnt]", "print stack backtrace", kt_stack },
 519         { "$C", "?[cnt]", "print stack backtrace", kt_stackv },
 520         { "$r", NULL, "print general-purpose registers", kt_regs },
 521         { "$?", NULL, "print status and registers", kt_regs },
 522         { "regs", NULL, "print general-purpose registers", kt_regs },
 523         { "stack", "?[cnt]", "print stack backtrace", kt_stack },
 524         { "stackregs", "?", "print stack backtrace and registers", kt_stackr },
 525 #ifdef __x86
 526         { "cpustack", "?[-v] [-c cpuid] [cnt]", "print stack backtrace for a "
 527             "specific CPU", kt_cpustack },
 528         { "cpuregs", "?[-c cpuid]", "print general-purpose registers for a "
 529             "specific CPU", kt_cpuregs },
 530 #endif


 574                 /*
 575                  * If we're examining a crash dump, root is /, and uname(2)
 576                  * does not match the utsname in the dump, issue a warning.
 577                  * Note that we are assuming that the modules and macros in
 578                  * /usr/lib are compiled against the kernel from uname -rv.
 579                  */
 580                 if (mdb_prop_postmortem && strcmp(mdb.m_root, "/") == 0 &&
 581                     uname(&u1) >= 0 && kt_uname(t, &u2) >= 0 &&
 582                     (strcmp(u1.release, u2.release) ||
 583                     strcmp(u1.version, u2.version))) {
 584                         mdb_warn("warning: dump is from %s %s %s; dcmds and "
 585                             "macros may not match kernel implementation\n",
 586                             u2.sysname, u2.release, u2.version);
 587                 }
 588 
 589                 if (mdb_module_load(KT_MODULE, MDB_MOD_GLOBAL) < 0) {
 590                         warn("failed to load kernel support module -- "
 591                             "some modules may not load\n");
 592                 }
 593 
 594                 print_buildversion = (void (*)(void))dlsym(RTLD_NEXT,
 595                     "mdb_print_buildversion");
 596 
 597                 if (mdb_prop_postmortem && kt->k_dumphdr != NULL) {
 598                         sym = dlsym(RTLD_NEXT, "mdb_dump_print_content");
 599                         if (sym != NULL)
 600                                 kt->k_dump_print_content = (void (*)())sym;
 601 
 602                         sym = dlsym(RTLD_NEXT, "mdb_dump_find_curproc");
 603                         if (sym != NULL)
 604                                 kt->k_dump_find_curproc = (int (*)())sym;
 605 
 606                         kt->k_dumpcontent = kt_find_dump_contents(kt);
 607                 }
 608 
 609                 if (t->t_flags & MDB_TGT_F_PRELOAD) {
 610                         oflag = mdb_iob_getflags(mdb.m_out) & MDB_IOB_PGENABLE;
 611 
 612                         mdb_iob_clrflags(mdb.m_out, oflag);
 613                         mdb_iob_puts(mdb.m_out, "Preloading module symbols: [");
 614                         mdb_iob_flush(mdb.m_out);
 615                 }
 616