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