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