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