hotspot/src/os/solaris/vm/dtraceJSDT_solaris.cpp
changeset 29262 1698800c8606
parent 29261 ea6e20f98dfa
parent 29099 766801b4d95d
child 29263 66e30e926405
child 29505 682be03b8f41
equal deleted inserted replaced
29261:ea6e20f98dfa 29262:1698800c8606
     1 /*
       
     2  * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
       
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       
     4  *
       
     5  * This code is free software; you can redistribute it and/or modify it
       
     6  * under the terms of the GNU General Public License version 2 only, as
       
     7  * published by the Free Software Foundation.
       
     8  *
       
     9  * This code is distributed in the hope that it will be useful, but WITHOUT
       
    10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
       
    11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
       
    12  * version 2 for more details (a copy is included in the LICENSE file that
       
    13  * accompanied this code).
       
    14  *
       
    15  * You should have received a copy of the GNU General Public License version
       
    16  * 2 along with this work; if not, write to the Free Software Foundation,
       
    17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
       
    18  *
       
    19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
       
    20  * or visit www.oracle.com if you need additional information or have any
       
    21  * questions.
       
    22  *
       
    23  */
       
    24 
       
    25 #include "precompiled.hpp"
       
    26 #include "classfile/javaClasses.hpp"
       
    27 #include "code/codeBlob.hpp"
       
    28 #include "memory/allocation.hpp"
       
    29 #include "prims/jvm.h"
       
    30 #include "runtime/dtraceJSDT.hpp"
       
    31 #include "runtime/jniHandles.hpp"
       
    32 #include "runtime/os.hpp"
       
    33 #include "runtime/signature.hpp"
       
    34 #include "utilities/globalDefinitions.hpp"
       
    35 
       
    36 #ifdef HAVE_DTRACE_H
       
    37 
       
    38 #include <sys/types.h>
       
    39 #include <sys/stat.h>
       
    40 #include <fcntl.h>
       
    41 #include <unistd.h>
       
    42 #include <dtrace.h>
       
    43 
       
    44 static const char* devname    = "/dev/dtrace/helper";
       
    45 static const char* olddevname = "/devices/pseudo/dtrace@0:helper";
       
    46 
       
    47 static const char* string_sig = "uintptr_t";
       
    48 static const char* int_sig    = "long";
       
    49 static const char* long_sig   = "long long";
       
    50 
       
    51 static void printDOFHelper(dof_helper_t* helper);
       
    52 
       
    53 static int dofhelper_open() {
       
    54   int fd;
       
    55   if ((fd = open64(devname, O_RDWR)) < 0) {
       
    56     // Optimize next calls
       
    57     devname = olddevname;
       
    58     if ((fd = open64(devname, O_RDWR)) < 0) {
       
    59       return -1;
       
    60     }
       
    61   }
       
    62   return fd;
       
    63 }
       
    64 
       
    65 static jint dof_register(jstring module, uint8_t* dof, void* modaddr) {
       
    66   int probe;
       
    67   dof_helper_t dh;
       
    68   int fd;
       
    69 
       
    70   memset(&dh, 0, sizeof(dh));
       
    71 
       
    72   char* module_name = java_lang_String::as_utf8_string(
       
    73         JNIHandles::resolve_non_null(module));
       
    74   jio_snprintf(dh.dofhp_mod, sizeof(dh.dofhp_mod), "%s", module_name);
       
    75   dh.dofhp_dof  = (uint64_t)dof;
       
    76   dh.dofhp_addr = (uint64_t)modaddr;
       
    77 
       
    78   fd = dofhelper_open();
       
    79   if (fd < 0)
       
    80     return -1;
       
    81   probe = ioctl(fd, DTRACEHIOC_ADDDOF, &dh);
       
    82   close(fd);
       
    83   if (PrintDTraceDOF) {
       
    84     printDOFHelper(&dh);
       
    85     tty->print_cr("DOF helper id = %d", probe);
       
    86   }
       
    87   return probe;
       
    88 }
       
    89 
       
    90 int DTraceJSDT::pd_activate(
       
    91     void* moduleBaseAddress, jstring module,
       
    92     jint providers_count, JVM_DTraceProvider* providers) {
       
    93 
       
    94   // We need sections:
       
    95   //  (1) STRTAB
       
    96   //  (
       
    97   //    (2) PROVIDER
       
    98   //    (3) PROBES
       
    99   //    (4) PROBOFFS
       
   100   //    (5) PROBARGS
       
   101   //  ) * Number of Providers
       
   102 
       
   103   // Type of sections we create
       
   104   enum {
       
   105     STRTAB = 0,
       
   106     PROVIDERS = 1,
       
   107     PROBES = 2,
       
   108     PROBE_OFFSETS = 3,
       
   109     ARG_OFFSETS = 4,
       
   110     NUM_SECTIONS = 5
       
   111   };
       
   112 
       
   113   static int alignment_for[NUM_SECTIONS] = { 1, 4, 8, 4, 1 };
       
   114 
       
   115   ResourceMark rm;
       
   116 
       
   117   uint32_t num_sections = 1 + 4 * providers_count;
       
   118   uint32_t offset = sizeof(dof_hdr_t) + (num_sections * sizeof(dof_sec_t));
       
   119   uint32_t* secoffs = NEW_RESOURCE_ARRAY(uint32_t, num_sections);
       
   120   uint32_t* secsize = NEW_RESOURCE_ARRAY(uint32_t, num_sections);
       
   121 
       
   122   // Store offsets of all strings here in such order:
       
   123   //  zero-string (always 0)
       
   124   //  provider1-name
       
   125   //    probe1-function
       
   126   //    probe1-name
       
   127   //    arg-1
       
   128   //    arg-2
       
   129   //    ...
       
   130   //    probe2-function
       
   131   //    probe2-name
       
   132   //    arg-1
       
   133   //    arg-2
       
   134   //  provider2-name
       
   135   //    ...
       
   136 
       
   137   uint32_t strcount  = 0;
       
   138   // Count the number of strings we'll need
       
   139   for(int prvc = 0; prvc < providers_count; ++prvc) {
       
   140     JVM_DTraceProvider* provider = &providers[prvc];
       
   141     // Provider name
       
   142     ++strcount;
       
   143     for(int prbc = 0; prbc < provider->probe_count; ++prbc) {
       
   144       JVM_DTraceProbe* p = &(provider->probes[prbc]);
       
   145       Symbol* sig = Method::resolve_jmethod_id(p->method)->signature();
       
   146       // function + name + one per argument
       
   147       strcount += 2 + ArgumentCount(sig).size();
       
   148     }
       
   149   }
       
   150 
       
   151   // Create place for string offsets
       
   152   uint32_t* stroffs = NEW_RESOURCE_ARRAY(uint32_t, strcount + 1);
       
   153   uint32_t string_index = 0;
       
   154   uint32_t curstr = 0;
       
   155 
       
   156   // First we need an empty string: ""
       
   157   stroffs[curstr++] = string_index;
       
   158   string_index += strlen("") + 1;
       
   159 
       
   160   for(int prvc = 0; prvc < providers_count; ++prvc) {
       
   161     JVM_DTraceProvider* provider = &providers[prvc];
       
   162     char* provider_name = java_lang_String::as_utf8_string(
       
   163         JNIHandles::resolve_non_null(provider->name));
       
   164     stroffs[curstr++] = string_index;
       
   165     string_index += strlen(provider_name) + 1;
       
   166 
       
   167     // All probes
       
   168     for(int prbc = 0; prbc < provider->probe_count; ++prbc) {
       
   169       JVM_DTraceProbe* p = &(provider->probes[prbc]);
       
   170 
       
   171       char* function = java_lang_String::as_utf8_string(
       
   172           JNIHandles::resolve_non_null(p->function));
       
   173       stroffs[curstr++] = string_index;
       
   174       string_index += strlen(function) + 1;
       
   175 
       
   176       char* name = java_lang_String::as_utf8_string(
       
   177           JNIHandles::resolve_non_null(p->name));
       
   178       stroffs[curstr++] = string_index;
       
   179       string_index += strlen(name) + 1;
       
   180 
       
   181       Symbol* sig = Method::resolve_jmethod_id(p->method)->signature();
       
   182       SignatureStream ss(sig);
       
   183       for ( ; !ss.at_return_type(); ss.next()) {
       
   184         BasicType bt = ss.type();
       
   185         const char* t = NULL;
       
   186         if (bt == T_OBJECT &&
       
   187             ss.as_symbol_or_null() == vmSymbols::java_lang_String()) {
       
   188           t = string_sig;
       
   189         } else if (bt == T_LONG) {
       
   190           t = long_sig;
       
   191         } else {
       
   192           t = int_sig;
       
   193         }
       
   194         stroffs[curstr++] = string_index;
       
   195         string_index += strlen(t) + 1;
       
   196       }
       
   197     }
       
   198   }
       
   199   secoffs[STRTAB] = offset;
       
   200   secsize[STRTAB] = string_index;
       
   201   offset += string_index;
       
   202 
       
   203   // Calculate the size of the rest
       
   204   for(int prvc = 0; prvc < providers_count; ++prvc) {
       
   205     JVM_DTraceProvider* provider = &providers[prvc];
       
   206     size_t provider_sec  = PROVIDERS     + prvc * 4;
       
   207     size_t probe_sec     = PROBES        + prvc * 4;
       
   208     size_t probeoffs_sec = PROBE_OFFSETS + prvc * 4;
       
   209     size_t argoffs_sec   = ARG_OFFSETS   + prvc * 4;
       
   210 
       
   211     // Allocate space for the provider data struction
       
   212     secoffs[provider_sec] = align_size_up(offset, alignment_for[PROVIDERS]);
       
   213     secsize[provider_sec] = sizeof(dof_provider_t);
       
   214     offset = secoffs[provider_sec] + secsize[provider_sec];
       
   215 
       
   216     // Allocate space for all the probes
       
   217     secoffs[probe_sec] = align_size_up(offset, alignment_for[PROBES]);
       
   218     secsize[probe_sec] = sizeof(dof_probe_t) * provider->probe_count;
       
   219     offset = secoffs[probe_sec] + secsize[probe_sec];
       
   220 
       
   221     // Allocate space for the probe offsets
       
   222     secoffs[probeoffs_sec] = align_size_up(offset, alignment_for[PROBE_OFFSETS]);
       
   223     secsize[probeoffs_sec] = sizeof(uint32_t) * provider->probe_count;
       
   224     offset = secoffs[probeoffs_sec] + secsize[probeoffs_sec];
       
   225 
       
   226     // We need number of arguments argoffs
       
   227     uint32_t argscount = 0;
       
   228     for(int prbc = 0; prbc < provider->probe_count; ++prbc) {
       
   229        JVM_DTraceProbe* p = &(provider->probes[prbc]);
       
   230        Symbol* sig = Method::resolve_jmethod_id(p->method)->signature();
       
   231        argscount += ArgumentCount(sig).size();
       
   232     }
       
   233     secoffs[argoffs_sec] = align_size_up(offset, alignment_for[ARG_OFFSETS]);
       
   234     secsize[argoffs_sec] = sizeof(uint8_t) * argscount;
       
   235     offset = secoffs[argoffs_sec] + secsize[argoffs_sec];
       
   236   }
       
   237 
       
   238   uint32_t size = offset;
       
   239 
       
   240   uint8_t* dof = NEW_RESOURCE_ARRAY(uint8_t, size);
       
   241   if (!dof) {
       
   242     return -1;
       
   243   }
       
   244   memset((void*)dof, 0, size);
       
   245 
       
   246   // Fill memory with proper values
       
   247   dof_hdr_t* hdr = (dof_hdr_t*)dof;
       
   248   hdr->dofh_ident[DOF_ID_MAG0]     = DOF_MAG_MAG0;
       
   249   hdr->dofh_ident[DOF_ID_MAG1]     = DOF_MAG_MAG1;
       
   250   hdr->dofh_ident[DOF_ID_MAG2]     = DOF_MAG_MAG2;
       
   251   hdr->dofh_ident[DOF_ID_MAG3]     = DOF_MAG_MAG3;
       
   252   hdr->dofh_ident[DOF_ID_MODEL]    = DOF_MODEL_NATIVE;  // No variants
       
   253   hdr->dofh_ident[DOF_ID_ENCODING] = DOF_ENCODE_NATIVE; // No variants
       
   254   hdr->dofh_ident[DOF_ID_VERSION]  = DOF_VERSION_1;     // No variants
       
   255   hdr->dofh_ident[DOF_ID_DIFVERS]  = DIF_VERSION_2;     // No variants
       
   256   // all other fields of ident to zero
       
   257 
       
   258   hdr->dofh_flags   = 0;
       
   259   hdr->dofh_hdrsize = sizeof(dof_hdr_t);
       
   260   hdr->dofh_secsize = sizeof(dof_sec_t);
       
   261   hdr->dofh_secnum  = num_sections;
       
   262   hdr->dofh_secoff  = sizeof(dof_hdr_t);
       
   263   hdr->dofh_loadsz  = size;
       
   264   hdr->dofh_filesz  = size;
       
   265 
       
   266   // First section: STRTAB
       
   267   dof_sec_t* sec = (dof_sec_t*)(dof + sizeof(dof_hdr_t));
       
   268   sec->dofs_type    = DOF_SECT_STRTAB;
       
   269   sec->dofs_align   = alignment_for[STRTAB];
       
   270   sec->dofs_flags   = DOF_SECF_LOAD;
       
   271   sec->dofs_entsize = 0;
       
   272   sec->dofs_offset  = secoffs[STRTAB];
       
   273   sec->dofs_size    = secsize[STRTAB];
       
   274   // Make data for this section
       
   275   char* str = (char*)(dof + sec->dofs_offset);
       
   276 
       
   277   *str = 0; str += 1; // ""
       
   278 
       
   279   // Run through all strings again
       
   280   for(int prvc = 0; prvc < providers_count; ++prvc) {
       
   281     JVM_DTraceProvider* provider = &providers[prvc];
       
   282     char* provider_name = java_lang_String::as_utf8_string(
       
   283         JNIHandles::resolve_non_null(provider->name));
       
   284     strcpy(str, provider_name);
       
   285     str += strlen(provider_name) + 1;
       
   286 
       
   287     // All probes
       
   288     for(int prbc = 0; prbc < provider->probe_count; ++prbc) {
       
   289       JVM_DTraceProbe* p = &(provider->probes[prbc]);
       
   290 
       
   291       char* function = java_lang_String::as_utf8_string(
       
   292           JNIHandles::resolve_non_null(p->function));
       
   293       strcpy(str, function);
       
   294       str += strlen(str) + 1;
       
   295 
       
   296       char* name = java_lang_String::as_utf8_string(
       
   297           JNIHandles::resolve_non_null(p->name));
       
   298       strcpy(str, name);
       
   299       str += strlen(name) + 1;
       
   300 
       
   301       Symbol* sig = Method::resolve_jmethod_id(p->method)->signature();
       
   302       SignatureStream ss(sig);
       
   303       for ( ; !ss.at_return_type(); ss.next()) {
       
   304         BasicType bt = ss.type();
       
   305         const char* t;
       
   306         if (bt == T_OBJECT &&
       
   307             ss.as_symbol_or_null() == vmSymbols::java_lang_String()) {
       
   308           t = string_sig;
       
   309         } else if (bt == T_LONG) {
       
   310           t = long_sig;
       
   311         } else {
       
   312           t = int_sig;
       
   313         }
       
   314         strcpy(str, t);
       
   315         str += strlen(t) + 1;
       
   316       }
       
   317     }
       
   318   }
       
   319 
       
   320   curstr = 1;
       
   321   for(int prvc = 0; prvc < providers_count; ++prvc) {
       
   322     JVM_DTraceProvider* provider = &providers[prvc];
       
   323     size_t provider_sec  = PROVIDERS     + prvc * 4;
       
   324     size_t probe_sec     = PROBES        + prvc * 4;
       
   325     size_t probeoffs_sec = PROBE_OFFSETS + prvc * 4;
       
   326     size_t argoffs_sec   = ARG_OFFSETS   + prvc * 4;
       
   327 
       
   328     // PROVIDER ///////////////////////////////////////////////////////////////
       
   329     // Section header
       
   330     sec = (dof_sec_t*)
       
   331         (dof + sizeof(dof_hdr_t) + sizeof(dof_sec_t) * provider_sec);
       
   332     sec->dofs_type    = DOF_SECT_PROVIDER;
       
   333     sec->dofs_align   = alignment_for[PROVIDERS];
       
   334     sec->dofs_flags   = DOF_SECF_LOAD;
       
   335     sec->dofs_entsize = 0;
       
   336     sec->dofs_offset  = secoffs[provider_sec];
       
   337     sec->dofs_size    = secsize[provider_sec];
       
   338     // Make provider decriiption
       
   339     dof_provider_t* prv = (dof_provider_t*)(dof + sec->dofs_offset);
       
   340     prv->dofpv_strtab   = STRTAB;
       
   341     prv->dofpv_probes   = probe_sec;
       
   342     prv->dofpv_prargs   = argoffs_sec;
       
   343     prv->dofpv_proffs   = probeoffs_sec;
       
   344     prv->dofpv_name     = stroffs[curstr++]; // Index in string table
       
   345     prv->dofpv_provattr = DOF_ATTR(
       
   346         provider->providerAttributes.nameStability,
       
   347         provider->providerAttributes.dataStability,
       
   348         provider->providerAttributes.dependencyClass);
       
   349     prv->dofpv_modattr = DOF_ATTR(
       
   350         provider->moduleAttributes.nameStability,
       
   351         provider->moduleAttributes.dataStability,
       
   352         provider->moduleAttributes.dependencyClass);
       
   353     prv->dofpv_funcattr = DOF_ATTR(
       
   354         provider->functionAttributes.nameStability,
       
   355         provider->functionAttributes.dataStability,
       
   356         provider->functionAttributes.dependencyClass);
       
   357     prv->dofpv_nameattr = DOF_ATTR(
       
   358         provider->nameAttributes.nameStability,
       
   359         provider->nameAttributes.dataStability,
       
   360         provider->nameAttributes.dependencyClass);
       
   361     prv->dofpv_argsattr = DOF_ATTR(
       
   362         provider->argsAttributes.nameStability,
       
   363         provider->argsAttributes.dataStability,
       
   364         provider->argsAttributes.dependencyClass);
       
   365 
       
   366     // PROBES /////////////////////////////////////////////////////////////////
       
   367     // Section header
       
   368     sec = (dof_sec_t*)
       
   369         (dof + sizeof(dof_hdr_t) + sizeof(dof_sec_t) * probe_sec);
       
   370     sec->dofs_type    = DOF_SECT_PROBES;
       
   371     sec->dofs_align   = alignment_for[PROBES];
       
   372     sec->dofs_flags   = DOF_SECF_LOAD;
       
   373     sec->dofs_entsize = sizeof(dof_probe_t);
       
   374     sec->dofs_offset  = secoffs[probe_sec];
       
   375     sec->dofs_size    = secsize[probe_sec];
       
   376     // Make probes descriptions
       
   377     uint32_t argsoffs = 0;
       
   378     for(int prbc = 0; prbc < provider->probe_count; ++prbc) {
       
   379       JVM_DTraceProbe* probe = &(provider->probes[prbc]);
       
   380       Method* m = Method::resolve_jmethod_id(probe->method);
       
   381       int arg_count = ArgumentCount(m->signature()).size();
       
   382       assert(m->code() != NULL, "must have an nmethod");
       
   383 
       
   384       dof_probe_t* prb =
       
   385          (dof_probe_t*)(dof + sec->dofs_offset + prbc * sizeof(dof_probe_t));
       
   386 
       
   387       prb->dofpr_addr   = (uint64_t)m->code()->entry_point();
       
   388       prb->dofpr_func   = stroffs[curstr++]; // Index in string table
       
   389       prb->dofpr_name   = stroffs[curstr++]; // Index in string table
       
   390       prb->dofpr_nargv  = stroffs[curstr  ]; // Index in string table
       
   391       // We spent siglen strings here
       
   392       curstr += arg_count;
       
   393       prb->dofpr_xargv  = prb->dofpr_nargv;  // Same bunch of strings
       
   394       prb->dofpr_argidx = argsoffs;
       
   395       prb->dofpr_offidx = prbc;
       
   396       prb->dofpr_nargc  = arg_count;
       
   397       prb->dofpr_xargc  = arg_count;
       
   398       prb->dofpr_noffs  = 1; // Number of offsets
       
   399       // Next bunch of offsets
       
   400       argsoffs += arg_count;
       
   401     }
       
   402 
       
   403     // PROFFS /////////////////////////////////////////////////////////////////
       
   404     // Section header
       
   405     sec = (dof_sec_t*)
       
   406         (dof + sizeof(dof_hdr_t) + sizeof(dof_sec_t) * probeoffs_sec);
       
   407     sec->dofs_type    = DOF_SECT_PROFFS;
       
   408     sec->dofs_align   = alignment_for[PROBE_OFFSETS];
       
   409     sec->dofs_flags   = DOF_SECF_LOAD;
       
   410     sec->dofs_entsize = sizeof(uint32_t);
       
   411     sec->dofs_offset  = secoffs[probeoffs_sec];
       
   412     sec->dofs_size    = secsize[probeoffs_sec];
       
   413     // Make offsets
       
   414     for (int prbc = 0; prbc < provider->probe_count; ++prbc) {
       
   415       uint32_t* pof =
       
   416           (uint32_t*)(dof + sec->dofs_offset + sizeof(uint32_t) * prbc);
       
   417       JVM_DTraceProbe* probe = &(provider->probes[prbc]);
       
   418       Method* m = Method::resolve_jmethod_id(probe->method);
       
   419       *pof = m->code()->trap_offset();
       
   420     }
       
   421 
       
   422     // PRARGS /////////////////////////////////////////////////////////////////
       
   423     // Section header
       
   424     sec = (dof_sec_t*)
       
   425         (dof + sizeof(dof_hdr_t) + sizeof(dof_sec_t) * argoffs_sec);
       
   426     sec->dofs_type    = DOF_SECT_PRARGS;
       
   427     sec->dofs_align   = alignment_for[ARG_OFFSETS];
       
   428     sec->dofs_flags   = DOF_SECF_LOAD;
       
   429     sec->dofs_entsize = sizeof(uint8_t);
       
   430     sec->dofs_offset  = secoffs[argoffs_sec];
       
   431     sec->dofs_size    = secsize[argoffs_sec];
       
   432     // Make arguments
       
   433     uint8_t* par = (uint8_t*)(dof + sec->dofs_offset);
       
   434     for (int prbc = 0; prbc < provider->probe_count; ++prbc) {
       
   435       JVM_DTraceProbe* p = &(provider->probes[prbc]);
       
   436       Symbol* sig = Method::resolve_jmethod_id(p->method)->signature();
       
   437       uint8_t count = (uint8_t)ArgumentCount(sig).size();
       
   438       for (uint8_t i = 0; i < count; ++i) {
       
   439         *par++ = i;
       
   440       }
       
   441     }
       
   442   }
       
   443 
       
   444   // Register module
       
   445   return dof_register(module, dof, moduleBaseAddress);
       
   446 }
       
   447 
       
   448 
       
   449 void DTraceJSDT::pd_dispose(int handle) {
       
   450   int fd;
       
   451   if (handle == -1) {
       
   452     return;
       
   453   }
       
   454   fd = dofhelper_open();
       
   455   if (fd < 0)
       
   456     return;
       
   457   ioctl(fd, DTRACEHIOC_REMOVE, handle);
       
   458   close(fd);
       
   459 }
       
   460 
       
   461 jboolean DTraceJSDT::pd_is_supported() {
       
   462   int fd = dofhelper_open();
       
   463   if (fd < 0) {
       
   464     return false;
       
   465   }
       
   466   close(fd);
       
   467   return true;
       
   468 }
       
   469 
       
   470 static const char* dofSecTypeFor(uint32_t type) {
       
   471   switch (type) {
       
   472     case 0:  return "DOF_SECT_NONE";
       
   473     case 1:  return "DOF_SECT_COMMENTS";
       
   474     case 2:  return "DOF_SECT_SOURCE";
       
   475     case 3:  return "DOF_SECT_ECBDESC";
       
   476     case 4:  return "DOF_SECT_PROBEDESC";
       
   477     case 5:  return "DOF_SECT_ACTDESC";
       
   478     case 6:  return "DOF_SECT_DIFOHDR";
       
   479     case 7:  return "DOF_SECT_DIF";
       
   480     case 8:  return "DOF_SECT_STRTAB";
       
   481     case 9:  return "DOF_SECT_VARTAB";
       
   482     case 10: return "DOF_SECT_RELTAB";
       
   483     case 11: return "DOF_SECT_TYPETAB";
       
   484     case 12: return "DOF_SECT_URELHDR";
       
   485     case 13: return "DOF_SECT_KRELHDR";
       
   486     case 14: return "DOF_SECT_OPTDESC";
       
   487     case 15: return "DOF_SECT_PROVIDER";
       
   488     case 16: return "DOF_SECT_PROBES";
       
   489     case 17: return "DOF_SECT_PRARGS";
       
   490     case 18: return "DOF_SECT_PROFFS";
       
   491     case 19: return "DOF_SECT_INTTAB";
       
   492     case 20: return "DOF_SECT_UTSNAME";
       
   493     case 21: return "DOF_SECT_XLTAB";
       
   494     case 22: return "DOF_SECT_XLMEMBERS";
       
   495     case 23: return "DOF_SECT_XLIMPORT";
       
   496     case 24: return "DOF_SECT_XLEXPORT";
       
   497     case 25: return "DOF_SECT_PREXPORT";
       
   498     case 26: return "DOF_SECT_PRENOFFS";
       
   499     default: return "<unknown>";
       
   500   }
       
   501 }
       
   502 
       
   503 static void printDOFStringTabSec(void* dof, dof_sec_t* sec) {
       
   504   size_t tab = sec->dofs_offset;
       
   505   size_t limit = sec->dofs_size;
       
   506   tty->print_cr("//   String Table:");
       
   507   for (size_t idx = 0; idx < limit; /*empty*/) {
       
   508     char* str = ((char*)dof) + tab + idx;
       
   509     tty->print_cr("//   [0x%x + 0x%x] '%s'", tab, idx, str);
       
   510     idx += strlen(str) + 1;
       
   511   }
       
   512 }
       
   513 
       
   514 static void printDOFProviderSec(void* dof, dof_sec_t* sec) {
       
   515   dof_provider_t* prov = (dof_provider_t*)((char*)dof + sec->dofs_offset);
       
   516   tty->print_cr("//   dof_provider_t {");
       
   517   tty->print_cr("//     dofpv_strtab = %d", prov->dofpv_strtab);
       
   518   tty->print_cr("//     dofpv_probes = %d", prov->dofpv_probes);
       
   519   tty->print_cr("//     dofpv_prargs = %d", prov->dofpv_prargs);
       
   520   tty->print_cr("//     dofpv_proffs = %d", prov->dofpv_proffs);
       
   521   tty->print_cr("//     dofpv_name = 0x%x", prov->dofpv_name);
       
   522   tty->print_cr("//     dofpv_provattr = 0x%08x", prov->dofpv_provattr);
       
   523   tty->print_cr("//     dofpv_modattr = 0x%08x", prov->dofpv_modattr);
       
   524   tty->print_cr("//     dofpv_funcattr = 0x%08x", prov->dofpv_funcattr);
       
   525   tty->print_cr("//     dofpv_nameattr = 0x%08x", prov->dofpv_nameattr);
       
   526   tty->print_cr("//     dofpv_argsattr = 0x%08x", prov->dofpv_argsattr);
       
   527   tty->print_cr("//   }");
       
   528 }
       
   529 
       
   530 static void printDOFProbesSec(void* dof, dof_sec_t* sec) {
       
   531   size_t idx = sec->dofs_offset;
       
   532   size_t limit = idx + sec->dofs_size;
       
   533   for (size_t idx = sec->dofs_offset; idx < limit; idx += sec->dofs_entsize) {
       
   534     dof_probe_t* prb = (dof_probe_t*)((char*)dof + idx);
       
   535     tty->print_cr("//   dof_probe_t {");
       
   536     tty->print_cr("//     dofpr_addr = 0x%016llx", prb->dofpr_addr);
       
   537     tty->print_cr("//     dofpr_func = 0x%x", prb->dofpr_func);
       
   538     tty->print_cr("//     dofpr_name = 0x%x", prb->dofpr_name);
       
   539     tty->print_cr("//     dofpr_nargv = 0x%x", prb->dofpr_nargv);
       
   540     tty->print_cr("//     dofpr_xargv = 0x%x", prb->dofpr_xargv);
       
   541     tty->print_cr("//     dofpr_argidx = 0x%x", prb->dofpr_argidx);
       
   542     tty->print_cr("//     dofpr_offidx = 0x%x", prb->dofpr_offidx);
       
   543     tty->print_cr("//     dofpr_nargc = %d", prb->dofpr_nargc);
       
   544     tty->print_cr("//     dofpr_xargc = %d", prb->dofpr_xargc);
       
   545     tty->print_cr("//     dofpr_noffs = %d", prb->dofpr_noffs);
       
   546     tty->print_cr("//   }");
       
   547   }
       
   548 }
       
   549 
       
   550 static void printDOFOffsetsSec(void* dof, dof_sec_t* sec) {
       
   551   size_t tab = sec->dofs_offset;
       
   552   size_t limit = sec->dofs_size;
       
   553   tty->print_cr("//   Offsets:");
       
   554   for (size_t idx = 0; idx < limit; idx += sec->dofs_entsize) {
       
   555     uint32_t* off = (uint32_t*)((char*)dof + tab + idx);
       
   556     tty->print_cr("//   [0x%x + 0x%x]: %d", tab, idx, *off);
       
   557   }
       
   558 }
       
   559 
       
   560 static void printDOFArgsSec(void* dof, dof_sec_t* sec) {
       
   561   size_t tab = sec->dofs_offset;
       
   562   size_t limit = sec->dofs_size;
       
   563   tty->print_cr("//   Arguments:");
       
   564   for (size_t idx = 0; idx < limit; idx += sec->dofs_entsize) {
       
   565     uint8_t* arg = (uint8_t*)((char*)dof + tab + idx);
       
   566     tty->print_cr("//   [0x%x + 0x%x]: %d", tab, idx, *arg);
       
   567   }
       
   568 }
       
   569 
       
   570 static void printDOFSection(void* dof, dof_sec_t* sec) {
       
   571   tty->print_cr("//   dof_sec_t {");
       
   572   tty->print_cr("//     dofs_type = 0x%x /* %s */",
       
   573                 sec->dofs_type, dofSecTypeFor(sec->dofs_type));
       
   574   tty->print_cr("//     dofs_align = %d", sec->dofs_align);
       
   575   tty->print_cr("//     dofs_flags = 0x%x", sec->dofs_flags);
       
   576   tty->print_cr("//     dofs_entsize = %d", sec->dofs_entsize);
       
   577   tty->print_cr("//     dofs_offset = 0x%llx", sec->dofs_offset);
       
   578   tty->print_cr("//     dofs_size = %lld", sec->dofs_size);
       
   579   tty->print_cr("//   }");
       
   580   switch (sec->dofs_type) {
       
   581     case DOF_SECT_STRTAB:    printDOFStringTabSec(dof, sec); break;
       
   582     case DOF_SECT_PROVIDER:  printDOFProviderSec(dof, sec);  break;
       
   583     case DOF_SECT_PROBES:    printDOFProbesSec(dof, sec);    break;
       
   584     case DOF_SECT_PROFFS:    printDOFOffsetsSec(dof, sec);   break;
       
   585     case DOF_SECT_PRARGS:    printDOFArgsSec(dof, sec);      break;
       
   586     default: tty->print_cr("//   <section type not recognized>");
       
   587   }
       
   588 }
       
   589 
       
   590 static void printDOFHeader(dof_hdr_t* hdr) {
       
   591   tty->print_cr("//   dof_hdr_t {");
       
   592   tty->print_cr("//     dofh_ident[DOF_ID_MAG0] = 0x%x",
       
   593                 hdr->dofh_ident[DOF_ID_MAG0]);
       
   594   tty->print_cr("//     dofh_ident[DOF_ID_MAG1] = 0x%x",
       
   595                 hdr->dofh_ident[DOF_ID_MAG1]);
       
   596   tty->print_cr("//     dofh_ident[DOF_ID_MAG2] = 0x%x",
       
   597                 hdr->dofh_ident[DOF_ID_MAG2]);
       
   598   tty->print_cr("//     dofh_ident[DOF_ID_MAG3] = 0x%x",
       
   599                 hdr->dofh_ident[DOF_ID_MAG3]);
       
   600   tty->print_cr("//     dofh_ident[DOF_ID_MODEL] = 0x%x",
       
   601                 hdr->dofh_ident[DOF_ID_MODEL]);
       
   602   tty->print_cr("//     dofh_ident[DOF_ID_ENCODING] = 0x%x",
       
   603                 hdr->dofh_ident[DOF_ID_ENCODING]);
       
   604   tty->print_cr("//     dofh_ident[DOF_ID_VERSION] = 0x%x",
       
   605                 hdr->dofh_ident[DOF_ID_VERSION]);
       
   606   tty->print_cr("//     dofh_ident[DOF_ID_DIFVERS] = 0x%x",
       
   607                 hdr->dofh_ident[DOF_ID_DIFVERS]);
       
   608   tty->print_cr("//     dofh_flags = 0x%x", hdr->dofh_flags);
       
   609   tty->print_cr("//     dofh_hdrsize = %d", hdr->dofh_hdrsize);
       
   610   tty->print_cr("//     dofh_secsize = %d", hdr->dofh_secsize);
       
   611   tty->print_cr("//     dofh_secnum = %d", hdr->dofh_secnum);
       
   612   tty->print_cr("//     dofh_secoff = %lld", hdr->dofh_secoff);
       
   613   tty->print_cr("//     dofh_loadsz = %lld", hdr->dofh_loadsz);
       
   614   tty->print_cr("//     dofh_filesz = %lld", hdr->dofh_filesz);
       
   615   tty->print_cr("//   }");
       
   616 }
       
   617 
       
   618 static void printDOF(void* dof) {
       
   619   dof_hdr_t* hdr = (dof_hdr_t*)dof;
       
   620   printDOFHeader(hdr);
       
   621   for (int i = 0; i < hdr->dofh_secnum; ++i) {
       
   622     dof_sec_t* sec =
       
   623       (dof_sec_t*)((char*)dof + sizeof(dof_hdr_t) + i * sizeof(dof_sec_t));
       
   624     tty->print_cr("//   [Section #%d]", i);
       
   625     printDOFSection(dof, sec);
       
   626   }
       
   627 }
       
   628 
       
   629 static void printDOFHelper(dof_helper_t* helper) {
       
   630   tty->print_cr("// dof_helper_t {");
       
   631   tty->print_cr("//   dofhp_mod = \"%s\"", helper->dofhp_mod);
       
   632   tty->print_cr("//   dofhp_addr = 0x%016llx", helper->dofhp_addr);
       
   633   tty->print_cr("//   dofhp_dof = 0x%016llx", helper->dofhp_dof);
       
   634   printDOF((void*)helper->dofhp_dof);
       
   635   tty->print_cr("// }");
       
   636   size_t len = ((dof_hdr_t*)helper)->dofh_loadsz;
       
   637   tty->print_data((void*)helper->dofhp_dof, len, true);
       
   638 }
       
   639 
       
   640 #else // ndef HAVE_DTRACE_H
       
   641 
       
   642 // Get here if we're not building on at least Solaris 10
       
   643 int DTraceJSDT::pd_activate(
       
   644   void* baseAddress, jstring module,
       
   645   jint provider_count, JVM_DTraceProvider* providers) {
       
   646   return -1;
       
   647 }
       
   648 
       
   649 void DTraceJSDT::pd_dispose(int handle) {
       
   650 }
       
   651 
       
   652 jboolean DTraceJSDT::pd_is_supported() {
       
   653   return false;
       
   654 }
       
   655 #endif