libjvm_db.c revision 2767:436b4a3231bf
1/*
2 * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25#include <stdio.h>
26#include <stdlib.h>
27#include <string.h>
28#include <errno.h>
29// not available on macosx #include <gelf.h>
30
31#include "libjvm_db.h"
32#include "JvmOffsets.h"
33
34#define LIBJVM_SO "libjvm.so"
35
36#if defined(i386) || defined(__i386) || defined(__amd64)
37#ifdef COMPILER2
38#define X86_COMPILER2
39#endif /* COMPILER2 */
40#endif /* i386 */
41
42typedef 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
52int Jlookup_by_regs(jvm_agent_t* J, const prgregset_t regs, char *name,
53                    size_t size, Jframe_t *jframe);
54
55int main(int arg) { return arg; }
56
57static int debug = 0;
58
59static 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
65static 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
71static 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
84typedef 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
94int 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
103typedef 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
111typedef 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
118typedef 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
141struct 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
175static int
176read_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
193static 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
201static 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
218static 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
237static 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
256static 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
308static 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
321static 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
365static 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
370static uint64_t segment_for(jvm_agent_t* J, uint64_t p) {
371  return (p - J->CodeCache_low) >> J->SIZE_CodeCache_log2_segment;
372}
373
374static uint64_t block_at(jvm_agent_t* J, int i) {
375  return J->CodeCache_low + (i << J->SIZE_CodeCache_log2_segment);
376}
377
378static 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
409static 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
420jvm_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
471void Jagent_destroy(jvm_agent_t *J) {
472  if (J != NULL) {
473    free(J);
474  }
475}
476
477static 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
498static int
499name_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  // 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
583static 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
647static int
648raw_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
693static int
694read_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
754static int
755line_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
835static int
836get_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 */
856static 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
908static int
909scope_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
943static 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
997static int
998name_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
1087int 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
1097static int
1098name_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
1146static int
1147name_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
1305int 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
1338int 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
1480void 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 */
1514int 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}
1549