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