/* * Class: sun_jvm_hotspot_debugger_proc_ProcDebuggerLocal * Method: lookupByAddress0 * Signature: (J)Lsun/jvm/hotspot/debugger/cdbg/ClosestSymbol; * Description: lookup symbol name for a given address */ JNIEXPORT jobject JNICALL Java_sun_jvm_hotspot_debugger_proc_ProcDebuggerLocal_lookupByAddress0 (JNIEnv *env, jobject this_obj, jlong address) { jlong p_ps_prochandle; p_ps_prochandle = env->GetLongField(this_obj, p_ps_prochandle_ID); char nameBuf[SYMBOL_BUF_SIZE + 1]; GElf_Sym sym; int res = Plookup_by_addr((struct ps_prochandle*) p_ps_prochandle, (uintptr_t) address, nameBuf, sizeof(nameBuf), &sym); if (res != 0) { // failed return 0; } jstring resSym = env->NewStringUTF(nameBuf); CHECK_EXCEPTION_(0); return env->CallObjectMethod(this_obj, createClosestSymbol_ID, resSym, (address - sym.st_value)); }
static int dt_pid_per_mod(void *arg, const prmap_t *pmp, const char *obj) { dt_pid_probe_t *pp = arg; dtrace_hdl_t *dtp = pp->dpp_dtp; dt_pcb_t *pcb = pp->dpp_pcb; dt_proc_t *dpr = pp->dpp_dpr; GElf_Sym sym; if (obj == NULL) return (0); #if defined(sun) (void) Plmid(pp->dpp_pr, pmp->pr_vaddr, &pp->dpp_lmid); #endif if ((pp->dpp_obj = strrchr(obj, '/')) == NULL) pp->dpp_obj = obj; else pp->dpp_obj++; #if defined(sun) if (Pxlookup_by_name(pp->dpp_pr, pp->dpp_lmid, obj, ".stret1", &sym, NULL) == 0) pp->dpp_stret[0] = sym.st_value; else pp->dpp_stret[0] = 0; if (Pxlookup_by_name(pp->dpp_pr, pp->dpp_lmid, obj, ".stret2", &sym, NULL) == 0) pp->dpp_stret[1] = sym.st_value; else pp->dpp_stret[1] = 0; if (Pxlookup_by_name(pp->dpp_pr, pp->dpp_lmid, obj, ".stret4", &sym, NULL) == 0) pp->dpp_stret[2] = sym.st_value; else pp->dpp_stret[2] = 0; if (Pxlookup_by_name(pp->dpp_pr, pp->dpp_lmid, obj, ".stret8", &sym, NULL) == 0) pp->dpp_stret[3] = sym.st_value; else pp->dpp_stret[3] = 0; #else pp->dpp_stret[0] = 0; pp->dpp_stret[1] = 0; pp->dpp_stret[2] = 0; pp->dpp_stret[3] = 0; #endif dt_dprintf("%s stret %llx %llx %llx %llx\n", obj, (u_longlong_t)pp->dpp_stret[0], (u_longlong_t)pp->dpp_stret[1], (u_longlong_t)pp->dpp_stret[2], (u_longlong_t)pp->dpp_stret[3]); /* * If pp->dpp_func contains any globbing meta-characters, we need * to iterate over the symbol table and compare each function name * against the pattern. */ if (!strisglob(pp->dpp_func)) { /* * If we fail to lookup the symbol, try interpreting the * function as the special "-" function that indicates that the * probe name should be interpreted as a absolute virtual * address. If that fails and we were matching a specific * function in a specific module, report the error, otherwise * just fail silently in the hopes that some other object will * contain the desired symbol. */ if (Pxlookup_by_name(pp->dpp_pr, pp->dpp_lmid, obj, pp->dpp_func, &sym, NULL) != 0) { if (strcmp("-", pp->dpp_func) == 0) { sym.st_name = 0; sym.st_info = GELF_ST_INFO(STB_LOCAL, STT_FUNC); sym.st_other = 0; sym.st_value = 0; #if defined(sun) sym.st_size = Pstatus(pp->dpp_pr)->pr_dmodel == PR_MODEL_ILP32 ? -1U : -1ULL; #else sym.st_size = ~((Elf64_Xword) 0); #endif } else if (!strisglob(pp->dpp_mod)) { return (dt_pid_error(dtp, pcb, dpr, NULL, D_PROC_FUNC, "failed to lookup '%s' in module '%s'", pp->dpp_func, pp->dpp_mod)); } else { return (0); } } /* * Only match defined functions of non-zero size. */ if (GELF_ST_TYPE(sym.st_info) != STT_FUNC || sym.st_shndx == SHN_UNDEF || sym.st_size == 0) return (0); /* * We don't instrument PLTs -- they're dynamically rewritten, * and, so, inherently dicey to instrument. */ #ifdef DOODAD if (Ppltdest(pp->dpp_pr, sym.st_value) != NULL) return (0); #endif (void) Plookup_by_addr(pp->dpp_pr, sym.st_value, pp->dpp_func, DTRACE_FUNCNAMELEN, &sym); return (dt_pid_per_sym(pp, &sym, pp->dpp_func)); } else { uint_t nmatches = pp->dpp_nmatches; if (Psymbol_iter_by_addr(pp->dpp_pr, obj, PR_SYMTAB, BIND_ANY | TYPE_FUNC, dt_pid_sym_filt, pp) == 1) return (1); if (nmatches == pp->dpp_nmatches) { /* * If we didn't match anything in the PR_SYMTAB, try * the PR_DYNSYM. */ if (Psymbol_iter_by_addr(pp->dpp_pr, obj, PR_DYNSYM, BIND_ANY | TYPE_FUNC, dt_pid_sym_filt, pp) == 1) return (1); } } return (0); }