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