1 /* 2 * Copyright (C) 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef NATIVE_BRIDGE_H_ 18 #define NATIVE_BRIDGE_H_ 19 20 #include <signal.h> 21 #include <stdbool.h> 22 #include <stdint.h> 23 #include <sys/types.h> 24 25 #include "jni.h" 26 27 #ifdef __cplusplus 28 namespace android { 29 extern "C" { 30 #endif // __cplusplus 31 32 struct NativeBridgeRuntimeCallbacks; 33 struct NativeBridgeRuntimeValues; 34 35 // Function pointer type for sigaction. This is mostly the signature of a signal handler, except 36 // for the return type. The runtime needs to know whether the signal was handled or should be given 37 // to the chain. 38 typedef bool (*NativeBridgeSignalHandlerFn)(int, siginfo_t*, void*); 39 40 // Open the native bridge, if any. Should be called by Runtime::Init(). A null library filename 41 // signals that we do not want to load a native bridge. 42 bool LoadNativeBridge(const char* native_bridge_library_filename, 43 const struct NativeBridgeRuntimeCallbacks* runtime_callbacks); 44 45 // Quick check whether a native bridge will be needed. This is based off of the instruction set 46 // of the process. 47 bool NeedsNativeBridge(const char* instruction_set); 48 49 // Do the early initialization part of the native bridge, if necessary. This should be done under 50 // high privileges. 51 bool PreInitializeNativeBridge(const char* app_data_dir, const char* instruction_set); 52 53 // Initialize the native bridge, if any. Should be called by Runtime::DidForkFromZygote. The JNIEnv* 54 // will be used to modify the app environment for the bridge. 55 bool InitializeNativeBridge(JNIEnv* env, const char* instruction_set); 56 57 // Unload the native bridge, if any. Should be called by Runtime::DidForkFromZygote. 58 void UnloadNativeBridge(); 59 60 // Check whether a native bridge is available (opened or initialized). Requires a prior call to 61 // LoadNativeBridge. 62 bool NativeBridgeAvailable(); 63 64 // Check whether a native bridge is available (initialized). Requires a prior call to 65 // LoadNativeBridge & InitializeNativeBridge. 66 bool NativeBridgeInitialized(); 67 68 // Load a shared library that is supported by the native bridge. 69 // 70 // Starting with v3, NativeBridge has two scenarios: with/without namespace. 71 // Use NativeBridgeLoadLibraryExt() instead in namespace scenario. 72 void* NativeBridgeLoadLibrary(const char* libpath, int flag); 73 74 // Get a native bridge trampoline for specified native method. 75 void* NativeBridgeGetTrampoline(void* handle, const char* name, const char* shorty, uint32_t len); 76 77 // True if native library paths are valid and is for an ABI that is supported by native bridge. 78 // The *libpath* must point to a library. 79 // 80 // Starting with v3, NativeBridge has two scenarios: with/without namespace. 81 // Use NativeBridgeIsPathSupported() instead in namespace scenario. 82 bool NativeBridgeIsSupported(const char* libpath); 83 84 // Returns the version number of the native bridge. This information is available after a 85 // successful LoadNativeBridge() and before closing it, that is, as long as NativeBridgeAvailable() 86 // returns true. Returns 0 otherwise. 87 uint32_t NativeBridgeGetVersion(); 88 89 // Returns a signal handler that the bridge would like to be managed. Only valid for a native 90 // bridge supporting the version 2 interface. Will return null if the bridge does not support 91 // version 2, or if it doesn't have a signal handler it wants to be known. 92 NativeBridgeSignalHandlerFn NativeBridgeGetSignalHandler(int signal); 93 94 // Returns whether we have seen a native bridge error. This could happen because the library 95 // was not found, rejected, could not be initialized and so on. 96 // 97 // This functionality is mainly for testing. 98 bool NativeBridgeError(); 99 100 // Returns whether a given string is acceptable as a native bridge library filename. 101 // 102 // This functionality is exposed mainly for testing. 103 bool NativeBridgeNameAcceptable(const char* native_bridge_library_filename); 104 105 // Decrements the reference count on the dynamic library handler. If the reference count drops 106 // to zero then the dynamic library is unloaded. Returns 0 on success and non-zero on error. 107 int NativeBridgeUnloadLibrary(void* handle); 108 109 // Get last error message of native bridge when fail to load library or search symbol. 110 // This is reflection of dlerror() for native bridge. 111 const char* NativeBridgeGetError(); 112 113 struct native_bridge_namespace_t; 114 115 // True if native library paths are valid and is for an ABI that is supported by native bridge. 116 // Different from NativeBridgeIsSupported(), the *path* here must be a directory containing 117 // libraries of an ABI. 118 // 119 // Starting with v3, NativeBridge has two scenarios: with/without namespace. 120 // Use NativeBridgeIsSupported() instead in non-namespace scenario. 121 bool NativeBridgeIsPathSupported(const char* path); 122 123 // Initializes anonymous namespace. 124 // NativeBridge's peer of android_init_anonymous_namespace() of dynamic linker. 125 // 126 // The anonymous namespace is used in the case when a NativeBridge implementation 127 // cannot identify the caller of dlopen/dlsym which happens for the code not loaded 128 // by dynamic linker; for example calls from the mono-compiled code. 129 // 130 // Starting with v3, NativeBridge has two scenarios: with/without namespace. 131 // Should not use in non-namespace scenario. 132 bool NativeBridgeInitAnonymousNamespace(const char* public_ns_sonames, 133 const char* anon_ns_library_path); 134 135 // Create new namespace in which native libraries will be loaded. 136 // NativeBridge's peer of android_create_namespace() of dynamic linker. 137 // 138 // The libraries in the namespace are searched by folowing order: 139 // 1. ld_library_path (Think of this as namespace-local LD_LIBRARY_PATH) 140 // 2. In directories specified by DT_RUNPATH of the "needed by" binary. 141 // 3. deault_library_path (This of this as namespace-local default library path) 142 // 143 // Starting with v3, NativeBridge has two scenarios: with/without namespace. 144 // Should not use in non-namespace scenario. 145 struct native_bridge_namespace_t* NativeBridgeCreateNamespace( 146 const char* name, const char* ld_library_path, const char* default_library_path, uint64_t type, 147 const char* permitted_when_isolated_path, struct native_bridge_namespace_t* parent_ns); 148 149 // Creates a link which shares some libraries from one namespace to another. 150 // NativeBridge's peer of android_link_namespaces() of dynamic linker. 151 // 152 // Starting with v3, NativeBridge has two scenarios: with/without namespace. 153 // Should not use in non-namespace scenario. 154 bool NativeBridgeLinkNamespaces(struct native_bridge_namespace_t* from, 155 struct native_bridge_namespace_t* to, 156 const char* shared_libs_sonames); 157 158 // Load a shared library with namespace key that is supported by the native bridge. 159 // NativeBridge's peer of android_dlopen_ext() of dynamic linker, only supports namespace 160 // extension. 161 // 162 // Starting with v3, NativeBridge has two scenarios: with/without namespace. 163 // Use NativeBridgeLoadLibrary() instead in non-namespace scenario. 164 void* NativeBridgeLoadLibraryExt(const char* libpath, int flag, 165 struct native_bridge_namespace_t* ns); 166 167 // Returns exported namespace by the name. This is a reflection of 168 // android_get_exported_namespace function. Introduced in v5. 169 struct native_bridge_namespace_t* NativeBridgeGetExportedNamespace(const char* name); 170 171 // Native bridge interfaces to runtime. 172 struct NativeBridgeCallbacks { 173 // Version number of the interface. 174 uint32_t version; 175 176 // Initialize native bridge. Native bridge's internal implementation must ensure MT safety and 177 // that the native bridge is initialized only once. Thus it is OK to call this interface for an 178 // already initialized native bridge. 179 // 180 // Parameters: 181 // runtime_cbs [IN] the pointer to NativeBridgeRuntimeCallbacks. 182 // Returns: 183 // true if initialization was successful. 184 bool (*initialize)(const struct NativeBridgeRuntimeCallbacks* runtime_cbs, 185 const char* private_dir, const char* instruction_set); 186 187 // Load a shared library that is supported by the native bridge. 188 // 189 // Parameters: 190 // libpath [IN] path to the shared library 191 // flag [IN] the stardard RTLD_XXX defined in bionic dlfcn.h 192 // Returns: 193 // The opaque handle of the shared library if sucessful, otherwise NULL 194 // 195 // Starting with v3, NativeBridge has two scenarios: with/without namespace. 196 // Use loadLibraryExt instead in namespace scenario. 197 void* (*loadLibrary)(const char* libpath, int flag); 198 199 // Get a native bridge trampoline for specified native method. The trampoline has same 200 // sigature as the native method. 201 // 202 // Parameters: 203 // handle [IN] the handle returned from loadLibrary 204 // shorty [IN] short descriptor of native method 205 // len [IN] length of shorty 206 // Returns: 207 // address of trampoline if successful, otherwise NULL 208 void* (*getTrampoline)(void* handle, const char* name, const char* shorty, uint32_t len); 209 210 // Check whether native library is valid and is for an ABI that is supported by native bridge. 211 // 212 // Parameters: 213 // libpath [IN] path to the shared library 214 // Returns: 215 // TRUE if library is supported by native bridge, FALSE otherwise 216 // 217 // Starting with v3, NativeBridge has two scenarios: with/without namespace. 218 // Use isPathSupported instead in namespace scenario. 219 bool (*isSupported)(const char* libpath); 220 221 // Provide environment values required by the app running with native bridge according to the 222 // instruction set. 223 // 224 // Parameters: 225 // instruction_set [IN] the instruction set of the app 226 // Returns: 227 // NULL if not supported by native bridge. 228 // Otherwise, return all environment values to be set after fork. 229 const struct NativeBridgeRuntimeValues* (*getAppEnv)(const char* instruction_set); 230 231 // Added callbacks in version 2. 232 233 // Check whether the bridge is compatible with the given version. A bridge may decide not to be 234 // forwards- or backwards-compatible, and libnativebridge will then stop using it. 235 // 236 // Parameters: 237 // bridge_version [IN] the version of libnativebridge. 238 // Returns: 239 // true if the native bridge supports the given version of libnativebridge. 240 bool (*isCompatibleWith)(uint32_t bridge_version); 241 242 // A callback to retrieve a native bridge's signal handler for the specified signal. The runtime 243 // will ensure that the signal handler is being called after the runtime's own handler, but before 244 // all chained handlers. The native bridge should not try to install the handler by itself, as 245 // that will potentially lead to cycles. 246 // 247 // Parameters: 248 // signal [IN] the signal for which the handler is asked for. Currently, only SIGSEGV is 249 // supported by the runtime. 250 // Returns: 251 // NULL if the native bridge doesn't use a handler or doesn't want it to be managed by the 252 // runtime. 253 // Otherwise, a pointer to the signal handler. 254 NativeBridgeSignalHandlerFn (*getSignalHandler)(int signal); 255 256 // Added callbacks in version 3. 257 258 // Decrements the reference count on the dynamic library handler. If the reference count drops 259 // to zero then the dynamic library is unloaded. 260 // 261 // Parameters: 262 // handle [IN] the handler of a dynamic library. 263 // 264 // Returns: 265 // 0 on success, and nonzero on error. 266 int (*unloadLibrary)(void* handle); 267 268 // Dump the last failure message of native bridge when fail to load library or search symbol. 269 // 270 // Parameters: 271 // 272 // Returns: 273 // A string describing the most recent error that occurred when load library 274 // or lookup symbol via native bridge. 275 const char* (*getError)(); 276 277 // Check whether library paths are supported by native bridge. 278 // 279 // Parameters: 280 // library_path [IN] search paths for native libraries (directories separated by ':') 281 // Returns: 282 // TRUE if libraries within search paths are supported by native bridge, FALSE otherwise 283 // 284 // Starting with v3, NativeBridge has two scenarios: with/without namespace. 285 // Use isSupported instead in non-namespace scenario. 286 bool (*isPathSupported)(const char* library_path); 287 288 // Initializes anonymous namespace at native bridge side. 289 // NativeBridge's peer of android_init_anonymous_namespace() of dynamic linker. 290 // 291 // The anonymous namespace is used in the case when a NativeBridge implementation 292 // cannot identify the caller of dlopen/dlsym which happens for the code not loaded 293 // by dynamic linker; for example calls from the mono-compiled code. 294 // 295 // Parameters: 296 // public_ns_sonames [IN] the name of "public" libraries. 297 // anon_ns_library_path [IN] the library search path of (anonymous) namespace. 298 // Returns: 299 // true if the pass is ok. 300 // Otherwise, false. 301 // 302 // Starting with v3, NativeBridge has two scenarios: with/without namespace. 303 // Should not use in non-namespace scenario. 304 bool (*initAnonymousNamespace)(const char* public_ns_sonames, const char* anon_ns_library_path); 305 306 // Create new namespace in which native libraries will be loaded. 307 // NativeBridge's peer of android_create_namespace() of dynamic linker. 308 // 309 // Parameters: 310 // name [IN] the name of the namespace. 311 // ld_library_path [IN] the first set of library search paths of the namespace. 312 // default_library_path [IN] the second set of library search path of the namespace. 313 // type [IN] the attribute of the namespace. 314 // permitted_when_isolated_path [IN] the permitted path for isolated namespace(if it is). 315 // parent_ns [IN] the pointer of the parent namespace to be inherited from. 316 // Returns: 317 // native_bridge_namespace_t* for created namespace or nullptr in the case of error. 318 // 319 // Starting with v3, NativeBridge has two scenarios: with/without namespace. 320 // Should not use in non-namespace scenario. 321 struct native_bridge_namespace_t* (*createNamespace)(const char* name, 322 const char* ld_library_path, 323 const char* default_library_path, 324 uint64_t type, 325 const char* permitted_when_isolated_path, 326 struct native_bridge_namespace_t* parent_ns); 327 328 // Creates a link which shares some libraries from one namespace to another. 329 // NativeBridge's peer of android_link_namespaces() of dynamic linker. 330 // 331 // Parameters: 332 // from [IN] the namespace where libraries are accessed. 333 // to [IN] the namespace where libraries are loaded. 334 // shared_libs_sonames [IN] the libraries to be shared. 335 // 336 // Returns: 337 // Whether successed or not. 338 // 339 // Starting with v3, NativeBridge has two scenarios: with/without namespace. 340 // Should not use in non-namespace scenario. 341 bool (*linkNamespaces)(struct native_bridge_namespace_t* from, 342 struct native_bridge_namespace_t* to, const char* shared_libs_sonames); 343 344 // Load a shared library within a namespace. 345 // NativeBridge's peer of android_dlopen_ext() of dynamic linker, only supports namespace 346 // extension. 347 // 348 // Parameters: 349 // libpath [IN] path to the shared library 350 // flag [IN] the stardard RTLD_XXX defined in bionic dlfcn.h 351 // ns [IN] the pointer of the namespace in which the library should be loaded. 352 // Returns: 353 // The opaque handle of the shared library if sucessful, otherwise NULL 354 // 355 // Starting with v3, NativeBridge has two scenarios: with/without namespace. 356 // Use loadLibrary instead in non-namespace scenario. 357 void* (*loadLibraryExt)(const char* libpath, int flag, struct native_bridge_namespace_t* ns); 358 359 // Get native bridge version of vendor namespace. 360 // The vendor namespace is the namespace used to load vendor public libraries. 361 // With O release this namespace can be different from the default namespace. 362 // For the devices without enable vendor namespaces this function should return null 363 // 364 // Returns: 365 // vendor namespace or null if it was not set up for the device 366 // 367 // Starting with v5 (Android Q) this function is no longer used. 368 // Use getExportedNamespace() below. 369 struct native_bridge_namespace_t* (*getVendorNamespace)(); 370 371 // Get native bridge version of exported namespace. Peer of 372 // android_get_exported_namespace(const char*) function. 373 // 374 // Returns: 375 // exported namespace or null if it was not set up for the device 376 struct native_bridge_namespace_t* (*getExportedNamespace)(const char* name); 377 }; 378 379 // Runtime interfaces to native bridge. 380 struct NativeBridgeRuntimeCallbacks { 381 // Get shorty of a Java method. The shorty is supposed to be persistent in memory. 382 // 383 // Parameters: 384 // env [IN] pointer to JNIenv. 385 // mid [IN] Java methodID. 386 // Returns: 387 // short descriptor for method. 388 const char* (*getMethodShorty)(JNIEnv* env, jmethodID mid); 389 390 // Get number of native methods for specified class. 391 // 392 // Parameters: 393 // env [IN] pointer to JNIenv. 394 // clazz [IN] Java class object. 395 // Returns: 396 // number of native methods. 397 uint32_t (*getNativeMethodCount)(JNIEnv* env, jclass clazz); 398 399 // Get at most 'method_count' native methods for specified class 'clazz'. Results are outputed 400 // via 'methods' [OUT]. The signature pointer in JNINativeMethod is reused as the method shorty. 401 // 402 // Parameters: 403 // env [IN] pointer to JNIenv. 404 // clazz [IN] Java class object. 405 // methods [OUT] array of method with the name, shorty, and fnPtr. 406 // method_count [IN] max number of elements in methods. 407 // Returns: 408 // number of method it actually wrote to methods. 409 uint32_t (*getNativeMethods)(JNIEnv* env, jclass clazz, JNINativeMethod* methods, 410 uint32_t method_count); 411 }; 412 413 #ifdef __cplusplus 414 } // extern "C" 415 } // namespace android 416 #endif // __cplusplus 417 418 #endif // NATIVE_BRIDGE_H_ 419