src/os/solaris/vm/dtraceJSDT_solaris.cpp

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

mercurial