--- /dev/null 2019-11-25 13:54:31.704988400 +0900 +++ new/src/jdk.hotspot.agent/linux/native/libsaproc/DwarfParser.cpp 2019-11-25 14:00:59.749470700 +0900 @@ -0,0 +1,227 @@ +/* + * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 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 + +#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)); + if (!parser->can_parsable()) { + jclass ex_cls = env->FindClass("sun/jvm/hotspot/debugger/DebuggerException"); + env->ThrowNew(ex_cls, "DWARF not found"); + return 0L; + } + + return reinterpret_cast(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(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(get_dwarf_context(env, this_obj)); + return static_cast(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(get_dwarf_context(env, this_obj)); + parser->process_dwarf(pc); +} + +/* + * 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(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(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(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(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(get_dwarf_context(env, this_obj)); + return parser->is_bp_offset_available(); +} +