1 /*
   2  * Copyright (c) 2003, 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 /* This file is auto-generated */
  26 #include "JvmOffsetsIndex.h"
  27 
  28 #define DEBUG
  29 
  30 #ifdef DEBUG
  31 #define MARK_LINE this->line = __LINE__
  32 #else
  33 #define MARK_LINE 
  34 #endif
  35 
  36 #ifdef _LP64
  37 #define STACK_BIAS 0x7ff
  38 #define pointer uint64_t
  39 #else
  40 #define STACK_BIAS 0
  41 #define pointer uint32_t
  42 #endif
  43 
  44 extern pointer __JvmOffsets;
  45 
  46 extern pointer __1cJCodeCacheF_heap_;
  47 extern pointer __1cIUniverseO_collectedHeap_;
  48 
  49 extern pointer __1cHnmethodG__vtbl_;
  50 extern pointer __1cNMethodG__vtbl_;
  51 extern pointer __1cKBufferBlobG__vtbl_;
  52 
  53 #define copyin_ptr(ADDR)    *(pointer*)  copyin((pointer) (ADDR), sizeof(pointer))
  54 #define copyin_uchar(ADDR)  *(uchar_t*)  copyin((pointer) (ADDR), sizeof(uchar_t))
  55 #define copyin_uint16(ADDR) *(uint16_t*) copyin((pointer) (ADDR), sizeof(uint16_t))
  56 #define copyin_uint32(ADDR) *(uint32_t*) copyin((pointer) (ADDR), sizeof(uint32_t))
  57 #define copyin_int32(ADDR)  *(int32_t*)  copyin((pointer) (ADDR), sizeof(int32_t))
  58 #define copyin_uint8(ADDR)  *(uint8_t*)  copyin((pointer) (ADDR), sizeof(uint8_t))
  59 
  60 #define SAME(x) x
  61 #define copyin_offset(JVM_CONST)  JVM_CONST = \
  62         copyin_int32(JvmOffsetsPtr + SAME(IDX_)JVM_CONST * sizeof(int32_t))
  63 
  64 int init_done;
  65 
  66 dtrace:helper:ustack:
  67 {
  68   MARK_LINE;
  69   this->done = 0;
  70   /*
  71    * TBD:
  72    * Here we initialize init_done, otherwise jhelper does not work.
  73    * Therefore, copyin_offset() statements work multiple times now.
  74    * There is a hope we could avoid it in the future, and so,
  75    * this initialization can be removed.
  76    */
  77   init_done  = 0;
  78   this->error = (char *) NULL;
  79   this->result = (char *) NULL;
  80   this->isMethod = 0;
  81   this->codecache = 0;
  82   this->klass = (pointer) NULL;
  83   this->vtbl  = (pointer) NULL;
  84   this->suffix = '\0';
  85 }
  86 
  87 dtrace:helper:ustack:
  88 {
  89   MARK_LINE;
  90   /* Initialization of JvmOffsets constants */
  91   JvmOffsetsPtr = (pointer) &``__JvmOffsets;
  92 }
  93 
  94 dtrace:helper:ustack:
  95 /!init_done && !this->done/
  96 {
  97   MARK_LINE;
  98   init_done = 1;
  99 
 100   copyin_offset(COMPILER);
 101   copyin_offset(OFFSET_CollectedHeap_reserved);
 102   copyin_offset(OFFSET_MemRegion_start);
 103   copyin_offset(OFFSET_MemRegion_word_size);
 104   copyin_offset(SIZE_HeapWord);
 105 
 106   copyin_offset(OFFSET_interpreter_frame_method);
 107   copyin_offset(OFFSET_Klass_name);
 108   copyin_offset(OFFSET_ConstantPool_pool_holder);
 109 
 110   copyin_offset(OFFSET_HeapBlockHeader_used);
 111   copyin_offset(OFFSET_oopDesc_metadata);
 112 
 113   copyin_offset(OFFSET_Symbol_length);
 114   copyin_offset(OFFSET_Symbol_body);
 115 
 116   copyin_offset(OFFSET_Method_constMethod);
 117   copyin_offset(OFFSET_ConstMethod_constants);
 118   copyin_offset(OFFSET_ConstMethod_name_index);
 119   copyin_offset(OFFSET_ConstMethod_signature_index);
 120 
 121   copyin_offset(OFFSET_CodeHeap_memory);
 122   copyin_offset(OFFSET_CodeHeap_segmap);
 123   copyin_offset(OFFSET_CodeHeap_log2_segment_size);
 124 
 125   copyin_offset(OFFSET_VirtualSpace_low);
 126   copyin_offset(OFFSET_VirtualSpace_high);
 127 
 128   copyin_offset(OFFSET_CodeBlob_name);
 129 
 130   copyin_offset(OFFSET_nmethod_method);
 131   copyin_offset(SIZE_HeapBlockHeader);
 132   copyin_offset(SIZE_oopDesc);
 133   copyin_offset(SIZE_ConstantPool);
 134 
 135   copyin_offset(OFFSET_NarrowPtrStruct_base);
 136   copyin_offset(OFFSET_NarrowPtrStruct_shift);
 137 
 138   /*
 139    * The PC to translate is in arg0.
 140    */
 141   this->pc = arg0;
 142 
 143   /*
 144    * The methodPtr is in %l2 on SPARC.  This can be found at
 145    * offset 8 from the frame pointer on 32-bit processes.
 146    */
 147 #if   defined(__sparc)
 148   this->methodPtr = copyin_ptr(arg1 + 2 * sizeof(pointer) + STACK_BIAS);
 149 #elif defined(__i386) || defined(__amd64)
 150   this->methodPtr = copyin_ptr(arg1 + OFFSET_interpreter_frame_method);
 151 #else
 152 #error "Don't know architecture"
 153 #endif
 154 
 155   this->CodeCache_heap_address = copyin_ptr(&``__1cJCodeCacheF_heap_);
 156 
 157   /* Reading volatile values */
 158   this->CodeCache_low = copyin_ptr(this->CodeCache_heap_address + 
 159       OFFSET_CodeHeap_memory + OFFSET_VirtualSpace_low);
 160 
 161   this->CodeCache_high = copyin_ptr(this->CodeCache_heap_address +
 162       OFFSET_CodeHeap_memory + OFFSET_VirtualSpace_high);
 163 
 164   this->CodeCache_segmap_low = copyin_ptr(this->CodeCache_heap_address +
 165       OFFSET_CodeHeap_segmap + OFFSET_VirtualSpace_low);
 166 
 167   this->CodeCache_segmap_high = copyin_ptr(this->CodeCache_heap_address +
 168       OFFSET_CodeHeap_segmap + OFFSET_VirtualSpace_high);
 169 
 170   this->CodeHeap_log2_segment_size = copyin_uint32(
 171       this->CodeCache_heap_address + OFFSET_CodeHeap_log2_segment_size);
 172 
 173   this->Method_vtbl             = (pointer) &``__1cNMethodG__vtbl_;
 174 
 175   /*
 176    * Get Java heap bounds
 177    */
 178   this->Universe_collectedHeap = copyin_ptr(&``__1cIUniverseO_collectedHeap_);
 179   this->heap_start = copyin_ptr(this->Universe_collectedHeap +
 180       OFFSET_CollectedHeap_reserved +
 181       OFFSET_MemRegion_start);
 182   this->heap_size = SIZE_HeapWord *
 183     copyin_ptr(this->Universe_collectedHeap +
 184         OFFSET_CollectedHeap_reserved +
 185         OFFSET_MemRegion_word_size
 186         );
 187   this->heap_end = this->heap_start + this->heap_size;
 188 }
 189 
 190 dtrace:helper:ustack:
 191 /!this->done &&
 192 this->CodeCache_low <= this->pc && this->pc < this->CodeCache_high/
 193 {
 194   MARK_LINE;
 195   this->codecache = 1;
 196 
 197   /*
 198    * Find start.
 199    */
 200   this->segment = (this->pc - this->CodeCache_low) >>
 201     this->CodeHeap_log2_segment_size;
 202   this->block = this->CodeCache_segmap_low;
 203   this->tag = copyin_uchar(this->block + this->segment);
 204   "second";
 205 }
 206 
 207 dtrace:helper:ustack:
 208 /!this->done && this->codecache && this->tag > 0/
 209 {
 210   MARK_LINE;
 211   this->tag = copyin_uchar(this->block + this->segment);
 212   this->segment = this->segment - this->tag;
 213 }
 214 
 215 dtrace:helper:ustack:
 216 /!this->done && this->codecache && this->tag > 0/
 217 {
 218   MARK_LINE;
 219   this->tag = copyin_uchar(this->block + this->segment);
 220   this->segment = this->segment - this->tag;
 221 }
 222 
 223 dtrace:helper:ustack:
 224 /!this->done && this->codecache && this->tag > 0/
 225 {
 226   MARK_LINE;
 227   this->tag = copyin_uchar(this->block + this->segment);
 228   this->segment = this->segment - this->tag;
 229 }
 230 
 231 dtrace:helper:ustack:
 232 /!this->done && this->codecache && this->tag > 0/
 233 {
 234   MARK_LINE;
 235   this->tag = copyin_uchar(this->block + this->segment);
 236   this->segment = this->segment - this->tag;
 237 }
 238 
 239 dtrace:helper:ustack:
 240 /!this->done && this->codecache && this->tag > 0/
 241 {
 242   MARK_LINE;
 243   this->tag = copyin_uchar(this->block + this->segment);
 244   this->segment = this->segment - this->tag;
 245 }
 246 
 247 dtrace:helper:ustack:
 248 /!this->done && this->codecache && this->tag > 0/
 249 {
 250   MARK_LINE;
 251   this->error = "<couldn't find start>";
 252   this->done = 1;
 253 }
 254 
 255 dtrace:helper:ustack:
 256 /!this->done && this->codecache/
 257 {
 258   MARK_LINE;
 259   this->block = this->CodeCache_low +
 260     (this->segment << this->CodeHeap_log2_segment_size);
 261   this->used = copyin_uint32(this->block + OFFSET_HeapBlockHeader_used);
 262 }
 263 
 264 dtrace:helper:ustack:
 265 /!this->done && this->codecache && !this->used/
 266 {
 267   MARK_LINE;
 268   this->error = "<block not in use>";
 269   this->done = 1;
 270 }
 271 
 272 dtrace:helper:ustack:
 273 /!this->done && this->codecache/
 274 {
 275   MARK_LINE;
 276   this->start = this->block + SIZE_HeapBlockHeader;
 277   this->vtbl = copyin_ptr(this->start);
 278 
 279   this->nmethod_vtbl            = (pointer) &``__1cHnmethodG__vtbl_;
 280   this->BufferBlob_vtbl         = (pointer) &``__1cKBufferBlobG__vtbl_;
 281 }
 282 
 283 dtrace:helper:ustack:
 284 /!this->done && this->vtbl == this->nmethod_vtbl/
 285 {
 286   MARK_LINE;
 287   this->methodPtr = copyin_ptr(this->start + OFFSET_nmethod_method);
 288   this->suffix = '*';
 289   this->isMethod = 1;
 290 }
 291 
 292 dtrace:helper:ustack:
 293 /!this->done && this->vtbl == this->BufferBlob_vtbl/
 294 {
 295   MARK_LINE;
 296   this->name = copyin_ptr(this->start + OFFSET_CodeBlob_name);
 297 }
 298 
 299 
 300 dtrace:helper:ustack:
 301 /!this->done && this->vtbl == this->BufferBlob_vtbl && this->methodPtr != 0/
 302 {
 303   MARK_LINE;
 304   this->klass = copyin_ptr(this->methodPtr);
 305   this->isMethod = this->klass == this->Method_vtbl;
 306   this->done = !this->isMethod;
 307 }
 308 
 309 dtrace:helper:ustack:
 310 /!this->done && !this->isMethod/
 311 {
 312   MARK_LINE;
 313   this->name = copyin_ptr(this->start + OFFSET_CodeBlob_name);
 314   this->result = this->name != 0 ? copyinstr(this->name) : "<CodeBlob>";
 315   this->done = 1;
 316 }
 317 
 318 dtrace:helper:ustack:
 319 /!this->done && this->isMethod/
 320 {
 321   MARK_LINE;
 322   this->constMethod = copyin_ptr(this->methodPtr +
 323       OFFSET_Method_constMethod);
 324 
 325   this->nameIndex = copyin_uint16(this->constMethod +
 326       OFFSET_ConstMethod_name_index);
 327 
 328   this->signatureIndex = copyin_uint16(this->constMethod +
 329       OFFSET_ConstMethod_signature_index);
 330 
 331   this->constantPool = copyin_ptr(this->constMethod +
 332       OFFSET_ConstMethod_constants);
 333 
 334   this->nameSymbol = copyin_ptr(this->constantPool +
 335       this->nameIndex * sizeof (pointer) + SIZE_ConstantPool);
 336 
 337   this->nameSymbolLength = copyin_uint16(this->nameSymbol +
 338       OFFSET_Symbol_length);
 339 
 340   this->signatureSymbol = copyin_ptr(this->constantPool +
 341       this->signatureIndex * sizeof (pointer) + SIZE_ConstantPool);
 342 
 343   this->signatureSymbolLength = copyin_uint16(this->signatureSymbol +
 344       OFFSET_Symbol_length);
 345 
 346   this->klassPtr = copyin_ptr(this->constantPool +
 347       OFFSET_ConstantPool_pool_holder);
 348 
 349   this->klassSymbol = copyin_ptr(this->klassPtr +
 350       OFFSET_Klass_name);
 351 
 352   this->klassSymbolLength = copyin_uint16(this->klassSymbol +
 353       OFFSET_Symbol_length);
 354 
 355   /*
 356    * Enough for three strings, plus the '.', plus the trailing '\0'.
 357    */
 358   this->result = (char *) alloca(this->klassSymbolLength +
 359       this->nameSymbolLength +
 360       this->signatureSymbolLength + 2 + 1);
 361 
 362   copyinto(this->klassSymbol + OFFSET_Symbol_body,
 363       this->klassSymbolLength, this->result);
 364 
 365   /*
 366    * Add the '.' between the class and the name.
 367    */
 368   this->result[this->klassSymbolLength] = '.';
 369 
 370   copyinto(this->nameSymbol + OFFSET_Symbol_body,
 371       this->nameSymbolLength,
 372       this->result + this->klassSymbolLength + 1);
 373 
 374   copyinto(this->signatureSymbol + OFFSET_Symbol_body,
 375       this->signatureSymbolLength,
 376       this->result + this->klassSymbolLength +
 377       this->nameSymbolLength + 1);
 378 
 379   /*
 380    * Now we need to add a trailing '\0' and possibly a tag character.
 381    */
 382   this->result[this->klassSymbolLength + 1 + 
 383       this->nameSymbolLength +
 384       this->signatureSymbolLength] = this->suffix;
 385   this->result[this->klassSymbolLength + 2 + 
 386       this->nameSymbolLength +
 387       this->signatureSymbolLength] = '\0';
 388 
 389   this->done = 1;
 390 }
 391 
 392 dtrace:helper:ustack:
 393 /this->done && this->error == (char *) NULL/
 394 {
 395   this->result;   
 396 }
 397 
 398 dtrace:helper:ustack:
 399 /this->done && this->error != (char *) NULL/
 400 {
 401   this->error;
 402 }
 403 
 404 dtrace:helper:ustack:
 405 /!this->done && this->codecache/
 406 {
 407   this->done = 1;
 408   "error";
 409 }
 410 
 411 
 412 dtrace:helper:ustack:
 413 /!this->done/
 414 {
 415   NULL;
 416 }