Commit 2bf301bc authored by Vít Kabele's avatar Vít Kabele

Merging DiSL functionality into SHVM agent.

parent c36d677d
......@@ -22,7 +22,6 @@ add_executable(src_disl_agent
codeflags.h
common.c
common.h
config.c
config.h
connection.c
connection.h
......
# DiSL instrumentation agent
## Usage
### Options
* `disl.instrumentation` - As an argument takes list of paths to instrumentation
jars, separated by `:`
* `disl.bypass` - Sets the bypass. Options are `dynamic`, `never` and `bootstrap`
more of them -> here
* `disl.splitmethods` - default is true
* `disl.excepthandler` - default is false
* `disl.forceinterface` - default false
* `disl.forcesuperclass` - default false
* `debug`
\ No newline at end of file
/**
* This file is part of src_disl_agent
*
* Created by Vít Kabele on 25/11/2018.
*/
#include "config.h"
......@@ -64,6 +64,8 @@ SOURCES = common.c jvmtiutil.c config.c \
shared/threadlocal.c shared/messagetype.c \
tagger.c sender.c dislreagent.c pbmanager.c redispatcher.c netref.c \
globalbuffer.c tlocalbuffer.c freehandler.c \
disl/connection.c disl/connpool.c disl/msgchannel.c disl/network.c \
disl/disl.c disl/bytecode.c disl/classparser.c sessions.c \
protocol/protobuf-c.c protocol/shvm.pb-c.c protocol/main.pb-c.c protocol/disl.pb-c.c
HEADERS = $(wildcard *.h)
......
......@@ -3,6 +3,50 @@
The purpose of this agent is to handle the invocation of REDispatch methods in
java code and send the analysis requests to the server.
## Usage
The agent accepts several options, that can alter his behaviour:
### DiSL module options
Those options are used to setup the behaviour of remote instrumentation client.
Note that all of this settings takes an effect, only when `disl.allow` option
is turned on.
* `disl.allow=(true|false)` - allow the agent to act as the remote instrumentation agent,
when this option is passed, the option `disl.instrumentation` is also
required. Default value is false.
* `disl.instrumentation=jar1:jar2` - specify the `:` separated list of jar files containing
instrumentation, that will be sent to the instrumentation server.
* `disl.debug` - When turned on, the behaviour of the DiSL part of the agent
will be printed to the standard output. Default value is false.
* `disl.bypass=(disabled|bootstrap|dynamic)`
* `disl.server.host=localhost`
* `disl.server.port=11217`
* `disl.splitmethods`
* `disl.excepthandler`
* `disl.forcesuperclass`
* `disl.forceinterfaces`
### SHVM module options
Those options are used to setup the behaviour of remote analysis agent.
* `svm-agent.shadow.host`
* `svm-agent.shadow.port`
* `svm-agent.debug`
## How is this done?
Firstly, the agent initializes itself. That means parsing the options,
......
......@@ -5,6 +5,7 @@
#include <stdarg.h>
#include <string.h>
#include <strings.h>
#include <assert.h>
//
......@@ -60,6 +61,33 @@ die_with_std_error (int errnum, const char * restrict format, va_list args) {
exit (ERROR_STD);
}
// ****************************************************************************
// STRING UTILS SECTION
// ****************************************************************************
size_t
substr_count(const char * string, const char * restrict substr) {
size_t count = 0;
for(const char * token = string; (token = strstr(token, substr)) != NULL; ++token)
{
++count;
}
return (count);
}
char **
split_string(char * string, const char * restrict separator, size_t * tkns) {
size_t tokens = substr_count(string, separator) + 1;
assert(tokens > 0);
char ** arr = malloc(tokens * sizeof(char *));
arr[0] = strtok(string, separator);
for(size_t i = 1; i < tokens; ++i)
arr[i] = strtok(NULL, separator);
*tkns = tokens;
return (arr);
}
#ifdef MINGW
......
......@@ -129,7 +129,15 @@ check_std_error (bool error, const char * format, ...) {
}
}
//
// ****************************************************************************
// STRING UTILS SECTION
// ****************************************************************************
size_t
substr_count(const char * string, const char * restrict substr);
char **
split_string(char * string, const char * restrict separator, size_t * tkns);
#ifdef MINGW
......
......@@ -3,36 +3,31 @@
#include "jvmtiutil.h"
#include <string.h>
#include <assert.h>
#include <jvmti.h>
//
#define PROP_SHADOW_HOST "svm-agent.shadow.host"
#define CONF_SHADOW_HOST_DEFAULT "localhost"
#define PROP_SHADOW_PORT "svm-agent.shadow.port"
#define CONF_SHADOW_PORT_DEFAULT "11218"
#define PROP_DEBUG "svm-agent.debug"
#define CONF_DEBUG_DEFAULT false
//
struct config {
char * shadow_host;
char * shadow_port;
bool debug;
};
/**
/*
* Agent configuration.
*/
static struct config agent_config;
/**
* Parse the instrumentation jar list in format "jar:jar2:...:jarN" to agent_config struct.
*
* @param list The list of jar files separated by :
* @param config
*/
static void
__parse_instrumentations( char * list, struct config * config ){
size_t jar_count;
char ** jar_paths = split_string(list, LIST_SEPARATOR, &jar_count);
config->jar_count = jar_count;
config->instrumentation_jars = jar_paths;
}
static void
__configure_from_properties (jvmtiEnv * jvmti, struct config * config) {
......@@ -41,12 +36,72 @@ __configure_from_properties (jvmtiEnv * jvmti, struct config * config) {
//
config->debug = jvmti_get_system_property_bool (
jvmti, PROP_DEBUG, CONF_DEBUG_DEFAULT
);
config->disl_functionality = jvmti_get_system_property_bool(
jvmti, DISL_FUNCTIONALITY, DISL_FUNCTIONALITY_DEFAULT
);
config->disl_host = jvmti_get_system_property_string(
jvmti, DISL_SERVER_HOST, DISL_SERVER_HOST_DEFAULT
);
config->disl_port = jvmti_get_system_property_string(
jvmti, DISL_SERVER_PORT, DISL_SERVER_PORT_DEFAULT
);
config->split_methods = jvmti_get_system_property_bool (
jvmti, DISL_SPLIT_METHODS, DISL_SPLIT_METHODS_DEFAULT
);
config->catch_exceptions = jvmti_get_system_property_bool (
jvmti, DISL_CATCH_EXCEPTIONS, DISL_CATCH_EXCEPTIONS_DEFAULT
);
config->force_superclass = jvmti_get_system_property_bool (
jvmti, DISL_FORCE_SUPERCLASS, DISL_FORCE_SUPERCLASS_DEFAULT
);
config->force_interfaces = jvmti_get_system_property_bool (
jvmti, DISL_FORCE_INTERFACES, DISL_FORCE_INTERFACES_DEFAULT
);
config->disl_debug = jvmti_get_system_property_bool (
jvmti, DISL_DEBUG, DISL_DEBUG_DEFAULT
);
//
// Get bypass mode configuration
//
char * bypass = jvmti_get_system_property_string (
jvmti, DISL_BYPASS, DISL_BYPASS_DEFAULT
);
static const char * values [] = { "disabled", "bootstrap", "dynamic" };
int bypass_index = find_value_index (bypass, values, sizeof_array (values));
check_error (bypass_index < 0, "invalid bypass mode, check " DISL_BYPASS);
config->bypass_mode = bypass_index;
free (bypass);
//
// Get instrumentation list
//
if (config->disl_functionality) {
char * instrumentation = jvmti_get_system_property_string(
jvmti, DISL_INSTRUMENTATION, NULL
);
assert(instrumentation != NULL);
__parse_instrumentations(instrumentation, config);
}
}
static void
__configure_from_options (const char * options, struct config * config) {
__configure_from_options(const char * options, struct config * config)
{
//
// Assign default Shadow VM host name and port and bail out
// if there are no agent options.
......@@ -80,8 +135,9 @@ __configure_from_options (const char * options, struct config * config) {
}
void
config_init (jvmtiEnv * jvmti, const char * options) {
const struct config *
config_init (jvmtiEnv * jvmti, const char * options)
{
__configure_from_options (options, &agent_config);
__configure_from_properties (jvmti, &agent_config);
......@@ -93,22 +149,38 @@ config_init (jvmtiEnv * jvmti, const char * options) {
rdaprefix ("port: %s\n", agent_config.shadow_port);
rdaprefix ("debug: %d\n", agent_config.debug);
}
return (&agent_config);
}
bool
config_debug_is_enabled () {
config_debug_is_enabled()
{
return agent_config.debug;
}
const char *
config_shadow_host () {
config_shadow_host()
{
return agent_config.shadow_host;
}
const char *
config_shadow_port () {
config_shadow_port()
{
return agent_config.shadow_port;
}
bool
config_do_disl()
{
return (agent_config.disl_functionality);
}
bool
config_disl_debug()
{
return (agent_config.disl_debug);
}
\ No newline at end of file
/*
* Manage the configuration, allow parsing the configuration from properties
* (those provided via -D option) and from options (those appended to the agent
* option).
*
* Provides a getter functions to configuration options.
*/
#ifndef _CONFIG_H_
#define _CONFIG_H_
#include "common.h"
#include <stdbool.h>
#include <jvmti.h>
#include <sys/types.h>
// ****************************************************************************
// SHVM AGENT CONFIG
// ****************************************************************************
#define PROP_SHADOW_HOST "svm-agent.shadow.host"
#define CONF_SHADOW_HOST_DEFAULT "localhost"
#define PROP_SHADOW_PORT "svm-agent.shadow.port"
#define CONF_SHADOW_PORT_DEFAULT "11218"
#define PROP_DEBUG "svm-agent.debug"
#define CONF_DEBUG_DEFAULT false
// ****************************************************************************
// DiSL AGENT CONFIG
// ****************************************************************************
#define DISL_FUNCTIONALITY "disl.allow"
#define DISL_FUNCTIONALITY_DEFAULT false
#define DISL_SERVER_HOST "disl.server.host"
#define DISL_SERVER_HOST_DEFAULT "localhost"
#define DISL_SERVER_PORT "disl.server.port"
#define DISL_SERVER_PORT_DEFAULT "11217"
// Required argument
// No default value.
#define DISL_INSTRUMENTATION "disl.instrumentation"
#define LIST_SEPARATOR ":"
#define DISL_BYPASS "disl.bypass"
#define DISL_BYPASS_DEFAULT "dynamic"
#define DISL_SPLIT_METHODS "disl.splitmethods"
#define DISL_SPLIT_METHODS_DEFAULT true
#define DISL_CATCH_EXCEPTIONS "disl.excepthandler"
#define DISL_CATCH_EXCEPTIONS_DEFAULT false
#define DISL_FORCE_SUPERCLASS "disl.forcesuperclass"
#define DISL_FORCE_SUPERCLASS_DEFAULT false
#define DISL_FORCE_INTERFACES "disl.forceinterfaces"
#define DISL_FORCE_INTERFACES_DEFAULT false
#define DISL_DEBUG "disl.debug"
#define DISL_DEBUG_DEFAULT false
/**
* The instrumentation bypass mode.
* NOTE: The ordering of the modes is important!
*/
enum bypass_mode {
/**
* The original method code will not be preserved. Consequently, the
* instrumented version of a method will be always executed, even when
* invoked inside a DiSL snippet.
*/
BYPASS_MODE_DISABLED = 0,
/**
* The original method code will be preserved, and will be always
* executed instead of the instrumented version during JVM bootstrap.
* After bootstrap, only the instrumented version of a method will
* be executed.
*/
BYPASS_MODE_BOOTSTRAP = 1,
/**
* The original method code will be preserved, and executed whenever
* invoked from inside a DiSL snippet.
*/
BYPASS_MODE_DYNAMIC = 2
};
/*
* Configuration struct
*/
struct config {
// ShadowVM client options
char * shadow_host; // ShadowVM server hostname
char * shadow_port; // ShadowVM server port
bool debug; // ShadowVM functionality debugging
// DiSL Options
bool disl_functionality; // When false, the agent acts as ShadowVM agent only
char * disl_host; // DiSL server hostname
char * disl_port; // DiSL server port
size_t jar_count; // DiSL instrumentation jars count
char ** instrumentation_jars;// Pointer to loaded instrumentation jars
enum bypass_mode bypass_mode;// DiSL BypassMode
bool split_methods;
bool catch_exceptions;
bool force_superclass;
bool force_interfaces;
int32_t session_id; // DiSL session id
bool disl_debug; // DiSL functionality debugging
};
/*
* Initialize the config structure
* @param jvmti
* @param options
*/
const struct config *
config_init (jvmtiEnv * jvmti, const char * options);
/*
* config_debug_is_enabled()
*
* @return True, when the debug property was set
*/
bool
config_debug_is_enabled ();
/*
* config_shadow_host()
*
* @return The string with hostname of shadowVM server.
*/
const char *
config_shadow_host ();
/*
* config_shadow_port()
*
* @return The string with port of shadowVM server.
*/
const char *
config_shadow_port ();
void config_init (jvmtiEnv * jvmti, const char * options);
bool
config_do_disl();
bool config_debug_is_enabled ();
const char * config_shadow_host ();
const char * config_shadow_port ();
bool
config_disl_debug();
#endif /* _CONFIG_H_ */
......@@ -6,6 +6,9 @@
/**
* debug(...)
*
* This is a compile time enabled function.
* Prints a debug message to stdout (unless NDEBUG is defined).
*
* @args arguments to pass to fprintf()
......@@ -19,6 +22,9 @@
/**
* ldebug(...)
*
* This is a compile time enabled function.
* Prints a debug message including the function name and
* line number to stdout (unless NDEBUG is defined).
*
......@@ -29,19 +35,38 @@
debug (args); \
}
/**
* Runtime debuging output macros.
*/
#define rdexec \
if (config_debug_is_enabled ())
// ****************************************************************************
// COMMON RUNTIME DEBUGGING MACROS
// ****************************************************************************
#define rdoutput(args...) \
fprintf (stdout, args);
#define __safe_name(name) \
(((name) == NULL) ? "<unknown>" : (name))
/**
* rdatiprefix - Runtime Diagnostics Thread Info Prefixed printf
*/
#define common_rdatiprefix(agent_name, info, args...) \
rdoutput (agent_name " [%s, %" PRId64 "]: ", __safe_name ((info)->name), (info)->id); \
rdoutput (args);
// ****************************************************************************
// RUNTIME DEBUGGING MACROS FOR SHVM MODULE
// ****************************************************************************
/**
* rdexec - SHVM module Runtime Debugging Execution
*
* Use as following:
*
* rdexec {
* printf("This will be printed when -Ddebug.shvm option passed");
* }
*/
#define rdexec \
if (config_debug_is_enabled ())
#define rdaprefix(args...) \
rdoutput (AGENT_NAME ": "); \
rdoutput (args);
......@@ -50,6 +75,9 @@
rdoutput (AGENT_NAME " [%s]: ", __safe_name ((info)->name)); \
rdoutput (args);
/**
* rdatiprefix - Runtime Diagnostics Thread Info Prefixed printf
*/
#define rdatiprefix(info, args...) \
rdoutput (AGENT_NAME " [%s, %" PRId64 "]: ", __safe_name ((info)->name), (info)->id); \
rdoutput (args);
......@@ -69,4 +97,48 @@
rdatiprefix (info, args); \
}
// ****************************************************************************
// RUNTIME DEBUGGING MACROS FOR DiSL MODULE
// ****************************************************************************
/**
* disl_rdexec - DiSL module Runtime Debugging Execution
*
* Use as following:
*
* disl_rdexec {
* printf("This will be printed when -Ddebug.disl option passed");
* }
*/
#define disl_rdexec \
if (config_disl_debug())
/**
* disl_rdaprefix - DiSL module Runtime Debugging Prefix printf
*
* Takes the arguments in the format of printf(2). Print the agent name and then
* print the arguments using printf(2)
*/
#define disl_rdaprefix(args...) \
rdoutput ("DISL: "); \
rdoutput (args)
/**
* disl_rdaprintf - DiSL module Runtime Debugging Prefix printf
*
* Prints out the arguments via printf(2) prefixed via agent name, only if the
* -Ddisl.debug flag was specified.
*/
#define disl_rdaprintf(args...) \
disl_rdexec { \
disl_rdaprefix (args); \
}
#define disl_rdatiprefix(info, args...) \
common_rdatiprefix("DiSL", info, args);
#define disl_rdatiprintf(info, args...) \
disl_rdexec { \
disl_rdatiprefix (info, args); \
}
#endif /* _DEBUG_H_ */
/**
* DO NOT EDIT!
*
* This file was generated using the 'generate-disl-agent-bytecode' target.
*/
#include <jvmti.h>
jvmtiClassDefinition always_BypassCheck_classdef = {
.class_byte_count = 388,
.class_bytes = (unsigned char *)
"\xca\xfe\xba\xbe\x00\x00\x00\x30\x00\x12\x0a\x00\x03\x00\x0f\x07"
"\x00\x10\x07\x00\x11\x01\x00\x06\x3c\x69\x6e\x69\x74\x3e\x01\x00"
"\x03\x28\x29\x56\x01\x00\x04\x43\x6f\x64\x65\x01\x00\x0f\x4c\x69"
"\x6e\x65\x4e\x75\x6d\x62\x65\x72\x54\x61\x62\x6c\x65\x01\x00\x12"
"\x4c\x6f\x63\x61\x6c\x56\x61\x72\x69\x61\x62\x6c\x65\x54\x61\x62"
"\x6c\x65\x01\x00\x04\x74\x68\x69\x73\x01\x00\x2b\x4c\x63\x68\x2f"
"\x75\x73\x69\x2f\x64\x61\x67\x2f\x64\x69\x73\x6c\x2f\x64\x79\x6e"
"\x61\x6d\x69\x63\x62\x79\x70\x61\x73\x73\x2f\x42\x79\x70\x61\x73"
"\x73\x43\x68\x65\x63\x6b\x3b\x01\x00\x15\x65\x78\x65\x63\x75\x74"
"\x65\x55\x6e\x69\x6e\x73\x74\x72\x75\x6d\x65\x6e\x74\x65\x64\x01"
"\x00\x03\x28\x29\x5a\x01\x00\x0a\x53\x6f\x75\x72\x63\x65\x46\x69"
"\x6c\x65\x01\x00\x10\x42\x79\x70\x61\x73\x73\x43\x68\x65\x63\x6b"
"\x2e\x6a\x61\x76\x61\x0c\x00\x04\x00\x05\x01\x00\x29\x63\x68\x2f"
"\x75\x73\x69\x2f\x64\x61\x67\x2f\x64\x69\x73\x6c\x2f\x64\x79\x6e"
"\x61\x6d\x69\x63\x62\x79\x70\x61\x73\x73\x2f\x42\x79\x70\x61\x73"
"\x73\x43\x68\x65\x63\x6b\x01\x00\x10\x6a\x61\x76\x61\x2f\x6c\x61"
"\x6e\x67\x2f\x4f\x62\x6a\x65\x63\x74\x00\x31\x00\x02\x00\x03\x00"
"\x00\x00\x00\x00\x02\x00\x01\x00\x04\x00\x05\x00\x01\x00\x06\x00"
"\x00\x00\x2f\x00\x01\x00\x01\x00\x00\x00\x05\x2a\xb7\x00\x01\xb1"
"\x00\x00\x00\x02\x00\x07\x00\x00\x00\x06\x00\x01\x00\x00\x00\x0c"
"\x00\x08\x00\x00\x00\x0c\x00\x01\x00\x00\x00\x05\x00\x09\x00\x0a"
"\x00\x00\x00\x09\x00\x0b\x00\x0c\x00\x01\x00\x06\x00\x00\x00\x1a"
"\x00\x01\x00\x00\x00\x00\x00\x02\x04\xac\x00\x00\x00\x01\x00\x07"
"\x00\x00\x00\x06\x00\x01\x00\x00\x00\x0f\x00\x01\x00\x0d\x00\x00"
"\x00\x02\x00\x0e",
};
jvmtiClassDefinition dynamic_BypassCheck_classdef = {
.class_byte_count = 460,
.class_bytes = (unsigned char *)
"\xca\xfe\xba\xbe\x00\x00\x00\x30\x00\x17\x0a\x00\x04\x00\x10\x0a"
"\x00\x11\x00\x12\x07\x00\x13\x07\x00\x14\x01\x00\x06\x3c\x69\x6e"
"\x69\x74\x3e\x01\x00\x03\x28\x29\x56\x01\x00\x04\x43\x6f\x64\x65"
"\x01\x00\x0f\x4c\x69\x6e\x65\x4e\x75\x6d\x62\x65\x72\x54\x61\x62"
"\x6c\x65\x01\x00\x12\x4c\x6f\x63\x61\x6c\x56\x61\x72\x69\x61\x62"
"\x6c\x65\x54\x61\x62\x6c\x65\x01\x00\x04\x74\x68\x69\x73\x01\x00"
"\x2b\x4c\x63\x68\x2f\x75\x73\x69\x2f\x64\x61\x67\x2f\x64\x69\x73"
"\x6c\x2f\x64\x79\x6e\x61\x6d\x69\x63\x62\x79\x70\x61\x73\x73\x2f"
"\x42\x79\x70\x61\x73\x73\x43\x68\x65\x63\x6b\x3b\x01\x00\x15\x65"
"\x78\x65\x63\x75\x74\x65\x55\x6e\x69\x6e\x73\x74\x72\x75\x6d\x65"
"\x6e\x74\x65\x64\x01\x00\x03\x28\x29\x5a\x01\x00\x0a\x53\x6f\x75"
"\x72\x63\x65\x46\x69\x6c\x65\x01\x00\x10\x42\x79\x70\x61\x73\x73"
"\x43\x68\x65\x63\x6b\x2e\x6a\x61\x76\x61\x0c\x00\x05\x00\x06\x07"
"\x00\x15\x0c\x00\x16\x00\x0d\x01\x00\x29\x63\x68\x2f\x75\x73\x69"
"\x2f\x64\x61\x67\x2f\x64\x69\x73\x6c\x2f\x64\x79\x6e\x61\x6d\x69"
"\x63\x62\x79\x70\x61\x73\x73\x2f\x42\x79\x70\x61\x73\x73\x43\x68"
"\x65\x63\x6b\x01\x00\x10\x6a\x61\x76\x61\x2f\x6c\x61\x6e\x67\x2f"
"\x4f\x62\x6a\x65\x63\x74\x01\x00\x2b\x63\x68\x2f\x75\x73\x69\x2f"
"\x64\x61\x67\x2f\x64\x69\x73\x6c\x2f\x64\x79\x6e\x61\x6d\x69\x63"
"\x62\x79\x70\x61\x73\x73\x2f\x44\x79\x6e\x61\x6d\x69\x63\x42\x79"
"\x70\x61\x73\x73\x01\x00\x08\x69\x73\x41\x63\x74\x69\x76\x65\x00"
"\x31\x00\x03\x00\x04\x00\x00\x00\x00\x00\x02\x00\x01\x00\x05\x00"
"\x06\x00\x01\x00\x07\x00\x00\x00\x2f\x00\x01\x00\x01\x00\x00\x00"
"\x05\x2a\xb7\x00\x01\xb1\x00\x00\x00\x02\x00\x08\x00\x00\x00\x06"
"\x00\x01\x00\x00\x00\x08\x00\x09\x00\x00\x00\x0c\x00\x01\x00\x00"
"\x00\x05\x00\x0a\x00\x0b\x00\x00\x00\x09\x00\x0c\x00\x0d\x00\x01"
"\x00\x07\x00\x00\x00\x1c\x00\x01\x00\x00\x00\x00\x00\x04\xb8\x00"
"\x02\xac\x00\x00\x00\x01\x00\x08\x00\x00\x00\x06\x00\x01\x00\x00"
"\x00\x0b\x00\x01\x00\x0e\x00\x00\x00\x02\x00\x0f",
};
jvmtiClassDefinition never_BypassCheck_classdef = {
.class_byte_count = 388,
.class_bytes = (unsigned char *)
"\xca\xfe\xba\xbe\x00\x00\x00\x30\x00\x12\x0a\x00\x03\x00\x0f\x07"
"\x00\x10\x07\x00\x11\x01\x00\x06\x3c\x69\x6e\x69\x74\x3e\x01\x00"
"\x03\x28\x29\x56\x01\x00\x04\x43\x6f\x64\x65\x01\x00\x0f\x4c\x69"
"\x6e\x65\x4e\x75\x6d\x62\x65\x72\x54\x61\x62\x6c\x65\x01\x00\x12"
"\x4c\x6f\x63\x61\x6c\x56\x61\x72\x69\x61\x62\x6c\x65\x54\x61\x62"
"\x6c\x65\x01\x00\x04\x74\x68\x69\x73\x01\x00\x2b\x4c\x63\x68\x2f"
"\x75\x73\x69\x2f\x64\x61\x67\x2f\x64\x69\x73\x6c\x2f\x64\x79\x6e"
"\x61\x6d\x69\x63\x62\x79\x70\x61\x73\x73\x2f\x42\x79\x70\x61\x73"
"\x73\x43\x68\x65\x63\x6b\x3b\x01\x00\x15\x65\x78\x65\x63\x75\x74"
"\x65\x55\x6e\x69\x6e\x73\x74\x72\x75\x6d\x65\x6e\x74\x65\x64\x01"
"\x00\x03\x28\x29\x5a\x01\x00\x0a\x53\x6f\x75\x72\x63\x65\x46\x69"
"\x6c\x65\x01\x00\x10\x42\x79\x70\x61\x73\x73\x43\x68\x65\x63\x6b"
"\x2e\x6a\x61\x76\x61\x0c\x00\x04\x00\x05\x01\x00\x29\x63\x68\x2f"
"\x75\x73\x69\x2f\x64\x61\x67\x2f\x64\x69\x73\x6c\x2f\x64\x79\x6e"
"\x61\x6d\x69\x63\x62\x79\x70\x61\x73\x73\x2f\x42\x79\x70\x61\x73"
"\x73\x43\x68\x65\x63\x6b\x01\x00\x10\x6a\x61\x76\x61\x2f\x6c\x61"
"\x6e\x67\x2f\x4f\x62\x6a\x65\x63\x74\x00\x31\x00\x02\x00\x03\x00"
"\x00\x00\x00\x00\x02\x00\x01\x00\x04\x00\x05\x00\x01\x00\x06\x00"
"\x00\x00\x2f\x00\x01\x00\x01\x00\x00\x00\x05\x2a\xb7\x00\x01\xb1"
"\x00\x00\x00\x02\x00\x07\x00\x00\x00\x06\x00\x01\x00\x00\x00\x08"
"\x00\x08\x00\x00\x00\x0c\x00\x01\x00\x00\x00\x05\x00\x09\x00\x0a"
"\x00\x00\x00\x09\x00\x0b\x00\x0c\x00\x01\x00\x06\x00\x00\x00\x1a"
"\x00\x01\x00\x00\x00\x00\x00\x02\x03\xac\x00\x00\x00\x01\x00\x07"
"\x00\x00\x00\x06\x00\x01\x00\x00\x00\x0b\x00\x01\x00\x0d\x00\x00"
"\x00\x02\x00\x0e",
};
#ifndef _BYTECODE_H_
#define _BYTECODE_H_
#include <jvmti.h>
/**
* Name of the class used for bypass checks.
*/
#define BPC_CLASS_NAME "ch/usi/dag/disl/dynamicbypass/BypassCheck"
/**
* Externs for various implementations of the BypassCheck class.
*/
extern jvmtiClassDefinition always_BypassCheck_classdef;
extern jvmtiClassDefinition dynamic_BypassCheck_classdef;
extern jvmtiClassDefinition never_BypassCheck_classdef;
#endif /* _BYTECODE_H_ */
#include "../common.h"
#include "classparser.h"
#include <assert.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
//