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