12abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni#include "rsCpuExecutable.h" 22abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni#include "rsCppUtils.h" 32abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 42abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni#include <fstream> 52abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni#include <set> 62abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni#include <memory> 72abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 82a61168a777ee434ce2c28945aa74f6a6bcf2820Miao Wang#include <sys/stat.h> 92a61168a777ee434ce2c28945aa74f6a6bcf2820Miao Wang 102abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni#ifdef RS_COMPATIBILITY_LIB 112abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni#include <stdio.h> 122abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni#else 1303fab68da223638671c6e21864283e25bb1fec41Jean-Luc Brouillet#include "bcc/Config.h" 142abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni#endif 152abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 16316ffa59464f42ac94fd5f992f608c7767001e6dJiyong Park#include <unistd.h> 172abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni#include <dlfcn.h> 182536d3fdafb08cef53b9f099e966dbbe82943a85Mathias Agopian#include <sys/stat.h> 192abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 202abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ninamespace android { 212abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ninamespace renderscript { 222abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 232abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ninamespace { 242abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 252abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni// Check if a path exists and attempt to create it if it doesn't. 262abfcc6d129fe3defddef4540aa95cc445c03a7aYang Nistatic bool ensureCacheDirExists(const char *path) { 272abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni if (access(path, R_OK | W_OK | X_OK) == 0) { 282abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni // Done if we can rwx the directory 292abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni return true; 302abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni } 312abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni if (mkdir(path, 0700) == 0) { 322abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni return true; 332abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni } 342abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni return false; 352abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni} 362abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 372abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni// Copy the file named \p srcFile to \p dstFile. 382abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni// Return 0 on success and -1 if anything wasn't copied. 392abfcc6d129fe3defddef4540aa95cc445c03a7aYang Nistatic int copyFile(const char *dstFile, const char *srcFile) { 402abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni std::ifstream srcStream(srcFile); 412abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni if (!srcStream) { 422abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni ALOGE("Could not verify or read source file: %s", srcFile); 432abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni return -1; 442abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni } 452abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni std::ofstream dstStream(dstFile); 462abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni if (!dstStream) { 472abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni ALOGE("Could not verify or write destination file: %s", dstFile); 482abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni return -1; 492abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni } 502abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni dstStream << srcStream.rdbuf(); 512abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni if (!dstStream) { 522abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni ALOGE("Could not write destination file: %s", dstFile); 532abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni return -1; 542abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni } 552abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 562abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni srcStream.close(); 572abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni dstStream.close(); 582abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 592abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni return 0; 602abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni} 612abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 622abfcc6d129fe3defddef4540aa95cc445c03a7aYang Nistatic std::string findSharedObjectName(const char *cacheDir, 63a845c35880f8434619ac299e8af47aa6a5049e8dYang Ni const char *resName, 64a845c35880f8434619ac299e8af47aa6a5049e8dYang Ni const bool reuse = true) { 652abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni std::string scriptSOName(cacheDir); 662abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni#if defined(RS_COMPATIBILITY_LIB) && !defined(__LP64__) 672abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni size_t cutPos = scriptSOName.rfind("cache"); 682abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni if (cutPos != std::string::npos) { 692abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni scriptSOName.erase(cutPos); 702abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni } else { 712abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni ALOGE("Found peculiar cacheDir (missing \"cache\"): %s", cacheDir); 722abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni } 732abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni scriptSOName.append("/lib/librs."); 742abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni#else 752abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni scriptSOName.append("/librs."); 762abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni#endif // RS_COMPATIBILITY_LIB 772abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni scriptSOName.append(resName); 78a845c35880f8434619ac299e8af47aa6a5049e8dYang Ni if (!reuse) { 79a845c35880f8434619ac299e8af47aa6a5049e8dYang Ni // If the generated shared library is not reused, e.g., with a debug 80a845c35880f8434619ac299e8af47aa6a5049e8dYang Ni // context or forced by a system property, multiple threads may read 81a845c35880f8434619ac299e8af47aa6a5049e8dYang Ni // and write the shared library at the same time. To avoid the race 82a845c35880f8434619ac299e8af47aa6a5049e8dYang Ni // on the generated shared library, delete it before finishing script 83a845c35880f8434619ac299e8af47aa6a5049e8dYang Ni // initialization. To avoid deleting a file generated by a regular 84a845c35880f8434619ac299e8af47aa6a5049e8dYang Ni // context, use a special suffix here. 85a845c35880f8434619ac299e8af47aa6a5049e8dYang Ni // Because the script initialization is guarded by a lock from the Java 86a845c35880f8434619ac299e8af47aa6a5049e8dYang Ni // API, it is safe to name this file with a consistent name and suffix 87a845c35880f8434619ac299e8af47aa6a5049e8dYang Ni // and delete it after loading. The same lock has also prevented write- 88a845c35880f8434619ac299e8af47aa6a5049e8dYang Ni // write races on the .so during script initialization even if reuse is 89a845c35880f8434619ac299e8af47aa6a5049e8dYang Ni // true. 90a845c35880f8434619ac299e8af47aa6a5049e8dYang Ni scriptSOName.append("#delete_after_load"); 91a845c35880f8434619ac299e8af47aa6a5049e8dYang Ni } 922abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni scriptSOName.append(".so"); 932abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 942abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni return scriptSOName; 952abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni} 962abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 97da43d5866f6224e17e756fdfea405ca4b00a38fcJiyong Park#ifndef RS_COMPATIBILITY_LIB 98da43d5866f6224e17e756fdfea405ca4b00a38fcJiyong Parkstatic bool isRunningInVndkNamespace() { 99da43d5866f6224e17e756fdfea405ca4b00a38fcJiyong Park static bool result = []() { 100da43d5866f6224e17e756fdfea405ca4b00a38fcJiyong Park Dl_info info; 101da43d5866f6224e17e756fdfea405ca4b00a38fcJiyong Park if (dladdr(reinterpret_cast<const void*>(&isRunningInVndkNamespace), &info) != 0) { 102da43d5866f6224e17e756fdfea405ca4b00a38fcJiyong Park std::string filename = std::string(info.dli_fname); 103da43d5866f6224e17e756fdfea405ca4b00a38fcJiyong Park return filename.find("/vndk-sp") != std::string::npos; 104da43d5866f6224e17e756fdfea405ca4b00a38fcJiyong Park } else { 105da43d5866f6224e17e756fdfea405ca4b00a38fcJiyong Park ALOGW("Can't determine whether this lib is running in vndk namespace or not. Assuming it is in vndk namespace."); 106da43d5866f6224e17e756fdfea405ca4b00a38fcJiyong Park } 107da43d5866f6224e17e756fdfea405ca4b00a38fcJiyong Park return true; 108da43d5866f6224e17e756fdfea405ca4b00a38fcJiyong Park }(); 109da43d5866f6224e17e756fdfea405ca4b00a38fcJiyong Park return result; 110da43d5866f6224e17e756fdfea405ca4b00a38fcJiyong Park} 111da43d5866f6224e17e756fdfea405ca4b00a38fcJiyong Park#endif 112da43d5866f6224e17e756fdfea405ca4b00a38fcJiyong Park 1132abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni} // anonymous namespace 1142abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 1152abfcc6d129fe3defddef4540aa95cc445c03a7aYang Niconst char* SharedLibraryUtils::LD_EXE_PATH = "/system/bin/ld.mc"; 1162abfcc6d129fe3defddef4540aa95cc445c03a7aYang Niconst char* SharedLibraryUtils::RS_CACHE_DIR = "com.android.renderscript.cache"; 1172abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 1182abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni#ifndef RS_COMPATIBILITY_LIB 1192abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 1204c368af7e705f0bcb77fa99495b2e33ef20d2699Stephen Hinesbool SharedLibraryUtils::createSharedLibrary(const char *driverName, 1214c368af7e705f0bcb77fa99495b2e33ef20d2699Stephen Hines const char *cacheDir, 122a845c35880f8434619ac299e8af47aa6a5049e8dYang Ni const char *resName, 123a845c35880f8434619ac299e8af47aa6a5049e8dYang Ni const bool reuse, 124a845c35880f8434619ac299e8af47aa6a5049e8dYang Ni std::string *fullPath) { 125a845c35880f8434619ac299e8af47aa6a5049e8dYang Ni std::string sharedLibName = findSharedObjectName(cacheDir, resName, reuse); 126a845c35880f8434619ac299e8af47aa6a5049e8dYang Ni if (fullPath) { 127a845c35880f8434619ac299e8af47aa6a5049e8dYang Ni *fullPath = sharedLibName; 128a845c35880f8434619ac299e8af47aa6a5049e8dYang Ni } 1292abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni std::string objFileName = cacheDir; 1302abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni objFileName.append("/"); 1312abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni objFileName.append(resName); 1322abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni objFileName.append(".o"); 1334c368af7e705f0bcb77fa99495b2e33ef20d2699Stephen Hines // Should be something like "libRSDriver.so". 1344c368af7e705f0bcb77fa99495b2e33ef20d2699Stephen Hines std::string linkDriverName = driverName; 1354c368af7e705f0bcb77fa99495b2e33ef20d2699Stephen Hines // Remove ".so" and replace "lib" with "-l". 1364c368af7e705f0bcb77fa99495b2e33ef20d2699Stephen Hines // This will leave us with "-lRSDriver" instead. 1374c368af7e705f0bcb77fa99495b2e33ef20d2699Stephen Hines linkDriverName.erase(linkDriverName.length() - 3); 1384c368af7e705f0bcb77fa99495b2e33ef20d2699Stephen Hines linkDriverName.replace(0, 3, "-l"); 1392abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 140e0f1e2ef6df041d4d88a4d4135c46ddcb0c50029Justin Yun static const std::string vndkLibCompilerRt = 141e0f1e2ef6df041d4d88a4d4135c46ddcb0c50029Justin Yun getVndkSysLibPath() + "/libcompiler_rt.so"; 142da43d5866f6224e17e756fdfea405ca4b00a38fcJiyong Park const char *compiler_rt = isRunningInVndkNamespace() ? 143e0f1e2ef6df041d4d88a4d4135c46ddcb0c50029Justin Yun vndkLibCompilerRt.c_str() : SYSLIBPATH "/libcompiler_rt.so"; 144c2be413317efcc44e3b282fd38fca3334c11777ePirama Arumuga Nainar const char *mTriple = "-mtriple=" DEFAULT_TARGET_TRIPLE_STRING; 145c2be413317efcc44e3b282fd38fca3334c11777ePirama Arumuga Nainar const char *libPath = "--library-path=" SYSLIBPATH; 146da43d5866f6224e17e756fdfea405ca4b00a38fcJiyong Park // vndk path is only added when RS framework is running in vndk namespace. 147da43d5866f6224e17e756fdfea405ca4b00a38fcJiyong Park // If we unconditionally add the vndk path to the library path, then RS 148da43d5866f6224e17e756fdfea405ca4b00a38fcJiyong Park // driver in the vndk-sp directory will always be used even for CPU fallback 149da43d5866f6224e17e756fdfea405ca4b00a38fcJiyong Park // case, where RS framework is loaded from the default namespace. 150e0f1e2ef6df041d4d88a4d4135c46ddcb0c50029Justin Yun static const std::string vndkLibPathString = 151e0f1e2ef6df041d4d88a4d4135c46ddcb0c50029Justin Yun "--library-path=" + getVndkSysLibPath(); 152da43d5866f6224e17e756fdfea405ca4b00a38fcJiyong Park const char *vndkLibPath = isRunningInVndkNamespace() ? 153e0f1e2ef6df041d4d88a4d4135c46ddcb0c50029Justin Yun vndkLibPathString.c_str() : ""; 154682672e36b05349bc4d9dee74e9fab73ce804183Pirama Arumuga Nainar const char *vendorLibPath = "--library-path=" SYSLIBPATH_VENDOR; 155c2be413317efcc44e3b282fd38fca3334c11777ePirama Arumuga Nainar 156da43d5866f6224e17e756fdfea405ca4b00a38fcJiyong Park // The search path order should be vendor -> vndk -> system 1572abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni std::vector<const char *> args = { 1582abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni LD_EXE_PATH, 1592abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni "-shared", 1602abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni "-nostdlib", 161da43d5866f6224e17e756fdfea405ca4b00a38fcJiyong Park compiler_rt, mTriple, vendorLibPath, vndkLibPath, libPath, 1624c368af7e705f0bcb77fa99495b2e33ef20d2699Stephen Hines linkDriverName.c_str(), "-lm", "-lc", 1632abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni objFileName.c_str(), 1642abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni "-o", sharedLibName.c_str(), 1652abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni nullptr 1662abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni }; 1672abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 1682fa8a238dd69afebdeb757adcb1d674043d78e32Pirama Arumuga Nainar return rsuExecuteCommand(LD_EXE_PATH, args.size()-1, args.data()); 1692abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 1702abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni} 1712abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 1722abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni#endif // RS_COMPATIBILITY_LIB 1732abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 1742abfcc6d129fe3defddef4540aa95cc445c03a7aYang Niconst char* RsdCpuScriptImpl::BCC_EXE_PATH = "/system/bin/bcc"; 1752abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 176a845c35880f8434619ac299e8af47aa6a5049e8dYang Nivoid* SharedLibraryUtils::loadAndDeleteSharedLibrary(const char *fullPath) { 177a845c35880f8434619ac299e8af47aa6a5049e8dYang Ni void *loaded = dlopen(fullPath, RTLD_NOW | RTLD_LOCAL); 178a845c35880f8434619ac299e8af47aa6a5049e8dYang Ni if (loaded == nullptr) { 179a845c35880f8434619ac299e8af47aa6a5049e8dYang Ni ALOGE("Unable to open shared library (%s): %s", fullPath, dlerror()); 180a845c35880f8434619ac299e8af47aa6a5049e8dYang Ni return nullptr; 181a845c35880f8434619ac299e8af47aa6a5049e8dYang Ni } 182a845c35880f8434619ac299e8af47aa6a5049e8dYang Ni 183a845c35880f8434619ac299e8af47aa6a5049e8dYang Ni int r = unlink(fullPath); 184a845c35880f8434619ac299e8af47aa6a5049e8dYang Ni if (r != 0) { 185a845c35880f8434619ac299e8af47aa6a5049e8dYang Ni ALOGE("Could not unlink copy %s", fullPath); 186a845c35880f8434619ac299e8af47aa6a5049e8dYang Ni return nullptr; 187a845c35880f8434619ac299e8af47aa6a5049e8dYang Ni } 188a845c35880f8434619ac299e8af47aa6a5049e8dYang Ni return loaded; 189a845c35880f8434619ac299e8af47aa6a5049e8dYang Ni} 190a845c35880f8434619ac299e8af47aa6a5049e8dYang Ni 1912abfcc6d129fe3defddef4540aa95cc445c03a7aYang Nivoid* SharedLibraryUtils::loadSharedLibrary(const char *cacheDir, 1922abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni const char *resName, 1931efae29f4bbe6c165caf6dfc4b89cf8a5f8c469bYang Ni const char *nativeLibDir, 1941efae29f4bbe6c165caf6dfc4b89cf8a5f8c469bYang Ni bool* alreadyLoaded) { 1952abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni void *loaded = nullptr; 1962abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 1972abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni#if defined(RS_COMPATIBILITY_LIB) && defined(__LP64__) 1982abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni std::string scriptSOName = findSharedObjectName(nativeLibDir, resName); 1992abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni#else 2002abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni std::string scriptSOName = findSharedObjectName(cacheDir, resName); 2012abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni#endif 2022abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 2032abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni // We should check if we can load the library from the standard app 2042abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni // location for shared libraries first. 2051efae29f4bbe6c165caf6dfc4b89cf8a5f8c469bYang Ni loaded = loadSOHelper(scriptSOName.c_str(), cacheDir, resName, alreadyLoaded); 2062abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 2072abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni if (loaded == nullptr) { 2082abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni ALOGE("Unable to open shared library (%s): %s", 2092abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni scriptSOName.c_str(), dlerror()); 2102abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 2112abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni#ifdef RS_COMPATIBILITY_LIB 2122abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni // One final attempt to find the library in "/system/lib". 2132abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni // We do this to allow bundled applications to use the compatibility 2142abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni // library fallback path. Those applications don't have a private 2152abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni // library path, so they need to install to the system directly. 2162abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni // Note that this is really just a testing path. 2172abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni std::string scriptSONameSystem("/system/lib/librs."); 2182abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni scriptSONameSystem.append(resName); 2192abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni scriptSONameSystem.append(".so"); 2202abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni loaded = loadSOHelper(scriptSONameSystem.c_str(), cacheDir, 2212abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni resName); 2222abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni if (loaded == nullptr) { 2232abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni ALOGE("Unable to open system shared library (%s): %s", 2242abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni scriptSONameSystem.c_str(), dlerror()); 2252abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni } 2262abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni#endif 2272abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni } 2282abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 2292abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni return loaded; 2302abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni} 2312abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 23282e135c4bbe18855d8ed02632bb074f8da0b96e0Miao Wangstd::string SharedLibraryUtils::getRandomString(size_t len) { 2331efae29f4bbe6c165caf6dfc4b89cf8a5f8c469bYang Ni char buf[len + 1]; 2341efae29f4bbe6c165caf6dfc4b89cf8a5f8c469bYang Ni for (size_t i = 0; i < len; i++) { 2351efae29f4bbe6c165caf6dfc4b89cf8a5f8c469bYang Ni uint32_t r = arc4random() & 0xffff; 2361efae29f4bbe6c165caf6dfc4b89cf8a5f8c469bYang Ni r %= 62; 2371efae29f4bbe6c165caf6dfc4b89cf8a5f8c469bYang Ni if (r < 26) { 2381efae29f4bbe6c165caf6dfc4b89cf8a5f8c469bYang Ni // lowercase 2391efae29f4bbe6c165caf6dfc4b89cf8a5f8c469bYang Ni buf[i] = 'a' + r; 2401efae29f4bbe6c165caf6dfc4b89cf8a5f8c469bYang Ni } else if (r < 52) { 2411efae29f4bbe6c165caf6dfc4b89cf8a5f8c469bYang Ni // uppercase 2421efae29f4bbe6c165caf6dfc4b89cf8a5f8c469bYang Ni buf[i] = 'A' + (r - 26); 2431efae29f4bbe6c165caf6dfc4b89cf8a5f8c469bYang Ni } else { 2441efae29f4bbe6c165caf6dfc4b89cf8a5f8c469bYang Ni // Use a number 2451efae29f4bbe6c165caf6dfc4b89cf8a5f8c469bYang Ni buf[i] = '0' + (r - 52); 2461efae29f4bbe6c165caf6dfc4b89cf8a5f8c469bYang Ni } 2471efae29f4bbe6c165caf6dfc4b89cf8a5f8c469bYang Ni } 2481efae29f4bbe6c165caf6dfc4b89cf8a5f8c469bYang Ni buf[len] = '\0'; 24982e135c4bbe18855d8ed02632bb074f8da0b96e0Miao Wang return std::string(buf); 2501efae29f4bbe6c165caf6dfc4b89cf8a5f8c469bYang Ni} 2511efae29f4bbe6c165caf6dfc4b89cf8a5f8c469bYang Ni 2522abfcc6d129fe3defddef4540aa95cc445c03a7aYang Nivoid* SharedLibraryUtils::loadSOHelper(const char *origName, const char *cacheDir, 2531efae29f4bbe6c165caf6dfc4b89cf8a5f8c469bYang Ni const char *resName, bool *alreadyLoaded) { 2542abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni // Keep track of which .so libraries have been loaded. Once a library is 2552abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni // in the set (per-process granularity), we must instead make a copy of 2562abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni // the original shared object (randomly named .so file) and load that one 2572abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni // instead. If we don't do this, we end up aliasing global data between 2582abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni // the various Script instances (which are supposed to be completely 2592abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni // independent). 2602abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni static std::set<std::string> LoadedLibraries; 2612abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 2622abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni void *loaded = nullptr; 2632abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 2642abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni // Skip everything if we don't even have the original library available. 2652abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni if (access(origName, F_OK) != 0) { 2662abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni return nullptr; 2672abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni } 2682abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 2692abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni // Common path is that we have not loaded this Script/library before. 2702abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni if (LoadedLibraries.find(origName) == LoadedLibraries.end()) { 2711efae29f4bbe6c165caf6dfc4b89cf8a5f8c469bYang Ni if (alreadyLoaded != nullptr) { 2721efae29f4bbe6c165caf6dfc4b89cf8a5f8c469bYang Ni *alreadyLoaded = false; 2731efae29f4bbe6c165caf6dfc4b89cf8a5f8c469bYang Ni } 2742abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni loaded = dlopen(origName, RTLD_NOW | RTLD_LOCAL); 2752abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni if (loaded) { 2762abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni LoadedLibraries.insert(origName); 2772abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni } 2782abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni return loaded; 2792abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni } 2802abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 2811efae29f4bbe6c165caf6dfc4b89cf8a5f8c469bYang Ni if (alreadyLoaded != nullptr) { 2821efae29f4bbe6c165caf6dfc4b89cf8a5f8c469bYang Ni *alreadyLoaded = true; 2831efae29f4bbe6c165caf6dfc4b89cf8a5f8c469bYang Ni } 2841efae29f4bbe6c165caf6dfc4b89cf8a5f8c469bYang Ni 2852abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni std::string newName(cacheDir); 2862abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 2872abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni // Append RS_CACHE_DIR only if it is not found in cacheDir 2882abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni // In driver mode, RS_CACHE_DIR is already appended to cacheDir. 2892abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni if (newName.find(RS_CACHE_DIR) == std::string::npos) { 2902abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni newName.append("/"); 2912abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni newName.append(RS_CACHE_DIR); 2922abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni newName.append("/"); 2932abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni } 2942abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 2952abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni if (!ensureCacheDirExists(newName.c_str())) { 2962abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni ALOGE("Could not verify or create cache dir: %s", cacheDir); 2972abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni return nullptr; 2982abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni } 2992abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 3002abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni // Construct an appropriately randomized filename for the copy. 3012abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni newName.append("librs."); 3022abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni newName.append(resName); 3032abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni newName.append("#"); 30482e135c4bbe18855d8ed02632bb074f8da0b96e0Miao Wang newName.append(getRandomString(6).c_str()); // 62^6 potential filename variants. 3052abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni newName.append(".so"); 3062abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 3072abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni int r = copyFile(newName.c_str(), origName); 3082abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni if (r != 0) { 3092abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni ALOGE("Could not create copy %s -> %s", origName, newName.c_str()); 3102abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni return nullptr; 3112abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni } 3122abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni loaded = dlopen(newName.c_str(), RTLD_NOW | RTLD_LOCAL); 3132abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni r = unlink(newName.c_str()); 3142abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni if (r != 0) { 3152abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni ALOGE("Could not unlink copy %s", newName.c_str()); 3162abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni } 3172abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni if (loaded) { 3182abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni LoadedLibraries.insert(newName.c_str()); 3192abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni } 3202abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 3212abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni return loaded; 3222abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni} 3232abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 324d48481048a68725e79bbe8ba8ea75e710c646fe1Miao Wang// MAXLINESTR must be compatible with operator '#' in C macro. 325d48481048a68725e79bbe8ba8ea75e710c646fe1Miao Wang#define MAXLINESTR 499 326d48481048a68725e79bbe8ba8ea75e710c646fe1Miao Wang// MAXLINE must be (MAXLINESTR + 1), representing the size of a C string 327d48481048a68725e79bbe8ba8ea75e710c646fe1Miao Wang// containing MAXLINESTR non-null chars plus a null. 328d48481048a68725e79bbe8ba8ea75e710c646fe1Miao Wang#define MAXLINE (MAXLINESTR + 1) 3292abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni#define MAKE_STR_HELPER(S) #S 3302abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni#define MAKE_STR(S) MAKE_STR_HELPER(S) 3312abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni#define EXPORT_VAR_STR "exportVarCount: " 3322abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni#define EXPORT_FUNC_STR "exportFuncCount: " 3332abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni#define EXPORT_FOREACH_STR "exportForEachCount: " 33414ce007a633b10e3b9a3fae29d8f53a7e8c9b59fMatt Wala#define EXPORT_REDUCE_STR "exportReduceCount: " 3352abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni#define OBJECT_SLOT_STR "objectSlotCount: " 3362abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni#define PRAGMA_STR "pragmaCount: " 3372abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni#define THREADABLE_STR "isThreadable: " 338aa6757ffc1b23d771566439c3179fdbc1e5ba569Pirama Arumuga Nainar#define CHECKSUM_STR "buildChecksum: " 3393bc02c5bbcc1f1cd838455bf1a32c57c18addda8Luke Drummond#define VERSIONINFO_STR "versionInfo: " 3402abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 3412abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni// Copy up to a newline or size chars from str -> s, updating str 3422abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni// Returns s when successful and nullptr when '\0' is finally reached. 3432abfcc6d129fe3defddef4540aa95cc445c03a7aYang Nistatic char* strgets(char *s, int size, const char **ppstr) { 3442abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni if (!ppstr || !*ppstr || **ppstr == '\0' || size < 1) { 3452abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni return nullptr; 3462abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni } 3472abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 3482abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni int i; 3492abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni for (i = 0; i < (size - 1); i++) { 3502abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni s[i] = **ppstr; 3512abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni (*ppstr)++; 3522abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni if (s[i] == '\0') { 3532abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni return s; 3542abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni } else if (s[i] == '\n') { 3552abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni s[i+1] = '\0'; 3562abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni return s; 3572abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni } 3582abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni } 3592abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 3602abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni // size has been exceeded. 3612abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni s[i] = '\0'; 3622abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 3632abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni return s; 3642abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni} 3652abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 366ca451c3280b6265a9b79273b4bf89e121a050cabMichael Butler// Creates a duplicate of a string. The new string is as small as possible, 367ca451c3280b6265a9b79273b4bf89e121a050cabMichael Butler// only including characters up to and including the first null-terminator; 368ca451c3280b6265a9b79273b4bf89e121a050cabMichael Butler// otherwise, the new string will be the same size as the input string. 369ca451c3280b6265a9b79273b4bf89e121a050cabMichael Butler// The code that calls duplicateString is responsible for the new string's 370ca451c3280b6265a9b79273b4bf89e121a050cabMichael Butler// lifetime, and is responsible for freeing it when it is no longer needed. 371ca451c3280b6265a9b79273b4bf89e121a050cabMichael Butlerstatic char* duplicateString(const char *str, size_t length) { 372ca451c3280b6265a9b79273b4bf89e121a050cabMichael Butler const size_t newLen = strnlen(str, length-1) + 1; 373ca451c3280b6265a9b79273b4bf89e121a050cabMichael Butler char *newStr = new char[newLen]; 374ca451c3280b6265a9b79273b4bf89e121a050cabMichael Butler strlcpy(newStr, str, newLen); 375ca451c3280b6265a9b79273b4bf89e121a050cabMichael Butler return newStr; 376ca451c3280b6265a9b79273b4bf89e121a050cabMichael Butler} 377ca451c3280b6265a9b79273b4bf89e121a050cabMichael Butler 3782abfcc6d129fe3defddef4540aa95cc445c03a7aYang NiScriptExecutable* ScriptExecutable::createFromSharedObject( 3795e48002cc4a11e9ce63852a77488cfb9f6765c2bYang Ni void* sharedObj, uint32_t expectedChecksum) { 3802abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni char line[MAXLINE]; 3812abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 3822abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni size_t varCount = 0; 3832abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni size_t funcCount = 0; 3842abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni size_t forEachCount = 0; 38514ce007a633b10e3b9a3fae29d8f53a7e8c9b59fMatt Wala size_t reduceCount = 0; 3862abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni size_t objectSlotCount = 0; 3872abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni size_t pragmaCount = 0; 3882abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni bool isThreadable = true; 3892abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 3902abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni void** fieldAddress = nullptr; 3912abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni bool* fieldIsObject = nullptr; 392062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni char** fieldName = nullptr; 3932abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni InvokeFunc_t* invokeFunctions = nullptr; 3942abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni ForEachFunc_t* forEachFunctions = nullptr; 3952abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni uint32_t* forEachSignatures = nullptr; 396ae2ec3febedfc29376b9104413fb4042028f1265David Gross ReduceDescription* reduceDescriptions = nullptr; 3972abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni const char ** pragmaKeys = nullptr; 3982abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni const char ** pragmaValues = nullptr; 399cb17015fed6b11a5028f31cc804a3847e379945dYang Ni uint32_t checksum = 0; 4002abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 4015aa018cc36e589b07674957714d27ae3d1fa1c4eStephen Hines const char *rsInfo = (const char *) dlsym(sharedObj, kRsInfo); 4028409d6414dd4a42aa59779fcfe9fce18648cb135Stephen Hines int numEntries = 0; 4035aa018cc36e589b07674957714d27ae3d1fa1c4eStephen Hines const int *rsGlobalEntries = (const int *) dlsym(sharedObj, kRsGlobalEntries); 4045aa018cc36e589b07674957714d27ae3d1fa1c4eStephen Hines const char **rsGlobalNames = (const char **) dlsym(sharedObj, kRsGlobalNames); 4055aa018cc36e589b07674957714d27ae3d1fa1c4eStephen Hines const void **rsGlobalAddresses = (const void **) dlsym(sharedObj, kRsGlobalAddresses); 4065aa018cc36e589b07674957714d27ae3d1fa1c4eStephen Hines const size_t *rsGlobalSizes = (const size_t *) dlsym(sharedObj, kRsGlobalSizes); 4075aa018cc36e589b07674957714d27ae3d1fa1c4eStephen Hines const uint32_t *rsGlobalProperties = (const uint32_t *) dlsym(sharedObj, kRsGlobalProperties); 4082abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 4092abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni if (strgets(line, MAXLINE, &rsInfo) == nullptr) { 4102abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni return nullptr; 4112abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni } 4122abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni if (sscanf(line, EXPORT_VAR_STR "%zu", &varCount) != 1) { 4132abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni ALOGE("Invalid export var count!: %s", line); 4142abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni return nullptr; 4152abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni } 4162abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 4172abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni fieldAddress = new void*[varCount]; 4182abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni if (fieldAddress == nullptr) { 4192abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni return nullptr; 4202abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni } 4212abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 4222abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni fieldIsObject = new bool[varCount]; 4232abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni if (fieldIsObject == nullptr) { 4242abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni goto error; 4252abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni } 4262abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 427062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni fieldName = new char*[varCount]; 428062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni if (fieldName == nullptr) { 429062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni goto error; 430062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni } 431062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni 4322abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni for (size_t i = 0; i < varCount; ++i) { 4332abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni if (strgets(line, MAXLINE, &rsInfo) == nullptr) { 4342abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni goto error; 4352abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni } 4362abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni char *c = strrchr(line, '\n'); 4372abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni if (c) { 4382abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni *c = '\0'; 4392abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni } 4402abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni void* addr = dlsym(sharedObj, line); 4412abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni if (addr == nullptr) { 4422abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni ALOGE("Failed to find variable address for %s: %s", 4432abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni line, dlerror()); 4442abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni // Not a critical error if we don't find a global variable. 4452abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni } 4462abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni fieldAddress[i] = addr; 4472abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni fieldIsObject[i] = false; 448ca451c3280b6265a9b79273b4bf89e121a050cabMichael Butler fieldName[i] = duplicateString(line, sizeof(line)); 4492abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni } 4502abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 4512abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni if (strgets(line, MAXLINE, &rsInfo) == nullptr) { 4522abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni goto error; 4532abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni } 4542abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni if (sscanf(line, EXPORT_FUNC_STR "%zu", &funcCount) != 1) { 4552abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni ALOGE("Invalid export func count!: %s", line); 4562abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni goto error; 4572abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni } 4582abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 4592abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni invokeFunctions = new InvokeFunc_t[funcCount]; 4602abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni if (invokeFunctions == nullptr) { 4612abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni goto error; 4622abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni } 4632abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 4642abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni for (size_t i = 0; i < funcCount; ++i) { 4652abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni if (strgets(line, MAXLINE, &rsInfo) == nullptr) { 4662abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni goto error; 4672abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni } 4682abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni char *c = strrchr(line, '\n'); 4692abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni if (c) { 4702abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni *c = '\0'; 4712abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni } 4722abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 4732abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni invokeFunctions[i] = (InvokeFunc_t) dlsym(sharedObj, line); 4742abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni if (invokeFunctions[i] == nullptr) { 4752abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni ALOGE("Failed to get function address for %s(): %s", 4762abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni line, dlerror()); 4772abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni goto error; 4782abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni } 4792abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni } 4802abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 4812abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni if (strgets(line, MAXLINE, &rsInfo) == nullptr) { 4822abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni goto error; 4832abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni } 4842abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni if (sscanf(line, EXPORT_FOREACH_STR "%zu", &forEachCount) != 1) { 4852abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni ALOGE("Invalid export forEach count!: %s", line); 4862abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni goto error; 4872abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni } 4882abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 4892abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni forEachFunctions = new ForEachFunc_t[forEachCount]; 4902abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni if (forEachFunctions == nullptr) { 4912abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni goto error; 4922abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni } 4932abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 4942abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni forEachSignatures = new uint32_t[forEachCount]; 4952abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni if (forEachSignatures == nullptr) { 4962abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni goto error; 4972abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni } 4982abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 4992abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni for (size_t i = 0; i < forEachCount; ++i) { 5002abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni unsigned int tmpSig = 0; 5012abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni char tmpName[MAXLINE]; 5022abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 5032abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni if (strgets(line, MAXLINE, &rsInfo) == nullptr) { 5042abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni goto error; 5052abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni } 506d48481048a68725e79bbe8ba8ea75e710c646fe1Miao Wang if (sscanf(line, "%u - %" MAKE_STR(MAXLINESTR) "s", 5072abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni &tmpSig, tmpName) != 2) { 5082abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni ALOGE("Invalid export forEach!: %s", line); 5092abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni goto error; 5102abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni } 5112abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 5122abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni // Lookup the expanded ForEach kernel. 513d48481048a68725e79bbe8ba8ea75e710c646fe1Miao Wang strncat(tmpName, ".expand", MAXLINESTR-strlen(tmpName)); 5142abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni forEachSignatures[i] = tmpSig; 5152abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni forEachFunctions[i] = 5162abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni (ForEachFunc_t) dlsym(sharedObj, tmpName); 517062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni if (i != 0 && forEachFunctions[i] == nullptr && 518062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni strcmp(tmpName, "root.expand")) { 5192abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni // Ignore missing root.expand functions. 5202abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni // root() is always specified at location 0. 52114ce007a633b10e3b9a3fae29d8f53a7e8c9b59fMatt Wala ALOGE("Failed to find forEach function address for %s(): %s", 5222abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni tmpName, dlerror()); 5232abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni goto error; 5242abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni } 5252abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni } 5262abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 5276c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross // Read general reduce kernels 52846c93e405b0ad7e8fca12d0b1f9eac3997798e45David Gross if (strgets(line, MAXLINE, &rsInfo) == nullptr) { 52946c93e405b0ad7e8fca12d0b1f9eac3997798e45David Gross goto error; 53046c93e405b0ad7e8fca12d0b1f9eac3997798e45David Gross } 531ae2ec3febedfc29376b9104413fb4042028f1265David Gross if (sscanf(line, EXPORT_REDUCE_STR "%zu", &reduceCount) != 1) { 53246c93e405b0ad7e8fca12d0b1f9eac3997798e45David Gross ALOGE("Invalid export reduce new count!: %s", line); 53346c93e405b0ad7e8fca12d0b1f9eac3997798e45David Gross goto error; 53446c93e405b0ad7e8fca12d0b1f9eac3997798e45David Gross } 5356c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross 536ae2ec3febedfc29376b9104413fb4042028f1265David Gross reduceDescriptions = new ReduceDescription[reduceCount]; 537ae2ec3febedfc29376b9104413fb4042028f1265David Gross if (reduceDescriptions == nullptr) { 53846c93e405b0ad7e8fca12d0b1f9eac3997798e45David Gross goto error; 53946c93e405b0ad7e8fca12d0b1f9eac3997798e45David Gross } 54046c93e405b0ad7e8fca12d0b1f9eac3997798e45David Gross 541ae2ec3febedfc29376b9104413fb4042028f1265David Gross for (size_t i = 0; i < reduceCount; ++i) { 5426c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross static const char kNoName[] = "."; 5436c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross 5446c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross unsigned int tmpSig = 0; 5456c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross size_t tmpSize = 0; 5466c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross char tmpNameReduce[MAXLINE]; 5476c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross char tmpNameInitializer[MAXLINE]; 5486c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross char tmpNameAccumulator[MAXLINE]; 5496c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross char tmpNameCombiner[MAXLINE]; 5506c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross char tmpNameOutConverter[MAXLINE]; 5516c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross char tmpNameHalter[MAXLINE]; 5526c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross 5536c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross if (strgets(line, MAXLINE, &rsInfo) == nullptr) { 5546c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross goto error; 5556c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross } 556d48481048a68725e79bbe8ba8ea75e710c646fe1Miao Wang#define DELIMNAME " - %" MAKE_STR(MAXLINESTR) "s" 5576c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross if (sscanf(line, "%u - %zu" DELIMNAME DELIMNAME DELIMNAME DELIMNAME DELIMNAME DELIMNAME, 5586c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross &tmpSig, &tmpSize, tmpNameReduce, tmpNameInitializer, tmpNameAccumulator, 5596c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross tmpNameCombiner, tmpNameOutConverter, tmpNameHalter) != 8) { 5606c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross ALOGE("Invalid export reduce new!: %s", line); 5616c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross goto error; 5626c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross } 5636c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross#undef DELIMNAME 5646c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross 5656c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross // For now, we expect 5666c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross // - Reduce and Accumulator names 5676c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross // - optional Initializer, Combiner, and OutConverter name 5686c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross // - no Halter name 5696c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross if (!strcmp(tmpNameReduce, kNoName) || 5706c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross !strcmp(tmpNameAccumulator, kNoName)) { 5716c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross ALOGE("Expected reduce and accumulator names!: %s", line); 5726c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross goto error; 5736c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross } 5746c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross if (strcmp(tmpNameHalter, kNoName)) { 5756c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross ALOGE("Did not expect halter name!: %s", line); 5766c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross goto error; 5776c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross } 5786c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross 57910adb0c2029f112b5738228617d5645f6ecea0c5David Gross // The current implementation does not use the signature 58010adb0c2029f112b5738228617d5645f6ecea0c5David Gross // or reduce name. 5816c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross 582ae2ec3febedfc29376b9104413fb4042028f1265David Gross reduceDescriptions[i].accumSize = tmpSize; 5836c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross 5846c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross // Process the (optional) initializer. 5856c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross if (strcmp(tmpNameInitializer, kNoName)) { 5866c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross // Lookup the original user-written initializer. 587ae2ec3febedfc29376b9104413fb4042028f1265David Gross if (!(reduceDescriptions[i].initFunc = 588ae2ec3febedfc29376b9104413fb4042028f1265David Gross (ReduceInitializerFunc_t) dlsym(sharedObj, tmpNameInitializer))) { 5896c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross ALOGE("Failed to find initializer function address for %s(): %s", 5906c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross tmpNameInitializer, dlerror()); 5916c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross goto error; 5926c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross } 5936c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross } else { 594ae2ec3febedfc29376b9104413fb4042028f1265David Gross reduceDescriptions[i].initFunc = nullptr; 5956c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross } 5966c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross 5976c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross // Lookup the expanded accumulator. 598d48481048a68725e79bbe8ba8ea75e710c646fe1Miao Wang strncat(tmpNameAccumulator, ".expand", MAXLINESTR-strlen(tmpNameAccumulator)); 599ae2ec3febedfc29376b9104413fb4042028f1265David Gross if (!(reduceDescriptions[i].accumFunc = 600ae2ec3febedfc29376b9104413fb4042028f1265David Gross (ReduceAccumulatorFunc_t) dlsym(sharedObj, tmpNameAccumulator))) { 6016c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross ALOGE("Failed to find accumulator function address for %s(): %s", 6026c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross tmpNameAccumulator, dlerror()); 6036c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross goto error; 6046c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross } 6056c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross 60610adb0c2029f112b5738228617d5645f6ecea0c5David Gross // Process the (optional) combiner. 60710adb0c2029f112b5738228617d5645f6ecea0c5David Gross if (strcmp(tmpNameCombiner, kNoName)) { 60810adb0c2029f112b5738228617d5645f6ecea0c5David Gross // Lookup the original user-written combiner. 609ae2ec3febedfc29376b9104413fb4042028f1265David Gross if (!(reduceDescriptions[i].combFunc = 610ae2ec3febedfc29376b9104413fb4042028f1265David Gross (ReduceCombinerFunc_t) dlsym(sharedObj, tmpNameCombiner))) { 61110adb0c2029f112b5738228617d5645f6ecea0c5David Gross ALOGE("Failed to find combiner function address for %s(): %s", 61210adb0c2029f112b5738228617d5645f6ecea0c5David Gross tmpNameCombiner, dlerror()); 61310adb0c2029f112b5738228617d5645f6ecea0c5David Gross goto error; 61410adb0c2029f112b5738228617d5645f6ecea0c5David Gross } 61510adb0c2029f112b5738228617d5645f6ecea0c5David Gross } else { 616ae2ec3febedfc29376b9104413fb4042028f1265David Gross reduceDescriptions[i].combFunc = nullptr; 61710adb0c2029f112b5738228617d5645f6ecea0c5David Gross } 61810adb0c2029f112b5738228617d5645f6ecea0c5David Gross 6196c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross // Process the (optional) outconverter. 6206c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross if (strcmp(tmpNameOutConverter, kNoName)) { 6216c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross // Lookup the original user-written outconverter. 622ae2ec3febedfc29376b9104413fb4042028f1265David Gross if (!(reduceDescriptions[i].outFunc = 623ae2ec3febedfc29376b9104413fb4042028f1265David Gross (ReduceOutConverterFunc_t) dlsym(sharedObj, tmpNameOutConverter))) { 6246c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross ALOGE("Failed to find outconverter function address for %s(): %s", 6256c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross tmpNameOutConverter, dlerror()); 6266c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross goto error; 6276c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross } 6286c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross } else { 629ae2ec3febedfc29376b9104413fb4042028f1265David Gross reduceDescriptions[i].outFunc = nullptr; 6306c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross } 6316c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross } 6326c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross 6332abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni if (strgets(line, MAXLINE, &rsInfo) == nullptr) { 6342abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni goto error; 6352abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni } 6362abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni if (sscanf(line, OBJECT_SLOT_STR "%zu", &objectSlotCount) != 1) { 6372abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni ALOGE("Invalid object slot count!: %s", line); 6382abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni goto error; 6392abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni } 6402abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 6412abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni for (size_t i = 0; i < objectSlotCount; ++i) { 6422abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni uint32_t varNum = 0; 6432abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni if (strgets(line, MAXLINE, &rsInfo) == nullptr) { 6442abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni goto error; 6452abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni } 6462abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni if (sscanf(line, "%u", &varNum) != 1) { 6472abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni ALOGE("Invalid object slot!: %s", line); 6482abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni goto error; 6492abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni } 6502abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 6512abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni if (varNum < varCount) { 6522abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni fieldIsObject[varNum] = true; 6532abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni } 6542abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni } 6552abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 6562abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni#ifndef RS_COMPATIBILITY_LIB 6572abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni // Do not attempt to read pragmas or isThreadable flag in compat lib path. 6582abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni // Neither is applicable for compat lib 6592abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 6602abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni if (strgets(line, MAXLINE, &rsInfo) == nullptr) { 6612abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni goto error; 6622abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni } 6632abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 6642abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni if (sscanf(line, PRAGMA_STR "%zu", &pragmaCount) != 1) { 6652abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni ALOGE("Invalid pragma count!: %s", line); 6662abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni goto error; 6672abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni } 6682abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 6692abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni pragmaKeys = new const char*[pragmaCount]; 6702abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni if (pragmaKeys == nullptr) { 6712abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni goto error; 6722abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni } 6732abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 6742abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni pragmaValues = new const char*[pragmaCount]; 6752abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni if (pragmaValues == nullptr) { 6762abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni goto error; 6772abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni } 6782abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 6792abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni bzero(pragmaKeys, sizeof(char*) * pragmaCount); 6802abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni bzero(pragmaValues, sizeof(char*) * pragmaCount); 6812abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 6822abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni for (size_t i = 0; i < pragmaCount; ++i) { 6832abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni if (strgets(line, MAXLINE, &rsInfo) == nullptr) { 6842abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni ALOGE("Unable to read pragma at index %zu!", i); 6852abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni goto error; 6862abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni } 6872abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni char key[MAXLINE]; 6882abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni char value[MAXLINE] = ""; // initialize in case value is empty 6892abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 6902abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni // pragmas can just have a key and no value. Only check to make sure 6912abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni // that the key is not empty 692d48481048a68725e79bbe8ba8ea75e710c646fe1Miao Wang if (sscanf(line, "%" MAKE_STR(MAXLINESTR) "s - %" MAKE_STR(MAXLINESTR) "s", 6932abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni key, value) == 0 || 6942abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni strlen(key) == 0) 6952abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni { 6962abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni ALOGE("Invalid pragma value!: %s", line); 6972abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 6982abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni goto error; 6992abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni } 7002abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 701ca451c3280b6265a9b79273b4bf89e121a050cabMichael Butler pragmaKeys[i] = duplicateString(key, sizeof(key)); 702ca451c3280b6265a9b79273b4bf89e121a050cabMichael Butler pragmaValues[i] = duplicateString(value, sizeof(value)); 7032abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni //ALOGE("Pragma %zu: Key: '%s' Value: '%s'", i, pKey, pValue); 7042abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni } 7052abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 7062abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni if (strgets(line, MAXLINE, &rsInfo) == nullptr) { 7072abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni goto error; 7082abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni } 7092abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 7102abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni char tmpFlag[4]; 711d48481048a68725e79bbe8ba8ea75e710c646fe1Miao Wang if (sscanf(line, THREADABLE_STR "%3s", tmpFlag) != 1) { 7122abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni ALOGE("Invalid threadable flag!: %s", line); 7132abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni goto error; 7142abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni } 7152abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni if (strcmp(tmpFlag, "yes") == 0) { 7162abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni isThreadable = true; 7172abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni } else if (strcmp(tmpFlag, "no") == 0) { 7182abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni isThreadable = false; 7192abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni } else { 7202abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni ALOGE("Invalid threadable flag!: %s", tmpFlag); 7212abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni goto error; 7222abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni } 7232abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 724aa6757ffc1b23d771566439c3179fdbc1e5ba569Pirama Arumuga Nainar if (strgets(line, MAXLINE, &rsInfo) != nullptr) { 725cb17015fed6b11a5028f31cc804a3847e379945dYang Ni if (sscanf(line, CHECKSUM_STR "%08x", &checksum) != 1) { 726aa6757ffc1b23d771566439c3179fdbc1e5ba569Pirama Arumuga Nainar ALOGE("Invalid checksum flag!: %s", line); 727aa6757ffc1b23d771566439c3179fdbc1e5ba569Pirama Arumuga Nainar goto error; 728aa6757ffc1b23d771566439c3179fdbc1e5ba569Pirama Arumuga Nainar } 729062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni } else { 730062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni ALOGE("Missing checksum in shared obj file"); 731aa6757ffc1b23d771566439c3179fdbc1e5ba569Pirama Arumuga Nainar goto error; 732aa6757ffc1b23d771566439c3179fdbc1e5ba569Pirama Arumuga Nainar } 733aa6757ffc1b23d771566439c3179fdbc1e5ba569Pirama Arumuga Nainar 734cb17015fed6b11a5028f31cc804a3847e379945dYang Ni if (expectedChecksum != 0 && checksum != expectedChecksum) { 735cb17015fed6b11a5028f31cc804a3847e379945dYang Ni ALOGE("Found invalid checksum. Expected %08x, got %08x\n", 736cb17015fed6b11a5028f31cc804a3847e379945dYang Ni expectedChecksum, checksum); 737cb17015fed6b11a5028f31cc804a3847e379945dYang Ni goto error; 738cb17015fed6b11a5028f31cc804a3847e379945dYang Ni } 739cb17015fed6b11a5028f31cc804a3847e379945dYang Ni 7403bc02c5bbcc1f1cd838455bf1a32c57c18addda8Luke Drummond { 7413bc02c5bbcc1f1cd838455bf1a32c57c18addda8Luke Drummond // Parse the version info string, but ignore its contents as it's only 7423bc02c5bbcc1f1cd838455bf1a32c57c18addda8Luke Drummond // used by the debugger 7433bc02c5bbcc1f1cd838455bf1a32c57c18addda8Luke Drummond size_t nLines = 0; 7443bc02c5bbcc1f1cd838455bf1a32c57c18addda8Luke Drummond if (strgets(line, MAXLINE, &rsInfo) != nullptr) { 7453bc02c5bbcc1f1cd838455bf1a32c57c18addda8Luke Drummond if (sscanf(line, VERSIONINFO_STR "%zu", &nLines) != 1) { 7463bc02c5bbcc1f1cd838455bf1a32c57c18addda8Luke Drummond ALOGE("invalid versionInfo count"); 7473bc02c5bbcc1f1cd838455bf1a32c57c18addda8Luke Drummond goto error; 7483bc02c5bbcc1f1cd838455bf1a32c57c18addda8Luke Drummond } else { 7493bc02c5bbcc1f1cd838455bf1a32c57c18addda8Luke Drummond // skip the versionInfo packet as libRs doesn't use it 7505f4af759693231777add7683eb06c2cb8af5022cIvan Lozano while (nLines) { 7515f4af759693231777add7683eb06c2cb8af5022cIvan Lozano --nLines; 7523bc02c5bbcc1f1cd838455bf1a32c57c18addda8Luke Drummond if (strgets(line, MAXLINE, &rsInfo) == nullptr) 7533bc02c5bbcc1f1cd838455bf1a32c57c18addda8Luke Drummond goto error; 7543bc02c5bbcc1f1cd838455bf1a32c57c18addda8Luke Drummond } 7553bc02c5bbcc1f1cd838455bf1a32c57c18addda8Luke Drummond } 7563bc02c5bbcc1f1cd838455bf1a32c57c18addda8Luke Drummond } else { 7573bc02c5bbcc1f1cd838455bf1a32c57c18addda8Luke Drummond ALOGE(".rs.info is missing versionInfo section"); 7583bc02c5bbcc1f1cd838455bf1a32c57c18addda8Luke Drummond } 7593bc02c5bbcc1f1cd838455bf1a32c57c18addda8Luke Drummond } 7603bc02c5bbcc1f1cd838455bf1a32c57c18addda8Luke Drummond 7612abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni#endif // RS_COMPATIBILITY_LIB 7622abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 7638409d6414dd4a42aa59779fcfe9fce18648cb135Stephen Hines // Read in information about mutable global variables provided by bcc's 7648409d6414dd4a42aa59779fcfe9fce18648cb135Stephen Hines // RSGlobalInfoPass 7658409d6414dd4a42aa59779fcfe9fce18648cb135Stephen Hines if (rsGlobalEntries) { 7668409d6414dd4a42aa59779fcfe9fce18648cb135Stephen Hines numEntries = *rsGlobalEntries; 7678409d6414dd4a42aa59779fcfe9fce18648cb135Stephen Hines if (numEntries > 0) { 7688409d6414dd4a42aa59779fcfe9fce18648cb135Stephen Hines rsAssert(rsGlobalNames); 7698409d6414dd4a42aa59779fcfe9fce18648cb135Stephen Hines rsAssert(rsGlobalAddresses); 7708409d6414dd4a42aa59779fcfe9fce18648cb135Stephen Hines rsAssert(rsGlobalSizes); 7715aa018cc36e589b07674957714d27ae3d1fa1c4eStephen Hines rsAssert(rsGlobalProperties); 7728409d6414dd4a42aa59779fcfe9fce18648cb135Stephen Hines } 7738409d6414dd4a42aa59779fcfe9fce18648cb135Stephen Hines } 7748409d6414dd4a42aa59779fcfe9fce18648cb135Stephen Hines 7752abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni return new ScriptExecutable( 7765e48002cc4a11e9ce63852a77488cfb9f6765c2bYang Ni fieldAddress, fieldIsObject, fieldName, varCount, 7772abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni invokeFunctions, funcCount, 7782abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni forEachFunctions, forEachSignatures, forEachCount, 779ae2ec3febedfc29376b9104413fb4042028f1265David Gross reduceDescriptions, reduceCount, 7802abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni pragmaKeys, pragmaValues, pragmaCount, 7815aa018cc36e589b07674957714d27ae3d1fa1c4eStephen Hines rsGlobalNames, rsGlobalAddresses, rsGlobalSizes, rsGlobalProperties, 7825aa018cc36e589b07674957714d27ae3d1fa1c4eStephen Hines numEntries, isThreadable, checksum); 7832abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 7842abfcc6d129fe3defddef4540aa95cc445c03a7aYang Nierror: 7852abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 7862abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni#ifndef RS_COMPATIBILITY_LIB 787aa6757ffc1b23d771566439c3179fdbc1e5ba569Pirama Arumuga Nainar 788a824b7c0138e49136fabe166ab4431aa9c220b9fTing-Yuan Huang if (pragmaKeys) { 789a824b7c0138e49136fabe166ab4431aa9c220b9fTing-Yuan Huang for (size_t idx = 0; idx < pragmaCount; ++idx) { 790a824b7c0138e49136fabe166ab4431aa9c220b9fTing-Yuan Huang delete [] pragmaKeys[idx]; 791a824b7c0138e49136fabe166ab4431aa9c220b9fTing-Yuan Huang } 792a824b7c0138e49136fabe166ab4431aa9c220b9fTing-Yuan Huang } 793a824b7c0138e49136fabe166ab4431aa9c220b9fTing-Yuan Huang 794a824b7c0138e49136fabe166ab4431aa9c220b9fTing-Yuan Huang if (pragmaValues) { 795a824b7c0138e49136fabe166ab4431aa9c220b9fTing-Yuan Huang for (size_t idx = 0; idx < pragmaCount; ++idx) { 796a824b7c0138e49136fabe166ab4431aa9c220b9fTing-Yuan Huang delete [] pragmaValues[idx]; 797a824b7c0138e49136fabe166ab4431aa9c220b9fTing-Yuan Huang } 7982abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni } 7992abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 8002abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni delete[] pragmaValues; 8012abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni delete[] pragmaKeys; 8022abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni#endif // RS_COMPATIBILITY_LIB 8032abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 804a824b7c0138e49136fabe166ab4431aa9c220b9fTing-Yuan Huang delete[] reduceDescriptions; 805a824b7c0138e49136fabe166ab4431aa9c220b9fTing-Yuan Huang 8062abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni delete[] forEachSignatures; 8072abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni delete[] forEachFunctions; 808062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni 8092abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni delete[] invokeFunctions; 810062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni 811062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni for (size_t i = 0; i < varCount; i++) { 812062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni delete[] fieldName[i]; 813062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni } 814062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni delete[] fieldName; 8152abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni delete[] fieldIsObject; 8162abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni delete[] fieldAddress; 8172abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 8182abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni return nullptr; 8192abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni} 8202abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 821062c287f573ecc06c38ee4295e5627e12c52ac3dYang Nivoid* ScriptExecutable::getFieldAddress(const char* name) const { 822062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni // TODO: improve this by using a hash map. 823062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni for (size_t i = 0; i < mExportedVarCount; i++) { 824062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni if (strcmp(name, mFieldName[i]) == 0) { 825062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni return mFieldAddress[i]; 826062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni } 827062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni } 828062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni return nullptr; 829062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni} 830062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni 8318409d6414dd4a42aa59779fcfe9fce18648cb135Stephen Hinesbool ScriptExecutable::dumpGlobalInfo() const { 8328409d6414dd4a42aa59779fcfe9fce18648cb135Stephen Hines ALOGE("Globals: %p %p %p", mGlobalAddresses, mGlobalSizes, mGlobalNames); 8335aa018cc36e589b07674957714d27ae3d1fa1c4eStephen Hines ALOGE("P - Pointer"); 8345aa018cc36e589b07674957714d27ae3d1fa1c4eStephen Hines ALOGE(" C - Constant"); 8355aa018cc36e589b07674957714d27ae3d1fa1c4eStephen Hines ALOGE(" S - Static"); 8368409d6414dd4a42aa59779fcfe9fce18648cb135Stephen Hines for (int i = 0; i < mGlobalEntries; i++) { 8378409d6414dd4a42aa59779fcfe9fce18648cb135Stephen Hines ALOGE("Global[%d]: %p %zu %s", i, mGlobalAddresses[i], mGlobalSizes[i], 8388409d6414dd4a42aa59779fcfe9fce18648cb135Stephen Hines mGlobalNames[i]); 8395aa018cc36e589b07674957714d27ae3d1fa1c4eStephen Hines uint32_t properties = mGlobalProperties[i]; 8405aa018cc36e589b07674957714d27ae3d1fa1c4eStephen Hines ALOGE("%c%c%c Type: %u", 8415aa018cc36e589b07674957714d27ae3d1fa1c4eStephen Hines isGlobalPointer(properties) ? 'P' : ' ', 8425aa018cc36e589b07674957714d27ae3d1fa1c4eStephen Hines isGlobalConstant(properties) ? 'C' : ' ', 8435aa018cc36e589b07674957714d27ae3d1fa1c4eStephen Hines isGlobalStatic(properties) ? 'S' : ' ', 8445aa018cc36e589b07674957714d27ae3d1fa1c4eStephen Hines getGlobalRsType(properties)); 8458409d6414dd4a42aa59779fcfe9fce18648cb135Stephen Hines } 8468409d6414dd4a42aa59779fcfe9fce18648cb135Stephen Hines return true; 8478409d6414dd4a42aa59779fcfe9fce18648cb135Stephen Hines} 8488409d6414dd4a42aa59779fcfe9fce18648cb135Stephen Hines 8492abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni} // namespace renderscript 8502abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni} // namespace android 851