summaryrefslogtreecommitdiff
path: root/java/method.c
diff options
context:
space:
mode:
authorRodrigo Arias Mallo <rodarima@gmail.com>2024-12-10 22:30:12 +0100
committerRodrigo Arias Mallo <rodarima@gmail.com>2024-12-10 22:30:12 +0100
commit429d5f88b94ff28416cbfc6420b6389fa284df97 (patch)
treefb6fdaf7731de1ef396f98b748c56f3149801c84 /java/method.c
Import RTFL 0.1.1v0.1.1
Diffstat (limited to 'java/method.c')
-rw-r--r--java/method.c111
1 files changed, 111 insertions, 0 deletions
diff --git a/java/method.c b/java/method.c
new file mode 100644
index 0000000..35e6022
--- /dev/null
+++ b/java/method.c
@@ -0,0 +1,111 @@
+#include <string.h>
+
+#include "method.h"
+#include "config.h"
+#include "misc.h"
+
+static bool handle_method (jvmtiEnv *jvmti, JNIEnv* jni, jthread thread,
+ jmethodID method, char **object, char **method_name,
+ char **class_name)
+{
+ jvmtiError error;
+ char *class_sig = NULL, object_buf[SIZE_OBJECT_BUF];
+ jclass klass;
+ bool success = FALSE;
+
+ *object = *method_name = *class_name = NULL;
+
+ if ((error =
+ (*jvmti)->GetMethodName (jvmti, method, method_name, NULL, NULL))
+ != JVMTI_ERROR_NONE)
+ jvmti_error (jvmti, error, "GetMethodName");
+ else if ((error =
+ (*jvmti)->GetMethodDeclaringClass (jvmti, method, &klass))
+ != JVMTI_ERROR_NONE)
+ jvmti_error (jvmti, error, "GetMethodDeclaringClass");
+ else if ((error =
+ (*jvmti)->GetClassSignature (jvmti, klass, &class_sig, NULL))
+ != JVMTI_ERROR_NONE)
+ jvmti_error (jvmti, error, "GetClassSignature");
+ else {
+ if ((*class_name = get_class_name_from_sig (class_sig, TRUE)) &&
+ include_class (*class_name)) {
+ jint numlocals;
+ jvmtiLocalVariableEntry *locals;
+ if ((error = (*jvmti)->GetLocalVariableTable (jvmti, method,
+ &numlocals, &locals))
+ != JVMTI_ERROR_NONE)
+ jvmti_error (jvmti, error, "GetLocalVariableTable");
+ else {
+ jint j, this_slot = -1;
+ for (j = 0; j < numlocals && this_slot == -1; j++)
+ if (strcmp (locals[j].name, "this") == 0)
+ this_slot = locals[j].slot;
+
+ jobject this_obj;
+
+ if (this_slot == -1) {
+ this_obj = NULL;
+ success = TRUE;
+ } else {
+ if ((error = (*jvmti)->GetLocalObject (jvmti, thread, 0,
+ this_slot, &this_obj))
+ != JVMTI_ERROR_NONE) {
+ jvmti_error (jvmti, error, "GetLocalObject");
+ } else
+ success = TRUE;
+ }
+
+ if (success) {
+ fill_object_buf (jni, object_buf, this_obj);
+ *object = strdup (object_buf);
+ }
+ }
+ }
+ }
+
+ jvmti_dealloc (jvmti, class_sig);
+
+ return success;
+}
+
+static void handle_method_free (jvmtiEnv *jvmti, char *object,
+ char *method_name, char *class_name)
+{
+ simple_free (object);
+ jvmti_dealloc (jvmti, method_name);
+ simple_free (class_name);
+}
+
+void JNICALL method_entry (jvmtiEnv *jvmti, JNIEnv* jni, jthread thread,
+ jmethodID method)
+{
+ char *object, *method_name, *class_name;
+
+ if (handle_method (jvmti, jni, thread, method, &object, &method_name,
+ &class_name)) {
+ if (strcmp (method_name, "<init>") == 0)
+ RTFL_OBJ_PRINT ("create", "s:s", object, class_name);
+ else
+ RTFL_OBJ_PRINT ("enter", "s:s:d:s:",
+ object, "", 0, method_name, class_name);
+ }
+
+ handle_method_free (jvmti, object, method_name, class_name);
+}
+
+void JNICALL method_exit (jvmtiEnv *jvmti, JNIEnv* jni, jthread thread,
+ jmethodID method, jboolean was_popped_by_exception,
+ jvalue return_value)
+{
+ char *object, *method_name, *class_name;
+
+ if (handle_method (jvmti, jni, thread, method, &object, &method_name,
+ &class_name)) {
+ if (strcmp (method_name, "<init>") != 0)
+ // Hopefully, this is the correct method.
+ RTFL_OBJ_PRINT ("leave", "s", object);
+ }
+
+ handle_method_free (jvmti, object, method_name, class_name);
+}