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