diff options
author | Dmitriy Ivanov <dimitry@google.com> | 2014-07-18 10:08:57 -0700 |
---|---|---|
committer | Dmitriy Ivanov <dimitry@google.com> | 2015-03-23 11:38:54 -0700 |
commit | 785049f8083e56e88dfeab5ff74fb3817f9854e3 (patch) | |
tree | ab06a7fb4acb2ed73eed4b58327ba485f61560c4 /runtime | |
parent | f5988cf0c47ff935bb19c89ed0398be5fbe44bb6 (diff) | |
download | art-785049f8083e56e88dfeab5ff74fb3817f9854e3.zip art-785049f8083e56e88dfeab5ff74fb3817f9854e3.tar.gz art-785049f8083e56e88dfeab5ff74fb3817f9854e3.tar.bz2 |
Add paths to apk!lib/<abi> to LD_LIBRARY_PATH
Add paths to .apk to LD_LIBRARY_PATH to enable
bionic linker's "open from zip-file" feature.
Bug: 8076853
Change-Id: I1aa2c039bb2a590ae72f256acc9ba5401c2c59b1
Diffstat (limited to 'runtime')
-rw-r--r-- | runtime/java_vm_ext.cc | 2 | ||||
-rw-r--r-- | runtime/native/java_lang_Runtime.cc | 69 | ||||
-rw-r--r-- | runtime/parsed_options.cc | 3 | ||||
-rw-r--r-- | runtime/runtime.cc | 2 | ||||
-rw-r--r-- | runtime/runtime.h | 7 | ||||
-rw-r--r-- | runtime/runtime_options.def | 1 | ||||
-rw-r--r-- | runtime/well_known_classes.cc | 2 |
7 files changed, 64 insertions, 22 deletions
diff --git a/runtime/java_vm_ext.cc b/runtime/java_vm_ext.cc index e68616f..13f3573 100644 --- a/runtime/java_vm_ext.cc +++ b/runtime/java_vm_ext.cc @@ -644,7 +644,7 @@ bool JavaVMExt::LoadNativeLibrary(JNIEnv* env, const std::string& path, jobject if (handle == nullptr) { *error_msg = dlerror(); - LOG(ERROR) << "dlopen(\"" << path << "\", RTLD_LAZY) failed: " << *error_msg; + VLOG(jni) << "dlopen(\"" << path << "\", RTLD_LAZY) failed: " << *error_msg; return false; } diff --git a/runtime/native/java_lang_Runtime.cc b/runtime/native/java_lang_Runtime.cc index 84b18ab..bd043a8 100644 --- a/runtime/native/java_lang_Runtime.cc +++ b/runtime/native/java_lang_Runtime.cc @@ -30,6 +30,12 @@ #include "ScopedUtfChars.h" #include "verify_object-inl.h" +#include <sstream> +#ifdef HAVE_ANDROID_OS +// This function is provided by android linker. +extern "C" void android_update_LD_LIBRARY_PATH(const char* ld_library_path); +#endif // HAVE_ANDROID_OS + namespace art { static void Runtime_gc(JNIEnv*, jclass) { @@ -46,30 +52,53 @@ NO_RETURN static void Runtime_nativeExit(JNIEnv*, jclass, jint status) { exit(status); } -static jstring Runtime_nativeLoad(JNIEnv* env, jclass, jstring javaFilename, jobject javaLoader, - jstring javaLdLibraryPath) { - // TODO: returns NULL on success or an error message describing the failure on failure. This - // should be refactored in terms of suppressed exceptions. - ScopedUtfChars filename(env, javaFilename); - if (filename.c_str() == NULL) { - return NULL; +static void SetLdLibraryPath(JNIEnv* env, jstring javaLdLibraryPathJstr, jstring javaDexPathJstr) { +#ifdef HAVE_ANDROID_OS + std::stringstream ss; + if (javaLdLibraryPathJstr != nullptr) { + ScopedUtfChars javaLdLibraryPath(env, javaLdLibraryPathJstr); + if (javaLdLibraryPath.c_str() != nullptr) { + ss << javaLdLibraryPath.c_str(); + } } - if (javaLdLibraryPath != NULL) { - ScopedUtfChars ldLibraryPath(env, javaLdLibraryPath); - if (ldLibraryPath.c_str() == NULL) { - return NULL; - } - void* sym = dlsym(RTLD_DEFAULT, "android_update_LD_LIBRARY_PATH"); - if (sym != NULL) { - typedef void (*Fn)(const char*); - Fn android_update_LD_LIBRARY_PATH = reinterpret_cast<Fn>(sym); - (*android_update_LD_LIBRARY_PATH)(ldLibraryPath.c_str()); - } else { - LOG(WARNING) << "android_update_LD_LIBRARY_PATH not found; .so dependencies will not work!"; + if (javaDexPathJstr != nullptr) { + ScopedUtfChars javaDexPath(env, javaDexPathJstr); + if (javaDexPath.c_str() != nullptr) { + std::vector<std::string> dexPathVector; + Split(javaDexPath.c_str(), ':', &dexPathVector); + + for (auto abi : art::Runtime::Current()->GetCpuAbilist()) { + for (auto zip_path : dexPathVector) { + // Native libraries live under lib/<abi>/ inside .apk file. + ss << ":" << zip_path << "!" << "lib/" << abi; + } + } } } + std::string ldLibraryPathStr = ss.str(); + const char* ldLibraryPath = ldLibraryPathStr.c_str(); + if (*ldLibraryPath == ':') { + ++ldLibraryPath; + } + + android_update_LD_LIBRARY_PATH(ldLibraryPath); +#else + LOG(WARNING) << "android_update_LD_LIBRARY_PATH not found; .so dependencies will not work!"; + UNUSED(javaLdLibraryPathJstr, javaDexPathJstr, env); +#endif +} + +static jstring Runtime_nativeLoad(JNIEnv* env, jclass, jstring javaFilename, jobject javaLoader, + jstring javaLdLibraryPathJstr, jstring javaDexPathJstr) { + ScopedUtfChars filename(env, javaFilename); + if (filename.c_str() == nullptr) { + return nullptr; + } + + SetLdLibraryPath(env, javaLdLibraryPathJstr, javaDexPathJstr); + std::string error_msg; { JavaVMExt* vm = Runtime::Current()->GetJavaVM(); @@ -101,7 +130,7 @@ static JNINativeMethod gMethods[] = { NATIVE_METHOD(Runtime, gc, "()V"), NATIVE_METHOD(Runtime, maxMemory, "!()J"), NATIVE_METHOD(Runtime, nativeExit, "(I)V"), - NATIVE_METHOD(Runtime, nativeLoad, "(Ljava/lang/String;Ljava/lang/ClassLoader;Ljava/lang/String;)Ljava/lang/String;"), + NATIVE_METHOD(Runtime, nativeLoad, "(Ljava/lang/String;Ljava/lang/ClassLoader;Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;"), NATIVE_METHOD(Runtime, totalMemory, "!()J"), }; diff --git a/runtime/parsed_options.cc b/runtime/parsed_options.cc index a53aeaa..337c5df 100644 --- a/runtime/parsed_options.cc +++ b/runtime/parsed_options.cc @@ -255,6 +255,9 @@ std::unique_ptr<RuntimeParser> ParsedOptions::MakeParser(bool ignore_unrecognize .IntoKey(M::ZygoteMaxFailedBoots) .Define("-Xno-dex-file-fallback") .IntoKey(M::NoDexFileFallback) + .Define("--cpu-abilist=_") + .WithType<std::string>() + .IntoKey(M::CpuAbiList) .Ignore({ "-ea", "-da", "-enableassertions", "-disableassertions", "--runtime-arg", "-esa", "-dsa", "-enablesystemassertions", "-disablesystemassertions", "-Xrs", "-Xint:_", diff --git a/runtime/runtime.cc b/runtime/runtime.cc index 0f0c327..2dacfe2 100644 --- a/runtime/runtime.cc +++ b/runtime/runtime.cc @@ -792,6 +792,8 @@ bool Runtime::Init(const RuntimeOptions& raw_options, bool ignore_unrecognized) verify_ = runtime_options.GetOrDefault(Opt::Verify); allow_dex_file_fallback_ = !runtime_options.Exists(Opt::NoDexFileFallback); + Split(runtime_options.GetOrDefault(Opt::CpuAbiList), ',', &cpu_abilist_); + if (runtime_options.GetOrDefault(Opt::Interpret)) { GetInstrumentation()->ForceInterpretOnly(); } diff --git a/runtime/runtime.h b/runtime/runtime.h index 7f33547..9a04835 100644 --- a/runtime/runtime.h +++ b/runtime/runtime.h @@ -524,6 +524,10 @@ class Runtime { return allow_dex_file_fallback_; } + const std::vector<std::string>& GetCpuAbilist() const { + return cpu_abilist_; + } + bool RunningOnValgrind() const { return running_on_valgrind_; } @@ -706,6 +710,9 @@ class Runtime { // available/usable. bool allow_dex_file_fallback_; + // List of supported cpu abis. + std::vector<std::string> cpu_abilist_; + // Specifies target SDK version to allow workarounds for certain API levels. int32_t target_sdk_version_; diff --git a/runtime/runtime_options.def b/runtime/runtime_options.def index 8775f8d..6401d44 100644 --- a/runtime/runtime_options.def +++ b/runtime/runtime_options.def @@ -104,6 +104,7 @@ RUNTIME_OPTIONS_KEY (std::vector<std::string>, \ ImageCompilerOptions) // -Ximage-compiler-option ... RUNTIME_OPTIONS_KEY (bool, Verify, true) RUNTIME_OPTIONS_KEY (std::string, NativeBridge) +RUNTIME_OPTIONS_KEY (std::string, CpuAbiList) // Not parse-able from command line, but can be provided explicitly. RUNTIME_OPTIONS_KEY (const std::vector<const DexFile*>*, \ diff --git a/runtime/well_known_classes.cc b/runtime/well_known_classes.cc index 78185bf..00b4cef 100644 --- a/runtime/well_known_classes.cc +++ b/runtime/well_known_classes.cc @@ -269,7 +269,7 @@ void WellKnownClasses::Init(JNIEnv* env) { void WellKnownClasses::LateInit(JNIEnv* env) { ScopedLocalRef<jclass> java_lang_Runtime(env, env->FindClass("java/lang/Runtime")); - java_lang_Runtime_nativeLoad = CacheMethod(env, java_lang_Runtime.get(), true, "nativeLoad", "(Ljava/lang/String;Ljava/lang/ClassLoader;Ljava/lang/String;)Ljava/lang/String;"); + java_lang_Runtime_nativeLoad = CacheMethod(env, java_lang_Runtime.get(), true, "nativeLoad", "(Ljava/lang/String;Ljava/lang/ClassLoader;Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;"); } mirror::Class* WellKnownClasses::ToClass(jclass global_jclass) { |