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