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>
Reviewed by: Yuri Pankov <yuripv@yuripv.net>
    
      
        | Split | 
	Close | 
      
      | Expand all | 
      | Collapse all | 
    
    
          --- old/usr/src/cmd/mdb/common/kmdb/kmdb_kvm.c
          +++ new/usr/src/cmd/mdb/common/kmdb/kmdb_kvm.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 (the "License").
   6    6   * You may not use this file except in compliance with the License.
   7    7   *
   8    8   * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9    9   * or http://www.opensolaris.org/os/licensing.
  10   10   * See the License for the specific language governing permissions
  11   11   * and limitations under the License.
  12   12   *
  13   13   * When distributing Covered Code, include this CDDL HEADER in each
  
    | 
      ↓ open down ↓ | 
    13 lines elided | 
    
      ↑ open up ↑ | 
  
  14   14   * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15   15   * If applicable, add the following below this CDDL HEADER, with the
  16   16   * fields enclosed by brackets "[]" replaced with your own identifying
  17   17   * information: Portions Copyright [yyyy] [name of copyright owner]
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  /*
  22   22   * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
  23   23   * Copyright (c) 2013 by Delphix. All rights reserved.
       24 + *
       25 + * Copyright 2018 Joyent, Inc.
  24   26   */
  25   27  
  26   28  #include <kmdb/kmdb_kvm.h>
  27   29  #include <kmdb/kvm.h>
  28   30  #include <kmdb/kmdb_kdi.h>
  29   31  #include <kmdb/kmdb_promif.h>
  30   32  #include <kmdb/kmdb_module.h>
  31   33  #include <kmdb/kmdb_asmutil.h>
  32   34  #include <mdb/mdb_types.h>
  33   35  #include <mdb/mdb_conf.h>
  34   36  #include <mdb/mdb_err.h>
  35   37  #include <mdb/mdb_modapi.h>
  36   38  #include <mdb/mdb_target_impl.h>
  37   39  #include <mdb/mdb_debug.h>
  38   40  #include <mdb/mdb_string.h>
  39   41  #include <mdb/mdb_ctf.h>
  40   42  #include <mdb/mdb_kreg_impl.h>
  41   43  #include <mdb/mdb_ks.h>
  42   44  #include <mdb/mdb.h>
  43   45  
  44   46  #include <strings.h>
  45   47  #include <dlfcn.h>
  46   48  #include <sys/isa_defs.h>
  47   49  #include <sys/kobj.h>
  48   50  #include <sys/kobj_impl.h>
  49   51  #include <sys/bitmap.h>
  50   52  #include <vm/as.h>
  51   53  
  52   54  static const char KMT_RTLD_NAME[] = "krtld";
  53   55  static const char KMT_MODULE[] = "mdb_ks";
  54   56  static const char KMT_CTFPARENT[] = "genunix";
  55   57  
  56   58  static mdb_list_t kmt_defbp_list;       /* List of current deferred bp's */
  57   59  static int kmt_defbp_lock;              /* For list, running kernel holds */
  58   60  static uint_t kmt_defbp_modchg_isload;  /* Whether mod change is load/unload */
  59   61  static struct modctl *kmt_defbp_modchg_modctl; /* modctl for defbp checking */
  60   62  static uint_t kmt_defbp_num;            /* Number of referenced def'd bp's */
  61   63  static int kmt_defbp_bpspec;            /* vespec for def'd bp activation bp */
  62   64  
  63   65  static const mdb_se_ops_t kmt_brkpt_ops;
  64   66  static const mdb_se_ops_t kmt_wapt_ops;
  65   67  
  66   68  static void kmt_sync(mdb_tgt_t *);
  67   69  
  68   70  typedef struct kmt_symarg {
  69   71          mdb_tgt_sym_f *sym_cb;          /* Caller's callback function */
  70   72          void *sym_data;                 /* Callback function argument */
  71   73          uint_t sym_type;                /* Symbol type/binding filter */
  72   74          mdb_syminfo_t sym_info;         /* Symbol id and table id */
  73   75          const char *sym_obj;            /* Containing object */
  74   76  } kmt_symarg_t;
  75   77  
  76   78  typedef struct kmt_maparg {
  77   79          mdb_tgt_t *map_target;          /* Target used for mapping iter */
  78   80          mdb_tgt_map_f *map_cb;          /* Caller's callback function */
  79   81          void *map_data;                 /* Callback function argument */
  80   82  } kmt_maparg_t;
  81   83  
  82   84  /*ARGSUSED*/
  83   85  int
  84   86  kmt_setflags(mdb_tgt_t *t, int flags)
  85   87  {
  86   88          /*
  87   89           * We only handle one flag (ALLOWIO), and we can't fail to set or clear
  88   90           * it, so we just blindly replace the t_flags version with the one
  89   91           * passed.
  90   92           */
  91   93          t->t_flags = (t->t_flags & ~MDB_TGT_F_ALLOWIO) |
  92   94              (flags & MDB_TGT_F_ALLOWIO);
  93   95  
  94   96          return (0);
  95   97  }
  96   98  
  97   99  /*ARGSUSED*/
  98  100  const char *
  99  101  kmt_name(mdb_tgt_t *t)
 100  102  {
 101  103          return ("kmdb_kvm");
 102  104  }
 103  105  
 104  106  /*ARGSUSED*/
 105  107  static const char *
 106  108  kmt_platform(mdb_tgt_t *t)
 107  109  {
 108  110          static char platform[SYS_NMLN];
 109  111  
 110  112          if (kmdb_dpi_get_state(NULL) == DPI_STATE_INIT)
 111  113                  return (mdb_conf_platform());
 112  114  
 113  115          if (mdb_tgt_readsym(mdb.m_target, MDB_TGT_AS_VIRT, platform,
 114  116              sizeof (platform), "unix", "platform") != sizeof (platform)) {
 115  117                  warn("'platform' symbol is missing from kernel\n");
 116  118                  return ("unknown");
 117  119          }
 118  120  
 119  121          return (platform);
 120  122  }
 121  123  
 122  124  static int
 123  125  kmt_uname(mdb_tgt_t *t, struct utsname *utsp)
 124  126  {
 125  127          return (mdb_tgt_readsym(t, MDB_TGT_AS_VIRT, utsp,
 126  128              sizeof (struct utsname), MDB_TGT_OBJ_EXEC, "utsname"));
 127  129  }
 128  130  
 129  131  /*ARGSUSED*/
 130  132  static int
 131  133  kmt_dmodel(mdb_tgt_t *t)
 132  134  {
 133  135          return (MDB_TGT_MODEL_NATIVE);
 134  136  }
 135  137  
 136  138  /*ARGSUSED*/
 137  139  ssize_t
 138  140  kmt_rw(mdb_tgt_t *t, void *buf, size_t nbytes, uint64_t addr,
 139  141      ssize_t (*rw)(void *, size_t, uint64_t))
 140  142  {
 141  143          /*
 142  144           * chunksz needs to be volatile because of the use of setjmp() in this
 143  145           * function.
 144  146           */
 145  147          volatile size_t chunksz;
 146  148          size_t n, ndone;
 147  149          jmp_buf *oldpcb = NULL;
 148  150          jmp_buf pcb;
 149  151          ssize_t res;
 150  152  
 151  153          kmdb_prom_check_interrupt();
 152  154  
 153  155          if (nbytes == 0)
 154  156                  return (0);
 155  157  
 156  158          /*
 157  159           * Try to process the entire buffer, as requested.  If we catch a fault,
 158  160           * try smaller chunks.  This allows us to handle regions that cross
 159  161           * mapping boundaries.
 160  162           */
 161  163          chunksz = nbytes;
 162  164          ndone = 0;
 163  165          if (setjmp(pcb) != 0) {
 164  166                  if (chunksz == 1) {
 165  167                          /* We failed with the smallest chunk - give up */
 166  168                          kmdb_dpi_restore_fault_hdlr(oldpcb);
 167  169                          return (ndone > 0 ? ndone : -1); /* errno set for us */
 168  170                  } else if (chunksz > 4)
 169  171                          chunksz = 4;
 170  172                  else
 171  173                          chunksz = 1;
 172  174          }
 173  175  
 174  176          oldpcb = kmdb_dpi_set_fault_hdlr(&pcb);
 175  177          while (nbytes > 0) {
 176  178                  n = MIN(chunksz, nbytes);
 177  179  
 178  180                  if ((res = rw(buf, n, addr)) != n)
 179  181                          return (res < 0 ? res : ndone + res);
 180  182  
 181  183                  addr += n;
 182  184                  nbytes -= n;
 183  185                  ndone += n;
 184  186                  buf = ((caddr_t)buf + n);
 185  187          }
 186  188  
 187  189          kmdb_dpi_restore_fault_hdlr(oldpcb);
 188  190  
 189  191          return (ndone);
 190  192  }
 191  193  
 192  194  static void
 193  195  kmt_bcopy(const void *s1, void *s2, size_t n)
 194  196  {
 195  197          /*
 196  198           * We need to guarantee atomic accesses for certain sizes.  bcopy won't
 197  199           * make that guarantee, so we need to do it ourselves.
 198  200           */
 199  201  #ifdef  _LP64
 200  202          if (n == 8 && ((uintptr_t)s1 & 7) == 0 && ((uintptr_t)s2 & 7) == 0)
 201  203                  *(uint64_t *)s2 = *(uint64_t *)s1;
 202  204          else
 203  205  #endif
 204  206          if (n == 4 && ((uintptr_t)s1 & 3) == 0 && ((uintptr_t)s2 & 3) == 0)
 205  207                  *(uint32_t *)s2 = *(uint32_t *)s1;
 206  208          else if (n == 2 && ((uintptr_t)s1 & 1) == 0 && ((uintptr_t)s2 & 1) == 0)
 207  209                  *(uint16_t *)s2 = *(uint16_t *)s1;
 208  210          else if (n == 1)
 209  211                  *(uint8_t *)s2 = *(uint8_t *)s1;
 210  212          else
 211  213                  bcopy(s1, s2, n);
 212  214  }
 213  215  
 214  216  static ssize_t
 215  217  kmt_reader(void *buf, size_t nbytes, uint64_t addr)
 216  218  {
 217  219          kmt_bcopy((void *)(uintptr_t)addr, buf, nbytes);
 218  220          return (nbytes);
 219  221  }
 220  222  
 221  223  ssize_t
 222  224  kmt_writer(void *buf, size_t nbytes, uint64_t addr)
 223  225  {
 224  226          kmt_bcopy(buf, (void *)(uintptr_t)addr, nbytes);
 225  227          return (nbytes);
 226  228  }
 227  229  
 228  230  /*ARGSUSED*/
 229  231  static ssize_t
 230  232  kmt_read(mdb_tgt_t *t, void *buf, size_t nbytes, uintptr_t addr)
 231  233  {
 232  234          /*
 233  235           * We don't want to allow reads of I/O-mapped memory.  Multi-page reads
 234  236           * that cross into I/O-mapped memory should be restricted to the initial
 235  237           * non-I/O region.  Reads that begin in I/O-mapped memory are failed
 236  238           * outright.
 237  239           */
 238  240          if (!(t->t_flags & MDB_TGT_F_ALLOWIO) &&
 239  241              (nbytes = kmdb_kdi_range_is_nontoxic(addr, nbytes, 0)) == 0)
 240  242                  return (set_errno(EMDB_NOMAP));
 241  243  
 242  244          return (kmt_rw(t, buf, nbytes, addr, kmt_reader));
 243  245  }
 244  246  
 245  247  /*ARGSUSED*/
 246  248  static ssize_t
 247  249  kmt_pread(mdb_tgt_t *t, void *buf, size_t nbytes, physaddr_t addr)
 248  250  {
 249  251          return (kmt_rw(t, buf, nbytes, addr, kmdb_kdi_pread));
 250  252  }
 251  253  
 252  254  /*ARGSUSED*/
 253  255  ssize_t
 254  256  kmt_pwrite(mdb_tgt_t *t, const void *buf, size_t nbytes, physaddr_t addr)
 255  257  {
 256  258          return (kmt_rw(t, (void *)buf, nbytes, addr, kmdb_kdi_pwrite));
 257  259  }
 258  260  
 259  261  static uintptr_t
 260  262  kmt_read_kas(mdb_tgt_t *t)
 261  263  {
 262  264          GElf_Sym sym;
 263  265  
 264  266          if (mdb_tgt_lookup_by_name(t, "unix", "kas", &sym, NULL) < 0) {
 265  267                  warn("'kas' symbol is missing from kernel\n");
 266  268                  (void) set_errno(EMDB_NOSYM);
 267  269                  return (0);
 268  270          }
 269  271  
 270  272          return ((uintptr_t)sym.st_value);
 271  273  }
 272  274  
 273  275  static int
 274  276  kmt_vtop(mdb_tgt_t *t, mdb_tgt_as_t as, uintptr_t va, physaddr_t *pap)
 275  277  {
 276  278          mdb_module_t *mod;
 277  279          struct as *asp;
 278  280          mdb_var_t *v;
 279  281  
 280  282          switch ((uintptr_t)as) {
 281  283          case (uintptr_t)MDB_TGT_AS_PHYS:
 282  284          case (uintptr_t)MDB_TGT_AS_FILE:
 283  285          case (uintptr_t)MDB_TGT_AS_IO:
 284  286                  return (set_errno(EINVAL));
 285  287          case (uintptr_t)MDB_TGT_AS_VIRT:
 286  288                  if ((asp = (struct as *)kmt_read_kas(t)) == NULL)
 287  289                          return (-1); /* errno is set for us */
 288  290                  break;
 289  291          default:
 290  292                  asp = (struct as *)as;
 291  293  
 292  294                  /* We don't support non-kas vtop */
 293  295                  if (asp != (struct as *)kmt_read_kas(t))
 294  296                          return (set_errno(EMDB_TGTNOTSUP));
 295  297          }
 296  298  
 297  299          if (kmdb_prom_vtop(va, pap) == 0)
 298  300                  return (0);
 299  301  
 300  302          if ((v = mdb_nv_lookup(&mdb.m_modules, "unix")) != NULL &&
 301  303              (mod = mdb_nv_get_cookie(v)) != NULL) {
 302  304                  int (*fptr)(uintptr_t, struct as *, physaddr_t *);
 303  305  
 304  306                  fptr = (int (*)(uintptr_t, struct as *, physaddr_t *))
 305  307                      dlsym(mod->mod_hdl, "platform_vtop");
 306  308  
 307  309                  if ((fptr != NULL) && ((*fptr)(va, asp, pap) == 0))
 308  310                          return (0);
 309  311          }
 310  312  
 311  313          return (set_errno(EMDB_NOMAP));
 312  314  }
 313  315  
 314  316  /*ARGSUSED*/
 315  317  static int
 316  318  kmt_cpuregs(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
 317  319  {
 318  320          const mdb_tgt_gregset_t *gregs;
 319  321          intptr_t cpuid = DPI_MASTER_CPUID;
 320  322          int i;
 321  323  
 322  324          if (flags & DCMD_ADDRSPEC) {
 323  325                  if (argc != 0)
 324  326                          return (DCMD_USAGE);
 325  327                  if ((cpuid = mdb_cpu2cpuid(addr)) < 0) {
 326  328                          (void) set_errno(EMDB_NOMAP);
 327  329                          mdb_warn("failed to find cpuid for cpu at %p", addr);
 328  330                          return (DCMD_ERR);
 329  331                  }
 330  332          }
 331  333  
 332  334          i = mdb_getopts(argc, argv,
 333  335              'c', MDB_OPT_UINTPTR, &cpuid,
 334  336              NULL);
 335  337  
 336  338          argc -= i;
 337  339          argv += i;
 338  340  
 339  341          if (argc != 0)
 340  342                  return (DCMD_USAGE);
 341  343  
 342  344          if ((gregs = kmdb_dpi_get_gregs(cpuid)) == NULL) {
 343  345                  warn("failed to retrieve registers for cpu %d", (int)cpuid);
 344  346                  return (DCMD_ERR);
 345  347          }
 346  348  
 347  349          kmt_printregs(gregs);
 348  350  
 349  351          return (DCMD_OK);
 350  352  }
 351  353  
 352  354  static int
 353  355  kmt_regs(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
 354  356  {
 355  357          if (flags & DCMD_ADDRSPEC)
 356  358                  return (DCMD_USAGE);
 357  359  
 358  360          return (kmt_cpuregs(addr, flags, argc, argv));
 359  361  }
 360  362  
 361  363  static int
 362  364  kmt_cpustack_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
 363  365  {
 364  366          intptr_t cpuid = DPI_MASTER_CPUID;
 365  367          uint_t verbose = 0;
 366  368          int i;
 367  369  
 368  370          if (flags & DCMD_ADDRSPEC) {
 369  371                  if ((cpuid = mdb_cpu2cpuid(addr)) < 0) {
 370  372                          (void) set_errno(EMDB_NOMAP);
 371  373                          mdb_warn("failed to find cpuid for cpu at %p", addr);
 372  374                          return (DCMD_ERR);
 373  375                  }
 374  376                  flags &= ~DCMD_ADDRSPEC;
 375  377          }
 376  378  
 377  379          i = mdb_getopts(argc, argv,
 378  380              'c', MDB_OPT_UINTPTR, &cpuid,
 379  381              'v', MDB_OPT_SETBITS, 1, &verbose,
 380  382              NULL);
 381  383  
 382  384          argc -= i;
 383  385          argv += i;
 384  386  
 385  387          return (kmt_cpustack(addr, flags, argc, argv, cpuid, verbose));
 386  388  }
 387  389  
 388  390  /*
 389  391   * Lasciate ogne speranza, voi ch'intrate.
 390  392   */
 391  393  static int
 392  394  kmt_call(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
 393  395  {
 394  396          uintptr_t *call_argv, rval;
 395  397          int parse_strings = 1;
 396  398          GElf_Sym sym;
 397  399          jmp_buf *oldpcb = NULL;
 398  400          jmp_buf pcb;
 399  401          int i;
 400  402  
 401  403          if (!(flags & DCMD_ADDRSPEC))
 402  404                  return (DCMD_USAGE);
 403  405  
 404  406          if (mdb_tgt_lookup_by_addr(mdb.m_target, addr, MDB_TGT_SYM_EXACT,
 405  407              NULL, 0, &sym, NULL) == 0 && GELF_ST_TYPE(sym.st_info) !=
 406  408              STT_FUNC) {
 407  409                  warn("%a is not a function\n", addr);
 408  410                  return (DCMD_ERR);
 409  411          }
 410  412  
 411  413          if (argc > 1 && argv[0].a_type == MDB_TYPE_STRING &&
 412  414              strcmp(argv[0].a_un.a_str, "-s") == 0) {
 413  415                  parse_strings = 0;
 414  416                  argc--;
 415  417                  argv++;
 416  418          }
 417  419  
 418  420          call_argv = mdb_alloc(sizeof (uintptr_t) * argc, UM_SLEEP);
 419  421  
 420  422          for (i = 0; i < argc; i++) {
 421  423                  switch (argv[i].a_type) {
 422  424                  case MDB_TYPE_STRING:
 423  425                          /*
 424  426                           * mdb_strtoull doesn't return on error, so we have to
 425  427                           * pre-check strings suspected to contain numbers.
 426  428                           */
 427  429                          if (parse_strings && strisbasenum(argv[i].a_un.a_str)) {
 428  430                                  call_argv[i] = (uintptr_t)mdb_strtoull(
 429  431                                      argv[i].a_un.a_str);
 430  432                          } else
 431  433                                  call_argv[i] = (uintptr_t)argv[i].a_un.a_str;
 432  434  
 433  435                          break;
 434  436  
 435  437                  case MDB_TYPE_IMMEDIATE:
 436  438                          call_argv[i] = argv[i].a_un.a_val;
 437  439                          break;
 438  440  
 439  441                  default:
 440  442                          mdb_free(call_argv,
 441  443                              sizeof (uintptr_t) * argc);
 442  444                          return (DCMD_USAGE);
 443  445                  }
 444  446          }
 445  447  
 446  448          if (setjmp(pcb) != 0) {
 447  449                  warn("call failed: caught a trap\n");
 448  450  
 449  451                  kmdb_dpi_restore_fault_hdlr(oldpcb);
 450  452                  mdb_free(call_argv, sizeof (uintptr_t) * argc);
 451  453                  return (DCMD_ERR);
 452  454          }
 453  455  
 454  456          oldpcb = kmdb_dpi_set_fault_hdlr(&pcb);
 455  457          rval = kmdb_dpi_call(addr, argc, call_argv);
 456  458          kmdb_dpi_restore_fault_hdlr(oldpcb);
 457  459  
 458  460          if (flags & DCMD_PIPE_OUT) {
 459  461                  mdb_printf("%p\n", rval);
 460  462          } else {
 461  463                  /* pretty-print the results */
 462  464                  mdb_printf("%p = %a(", rval, addr);
 463  465                  for (i = 0; i < argc; i++) {
 464  466                          if (i > 0)
 465  467                                  mdb_printf(", ");
 466  468                          if (argv[i].a_type == MDB_TYPE_STRING) {
 467  469                                  /* I'm ashamed but amused */
 468  470                                  char *quote = &("\""[parse_strings &&
 469  471                                      strisbasenum(argv[i].a_un.a_str)]);
 470  472  
 471  473                                  mdb_printf("%s%s%s", quote, argv[i].a_un.a_str,
 472  474                                      quote);
 473  475                          } else
 474  476                                  mdb_printf("%p", argv[i].a_un.a_val);
 475  477                  }
 476  478                  mdb_printf(");\n");
 477  479          }
 478  480  
 479  481          mdb_free(call_argv, sizeof (uintptr_t) * argc);
 480  482  
 481  483          return (DCMD_OK);
 482  484  }
 483  485  
 484  486  /*ARGSUSED*/
 485  487  int
 486  488  kmt_dump_crumbs(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
 487  489  {
 488  490          intptr_t cpu = -1;
 489  491  
 490  492          if (flags & DCMD_ADDRSPEC) {
 491  493                  if (argc != 0)
 492  494                          return (DCMD_USAGE);
 493  495          } else {
 494  496                  addr = 0;
 495  497  
 496  498                  if (mdb_getopts(argc, argv,
 497  499                      'c', MDB_OPT_UINTPTR, &cpu,
 498  500                      NULL) != argc)
 499  501                          return (DCMD_USAGE);
 500  502          }
 501  503  
 502  504          kmdb_dpi_dump_crumbs(addr, cpu);
 503  505  
 504  506          return (DCMD_OK);
 505  507  }
 506  508  
 507  509  /*ARGSUSED*/
 508  510  static int
 509  511  kmt_noducttape(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
 510  512  {
 511  513          int a = 0;
 512  514  
 513  515          return (a/a);
 514  516  }
 515  517  
 516  518  static int
 517  519  kmt_dmod_status(char *msg, int state)
 518  520  {
 519  521          kmdb_modctl_t *kmc;
 520  522          mdb_var_t *v;
 521  523          int first = 1, n = 0;
 522  524  
 523  525          mdb_nv_rewind(&mdb.m_dmodctl);
 524  526          while ((v = mdb_nv_advance(&mdb.m_dmodctl)) != NULL) {
 525  527                  kmc = MDB_NV_COOKIE(v);
 526  528  
 527  529                  if (kmc->kmc_state != state)
 528  530                          continue;
 529  531  
 530  532                  n++;
 531  533  
 532  534                  if (msg != NULL) {
 533  535                          if (first) {
 534  536                                  mdb_printf(msg, NULL);
 535  537                                  first = 0;
 536  538                          }
 537  539  
 538  540                          mdb_printf(" %s", kmc->kmc_modname);
 539  541                  }
 540  542          }
 541  543  
  
    | 
      ↓ open down ↓ | 
    508 lines elided | 
    
      ↑ open up ↑ | 
  
 542  544          if (!first && msg != NULL)
 543  545                  mdb_printf("\n");
 544  546  
 545  547          return (n);
 546  548  }
 547  549  
 548  550  /*ARGSUSED*/
 549  551  static int
 550  552  kmt_status_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
 551  553  {
 552      -        kmt_data_t *kmt = mdb.m_target->t_data;
 553  554          struct utsname uts;
 554  555          char uuid[37];
 555  556          kreg_t tt;
 556  557  
 557  558          if (mdb_tgt_readsym(mdb.m_target, MDB_TGT_AS_VIRT, &uts, sizeof (uts),
 558  559              "unix", "utsname") != sizeof (uts)) {
 559  560                  warn("failed to read 'utsname' struct from kernel\n");
 560  561                  bzero(&uts, sizeof (uts));
 561  562                  (void) strcpy(uts.nodename, "unknown machine");
 562  563          }
 563  564  
 564  565          mdb_printf("debugging live kernel (%d-bit) on %s\n",
 565  566              (int)(sizeof (void *) * NBBY),
 566  567              (*uts.nodename == '\0' ? "(not set)" : uts.nodename));
 567  568          mdb_printf("operating system: %s %s (%s)\n",
 568  569              uts.release, uts.version, uts.machine);
 569  570  
 570  571          if (mdb_tgt_readsym(mdb.m_target, MDB_TGT_AS_VIRT, uuid, sizeof (uuid),
  
    | 
      ↓ open down ↓ | 
    8 lines elided | 
    
      ↑ open up ↑ | 
  
 571  572              "genunix", "dump_osimage_uuid") != sizeof (uuid)) {
 572  573                  warn("failed to read 'dump_osimage_uuid' string from kernel\n");
 573  574                  (void) strcpy(uuid, "(error)");
 574  575          } else if (*uuid == '\0') {
 575  576                  (void) strcpy(uuid, "(not set)");
 576  577          } else if (uuid[36] != '\0') {
 577  578                  (void) strcpy(uuid, "(invalid)");
 578  579          }
 579  580          mdb_printf("image uuid: %s\n", uuid);
 580  581  
 581      -        if (kmt->kmt_cpu != NULL) {
 582      -                mdb_printf("CPU-specific support: %s\n",
 583      -                    kmt_cpu_name(kmt->kmt_cpu));
 584      -        }
 585      -
 586  582          mdb_printf("DTrace state: %s\n", (kmdb_kdi_dtrace_get_state() ==
 587  583              KDI_DTSTATE_DTRACE_ACTIVE ? "active (debugger breakpoints cannot "
 588  584              "be armed)" : "inactive"));
 589  585  
 590  586          (void) kmdb_dpi_get_register("tt", &tt);
 591  587          mdb_printf("stopped on: %s\n", kmt_trapname(tt));
 592  588  
 593  589          (void) kmt_dmod_status("pending dmod loads:", KMDB_MC_STATE_LOADING);
 594  590          (void) kmt_dmod_status("pending dmod unloads:",
 595  591              KMDB_MC_STATE_UNLOADING);
 596  592  
 597  593          return (DCMD_OK);
 598  594  }
 599  595  
 600  596  /*ARGSUSED*/
 601  597  static int
 602  598  kmt_switch(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
 603  599  {
 604  600          if (!(flags & DCMD_ADDRSPEC) || argc != 0)
 605  601                  return (DCMD_USAGE);
 606  602  
 607  603          if (kmdb_dpi_switch_master((int)addr) < 0) {
 608  604                  warn("failed to switch to CPU %d", (int)addr);
 609  605                  return (DCMD_ERR);
 610  606          }
 611  607  
 612  608          return (DCMD_OK);
 613  609  }
 614  610  
 615  611  static const mdb_dcmd_t kmt_dcmds[] = {
 616  612          { "$c", "?[cnt]", "print stack backtrace", kmt_stack },
 617  613          { "$C", "?[cnt]", "print stack backtrace", kmt_stackv },
 618  614          { "$r", NULL, "print general-purpose registers", kmt_regs },
 619  615          { "$?", NULL, "print status and registers", kmt_regs },
 620  616          { ":x", ":", "change the active CPU", kmt_switch },
 621  617          { "call", ":[arg ...]", "call a kernel function", kmt_call },
 622  618          { "cpustack", "?[-v] [-c cpuid] [cnt]", "print stack backtrace for a "
 623  619              "specific CPU", kmt_cpustack_dcmd },
 624  620          { "cpuregs", "?[-c cpuid]", "print general-purpose registers for a "
 625  621              "specific CPU", kmt_cpuregs },
 626  622          { "crumbs", NULL, NULL, kmt_dump_crumbs },
 627  623  #if defined(__i386) || defined(__amd64)
 628  624          { "in", ":[-L len]", "read from I/O port", kmt_in_dcmd },
 629  625          { "out", ":[-L len] val", "write to I/O port", kmt_out_dcmd },
 630  626          { "rdmsr", ":", "read an MSR", kmt_rdmsr },
 631  627          { "wrmsr", ": val", "write an MSR", kmt_wrmsr },
 632  628          { "rdpcicfg", ": bus dev func", "read a register in PCI config space",
 633  629          kmt_rdpcicfg },
 634  630          { "wrpcicfg", ": bus dev func val", "write a register in PCI config "
 635  631          "space", kmt_wrpcicfg },
 636  632  #endif
 637  633          { "noducttape", NULL, NULL, kmt_noducttape },
 638  634          { "regs", NULL, "print general-purpose registers", kmt_regs },
 639  635          { "stack", "?[cnt]", "print stack backtrace", kmt_stack },
 640  636          { "stackregs", "?", "print stack backtrace and registers", kmt_stackr },
 641  637          { "status", NULL, "print summary of current target", kmt_status_dcmd },
 642  638          { "switch", ":", "change the active CPU", kmt_switch },
 643  639          { NULL }
 644  640  };
 645  641  
 646  642  static uintmax_t
 647  643  kmt_reg_disc_get(const mdb_var_t *v)
 648  644  {
 649  645          mdb_tgt_reg_t r = 0;
 650  646  
 651  647          (void) mdb_tgt_getareg(MDB_NV_COOKIE(v), 0, mdb_nv_get_name(v), &r);
 652  648  
 653  649          return (r);
 654  650  }
 655  651  
 656  652  static void
 657  653  kmt_reg_disc_set(mdb_var_t *v, uintmax_t r)
 658  654  {
 659  655          if (mdb_tgt_putareg(MDB_NV_COOKIE(v), 0, mdb_nv_get_name(v), r) == -1)
 660  656                  warn("failed to modify %%%s register", mdb_nv_get_name(v));
 661  657  }
 662  658  
 663  659  static const mdb_nv_disc_t kmt_reg_disc = {
 664  660          kmt_reg_disc_set,
 665  661          kmt_reg_disc_get
 666  662  };
 667  663  
 668  664  /*ARGSUSED*/
 669  665  static int
 670  666  kmt_getareg(mdb_tgt_t *t, mdb_tgt_tid_t tid, const char *rname,
 671  667      mdb_tgt_reg_t *rp)
 672  668  {
 673  669          kreg_t val;
 674  670  
 675  671          if (kmdb_dpi_get_register(rname, &val) < 0)
 676  672                  return (set_errno(EMDB_BADREG));
 677  673  
 678  674          *rp = val;
 679  675          return (0);
 680  676  }
 681  677  
 682  678  /*ARGSUSED*/
 683  679  static int
 684  680  kmt_putareg(mdb_tgt_t *t, mdb_tgt_tid_t tid, const char *rname, mdb_tgt_reg_t r)
 685  681  {
 686  682          if (kmdb_dpi_set_register(rname, r) < 0)
 687  683                  return (set_errno(EMDB_BADREG));
 688  684  
 689  685          return (0);
 690  686  }
 691  687  
 692  688  static void
 693  689  kmt_mod_destroy(kmt_module_t *km)
 694  690  {
 695  691          if (km->km_name != NULL)
 696  692                  strfree(km->km_name);
 697  693          if (km->km_symtab != NULL)
 698  694                  mdb_gelf_symtab_destroy(km->km_symtab);
 699  695          if (km->km_ctfp != NULL)
 700  696                  mdb_ctf_close(km->km_ctfp);
 701  697  }
 702  698  
 703  699  static kmt_module_t *
 704  700  kmt_mod_create(mdb_tgt_t *t, struct modctl *ctlp, char *name)
 705  701  {
 706  702          kmt_module_t *km = mdb_zalloc(sizeof (kmt_module_t), UM_SLEEP);
 707  703          struct module *mod;
 708  704  
 709  705          km->km_name = mdb_alloc(strlen(name) + 1, UM_SLEEP);
 710  706          (void) strcpy(km->km_name, name);
 711  707  
 712  708          bcopy(ctlp, &km->km_modctl, sizeof (struct modctl));
 713  709  
 714  710          if (mdb_tgt_vread(t, &km->km_module, sizeof (struct module),
 715  711              (uintptr_t)km->km_modctl.mod_mp) != sizeof (struct module))
 716  712                  goto create_module_cleanup;
 717  713          mod = &km->km_module;
 718  714  
 719  715          if (mod->symhdr != NULL && mod->strhdr != NULL && mod->symtbl != NULL &&
 720  716              mod->strings != NULL) {
 721  717                  mdb_gelf_ehdr_to_gehdr(&mod->hdr, &km->km_ehdr);
 722  718  
 723  719                  km->km_symtab = mdb_gelf_symtab_create_raw(&km->km_ehdr,
 724  720                      mod->symhdr, mod->symtbl, mod->strhdr, mod->strings,
 725  721                      MDB_TGT_SYMTAB);
 726  722  
 727  723                  km->km_symtab_va = mod->symtbl;
 728  724                  km->km_strtab_va = mod->strings;
 729  725  
 730  726                  if (mdb_tgt_vread(t, &km->km_symtab_hdr, sizeof (Shdr),
 731  727                      (uintptr_t)mod->symhdr) != sizeof (Shdr) ||
 732  728                      mdb_tgt_vread(t, &km->km_strtab_hdr, sizeof (Shdr),
 733  729                      (uintptr_t)mod->strhdr) != sizeof (Shdr))
 734  730                          goto create_module_cleanup;
 735  731          }
 736  732  
 737  733          /*
 738  734           * We don't want everyone rooting around in the module structure, so we
 739  735           * make copies of the interesting members.
 740  736           */
 741  737          km->km_text_va = (uintptr_t)mod->text;
 742  738          km->km_text_size = mod->text_size;
 743  739          km->km_data_va = (uintptr_t)mod->data;
 744  740          km->km_data_size = mod->data_size;
 745  741          km->km_bss_va = (uintptr_t)mod->bss;
 746  742          km->km_bss_size = mod->bss_size;
 747  743          km->km_ctf_va = mod->ctfdata;
 748  744          km->km_ctf_size = mod->ctfsize;
 749  745  
 750  746          if (mod->flags & KOBJ_PRIM)
 751  747                  km->km_flags |= KM_F_PRIMARY;
 752  748  
 753  749          return (km);
 754  750  
 755  751  create_module_cleanup:
 756  752          warn("failed to read module %s\n", name);
 757  753          kmt_mod_destroy(km);
 758  754          return (NULL);
 759  755  }
 760  756  
 761  757  static void
 762  758  kmt_mod_remove(kmt_data_t *kmt, kmt_module_t *km)
 763  759  {
 764  760          mdb_var_t *v = mdb_nv_lookup(&kmt->kmt_modules, km->km_name);
 765  761  
 766  762          ASSERT(v != NULL);
 767  763  
 768  764          mdb_dprintf(MDB_DBG_KMOD, "removing module %s\n", km->km_name);
 769  765  
 770  766          mdb_list_delete(&kmt->kmt_modlist, km);
 771  767          mdb_nv_remove(&kmt->kmt_modules, v);
 772  768          kmt_mod_destroy(km);
 773  769  }
 774  770  
 775  771  static int
 776  772  kmt_modlist_update_cb(struct modctl *modp, void *arg)
 777  773  {
 778  774          mdb_tgt_t *t = arg;
 779  775          kmt_data_t *kmt = t->t_data;
 780  776          kmt_module_t *km;
 781  777          mdb_var_t *v;
 782  778          char name[MAXNAMELEN];
 783  779  
 784  780          if (mdb_tgt_readstr(t, MDB_TGT_AS_VIRT, name, MAXNAMELEN,
 785  781              (uintptr_t)modp->mod_modname) <= 0) {
 786  782                  warn("failed to read module name at %p",
 787  783                      (void *)modp->mod_modname);
 788  784          }
 789  785  
 790  786          /* We only care about modules that are actually loaded */
 791  787          if (!kmdb_kdi_mod_isloaded(modp))
 792  788                  return (0);
 793  789  
 794  790          /*
 795  791           * Skip the modules we already know about and that haven't
 796  792           * changed since last time we were here.
 797  793           */
 798  794          if ((v = mdb_nv_lookup(&kmt->kmt_modules, name)) != NULL) {
 799  795                  km = MDB_NV_COOKIE(v);
 800  796  
 801  797                  if (kmdb_kdi_mod_haschanged(&km->km_modctl, &km->km_module,
 802  798                      modp, modp->mod_mp)) {
 803  799                          /*
 804  800                           * The module has changed since last we saw it.  For
 805  801                           * safety, remove our old version, and treat it as a
 806  802                           * new module.
 807  803                           */
 808  804                          mdb_dprintf(MDB_DBG_KMOD, "stutter module %s\n", name);
 809  805                          kmt_mod_remove(kmt, km);
 810  806                  } else {
 811  807                          km->km_seen = 1;
 812  808                          return (0);
 813  809                  }
 814  810          }
 815  811  
 816  812          mdb_dprintf(MDB_DBG_KMOD, "found new module %s\n", name);
 817  813  
 818  814          if ((km = kmt_mod_create(t, modp, name)) != NULL) {
 819  815                  mdb_list_append(&kmt->kmt_modlist, km);
 820  816                  (void) mdb_nv_insert(&kmt->kmt_modules, name, NULL,
 821  817                      (uintptr_t)km, 0);
 822  818                  km->km_seen = 1;
 823  819          }
 824  820  
 825  821          return (0);
 826  822  }
 827  823  
 828  824  static void
 829  825  kmt_modlist_update(mdb_tgt_t *t)
 830  826  {
 831  827          kmt_data_t *kmt = t->t_data;
 832  828          kmt_module_t *km, *kmn;
 833  829  
 834  830          if (kmdb_kdi_mod_iter(kmt_modlist_update_cb, t) < 0) {
 835  831                  warn("failed to complete update of kernel module list\n");
 836  832                  return;
 837  833          }
 838  834  
 839  835          km = mdb_list_next(&kmt->kmt_modlist);
 840  836          while (km != NULL) {
 841  837                  kmn = mdb_list_next(km);
 842  838  
 843  839                  if (km->km_seen == 1) {
 844  840                          /* Reset the mark for next time */
 845  841                          km->km_seen = 0;
 846  842                  } else {
 847  843                          /*
 848  844                           * We didn't see it on the kernel's module list, so
 849  845                           * remove it from our view of the world.
 850  846                           */
 851  847                          kmt_mod_remove(kmt, km);
 852  848                  }
 853  849  
 854  850                  km = kmn;
 855  851          }
 856  852  }
 857  853  
 858  854  static void
 859  855  kmt_periodic(mdb_tgt_t *t)
 860  856  {
 861  857          (void) mdb_tgt_status(t, &t->t_status);
 862  858  }
 863  859  
 864  860  int
 865  861  kmt_lookup_by_addr(mdb_tgt_t *t, uintptr_t addr, uint_t flags,
 866  862      char *buf, size_t nbytes, GElf_Sym *symp, mdb_syminfo_t *sip)
 867  863  {
 868  864          kmt_data_t *kmt = t->t_data;
 869  865          kmt_module_t *km = mdb_list_next(&kmt->kmt_modlist);
 870  866          kmt_module_t *sym_km = NULL;
 871  867          kmt_module_t prmod;
 872  868          GElf_Sym sym;
 873  869          uint_t symid;
 874  870          const char *name;
 875  871  
 876  872          /*
 877  873           * We look through the private symbols (if any), then through the module
 878  874           * symbols.  We can simplify the loop if we pretend the private symbols
 879  875           * come from a module.
 880  876           */
 881  877          if (mdb.m_prsym != NULL) {
 882  878                  bzero(&prmod, sizeof (kmt_module_t));
 883  879                  prmod.km_name = "<<<prmod>>>";
 884  880                  prmod.km_symtab = mdb.m_prsym;
 885  881                  prmod.km_list.ml_next = (mdb_list_t *)km;
 886  882                  km = &prmod;
 887  883          }
 888  884  
 889  885          /* Symbol resolution isn't available during initialization */
 890  886          if (kmdb_dpi_get_state(NULL) == DPI_STATE_INIT)
 891  887                  return (set_errno(EMDB_NOSYM));
 892  888  
 893  889          for (; km != NULL; km = mdb_list_next(km)) {
 894  890                  if (km != &prmod && !kmt->kmt_symavail)
 895  891                          continue;
 896  892  
 897  893                  if (km->km_symtab == NULL)
 898  894                          continue;
 899  895  
 900  896                  if (mdb_gelf_symtab_lookup_by_addr(km->km_symtab, addr, flags,
 901  897                      buf, nbytes, symp, &sip->sym_id) != 0 ||
 902  898                      symp->st_value == 0)
 903  899                          continue;
 904  900  
 905  901                  if (flags & MDB_TGT_SYM_EXACT) {
 906  902                          sym_km = km;
 907  903                          goto found;
 908  904                  }
 909  905  
 910  906                  /*
 911  907                   * If this is the first match we've found, or if this symbol is
 912  908                   * closer to the specified address than the last one we found,
 913  909                   * use it.
 914  910                   */
 915  911                  if (sym_km == NULL || mdb_gelf_sym_closer(symp, &sym, addr)) {
 916  912                          sym_km = km;
 917  913                          sym = *symp;
 918  914                          symid = sip->sym_id;
 919  915                  }
 920  916          }
 921  917  
 922  918          /*
 923  919           * kmdb dmods are normal kernel modules, loaded by krtld as such.  To
 924  920           * avoid polluting modinfo, and to keep from confusing the module
 925  921           * subsystem (many dmods have the same names as real kernel modules),
 926  922           * kmdb keeps their modctls separate, and doesn't allow their loading
 927  923           * to be broadcast via the krtld module load/unload mechanism.  As a
 928  924           * result, kmdb_kvm doesn't find out about them, and can't turn their
 929  925           * addresses into symbols.  This can be most inconvenient during
 930  926           * debugger faults, as the dmod frames will show up without names.
 931  927           * We weren't able to turn the requested address into a symbol, so we'll
 932  928           * take a spin through the dmods, trying to match our address against
 933  929           * their symbols.
 934  930           */
 935  931          if (sym_km == NULL) {
 936  932                  return (kmdb_module_lookup_by_addr(addr, flags, buf, nbytes,
 937  933                      symp, sip));
 938  934          }
 939  935  
 940  936          *symp = sym;
 941  937          sip->sym_id = symid;
 942  938  
 943  939  found:
 944  940          /*
 945  941           * Once we've found something, copy the final name into the caller's
 946  942           * buffer and prefix it with the load object name if appropriate.
 947  943           */
 948  944          name = mdb_gelf_sym_name(sym_km->km_symtab, symp);
 949  945  
 950  946          if (sym_km == &prmod) {
 951  947                  if (buf != NULL) {
 952  948                          (void) strncpy(buf, name, nbytes);
 953  949                          buf[nbytes - 1] = '\0';
 954  950                  }
 955  951                  sip->sym_table = MDB_TGT_PRVSYM;
 956  952          } else {
 957  953                  if (buf != NULL) {
 958  954                          if (sym_km->km_flags & KM_F_PRIMARY) {
 959  955                                  (void) strncpy(buf, name, nbytes);
 960  956                                  buf[nbytes - 1] = '\0';
 961  957                          } else {
 962  958                                  (void) mdb_snprintf(buf, nbytes, "%s`%s",
 963  959                                      sym_km->km_name, name);
 964  960                          }
 965  961                  }
 966  962                  sip->sym_table = MDB_TGT_SYMTAB;
 967  963          }
 968  964  
 969  965          return (0);
 970  966  }
 971  967  
 972  968  static int
 973  969  kmt_lookup_by_name(mdb_tgt_t *t, const char *obj, const char *name,
 974  970      GElf_Sym *symp, mdb_syminfo_t *sip)
 975  971  {
 976  972          kmt_data_t *kmt = t->t_data;
 977  973          kmt_module_t *km;
 978  974          mdb_var_t *v;
 979  975          GElf_Sym sym;
 980  976          uint_t symid;
 981  977          int n;
 982  978  
 983  979          if (!kmt->kmt_symavail)
 984  980                  return (set_errno(EMDB_NOSYM));
 985  981  
 986  982          switch ((uintptr_t)obj) {
 987  983          case (uintptr_t)MDB_TGT_OBJ_EXEC:
 988  984          case (uintptr_t)MDB_TGT_OBJ_EVERY:
 989  985                  km = mdb_list_next(&kmt->kmt_modlist);
 990  986                  n = mdb_nv_size(&kmt->kmt_modules);
 991  987                  break;
 992  988  
 993  989          case (uintptr_t)MDB_TGT_OBJ_RTLD:
 994  990                  obj = kmt->kmt_rtld_name;
 995  991                  /*FALLTHROUGH*/
 996  992  
 997  993          default:
 998  994                  /*
 999  995                   * If this is a request for a dmod symbol, let kmdb_module
1000  996                   * handle it.
1001  997                   */
1002  998                  if (obj != NULL && strncmp(obj, "DMOD`", 5) == 0) {
1003  999                          return (kmdb_module_lookup_by_name(obj + 5, name,
1004 1000                              symp, sip));
1005 1001                  }
1006 1002  
1007 1003                  if ((v = mdb_nv_lookup(&kmt->kmt_modules, obj)) == NULL)
1008 1004                          return (set_errno(EMDB_NOOBJ));
1009 1005  
1010 1006                  km = mdb_nv_get_cookie(v);
1011 1007                  n = 1;
1012 1008          }
1013 1009  
1014 1010          /*
1015 1011           * kmdb's kvm target is at a bit of a disadvantage compared to mdb's
1016 1012           * kvm target when it comes to global symbol lookups.  mdb has ksyms,
1017 1013           * which hides pesky things like symbols that are undefined in unix,
1018 1014           * but which are defined in genunix.  We don't have such a facility -
1019 1015           * we simply iterate through the modules, looking for a given symbol
1020 1016           * in each.  Unless we're careful, we'll return the undef in the
1021 1017           * aforementioned case.
1022 1018           */
1023 1019          for (; n > 0; n--, km = mdb_list_next(km)) {
1024 1020                  if (mdb_gelf_symtab_lookup_by_name(km->km_symtab, name,
1025 1021                      &sym, &symid) == 0 && sym.st_shndx != SHN_UNDEF)
1026 1022                          break;
1027 1023          }
1028 1024  
1029 1025          if (n == 0)
1030 1026                  return (set_errno(EMDB_NOSYM));
1031 1027  
1032 1028  found:
1033 1029          bcopy(&sym, symp, sizeof (GElf_Sym));
1034 1030          sip->sym_id = symid;
1035 1031          sip->sym_table = MDB_TGT_SYMTAB;
1036 1032  
1037 1033          return (0);
1038 1034  }
1039 1035  
1040 1036  static int
1041 1037  kmt_symtab_func(void *data, const GElf_Sym *sym, const char *name, uint_t id)
1042 1038  {
1043 1039          kmt_symarg_t *arg = data;
1044 1040  
1045 1041          if (mdb_tgt_sym_match(sym, arg->sym_type)) {
1046 1042                  arg->sym_info.sym_id = id;
1047 1043  
1048 1044                  return (arg->sym_cb(arg->sym_data, sym, name, &arg->sym_info,
1049 1045                      arg->sym_obj));
1050 1046          }
1051 1047  
1052 1048          return (0);
1053 1049  }
1054 1050  
1055 1051  static void
1056 1052  kmt_symtab_iter(mdb_gelf_symtab_t *gst, uint_t type, const char *obj,
1057 1053      mdb_tgt_sym_f *cb, void *p)
1058 1054  {
1059 1055          kmt_symarg_t arg;
1060 1056  
1061 1057          arg.sym_cb = cb;
1062 1058          arg.sym_data = p;
1063 1059          arg.sym_type = type;
1064 1060          arg.sym_info.sym_table = gst->gst_tabid;
1065 1061          arg.sym_obj = obj;
1066 1062  
1067 1063          mdb_gelf_symtab_iter(gst, kmt_symtab_func, &arg);
1068 1064  }
1069 1065  
1070 1066  static int
1071 1067  kmt_symbol_iter(mdb_tgt_t *t, const char *obj, uint_t which, uint_t type,
1072 1068      mdb_tgt_sym_f *cb, void *data)
1073 1069  {
1074 1070          kmt_data_t *kmt = t->t_data;
1075 1071          kmt_module_t *km;
1076 1072  
1077 1073          mdb_gelf_symtab_t *symtab = NULL;
1078 1074          mdb_var_t *v;
1079 1075  
1080 1076          if (which == MDB_TGT_DYNSYM)
1081 1077                  return (set_errno(EMDB_TGTNOTSUP));
1082 1078  
1083 1079          switch ((uintptr_t)obj) {
1084 1080          case (uintptr_t)MDB_TGT_OBJ_EXEC:
1085 1081          case (uintptr_t)MDB_TGT_OBJ_EVERY:
1086 1082                  mdb_nv_rewind(&kmt->kmt_modules);
1087 1083                  while ((v = mdb_nv_advance(&kmt->kmt_modules)) != NULL) {
1088 1084                          km = mdb_nv_get_cookie(v);
1089 1085  
1090 1086                          if (km->km_symtab != NULL) {
1091 1087                                  kmt_symtab_iter(km->km_symtab, type,
1092 1088                                      km->km_name, cb, data);
1093 1089                          }
1094 1090                  }
1095 1091                  return (0);
1096 1092  
1097 1093          case (uintptr_t)MDB_TGT_OBJ_RTLD:
1098 1094                  obj = kmt->kmt_rtld_name;
1099 1095                  /*FALLTHROUGH*/
1100 1096  
1101 1097          default:
1102 1098                  if (strncmp(obj, "DMOD`", 5) == 0) {
1103 1099                          return (kmdb_module_symbol_iter(obj + 5, type,
1104 1100                              cb, data));
1105 1101                  }
1106 1102  
1107 1103                  if ((v = mdb_nv_lookup(&kmt->kmt_modules, obj)) == NULL)
1108 1104                          return (set_errno(EMDB_NOOBJ));
1109 1105                  km = mdb_nv_get_cookie(v);
1110 1106  
1111 1107                  symtab = km->km_symtab;
1112 1108          }
1113 1109  
1114 1110          if (symtab != NULL)
1115 1111                  kmt_symtab_iter(symtab, type, obj, cb, data);
1116 1112  
1117 1113          return (0);
1118 1114  }
1119 1115  
1120 1116  static int
1121 1117  kmt_mapping_walk(uintptr_t addr, const void *data, kmt_maparg_t *marg)
1122 1118  {
1123 1119          /*
1124 1120           * This is a bit sketchy but avoids problematic compilation of this
1125 1121           * target against the current VM implementation.  Now that we have
1126 1122           * vmem, we can make this less broken and more informative by changing
1127 1123           * this code to invoke the vmem walker in the near future.
1128 1124           */
1129 1125          const struct kmt_seg {
1130 1126                  caddr_t s_base;
1131 1127                  size_t s_size;
1132 1128          } *segp = (const struct kmt_seg *)data;
1133 1129  
1134 1130          mdb_map_t map;
1135 1131          GElf_Sym sym;
1136 1132          mdb_syminfo_t info;
1137 1133  
1138 1134          map.map_base = (uintptr_t)segp->s_base;
1139 1135          map.map_size = segp->s_size;
1140 1136          map.map_flags = MDB_TGT_MAP_R | MDB_TGT_MAP_W | MDB_TGT_MAP_X;
1141 1137  
1142 1138          if (kmt_lookup_by_addr(marg->map_target, addr, MDB_TGT_SYM_EXACT,
1143 1139              map.map_name, MDB_TGT_MAPSZ, &sym, &info) == -1) {
1144 1140  
1145 1141                  (void) mdb_iob_snprintf(map.map_name, MDB_TGT_MAPSZ,
1146 1142                      "%lr", addr);
1147 1143          }
1148 1144  
1149 1145          return (marg->map_cb(marg->map_data, &map, map.map_name));
1150 1146  }
1151 1147  
1152 1148  static int
1153 1149  kmt_mapping_iter(mdb_tgt_t *t, mdb_tgt_map_f *func, void *private)
1154 1150  {
1155 1151          kmt_maparg_t m;
1156 1152          uintptr_t kas;
1157 1153  
1158 1154          m.map_target = t;
1159 1155          m.map_cb = func;
1160 1156          m.map_data = private;
1161 1157  
1162 1158          if ((kas = kmt_read_kas(t)) == NULL)
1163 1159                  return (-1); /* errno is set for us */
1164 1160  
1165 1161          return (mdb_pwalk("seg", (mdb_walk_cb_t)kmt_mapping_walk, &m, kas));
1166 1162  }
1167 1163  
1168 1164  static const mdb_map_t *
1169 1165  kmt_mod_to_map(kmt_module_t *km, mdb_map_t *map)
1170 1166  {
1171 1167          (void) strncpy(map->map_name, km->km_name, MDB_TGT_MAPSZ);
1172 1168          map->map_name[MDB_TGT_MAPSZ - 1] = '\0';
1173 1169          map->map_base = km->km_text_va;
1174 1170          map->map_size = km->km_text_size;
1175 1171          map->map_flags = MDB_TGT_MAP_R | MDB_TGT_MAP_W | MDB_TGT_MAP_X;
1176 1172  
1177 1173          return (map);
1178 1174  }
1179 1175  
1180 1176  static int
1181 1177  kmt_object_iter(mdb_tgt_t *t, mdb_tgt_map_f *func, void *private)
1182 1178  {
1183 1179          kmt_data_t *kmt = t->t_data;
1184 1180          kmt_module_t *km;
1185 1181          mdb_map_t m;
1186 1182  
1187 1183          for (km = mdb_list_next(&kmt->kmt_modlist); km != NULL;
1188 1184              km = mdb_list_next(km)) {
1189 1185                  if (func(private, kmt_mod_to_map(km, &m), km->km_name) == -1)
1190 1186                          break;
1191 1187          }
1192 1188  
1193 1189          return (0);
1194 1190  }
1195 1191  
1196 1192  static const mdb_map_t *
1197 1193  kmt_addr_to_map(mdb_tgt_t *t, uintptr_t addr)
1198 1194  {
1199 1195          kmt_data_t *kmt = t->t_data;
1200 1196          kmt_module_t *km;
1201 1197  
1202 1198          for (km = mdb_list_next(&kmt->kmt_modlist); km != NULL;
1203 1199              km = mdb_list_next(km)) {
1204 1200                  if (addr - km->km_text_va < km->km_text_size ||
1205 1201                      addr - km->km_data_va < km->km_data_size ||
1206 1202                      addr - km->km_bss_va < km->km_bss_size)
1207 1203                          return (kmt_mod_to_map(km, &kmt->kmt_map));
1208 1204          }
1209 1205  
1210 1206          (void) set_errno(EMDB_NOMAP);
1211 1207          return (NULL);
1212 1208  }
1213 1209  
1214 1210  static kmt_module_t *
1215 1211  kmt_module_by_name(kmt_data_t *kmt, const char *name)
1216 1212  {
1217 1213          kmt_module_t *km;
1218 1214  
1219 1215          for (km = mdb_list_next(&kmt->kmt_modlist); km != NULL;
1220 1216              km = mdb_list_next(km)) {
1221 1217                  if (strcmp(name, km->km_name) == 0)
1222 1218                          return (km);
1223 1219          }
1224 1220  
1225 1221          return (NULL);
1226 1222  }
1227 1223  
1228 1224  static const mdb_map_t *
1229 1225  kmt_name_to_map(mdb_tgt_t *t, const char *name)
1230 1226  {
1231 1227          kmt_data_t *kmt = t->t_data;
1232 1228          kmt_module_t *km;
1233 1229          mdb_map_t m;
1234 1230  
1235 1231          /*
1236 1232           * If name is MDB_TGT_OBJ_EXEC, return the first module on the list,
1237 1233           * which will be unix since we keep kmt_modlist in load order.
1238 1234           */
1239 1235          if (name == MDB_TGT_OBJ_EXEC) {
1240 1236                  return (kmt_mod_to_map(mdb_list_next(&kmt->kmt_modlist),
1241 1237                      &m));
1242 1238          }
1243 1239  
1244 1240          if (name == MDB_TGT_OBJ_RTLD)
1245 1241                  name = kmt->kmt_rtld_name;
1246 1242  
1247 1243          if ((km = kmt_module_by_name(kmt, name)) != NULL)
1248 1244                  return (kmt_mod_to_map(km, &m));
1249 1245  
1250 1246          (void) set_errno(EMDB_NOOBJ);
1251 1247          return (NULL);
1252 1248  }
1253 1249  
1254 1250  static ctf_file_t *
1255 1251  kmt_load_ctfdata(mdb_tgt_t *t, kmt_module_t *km)
1256 1252  {
1257 1253          kmt_data_t *kmt = t->t_data;
1258 1254          int err;
1259 1255  
1260 1256          if (km->km_ctfp != NULL)
1261 1257                  return (km->km_ctfp);
1262 1258  
1263 1259          if (km->km_ctf_va == NULL || km->km_symtab == NULL) {
1264 1260                  (void) set_errno(EMDB_NOCTF);
1265 1261                  return (NULL);
1266 1262          }
1267 1263  
1268 1264          if ((km->km_ctfp = mdb_ctf_bufopen(km->km_ctf_va, km->km_ctf_size,
1269 1265              km->km_symtab_va, &km->km_symtab_hdr, km->km_strtab_va,
1270 1266              &km->km_strtab_hdr, &err)) == NULL) {
1271 1267                  (void) set_errno(ctf_to_errno(err));
1272 1268                  return (NULL);
1273 1269          }
1274 1270  
1275 1271          mdb_dprintf(MDB_DBG_KMOD, "loaded %lu bytes of CTF data for %s\n",
1276 1272              (ulong_t)km->km_ctf_size, km->km_name);
1277 1273  
1278 1274          if (ctf_parent_name(km->km_ctfp) != NULL) {
1279 1275                  mdb_var_t *v;
1280 1276  
1281 1277                  if ((v = mdb_nv_lookup(&kmt->kmt_modules,
1282 1278                      ctf_parent_name(km->km_ctfp))) != NULL) {
1283 1279                          kmt_module_t *pm = mdb_nv_get_cookie(v);
1284 1280  
1285 1281                          if (pm->km_ctfp == NULL)
1286 1282                                  (void) kmt_load_ctfdata(t, pm);
1287 1283  
1288 1284                          if (pm->km_ctfp != NULL && ctf_import(km->km_ctfp,
1289 1285                              pm->km_ctfp) == CTF_ERR) {
1290 1286                                  warn("failed to import parent types into "
1291 1287                                      "%s: %s\n", km->km_name,
1292 1288                                      ctf_errmsg(ctf_errno(km->km_ctfp)));
1293 1289                          }
1294 1290                  } else {
1295 1291                          warn("failed to load CTF data for %s - parent %s not "
1296 1292                              "loaded\n", km->km_name,
1297 1293                              ctf_parent_name(km->km_ctfp));
1298 1294                  }
1299 1295          }
1300 1296  
1301 1297          return (km->km_ctfp);
1302 1298  }
1303 1299  
1304 1300  ctf_file_t *
1305 1301  kmt_addr_to_ctf(mdb_tgt_t *t, uintptr_t addr)
1306 1302  {
1307 1303          kmt_data_t *kmt = t->t_data;
1308 1304          kmt_module_t *km;
1309 1305  
1310 1306          for (km = mdb_list_next(&kmt->kmt_modlist); km != NULL;
1311 1307              km = mdb_list_next(km)) {
1312 1308                  if (addr - km->km_text_va < km->km_text_size ||
1313 1309                      addr - km->km_data_va < km->km_data_size ||
1314 1310                      addr - km->km_bss_va < km->km_bss_size)
1315 1311                          return (kmt_load_ctfdata(t, km));
1316 1312          }
1317 1313  
1318 1314          return (kmdb_module_addr_to_ctf(addr));
1319 1315  }
1320 1316  
1321 1317  ctf_file_t *
1322 1318  kmt_name_to_ctf(mdb_tgt_t *t, const char *name)
1323 1319  {
1324 1320          kmt_data_t *kt = t->t_data;
1325 1321          kmt_module_t *km;
1326 1322  
1327 1323          if (name == MDB_TGT_OBJ_EXEC) {
1328 1324                  name = KMT_CTFPARENT;
1329 1325          } else if (name == MDB_TGT_OBJ_RTLD) {
1330 1326                  name = kt->kmt_rtld_name;
1331 1327          } else if (strncmp(name, "DMOD`", 5) == 0) {
1332 1328                  /* Request for CTF data for a DMOD symbol */
1333 1329                  return (kmdb_module_name_to_ctf(name + 5));
1334 1330          }
1335 1331  
1336 1332          if ((km = kmt_module_by_name(kt, name)) != NULL)
1337 1333                  return (kmt_load_ctfdata(t, km));
1338 1334  
1339 1335          (void) set_errno(EMDB_NOOBJ);
1340 1336          return (NULL);
1341 1337  }
1342 1338  
1343 1339  /*ARGSUSED*/
1344 1340  static int
1345 1341  kmt_status(mdb_tgt_t *t, mdb_tgt_status_t *tsp)
1346 1342  {
1347 1343          int state;
1348 1344  
1349 1345          bzero(tsp, sizeof (mdb_tgt_status_t));
1350 1346  
1351 1347          switch ((state = kmdb_dpi_get_state(NULL))) {
1352 1348          case DPI_STATE_INIT:
1353 1349                  tsp->st_state = MDB_TGT_RUNNING;
1354 1350                  tsp->st_pc = 0;
1355 1351                  break;
1356 1352  
1357 1353          case DPI_STATE_STOPPED:
1358 1354                  tsp->st_state = MDB_TGT_STOPPED;
1359 1355  
1360 1356                  (void) kmdb_dpi_get_register("pc", &tsp->st_pc);
1361 1357                  break;
1362 1358  
1363 1359          case DPI_STATE_FAULTED:
1364 1360                  tsp->st_state = MDB_TGT_STOPPED;
1365 1361  
1366 1362                  (void) kmdb_dpi_get_register("pc", &tsp->st_pc);
1367 1363  
1368 1364                  tsp->st_flags |= MDB_TGT_ISTOP;
1369 1365                  break;
1370 1366  
1371 1367          case DPI_STATE_LOST:
1372 1368                  tsp->st_state = MDB_TGT_LOST;
1373 1369  
1374 1370                  (void) kmdb_dpi_get_register("pc", &tsp->st_pc);
1375 1371                  break;
1376 1372          }
1377 1373  
1378 1374          mdb_dprintf(MDB_DBG_KMOD, "kmt_status, dpi: %d tsp: %d, pc = %p %A\n",
1379 1375              state, tsp->st_state, (void *)tsp->st_pc, tsp->st_pc);
1380 1376  
1381 1377          return (0);
1382 1378  }
1383 1379  
1384 1380  /*
1385 1381   * Invoked when kmt_defbp_enter_debugger is called, this routine activates and
1386 1382   * deactivates deferred breakpoints in response to module load and unload
1387 1383   * events.
1388 1384   */
1389 1385  /*ARGSUSED*/
1390 1386  static void
1391 1387  kmt_defbp_event(mdb_tgt_t *t, int vid, void *private)
1392 1388  {
1393 1389          if (kmt_defbp_modchg_isload) {
1394 1390                  if (!mdb_tgt_sespec_activate_all(t) &&
1395 1391                      (mdb.m_flags & MDB_FL_BPTNOSYMSTOP)) {
1396 1392                          /*
1397 1393                           * We weren't able to activate the breakpoints.
1398 1394                           * If so requested, we'll return without calling
1399 1395                           * continue, thus throwing the user into the debugger.
1400 1396                           */
1401 1397                          return;
1402 1398                  }
1403 1399  
1404 1400          } else {
1405 1401                  mdb_sespec_t *sep, *nsep;
1406 1402                  const mdb_map_t *map, *bpmap;
1407 1403                  mdb_map_t modmap;
1408 1404  
1409 1405                  if ((map = kmt_addr_to_map(t,
1410 1406                      (uintptr_t)kmt_defbp_modchg_modctl->mod_text)) == NULL) {
1411 1407                          warn("module unload notification for unknown module %s",
1412 1408                              kmt_defbp_modchg_modctl->mod_modname);
1413 1409                          return; /* drop into the debugger */
1414 1410                  }
1415 1411  
1416 1412                  bcopy(map, &modmap, sizeof (mdb_map_t));
1417 1413  
1418 1414                  for (sep = mdb_list_next(&t->t_active); sep; sep = nsep) {
1419 1415                          nsep = mdb_list_next(sep);
1420 1416  
1421 1417                          if (sep->se_ops == &kmt_brkpt_ops) {
1422 1418                                  kmt_brkpt_t *kb = sep->se_data;
1423 1419  
1424 1420                                  if ((bpmap = kmt_addr_to_map(t,
1425 1421                                      kb->kb_addr)) == NULL ||
1426 1422                                      (bpmap->map_base == modmap.map_base &&
1427 1423                                      bpmap->map_size == modmap.map_size)) {
1428 1424                                          mdb_tgt_sespec_idle_one(t, sep,
1429 1425                                              EMDB_NOMAP);
1430 1426                                  }
1431 1427                          }
1432 1428                  }
1433 1429          }
1434 1430  
1435 1431          (void) mdb_tgt_continue(t, NULL);
1436 1432  }
1437 1433  
1438 1434  static void
1439 1435  kmt_defbp_enter_debugger(void)
1440 1436  {
1441 1437          /*
1442 1438           * The debugger places a breakpoint here.  We can't have a simple
1443 1439           * nop function here, because GCC knows much more than we do, and
1444 1440           * will optimize away the call to it.
1445 1441           */
1446 1442          (void) get_fp();
1447 1443  }
1448 1444  
1449 1445  /*
1450 1446   * This routine is called while the kernel is running.  It attempts to determine
1451 1447   * whether any deferred breakpoints exist for the module being changed (loaded
1452 1448   * or unloaded).  If any such breakpoints exist, the debugger will be entered to
1453 1449   * process them.
1454 1450   */
1455 1451  static void
1456 1452  kmt_defbp_modchg(struct modctl *mctl, int isload)
1457 1453  {
1458 1454          kmt_defbp_t *dbp;
1459 1455  
1460 1456          kmt_defbp_lock = 1;
1461 1457  
1462 1458          for (dbp = mdb_list_next(&kmt_defbp_list); dbp;
1463 1459              dbp = mdb_list_next(dbp)) {
1464 1460                  if (!dbp->dbp_ref)
1465 1461                          continue;
1466 1462  
1467 1463                  if (strcmp(mctl->mod_modname, dbp->dbp_objname) == 0) {
1468 1464                          /*
1469 1465                           * Activate the breakpoint
1470 1466                           */
1471 1467                          kmt_defbp_modchg_isload = isload;
1472 1468                          kmt_defbp_modchg_modctl = mctl;
1473 1469  
1474 1470                          kmt_defbp_enter_debugger();
1475 1471                          break;
1476 1472                  }
1477 1473          }
1478 1474  
1479 1475          kmt_defbp_lock = 0;
1480 1476  }
1481 1477  
1482 1478  /*ARGSUSED*/
1483 1479  static int
1484 1480  kmt_continue(mdb_tgt_t *t, mdb_tgt_status_t *tsp)
1485 1481  {
1486 1482          int n;
1487 1483  
1488 1484          kmdb_dpi_resume();
1489 1485  
1490 1486          /*
1491 1487           * The order of the following two calls is important.  If there are
1492 1488           * load acks on the work queue, we'll initialize the dmods they
1493 1489           * represent.  This will involve a call to _mdb_init, which may very
1494 1490           * well result in a symbol lookup.  If we haven't resynced our view
1495 1491           * of symbols with the current state of the world, this lookup could
1496 1492           * end very badly.  We therefore make sure to sync before processing
1497 1493           * the work queue.
1498 1494           */
1499 1495          kmt_sync(t);
1500 1496          kmdb_dpi_process_work_queue();
1501 1497  
1502 1498          if (kmdb_kdi_get_unload_request())
1503 1499                  t->t_flags |= MDB_TGT_F_UNLOAD;
1504 1500  
1505 1501          (void) mdb_tgt_status(t, &t->t_status);
1506 1502  
1507 1503          if ((n = kmt_dmod_status(NULL, KMDB_MC_STATE_LOADING) +
1508 1504              kmt_dmod_status(NULL, KMDB_MC_STATE_UNLOADING)) != 0) {
1509 1505                  mdb_warn("%d dmod load%c/unload%c pending\n", n,
1510 1506                      "s"[n == 1], "s"[n == 1]);
1511 1507          }
1512 1508  
1513 1509          return (0);
1514 1510  }
1515 1511  
1516 1512  /*ARGSUSED*/
1517 1513  static int
1518 1514  kmt_step(mdb_tgt_t *t, mdb_tgt_status_t *tsp)
1519 1515  {
1520 1516          int rc;
1521 1517  
1522 1518          if ((rc = kmdb_dpi_step()) == 0)
1523 1519                  (void) mdb_tgt_status(t, &t->t_status);
1524 1520  
1525 1521          return (rc);
1526 1522  }
1527 1523  
1528 1524  static int
1529 1525  kmt_defbp_activate(mdb_tgt_t *t)
1530 1526  {
1531 1527          kmdb_dpi_modchg_register(kmt_defbp_modchg);
1532 1528  
1533 1529          /*
1534 1530           * The routines that add and arm breakpoints will check for the proper
1535 1531           * DTrace state, but they'll just put this breakpoint on the idle list
1536 1532           * if DTrace is active.  It'll correctly move to the active list when
1537 1533           * DTrace deactivates, but that's insufficient for our purposes -- we
1538 1534           * need to do extra processing at that point.  We won't get to do said
1539 1535           * processing with with a normal idle->active transition, so we just
1540 1536           * won't add it add it until we're sure that it'll stick.
1541 1537           */
1542 1538  
1543 1539          if (kmdb_kdi_dtrace_get_state() == KDI_DTSTATE_DTRACE_ACTIVE)
1544 1540                  return (set_errno(EMDB_DTACTIVE));
1545 1541  
1546 1542          kmt_defbp_bpspec = mdb_tgt_add_vbrkpt(t,
1547 1543              (uintptr_t)kmt_defbp_enter_debugger,
1548 1544              MDB_TGT_SPEC_HIDDEN, kmt_defbp_event, NULL);
1549 1545  
1550 1546          return (0);
1551 1547  }
1552 1548  
1553 1549  static void
1554 1550  kmt_defbp_deactivate(mdb_tgt_t *t)
1555 1551  {
1556 1552          kmdb_dpi_modchg_cancel();
1557 1553  
1558 1554          if (kmt_defbp_bpspec != 0) {
1559 1555                  if (t != NULL)
1560 1556                          (void) mdb_tgt_vespec_delete(t, kmt_defbp_bpspec);
1561 1557  
1562 1558                  kmt_defbp_bpspec = 0;
1563 1559          }
1564 1560  }
1565 1561  
1566 1562  static kmt_defbp_t *
1567 1563  kmt_defbp_create(mdb_tgt_t *t, const char *objname, const char *symname)
1568 1564  {
1569 1565          kmt_defbp_t *dbp = mdb_alloc(sizeof (kmt_defbp_t), UM_SLEEP);
1570 1566  
1571 1567          mdb_dprintf(MDB_DBG_KMOD, "defbp_create %s`%s\n", objname, symname);
1572 1568  
1573 1569          dbp->dbp_objname = strdup(objname);
1574 1570          dbp->dbp_symname = strdup(symname);
1575 1571          dbp->dbp_ref = 1;
1576 1572  
1577 1573          kmt_defbp_num++;
1578 1574  
1579 1575          if (kmt_defbp_num == 1 || kmt_defbp_bpspec == 0) {
1580 1576                  if (kmt_defbp_activate(t) < 0)
1581 1577                          warn("failed to activate deferred breakpoints");
1582 1578          }
1583 1579  
1584 1580          mdb_list_append(&kmt_defbp_list, dbp);
1585 1581  
1586 1582          return (dbp);
1587 1583  }
1588 1584  
1589 1585  static void
1590 1586  kmt_defbp_destroy(kmt_defbp_t *dbp)
1591 1587  {
1592 1588          mdb_dprintf(MDB_DBG_KMOD, "defbp_destroy %s`%s\n", dbp->dbp_objname,
1593 1589              dbp->dbp_symname);
1594 1590  
1595 1591          mdb_list_delete(&kmt_defbp_list, dbp);
1596 1592  
1597 1593          strfree(dbp->dbp_objname);
1598 1594          strfree(dbp->dbp_symname);
1599 1595          mdb_free(dbp, sizeof (kmt_defbp_t));
1600 1596  }
1601 1597  
1602 1598  static void
1603 1599  kmt_defbp_prune_common(int all)
1604 1600  {
1605 1601          kmt_defbp_t *dbp, *ndbp;
1606 1602  
1607 1603          /* We can't remove items from the list while the driver is using it. */
1608 1604          if (kmt_defbp_lock)
1609 1605                  return;
1610 1606  
1611 1607          for (dbp = mdb_list_next(&kmt_defbp_list); dbp != NULL; dbp = ndbp) {
1612 1608                  ndbp = mdb_list_next(dbp);
1613 1609  
1614 1610                  if (!all && dbp->dbp_ref)
1615 1611                          continue;
1616 1612  
1617 1613                  kmt_defbp_destroy(dbp);
1618 1614          }
1619 1615  }
1620 1616  
1621 1617  static void
1622 1618  kmt_defbp_prune(void)
1623 1619  {
1624 1620          kmt_defbp_prune_common(0);
1625 1621  }
1626 1622  
1627 1623  static void
1628 1624  kmt_defbp_destroy_all(void)
1629 1625  {
1630 1626          kmt_defbp_prune_common(1);
1631 1627  }
1632 1628  
1633 1629  static void
1634 1630  kmt_defbp_delete(mdb_tgt_t *t, kmt_defbp_t *dbp)
1635 1631  {
1636 1632          dbp->dbp_ref = 0;
1637 1633  
1638 1634          ASSERT(kmt_defbp_num > 0);
1639 1635          kmt_defbp_num--;
1640 1636  
1641 1637          if (kmt_defbp_num == 0)
1642 1638                  kmt_defbp_deactivate(t);
1643 1639  
1644 1640          kmt_defbp_prune();
1645 1641  }
1646 1642  
1647 1643  static int
1648 1644  kmt_brkpt_ctor(mdb_tgt_t *t, mdb_sespec_t *sep, void *args)
1649 1645  {
1650 1646          mdb_tgt_status_t tsp;
1651 1647          kmt_bparg_t *ka = args;
1652 1648          kmt_brkpt_t *kb;
1653 1649          GElf_Sym s;
1654 1650          mdb_instr_t instr;
1655 1651  
1656 1652          (void) mdb_tgt_status(t, &tsp);
1657 1653          if (tsp.st_state != MDB_TGT_RUNNING && tsp.st_state != MDB_TGT_STOPPED)
1658 1654                  return (set_errno(EMDB_NOPROC));
1659 1655  
1660 1656          if (ka->ka_symbol != NULL) {
1661 1657                  if (mdb_tgt_lookup_by_scope(t, ka->ka_symbol, &s, NULL) == -1) {
1662 1658                          if (errno != EMDB_NOOBJ && !(errno == EMDB_NOSYM &&
1663 1659                              !(mdb.m_flags & MDB_FL_BPTNOSYMSTOP))) {
1664 1660                                  warn("breakpoint %s activation failed",
1665 1661                                      ka->ka_symbol);
1666 1662                          }
1667 1663                          return (-1); /* errno is set for us */
1668 1664                  }
1669 1665  
1670 1666                  ka->ka_addr = (uintptr_t)s.st_value;
1671 1667          }
1672 1668  
1673 1669  #ifdef __sparc
1674 1670          if (ka->ka_addr & 3)
1675 1671                  return (set_errno(EMDB_BPALIGN));
1676 1672  #endif
1677 1673  
1678 1674          if (mdb_vread(&instr, sizeof (instr), ka->ka_addr) != sizeof (instr))
1679 1675                  return (-1); /* errno is set for us */
1680 1676  
1681 1677          if (kmdb_kdi_dtrace_get_state() == KDI_DTSTATE_DTRACE_ACTIVE)
1682 1678                  warn("breakpoint will not arm until DTrace is inactive\n");
1683 1679  
1684 1680          kb = mdb_zalloc(sizeof (kmt_brkpt_t), UM_SLEEP);
1685 1681          kb->kb_addr = ka->ka_addr;
1686 1682          sep->se_data = kb;
1687 1683  
1688 1684          return (0);
1689 1685  }
1690 1686  
1691 1687  /*ARGSUSED*/
1692 1688  static void
1693 1689  kmt_brkpt_dtor(mdb_tgt_t *t, mdb_sespec_t *sep)
1694 1690  {
1695 1691          mdb_free(sep->se_data, sizeof (kmt_brkpt_t));
1696 1692  }
1697 1693  
1698 1694  /*ARGSUSED*/
1699 1695  static char *
1700 1696  kmt_brkpt_info(mdb_tgt_t *t, mdb_sespec_t *sep, mdb_vespec_t *vep,
1701 1697      mdb_tgt_spec_desc_t *sp, char *buf, size_t nbytes)
1702 1698  {
1703 1699          uintptr_t addr = NULL;
1704 1700  
1705 1701          if (vep != NULL) {
1706 1702                  kmt_bparg_t *ka = vep->ve_args;
1707 1703  
1708 1704                  if (ka->ka_symbol != NULL) {
1709 1705                          (void) mdb_iob_snprintf(buf, nbytes, "stop at %s",
1710 1706                              ka->ka_symbol);
1711 1707                  } else {
1712 1708                          (void) mdb_iob_snprintf(buf, nbytes, "stop at %a",
1713 1709                              ka->ka_addr);
1714 1710                          addr = ka->ka_addr;
1715 1711                  }
1716 1712  
1717 1713          } else {
1718 1714                  addr = ((kmt_brkpt_t *)sep->se_data)->kb_addr;
1719 1715                  (void) mdb_iob_snprintf(buf, nbytes, "stop at %a", addr);
1720 1716          }
1721 1717  
1722 1718          sp->spec_base = addr;
1723 1719          sp->spec_size = sizeof (mdb_instr_t);
1724 1720  
1725 1721          return (buf);
1726 1722  }
1727 1723  
1728 1724  static int
1729 1725  kmt_brkpt_secmp(mdb_tgt_t *t, mdb_sespec_t *sep, void *args)
1730 1726  {
1731 1727          kmt_brkpt_t *kb = sep->se_data;
1732 1728          kmt_bparg_t *ka = args;
1733 1729          GElf_Sym sym;
1734 1730  
1735 1731          if (ka->ka_symbol != NULL) {
1736 1732                  return (mdb_tgt_lookup_by_scope(t, ka->ka_symbol,
1737 1733                      &sym, NULL) == 0 && sym.st_value == kb->kb_addr);
1738 1734          }
1739 1735  
1740 1736          return (ka->ka_addr == kb->kb_addr);
1741 1737  }
1742 1738  
1743 1739  /*ARGSUSED*/
1744 1740  static int
1745 1741  kmt_brkpt_vecmp(mdb_tgt_t *t, mdb_vespec_t *vep, void *args)
1746 1742  {
1747 1743          kmt_bparg_t *ka1 = vep->ve_args;
1748 1744          kmt_bparg_t *ka2 = args;
1749 1745  
1750 1746          if (ka1->ka_symbol != NULL && ka2->ka_symbol != NULL)
1751 1747                  return (strcmp(ka1->ka_symbol, ka2->ka_symbol) == 0);
1752 1748  
1753 1749          if (ka1->ka_symbol == NULL && ka2->ka_symbol == NULL)
1754 1750                  return (ka1->ka_addr == ka2->ka_addr);
1755 1751  
1756 1752          return (0); /* fail if one is symbolic, other is an explicit address */
1757 1753  }
1758 1754  
1759 1755  static int
1760 1756  kmt_brkpt_arm(mdb_tgt_t *t, mdb_sespec_t *sep)
1761 1757  {
1762 1758          kmt_data_t *kmt = t->t_data;
1763 1759          kmt_brkpt_t *kb = sep->se_data;
1764 1760          int rv;
1765 1761  
1766 1762          if (kmdb_kdi_dtrace_get_state() == KDI_DTSTATE_DTRACE_ACTIVE)
1767 1763                  return (set_errno(EMDB_DTACTIVE));
1768 1764  
1769 1765          if ((rv = kmdb_dpi_brkpt_arm(kb->kb_addr, &kb->kb_oinstr)) != 0)
1770 1766                  return (rv);
1771 1767  
1772 1768          if (kmt->kmt_narmedbpts++ == 0)
1773 1769                  (void) kmdb_kdi_dtrace_set(KDI_DTSET_KMDB_BPT_ACTIVATE);
1774 1770  
1775 1771          return (0);
1776 1772  }
1777 1773  
1778 1774  static int
1779 1775  kmt_brkpt_disarm(mdb_tgt_t *t, mdb_sespec_t *sep)
1780 1776  {
1781 1777          kmt_data_t *kmt = t->t_data;
1782 1778          kmt_brkpt_t *kb = sep->se_data;
1783 1779          int rv;
1784 1780  
1785 1781          ASSERT(kmdb_kdi_dtrace_get_state() == KDI_DTSTATE_KMDB_BPT_ACTIVE);
1786 1782  
1787 1783          if ((rv = kmdb_dpi_brkpt_disarm(kb->kb_addr, kb->kb_oinstr)) != 0)
1788 1784                  return (rv);
1789 1785  
1790 1786          if (--kmt->kmt_narmedbpts == 0)
1791 1787                  (void) kmdb_kdi_dtrace_set(KDI_DTSET_KMDB_BPT_DEACTIVATE);
1792 1788  
1793 1789          return (0);
1794 1790  }
1795 1791  
1796 1792  /*
1797 1793   * Determine whether the specified sespec is an armed watchpoint that overlaps
1798 1794   * with the given breakpoint and has the given flags set.  We use this to find
1799 1795   * conflicts with breakpoints, below.
1800 1796   */
1801 1797  static int
1802 1798  kmt_wp_overlap(mdb_sespec_t *sep, kmt_brkpt_t *kb, int flags)
1803 1799  {
1804 1800          const kmdb_wapt_t *wp = sep->se_data;
1805 1801  
1806 1802          return (sep->se_state == MDB_TGT_SPEC_ARMED &&
1807 1803              sep->se_ops == &kmt_wapt_ops && (wp->wp_wflags & flags) &&
1808 1804              kb->kb_addr - wp->wp_addr < wp->wp_size);
1809 1805  }
1810 1806  
1811 1807  /*
1812 1808   * We step over breakpoints using our single-stepper.  If a conflicting
1813 1809   * watchpoint is present, we must temporarily remove it before stepping over the
1814 1810   * breakpoint so we don't immediately re-trigger the watchpoint.  We know the
1815 1811   * watchpoint has already triggered on our trap instruction as part of fetching
1816 1812   * it.  Before we return, we must re-install any disabled watchpoints.
1817 1813   */
1818 1814  static int
1819 1815  kmt_brkpt_cont(mdb_tgt_t *t, mdb_sespec_t *sep, mdb_tgt_status_t *tsp)
1820 1816  {
1821 1817          kmt_brkpt_t *kb = sep->se_data;
1822 1818          int status = -1;
1823 1819          int error;
1824 1820  
1825 1821          for (sep = mdb_list_next(&t->t_active); sep; sep = mdb_list_next(sep)) {
1826 1822                  if (kmt_wp_overlap(sep, kb, MDB_TGT_WA_X))
1827 1823                          (void) kmdb_dpi_wapt_disarm(sep->se_data);
1828 1824          }
1829 1825  
1830 1826          if (kmdb_dpi_brkpt_disarm(kb->kb_addr, kb->kb_oinstr) == 0 &&
1831 1827              kmt_step(t, tsp) == 0)
1832 1828                  status = kmt_status(t, tsp);
1833 1829  
1834 1830          error = errno; /* save errno from disarm, step, or status */
1835 1831  
1836 1832          for (sep = mdb_list_next(&t->t_active); sep; sep = mdb_list_next(sep)) {
1837 1833                  if (kmt_wp_overlap(sep, kb, MDB_TGT_WA_X))
1838 1834                          kmdb_dpi_wapt_arm(sep->se_data);
1839 1835          }
1840 1836  
1841 1837          (void) set_errno(error);
1842 1838          return (status);
1843 1839  }
1844 1840  
1845 1841  /*ARGSUSED*/
1846 1842  static int
1847 1843  kmt_brkpt_match(mdb_tgt_t *t, mdb_sespec_t *sep, mdb_tgt_status_t *tsp)
1848 1844  {
1849 1845          kmt_brkpt_t *kb = sep->se_data;
1850 1846          int state, why;
1851 1847          kreg_t pc;
1852 1848  
1853 1849          state = kmdb_dpi_get_state(&why);
1854 1850          (void) kmdb_dpi_get_register("pc", &pc);
1855 1851  
1856 1852          return (state == DPI_STATE_FAULTED && why == DPI_STATE_WHY_BKPT &&
1857 1853              pc == kb->kb_addr);
1858 1854  }
1859 1855  
1860 1856  static const mdb_se_ops_t kmt_brkpt_ops = {
1861 1857          kmt_brkpt_ctor,         /* se_ctor */
1862 1858          kmt_brkpt_dtor,         /* se_dtor */
1863 1859          kmt_brkpt_info,         /* se_info */
1864 1860          kmt_brkpt_secmp,        /* se_secmp */
1865 1861          kmt_brkpt_vecmp,        /* se_vecmp */
1866 1862          kmt_brkpt_arm,          /* se_arm */
1867 1863          kmt_brkpt_disarm,       /* se_disarm */
1868 1864          kmt_brkpt_cont,         /* se_cont */
1869 1865          kmt_brkpt_match         /* se_match */
1870 1866  };
1871 1867  
1872 1868  static int
1873 1869  kmt_wapt_ctor(mdb_tgt_t *t, mdb_sespec_t *sep, void *args)
1874 1870  {
1875 1871          mdb_tgt_status_t tsp;
1876 1872          kmdb_wapt_t *vwp = args;
1877 1873          kmdb_wapt_t *swp;
1878 1874  
1879 1875          (void) mdb_tgt_status(t, &tsp);
1880 1876          if (tsp.st_state != MDB_TGT_RUNNING && tsp.st_state != MDB_TGT_STOPPED)
1881 1877                  return (set_errno(EMDB_NOPROC));
1882 1878  
1883 1879          swp = mdb_alloc(sizeof (kmdb_wapt_t), UM_SLEEP);
1884 1880          bcopy(vwp, swp, sizeof (kmdb_wapt_t));
1885 1881  
1886 1882          if (kmdb_dpi_wapt_reserve(swp) < 0) {
1887 1883                  mdb_free(swp, sizeof (kmdb_wapt_t));
1888 1884                  return (-1); /* errno is set for us */
1889 1885          }
1890 1886  
1891 1887          sep->se_data = swp;
1892 1888  
1893 1889          return (0);
1894 1890  }
1895 1891  
1896 1892  /*ARGSUSED*/
1897 1893  static void
1898 1894  kmt_wapt_dtor(mdb_tgt_t *t, mdb_sespec_t *sep)
1899 1895  {
1900 1896          kmdb_wapt_t *wp = sep->se_data;
1901 1897  
1902 1898          kmdb_dpi_wapt_release(wp);
1903 1899          mdb_free(wp, sizeof (kmdb_wapt_t));
1904 1900  }
1905 1901  
1906 1902  /*ARGSUSED*/
1907 1903  static char *
1908 1904  kmt_wapt_info(mdb_tgt_t *t, mdb_sespec_t *sep, mdb_vespec_t *vep,
1909 1905      mdb_tgt_spec_desc_t *sp, char *buf, size_t nbytes)
1910 1906  {
1911 1907          kmdb_wapt_t *wp = vep != NULL ? vep->ve_args : sep->se_data;
1912 1908          const char *fmt;
1913 1909          char desc[24];
1914 1910  
1915 1911          ASSERT(wp->wp_wflags != 0);
1916 1912          desc[0] = '\0';
1917 1913  
1918 1914          switch (wp->wp_wflags) {
1919 1915          case MDB_TGT_WA_R:
1920 1916                  (void) strcat(desc, "/read");
1921 1917                  break;
1922 1918          case MDB_TGT_WA_W:
1923 1919                  (void) strcat(desc, "/write");
1924 1920                  break;
1925 1921          case MDB_TGT_WA_X:
1926 1922                  (void) strcat(desc, "/exec");
1927 1923                  break;
1928 1924          default:
1929 1925                  if (wp->wp_wflags & MDB_TGT_WA_R)
1930 1926                          (void) strcat(desc, "/r");
1931 1927                  if (wp->wp_wflags & MDB_TGT_WA_W)
1932 1928                          (void) strcat(desc, "/w");
1933 1929                  if (wp->wp_wflags & MDB_TGT_WA_X)
1934 1930                          (void) strcat(desc, "/x");
1935 1931          }
1936 1932  
1937 1933          switch (wp->wp_type) {
1938 1934          case DPI_WAPT_TYPE_PHYS:
1939 1935                  fmt = "stop on %s of phys [%p, %p)";
1940 1936                  break;
1941 1937  
1942 1938          case DPI_WAPT_TYPE_VIRT:
1943 1939                  fmt = "stop on %s of [%la, %la)";
1944 1940                  break;
1945 1941  
1946 1942          case DPI_WAPT_TYPE_IO:
1947 1943                  if (wp->wp_size == 1)
1948 1944                          fmt = "stop on %s of I/O port %p";
1949 1945                  else
1950 1946                          fmt = "stop on %s of I/O port [%p, %p)";
1951 1947                  break;
1952 1948          }
1953 1949  
1954 1950          (void) mdb_iob_snprintf(buf, nbytes, fmt, desc + 1, wp->wp_addr,
1955 1951              wp->wp_addr + wp->wp_size);
1956 1952  
1957 1953          sp->spec_base = wp->wp_addr;
1958 1954          sp->spec_size = wp->wp_size;
1959 1955  
1960 1956          return (buf);
1961 1957  }
1962 1958  
1963 1959  /*ARGSUSED*/
1964 1960  static int
1965 1961  kmt_wapt_secmp(mdb_tgt_t *t, mdb_sespec_t *sep, void *args)
1966 1962  {
1967 1963          kmdb_wapt_t *wp1 = sep->se_data;
1968 1964          kmdb_wapt_t *wp2 = args;
1969 1965  
1970 1966          return (wp1->wp_addr == wp2->wp_addr && wp1->wp_size == wp2->wp_size &&
1971 1967              wp1->wp_wflags == wp2->wp_wflags);
1972 1968  }
1973 1969  
1974 1970  /*ARGSUSED*/
1975 1971  static int
1976 1972  kmt_wapt_vecmp(mdb_tgt_t *t, mdb_vespec_t *vep, void *args)
1977 1973  {
1978 1974          kmdb_wapt_t *wp1 = vep->ve_args;
1979 1975          kmdb_wapt_t *wp2 = args;
1980 1976  
1981 1977          return (wp1->wp_addr == wp2->wp_addr && wp1->wp_size == wp2->wp_size &&
1982 1978              wp1->wp_wflags == wp2->wp_wflags);
1983 1979  }
1984 1980  
1985 1981  /*ARGSUSED*/
1986 1982  static int
1987 1983  kmt_wapt_arm(mdb_tgt_t *t, mdb_sespec_t *sep)
1988 1984  {
1989 1985          kmdb_dpi_wapt_arm(sep->se_data);
1990 1986  
1991 1987          return (0);
1992 1988  }
1993 1989  
1994 1990  /*ARGSUSED*/
1995 1991  static int
1996 1992  kmt_wapt_disarm(mdb_tgt_t *t, mdb_sespec_t *sep)
1997 1993  {
1998 1994          kmdb_dpi_wapt_disarm(sep->se_data);
1999 1995  
2000 1996          return (0);
2001 1997  }
2002 1998  
2003 1999  /*
2004 2000   * Determine whether the specified sespec is an armed breakpoint at the given
2005 2001   * %pc.  We use this to find conflicts with watchpoints below.
2006 2002   */
2007 2003  static int
2008 2004  kmt_bp_overlap(mdb_sespec_t *sep, uintptr_t pc)
2009 2005  {
2010 2006          kmt_brkpt_t *kb = sep->se_data;
2011 2007  
2012 2008          return (sep->se_state == MDB_TGT_SPEC_ARMED &&
2013 2009              sep->se_ops == &kmt_brkpt_ops && kb->kb_addr == pc);
2014 2010  }
2015 2011  
2016 2012  /*
2017 2013   * We step over watchpoints using our single-stepper.  If a conflicting
2018 2014   * breakpoint is present, we must temporarily disarm it before stepping over
2019 2015   * the watchpoint so we do not immediately re-trigger the breakpoint.  This is
2020 2016   * similar to the case handled in kmt_brkpt_cont(), above.
2021 2017   */
2022 2018  static int
2023 2019  kmt_wapt_cont(mdb_tgt_t *t, mdb_sespec_t *sep, mdb_tgt_status_t *tsp)
2024 2020  {
2025 2021          mdb_sespec_t *bep = NULL;
2026 2022          int status = -1;
2027 2023          int error, why;
2028 2024  
2029 2025          /*
2030 2026           * If we stopped for anything other than a watchpoint, check to see
2031 2027           * if there's a breakpoint here.
2032 2028           */
2033 2029          if (!(kmdb_dpi_get_state(&why) == DPI_STATE_FAULTED &&
2034 2030              (why == DPI_STATE_WHY_V_WAPT || why == DPI_STATE_WHY_P_WAPT))) {
2035 2031                  kreg_t pc;
2036 2032  
2037 2033                  (void) kmdb_dpi_get_register("pc", &pc);
2038 2034  
2039 2035                  for (bep = mdb_list_next(&t->t_active); bep != NULL;
2040 2036                      bep = mdb_list_next(bep)) {
2041 2037                          if (kmt_bp_overlap(bep, pc)) {
2042 2038                                  (void) bep->se_ops->se_disarm(t, bep);
2043 2039                                  bep->se_state = MDB_TGT_SPEC_ACTIVE;
2044 2040                                  break;
2045 2041                          }
2046 2042                  }
2047 2043          }
2048 2044  
2049 2045          kmdb_dpi_wapt_disarm(sep->se_data);
2050 2046          if (kmt_step(t, tsp) == 0)
2051 2047                  status = kmt_status(t, tsp);
2052 2048  
2053 2049          error = errno; /* save errno from step or status */
2054 2050  
2055 2051          if (bep != NULL)
2056 2052                  mdb_tgt_sespec_arm_one(t, bep);
2057 2053  
2058 2054          (void) set_errno(error);
2059 2055          return (status);
2060 2056  }
2061 2057  
2062 2058  /*ARGSUSED*/
2063 2059  static int
2064 2060  kmt_wapt_match(mdb_tgt_t *t, mdb_sespec_t *sep, mdb_tgt_status_t *tsp)
2065 2061  {
2066 2062          return (kmdb_dpi_wapt_match(sep->se_data));
2067 2063  }
2068 2064  
2069 2065  static const mdb_se_ops_t kmt_wapt_ops = {
2070 2066          kmt_wapt_ctor,          /* se_ctor */
2071 2067          kmt_wapt_dtor,          /* se_dtor */
2072 2068          kmt_wapt_info,          /* se_info */
2073 2069          kmt_wapt_secmp,         /* se_secmp */
2074 2070          kmt_wapt_vecmp,         /* se_vecmp */
2075 2071          kmt_wapt_arm,           /* se_arm */
2076 2072          kmt_wapt_disarm,        /* se_disarm */
2077 2073          kmt_wapt_cont,          /* se_cont */
2078 2074          kmt_wapt_match          /* se_match */
2079 2075  };
2080 2076  
2081 2077  /*ARGSUSED*/
2082 2078  static int
2083 2079  kmt_trap_ctor(mdb_tgt_t *t, mdb_sespec_t *sep, void *args)
2084 2080  {
2085 2081          sep->se_data = args; /* trap number */
2086 2082  
2087 2083          return (0);
2088 2084  }
2089 2085  
2090 2086  /*ARGSUSED*/
2091 2087  static char *
2092 2088  kmt_trap_info(mdb_tgt_t *t, mdb_sespec_t *sep, mdb_vespec_t *vep,
2093 2089      mdb_tgt_spec_desc_t *sp, char *buf, size_t nbytes)
2094 2090  {
2095 2091          const char *name;
2096 2092          int trapnum;
2097 2093  
2098 2094          if (vep != NULL)
2099 2095                  trapnum = (intptr_t)vep->ve_args;
2100 2096          else
2101 2097                  trapnum = (intptr_t)sep->se_data;
2102 2098  
2103 2099          if (trapnum == KMT_TRAP_ALL)
2104 2100                  name = "any trap";
2105 2101          else if (trapnum == KMT_TRAP_NOTENUM)
2106 2102                  name = "miscellaneous trap";
2107 2103          else
2108 2104                  name = kmt_trapname(trapnum);
2109 2105  
2110 2106          (void) mdb_iob_snprintf(buf, nbytes, "single-step stop on %s", name);
2111 2107  
2112 2108          return (buf);
2113 2109  }
2114 2110  
2115 2111  /*ARGSUSED2*/
2116 2112  static int
2117 2113  kmt_trap_match(mdb_tgt_t *t, mdb_sespec_t *sep, mdb_tgt_status_t *tsp)
2118 2114  {
2119 2115          int spectt = (intptr_t)sep->se_data;
2120 2116          kmt_data_t *kmt = t->t_data;
2121 2117          kreg_t tt;
2122 2118  
2123 2119          (void) kmdb_dpi_get_register("tt", &tt);
2124 2120  
2125 2121          switch (spectt) {
2126 2122          case KMT_TRAP_ALL:
2127 2123                  return (1);
2128 2124          case KMT_TRAP_NOTENUM:
2129 2125                  return (tt > kmt->kmt_trapmax ||
2130 2126                      !BT_TEST(kmt->kmt_trapmap, tt));
2131 2127          default:
2132 2128                  return (tt == spectt);
2133 2129          }
2134 2130  }
2135 2131  
2136 2132  static const mdb_se_ops_t kmt_trap_ops = {
2137 2133          kmt_trap_ctor,          /* se_ctor */
2138 2134          no_se_dtor,             /* se_dtor */
2139 2135          kmt_trap_info,          /* se_info */
2140 2136          no_se_secmp,            /* se_secmp */
2141 2137          no_se_vecmp,            /* se_vecmp */
2142 2138          no_se_arm,              /* se_arm */
2143 2139          no_se_disarm,           /* se_disarm */
2144 2140          no_se_cont,             /* se_cont */
2145 2141          kmt_trap_match          /* se_match */
2146 2142  };
2147 2143  
2148 2144  static void
2149 2145  kmt_bparg_dtor(mdb_vespec_t *vep)
2150 2146  {
2151 2147          kmt_bparg_t *ka = vep->ve_args;
2152 2148  
2153 2149          if (ka->ka_symbol != NULL)
2154 2150                  strfree(ka->ka_symbol);
2155 2151  
2156 2152          if (ka->ka_defbp != NULL)
2157 2153                  kmt_defbp_delete(mdb.m_target, ka->ka_defbp);
2158 2154  
2159 2155          mdb_free(ka, sizeof (kmt_bparg_t));
2160 2156  }
2161 2157  
2162 2158  static int
2163 2159  kmt_add_vbrkpt(mdb_tgt_t *t, uintptr_t addr,
2164 2160      int spec_flags, mdb_tgt_se_f *func, void *data)
2165 2161  {
2166 2162          kmt_bparg_t *ka = mdb_alloc(sizeof (kmt_bparg_t), UM_SLEEP);
2167 2163  
2168 2164          ka->ka_addr = addr;
2169 2165          ka->ka_symbol = NULL;
2170 2166          ka->ka_defbp = NULL;
2171 2167  
2172 2168          return (mdb_tgt_vespec_insert(t, &kmt_brkpt_ops, spec_flags,
2173 2169              func, data, ka, kmt_bparg_dtor));
2174 2170  }
2175 2171  
2176 2172  static int
2177 2173  kmt_add_sbrkpt(mdb_tgt_t *t, const char *fullname,
2178 2174      int spec_flags, mdb_tgt_se_f *func, void *data)
2179 2175  {
2180 2176          kmt_bparg_t *ka;
2181 2177          kmt_defbp_t *dbp;
2182 2178          GElf_Sym sym;
2183 2179          char *tick, *objname, *symname;
2184 2180          int serrno;
2185 2181  
2186 2182          if ((tick = strchr(fullname, '`')) == fullname) {
2187 2183                  (void) set_errno(EMDB_NOOBJ);
2188 2184                  return (0);
2189 2185          }
2190 2186  
2191 2187          /*
2192 2188           * Deferred breakpoints are always scoped.  If we didn't find a tick,
2193 2189           * there's no scope.  We'll create a vbrkpt, but only if we can turn the
2194 2190           * provided string into an address.
2195 2191           */
2196 2192          if (tick == NULL) {
2197 2193                  uintptr_t addr;
2198 2194  
2199 2195                  if (strisbasenum(fullname)) {
2200 2196                          addr = mdb_strtoull(fullname); /* a bare address */
2201 2197                  } else if (mdb_tgt_lookup_by_name(t, MDB_TGT_OBJ_EVERY,
2202 2198                      fullname, &sym, NULL) < 0) {
2203 2199                          (void) set_errno(EMDB_NOSYM);
2204 2200                          return (0);
2205 2201                  } else {
2206 2202                          addr = (uintptr_t)sym.st_value; /* unscoped sym name */
2207 2203                  }
2208 2204  
2209 2205                  return (kmt_add_vbrkpt(t, addr, spec_flags, func, data));
2210 2206          }
2211 2207  
2212 2208          if (*(tick + 1) == '\0') {
2213 2209                  (void) set_errno(EMDB_NOSYM);
2214 2210                  return (0);
2215 2211          }
2216 2212  
2217 2213          objname = strndup(fullname, tick - fullname);
2218 2214          symname = tick + 1;
2219 2215  
2220 2216          if (mdb_tgt_lookup_by_name(t, objname, symname, NULL, NULL) < 0 &&
2221 2217              errno != EMDB_NOOBJ) {
2222 2218                  serrno = errno;
2223 2219                  strfree(objname);
2224 2220  
2225 2221                  (void) set_errno(serrno);
2226 2222                  return (0); /* errno is set for us */
2227 2223          }
2228 2224  
2229 2225          dbp = kmt_defbp_create(t, objname, symname);
2230 2226          strfree(objname);
2231 2227  
2232 2228          ka = mdb_alloc(sizeof (kmt_bparg_t), UM_SLEEP);
2233 2229          ka->ka_symbol = strdup(fullname);
2234 2230          ka->ka_addr = NULL;
2235 2231          ka->ka_defbp = dbp;
2236 2232  
2237 2233          return (mdb_tgt_vespec_insert(t, &kmt_brkpt_ops, spec_flags,
2238 2234              func, data, ka, kmt_bparg_dtor));
2239 2235  }
2240 2236  
2241 2237  static int
2242 2238  kmt_wparg_overlap(const kmdb_wapt_t *wp1, const kmdb_wapt_t *wp2)
2243 2239  {
2244 2240          /* Assume the watchpoint spaces don't overlap */
2245 2241          if (wp1->wp_type != wp2->wp_type)
2246 2242                  return (0);
2247 2243  
2248 2244          if (wp2->wp_addr + wp2->wp_size <= wp1->wp_addr)
2249 2245                  return (0); /* no range overlap */
2250 2246  
2251 2247          if (wp1->wp_addr + wp1->wp_size <= wp2->wp_addr)
2252 2248                  return (0); /* no range overlap */
2253 2249  
2254 2250          return (wp1->wp_addr != wp2->wp_addr || wp1->wp_size != wp2->wp_size ||
2255 2251              wp1->wp_wflags != wp2->wp_wflags);
2256 2252  }
2257 2253  
2258 2254  static void
2259 2255  kmt_wparg_dtor(mdb_vespec_t *vep)
2260 2256  {
2261 2257          mdb_free(vep->ve_args, sizeof (kmdb_wapt_t));
2262 2258  }
2263 2259  
2264 2260  static int
2265 2261  kmt_add_wapt_common(mdb_tgt_t *t, uintptr_t addr, size_t len, uint_t wflags,
2266 2262      int spec_flags, mdb_tgt_se_f *func, void *data, int type)
2267 2263  {
2268 2264          kmdb_wapt_t *wp = mdb_alloc(sizeof (kmdb_wapt_t), UM_SLEEP);
2269 2265          mdb_sespec_t *sep;
2270 2266  
2271 2267          wp->wp_addr = addr;
2272 2268          wp->wp_size = len;
2273 2269          wp->wp_type = type;
2274 2270          wp->wp_wflags = wflags;
2275 2271  
2276 2272          if (kmdb_dpi_wapt_validate(wp) < 0)
2277 2273                  return (0); /* errno is set for us */
2278 2274  
2279 2275          for (sep = mdb_list_next(&t->t_active); sep; sep = mdb_list_next(sep)) {
2280 2276                  if (sep->se_ops == &kmt_wapt_ops &&
2281 2277                      mdb_list_next(&sep->se_velist) != NULL &&
2282 2278                      kmt_wparg_overlap(wp, sep->se_data))
2283 2279                          goto wapt_dup;
2284 2280          }
2285 2281  
2286 2282          for (sep = mdb_list_next(&t->t_idle); sep; sep = mdb_list_next(sep)) {
2287 2283                  if (sep->se_ops == &kmt_wapt_ops && kmt_wparg_overlap(wp,
2288 2284                      ((mdb_vespec_t *)mdb_list_next(&sep->se_velist))->ve_args))
2289 2285                          goto wapt_dup;
2290 2286          }
2291 2287  
2292 2288          return (mdb_tgt_vespec_insert(t, &kmt_wapt_ops, spec_flags,
2293 2289              func, data, wp, kmt_wparg_dtor));
2294 2290  
2295 2291  wapt_dup:
2296 2292          mdb_free(wp, sizeof (kmdb_wapt_t));
2297 2293          (void) set_errno(EMDB_WPDUP);
2298 2294          return (0);
2299 2295  }
2300 2296  
2301 2297  static int
2302 2298  kmt_add_pwapt(mdb_tgt_t *t, physaddr_t addr, size_t len, uint_t wflags,
2303 2299      int spec_flags, mdb_tgt_se_f *func, void *data)
2304 2300  {
2305 2301          return (kmt_add_wapt_common(t, (uintptr_t)addr, len, wflags, spec_flags,
2306 2302              func, data, DPI_WAPT_TYPE_PHYS));
2307 2303  }
2308 2304  
2309 2305  static int
2310 2306  kmt_add_vwapt(mdb_tgt_t *t, uintptr_t addr, size_t len, uint_t wflags,
2311 2307      int spec_flags, mdb_tgt_se_f *func, void *data)
2312 2308  {
2313 2309          return (kmt_add_wapt_common(t, addr, len, wflags, spec_flags, func,
2314 2310              data, DPI_WAPT_TYPE_VIRT));
2315 2311  }
2316 2312  
2317 2313  static int
2318 2314  kmt_add_iowapt(mdb_tgt_t *t, uintptr_t addr, size_t len, uint_t wflags,
2319 2315      int spec_flags, mdb_tgt_se_f *func, void *data)
2320 2316  {
2321 2317          return (kmt_add_wapt_common(t, addr, len, wflags, spec_flags, func,
2322 2318              data, DPI_WAPT_TYPE_IO));
2323 2319  }
2324 2320  
2325 2321  static int
2326 2322  kmt_add_trap(mdb_tgt_t *t, int trapnum, int spec_flags, mdb_tgt_se_f *func,
2327 2323      void *data)
2328 2324  {
2329 2325          kmt_data_t *kmt = t->t_data;
2330 2326  
2331 2327          if (trapnum != KMT_TRAP_ALL && trapnum != KMT_TRAP_NOTENUM) {
2332 2328                  if (trapnum < 0 || trapnum > kmt->kmt_trapmax) {
2333 2329                          (void) set_errno(EMDB_BADFLTNUM);
2334 2330                          return (0);
2335 2331                  }
2336 2332  
2337 2333                  BT_SET(kmt->kmt_trapmap, trapnum);
2338 2334          }
2339 2335  
2340 2336          return (mdb_tgt_vespec_insert(t, &kmt_trap_ops, spec_flags, func, data,
2341 2337              (void *)(uintptr_t)trapnum, no_ve_dtor));
2342 2338  }
2343 2339  
2344 2340  /*ARGSUSED*/
2345 2341  static uintmax_t
2346 2342  kmt_cpuid_disc_get(const mdb_var_t *v)
2347 2343  {
2348 2344          return (kmdb_dpi_get_master_cpuid());
2349 2345  }
2350 2346  
2351 2347  static const mdb_nv_disc_t kmt_cpuid_disc = {
2352 2348          NULL,
2353 2349          kmt_cpuid_disc_get
2354 2350  };
2355 2351  
2356 2352  /*
2357 2353   * This routine executes while the kernel is running.
2358 2354   */
2359 2355  void
2360 2356  kmt_activate(mdb_tgt_t *t)
2361 2357  {
2362 2358          kmt_data_t *kmt = t->t_data;
2363 2359  
2364 2360          mdb_prop_postmortem = FALSE;
2365 2361          mdb_prop_kernel = TRUE;
2366 2362  
2367 2363          (void) mdb_tgt_register_dcmds(t, &kmt_dcmds[0], MDB_MOD_FORCE);
2368 2364          mdb_tgt_register_regvars(t, kmt->kmt_rds, &kmt_reg_disc, 0);
2369 2365  
2370 2366          /*
2371 2367           * Force load of the MDB krtld module, in case it's been rolled into
2372 2368           * unix.
2373 2369           */
2374 2370          (void) mdb_module_load(KMT_RTLD_NAME, MDB_MOD_SILENT | MDB_MOD_DEFER);
2375 2371  }
2376 2372  
2377 2373  static void
2378 2374  kmt_destroy(mdb_tgt_t *t)
2379 2375  {
2380 2376          kmt_data_t *kmt = t->t_data;
2381 2377          kmt_module_t *km, *pkm;
2382 2378  
2383 2379          mdb_nv_destroy(&kmt->kmt_modules);
2384 2380          for (km = mdb_list_prev(&kmt->kmt_modlist); km != NULL; km = pkm) {
  
    | 
      ↓ open down ↓ | 
    1789 lines elided | 
    
      ↑ open up ↑ | 
  
2385 2381                  pkm = mdb_list_prev(km);
2386 2382                  mdb_free(km, sizeof (kmt_module_t));
2387 2383          }
2388 2384  
2389 2385          if (!kmt_defbp_lock)
2390 2386                  kmt_defbp_destroy_all();
2391 2387  
2392 2388          if (kmt->kmt_trapmap != NULL)
2393 2389                  mdb_free(kmt->kmt_trapmap, BT_SIZEOFMAP(kmt->kmt_trapmax));
2394 2390  
2395      -        if (kmt->kmt_cpu != NULL)
2396      -                kmt_cpu_destroy(kmt->kmt_cpu);
2397      -
2398 2391          if (kmt != NULL)
2399 2392                  mdb_free(kmt, sizeof (kmt_data_t));
2400 2393  }
2401 2394  
2402 2395  static const mdb_tgt_ops_t kmt_ops = {
2403 2396          kmt_setflags,                           /* t_setflags */
2404 2397          (int (*)()) mdb_tgt_notsup,             /* t_setcontext */
2405 2398          kmt_activate,                           /* t_activate */
2406 2399          (void (*)()) mdb_tgt_nop,               /* t_deactivate */
2407 2400          kmt_periodic,                           /* t_periodic */
2408 2401          kmt_destroy,                            /* t_destroy */
2409 2402          kmt_name,                               /* t_name */
2410 2403          (const char *(*)()) mdb_conf_isa,       /* t_isa */
2411 2404          kmt_platform,                           /* t_platform */
2412 2405          kmt_uname,                              /* t_uname */
2413 2406          kmt_dmodel,                             /* t_dmodel */
2414 2407          (ssize_t (*)()) mdb_tgt_notsup,         /* t_aread */
2415 2408          (ssize_t (*)()) mdb_tgt_notsup,         /* t_awrite */
2416 2409          kmt_read,                               /* t_vread */
2417 2410          kmt_write,                              /* t_vwrite */
2418 2411          kmt_pread,                              /* t_pread */
2419 2412          kmt_pwrite,                             /* t_pwrite */
2420 2413          kmt_read,                               /* t_fread */
2421 2414          kmt_write,                              /* t_fwrite */
2422 2415          kmt_ioread,                             /* t_ioread */
2423 2416          kmt_iowrite,                            /* t_iowrite */
2424 2417          kmt_vtop,                               /* t_vtop */
2425 2418          kmt_lookup_by_name,                     /* t_lookup_by_name */
2426 2419          kmt_lookup_by_addr,                     /* t_lookup_by_addr */
2427 2420          kmt_symbol_iter,                        /* t_symbol_iter */
  
    | 
      ↓ open down ↓ | 
    20 lines elided | 
    
      ↑ open up ↑ | 
  
2428 2421          kmt_mapping_iter,                       /* t_mapping_iter */
2429 2422          kmt_object_iter,                        /* t_object_iter */
2430 2423          kmt_addr_to_map,                        /* t_addr_to_map */
2431 2424          kmt_name_to_map,                        /* t_name_to_map */
2432 2425          kmt_addr_to_ctf,                        /* t_addr_to_ctf */
2433 2426          kmt_name_to_ctf,                        /* t_name_to_ctf */
2434 2427          kmt_status,                             /* t_status */
2435 2428          (int (*)()) mdb_tgt_notsup,             /* t_run */
2436 2429          kmt_step,                               /* t_step */
2437 2430          kmt_step_out,                           /* t_step_out */
2438      -        kmt_step_branch,                        /* t_step_branch */
2439 2431          kmt_next,                               /* t_next */
2440 2432          kmt_continue,                           /* t_cont */
2441 2433          (int (*)()) mdb_tgt_notsup,             /* t_signal */
2442 2434          kmt_add_vbrkpt,                         /* t_add_vbrkpt */
2443 2435          kmt_add_sbrkpt,                         /* t_add_sbrkpt */
2444 2436          kmt_add_pwapt,                          /* t_add_pwapt */
2445 2437          kmt_add_vwapt,                          /* t_add_vwapt */
2446 2438          kmt_add_iowapt,                         /* t_add_iowapt */
2447 2439          (int (*)()) mdb_tgt_null,               /* t_add_sysenter */
2448 2440          (int (*)()) mdb_tgt_null,               /* t_add_sysexit */
2449 2441          (int (*)()) mdb_tgt_null,               /* t_add_signal */
2450 2442          kmt_add_trap,                           /* t_add_fault */
2451 2443          kmt_getareg,                            /* t_getareg */
2452 2444          kmt_putareg,                            /* t_putareg */
2453 2445          (int (*)()) mdb_tgt_nop,                /* XXX t_stack_iter */
2454 2446          (int (*)()) mdb_tgt_notsup              /* t_auxv */
2455 2447  };
2456 2448  
2457 2449  /*
2458 2450   * Called immediately upon resumption of the system after a step or continue.
2459 2451   * Allows us to synchronize kmt's view of the world with reality.
2460 2452   */
2461 2453  /*ARGSUSED*/
2462 2454  static void
2463 2455  kmt_sync(mdb_tgt_t *t)
2464 2456  {
2465 2457          kmt_data_t *kmt = t->t_data;
2466 2458          int symavail;
2467 2459  
2468 2460          mdb_dprintf(MDB_DBG_KMOD, "synchronizing with kernel\n");
2469 2461  
2470 2462          symavail = kmt->kmt_symavail;
2471 2463          kmt->kmt_symavail = FALSE;
2472 2464  
2473 2465          /*
2474 2466           * Resync our view of the world if the modules have changed, or if we
2475 2467           * didn't have any symbols coming into this function.  The latter will
2476 2468           * only happen on startup.
2477 2469           */
2478 2470          if (kmdb_kdi_mods_changed() || !symavail)
2479 2471                  kmt_modlist_update(t);
2480 2472  
2481 2473          /*
2482 2474           * It would be nice if we could run this less frequently, perhaps
2483 2475           * after a dvec-initiated trigger.
2484 2476           */
2485 2477          kmdb_module_sync();
2486 2478  
2487 2479          kmt->kmt_symavail = TRUE;
2488 2480  
2489 2481          mdb_dprintf(MDB_DBG_KMOD, "synchronization complete\n");
2490 2482  
2491 2483          kmt_defbp_prune();
2492 2484  
2493 2485          if (kmt_defbp_num > 0 && kmt_defbp_bpspec == 0 &&
2494 2486              kmdb_kdi_dtrace_get_state() != KDI_DTSTATE_DTRACE_ACTIVE) {
2495 2487                  /*
2496 2488                   * Deferred breakpoints were created while DTrace was active,
  
    | 
      ↓ open down ↓ | 
    48 lines elided | 
    
      ↑ open up ↑ | 
  
2497 2489                   * and consequently the deferred breakpoint enabling mechanism
2498 2490                   * wasn't activated.  Activate it now, and then try to activate
2499 2491                   * the deferred breakpoints.  We do this so that we can catch
2500 2492                   * the ones which may apply to modules that have been loaded
2501 2493                   * while they were waiting for DTrace to deactivate.
2502 2494                   */
2503 2495                  (void) kmt_defbp_activate(t);
2504 2496                  (void) mdb_tgt_sespec_activate_all(t);
2505 2497          }
2506 2498  
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 2499          (void) mdb_tgt_status(t, &t->t_status);
2512 2500  }
2513 2501  
2514 2502  /*
2515 2503   * This routine executes while the kernel is running.
2516 2504   */
2517 2505  /*ARGSUSED*/
2518 2506  int
2519 2507  kmdb_kvm_create(mdb_tgt_t *t, int argc, const char *argv[])
2520 2508  {
2521 2509          kmt_data_t *kmt;
2522 2510  
2523 2511          if (argc != 0)
2524 2512                  return (set_errno(EINVAL));
2525 2513  
2526 2514          kmt = mdb_zalloc(sizeof (kmt_data_t), UM_SLEEP);
2527 2515          t->t_data = kmt;
2528 2516          t->t_ops = &kmt_ops;
  
    | 
      ↓ open down ↓ | 
    8 lines elided | 
    
      ↑ open up ↑ | 
  
2529 2517          t->t_flags |= MDB_TGT_F_RDWR;   /* kmdb is always r/w */
2530 2518  
2531 2519          (void) mdb_nv_insert(&mdb.m_nv, "cpuid", &kmt_cpuid_disc, 0,
2532 2520              MDB_NV_PERSIST | MDB_NV_RDONLY);
2533 2521  
2534 2522          (void) mdb_nv_create(&kmt->kmt_modules, UM_SLEEP);
2535 2523  
2536 2524          kmt_init_isadep(t);
2537 2525  
2538 2526          kmt->kmt_symavail = FALSE;
2539      -        kmt->kmt_cpu_retry = TRUE;
2540 2527  
2541 2528          bzero(&kmt_defbp_list, sizeof (mdb_list_t));
2542 2529  
2543 2530          return (0);
2544 2531  
2545 2532  create_err:
2546 2533          kmt_destroy(t);
2547 2534  
2548 2535          return (-1);
2549 2536  }
2550 2537  
2551 2538  /*
2552 2539   * This routine is called once, when kmdb first has control of the world.
2553 2540   */
2554 2541  void
2555 2542  kmdb_kvm_startup(void)
2556 2543  {
2557 2544          kmt_data_t *kmt = mdb.m_target->t_data;
2558 2545  
2559 2546          mdb_dprintf(MDB_DBG_KMOD, "kmdb_kvm startup\n");
2560 2547  
2561 2548          kmt_sync(mdb.m_target);
2562 2549          (void) mdb_module_load_builtin(KMT_MODULE);
2563 2550          kmt_startup_isadep(mdb.m_target);
2564 2551  
2565 2552          /*
2566 2553           * This is here because we need to write the deferred breakpoint
2567 2554           * breakpoint when the debugger starts.  Our normal r/o write routines
2568 2555           * don't work when the kernel is running, so we have to do it during
2569 2556           * startup.
2570 2557           */
2571 2558          (void) mdb_tgt_sespec_activate_all(mdb.m_target);
2572 2559  
2573 2560          kmt->kmt_rtld_name = KMT_RTLD_NAME;
2574 2561  
2575 2562          if (kmt_module_by_name(kmt, KMT_RTLD_NAME) == NULL)
2576 2563                  kmt->kmt_rtld_name = "unix";
2577 2564  }
2578 2565  
2579 2566  /*
2580 2567   * This routine is called after kmdb has loaded its initial set of modules.
2581 2568   */
2582 2569  void
2583 2570  kmdb_kvm_poststartup(void)
2584 2571  {
2585 2572          mdb_dprintf(MDB_DBG_KMOD, "kmdb_kvm post-startup\n");
2586 2573  
2587 2574          (void) mdb_dis_select(kmt_def_dismode());
2588 2575  }
  
    | 
      ↓ open down ↓ | 
    39 lines elided | 
    
      ↑ open up ↑ | 
  
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX