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 #include <stdio.h>
  26 #include <stdlib.h>
  27 #include <string.h>
  28 #include <errno.h>
  29 #include <gelf.h>
  30 
  31 #include "libjvm_db.h"
  32 #include "JvmOffsets.h"
  33 
  34 #define LIBJVM_SO "libjvm.so"
  35 
  36 #if defined(i386) || defined(__i386) || defined(__amd64)
  37 #ifdef COMPILER2
  38 #define X86_COMPILER2
  39 #endif /* COMPILER2 */
  40 #endif /* i386 */
  41 
  42 typedef struct {
  43     short     vf_cnt; /* number of recognized java vframes */
  44     short     bci;    /* current frame method byte code index */
  45     int       line;   /* current frame method source line */
  46     uint64_t new_fp; /* fp for the next frame */
  47     uint64_t new_pc; /* pc for the next frame */
  48     uint64_t new_sp; /* "raw" sp for the next frame (includes extension by interpreter/adapter */
  49     char      locinf; /* indicates there is valid location info */
  50 } Jframe_t;
  51 
  52 int Jlookup_by_regs(jvm_agent_t* J, const prgregset_t regs, char *name,
  53                     size_t size, Jframe_t *jframe);
  54 
  55 int main(int arg) { return arg; }
  56 
  57 static int debug = 0;
  58 
  59 static void failed(int err, const char * file, int line) {
  60   if (debug) {
  61     fprintf(stderr, "failed %d at %s:%d\n", err, file, line);
  62   }
  63 }
  64 
  65 static void warn(const char * file, int line, const char * msg) {
  66   if (debug) {
  67     fprintf(stderr, "warning: %s at %s:%d\n", msg, file, line);
  68   }
  69 }
  70 
  71 static void warn1(const char * file, int line, const char * msg, intptr_t arg1) {
  72   if (debug) {
  73     fprintf(stderr, "warning: ");
  74     fprintf(stderr, msg, arg1);
  75     fprintf(stderr, " at %s:%d\n", file, line);
  76   }
  77 }
  78 
  79 #define CHECK_FAIL(err) \
  80         if (err != PS_OK) { failed(err, __FILE__, __LINE__); goto fail; }
  81 #define WARN(msg)  warn(__FILE__, __LINE__, msg)
  82 #define WARN1(msg, arg1)  warn1(__FILE__, __LINE__, msg, arg1)
  83 
  84 typedef struct VMStructEntry {
  85   const char * typeName;           /* The type name containing the given field (example: "Klass") */
  86   const char * fieldName;          /* The field name within the type           (example: "_name") */
  87   uint64_t address;                /* Address of field; only used for static fields */
  88                                    /* ("offset" can not be reused because of apparent SparcWorks compiler bug */
  89                                    /* in generation of initializer data) */
  90 } VMStructEntry;
  91 
  92 /* Prototyping inlined methods */
  93 
  94 int sprintf(char *s, const char *format, ...);
  95 
  96 #define SZ16  sizeof(int16_t)
  97 #define SZ32  sizeof(int32_t)
  98 
  99 #define COMP_METHOD_SIGN '*'
 100 
 101 #define MAX_VFRAMES_CNT 256
 102 
 103 typedef struct vframe {
 104   uint64_t method;
 105   int32_t  sender_decode_offset;
 106   int32_t  methodIdx;
 107   int32_t  bci;
 108   int32_t  line;
 109 } Vframe_t;
 110 
 111 typedef struct frame {
 112   uintptr_t fp;
 113   uintptr_t pc;
 114   uintptr_t sp;
 115   uintptr_t sender_sp; // The unextended sp of the caller
 116 } Frame_t;
 117 
 118 typedef struct Nmethod_t {
 119   struct jvm_agent* J;
 120   Jframe_t *jframe;
 121 
 122   uint64_t nm;                  /* _nmethod */
 123   uint64_t pc;
 124   uint64_t pc_desc;
 125 
 126   int32_t  orig_pc_offset;      /* _orig_pc_offset */
 127   int32_t  instrs_beg;          /* _code_offset */
 128   int32_t  instrs_end;
 129   int32_t  deopt_beg;           /* _deoptimize_offset */
 130   int32_t  scopes_data_beg;     /* _scopes_data_offset */
 131   int32_t  scopes_data_end;
 132   int32_t  metadata_beg;        /* _metadata_offset */
 133   int32_t  metadata_end;
 134   int32_t  scopes_pcs_beg;      /* _scopes_pcs_offset */
 135   int32_t  scopes_pcs_end;
 136 
 137   int      vf_cnt;
 138   Vframe_t vframes[MAX_VFRAMES_CNT];
 139 } Nmethod_t;
 140 
 141 struct jvm_agent {
 142   struct ps_prochandle* P;
 143 
 144   uint64_t nmethod_vtbl;
 145   uint64_t CodeBlob_vtbl;
 146   uint64_t BufferBlob_vtbl;
 147   uint64_t RuntimeStub_vtbl;
 148   uint64_t Method_vtbl;
 149 
 150   uint64_t Use_Compressed_Oops_address;
 151   uint64_t Universe_narrow_oop_base_address;
 152   uint64_t Universe_narrow_oop_shift_address;
 153   uint64_t CodeCache_heaps_address;
 154 
 155   /* Volatiles */
 156   uint8_t  Use_Compressed_Oops;
 157   uint64_t Universe_narrow_oop_base;
 158   uint32_t Universe_narrow_oop_shift;
 159   // Code cache heaps
 160   int32_t  Number_of_heaps;
 161   uint64_t* Heap_low;
 162   uint64_t* Heap_high;
 163   uint64_t* Heap_segmap_low;
 164   uint64_t* Heap_segmap_high;
 165 
 166   int32_t  SIZE_CodeCache_log2_segment;
 167 
 168   uint64_t methodPtr;
 169   uint64_t bcx;
 170 
 171   Nmethod_t *N;                 /*Inlined methods support */
 172   Frame_t   prev_fr;
 173   Frame_t   curr_fr;
 174 };
 175 
 176 static int
 177 read_string(struct ps_prochandle *P,
 178         char *buf,              /* caller's buffer */
 179         size_t size,            /* upper limit on bytes to read */
 180         uintptr_t addr)         /* address in process */
 181 {
 182   int err = PS_OK;
 183   while (size-- > 1 && err == PS_OK) {
 184     err = ps_pread(P, addr, buf, 1);
 185     if (*buf == '\0') {
 186       return PS_OK;
 187     }
 188     addr += 1;
 189     buf += 1;
 190   }
 191   return -1;
 192 }
 193 
 194 static int read_compressed_pointer(jvm_agent_t* J, uint64_t base, uint32_t *ptr) {
 195   int err = -1;
 196   uint32_t ptr32;
 197   err = ps_pread(J->P, base, &ptr32, sizeof(uint32_t));
 198   *ptr = ptr32;
 199   return err;
 200 }
 201 
 202 static int read_pointer(jvm_agent_t* J, uint64_t base, uint64_t* ptr) {
 203   int err = -1;
 204   uint32_t ptr32;
 205 
 206   switch (DATA_MODEL) {
 207   case PR_MODEL_LP64:
 208     err = ps_pread(J->P, base, ptr, sizeof(uint64_t));
 209     break;
 210   case PR_MODEL_ILP32:
 211     err = ps_pread(J->P, base, &ptr32, sizeof(uint32_t));
 212     *ptr = ptr32;
 213     break;
 214   }
 215 
 216   return err;
 217 }
 218 
 219 static int read_string_pointer(jvm_agent_t* J, uint64_t base, const char ** stringp) {
 220   uint64_t ptr;
 221   int err;
 222   char buffer[1024];
 223 
 224   *stringp = NULL;
 225   err = read_pointer(J, base, &ptr);
 226   CHECK_FAIL(err);
 227   if (ptr != 0) {
 228     err = read_string(J->P, buffer, sizeof(buffer), ptr);
 229     CHECK_FAIL(err);
 230     *stringp = strdup(buffer);
 231   }
 232   return PS_OK;
 233 
 234  fail:
 235   return err;
 236 }
 237 
 238 static int parse_vmstruct_entry(jvm_agent_t* J, uint64_t base, VMStructEntry* vmp) {
 239   uint64_t ptr;
 240   int err;
 241 
 242   err = read_string_pointer(J, base + OFFSET_VMStructEntrytypeName, &vmp->typeName);
 243   CHECK_FAIL(err);
 244   err = read_string_pointer(J, base + OFFSET_VMStructEntryfieldName, &vmp->fieldName);
 245   CHECK_FAIL(err);
 246   err = read_pointer(J, base + OFFSET_VMStructEntryaddress, &vmp->address);
 247   CHECK_FAIL(err);
 248 
 249   return PS_OK;
 250 
 251  fail:
 252   if (vmp->typeName != NULL) free((void*)vmp->typeName);
 253   if (vmp->fieldName != NULL) free((void*)vmp->fieldName);
 254   return err;
 255 }
 256 
 257 static int parse_vmstructs(jvm_agent_t* J) {
 258   VMStructEntry  vmVar;
 259   VMStructEntry* vmp = &vmVar;
 260   uint64_t gHotSpotVMStructs;
 261   psaddr_t sym_addr;
 262   uint64_t base;
 263   int err;
 264 
 265   err = ps_pglobal_lookup(J->P, LIBJVM_SO, "gHotSpotVMStructs", &sym_addr);
 266   CHECK_FAIL(err);
 267   err = read_pointer(J, sym_addr, &gHotSpotVMStructs);
 268   CHECK_FAIL(err);
 269   base = gHotSpotVMStructs;
 270 
 271   err = PS_OK;
 272   while (err == PS_OK) {
 273     memset(vmp, 0, sizeof(VMStructEntry));
 274     err = parse_vmstruct_entry(J, base, vmp);
 275     if (err != PS_OK || vmp->typeName == NULL) {
 276       break;
 277     }
 278 
 279     if (vmp->typeName[0] == 'C' && strcmp("CodeCache", vmp->typeName) == 0) {
 280       /* Read _heaps field of type GrowableArray<CodeHeaps*>*      */
 281       if (strcmp("_heaps", vmp->fieldName) == 0) {
 282         err = read_pointer(J, vmp->address, &J->CodeCache_heaps_address);
 283       } 
 284     } else if (vmp->typeName[0] == 'U' && strcmp("Universe", vmp->typeName) == 0) {
 285       if (strcmp("_narrow_oop._base", vmp->fieldName) == 0) {
 286         J->Universe_narrow_oop_base_address = vmp->address;
 287       }
 288       if (strcmp("_narrow_oop._shift", vmp->fieldName) == 0) {
 289         J->Universe_narrow_oop_shift_address = vmp->address;
 290       }
 291     }
 292     CHECK_FAIL(err);
 293 
 294     base += SIZE_VMStructEntry;
 295     if (vmp->typeName != NULL) free((void*)vmp->typeName);
 296     if (vmp->fieldName != NULL) free((void*)vmp->fieldName);
 297   }
 298 
 299   return PS_OK;
 300 
 301  fail:
 302   if (vmp->typeName != NULL) free((void*)vmp->typeName);
 303   if (vmp->fieldName != NULL) free((void*)vmp->fieldName);
 304   return -1;
 305 }
 306 
 307 static int find_symbol(jvm_agent_t* J, const char *name, uint64_t* valuep) {
 308   psaddr_t sym_addr;
 309   int err;
 310 
 311   err = ps_pglobal_lookup(J->P, LIBJVM_SO, name, &sym_addr);
 312   if (err != PS_OK) goto fail;
 313   *valuep = sym_addr;
 314   return PS_OK;
 315 
 316  fail:
 317   return err;
 318 }
 319 
 320 static int read_volatiles(jvm_agent_t* J) {
 321   int i;
 322   uint64_t array_data;
 323   uint64_t code_heap_address;
 324   int err;
 325 
 326   err = find_symbol(J, "UseCompressedOops", &J->Use_Compressed_Oops_address);
 327   if (err == PS_OK) {
 328     err = ps_pread(J->P,  J->Use_Compressed_Oops_address, &J->Use_Compressed_Oops, sizeof(uint8_t));
 329     CHECK_FAIL(err);
 330   } else {
 331     J->Use_Compressed_Oops = 0;
 332   }
 333 
 334   err = read_pointer(J, J->Universe_narrow_oop_base_address, &J->Universe_narrow_oop_base);
 335   CHECK_FAIL(err);
 336   err = ps_pread(J->P,  J->Universe_narrow_oop_shift_address, &J->Universe_narrow_oop_shift, sizeof(uint32_t));
 337   CHECK_FAIL(err);
 338 
 339   /* CodeCache_heaps_address points to GrowableArray<CodeHeaps*>, read _data field 
 340      pointing to the first entry of type CodeCache* in the array */
 341   err = read_pointer(J, J->CodeCache_heaps_address + OFFSET_GrowableArray_CodeHeap_data, &array_data);
 342   /* Read _len field containing the number of code heaps */
 343   err = ps_pread(J->P, J->CodeCache_heaps_address + OFFSET_GrowableArray_CodeHeap_len,
 344                  &J->Number_of_heaps, sizeof(J->Number_of_heaps));
 345 
 346   /* Allocate memory for heap configurations */
 347   J->Heap_low = (jvm_agent_t*)calloc(J->Number_of_heaps, sizeof(uint64_t));
 348   J->Heap_high = (jvm_agent_t*)calloc(J->Number_of_heaps, sizeof(uint64_t));
 349   J->Heap_segmap_low = (jvm_agent_t*)calloc(J->Number_of_heaps, sizeof(uint64_t));
 350   J->Heap_segmap_high = (jvm_agent_t*)calloc(J->Number_of_heaps, sizeof(uint64_t));
 351 
 352   /* Read code heap configurations */
 353   for (i = 0; i < J->Number_of_heaps; ++i) {
 354     /* Read address of heap */
 355     err = read_pointer(J, array_data, &code_heap_address);
 356     CHECK_FAIL(err);
 357     
 358     err = read_pointer(J, code_heap_address + OFFSET_CodeHeap_memory +
 359                        OFFSET_VirtualSpace_low, &J->Heap_low[i]);
 360     CHECK_FAIL(err);
 361     err = read_pointer(J, code_heap_address + OFFSET_CodeHeap_memory +
 362                        OFFSET_VirtualSpace_high, &J->Heap_high[i]);
 363     CHECK_FAIL(err);
 364     err = read_pointer(J, code_heap_address + OFFSET_CodeHeap_segmap +
 365                        OFFSET_VirtualSpace_low, &J->Heap_segmap_low[i]);
 366     CHECK_FAIL(err);
 367     err = read_pointer(J, code_heap_address + OFFSET_CodeHeap_segmap +
 368                        OFFSET_VirtualSpace_high, &J->Heap_segmap_high[i]);
 369     CHECK_FAIL(err);
 370 
 371     /* Increment pointer to next entry */
 372     array_data = array_data + POINTER_SIZE;
 373   }
 374 
 375   err = ps_pread(J->P, code_heap_address + OFFSET_CodeHeap_log2_segment_size,
 376                  &J->SIZE_CodeCache_log2_segment, sizeof(J->SIZE_CodeCache_log2_segment));
 377   CHECK_FAIL(err);
 378 
 379   return PS_OK;
 380 
 381  fail:
 382   return err;
 383 }
 384 
 385 static int codeheap_contains(int heap_num, jvm_agent_t* J, uint64_t ptr) {
 386   return (J->Heap_low[heap_num] <= ptr && ptr < J->Heap_high[heap_num]);
 387 }
 388 
 389 static int codecache_contains(jvm_agent_t* J, uint64_t ptr) {
 390   int i;
 391   for (i = 0; i < J->Number_of_heaps; ++i) {
 392     if (codeheap_contains(i, J, ptr)) {
 393       return 1;
 394     }
 395   }
 396   return 0;
 397 }
 398 
 399 static uint64_t segment_for(int heap_num, jvm_agent_t* J, uint64_t p) {
 400   return (p - J->Heap_low[heap_num]) >> J->SIZE_CodeCache_log2_segment;
 401 }
 402 
 403 static uint64_t block_at(int heap_num, jvm_agent_t* J, int i) {
 404   return J->Heap_low[heap_num] + (i << J->SIZE_CodeCache_log2_segment);
 405 }
 406 
 407 static int find_start(jvm_agent_t* J, uint64_t ptr, uint64_t *startp) {
 408   int err;
 409   int i;
 410 
 411   for (i = 0; i < J->Number_of_heaps; ++i) {
 412     *startp = 0;
 413     if (codeheap_contains(i, J, ptr)) {
 414       int32_t used;
 415       uint64_t segment = segment_for(i, J, ptr);
 416       uint64_t block = J->Heap_segmap_low[i];
 417       uint8_t tag;
 418       err = ps_pread(J->P, block + segment, &tag, sizeof(tag));
 419       CHECK_FAIL(err);
 420       if (tag == 0xff)
 421         return PS_OK;
 422       while (tag > 0) {
 423         err = ps_pread(J->P, block + segment, &tag, sizeof(tag));
 424         CHECK_FAIL(err);
 425         segment -= tag;
 426       }
 427       block = block_at(i, J, segment);
 428       err = ps_pread(J->P, block + OFFSET_HeapBlockHeader_used, &used, sizeof(used));
 429       CHECK_FAIL(err);
 430       if (used) {
 431         *startp = block + SIZE_HeapBlockHeader;
 432       }
 433     }
 434     return PS_OK;
 435   }
 436 
 437  fail:
 438   return -1;
 439 }
 440 
 441 static int find_jlong_constant(jvm_agent_t* J, const char *name, uint64_t* valuep) {
 442   psaddr_t sym_addr;
 443   int err = ps_pglobal_lookup(J->P, LIBJVM_SO, name, &sym_addr);
 444   if (err == PS_OK) {
 445     err = ps_pread(J->P, sym_addr, valuep, sizeof(uint64_t));
 446     return err;
 447   }
 448   *valuep = -1;
 449   return -1;
 450 }
 451 
 452 jvm_agent_t *Jagent_create(struct ps_prochandle *P, int vers) {
 453   jvm_agent_t* J;
 454   int err;
 455 
 456   if (vers != JVM_DB_VERSION) {
 457     errno = ENOTSUP;
 458     return NULL;
 459   }
 460 
 461   J = (jvm_agent_t*)calloc(sizeof(struct jvm_agent), 1);
 462 
 463   debug = getenv("LIBJVMDB_DEBUG") != NULL;
 464   if (debug) debug = 3;
 465 
 466   if (debug) {
 467       fprintf(stderr, "Jagent_create: debug=%d\n", debug);
 468 #ifdef X86_COMPILER2
 469       fprintf(stderr, "Jagent_create: R_SP=%d, R_FP=%d, POINTER_SIZE=%d\n", R_SP, R_FP, POINTER_SIZE);
 470 #endif  /* X86_COMPILER2 */
 471   }
 472 
 473   J->P = P;
 474 
 475   // Initialize the initial previous frame
 476 
 477   J->prev_fr.fp = 0;
 478   J->prev_fr.pc = 0;
 479   J->prev_fr.sp = 0;
 480   J->prev_fr.sender_sp = 0;
 481 
 482   err = find_symbol(J, "__1cHnmethodG__vtbl_", &J->nmethod_vtbl);
 483   CHECK_FAIL(err);
 484   err = find_symbol(J, "__1cKBufferBlobG__vtbl_", &J->BufferBlob_vtbl);
 485   if (err != PS_OK) J->BufferBlob_vtbl = 0;
 486   err = find_symbol(J, "__1cICodeBlobG__vtbl_", &J->CodeBlob_vtbl);
 487   CHECK_FAIL(err);
 488   err = find_symbol(J, "__1cLRuntimeStubG__vtbl_", &J->RuntimeStub_vtbl);
 489   CHECK_FAIL(err);
 490   err = find_symbol(J, "__1cGMethodG__vtbl_", &J->Method_vtbl);
 491   CHECK_FAIL(err);
 492 
 493   err = parse_vmstructs(J);
 494   CHECK_FAIL(err);
 495   err = read_volatiles(J);
 496   CHECK_FAIL(err);
 497 
 498   return J;
 499 
 500  fail:
 501   Jagent_destroy(J);
 502   return NULL;
 503 }
 504 
 505 void Jagent_destroy(jvm_agent_t *J) {
 506   if (J != NULL) {
 507     free(J);
 508   }
 509 }
 510 
 511 static int is_method(jvm_agent_t* J, uint64_t methodPtr) {
 512   uint64_t klass;
 513   int err = read_pointer(J, methodPtr, &klass);
 514   if (err != PS_OK) goto fail;
 515   return klass == J->Method_vtbl;
 516 
 517  fail:
 518   return 0;
 519 }
 520 
 521 static int
 522 name_for_methodPtr(jvm_agent_t* J, uint64_t methodPtr, char * result, size_t size)
 523 {
 524   short nameIndex;
 525   short signatureIndex;
 526   uint64_t constantPool;
 527   uint64_t constMethod;
 528   uint64_t nameSymbol;
 529   uint64_t signatureSymbol;
 530   uint64_t klassPtr;
 531   uint64_t klassSymbol;
 532   short klassSymbolLength;
 533   short nameSymbolLength;
 534   short signatureSymbolLength;
 535   char * nameString = NULL;
 536   char * klassString = NULL;
 537   char * signatureString = NULL;
 538   int err;
 539 
 540   err = read_pointer(J, methodPtr + OFFSET_Method_constMethod, &constMethod);
 541   CHECK_FAIL(err);
 542   err = read_pointer(J, constMethod + OFFSET_ConstMethod_constants, &constantPool);
 543   CHECK_FAIL(err);
 544 
 545   /* To get name string */
 546   err = ps_pread(J->P, constMethod + OFFSET_ConstMethod_name_index, &nameIndex, 2);
 547   CHECK_FAIL(err);
 548   err = read_pointer(J, constantPool + nameIndex * POINTER_SIZE + SIZE_ConstantPool, &nameSymbol);
 549   CHECK_FAIL(err);
 550   // The symbol is a CPSlot and has lower bit set to indicate metadata
 551   nameSymbol &= (~1); // remove metadata lsb
 552   err = ps_pread(J->P, nameSymbol + OFFSET_Symbol_length, &nameSymbolLength, 2);
 553   CHECK_FAIL(err);
 554   nameString = (char*)calloc(nameSymbolLength + 1, 1);
 555   err = ps_pread(J->P, nameSymbol + OFFSET_Symbol_body, nameString, nameSymbolLength);
 556   CHECK_FAIL(err);
 557 
 558   /* To get signature string */
 559   err = ps_pread(J->P, constMethod + OFFSET_ConstMethod_signature_index, &signatureIndex, 2);
 560   CHECK_FAIL(err);
 561   err = read_pointer(J, constantPool + signatureIndex * POINTER_SIZE + SIZE_ConstantPool, &signatureSymbol);
 562   CHECK_FAIL(err);
 563   signatureSymbol &= (~1);  // remove metadata lsb
 564   err = ps_pread(J->P, signatureSymbol + OFFSET_Symbol_length, &signatureSymbolLength, 2);
 565   CHECK_FAIL(err);
 566   signatureString = (char*)calloc(signatureSymbolLength + 1, 1);
 567   err = ps_pread(J->P, signatureSymbol + OFFSET_Symbol_body, signatureString, signatureSymbolLength);
 568   CHECK_FAIL(err);
 569 
 570   /* To get klass string */
 571   err = read_pointer(J, constantPool + OFFSET_ConstantPool_pool_holder, &klassPtr);
 572   CHECK_FAIL(err);
 573   err = read_pointer(J, klassPtr + OFFSET_Klass_name, &klassSymbol);
 574   CHECK_FAIL(err);
 575   err = ps_pread(J->P, klassSymbol + OFFSET_Symbol_length, &klassSymbolLength, 2);
 576   CHECK_FAIL(err);
 577   klassString = (char*)calloc(klassSymbolLength + 1, 1);
 578   err = ps_pread(J->P, klassSymbol + OFFSET_Symbol_body, klassString, klassSymbolLength);
 579   CHECK_FAIL(err);
 580 
 581   result[0] = '\0';
 582   strncat(result, klassString, size);
 583   size -= strlen(klassString);
 584   strncat(result, ".", size);
 585   size -= 1;
 586   strncat(result, nameString, size);
 587   size -= strlen(nameString);
 588   strncat(result, signatureString, size);
 589 
 590   if (nameString != NULL) free(nameString);
 591   if (klassString != NULL) free(klassString);
 592   if (signatureString != NULL) free(signatureString);
 593 
 594   return PS_OK;
 595 
 596  fail:
 597   if (debug) {
 598       fprintf(stderr, "name_for_methodPtr: FAIL \n\n");
 599   }
 600   if (nameString != NULL) free(nameString);
 601   if (klassString != NULL) free(klassString);
 602   if (signatureString != NULL) free(signatureString);
 603   return -1;
 604 }
 605 
 606 static int nmethod_info(Nmethod_t *N)
 607 {
 608   jvm_agent_t *J = N->J;
 609   uint64_t    nm = N->nm;
 610   int32_t err;
 611 
 612   if (debug > 2 )
 613       fprintf(stderr, "\t nmethod_info: BEGIN \n");
 614 
 615   /* Instructions */
 616   err = ps_pread(J->P, nm + OFFSET_CodeBlob_code_offset, &N->instrs_beg, SZ32);
 617   CHECK_FAIL(err);
 618   err = ps_pread(J->P, nm + OFFSET_CodeBlob_data_offset, &N->instrs_end, SZ32);
 619   CHECK_FAIL(err);
 620   err = ps_pread(J->P, nm + OFFSET_nmethod_deoptimize_offset, &N->deopt_beg, SZ32);
 621   CHECK_FAIL(err);
 622   err = ps_pread(J->P, nm + OFFSET_nmethod_orig_pc_offset, &N->orig_pc_offset, SZ32);
 623   CHECK_FAIL(err);
 624 
 625   /* Metadata */
 626   err = ps_pread(J->P, nm + OFFSET_nmethod_metadata_offset, &N->metadata_beg, SZ32);
 627   CHECK_FAIL(err);
 628   err = ps_pread(J->P, nm + OFFSET_nmethod_scopes_data_offset, &N->metadata_end, SZ32);
 629   CHECK_FAIL(err);
 630 
 631   /* scopes_pcs */
 632   err = ps_pread(J->P, nm + OFFSET_nmethod_scopes_pcs_offset, &N->scopes_pcs_beg, SZ32);
 633   CHECK_FAIL(err);
 634   err = ps_pread(J->P, nm + OFFSET_nmethod_handler_table_offset, &N->scopes_pcs_end, SZ32);
 635   CHECK_FAIL(err);
 636 
 637   /* scopes_data */
 638   err = ps_pread(J->P, nm + OFFSET_nmethod_scopes_data_offset, &N->scopes_data_beg, SZ32);
 639   CHECK_FAIL(err);
 640 
 641   if (debug > 2 ) {
 642       N->scopes_data_end = N->scopes_pcs_beg;
 643 
 644       fprintf(stderr, "\t nmethod_info: instrs_beg: %#x, instrs_end: %#x\n",
 645                        N->instrs_beg, N->instrs_end);
 646 
 647       fprintf(stderr, "\t nmethod_info: deopt_beg: %#x \n",
 648                        N->deopt_beg);
 649 
 650       fprintf(stderr, "\t nmethod_info: orig_pc_offset: %#x \n",
 651                        N->orig_pc_offset);
 652 
 653       fprintf(stderr, "\t nmethod_info: metadata_beg: %#x, metadata_end: %#x\n",
 654                        N->metadata_beg, N->metadata_end);
 655 
 656       fprintf(stderr, "\t nmethod_info: scopes_data_beg: %#x, scopes_data_end: %#x\n",
 657                        N->scopes_data_beg, N->scopes_data_end);
 658 
 659       fprintf(stderr, "\t nmethod_info: scopes_pcs_beg: %#x, scopes_pcs_end: %#x\n",
 660                        N->scopes_pcs_beg, N->scopes_pcs_end);
 661 
 662       fprintf(stderr, "\t nmethod_info: END \n\n");
 663   }
 664   return PS_OK;
 665 
 666  fail:
 667   return err;
 668 }
 669 
 670 static int
 671 raw_read_int(jvm_agent_t* J, uint64_t *buffer, int32_t *val)
 672 {
 673   int shift = 0;
 674   int value = 0;
 675   uint8_t ch = 0;
 676   int32_t  err;
 677   int32_t sum;
 678   // Constants for UNSIGNED5 coding of Pack200
 679   // see compressedStream.hpp
 680   enum {
 681     lg_H = 6,
 682     H = 1<<lg_H,
 683     BitsPerByte = 8,
 684     L = (1<<BitsPerByte)-H,
 685   };
 686   int i;
 687 
 688   err = ps_pread(J->P, (*buffer)++, &ch, sizeof(uint8_t));
 689   CHECK_FAIL(err);
 690   if (debug > 2)
 691       fprintf(stderr, "\t\t\t raw_read_int: *buffer: %#llx, ch: %#x\n", *buffer, ch);
 692 
 693   sum = ch;
 694   if ( sum >= L ) {
 695     int32_t lg_H_i = lg_H;
 696     // Read maximum of 5 total bytes (we've already read 1).
 697     // See CompressedReadStream::read_int_mb
 698     for ( i = 0;  i < 4; i++) {
 699       err = ps_pread(J->P, (*buffer)++, &ch, sizeof(uint8_t));
 700       CHECK_FAIL(err);
 701       sum += ch << lg_H_i;
 702       if (ch < L ) {
 703         *val = sum;
 704         return PS_OK;
 705       }
 706       lg_H_i += lg_H;
 707     }
 708   }
 709   *val = sum;
 710   return PS_OK;
 711 
 712  fail:
 713   return err;
 714 }
 715 
 716 static int
 717 read_pair(jvm_agent_t* J, uint64_t *buffer, int32_t *bci, int32_t *line)
 718 {
 719   uint8_t next = 0;
 720   int32_t bci_delta;
 721   int32_t line_delta;
 722   int32_t err;
 723 
 724   if (debug > 2)
 725       fprintf(stderr, "\t\t read_pair: BEGIN\n");
 726 
 727   err = ps_pread(J->P, (*buffer)++, &next, sizeof(uint8_t));
 728   CHECK_FAIL(err);
 729 
 730   if (next == 0) {
 731       if (debug > 2)
 732           fprintf(stderr, "\t\t read_pair: END: next == 0\n");
 733       return 1; /* stream terminated */
 734   }
 735   if (next == 0xFF) {
 736       if (debug > 2)
 737           fprintf(stderr, "\t\t read_pair: END: next == 0xFF\n");
 738 
 739       /* Escape character, regular compression used */
 740 
 741       err = raw_read_int(J, buffer, &bci_delta);
 742       CHECK_FAIL(err);
 743 
 744       err = raw_read_int(J, buffer, &line_delta);
 745       CHECK_FAIL(err);
 746 
 747       *bci  += bci_delta;
 748       *line += line_delta;
 749 
 750       if (debug > 2) {
 751           fprintf(stderr, "\t\t read_pair: delta = (line %d: %d)\n",
 752                           line_delta, bci_delta);
 753           fprintf(stderr, "\t\t read_pair: unpack= (line %d: %d)\n",
 754                           *line, *bci);
 755       }
 756   } else {
 757       /* Single byte compression used */
 758       *bci  += next >> 3;
 759       *line += next & 0x7;
 760       if (debug > 2) {
 761           fprintf(stderr, "\t\t read_pair: delta = (line %d: %d)\n",
 762                           next & 0x7, next >> 3);
 763           fprintf(stderr, "\t\t read_pair: unpack= (line %d: %d)\n",
 764                           *line, *bci);
 765       }
 766   }
 767   if (debug > 2)
 768       fprintf(stderr, "\t\t read_pair: END\n");
 769   return PS_OK;
 770 
 771  fail:
 772   if (debug)
 773       fprintf(stderr, "\t\t read_pair: FAIL\n");
 774   return err;
 775 }
 776 
 777 static int
 778 line_number_from_bci(jvm_agent_t* J, Vframe_t *vf)
 779 {
 780   uint64_t buffer;
 781   uint16_t code_size;
 782   uint64_t code_end_delta;
 783   uint64_t constMethod;
 784   int8_t   access_flags;
 785   int32_t  best_bci    = 0;
 786   int32_t  stream_bci  = 0;
 787   int32_t  stream_line = 0;
 788   int32_t  err;
 789 
 790   if (debug > 2) {
 791       char name[256];
 792       err = name_for_methodPtr(J, vf->method, name, 256);
 793       CHECK_FAIL(err);
 794       fprintf(stderr, "\t line_number_from_bci: BEGIN, method name: %s, targ bci: %d\n",
 795                        name, vf->bci);
 796   }
 797 
 798   err = read_pointer(J, vf->method + OFFSET_Method_constMethod, &constMethod);
 799   CHECK_FAIL(err);
 800 
 801   vf->line = 0;
 802   err = ps_pread(J->P, constMethod + OFFSET_ConstMethod_flags, &access_flags, sizeof(int8_t));
 803   CHECK_FAIL(err);
 804 
 805   if (!(access_flags & ConstMethod_has_linenumber_table)) {
 806       if (debug > 2)
 807           fprintf(stderr, "\t line_number_from_bci: END: !HAS_LINE_NUMBER_TABLE \n\n");
 808       return PS_OK;
 809   }
 810 
 811   /*  The line numbers are a short array of 2-tuples [start_pc, line_number].
 812    *  Not necessarily sorted and not necessarily one-to-one.
 813    */
 814 
 815   err = ps_pread(J->P, constMethod + OFFSET_ConstMethod_code_size, &code_size, SZ16);
 816   CHECK_FAIL(err);
 817 
 818   /* inlined_table_start() */
 819   code_end_delta = (uint64_t) (access_flags & AccessFlags_NATIVE) ? 2*POINTER_SIZE : 0;
 820   buffer = constMethod + (uint64_t) SIZE_ConstMethod + (uint64_t) code_size + code_end_delta;
 821 
 822   if (debug > 2) {
 823       fprintf(stderr, "\t\t line_number_from_bci: method: %#llx, native: %d\n",
 824                       vf->method, (access_flags & AccessFlags_NATIVE));
 825       fprintf(stderr, "\t\t line_number_from_bci: buffer: %#llx, code_size: %d\n",
 826                       buffer, (int) code_size);
 827   }
 828 
 829   while (read_pair(J, &buffer, &stream_bci, &stream_line) == 0) {
 830       if (stream_bci == vf->bci) {
 831           /* perfect match */
 832           if (debug > 2)
 833               fprintf(stderr, "\t line_number_from_bci: END: exact line: %ld \n\n", vf->line);
 834           vf->line = stream_line;
 835           return PS_OK;
 836       } else {
 837           /* update best_bci/line */
 838           if (stream_bci < vf->bci && stream_bci >= best_bci) {
 839               best_bci = stream_bci;
 840               vf->line = stream_line;
 841               if (debug > 2) {
 842                   fprintf(stderr, "\t line_number_from_bci: best_bci: %ld, best_line: %ld\n",
 843                                    best_bci, vf->line);
 844               }
 845           }
 846       }
 847   }
 848   if (debug > 2)
 849       fprintf(stderr, "\t line_number_from_bci: END: line: %ld \n\n", vf->line);
 850   return PS_OK;
 851 
 852  fail:
 853   if (debug)
 854       fprintf(stderr, "\t line_number_from_bci: FAIL\n");
 855   return err;
 856 }
 857 
 858 static int
 859 get_real_pc(Nmethod_t *N, uint64_t pc_desc, uint64_t *real_pc)
 860 {
 861   int32_t pc_offset;
 862   int32_t err;
 863 
 864   err = ps_pread(N->J->P, pc_desc + OFFSET_PcDesc_pc_offset, &pc_offset, SZ32);
 865   CHECK_FAIL(err);
 866 
 867   *real_pc = N->nm + N->instrs_beg + pc_offset;
 868   if (debug > 2) {
 869       fprintf(stderr, "\t\t get_real_pc: pc_offset: %lx, real_pc: %llx\n",
 870                        pc_offset, *real_pc);
 871   }
 872   return PS_OK;
 873 
 874  fail:
 875   return err;
 876 }
 877 
 878 /* Finds a PcDesc with real-pc equal to N->pc */
 879 static int pc_desc_at(Nmethod_t *N)
 880 {
 881   uint64_t pc_diff;
 882   int32_t offs;
 883   int32_t err;
 884 
 885   if (debug > 2)
 886       fprintf(stderr, "\t pc_desc_at: BEGIN\n");
 887 
 888   N->vf_cnt  = 0;
 889   N->pc_desc = 0;
 890 
 891   for (offs = N->scopes_pcs_beg; offs < N->scopes_pcs_end; offs += SIZE_PcDesc) {
 892       uint64_t pd;
 893       uint64_t best_pc_diff = 16;       /* some approximation */
 894       uint64_t real_pc = 0;
 895 
 896       pd = N->nm + offs;
 897       err = get_real_pc(N, pd, &real_pc);
 898       CHECK_FAIL(err);
 899 
 900       pc_diff = real_pc - N->pc;
 901 
 902       /* In general, this fragment should work */
 903       if (pc_diff == 0) {
 904           N->pc_desc = pd;
 905           if (debug) {
 906             fprintf(stderr, "\t pc_desc_at: END: pc_desc: FOUND: %#lx \n\n", pd);
 907           }
 908           return PS_OK;
 909       }
 910       /* This fragment is to be able to find out an appropriate
 911        * pc_desc entry even if pc_desc info is inaccurate.
 912        */
 913       if (best_pc_diff > pc_diff && pc_diff > 0) {
 914           best_pc_diff = pc_diff;
 915           N->pc_desc = pd;
 916       }
 917   }
 918   if (debug) {
 919       fprintf(stderr, "\t pc_desc_at: END: pc_desc NOT FOUND");
 920       if (pc_diff < 20)
 921           fprintf(stderr, ", best pc_diff: %d\n\n", pc_diff);
 922       else
 923           fprintf(stderr, "\n\n");
 924   }
 925   return PS_OK;
 926 
 927  fail:
 928   return err;
 929 }
 930 
 931 static int
 932 scope_desc_at(Nmethod_t *N, int32_t decode_offset, Vframe_t *vf)
 933 {
 934   uint64_t buffer;
 935   int32_t  err;
 936 
 937   if (debug > 2) {
 938       fprintf(stderr, "\t\t scope_desc_at: BEGIN \n");
 939   }
 940 
 941   buffer = N->nm + N->scopes_data_beg + decode_offset;
 942 
 943   err = raw_read_int(N->J, &buffer, &vf->sender_decode_offset);
 944   CHECK_FAIL(err);
 945 
 946   err = raw_read_int(N->J, &buffer, &vf->methodIdx);
 947   CHECK_FAIL(err);
 948 
 949   err = raw_read_int(N->J, &buffer, &vf->bci);
 950   CHECK_FAIL(err);
 951 
 952   if (debug > 2) {
 953       fprintf(stderr, "\t\t scope_desc_at: sender_decode_offset: %#x\n",
 954                       vf->sender_decode_offset);
 955       fprintf(stderr, "\t\t scope_desc_at: methodIdx: %d\n", vf->methodIdx);
 956       fprintf(stderr, "\t\t scope_desc_at: bci: %d\n", vf->bci);
 957 
 958       fprintf(stderr, "\t\t scope_desc_at: END \n\n");
 959   }
 960   return PS_OK;
 961 
 962  fail:
 963   return err;
 964 }
 965 
 966 static int scopeDesc_chain(Nmethod_t *N) {
 967   int32_t decode_offset = 0;
 968   int32_t err;
 969 
 970   if (debug > 2) {
 971     fprintf(stderr, "\t scopeDesc_chain: BEGIN\n");
 972   }
 973 
 974   err = ps_pread(N->J->P, N->pc_desc + OFFSET_PcDesc_scope_decode_offset,
 975                  &decode_offset, SZ32);
 976   CHECK_FAIL(err);
 977 
 978   while (decode_offset > 0) {
 979     Vframe_t *vf = &N->vframes[N->vf_cnt];
 980 
 981     if (debug > 2) {
 982       fprintf(stderr, "\t scopeDesc_chain: decode_offset: %#x\n", decode_offset);
 983     }
 984 
 985     err = scope_desc_at(N, decode_offset, vf);
 986     CHECK_FAIL(err);
 987 
 988     if (vf->methodIdx > ((N->metadata_end - N->metadata_beg) / POINTER_SIZE)) {
 989       fprintf(stderr, "\t scopeDesc_chain: (methodIdx > metadata length) !\n");
 990       return -1;
 991     }
 992     err = read_pointer(N->J, N->nm + N->metadata_beg + (vf->methodIdx-1)*POINTER_SIZE,
 993                        &vf->method);
 994     CHECK_FAIL(err);
 995 
 996     if (vf->method) {
 997       N->vf_cnt++;
 998       err = line_number_from_bci(N->J, vf);
 999       CHECK_FAIL(err);
1000       if (debug > 2) {
1001         fprintf(stderr, "\t scopeDesc_chain: method: %#8llx, line: %ld\n",
1002                 vf->method, vf->line);
1003       }
1004     }
1005     decode_offset = vf->sender_decode_offset;
1006   }
1007   if (debug > 2) {
1008     fprintf(stderr, "\t scopeDesc_chain: END \n\n");
1009   }
1010   return PS_OK;
1011 
1012  fail:
1013   if (debug) {
1014     fprintf(stderr, "\t scopeDesc_chain: FAIL \n\n");
1015   }
1016   return err;
1017 }
1018 
1019 
1020 static int
1021 name_for_nmethod(jvm_agent_t* J,
1022                  uint64_t nm,
1023                  uint64_t pc,
1024                  uint64_t method,
1025                  char *result,
1026                  size_t size,
1027                  Jframe_t *jframe
1028 ) {
1029   Nmethod_t *N;
1030   Vframe_t *vf;
1031   int32_t err;
1032   int deoptimized = 0;
1033 
1034   if (debug) {
1035       fprintf(stderr, "name_for_nmethod: BEGIN: nmethod: %#llx, pc: %#llx\n", nm, pc);
1036   }
1037   if (J->N == NULL) {
1038     J->N = (Nmethod_t *) malloc(sizeof(Nmethod_t));
1039   }
1040   memset(J->N, 0, sizeof(Nmethod_t));   /* Initial stat: all values are zeros */
1041   N     = J->N;
1042   N->J  = J;
1043   N->nm = nm;
1044   N->pc = pc;
1045   N->jframe = jframe;
1046 
1047   err = nmethod_info(N);
1048   CHECK_FAIL(err);
1049   if (debug) {
1050       fprintf(stderr, "name_for_nmethod: pc: %#llx, deopt_pc:  %#llx\n",
1051               pc, N->nm + N->deopt_beg);
1052   }
1053 
1054   /* check for a deoptimized frame */
1055   if ( pc == N->nm + N->deopt_beg) {
1056     uint64_t base;
1057     if (debug) {
1058         fprintf(stderr, "name_for_nmethod: found deoptimized frame\n");
1059     }
1060     if (J->prev_fr.sender_sp != 0) {
1061       base = J->prev_fr.sender_sp + N->orig_pc_offset;
1062     } else {
1063       base = J->curr_fr.sp + N->orig_pc_offset;
1064     }
1065     err = read_pointer(J, base, &N->pc);
1066     CHECK_FAIL(err);
1067     if (debug) {
1068         fprintf(stderr, "name_for_nmethod: found deoptimized frame converting pc from %#8llx to %#8llx\n",
1069         pc,  N->pc);
1070     }
1071     deoptimized = 1;
1072   }
1073 
1074   err = pc_desc_at(N);
1075   CHECK_FAIL(err);
1076 
1077   if (N->pc_desc > 0) {
1078       jframe->locinf = 1;
1079       err = scopeDesc_chain(N);
1080       CHECK_FAIL(err);
1081   }
1082   result[0] = COMP_METHOD_SIGN;
1083   vf = &N->vframes[0];
1084   if (N->vf_cnt > 0) {
1085       jframe->vf_cnt = N->vf_cnt;
1086       jframe->bci  = vf->bci;
1087       jframe->line = vf->line;
1088       err = name_for_methodPtr(J, N->vframes[0].method, result+1, size-1);
1089       CHECK_FAIL(err);
1090   } else {
1091       err = name_for_methodPtr(J, method, result+1, size-1);
1092       CHECK_FAIL(err);
1093   }
1094   if (deoptimized) {
1095     strncat(result + 1, " [deoptimized frame]; ", size-1);
1096   } else {
1097     strncat(result + 1, " [compiled] ", size-1);
1098   }
1099   if (debug)
1100       fprintf(stderr, "name_for_nmethod: END: method name: %s, vf_cnt: %d\n\n",
1101                       result, N->vf_cnt);
1102   return PS_OK;
1103 
1104  fail:
1105   if (debug)
1106       fprintf(stderr, "name_for_nmethod: FAIL \n\n");
1107   return err;
1108 }
1109 
1110 int is_bci(intptr_t bcx) {
1111   switch (DATA_MODEL) {
1112   case PR_MODEL_LP64:
1113     return ((uintptr_t) bcx) <= ((uintptr_t) MAX_METHOD_CODE_SIZE) ;
1114   case PR_MODEL_ILP32:
1115   default:
1116     return 0 <= bcx && bcx <= MAX_METHOD_CODE_SIZE;
1117   }
1118 }
1119 
1120 static int
1121 name_for_imethod(jvm_agent_t* J,
1122                  uint64_t bcx,
1123                  uint64_t method,
1124                  char *result,
1125                  size_t size,
1126                  Jframe_t *jframe
1127 ) {
1128   uint64_t bci;
1129   uint64_t constMethod;
1130   Vframe_t vframe = {0};
1131   Vframe_t *vf = &vframe;
1132   int32_t   err;
1133 
1134   err = read_pointer(J, method + OFFSET_Method_constMethod, &constMethod);
1135   CHECK_FAIL(err);
1136 
1137   bci = is_bci(bcx) ? bcx : bcx - (constMethod + (uint64_t) SIZE_ConstMethod);
1138 
1139   if (debug)
1140       fprintf(stderr, "\t name_for_imethod: BEGIN: method: %#llx\n", method);
1141 
1142   err = name_for_methodPtr(J, method, result, size);
1143   CHECK_FAIL(err);
1144   if (debug)
1145       fprintf(stderr, "\t name_for_imethod: method name: %s\n", result);
1146 
1147   if (bci > 0) {
1148       vf->method = method;
1149       vf->bci       = bci;
1150       err = line_number_from_bci(J, vf);
1151       CHECK_FAIL(err);
1152   }
1153   jframe->bci  = vf->bci;
1154   jframe->line = vf->line;
1155   jframe->locinf = 1;
1156 
1157   if (debug) {
1158       fprintf(stderr, "\t name_for_imethod: END: bci: %d, line: %d\n\n",
1159                       vf->bci, vf->line);
1160   }
1161   return PS_OK;
1162 
1163  fail:
1164   if (debug)
1165       fprintf(stderr, "\t name_for_imethod: FAIL\n");
1166   return err;
1167 }
1168 
1169 static int
1170 name_for_codecache(jvm_agent_t* J, uint64_t fp, uint64_t pc, char * result,
1171                    size_t size, Jframe_t *jframe, int* is_interpreted)
1172 {
1173   uint64_t start;
1174   uint64_t vtbl;
1175   int32_t err;
1176   *is_interpreted = 0;
1177 
1178   result[0] = '\0';
1179 
1180   err = find_start(J, pc, &start);
1181   CHECK_FAIL(err);
1182 
1183   err = read_pointer(J, start, &vtbl);
1184   CHECK_FAIL(err);
1185 
1186   if (vtbl == J->nmethod_vtbl) {
1187     uint64_t method;
1188 
1189     err = read_pointer(J, start + OFFSET_nmethod_method, &method);
1190     CHECK_FAIL(err);
1191 
1192     if (debug) {
1193         fprintf(stderr, "name_for_codecache: start: %#8llx, pc: %#8llx, method: %#8llx \n",
1194                         start, pc, method);
1195     }
1196     err = name_for_nmethod(J, start, pc, method, result, size, jframe);
1197     CHECK_FAIL(err);
1198   } else if (vtbl == J->BufferBlob_vtbl) {
1199     const char * name;
1200 
1201     err = read_string_pointer(J, start + OFFSET_CodeBlob_name, &name);
1202 
1203     /*
1204      * Temporary usage of string "Interpreter".
1205      * We need some other way to distinguish "StubRoutines"
1206      * and regular interpreted frames.
1207      */
1208     if (err == PS_OK && strncmp(name, "Interpreter", 11) == 0) {
1209       *is_interpreted = 1;
1210       if (is_method(J, J->methodPtr)) {
1211         return name_for_imethod(J, J->bcx, J->methodPtr, result, size, jframe);
1212       }
1213     }
1214 
1215     if (err == PS_OK) {
1216       strncpy(result, name, size);
1217       free((void*)name);
1218     } else {
1219       strncpy(result, "<unknown BufferBlob>", size);
1220     }
1221     /* return PS_OK; */
1222   } else {
1223     const char * name;
1224 
1225     err = read_string_pointer(J, start + OFFSET_CodeBlob_name, &name);
1226     if (err == PS_OK) {
1227       strncpy(result, name, size);
1228       free((void*)name);
1229     } else {
1230       strncpy(result, "<unknown CodeBlob>", size);
1231       WARN1("unknown CodeBlob: vtbl = 0x%x", vtbl);
1232     }
1233   }
1234   result[size-1] = '\0';
1235 
1236 #ifdef X86_COMPILER2
1237   if (vtbl != J->RuntimeStub_vtbl) {
1238     uint64_t trial_pc;
1239     int frame_size;
1240     err = ps_pread(J->P, start + OFFSET_CodeBlob_frame_size,
1241                          &frame_size, SZ32);
1242     CHECK_FAIL(err);
1243 
1244     // frame_size is in words, we want bytes.
1245     frame_size *= POINTER_SIZE; /* word => byte conversion */
1246 
1247     /*
1248       Because c2 doesn't use FP as a framepointer the value of sp/fp we receive
1249       in the initial entry to a set of stack frames containing server frames
1250       will pretty much be nonsense. We can detect that nonsense by looking to
1251       see if the PC we received is correct if we look at the expected storage
1252       location in relation to the FP (ie. POINTER_SIZE(FP) )
1253     */
1254 
1255     err = read_pointer(J, fp + POINTER_SIZE , &trial_pc);
1256     if ( (err != PS_OK || trial_pc != pc) && frame_size > 0 ) {
1257       // Either we couldn't even read at the "fp" or the pc didn't match
1258       // both are sure clues that the fp is bogus. We no search the stack
1259       // for a reasonable number of words trying to find the bogus fp
1260       // and the current pc in adjacent words. The we will be able to
1261       // deduce an approximation of the frame pointer and actually get
1262       // the correct stack pointer. Which we can then unwind for the
1263       // next frame.
1264       int i;
1265       uint64_t check;
1266       uint64_t base = J->curr_fr.sp;
1267       uint64_t prev_fp = 0;
1268       for ( i = 0; i < frame_size * 5 ; i++, base += POINTER_SIZE ) {
1269         err = read_pointer(J, base , &check);
1270         CHECK_FAIL(err);
1271         if (check == fp) {
1272           base += POINTER_SIZE;
1273           err = read_pointer(J, base , &check);
1274           CHECK_FAIL(err);
1275           if (check == pc) {
1276             if (debug) {
1277               fprintf(stderr, "name_for_codecache: found matching fp/pc combo at 0x%llx\n", base - POINTER_SIZE);
1278             }
1279             prev_fp = base - 2 * POINTER_SIZE;
1280             break;
1281           }
1282         }
1283       }
1284       if ( prev_fp != 0 ) {
1285         // real_sp is the sp we should have received for this frame
1286         uint64_t real_sp = prev_fp + 2 * POINTER_SIZE;
1287         // +POINTER_SIZE because callee owns the return address so caller's sp is +1 word
1288         jframe->new_sp = real_sp + frame_size + POINTER_SIZE;
1289         err = read_pointer(J, jframe->new_sp - POINTER_SIZE , &jframe->new_pc);
1290         CHECK_FAIL(err);
1291         err = read_pointer(J, jframe->new_sp - 2*POINTER_SIZE, &jframe->new_fp);
1292         CHECK_FAIL(err);
1293         return PS_OK;
1294       }
1295     }
1296 
1297     /* A prototype to workaround FP absence */
1298     /*
1299      * frame_size can be 0 for StubRoutines (1) frame.
1300      * In this case it should work with fp as usual.
1301      */
1302     if (frame_size > 0) {
1303       jframe->new_fp = J->prev_fr.fp + frame_size;
1304       jframe->new_sp = jframe->new_fp + 2 * POINTER_SIZE;
1305     } else {
1306       memset(&J->curr_fr, 0, sizeof(Frame_t));
1307       err = read_pointer(J,  fp, &jframe->new_fp);
1308       CHECK_FAIL(err);
1309 
1310       err = read_pointer(J,  jframe->new_fp + POINTER_SIZE,  &jframe->new_pc);
1311       CHECK_FAIL(err);
1312     }
1313     if (debug) {
1314       fprintf(stderr, "name_for_codecache: %s, frame_size=%#lx\n",
1315                        result, frame_size);
1316       fprintf(stderr, "name_for_codecache: prev_fr.fp=%#lx, fp=%#lx\n",
1317                        J->prev_fr.fp, jframe->new_fp);
1318     }
1319   }
1320 #endif /* X86_COMPILER2 */
1321 
1322   return PS_OK;
1323 
1324  fail:
1325   return err;
1326 }
1327 
1328 int Jget_vframe(jvm_agent_t* J, int vframe_no,
1329                 char *name, size_t size, Jframe_t *jframe)
1330 {
1331   Nmethod_t *N = J->N;
1332   Vframe_t  *vf;
1333   int32_t   err;
1334 
1335   if (vframe_no >= N->vf_cnt) {
1336      (void) sprintf(name, "Wrong inlinedMethod%1d()", vframe_no);
1337      return -1;
1338   }
1339   vf = N->vframes + vframe_no;
1340   name[0] = COMP_METHOD_SIGN;
1341   err = name_for_methodPtr(J, vf->method, name + 1, size);
1342   CHECK_FAIL(err);
1343 
1344   jframe->bci = vf->bci;
1345   jframe->line = vf->line;
1346   if (debug) {
1347       fprintf(stderr, "\t Jget_vframe: method name: %s, line: %ld\n",
1348                        name, vf->line);
1349   }
1350   return PS_OK;
1351 
1352  fail:
1353   if (debug) {
1354       fprintf(stderr, "\t Jget_vframe: FAIL\n");
1355   }
1356   return err;
1357 }
1358 
1359 #define MAX_SYM_SIZE 256
1360 
1361 int Jlookup_by_regs(jvm_agent_t* J, const prgregset_t regs, char *name,
1362                     size_t size, Jframe_t *jframe) {
1363   uintptr_t fp;
1364   uintptr_t pc;
1365   /* arguments given to read_pointer need to be worst case sized */
1366   uint64_t methodPtr = 0;
1367   uint64_t sender_sp;
1368   uint64_t bcx = 0;
1369   int is_interpreted = 0;
1370   int result = PS_OK;
1371   int err = PS_OK;
1372 
1373   if (J == NULL) {
1374     return -1;
1375   }
1376 
1377   jframe->vf_cnt = 1;
1378   jframe->new_fp = 0;
1379   jframe->new_pc = 0;
1380   jframe->line   = 0;
1381   jframe->bci    = 0;
1382   jframe->locinf = 0;
1383 
1384   read_volatiles(J);
1385   pc = (uintptr_t) regs[R_PC];
1386   J->curr_fr.pc = pc;
1387   J->curr_fr.fp = regs[R_FP];
1388   J->curr_fr.sp = regs[R_SP];
1389 
1390   if (debug)
1391       fprintf(stderr, "Jlookup_by_regs: BEGINs: fp=%#lx, pc=%#lx\n", regs[R_FP], pc);
1392 
1393 #if defined(sparc) || defined(__sparc)
1394     /* The following workaround is for SPARC. CALL instruction occupates 8 bytes.
1395      * In the pcDesc structure return pc offset is recorded for CALL instructions.
1396      * regs[R_PC] contains a CALL instruction pc offset.
1397      */
1398     pc += 8;
1399     bcx          = (uintptr_t) regs[R_L1];
1400     methodPtr = (uintptr_t) regs[R_L2];
1401     sender_sp = regs[R_I5];
1402     if (debug > 2) {
1403         fprintf(stderr, "\nregs[R_I1]=%lx, regs[R_I2]=%lx, regs[R_I5]=%lx, regs[R_L1]=%lx, regs[R_L2]=%lx\n",
1404                          regs[R_I1], regs[R_I2], regs[R_I5], regs[R_L1], regs[R_L2]);
1405     }
1406 #elif defined(i386) || defined(__i386) || defined(__amd64)
1407 
1408     fp = (uintptr_t) regs[R_FP];
1409     if (J->prev_fr.fp == 0) {
1410 #ifdef X86_COMPILER2
1411         /* A workaround for top java frames */
1412         J->prev_fr.fp = (uintptr_t)(regs[R_SP] - 2 * POINTER_SIZE);
1413 #else
1414         J->prev_fr.fp = (uintptr_t)(regs[R_SP] - POINTER_SIZE);
1415 #endif /* COMPILER2 */
1416     }
1417     if (debug > 2) {
1418         printf("Jlookup_by_regs: J->prev_fr.fp = %#lx\n", J->prev_fr.fp);
1419     }
1420 
1421     if (read_pointer(J,  fp + OFFSET_interpreter_frame_method, &methodPtr) != PS_OK) {
1422       methodPtr = 0;
1423     }
1424     if (read_pointer(J,  fp + OFFSET_interpreter_frame_sender_sp, &sender_sp) != PS_OK) {
1425       sender_sp = 0;
1426     }
1427     if (read_pointer(J,  fp + OFFSET_interpreter_frame_bcx_offset, &bcx) != PS_OK) {
1428       bcx = 0;
1429     }
1430 #endif /* i386 */
1431 
1432   J->methodPtr = methodPtr;
1433   J->bcx = bcx;
1434 
1435   /* On x86 with C2 JVM: native frame may have wrong regs[R_FP]
1436    * For example: JVM_SuspendThread frame poins to the top interpreted frame.
1437    * If we call is_method(J, methodPtr) before codecache_contains(J, pc)
1438    * then we go over and omit both: nmethod and I2CAdapter frames.
1439    * Note, that regs[R_PC] is always correct if frame defined correctly.
1440    * So it is better to call codecache_contains(J, pc) from the beginning.
1441    */
1442 #ifndef X86_COMPILER2
1443   if (is_method(J, J->methodPtr)) {
1444     result = name_for_imethod(J, bcx, J->methodPtr, name, size, jframe);
1445     /* If the methodPtr is a method then this is highly likely to be
1446        an interpreter frame */
1447     if (result >= 0) {
1448       is_interpreted = 1;
1449     }
1450   } else
1451 #endif /* ! X86_COMPILER2 */
1452 
1453   if (codecache_contains(J, pc)) {
1454     result = name_for_codecache(J, fp, pc, name, size, jframe, &is_interpreted);
1455   }
1456 #ifdef X86_COMPILER2
1457   else if (is_method(J, J->methodPtr)) {
1458     result = name_for_imethod(J, bcx, J->methodPtr, name, size, jframe);
1459     /* If the methodPtr is a method then this is highly likely to be
1460        an interpreter frame */
1461     if (result >= 0) {
1462       is_interpreted = 1;
1463     }
1464   }
1465 #endif /* X86_COMPILER2 */
1466   else {
1467     if (debug) {
1468         fprintf(stderr, "Jlookup_by_regs: END with -1\n\n");
1469     }
1470     result = -1;
1471   }
1472   if (!is_interpreted) {
1473     sender_sp = 0;
1474   }
1475   J->curr_fr.sender_sp = sender_sp;
1476 
1477 #ifdef X86_COMPILER2
1478   if (!J->curr_fr.fp) {
1479     J->curr_fr.fp = (jframe->new_fp) ? jframe->new_fp : (uintptr_t)regs[R_FP];
1480   }
1481   if (!jframe->new_pc && jframe->new_fp) {
1482     // This seems dubious
1483     read_pointer(J,  jframe->new_fp + POINTER_SIZE,  &jframe->new_pc);
1484     CHECK_FAIL(err);
1485     if (debug > 2) {
1486         printf("Jlookup_by_regs: (update pc) jframe->new_fp: %#llx, jframe->new_pc: %#llx\n",
1487                jframe->new_fp, jframe->new_pc);
1488     }
1489   }
1490 
1491 #endif /* X86_COMPILER2 */
1492   J->prev_fr = J->curr_fr;
1493 
1494   if (debug)
1495       fprintf(stderr, "Jlookup_by_regs: END\n\n");
1496 
1497   return result;
1498 
1499  fail:
1500   return err;
1501 }
1502 
1503 void update_gregs(prgregset_t gregs, Jframe_t jframe) {
1504 #ifdef X86_COMPILER2
1505     if (debug > 0) {
1506       fprintf(stderr, "update_gregs: before update sp = 0x%llx, fp = 0x%llx, pc = 0x%llx\n", gregs[R_SP], gregs[R_FP], gregs[R_PC]);
1507     }
1508     /*
1509      * A workaround for java C2 frames with unconventional FP.
1510      * may have to modify regset with new values for FP/PC/SP when needed.
1511      */
1512      if (jframe.new_sp) {
1513          *((uintptr_t *) &gregs[R_SP]) = (uintptr_t) jframe.new_sp;
1514      } else {
1515          // *((uintptr_t *) &gregs[R_SP]) = (uintptr_t) gregs[R_FP] + 2 * POINTER_SIZE;
1516      }
1517 
1518      if (jframe.new_fp) {
1519          *((uintptr_t *) &gregs[R_FP]) = (uintptr_t) jframe.new_fp;
1520      }
1521      if (jframe.new_pc) {
1522          *((uintptr_t *) &gregs[R_PC]) = (uintptr_t) jframe.new_pc;
1523      }
1524     if (debug > 0) {
1525       fprintf(stderr, "update_gregs: after update sp = 0x%llx, fp = 0x%llx, pc = 0x%llx\n", gregs[R_SP], gregs[R_FP], gregs[R_PC]);
1526     }
1527 #endif  /* X86_COMPILER2 */
1528 }
1529 
1530 /*
1531  * Iterates over java frames at current location given by 'gregs'.
1532  *
1533  *  Returns -1 if no java frames are present or if an error is encountered.
1534  *  Returns the result of calling 'func' if the return value is non-zero.
1535  *  Returns 0 otherwise.
1536  */
1537 int Jframe_iter(jvm_agent_t *J, prgregset_t gregs, java_stack_f *func, void* cld) {
1538     char buf[MAX_SYM_SIZE + 1];
1539     Jframe_t jframe;
1540     int i = 0, res;
1541 #ifdef X86_COMPILER2
1542     if (debug > 0) {
1543       fprintf(stderr, "Jframe_iter: Entry sp = 0x%llx, fp = 0x%llx, pc = 0x%llx\n", gregs[R_SP], gregs[R_FP], gregs[R_PC]);
1544     }
1545 #endif  /* X86_COMPILER2 */
1546 
1547     memset(&jframe, 0, sizeof(Jframe_t));
1548     memset(buf, 0, sizeof(buf));
1549     res =  Jlookup_by_regs(J, gregs, buf, sizeof(buf), &jframe);
1550     if (res != PS_OK)
1551         return (-1);
1552 
1553 
1554     res = func(cld, gregs, buf, (jframe.locinf)? jframe.bci : -1,
1555                jframe.line, NULL);
1556     if (res != 0) {
1557         update_gregs(gregs, jframe);
1558         return (res);
1559     }
1560     for (i = 1; i < jframe.vf_cnt; i++) {
1561         Jget_vframe(J, i, buf, sizeof(buf), &jframe);
1562         res = func(cld, gregs, buf, (jframe.locinf)? jframe.bci : -1,
1563                    jframe.line, NULL);
1564         if (res != 0) {
1565             update_gregs(gregs, jframe);
1566             return (res);
1567         }
1568     }
1569     update_gregs(gregs, jframe);
1570     return (0);
1571 }
--- EOF ---