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