/*
 * Copyright (C) 2013 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "nativehelper/JniInvocation.h"

#include <string>

#ifdef _WIN32
#include <windows.h>
#else
#include <dlfcn.h>
#endif

#define LOG_TAG "JniInvocation"
#include <log/log.h>

#if defined(__ANDROID__)
#include <sys/system_properties.h>
#elif defined(_WIN32)
#include <android-base/errors.h>
#endif

#include "JniConstants.h"

namespace {

template <typename T>
void UNUSED(const T&) {}

bool IsDebuggable() {
#ifdef __ANDROID__
  char debuggable[PROP_VALUE_MAX] = {0};
  __system_property_get("ro.debuggable", debuggable);
  return strcmp(debuggable, "1") == 0;
#else
  return false;
#endif
}

int GetLibrarySystemProperty(char* buffer) {
#ifdef __ANDROID__
  return __system_property_get("persist.sys.dalvik.vm.lib.2", buffer);
#else
  UNUSED(buffer);
  return 0;
#endif
}

#ifdef _WIN32
#define FUNC_POINTER FARPROC
#else
#define FUNC_POINTER void*
#endif

void* OpenLibrary(const char* filename) {
#ifdef _WIN32
  return LoadLibrary(filename);
#else
  // Load with RTLD_NODELETE in order to ensure that libart.so is not unmapped when it is closed.
  // This is due to the fact that it is possible that some threads might have yet to finish
  // exiting even after JNI_DeleteJavaVM returns, which can lead to segfaults if the library is
  // unloaded.
  const int kDlopenFlags = RTLD_NOW | RTLD_NODELETE;
  return dlopen(filename, kDlopenFlags);
#endif
}

int CloseLibrary(void* handle) {
#ifdef _WIN32
  return FreeLibrary(static_cast<HMODULE>(handle));
#else
  return dlclose(handle);
#endif
}

FUNC_POINTER GetSymbol(void* handle, const char* symbol) {
#ifdef _WIN32
  return GetProcAddress(static_cast<HMODULE>(handle), symbol);
#else
  return dlsym(handle, symbol);
#endif
}

std::string GetError() {
#ifdef _WIN32
  return android::base::SystemErrorCodeToString(GetLastError());
#else
  return std::string(dlerror());
#endif
}

}  // namespace

struct JniInvocationImpl final {
 public:
  JniInvocationImpl();
  ~JniInvocationImpl();

  bool Init(const char* library);

  static const char* GetLibrary(const char* library,
                                char* buffer,
                                bool (*is_debuggable)() = IsDebuggable,
                                int (*get_library_system_property)(char* buffer) = GetLibrarySystemProperty);

  static JniInvocationImpl& GetJniInvocation();
  static bool IsInitialized();

  jint JNI_GetDefaultJavaVMInitArgs(void* vmargs);
  jint JNI_CreateJavaVM(JavaVM** p_vm, JNIEnv** p_env, void* vm_args);
  jint JNI_GetCreatedJavaVMs(JavaVM** vms, jsize size, jsize* vm_count);

 private:
  JniInvocationImpl(const JniInvocationImpl&) = delete;
  JniInvocationImpl& operator=(const JniInvocationImpl&) = delete;

  bool FindSymbol(FUNC_POINTER* pointer, const char* symbol);

  static JniInvocationImpl* jni_invocation_;

  // Handle to library opened with dlopen(). Library exports
  // JNI_GetDefaultJavaVMInitArgs, JNI_CreateJavaVM, JNI_GetCreatedJavaVMs.
  void* handle_;
  jint (*JNI_GetDefaultJavaVMInitArgs_)(void*);
  jint (*JNI_CreateJavaVM_)(JavaVM**, JNIEnv**, void*);
  jint (*JNI_GetCreatedJavaVMs_)(JavaVM**, jsize, jsize*);

  friend class JNIInvocation_Debuggable_Test;
  friend class JNIInvocation_NonDebuggable_Test;
};

// Check JniInvocationImpl size is same as fields, e.g. no vtable present.
static_assert(sizeof(JniInvocationImpl) == 4 * sizeof(uintptr_t));

JniInvocationImpl* JniInvocationImpl::jni_invocation_ = NULL;

JniInvocationImpl::JniInvocationImpl() :
    handle_(NULL),
    JNI_GetDefaultJavaVMInitArgs_(NULL),
    JNI_CreateJavaVM_(NULL),
    JNI_GetCreatedJavaVMs_(NULL) {
  LOG_ALWAYS_FATAL_IF(jni_invocation_ != NULL, "JniInvocation instance already initialized");
  jni_invocation_ = this;
}

JniInvocationImpl::~JniInvocationImpl() {
  jni_invocation_ = NULL;
  if (handle_ != NULL) {
    CloseLibrary(handle_);
  }
}

static const char* kLibraryFallback = "libart.so";

const char* JniInvocationImpl::GetLibrary(const char* library,
                                          char* buffer,
                                          bool (*is_debuggable)(),
                                          int (*get_library_system_property)(char* buffer)) {
#ifdef __ANDROID__
  const char* default_library;

  if (!is_debuggable()) {
    // Not a debuggable build.
    // Do not allow arbitrary library. Ignore the library parameter. This
    // will also ignore the default library, but initialize to fallback
    // for cleanliness.
    library = kLibraryFallback;
    default_library = kLibraryFallback;
  } else {
    // Debuggable build.
    // Accept the library parameter. For the case it is NULL, load the default
    // library from the system property.
    if (buffer != NULL) {
      if (get_library_system_property(buffer) > 0) {
        default_library = buffer;
      } else {
        default_library = kLibraryFallback;
      }
    } else {
      // No buffer given, just use default fallback.
      default_library = kLibraryFallback;
    }
  }
#else
  UNUSED(buffer);
  UNUSED(is_debuggable);
  UNUSED(get_library_system_property);
  const char* default_library = kLibraryFallback;
#endif
  if (library == NULL) {
    library = default_library;
  }

  return library;
}

bool JniInvocationImpl::Init(const char* library) {
#ifdef __ANDROID__
  char buffer[PROP_VALUE_MAX];
#else
  char* buffer = NULL;
#endif
  library = GetLibrary(library, buffer);
  handle_ = OpenLibrary(library);
  if (handle_ == NULL) {
    if (strcmp(library, kLibraryFallback) == 0) {
      // Nothing else to try.
      ALOGE("Failed to dlopen %s: %s", library, GetError().c_str());
      return false;
    }
    // Note that this is enough to get something like the zygote
    // running, we can't property_set here to fix this for the future
    // because we are root and not the system user. See
    // RuntimeInit.commonInit for where we fix up the property to
    // avoid future fallbacks. http://b/11463182
    ALOGW("Falling back from %s to %s after dlopen error: %s",
          library, kLibraryFallback, GetError().c_str());
    library = kLibraryFallback;
    handle_ = OpenLibrary(library);
    if (handle_ == NULL) {
      ALOGE("Failed to dlopen %s: %s", library, GetError().c_str());
      return false;
    }
  }
  if (!FindSymbol(reinterpret_cast<FUNC_POINTER*>(&JNI_GetDefaultJavaVMInitArgs_),
                  "JNI_GetDefaultJavaVMInitArgs")) {
    return false;
  }
  if (!FindSymbol(reinterpret_cast<FUNC_POINTER*>(&JNI_CreateJavaVM_),
                  "JNI_CreateJavaVM")) {
    return false;
  }
  if (!FindSymbol(reinterpret_cast<FUNC_POINTER*>(&JNI_GetCreatedJavaVMs_),
                  "JNI_GetCreatedJavaVMs")) {
    return false;
  }
  return true;
}

jint JniInvocationImpl::JNI_GetDefaultJavaVMInitArgs(void* vmargs) {
  return JNI_GetDefaultJavaVMInitArgs_(vmargs);
}

jint JniInvocationImpl::JNI_CreateJavaVM(JavaVM** p_vm, JNIEnv** p_env, void* vm_args) {
  return JNI_CreateJavaVM_(p_vm, p_env, vm_args);
}

jint JniInvocationImpl::JNI_GetCreatedJavaVMs(JavaVM** vms, jsize size, jsize* vm_count) {
  return JNI_GetCreatedJavaVMs_(vms, size, vm_count);
}

bool JniInvocationImpl::FindSymbol(FUNC_POINTER* pointer, const char* symbol) {
  *pointer = GetSymbol(handle_, symbol);
  if (*pointer == NULL) {
    ALOGE("Failed to find symbol %s: %s\n", symbol, GetError().c_str());
    CloseLibrary(handle_);
    handle_ = NULL;
    return false;
  }
  return true;
}

JniInvocationImpl& JniInvocationImpl::GetJniInvocation() {
  LOG_ALWAYS_FATAL_IF(jni_invocation_ == NULL,
                      "Failed to create JniInvocation instance before using JNI invocation API");
  return *jni_invocation_;
}

bool JniInvocationImpl::IsInitialized() {
  return jni_invocation_ != nullptr;
}

jint JNI_GetDefaultJavaVMInitArgs(void* vm_args) {
  return JniInvocationImpl::GetJniInvocation().JNI_GetDefaultJavaVMInitArgs(vm_args);
}

jint JNI_CreateJavaVM(JavaVM** p_vm, JNIEnv** p_env, void* vm_args) {
  // Ensure any cached heap objects from previous VM instances are
  // invalidated. There is no notification here that a VM is destroyed. These
  // cached objects limit us to one VM instance per process.
  JniConstants::Uninitialize();
  return JniInvocationImpl::GetJniInvocation().JNI_CreateJavaVM(p_vm, p_env, vm_args);
}

jint JNI_GetCreatedJavaVMs(JavaVM** vms, jsize size, jsize* vm_count) {
  if (!JniInvocationImpl::IsInitialized()) {
    *vm_count = 0;
    return JNI_OK;
  }
  return JniInvocationImpl::GetJniInvocation().JNI_GetCreatedJavaVMs(vms, size, vm_count);
}

const char* JniInvocation::GetLibrary(const char* library,
                                      char* buffer,
                                      bool (*is_debuggable)(),
                                      int (*get_library_system_property)(char* buffer)) {
  return JniInvocationImpl::GetLibrary(library, buffer, is_debuggable, get_library_system_property);
}

JniInvocationImpl* JniInvocationCreate() {
  return new JniInvocationImpl();
}

void JniInvocationDestroy(JniInvocationImpl* instance) {
  delete instance;
}

int JniInvocationInit(JniInvocationImpl* instance, const char* library) {
  return instance->Init(library) ? 1 : 0;
}

const char* JniInvocationGetLibrary(const char* library, char* buffer) {
  return JniInvocationImpl::GetLibrary(library, buffer);
}
