diff --git a/libnativebridge/Android.bp b/libnativebridge/Android.bp index c54570ee6..10d42e41f 100644 --- a/libnativebridge/Android.bp +++ b/libnativebridge/Android.bp @@ -1,5 +1,18 @@ +cc_defaults { + name: "libnativebridge-defaults", + cflags: [ + "-Werror", + "-Wall", + ], + cppflags: [ + "-fvisibility=protected", + ], + header_libs: ["libnativebridge-headers"], + export_header_lib_headers: ["libnativebridge-headers"], +} + cc_library_headers { - name: "libnativebridge-dummy-headers", + name: "libnativebridge-headers", host_supported: true, export_include_dirs: ["include"], @@ -7,6 +20,7 @@ cc_library_headers { cc_library { name: "libnativebridge", + defaults: ["libnativebridge-defaults"], host_supported: true, srcs: ["native_bridge.cc"], @@ -16,6 +30,8 @@ cc_library { shared_libs: [ "liblog", ], + // TODO(jiyong): remove this line after aosp/885921 lands + export_include_dirs: ["include"], target: { android: { @@ -30,16 +46,16 @@ cc_library { symbol_file: "libnativebridge.map.txt", versions: ["1"], }, +} - export_include_dirs: ["include"], +// TODO(b/124250621): eliminate the need for this library +cc_library { + name: "libnativebridge_lazy", + defaults: ["libnativebridge-defaults"], - cflags: [ - "-Werror", - "-Wall", - ], - cppflags: [ - "-fvisibility=protected", - ], + host_supported: false, + srcs: ["native_bridge_lazy.cc"], + required: ["libnativebridge"], } subdirs = ["tests"] diff --git a/libnativebridge/native_bridge_lazy.cc b/libnativebridge/native_bridge_lazy.cc new file mode 100644 index 000000000..94c80848e --- /dev/null +++ b/libnativebridge/native_bridge_lazy.cc @@ -0,0 +1,167 @@ +/* + * 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. + */ + +#include "nativebridge/native_bridge.h" +#define LOG_TAG "nativebridge" + +#include +#include +#include + +#include + +namespace android { + +namespace { + +void* GetLibHandle() { + static void* handle = dlopen("libnativebridge.so", RTLD_NOW); + LOG_FATAL_IF(handle == nullptr, "Failed to load libnativebridge.so: %s", dlerror()); + return handle; +} + +template +FuncPtr GetFuncPtr(const char* function_name) { + auto f = reinterpret_cast(dlsym(GetLibHandle(), function_name)); + LOG_FATAL_IF(f == nullptr, "Failed to get address of %s: %s", function_name, dlerror()); + return f; +} + +#define GET_FUNC_PTR(name) GetFuncPtr(#name) + +} // namespace + +bool LoadNativeBridge(const char* native_bridge_library_filename, + const struct NativeBridgeRuntimeCallbacks* runtime_callbacks) { + static auto f = GET_FUNC_PTR(LoadNativeBridge); + return f(native_bridge_library_filename, runtime_callbacks); +} + +bool NeedsNativeBridge(const char* instruction_set) { + static auto f = GET_FUNC_PTR(NeedsNativeBridge); + return f(instruction_set); +} + +bool PreInitializeNativeBridge(const char* app_data_dir, const char* instruction_set) { + static auto f = GET_FUNC_PTR(PreInitializeNativeBridge); + return f(app_data_dir, instruction_set); +} + +bool InitializeNativeBridge(JNIEnv* env, const char* instruction_set) { + static auto f = GET_FUNC_PTR(InitializeNativeBridge); + return f(env, instruction_set); +} + +void UnloadNativeBridge() { + static auto f = GET_FUNC_PTR(UnloadNativeBridge); + return f(); +} + +bool NativeBridgeAvailable() { + static auto f = GET_FUNC_PTR(NativeBridgeAvailable); + return f(); +} + +bool NativeBridgeInitialized() { + static auto f = GET_FUNC_PTR(NativeBridgeInitialized); + return f(); +} + +void* NativeBridgeLoadLibrary(const char* libpath, int flag) { + static auto f = GET_FUNC_PTR(NativeBridgeLoadLibrary); + return f(libpath, flag); +} + +void* NativeBridgeGetTrampoline(void* handle, const char* name, const char* shorty, uint32_t len) { + static auto f = GET_FUNC_PTR(NativeBridgeGetTrampoline); + return f(handle, name, shorty, len); +} + +bool NativeBridgeIsSupported(const char* libpath) { + static auto f = GET_FUNC_PTR(NativeBridgeIsSupported); + return f(libpath); +} + +uint32_t NativeBridgeGetVersion() { + static auto f = GET_FUNC_PTR(NativeBridgeGetVersion); + return f(); +} + +NativeBridgeSignalHandlerFn NativeBridgeGetSignalHandler(int signal) { + static auto f = GET_FUNC_PTR(NativeBridgeGetSignalHandler); + return f(signal); +} + +bool NativeBridgeError() { + static auto f = GET_FUNC_PTR(NativeBridgeError); + return f(); +} + +bool NativeBridgeNameAcceptable(const char* native_bridge_library_filename) { + static auto f = GET_FUNC_PTR(NativeBridgeNameAcceptable); + return f(native_bridge_library_filename); +} + +int NativeBridgeUnloadLibrary(void* handle) { + static auto f = GET_FUNC_PTR(NativeBridgeUnloadLibrary); + return f(handle); +} + +const char* NativeBridgeGetError() { + static auto f = GET_FUNC_PTR(NativeBridgeGetError); + return f(); +} + +bool NativeBridgeIsPathSupported(const char* path) { + static auto f = GET_FUNC_PTR(NativeBridgeIsPathSupported); + return f(path); +} + +bool NativeBridgeInitAnonymousNamespace(const char* public_ns_sonames, + const char* anon_ns_library_path) { + static auto f = GET_FUNC_PTR(NativeBridgeInitAnonymousNamespace); + return f(public_ns_sonames, anon_ns_library_path); +} + +struct native_bridge_namespace_t* NativeBridgeCreateNamespace( + const char* name, const char* ld_library_path, const char* default_library_path, uint64_t type, + const char* permitted_when_isolated_path, struct native_bridge_namespace_t* parent_ns) { + static auto f = GET_FUNC_PTR(NativeBridgeCreateNamespace); + return f(name, ld_library_path, default_library_path, type, permitted_when_isolated_path, + parent_ns); +} + +bool NativeBridgeLinkNamespaces(struct native_bridge_namespace_t* from, + struct native_bridge_namespace_t* to, + const char* shared_libs_sonames) { + static auto f = GET_FUNC_PTR(NativeBridgeLinkNamespaces); + return f(from, to, shared_libs_sonames); +} + +void* NativeBridgeLoadLibraryExt(const char* libpath, int flag, + struct native_bridge_namespace_t* ns) { + static auto f = GET_FUNC_PTR(NativeBridgeLoadLibraryExt); + return f(libpath, flag, ns); +} + +struct native_bridge_namespace_t* NativeBridgeGetVendorNamespace() { + static auto f = GET_FUNC_PTR(NativeBridgeGetVendorNamespace); + return f(); +} + +#undef GET_FUNC_PTR + +} // namespace android diff --git a/libnativebridge/tests/Android.bp b/libnativebridge/tests/Android.bp index 744a4a8b8..2bb846738 100644 --- a/libnativebridge/tests/Android.bp +++ b/libnativebridge/tests/Android.bp @@ -23,7 +23,7 @@ cc_defaults { "-Wextra", "-Werror", ], - header_libs: ["libnativebridge-dummy-headers"], + header_libs: ["libnativebridge-headers"], cppflags: ["-fvisibility=protected"], } @@ -46,9 +46,8 @@ cc_library_shared { } // Build the unit tests. -cc_test { - name: "libnativebridge-tests", - host_supported: true, +cc_defaults { + name: "libnativebridge-tests-defaults", test_per_src: true, cflags: [ @@ -81,12 +80,24 @@ cc_test { shared_libs: [ "liblog", - "libnativebridge", "libnativebridge-dummy", ], header_libs: ["libbase_headers"], } +cc_test { + name: "libnativebridge-tests", + defaults: ["libnativebridge-tests-defaults"], + host_supported: true, + shared_libs: ["libnativebridge"], +} + +cc_test { + name: "libnativebridge-lazy-tests", + defaults: ["libnativebridge-tests-defaults"], + shared_libs: ["libnativebridge_lazy"], +} + // Build the test for the C API. cc_test { name: "libnativebridge-api-tests", @@ -95,5 +106,5 @@ cc_test { srcs: [ "NativeBridgeApi.c", ], - header_libs: ["libnativebridge-dummy-headers"], + header_libs: ["libnativebridge-headers"], } diff --git a/libnativeloader/Android.bp b/libnativeloader/Android.bp index 1ec21e9d2..b806ae408 100644 --- a/libnativeloader/Android.bp +++ b/libnativeloader/Android.bp @@ -1,7 +1,21 @@ // Shared library for target // ======================================================== +cc_defaults { + name: "libnativeloader-defaults", + cflags: [ + "-Werror", + "-Wall", + ], + cppflags: [ + "-fvisibility=hidden", + ], + header_libs: ["libnativeloader-headers"], + export_header_lib_headers: ["libnativeloader-headers"], +} + cc_library { name: "libnativeloader", + defaults: ["libnativeloader-defaults"], host_supported: true, srcs: ["native_loader.cpp"], shared_libs: [ @@ -11,14 +25,6 @@ cc_library { "libnativebridge", "libbase", ], - cflags: [ - "-Werror", - "-Wall", - ], - cppflags: [ - "-fvisibility=hidden", - ], - export_include_dirs: ["include"], required: [ "llndk.libraries.txt", "vndksp.libraries.txt", @@ -29,9 +35,25 @@ cc_library { }, } -cc_library_headers { - name: "libnativeloader-dummy-headers", +// TODO(b/124250621) eliminate the need for this library +cc_library { + name: "libnativeloader_lazy", + defaults: ["libnativeloader-defaults"], + host_supported: false, + srcs: ["native_loader_lazy.cpp"], + required: ["libnativeloader"], +} +cc_library_headers { + name: "libnativeloader-headers", + host_supported: true, + export_include_dirs: ["include"], +} + +// TODO(jiyong) Remove this when its use in the internal master is +// switched to libnativeloader-headers +cc_library_headers { + name: "libnativeloader-dummy-headers", host_supported: true, export_include_dirs: ["include"], } diff --git a/libnativeloader/native_loader_lazy.cpp b/libnativeloader/native_loader_lazy.cpp new file mode 100644 index 000000000..11ecc431a --- /dev/null +++ b/libnativeloader/native_loader_lazy.cpp @@ -0,0 +1,102 @@ +/* + * 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. + */ + +#include "nativeloader/native_loader.h" +#define LOG_TAG "nativeloader" + +#include +#include +#include + +#include + +namespace android { + +namespace { + +void* GetLibHandle() { + static void* handle = dlopen("libnativeloader.so", RTLD_NOW); + LOG_FATAL_IF(handle == nullptr, "Failed to load libnativeloader.so: %s", dlerror()); + return handle; +} + +template +FuncPtr GetFuncPtr(const char* function_name) { + auto f = reinterpret_cast(dlsym(GetLibHandle(), function_name)); + LOG_FATAL_IF(f == nullptr, "Failed to get address of %s: %s", function_name, dlerror()); + return f; +} + +#define GET_FUNC_PTR(name) GetFuncPtr(#name) + +} // namespace + +void InitializeNativeLoader() { + static auto f = GET_FUNC_PTR(InitializeNativeLoader); + return f(); +} + +jstring CreateClassLoaderNamespace(JNIEnv* env, int32_t target_sdk_version, jobject class_loader, + bool is_shared, bool is_for_vendor, jstring library_path, + jstring permitted_path) { + static auto f = GET_FUNC_PTR(CreateClassLoaderNamespace); + return f(env, target_sdk_version, class_loader, is_shared, is_for_vendor, library_path, + permitted_path); +} + +void* OpenNativeLibrary(JNIEnv* env, int32_t target_sdk_version, const char* path, + jobject class_loader, const char* caller_location, jstring library_path, + bool* needs_native_bridge, char** error_msg) { + static auto f = GET_FUNC_PTR(OpenNativeLibrary); + return f(env, target_sdk_version, path, class_loader, caller_location, library_path, + needs_native_bridge, error_msg); +} + +bool CloseNativeLibrary(void* handle, const bool needs_native_bridge, char** error_msg) { + static auto f = GET_FUNC_PTR(CloseNativeLibrary); + return f(handle, needs_native_bridge, error_msg); +} + +void NativeLoaderFreeErrorMessage(char* msg) { + static auto f = GET_FUNC_PTR(NativeLoaderFreeErrorMessage); + return f(msg); +} + +struct android_namespace_t* FindNamespaceByClassLoader(JNIEnv* env, jobject class_loader) { + static auto f = GET_FUNC_PTR(FindNamespaceByClassLoader); + return f(env, class_loader); +} + +struct NativeLoaderNamespace* FindNativeLoaderNamespaceByClassLoader(JNIEnv* env, + jobject class_loader) { + static auto f = GET_FUNC_PTR(FindNativeLoaderNamespaceByClassLoader); + return f(env, class_loader); +} + +void* OpenNativeLibraryInNamespace(struct NativeLoaderNamespace* ns, const char* path, + bool* needs_native_bridge, char** error_msg) { + static auto f = GET_FUNC_PTR(OpenNativeLibraryInNamespace); + return f(ns, path, needs_native_bridge, error_msg); +} + +void ResetNativeLoader() { + static auto f = GET_FUNC_PTR(ResetNativeLoader); + return f(); +} + +#undef GET_FUNC_PTR + +} // namespace android diff --git a/libnativeloader/test/Android.bp b/libnativeloader/test/Android.bp index 1464e39f3..4d5c53dba 100644 --- a/libnativeloader/test/Android.bp +++ b/libnativeloader/test/Android.bp @@ -78,5 +78,5 @@ cc_test { srcs: [ "api_test.c", ], - header_libs: ["libnativeloader-dummy-headers"], + header_libs: ["libnativeloader-headers"], }