Path: blob/jdk8u272-b10-aarch32-20201026/hotspot/agent/src/os/bsd/BsdDebuggerLocal.c
48792 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#if defined(sparc) || defined(sparcv9)41#include "sun_jvm_hotspot_debugger_sparc_SPARCThreadContext.h"42#endif4344static jfieldID p_ps_prochandle_ID = 0;45static jfieldID threadList_ID = 0;46static jfieldID loadObjectList_ID = 0;4748static jmethodID createClosestSymbol_ID = 0;49static jmethodID createLoadObject_ID = 0;50static jmethodID getThreadForThreadId_ID = 0;51static jmethodID listAdd_ID = 0;5253#define CHECK_EXCEPTION_(value) if ((*env)->ExceptionOccurred(env)) { return value; }54#define CHECK_EXCEPTION if ((*env)->ExceptionOccurred(env)) { return;}55#define THROW_NEW_DEBUGGER_EXCEPTION_(str, value) { throw_new_debugger_exception(env, str); return value; }56#define THROW_NEW_DEBUGGER_EXCEPTION(str) { throw_new_debugger_exception(env, str); return;}5758static void throw_new_debugger_exception(JNIEnv* env, const char* errMsg) {59(*env)->ThrowNew(env, (*env)->FindClass(env, "sun/jvm/hotspot/debugger/DebuggerException"), errMsg);60}6162static struct ps_prochandle* get_proc_handle(JNIEnv* env, jobject this_obj) {63jlong ptr = (*env)->GetLongField(env, this_obj, p_ps_prochandle_ID);64return (struct ps_prochandle*)(intptr_t)ptr;65}6667/*68* Class: sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal69* Method: init070* Signature: ()V71*/72JNIEXPORT void JNICALL Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_init073(JNIEnv *env, jclass cls) {74jclass listClass;7576if (init_libproc(getenv("LIBSAPROC_DEBUG") != NULL) != true) {77THROW_NEW_DEBUGGER_EXCEPTION("can't initialize libproc");78}7980// fields we use81p_ps_prochandle_ID = (*env)->GetFieldID(env, cls, "p_ps_prochandle", "J");82CHECK_EXCEPTION;83threadList_ID = (*env)->GetFieldID(env, cls, "threadList", "Ljava/util/List;");84CHECK_EXCEPTION;85loadObjectList_ID = (*env)->GetFieldID(env, cls, "loadObjectList", "Ljava/util/List;");86CHECK_EXCEPTION;8788// methods we use89createClosestSymbol_ID = (*env)->GetMethodID(env, cls, "createClosestSymbol",90"(Ljava/lang/String;J)Lsun/jvm/hotspot/debugger/cdbg/ClosestSymbol;");91CHECK_EXCEPTION;92createLoadObject_ID = (*env)->GetMethodID(env, cls, "createLoadObject",93"(Ljava/lang/String;JJ)Lsun/jvm/hotspot/debugger/cdbg/LoadObject;");94CHECK_EXCEPTION;95getThreadForThreadId_ID = (*env)->GetMethodID(env, cls, "getThreadForThreadId",96"(J)Lsun/jvm/hotspot/debugger/ThreadProxy;");97CHECK_EXCEPTION;98// java.util.List method we call99listClass = (*env)->FindClass(env, "java/util/List");100CHECK_EXCEPTION;101listAdd_ID = (*env)->GetMethodID(env, listClass, "add", "(Ljava/lang/Object;)Z");102CHECK_EXCEPTION;103}104105JNIEXPORT jint JNICALL Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_getAddressSize106(JNIEnv *env, jclass cls)107{108#ifdef _LP64109return 8;110#else111return 4;112#endif113114}115116117static void fillThreadsAndLoadObjects(JNIEnv* env, jobject this_obj, struct ps_prochandle* ph) {118int n = 0, i = 0;119120// add threads121n = get_num_threads(ph);122for (i = 0; i < n; i++) {123jobject thread;124jobject threadList;125lwpid_t lwpid;126127lwpid = get_lwp_id(ph, i);128thread = (*env)->CallObjectMethod(env, this_obj, getThreadForThreadId_ID,129(jlong)lwpid);130CHECK_EXCEPTION;131threadList = (*env)->GetObjectField(env, this_obj, threadList_ID);132CHECK_EXCEPTION;133(*env)->CallBooleanMethod(env, threadList, listAdd_ID, thread);134CHECK_EXCEPTION;135}136137// add load objects138n = get_num_libs(ph);139for (i = 0; i < n; i++) {140uintptr_t base;141const char* name;142jobject loadObject;143jobject loadObjectList;144145base = get_lib_base(ph, i);146name = get_lib_name(ph, i);147loadObject = (*env)->CallObjectMethod(env, this_obj, createLoadObject_ID,148(*env)->NewStringUTF(env, name), (jlong)0, (jlong)base);149CHECK_EXCEPTION;150loadObjectList = (*env)->GetObjectField(env, this_obj, loadObjectList_ID);151CHECK_EXCEPTION;152(*env)->CallBooleanMethod(env, loadObjectList, listAdd_ID, loadObject);153CHECK_EXCEPTION;154}155}156157/*158* Class: sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal159* Method: attach0160* Signature: (I)V161*/162JNIEXPORT void JNICALL Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_attach0__I163(JNIEnv *env, jobject this_obj, jint jpid) {164165struct ps_prochandle* ph;166if ( (ph = Pgrab(jpid)) == NULL) {167THROW_NEW_DEBUGGER_EXCEPTION("Can't attach to the process");168}169(*env)->SetLongField(env, this_obj, p_ps_prochandle_ID, (jlong)(intptr_t)ph);170fillThreadsAndLoadObjects(env, this_obj, ph);171}172173/*174* Class: sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal175* Method: attach0176* Signature: (Ljava/lang/String;Ljava/lang/String;)V177*/178JNIEXPORT void JNICALL Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_attach0__Ljava_lang_String_2Ljava_lang_String_2179(JNIEnv *env, jobject this_obj, jstring execName, jstring coreName) {180const char *execName_cstr;181const char *coreName_cstr;182jboolean isCopy;183struct ps_prochandle* ph;184185execName_cstr = (*env)->GetStringUTFChars(env, execName, &isCopy);186CHECK_EXCEPTION;187coreName_cstr = (*env)->GetStringUTFChars(env, coreName, &isCopy);188CHECK_EXCEPTION;189190if ( (ph = Pgrab_core(execName_cstr, coreName_cstr)) == NULL) {191(*env)->ReleaseStringUTFChars(env, execName, execName_cstr);192(*env)->ReleaseStringUTFChars(env, coreName, coreName_cstr);193THROW_NEW_DEBUGGER_EXCEPTION("Can't attach to the core file");194}195(*env)->SetLongField(env, this_obj, p_ps_prochandle_ID, (jlong)(intptr_t)ph);196(*env)->ReleaseStringUTFChars(env, execName, execName_cstr);197(*env)->ReleaseStringUTFChars(env, coreName, coreName_cstr);198fillThreadsAndLoadObjects(env, this_obj, ph);199}200201/*202* Class: sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal203* Method: detach0204* Signature: ()V205*/206JNIEXPORT void JNICALL Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_detach0207(JNIEnv *env, jobject this_obj) {208struct ps_prochandle* ph = get_proc_handle(env, this_obj);209if (ph != NULL) {210Prelease(ph);211}212}213214/*215* Class: sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal216* Method: lookupByName0217* Signature: (Ljava/lang/String;Ljava/lang/String;)J218*/219JNIEXPORT jlong JNICALL Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_lookupByName0220(JNIEnv *env, jobject this_obj, jstring objectName, jstring symbolName) {221const char *objectName_cstr, *symbolName_cstr;222jlong addr;223jboolean isCopy;224struct ps_prochandle* ph = get_proc_handle(env, this_obj);225226objectName_cstr = NULL;227if (objectName != NULL) {228objectName_cstr = (*env)->GetStringUTFChars(env, objectName, &isCopy);229CHECK_EXCEPTION_(0);230}231symbolName_cstr = (*env)->GetStringUTFChars(env, symbolName, &isCopy);232CHECK_EXCEPTION_(0);233234addr = (jlong) lookup_symbol(ph, objectName_cstr, symbolName_cstr);235236if (objectName_cstr != NULL) {237(*env)->ReleaseStringUTFChars(env, objectName, objectName_cstr);238}239(*env)->ReleaseStringUTFChars(env, symbolName, symbolName_cstr);240return addr;241}242243/*244* Class: sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal245* Method: lookupByAddress0246* Signature: (J)Lsun/jvm/hotspot/debugger/cdbg/ClosestSymbol;247*/248JNIEXPORT jobject JNICALL Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_lookupByAddress0249(JNIEnv *env, jobject this_obj, jlong addr) {250uintptr_t offset;251const char* sym = NULL;252253struct ps_prochandle* ph = get_proc_handle(env, this_obj);254sym = symbol_for_pc(ph, (uintptr_t) addr, &offset);255if (sym == NULL) return 0;256return (*env)->CallObjectMethod(env, this_obj, createClosestSymbol_ID,257(*env)->NewStringUTF(env, sym), (jlong)offset);258}259260/*261* Class: sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal262* Method: readBytesFromProcess0263* Signature: (JJ)Lsun/jvm/hotspot/debugger/ReadResult;264*/265JNIEXPORT jbyteArray JNICALL Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_readBytesFromProcess0266(JNIEnv *env, jobject this_obj, jlong addr, jlong numBytes) {267268jboolean isCopy;269jbyteArray array;270jbyte *bufPtr;271ps_err_e err;272273array = (*env)->NewByteArray(env, numBytes);274CHECK_EXCEPTION_(0);275bufPtr = (*env)->GetByteArrayElements(env, array, &isCopy);276CHECK_EXCEPTION_(0);277278err = ps_pread(get_proc_handle(env, this_obj), (psaddr_t) (uintptr_t)addr, bufPtr, numBytes);279(*env)->ReleaseByteArrayElements(env, array, bufPtr, 0);280return (err == PS_OK)? array : 0;281}282283JNIEXPORT jlongArray JNICALL Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_getThreadIntegerRegisterSet0284(JNIEnv *env, jobject this_obj, jint lwp_id) {285286struct reg gregs;287jboolean isCopy;288jlongArray array;289jlong *regs;290291struct ps_prochandle* ph = get_proc_handle(env, this_obj);292if (get_lwp_regs(ph, lwp_id, &gregs) != true) {293THROW_NEW_DEBUGGER_EXCEPTION_("get_thread_regs failed for a lwp", 0);294}295296#undef NPRGREG297#ifdef i386298#define NPRGREG sun_jvm_hotspot_debugger_x86_X86ThreadContext_NPRGREG299#endif300#ifdef ia64301#define NPRGREG IA64_REG_COUNT302#endif303#ifdef amd64304#define NPRGREG sun_jvm_hotspot_debugger_amd64_AMD64ThreadContext_NPRGREG305#endif306#if defined(sparc) || defined(sparcv9)307#define NPRGREG sun_jvm_hotspot_debugger_sparc_SPARCThreadContext_NPRGREG308#endif309310array = (*env)->NewLongArray(env, NPRGREG);311CHECK_EXCEPTION_(0);312regs = (*env)->GetLongArrayElements(env, array, &isCopy);313314#undef REG_INDEX315316#ifdef i386317#define REG_INDEX(reg) sun_jvm_hotspot_debugger_x86_X86ThreadContext_##reg318319regs[REG_INDEX(GS)] = (uintptr_t) gregs.r_gs;320regs[REG_INDEX(FS)] = (uintptr_t) gregs.r_fs;321regs[REG_INDEX(ES)] = (uintptr_t) gregs.r_es;322regs[REG_INDEX(DS)] = (uintptr_t) gregs.r_ds;323regs[REG_INDEX(EDI)] = (uintptr_t) gregs.r_edi;324regs[REG_INDEX(ESI)] = (uintptr_t) gregs.r_esi;325regs[REG_INDEX(FP)] = (uintptr_t) gregs.r_ebp;326regs[REG_INDEX(SP)] = (uintptr_t) gregs.r_isp;327regs[REG_INDEX(EBX)] = (uintptr_t) gregs.r_ebx;328regs[REG_INDEX(EDX)] = (uintptr_t) gregs.r_edx;329regs[REG_INDEX(ECX)] = (uintptr_t) gregs.r_ecx;330regs[REG_INDEX(EAX)] = (uintptr_t) gregs.r_eax;331regs[REG_INDEX(PC)] = (uintptr_t) gregs.r_eip;332regs[REG_INDEX(CS)] = (uintptr_t) gregs.r_cs;333regs[REG_INDEX(SS)] = (uintptr_t) gregs.r_ss;334335#endif /* i386 */336337#if ia64338regs = (*env)->GetLongArrayElements(env, array, &isCopy);339int i;340for (i = 0; i < NPRGREG; i++ ) {341regs[i] = 0xDEADDEAD;342}343#endif /* ia64 */344345#ifdef amd64346#define REG_INDEX(reg) sun_jvm_hotspot_debugger_amd64_AMD64ThreadContext_##reg347348regs[REG_INDEX(R15)] = gregs.r_r15;349regs[REG_INDEX(R14)] = gregs.r_r14;350regs[REG_INDEX(R13)] = gregs.r_r13;351regs[REG_INDEX(R12)] = gregs.r_r12;352regs[REG_INDEX(RBP)] = gregs.r_rbp;353regs[REG_INDEX(RBX)] = gregs.r_rbx;354regs[REG_INDEX(R11)] = gregs.r_r11;355regs[REG_INDEX(R10)] = gregs.r_r10;356regs[REG_INDEX(R9)] = gregs.r_r9;357regs[REG_INDEX(R8)] = gregs.r_r8;358regs[REG_INDEX(RAX)] = gregs.r_rax;359regs[REG_INDEX(RCX)] = gregs.r_rcx;360regs[REG_INDEX(RDX)] = gregs.r_rdx;361regs[REG_INDEX(RSI)] = gregs.r_rsi;362regs[REG_INDEX(RDI)] = gregs.r_rdi;363regs[REG_INDEX(RIP)] = gregs.r_rip;364regs[REG_INDEX(CS)] = gregs.r_cs;365regs[REG_INDEX(RSP)] = gregs.r_rsp;366regs[REG_INDEX(SS)] = gregs.r_ss;367// regs[REG_INDEX(FSBASE)] = gregs.fs_base;368// regs[REG_INDEX(GSBASE)] = gregs.gs_base;369// regs[REG_INDEX(DS)] = gregs.ds;370// regs[REG_INDEX(ES)] = gregs.es;371// regs[REG_INDEX(FS)] = gregs.fs;372// regs[REG_INDEX(GS)] = gregs.gs;373374#endif /* amd64 */375376#if defined(sparc) || defined(sparcv9)377378#define REG_INDEX(reg) sun_jvm_hotspot_debugger_sparc_SPARCThreadContext_##reg379380#ifdef _LP64381regs[REG_INDEX(R_PSR)] = gregs.tstate;382regs[REG_INDEX(R_PC)] = gregs.tpc;383regs[REG_INDEX(R_nPC)] = gregs.tnpc;384regs[REG_INDEX(R_Y)] = gregs.y;385#else386regs[REG_INDEX(R_PSR)] = gregs.psr;387regs[REG_INDEX(R_PC)] = gregs.pc;388regs[REG_INDEX(R_nPC)] = gregs.npc;389regs[REG_INDEX(R_Y)] = gregs.y;390#endif391regs[REG_INDEX(R_G0)] = 0 ;392regs[REG_INDEX(R_G1)] = gregs.u_regs[0];393regs[REG_INDEX(R_G2)] = gregs.u_regs[1];394regs[REG_INDEX(R_G3)] = gregs.u_regs[2];395regs[REG_INDEX(R_G4)] = gregs.u_regs[3];396regs[REG_INDEX(R_G5)] = gregs.u_regs[4];397regs[REG_INDEX(R_G6)] = gregs.u_regs[5];398regs[REG_INDEX(R_G7)] = gregs.u_regs[6];399regs[REG_INDEX(R_O0)] = gregs.u_regs[7];400regs[REG_INDEX(R_O1)] = gregs.u_regs[8];401regs[REG_INDEX(R_O2)] = gregs.u_regs[ 9];402regs[REG_INDEX(R_O3)] = gregs.u_regs[10];403regs[REG_INDEX(R_O4)] = gregs.u_regs[11];404regs[REG_INDEX(R_O5)] = gregs.u_regs[12];405regs[REG_INDEX(R_O6)] = gregs.u_regs[13];406regs[REG_INDEX(R_O7)] = gregs.u_regs[14];407#endif /* sparc */408409410(*env)->ReleaseLongArrayElements(env, array, regs, JNI_COMMIT);411return array;412}413414415