Print this page
4474 DTrace Userland CTF Support
4475 DTrace userland Keyword
4476 DTrace tests should be better citizens
4479 pid provider types
4480 dof emulation missing checks
Reviewed by: Bryan Cantrill <bryan@joyent.com>

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/common/dtrace/dtrace.c
          +++ new/usr/src/uts/common/dtrace/dtrace.c
↓ open down ↓ 5711 lines elided ↑ open up ↑
5712 5712                          regs[rd] = dtrace_load32(regs[r1]);
5713 5713                          break;
5714 5714                  case DIF_OP_RLDX:
5715 5715                          if (!dtrace_canload(regs[r1], 8, mstate, vstate))
5716 5716                                  break;
5717 5717                          /*FALLTHROUGH*/
5718 5718                  case DIF_OP_LDX:
5719 5719                          regs[rd] = dtrace_load64(regs[r1]);
5720 5720                          break;
5721 5721                  case DIF_OP_ULDSB:
     5722 +                        DTRACE_CPUFLAG_SET(CPU_DTRACE_NOFAULT);
5722 5723                          regs[rd] = (int8_t)
5723 5724                              dtrace_fuword8((void *)(uintptr_t)regs[r1]);
     5725 +                        DTRACE_CPUFLAG_CLEAR(CPU_DTRACE_NOFAULT);
5724 5726                          break;
5725 5727                  case DIF_OP_ULDSH:
     5728 +                        DTRACE_CPUFLAG_SET(CPU_DTRACE_NOFAULT);
5726 5729                          regs[rd] = (int16_t)
5727 5730                              dtrace_fuword16((void *)(uintptr_t)regs[r1]);
     5731 +                        DTRACE_CPUFLAG_CLEAR(CPU_DTRACE_NOFAULT);
5728 5732                          break;
5729 5733                  case DIF_OP_ULDSW:
     5734 +                        DTRACE_CPUFLAG_SET(CPU_DTRACE_NOFAULT);
5730 5735                          regs[rd] = (int32_t)
5731 5736                              dtrace_fuword32((void *)(uintptr_t)regs[r1]);
     5737 +                        DTRACE_CPUFLAG_CLEAR(CPU_DTRACE_NOFAULT);
5732 5738                          break;
5733 5739                  case DIF_OP_ULDUB:
     5740 +                        DTRACE_CPUFLAG_SET(CPU_DTRACE_NOFAULT);
5734 5741                          regs[rd] =
5735 5742                              dtrace_fuword8((void *)(uintptr_t)regs[r1]);
     5743 +                        DTRACE_CPUFLAG_CLEAR(CPU_DTRACE_NOFAULT);
5736 5744                          break;
5737 5745                  case DIF_OP_ULDUH:
     5746 +                        DTRACE_CPUFLAG_SET(CPU_DTRACE_NOFAULT);
5738 5747                          regs[rd] =
5739 5748                              dtrace_fuword16((void *)(uintptr_t)regs[r1]);
     5749 +                        DTRACE_CPUFLAG_CLEAR(CPU_DTRACE_NOFAULT);
5740 5750                          break;
5741 5751                  case DIF_OP_ULDUW:
     5752 +                        DTRACE_CPUFLAG_SET(CPU_DTRACE_NOFAULT);
5742 5753                          regs[rd] =
5743 5754                              dtrace_fuword32((void *)(uintptr_t)regs[r1]);
     5755 +                        DTRACE_CPUFLAG_CLEAR(CPU_DTRACE_NOFAULT);
5744 5756                          break;
5745 5757                  case DIF_OP_ULDX:
     5758 +                        DTRACE_CPUFLAG_SET(CPU_DTRACE_NOFAULT);
5746 5759                          regs[rd] =
5747 5760                              dtrace_fuword64((void *)(uintptr_t)regs[r1]);
     5761 +                        DTRACE_CPUFLAG_CLEAR(CPU_DTRACE_NOFAULT);
5748 5762                          break;
5749 5763                  case DIF_OP_RET:
5750 5764                          rval = regs[rd];
5751 5765                          pc = textlen;
5752 5766                          break;
5753 5767                  case DIF_OP_NOP:
5754 5768                          break;
5755 5769                  case DIF_OP_SETX:
5756 5770                          regs[rd] = inttab[DIF_INSTR_INTEGER(instr)];
5757 5771                          break;
↓ open down ↓ 787 lines elided ↑ open up ↑
6545 6559                  dtrace_error(&state->dts_stkstroverflows);
6546 6560          }
6547 6561  
6548 6562          while (offs < strsize)
6549 6563                  str[offs++] = '\0';
6550 6564  
6551 6565  out:
6552 6566          mstate->dtms_scratch_ptr = old;
6553 6567  }
6554 6568  
     6569 +static void
     6570 +dtrace_store_by_ref(dtrace_difo_t *dp, caddr_t tomax, size_t size,
     6571 +    size_t *valoffsp, uint64_t *valp, uint64_t end, int intuple, int dtkind)
     6572 +{
     6573 +        volatile uint16_t *flags;
     6574 +        uint64_t val = *valp;
     6575 +        size_t valoffs = *valoffsp;
     6576 +
     6577 +        flags = (volatile uint16_t *)&cpu_core[CPU->cpu_id].cpuc_dtrace_flags;
     6578 +        ASSERT(dtkind == DIF_TF_BYREF || dtkind == DIF_TF_BYUREF);
     6579 +
     6580 +        /*
     6581 +         * If this is a string, we're going to only load until we find the zero
     6582 +         * byte -- after which we'll store zero bytes.
     6583 +         */
     6584 +        if (dp->dtdo_rtype.dtdt_kind == DIF_TYPE_STRING) {
     6585 +                char c = '\0' + 1;
     6586 +                size_t s;
     6587 +
     6588 +                for (s = 0; s < size; s++) {
     6589 +                        if (c != '\0' && dtkind == DIF_TF_BYREF) {
     6590 +                                c = dtrace_load8(val++);
     6591 +                        } else if (c != '\0' && dtkind == DIF_TF_BYUREF) {
     6592 +                                DTRACE_CPUFLAG_SET(CPU_DTRACE_NOFAULT);
     6593 +                                c = dtrace_fuword8((void *)(uintptr_t)val++);
     6594 +                                DTRACE_CPUFLAG_CLEAR(CPU_DTRACE_NOFAULT);
     6595 +                                if (*flags & CPU_DTRACE_FAULT)
     6596 +                                        break;
     6597 +                        }
     6598 +
     6599 +                        DTRACE_STORE(uint8_t, tomax, valoffs++, c);
     6600 +
     6601 +                        if (c == '\0' && intuple)
     6602 +                                break;
     6603 +                }
     6604 +        } else {
     6605 +                uint8_t c;
     6606 +                while (valoffs < end) {
     6607 +                        if (dtkind == DIF_TF_BYREF) {
     6608 +                                c = dtrace_load8(val++);
     6609 +                        } else if (dtkind == DIF_TF_BYUREF) {
     6610 +                                DTRACE_CPUFLAG_SET(CPU_DTRACE_NOFAULT);
     6611 +                                c = dtrace_fuword8((void *)(uintptr_t)val++);
     6612 +                                DTRACE_CPUFLAG_CLEAR(CPU_DTRACE_NOFAULT);
     6613 +                                if (*flags & CPU_DTRACE_FAULT)
     6614 +                                        break;
     6615 +                        }
     6616 +
     6617 +                        DTRACE_STORE(uint8_t, tomax,
     6618 +                            valoffs++, c);
     6619 +                }
     6620 +        }
     6621 +
     6622 +        *valp = val;
     6623 +        *valoffsp = valoffs;
     6624 +}
     6625 +
6555 6626  /*
6556 6627   * If you're looking for the epicenter of DTrace, you just found it.  This
6557 6628   * is the function called by the provider to fire a probe -- from which all
6558 6629   * subsequent probe-context DTrace activity emanates.
6559 6630   */
6560 6631  void
6561 6632  dtrace_probe(dtrace_id_t id, uintptr_t arg0, uintptr_t arg1,
6562 6633      uintptr_t arg2, uintptr_t arg3, uintptr_t arg4)
6563 6634  {
6564 6635          processorid_t cpuid;
↓ open down ↓ 471 lines elided ↑ open up ↑
7036 7107                                          continue;
7037 7108                                  }
7038 7109  
7039 7110                                  break;
7040 7111                          }
7041 7112  
7042 7113                          default:
7043 7114                                  ASSERT(0);
7044 7115                          }
7045 7116  
7046      -                        if (dp->dtdo_rtype.dtdt_flags & DIF_TF_BYREF) {
     7117 +                        if (dp->dtdo_rtype.dtdt_flags & DIF_TF_BYREF ||
     7118 +                            dp->dtdo_rtype.dtdt_flags & DIF_TF_BYUREF) {
7047 7119                                  uintptr_t end = valoffs + size;
7048 7120  
7049 7121                                  if (tracememsize != 0 &&
7050 7122                                      valoffs + tracememsize < end) {
7051 7123                                          end = valoffs + tracememsize;
7052 7124                                          tracememsize = 0;
7053 7125                                  }
7054 7126  
7055      -                                if (!dtrace_vcanload((void *)(uintptr_t)val,
     7127 +                                if (dp->dtdo_rtype.dtdt_flags & DIF_TF_BYREF &&
     7128 +                                    !dtrace_vcanload((void *)(uintptr_t)val,
7056 7129                                      &dp->dtdo_rtype, &mstate, vstate))
7057 7130                                          continue;
7058 7131  
7059      -                                /*
7060      -                                 * If this is a string, we're going to only
7061      -                                 * load until we find the zero byte -- after
7062      -                                 * which we'll store zero bytes.
7063      -                                 */
7064      -                                if (dp->dtdo_rtype.dtdt_kind ==
7065      -                                    DIF_TYPE_STRING) {
7066      -                                        char c = '\0' + 1;
7067      -                                        int intuple = act->dta_intuple;
7068      -                                        size_t s;
7069      -
7070      -                                        for (s = 0; s < size; s++) {
7071      -                                                if (c != '\0')
7072      -                                                        c = dtrace_load8(val++);
7073      -
7074      -                                                DTRACE_STORE(uint8_t, tomax,
7075      -                                                    valoffs++, c);
7076      -
7077      -                                                if (c == '\0' && intuple)
7078      -                                                        break;
7079      -                                        }
7080      -
7081      -                                        continue;
7082      -                                }
7083      -
7084      -                                while (valoffs < end) {
7085      -                                        DTRACE_STORE(uint8_t, tomax, valoffs++,
7086      -                                            dtrace_load8(val++));
7087      -                                }
7088      -
     7132 +                                dtrace_store_by_ref(dp, tomax, size, &valoffs,
     7133 +                                    &val, end, act->dta_intuple,
     7134 +                                    dp->dtdo_rtype.dtdt_flags & DIF_TF_BYREF ?
     7135 +                                    DIF_TF_BYREF: DIF_TF_BYUREF);
7089 7136                                  continue;
7090 7137                          }
7091 7138  
7092 7139                          switch (size) {
7093 7140                          case 0:
7094 7141                                  break;
7095 7142  
7096 7143                          case sizeof (uint8_t):
7097 7144                                  DTRACE_STORE(uint8_t, tomax, valoffs, val);
7098 7145                                  break;
↓ open down ↓ 2097 lines elided ↑ open up ↑
9196 9243                              DIF_INSTR_OP(instr));
9197 9244                  }
9198 9245          }
9199 9246  
9200 9247          if (dp->dtdo_len != 0 &&
9201 9248              DIF_INSTR_OP(dp->dtdo_buf[dp->dtdo_len - 1]) != DIF_OP_RET) {
9202 9249                  err += efunc(dp->dtdo_len - 1,
9203 9250                      "expected 'ret' as last DIF instruction\n");
9204 9251          }
9205 9252  
9206      -        if (!(dp->dtdo_rtype.dtdt_flags & DIF_TF_BYREF)) {
     9253 +        if (!(dp->dtdo_rtype.dtdt_flags & (DIF_TF_BYREF | DIF_TF_BYUREF))) {
9207 9254                  /*
9208 9255                   * If we're not returning by reference, the size must be either
9209 9256                   * 0 or the size of one of the base types.
9210 9257                   */
9211 9258                  switch (dp->dtdo_rtype.dtdt_size) {
9212 9259                  case 0:
9213 9260                  case sizeof (uint8_t):
9214 9261                  case sizeof (uint16_t):
9215 9262                  case sizeof (uint32_t):
9216 9263                  case sizeof (uint64_t):
↓ open down ↓ 7629 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX