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