OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // This is the Android-specific content linker, a tiny shared library | 5 // This is the Android-specific Chromium linker, a tiny shared library |
6 // implementing a custom dynamic linker that can be used to load the | 6 // implementing a custom dynamic linker that can be used to load the |
7 // real content-based libraries (e.g. libcontentshell.so). | 7 // real Chromium libraries (e.g. libcontentshell.so). |
8 | 8 |
9 // The main point of this linker is to be able to share the RELRO | 9 // The main point of this linker is to be able to share the RELRO |
10 // section of libcontentshell.so (or equivalent) between the browser and | 10 // section of libcontentshell.so (or equivalent) between the browser and |
11 // renderer process. | 11 // renderer process. |
12 | 12 |
13 // This source code *cannot* depend on anything from base/ or the C++ | 13 // This source code *cannot* depend on anything from base/ or the C++ |
14 // STL, to keep the final library small, and avoid ugly dependency issues. | 14 // STL, to keep the final library small, and avoid ugly dependency issues. |
15 | 15 |
16 #include <android/log.h> | 16 #include <android/log.h> |
17 #include <crazy_linker.h> | 17 #include <crazy_linker.h> |
18 #include <jni.h> | 18 #include <jni.h> |
19 #include <stdlib.h> | 19 #include <stdlib.h> |
20 #include <unistd.h> | 20 #include <unistd.h> |
21 | 21 |
22 // Set this to 1 to enable debug traces to the Android log. | 22 // Set this to 1 to enable debug traces to the Android log. |
23 // Note that LOG() from "base/logging.h" cannot be used, since it is | 23 // Note that LOG() from "base/logging.h" cannot be used, since it is |
24 // in base/ which hasn't been loaded yet. | 24 // in base/ which hasn't been loaded yet. |
25 #define DEBUG 0 | 25 #define DEBUG 0 |
26 | 26 |
27 #define TAG "content_android_linker" | 27 #define TAG "chromium_android_linker" |
28 | 28 |
29 #if DEBUG | 29 #if DEBUG |
30 #define LOG_INFO(...) __android_log_print(ANDROID_LOG_INFO, TAG, __VA_ARGS__) | 30 #define LOG_INFO(...) __android_log_print(ANDROID_LOG_INFO, TAG, __VA_ARGS__) |
31 #define LOG_ERROR(...) __android_log_print(ANDROID_LOG_ERROR, TAG, __VA_ARGS__) | 31 #define LOG_ERROR(...) __android_log_print(ANDROID_LOG_ERROR, TAG, __VA_ARGS__) |
32 #else | 32 #else |
33 #define LOG_INFO(...) ((void)0) | 33 #define LOG_INFO(...) ((void)0) |
34 #define LOG_ERROR(...) ((void)0) | 34 #define LOG_ERROR(...) ((void)0) |
35 #endif | 35 #endif |
36 | 36 |
37 #define UNUSED __attribute__((unused)) | 37 #define UNUSED __attribute__((unused)) |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
147 jfieldID load_address_id; | 147 jfieldID load_address_id; |
148 jfieldID load_size_id; | 148 jfieldID load_size_id; |
149 jfieldID relro_start_id; | 149 jfieldID relro_start_id; |
150 jfieldID relro_size_id; | 150 jfieldID relro_size_id; |
151 jfieldID relro_fd_id; | 151 jfieldID relro_fd_id; |
152 | 152 |
153 // Initialize an instance. | 153 // Initialize an instance. |
154 bool Init(JNIEnv* env) { | 154 bool Init(JNIEnv* env) { |
155 jclass clazz; | 155 jclass clazz; |
156 if (!InitClassReference( | 156 if (!InitClassReference( |
157 env, "org/chromium/content/app/Linker$LibInfo", &clazz)) { | 157 env, "org/chromium/base/library_loader/Linker$LibInfo", &clazz)) { |
158 return false; | 158 return false; |
159 } | 159 } |
160 | 160 |
161 return InitFieldId(env, clazz, "mLoadAddress", "J", &load_address_id) && | 161 return InitFieldId(env, clazz, "mLoadAddress", "J", &load_address_id) && |
162 InitFieldId(env, clazz, "mLoadSize", "J", &load_size_id) && | 162 InitFieldId(env, clazz, "mLoadSize", "J", &load_size_id) && |
163 InitFieldId(env, clazz, "mRelroStart", "J", &relro_start_id) && | 163 InitFieldId(env, clazz, "mRelroStart", "J", &relro_start_id) && |
164 InitFieldId(env, clazz, "mRelroSize", "J", &relro_size_id) && | 164 InitFieldId(env, clazz, "mRelroSize", "J", &relro_size_id) && |
165 InitFieldId(env, clazz, "mRelroFd", "I", &relro_fd_id); | 165 InitFieldId(env, clazz, "mRelroFd", "I", &relro_fd_id); |
166 } | 166 } |
167 | 167 |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
214 | 214 |
215 // Ensure libraries located in the same directory as the linker | 215 // Ensure libraries located in the same directory as the linker |
216 // can be loaded before system ones. | 216 // can be loaded before system ones. |
217 crazy_context_add_search_path_for_address( | 217 crazy_context_add_search_path_for_address( |
218 s_crazy_context, reinterpret_cast<void*>(&s_crazy_context)); | 218 s_crazy_context, reinterpret_cast<void*>(&s_crazy_context)); |
219 } | 219 } |
220 | 220 |
221 return s_crazy_context; | 221 return s_crazy_context; |
222 } | 222 } |
223 | 223 |
224 // Load a library with the content linker. This will also call its | 224 // Load a library with the chromium linker. This will also call its |
225 // JNI_OnLoad() method, which shall register its methods. Note that | 225 // JNI_OnLoad() method, which shall register its methods. Note that |
226 // lazy native method resolution will _not_ work after this, because | 226 // lazy native method resolution will _not_ work after this, because |
227 // Dalvik uses the system's dlsym() which won't see the new library, | 227 // Dalvik uses the system's dlsym() which won't see the new library, |
228 // so explicit registration is mandatory. | 228 // so explicit registration is mandatory. |
229 // |env| is the current JNI environment handle. | 229 // |env| is the current JNI environment handle. |
230 // |clazz| is the static class handle for org.chromium.base.Linker, | 230 // |clazz| is the static class handle for org.chromium.base.Linker, |
231 // and is ignored here. | 231 // and is ignored here. |
232 // |library_name| is the library name (e.g. libfoo.so). | 232 // |library_name| is the library name (e.g. libfoo.so). |
233 // |load_address| is an explicit load address. | 233 // |load_address| is an explicit load address. |
234 // |library_info| is a LibInfo handle used to communicate information | 234 // |library_info| is a LibInfo handle used to communicate information |
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
380 jlong result = static_cast<jlong>(sysconf(_SC_PAGESIZE)); | 380 jlong result = static_cast<jlong>(sysconf(_SC_PAGESIZE)); |
381 LOG_INFO("%s: System page size is %lld bytes\n", __FUNCTION__, result); | 381 LOG_INFO("%s: System page size is %lld bytes\n", __FUNCTION__, result); |
382 return result; | 382 return result; |
383 } | 383 } |
384 | 384 |
385 const JNINativeMethod kNativeMethods[] = { | 385 const JNINativeMethod kNativeMethods[] = { |
386 {"nativeLoadLibrary", | 386 {"nativeLoadLibrary", |
387 "(" | 387 "(" |
388 "Ljava/lang/String;" | 388 "Ljava/lang/String;" |
389 "J" | 389 "J" |
390 "Lorg/chromium/content/app/Linker$LibInfo;" | 390 "Lorg/chromium/base/library_loader/Linker$LibInfo;" |
391 ")" | 391 ")" |
392 "Z", | 392 "Z", |
393 reinterpret_cast<void*>(&LoadLibrary)}, | 393 reinterpret_cast<void*>(&LoadLibrary)}, |
394 {"nativeCreateSharedRelro", | 394 {"nativeCreateSharedRelro", |
395 "(" | 395 "(" |
396 "Ljava/lang/String;" | 396 "Ljava/lang/String;" |
397 "J" | 397 "J" |
398 "Lorg/chromium/content/app/Linker$LibInfo;" | 398 "Lorg/chromium/base/library_loader/Linker$LibInfo;" |
399 ")" | 399 ")" |
400 "Z", | 400 "Z", |
401 reinterpret_cast<void*>(&CreateSharedRelro)}, | 401 reinterpret_cast<void*>(&CreateSharedRelro)}, |
402 {"nativeUseSharedRelro", | 402 {"nativeUseSharedRelro", |
403 "(" | 403 "(" |
404 "Ljava/lang/String;" | 404 "Ljava/lang/String;" |
405 "Lorg/chromium/content/app/Linker$LibInfo;" | 405 "Lorg/chromium/base/library_loader/Linker$LibInfo;" |
406 ")" | 406 ")" |
407 "Z", | 407 "Z", |
408 reinterpret_cast<void*>(&UseSharedRelro)}, | 408 reinterpret_cast<void*>(&UseSharedRelro)}, |
409 {"nativeCanUseSharedRelro", | 409 {"nativeCanUseSharedRelro", |
410 "(" | 410 "(" |
411 ")" | 411 ")" |
412 "Z", | 412 "Z", |
413 reinterpret_cast<void*>(&CanUseSharedRelro)}, | 413 reinterpret_cast<void*>(&CanUseSharedRelro)}, |
414 {"nativeGetPageSize", | 414 {"nativeGetPageSize", |
415 "(" | 415 "(" |
(...skipping 11 matching lines...) Expand all Loading... |
427 // Get new JNIEnv | 427 // Get new JNIEnv |
428 JNIEnv* env; | 428 JNIEnv* env; |
429 if (JNI_OK != vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_4)) { | 429 if (JNI_OK != vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_4)) { |
430 LOG_ERROR("Could not create JNIEnv"); | 430 LOG_ERROR("Could not create JNIEnv"); |
431 return -1; | 431 return -1; |
432 } | 432 } |
433 | 433 |
434 // Register native methods. | 434 // Register native methods. |
435 jclass linker_class; | 435 jclass linker_class; |
436 if (!InitClassReference( | 436 if (!InitClassReference( |
437 env, "org/chromium/content/app/Linker", &linker_class)) | 437 env, "org/chromium/base/library_loader/Linker", &linker_class)) |
438 return -1; | 438 return -1; |
439 | 439 |
440 LOG_INFO("%s: Registering native methods", __FUNCTION__); | 440 LOG_INFO("%s: Registering native methods", __FUNCTION__); |
441 env->RegisterNatives(linker_class, | 441 env->RegisterNatives(linker_class, |
442 kNativeMethods, | 442 kNativeMethods, |
443 sizeof(kNativeMethods) / sizeof(kNativeMethods[0])); | 443 sizeof(kNativeMethods) / sizeof(kNativeMethods[0])); |
444 | 444 |
445 // Find LibInfo field ids. | 445 // Find LibInfo field ids. |
446 LOG_INFO("%s: Caching field IDs", __FUNCTION__); | 446 LOG_INFO("%s: Caching field IDs", __FUNCTION__); |
447 if (!s_lib_info_fields.Init(env)) { | 447 if (!s_lib_info_fields.Init(env)) { |
448 return -1; | 448 return -1; |
449 } | 449 } |
450 | 450 |
451 // Save JavaVM* handle into context. | 451 // Save JavaVM* handle into context. |
452 crazy_context_t* context = GetCrazyContext(); | 452 crazy_context_t* context = GetCrazyContext(); |
453 crazy_context_set_java_vm(context, vm, JNI_VERSION_1_4); | 453 crazy_context_set_java_vm(context, vm, JNI_VERSION_1_4); |
454 | 454 |
455 LOG_INFO("%s: Done", __FUNCTION__); | 455 LOG_INFO("%s: Done", __FUNCTION__); |
456 return JNI_VERSION_1_4; | 456 return JNI_VERSION_1_4; |
457 } | 457 } |
OLD | NEW |