1 /* 2 * Copyright (c) 2003, 2018, 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 55 int main(int arg) { return arg; } 56 57 static int debug = 0; 58 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 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 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 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_begin */ 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_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 176 static int 177 read_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 194 static 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 202 static 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 219 static 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 238 static 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 257 static 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 310 static 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 323 static 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 388 static 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 392 static 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 402 static 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 406 static 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 410 static 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 444 static 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 455 jvm_agent_t *Jagent_create(struct ps_prochandle *P, int vers) { 456 jvm_agent_t* J; 457 int err; 458 459 if (vers != JVM_DB_VERSION) { 460 errno = ENOTSUP; 461 return NULL; 462 } 463 464 J = (jvm_agent_t*)calloc(sizeof(struct jvm_agent), 1); 465 466 debug = getenv("LIBJVMDB_DEBUG") != NULL; 467 if (debug) debug = 3; 468 469 if (debug) { 470 fprintf(stderr, "Jagent_create: debug=%d\n", debug); 471 #ifdef X86_COMPILER2 472 fprintf(stderr, "Jagent_create: R_SP=%d, R_FP=%d, POINTER_SIZE=%d\n", R_SP, R_FP, POINTER_SIZE); 473 #endif /* X86_COMPILER2 */ 474 } 475 476 J->P = P; 477 478 // Initialize the initial previous frame 479 480 J->prev_fr.fp = 0; 481 J->prev_fr.pc = 0; 482 J->prev_fr.sp = 0; 483 J->prev_fr.sender_sp = 0; 484 485 err = find_symbol(J, "__1cHnmethodG__vtbl_", &J->nmethod_vtbl); 486 CHECK_FAIL(err); 487 err = find_symbol(J, "__1cKBufferBlobG__vtbl_", &J->BufferBlob_vtbl); 488 if (err != PS_OK) J->BufferBlob_vtbl = 0; 489 err = find_symbol(J, "__1cICodeBlobG__vtbl_", &J->CodeBlob_vtbl); 490 CHECK_FAIL(err); 491 err = find_symbol(J, "__1cLRuntimeStubG__vtbl_", &J->RuntimeStub_vtbl); 492 CHECK_FAIL(err); 493 err = find_symbol(J, "__1cGMethodG__vtbl_", &J->Method_vtbl); 494 CHECK_FAIL(err); 495 496 err = parse_vmstructs(J); 497 CHECK_FAIL(err); 498 err = read_volatiles(J); 499 CHECK_FAIL(err); 500 501 return J; 502 503 fail: 504 Jagent_destroy(J); 505 return NULL; 506 } 507 508 void Jagent_destroy(jvm_agent_t *J) { 509 if (J != NULL) { 510 free(J); 511 } 512 } 513 514 static 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 524 static int 525 name_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 // The length is in the top half of the word. 556 err = ps_pread(J->P, nameSymbol + OFFSET_Symbol_length_and_refcount, &nameSymbolLength, 2); 557 CHECK_FAIL(err); 558 nameString = (char*)calloc(nameSymbolLength + 1, 1); 559 err = ps_pread(J->P, nameSymbol + OFFSET_Symbol_body, nameString, nameSymbolLength); 560 CHECK_FAIL(err); 561 562 /* To get signature string */ 563 err = ps_pread(J->P, constMethod + OFFSET_ConstMethod_signature_index, &signatureIndex, 2); 564 CHECK_FAIL(err); 565 err = read_pointer(J, constantPool + signatureIndex * POINTER_SIZE + SIZE_ConstantPool, &signatureSymbol); 566 CHECK_FAIL(err); 567 signatureSymbol &= (~1); // remove metadata lsb 568 err = ps_pread(J->P, signatureSymbol + OFFSET_Symbol_length_and_refcount, &signatureSymbolLength, 2); 569 CHECK_FAIL(err); 570 signatureString = (char*)calloc(signatureSymbolLength + 1, 1); 571 err = ps_pread(J->P, signatureSymbol + OFFSET_Symbol_body, signatureString, signatureSymbolLength); 572 CHECK_FAIL(err); 573 574 /* To get klass string */ 575 err = read_pointer(J, constantPool + OFFSET_ConstantPool_pool_holder, &klassPtr); 576 CHECK_FAIL(err); 577 err = read_pointer(J, klassPtr + OFFSET_Klass_name, &klassSymbol); 578 CHECK_FAIL(err); 579 err = ps_pread(J->P, klassSymbol + OFFSET_Symbol_length_and_refcount, &klassSymbolLength, 2); 580 CHECK_FAIL(err); 581 klassString = (char*)calloc(klassSymbolLength + 1, 1); 582 err = ps_pread(J->P, klassSymbol + OFFSET_Symbol_body, klassString, klassSymbolLength); 583 CHECK_FAIL(err); 584 585 result[0] = '\0'; 586 if (snprintf(result, size, 587 "%s.%s%s", 588 klassString, 589 nameString, 590 signatureString) >= size) { 591 // truncation 592 goto fail; 593 } 594 595 if (nameString != NULL) free(nameString); 596 if (klassString != NULL) free(klassString); 597 if (signatureString != NULL) free(signatureString); 598 599 return PS_OK; 600 601 fail: 602 if (debug) { 603 fprintf(stderr, "name_for_methodPtr: FAIL \n\n"); 604 } 605 if (nameString != NULL) free(nameString); 606 if (klassString != NULL) free(klassString); 607 if (signatureString != NULL) free(signatureString); 608 return -1; 609 } 610 611 static int nmethod_info(Nmethod_t *N) 612 { 613 jvm_agent_t *J = N->J; 614 uint64_t nm = N->nm; 615 int32_t err; 616 617 if (debug > 2 ) 618 fprintf(stderr, "\t nmethod_info: BEGIN \n"); 619 620 /* Instructions */ 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_begin, &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 675 static int 676 raw_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 721 static int 722 read_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 782 static int 783 line_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 863 static int 864 get_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 */ 884 static 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 936 static int 937 scope_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 971 static 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 1025 static int 1026 name_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 1115 static int 1116 name_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 1164 static int 1165 name_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 1323 int 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 1356 int 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 fp = (uintptr_t) regs[R_FP]; 1398 if (debug > 2) { 1399 fprintf(stderr, "\nregs[R_I1]=%lx, regs[R_I2]=%lx, regs[R_I5]=%lx, regs[R_L1]=%lx, regs[R_L2]=%lx\n", 1400 regs[R_I1], regs[R_I2], regs[R_I5], regs[R_L1], regs[R_L2]); 1401 } 1402 #elif defined(i386) || defined(__i386) || defined(__amd64) 1403 1404 fp = (uintptr_t) regs[R_FP]; 1405 if (J->prev_fr.fp == 0) { 1406 #ifdef X86_COMPILER2 1407 /* A workaround for top java frames */ 1408 J->prev_fr.fp = (uintptr_t)(regs[R_SP] - 2 * POINTER_SIZE); 1409 #else 1410 J->prev_fr.fp = (uintptr_t)(regs[R_SP] - POINTER_SIZE); 1411 #endif /* COMPILER2 */ 1412 } 1413 if (debug > 2) { 1414 printf("Jlookup_by_regs: J->prev_fr.fp = %#lx\n", J->prev_fr.fp); 1415 } 1416 1417 if (read_pointer(J, fp + OFFSET_interpreter_frame_method, &methodPtr) != PS_OK) { 1418 methodPtr = 0; 1419 } 1420 if (read_pointer(J, fp + OFFSET_interpreter_frame_sender_sp, &sender_sp) != PS_OK) { 1421 sender_sp = 0; 1422 } 1423 if (read_pointer(J, fp + OFFSET_interpreter_frame_bcp_offset, &bcp) != PS_OK) { 1424 bcp = 0; 1425 } 1426 #endif /* i386 */ 1427 1428 J->methodPtr = methodPtr; 1429 J->bcp = bcp; 1430 1431 /* On x86 with C2 JVM: native frame may have wrong regs[R_FP] 1432 * For example: JVM_SuspendThread frame poins to the top interpreted frame. 1433 * If we call is_method(J, methodPtr) before codecache_contains(J, pc) 1434 * then we go over and omit both: nmethod and I2CAdapter frames. 1435 * Note, that regs[R_PC] is always correct if frame defined correctly. 1436 * So it is better to call codecache_contains(J, pc) from the beginning. 1437 */ 1438 #ifndef X86_COMPILER2 1439 if (is_method(J, J->methodPtr)) { 1440 result = name_for_imethod(J, bcp, J->methodPtr, name, size, jframe); 1441 /* If the methodPtr is a method then this is highly likely to be 1442 an interpreter frame */ 1443 if (result >= 0) { 1444 is_interpreted = 1; 1445 } 1446 } else 1447 #endif /* ! X86_COMPILER2 */ 1448 1449 if (codecache_contains(J, pc)) { 1450 result = name_for_codecache(J, fp, pc, name, size, jframe, &is_interpreted); 1451 } 1452 #ifdef X86_COMPILER2 1453 else if (is_method(J, J->methodPtr)) { 1454 result = name_for_imethod(J, bcp, J->methodPtr, name, size, jframe); 1455 /* If the methodPtr is a method then this is highly likely to be 1456 an interpreter frame */ 1457 if (result >= 0) { 1458 is_interpreted = 1; 1459 } 1460 } 1461 #endif /* X86_COMPILER2 */ 1462 else { 1463 if (debug) { 1464 fprintf(stderr, "Jlookup_by_regs: END with -1\n\n"); 1465 } 1466 result = -1; 1467 } 1468 if (!is_interpreted) { 1469 sender_sp = 0; 1470 } 1471 J->curr_fr.sender_sp = sender_sp; 1472 1473 #ifdef X86_COMPILER2 1474 if (!J->curr_fr.fp) { 1475 J->curr_fr.fp = (jframe->new_fp) ? jframe->new_fp : (uintptr_t)regs[R_FP]; 1476 } 1477 if (!jframe->new_pc && jframe->new_fp) { 1478 // This seems dubious 1479 read_pointer(J, jframe->new_fp + POINTER_SIZE, &jframe->new_pc); 1480 CHECK_FAIL(err); 1481 if (debug > 2) { 1482 printf("Jlookup_by_regs: (update pc) jframe->new_fp: %#llx, jframe->new_pc: %#llx\n", 1483 jframe->new_fp, jframe->new_pc); 1484 } 1485 } 1486 1487 #endif /* X86_COMPILER2 */ 1488 J->prev_fr = J->curr_fr; 1489 1490 if (debug) 1491 fprintf(stderr, "Jlookup_by_regs: END\n\n"); 1492 1493 return result; 1494 1495 fail: 1496 return err; 1497 } 1498 1499 void update_gregs(prgregset_t gregs, Jframe_t jframe) { 1500 #ifdef X86_COMPILER2 1501 if (debug > 0) { 1502 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]); 1503 } 1504 /* 1505 * A workaround for java C2 frames with unconventional FP. 1506 * may have to modify regset with new values for FP/PC/SP when needed. 1507 */ 1508 if (jframe.new_sp) { 1509 *((uintptr_t *) &gregs[R_SP]) = (uintptr_t) jframe.new_sp; 1510 } else { 1511 // *((uintptr_t *) &gregs[R_SP]) = (uintptr_t) gregs[R_FP] + 2 * POINTER_SIZE; 1512 } 1513 1514 if (jframe.new_fp) { 1515 *((uintptr_t *) &gregs[R_FP]) = (uintptr_t) jframe.new_fp; 1516 } 1517 if (jframe.new_pc) { 1518 *((uintptr_t *) &gregs[R_PC]) = (uintptr_t) jframe.new_pc; 1519 } 1520 if (debug > 0) { 1521 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]); 1522 } 1523 #endif /* X86_COMPILER2 */ 1524 } 1525 1526 /* 1527 * Iterates over java frames at current location given by 'gregs'. 1528 * 1529 * Returns -1 if no java frames are present or if an error is encountered. 1530 * Returns the result of calling 'func' if the return value is non-zero. 1531 * Returns 0 otherwise. 1532 */ 1533 int Jframe_iter(jvm_agent_t *J, prgregset_t gregs, java_stack_f *func, void* cld) { 1534 char buf[MAX_SYM_SIZE + 1]; 1535 Jframe_t jframe; 1536 int i = 0, res; 1537 #ifdef X86_COMPILER2 1538 if (debug > 0) { 1539 fprintf(stderr, "Jframe_iter: Entry sp = 0x%llx, fp = 0x%llx, pc = 0x%llx\n", gregs[R_SP], gregs[R_FP], gregs[R_PC]); 1540 } 1541 #endif /* X86_COMPILER2 */ 1542 1543 memset(&jframe, 0, sizeof(Jframe_t)); 1544 memset(buf, 0, sizeof(buf)); 1545 res = Jlookup_by_regs(J, gregs, buf, sizeof(buf), &jframe); 1546 if (res != PS_OK) 1547 return (-1); 1548 1549 1550 res = func(cld, gregs, buf, (jframe.locinf)? jframe.bci : -1, 1551 jframe.line, NULL); 1552 if (res != 0) { 1553 update_gregs(gregs, jframe); 1554 return (res); 1555 } 1556 for (i = 1; i < jframe.vf_cnt; i++) { 1557 Jget_vframe(J, i, buf, sizeof(buf), &jframe); 1558 res = func(cld, gregs, buf, (jframe.locinf)? jframe.bci : -1, 1559 jframe.line, NULL); 1560 if (res != 0) { 1561 update_gregs(gregs, jframe); 1562 return (res); 1563 } 1564 } 1565 update_gregs(gregs, jframe); 1566 return (0); 1567 }