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