1 /*
   2  * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 #include <stdio.h>
  26 #include <stdlib.h>
  27 #include <string.h>
  28 #include <errno.h>
  29 #include <gelf.h>
  30 
  31 #include "libjvm_db.h"
  32 #include "JvmOffsets.h"
  33 
  34 #define LIBJVM_SO "libjvm.so"
  35 
  36 #if defined(i386) || defined(__i386) || defined(__amd64)
  37 #ifdef COMPILER2
  38 #define X86_COMPILER2
  39 #endif /* COMPILER2 */
  40 #endif /* i386 */
  41 
  42 typedef struct {
  43     short     vf_cnt; /* number of recognized java vframes */
  44     short     bci;    /* current frame method byte code index */
  45     int       line;   /* current frame method source line */
  46     uint64_t new_fp; /* fp for the next frame */
  47     uint64_t new_pc; /* pc for the next frame */
  48     uint64_t new_sp; /* "raw" sp for the next frame (includes extension by interpreter/adapter */
  49     char      locinf; /* indicates there is valid location info */
  50 } Jframe_t;
  51 
  52 int Jlookup_by_regs(jvm_agent_t* J, const prgregset_t regs, char *name,
  53                     size_t size, Jframe_t *jframe);
  54 
  55 int main(int arg) { return arg; }
  56 
  57 static int debug = 0;
  58 
  59 static void failed(int err, const char * file, int line) {
  60   if (debug) {
  61     fprintf(stderr, "failed %d at %s:%d\n", err, file, line);
  62   }
  63 }
  64 
  65 static void warn(const char * file, int line, const char * msg) {
  66   if (debug) {
  67     fprintf(stderr, "warning: %s at %s:%d\n", msg, file, line);
  68   }
  69 }
  70 
  71 static void warn1(const char * file, int line, const char * msg, intptr_t arg1) {
  72   if (debug) {
  73     fprintf(stderr, "warning: ");
  74     fprintf(stderr, msg, arg1);
  75     fprintf(stderr, " at %s:%d\n", file, line);
  76   }
  77 }
  78 
  79 #define CHECK_FAIL(err) \
  80         if (err != PS_OK) { failed(err, __FILE__, __LINE__); goto fail; }
  81 #define WARN(msg)  warn(__FILE__, __LINE__, msg)
  82 #define WARN1(msg, arg1)  warn1(__FILE__, __LINE__, msg, arg1)
  83 
  84 typedef struct VMStructEntry {
  85   const char * typeName;           /* The type name containing the given field (example: "Klass") */
  86   const char * fieldName;          /* The field name within the type           (example: "_name") */
  87   uint64_t address;                /* Address of field; only used for static fields */
  88                                    /* ("offset" can not be reused because of apparent SparcWorks compiler bug */
  89                                    /* in generation of initializer data) */
  90 } VMStructEntry;
  91 
  92 /* Prototyping inlined methods */
  93 
  94 int sprintf(char *s, const char *format, ...);
  95 
  96 #define SZ16  sizeof(int16_t)
  97 #define SZ32  sizeof(int32_t)
  98 
  99 #define COMP_METHOD_SIGN '*'
 100 
 101 #define MAX_VFRAMES_CNT 256
 102 
 103 typedef struct vframe {
 104   uint64_t 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;          /* _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  oops_beg;            /* _oops_offset */
 133   int32_t  oops_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 
 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_constMethod, &constMethod);
 518   CHECK_FAIL(err);
 519   err = read_pointer(J, constMethod + OFFSET_constMethodOopDesc_constants, &constantPool);
 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   // The symbol is a CPSlot and has lower bit set to indicate metadata
 528   nameSymbol &= (~1); // remove metadata lsb
 529   err = ps_pread(J->P, nameSymbol + OFFSET_Symbol_length, &nameSymbolLength, 2);
 530   CHECK_FAIL(err);
 531   nameString = (char*)calloc(nameSymbolLength + 1, 1);
 532   err = ps_pread(J->P, nameSymbol + OFFSET_Symbol_body, nameString, nameSymbolLength);
 533   CHECK_FAIL(err);
 534 
 535   /* To get signature string */
 536   err = ps_pread(J->P, constMethod + OFFSET_constMethodOopDesc_signature_index, &signatureIndex, 2);
 537   CHECK_FAIL(err);
 538   err = read_pointer(J, constantPool + signatureIndex * POINTER_SIZE + SIZE_constantPoolOopDesc, &signatureSymbol);
 539   CHECK_FAIL(err);
 540   signatureSymbol &= (~1);  // remove metadata lsb
 541   err = ps_pread(J->P, signatureSymbol + OFFSET_Symbol_length, &signatureSymbolLength, 2);
 542   CHECK_FAIL(err);
 543   signatureString = (char*)calloc(signatureSymbolLength + 1, 1);
 544   err = ps_pread(J->P, signatureSymbol + OFFSET_Symbol_body, signatureString, signatureSymbolLength);
 545   CHECK_FAIL(err);
 546 
 547   /* To get klass string */
 548   err = read_pointer(J, constantPool + OFFSET_constantPoolOopDesc_pool_holder, &klassPtr);
 549   CHECK_FAIL(err);
 550   err = read_pointer(J, klassPtr + OFFSET_Klass_name + SIZE_oopDesc, &klassSymbol);
 551   CHECK_FAIL(err);
 552   err = ps_pread(J->P, klassSymbol + OFFSET_Symbol_length, &klassSymbolLength, 2);
 553   CHECK_FAIL(err);
 554   klassString = (char*)calloc(klassSymbolLength + 1, 1);
 555   err = ps_pread(J->P, klassSymbol + OFFSET_Symbol_body, klassString, klassSymbolLength);
 556   CHECK_FAIL(err);
 557 
 558   result[0] = '\0';
 559   strncat(result, klassString, size);
 560   size -= strlen(klassString);
 561   strncat(result, ".", size);
 562   size -= 1;
 563   strncat(result, nameString, size);
 564   size -= strlen(nameString);
 565   strncat(result, signatureString, size);
 566 
 567   if (nameString != NULL) free(nameString);
 568   if (klassString != NULL) free(klassString);
 569   if (signatureString != NULL) free(signatureString);
 570 
 571   return PS_OK;
 572 
 573  fail:
 574   if (debug) {
 575       fprintf(stderr, "name_for_methodOop: FAIL \n\n");
 576   }
 577   if (nameString != NULL) free(nameString);
 578   if (klassString != NULL) free(klassString);
 579   if (signatureString != NULL) free(signatureString);
 580   return -1;
 581 }
 582 
 583 static int nmethod_info(Nmethod_t *N)
 584 {
 585   jvm_agent_t *J = N->J;
 586   uint64_t    nm = N->nm;
 587   int32_t err;
 588 
 589   if (debug > 2 )
 590       fprintf(stderr, "\t nmethod_info: BEGIN \n");
 591 
 592   /* Instructions */
 593   err = ps_pread(J->P, nm + OFFSET_CodeBlob_code_offset, &N->instrs_beg, SZ32);
 594   CHECK_FAIL(err);
 595   err = ps_pread(J->P, nm + OFFSET_CodeBlob_data_offset, &N->instrs_end, SZ32);
 596   CHECK_FAIL(err);
 597   err = ps_pread(J->P, nm + OFFSET_nmethod_deoptimize_offset, &N->deopt_beg, SZ32);
 598   CHECK_FAIL(err);
 599   err = ps_pread(J->P, nm + OFFSET_nmethod_orig_pc_offset, &N->orig_pc_offset, SZ32);
 600   CHECK_FAIL(err);
 601 
 602   /* Oops */
 603   err = ps_pread(J->P, nm + OFFSET_nmethod_oops_offset, &N->oops_beg, SZ32);
 604   CHECK_FAIL(err);
 605   err = ps_pread(J->P, nm + OFFSET_nmethod_scopes_data_offset, &N->oops_end, SZ32);
 606   CHECK_FAIL(err);
 607 
 608   /* scopes_pcs */
 609   err = ps_pread(J->P, nm + OFFSET_nmethod_scopes_pcs_offset, &N->scopes_pcs_beg, SZ32);
 610   CHECK_FAIL(err);
 611   err = ps_pread(J->P, nm + OFFSET_nmethod_handler_table_offset, &N->scopes_pcs_end, SZ32);
 612   CHECK_FAIL(err);
 613 
 614   /* scopes_data */
 615   err = ps_pread(J->P, nm + OFFSET_nmethod_scopes_data_offset, &N->scopes_data_beg, SZ32);
 616   CHECK_FAIL(err);
 617 
 618   if (debug > 2 ) {
 619       N->scopes_data_end = N->scopes_pcs_beg;
 620 
 621       fprintf(stderr, "\t nmethod_info: instrs_beg: %#x, instrs_end: %#x\n",
 622                        N->instrs_beg, N->instrs_end);
 623 
 624       fprintf(stderr, "\t nmethod_info: deopt_beg: %#x \n",
 625                        N->deopt_beg);
 626 
 627       fprintf(stderr, "\t nmethod_info: orig_pc_offset: %#x \n",
 628                        N->orig_pc_offset);
 629 
 630       fprintf(stderr, "\t nmethod_info: oops_beg: %#x, oops_end: %#x\n",
 631                        N->oops_beg, N->oops_end);
 632 
 633       fprintf(stderr, "\t nmethod_info: scopes_data_beg: %#x, scopes_data_end: %#x\n",
 634                        N->scopes_data_beg, N->scopes_data_end);
 635 
 636       fprintf(stderr, "\t nmethod_info: scopes_pcs_beg: %#x, scopes_pcs_end: %#x\n",
 637                        N->scopes_pcs_beg, N->scopes_pcs_end);
 638 
 639       fprintf(stderr, "\t nmethod_info: END \n\n");
 640   }
 641   return PS_OK;
 642 
 643  fail:
 644   return err;
 645 }
 646 
 647 static int
 648 raw_read_int(jvm_agent_t* J, uint64_t *buffer, int32_t *val)
 649 {
 650   int shift = 0;
 651   int value = 0;
 652   uint8_t ch = 0;
 653   int32_t  err;
 654   int32_t sum;
 655   // Constants for UNSIGNED5 coding of Pack200
 656   // see compressedStream.hpp
 657   enum {
 658     lg_H = 6,
 659     H = 1<<lg_H,
 660     BitsPerByte = 8,
 661     L = (1<<BitsPerByte)-H,
 662   };
 663   int i;
 664 
 665   err = ps_pread(J->P, (*buffer)++, &ch, sizeof(uint8_t));
 666   CHECK_FAIL(err);
 667   if (debug > 2)
 668       fprintf(stderr, "\t\t\t raw_read_int: *buffer: %#llx, ch: %#x\n", *buffer, ch);
 669 
 670   sum = ch;
 671   if ( sum >= L ) {
 672     int32_t lg_H_i = lg_H;
 673     // Read maximum of 5 total bytes (we've already read 1).
 674     // See CompressedReadStream::read_int_mb
 675     for ( i = 0;  i < 4; i++) {
 676       err = ps_pread(J->P, (*buffer)++, &ch, sizeof(uint8_t));
 677       CHECK_FAIL(err);
 678       sum += ch << lg_H_i;
 679       if (ch < L ) {
 680         *val = sum;
 681         return PS_OK;
 682       }
 683       lg_H_i += lg_H;
 684     }
 685   }
 686   *val = sum;
 687   return PS_OK;
 688 
 689  fail:
 690   return err;
 691 }
 692 
 693 static int
 694 read_pair(jvm_agent_t* J, uint64_t *buffer, int32_t *bci, int32_t *line)
 695 {
 696   uint8_t next = 0;
 697   int32_t bci_delta;
 698   int32_t line_delta;
 699   int32_t err;
 700 
 701   if (debug > 2)
 702       fprintf(stderr, "\t\t read_pair: BEGIN\n");
 703 
 704   err = ps_pread(J->P, (*buffer)++, &next, sizeof(uint8_t));
 705   CHECK_FAIL(err);
 706 
 707   if (next == 0) {
 708       if (debug > 2)
 709           fprintf(stderr, "\t\t read_pair: END: next == 0\n");
 710       return 1; /* stream terminated */
 711   }
 712   if (next == 0xFF) {
 713       if (debug > 2)
 714           fprintf(stderr, "\t\t read_pair: END: next == 0xFF\n");
 715 
 716       /* Escape character, regular compression used */
 717 
 718       err = raw_read_int(J, buffer, &bci_delta);
 719       CHECK_FAIL(err);
 720 
 721       err = raw_read_int(J, buffer, &line_delta);
 722       CHECK_FAIL(err);
 723 
 724       *bci  += bci_delta;
 725       *line += line_delta;
 726 
 727       if (debug > 2) {
 728           fprintf(stderr, "\t\t read_pair: delta = (line %d: %d)\n",
 729                           line_delta, bci_delta);
 730           fprintf(stderr, "\t\t read_pair: unpack= (line %d: %d)\n",
 731                           *line, *bci);
 732       }
 733   } else {
 734       /* Single byte compression used */
 735       *bci  += next >> 3;
 736       *line += next & 0x7;
 737       if (debug > 2) {
 738           fprintf(stderr, "\t\t read_pair: delta = (line %d: %d)\n",
 739                           next & 0x7, next >> 3);
 740           fprintf(stderr, "\t\t read_pair: unpack= (line %d: %d)\n",
 741                           *line, *bci);
 742       }
 743   }
 744   if (debug > 2)
 745       fprintf(stderr, "\t\t read_pair: END\n");
 746   return PS_OK;
 747 
 748  fail:
 749   if (debug)
 750       fprintf(stderr, "\t\t read_pair: FAIL\n");
 751   return err;
 752 }
 753 
 754 static int
 755 line_number_from_bci(jvm_agent_t* J, Vframe_t *vf)
 756 {
 757   uint64_t buffer;
 758   uint16_t code_size;
 759   uint64_t code_end_delta;
 760   uint64_t constMethod;
 761   int8_t   access_flags;
 762   int32_t  best_bci    = 0;
 763   int32_t  stream_bci  = 0;
 764   int32_t  stream_line = 0;
 765   int32_t  err;
 766 
 767   if (debug > 2) {
 768       char name[256];
 769       err = name_for_methodOop(J, vf->methodOop, name, 256);
 770       CHECK_FAIL(err);
 771       fprintf(stderr, "\t line_number_from_bci: BEGIN, method name: %s, targ bci: %d\n",
 772                        name, vf->bci);
 773   }
 774 
 775   err = read_pointer(J, vf->methodOop + OFFSET_methodOopDesc_constMethod, &constMethod);
 776   CHECK_FAIL(err);
 777 
 778   vf->line = 0;
 779   err = ps_pread(J->P, constMethod + OFFSET_constMethodOopDesc_flags, &access_flags, sizeof(int8_t));
 780   CHECK_FAIL(err);
 781 
 782   if (!(access_flags & constMethodOopDesc_has_linenumber_table)) {
 783       if (debug > 2)
 784           fprintf(stderr, "\t line_number_from_bci: END: !HAS_LINE_NUMBER_TABLE \n\n");
 785       return PS_OK;
 786   }
 787 
 788   /*  The line numbers are a short array of 2-tuples [start_pc, line_number].
 789    *  Not necessarily sorted and not necessarily one-to-one.
 790    */
 791 
 792   err = ps_pread(J->P, constMethod + OFFSET_constMethodOopDesc_code_size, &code_size, SZ16);
 793   CHECK_FAIL(err);
 794 
 795   /* inlined_table_start() */
 796   code_end_delta = (uint64_t) (access_flags & AccessFlags_NATIVE) ? 2*POINTER_SIZE : 0;
 797   buffer = constMethod + (uint64_t) SIZE_constMethodOopDesc + (uint64_t) code_size + code_end_delta;
 798 
 799   if (debug > 2) {
 800       fprintf(stderr, "\t\t line_number_from_bci: methodOop: %#llx, native: %d\n",
 801                       vf->methodOop, (access_flags & AccessFlags_NATIVE));
 802       fprintf(stderr, "\t\t line_number_from_bci: buffer: %#llx, code_size: %d\n",
 803                       buffer, (int) code_size);
 804   }
 805 
 806   while (read_pair(J, &buffer, &stream_bci, &stream_line) == 0) {
 807       if (stream_bci == vf->bci) {
 808           /* perfect match */
 809           if (debug > 2)
 810               fprintf(stderr, "\t line_number_from_bci: END: exact line: %ld \n\n", vf->line);
 811           vf->line = stream_line;
 812           return PS_OK;
 813       } else {
 814           /* update best_bci/line */
 815           if (stream_bci < vf->bci && stream_bci >= best_bci) {
 816               best_bci = stream_bci;
 817               vf->line = stream_line;
 818               if (debug > 2) {
 819                   fprintf(stderr, "\t line_number_from_bci: best_bci: %ld, best_line: %ld\n",
 820                                    best_bci, vf->line);
 821               }
 822           }
 823       }
 824   }
 825   if (debug > 2)
 826       fprintf(stderr, "\t line_number_from_bci: END: line: %ld \n\n", vf->line);
 827   return PS_OK;
 828 
 829  fail:
 830   if (debug)
 831       fprintf(stderr, "\t line_number_from_bci: FAIL\n");
 832   return err;
 833 }
 834 
 835 static int
 836 get_real_pc(Nmethod_t *N, uint64_t pc_desc, uint64_t *real_pc)
 837 {
 838   int32_t pc_offset;
 839   int32_t err;
 840 
 841   err = ps_pread(N->J->P, pc_desc + OFFSET_PcDesc_pc_offset, &pc_offset, SZ32);
 842   CHECK_FAIL(err);
 843 
 844   *real_pc = N->nm + N->instrs_beg + pc_offset;
 845   if (debug > 2) {
 846       fprintf(stderr, "\t\t get_real_pc: pc_offset: %lx, real_pc: %llx\n",
 847                        pc_offset, *real_pc);
 848   }
 849   return PS_OK;
 850 
 851  fail:
 852   return err;
 853 }
 854 
 855 /* Finds a PcDesc with real-pc equal to N->pc */
 856 static int pc_desc_at(Nmethod_t *N)
 857 {
 858   uint64_t pc_diff;
 859   int32_t offs;
 860   int32_t err;
 861 
 862   if (debug > 2)
 863       fprintf(stderr, "\t pc_desc_at: BEGIN\n");
 864 
 865   N->vf_cnt  = 0;
 866   N->pc_desc = 0;
 867 
 868   for (offs = N->scopes_pcs_beg; offs < N->scopes_pcs_end; offs += SIZE_PcDesc) {
 869       uint64_t pd;
 870       uint64_t best_pc_diff = 16;       /* some approximation */
 871       uint64_t real_pc = 0;
 872 
 873       pd = N->nm + offs;
 874       err = get_real_pc(N, pd, &real_pc);
 875       CHECK_FAIL(err);
 876 
 877       pc_diff = real_pc - N->pc;
 878 
 879       /* In general, this fragment should work */
 880       if (pc_diff == 0) {
 881           N->pc_desc = pd;
 882           if (debug) {
 883             fprintf(stderr, "\t pc_desc_at: END: pc_desc: FOUND: %#lx \n\n", pd);
 884           }
 885           return PS_OK;
 886       }
 887       /* This fragment is to be able to find out an appropriate
 888        * pc_desc entry even if pc_desc info is inaccurate.
 889        */
 890       if (best_pc_diff > pc_diff && pc_diff > 0) {
 891           best_pc_diff = pc_diff;
 892           N->pc_desc = pd;
 893       }
 894   }
 895   if (debug) {
 896       fprintf(stderr, "\t pc_desc_at: END: pc_desc NOT FOUND");
 897       if (pc_diff < 20)
 898           fprintf(stderr, ", best pc_diff: %d\n\n", pc_diff);
 899       else
 900           fprintf(stderr, "\n\n");
 901   }
 902   return PS_OK;
 903 
 904  fail:
 905   return err;
 906 }
 907 
 908 static int
 909 scope_desc_at(Nmethod_t *N, int32_t decode_offset, Vframe_t *vf)
 910 {
 911   uint64_t buffer;
 912   int32_t  err;
 913 
 914   if (debug > 2) {
 915       fprintf(stderr, "\t\t scope_desc_at: BEGIN \n");
 916   }
 917 
 918   buffer = N->nm + N->scopes_data_beg + decode_offset;
 919 
 920   err = raw_read_int(N->J, &buffer, &vf->sender_decode_offset);
 921   CHECK_FAIL(err);
 922 
 923   err = raw_read_int(N->J, &buffer, &vf->methodIdx);
 924   CHECK_FAIL(err);
 925 
 926   err = raw_read_int(N->J, &buffer, &vf->bci);
 927   CHECK_FAIL(err);
 928 
 929   if (debug > 2) {
 930       fprintf(stderr, "\t\t scope_desc_at: sender_decode_offset: %#x\n",
 931                       vf->sender_decode_offset);
 932       fprintf(stderr, "\t\t scope_desc_at: methodIdx: %d\n", vf->methodIdx);
 933       fprintf(stderr, "\t\t scope_desc_at: bci: %d\n", vf->bci);
 934 
 935       fprintf(stderr, "\t\t scope_desc_at: END \n\n");
 936   }
 937   return PS_OK;
 938 
 939  fail:
 940   return err;
 941 }
 942 
 943 static int scopeDesc_chain(Nmethod_t *N) {
 944   int32_t decode_offset = 0;
 945   int32_t err;
 946 
 947   if (debug > 2) {
 948     fprintf(stderr, "\t scopeDesc_chain: BEGIN\n");
 949   }
 950 
 951   err = ps_pread(N->J->P, N->pc_desc + OFFSET_PcDesc_scope_decode_offset,
 952                  &decode_offset, SZ32);
 953   CHECK_FAIL(err);
 954 
 955   while (decode_offset > 0) {
 956     Vframe_t *vf = &N->vframes[N->vf_cnt];
 957 
 958     if (debug > 2) {
 959       fprintf(stderr, "\t scopeDesc_chain: decode_offset: %#x\n", decode_offset);
 960     }
 961 
 962     err = scope_desc_at(N, decode_offset, vf);
 963     CHECK_FAIL(err);
 964 
 965     if (vf->methodIdx > ((N->oops_end - N->oops_beg) / POINTER_SIZE)) {
 966       fprintf(stderr, "\t scopeDesc_chain: (methodIdx > oops length) !\n");
 967       return -1;
 968     }
 969     err = read_pointer(N->J, N->nm + N->oops_beg + (vf->methodIdx-1)*POINTER_SIZE,
 970                        &vf->methodOop);
 971     CHECK_FAIL(err);
 972 
 973     if (vf->methodOop) {
 974       N->vf_cnt++;
 975       err = line_number_from_bci(N->J, vf);
 976       CHECK_FAIL(err);
 977       if (debug > 2) {
 978         fprintf(stderr, "\t scopeDesc_chain: methodOop: %#8llx, line: %ld\n",
 979                 vf->methodOop, vf->line);
 980       }
 981     }
 982     decode_offset = vf->sender_decode_offset;
 983   }
 984   if (debug > 2) {
 985     fprintf(stderr, "\t scopeDesc_chain: END \n\n");
 986   }
 987   return PS_OK;
 988 
 989  fail:
 990   if (debug) {
 991     fprintf(stderr, "\t scopeDesc_chain: FAIL \n\n");
 992   }
 993   return err;
 994 }
 995 
 996 
 997 static int
 998 name_for_nmethod(jvm_agent_t* J,
 999                  uint64_t nm,
1000                  uint64_t pc,
1001                  uint64_t methodOop,
1002                  char *result,
1003                  size_t size,
1004                  Jframe_t *jframe
1005 ) {
1006   Nmethod_t *N;
1007   Vframe_t *vf;
1008   int32_t err;
1009   int deoptimized = 0;
1010 
1011   if (debug) {
1012       fprintf(stderr, "name_for_nmethod: BEGIN: nmethod: %#llx, pc: %#llx\n", nm, pc);
1013   }
1014   if (J->N == NULL) {
1015     J->N = (Nmethod_t *) malloc(sizeof(Nmethod_t));
1016   }
1017   memset(J->N, 0, sizeof(Nmethod_t));   /* Initial stat: all values are zeros */
1018   N     = J->N;
1019   N->J  = J;
1020   N->nm = nm;
1021   N->pc = pc;
1022   N->jframe = jframe;
1023 
1024   err = nmethod_info(N);
1025   CHECK_FAIL(err);
1026   if (debug) {
1027       fprintf(stderr, "name_for_nmethod: pc: %#llx, deopt_pc:  %#llx\n",
1028               pc, N->nm + N->deopt_beg);
1029   }
1030 
1031   /* check for a deoptimized frame */
1032   if ( pc == N->nm + N->deopt_beg) {
1033     uint64_t base;
1034     if (debug) {
1035         fprintf(stderr, "name_for_nmethod: found deoptimized frame\n");
1036     }
1037     if (J->prev_fr.sender_sp != 0) {
1038       base = J->prev_fr.sender_sp + N->orig_pc_offset;
1039     } else {
1040       base = J->curr_fr.sp + N->orig_pc_offset;
1041     }
1042     err = read_pointer(J, base, &N->pc);
1043     CHECK_FAIL(err);
1044     if (debug) {
1045         fprintf(stderr, "name_for_nmethod: found deoptimized frame converting pc from %#8llx to %#8llx\n",
1046         pc,  N->pc);
1047     }
1048     deoptimized = 1;
1049   }
1050 
1051   err = pc_desc_at(N);
1052   CHECK_FAIL(err);
1053 
1054   if (N->pc_desc > 0) {
1055       jframe->locinf = 1;
1056       err = scopeDesc_chain(N);
1057       CHECK_FAIL(err);
1058   }
1059   result[0] = COMP_METHOD_SIGN;
1060   vf = &N->vframes[0];
1061   if (N->vf_cnt > 0) {
1062       jframe->vf_cnt = N->vf_cnt;
1063       jframe->bci  = vf->bci;
1064       jframe->line = vf->line;
1065       err = name_for_methodOop(J, N->vframes[0].methodOop, result+1, size-1);
1066       CHECK_FAIL(err);
1067   } else {
1068       err = name_for_methodOop(J, methodOop, result+1, size-1);
1069       CHECK_FAIL(err);
1070   }
1071   if (deoptimized) {
1072     strncat(result + 1, " [deoptimized frame]; ", size-1);
1073   } else {
1074     strncat(result + 1, " [compiled] ", size-1);
1075   }
1076   if (debug)
1077       fprintf(stderr, "name_for_nmethod: END: method name: %s, vf_cnt: %d\n\n",
1078                       result, N->vf_cnt);
1079   return PS_OK;
1080 
1081  fail:
1082   if (debug)
1083       fprintf(stderr, "name_for_nmethod: FAIL \n\n");
1084   return err;
1085 }
1086 
1087 int is_bci(intptr_t bcx) {
1088   switch (DATA_MODEL) {
1089   case PR_MODEL_LP64:
1090     return ((uintptr_t) bcx) <= ((uintptr_t) MAX_METHOD_CODE_SIZE) ;
1091   case PR_MODEL_ILP32:
1092   default:
1093     return 0 <= bcx && bcx <= MAX_METHOD_CODE_SIZE;
1094   }
1095 }
1096 
1097 static int
1098 name_for_imethod(jvm_agent_t* J,
1099                  uint64_t bcx,
1100                  uint64_t methodOop,
1101                  char *result,
1102                  size_t size,
1103                  Jframe_t *jframe
1104 ) {
1105   uint64_t bci;
1106   uint64_t constMethod;
1107   Vframe_t vframe = {0};
1108   Vframe_t *vf = &vframe;
1109   int32_t   err;
1110 
1111   err = read_pointer(J, methodOop + OFFSET_methodOopDesc_constMethod, &constMethod);
1112   CHECK_FAIL(err);
1113 
1114   bci = is_bci(bcx) ? bcx : bcx - (constMethod + (uint64_t) SIZE_constMethodOopDesc);
1115 
1116   if (debug)
1117       fprintf(stderr, "\t name_for_imethod: BEGIN: methodOop: %#llx\n", methodOop);
1118 
1119   err = name_for_methodOop(J, methodOop, result, size);
1120   CHECK_FAIL(err);
1121   if (debug)
1122       fprintf(stderr, "\t name_for_imethod: method name: %s\n", result);
1123 
1124   if (bci > 0) {
1125       vf->methodOop = methodOop;
1126       vf->bci       = bci;
1127       err = line_number_from_bci(J, vf);
1128       CHECK_FAIL(err);
1129   }
1130   jframe->bci  = vf->bci;
1131   jframe->line = vf->line;
1132   jframe->locinf = 1;
1133 
1134   if (debug) {
1135       fprintf(stderr, "\t name_for_imethod: END: bci: %d, line: %d\n\n",
1136                       vf->bci, vf->line);
1137   }
1138   return PS_OK;
1139 
1140  fail:
1141   if (debug)
1142       fprintf(stderr, "\t name_for_imethod: FAIL\n");
1143   return err;
1144 }
1145 
1146 static int
1147 name_for_codecache(jvm_agent_t* J, uint64_t fp, uint64_t pc, char * result,
1148                    size_t size, Jframe_t *jframe, int* is_interpreted)
1149 {
1150   uint64_t start;
1151   uint64_t vtbl;
1152   int32_t err;
1153   *is_interpreted = 0;
1154 
1155   result[0] = '\0';
1156 
1157   err = find_start(J, pc, &start);
1158   CHECK_FAIL(err);
1159 
1160   err = read_pointer(J, start, &vtbl);
1161   CHECK_FAIL(err);
1162 
1163   if (vtbl == J->nmethod_vtbl) {
1164     uint64_t methodOop;
1165 
1166     err = read_pointer(J, start + OFFSET_nmethod_method, &methodOop);
1167     CHECK_FAIL(err);
1168 
1169     if (debug) {
1170         fprintf(stderr, "name_for_codecache: start: %#8llx, pc: %#8llx, methodOop: %#8llx \n",
1171                         start, pc, methodOop);
1172     }
1173     err = name_for_nmethod(J, start, pc, methodOop, result, size, jframe);
1174     CHECK_FAIL(err);
1175   } else if (vtbl == J->BufferBlob_vtbl) {
1176     const char * name;
1177 
1178     err = read_string_pointer(J, start + OFFSET_CodeBlob_name, &name);
1179 
1180     /*
1181      * Temporary usage of string "Interpreter".
1182      * We need some other way to distinguish "StubRoutines"
1183      * and regular interpreted frames.
1184      */
1185     if (err == PS_OK && strncmp(name, "Interpreter", 11) == 0) {
1186       *is_interpreted = 1;
1187       if (is_methodOop(J, J->methodOopPtr)) {
1188         return name_for_imethod(J, J->bcx, J->methodOopPtr, result, size, jframe);
1189       }
1190     }
1191 
1192     if (err == PS_OK) {
1193       strncpy(result, name, size);
1194       free((void*)name);
1195     } else {
1196       strncpy(result, "<unknown BufferBlob>", size);
1197     }
1198     /* return PS_OK; */
1199   } else {
1200     const char * name;
1201 
1202     err = read_string_pointer(J, start + OFFSET_CodeBlob_name, &name);
1203     if (err == PS_OK) {
1204       strncpy(result, name, size);
1205       free((void*)name);
1206     } else {
1207       strncpy(result, "<unknown CodeBlob>", size);
1208       WARN1("unknown CodeBlob: vtbl = 0x%x", vtbl);
1209     }
1210   }
1211   result[size-1] = '\0';
1212 
1213 #ifdef X86_COMPILER2
1214   if (vtbl != J->RuntimeStub_vtbl) {
1215     uint64_t trial_pc;
1216     int frame_size;
1217     err = ps_pread(J->P, start + OFFSET_CodeBlob_frame_size,
1218                          &frame_size, SZ32);
1219     CHECK_FAIL(err);
1220 
1221     // frame_size is in words, we want bytes.
1222     frame_size *= POINTER_SIZE; /* word => byte conversion */
1223 
1224     /*
1225       Because c2 doesn't use FP as a framepointer the value of sp/fp we receive
1226       in the initial entry to a set of stack frames containing server frames
1227       will pretty much be nonsense. We can detect that nonsense by looking to
1228       see if the PC we received is correct if we look at the expected storage
1229       location in relation to the FP (ie. POINTER_SIZE(FP) )
1230     */
1231 
1232     err = read_pointer(J, fp + POINTER_SIZE , &trial_pc);
1233     if ( (err != PS_OK || trial_pc != pc) && frame_size > 0 ) {
1234       // Either we couldn't even read at the "fp" or the pc didn't match
1235       // both are sure clues that the fp is bogus. We no search the stack
1236       // for a reasonable number of words trying to find the bogus fp
1237       // and the current pc in adjacent words. The we will be able to
1238       // deduce an approximation of the frame pointer and actually get
1239       // the correct stack pointer. Which we can then unwind for the
1240       // next frame.
1241       int i;
1242       uint64_t check;
1243       uint64_t base = J->curr_fr.sp;
1244       uint64_t prev_fp = 0;
1245       for ( i = 0; i < frame_size * 5 ; i++, base += POINTER_SIZE ) {
1246         err = read_pointer(J, base , &check);
1247         CHECK_FAIL(err);
1248         if (check == fp) {
1249           base += POINTER_SIZE;
1250           err = read_pointer(J, base , &check);
1251           CHECK_FAIL(err);
1252           if (check == pc) {
1253             if (debug) {
1254               fprintf(stderr, "name_for_codecache: found matching fp/pc combo at 0x%llx\n", base - POINTER_SIZE);
1255             }
1256             prev_fp = base - 2 * POINTER_SIZE;
1257             break;
1258           }
1259         }
1260       }
1261       if ( prev_fp != 0 ) {
1262         // real_sp is the sp we should have received for this frame
1263         uint64_t real_sp = prev_fp + 2 * POINTER_SIZE;
1264         // +POINTER_SIZE because callee owns the return address so caller's sp is +1 word
1265         jframe->new_sp = real_sp + frame_size + POINTER_SIZE;
1266         err = read_pointer(J, jframe->new_sp - POINTER_SIZE , &jframe->new_pc);
1267         CHECK_FAIL(err);
1268         err = read_pointer(J, jframe->new_sp - 2*POINTER_SIZE, &jframe->new_fp);
1269         CHECK_FAIL(err);
1270         return PS_OK;
1271       }
1272     }
1273 
1274     /* A prototype to workaround FP absence */
1275     /*
1276      * frame_size can be 0 for StubRoutines (1) frame.
1277      * In this case it should work with fp as usual.
1278      */
1279     if (frame_size > 0) {
1280       jframe->new_fp = J->prev_fr.fp + frame_size;
1281       jframe->new_sp = jframe->new_fp + 2 * POINTER_SIZE;
1282     } else {
1283       memset(&J->curr_fr, 0, sizeof(Frame_t));
1284       err = read_pointer(J,  fp, &jframe->new_fp);
1285       CHECK_FAIL(err);
1286 
1287       err = read_pointer(J,  jframe->new_fp + POINTER_SIZE,  &jframe->new_pc);
1288       CHECK_FAIL(err);
1289     }
1290     if (debug) {
1291       fprintf(stderr, "name_for_codecache: %s, frame_size=%#lx\n",
1292                        result, frame_size);
1293       fprintf(stderr, "name_for_codecache: prev_fr.fp=%#lx, fp=%#lx\n",
1294                        J->prev_fr.fp, jframe->new_fp);
1295     }
1296   }
1297 #endif /* X86_COMPILER2 */
1298 
1299   return PS_OK;
1300 
1301  fail:
1302   return err;
1303 }
1304 
1305 int Jget_vframe(jvm_agent_t* J, int vframe_no,
1306                 char *name, size_t size, Jframe_t *jframe)
1307 {
1308   Nmethod_t *N = J->N;
1309   Vframe_t  *vf;
1310   int32_t   err;
1311 
1312   if (vframe_no >= N->vf_cnt) {
1313      (void) sprintf(name, "Wrong inlinedMethod%1d()", vframe_no);
1314      return -1;
1315   }
1316   vf = N->vframes + vframe_no;
1317   name[0] = COMP_METHOD_SIGN;
1318   err = name_for_methodOop(J, vf->methodOop, name + 1, size);
1319   CHECK_FAIL(err);
1320 
1321   jframe->bci = vf->bci;
1322   jframe->line = vf->line;
1323   if (debug) {
1324       fprintf(stderr, "\t Jget_vframe: method name: %s, line: %ld\n",
1325                        name, vf->line);
1326   }
1327   return PS_OK;
1328 
1329  fail:
1330   if (debug) {
1331       fprintf(stderr, "\t Jget_vframe: FAIL\n");
1332   }
1333   return err;
1334 }
1335 
1336 #define MAX_SYM_SIZE 256
1337 
1338 int Jlookup_by_regs(jvm_agent_t* J, const prgregset_t regs, char *name,
1339                     size_t size, Jframe_t *jframe) {
1340   uintptr_t fp;
1341   uintptr_t pc;
1342   /* arguments given to read_pointer need to be worst case sized */
1343   uint64_t methodOopPtr = 0;
1344   uint64_t sender_sp;
1345   uint64_t bcx = 0;
1346   int is_interpreted = 0;
1347   int result = PS_OK;
1348   int err = PS_OK;
1349 
1350   if (J == NULL) {
1351     return -1;
1352   }
1353 
1354   jframe->vf_cnt = 1;
1355   jframe->new_fp = 0;
1356   jframe->new_pc = 0;
1357   jframe->line   = 0;
1358   jframe->bci    = 0;
1359   jframe->locinf = 0;
1360 
1361   read_volatiles(J);
1362   pc = (uintptr_t) regs[R_PC];
1363   J->curr_fr.pc = pc;
1364   J->curr_fr.fp = regs[R_FP];
1365   J->curr_fr.sp = regs[R_SP];
1366 
1367   if (debug)
1368       fprintf(stderr, "Jlookup_by_regs: BEGINs: fp=%#lx, pc=%#lx\n", regs[R_FP], pc);
1369 
1370 #if defined(sparc) || defined(__sparc)
1371     /* The following workaround is for SPARC. CALL instruction occupates 8 bytes.
1372      * In the pcDesc structure return pc offset is recorded for CALL instructions.
1373      * regs[R_PC] contains a CALL instruction pc offset.
1374      */
1375     pc += 8;
1376     bcx          = (uintptr_t) regs[R_L1];
1377     methodOopPtr = (uintptr_t) regs[R_L2];
1378     sender_sp = regs[R_I5];
1379     if (debug > 2) {
1380         fprintf(stderr, "\nregs[R_I1]=%lx, regs[R_I2]=%lx, regs[R_I5]=%lx, regs[R_L1]=%lx, regs[R_L2]=%lx\n",
1381                          regs[R_I1], regs[R_I2], regs[R_I5], regs[R_L1], regs[R_L2]);
1382     }
1383 #elif defined(i386) || defined(__i386) || defined(__amd64)
1384 
1385     fp = (uintptr_t) regs[R_FP];
1386     if (J->prev_fr.fp == 0) {
1387 #ifdef X86_COMPILER2
1388         /* A workaround for top java frames */
1389         J->prev_fr.fp = (uintptr_t)(regs[R_SP] - 2 * POINTER_SIZE);
1390 #else
1391         J->prev_fr.fp = (uintptr_t)(regs[R_SP] - POINTER_SIZE);
1392 #endif /* COMPILER2 */
1393     }
1394     if (debug > 2) {
1395         printf("Jlookup_by_regs: J->prev_fr.fp = %#lx\n", J->prev_fr.fp);
1396     }
1397 
1398     if (read_pointer(J,  fp + OFFSET_interpreter_frame_method, &methodOopPtr) != PS_OK) {
1399       methodOopPtr = 0;
1400     }
1401     if (read_pointer(J,  fp + OFFSET_interpreter_frame_sender_sp, &sender_sp) != PS_OK) {
1402       sender_sp = 0;
1403     }
1404     if (read_pointer(J,  fp + OFFSET_interpreter_frame_bcx_offset, &bcx) != PS_OK) {
1405       bcx = 0;
1406     }
1407 #endif /* i386 */
1408 
1409   J->methodOopPtr = methodOopPtr;
1410   J->bcx = bcx;
1411 
1412   /* On x86 with C2 JVM: native frame may have wrong regs[R_FP]
1413    * For example: JVM_SuspendThread frame poins to the top interpreted frame.
1414    * If we call is_methodOop(J, methodOopPtr) before codecache_contains(J, pc)
1415    * then we go over and omit both: nmethod and I2CAdapter frames.
1416    * Note, that regs[R_PC] is always correct if frame defined correctly.
1417    * So it is better to call codecache_contains(J, pc) from the beginning.
1418    */
1419 #ifndef X86_COMPILER2
1420   if (is_methodOop(J, J->methodOopPtr)) {
1421     result = name_for_imethod(J, bcx, J->methodOopPtr, name, size, jframe);
1422     /* If the methodOopPtr is a method then this is highly likely to be
1423        an interpreter frame */
1424     if (result >= 0) {
1425       is_interpreted = 1;
1426     }
1427   } else
1428 #endif /* ! X86_COMPILER2 */
1429 
1430   if (codecache_contains(J, pc)) {
1431     result = name_for_codecache(J, fp, pc, name, size, jframe, &is_interpreted);
1432   }
1433 #ifdef X86_COMPILER2
1434   else if (is_methodOop(J, J->methodOopPtr)) {
1435     result = name_for_imethod(J, bcx, J->methodOopPtr, name, size, jframe);
1436     /* If the methodOopPtr is a method then this is highly likely to be
1437        an interpreter frame */
1438     if (result >= 0) {
1439       is_interpreted = 1;
1440     }
1441   }
1442 #endif /* X86_COMPILER2 */
1443   else {
1444     if (debug) {
1445         fprintf(stderr, "Jlookup_by_regs: END with -1\n\n");
1446     }
1447     result = -1;
1448   }
1449   if (!is_interpreted) {
1450     sender_sp = 0;
1451   }
1452   J->curr_fr.sender_sp = sender_sp;
1453 
1454 #ifdef X86_COMPILER2
1455   if (!J->curr_fr.fp) {
1456     J->curr_fr.fp = (jframe->new_fp) ? jframe->new_fp : (uintptr_t)regs[R_FP];
1457   }
1458   if (!jframe->new_pc && jframe->new_fp) {
1459     // This seems dubious
1460     read_pointer(J,  jframe->new_fp + POINTER_SIZE,  &jframe->new_pc);
1461     CHECK_FAIL(err);
1462     if (debug > 2) {
1463         printf("Jlookup_by_regs: (update pc) jframe->new_fp: %#llx, jframe->new_pc: %#llx\n",
1464                jframe->new_fp, jframe->new_pc);
1465     }
1466   }
1467 
1468 #endif /* X86_COMPILER2 */
1469   J->prev_fr = J->curr_fr;
1470 
1471   if (debug)
1472       fprintf(stderr, "Jlookup_by_regs: END\n\n");
1473 
1474   return result;
1475 
1476  fail:
1477   return err;
1478 }
1479 
1480 void update_gregs(prgregset_t gregs, Jframe_t jframe) {
1481 #ifdef X86_COMPILER2
1482     if (debug > 0) {
1483       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]);
1484     }
1485     /*
1486      * A workaround for java C2 frames with unconventional FP.
1487      * may have to modify regset with new values for FP/PC/SP when needed.
1488      */
1489      if (jframe.new_sp) {
1490          *((uintptr_t *) &gregs[R_SP]) = (uintptr_t) jframe.new_sp;
1491      } else {
1492          // *((uintptr_t *) &gregs[R_SP]) = (uintptr_t) gregs[R_FP] + 2 * POINTER_SIZE;
1493      }
1494 
1495      if (jframe.new_fp) {
1496          *((uintptr_t *) &gregs[R_FP]) = (uintptr_t) jframe.new_fp;
1497      }
1498      if (jframe.new_pc) {
1499          *((uintptr_t *) &gregs[R_PC]) = (uintptr_t) jframe.new_pc;
1500      }
1501     if (debug > 0) {
1502       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]);
1503     }
1504 #endif  /* X86_COMPILER2 */
1505 }
1506 
1507 /*
1508  * Iterates over java frames at current location given by 'gregs'.
1509  *
1510  *  Returns -1 if no java frames are present or if an error is encountered.
1511  *  Returns the result of calling 'func' if the return value is non-zero.
1512  *  Returns 0 otherwise.
1513  */
1514 int Jframe_iter(jvm_agent_t *J, prgregset_t gregs, java_stack_f *func, void* cld) {
1515     char buf[MAX_SYM_SIZE + 1];
1516     Jframe_t jframe;
1517     int i = 0, res;
1518 #ifdef X86_COMPILER2
1519     if (debug > 0) {
1520       fprintf(stderr, "Jframe_iter: Entry sp = 0x%llx, fp = 0x%llx, pc = 0x%llx\n", gregs[R_SP], gregs[R_FP], gregs[R_PC]);
1521     }
1522 #endif  /* X86_COMPILER2 */
1523 
1524     memset(&jframe, 0, sizeof(Jframe_t));
1525     memset(buf, 0, sizeof(buf));
1526     res =  Jlookup_by_regs(J, gregs, buf, sizeof(buf), &jframe);
1527     if (res != PS_OK)
1528         return (-1);
1529 
1530 
1531     res = func(cld, gregs, buf, (jframe.locinf)? jframe.bci : -1,
1532                jframe.line, NULL);
1533     if (res != 0) {
1534         update_gregs(gregs, jframe);
1535         return (res);
1536     }
1537     for (i = 1; i < jframe.vf_cnt; i++) {
1538         Jget_vframe(J, i, buf, sizeof(buf), &jframe);
1539         res = func(cld, gregs, buf, (jframe.locinf)? jframe.bci : -1,
1540                    jframe.line, NULL);
1541         if (res != 0) {
1542             update_gregs(gregs, jframe);
1543             return (res);
1544         }
1545     }
1546     update_gregs(gregs, jframe);
1547     return (0);
1548 }