// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Implements the crazy linker C-based API exposed by <crazy_linker.h>

#include <crazy_linker.h>

#include <string.h>

#include "crazy_linker_ashmem.h"
#include "crazy_linker_error.h"
#include "crazy_linker_globals.h"
#include "crazy_linker_library_view.h"
#include "crazy_linker_proc_maps.h"
#include "crazy_linker_search_path_list.h"
#include "crazy_linker_shared_library.h"
#include "crazy_linker_system.h"
#include "crazy_linker_thread_data.h"
#include "crazy_linker_util.h"

using crazy::Globals;
using crazy::Error;
using crazy::RDebug;
using crazy::SearchPathList;
using crazy::ScopedLockedGlobals;
using crazy::LibraryView;

//
// crazy_context_t
//

struct crazy_context_t {
  size_t load_address = 0;
  Error error;
};

//
// API functions
//

extern "C" {

crazy_context_t* crazy_context_create() {
  return new crazy_context_t();
}

const char* crazy_context_get_error(crazy_context_t* context) {
  const char* error = context->error.c_str();
  return (error[0] != '\0') ? error : NULL;
}

// Clear error in a given context.
void crazy_context_clear_error(crazy_context_t* context) {
  context->error = "";
}

void crazy_context_set_load_address(crazy_context_t* context,
                                    size_t load_address) {
  context->load_address = load_address;
}

size_t crazy_context_get_load_address(crazy_context_t* context) {
  return context->load_address;
}

void crazy_context_destroy(crazy_context_t* context) {
  delete context;
}

void crazy_set_java_vm(void* java_vm, int minimum_jni_version) {
  ScopedLockedGlobals globals;
  globals->InitJavaVm(java_vm, minimum_jni_version);
}

void crazy_get_java_vm(void** java_vm, int* minimum_jni_version) {
  ScopedLockedGlobals globals;
  *java_vm = globals->java_vm();
  *minimum_jni_version = globals->minimum_jni_version();
}

crazy_status_t crazy_add_search_path(const char* file_path) {
  ScopedLockedGlobals globals;
  globals->search_path_list()->AddPaths(file_path);
  return CRAZY_STATUS_SUCCESS;
}

crazy_status_t crazy_add_search_path_for_address(void* address) {
  uintptr_t load_address;
  char path[512];
  char* p;

  if (crazy::FindElfBinaryForAddress(
          address, &load_address, path, sizeof(path)) &&
      (p = strrchr(path, '/')) != NULL && p[1]) {
    *p = '\0';
    return crazy_add_search_path(path);
  }

  return CRAZY_STATUS_FAILURE;
}

void crazy_reset_search_paths(void) {
  ScopedLockedGlobals globals;
  globals->search_path_list()->ResetFromEnv("LD_LIBRARY_PATH");
}

crazy_status_t crazy_library_open(crazy_library_t** library,
                                  const char* lib_name,
                                  crazy_context_t* context) {
  ScopedLockedGlobals globals;
  LibraryView* view = globals->libraries()->LoadLibrary(
      lib_name, context->load_address, globals->search_path_list(),
      &context->error);

  if (!view)
    return CRAZY_STATUS_FAILURE;

  *library = reinterpret_cast<crazy_library_t*>(view);
  return CRAZY_STATUS_SUCCESS;
}

crazy_status_t crazy_library_get_info(crazy_library_t* library,
                                      crazy_context_t* context,
                                      crazy_library_info_t* info) {
  if (!library) {
    context->error = "Invalid library file handle";
    return CRAZY_STATUS_FAILURE;
  }

  LibraryView* wrap = reinterpret_cast<LibraryView*>(library);
  if (!wrap->GetInfo(&info->load_address,
                     &info->load_size,
                     &info->relro_start,
                     &info->relro_size,
                     &context->error)) {
    return CRAZY_STATUS_FAILURE;
  }

  return CRAZY_STATUS_SUCCESS;
}

crazy_status_t crazy_library_create_shared_relro(crazy_library_t* library,
                                                 crazy_context_t* context,
                                                 size_t load_address,
                                                 size_t* relro_start,
                                                 size_t* relro_size,
                                                 int* relro_fd) {
  LibraryView* wrap = reinterpret_cast<LibraryView*>(library);

  if (!library || !wrap->IsCrazy()) {
    context->error = "Invalid library file handle";
    return CRAZY_STATUS_FAILURE;
  }

  crazy::SharedLibrary* lib = wrap->GetCrazy();
  if (!lib->CreateSharedRelro(
           load_address, relro_start, relro_size, relro_fd, &context->error))
    return CRAZY_STATUS_FAILURE;

  return CRAZY_STATUS_SUCCESS;
}

crazy_status_t crazy_library_use_shared_relro(crazy_library_t* library,
                                              crazy_context_t* context,
                                              size_t relro_start,
                                              size_t relro_size,
                                              int relro_fd) {
  LibraryView* wrap = reinterpret_cast<LibraryView*>(library);

  if (!library || !wrap->IsCrazy()) {
    context->error = "Invalid library file handle";
    return CRAZY_STATUS_FAILURE;
  }

  crazy::SharedLibrary* lib = wrap->GetCrazy();
  if (!lib->UseSharedRelro(relro_start, relro_size, relro_fd, &context->error))
    return CRAZY_STATUS_FAILURE;

  return CRAZY_STATUS_SUCCESS;
}

crazy_status_t crazy_library_find_by_name(const char* library_name,
                                          crazy_library_t** library) {
  {
    ScopedLockedGlobals globals;
    LibraryView* wrap = globals->libraries()->FindLibraryByName(library_name);
    if (!wrap)
      return CRAZY_STATUS_FAILURE;

    wrap->AddRef();
    *library = reinterpret_cast<crazy_library_t*>(wrap);
  }
  return CRAZY_STATUS_SUCCESS;
}

crazy_status_t crazy_library_find_symbol(crazy_library_t* library,
                                         const char* symbol_name,
                                         void** symbol_address) {
  LibraryView* wrap = reinterpret_cast<LibraryView*>(library);

  // TODO(digit): Handle NULL symbols properly.
  LibraryView::SearchResult sym = wrap->LookupSymbol(symbol_name);
  *symbol_address = sym.address;
  return sym.IsValid() ? CRAZY_STATUS_SUCCESS : CRAZY_STATUS_FAILURE;
}

crazy_status_t crazy_linker_find_symbol(const char* symbol_name,
                                        void** symbol_address) {
  // TODO(digit): Implement this.
  return CRAZY_STATUS_FAILURE;
}

crazy_status_t crazy_library_find_from_address(void* address,
                                               crazy_library_t** library) {
  {
    ScopedLockedGlobals globals;
    LibraryView* wrap = globals->libraries()->FindLibraryForAddress(address);
    if (!wrap)
      return CRAZY_STATUS_FAILURE;

    wrap->AddRef();

    *library = reinterpret_cast<crazy_library_t*>(wrap);
    return CRAZY_STATUS_SUCCESS;
  }
}

void crazy_library_close(crazy_library_t* library) {
  crazy_library_close_with_context(library, NULL);
}

void crazy_library_close_with_context(crazy_library_t* library,
                                      crazy_context_t* context) {
  if (library) {
    ScopedLockedGlobals globals;
    LibraryView* wrap = reinterpret_cast<LibraryView*>(library);

    globals->libraries()->UnloadLibrary(wrap);
  }
}

}  // extern "C"
