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