ld.mc uses libcompier_rt and libRSDriver from the vndk-sp directory

When ld.mc links the compiled bc, it now correctly uses libcompiler_rt
and libRSDriver from the vndk-sp directory. This is because when the bc
is loaded inside the app process, it is provided with the libs in
vndk-sp directory.

Bug: 62848943
Test: Renderscript app (e.g. CameraScript) runs well.
Test: logcat | grep ld.mc shows /system/lib/vndk-sp/libcompiler_rt.so
and --library-path=/system/lib/vndk-sp

Change-Id: Ib6354081af797f395ff042ebe87731311d768784
diff --git a/cpu_ref/rsCpuExecutable.cpp b/cpu_ref/rsCpuExecutable.cpp
index 83ef757..c42ea0f 100644
--- a/cpu_ref/rsCpuExecutable.cpp
+++ b/cpu_ref/rsCpuExecutable.cpp
@@ -94,6 +94,22 @@
     return scriptSOName;
 }
 
+#ifndef RS_COMPATIBILITY_LIB
+static bool isRunningInVndkNamespace() {
+    static bool result = []() {
+        Dl_info info;
+        if (dladdr(reinterpret_cast<const void*>(&isRunningInVndkNamespace), &info) != 0) {
+            std::string filename = std::string(info.dli_fname);
+            return filename.find("/vndk-sp") != std::string::npos;
+        } else {
+            ALOGW("Can't determine whether this lib is running in vndk namespace or not. Assuming it is in vndk namespace.");
+        }
+        return true;
+    }();
+    return result;
+}
+#endif
+
 }  // anonymous namespace
 
 const char* SharedLibraryUtils::LD_EXE_PATH = "/system/bin/ld.mc";
@@ -121,16 +137,24 @@
     linkDriverName.erase(linkDriverName.length() - 3);
     linkDriverName.replace(0, 3, "-l");
 
-    const char *compiler_rt = SYSLIBPATH"/libcompiler_rt.so";
+    const char *compiler_rt = isRunningInVndkNamespace() ?
+        SYSLIBPATH_VNDK "/libcompiler_rt.so" : SYSLIBPATH "/libcompiler_rt.so";
     const char *mTriple = "-mtriple=" DEFAULT_TARGET_TRIPLE_STRING;
     const char *libPath = "--library-path=" SYSLIBPATH;
+    // vndk path is only added when RS framework is running in vndk namespace.
+    // If we unconditionally add the vndk path to the library path, then RS
+    // driver in the vndk-sp directory will always be used even for CPU fallback
+    // case, where RS framework is loaded from the default namespace.
+    const char *vndkLibPath = isRunningInVndkNamespace() ?
+        "--library-path=" SYSLIBPATH_VNDK : "";
     const char *vendorLibPath = "--library-path=" SYSLIBPATH_VENDOR;
 
+    // The search path order should be vendor -> vndk -> system
     std::vector<const char *> args = {
         LD_EXE_PATH,
         "-shared",
         "-nostdlib",
-        compiler_rt, mTriple, vendorLibPath, libPath,
+        compiler_rt, mTriple, vendorLibPath, vndkLibPath, libPath,
         linkDriverName.c_str(), "-lm", "-lc",
         objFileName.c_str(),
         "-o", sharedLibName.c_str(),
diff --git a/cpu_ref/rsCpuScript.cpp b/cpu_ref/rsCpuScript.cpp
index f2f3d2e..e42be8e 100644
--- a/cpu_ref/rsCpuScript.cpp
+++ b/cpu_ref/rsCpuScript.cpp
@@ -162,6 +162,7 @@
 // reinstalled, which would already clear the code_cache/ directory.
 bool isChecksumNeeded(const char *cacheDir) {
     if ((::strcmp(SYSLIBPATH, cacheDir) == 0) ||
+        (::strcmp(SYSLIBPATH_VNDK, cacheDir) == 0) ||
         (::strcmp(SYSLIBPATH_VENDOR, cacheDir) == 0))
         return false;
     char buf[PROP_VALUE_MAX];
diff --git a/cpu_ref/rsCpuScript.h b/cpu_ref/rsCpuScript.h
index dc96f8b..bd192ab 100644
--- a/cpu_ref/rsCpuScript.h
+++ b/cpu_ref/rsCpuScript.h
@@ -157,14 +157,17 @@
 
 #ifdef __LP64__
 #define SYSLIBPATH "/system/lib64"
+#define SYSLIBPATH_VNDK "/system/lib64/vndk-sp"
 #define SYSLIBPATH_BC "/system/lib64"
 #define SYSLIBPATH_VENDOR "/system/vendor/lib64"
 #elif defined(BUILD_ARM_FOR_X86) && defined(__arm__)
 #define SYSLIBPATH "/system/lib/arm"
+#define SYSLIBPATH_VNDK "/system/lib/arm/vndk-sp"
 #define SYSLIBPATH_BC "/system/lib"
 #define SYSLIBPATH_VENDOR "/system/vendor/lib/arm"
 #else
 #define SYSLIBPATH "/system/lib"
+#define SYSLIBPATH_VNDK "/system/lib/vndk-sp"
 #define SYSLIBPATH_BC "/system/lib"
 #define SYSLIBPATH_VENDOR "/system/vendor/lib"
 #endif