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