src/os/solaris/vm/dtraceJSDT_solaris.cpp

changeset 0
f90c822e73f8
child 6876
710a3c8b516e
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/src/os/solaris/vm/dtraceJSDT_solaris.cpp	Wed Apr 27 01:25:04 2016 +0800
     1.3 @@ -0,0 +1,655 @@
     1.4 +/*
     1.5 + * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
     1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     1.7 + *
     1.8 + * This code is free software; you can redistribute it and/or modify it
     1.9 + * under the terms of the GNU General Public License version 2 only, as
    1.10 + * published by the Free Software Foundation.
    1.11 + *
    1.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
    1.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    1.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    1.15 + * version 2 for more details (a copy is included in the LICENSE file that
    1.16 + * accompanied this code).
    1.17 + *
    1.18 + * You should have received a copy of the GNU General Public License version
    1.19 + * 2 along with this work; if not, write to the Free Software Foundation,
    1.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    1.21 + *
    1.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    1.23 + * or visit www.oracle.com if you need additional information or have any
    1.24 + * questions.
    1.25 + *
    1.26 + */
    1.27 +
    1.28 +#include "precompiled.hpp"
    1.29 +#include "classfile/javaClasses.hpp"
    1.30 +#include "code/codeBlob.hpp"
    1.31 +#include "memory/allocation.hpp"
    1.32 +#include "prims/jvm.h"
    1.33 +#include "runtime/dtraceJSDT.hpp"
    1.34 +#include "runtime/jniHandles.hpp"
    1.35 +#include "runtime/os.hpp"
    1.36 +#include "runtime/signature.hpp"
    1.37 +#include "utilities/globalDefinitions.hpp"
    1.38 +
    1.39 +#ifdef HAVE_DTRACE_H
    1.40 +
    1.41 +#include <sys/types.h>
    1.42 +#include <sys/stat.h>
    1.43 +#include <fcntl.h>
    1.44 +#include <unistd.h>
    1.45 +#include <dtrace.h>
    1.46 +
    1.47 +static const char* devname    = "/dev/dtrace/helper";
    1.48 +static const char* olddevname = "/devices/pseudo/dtrace@0:helper";
    1.49 +
    1.50 +static const char* string_sig = "uintptr_t";
    1.51 +static const char* int_sig    = "long";
    1.52 +static const char* long_sig   = "long long";
    1.53 +
    1.54 +static void printDOFHelper(dof_helper_t* helper);
    1.55 +
    1.56 +static int dofhelper_open() {
    1.57 +  int fd;
    1.58 +  if ((fd = open64(devname, O_RDWR)) < 0) {
    1.59 +    // Optimize next calls
    1.60 +    devname = olddevname;
    1.61 +    if ((fd = open64(devname, O_RDWR)) < 0) {
    1.62 +      return -1;
    1.63 +    }
    1.64 +  }
    1.65 +  return fd;
    1.66 +}
    1.67 +
    1.68 +static jint dof_register(jstring module, uint8_t* dof, void* modaddr) {
    1.69 +  int probe;
    1.70 +  dof_helper_t dh;
    1.71 +  int fd;
    1.72 +
    1.73 +  memset(&dh, 0, sizeof(dh));
    1.74 +
    1.75 +  char* module_name = java_lang_String::as_utf8_string(
    1.76 +        JNIHandles::resolve_non_null(module));
    1.77 +  jio_snprintf(dh.dofhp_mod, sizeof(dh.dofhp_mod), "%s", module_name);
    1.78 +  dh.dofhp_dof  = (uint64_t)dof;
    1.79 +  dh.dofhp_addr = (uint64_t)modaddr;
    1.80 +
    1.81 +  fd = dofhelper_open();
    1.82 +  if (fd < 0)
    1.83 +    return -1;
    1.84 +  probe = ioctl(fd, DTRACEHIOC_ADDDOF, &dh);
    1.85 +  close(fd);
    1.86 +  if (PrintDTraceDOF) {
    1.87 +    printDOFHelper(&dh);
    1.88 +    tty->print_cr("DOF helper id = %d", probe);
    1.89 +  }
    1.90 +  return probe;
    1.91 +}
    1.92 +
    1.93 +int DTraceJSDT::pd_activate(
    1.94 +    void* moduleBaseAddress, jstring module,
    1.95 +    jint providers_count, JVM_DTraceProvider* providers) {
    1.96 +
    1.97 +  // We need sections:
    1.98 +  //  (1) STRTAB
    1.99 +  //  (
   1.100 +  //    (2) PROVIDER
   1.101 +  //    (3) PROBES
   1.102 +  //    (4) PROBOFFS
   1.103 +  //    (5) PROBARGS
   1.104 +  //  ) * Number of Providers
   1.105 +
   1.106 +  // Type of sections we create
   1.107 +  enum {
   1.108 +    STRTAB = 0,
   1.109 +    PROVIDERS = 1,
   1.110 +    PROBES = 2,
   1.111 +    PROBE_OFFSETS = 3,
   1.112 +    ARG_OFFSETS = 4,
   1.113 +    NUM_SECTIONS = 5
   1.114 +  };
   1.115 +
   1.116 +  static int alignment_for[NUM_SECTIONS] = { 1, 4, 8, 4, 1 };
   1.117 +
   1.118 +  ResourceMark rm;
   1.119 +
   1.120 +  uint32_t num_sections = 1 + 4 * providers_count;
   1.121 +  uint32_t offset = sizeof(dof_hdr_t) + (num_sections * sizeof(dof_sec_t));
   1.122 +  uint32_t* secoffs = NEW_RESOURCE_ARRAY(uint32_t, num_sections);
   1.123 +  uint32_t* secsize = NEW_RESOURCE_ARRAY(uint32_t, num_sections);
   1.124 +
   1.125 +  // Store offsets of all strings here in such order:
   1.126 +  //  zero-string (always 0)
   1.127 +  //  provider1-name
   1.128 +  //    probe1-function
   1.129 +  //    probe1-name
   1.130 +  //    arg-1
   1.131 +  //    arg-2
   1.132 +  //    ...
   1.133 +  //    probe2-function
   1.134 +  //    probe2-name
   1.135 +  //    arg-1
   1.136 +  //    arg-2
   1.137 +  //  provider2-name
   1.138 +  //    ...
   1.139 +
   1.140 +  uint32_t strcount  = 0;
   1.141 +  // Count the number of strings we'll need
   1.142 +  for(int prvc = 0; prvc < providers_count; ++prvc) {
   1.143 +    JVM_DTraceProvider* provider = &providers[prvc];
   1.144 +    // Provider name
   1.145 +    ++strcount;
   1.146 +    for(int prbc = 0; prbc < provider->probe_count; ++prbc) {
   1.147 +      JVM_DTraceProbe* p = &(provider->probes[prbc]);
   1.148 +      Symbol* sig = Method::resolve_jmethod_id(p->method)->signature();
   1.149 +      // function + name + one per argument
   1.150 +      strcount += 2 + ArgumentCount(sig).size();
   1.151 +    }
   1.152 +  }
   1.153 +
   1.154 +  // Create place for string offsets
   1.155 +  uint32_t* stroffs = NEW_RESOURCE_ARRAY(uint32_t, strcount + 1);
   1.156 +  uint32_t string_index = 0;
   1.157 +  uint32_t curstr = 0;
   1.158 +
   1.159 +  // First we need an empty string: ""
   1.160 +  stroffs[curstr++] = string_index;
   1.161 +  string_index += strlen("") + 1;
   1.162 +
   1.163 +  for(int prvc = 0; prvc < providers_count; ++prvc) {
   1.164 +    JVM_DTraceProvider* provider = &providers[prvc];
   1.165 +    char* provider_name = java_lang_String::as_utf8_string(
   1.166 +        JNIHandles::resolve_non_null(provider->name));
   1.167 +    stroffs[curstr++] = string_index;
   1.168 +    string_index += strlen(provider_name) + 1;
   1.169 +
   1.170 +    // All probes
   1.171 +    for(int prbc = 0; prbc < provider->probe_count; ++prbc) {
   1.172 +      JVM_DTraceProbe* p = &(provider->probes[prbc]);
   1.173 +
   1.174 +      char* function = java_lang_String::as_utf8_string(
   1.175 +          JNIHandles::resolve_non_null(p->function));
   1.176 +      stroffs[curstr++] = string_index;
   1.177 +      string_index += strlen(function) + 1;
   1.178 +
   1.179 +      char* name = java_lang_String::as_utf8_string(
   1.180 +          JNIHandles::resolve_non_null(p->name));
   1.181 +      stroffs[curstr++] = string_index;
   1.182 +      string_index += strlen(name) + 1;
   1.183 +
   1.184 +      Symbol* sig = Method::resolve_jmethod_id(p->method)->signature();
   1.185 +      SignatureStream ss(sig);
   1.186 +      for ( ; !ss.at_return_type(); ss.next()) {
   1.187 +        BasicType bt = ss.type();
   1.188 +        const char* t = NULL;
   1.189 +        if (bt == T_OBJECT &&
   1.190 +            ss.as_symbol_or_null() == vmSymbols::java_lang_String()) {
   1.191 +          t = string_sig;
   1.192 +        } else if (bt == T_LONG) {
   1.193 +          t = long_sig;
   1.194 +        } else {
   1.195 +          t = int_sig;
   1.196 +        }
   1.197 +        stroffs[curstr++] = string_index;
   1.198 +        string_index += strlen(t) + 1;
   1.199 +      }
   1.200 +    }
   1.201 +  }
   1.202 +  secoffs[STRTAB] = offset;
   1.203 +  secsize[STRTAB] = string_index;
   1.204 +  offset += string_index;
   1.205 +
   1.206 +  // Calculate the size of the rest
   1.207 +  for(int prvc = 0; prvc < providers_count; ++prvc) {
   1.208 +    JVM_DTraceProvider* provider = &providers[prvc];
   1.209 +    size_t provider_sec  = PROVIDERS     + prvc * 4;
   1.210 +    size_t probe_sec     = PROBES        + prvc * 4;
   1.211 +    size_t probeoffs_sec = PROBE_OFFSETS + prvc * 4;
   1.212 +    size_t argoffs_sec   = ARG_OFFSETS   + prvc * 4;
   1.213 +
   1.214 +    // Allocate space for the provider data struction
   1.215 +    secoffs[provider_sec] = align_size_up(offset, alignment_for[PROVIDERS]);
   1.216 +    secsize[provider_sec] = sizeof(dof_provider_t);
   1.217 +    offset = secoffs[provider_sec] + secsize[provider_sec];
   1.218 +
   1.219 +    // Allocate space for all the probes
   1.220 +    secoffs[probe_sec] = align_size_up(offset, alignment_for[PROBES]);
   1.221 +    secsize[probe_sec] = sizeof(dof_probe_t) * provider->probe_count;
   1.222 +    offset = secoffs[probe_sec] + secsize[probe_sec];
   1.223 +
   1.224 +    // Allocate space for the probe offsets
   1.225 +    secoffs[probeoffs_sec] = align_size_up(offset, alignment_for[PROBE_OFFSETS]);
   1.226 +    secsize[probeoffs_sec] = sizeof(uint32_t) * provider->probe_count;
   1.227 +    offset = secoffs[probeoffs_sec] + secsize[probeoffs_sec];
   1.228 +
   1.229 +    // We need number of arguments argoffs
   1.230 +    uint32_t argscount = 0;
   1.231 +    for(int prbc = 0; prbc < provider->probe_count; ++prbc) {
   1.232 +       JVM_DTraceProbe* p = &(provider->probes[prbc]);
   1.233 +       Symbol* sig = Method::resolve_jmethod_id(p->method)->signature();
   1.234 +       argscount += ArgumentCount(sig).size();
   1.235 +    }
   1.236 +    secoffs[argoffs_sec] = align_size_up(offset, alignment_for[ARG_OFFSETS]);
   1.237 +    secsize[argoffs_sec] = sizeof(uint8_t) * argscount;
   1.238 +    offset = secoffs[argoffs_sec] + secsize[argoffs_sec];
   1.239 +  }
   1.240 +
   1.241 +  uint32_t size = offset;
   1.242 +
   1.243 +  uint8_t* dof = NEW_RESOURCE_ARRAY(uint8_t, size);
   1.244 +  if (!dof) {
   1.245 +    return -1;
   1.246 +  }
   1.247 +  memset((void*)dof, 0, size);
   1.248 +
   1.249 +  // Fill memory with proper values
   1.250 +  dof_hdr_t* hdr = (dof_hdr_t*)dof;
   1.251 +  hdr->dofh_ident[DOF_ID_MAG0]     = DOF_MAG_MAG0;
   1.252 +  hdr->dofh_ident[DOF_ID_MAG1]     = DOF_MAG_MAG1;
   1.253 +  hdr->dofh_ident[DOF_ID_MAG2]     = DOF_MAG_MAG2;
   1.254 +  hdr->dofh_ident[DOF_ID_MAG3]     = DOF_MAG_MAG3;
   1.255 +  hdr->dofh_ident[DOF_ID_MODEL]    = DOF_MODEL_NATIVE;  // No variants
   1.256 +  hdr->dofh_ident[DOF_ID_ENCODING] = DOF_ENCODE_NATIVE; // No variants
   1.257 +  hdr->dofh_ident[DOF_ID_VERSION]  = DOF_VERSION_1;     // No variants
   1.258 +  hdr->dofh_ident[DOF_ID_DIFVERS]  = DIF_VERSION_2;     // No variants
   1.259 +  // all other fields of ident to zero
   1.260 +
   1.261 +  hdr->dofh_flags   = 0;
   1.262 +  hdr->dofh_hdrsize = sizeof(dof_hdr_t);
   1.263 +  hdr->dofh_secsize = sizeof(dof_sec_t);
   1.264 +  hdr->dofh_secnum  = num_sections;
   1.265 +  hdr->dofh_secoff  = sizeof(dof_hdr_t);
   1.266 +  hdr->dofh_loadsz  = size;
   1.267 +  hdr->dofh_filesz  = size;
   1.268 +
   1.269 +  // First section: STRTAB
   1.270 +  dof_sec_t* sec = (dof_sec_t*)(dof + sizeof(dof_hdr_t));
   1.271 +  sec->dofs_type    = DOF_SECT_STRTAB;
   1.272 +  sec->dofs_align   = alignment_for[STRTAB];
   1.273 +  sec->dofs_flags   = DOF_SECF_LOAD;
   1.274 +  sec->dofs_entsize = 0;
   1.275 +  sec->dofs_offset  = secoffs[STRTAB];
   1.276 +  sec->dofs_size    = secsize[STRTAB];
   1.277 +  // Make data for this section
   1.278 +  char* str = (char*)(dof + sec->dofs_offset);
   1.279 +
   1.280 +  *str = 0; str += 1; // ""
   1.281 +
   1.282 +  // Run through all strings again
   1.283 +  for(int prvc = 0; prvc < providers_count; ++prvc) {
   1.284 +    JVM_DTraceProvider* provider = &providers[prvc];
   1.285 +    char* provider_name = java_lang_String::as_utf8_string(
   1.286 +        JNIHandles::resolve_non_null(provider->name));
   1.287 +    strcpy(str, provider_name);
   1.288 +    str += strlen(provider_name) + 1;
   1.289 +
   1.290 +    // All probes
   1.291 +    for(int prbc = 0; prbc < provider->probe_count; ++prbc) {
   1.292 +      JVM_DTraceProbe* p = &(provider->probes[prbc]);
   1.293 +
   1.294 +      char* function = java_lang_String::as_utf8_string(
   1.295 +          JNIHandles::resolve_non_null(p->function));
   1.296 +      strcpy(str, function);
   1.297 +      str += strlen(str) + 1;
   1.298 +
   1.299 +      char* name = java_lang_String::as_utf8_string(
   1.300 +          JNIHandles::resolve_non_null(p->name));
   1.301 +      strcpy(str, name);
   1.302 +      str += strlen(name) + 1;
   1.303 +
   1.304 +      Symbol* sig = Method::resolve_jmethod_id(p->method)->signature();
   1.305 +      SignatureStream ss(sig);
   1.306 +      for ( ; !ss.at_return_type(); ss.next()) {
   1.307 +        BasicType bt = ss.type();
   1.308 +        const char* t;
   1.309 +        if (bt == T_OBJECT &&
   1.310 +            ss.as_symbol_or_null() == vmSymbols::java_lang_String()) {
   1.311 +          t = string_sig;
   1.312 +        } else if (bt == T_LONG) {
   1.313 +          t = long_sig;
   1.314 +        } else {
   1.315 +          t = int_sig;
   1.316 +        }
   1.317 +        strcpy(str, t);
   1.318 +        str += strlen(t) + 1;
   1.319 +      }
   1.320 +    }
   1.321 +  }
   1.322 +
   1.323 +  curstr = 1;
   1.324 +  for(int prvc = 0; prvc < providers_count; ++prvc) {
   1.325 +    JVM_DTraceProvider* provider = &providers[prvc];
   1.326 +    size_t provider_sec  = PROVIDERS     + prvc * 4;
   1.327 +    size_t probe_sec     = PROBES        + prvc * 4;
   1.328 +    size_t probeoffs_sec = PROBE_OFFSETS + prvc * 4;
   1.329 +    size_t argoffs_sec   = ARG_OFFSETS   + prvc * 4;
   1.330 +
   1.331 +    // PROVIDER ///////////////////////////////////////////////////////////////
   1.332 +    // Section header
   1.333 +    sec = (dof_sec_t*)
   1.334 +        (dof + sizeof(dof_hdr_t) + sizeof(dof_sec_t) * provider_sec);
   1.335 +    sec->dofs_type    = DOF_SECT_PROVIDER;
   1.336 +    sec->dofs_align   = alignment_for[PROVIDERS];
   1.337 +    sec->dofs_flags   = DOF_SECF_LOAD;
   1.338 +    sec->dofs_entsize = 0;
   1.339 +    sec->dofs_offset  = secoffs[provider_sec];
   1.340 +    sec->dofs_size    = secsize[provider_sec];
   1.341 +    // Make provider decriiption
   1.342 +    dof_provider_t* prv = (dof_provider_t*)(dof + sec->dofs_offset);
   1.343 +    prv->dofpv_strtab   = STRTAB;
   1.344 +    prv->dofpv_probes   = probe_sec;
   1.345 +    prv->dofpv_prargs   = argoffs_sec;
   1.346 +    prv->dofpv_proffs   = probeoffs_sec;
   1.347 +    prv->dofpv_name     = stroffs[curstr++]; // Index in string table
   1.348 +    prv->dofpv_provattr = DOF_ATTR(
   1.349 +        provider->providerAttributes.nameStability,
   1.350 +        provider->providerAttributes.dataStability,
   1.351 +        provider->providerAttributes.dependencyClass);
   1.352 +    prv->dofpv_modattr = DOF_ATTR(
   1.353 +        provider->moduleAttributes.nameStability,
   1.354 +        provider->moduleAttributes.dataStability,
   1.355 +        provider->moduleAttributes.dependencyClass);
   1.356 +    prv->dofpv_funcattr = DOF_ATTR(
   1.357 +        provider->functionAttributes.nameStability,
   1.358 +        provider->functionAttributes.dataStability,
   1.359 +        provider->functionAttributes.dependencyClass);
   1.360 +    prv->dofpv_nameattr = DOF_ATTR(
   1.361 +        provider->nameAttributes.nameStability,
   1.362 +        provider->nameAttributes.dataStability,
   1.363 +        provider->nameAttributes.dependencyClass);
   1.364 +    prv->dofpv_argsattr = DOF_ATTR(
   1.365 +        provider->argsAttributes.nameStability,
   1.366 +        provider->argsAttributes.dataStability,
   1.367 +        provider->argsAttributes.dependencyClass);
   1.368 +
   1.369 +    // PROBES /////////////////////////////////////////////////////////////////
   1.370 +    // Section header
   1.371 +    sec = (dof_sec_t*)
   1.372 +        (dof + sizeof(dof_hdr_t) + sizeof(dof_sec_t) * probe_sec);
   1.373 +    sec->dofs_type    = DOF_SECT_PROBES;
   1.374 +    sec->dofs_align   = alignment_for[PROBES];
   1.375 +    sec->dofs_flags   = DOF_SECF_LOAD;
   1.376 +    sec->dofs_entsize = sizeof(dof_probe_t);
   1.377 +    sec->dofs_offset  = secoffs[probe_sec];
   1.378 +    sec->dofs_size    = secsize[probe_sec];
   1.379 +    // Make probes descriptions
   1.380 +    uint32_t argsoffs = 0;
   1.381 +    for(int prbc = 0; prbc < provider->probe_count; ++prbc) {
   1.382 +      JVM_DTraceProbe* probe = &(provider->probes[prbc]);
   1.383 +      Method* m = Method::resolve_jmethod_id(probe->method);
   1.384 +      int arg_count = ArgumentCount(m->signature()).size();
   1.385 +      assert(m->code() != NULL, "must have an nmethod");
   1.386 +
   1.387 +      dof_probe_t* prb =
   1.388 +         (dof_probe_t*)(dof + sec->dofs_offset + prbc * sizeof(dof_probe_t));
   1.389 +
   1.390 +      prb->dofpr_addr   = (uint64_t)m->code()->entry_point();
   1.391 +      prb->dofpr_func   = stroffs[curstr++]; // Index in string table
   1.392 +      prb->dofpr_name   = stroffs[curstr++]; // Index in string table
   1.393 +      prb->dofpr_nargv  = stroffs[curstr  ]; // Index in string table
   1.394 +      // We spent siglen strings here
   1.395 +      curstr += arg_count;
   1.396 +      prb->dofpr_xargv  = prb->dofpr_nargv;  // Same bunch of strings
   1.397 +      prb->dofpr_argidx = argsoffs;
   1.398 +      prb->dofpr_offidx = prbc;
   1.399 +      prb->dofpr_nargc  = arg_count;
   1.400 +      prb->dofpr_xargc  = arg_count;
   1.401 +      prb->dofpr_noffs  = 1; // Number of offsets
   1.402 +      // Next bunch of offsets
   1.403 +      argsoffs += arg_count;
   1.404 +    }
   1.405 +
   1.406 +    // PROFFS /////////////////////////////////////////////////////////////////
   1.407 +    // Section header
   1.408 +    sec = (dof_sec_t*)
   1.409 +        (dof + sizeof(dof_hdr_t) + sizeof(dof_sec_t) * probeoffs_sec);
   1.410 +    sec->dofs_type    = DOF_SECT_PROFFS;
   1.411 +    sec->dofs_align   = alignment_for[PROBE_OFFSETS];
   1.412 +    sec->dofs_flags   = DOF_SECF_LOAD;
   1.413 +    sec->dofs_entsize = sizeof(uint32_t);
   1.414 +    sec->dofs_offset  = secoffs[probeoffs_sec];
   1.415 +    sec->dofs_size    = secsize[probeoffs_sec];
   1.416 +    // Make offsets
   1.417 +    for (int prbc = 0; prbc < provider->probe_count; ++prbc) {
   1.418 +      uint32_t* pof =
   1.419 +          (uint32_t*)(dof + sec->dofs_offset + sizeof(uint32_t) * prbc);
   1.420 +      JVM_DTraceProbe* probe = &(provider->probes[prbc]);
   1.421 +      Method* m = Method::resolve_jmethod_id(probe->method);
   1.422 +      *pof = m->code()->trap_offset();
   1.423 +    }
   1.424 +
   1.425 +    // PRARGS /////////////////////////////////////////////////////////////////
   1.426 +    // Section header
   1.427 +    sec = (dof_sec_t*)
   1.428 +        (dof + sizeof(dof_hdr_t) + sizeof(dof_sec_t) * argoffs_sec);
   1.429 +    sec->dofs_type    = DOF_SECT_PRARGS;
   1.430 +    sec->dofs_align   = alignment_for[ARG_OFFSETS];
   1.431 +    sec->dofs_flags   = DOF_SECF_LOAD;
   1.432 +    sec->dofs_entsize = sizeof(uint8_t);
   1.433 +    sec->dofs_offset  = secoffs[argoffs_sec];
   1.434 +    sec->dofs_size    = secsize[argoffs_sec];
   1.435 +    // Make arguments
   1.436 +    uint8_t* par = (uint8_t*)(dof + sec->dofs_offset);
   1.437 +    for (int prbc = 0; prbc < provider->probe_count; ++prbc) {
   1.438 +      JVM_DTraceProbe* p = &(provider->probes[prbc]);
   1.439 +      Symbol* sig = Method::resolve_jmethod_id(p->method)->signature();
   1.440 +      uint8_t count = (uint8_t)ArgumentCount(sig).size();
   1.441 +      for (uint8_t i = 0; i < count; ++i) {
   1.442 +        *par++ = i;
   1.443 +      }
   1.444 +    }
   1.445 +  }
   1.446 +
   1.447 +  // Register module
   1.448 +  return dof_register(module, dof, moduleBaseAddress);
   1.449 +}
   1.450 +
   1.451 +
   1.452 +void DTraceJSDT::pd_dispose(int handle) {
   1.453 +  int fd;
   1.454 +  if (handle == -1) {
   1.455 +    return;
   1.456 +  }
   1.457 +  fd = dofhelper_open();
   1.458 +  if (fd < 0)
   1.459 +    return;
   1.460 +  ioctl(fd, DTRACEHIOC_REMOVE, handle);
   1.461 +  close(fd);
   1.462 +}
   1.463 +
   1.464 +jboolean DTraceJSDT::pd_is_supported() {
   1.465 +  int fd = dofhelper_open();
   1.466 +  if (fd < 0) {
   1.467 +    return false;
   1.468 +  }
   1.469 +  close(fd);
   1.470 +  return true;
   1.471 +}
   1.472 +
   1.473 +static const char* dofSecTypeFor(uint32_t type) {
   1.474 +  switch (type) {
   1.475 +    case 0:  return "DOF_SECT_NONE";
   1.476 +    case 1:  return "DOF_SECT_COMMENTS";
   1.477 +    case 2:  return "DOF_SECT_SOURCE";
   1.478 +    case 3:  return "DOF_SECT_ECBDESC";
   1.479 +    case 4:  return "DOF_SECT_PROBEDESC";
   1.480 +    case 5:  return "DOF_SECT_ACTDESC";
   1.481 +    case 6:  return "DOF_SECT_DIFOHDR";
   1.482 +    case 7:  return "DOF_SECT_DIF";
   1.483 +    case 8:  return "DOF_SECT_STRTAB";
   1.484 +    case 9:  return "DOF_SECT_VARTAB";
   1.485 +    case 10: return "DOF_SECT_RELTAB";
   1.486 +    case 11: return "DOF_SECT_TYPETAB";
   1.487 +    case 12: return "DOF_SECT_URELHDR";
   1.488 +    case 13: return "DOF_SECT_KRELHDR";
   1.489 +    case 14: return "DOF_SECT_OPTDESC";
   1.490 +    case 15: return "DOF_SECT_PROVIDER";
   1.491 +    case 16: return "DOF_SECT_PROBES";
   1.492 +    case 17: return "DOF_SECT_PRARGS";
   1.493 +    case 18: return "DOF_SECT_PROFFS";
   1.494 +    case 19: return "DOF_SECT_INTTAB";
   1.495 +    case 20: return "DOF_SECT_UTSNAME";
   1.496 +    case 21: return "DOF_SECT_XLTAB";
   1.497 +    case 22: return "DOF_SECT_XLMEMBERS";
   1.498 +    case 23: return "DOF_SECT_XLIMPORT";
   1.499 +    case 24: return "DOF_SECT_XLEXPORT";
   1.500 +    case 25: return "DOF_SECT_PREXPORT";
   1.501 +    case 26: return "DOF_SECT_PRENOFFS";
   1.502 +    default: return "<unknown>";
   1.503 +  }
   1.504 +}
   1.505 +
   1.506 +static void printDOFStringTabSec(void* dof, dof_sec_t* sec) {
   1.507 +  size_t tab = sec->dofs_offset;
   1.508 +  size_t limit = sec->dofs_size;
   1.509 +  tty->print_cr("//   String Table:");
   1.510 +  for (size_t idx = 0; idx < limit; /*empty*/) {
   1.511 +    char* str = ((char*)dof) + tab + idx;
   1.512 +    tty->print_cr("//   [0x%x + 0x%x] '%s'", tab, idx, str);
   1.513 +    idx += strlen(str) + 1;
   1.514 +  }
   1.515 +}
   1.516 +
   1.517 +static void printDOFProviderSec(void* dof, dof_sec_t* sec) {
   1.518 +  dof_provider_t* prov = (dof_provider_t*)((char*)dof + sec->dofs_offset);
   1.519 +  tty->print_cr("//   dof_provider_t {");
   1.520 +  tty->print_cr("//     dofpv_strtab = %d", prov->dofpv_strtab);
   1.521 +  tty->print_cr("//     dofpv_probes = %d", prov->dofpv_probes);
   1.522 +  tty->print_cr("//     dofpv_prargs = %d", prov->dofpv_prargs);
   1.523 +  tty->print_cr("//     dofpv_proffs = %d", prov->dofpv_proffs);
   1.524 +  tty->print_cr("//     dofpv_name = 0x%x", prov->dofpv_name);
   1.525 +  tty->print_cr("//     dofpv_provattr = 0x%08x", prov->dofpv_provattr);
   1.526 +  tty->print_cr("//     dofpv_modattr = 0x%08x", prov->dofpv_modattr);
   1.527 +  tty->print_cr("//     dofpv_funcattr = 0x%08x", prov->dofpv_funcattr);
   1.528 +  tty->print_cr("//     dofpv_nameattr = 0x%08x", prov->dofpv_nameattr);
   1.529 +  tty->print_cr("//     dofpv_argsattr = 0x%08x", prov->dofpv_argsattr);
   1.530 +  tty->print_cr("//   }");
   1.531 +}
   1.532 +
   1.533 +static void printDOFProbesSec(void* dof, dof_sec_t* sec) {
   1.534 +  size_t idx = sec->dofs_offset;
   1.535 +  size_t limit = idx + sec->dofs_size;
   1.536 +  for (size_t idx = sec->dofs_offset; idx < limit; idx += sec->dofs_entsize) {
   1.537 +    dof_probe_t* prb = (dof_probe_t*)((char*)dof + idx);
   1.538 +    tty->print_cr("//   dof_probe_t {");
   1.539 +    tty->print_cr("//     dofpr_addr = 0x%016llx", prb->dofpr_addr);
   1.540 +    tty->print_cr("//     dofpr_func = 0x%x", prb->dofpr_func);
   1.541 +    tty->print_cr("//     dofpr_name = 0x%x", prb->dofpr_name);
   1.542 +    tty->print_cr("//     dofpr_nargv = 0x%x", prb->dofpr_nargv);
   1.543 +    tty->print_cr("//     dofpr_xargv = 0x%x", prb->dofpr_xargv);
   1.544 +    tty->print_cr("//     dofpr_argidx = 0x%x", prb->dofpr_argidx);
   1.545 +    tty->print_cr("//     dofpr_offidx = 0x%x", prb->dofpr_offidx);
   1.546 +    tty->print_cr("//     dofpr_nargc = %d", prb->dofpr_nargc);
   1.547 +    tty->print_cr("//     dofpr_xargc = %d", prb->dofpr_xargc);
   1.548 +    tty->print_cr("//     dofpr_noffs = %d", prb->dofpr_noffs);
   1.549 +    tty->print_cr("//   }");
   1.550 +  }
   1.551 +}
   1.552 +
   1.553 +static void printDOFOffsetsSec(void* dof, dof_sec_t* sec) {
   1.554 +  size_t tab = sec->dofs_offset;
   1.555 +  size_t limit = sec->dofs_size;
   1.556 +  tty->print_cr("//   Offsets:");
   1.557 +  for (size_t idx = 0; idx < limit; idx += sec->dofs_entsize) {
   1.558 +    uint32_t* off = (uint32_t*)((char*)dof + tab + idx);
   1.559 +    tty->print_cr("//   [0x%x + 0x%x]: %d", tab, idx, *off);
   1.560 +  }
   1.561 +}
   1.562 +
   1.563 +static void printDOFArgsSec(void* dof, dof_sec_t* sec) {
   1.564 +  size_t tab = sec->dofs_offset;
   1.565 +  size_t limit = sec->dofs_size;
   1.566 +  tty->print_cr("//   Arguments:");
   1.567 +  for (size_t idx = 0; idx < limit; idx += sec->dofs_entsize) {
   1.568 +    uint8_t* arg = (uint8_t*)((char*)dof + tab + idx);
   1.569 +    tty->print_cr("//   [0x%x + 0x%x]: %d", tab, idx, *arg);
   1.570 +  }
   1.571 +}
   1.572 +
   1.573 +static void printDOFSection(void* dof, dof_sec_t* sec) {
   1.574 +  tty->print_cr("//   dof_sec_t {");
   1.575 +  tty->print_cr("//     dofs_type = 0x%x /* %s */",
   1.576 +                sec->dofs_type, dofSecTypeFor(sec->dofs_type));
   1.577 +  tty->print_cr("//     dofs_align = %d", sec->dofs_align);
   1.578 +  tty->print_cr("//     dofs_flags = 0x%x", sec->dofs_flags);
   1.579 +  tty->print_cr("//     dofs_entsize = %d", sec->dofs_entsize);
   1.580 +  tty->print_cr("//     dofs_offset = 0x%llx", sec->dofs_offset);
   1.581 +  tty->print_cr("//     dofs_size = %lld", sec->dofs_size);
   1.582 +  tty->print_cr("//   }");
   1.583 +  switch (sec->dofs_type) {
   1.584 +    case DOF_SECT_STRTAB:    printDOFStringTabSec(dof, sec); break;
   1.585 +    case DOF_SECT_PROVIDER:  printDOFProviderSec(dof, sec);  break;
   1.586 +    case DOF_SECT_PROBES:    printDOFProbesSec(dof, sec);    break;
   1.587 +    case DOF_SECT_PROFFS:    printDOFOffsetsSec(dof, sec);   break;
   1.588 +    case DOF_SECT_PRARGS:    printDOFArgsSec(dof, sec);      break;
   1.589 +    default: tty->print_cr("//   <section type not recognized>");
   1.590 +  }
   1.591 +}
   1.592 +
   1.593 +static void printDOFHeader(dof_hdr_t* hdr) {
   1.594 +  tty->print_cr("//   dof_hdr_t {");
   1.595 +  tty->print_cr("//     dofh_ident[DOF_ID_MAG0] = 0x%x",
   1.596 +                hdr->dofh_ident[DOF_ID_MAG0]);
   1.597 +  tty->print_cr("//     dofh_ident[DOF_ID_MAG1] = 0x%x",
   1.598 +                hdr->dofh_ident[DOF_ID_MAG1]);
   1.599 +  tty->print_cr("//     dofh_ident[DOF_ID_MAG2] = 0x%x",
   1.600 +                hdr->dofh_ident[DOF_ID_MAG2]);
   1.601 +  tty->print_cr("//     dofh_ident[DOF_ID_MAG3] = 0x%x",
   1.602 +                hdr->dofh_ident[DOF_ID_MAG3]);
   1.603 +  tty->print_cr("//     dofh_ident[DOF_ID_MODEL] = 0x%x",
   1.604 +                hdr->dofh_ident[DOF_ID_MODEL]);
   1.605 +  tty->print_cr("//     dofh_ident[DOF_ID_ENCODING] = 0x%x",
   1.606 +                hdr->dofh_ident[DOF_ID_ENCODING]);
   1.607 +  tty->print_cr("//     dofh_ident[DOF_ID_VERSION] = 0x%x",
   1.608 +                hdr->dofh_ident[DOF_ID_VERSION]);
   1.609 +  tty->print_cr("//     dofh_ident[DOF_ID_DIFVERS] = 0x%x",
   1.610 +                hdr->dofh_ident[DOF_ID_DIFVERS]);
   1.611 +  tty->print_cr("//     dofh_flags = 0x%x", hdr->dofh_flags);
   1.612 +  tty->print_cr("//     dofh_hdrsize = %d", hdr->dofh_hdrsize);
   1.613 +  tty->print_cr("//     dofh_secsize = %d", hdr->dofh_secsize);
   1.614 +  tty->print_cr("//     dofh_secnum = %d", hdr->dofh_secnum);
   1.615 +  tty->print_cr("//     dofh_secoff = %lld", hdr->dofh_secoff);
   1.616 +  tty->print_cr("//     dofh_loadsz = %lld", hdr->dofh_loadsz);
   1.617 +  tty->print_cr("//     dofh_filesz = %lld", hdr->dofh_filesz);
   1.618 +  tty->print_cr("//   }");
   1.619 +}
   1.620 +
   1.621 +static void printDOF(void* dof) {
   1.622 +  dof_hdr_t* hdr = (dof_hdr_t*)dof;
   1.623 +  printDOFHeader(hdr);
   1.624 +  for (int i = 0; i < hdr->dofh_secnum; ++i) {
   1.625 +    dof_sec_t* sec =
   1.626 +      (dof_sec_t*)((char*)dof + sizeof(dof_hdr_t) + i * sizeof(dof_sec_t));
   1.627 +    tty->print_cr("//   [Section #%d]", i);
   1.628 +    printDOFSection(dof, sec);
   1.629 +  }
   1.630 +}
   1.631 +
   1.632 +static void printDOFHelper(dof_helper_t* helper) {
   1.633 +  tty->print_cr("// dof_helper_t {");
   1.634 +  tty->print_cr("//   dofhp_mod = \"%s\"", helper->dofhp_mod);
   1.635 +  tty->print_cr("//   dofhp_addr = 0x%016llx", helper->dofhp_addr);
   1.636 +  tty->print_cr("//   dofhp_dof = 0x%016llx", helper->dofhp_dof);
   1.637 +  printDOF((void*)helper->dofhp_dof);
   1.638 +  tty->print_cr("// }");
   1.639 +  size_t len = ((dof_hdr_t*)helper)->dofh_loadsz;
   1.640 +  tty->print_data((void*)helper->dofhp_dof, len, true);
   1.641 +}
   1.642 +
   1.643 +#else // ndef HAVE_DTRACE_H
   1.644 +
   1.645 +// Get here if we're not building on at least Solaris 10
   1.646 +int DTraceJSDT::pd_activate(
   1.647 +  void* baseAddress, jstring module,
   1.648 +  jint provider_count, JVM_DTraceProvider* providers) {
   1.649 +  return -1;
   1.650 +}
   1.651 +
   1.652 +void DTraceJSDT::pd_dispose(int handle) {
   1.653 +}
   1.654 +
   1.655 +jboolean DTraceJSDT::pd_is_supported() {
   1.656 +  return false;
   1.657 +}
   1.658 +#endif

mercurial