Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 821b80c4 authored by Nicolas Geoffray's avatar Nicolas Geoffray Committed by android-build-merger
Browse files

Merge "Move to C API of libnativeloader."

am: a88a0fa3

Change-Id: Ib43bcb5a26cedcb454732936eda2c7038bdc4219
parents 263ff671 a88a0fa3
Loading
Loading
Loading
Loading
+16 −0
Original line number Diff line number Diff line
@@ -23,4 +23,20 @@ cc_library {
        "llndk.libraries.txt",
        "vndksp.libraries.txt",
    ],
    target: {
        android: {
            version_script: "libnativeloader.map.txt",
        },
    },
    stubs: {
        symbol_file: "libnativeloader.map.txt",
        versions: ["1"],
    },
}

cc_library_headers {
    name: "libnativeloader-dummy-headers",

    host_supported: true,
    export_include_dirs: ["include"],
}
+7 −9
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@
#define __ANDROID_DLEXT_NAMESPACES_H__

#include <android/dlext.h>
#include <stdbool.h>

__BEGIN_DECLS

@@ -84,12 +85,9 @@ enum {
 * If a library or any of its dependencies are outside of the permitted_when_isolated_path
 * and search_path, and it is not part of the public namespace dlopen will fail.
 */
extern struct android_namespace_t* android_create_namespace(const char* name,
                                                            const char* ld_library_path,
                                                            const char* default_library_path,
                                                            uint64_t type,
                                                            const char* permitted_when_isolated_path,
                                                            android_namespace_t* parent);
extern struct android_namespace_t* android_create_namespace(
    const char* name, const char* ld_library_path, const char* default_library_path, uint64_t type,
    const char* permitted_when_isolated_path, struct android_namespace_t* parent);

/*
 * Creates a link between namespaces. Every link has list of sonames of
@@ -107,8 +105,8 @@ extern struct android_namespace_t* android_create_namespace(const char* name,
 *      step will not go deeper into linked namespaces for this library but
 *      will do so for DT_NEEDED libraries.
 */
extern bool android_link_namespaces(android_namespace_t* from,
                                    android_namespace_t* to,
extern bool android_link_namespaces(struct android_namespace_t* from,
                                    struct android_namespace_t* to,
                                    const char* shared_libs_sonames);

/*
@@ -124,7 +122,7 @@ extern bool android_link_namespaces(android_namespace_t* from,
 */
extern void android_get_LD_LIBRARY_PATH(char* buffer, size_t buffer_size);

extern android_namespace_t* android_get_exported_namespace(const char* name);
extern struct android_namespace_t* android_get_exported_namespace(const char* name);

__END_DECLS

+27 −23
Original line number Diff line number Diff line
@@ -17,14 +17,21 @@
#ifndef NATIVE_LOADER_H_
#define NATIVE_LOADER_H_

#include "jni.h"
#include <stdbool.h>
#include <stdint.h>
#include <string>
#include "jni.h"
#if defined(__ANDROID__)
#include <android/dlext.h>
#endif

#ifdef __cplusplus
namespace android {
extern "C" {
#endif  // __cplusplus

// README: the char** error message parameter being passed
// to the methods below need to be freed through calling NativeLoaderFreeErrorMessage.
// It's the caller's responsibility to call that method.

__attribute__((visibility("default")))
void InitializeNativeLoader();
@@ -38,42 +45,39 @@ jstring CreateClassLoaderNamespace(JNIEnv* env,
                                   jstring library_path,
                                   jstring permitted_path);

__attribute__((visibility("default")))
void* OpenNativeLibrary(JNIEnv* env,
                        int32_t target_sdk_version,
                        const char* path,
                        jobject class_loader,
                        jstring library_path,
                        bool* needs_native_bridge,
                        std::string* error_msg);
__attribute__((visibility("default"))) void* OpenNativeLibrary(
    JNIEnv* env, int32_t target_sdk_version, const char* path, jobject class_loader,
    jstring library_path, bool* needs_native_bridge, char** error_msg);

__attribute__((visibility("default"))) bool CloseNativeLibrary(void* handle,
                                                               const bool needs_native_bridge,
                                                               std::string* error_msg);
                                                               char** error_msg);

__attribute__((visibility("default"))) void NativeLoaderFreeErrorMessage(char* msg);

#if defined(__ANDROID__)
// Look up linker namespace by class_loader. Returns nullptr if
// there is no namespace associated with the class_loader.
// TODO(b/79940628): move users to FindNativeLoaderNamespaceByClassLoader and remove this function.
__attribute__((visibility("default")))
android_namespace_t* FindNamespaceByClassLoader(JNIEnv* env, jobject class_loader);
// That version works with native bridge namespaces, but requires use of OpenNativeLibrary.
class NativeLoaderNamespace;
__attribute__((visibility("default")))
NativeLoaderNamespace* FindNativeLoaderNamespaceByClassLoader(
__attribute__((visibility("default"))) struct android_namespace_t* FindNamespaceByClassLoader(
    JNIEnv* env, jobject class_loader);
// That version works with native bridge namespaces, but requires use of OpenNativeLibrary.
struct NativeLoaderNamespace;
__attribute__((visibility("default"))) struct NativeLoaderNamespace*
FindNativeLoaderNamespaceByClassLoader(JNIEnv* env, jobject class_loader);
// Load library.  Unlinke OpenNativeLibrary above couldn't create namespace on demand, but does
// not require access to JNIEnv either.
__attribute__((visibility("default")))
void* OpenNativeLibrary(NativeLoaderNamespace* ns,
                        const char* path,
                        bool* needs_native_bridge,
                        std::string* error_msg);
__attribute__((visibility("default"))) void* OpenNativeLibraryInNamespace(
    struct NativeLoaderNamespace* ns, const char* path, bool* needs_native_bridge,
    char** error_msg);
#endif

__attribute__((visibility("default")))
void ResetNativeLoader();

};  // namespace android
#ifdef __cplusplus
}  // extern "C"
}  // namespace android
#endif  // __cplusplus

#endif  // NATIVE_BRIDGE_H_
+31 −0
Original line number Diff line number Diff line
#
# 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.
#

# TODO(b/122710865): Prune these uses once the runtime APEX is complete.
LIBNATIVELOADER_1 {
  global:
    OpenNativeLibrary;
    InitializeNativeLoader;
    ResetNativeLoader;
    CloseNativeLibrary;
    OpenNativeLibraryInNamespace;
    FindNamespaceByClassLoader;
    FindNativeLoaderNamespaceByClassLoader;
    CreateClassLoaderNamespace;
    NativeLoaderFreeErrorMessage;
  local:
    *;
};
+27 −34
Original line number Diff line number Diff line
@@ -52,7 +52,7 @@ using namespace std::string_literals;
namespace android {

#if defined(__ANDROID__)
class NativeLoaderNamespace {
struct NativeLoaderNamespace {
 public:
  NativeLoaderNamespace()
      : android_ns_(nullptr), native_bridge_ns_(nullptr) { }
@@ -151,14 +151,9 @@ class LibraryNamespaces {
 public:
  LibraryNamespaces() : initialized_(false) { }

  NativeLoaderNamespace* Create(JNIEnv* env,
                                uint32_t target_sdk_version,
                                jobject class_loader,
                                bool is_shared,
                                bool is_for_vendor,
                                jstring java_library_path,
                                jstring java_permitted_path,
                                std::string* error_msg) {
  NativeLoaderNamespace* Create(JNIEnv* env, uint32_t target_sdk_version, jobject class_loader,
                                bool is_shared, bool is_for_vendor, jstring java_library_path,
                                jstring java_permitted_path, std::string* error_msg) {
    std::string library_path; // empty string by default.

    if (java_library_path != nullptr) {
@@ -628,13 +623,9 @@ jstring CreateClassLoaderNamespace(JNIEnv* env,
  return nullptr;
}

void* OpenNativeLibrary(JNIEnv* env,
                        int32_t target_sdk_version,
                        const char* path,
                        jobject class_loader,
                        jstring library_path,
                        bool* needs_native_bridge,
                        std::string* error_msg) {
void* OpenNativeLibrary(JNIEnv* env, int32_t target_sdk_version, const char* path,
                        jobject class_loader, jstring library_path, bool* needs_native_bridge,
                        char** error_msg) {
#if defined(__ANDROID__)
  UNUSED(target_sdk_version);
  if (class_loader == nullptr) {
@@ -652,19 +643,16 @@ void* OpenNativeLibrary(JNIEnv* env,
  if ((ns = g_namespaces->FindNamespaceByClassLoader(env, class_loader)) == nullptr) {
    // This is the case where the classloader was not created by ApplicationLoaders
    // In this case we create an isolated not-shared namespace for it.
    if ((ns = g_namespaces->Create(env,
                                   target_sdk_version,
                                   class_loader,
                                   false /* is_shared */,
                                   false /* is_for_vendor */,
                                   library_path,
                                   nullptr,
                                   error_msg)) == nullptr) {
    std::string create_error_msg;
    if ((ns = g_namespaces->Create(env, target_sdk_version, class_loader, false /* is_shared */,
                                   false /* is_for_vendor */, library_path, nullptr,
                                   &create_error_msg)) == nullptr) {
      *error_msg = strdup(create_error_msg.c_str());
      return nullptr;
    }
  }

  return OpenNativeLibrary(ns, path, needs_native_bridge, error_msg);
  return OpenNativeLibraryInNamespace(ns, path, needs_native_bridge, error_msg);
#else
  UNUSED(env, target_sdk_version, class_loader);

@@ -705,35 +693,40 @@ void* OpenNativeLibrary(JNIEnv* env,
      if (handle != nullptr) {
        return handle;
      }
      *error_msg = NativeBridgeGetError();
      *error_msg = strdup(NativeBridgeGetError());
    } else {
      *error_msg = dlerror();
      *error_msg = strdup(dlerror());
    }
  }
  return nullptr;
#endif
}

bool CloseNativeLibrary(void* handle, const bool needs_native_bridge, std::string* error_msg) {
bool CloseNativeLibrary(void* handle, const bool needs_native_bridge, char** error_msg) {
  bool success;
  if (needs_native_bridge) {
    success = (NativeBridgeUnloadLibrary(handle) == 0);
    if (!success) {
      *error_msg = NativeBridgeGetError();
      *error_msg = strdup(NativeBridgeGetError());
    }
  } else {
    success = (dlclose(handle) == 0);
    if (!success) {
      *error_msg = dlerror();
      *error_msg = strdup(dlerror());
    }
  }

  return success;
}

void NativeLoaderFreeErrorMessage(char* msg) {
  // The error messages get allocated through strdup, so we must call free on them.
  free(msg);
}

#if defined(__ANDROID__)
void* OpenNativeLibrary(NativeLoaderNamespace* ns, const char* path, bool* needs_native_bridge,
                        std::string* error_msg) {
void* OpenNativeLibraryInNamespace(NativeLoaderNamespace* ns, const char* path,
                                   bool* needs_native_bridge, char** error_msg) {
  if (ns->is_android_namespace()) {
    android_dlextinfo extinfo;
    extinfo.flags = ANDROID_DLEXT_USE_NAMESPACE;
@@ -741,14 +734,14 @@ void* OpenNativeLibrary(NativeLoaderNamespace* ns, const char* path, bool* needs

    void* handle = android_dlopen_ext(path, RTLD_NOW, &extinfo);
    if (handle == nullptr) {
      *error_msg = dlerror();
      *error_msg = strdup(dlerror());
    }
    *needs_native_bridge = false;
    return handle;
  } else {
    void* handle = NativeBridgeLoadLibraryExt(path, RTLD_NOW, ns->get_native_bridge_ns());
    if (handle == nullptr) {
      *error_msg = NativeBridgeGetError();
      *error_msg = strdup(NativeBridgeGetError());
    }
    *needs_native_bridge = true;
    return handle;
Loading