src/os/solaris/vm/dtraceJSDT_solaris.cpp

Thu, 19 Mar 2009 09:13:24 -0700

author
kvn
date
Thu, 19 Mar 2009 09:13:24 -0700
changeset 1082
bd441136a5ce
parent 631
d1605aabd0a1
child 1907
c18cbe5936b8
permissions
-rw-r--r--

Merge

     1 /*
     2  * Copyright 2005-2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
    20  * CA 95054 USA or visit www.sun.com if you need additional information or
    21  * have any questions.
    22  *
    23  */
    25 #include "incls/_precompiled.incl"
    26 #include "incls/_dtraceJSDT_solaris.cpp.incl"
    28 #ifdef HAVE_DTRACE_H
    30 #include <sys/types.h>
    31 #include <sys/stat.h>
    32 #include <fcntl.h>
    33 #include <unistd.h>
    34 #include <dtrace.h>
    36 static const char* devname    = "/dev/dtrace/helper";
    37 static const char* olddevname = "/devices/pseudo/dtrace@0:helper";
    39 static const char* string_sig = "uintptr_t";
    40 static const char* int_sig    = "long";
    41 static const char* long_sig   = "long long";
    43 static void printDOFHelper(dof_helper_t* helper);
    45 static int dofhelper_open() {
    46   int fd;
    47   if ((fd = open64(devname, O_RDWR)) < 0) {
    48     // Optimize next calls
    49     devname = olddevname;
    50     if ((fd = open64(devname, O_RDWR)) < 0) {
    51       return -1;
    52     }
    53   }
    54   return fd;
    55 }
    57 static jint dof_register(jstring module, uint8_t* dof, void* modaddr) {
    58   int probe;
    59   dof_helper_t dh;
    60   int fd;
    62   memset(&dh, 0, sizeof(dh));
    64   char* module_name = java_lang_String::as_utf8_string(
    65         JNIHandles::resolve_non_null(module));
    66   jio_snprintf(dh.dofhp_mod, sizeof(dh.dofhp_mod), "%s", module_name);
    67   dh.dofhp_dof  = (uint64_t)dof;
    68   dh.dofhp_addr = (uint64_t)modaddr;
    70   fd = dofhelper_open();
    71   if (fd < 0)
    72     return -1;
    73   probe = ioctl(fd, DTRACEHIOC_ADDDOF, &dh);
    74   close(fd);
    75   if (PrintDTraceDOF) {
    76     printDOFHelper(&dh);
    77     tty->print_cr("DOF helper id = %d", probe);
    78   }
    79   return probe;
    80 }
    82 int DTraceJSDT::pd_activate(
    83     void* moduleBaseAddress, jstring module,
    84     jint providers_count, JVM_DTraceProvider* providers) {
    86   // We need sections:
    87   //  (1) STRTAB
    88   //  (
    89   //    (2) PROVIDER
    90   //    (3) PROBES
    91   //    (4) PROBOFFS
    92   //    (5) PROBARGS
    93   //  ) * Number of Providers
    95   // Type of sections we create
    96   enum {
    97     STRTAB = 0,
    98     PROVIDERS = 1,
    99     PROBES = 2,
   100     PROBE_OFFSETS = 3,
   101     ARG_OFFSETS = 4,
   102     NUM_SECTIONS = 5
   103   };
   105   static int alignment_for[NUM_SECTIONS] = { 1, 4, 8, 4, 1 };
   107   ResourceMark rm;
   109   uint32_t num_sections = 1 + 4 * providers_count;
   110   uint32_t offset = sizeof(dof_hdr_t) + (num_sections * sizeof(dof_sec_t));
   111   uint32_t* secoffs = NEW_RESOURCE_ARRAY(uint32_t, num_sections);
   112   uint32_t* secsize = NEW_RESOURCE_ARRAY(uint32_t, num_sections);
   114   // Store offsets of all strings here in such order:
   115   //  zero-string (always 0)
   116   //  provider1-name
   117   //    probe1-function
   118   //    probe1-name
   119   //    arg-1
   120   //    arg-2
   121   //    ...
   122   //    probe2-function
   123   //    probe2-name
   124   //    arg-1
   125   //    arg-2
   126   //  provider2-name
   127   //    ...
   129   uint32_t strcount  = 0;
   130   // Count the number of strings we'll need
   131   for(int prvc = 0; prvc < providers_count; ++prvc) {
   132     JVM_DTraceProvider* provider = &providers[prvc];
   133     // Provider name
   134     ++strcount;
   135     for(int prbc = 0; prbc < provider->probe_count; ++prbc) {
   136       JVM_DTraceProbe* p = &(provider->probes[prbc]);
   137       symbolOop sig = JNIHandles::resolve_jmethod_id(p->method)->signature();
   138       // function + name + one per argument
   139       strcount += 2 + ArgumentCount(sig).size();
   140     }
   141   }
   143   // Create place for string offsets
   144   uint32_t* stroffs = NEW_RESOURCE_ARRAY(uint32_t, strcount + 1);
   145   uint32_t string_index = 0;
   146   uint32_t curstr = 0;
   148   // First we need an empty string: ""
   149   stroffs[curstr++] = string_index;
   150   string_index += strlen("") + 1;
   152   for(int prvc = 0; prvc < providers_count; ++prvc) {
   153     JVM_DTraceProvider* provider = &providers[prvc];
   154     char* provider_name = java_lang_String::as_utf8_string(
   155         JNIHandles::resolve_non_null(provider->name));
   156     stroffs[curstr++] = string_index;
   157     string_index += strlen(provider_name) + 1;
   159     // All probes
   160     for(int prbc = 0; prbc < provider->probe_count; ++prbc) {
   161       JVM_DTraceProbe* p = &(provider->probes[prbc]);
   163       char* function = java_lang_String::as_utf8_string(
   164           JNIHandles::resolve_non_null(p->function));
   165       stroffs[curstr++] = string_index;
   166       string_index += strlen(function) + 1;
   168       char* name = java_lang_String::as_utf8_string(
   169           JNIHandles::resolve_non_null(p->name));
   170       stroffs[curstr++] = string_index;
   171       string_index += strlen(name) + 1;
   173       symbolOop sig = JNIHandles::resolve_jmethod_id(p->method)->signature();
   174       SignatureStream ss(sig);
   175       for ( ; !ss.at_return_type(); ss.next()) {
   176         BasicType bt = ss.type();
   177         const char* t = NULL;
   178         if (bt == T_OBJECT &&
   179             ss.as_symbol_or_null() == vmSymbols::java_lang_String()) {
   180           t = string_sig;
   181         } else if (bt == T_LONG) {
   182           t = long_sig;
   183         } else {
   184           t = int_sig;
   185         }
   186         stroffs[curstr++] = string_index;
   187         string_index += strlen(t) + 1;
   188       }
   189     }
   190   }
   191   secoffs[STRTAB] = offset;
   192   secsize[STRTAB] = string_index;
   193   offset += string_index;
   195   // Calculate the size of the rest
   196   for(int prvc = 0; prvc < providers_count; ++prvc) {
   197     JVM_DTraceProvider* provider = &providers[prvc];
   198     size_t provider_sec  = PROVIDERS     + prvc * 4;
   199     size_t probe_sec     = PROBES        + prvc * 4;
   200     size_t probeoffs_sec = PROBE_OFFSETS + prvc * 4;
   201     size_t argoffs_sec   = ARG_OFFSETS   + prvc * 4;
   203     // Allocate space for the provider data struction
   204     secoffs[provider_sec] = align_size_up(offset, alignment_for[PROVIDERS]);
   205     secsize[provider_sec] = sizeof(dof_provider_t);
   206     offset = secoffs[provider_sec] + secsize[provider_sec];
   208     // Allocate space for all the probes
   209     secoffs[probe_sec] = align_size_up(offset, alignment_for[PROBES]);
   210     secsize[probe_sec] = sizeof(dof_probe_t) * provider->probe_count;
   211     offset = secoffs[probe_sec] + secsize[probe_sec];
   213     // Allocate space for the probe offsets
   214     secoffs[probeoffs_sec] = align_size_up(offset, alignment_for[PROBE_OFFSETS]);
   215     secsize[probeoffs_sec] = sizeof(uint32_t) * provider->probe_count;
   216     offset = secoffs[probeoffs_sec] + secsize[probeoffs_sec];
   218     // We need number of arguments argoffs
   219     uint32_t argscount = 0;
   220     for(int prbc = 0; prbc < provider->probe_count; ++prbc) {
   221        JVM_DTraceProbe* p = &(provider->probes[prbc]);
   222        symbolOop sig = JNIHandles::resolve_jmethod_id(p->method)->signature();
   223        argscount += ArgumentCount(sig).size();
   224     }
   225     secoffs[argoffs_sec] = align_size_up(offset, alignment_for[ARG_OFFSETS]);
   226     secsize[argoffs_sec] = sizeof(uint8_t) * argscount;
   227     offset = secoffs[argoffs_sec] + secsize[argoffs_sec];
   228   }
   230   uint32_t size = offset;
   232   uint8_t* dof = NEW_RESOURCE_ARRAY(uint8_t, size);
   233   if (!dof) {
   234     return -1;
   235   }
   236   memset((void*)dof, 0, size);
   238   // Fill memory with proper values
   239   dof_hdr_t* hdr = (dof_hdr_t*)dof;
   240   hdr->dofh_ident[DOF_ID_MAG0]     = DOF_MAG_MAG0;
   241   hdr->dofh_ident[DOF_ID_MAG1]     = DOF_MAG_MAG1;
   242   hdr->dofh_ident[DOF_ID_MAG2]     = DOF_MAG_MAG2;
   243   hdr->dofh_ident[DOF_ID_MAG3]     = DOF_MAG_MAG3;
   244   hdr->dofh_ident[DOF_ID_MODEL]    = DOF_MODEL_NATIVE;  // No variants
   245   hdr->dofh_ident[DOF_ID_ENCODING] = DOF_ENCODE_NATIVE; // No variants
   246   hdr->dofh_ident[DOF_ID_VERSION]  = DOF_VERSION_1;     // No variants
   247   hdr->dofh_ident[DOF_ID_DIFVERS]  = DIF_VERSION_2;     // No variants
   248   // all other fields of ident to zero
   250   hdr->dofh_flags   = 0;
   251   hdr->dofh_hdrsize = sizeof(dof_hdr_t);
   252   hdr->dofh_secsize = sizeof(dof_sec_t);
   253   hdr->dofh_secnum  = num_sections;
   254   hdr->dofh_secoff  = sizeof(dof_hdr_t);
   255   hdr->dofh_loadsz  = size;
   256   hdr->dofh_filesz  = size;
   258   // First section: STRTAB
   259   dof_sec_t* sec = (dof_sec_t*)(dof + sizeof(dof_hdr_t));
   260   sec->dofs_type    = DOF_SECT_STRTAB;
   261   sec->dofs_align   = alignment_for[STRTAB];
   262   sec->dofs_flags   = DOF_SECF_LOAD;
   263   sec->dofs_entsize = 0;
   264   sec->dofs_offset  = secoffs[STRTAB];
   265   sec->dofs_size    = secsize[STRTAB];
   266   // Make data for this section
   267   char* str = (char*)(dof + sec->dofs_offset);
   269   *str = 0; str += 1; // ""
   271   // Run through all strings again
   272   for(int prvc = 0; prvc < providers_count; ++prvc) {
   273     JVM_DTraceProvider* provider = &providers[prvc];
   274     char* provider_name = java_lang_String::as_utf8_string(
   275         JNIHandles::resolve_non_null(provider->name));
   276     strcpy(str, provider_name);
   277     str += strlen(provider_name) + 1;
   279     // All probes
   280     for(int prbc = 0; prbc < provider->probe_count; ++prbc) {
   281       JVM_DTraceProbe* p = &(provider->probes[prbc]);
   283       char* function = java_lang_String::as_utf8_string(
   284           JNIHandles::resolve_non_null(p->function));
   285       strcpy(str, function);
   286       str += strlen(str) + 1;
   288       char* name = java_lang_String::as_utf8_string(
   289           JNIHandles::resolve_non_null(p->name));
   290       strcpy(str, name);
   291       str += strlen(name) + 1;
   293       symbolOop sig = JNIHandles::resolve_jmethod_id(p->method)->signature();
   294       SignatureStream ss(sig);
   295       for ( ; !ss.at_return_type(); ss.next()) {
   296         BasicType bt = ss.type();
   297         const char* t;
   298         if (bt == T_OBJECT &&
   299             ss.as_symbol_or_null() == vmSymbols::java_lang_String()) {
   300           t = string_sig;
   301         } else if (bt == T_LONG) {
   302           t = long_sig;
   303         } else {
   304           t = int_sig;
   305         }
   306         strcpy(str, t);
   307         str += strlen(t) + 1;
   308       }
   309     }
   310   }
   312   curstr = 1;
   313   for(int prvc = 0; prvc < providers_count; ++prvc) {
   314     JVM_DTraceProvider* provider = &providers[prvc];
   315     size_t provider_sec  = PROVIDERS     + prvc * 4;
   316     size_t probe_sec     = PROBES        + prvc * 4;
   317     size_t probeoffs_sec = PROBE_OFFSETS + prvc * 4;
   318     size_t argoffs_sec   = ARG_OFFSETS   + prvc * 4;
   320     // PROVIDER ///////////////////////////////////////////////////////////////
   321     // Section header
   322     sec = (dof_sec_t*)
   323         (dof + sizeof(dof_hdr_t) + sizeof(dof_sec_t) * provider_sec);
   324     sec->dofs_type    = DOF_SECT_PROVIDER;
   325     sec->dofs_align   = alignment_for[PROVIDERS];
   326     sec->dofs_flags   = DOF_SECF_LOAD;
   327     sec->dofs_entsize = 0;
   328     sec->dofs_offset  = secoffs[provider_sec];
   329     sec->dofs_size    = secsize[provider_sec];
   330     // Make provider decriiption
   331     dof_provider_t* prv = (dof_provider_t*)(dof + sec->dofs_offset);
   332     prv->dofpv_strtab   = STRTAB;
   333     prv->dofpv_probes   = probe_sec;
   334     prv->dofpv_prargs   = argoffs_sec;
   335     prv->dofpv_proffs   = probeoffs_sec;
   336     prv->dofpv_name     = stroffs[curstr++]; // Index in string table
   337     prv->dofpv_provattr = DOF_ATTR(
   338         provider->providerAttributes.nameStability,
   339         provider->providerAttributes.dataStability,
   340         provider->providerAttributes.dependencyClass);
   341     prv->dofpv_modattr = DOF_ATTR(
   342         provider->moduleAttributes.nameStability,
   343         provider->moduleAttributes.dataStability,
   344         provider->moduleAttributes.dependencyClass);
   345     prv->dofpv_funcattr = DOF_ATTR(
   346         provider->functionAttributes.nameStability,
   347         provider->functionAttributes.dataStability,
   348         provider->functionAttributes.dependencyClass);
   349     prv->dofpv_nameattr = DOF_ATTR(
   350         provider->nameAttributes.nameStability,
   351         provider->nameAttributes.dataStability,
   352         provider->nameAttributes.dependencyClass);
   353     prv->dofpv_argsattr = DOF_ATTR(
   354         provider->argsAttributes.nameStability,
   355         provider->argsAttributes.dataStability,
   356         provider->argsAttributes.dependencyClass);
   358     // PROBES /////////////////////////////////////////////////////////////////
   359     // Section header
   360     sec = (dof_sec_t*)
   361         (dof + sizeof(dof_hdr_t) + sizeof(dof_sec_t) * probe_sec);
   362     sec->dofs_type    = DOF_SECT_PROBES;
   363     sec->dofs_align   = alignment_for[PROBES];
   364     sec->dofs_flags   = DOF_SECF_LOAD;
   365     sec->dofs_entsize = sizeof(dof_probe_t);
   366     sec->dofs_offset  = secoffs[probe_sec];
   367     sec->dofs_size    = secsize[probe_sec];
   368     // Make probes descriptions
   369     uint32_t argsoffs = 0;
   370     for(int prbc = 0; prbc < provider->probe_count; ++prbc) {
   371       JVM_DTraceProbe* probe = &(provider->probes[prbc]);
   372       methodOop m = JNIHandles::resolve_jmethod_id(probe->method);
   373       int arg_count = ArgumentCount(m->signature()).size();
   374       assert(m->code() != NULL, "must have an nmethod");
   376       dof_probe_t* prb =
   377          (dof_probe_t*)(dof + sec->dofs_offset + prbc * sizeof(dof_probe_t));
   379       prb->dofpr_addr   = (uint64_t)m->code()->entry_point();
   380       prb->dofpr_func   = stroffs[curstr++]; // Index in string table
   381       prb->dofpr_name   = stroffs[curstr++]; // Index in string table
   382       prb->dofpr_nargv  = stroffs[curstr  ]; // Index in string table
   383       // We spent siglen strings here
   384       curstr += arg_count;
   385       prb->dofpr_xargv  = prb->dofpr_nargv;  // Same bunch of strings
   386       prb->dofpr_argidx = argsoffs;
   387       prb->dofpr_offidx = prbc;
   388       prb->dofpr_nargc  = arg_count;
   389       prb->dofpr_xargc  = arg_count;
   390       prb->dofpr_noffs  = 1; // Number of offsets
   391       // Next bunch of offsets
   392       argsoffs += arg_count;
   393     }
   395     // PROFFS /////////////////////////////////////////////////////////////////
   396     // Section header
   397     sec = (dof_sec_t*)
   398         (dof + sizeof(dof_hdr_t) + sizeof(dof_sec_t) * probeoffs_sec);
   399     sec->dofs_type    = DOF_SECT_PROFFS;
   400     sec->dofs_align   = alignment_for[PROBE_OFFSETS];
   401     sec->dofs_flags   = DOF_SECF_LOAD;
   402     sec->dofs_entsize = sizeof(uint32_t);
   403     sec->dofs_offset  = secoffs[probeoffs_sec];
   404     sec->dofs_size    = secsize[probeoffs_sec];
   405     // Make offsets
   406     for (int prbc = 0; prbc < provider->probe_count; ++prbc) {
   407       uint32_t* pof =
   408           (uint32_t*)(dof + sec->dofs_offset + sizeof(uint32_t) * prbc);
   409       JVM_DTraceProbe* probe = &(provider->probes[prbc]);
   410       methodOop m = JNIHandles::resolve_jmethod_id(probe->method);
   411       *pof = m->code()->trap_offset();
   412     }
   414     // PRARGS /////////////////////////////////////////////////////////////////
   415     // Section header
   416     sec = (dof_sec_t*)
   417         (dof + sizeof(dof_hdr_t) + sizeof(dof_sec_t) * argoffs_sec);
   418     sec->dofs_type    = DOF_SECT_PRARGS;
   419     sec->dofs_align   = alignment_for[ARG_OFFSETS];
   420     sec->dofs_flags   = DOF_SECF_LOAD;
   421     sec->dofs_entsize = sizeof(uint8_t);
   422     sec->dofs_offset  = secoffs[argoffs_sec];
   423     sec->dofs_size    = secsize[argoffs_sec];
   424     // Make arguments
   425     uint8_t* par = (uint8_t*)(dof + sec->dofs_offset);
   426     for (int prbc = 0; prbc < provider->probe_count; ++prbc) {
   427       JVM_DTraceProbe* p = &(provider->probes[prbc]);
   428       symbolOop sig = JNIHandles::resolve_jmethod_id(p->method)->signature();
   429       uint8_t count = (uint8_t)ArgumentCount(sig).size();
   430       for (uint8_t i = 0; i < count; ++i) {
   431         *par++ = i;
   432       }
   433     }
   434   }
   436   // Register module
   437   return dof_register(module, dof, moduleBaseAddress);
   438 }
   441 void DTraceJSDT::pd_dispose(int handle) {
   442   int fd;
   443   if (handle == -1) {
   444     return;
   445   }
   446   fd = dofhelper_open();
   447   if (fd < 0)
   448     return;
   449   ioctl(fd, DTRACEHIOC_REMOVE, handle);
   450   close(fd);
   451 }
   453 jboolean DTraceJSDT::pd_is_supported() {
   454   int fd = dofhelper_open();
   455   if (fd < 0) {
   456     return false;
   457   }
   458   close(fd);
   459   return true;
   460 }
   462 static const char* dofSecTypeFor(uint32_t type) {
   463   switch (type) {
   464     case 0:  return "DOF_SECT_NONE";
   465     case 1:  return "DOF_SECT_COMMENTS";
   466     case 2:  return "DOF_SECT_SOURCE";
   467     case 3:  return "DOF_SECT_ECBDESC";
   468     case 4:  return "DOF_SECT_PROBEDESC";
   469     case 5:  return "DOF_SECT_ACTDESC";
   470     case 6:  return "DOF_SECT_DIFOHDR";
   471     case 7:  return "DOF_SECT_DIF";
   472     case 8:  return "DOF_SECT_STRTAB";
   473     case 9:  return "DOF_SECT_VARTAB";
   474     case 10: return "DOF_SECT_RELTAB";
   475     case 11: return "DOF_SECT_TYPETAB";
   476     case 12: return "DOF_SECT_URELHDR";
   477     case 13: return "DOF_SECT_KRELHDR";
   478     case 14: return "DOF_SECT_OPTDESC";
   479     case 15: return "DOF_SECT_PROVIDER";
   480     case 16: return "DOF_SECT_PROBES";
   481     case 17: return "DOF_SECT_PRARGS";
   482     case 18: return "DOF_SECT_PROFFS";
   483     case 19: return "DOF_SECT_INTTAB";
   484     case 20: return "DOF_SECT_UTSNAME";
   485     case 21: return "DOF_SECT_XLTAB";
   486     case 22: return "DOF_SECT_XLMEMBERS";
   487     case 23: return "DOF_SECT_XLIMPORT";
   488     case 24: return "DOF_SECT_XLEXPORT";
   489     case 25: return "DOF_SECT_PREXPORT";
   490     case 26: return "DOF_SECT_PRENOFFS";
   491     default: return "<unknown>";
   492   }
   493 }
   495 static void printDOFStringTabSec(void* dof, dof_sec_t* sec) {
   496   size_t tab = sec->dofs_offset;
   497   size_t limit = sec->dofs_size;
   498   tty->print_cr("//   String Table:");
   499   for (size_t idx = 0; idx < limit; /*empty*/) {
   500     char* str = ((char*)dof) + tab + idx;
   501     tty->print_cr("//   [0x%x + 0x%x] '%s'", tab, idx, str);
   502     idx += strlen(str) + 1;
   503   }
   504 }
   506 static void printDOFProviderSec(void* dof, dof_sec_t* sec) {
   507   dof_provider_t* prov = (dof_provider_t*)((char*)dof + sec->dofs_offset);
   508   tty->print_cr("//   dof_provider_t {");
   509   tty->print_cr("//     dofpv_strtab = %d", prov->dofpv_strtab);
   510   tty->print_cr("//     dofpv_probes = %d", prov->dofpv_probes);
   511   tty->print_cr("//     dofpv_prargs = %d", prov->dofpv_prargs);
   512   tty->print_cr("//     dofpv_proffs = %d", prov->dofpv_proffs);
   513   tty->print_cr("//     dofpv_name = 0x%x", prov->dofpv_name);
   514   tty->print_cr("//     dofpv_provattr = 0x%08x", prov->dofpv_provattr);
   515   tty->print_cr("//     dofpv_modattr = 0x%08x", prov->dofpv_modattr);
   516   tty->print_cr("//     dofpv_funcattr = 0x%08x", prov->dofpv_funcattr);
   517   tty->print_cr("//     dofpv_nameattr = 0x%08x", prov->dofpv_nameattr);
   518   tty->print_cr("//     dofpv_argsattr = 0x%08x", prov->dofpv_argsattr);
   519   tty->print_cr("//   }");
   520 }
   522 static void printDOFProbesSec(void* dof, dof_sec_t* sec) {
   523   size_t idx = sec->dofs_offset;
   524   size_t limit = idx + sec->dofs_size;
   525   for (size_t idx = sec->dofs_offset; idx < limit; idx += sec->dofs_entsize) {
   526     dof_probe_t* prb = (dof_probe_t*)((char*)dof + idx);
   527     tty->print_cr("//   dof_probe_t {");
   528     tty->print_cr("//     dofpr_addr = 0x%016llx", prb->dofpr_addr);
   529     tty->print_cr("//     dofpr_func = 0x%x", prb->dofpr_func);
   530     tty->print_cr("//     dofpr_name = 0x%x", prb->dofpr_name);
   531     tty->print_cr("//     dofpr_nargv = 0x%x", prb->dofpr_nargv);
   532     tty->print_cr("//     dofpr_xargv = 0x%x", prb->dofpr_xargv);
   533     tty->print_cr("//     dofpr_argidx = 0x%x", prb->dofpr_argidx);
   534     tty->print_cr("//     dofpr_offidx = 0x%x", prb->dofpr_offidx);
   535     tty->print_cr("//     dofpr_nargc = %d", prb->dofpr_nargc);
   536     tty->print_cr("//     dofpr_xargc = %d", prb->dofpr_xargc);
   537     tty->print_cr("//     dofpr_noffs = %d", prb->dofpr_noffs);
   538     tty->print_cr("//   }");
   539   }
   540 }
   542 static void printDOFOffsetsSec(void* dof, dof_sec_t* sec) {
   543   size_t tab = sec->dofs_offset;
   544   size_t limit = sec->dofs_size;
   545   tty->print_cr("//   Offsets:");
   546   for (size_t idx = 0; idx < limit; idx += sec->dofs_entsize) {
   547     uint32_t* off = (uint32_t*)((char*)dof + tab + idx);
   548     tty->print_cr("//   [0x%x + 0x%x]: %d", tab, idx, *off);
   549   }
   550 }
   552 static void printDOFArgsSec(void* dof, dof_sec_t* sec) {
   553   size_t tab = sec->dofs_offset;
   554   size_t limit = sec->dofs_size;
   555   tty->print_cr("//   Arguments:");
   556   for (size_t idx = 0; idx < limit; idx += sec->dofs_entsize) {
   557     uint8_t* arg = (uint8_t*)((char*)dof + tab + idx);
   558     tty->print_cr("//   [0x%x + 0x%x]: %d", tab, idx, *arg);
   559   }
   560 }
   562 static void printDOFSection(void* dof, dof_sec_t* sec) {
   563   tty->print_cr("//   dof_sec_t {");
   564   tty->print_cr("//     dofs_type = 0x%x /* %s */",
   565                 sec->dofs_type, dofSecTypeFor(sec->dofs_type));
   566   tty->print_cr("//     dofs_align = %d", sec->dofs_align);
   567   tty->print_cr("//     dofs_flags = 0x%x", sec->dofs_flags);
   568   tty->print_cr("//     dofs_entsize = %d", sec->dofs_entsize);
   569   tty->print_cr("//     dofs_offset = 0x%llx", sec->dofs_offset);
   570   tty->print_cr("//     dofs_size = %lld", sec->dofs_size);
   571   tty->print_cr("//   }");
   572   switch (sec->dofs_type) {
   573     case DOF_SECT_STRTAB:    printDOFStringTabSec(dof, sec); break;
   574     case DOF_SECT_PROVIDER:  printDOFProviderSec(dof, sec);  break;
   575     case DOF_SECT_PROBES:    printDOFProbesSec(dof, sec);    break;
   576     case DOF_SECT_PROFFS:    printDOFOffsetsSec(dof, sec);   break;
   577     case DOF_SECT_PRARGS:    printDOFArgsSec(dof, sec);      break;
   578     default: tty->print_cr("//   <section type not recognized>");
   579   }
   580 }
   582 static void printDOFHeader(dof_hdr_t* hdr) {
   583   tty->print_cr("//   dof_hdr_t {");
   584   tty->print_cr("//     dofh_ident[DOF_ID_MAG0] = 0x%x",
   585                 hdr->dofh_ident[DOF_ID_MAG0]);
   586   tty->print_cr("//     dofh_ident[DOF_ID_MAG1] = 0x%x",
   587                 hdr->dofh_ident[DOF_ID_MAG1]);
   588   tty->print_cr("//     dofh_ident[DOF_ID_MAG2] = 0x%x",
   589                 hdr->dofh_ident[DOF_ID_MAG2]);
   590   tty->print_cr("//     dofh_ident[DOF_ID_MAG3] = 0x%x",
   591                 hdr->dofh_ident[DOF_ID_MAG3]);
   592   tty->print_cr("//     dofh_ident[DOF_ID_MODEL] = 0x%x",
   593                 hdr->dofh_ident[DOF_ID_MODEL]);
   594   tty->print_cr("//     dofh_ident[DOF_ID_ENCODING] = 0x%x",
   595                 hdr->dofh_ident[DOF_ID_ENCODING]);
   596   tty->print_cr("//     dofh_ident[DOF_ID_VERSION] = 0x%x",
   597                 hdr->dofh_ident[DOF_ID_VERSION]);
   598   tty->print_cr("//     dofh_ident[DOF_ID_DIFVERS] = 0x%x",
   599                 hdr->dofh_ident[DOF_ID_DIFVERS]);
   600   tty->print_cr("//     dofh_flags = 0x%x", hdr->dofh_flags);
   601   tty->print_cr("//     dofh_hdrsize = %d", hdr->dofh_hdrsize);
   602   tty->print_cr("//     dofh_secsize = %d", hdr->dofh_secsize);
   603   tty->print_cr("//     dofh_secnum = %d", hdr->dofh_secnum);
   604   tty->print_cr("//     dofh_secoff = %lld", hdr->dofh_secoff);
   605   tty->print_cr("//     dofh_loadsz = %lld", hdr->dofh_loadsz);
   606   tty->print_cr("//     dofh_filesz = %lld", hdr->dofh_filesz);
   607   tty->print_cr("//   }");
   608 }
   610 static void printDOF(void* dof) {
   611   dof_hdr_t* hdr = (dof_hdr_t*)dof;
   612   printDOFHeader(hdr);
   613   for (int i = 0; i < hdr->dofh_secnum; ++i) {
   614     dof_sec_t* sec =
   615       (dof_sec_t*)((char*)dof + sizeof(dof_hdr_t) + i * sizeof(dof_sec_t));
   616     tty->print_cr("//   [Section #%d]", i);
   617     printDOFSection(dof, sec);
   618   }
   619 }
   621 /**
   622  * This prints out hex data in a 'windbg' or 'xxd' form, where each line is:
   623  *   <hex-address>: 8 * <hex-halfword> <ascii translation>
   624  * example:
   625  * 0000000: 7f44 4f46 0102 0102 0000 0000 0000 0000  .DOF............
   626  * 0000010: 0000 0000 0000 0040 0000 0020 0000 0005  .......@... ....
   627  * 0000020: 0000 0000 0000 0040 0000 0000 0000 015d  .......@.......]
   628  * ...
   629  */
   630 static void printDOFRawData(void* dof) {
   631   size_t size = ((dof_hdr_t*)dof)->dofh_loadsz;
   632   size_t limit = (size + 16) / 16 * 16;
   633   for (size_t i = 0; i < limit; ++i) {
   634     if (i % 16 == 0) {
   635       tty->print("%07x:", i);
   636     }
   637     if (i % 2 == 0) {
   638       tty->print(" ");
   639     }
   640     if (i < size) {
   641       tty->print("%02x", ((unsigned char*)dof)[i]);
   642     } else {
   643       tty->print("  ");
   644     }
   645     if ((i + 1) % 16 == 0) {
   646       tty->print("  ");
   647       for (size_t j = 0; j < 16; ++j) {
   648         size_t idx = i + j - 15;
   649         char c = ((char*)dof)[idx];
   650         if (idx < size) {
   651           tty->print("%c", c >= 32 && c <= 126 ? c : '.');
   652         }
   653       }
   654       tty->print_cr("");
   655     }
   656   }
   657   tty->print_cr("");
   658 }
   660 static void printDOFHelper(dof_helper_t* helper) {
   661   tty->print_cr("// dof_helper_t {");
   662   tty->print_cr("//   dofhp_mod = \"%s\"", helper->dofhp_mod);
   663   tty->print_cr("//   dofhp_addr = 0x%016llx", helper->dofhp_addr);
   664   tty->print_cr("//   dofhp_dof = 0x%016llx", helper->dofhp_dof);
   665   printDOF((void*)helper->dofhp_dof);
   666   tty->print_cr("// }");
   667   printDOFRawData((void*)helper->dofhp_dof);
   668 }
   670 #else // ndef HAVE_DTRACE_H
   672 // Get here if we're not building on at least Solaris 10
   673 int DTraceJSDT::pd_activate(
   674   void* baseAddress, jstring module,
   675   jint provider_count, JVM_DTraceProvider* providers) {
   676   return -1;
   677 }
   679 void DTraceJSDT::pd_dispose(int handle) {
   680 }
   682 jboolean DTraceJSDT::pd_is_supported() {
   683   return false;
   684 }
   685 #endif

mercurial