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