| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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 version of the Android-specific Chromium linker that uses | 5 // This is the version of the Android-specific Chromium linker that uses |
| 6 // the Android M and later system linker to load libraries. | 6 // the Android M and later system linker to load libraries. |
| 7 | 7 |
| 8 // This source code *cannot* depend on anything from base/ or the C++ | 8 // This source code *cannot* depend on anything from base/ or the C++ |
| 9 // STL, to keep the final library small, and avoid ugly dependency issues. | 9 // STL, to keep the final library small, and avoid ugly dependency issues. |
| 10 | 10 |
| (...skipping 26 matching lines...) Expand all Loading... |
| 37 // | 37 // |
| 38 // The returned string is used to construct the path to libchrome.so when | 38 // The returned string is used to construct the path to libchrome.so when |
| 39 // loading directly from APK. | 39 // loading directly from APK. |
| 40 // | 40 // |
| 41 // |env| is the current JNI environment handle. | 41 // |env| is the current JNI environment handle. |
| 42 // |clazz| is the static class handle for org.chromium.base.Linker, | 42 // |clazz| is the static class handle for org.chromium.base.Linker, |
| 43 // and is ignored here. | 43 // and is ignored here. |
| 44 // Returns the CPU ABI string for which the linker is running. | 44 // Returns the CPU ABI string for which the linker is running. |
| 45 jstring GetCpuAbi(JNIEnv* env, jclass clazz) { | 45 jstring GetCpuAbi(JNIEnv* env, jclass clazz) { |
| 46 #if defined(__arm__) && defined(__ARM_ARCH_7A__) | 46 #if defined(__arm__) && defined(__ARM_ARCH_7A__) |
| 47 static const char* kCurrentABI = "armeabi-v7a"; | 47 static const char* kCurrentAbi = "armeabi-v7a"; |
| 48 #elif defined(__arm__) | 48 #elif defined(__arm__) |
| 49 static const char* kCurrentABI = "armeabi"; | 49 static const char* kCurrentAbi = "armeabi"; |
| 50 #elif defined(__i386__) | 50 #elif defined(__i386__) |
| 51 static const char* kCurrentABI = "x86"; | 51 static const char* kCurrentAbi = "x86"; |
| 52 #elif defined(__mips__) | 52 #elif defined(__mips__) |
| 53 static const char* kCurrentABI = "mips"; | 53 static const char* kCurrentAbi = "mips"; |
| 54 #elif defined(__x86_64__) | 54 #elif defined(__x86_64__) |
| 55 static const char* kCurrentABI = "x86_64"; | 55 static const char* kCurrentAbi = "x86_64"; |
| 56 #elif defined(__aarch64__) | 56 #elif defined(__aarch64__) |
| 57 static const char* kCurrentABI = "arm64-v8a"; | 57 static const char* kCurrentAbi = "arm64-v8a"; |
| 58 #else | 58 #else |
| 59 #error "Unsupported target abi" | 59 #error "Unsupported target abi" |
| 60 #endif | 60 #endif |
| 61 return env->NewStringUTF(kCurrentABI); | 61 return env->NewStringUTF(kCurrentAbi); |
| 62 } | 62 } |
| 63 | 63 |
| 64 // Convenience wrapper around dlsym() on the main executable. Returns | 64 // Convenience wrapper around dlsym() on the main executable. Returns |
| 65 // the address of the requested symbol, or nullptr if not found. Status | 65 // the address of the requested symbol, or nullptr if not found. Status |
| 66 // is available from dlerror(). | 66 // is available from dlerror(). |
| 67 void* Dlsym(const char* symbol_name) { | 67 void* Dlsym(const char* symbol_name) { |
| 68 static void* handle = nullptr; | 68 static void* handle = nullptr; |
| 69 | 69 |
| 70 if (!handle) | 70 if (!handle) |
| 71 handle = dlopen(nullptr, RTLD_NOW); | 71 handle = dlopen(nullptr, RTLD_NOW); |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 134 if (!function_ptr) { | 134 if (!function_ptr) { |
| 135 LOG_ERROR("dlsym: android_dlopen_ext: %s", dlerror()); | 135 LOG_ERROR("dlsym: android_dlopen_ext: %s", dlerror()); |
| 136 return false; | 136 return false; |
| 137 } | 137 } |
| 138 } | 138 } |
| 139 | 139 |
| 140 const android_dlextinfo* extinfo = &dlextinfo->extinfo; | 140 const android_dlextinfo* extinfo = &dlextinfo->extinfo; |
| 141 LOG_INFO( | 141 LOG_INFO( |
| 142 "android_dlopen_ext:" | 142 "android_dlopen_ext:" |
| 143 " flags=0x%llx, reserved_addr=%p, reserved_size=%d, relro_fd=%d", | 143 " flags=0x%llx, reserved_addr=%p, reserved_size=%d, relro_fd=%d", |
| 144 extinfo->flags, extinfo->reserved_addr, extinfo->reserved_size, | 144 static_cast<long long>(extinfo->flags), extinfo->reserved_addr, |
| 145 extinfo->relro_fd); | 145 static_cast<int>(extinfo->reserved_size), extinfo->relro_fd); |
| 146 | 146 |
| 147 *status = (*function_ptr)(filename, flag, extinfo); | 147 *status = (*function_ptr)(filename, flag, extinfo); |
| 148 return true; | 148 return true; |
| 149 } | 149 } |
| 150 | 150 |
| 151 // Callback data for FindLoadedLibrarySize(). | 151 // Callback data for FindLoadedLibrarySize(). |
| 152 struct CallbackData { | 152 struct CallbackData { |
| 153 explicit CallbackData(void* address) : load_address(address), load_size(0) {} | 153 explicit CallbackData(void* address) : load_address(address), load_size(0) {} |
| 154 | 154 |
| 155 const void* load_address; | 155 const void* load_address; |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 230 if (addr < reinterpret_cast<void*>(kBreakpadGuardRegionBytes)) { | 230 if (addr < reinterpret_cast<void*>(kBreakpadGuardRegionBytes)) { |
| 231 LOG_ERROR("Fixed address %p is too low to accommodate Breakpad guard", | 231 LOG_ERROR("Fixed address %p is too low to accommodate Breakpad guard", |
| 232 addr); | 232 addr); |
| 233 addr_ = MAP_FAILED; | 233 addr_ = MAP_FAILED; |
| 234 size_ = 0; | 234 size_ = 0; |
| 235 return; | 235 return; |
| 236 } | 236 } |
| 237 addr = reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(addr) - | 237 addr = reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(addr) - |
| 238 kBreakpadGuardRegionBytes); | 238 kBreakpadGuardRegionBytes); |
| 239 } | 239 } |
| 240 LOG_INFO("Added %d to size, for Breakpad guard", kBreakpadGuardRegionBytes); | 240 LOG_INFO("Added %d to size, for Breakpad guard", |
| 241 static_cast<int>(kBreakpadGuardRegionBytes)); |
| 241 #endif | 242 #endif |
| 242 | 243 |
| 243 addr_ = mmap(addr, size, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); | 244 addr_ = mmap(addr, size, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); |
| 244 if (addr_ != MAP_FAILED) { | 245 if (addr_ != MAP_FAILED) { |
| 245 size_ = size; | 246 size_ = size; |
| 246 } else { | 247 } else { |
| 247 LOG_INFO("mmap failed: %s", strerror(errno)); | 248 LOG_INFO("mmap failed: %s", strerror(errno)); |
| 248 size_ = 0; | 249 size_ = 0; |
| 249 } | 250 } |
| 250 effective_addr_ = addr_; | 251 effective_addr_ = addr_; |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 285 *load_size = callback_data.load_size; | 286 *load_size = callback_data.load_size; |
| 286 return true; | 287 return true; |
| 287 } | 288 } |
| 288 | 289 |
| 289 // Helper for LoadLibrary(). We reserve an address space larger than | 290 // Helper for LoadLibrary(). We reserve an address space larger than |
| 290 // needed. After library loading we want to trim that reservation to only | 291 // needed. After library loading we want to trim that reservation to only |
| 291 // what is needed. | 292 // what is needed. |
| 292 bool ResizeReservedAddressSpace(void* addr, | 293 bool ResizeReservedAddressSpace(void* addr, |
| 293 size_t reserved_size, | 294 size_t reserved_size, |
| 294 size_t load_size) { | 295 size_t load_size) { |
| 295 LOG_INFO("Called for %p, reserved %d, loaded %d", addr, reserved_size, | 296 LOG_INFO("Called for %p, reserved %d, loaded %d", addr, |
| 296 load_size); | 297 static_cast<int>(reserved_size), static_cast<int>(load_size)); |
| 297 | 298 |
| 298 if (reserved_size < load_size) { | 299 if (reserved_size < load_size) { |
| 299 LOG_ERROR("WARNING: library reservation was too small"); | 300 LOG_ERROR("WARNING: library reservation was too small"); |
| 300 return true; | 301 return true; |
| 301 } | 302 } |
| 302 | 303 |
| 303 // Unmap the part of the reserved address space that is beyond the end of | 304 // Unmap the part of the reserved address space that is beyond the end of |
| 304 // the loaded library data. | 305 // the loaded library data. |
| 305 void* unmap = | 306 void* unmap = |
| 306 reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(addr) + load_size); | 307 reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(addr) + load_size); |
| (...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 586 env->RegisterNatives(linker_class, kNativeMethods, | 587 env->RegisterNatives(linker_class, kNativeMethods, |
| 587 sizeof(kNativeMethods) / sizeof(kNativeMethods[0])); | 588 sizeof(kNativeMethods) / sizeof(kNativeMethods[0])); |
| 588 | 589 |
| 589 // Record the Java VM handle. | 590 // Record the Java VM handle. |
| 590 s_java_vm = vm; | 591 s_java_vm = vm; |
| 591 | 592 |
| 592 return true; | 593 return true; |
| 593 } | 594 } |
| 594 | 595 |
| 595 } // namespace chromium_android_linker | 596 } // namespace chromium_android_linker |
| OLD | NEW |