// Copyright 2015 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.

// This is the version of the Android-specific Chromium linker that uses
// the Android M and later system linker to load libraries.

// This source code *cannot* depend on anything from base/ or the C++
// STL, to keep the final library small, and avoid ugly dependency issues.

#include "modern_linker_jni.h"

#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <dlfcn.h>
#include <errno.h>
#include <fcntl.h>
#include <jni.h>
#include <limits.h>
#include <link.h>
#include <string.h>

#include "android_dlext.h"
#include "linker_jni.h"

#define PAGE_START(x) ((x) & PAGE_MASK)
#define PAGE_END(x) PAGE_START((x) + (PAGE_SIZE - 1))

namespace chromium_android_linker {
namespace {

// Record of the Java VM passed to JNI_OnLoad().
static JavaVM* s_java_vm = nullptr;

// Get the CPU ABI string for which the linker is running.
//
// The returned string is used to construct the path to libchrome.so when
// loading directly from APK.
//
// |env| is the current JNI environment handle.
// |clazz| is the static class handle for org.chromium.base.Linker,
// and is ignored here.
// Returns the CPU ABI string for which the linker is running.
jstring GetCpuAbi(JNIEnv* env, jclass clazz) {
#if defined(__arm__) && defined(__ARM_ARCH_7A__)
  static const char* kCurrentAbi = "armeabi-v7a";
#elif defined(__arm__)
  static const char* kCurrentAbi = "armeabi";
#elif defined(__i386__)
  static const char* kCurrentAbi = "x86";
#elif defined(__mips__)
  static const char* kCurrentAbi = "mips";
#elif defined(__x86_64__)
  static const char* kCurrentAbi = "x86_64";
#elif defined(__aarch64__)
  static const char* kCurrentAbi = "arm64-v8a";
#else
#error "Unsupported target abi"
#endif
  return env->NewStringUTF(kCurrentAbi);
}

// Convenience wrapper around dlsym() on the main executable. Returns
// the address of the requested symbol, or nullptr if not found. Status
// is available from dlerror().
void* Dlsym(const char* symbol_name) {
  static void* handle = nullptr;

  if (!handle)
    handle = dlopen(nullptr, RTLD_NOW);

  void* result = dlsym(handle, symbol_name);
  return result;
}

// dl_iterate_phdr() wrapper, accessed via dlsym lookup. Done this way.
// so that this code compiles for Android versions that are too early to
// offer it. Checks in LibraryLoader.java should ensure that we
// never reach here at runtime on Android versions that are too old to
// supply dl_iterate_phdr; that is, earlier than Android M. Returns
// false if no dl_iterate_phdr() is available, otherwise true with the
// return value from dl_iterate_phdr() in |status|.
bool DlIteratePhdr(int (*callback)(dl_phdr_info*, size_t, void*),
                   void* data,
                   int* status) {
  using DlIteratePhdrCallback = int (*)(dl_phdr_info*, size_t, void*);
  using DlIteratePhdrFunctionPtr = int (*)(DlIteratePhdrCallback, void*);
  static DlIteratePhdrFunctionPtr function_ptr = nullptr;

  if (!function_ptr) {
    function_ptr =
        reinterpret_cast<DlIteratePhdrFunctionPtr>(Dlsym("dl_iterate_phdr"));
    if (!function_ptr) {
      LOG_ERROR("dlsym: dl_iterate_phdr: %s", dlerror());
      return false;
    }
  }

  *status = (*function_ptr)(callback, data);
  return true;
}

// Convenience struct wrapper round android_dlextinfo.
struct AndroidDlextinfo {
  AndroidDlextinfo(int flags,
                   void* reserved_addr, size_t reserved_size, int relro_fd) {
    memset(&extinfo, 0, sizeof(extinfo));
    extinfo.flags = flags;
    extinfo.reserved_addr = reserved_addr;
    extinfo.reserved_size = reserved_size;
    extinfo.relro_fd = relro_fd;
  }

  android_dlextinfo extinfo;
};

// android_dlopen_ext() wrapper, accessed via dlsym lookup. Returns false
// if no android_dlopen_ext() is available, otherwise true with the return
// value from android_dlopen_ext() in |status|.
bool AndroidDlopenExt(const char* filename,
                      int flag,
                      const AndroidDlextinfo* dlextinfo,
                      void** status) {
  using DlopenExtFunctionPtr = void* (*)(const char*,
                                         int, const android_dlextinfo*);
  static DlopenExtFunctionPtr function_ptr = nullptr;

  if (!function_ptr) {
    function_ptr =
        reinterpret_cast<DlopenExtFunctionPtr>(Dlsym("android_dlopen_ext"));
    if (!function_ptr) {
      LOG_ERROR("dlsym: android_dlopen_ext: %s", dlerror());
      return false;
    }
  }

  const android_dlextinfo* extinfo = &dlextinfo->extinfo;
  LOG_INFO("android_dlopen_ext:"
           " flags=0x%llx, reserved_addr=%p, reserved_size=%d, relro_fd=%d",
           static_cast<long long>(extinfo->flags),
           extinfo->reserved_addr,
           static_cast<int>(extinfo->reserved_size),
           extinfo->relro_fd);

  *status = (*function_ptr)(filename, flag, extinfo);
  return true;
}

// Callback data for FindLoadedLibrarySize().
struct CallbackData {
  explicit CallbackData(void* address)
      : load_address(address), load_size(0), min_vaddr(0) { }

  const void* load_address;
  size_t load_size;
  size_t min_vaddr;
};

// Callback for dl_iterate_phdr(). Read phdrs to identify whether or not
// this library's load address matches the |load_address| passed in
// |data|. If yes, pass back load size and min vaddr via |data|. A non-zero
// return value terminates iteration.
int FindLoadedLibrarySize(dl_phdr_info* info, size_t size UNUSED, void* data) {
  CallbackData* callback_data = reinterpret_cast<CallbackData*>(data);

  // Use max and min vaddr to compute the library's load size.
  ElfW(Addr) min_vaddr = ~0;
  ElfW(Addr) max_vaddr = 0;

  bool is_matching = false;
  for (size_t i = 0; i < info->dlpi_phnum; ++i) {
    const ElfW(Phdr)* phdr = &info->dlpi_phdr[i];
    if (phdr->p_type != PT_LOAD)
      continue;

    // See if this segment's load address matches what we passed to
    // android_dlopen_ext as extinfo.reserved_addr.
    void* load_addr = reinterpret_cast<void*>(info->dlpi_addr + phdr->p_vaddr);
    if (load_addr == callback_data->load_address)
      is_matching = true;

    if (phdr->p_vaddr < min_vaddr)
      min_vaddr = phdr->p_vaddr;
    if (phdr->p_vaddr + phdr->p_memsz > max_vaddr)
      max_vaddr = phdr->p_vaddr + phdr->p_memsz;
  }

  // If this library matches what we seek, return its load size.
  if (is_matching) {
    callback_data->load_size = PAGE_END(max_vaddr) - PAGE_START(min_vaddr);
    callback_data->min_vaddr = min_vaddr;
    return true;
  }

  return false;
}

// Helper class for anonymous memory mapping.
class ScopedAnonymousMmap {
 public:
  ScopedAnonymousMmap(void* addr, size_t size);

  ~ScopedAnonymousMmap() { munmap(addr_, size_); }

  void* GetAddr() const { return effective_addr_; }
  void Release() { addr_ = nullptr; size_ = 0; effective_addr_ = nullptr; }

 private:
  void* addr_;
  size_t size_;

  // The effective_addr_ is the address seen by client code. It may or may
  // not be the same as addr_, the real start of the anonymous mapping.
  void* effective_addr_;
};

// ScopedAnonymousMmap constructor. |addr| is a requested mapping address, or
// zero if any address will do, and |size| is the size of mapping required.
ScopedAnonymousMmap::ScopedAnonymousMmap(void* addr, size_t size) {
#if RESERVE_BREAKPAD_GUARD_REGION
  // Increase size to extend the address reservation mapping so that it will
  // also include a guard region from load_bias_ to start_addr. If loading
  // at a fixed address, move our requested address back by the guard region
  // size.
  size += kBreakpadGuardRegionBytes;
  if (addr) {
    if (addr < reinterpret_cast<void*>(kBreakpadGuardRegionBytes)) {
      LOG_ERROR("Fixed address %p is too low to accommodate Breakpad guard",
                addr);
      addr_ = MAP_FAILED;
      size_ = 0;
      return;
    }
    addr = reinterpret_cast<void*>(
        reinterpret_cast<uintptr_t>(addr) - kBreakpadGuardRegionBytes);
  }
  LOG_INFO("Added %d to size, for Breakpad guard",
           static_cast<int>(kBreakpadGuardRegionBytes));
#endif

  addr_ = mmap(addr, size, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
  if (addr_ != MAP_FAILED) {
    size_ = size;
  } else {
    LOG_INFO("mmap failed: %s", strerror(errno));
    size_ = 0;
  }
  effective_addr_ = addr_;

#if RESERVE_BREAKPAD_GUARD_REGION
  // If we increased size to accommodate a Breakpad guard region, move
  // the effective address, if valid, upwards by the size of the guard region.
  if (addr_ == MAP_FAILED)
    return;
  if (addr_ < reinterpret_cast<void*>(kBreakpadGuardRegionBytes)) {
    LOG_ERROR("Map address %p is too low to accommodate Breakpad guard",
              addr_);
    effective_addr_ = MAP_FAILED;
  } else {
    effective_addr_ = reinterpret_cast<void*>(
        reinterpret_cast<uintptr_t>(addr_) + kBreakpadGuardRegionBytes);
  }
#endif
}

// Helper for LoadLibrary(). Return the actual size of the library loaded
// at |addr| in |load_size|, and the min vaddr in |min_vaddr|. Returns false
// if the library appears not to be loaded.
bool GetLibraryLoadSize(void* addr, size_t* load_size, size_t* min_vaddr) {
  LOG_INFO("Called for %p", addr);

  // Find the real load size and min vaddr for the library loaded at |addr|.
  CallbackData callback_data(addr);
  int status = 0;
  if (!DlIteratePhdr(&FindLoadedLibrarySize, &callback_data, &status)) {
    LOG_ERROR("No dl_iterate_phdr function found");
    return false;
  }
  if (!status) {
    LOG_ERROR("Failed to find library at address %p", addr);
    return false;
  }

  *load_size = callback_data.load_size;
  *min_vaddr = callback_data.min_vaddr;
  return true;
}

// Helper for LoadLibrary(). We reserve an address space larger than
// needed. After library loading we want to trim that reservation to only
// what is needed.
bool ResizeReservedAddressSpace(void* addr,
                                size_t reserved_size,
                                size_t load_size,
                                size_t min_vaddr) {
  LOG_INFO("Called for %p, reserved %d, loaded %d, min_vaddr %d",
           addr, static_cast<int>(reserved_size),
           static_cast<int>(load_size), static_cast<int>(min_vaddr));

  const uintptr_t uintptr_addr = reinterpret_cast<uintptr_t>(addr);

  if (reserved_size < load_size) {
    LOG_ERROR("WARNING: library reservation was too small");
    return true;
  }

  // Unmap the part of the reserved address space that is beyond the end of
  // the loaded library data.
  void* unmap = reinterpret_cast<void*>(uintptr_addr + load_size);
  size_t length = reserved_size - load_size;
  if (munmap(unmap, length) == -1) {
    LOG_ERROR("Failed to unmap %d at %p", static_cast<int>(length), unmap);
    return false;
  }

#if RESERVE_BREAKPAD_GUARD_REGION
  if (min_vaddr > kBreakpadGuardRegionBytes) {
    LOG_ERROR("WARNING: breakpad guard region reservation was too small");
    return true;
  }

  // Unmap the part of the reserved address space that is ahead of where we
  // actually need the guard region to start. Resizes the guard region to
  // min_vaddr bytes.
  unmap = reinterpret_cast<void*>(uintptr_addr - kBreakpadGuardRegionBytes);
  length = kBreakpadGuardRegionBytes - min_vaddr;
  if (munmap(unmap, length) == -1) {
    LOG_ERROR("Failed to unmap %d at %p", static_cast<int>(length), unmap);
    return false;
  }
#endif

  return true;
}

// Load a library with the chromium linker, using android_dlopen_ext().
//
// android_dlopen_ext() understands how to directly load from a zipfile,
// based on the format of |dlopen_ext_path|. If it contains a "!/" separator
// then the string indicates <zip_path>!/<file_path> and indicates the
// file_path element within the zip file at zip_path. A library in a
// zipfile must be uncompressed and page aligned. The library is expected
// to be lib/<abi_tag>/crazy.<basename>. The <abi_tag> used will be the
// same as the abi for this linker. The "crazy." prefix is included
// so that the Android Package Manager doesn't extract the library into
// /data/app-lib.
//
// If |dlopen_ext_path| contains no "!/" separator then android_dlopen_ext()
// assumes that it is a normal path to a standalone library file.
//
// Loading the library will also call its JNI_OnLoad() method, which
// shall register its methods. Note that lazy native method resolution
// will _not_ work after this, because Dalvik uses the system's dlsym()
// which won't see the new library, so explicit registration is mandatory.
//
// |env| is the current JNI environment handle.
// |clazz| is the static class handle for org.chromium.base.Linker,
// and is ignored here.
// |dlopen_ext_path| is the library identifier (e.g. libfoo.so).
// |load_address| is an explicit load address.
// |relro_path| is the path to the file into which RELRO data is held.
// |lib_info_obj| is a LibInfo handle used to communicate information
// with the Java side.
// Return true on success.
jboolean LoadLibrary(JNIEnv* env,
                     jclass clazz,
                     jstring dlopen_ext_path,
                     jlong load_address,
                     jobject lib_info_obj) {
  String dlopen_library_path(env, dlopen_ext_path);
  LOG_INFO("Called for %s, at address 0x%llx",
           dlopen_library_path.c_str(), load_address);

  if (!IsValidAddress(load_address)) {
    LOG_ERROR("Invalid address 0x%llx", load_address);
    return false;
  }

  const size_t size = kAddressSpaceReservationSize;
  void* wanted_addr = reinterpret_cast<void*>(load_address);

  // Reserve the address space into which we load the library.
  ScopedAnonymousMmap mapping(wanted_addr, size);
  void* addr = mapping.GetAddr();
  if (addr == MAP_FAILED) {
    LOG_ERROR("Failed to reserve space for load");
    return false;
  }
  if (wanted_addr && addr != wanted_addr) {
    LOG_ERROR("Failed to obtain fixed address for load");
    return false;
  }

  // Build dlextinfo to load the library into the reserved space, using
  // the shared RELRO if supplied and if its start address matches addr.
  int relro_fd = -1;
  int flags = ANDROID_DLEXT_RESERVED_ADDRESS;
  if (wanted_addr && lib_info_obj) {
    void* relro_start;
    s_lib_info_fields.GetRelroInfo(env, lib_info_obj,
                                   reinterpret_cast<size_t*>(&relro_start),
                                   nullptr, &relro_fd);
    if (relro_fd != -1 && relro_start == addr) {
      flags |= ANDROID_DLEXT_USE_RELRO;
    }
  }
  AndroidDlextinfo dlextinfo(flags, addr, size, relro_fd);

  // Load the library into the reserved space.
  const char* path = dlopen_library_path.c_str();
  void* handle = nullptr;
  if (!AndroidDlopenExt(path, RTLD_NOW, &dlextinfo, &handle)) {
    LOG_ERROR("No android_dlopen_ext function found");
    return false;
  }
  if (handle == nullptr) {
    LOG_ERROR("android_dlopen_ext: %s", dlerror());
    return false;
  }

  // After loading, trim the mapping to match the library's actual size.
  size_t load_size = 0;
  size_t min_vaddr = 0;
  if (!GetLibraryLoadSize(addr, &load_size, &min_vaddr)) {
    LOG_ERROR("Unable to find size for load at %p", addr);
    return false;
  }
  if (!ResizeReservedAddressSpace(addr, size, load_size, min_vaddr)) {
    LOG_ERROR("Unable to resize reserved address mapping");
    return false;
  }

  // Locate and if found then call the loaded library's JNI_OnLoad() function.
  using JNI_OnLoadFunctionPtr = int (*)(void* vm, void* reserved);
  auto jni_onload =
      reinterpret_cast<JNI_OnLoadFunctionPtr>(dlsym(handle, "JNI_OnLoad"));
  if (jni_onload != nullptr) {
    // Check that JNI_OnLoad returns a usable JNI version.
    int jni_version = (*jni_onload)(s_java_vm, nullptr);
    if (jni_version < JNI_VERSION_1_4) {
      LOG_ERROR("JNI version is invalid: %d", jni_version);
      return false;
    }
  }

  // Release mapping before returning so that we do not unmap reserved space.
  mapping.Release();

  // Note the load address and load size in the supplied libinfo object.
  const size_t cast_addr = reinterpret_cast<size_t>(addr);
  s_lib_info_fields.SetLoadInfo(env, lib_info_obj, cast_addr, load_size);

  LOG_INFO("Success loading library %s", dlopen_library_path.c_str());
  return true;
}

// Create a shared RELRO file for a library, using android_dlopen_ext().
//
// Loads the library similarly to LoadLibrary() above, by reserving address
// space and then using android_dlopen_ext() to load into the reserved
// area. Adds flags to android_dlopen_ext() to saved the library's RELRO
// memory into the given file path, then unload the library and returns.
//
// Does not call JNI_OnLoad() or otherwise execute any code from the library.
//
// |env| is the current JNI environment handle.
// |clazz| is the static class handle for org.chromium.base.Linker,
// and is ignored here.
// |dlopen_ext_path| is the library identifier (e.g. libfoo.so).
// |load_address| is an explicit load address.
// |relro_path| is the path to the file into which RELRO data is written.
// |lib_info_obj| is a LibInfo handle used to communicate information
// with the Java side.
// Return true on success.
jboolean CreateSharedRelro(JNIEnv* env,
                           jclass clazz,
                           jstring dlopen_ext_path,
                           jlong load_address,
                           jstring relro_path,
                           jobject lib_info_obj) {
  String dlopen_library_path(env, dlopen_ext_path);
  LOG_INFO("Called for %s, at address 0x%llx",
           dlopen_library_path.c_str(), load_address);

  if (!IsValidAddress(load_address) || load_address == 0) {
    LOG_ERROR("Invalid address 0x%llx", load_address);
    return false;
  }

  const size_t size = kAddressSpaceReservationSize;
  void* wanted_addr = reinterpret_cast<void*>(load_address);

  // Reserve the address space into which we load the library.
  ScopedAnonymousMmap mapping(wanted_addr, size);
  void* addr = mapping.GetAddr();
  if (addr == MAP_FAILED) {
    LOG_ERROR("Failed to reserve space for load");
    return false;
  }
  if (addr != wanted_addr) {
    LOG_ERROR("Failed to obtain fixed address for load");
    return false;
  }

  // Open the shared RELRO file for write. Overwrites any prior content.
  String shared_relro_path(env, relro_path);
  const char* filepath = shared_relro_path.c_str();
  unlink(filepath);
  int relro_fd = open(filepath, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);
  if (relro_fd == -1) {
    LOG_ERROR("open: %s: %s", filepath, strerror(errno));
    return false;
  }

  // Use android_dlopen_ext() to create the shared RELRO.
  const int flags = ANDROID_DLEXT_RESERVED_ADDRESS
                    | ANDROID_DLEXT_WRITE_RELRO;
  AndroidDlextinfo dlextinfo(flags, addr, size, relro_fd);

  const char* path = dlopen_library_path.c_str();
  void* handle = nullptr;
  if (!AndroidDlopenExt(path, RTLD_NOW, &dlextinfo, &handle)) {
    LOG_ERROR("No android_dlopen_ext function found");
    close(relro_fd);
    return false;
  }
  if (handle == nullptr) {
    LOG_ERROR("android_dlopen_ext: %s", dlerror());
    close(relro_fd);
    return false;
  }

  // Unload the library from this address. The reserved space is
  // automatically unmapped on exit from this function.
  dlclose(handle);

  // Reopen the shared RELFO fd in read-only mode. This ensures that nothing
  // can write to it through the RELRO fd that we return in libinfo.
  close(relro_fd);
  relro_fd = open(filepath, O_RDONLY);
  if (relro_fd == -1) {
    LOG_ERROR("open: %s: %s", filepath, strerror(errno));
    return false;
  }

  // Delete the directory entry for the RELRO file. The fd we hold ensures
  // that its data remains intact.
  if (unlink(filepath) == -1) {
    LOG_ERROR("unlink: %s: %s", filepath, strerror(errno));
    return false;
  }

  // Note the shared RELRO fd in the supplied libinfo object. In this
  // implementation the RELRO start is set to the library's load address,
  // and the RELRO size is unused.
  const size_t cast_addr = reinterpret_cast<size_t>(addr);
  s_lib_info_fields.SetRelroInfo(env, lib_info_obj, cast_addr, 0, relro_fd);

  LOG_INFO("Success creating shared RELRO %s", shared_relro_path.c_str());
  return true;
}

const JNINativeMethod kNativeMethods[] = {
    {"nativeGetCpuAbi",
     "("
     ")"
     "Ljava/lang/String;",
     reinterpret_cast<void*>(&GetCpuAbi)},
    {"nativeLoadLibrary",
     "("
     "Ljava/lang/String;"
     "J"
     "Lorg/chromium/base/library_loader/Linker$LibInfo;"
     ")"
     "Z",
     reinterpret_cast<void*>(&LoadLibrary)},
    {"nativeCreateSharedRelro",
     "("
     "Ljava/lang/String;"
     "J"
     "Ljava/lang/String;"
     "Lorg/chromium/base/library_loader/Linker$LibInfo;"
     ")"
     "Z",
     reinterpret_cast<void*>(&CreateSharedRelro)},
};

}  // namespace

bool ModernLinkerJNIInit(JavaVM* vm, JNIEnv* env) {
  LOG_INFO("Entering");

  // Register native methods.
  jclass linker_class;
  if (!InitClassReference(env,
                          "org/chromium/base/library_loader/ModernLinker",
                          &linker_class))
    return false;

  LOG_INFO("Registering native methods");
  env->RegisterNatives(linker_class,
                       kNativeMethods,
                       sizeof(kNativeMethods) / sizeof(kNativeMethods[0]));

  // Record the Java VM handle.
  s_java_vm = vm;

  return true;
}

}  // namespace chromium_android_linker
