mirror of
https://github.com/openjdk/jdk.git
synced 2026-02-11 02:48:20 +00:00
232 lines
7.2 KiB
C++
232 lines
7.2 KiB
C++
/*
|
|
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
|
|
* Copyright (c) 2020, NTT DATA.
|
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
*
|
|
* This code is free software; you can redistribute it and/or modify it
|
|
* under the terms of the GNU General Public License version 2 only, as
|
|
* published by the Free Software Foundation.
|
|
*
|
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
* version 2 for more details (a copy is included in the LICENSE file that
|
|
* accompanied this code).
|
|
*
|
|
* You should have received a copy of the GNU General Public License version
|
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
*
|
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
|
* or visit www.oracle.com if you need additional information or have any
|
|
* questions.
|
|
*
|
|
*/
|
|
|
|
#include <jni.h>
|
|
|
|
#include "dwarf.hpp"
|
|
#include "libproc.h"
|
|
|
|
#define CHECK_EXCEPTION if (env->ExceptionOccurred()) { return; }
|
|
|
|
static jfieldID p_dwarf_context_ID = 0;
|
|
static jint sa_RAX = -1;
|
|
static jint sa_RDX = -1;
|
|
static jint sa_RCX = -1;
|
|
static jint sa_RBX = -1;
|
|
static jint sa_RSI = -1;
|
|
static jint sa_RDI = -1;
|
|
static jint sa_RBP = -1;
|
|
static jint sa_RSP = -1;
|
|
static jint sa_R8 = -1;
|
|
static jint sa_R9 = -1;
|
|
static jint sa_R10 = -1;
|
|
static jint sa_R11 = -1;
|
|
static jint sa_R12 = -1;
|
|
static jint sa_R13 = -1;
|
|
static jint sa_R14 = -1;
|
|
static jint sa_R15 = -1;
|
|
|
|
static jlong get_dwarf_context(JNIEnv *env, jobject obj) {
|
|
return env->GetLongField(obj, p_dwarf_context_ID);
|
|
}
|
|
|
|
#define SET_REG(env, reg, reg_cls) \
|
|
jfieldID reg##_ID = env->GetStaticFieldID(reg_cls, #reg, "I"); \
|
|
CHECK_EXCEPTION \
|
|
sa_##reg = env->GetStaticIntField(reg_cls, reg##_ID); \
|
|
CHECK_EXCEPTION
|
|
|
|
/*
|
|
* Class: sun_jvm_hotspot_debugger_linux_amd64_DwarfParser
|
|
* Method: init0
|
|
* Signature: ()V
|
|
*/
|
|
extern "C"
|
|
JNIEXPORT void JNICALL Java_sun_jvm_hotspot_debugger_linux_amd64_DwarfParser_init0
|
|
(JNIEnv *env, jclass this_cls) {
|
|
jclass cls = env->FindClass("sun/jvm/hotspot/debugger/linux/amd64/DwarfParser");
|
|
CHECK_EXCEPTION
|
|
p_dwarf_context_ID = env->GetFieldID(cls, "p_dwarf_context", "J");
|
|
CHECK_EXCEPTION
|
|
|
|
jclass reg_cls = env->FindClass("sun/jvm/hotspot/debugger/amd64/AMD64ThreadContext");
|
|
CHECK_EXCEPTION
|
|
SET_REG(env, RAX, reg_cls);
|
|
SET_REG(env, RDX, reg_cls);
|
|
SET_REG(env, RCX, reg_cls);
|
|
SET_REG(env, RBX, reg_cls);
|
|
SET_REG(env, RSI, reg_cls);
|
|
SET_REG(env, RDI, reg_cls);
|
|
SET_REG(env, RBP, reg_cls);
|
|
SET_REG(env, RSP, reg_cls);
|
|
SET_REG(env, R8, reg_cls);
|
|
SET_REG(env, R9, reg_cls);
|
|
SET_REG(env, R10, reg_cls);
|
|
SET_REG(env, R11, reg_cls);
|
|
SET_REG(env, R12, reg_cls);
|
|
SET_REG(env, R13, reg_cls);
|
|
SET_REG(env, R14, reg_cls);
|
|
SET_REG(env, R15, reg_cls);
|
|
}
|
|
|
|
/*
|
|
* Class: sun_jvm_hotspot_debugger_linux_amd64_DwarfParser
|
|
* Method: createDwarfContext
|
|
* Signature: (J)J
|
|
*/
|
|
extern "C"
|
|
JNIEXPORT jlong JNICALL Java_sun_jvm_hotspot_debugger_linux_amd64_DwarfParser_createDwarfContext
|
|
(JNIEnv *env, jclass this_cls, jlong lib) {
|
|
jlong result = 0L;
|
|
|
|
DwarfParser *parser = new DwarfParser(reinterpret_cast<lib_info *>(lib));
|
|
if (!parser->is_parseable()) {
|
|
jclass ex_cls = env->FindClass("sun/jvm/hotspot/debugger/DebuggerException");
|
|
env->ThrowNew(ex_cls, "DWARF not found");
|
|
return 0L;
|
|
}
|
|
|
|
return reinterpret_cast<jlong>(parser);
|
|
}
|
|
|
|
/*
|
|
* Class: sun_jvm_hotspot_debugger_linux_amd64_DwarfParser
|
|
* Method: destroyDwarfContext
|
|
* Signature: (J)V
|
|
*/
|
|
extern "C"
|
|
JNIEXPORT void JNICALL Java_sun_jvm_hotspot_debugger_linux_amd64_DwarfParser_destroyDwarfContext
|
|
(JNIEnv *env, jclass this_cls, jlong context) {
|
|
DwarfParser *parser = reinterpret_cast<DwarfParser *>(context);
|
|
delete parser;
|
|
}
|
|
|
|
/*
|
|
* Class: sun_jvm_hotspot_debugger_linux_amd64_DwarfParser
|
|
* Method: isIn0
|
|
* Signature: (J)Z
|
|
*/
|
|
extern "C"
|
|
JNIEXPORT jboolean JNICALL Java_sun_jvm_hotspot_debugger_linux_amd64_DwarfParser_isIn0
|
|
(JNIEnv *env, jobject this_obj, jlong pc) {
|
|
DwarfParser *parser = reinterpret_cast<DwarfParser *>(get_dwarf_context(env, this_obj));
|
|
return static_cast<jboolean>(parser->is_in(pc));
|
|
}
|
|
|
|
/*
|
|
* Class: sun_jvm_hotspot_debugger_linux_amd64_DwarfParser
|
|
* Method: processDwarf0
|
|
* Signature: (J)V
|
|
*/
|
|
extern "C"
|
|
JNIEXPORT void JNICALL Java_sun_jvm_hotspot_debugger_linux_amd64_DwarfParser_processDwarf0
|
|
(JNIEnv *env, jobject this_obj, jlong pc) {
|
|
DwarfParser *parser = reinterpret_cast<DwarfParser *>(get_dwarf_context(env, this_obj));
|
|
if (!parser->process_dwarf(pc)) {
|
|
jclass ex_cls = env->FindClass("sun/jvm/hotspot/debugger/DebuggerException");
|
|
env->ThrowNew(ex_cls, "Could not find PC in DWARF");
|
|
return;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Class: sun_jvm_hotspot_debugger_linux_amd64_DwarfParser
|
|
* Method: getCFARegister
|
|
* Signature: ()I
|
|
*/
|
|
extern "C"
|
|
JNIEXPORT jint JNICALL Java_sun_jvm_hotspot_debugger_linux_amd64_DwarfParser_getCFARegister
|
|
(JNIEnv *env, jobject this_obj) {
|
|
DwarfParser *parser = reinterpret_cast<DwarfParser *>(get_dwarf_context(env, this_obj));
|
|
switch (parser->get_cfa_register()) {
|
|
case RAX: return sa_RAX;
|
|
case RDX: return sa_RDX;
|
|
case RCX: return sa_RCX;
|
|
case RBX: return sa_RBX;
|
|
case RSI: return sa_RSI;
|
|
case RDI: return sa_RDI;
|
|
case RBP: return sa_RBP;
|
|
case RSP: return sa_RSP;
|
|
case R8: return sa_R8;
|
|
case R9: return sa_R9;
|
|
case R10: return sa_R10;
|
|
case R11: return sa_R11;
|
|
case R12: return sa_R12;
|
|
case R13: return sa_R13;
|
|
case R14: return sa_R14;
|
|
case R15: return sa_R15;
|
|
default: return -1;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Class: sun_jvm_hotspot_debugger_linux_amd64_DwarfParser
|
|
* Method: getCFAOffset
|
|
* Signature: ()I
|
|
*/
|
|
extern "C"
|
|
JNIEXPORT jint JNICALL Java_sun_jvm_hotspot_debugger_linux_amd64_DwarfParser_getCFAOffset
|
|
(JNIEnv *env, jobject this_obj) {
|
|
DwarfParser *parser = reinterpret_cast<DwarfParser *>(get_dwarf_context(env, this_obj));
|
|
return parser->get_cfa_offset();
|
|
}
|
|
|
|
/*
|
|
* Class: sun_jvm_hotspot_debugger_linux_amd64_DwarfParser
|
|
* Method: getReturnAddressOffsetFromCFA
|
|
* Signature: ()I
|
|
*/
|
|
extern "C"
|
|
JNIEXPORT jint JNICALL Java_sun_jvm_hotspot_debugger_linux_amd64_DwarfParser_getReturnAddressOffsetFromCFA
|
|
(JNIEnv *env, jobject this_obj) {
|
|
DwarfParser *parser = reinterpret_cast<DwarfParser *>(get_dwarf_context(env, this_obj));
|
|
return parser->get_ra_cfa_offset();
|
|
}
|
|
|
|
/*
|
|
* Class: sun_jvm_hotspot_debugger_linux_amd64_DwarfParser
|
|
* Method: getBasePointerOffsetFromCFA
|
|
* Signature: ()I
|
|
*/
|
|
extern "C"
|
|
JNIEXPORT jint JNICALL Java_sun_jvm_hotspot_debugger_linux_amd64_DwarfParser_getBasePointerOffsetFromCFA
|
|
(JNIEnv *env, jobject this_obj) {
|
|
DwarfParser *parser = reinterpret_cast<DwarfParser *>(get_dwarf_context(env, this_obj));
|
|
return parser->get_bp_cfa_offset();
|
|
}
|
|
|
|
/*
|
|
* Class: sun_jvm_hotspot_debugger_linux_amd64_DwarfParser
|
|
* Method: isBPOffsetAvailable
|
|
* Signature: ()Z
|
|
*/
|
|
extern "C"
|
|
JNIEXPORT jboolean JNICALL Java_sun_jvm_hotspot_debugger_linux_amd64_DwarfParser_isBPOffsetAvailable
|
|
(JNIEnv *env, jobject this_obj) {
|
|
DwarfParser *parser = reinterpret_cast<DwarfParser *>(get_dwarf_context(env, this_obj));
|
|
return parser->is_bp_offset_available();
|
|
}
|
|
|