147 uint64_t RuntimeStub_vtbl;
148 uint64_t Method_vtbl;
149
150 uint64_t Use_Compressed_Oops_address;
151 uint64_t Universe_narrow_oop_base_address;
152 uint64_t Universe_narrow_oop_shift_address;
153 uint64_t CodeCache_heap_address;
154
155 /* Volatiles */
156 uint8_t Use_Compressed_Oops;
157 uint64_t Universe_narrow_oop_base;
158 uint32_t Universe_narrow_oop_shift;
159 uint64_t CodeCache_low;
160 uint64_t CodeCache_high;
161 uint64_t CodeCache_segmap_low;
162 uint64_t CodeCache_segmap_high;
163
164 int32_t SIZE_CodeCache_log2_segment;
165
166 uint64_t methodPtr;
167 uint64_t bcx;
168
169 Nmethod_t *N; /*Inlined methods support */
170 Frame_t prev_fr;
171 Frame_t curr_fr;
172 };
173
174 static int
175 read_string(struct ps_prochandle *P,
176 char *buf, /* caller's buffer */
177 size_t size, /* upper limit on bytes to read */
178 uintptr_t addr) /* address in process */
179 {
180 int err = PS_OK;
181 while (size-- > 1 && err == PS_OK) {
182 err = ps_pread(P, addr, buf, 1);
183 if (*buf == '\0') {
184 return PS_OK;
185 }
186 addr += 1;
187 buf += 1;
1051 } else {
1052 err = name_for_methodPtr(J, method, result+1, size-1);
1053 CHECK_FAIL(err);
1054 }
1055 if (deoptimized) {
1056 strncat(result + 1, " [deoptimized frame]; ", size-1);
1057 } else {
1058 strncat(result + 1, " [compiled] ", size-1);
1059 }
1060 if (debug)
1061 fprintf(stderr, "name_for_nmethod: END: method name: %s, vf_cnt: %d\n\n",
1062 result, N->vf_cnt);
1063 return PS_OK;
1064
1065 fail:
1066 if (debug)
1067 fprintf(stderr, "name_for_nmethod: FAIL \n\n");
1068 return err;
1069 }
1070
1071 int is_bci(intptr_t bcx) {
1072 switch (DATA_MODEL) {
1073 case PR_MODEL_LP64:
1074 return ((uintptr_t) bcx) <= ((uintptr_t) MAX_METHOD_CODE_SIZE) ;
1075 case PR_MODEL_ILP32:
1076 default:
1077 return 0 <= bcx && bcx <= MAX_METHOD_CODE_SIZE;
1078 }
1079 }
1080
1081 static int
1082 name_for_imethod(jvm_agent_t* J,
1083 uint64_t bcx,
1084 uint64_t method,
1085 char *result,
1086 size_t size,
1087 Jframe_t *jframe
1088 ) {
1089 uint64_t bci;
1090 uint64_t constMethod;
1091 Vframe_t vframe = {0};
1092 Vframe_t *vf = &vframe;
1093 int32_t err;
1094
1095 err = read_pointer(J, method + OFFSET_Method_constMethod, &constMethod);
1096 CHECK_FAIL(err);
1097
1098 bci = is_bci(bcx) ? bcx : bcx - (constMethod + (uint64_t) SIZE_ConstMethod);
1099
1100 if (debug)
1101 fprintf(stderr, "\t name_for_imethod: BEGIN: method: %#llx\n", method);
1102
1103 err = name_for_methodPtr(J, method, result, size);
1104 CHECK_FAIL(err);
1105 if (debug)
1106 fprintf(stderr, "\t name_for_imethod: method name: %s\n", result);
1107
1108 if (bci > 0) {
1109 vf->method = method;
1110 vf->bci = bci;
1111 err = line_number_from_bci(J, vf);
1112 CHECK_FAIL(err);
1113 }
1114 jframe->bci = vf->bci;
1115 jframe->line = vf->line;
1116 jframe->locinf = 1;
1117
1118 if (debug) {
1152
1153 if (debug) {
1154 fprintf(stderr, "name_for_codecache: start: %#8llx, pc: %#8llx, method: %#8llx \n",
1155 start, pc, method);
1156 }
1157 err = name_for_nmethod(J, start, pc, method, result, size, jframe);
1158 CHECK_FAIL(err);
1159 } else if (vtbl == J->BufferBlob_vtbl) {
1160 const char * name;
1161
1162 err = read_string_pointer(J, start + OFFSET_CodeBlob_name, &name);
1163
1164 /*
1165 * Temporary usage of string "Interpreter".
1166 * We need some other way to distinguish "StubRoutines"
1167 * and regular interpreted frames.
1168 */
1169 if (err == PS_OK && strncmp(name, "Interpreter", 11) == 0) {
1170 *is_interpreted = 1;
1171 if (is_method(J, J->methodPtr)) {
1172 return name_for_imethod(J, J->bcx, J->methodPtr, result, size, jframe);
1173 }
1174 }
1175
1176 if (err == PS_OK) {
1177 strncpy(result, name, size);
1178 free((void*)name);
1179 } else {
1180 strncpy(result, "<unknown BufferBlob>", size);
1181 }
1182 /* return PS_OK; */
1183 } else {
1184 const char * name;
1185
1186 err = read_string_pointer(J, start + OFFSET_CodeBlob_name, &name);
1187 if (err == PS_OK) {
1188 strncpy(result, name, size);
1189 free((void*)name);
1190 } else {
1191 strncpy(result, "<unknown CodeBlob>", size);
1192 WARN1("unknown CodeBlob: vtbl = 0x%x", vtbl);
1309 name, vf->line);
1310 }
1311 return PS_OK;
1312
1313 fail:
1314 if (debug) {
1315 fprintf(stderr, "\t Jget_vframe: FAIL\n");
1316 }
1317 return err;
1318 }
1319
1320 #define MAX_SYM_SIZE 256
1321
1322 int Jlookup_by_regs(jvm_agent_t* J, const prgregset_t regs, char *name,
1323 size_t size, Jframe_t *jframe) {
1324 uintptr_t fp;
1325 uintptr_t pc;
1326 /* arguments given to read_pointer need to be worst case sized */
1327 uint64_t methodPtr = 0;
1328 uint64_t sender_sp;
1329 uint64_t bcx = 0;
1330 int is_interpreted = 0;
1331 int result = PS_OK;
1332 int err = PS_OK;
1333
1334 if (J == NULL) {
1335 return -1;
1336 }
1337
1338 jframe->vf_cnt = 1;
1339 jframe->new_fp = 0;
1340 jframe->new_pc = 0;
1341 jframe->line = 0;
1342 jframe->bci = 0;
1343 jframe->locinf = 0;
1344
1345 read_volatiles(J);
1346 pc = (uintptr_t) regs[R_PC];
1347 J->curr_fr.pc = pc;
1348 J->curr_fr.fp = regs[R_FP];
1349 J->curr_fr.sp = regs[R_SP];
1350
1351 if (debug)
1352 fprintf(stderr, "Jlookup_by_regs: BEGINs: fp=%#lx, pc=%#lx\n", regs[R_FP], pc);
1353
1354 #if defined(sparc) || defined(__sparc)
1355 /* The following workaround is for SPARC. CALL instruction occupates 8 bytes.
1356 * In the pcDesc structure return pc offset is recorded for CALL instructions.
1357 * regs[R_PC] contains a CALL instruction pc offset.
1358 */
1359 pc += 8;
1360 bcx = (uintptr_t) regs[R_L1];
1361 methodPtr = (uintptr_t) regs[R_L2];
1362 sender_sp = regs[R_I5];
1363 if (debug > 2) {
1364 fprintf(stderr, "\nregs[R_I1]=%lx, regs[R_I2]=%lx, regs[R_I5]=%lx, regs[R_L1]=%lx, regs[R_L2]=%lx\n",
1365 regs[R_I1], regs[R_I2], regs[R_I5], regs[R_L1], regs[R_L2]);
1366 }
1367 #elif defined(i386) || defined(__i386) || defined(__amd64)
1368
1369 fp = (uintptr_t) regs[R_FP];
1370 if (J->prev_fr.fp == 0) {
1371 #ifdef X86_COMPILER2
1372 /* A workaround for top java frames */
1373 J->prev_fr.fp = (uintptr_t)(regs[R_SP] - 2 * POINTER_SIZE);
1374 #else
1375 J->prev_fr.fp = (uintptr_t)(regs[R_SP] - POINTER_SIZE);
1376 #endif /* COMPILER2 */
1377 }
1378 if (debug > 2) {
1379 printf("Jlookup_by_regs: J->prev_fr.fp = %#lx\n", J->prev_fr.fp);
1380 }
1381
1382 if (read_pointer(J, fp + OFFSET_interpreter_frame_method, &methodPtr) != PS_OK) {
1383 methodPtr = 0;
1384 }
1385 if (read_pointer(J, fp + OFFSET_interpreter_frame_sender_sp, &sender_sp) != PS_OK) {
1386 sender_sp = 0;
1387 }
1388 if (read_pointer(J, fp + OFFSET_interpreter_frame_bcx_offset, &bcx) != PS_OK) {
1389 bcx = 0;
1390 }
1391 #endif /* i386 */
1392
1393 J->methodPtr = methodPtr;
1394 J->bcx = bcx;
1395
1396 /* On x86 with C2 JVM: native frame may have wrong regs[R_FP]
1397 * For example: JVM_SuspendThread frame poins to the top interpreted frame.
1398 * If we call is_method(J, methodPtr) before codecache_contains(J, pc)
1399 * then we go over and omit both: nmethod and I2CAdapter frames.
1400 * Note, that regs[R_PC] is always correct if frame defined correctly.
1401 * So it is better to call codecache_contains(J, pc) from the beginning.
1402 */
1403 #ifndef X86_COMPILER2
1404 if (is_method(J, J->methodPtr)) {
1405 result = name_for_imethod(J, bcx, J->methodPtr, name, size, jframe);
1406 /* If the methodPtr is a method then this is highly likely to be
1407 an interpreter frame */
1408 if (result >= 0) {
1409 is_interpreted = 1;
1410 }
1411 } else
1412 #endif /* ! X86_COMPILER2 */
1413
1414 if (codecache_contains(J, pc)) {
1415 result = name_for_codecache(J, fp, pc, name, size, jframe, &is_interpreted);
1416 }
1417 #ifdef X86_COMPILER2
1418 else if (is_method(J, J->methodPtr)) {
1419 result = name_for_imethod(J, bcx, J->methodPtr, name, size, jframe);
1420 /* If the methodPtr is a method then this is highly likely to be
1421 an interpreter frame */
1422 if (result >= 0) {
1423 is_interpreted = 1;
1424 }
1425 }
1426 #endif /* X86_COMPILER2 */
1427 else {
1428 if (debug) {
1429 fprintf(stderr, "Jlookup_by_regs: END with -1\n\n");
1430 }
1431 result = -1;
1432 }
1433 if (!is_interpreted) {
1434 sender_sp = 0;
1435 }
1436 J->curr_fr.sender_sp = sender_sp;
1437
1438 #ifdef X86_COMPILER2
1439 if (!J->curr_fr.fp) {
|
147 uint64_t RuntimeStub_vtbl;
148 uint64_t Method_vtbl;
149
150 uint64_t Use_Compressed_Oops_address;
151 uint64_t Universe_narrow_oop_base_address;
152 uint64_t Universe_narrow_oop_shift_address;
153 uint64_t CodeCache_heap_address;
154
155 /* Volatiles */
156 uint8_t Use_Compressed_Oops;
157 uint64_t Universe_narrow_oop_base;
158 uint32_t Universe_narrow_oop_shift;
159 uint64_t CodeCache_low;
160 uint64_t CodeCache_high;
161 uint64_t CodeCache_segmap_low;
162 uint64_t CodeCache_segmap_high;
163
164 int32_t SIZE_CodeCache_log2_segment;
165
166 uint64_t methodPtr;
167 uint64_t bcp;
168
169 Nmethod_t *N; /*Inlined methods support */
170 Frame_t prev_fr;
171 Frame_t curr_fr;
172 };
173
174 static int
175 read_string(struct ps_prochandle *P,
176 char *buf, /* caller's buffer */
177 size_t size, /* upper limit on bytes to read */
178 uintptr_t addr) /* address in process */
179 {
180 int err = PS_OK;
181 while (size-- > 1 && err == PS_OK) {
182 err = ps_pread(P, addr, buf, 1);
183 if (*buf == '\0') {
184 return PS_OK;
185 }
186 addr += 1;
187 buf += 1;
1051 } else {
1052 err = name_for_methodPtr(J, method, result+1, size-1);
1053 CHECK_FAIL(err);
1054 }
1055 if (deoptimized) {
1056 strncat(result + 1, " [deoptimized frame]; ", size-1);
1057 } else {
1058 strncat(result + 1, " [compiled] ", size-1);
1059 }
1060 if (debug)
1061 fprintf(stderr, "name_for_nmethod: END: method name: %s, vf_cnt: %d\n\n",
1062 result, N->vf_cnt);
1063 return PS_OK;
1064
1065 fail:
1066 if (debug)
1067 fprintf(stderr, "name_for_nmethod: FAIL \n\n");
1068 return err;
1069 }
1070
1071 static int
1072 name_for_imethod(jvm_agent_t* J,
1073 uint64_t bcp,
1074 uint64_t method,
1075 char *result,
1076 size_t size,
1077 Jframe_t *jframe
1078 ) {
1079 uint64_t bci;
1080 uint64_t constMethod;
1081 Vframe_t vframe = {0};
1082 Vframe_t *vf = &vframe;
1083 int32_t err;
1084
1085 err = read_pointer(J, method + OFFSET_Method_constMethod, &constMethod);
1086 CHECK_FAIL(err);
1087
1088 bci = bcp - (constMethod + (uint64_t) SIZE_ConstMethod);
1089
1090 if (debug)
1091 fprintf(stderr, "\t name_for_imethod: BEGIN: method: %#llx\n", method);
1092
1093 err = name_for_methodPtr(J, method, result, size);
1094 CHECK_FAIL(err);
1095 if (debug)
1096 fprintf(stderr, "\t name_for_imethod: method name: %s\n", result);
1097
1098 if (bci > 0) {
1099 vf->method = method;
1100 vf->bci = bci;
1101 err = line_number_from_bci(J, vf);
1102 CHECK_FAIL(err);
1103 }
1104 jframe->bci = vf->bci;
1105 jframe->line = vf->line;
1106 jframe->locinf = 1;
1107
1108 if (debug) {
1142
1143 if (debug) {
1144 fprintf(stderr, "name_for_codecache: start: %#8llx, pc: %#8llx, method: %#8llx \n",
1145 start, pc, method);
1146 }
1147 err = name_for_nmethod(J, start, pc, method, result, size, jframe);
1148 CHECK_FAIL(err);
1149 } else if (vtbl == J->BufferBlob_vtbl) {
1150 const char * name;
1151
1152 err = read_string_pointer(J, start + OFFSET_CodeBlob_name, &name);
1153
1154 /*
1155 * Temporary usage of string "Interpreter".
1156 * We need some other way to distinguish "StubRoutines"
1157 * and regular interpreted frames.
1158 */
1159 if (err == PS_OK && strncmp(name, "Interpreter", 11) == 0) {
1160 *is_interpreted = 1;
1161 if (is_method(J, J->methodPtr)) {
1162 return name_for_imethod(J, J->bcp, J->methodPtr, result, size, jframe);
1163 }
1164 }
1165
1166 if (err == PS_OK) {
1167 strncpy(result, name, size);
1168 free((void*)name);
1169 } else {
1170 strncpy(result, "<unknown BufferBlob>", size);
1171 }
1172 /* return PS_OK; */
1173 } else {
1174 const char * name;
1175
1176 err = read_string_pointer(J, start + OFFSET_CodeBlob_name, &name);
1177 if (err == PS_OK) {
1178 strncpy(result, name, size);
1179 free((void*)name);
1180 } else {
1181 strncpy(result, "<unknown CodeBlob>", size);
1182 WARN1("unknown CodeBlob: vtbl = 0x%x", vtbl);
1299 name, vf->line);
1300 }
1301 return PS_OK;
1302
1303 fail:
1304 if (debug) {
1305 fprintf(stderr, "\t Jget_vframe: FAIL\n");
1306 }
1307 return err;
1308 }
1309
1310 #define MAX_SYM_SIZE 256
1311
1312 int Jlookup_by_regs(jvm_agent_t* J, const prgregset_t regs, char *name,
1313 size_t size, Jframe_t *jframe) {
1314 uintptr_t fp;
1315 uintptr_t pc;
1316 /* arguments given to read_pointer need to be worst case sized */
1317 uint64_t methodPtr = 0;
1318 uint64_t sender_sp;
1319 uint64_t bcp = 0;
1320 int is_interpreted = 0;
1321 int result = PS_OK;
1322 int err = PS_OK;
1323
1324 if (J == NULL) {
1325 return -1;
1326 }
1327
1328 jframe->vf_cnt = 1;
1329 jframe->new_fp = 0;
1330 jframe->new_pc = 0;
1331 jframe->line = 0;
1332 jframe->bci = 0;
1333 jframe->locinf = 0;
1334
1335 read_volatiles(J);
1336 pc = (uintptr_t) regs[R_PC];
1337 J->curr_fr.pc = pc;
1338 J->curr_fr.fp = regs[R_FP];
1339 J->curr_fr.sp = regs[R_SP];
1340
1341 if (debug)
1342 fprintf(stderr, "Jlookup_by_regs: BEGINs: fp=%#lx, pc=%#lx\n", regs[R_FP], pc);
1343
1344 #if defined(sparc) || defined(__sparc)
1345 /* The following workaround is for SPARC. CALL instruction occupates 8 bytes.
1346 * In the pcDesc structure return pc offset is recorded for CALL instructions.
1347 * regs[R_PC] contains a CALL instruction pc offset.
1348 */
1349 pc += 8;
1350 bcp = (uintptr_t) regs[R_L1];
1351 methodPtr = (uintptr_t) regs[R_L2];
1352 sender_sp = regs[R_I5];
1353 if (debug > 2) {
1354 fprintf(stderr, "\nregs[R_I1]=%lx, regs[R_I2]=%lx, regs[R_I5]=%lx, regs[R_L1]=%lx, regs[R_L2]=%lx\n",
1355 regs[R_I1], regs[R_I2], regs[R_I5], regs[R_L1], regs[R_L2]);
1356 }
1357 #elif defined(i386) || defined(__i386) || defined(__amd64)
1358
1359 fp = (uintptr_t) regs[R_FP];
1360 if (J->prev_fr.fp == 0) {
1361 #ifdef X86_COMPILER2
1362 /* A workaround for top java frames */
1363 J->prev_fr.fp = (uintptr_t)(regs[R_SP] - 2 * POINTER_SIZE);
1364 #else
1365 J->prev_fr.fp = (uintptr_t)(regs[R_SP] - POINTER_SIZE);
1366 #endif /* COMPILER2 */
1367 }
1368 if (debug > 2) {
1369 printf("Jlookup_by_regs: J->prev_fr.fp = %#lx\n", J->prev_fr.fp);
1370 }
1371
1372 if (read_pointer(J, fp + OFFSET_interpreter_frame_method, &methodPtr) != PS_OK) {
1373 methodPtr = 0;
1374 }
1375 if (read_pointer(J, fp + OFFSET_interpreter_frame_sender_sp, &sender_sp) != PS_OK) {
1376 sender_sp = 0;
1377 }
1378 if (read_pointer(J, fp + OFFSET_interpreter_frame_bcp_offset, &bcp) != PS_OK) {
1379 bcp = 0;
1380 }
1381 #endif /* i386 */
1382
1383 J->methodPtr = methodPtr;
1384 J->bcp = bcp;
1385
1386 /* On x86 with C2 JVM: native frame may have wrong regs[R_FP]
1387 * For example: JVM_SuspendThread frame poins to the top interpreted frame.
1388 * If we call is_method(J, methodPtr) before codecache_contains(J, pc)
1389 * then we go over and omit both: nmethod and I2CAdapter frames.
1390 * Note, that regs[R_PC] is always correct if frame defined correctly.
1391 * So it is better to call codecache_contains(J, pc) from the beginning.
1392 */
1393 #ifndef X86_COMPILER2
1394 if (is_method(J, J->methodPtr)) {
1395 result = name_for_imethod(J, bcp, J->methodPtr, name, size, jframe);
1396 /* If the methodPtr is a method then this is highly likely to be
1397 an interpreter frame */
1398 if (result >= 0) {
1399 is_interpreted = 1;
1400 }
1401 } else
1402 #endif /* ! X86_COMPILER2 */
1403
1404 if (codecache_contains(J, pc)) {
1405 result = name_for_codecache(J, fp, pc, name, size, jframe, &is_interpreted);
1406 }
1407 #ifdef X86_COMPILER2
1408 else if (is_method(J, J->methodPtr)) {
1409 result = name_for_imethod(J, bcp, J->methodPtr, name, size, jframe);
1410 /* If the methodPtr is a method then this is highly likely to be
1411 an interpreter frame */
1412 if (result >= 0) {
1413 is_interpreted = 1;
1414 }
1415 }
1416 #endif /* X86_COMPILER2 */
1417 else {
1418 if (debug) {
1419 fprintf(stderr, "Jlookup_by_regs: END with -1\n\n");
1420 }
1421 result = -1;
1422 }
1423 if (!is_interpreted) {
1424 sender_sp = 0;
1425 }
1426 J->curr_fr.sender_sp = sender_sp;
1427
1428 #ifdef X86_COMPILER2
1429 if (!J->curr_fr.fp) {
|