Commit 3211be67 authored by Andrew Grieve's avatar Andrew Grieve Committed by Commit Bot

Android: Switch crazy linker to use implicit JNI registration

Hoping that this will resolve kitkat crashes where the JNI is
looking for a LegacyLinker method on the Linker class (see bug).

Bug: 849554
Change-Id: I11389b76142ead6281194cf6f363c8783d3ddbbc
Reviewed-on: https://chromium-review.googlesource.com/1088875
Commit-Queue: agrieve <agrieve@chromium.org>
Reviewed-by: default avatarEgor Pasko <pasko@chromium.org>
Cr-Commit-Position: refs/heads/master@{#565001}
parent fc5da42b
...@@ -18,6 +18,11 @@ shared_library("chromium_android_linker") { ...@@ -18,6 +18,11 @@ shared_library("chromium_android_linker") {
# '<(android_ndk_root)/crazy_linker.gyp:crazy_linker' # '<(android_ndk_root)/crazy_linker.gyp:crazy_linker'
# However, we use our own fork. See bug 384700. # However, we use our own fork. See bug 384700.
deps = [ deps = [
"//build:buildflag_header_h",
"//third_party/android_crazy_linker", "//third_party/android_crazy_linker",
] ]
# Export JNI symbols.
configs -= [ "//build/config/android:hide_all_but_jni_onload" ]
configs += [ "//build/config/android:hide_all_but_jni" ]
} }
...@@ -181,11 +181,13 @@ bool ZipLibraryOpener::Open(crazy_library_t** library, ...@@ -181,11 +181,13 @@ bool ZipLibraryOpener::Open(crazy_library_t** library,
// |library_info| is a LibInfo handle used to communicate information // |library_info| is a LibInfo handle used to communicate information
// with the Java side. // with the Java side.
// Return true on success. // Return true on success.
jboolean LoadLibrary(JNIEnv* env, JNI_GENERATOR_EXPORT jboolean
jclass clazz, Java_org_chromium_base_library_1loader_LegacyLinker_nativeLoadLibrary(
jstring library_name, JNIEnv* env,
jlong load_address, jclass clazz,
jobject lib_info_obj) { jstring library_name,
jlong load_address,
jobject lib_info_obj) {
String lib_name(env, library_name); String lib_name(env, library_name);
FileLibraryOpener opener; FileLibraryOpener opener;
...@@ -218,12 +220,14 @@ jboolean LoadLibrary(JNIEnv* env, ...@@ -218,12 +220,14 @@ jboolean LoadLibrary(JNIEnv* env,
// |library_info| is a LibInfo handle used to communicate information // |library_info| is a LibInfo handle used to communicate information
// with the Java side. // with the Java side.
// Returns true on success. // Returns true on success.
jboolean LoadLibraryInZipFile(JNIEnv* env, JNI_GENERATOR_EXPORT jboolean
jclass clazz, Java_org_chromium_base_library_1loader_LegacyLinker_nativeLoadLibraryInZipFile(
jstring zipfile_name, JNIEnv* env,
jstring library_name, jclass clazz,
jlong load_address, jstring zipfile_name,
jobject lib_info_obj) { jstring library_name,
jlong load_address,
jobject lib_info_obj) {
String zipfile_name_str(env, zipfile_name); String zipfile_name_str(env, zipfile_name);
String lib_name(env, library_name); String lib_name(env, library_name);
ZipLibraryOpener opener(zipfile_name_str.c_str()); ZipLibraryOpener opener(zipfile_name_str.c_str());
...@@ -260,7 +264,11 @@ static JavaCallbackBindings_class s_java_callback_bindings; ...@@ -260,7 +264,11 @@ static JavaCallbackBindings_class s_java_callback_bindings;
// |clazz| is the static class handle for org.chromium.base.Linker, // |clazz| is the static class handle for org.chromium.base.Linker,
// and is ignored here. // and is ignored here.
// |arg| is a pointer to an allocated crazy_callback_t, deleted after use. // |arg| is a pointer to an allocated crazy_callback_t, deleted after use.
void RunCallbackOnUiThread(JNIEnv* env, jclass clazz, jlong arg) { JNI_GENERATOR_EXPORT void
Java_org_chromium_base_library_1loader_LegacyLinker_nativeRunCallbackOnUiThread(
JNIEnv* env,
jclass clazz,
jlong arg) {
crazy_callback_t* callback = reinterpret_cast<crazy_callback_t*>(arg); crazy_callback_t* callback = reinterpret_cast<crazy_callback_t*>(arg);
LOG_INFO("Called back from java with handler %p, opaque %p", LOG_INFO("Called back from java with handler %p, opaque %p",
...@@ -319,11 +327,13 @@ static bool PostForLaterExecution(crazy_callback_t* callback_request, ...@@ -319,11 +327,13 @@ static bool PostForLaterExecution(crazy_callback_t* callback_request,
return true; return true;
} }
jboolean CreateSharedRelro(JNIEnv* env, JNI_GENERATOR_EXPORT jboolean
jclass clazz, Java_org_chromium_base_library_1loader_LegacyLinker_nativeCreateSharedRelro(
jstring library_name, JNIEnv* env,
jlong load_address, jclass clazz,
jobject lib_info_obj) { jstring library_name,
jlong load_address,
jobject lib_info_obj) {
String lib_name(env, library_name); String lib_name(env, library_name);
LOG_INFO("Called for %s", lib_name.c_str()); LOG_INFO("Called for %s", lib_name.c_str());
...@@ -362,10 +372,12 @@ jboolean CreateSharedRelro(JNIEnv* env, ...@@ -362,10 +372,12 @@ jboolean CreateSharedRelro(JNIEnv* env,
return true; return true;
} }
jboolean UseSharedRelro(JNIEnv* env, JNI_GENERATOR_EXPORT jboolean
jclass clazz, Java_org_chromium_base_library_1loader_LegacyLinker_nativeUseSharedRelro(
jstring library_name, JNIEnv* env,
jobject lib_info_obj) { jclass clazz,
jstring library_name,
jobject lib_info_obj) {
String lib_name(env, library_name); String lib_name(env, library_name);
LOG_INFO("Called for %s, lib_info_ref=%p", lib_name.c_str(), lib_info_obj); LOG_INFO("Called for %s, lib_info_ref=%p", lib_name.c_str(), lib_info_obj);
...@@ -400,50 +412,6 @@ jboolean UseSharedRelro(JNIEnv* env, ...@@ -400,50 +412,6 @@ jboolean UseSharedRelro(JNIEnv* env,
return true; return true;
} }
const JNINativeMethod kNativeMethods[] = {
{"nativeLoadLibrary",
"("
"Ljava/lang/String;"
"J"
"Lorg/chromium/base/library_loader/Linker$LibInfo;"
")"
"Z",
reinterpret_cast<void*>(&LoadLibrary)},
{"nativeLoadLibraryInZipFile",
"("
"Ljava/lang/String;"
"Ljava/lang/String;"
"J"
"Lorg/chromium/base/library_loader/Linker$LibInfo;"
")"
"Z",
reinterpret_cast<void*>(&LoadLibraryInZipFile)},
{"nativeRunCallbackOnUiThread",
"("
"J"
")"
"V",
reinterpret_cast<void*>(&RunCallbackOnUiThread)},
{"nativeCreateSharedRelro",
"("
"Ljava/lang/String;"
"J"
"Lorg/chromium/base/library_loader/Linker$LibInfo;"
")"
"Z",
reinterpret_cast<void*>(&CreateSharedRelro)},
{"nativeUseSharedRelro",
"("
"Ljava/lang/String;"
"Lorg/chromium/base/library_loader/Linker$LibInfo;"
")"
"Z",
reinterpret_cast<void*>(&UseSharedRelro)},
};
const size_t kNumNativeMethods =
sizeof(kNativeMethods) / sizeof(kNativeMethods[0]);
} // namespace } // namespace
bool LegacyLinkerJNIInit(JavaVM* vm, JNIEnv* env) { bool LegacyLinkerJNIInit(JavaVM* vm, JNIEnv* env) {
...@@ -461,10 +429,6 @@ bool LegacyLinkerJNIInit(JavaVM* vm, JNIEnv* env) { ...@@ -461,10 +429,6 @@ bool LegacyLinkerJNIInit(JavaVM* vm, JNIEnv* env) {
&linker_class)) &linker_class))
return false; return false;
LOG_INFO("Registering native methods");
if (env->RegisterNatives(linker_class, kNativeMethods, kNumNativeMethods) < 0)
return false;
// Resolve and save the Java side Linker callback class and method. // Resolve and save the Java side Linker callback class and method.
LOG_INFO("Resolving callback bindings"); LOG_INFO("Resolving callback bindings");
if (!s_java_callback_bindings.Init(env, linker_class)) { if (!s_java_callback_bindings.Init(env, linker_class)) {
......
...@@ -147,7 +147,10 @@ bool InitStaticInt(JNIEnv* env, ...@@ -147,7 +147,10 @@ bool InitStaticInt(JNIEnv* env,
// then loads the library normally at any available address. // then loads the library normally at any available address.
// |env| is the current JNI environment handle, and |clazz| a class. // |env| is the current JNI environment handle, and |clazz| a class.
// Returns the address selected by ASLR, or 0 on error. // Returns the address selected by ASLR, or 0 on error.
jlong GetRandomBaseLoadAddress(JNIEnv* env, jclass clazz) { JNI_GENERATOR_EXPORT jlong
Java_org_chromium_base_library_1loader_Linker_nativeGetRandomBaseLoadAddress(
JNIEnv* env,
jclass clazz) {
size_t bytes = kAddressSpaceReservationSize; size_t bytes = kAddressSpaceReservationSize;
#if RESERVE_BREAKPAD_GUARD_REGION #if RESERVE_BREAKPAD_GUARD_REGION
...@@ -175,32 +178,8 @@ jlong GetRandomBaseLoadAddress(JNIEnv* env, jclass clazz) { ...@@ -175,32 +178,8 @@ jlong GetRandomBaseLoadAddress(JNIEnv* env, jclass clazz) {
namespace { namespace {
const JNINativeMethod kNativeMethods[] = {
{"nativeGetRandomBaseLoadAddress",
"("
")"
"J",
reinterpret_cast<void*>(&GetRandomBaseLoadAddress)},
};
const size_t kNumNativeMethods =
sizeof(kNativeMethods) / sizeof(kNativeMethods[0]);
// JNI_OnLoad() initialization hook. // JNI_OnLoad() initialization hook.
bool LinkerJNIInit(JavaVM* vm, JNIEnv* env) { bool LinkerJNIInit(JavaVM* vm, JNIEnv* env) {
LOG_INFO("Entering");
// Register native methods.
jclass linker_class;
if (!InitClassReference(env,
"org/chromium/base/library_loader/Linker",
&linker_class))
return false;
LOG_INFO("Registering native methods");
if (env->RegisterNatives(linker_class, kNativeMethods, kNumNativeMethods) < 0)
return false;
// Find LibInfo field ids. // Find LibInfo field ids.
LOG_INFO("Caching field IDs"); LOG_INFO("Caching field IDs");
if (!s_lib_info_fields.Init(env)) { if (!s_lib_info_fields.Init(env)) {
......
...@@ -21,6 +21,8 @@ ...@@ -21,6 +21,8 @@
#include <stddef.h> #include <stddef.h>
#include <stdlib.h> #include <stdlib.h>
#include "build/build_config.h"
// Set this to 1 to enable debug traces to the Android log. // Set this to 1 to enable debug traces to the Android log.
// Note that LOG() from "base/logging.h" cannot be used, since it is // Note that LOG() from "base/logging.h" cannot be used, since it is
// in base/ which hasn't been loaded yet. // in base/ which hasn't been loaded yet.
...@@ -48,6 +50,16 @@ ...@@ -48,6 +50,16 @@
// https://crbug.com/504410 // https://crbug.com/504410
#define RESERVE_BREAKPAD_GUARD_REGION 1 #define RESERVE_BREAKPAD_GUARD_REGION 1
#if defined(ARCH_CPU_X86)
// Dalvik JIT generated code doesn't guarantee 16-byte stack alignment on
// x86 - use force_align_arg_pointer to realign the stack at the JNI
// boundary. https://crbug.com/655248
#define JNI_GENERATOR_EXPORT \
extern "C" __attribute__((visibility("default"), force_align_arg_pointer))
#else
#define JNI_GENERATOR_EXPORT extern "C" __attribute__((visibility("default")))
#endif
namespace chromium_android_linker { namespace chromium_android_linker {
// Larger than the largest library we might attempt to load. // Larger than the largest library we might attempt to load.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment