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