From 3a402d342138207a43bb576dadb5bce6cc64a222 Mon Sep 17 00:00:00 2001
From: Gary Frost <frost.gary@gmail.com>
Date: Wed, 16 Jan 2013 03:01:58 +0000
Subject: [PATCH] started adding kernel checker

---
 com.amd.aparapi.jni/src/cpp/agent.cpp | 428 +++++++++++++++++++-------
 1 file changed, 316 insertions(+), 112 deletions(-)

diff --git a/com.amd.aparapi.jni/src/cpp/agent.cpp b/com.amd.aparapi.jni/src/cpp/agent.cpp
index e13a78d8..bf03e15a 100644
--- a/com.amd.aparapi.jni/src/cpp/agent.cpp
+++ b/com.amd.aparapi.jni/src/cpp/agent.cpp
@@ -4,67 +4,264 @@
 #include <jni.h>
 #include <jvmti.h>
 
-
-
-
 jvmtiEnv     *jvmti;
 JavaVM       *jvm;
 
 static void JNICALL vmInit(jvmtiEnv *_jvmtiEnv, JNIEnv* _jniEnv, jthread thread) {
-   fprintf(stdout, "from agent vmInit()\n");
-   /*
-   if (_jniEnv->ExceptionOccurred()) {
-      fprintf(stdout, "Exception raised\n");
-      _jniEnv->ExceptionDescribe();
-      _jniEnv->ExceptionClear();
-   }
-   jclass classId = _jniEnv->FindClass("C");
-   classId = _jniEnv->FindClass("java/lang/String");
-   if (_jniEnv->ExceptionOccurred()) {
-      fprintf(stdout, "Exception raised\n");
-      _jniEnv->ExceptionDescribe();
-      _jniEnv->ExceptionClear();
-   }
-   */
+  fprintf(stdout, "from agent vmInit()\n");
+  /*
+     if (_jniEnv->ExceptionOccurred()) {
+     fprintf(stdout, "Exception raised\n");
+     _jniEnv->ExceptionDescribe();
+     _jniEnv->ExceptionClear();
+     }
+     jclass classId = _jniEnv->FindClass("C");
+     classId = _jniEnv->FindClass("java/lang/String");
+     if (_jniEnv->ExceptionOccurred()) {
+     fprintf(stdout, "Exception raised\n");
+     _jniEnv->ExceptionDescribe();
+     _jniEnv->ExceptionClear();
+     }
+     */
 }
 
-class NameToBytes{
+enum ConstantPoolType {
+  EMPTY, //0
+  UTF8, //1
+  UNICODE, //2
+  INTEGER, //3
+  FLOAT, //4
+  LONG, //5
+  DOUBLE, //6
+  CLASS, //7
+  STRING, //8
+  FIELD, //9
+  METHOD, //10
+  INTERFACEMETHOD, //11
+  NAMEANDTYPE, //12
+  UNUSED13,
+  UNUSED14,
+  METHODHANDLE, //15
+  METHODTYPE, //16
+  UNUSED17,
+  INVOKEDYNAMIC //18
+};
+
+class ByteBuffer; // forward reference
+
+class ConstantPoolEntry{
   private:
-    const char *name;
-    const jint len;
-    const unsigned char *bytes;
-    const NameToBytes* next;
+    ConstantPoolType constantPoolType;
+    int slot;
   public:
-    NameToBytes(const NameToBytes *_head, const char *_name, const jint _len, const unsigned char *_bytes) : len(_len) {
-      int nameLen = strlen(_name)+1;
-      name = new char [nameLen];
-      memcpy((void*)name, (void*)_name, nameLen);
-      for (char *ptr = (char *)name; *ptr; ptr++){
-         if (*ptr == '/'){
-            *ptr = '.';
-         }
+    ConstantPoolEntry(ByteBuffer *_byteBuffer, int _slot, ConstantPoolType _constantPoolType)
+      : slot(_slot), constantPoolType(_constantPoolType)
+    {
+    }
+
+    ConstantPoolType getConstantPoolType() {
+      return (constantPoolType);
+    }
+
+    int getSlot() {
+      return (slot);
+    }
+};
+
+class EmptyConstantPoolEntry : public ConstantPoolEntry{
+  public:
+    EmptyConstantPoolEntry(ByteBuffer *_byteBuffer, int _slot)
+      :  ConstantPoolEntry(_byteBuffer, _slot, EMPTY)
+    {
+    }
+};
+
+class UTF8ConstantPoolEntry: public ConstantPoolEntry{
+  private:
+    jstring utf8;
+  public:
+    UTF8ConstantPoolEntry(ByteBuffer *_byteBuffer, int _slot) 
+      : ConstantPoolEntry(_byteBuffer, _slot, UTF8)
+    {
+      //utf8 = _byteReader.utf8();
+    }
+    jstring getUTF8() {
+      return (utf8);
+    }
+};
+
+class ByteBuffer{
+  private:
+    jint len;
+    jbyte *bytes;
+    jbyte *ptr;
+  public:
+    ByteBuffer(jbyte *_bytes, jint _len)
+      : len(_len), bytes(new jbyte[len]), ptr(bytes){
+        memcpy((void*)bytes, (void*)_bytes, len);
       }
+    ~ByteBuffer(){
+      delete bytes;
+    }
+    jbyte *getBytes(){
+      return(bytes);
+    }
+    jint getLen(){
+      return(len);
+    }
+
+    unsigned int u1(jbyte *ptr){
+      int u1 = (unsigned int) (*ptr & 0xff);
+ //     fprintf(stderr, "u1 %01x\n", u1);
+      return (u1);
+    }
+    unsigned int u2(jbyte *ptr){
+      unsigned int u2 = (u1(ptr)<<8)|u1(ptr+1);
+ //     fprintf(stderr, "u2 %02x\n", u2);
+      return (u2);
+    }
+    unsigned int u4(jbyte *ptr){
+      unsigned int u4 = (u2(ptr)<<16)|u2(ptr+2);
+//      fprintf(stderr, "u4 %04x\n", u4);
+      return (u4);
+    }
+    unsigned long u8(jbyte *ptr){
+      unsigned long u8 = (((unsigned long)u4(ptr))<<32)|u4(ptr+4);
+//      fprintf(stderr, "u8 %08lx\n", u8);
+      return (u8);
+    }
 
-    //  name = (const char*)strdup(_name);
-      bytes = new unsigned char[len];
-      memcpy((void*)bytes, (void*)_bytes, len);
-      next = _head;
+    bool isKernel(){
+      unsigned int magic= u4(ptr); ptr+=4;
+      if (magic == 0xcafebabe){
+//        fprintf(stdout, "magic = %04x\n", magic);
+        unsigned int minor= u2(ptr); ptr+=2;
+        unsigned int major= u2(ptr); ptr+=2;
+        unsigned int constantPoolSize = u2(ptr); ptr+=2;
+//        fprintf(stdout, "constant pool size = %d\n", constantPoolSize);
+        unsigned int constantPoolIdx = 0;
+        if (0){
+          ConstantPoolEntry **entries=new ConstantPoolEntry *[constantPoolSize];
+          while (constantPoolIdx < constantPoolSize){
+            ConstantPoolType constantPoolType = (ConstantPoolType)u1(ptr); ptr++;
+            switch (constantPoolType){
+              case EMPTY: //0
+                {
+                  entries[constantPoolIdx] = new EmptyConstantPoolEntry(this, constantPoolIdx);
+                  constantPoolIdx++;
+                }
+                break;
+              case UTF8: //1
+                {
+                  entries[constantPoolIdx] = new UTF8ConstantPoolEntry(this, constantPoolIdx);
+                  constantPoolIdx++;
+                }
+                break;
+              case UNICODE: //2
+                {
+                }
+                break;
+              case INTEGER: //3
+                {
+                }
+                break;
+              case FLOAT: //4
+                {
+                }
+                break;
+              case LONG: //5
+                {
+                }
+                break;
+              case DOUBLE: //6
+                {
+                }
+                break;
+              case CLASS: //7
+                {
+                }
+                break;
+              case STRING: //8
+                {
+                }
+                break;
+              case FIELD: //9
+                {
+                }
+                break;
+              case METHOD: //10
+                {
+                }
+                break;
+              case INTERFACEMETHOD: //11
+                {
+                }
+                break;
+              case NAMEANDTYPE: //12
+                {
+                }
+                break;
+              case UNUSED13:
+                {
+                }
+                break;
+              case UNUSED14:
+                {
+                }
+                break;
+              case METHODHANDLE: //15
+                {
+                }
+                break;
+              case METHODTYPE: //16
+                {
+                }
+                break;
+              case UNUSED17:
+                {
+                }
+                break;
+              case INVOKEDYNAMIC: //18
+                {
+                }
+                break;
+            }
+          }
+        }
+      }
+      return(true);
     }
+};
+
+class NameToBytes{
+  private:
+    char *name;
+    ByteBuffer *byteBuffer;
+    NameToBytes* next;
+  public:
+    NameToBytes(NameToBytes *_head, char *_name, ByteBuffer *_byteBuffer)
+      : byteBuffer(_byteBuffer) {
+        int nameLen = strlen(_name)+1;
+        name = new char [nameLen];
+        memcpy((void*)name, (void*)_name, nameLen);
+        for (char *ptr = (char *)name; *ptr; ptr++){
+          if (*ptr == '/'){
+            *ptr = '.';
+          }
+        }
+        next = _head;
+      }
     ~NameToBytes(){
       delete name;
-      delete bytes;
-    }
-    const unsigned char *getBytes(){
-       return(bytes);
     }
-    const char *getName(){
-       return(name);
+    char *getName(){
+      return(name);
     }
-    const jint getLen(){
-       return(len);
+    NameToBytes *getNext(){
+      return(next);
     }
-    const NameToBytes *getNext(){
-       return(next);
+    ByteBuffer *getByteBuffer(){
+      return(byteBuffer);
     }
 };
 
@@ -78,89 +275,96 @@ NameToBytes *head = NULL;
 #ifdef __cplusplus
 extern "C" {
 #endif
-JNIEXPORT jbyteArray JNICALL Java_com_amd_aparapi_OpenCLJNI_getBytes (JNIEnv *jenv, jobject instance, jstring className){
-     jbyteArray bytes = NULL;
-     const char *nameChars = jenv->GetStringUTFChars(className, NULL);
-     fprintf(stdout, "inside getBytes(\"%s\")\n", nameChars);
-     for (NameToBytes *ptr = head; ptr != NULL; ptr=(NameToBytes *)ptr->getNext()){
-        //fprintf(stdout, "testing \"%s\"==\"%s\"\n", nameChars, ptr->getName());
-        if (!strcmp(ptr->getName(), nameChars)){
-           fprintf(stdout, "found bytes for \"%s\"\n", nameChars);
-           bytes = jenv->NewByteArray(ptr->getLen());
-           //fprintf(stdout, "created byte array size= %d\n", ptr->getLen());
-           jenv->SetByteArrayRegion(bytes, (jint)0, (jint)ptr->getLen() , (jbyte*)ptr->getBytes());
-           break;
-        }
-     }
-     if (bytes == NULL){
-        fprintf(stdout, "failed to find bytes for \"%s\"\n", nameChars);
-     }
-     jenv->ReleaseStringUTFChars(className, nameChars);
-     return (bytes);
-}
+  JNIEXPORT jbyteArray JNICALL Java_com_amd_aparapi_OpenCLJNI_getBytes (JNIEnv *jenv, jobject instance, jstring className){
+    jbyteArray bytes = NULL;
+    const char *nameChars = jenv->GetStringUTFChars(className, NULL);
+    fprintf(stdout, "inside getBytes(\"%s\")\n", nameChars);
+    for (NameToBytes *ptr = head; ptr != NULL; ptr=(NameToBytes *)ptr->getNext()){
+      //fprintf(stdout, "testing \"%s\"==\"%s\"\n", nameChars, ptr->getName());
+      if (!strcmp(ptr->getName(), nameChars)){
+        fprintf(stdout, "found bytes for \"%s\"\n", nameChars);
+        ByteBuffer *byteBuffer = ptr->getByteBuffer();
+        bytes = jenv->NewByteArray(byteBuffer->getLen());
+        //fprintf(stdout, "created byte array size= %d\n", ptr->getLen());
+        jenv->SetByteArrayRegion(bytes, (jint)0, byteBuffer->getLen() , byteBuffer->getBytes());
+        break;
+      }
+    }
+    if (bytes == NULL){
+      fprintf(stdout, "failed to find bytes for \"%s\"\n", nameChars);
+    }
+    jenv->ReleaseStringUTFChars(className, nameChars);
+    return (bytes);
+  }
 #ifdef __cplusplus
 }
 #endif
 
 
+
+
+
 static void JNICALL cbClassFileLoadHook(jvmtiEnv *jvmti_env, JNIEnv* jni_env,
-            jclass class_being_redefined,
-            jobject loader,
-            const char* name,
-            jobject protection_domain,
-            jint class_data_len,
-            const unsigned char* class_data,
-            jint* new_class_data_len,
-            unsigned char** new_class_data){
-//   fprintf(stdout, "from agent classFileLoadHook(%s)\n", name);
-   head =  new NameToBytes(head, name, class_data_len, class_data);
+    jclass class_being_redefined,
+    jobject loader,
+    const char* name,
+    jobject protection_domain,
+    jint class_data_len,
+    const unsigned char* class_data,
+    jint* new_class_data_len,
+    unsigned char** new_class_data){
+  //   fprintf(stdout, "from agent classFileLoadHook(%s)\n", name);
+  ByteBuffer *byteBuffer = new ByteBuffer((jbyte *)class_data, (jint)class_data_len);
+  if (byteBuffer->isKernel()){
+    head =  new NameToBytes(head, (char*)name, byteBuffer);
+  }
 }
 
 
 JNIEXPORT jint JNICALL Agent_OnLoad(JavaVM *vm, char *options, void *reserved) {
-   jint                returnValue = 0; // OK
-   jint                rc;
-   jvmtiError          err;
-   jvmtiCapabilities   capabilities;
-   jvmtiEventCallbacks callbacks;
-   fprintf(stdout, "Agent_Onload()\n");
-
-   // Get a handle on the JVM.
-   jvm = vm;
-
-   /* Get JVMTI environment */
-   rc = vm->GetEnv((void **)&jvmti, JVMTI_VERSION);
-   if (rc != JNI_OK) {
-      fprintf(stderr, "ERROR: Unable to create jvmtiEnv, GetEnv failed, error=%d\n", rc);
+  jint                returnValue = 0; // OK
+  jint                rc;
+  jvmtiError          err;
+  jvmtiCapabilities   capabilities;
+  jvmtiEventCallbacks callbacks;
+  fprintf(stdout, "Agent_Onload()\n");
+
+  // Get a handle on the JVM.
+  jvm = vm;
+
+  /* Get JVMTI environment */
+  rc = vm->GetEnv((void **)&jvmti, JVMTI_VERSION);
+  if (rc != JNI_OK) {
+    fprintf(stderr, "ERROR: Unable to create jvmtiEnv, GetEnv failed, error=%d\n", rc);
+    returnValue = -1;
+  }else{
+    /* Get/Add JVMTI capabilities */ 
+    if ((err = jvmti->GetCapabilities(&capabilities) ) != JVMTI_ERROR_NONE) {
+      fprintf(stderr, "ERROR: GetCapabilities failed, error=%d\n", err);
       returnValue = -1;
-   }else{
-      /* Get/Add JVMTI capabilities */ 
-      if ((err = jvmti->GetCapabilities(&capabilities) ) != JVMTI_ERROR_NONE) {
-         fprintf(stderr, "ERROR: GetCapabilities failed, error=%d\n", err);
-         returnValue = -1;
+    }else{
+      capabilities.can_tag_objects = 1;
+      capabilities.can_generate_all_class_hook_events = 1;
+      if ((err = jvmti->AddCapabilities(&capabilities))!= JVMTI_ERROR_NONE) {
+        fprintf(stderr, "ERROR: AddCapabilities failed, error=%d\n", err);
+        returnValue = -1;
       }else{
-         capabilities.can_tag_objects = 1;
-         capabilities.can_generate_all_class_hook_events = 1;
-         if ((err = jvmti->AddCapabilities(&capabilities))!= JVMTI_ERROR_NONE) {
-            fprintf(stderr, "ERROR: AddCapabilities failed, error=%d\n", err);
-            returnValue = -1;
-         }else{
-            /* Set callbacks and enable event notifications */
-            memset(&callbacks, 0, sizeof(callbacks));
-            callbacks.VMInit = &vmInit;
-            callbacks.ClassFileLoadHook = &cbClassFileLoadHook;
-
-            jvmti->SetEventCallbacks(&callbacks, sizeof(callbacks));
-            jvmti->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_VM_INIT, NULL);
-            jvmti->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_CLASS_FILE_LOAD_HOOK, NULL);
-         }
+        /* Set callbacks and enable event notifications */
+        memset(&callbacks, 0, sizeof(callbacks));
+        callbacks.VMInit = &vmInit;
+        callbacks.ClassFileLoadHook = &cbClassFileLoadHook;
+
+        jvmti->SetEventCallbacks(&callbacks, sizeof(callbacks));
+        jvmti->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_VM_INIT, NULL);
+        jvmti->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_CLASS_FILE_LOAD_HOOK, NULL);
       }
-   }
-   return returnValue;
+    }
+  }
+  return returnValue;
 }
 
 /* Agent_OnUnload() is called last */
 JNIEXPORT void JNICALL Agent_OnUnload(JavaVM *vm) {
-   fprintf(stdout, "Agent_OnUnload()\n");
+  fprintf(stdout, "Agent_OnUnload()\n");
 }
 
-- 
GitLab