Path: blob/aarch64-shenandoah-jdk8u272-b10/hotspot/agent/src/os/bsd/BsdDebuggerLocal.c
38833 views
/*1* Copyright (c) 2002, 2007, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*22*/2324#include <stdlib.h>25#include <jni.h>26#include "libproc.h"2728#if defined(x86_64) && !defined(amd64)29#define amd64 130#endif3132#ifdef i38633#include "sun_jvm_hotspot_debugger_x86_X86ThreadContext.h"34#endif3536#ifdef amd6437#include "sun_jvm_hotspot_debugger_amd64_AMD64ThreadContext.h"38#endif3940#ifdef aarch6441#include "sun_jvm_hotspot_debugger_aarch64_AARCH64ThreadContext.h"42#endif4344#if defined(sparc) || defined(sparcv9)45#include "sun_jvm_hotspot_debugger_sparc_SPARCThreadContext.h"46#endif4748static jfieldID p_ps_prochandle_ID = 0;49static jfieldID threadList_ID = 0;50static jfieldID loadObjectList_ID = 0;5152static jmethodID createClosestSymbol_ID = 0;53static jmethodID createLoadObject_ID = 0;54static jmethodID getThreadForThreadId_ID = 0;55static jmethodID listAdd_ID = 0;5657#define CHECK_EXCEPTION_(value) if ((*env)->ExceptionOccurred(env)) { return value; }58#define CHECK_EXCEPTION if ((*env)->ExceptionOccurred(env)) { return;}59#define THROW_NEW_DEBUGGER_EXCEPTION_(str, value) { throw_new_debugger_exception(env, str); return value; }60#define THROW_NEW_DEBUGGER_EXCEPTION(str) { throw_new_debugger_exception(env, str); return;}6162static void throw_new_debugger_exception(JNIEnv* env, const char* errMsg) {63(*env)->ThrowNew(env, (*env)->FindClass(env, "sun/jvm/hotspot/debugger/DebuggerException"), errMsg);64}6566static struct ps_prochandle* get_proc_handle(JNIEnv* env, jobject this_obj) {67jlong ptr = (*env)->GetLongField(env, this_obj, p_ps_prochandle_ID);68return (struct ps_prochandle*)(intptr_t)ptr;69}7071/*72* Class: sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal73* Method: init074* Signature: ()V75*/76JNIEXPORT void JNICALL Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_init077(JNIEnv *env, jclass cls) {78jclass listClass;7980if (init_libproc(getenv("LIBSAPROC_DEBUG") != NULL) != true) {81THROW_NEW_DEBUGGER_EXCEPTION("can't initialize libproc");82}8384// fields we use85p_ps_prochandle_ID = (*env)->GetFieldID(env, cls, "p_ps_prochandle", "J");86CHECK_EXCEPTION;87threadList_ID = (*env)->GetFieldID(env, cls, "threadList", "Ljava/util/List;");88CHECK_EXCEPTION;89loadObjectList_ID = (*env)->GetFieldID(env, cls, "loadObjectList", "Ljava/util/List;");90CHECK_EXCEPTION;9192// methods we use93createClosestSymbol_ID = (*env)->GetMethodID(env, cls, "createClosestSymbol",94"(Ljava/lang/String;J)Lsun/jvm/hotspot/debugger/cdbg/ClosestSymbol;");95CHECK_EXCEPTION;96createLoadObject_ID = (*env)->GetMethodID(env, cls, "createLoadObject",97"(Ljava/lang/String;JJ)Lsun/jvm/hotspot/debugger/cdbg/LoadObject;");98CHECK_EXCEPTION;99getThreadForThreadId_ID = (*env)->GetMethodID(env, cls, "getThreadForThreadId",100"(J)Lsun/jvm/hotspot/debugger/ThreadProxy;");101CHECK_EXCEPTION;102// java.util.List method we call103listClass = (*env)->FindClass(env, "java/util/List");104CHECK_EXCEPTION;105listAdd_ID = (*env)->GetMethodID(env, listClass, "add", "(Ljava/lang/Object;)Z");106CHECK_EXCEPTION;107}108109JNIEXPORT jint JNICALL Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_getAddressSize110(JNIEnv *env, jclass cls)111{112#ifdef _LP64113return 8;114#else115return 4;116#endif117118}119120121static void fillThreadsAndLoadObjects(JNIEnv* env, jobject this_obj, struct ps_prochandle* ph) {122int n = 0, i = 0;123124// add threads125n = get_num_threads(ph);126for (i = 0; i < n; i++) {127jobject thread;128jobject threadList;129lwpid_t lwpid;130131lwpid = get_lwp_id(ph, i);132thread = (*env)->CallObjectMethod(env, this_obj, getThreadForThreadId_ID,133(jlong)lwpid);134CHECK_EXCEPTION;135threadList = (*env)->GetObjectField(env, this_obj, threadList_ID);136CHECK_EXCEPTION;137(*env)->CallBooleanMethod(env, threadList, listAdd_ID, thread);138CHECK_EXCEPTION;139}140141// add load objects142n = get_num_libs(ph);143for (i = 0; i < n; i++) {144uintptr_t base;145const char* name;146jobject loadObject;147jobject loadObjectList;148149base = get_lib_base(ph, i);150name = get_lib_name(ph, i);151loadObject = (*env)->CallObjectMethod(env, this_obj, createLoadObject_ID,152(*env)->NewStringUTF(env, name), (jlong)0, (jlong)base);153CHECK_EXCEPTION;154loadObjectList = (*env)->GetObjectField(env, this_obj, loadObjectList_ID);155CHECK_EXCEPTION;156(*env)->CallBooleanMethod(env, loadObjectList, listAdd_ID, loadObject);157CHECK_EXCEPTION;158}159}160161/*162* Class: sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal163* Method: attach0164* Signature: (I)V165*/166JNIEXPORT void JNICALL Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_attach0__I167(JNIEnv *env, jobject this_obj, jint jpid) {168169struct ps_prochandle* ph;170if ( (ph = Pgrab(jpid)) == NULL) {171THROW_NEW_DEBUGGER_EXCEPTION("Can't attach to the process");172}173(*env)->SetLongField(env, this_obj, p_ps_prochandle_ID, (jlong)(intptr_t)ph);174fillThreadsAndLoadObjects(env, this_obj, ph);175}176177/*178* Class: sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal179* Method: attach0180* Signature: (Ljava/lang/String;Ljava/lang/String;)V181*/182JNIEXPORT void JNICALL Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_attach0__Ljava_lang_String_2Ljava_lang_String_2183(JNIEnv *env, jobject this_obj, jstring execName, jstring coreName) {184const char *execName_cstr;185const char *coreName_cstr;186jboolean isCopy;187struct ps_prochandle* ph;188189execName_cstr = (*env)->GetStringUTFChars(env, execName, &isCopy);190CHECK_EXCEPTION;191coreName_cstr = (*env)->GetStringUTFChars(env, coreName, &isCopy);192CHECK_EXCEPTION;193194if ( (ph = Pgrab_core(execName_cstr, coreName_cstr)) == NULL) {195(*env)->ReleaseStringUTFChars(env, execName, execName_cstr);196(*env)->ReleaseStringUTFChars(env, coreName, coreName_cstr);197THROW_NEW_DEBUGGER_EXCEPTION("Can't attach to the core file");198}199(*env)->SetLongField(env, this_obj, p_ps_prochandle_ID, (jlong)(intptr_t)ph);200(*env)->ReleaseStringUTFChars(env, execName, execName_cstr);201(*env)->ReleaseStringUTFChars(env, coreName, coreName_cstr);202fillThreadsAndLoadObjects(env, this_obj, ph);203}204205/*206* Class: sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal207* Method: detach0208* Signature: ()V209*/210JNIEXPORT void JNICALL Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_detach0211(JNIEnv *env, jobject this_obj) {212struct ps_prochandle* ph = get_proc_handle(env, this_obj);213if (ph != NULL) {214Prelease(ph);215}216}217218/*219* Class: sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal220* Method: lookupByName0221* Signature: (Ljava/lang/String;Ljava/lang/String;)J222*/223JNIEXPORT jlong JNICALL Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_lookupByName0224(JNIEnv *env, jobject this_obj, jstring objectName, jstring symbolName) {225const char *objectName_cstr, *symbolName_cstr;226jlong addr;227jboolean isCopy;228struct ps_prochandle* ph = get_proc_handle(env, this_obj);229230objectName_cstr = NULL;231if (objectName != NULL) {232objectName_cstr = (*env)->GetStringUTFChars(env, objectName, &isCopy);233CHECK_EXCEPTION_(0);234}235symbolName_cstr = (*env)->GetStringUTFChars(env, symbolName, &isCopy);236CHECK_EXCEPTION_(0);237238addr = (jlong) lookup_symbol(ph, objectName_cstr, symbolName_cstr);239240if (objectName_cstr != NULL) {241(*env)->ReleaseStringUTFChars(env, objectName, objectName_cstr);242}243(*env)->ReleaseStringUTFChars(env, symbolName, symbolName_cstr);244return addr;245}246247/*248* Class: sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal249* Method: lookupByAddress0250* Signature: (J)Lsun/jvm/hotspot/debugger/cdbg/ClosestSymbol;251*/252JNIEXPORT jobject JNICALL Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_lookupByAddress0253(JNIEnv *env, jobject this_obj, jlong addr) {254uintptr_t offset;255const char* sym = NULL;256257struct ps_prochandle* ph = get_proc_handle(env, this_obj);258sym = symbol_for_pc(ph, (uintptr_t) addr, &offset);259if (sym == NULL) return 0;260return (*env)->CallObjectMethod(env, this_obj, createClosestSymbol_ID,261(*env)->NewStringUTF(env, sym), (jlong)offset);262}263264/*265* Class: sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal266* Method: readBytesFromProcess0267* Signature: (JJ)Lsun/jvm/hotspot/debugger/ReadResult;268*/269JNIEXPORT jbyteArray JNICALL Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_readBytesFromProcess0270(JNIEnv *env, jobject this_obj, jlong addr, jlong numBytes) {271272jboolean isCopy;273jbyteArray array;274jbyte *bufPtr;275ps_err_e err;276277array = (*env)->NewByteArray(env, numBytes);278CHECK_EXCEPTION_(0);279bufPtr = (*env)->GetByteArrayElements(env, array, &isCopy);280CHECK_EXCEPTION_(0);281282err = ps_pread(get_proc_handle(env, this_obj), (psaddr_t) (uintptr_t)addr, bufPtr, numBytes);283(*env)->ReleaseByteArrayElements(env, array, bufPtr, 0);284return (err == PS_OK)? array : 0;285}286287JNIEXPORT jlongArray JNICALL Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_getThreadIntegerRegisterSet0288(JNIEnv *env, jobject this_obj, jint lwp_id) {289290struct reg gregs;291jboolean isCopy;292jlongArray array;293jlong *regs;294295struct ps_prochandle* ph = get_proc_handle(env, this_obj);296if (get_lwp_regs(ph, lwp_id, &gregs) != true) {297THROW_NEW_DEBUGGER_EXCEPTION_("get_thread_regs failed for a lwp", 0);298}299300#undef NPRGREG301#ifdef i386302#define NPRGREG sun_jvm_hotspot_debugger_x86_X86ThreadContext_NPRGREG303#endif304#ifdef ia64305#define NPRGREG IA64_REG_COUNT306#endif307#ifdef amd64308#define NPRGREG sun_jvm_hotspot_debugger_amd64_AMD64ThreadContext_NPRGREG309#endif310#ifdef aarch64311#define NPRGREG sun_jvm_hotspot_debugger_aarch64_AARCH64ThreadContext_NPRGREG312#endif313#if defined(sparc) || defined(sparcv9)314#define NPRGREG sun_jvm_hotspot_debugger_sparc_SPARCThreadContext_NPRGREG315#endif316317array = (*env)->NewLongArray(env, NPRGREG);318CHECK_EXCEPTION_(0);319regs = (*env)->GetLongArrayElements(env, array, &isCopy);320321#undef REG_INDEX322323#ifdef i386324#define REG_INDEX(reg) sun_jvm_hotspot_debugger_x86_X86ThreadContext_##reg325326regs[REG_INDEX(GS)] = (uintptr_t) gregs.r_gs;327regs[REG_INDEX(FS)] = (uintptr_t) gregs.r_fs;328regs[REG_INDEX(ES)] = (uintptr_t) gregs.r_es;329regs[REG_INDEX(DS)] = (uintptr_t) gregs.r_ds;330regs[REG_INDEX(EDI)] = (uintptr_t) gregs.r_edi;331regs[REG_INDEX(ESI)] = (uintptr_t) gregs.r_esi;332regs[REG_INDEX(FP)] = (uintptr_t) gregs.r_ebp;333regs[REG_INDEX(SP)] = (uintptr_t) gregs.r_isp;334regs[REG_INDEX(EBX)] = (uintptr_t) gregs.r_ebx;335regs[REG_INDEX(EDX)] = (uintptr_t) gregs.r_edx;336regs[REG_INDEX(ECX)] = (uintptr_t) gregs.r_ecx;337regs[REG_INDEX(EAX)] = (uintptr_t) gregs.r_eax;338regs[REG_INDEX(PC)] = (uintptr_t) gregs.r_eip;339regs[REG_INDEX(CS)] = (uintptr_t) gregs.r_cs;340regs[REG_INDEX(SS)] = (uintptr_t) gregs.r_ss;341342#endif /* i386 */343344#if ia64345regs = (*env)->GetLongArrayElements(env, array, &isCopy);346int i;347for (i = 0; i < NPRGREG; i++ ) {348regs[i] = 0xDEADDEAD;349}350#endif /* ia64 */351352#ifdef amd64353#define REG_INDEX(reg) sun_jvm_hotspot_debugger_amd64_AMD64ThreadContext_##reg354355regs[REG_INDEX(R15)] = gregs.r_r15;356regs[REG_INDEX(R14)] = gregs.r_r14;357regs[REG_INDEX(R13)] = gregs.r_r13;358regs[REG_INDEX(R12)] = gregs.r_r12;359regs[REG_INDEX(RBP)] = gregs.r_rbp;360regs[REG_INDEX(RBX)] = gregs.r_rbx;361regs[REG_INDEX(R11)] = gregs.r_r11;362regs[REG_INDEX(R10)] = gregs.r_r10;363regs[REG_INDEX(R9)] = gregs.r_r9;364regs[REG_INDEX(R8)] = gregs.r_r8;365regs[REG_INDEX(RAX)] = gregs.r_rax;366regs[REG_INDEX(RCX)] = gregs.r_rcx;367regs[REG_INDEX(RDX)] = gregs.r_rdx;368regs[REG_INDEX(RSI)] = gregs.r_rsi;369regs[REG_INDEX(RDI)] = gregs.r_rdi;370regs[REG_INDEX(RIP)] = gregs.r_rip;371regs[REG_INDEX(CS)] = gregs.r_cs;372regs[REG_INDEX(RSP)] = gregs.r_rsp;373regs[REG_INDEX(SS)] = gregs.r_ss;374// regs[REG_INDEX(FSBASE)] = gregs.fs_base;375// regs[REG_INDEX(GSBASE)] = gregs.gs_base;376// regs[REG_INDEX(DS)] = gregs.ds;377// regs[REG_INDEX(ES)] = gregs.es;378// regs[REG_INDEX(FS)] = gregs.fs;379// regs[REG_INDEX(GS)] = gregs.gs;380381#endif /* amd64 */382383#if defined(sparc) || defined(sparcv9)384385#define REG_INDEX(reg) sun_jvm_hotspot_debugger_sparc_SPARCThreadContext_##reg386387#ifdef _LP64388regs[REG_INDEX(R_PSR)] = gregs.tstate;389regs[REG_INDEX(R_PC)] = gregs.tpc;390regs[REG_INDEX(R_nPC)] = gregs.tnpc;391regs[REG_INDEX(R_Y)] = gregs.y;392#else393regs[REG_INDEX(R_PSR)] = gregs.psr;394regs[REG_INDEX(R_PC)] = gregs.pc;395regs[REG_INDEX(R_nPC)] = gregs.npc;396regs[REG_INDEX(R_Y)] = gregs.y;397#endif398regs[REG_INDEX(R_G0)] = 0 ;399regs[REG_INDEX(R_G1)] = gregs.u_regs[0];400regs[REG_INDEX(R_G2)] = gregs.u_regs[1];401regs[REG_INDEX(R_G3)] = gregs.u_regs[2];402regs[REG_INDEX(R_G4)] = gregs.u_regs[3];403regs[REG_INDEX(R_G5)] = gregs.u_regs[4];404regs[REG_INDEX(R_G6)] = gregs.u_regs[5];405regs[REG_INDEX(R_G7)] = gregs.u_regs[6];406regs[REG_INDEX(R_O0)] = gregs.u_regs[7];407regs[REG_INDEX(R_O1)] = gregs.u_regs[8];408regs[REG_INDEX(R_O2)] = gregs.u_regs[ 9];409regs[REG_INDEX(R_O3)] = gregs.u_regs[10];410regs[REG_INDEX(R_O4)] = gregs.u_regs[11];411regs[REG_INDEX(R_O5)] = gregs.u_regs[12];412regs[REG_INDEX(R_O6)] = gregs.u_regs[13];413regs[REG_INDEX(R_O7)] = gregs.u_regs[14];414#endif /* sparc */415416#if defined(aarch64)417#define REG_INDEX(reg) sun_jvm_hotspot_debugger_aarch64_AARCH64ThreadContext_##reg418{419int i;420for (i = 0; i < 31; i++)421regs[i] = gregs.x[i];422regs[REG_INDEX(SP)] = gregs.sp;423regs[REG_INDEX(PC)] = gregs.elr;424}425#endif /* aarch64 */426427(*env)->ReleaseLongArrayElements(env, array, regs, JNI_COMMIT);428return array;429}430431432