/*
 * Copyright (C) 2019 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.
 */

#if defined(ART_TARGET_ANDROID)

#define LOG_TAG "nativeloader"

#include "native_loader_namespace.h"

#include <dlfcn.h>

#include <functional>

#include <android-base/strings.h>
#include <log/log.h>
#include <nativebridge/native_bridge.h>

#include "nativeloader/dlext_namespaces.h"

using android::base::Error;

namespace android {

namespace {

constexpr const char* kDefaultNamespaceName = "default";
constexpr const char* kSystemNamespaceName = "system";

std::string GetLinkerError(bool is_bridged) {
  const char* msg = is_bridged ? NativeBridgeGetError() : dlerror();
  if (msg == nullptr) {
    return "no error";
  }
  return std::string(msg);
}

}  // namespace

Result<NativeLoaderNamespace> NativeLoaderNamespace::GetExportedNamespace(const std::string& name,
                                                                          bool is_bridged) {
  if (!is_bridged) {
    android_namespace_t* raw = android_get_exported_namespace(name.c_str());
    if (raw != nullptr) {
      return NativeLoaderNamespace(name, raw);
    }
  } else {
    native_bridge_namespace_t* raw = NativeBridgeGetExportedNamespace(name.c_str());
    if (raw != nullptr) {
      return NativeLoaderNamespace(name, raw);
    }
  }
  return Errorf("namespace {} does not exist or exported", name);
}

// The system namespace is called "default" for binaries in /system and
// "system" for those in the Runtime APEX. Try "system" first since
// "default" always exists.
Result<NativeLoaderNamespace> NativeLoaderNamespace::GetSystemNamespace(bool is_bridged) {
  if (Result<NativeLoaderNamespace> ns = GetExportedNamespace(kSystemNamespaceName, is_bridged);
      ns.ok()) {
    return ns;
  }
  if (Result<NativeLoaderNamespace> ns = GetExportedNamespace(kDefaultNamespaceName, is_bridged);
      ns.ok()) {
    return ns;
  }

  // If nothing is found, return NativeLoaderNamespace constructed from nullptr.
  // nullptr also means default namespace to the linker.
  if (!is_bridged) {
    return NativeLoaderNamespace(kDefaultNamespaceName, static_cast<android_namespace_t*>(nullptr));
  } else {
    return NativeLoaderNamespace(kDefaultNamespaceName,
                                 static_cast<native_bridge_namespace_t*>(nullptr));
  }
}

Result<NativeLoaderNamespace> NativeLoaderNamespace::Create(
    const std::string& name, const std::string& search_paths, const std::string& permitted_paths,
    const NativeLoaderNamespace* parent, bool is_shared, bool is_exempt_list_enabled,
    bool also_used_as_anonymous) {
  bool is_bridged = false;
  if (parent != nullptr) {
    is_bridged = parent->IsBridged();
  } else if (!search_paths.empty()) {
    is_bridged = NativeBridgeIsPathSupported(search_paths.c_str());
  }

  // Fall back to the system namespace if no parent is set.
  Result<NativeLoaderNamespace> system_ns = GetSystemNamespace(is_bridged);
  if (!system_ns.ok()) {
    return system_ns.error();
  }
  const NativeLoaderNamespace& effective_parent = parent != nullptr ? *parent : *system_ns;

  // All namespaces for apps are isolated
  uint64_t type = ANDROID_NAMESPACE_TYPE_ISOLATED;

  // The namespace is also used as the anonymous namespace
  // which is used when the linker fails to determine the caller address
  if (also_used_as_anonymous) {
    type |= ANDROID_NAMESPACE_TYPE_ALSO_USED_AS_ANONYMOUS;
  }

  // Bundled apps have access to all system libraries that are currently loaded
  // in the default namespace
  if (is_shared) {
    type |= ANDROID_NAMESPACE_TYPE_SHARED;
  }
  if (is_exempt_list_enabled) {
    type |= ANDROID_NAMESPACE_TYPE_EXEMPT_LIST_ENABLED;
  }

  if (!is_bridged) {
    android_namespace_t* raw =
        android_create_namespace(name.c_str(), nullptr, search_paths.c_str(), type,
                                 permitted_paths.c_str(), effective_parent.ToRawAndroidNamespace());
    if (raw != nullptr) {
      return NativeLoaderNamespace(name, raw);
    }
  } else {
    native_bridge_namespace_t* raw = NativeBridgeCreateNamespace(
        name.c_str(), nullptr, search_paths.c_str(), type, permitted_paths.c_str(),
        effective_parent.ToRawNativeBridgeNamespace());
    if (raw != nullptr) {
      return NativeLoaderNamespace(name, raw);
    }
  }
  return Errorf("failed to create {} namespace name:{}, search_paths:{}, permitted_paths:{}",
                is_bridged ? "bridged" : "native", name, search_paths, permitted_paths);
}

Result<void> NativeLoaderNamespace::Link(const NativeLoaderNamespace* target,
                                         const std::string& shared_libs) const {
  LOG_ALWAYS_FATAL_IF(shared_libs.empty(), "empty share lib when linking %s to %s",
                      this->name().c_str(), target == nullptr ? "default" : target->name().c_str());
  if (!IsBridged()) {
    if (android_link_namespaces(this->ToRawAndroidNamespace(),
                                target == nullptr ? nullptr : target->ToRawAndroidNamespace(),
                                shared_libs.c_str())) {
      return {};
    }
  } else {
    if (NativeBridgeLinkNamespaces(this->ToRawNativeBridgeNamespace(),
                                   target == nullptr ? nullptr : target->ToRawNativeBridgeNamespace(),
                                   shared_libs.c_str())) {
      return {};
    }
  }
  return Error() << GetLinkerError(IsBridged());
}

Result<void*> NativeLoaderNamespace::Load(const char* lib_name) const {
  if (!IsBridged()) {
    android_dlextinfo extinfo;
    extinfo.flags = ANDROID_DLEXT_USE_NAMESPACE;
    extinfo.library_namespace = this->ToRawAndroidNamespace();
    void* handle = android_dlopen_ext(lib_name, RTLD_NOW, &extinfo);
    if (handle != nullptr) {
      return handle;
    }
  } else {
    void* handle =
        NativeBridgeLoadLibraryExt(lib_name, RTLD_NOW, this->ToRawNativeBridgeNamespace());
    if (handle != nullptr) {
      return handle;
    }
  }
  return Error() << GetLinkerError(IsBridged());
}

}  // namespace android

#endif  // defined(ART_TARGET_ANDROID)
