| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 Chromium 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 Chromium 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 |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 121 *method_id = env->GetStaticMethodID(clazz, method_name, method_sig); | 121 *method_id = env->GetStaticMethodID(clazz, method_name, method_sig); |
| 122 if (!*method_id) { | 122 if (!*method_id) { |
| 123 LOG_ERROR("Could not find ID for static method '%s'", method_name); | 123 LOG_ERROR("Could not find ID for static method '%s'", method_name); |
| 124 return false; | 124 return false; |
| 125 } | 125 } |
| 126 LOG_INFO("%s: Found ID %p for static method '%s'", | 126 LOG_INFO("%s: Found ID %p for static method '%s'", |
| 127 __FUNCTION__, *method_id, method_name); | 127 __FUNCTION__, *method_id, method_name); |
| 128 return true; | 128 return true; |
| 129 } | 129 } |
| 130 | 130 |
| 131 // Initialize a jfieldID corresponding to the static field of a given |clazz|, |
| 132 // with name |field_name| and signature |field_sig|. |
| 133 // |env| is the current JNI environment handle. |
| 134 // On success, return true and set |*field_id|. |
| 135 bool InitStaticFieldId(JNIEnv* env, |
| 136 jclass clazz, |
| 137 const char* field_name, |
| 138 const char* field_sig, |
| 139 jfieldID* field_id) { |
| 140 *field_id = env->GetStaticFieldID(clazz, field_name, field_sig); |
| 141 if (!*field_id) { |
| 142 LOG_ERROR("Could not find ID for static field '%s'", field_name); |
| 143 return false; |
| 144 } |
| 145 LOG_INFO( |
| 146 "%s: Found ID %p for static field '%s'", |
| 147 __FUNCTION__, *field_id, field_name); |
| 148 return true; |
| 149 } |
| 150 |
| 151 // Initialize a jint corresponding to the static integer field of a class |
| 152 // with class name |class_name| and field name |field_name|. |
| 153 // |env| is the current JNI environment handle. |
| 154 // On success, return true and set |*value|. |
| 155 bool InitStaticInt(JNIEnv* env, |
| 156 const char* class_name, |
| 157 const char* field_name, |
| 158 jint* value) { |
| 159 jclass clazz; |
| 160 if (!InitClassReference(env, class_name, &clazz)) |
| 161 return false; |
| 162 |
| 163 jfieldID field_id; |
| 164 if (!InitStaticFieldId(env, clazz, field_name, "I", &field_id)) |
| 165 return false; |
| 166 |
| 167 *value = env->GetStaticIntField(clazz, field_id); |
| 168 LOG_INFO( |
| 169 "%s: Found value %d for class '%s', static field '%s'", |
| 170 __FUNCTION__, *value, class_name, field_name); |
| 171 |
| 172 return true; |
| 173 } |
| 174 |
| 131 // A class used to model the field IDs of the org.chromium.base.Linker | 175 // A class used to model the field IDs of the org.chromium.base.Linker |
| 132 // LibInfo inner class, used to communicate data with the Java side | 176 // LibInfo inner class, used to communicate data with the Java side |
| 133 // of the linker. | 177 // of the linker. |
| 134 struct LibInfo_class { | 178 struct LibInfo_class { |
| 135 jfieldID load_address_id; | 179 jfieldID load_address_id; |
| 136 jfieldID load_size_id; | 180 jfieldID load_size_id; |
| 137 jfieldID relro_start_id; | 181 jfieldID relro_start_id; |
| 138 jfieldID relro_size_id; | 182 jfieldID relro_size_id; |
| 139 jfieldID relro_fd_id; | 183 jfieldID relro_fd_id; |
| 140 | 184 |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 183 size_t relro_size, | 227 size_t relro_size, |
| 184 int relro_fd) { | 228 int relro_fd) { |
| 185 env->SetLongField(library_info_obj, relro_start_id, relro_start); | 229 env->SetLongField(library_info_obj, relro_start_id, relro_start); |
| 186 env->SetLongField(library_info_obj, relro_size_id, relro_size); | 230 env->SetLongField(library_info_obj, relro_size_id, relro_size); |
| 187 env->SetIntField(library_info_obj, relro_fd_id, relro_fd); | 231 env->SetIntField(library_info_obj, relro_fd_id, relro_fd); |
| 188 } | 232 } |
| 189 }; | 233 }; |
| 190 | 234 |
| 191 static LibInfo_class s_lib_info_fields; | 235 static LibInfo_class s_lib_info_fields; |
| 192 | 236 |
| 237 // Retrieve the SDK build version and pass it into the crazy linker. This |
| 238 // needs to be done early in initialization, before any other crazy linker |
| 239 // code is run. |
| 240 // |env| is the current JNI environment handle. |
| 241 // On success, return true. |
| 242 bool InitSDKVersionInfo(JNIEnv* env) { |
| 243 jint value = 0; |
| 244 if (!InitStaticInt(env, "android/os/Build$VERSION", "SDK_INT", &value)) |
| 245 return false; |
| 246 |
| 247 crazy_set_sdk_build_version(static_cast<int>(value)); |
| 248 LOG_INFO("%s: Set SDK build version to %d", |
| 249 __FUNCTION__, static_cast<int>(value)); |
| 250 |
| 251 return true; |
| 252 } |
| 253 |
| 193 // The linker uses a single crazy_context_t object created on demand. | 254 // The linker uses a single crazy_context_t object created on demand. |
| 194 // There is no need to protect this against concurrent access, locking | 255 // There is no need to protect this against concurrent access, locking |
| 195 // is already handled on the Java side. | 256 // is already handled on the Java side. |
| 196 static crazy_context_t* s_crazy_context; | 257 static crazy_context_t* s_crazy_context; |
| 197 | 258 |
| 198 crazy_context_t* GetCrazyContext() { | 259 crazy_context_t* GetCrazyContext() { |
| 199 if (!s_crazy_context) { | 260 if (!s_crazy_context) { |
| 200 // Create new context. | 261 // Create new context. |
| 201 s_crazy_context = crazy_context_create(); | 262 s_crazy_context = crazy_context_create(); |
| 202 | 263 |
| (...skipping 548 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 751 // handle and initialize LibInfo fields. | 812 // handle and initialize LibInfo fields. |
| 752 jint JNI_OnLoad(JavaVM* vm, void* reserved) { | 813 jint JNI_OnLoad(JavaVM* vm, void* reserved) { |
| 753 LOG_INFO("%s: Entering", __FUNCTION__); | 814 LOG_INFO("%s: Entering", __FUNCTION__); |
| 754 // Get new JNIEnv | 815 // Get new JNIEnv |
| 755 JNIEnv* env; | 816 JNIEnv* env; |
| 756 if (JNI_OK != vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_4)) { | 817 if (JNI_OK != vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_4)) { |
| 757 LOG_ERROR("Could not create JNIEnv"); | 818 LOG_ERROR("Could not create JNIEnv"); |
| 758 return -1; | 819 return -1; |
| 759 } | 820 } |
| 760 | 821 |
| 822 // Initialize SDK version info. |
| 823 LOG_INFO("%s: Retrieving SDK version info", __FUNCTION__); |
| 824 if (!InitSDKVersionInfo(env)) |
| 825 return -1; |
| 826 |
| 761 // Register native methods. | 827 // Register native methods. |
| 762 jclass linker_class; | 828 jclass linker_class; |
| 763 if (!InitClassReference(env, | 829 if (!InitClassReference(env, |
| 764 "org/chromium/base/library_loader/Linker", | 830 "org/chromium/base/library_loader/Linker", |
| 765 &linker_class)) | 831 &linker_class)) |
| 766 return -1; | 832 return -1; |
| 767 | 833 |
| 768 LOG_INFO("%s: Registering native methods", __FUNCTION__); | 834 LOG_INFO("%s: Registering native methods", __FUNCTION__); |
| 769 env->RegisterNatives(linker_class, | 835 env->RegisterNatives(linker_class, |
| 770 kNativeMethods, | 836 kNativeMethods, |
| (...skipping 15 matching lines...) Expand all Loading... |
| 786 crazy_context_t* context = GetCrazyContext(); | 852 crazy_context_t* context = GetCrazyContext(); |
| 787 crazy_context_set_java_vm(context, vm, JNI_VERSION_1_4); | 853 crazy_context_set_java_vm(context, vm, JNI_VERSION_1_4); |
| 788 | 854 |
| 789 // Register the function that the crazy linker can call to post code | 855 // Register the function that the crazy linker can call to post code |
| 790 // for later execution. | 856 // for later execution. |
| 791 crazy_context_set_callback_poster(context, &PostForLaterExecution, NULL); | 857 crazy_context_set_callback_poster(context, &PostForLaterExecution, NULL); |
| 792 | 858 |
| 793 LOG_INFO("%s: Done", __FUNCTION__); | 859 LOG_INFO("%s: Done", __FUNCTION__); |
| 794 return JNI_VERSION_1_4; | 860 return JNI_VERSION_1_4; |
| 795 } | 861 } |
| OLD | NEW |