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