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