blob: 9cf1bac0e2c37f3f122e03c51c2b1952f5793b95 [file] [log] [blame]
/**
* @author Intel, Petr Ivanov
*/
#define LOG_DOMAIN "ncai"
#include "cxxlog.h"
#include "jvmti_internal.h"
#include "suspend_checker.h"
#include "environment.h"
#include "jvmti_break_intf.h"
#include "ncai_direct.h"
#include "ncai_internal.h"
#include "ncai.h"
//////////////////////////////////////////////////////////////////////////////
// Stubs for functions which are not implemented yet
// FIXME: Possibly will be not needed after Capabilities implementation
static ncaiError JNICALL ncaiGetModuleClassLoaderStub(ncaiEnv*,ncaiModule,jobject*)
{ return NCAI_ERROR_NOT_AVAILABLE; }
static ncaiError JNICALL ncaiFindJavaMethodStub(ncaiEnv*,void*,jmethodID*)
{ return NCAI_ERROR_NOT_AVAILABLE; }
static ncaiError JNICALL ncaiGetBytcodeLocationStub(ncaiEnv* env, void* address, jmethodID* method, jlocation* location_ptr)
{ return NCAI_ERROR_NOT_AVAILABLE; }
static ncaiError JNICALL ncaiGetThreadStateStub(ncaiEnv*,ncaiThread,jint*)
{ return NCAI_ERROR_NOT_AVAILABLE; }
static ncaiError JNICALL ncaiGetVersionStub(ncaiEnv*,jint*)
{ return NCAI_ERROR_NOT_AVAILABLE; }
static ncaiError JNICALL ncaiGetErrorNameStub(ncaiEnv*,ncaiError,const char**)
{ return NCAI_ERROR_NOT_AVAILABLE; }
static ncaiError JNICALL ncaiGetPotentialCapabilitiesStub(ncaiEnv*,ncaiCapabilities*)
{ return NCAI_ERROR_NOT_AVAILABLE; }
static ncaiError JNICALL ncaiGetCapabilitiesStub(ncaiEnv*,ncaiCapabilities*)
{ return NCAI_ERROR_NOT_AVAILABLE; }
static ncaiError JNICALL ncaiAddCapabilitiesStub(ncaiEnv*,ncaiCapabilities*)
{ return NCAI_ERROR_NOT_AVAILABLE; }
static ncaiError JNICALL ncaiRelinquishCapabilitiesStub(ncaiEnv*,ncaiCapabilities*)
{ return NCAI_ERROR_NOT_AVAILABLE; }
static ncaiError JNICALL ncaiSetWatchpointStub(ncaiEnv*,void*,size_t,ncaiWatchpointMode)
{ return NCAI_ERROR_NOT_AVAILABLE; }
static ncaiError JNICALL ncaiClearWatchpointStub(ncaiEnv*,void*)
{ return NCAI_ERROR_NOT_AVAILABLE; }
static ncaiError JNICALL ncaiNotifyFramePopStub(ncaiEnv*,ncaiThread,void*)
{ return NCAI_ERROR_NOT_AVAILABLE; }
// Function table
const struct _ncai ncai_table =
{
ncaiGetAllLoadedModules,
ncaiGetModuleInfo,
ncaiGetModuleClassLoaderStub, //ncaiGetModuleClassLoader,
ncaiIsMethodCompiled,
ncaiGetMethodLocation,
ncaiFindJavaMethodStub, //ncaiFindJavaMethod,
ncaiGetBytcodeLocationStub, //ncaiGetBytcodeLocation,
ncaiGetNativeLocation,
ncaiGetAllThreads,
ncaiGetThreadInfo,
ncaiGetThreadHandle,
ncaiGetThreadObject,
ncaiSuspendThread,
ncaiResumeThread,
ncaiTerminateThread,
ncaiGetThreadStateStub, //ncaiGetThreadState,
ncaiGetFrameCount,
ncaiGetStackTrace,
ncaiGetRegisterCount,
ncaiGetRegisterInfo,
ncaiGetRegisterValue,
ncaiSetRegisterValue,
ncaiReadMemory,
ncaiWriteMemory,
ncaiGetSignalCount,
ncaiGetSignalInfo,
ncaiGetJvmtiEnv,
ncaiGetVersionStub, //ncaiGetVersion,
ncaiGetErrorNameStub, //ncaiGetErrorName,
ncaiGetPotentialCapabilitiesStub, //ncaiGetPotentialCapabilities,
ncaiGetCapabilitiesStub, //ncaiGetCapabilities,
ncaiAddCapabilitiesStub, //ncaiAddCapabilities,
ncaiRelinquishCapabilitiesStub, //ncaiRelinquishCapabilities,
ncaiGetEventCallbacks,
ncaiSetEventCallbacks,
ncaiSetEventNotificationMode,
ncaiSetBreakpoint,
ncaiClearBreakpoint,
ncaiSetWatchpointStub, //ncaiSetWatchpoint,
ncaiClearWatchpointStub, //ncaiClearWatchpoint,
ncaiSetStepMode,
ncaiNotifyFramePopStub, //ncaiNotifyFramePop,
};
jvmtiError create_ncai_environment(jvmtiEnv* jvmti_env, NCAIEnv** penv)
{
TRACE2("jvmti.ncai", "create_ncai_environment called");
TIEnv *ti_env = (TIEnv *)jvmti_env;
NCAIEnv *newenv;
jvmtiError error_code;
error_code = _allocate(sizeof(NCAIEnv), (unsigned char**)&newenv);
if (error_code != JVMTI_ERROR_NONE)
{
*penv = NULL;
return error_code;
}
newenv->functions = &ncai_table;
newenv->ti_env = ti_env;
newenv->modules = NULL;
ti_env->ncai_env = newenv;
memset(&newenv->event_table, 0, sizeof(ncaiEventCallbacks));
memset(&newenv->global_events, 0, sizeof(newenv->global_events));
memset(&newenv->event_threads, 0, sizeof(newenv->event_threads));
newenv->env_lock = new Lock_Manager();
assert(newenv->env_lock);
// Acquire interface for breakpoint handling
newenv->brpt_intf =
VM_Global_State::loader_env->TI->vm_brpt->new_intf(ti_env,
ncai_process_breakpoint_event, PRIORITY_NCAI_BREAKPOINT, false);
assert(newenv->brpt_intf);
*penv = newenv;
TRACE2("jvmti.ncai", "New NCAI environment created: " << newenv);
return JVMTI_ERROR_NONE;
}
jvmtiError JNICALL jvmtiGetNCAIEnvironment(jvmtiEnv* jvmti_env, ...)
{
TRACE2("jvmti.ncai", "GetNCAIEnvironment called");
SuspendEnabledChecker sec;
va_list args;
va_start(args, jvmti_env);
// GetExtensionEnv function has following prototype:
// GetExtensionEnv(jvmtiEnv* jvmti_env, void** ncai_env_ptr, jint version);
NCAIEnv** penv = (NCAIEnv**)va_arg(args, void**);
jint version = (jint)va_arg(args, jint);
va_end(args);
if (penv == NULL)
return JVMTI_ERROR_NULL_POINTER;
jint vmajor = (version & NCAI_VERSION_MASK_MAJOR) >> NCAI_VERSION_SHIFT_MAJOR;
jint vminor = (version & NCAI_VERSION_MASK_MINOR) >> NCAI_VERSION_SHIFT_MINOR;
jint vmicro = (version & NCAI_VERSION_MASK_MICRO) >> NCAI_VERSION_SHIFT_MICRO;
if (vmajor > NCAI_VERSION_MAJOR ||
vminor > NCAI_VERSION_MINOR ||
vmicro > NCAI_VERSION_MICRO)
{
*penv = NULL;
return JVMTI_ERROR_NOT_AVAILABLE;
}
GlobalNCAI* ncai = VM_Global_State::loader_env->NCAI;
TIEnv* ti_env = (TIEnv*)jvmti_env;
if (ti_env->ncai_env != NULL)
{
*penv = ti_env->ncai_env;
ncai->enabled = true;
return JVMTI_ERROR_NONE;
}
jvmtiError err = create_ncai_environment(jvmti_env, penv);
if (err == JVMTI_ERROR_NONE)
ncai->enabled = true;
return err;
}
ncaiError JNICALL ncaiGetJvmtiEnv(ncaiEnv *env, jvmtiEnv** jvmti_env_ptr)
{
if (env == NULL)
return NCAI_ERROR_INVALID_ENVIRONMENT;
if (jvmti_env_ptr == NULL)
return NCAI_ERROR_NULL_POINTER;
*jvmti_env_ptr = (jvmtiEnv*)((NCAIEnv*)env)->ti_env;
return NCAI_ERROR_NONE;
}
GlobalNCAI::GlobalNCAI():
enabled(false),
modules(NULL),
step_enabled(false),
step_mode(NCAI_STEP_INTO)
{
}
GlobalNCAI::~GlobalNCAI()
{
// Clean modules list
clean_all_modules(&modules);
}
bool GlobalNCAI::isEnabled()
{
return VM_Global_State::loader_env->NCAI &&
VM_Global_State::loader_env->NCAI->enabled;
}