nativebridge.cc revision 855564b83db7b106d2995d0e784f1f4b62e52371
1/* 2 * Copyright (C) 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17// A simple implementation of the native-bridge interface. 18 19#include <algorithm> 20#include <dlfcn.h> 21#include <vector> 22 23#include "jni.h" 24#include "stdio.h" 25#include "string.h" 26#include "unistd.h" 27 28#include "native_bridge.h" 29 30 31// Native bridge interfaces... 32 33struct NativeBridgeArtCallbacks { 34 const char* (*getMethodShorty)(JNIEnv* env, jmethodID mid); 35 int (*getNativeMethodCount)(JNIEnv* env, jclass clazz); 36 int (*getNativeMethods)(JNIEnv* env, jclass clazz, JNINativeMethod* methods, 37 uint32_t method_count); 38}; 39 40struct NativeBridgeCallbacks { 41 bool (*initialize)(NativeBridgeArtCallbacks* art_cbs); 42 void* (*loadLibrary)(const char* libpath, int flag); 43 void* (*getTrampoline)(void* handle, const char* name, const char* shorty, uint32_t len); 44 bool (*isSupported)(const char* libpath); 45}; 46 47 48 49static std::vector<void*> symbols; 50 51// NativeBridgeCallbacks implementations 52extern "C" bool native_bridge_initialize(NativeBridgeArtCallbacks* art_cbs) { 53 printf("Native bridge initialized.\n"); 54 return true; 55} 56 57extern "C" void* native_bridge_loadLibrary(const char* libpath, int flag) { 58 size_t len = strlen(libpath); 59 char* tmp = new char[len + 10]; 60 strncpy(tmp, libpath, len); 61 tmp[len - 3] = '2'; 62 tmp[len - 2] = '.'; 63 tmp[len - 1] = 's'; 64 tmp[len] = 'o'; 65 tmp[len + 1] = 0; 66 void* handle = dlopen(tmp, flag); 67 delete[] tmp; 68 69 if (handle == nullptr) { 70 printf("Handle = nullptr!\n"); 71 printf("Was looking for %s.\n", libpath); 72 printf("Error = %s.\n", dlerror()); 73 char cwd[1024]; 74 if (getcwd(cwd, sizeof(cwd)) != nullptr) { 75 printf("Current working dir: %s\n", cwd); 76 } 77 } 78 return handle; 79} 80 81extern "C" void* native_bridge_getTrampoline(void* handle, const char* name, const char* shorty, 82 uint32_t len) { 83 printf("Getting trampoline.\n"); 84 85 // The name here is actually the JNI name, so we can directly do the lookup. 86 void* sym = dlsym(handle, name); 87 if (sym != nullptr) { 88 symbols.push_back(sym); 89 } 90 91 // As libarttest is the same arch as the host, we can actually directly use the code and do not 92 // need to create a trampoline. :-) 93 return sym; 94} 95 96extern "C" bool native_bridge_isSupported(const char* libpath) { 97 printf("Checking for support.\n"); 98 99 if (libpath == nullptr) { 100 return false; 101 } 102 // We don't want to hijack javacore. So we should get libarttest... 103 return strcmp(libpath, "libjavacore.so") != 0; 104} 105 106NativeBridgeCallbacks NativeBridgeItf { 107 .initialize = &native_bridge_initialize, 108 .loadLibrary = &native_bridge_loadLibrary, 109 .getTrampoline = &native_bridge_getTrampoline, 110 .isSupported = &native_bridge_isSupported 111}; 112 113 114 115