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