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 82abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni#ifdef RS_COMPATIBILITY_LIB 92abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni#include <stdio.h> 102abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni#include <sys/stat.h> 112abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni#include <unistd.h> 122abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni#else 132abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni#include "bcc/Config/Config.h" 142abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni#endif 152abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 162abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni#include <dlfcn.h> 172abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 182abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ninamespace android { 192abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ninamespace renderscript { 202abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 212abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ninamespace { 222abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 232abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni// Check if a path exists and attempt to create it if it doesn't. 242abfcc6d129fe3defddef4540aa95cc445c03a7aYang Nistatic bool ensureCacheDirExists(const char *path) { 252abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni if (access(path, R_OK | W_OK | X_OK) == 0) { 262abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni // Done if we can rwx the directory 272abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni return true; 282abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni } 292abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni if (mkdir(path, 0700) == 0) { 302abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni return true; 312abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni } 322abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni return false; 332abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni} 342abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 352abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni// Copy the file named \p srcFile to \p dstFile. 362abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni// Return 0 on success and -1 if anything wasn't copied. 372abfcc6d129fe3defddef4540aa95cc445c03a7aYang Nistatic int copyFile(const char *dstFile, const char *srcFile) { 382abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni std::ifstream srcStream(srcFile); 392abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni if (!srcStream) { 402abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni ALOGE("Could not verify or read source file: %s", srcFile); 412abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni return -1; 422abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni } 432abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni std::ofstream dstStream(dstFile); 442abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni if (!dstStream) { 452abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni ALOGE("Could not verify or write destination file: %s", dstFile); 462abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni return -1; 472abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni } 482abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni dstStream << srcStream.rdbuf(); 492abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni if (!dstStream) { 502abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni ALOGE("Could not write destination file: %s", dstFile); 512abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni return -1; 522abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni } 532abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 542abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni srcStream.close(); 552abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni dstStream.close(); 562abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 572abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni return 0; 582abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni} 592abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 602abfcc6d129fe3defddef4540aa95cc445c03a7aYang Nistatic std::string findSharedObjectName(const char *cacheDir, 612abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni const char *resName) { 622abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni#ifndef RS_SERVER 632abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni std::string scriptSOName(cacheDir); 642abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni#if defined(RS_COMPATIBILITY_LIB) && !defined(__LP64__) 652abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni size_t cutPos = scriptSOName.rfind("cache"); 662abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni if (cutPos != std::string::npos) { 672abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni scriptSOName.erase(cutPos); 682abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni } else { 692abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni ALOGE("Found peculiar cacheDir (missing \"cache\"): %s", cacheDir); 702abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni } 712abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni scriptSOName.append("/lib/librs."); 722abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni#else 732abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni scriptSOName.append("/librs."); 742abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni#endif // RS_COMPATIBILITY_LIB 752abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 762abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni#else 772abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni std::string scriptSOName("lib"); 782abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni#endif // RS_SERVER 792abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni scriptSOName.append(resName); 802abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni scriptSOName.append(".so"); 812abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 822abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni return scriptSOName; 832abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni} 842abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 852abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni} // anonymous namespace 862abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 872abfcc6d129fe3defddef4540aa95cc445c03a7aYang Niconst char* SharedLibraryUtils::LD_EXE_PATH = "/system/bin/ld.mc"; 882abfcc6d129fe3defddef4540aa95cc445c03a7aYang Niconst char* SharedLibraryUtils::RS_CACHE_DIR = "com.android.renderscript.cache"; 892abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 902abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni#ifndef RS_COMPATIBILITY_LIB 912abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 92d97617a0a736b4dadcf978bfc1fa0aef0d4d50d3Jason Samsbool SharedLibraryUtils::createSharedLibrary(const char *driverName, 93d97617a0a736b4dadcf978bfc1fa0aef0d4d50d3Jason Sams const char *cacheDir, 94d97617a0a736b4dadcf978bfc1fa0aef0d4d50d3Jason Sams const char *resName) { 952abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni std::string sharedLibName = findSharedObjectName(cacheDir, resName); 962abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni std::string objFileName = cacheDir; 972abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni objFileName.append("/"); 982abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni objFileName.append(resName); 992abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni objFileName.append(".o"); 100d97617a0a736b4dadcf978bfc1fa0aef0d4d50d3Jason Sams // Should be something like "libRSDriver.so". 101d97617a0a736b4dadcf978bfc1fa0aef0d4d50d3Jason Sams std::string linkDriverName = driverName; 102d97617a0a736b4dadcf978bfc1fa0aef0d4d50d3Jason Sams // Remove ".so" and replace "lib" with "-l". 103d97617a0a736b4dadcf978bfc1fa0aef0d4d50d3Jason Sams // This will leave us with "-lRSDriver" instead. 104d97617a0a736b4dadcf978bfc1fa0aef0d4d50d3Jason Sams linkDriverName.erase(linkDriverName.length() - 3); 105d97617a0a736b4dadcf978bfc1fa0aef0d4d50d3Jason Sams linkDriverName.replace(0, 3, "-l"); 1062abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 1072abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni const char *compiler_rt = SYSLIBPATH"/libcompiler_rt.so"; 108c2be413317efcc44e3b282fd38fca3334c11777ePirama Arumuga Nainar const char *mTriple = "-mtriple=" DEFAULT_TARGET_TRIPLE_STRING; 109c2be413317efcc44e3b282fd38fca3334c11777ePirama Arumuga Nainar const char *libPath = "--library-path=" SYSLIBPATH; 11021732f493bd56ed83fb27f8823a66910ecbcf870Pirama Arumuga Nainar const char *vendorLibPath = "--library-path=" SYSLIBPATH_VENDOR; 111c2be413317efcc44e3b282fd38fca3334c11777ePirama Arumuga Nainar 1122abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni std::vector<const char *> args = { 1132abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni LD_EXE_PATH, 1142abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni "-shared", 1152abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni "-nostdlib", 11621732f493bd56ed83fb27f8823a66910ecbcf870Pirama Arumuga Nainar compiler_rt, mTriple, vendorLibPath, libPath, 117d97617a0a736b4dadcf978bfc1fa0aef0d4d50d3Jason Sams linkDriverName.c_str(), "-lm", "-lc", 1182abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni objFileName.c_str(), 1192abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni "-o", sharedLibName.c_str(), 1202abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni nullptr 1212abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni }; 1222abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 1232fa8a238dd69afebdeb757adcb1d674043d78e32Pirama Arumuga Nainar return rsuExecuteCommand(LD_EXE_PATH, args.size()-1, args.data()); 1242abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 1252abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni} 1262abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 1272abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni#endif // RS_COMPATIBILITY_LIB 1282abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 1292abfcc6d129fe3defddef4540aa95cc445c03a7aYang Niconst char* RsdCpuScriptImpl::BCC_EXE_PATH = "/system/bin/bcc"; 1302abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 1312abfcc6d129fe3defddef4540aa95cc445c03a7aYang Nivoid* SharedLibraryUtils::loadSharedLibrary(const char *cacheDir, 1322abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni const char *resName, 1339844cffc8af28c4829012bc0c48f85d04b671f88Yang Ni const char *nativeLibDir, 1349844cffc8af28c4829012bc0c48f85d04b671f88Yang Ni bool* alreadyLoaded) { 1352abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni void *loaded = nullptr; 1362abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 1372abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni#if defined(RS_COMPATIBILITY_LIB) && defined(__LP64__) 1382abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni std::string scriptSOName = findSharedObjectName(nativeLibDir, resName); 1392abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni#else 1402abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni std::string scriptSOName = findSharedObjectName(cacheDir, resName); 1412abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni#endif 1422abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 1432abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni // We should check if we can load the library from the standard app 1442abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni // location for shared libraries first. 1459844cffc8af28c4829012bc0c48f85d04b671f88Yang Ni loaded = loadSOHelper(scriptSOName.c_str(), cacheDir, resName, alreadyLoaded); 1462abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 1472abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni if (loaded == nullptr) { 1482abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni ALOGE("Unable to open shared library (%s): %s", 1492abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni scriptSOName.c_str(), dlerror()); 1502abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 1512abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni#ifdef RS_COMPATIBILITY_LIB 1522abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni // One final attempt to find the library in "/system/lib". 1532abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni // We do this to allow bundled applications to use the compatibility 1542abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni // library fallback path. Those applications don't have a private 1552abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni // library path, so they need to install to the system directly. 1562abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni // Note that this is really just a testing path. 1572abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni std::string scriptSONameSystem("/system/lib/librs."); 1582abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni scriptSONameSystem.append(resName); 1592abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni scriptSONameSystem.append(".so"); 1602abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni loaded = loadSOHelper(scriptSONameSystem.c_str(), cacheDir, 1612abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni resName); 1622abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni if (loaded == nullptr) { 1632abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni ALOGE("Unable to open system shared library (%s): %s", 1642abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni scriptSONameSystem.c_str(), dlerror()); 1652abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni } 1662abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni#endif 1672abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni } 1682abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 1692abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni return loaded; 1702abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni} 1712abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 1729844cffc8af28c4829012bc0c48f85d04b671f88Yang NiString8 SharedLibraryUtils::getRandomString(size_t len) { 1739844cffc8af28c4829012bc0c48f85d04b671f88Yang Ni char buf[len + 1]; 1749844cffc8af28c4829012bc0c48f85d04b671f88Yang Ni for (size_t i = 0; i < len; i++) { 1759844cffc8af28c4829012bc0c48f85d04b671f88Yang Ni uint32_t r = arc4random() & 0xffff; 1769844cffc8af28c4829012bc0c48f85d04b671f88Yang Ni r %= 62; 1779844cffc8af28c4829012bc0c48f85d04b671f88Yang Ni if (r < 26) { 1789844cffc8af28c4829012bc0c48f85d04b671f88Yang Ni // lowercase 1799844cffc8af28c4829012bc0c48f85d04b671f88Yang Ni buf[i] = 'a' + r; 1809844cffc8af28c4829012bc0c48f85d04b671f88Yang Ni } else if (r < 52) { 1819844cffc8af28c4829012bc0c48f85d04b671f88Yang Ni // uppercase 1829844cffc8af28c4829012bc0c48f85d04b671f88Yang Ni buf[i] = 'A' + (r - 26); 1839844cffc8af28c4829012bc0c48f85d04b671f88Yang Ni } else { 1849844cffc8af28c4829012bc0c48f85d04b671f88Yang Ni // Use a number 1859844cffc8af28c4829012bc0c48f85d04b671f88Yang Ni buf[i] = '0' + (r - 52); 1869844cffc8af28c4829012bc0c48f85d04b671f88Yang Ni } 1879844cffc8af28c4829012bc0c48f85d04b671f88Yang Ni } 1889844cffc8af28c4829012bc0c48f85d04b671f88Yang Ni buf[len] = '\0'; 1899844cffc8af28c4829012bc0c48f85d04b671f88Yang Ni return String8(buf); 1909844cffc8af28c4829012bc0c48f85d04b671f88Yang Ni} 1919844cffc8af28c4829012bc0c48f85d04b671f88Yang Ni 1922abfcc6d129fe3defddef4540aa95cc445c03a7aYang Nivoid* SharedLibraryUtils::loadSOHelper(const char *origName, const char *cacheDir, 1939844cffc8af28c4829012bc0c48f85d04b671f88Yang Ni const char *resName, bool *alreadyLoaded) { 1942abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni // Keep track of which .so libraries have been loaded. Once a library is 1952abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni // in the set (per-process granularity), we must instead make a copy of 1962abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni // the original shared object (randomly named .so file) and load that one 1972abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni // instead. If we don't do this, we end up aliasing global data between 1982abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni // the various Script instances (which are supposed to be completely 1992abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni // independent). 2002abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni static std::set<std::string> LoadedLibraries; 2012abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 2022abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni void *loaded = nullptr; 2032abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 2042abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni // Skip everything if we don't even have the original library available. 2052abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni if (access(origName, F_OK) != 0) { 2062abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni return nullptr; 2072abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni } 2082abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 2092abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni // Common path is that we have not loaded this Script/library before. 2102abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni if (LoadedLibraries.find(origName) == LoadedLibraries.end()) { 2119844cffc8af28c4829012bc0c48f85d04b671f88Yang Ni if (alreadyLoaded != nullptr) { 2129844cffc8af28c4829012bc0c48f85d04b671f88Yang Ni *alreadyLoaded = false; 2139844cffc8af28c4829012bc0c48f85d04b671f88Yang Ni } 2142abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni loaded = dlopen(origName, RTLD_NOW | RTLD_LOCAL); 2152abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni if (loaded) { 2162abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni LoadedLibraries.insert(origName); 2172abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni } 2182abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni return loaded; 2192abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni } 2202abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 2219844cffc8af28c4829012bc0c48f85d04b671f88Yang Ni if (alreadyLoaded != nullptr) { 2229844cffc8af28c4829012bc0c48f85d04b671f88Yang Ni *alreadyLoaded = true; 2239844cffc8af28c4829012bc0c48f85d04b671f88Yang Ni } 2249844cffc8af28c4829012bc0c48f85d04b671f88Yang Ni 2252abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni std::string newName(cacheDir); 2262abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 2272abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni // Append RS_CACHE_DIR only if it is not found in cacheDir 2282abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni // In driver mode, RS_CACHE_DIR is already appended to cacheDir. 2292abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni if (newName.find(RS_CACHE_DIR) == std::string::npos) { 2302abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni newName.append("/"); 2312abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni newName.append(RS_CACHE_DIR); 2322abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni newName.append("/"); 2332abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni } 2342abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 2352abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni if (!ensureCacheDirExists(newName.c_str())) { 2362abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni ALOGE("Could not verify or create cache dir: %s", cacheDir); 2372abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni return nullptr; 2382abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni } 2392abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 2402abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni // Construct an appropriately randomized filename for the copy. 2412abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni newName.append("librs."); 2422abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni newName.append(resName); 2432abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni newName.append("#"); 2449844cffc8af28c4829012bc0c48f85d04b671f88Yang Ni newName.append(getRandomString(6).string()); // 62^6 potential filename variants. 2452abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni newName.append(".so"); 2462abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 2472abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni int r = copyFile(newName.c_str(), origName); 2482abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni if (r != 0) { 2492abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni ALOGE("Could not create copy %s -> %s", origName, newName.c_str()); 2502abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni return nullptr; 2512abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni } 2522abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni loaded = dlopen(newName.c_str(), RTLD_NOW | RTLD_LOCAL); 2532abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni r = unlink(newName.c_str()); 2542abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni if (r != 0) { 2552abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni ALOGE("Could not unlink copy %s", newName.c_str()); 2562abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni } 2572abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni if (loaded) { 2582abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni LoadedLibraries.insert(newName.c_str()); 2592abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni } 2602abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 2612abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni return loaded; 2622abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni} 2632abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 2642abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni#define MAXLINE 500 2652abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni#define MAKE_STR_HELPER(S) #S 2662abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni#define MAKE_STR(S) MAKE_STR_HELPER(S) 2672abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni#define EXPORT_VAR_STR "exportVarCount: " 2682abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni#define EXPORT_FUNC_STR "exportFuncCount: " 2692abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni#define EXPORT_FOREACH_STR "exportForEachCount: " 2702abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni#define OBJECT_SLOT_STR "objectSlotCount: " 2712abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni#define PRAGMA_STR "pragmaCount: " 2722abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni#define THREADABLE_STR "isThreadable: " 273aa6757ffc1b23d771566439c3179fdbc1e5ba569Pirama Arumuga Nainar#define CHECKSUM_STR "buildChecksum: " 2742abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 2752abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni// Copy up to a newline or size chars from str -> s, updating str 2762abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni// Returns s when successful and nullptr when '\0' is finally reached. 2772abfcc6d129fe3defddef4540aa95cc445c03a7aYang Nistatic char* strgets(char *s, int size, const char **ppstr) { 2782abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni if (!ppstr || !*ppstr || **ppstr == '\0' || size < 1) { 2792abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni return nullptr; 2802abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni } 2812abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 2822abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni int i; 2832abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni for (i = 0; i < (size - 1); i++) { 2842abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni s[i] = **ppstr; 2852abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni (*ppstr)++; 2862abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni if (s[i] == '\0') { 2872abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni return s; 2882abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni } else if (s[i] == '\n') { 2892abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni s[i+1] = '\0'; 2902abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni return s; 2912abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni } 2922abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni } 2932abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 2942abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni // size has been exceeded. 2952abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni s[i] = '\0'; 2962abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 2972abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni return s; 2982abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni} 2992abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 3002abfcc6d129fe3defddef4540aa95cc445c03a7aYang NiScriptExecutable* ScriptExecutable::createFromSharedObject( 301cb17015fed6b11a5028f31cc804a3847e379945dYang Ni Context* RSContext, void* sharedObj, uint32_t expectedChecksum) { 3022abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni char line[MAXLINE]; 3032abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 3042abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni size_t varCount = 0; 3052abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni size_t funcCount = 0; 3062abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni size_t forEachCount = 0; 3072abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni size_t objectSlotCount = 0; 3082abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni size_t pragmaCount = 0; 3092abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni bool isThreadable = true; 3102abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 3112abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni void** fieldAddress = nullptr; 3122abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni bool* fieldIsObject = nullptr; 313062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni char** fieldName = nullptr; 3142abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni InvokeFunc_t* invokeFunctions = nullptr; 3152abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni ForEachFunc_t* forEachFunctions = nullptr; 3162abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni uint32_t* forEachSignatures = nullptr; 3172abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni const char ** pragmaKeys = nullptr; 3182abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni const char ** pragmaValues = nullptr; 319cb17015fed6b11a5028f31cc804a3847e379945dYang Ni uint32_t checksum = 0; 3202abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 3210e5d9f637a9ed4207582edb51e200912d8bf54cbStephen Hines const char *rsInfo = (const char *) dlsym(sharedObj, kRsInfo); 322a874c96bef8428131b83345dd92f37d8ce246d4eStephen Hines int numEntries = 0; 3230e5d9f637a9ed4207582edb51e200912d8bf54cbStephen Hines const int *rsGlobalEntries = (const int *) dlsym(sharedObj, kRsGlobalEntries); 3240e5d9f637a9ed4207582edb51e200912d8bf54cbStephen Hines const char **rsGlobalNames = (const char **) dlsym(sharedObj, kRsGlobalNames); 3250e5d9f637a9ed4207582edb51e200912d8bf54cbStephen Hines const void **rsGlobalAddresses = (const void **) dlsym(sharedObj, kRsGlobalAddresses); 3260e5d9f637a9ed4207582edb51e200912d8bf54cbStephen Hines const size_t *rsGlobalSizes = (const size_t *) dlsym(sharedObj, kRsGlobalSizes); 3270e5d9f637a9ed4207582edb51e200912d8bf54cbStephen Hines const uint32_t *rsGlobalProperties = (const uint32_t *) dlsym(sharedObj, kRsGlobalProperties); 3282abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 3292abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni if (strgets(line, MAXLINE, &rsInfo) == nullptr) { 3302abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni return nullptr; 3312abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni } 3322abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni if (sscanf(line, EXPORT_VAR_STR "%zu", &varCount) != 1) { 3332abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni ALOGE("Invalid export var count!: %s", line); 3342abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni return nullptr; 3352abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni } 3362abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 3372abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni fieldAddress = new void*[varCount]; 3382abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni if (fieldAddress == nullptr) { 3392abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni return nullptr; 3402abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni } 3412abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 3422abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni fieldIsObject = new bool[varCount]; 3432abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni if (fieldIsObject == nullptr) { 3442abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni goto error; 3452abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni } 3462abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 347062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni fieldName = new char*[varCount]; 348062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni if (fieldName == nullptr) { 349062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni goto error; 350062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni } 351062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni 3522abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni for (size_t i = 0; i < varCount; ++i) { 3532abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni if (strgets(line, MAXLINE, &rsInfo) == nullptr) { 3542abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni goto error; 3552abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni } 3562abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni char *c = strrchr(line, '\n'); 3572abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni if (c) { 3582abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni *c = '\0'; 3592abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni } 3602abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni void* addr = dlsym(sharedObj, line); 3612abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni if (addr == nullptr) { 3622abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni ALOGE("Failed to find variable address for %s: %s", 3632abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni line, dlerror()); 3642abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni // Not a critical error if we don't find a global variable. 3652abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni } 3662abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni fieldAddress[i] = addr; 3672abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni fieldIsObject[i] = false; 368062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni fieldName[i] = new char[strlen(line)+1]; 369062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni strcpy(fieldName[i], line); 3702abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni } 3712abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 3722abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni if (strgets(line, MAXLINE, &rsInfo) == nullptr) { 3732abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni goto error; 3742abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni } 3752abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni if (sscanf(line, EXPORT_FUNC_STR "%zu", &funcCount) != 1) { 3762abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni ALOGE("Invalid export func count!: %s", line); 3772abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni goto error; 3782abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni } 3792abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 3802abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni invokeFunctions = new InvokeFunc_t[funcCount]; 3812abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni if (invokeFunctions == nullptr) { 3822abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni goto error; 3832abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni } 3842abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 3852abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni for (size_t i = 0; i < funcCount; ++i) { 3862abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni if (strgets(line, MAXLINE, &rsInfo) == nullptr) { 3872abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni goto error; 3882abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni } 3892abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni char *c = strrchr(line, '\n'); 3902abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni if (c) { 3912abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni *c = '\0'; 3922abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni } 3932abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 3942abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni invokeFunctions[i] = (InvokeFunc_t) dlsym(sharedObj, line); 3952abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni if (invokeFunctions[i] == nullptr) { 3962abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni ALOGE("Failed to get function address for %s(): %s", 3972abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni line, dlerror()); 3982abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni goto error; 3992abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni } 4002abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni } 4012abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 4022abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni if (strgets(line, MAXLINE, &rsInfo) == nullptr) { 4032abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni goto error; 4042abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni } 4052abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni if (sscanf(line, EXPORT_FOREACH_STR "%zu", &forEachCount) != 1) { 4062abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni ALOGE("Invalid export forEach count!: %s", line); 4072abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni goto error; 4082abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni } 4092abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 4102abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni forEachFunctions = new ForEachFunc_t[forEachCount]; 4112abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni if (forEachFunctions == nullptr) { 4122abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni goto error; 4132abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni } 4142abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 4152abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni forEachSignatures = new uint32_t[forEachCount]; 4162abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni if (forEachSignatures == nullptr) { 4172abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni goto error; 4182abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni } 4192abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 4202abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni for (size_t i = 0; i < forEachCount; ++i) { 4212abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni unsigned int tmpSig = 0; 4222abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni char tmpName[MAXLINE]; 4232abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 4242abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni if (strgets(line, MAXLINE, &rsInfo) == nullptr) { 4252abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni goto error; 4262abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni } 4272abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni if (sscanf(line, "%u - %" MAKE_STR(MAXLINE) "s", 4282abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni &tmpSig, tmpName) != 2) { 4292abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni ALOGE("Invalid export forEach!: %s", line); 4302abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni goto error; 4312abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni } 4322abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 4332abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni // Lookup the expanded ForEach kernel. 4342abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni strncat(tmpName, ".expand", MAXLINE-1-strlen(tmpName)); 4352abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni forEachSignatures[i] = tmpSig; 4362abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni forEachFunctions[i] = 4372abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni (ForEachFunc_t) dlsym(sharedObj, tmpName); 438062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni if (i != 0 && forEachFunctions[i] == nullptr && 439062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni strcmp(tmpName, "root.expand")) { 4402abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni // Ignore missing root.expand functions. 4412abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni // root() is always specified at location 0. 4422abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni ALOGE("Failed to find forEach function address for %s: %s", 4432abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni tmpName, dlerror()); 4442abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni goto error; 4452abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni } 4462abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni } 4472abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 4482abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni if (strgets(line, MAXLINE, &rsInfo) == nullptr) { 4492abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni goto error; 4502abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni } 4512abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni if (sscanf(line, OBJECT_SLOT_STR "%zu", &objectSlotCount) != 1) { 4522abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni ALOGE("Invalid object slot count!: %s", line); 4532abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni goto error; 4542abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni } 4552abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 4562abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni for (size_t i = 0; i < objectSlotCount; ++i) { 4572abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni uint32_t varNum = 0; 4582abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni if (strgets(line, MAXLINE, &rsInfo) == nullptr) { 4592abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni goto error; 4602abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni } 4612abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni if (sscanf(line, "%u", &varNum) != 1) { 4622abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni ALOGE("Invalid object slot!: %s", line); 4632abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni goto error; 4642abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni } 4652abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 4662abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni if (varNum < varCount) { 4672abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni fieldIsObject[varNum] = true; 4682abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni } 4692abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni } 4702abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 4712abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni#ifndef RS_COMPATIBILITY_LIB 4722abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni // Do not attempt to read pragmas or isThreadable flag in compat lib path. 4732abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni // Neither is applicable for compat lib 4742abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 4752abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni if (strgets(line, MAXLINE, &rsInfo) == nullptr) { 4762abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni goto error; 4772abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni } 4782abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 4792abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni if (sscanf(line, PRAGMA_STR "%zu", &pragmaCount) != 1) { 4802abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni ALOGE("Invalid pragma count!: %s", line); 4812abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni goto error; 4822abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni } 4832abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 4842abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni pragmaKeys = new const char*[pragmaCount]; 4852abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni if (pragmaKeys == nullptr) { 4862abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni goto error; 4872abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni } 4882abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 4892abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni pragmaValues = new const char*[pragmaCount]; 4902abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni if (pragmaValues == nullptr) { 4912abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni goto error; 4922abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni } 4932abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 4942abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni bzero(pragmaKeys, sizeof(char*) * pragmaCount); 4952abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni bzero(pragmaValues, sizeof(char*) * pragmaCount); 4962abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 4972abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni for (size_t i = 0; i < pragmaCount; ++i) { 4982abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni if (strgets(line, MAXLINE, &rsInfo) == nullptr) { 4992abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni ALOGE("Unable to read pragma at index %zu!", i); 5002abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni goto error; 5012abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni } 5022abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni char key[MAXLINE]; 5032abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni char value[MAXLINE] = ""; // initialize in case value is empty 5042abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 5052abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni // pragmas can just have a key and no value. Only check to make sure 5062abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni // that the key is not empty 5072abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni if (sscanf(line, "%" MAKE_STR(MAXLINE) "s - %" MAKE_STR(MAXLINE) "s", 5082abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni key, value) == 0 || 5092abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni strlen(key) == 0) 5102abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni { 5112abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni ALOGE("Invalid pragma value!: %s", line); 5122abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 5132abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni goto error; 5142abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni } 5152abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 5162abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni char *pKey = new char[strlen(key)+1]; 5172abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni strcpy(pKey, key); 5182abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni pragmaKeys[i] = pKey; 5192abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 5202abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni char *pValue = new char[strlen(value)+1]; 5212abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni strcpy(pValue, value); 5222abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni pragmaValues[i] = pValue; 5232abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni //ALOGE("Pragma %zu: Key: '%s' Value: '%s'", i, pKey, pValue); 5242abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni } 5252abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 5262abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni if (strgets(line, MAXLINE, &rsInfo) == nullptr) { 5272abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni goto error; 5282abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni } 5292abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 5302abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni char tmpFlag[4]; 5312abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni if (sscanf(line, THREADABLE_STR "%4s", tmpFlag) != 1) { 5322abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni ALOGE("Invalid threadable flag!: %s", line); 5332abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni goto error; 5342abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni } 5352abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni if (strcmp(tmpFlag, "yes") == 0) { 5362abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni isThreadable = true; 5372abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni } else if (strcmp(tmpFlag, "no") == 0) { 5382abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni isThreadable = false; 5392abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni } else { 5402abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni ALOGE("Invalid threadable flag!: %s", tmpFlag); 5412abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni goto error; 5422abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni } 5432abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 544aa6757ffc1b23d771566439c3179fdbc1e5ba569Pirama Arumuga Nainar if (strgets(line, MAXLINE, &rsInfo) != nullptr) { 545cb17015fed6b11a5028f31cc804a3847e379945dYang Ni if (sscanf(line, CHECKSUM_STR "%08x", &checksum) != 1) { 546aa6757ffc1b23d771566439c3179fdbc1e5ba569Pirama Arumuga Nainar ALOGE("Invalid checksum flag!: %s", line); 547aa6757ffc1b23d771566439c3179fdbc1e5ba569Pirama Arumuga Nainar goto error; 548aa6757ffc1b23d771566439c3179fdbc1e5ba569Pirama Arumuga Nainar } 549062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni } else { 550062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni ALOGE("Missing checksum in shared obj file"); 551aa6757ffc1b23d771566439c3179fdbc1e5ba569Pirama Arumuga Nainar goto error; 552aa6757ffc1b23d771566439c3179fdbc1e5ba569Pirama Arumuga Nainar } 553aa6757ffc1b23d771566439c3179fdbc1e5ba569Pirama Arumuga Nainar 554cb17015fed6b11a5028f31cc804a3847e379945dYang Ni if (expectedChecksum != 0 && checksum != expectedChecksum) { 555cb17015fed6b11a5028f31cc804a3847e379945dYang Ni ALOGE("Found invalid checksum. Expected %08x, got %08x\n", 556cb17015fed6b11a5028f31cc804a3847e379945dYang Ni expectedChecksum, checksum); 557cb17015fed6b11a5028f31cc804a3847e379945dYang Ni goto error; 558cb17015fed6b11a5028f31cc804a3847e379945dYang Ni } 559cb17015fed6b11a5028f31cc804a3847e379945dYang Ni 5602abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni#endif // RS_COMPATIBILITY_LIB 5612abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 562a874c96bef8428131b83345dd92f37d8ce246d4eStephen Hines // Read in information about mutable global variables provided by bcc's 563a874c96bef8428131b83345dd92f37d8ce246d4eStephen Hines // RSGlobalInfoPass 564a874c96bef8428131b83345dd92f37d8ce246d4eStephen Hines if (rsGlobalEntries) { 565a874c96bef8428131b83345dd92f37d8ce246d4eStephen Hines numEntries = *rsGlobalEntries; 566a874c96bef8428131b83345dd92f37d8ce246d4eStephen Hines if (numEntries > 0) { 567a874c96bef8428131b83345dd92f37d8ce246d4eStephen Hines rsAssert(rsGlobalNames); 568a874c96bef8428131b83345dd92f37d8ce246d4eStephen Hines rsAssert(rsGlobalAddresses); 569a874c96bef8428131b83345dd92f37d8ce246d4eStephen Hines rsAssert(rsGlobalSizes); 5700e5d9f637a9ed4207582edb51e200912d8bf54cbStephen Hines rsAssert(rsGlobalProperties); 571a874c96bef8428131b83345dd92f37d8ce246d4eStephen Hines } 572a874c96bef8428131b83345dd92f37d8ce246d4eStephen Hines } else { 573a874c96bef8428131b83345dd92f37d8ce246d4eStephen Hines ALOGD("Missing .rs.global_entries from shared object"); 574a874c96bef8428131b83345dd92f37d8ce246d4eStephen Hines } 575a874c96bef8428131b83345dd92f37d8ce246d4eStephen Hines 5762abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni return new ScriptExecutable( 577062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni RSContext, fieldAddress, fieldIsObject, fieldName, varCount, 5782abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni invokeFunctions, funcCount, 5792abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni forEachFunctions, forEachSignatures, forEachCount, 5802abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni pragmaKeys, pragmaValues, pragmaCount, 5810e5d9f637a9ed4207582edb51e200912d8bf54cbStephen Hines rsGlobalNames, rsGlobalAddresses, rsGlobalSizes, rsGlobalProperties, 5820e5d9f637a9ed4207582edb51e200912d8bf54cbStephen Hines numEntries, isThreadable, checksum); 5832abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 5842abfcc6d129fe3defddef4540aa95cc445c03a7aYang Nierror: 5852abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 5862abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni#ifndef RS_COMPATIBILITY_LIB 587aa6757ffc1b23d771566439c3179fdbc1e5ba569Pirama Arumuga Nainar 5882abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni for (size_t idx = 0; idx < pragmaCount; ++idx) { 5892abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni delete [] pragmaKeys[idx]; 5902abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni delete [] pragmaValues[idx]; 5912abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni } 5922abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 5932abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni delete[] pragmaValues; 5942abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni delete[] pragmaKeys; 5952abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni#endif // RS_COMPATIBILITY_LIB 5962abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 5972abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni delete[] forEachSignatures; 5982abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni delete[] forEachFunctions; 599062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni 6002abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni delete[] invokeFunctions; 601062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni 602062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni for (size_t i = 0; i < varCount; i++) { 603062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni delete[] fieldName[i]; 604062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni } 605062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni delete[] fieldName; 6062abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni delete[] fieldIsObject; 6072abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni delete[] fieldAddress; 6082abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 6092abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni return nullptr; 6102abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni} 6112abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni 612062c287f573ecc06c38ee4295e5627e12c52ac3dYang Nivoid* ScriptExecutable::getFieldAddress(const char* name) const { 613062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni // TODO: improve this by using a hash map. 614062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni for (size_t i = 0; i < mExportedVarCount; i++) { 615062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni if (strcmp(name, mFieldName[i]) == 0) { 616062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni return mFieldAddress[i]; 617062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni } 618062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni } 619062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni return nullptr; 620062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni} 621062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni 622a874c96bef8428131b83345dd92f37d8ce246d4eStephen Hinesbool ScriptExecutable::dumpGlobalInfo() const { 623a874c96bef8428131b83345dd92f37d8ce246d4eStephen Hines ALOGE("Globals: %p %p %p", mGlobalAddresses, mGlobalSizes, mGlobalNames); 6240e5d9f637a9ed4207582edb51e200912d8bf54cbStephen Hines ALOGE("P - Pointer"); 6250e5d9f637a9ed4207582edb51e200912d8bf54cbStephen Hines ALOGE(" C - Constant"); 6260e5d9f637a9ed4207582edb51e200912d8bf54cbStephen Hines ALOGE(" S - Static"); 627a874c96bef8428131b83345dd92f37d8ce246d4eStephen Hines for (int i = 0; i < mGlobalEntries; i++) { 628a874c96bef8428131b83345dd92f37d8ce246d4eStephen Hines ALOGE("Global[%d]: %p %zu %s", i, mGlobalAddresses[i], mGlobalSizes[i], 629a874c96bef8428131b83345dd92f37d8ce246d4eStephen Hines mGlobalNames[i]); 6300e5d9f637a9ed4207582edb51e200912d8bf54cbStephen Hines uint32_t properties = mGlobalProperties[i]; 6310e5d9f637a9ed4207582edb51e200912d8bf54cbStephen Hines ALOGE("%c%c%c Type: %u", 6320e5d9f637a9ed4207582edb51e200912d8bf54cbStephen Hines isGlobalPointer(properties) ? 'P' : ' ', 6330e5d9f637a9ed4207582edb51e200912d8bf54cbStephen Hines isGlobalConstant(properties) ? 'C' : ' ', 6340e5d9f637a9ed4207582edb51e200912d8bf54cbStephen Hines isGlobalStatic(properties) ? 'S' : ' ', 6350e5d9f637a9ed4207582edb51e200912d8bf54cbStephen Hines getGlobalRsType(properties)); 636a874c96bef8428131b83345dd92f37d8ce246d4eStephen Hines } 637a874c96bef8428131b83345dd92f37d8ce246d4eStephen Hines return true; 638a874c96bef8428131b83345dd92f37d8ce246d4eStephen Hines} 639a874c96bef8428131b83345dd92f37d8ce246d4eStephen Hines 6402abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni} // namespace renderscript 6412abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni} // namespace android 642