#include "rsCpuExecutable.h"
#include "rsCppUtils.h"

#include <fstream>
#include <set>
#include <memory>

#include <sys/stat.h>

#ifdef RS_COMPATIBILITY_LIB
#include <stdio.h>
#else
#include "bcc/Config.h"
#endif

#include <unistd.h>
#include <dlfcn.h>
#include <android/dlext.h>
#include <sys/stat.h>

namespace android {
namespace renderscript {

namespace {

// Check if a path exists and attempt to create it if it doesn't.
[[maybe_unused]]
static bool ensureCacheDirExists(const char *path) {
    if (access(path, R_OK | W_OK | X_OK) == 0) {
        // Done if we can rwx the directory
        return true;
    }
    if (mkdir(path, 0700) == 0) {
        return true;
    }
    return false;
}

// Copy the file named \p srcFile to \p dstFile.
// Return 0 on success and -1 if anything wasn't copied.
[[maybe_unused]]
static int copyFile(const char *dstFile, const char *srcFile) {
    std::ifstream srcStream(srcFile);
    if (!srcStream) {
        ALOGE("Could not verify or read source file: %s", srcFile);
        return -1;
    }
    std::ofstream dstStream(dstFile);
    if (!dstStream) {
        ALOGE("Could not verify or write destination file: %s", dstFile);
        return -1;
    }
    dstStream << srcStream.rdbuf();
    if (!dstStream) {
        ALOGE("Could not write destination file: %s", dstFile);
        return -1;
    }

    srcStream.close();
    dstStream.close();

    return 0;
}

static std::string findSharedObjectName(const char *cacheDir,
                                        const char *resName,
                                        const bool reuse = true) {
    std::string scriptSOName(cacheDir);
#if defined(RS_COMPATIBILITY_LIB) && !defined(__LP64__)
    size_t cutPos = scriptSOName.rfind("cache");
    if (cutPos != std::string::npos) {
        scriptSOName.erase(cutPos);
    } else {
        ALOGE("Found peculiar cacheDir (missing \"cache\"): %s", cacheDir);
    }
    scriptSOName.append("/lib/librs.");
#else
    scriptSOName.append("/librs.");
#endif // RS_COMPATIBILITY_LIB
    scriptSOName.append(resName);
    if (!reuse) {
        // If the generated shared library is not reused, e.g., with a debug
        // context or forced by a system property, multiple threads may read
        // and write the shared library at the same time. To avoid the race
        // on the generated shared library, delete it before finishing script
        // initialization. To avoid deleting a file generated by a regular
        // context, use a special suffix here.
        // Because the script initialization is guarded by a lock from the Java
        // API, it is safe to name this file with a consistent name and suffix
        // and delete it after loading. The same lock has also prevented write-
        // write races on the .so during script initialization even if reuse is
        // true.
        scriptSOName.append("#delete_after_load");
    }
    scriptSOName.append(".so");

    return scriptSOName;
}

#ifndef RS_COMPATIBILITY_LIB
static bool isRunningInVndkNamespace() {
    static bool result = []() {
        Dl_info info;
        if (dladdr(reinterpret_cast<const void*>(&isRunningInVndkNamespace), &info) != 0) {
            std::string filename = std::string(info.dli_fname);
            return filename.find("/apex/com.android.vndk") != std::string::npos;
        } else {
            ALOGW("Can't determine whether this lib is running in vndk namespace or not. Assuming it is in vndk namespace.");
        }
        return true;
    }();
    return result;
}
#endif

}  // anonymous namespace

const char* SharedLibraryUtils::LD_EXE_PATH = "/system/bin/ld.mc";
const char* SharedLibraryUtils::RS_CACHE_DIR = "com.android.renderscript.cache";

#ifndef RS_COMPATIBILITY_LIB

bool SharedLibraryUtils::createSharedLibrary(const char *driverName,
                                             const char *cacheDir,
                                             const char *resName,
                                             const bool reuse,
                                             std::string *fullPath) {
    std::string sharedLibName = findSharedObjectName(cacheDir, resName, reuse);
    if (fullPath) {
        *fullPath = sharedLibName;
    }
    std::string objFileName = cacheDir;
    objFileName.append("/");
    objFileName.append(resName);
    objFileName.append(".o");
    // Should be something like "libRSDriver.so".
    std::string linkDriverName = driverName;
    // Remove ".so" and replace "lib" with "-l".
    // This will leave us with "-lRSDriver" instead.
    linkDriverName.erase(linkDriverName.length() - 3);
    linkDriverName.replace(0, 3, "-l");

    static const std::string vndkLibCompilerRt =
        getVndkSysLibPath() + "/libcompiler_rt.so";
    const char *compiler_rt = isRunningInVndkNamespace() ?
        vndkLibCompilerRt.c_str() : SYSLIBPATH "/libcompiler_rt.so";
    const char *mTriple = "-mtriple=" DEFAULT_TARGET_TRIPLE_STRING;
    const char *libPath = "--library-path=" SYSLIBPATH;
    // vndk path is only added when RS framework is running in vndk namespace.
    // If we unconditionally add the vndk path to the library path, then RS
    // driver in the vndk-sp directory will always be used even for CPU fallback
    // case, where RS framework is loaded from the default namespace.
    static const std::string vndkLibPathString =
        "--library-path=" + getVndkSysLibPath();
    const char *vndkLibPath = isRunningInVndkNamespace() ?
        vndkLibPathString.c_str() : "";
    const char *vendorLibPath = "--library-path=" SYSLIBPATH_VENDOR;

    // The search path order should be vendor -> vndk -> system
    std::vector<const char *> args = {
        LD_EXE_PATH,
        "-shared",
        "-nostdlib",
        compiler_rt, mTriple, vendorLibPath, vndkLibPath, libPath,
        linkDriverName.c_str(), "-lm", "-lc",
        objFileName.c_str(),
        "-o", sharedLibName.c_str(),
        nullptr
    };

    return rsuExecuteCommand(LD_EXE_PATH, args.size()-1, args.data());

}

#endif  // RS_COMPATIBILITY_LIB

const char* RsdCpuScriptImpl::BCC_EXE_PATH = "/system/bin/bcc";

void* SharedLibraryUtils::loadAndDeleteSharedLibrary(const char *fullPath) {
    void *loaded = dlopen(fullPath, RTLD_NOW | RTLD_LOCAL);
    if (loaded == nullptr) {
        ALOGE("Unable to open shared library (%s): %s", fullPath, dlerror());
        return nullptr;
    }

    int r = unlink(fullPath);
    if (r != 0) {
        ALOGE("Could not unlink copy %s", fullPath);
        return nullptr;
    }
    return loaded;
}

void* SharedLibraryUtils::loadSharedLibrary(const char *cacheDir,
                                            const char *resName,
                                            const char *nativeLibDir,
                                            bool* alreadyLoaded) {
    void *loaded = nullptr;

#if defined(RS_COMPATIBILITY_LIB) && defined(__LP64__)
    std::string scriptSOName = findSharedObjectName(nativeLibDir, resName);
#else
    std::string scriptSOName = findSharedObjectName(cacheDir, resName);
#endif

    // We should check if we can load the library from the standard app
    // location for shared libraries first.
    loaded = loadSOHelper(scriptSOName.c_str(), cacheDir, resName, alreadyLoaded);

    if (loaded != nullptr) {
       return loaded;
    }
    ALOGE("Unable to open shared library (%s): %s", scriptSOName.c_str(), dlerror());

#ifdef RS_COMPATIBILITY_LIB
    // Re-trying without absolute path.
    // For RS support lib, the shared object may not be extracted from the apk.
    // In order to access that, we need to load the library without specifying
    // the absolute path.
    std::string scriptSONameApk("librs.");
    scriptSONameApk.append(resName);
    scriptSONameApk.append(".so");
    loaded = loadSOHelper(scriptSONameApk.c_str(), cacheDir, resName);
    if (loaded != nullptr) {
        return loaded;
    }
    ALOGE("Unable to open APK shared library (%s): %s", scriptSONameApk.c_str(), dlerror());

    // One final attempt to find the library in "/system/lib".
    // We do this to allow bundled applications to use the compatibility
    // library fallback path. Those applications don't have a private
    // library path, so they need to install to the system directly.
    // Note that this is really just a testing path.
    std::string scriptSONameSystem("/system/lib/librs.");
    scriptSONameSystem.append(resName);
    scriptSONameSystem.append(".so");
    loaded = loadSOHelper(scriptSONameSystem.c_str(), cacheDir, resName);
    if (loaded == nullptr) {
        ALOGE("Unable to open system shared library (%s): %s",
              scriptSONameSystem.c_str(), dlerror());
    }
#endif

    return loaded;
}

std::string SharedLibraryUtils::getRandomString(size_t len) {
    char buf[len + 1];
    for (size_t i = 0; i < len; i++) {
        uint32_t r = arc4random() & 0xffff;
        r %= 62;
        if (r < 26) {
            // lowercase
            buf[i] = 'a' + r;
        } else if (r < 52) {
            // uppercase
            buf[i] = 'A' + (r - 26);
        } else {
            // Use a number
            buf[i] = '0' + (r - 52);
        }
    }
    buf[len] = '\0';
    return std::string(buf);
}

static void* loadAsCopy(const char *origName, std::string newName) {
    void *loaded = nullptr;
#ifndef RS_COMPATIBILITY_LIB
    int fd = TEMP_FAILURE_RETRY(open(origName, O_RDONLY | O_CLOEXEC));
    if (fd == -1) {
        ALOGE("Unable to open original file %s: %s", origName, strerror(errno));
        return nullptr;
    }

    android_dlextinfo extinfo;
    memset(&extinfo, 0, sizeof(extinfo));
    extinfo.flags = ANDROID_DLEXT_USE_LIBRARY_FD | ANDROID_DLEXT_FORCE_LOAD;
    extinfo.library_fd = fd;

    loaded = android_dlopen_ext(newName.c_str(), RTLD_NOW | RTLD_LOCAL, &extinfo);
    close(fd);
#else
    int r = copyFile(newName.c_str(), origName);
    if (r != 0) {
        ALOGE("Could not create copy %s -> %s", origName, newName.c_str());
        return nullptr;
    }
    loaded = dlopen(newName.c_str(), RTLD_NOW | RTLD_LOCAL);
    r = unlink(newName.c_str());
    if (r != 0) {
        ALOGE("Could not unlink copy %s", newName.c_str());
    }
#endif  // RS_COMPATIBILITY_LIB
    return loaded;
}

void* SharedLibraryUtils::loadSOHelper(const char *origName, const char *cacheDir,
                                       const char *resName, bool *alreadyLoaded) {
    // Keep track of which .so libraries have been loaded. Once a library is
    // in the set (per-process granularity), we must instead make a copy of
    // the original shared object (randomly named .so file) and load that one
    // instead. If we don't do this, we end up aliasing global data between
    // the various Script instances (which are supposed to be completely
    // independent).
    static std::set<std::string> LoadedLibraries;

    void *loaded = nullptr;

#ifndef RS_COMPATIBILITY_LIB
    // Skip everything if we don't even have the original library available.
    if (access(origName, F_OK) != 0) {
        return nullptr;
    }
#endif  // RS_COMPATIBILITY_LIB

    // Common path is that we have not loaded this Script/library before.
    if (LoadedLibraries.find(origName) == LoadedLibraries.end()) {
        if (alreadyLoaded != nullptr) {
            *alreadyLoaded = false;
        }
        loaded = dlopen(origName, RTLD_NOW | RTLD_LOCAL);
        if (loaded) {
            LoadedLibraries.insert(origName);
        }
        return loaded;
    }

    if (alreadyLoaded != nullptr) {
        *alreadyLoaded = true;
    }

    std::string newName(cacheDir);

    // Append RS_CACHE_DIR only if it is not found in cacheDir
    // In driver mode, RS_CACHE_DIR is already appended to cacheDir.
    if (newName.find(RS_CACHE_DIR) == std::string::npos) {
        newName.append("/");
        newName.append(RS_CACHE_DIR);
        newName.append("/");
    }

    if (!ensureCacheDirExists(newName.c_str())) {
        ALOGE("Could not verify or create cache dir: %s", cacheDir);
        return nullptr;
    }

    // Construct an appropriately randomized filename for the copy.
    newName.append("librs.");
    newName.append(resName);
    newName.append("#");
    newName.append(getRandomString(6).c_str());  // 62^6 potential filename variants.
    newName.append(".so");

    loaded = loadAsCopy(origName, newName);

    if (loaded) {
        LoadedLibraries.insert(newName.c_str());
    }

    return loaded;
}

// MAXLINESTR must be compatible with operator '#' in C macro.
#define MAXLINESTR 499
// MAXLINE must be (MAXLINESTR + 1), representing the size of a C string
// containing MAXLINESTR non-null chars plus a null.
#define MAXLINE (MAXLINESTR + 1)
#define MAKE_STR_HELPER(S) #S
#define MAKE_STR(S) MAKE_STR_HELPER(S)
#define EXPORT_VAR_STR "exportVarCount: "
#define EXPORT_FUNC_STR "exportFuncCount: "
#define EXPORT_FOREACH_STR "exportForEachCount: "
#define EXPORT_REDUCE_STR "exportReduceCount: "
#define OBJECT_SLOT_STR "objectSlotCount: "
#define PRAGMA_STR "pragmaCount: "
#define THREADABLE_STR "isThreadable: "
#define CHECKSUM_STR "buildChecksum: "
#define VERSIONINFO_STR "versionInfo: "

// Copy up to a newline or size chars from str -> s, updating str
// Returns s when successful and nullptr when '\0' is finally reached.
static char* strgets(char *s, int size, const char **ppstr) {
    if (!ppstr || !*ppstr || **ppstr == '\0' || size < 1) {
        return nullptr;
    }

    int i;
    for (i = 0; i < (size - 1); i++) {
        s[i] = **ppstr;
        (*ppstr)++;
        if (s[i] == '\0') {
            return s;
        } else if (s[i] == '\n') {
            s[i+1] = '\0';
            return s;
        }
    }

    // size has been exceeded.
    s[i] = '\0';

    return s;
}

// Creates a duplicate of a string. The new string is as small as possible,
// only including characters up to and including the first null-terminator;
// otherwise, the new string will be the same size as the input string.
// The code that calls duplicateString is responsible for the new string's
// lifetime, and is responsible for freeing it when it is no longer needed.
static char* duplicateString(const char *str, size_t length) {
    const size_t newLen = strnlen(str, length-1) + 1;
    char *newStr = new char[newLen];
    strlcpy(newStr, str, newLen);
    return newStr;
}

ScriptExecutable* ScriptExecutable::createFromSharedObject(
    void* sharedObj, uint32_t expectedChecksum) {
    char line[MAXLINE];

    size_t varCount = 0;
    size_t funcCount = 0;
    size_t forEachCount = 0;
    size_t reduceCount = 0;
    size_t objectSlotCount = 0;
    size_t pragmaCount = 0;
    bool isThreadable = true;

    void** fieldAddress = nullptr;
    bool* fieldIsObject = nullptr;
    char** fieldName = nullptr;
    InvokeFunc_t* invokeFunctions = nullptr;
    ForEachFunc_t* forEachFunctions = nullptr;
    uint32_t* forEachSignatures = nullptr;
    ReduceDescription* reduceDescriptions = nullptr;
    const char ** pragmaKeys = nullptr;
    const char ** pragmaValues = nullptr;
    uint32_t checksum = 0;

    const char *rsInfo = (const char *) dlsym(sharedObj, kRsInfo);
    int numEntries = 0;
    const int *rsGlobalEntries = (const int *) dlsym(sharedObj, kRsGlobalEntries);
    const char **rsGlobalNames = (const char **) dlsym(sharedObj, kRsGlobalNames);
    const void **rsGlobalAddresses = (const void **) dlsym(sharedObj, kRsGlobalAddresses);
    const size_t *rsGlobalSizes = (const size_t *) dlsym(sharedObj, kRsGlobalSizes);
    const uint32_t *rsGlobalProperties = (const uint32_t *) dlsym(sharedObj, kRsGlobalProperties);

    if (strgets(line, MAXLINE, &rsInfo) == nullptr) {
        return nullptr;
    }
    if (sscanf(line, EXPORT_VAR_STR "%zu", &varCount) != 1) {
        ALOGE("Invalid export var count!: %s", line);
        return nullptr;
    }

    fieldAddress = new void*[varCount];
    if (fieldAddress == nullptr) {
        return nullptr;
    }

    fieldIsObject = new bool[varCount];
    if (fieldIsObject == nullptr) {
        goto error;
    }

    fieldName = new char*[varCount];
    if (fieldName == nullptr) {
        goto error;
    }

    for (size_t i = 0; i < varCount; ++i) {
        if (strgets(line, MAXLINE, &rsInfo) == nullptr) {
            goto error;
        }
        char *c = strrchr(line, '\n');
        if (c) {
            *c = '\0';
        }
        void* addr = dlsym(sharedObj, line);
        if (addr == nullptr) {
            ALOGE("Failed to find variable address for %s: %s",
                  line, dlerror());
            // Not a critical error if we don't find a global variable.
        }
        fieldAddress[i] = addr;
        fieldIsObject[i] = false;
        fieldName[i] = duplicateString(line, sizeof(line));
    }

    if (strgets(line, MAXLINE, &rsInfo) == nullptr) {
        goto error;
    }
    if (sscanf(line, EXPORT_FUNC_STR "%zu", &funcCount) != 1) {
        ALOGE("Invalid export func count!: %s", line);
        goto error;
    }

    invokeFunctions = new InvokeFunc_t[funcCount];
    if (invokeFunctions == nullptr) {
        goto error;
    }

    for (size_t i = 0; i < funcCount; ++i) {
        if (strgets(line, MAXLINE, &rsInfo) == nullptr) {
            goto error;
        }
        char *c = strrchr(line, '\n');
        if (c) {
            *c = '\0';
        }

        invokeFunctions[i] = (InvokeFunc_t) dlsym(sharedObj, line);
        if (invokeFunctions[i] == nullptr) {
            ALOGE("Failed to get function address for %s(): %s",
                  line, dlerror());
            goto error;
        }
    }

    if (strgets(line, MAXLINE, &rsInfo) == nullptr) {
        goto error;
    }
    if (sscanf(line, EXPORT_FOREACH_STR "%zu", &forEachCount) != 1) {
        ALOGE("Invalid export forEach count!: %s", line);
        goto error;
    }

    forEachFunctions = new ForEachFunc_t[forEachCount];
    if (forEachFunctions == nullptr) {
        goto error;
    }

    forEachSignatures = new uint32_t[forEachCount];
    if (forEachSignatures == nullptr) {
        goto error;
    }

    for (size_t i = 0; i < forEachCount; ++i) {
        unsigned int tmpSig = 0;
        char tmpName[MAXLINE];

        if (strgets(line, MAXLINE, &rsInfo) == nullptr) {
            goto error;
        }
        if (sscanf(line, "%u - %" MAKE_STR(MAXLINESTR) "s",
                   &tmpSig, tmpName) != 2) {
          ALOGE("Invalid export forEach!: %s", line);
          goto error;
        }

        // Lookup the expanded ForEach kernel.
        strncat(tmpName, ".expand", MAXLINESTR-strlen(tmpName));
        forEachSignatures[i] = tmpSig;
        forEachFunctions[i] =
            (ForEachFunc_t) dlsym(sharedObj, tmpName);
        if (i != 0 && forEachFunctions[i] == nullptr &&
            strcmp(tmpName, "root.expand")) {
            // Ignore missing root.expand functions.
            // root() is always specified at location 0.
            ALOGE("Failed to find forEach function address for %s(): %s",
                  tmpName, dlerror());
            goto error;
        }
    }

    // Read general reduce kernels
    if (strgets(line, MAXLINE, &rsInfo) == nullptr) {
        goto error;
    }
    if (sscanf(line, EXPORT_REDUCE_STR "%zu", &reduceCount) != 1) {
        ALOGE("Invalid export reduce new count!: %s", line);
        goto error;
    }

    reduceDescriptions = new ReduceDescription[reduceCount];
    if (reduceDescriptions == nullptr) {
        goto error;
    }

    for (size_t i = 0; i < reduceCount; ++i) {
        static const char kNoName[] = ".";

        unsigned int tmpSig = 0;
        size_t tmpSize = 0;
        char tmpNameReduce[MAXLINE];
        char tmpNameInitializer[MAXLINE];
        char tmpNameAccumulator[MAXLINE];
        char tmpNameCombiner[MAXLINE];
        char tmpNameOutConverter[MAXLINE];
        char tmpNameHalter[MAXLINE];

        if (strgets(line, MAXLINE, &rsInfo) == nullptr) {
            goto error;
        }
#define DELIMNAME " - %" MAKE_STR(MAXLINESTR) "s"
        if (sscanf(line, "%u - %zu" DELIMNAME DELIMNAME DELIMNAME DELIMNAME DELIMNAME DELIMNAME,
                   &tmpSig, &tmpSize, tmpNameReduce, tmpNameInitializer, tmpNameAccumulator,
                   tmpNameCombiner, tmpNameOutConverter, tmpNameHalter) != 8) {
            ALOGE("Invalid export reduce new!: %s", line);
            goto error;
        }
#undef DELIMNAME

        // For now, we expect
        // - Reduce and Accumulator names
        // - optional Initializer, Combiner, and OutConverter name
        // - no Halter name
        if (!strcmp(tmpNameReduce, kNoName) ||
            !strcmp(tmpNameAccumulator, kNoName)) {
            ALOGE("Expected reduce and accumulator names!: %s", line);
            goto error;
        }
        if (strcmp(tmpNameHalter, kNoName)) {
            ALOGE("Did not expect halter name!: %s", line);
            goto error;
        }

        // The current implementation does not use the signature
        // or reduce name.

        reduceDescriptions[i].accumSize = tmpSize;

        // Process the (optional) initializer.
        if (strcmp(tmpNameInitializer, kNoName)) {
          // Lookup the original user-written initializer.
          if (!(reduceDescriptions[i].initFunc =
                (ReduceInitializerFunc_t) dlsym(sharedObj, tmpNameInitializer))) {
            ALOGE("Failed to find initializer function address for %s(): %s",
                  tmpNameInitializer, dlerror());
            goto error;
          }
        } else {
          reduceDescriptions[i].initFunc = nullptr;
        }

        // Lookup the expanded accumulator.
        strncat(tmpNameAccumulator, ".expand", MAXLINESTR-strlen(tmpNameAccumulator));
        if (!(reduceDescriptions[i].accumFunc =
              (ReduceAccumulatorFunc_t) dlsym(sharedObj, tmpNameAccumulator))) {
            ALOGE("Failed to find accumulator function address for %s(): %s",
                  tmpNameAccumulator, dlerror());
            goto error;
        }

        // Process the (optional) combiner.
        if (strcmp(tmpNameCombiner, kNoName)) {
          // Lookup the original user-written combiner.
          if (!(reduceDescriptions[i].combFunc =
                (ReduceCombinerFunc_t) dlsym(sharedObj, tmpNameCombiner))) {
            ALOGE("Failed to find combiner function address for %s(): %s",
                  tmpNameCombiner, dlerror());
            goto error;
          }
        } else {
          reduceDescriptions[i].combFunc = nullptr;
        }

        // Process the (optional) outconverter.
        if (strcmp(tmpNameOutConverter, kNoName)) {
          // Lookup the original user-written outconverter.
          if (!(reduceDescriptions[i].outFunc =
                (ReduceOutConverterFunc_t) dlsym(sharedObj, tmpNameOutConverter))) {
            ALOGE("Failed to find outconverter function address for %s(): %s",
                  tmpNameOutConverter, dlerror());
            goto error;
          }
        } else {
          reduceDescriptions[i].outFunc = nullptr;
        }
    }

    if (strgets(line, MAXLINE, &rsInfo) == nullptr) {
        goto error;
    }
    if (sscanf(line, OBJECT_SLOT_STR "%zu", &objectSlotCount) != 1) {
        ALOGE("Invalid object slot count!: %s", line);
        goto error;
    }

    for (size_t i = 0; i < objectSlotCount; ++i) {
        uint32_t varNum = 0;
        if (strgets(line, MAXLINE, &rsInfo) == nullptr) {
            goto error;
        }
        if (sscanf(line, "%u", &varNum) != 1) {
            ALOGE("Invalid object slot!: %s", line);
            goto error;
        }

        if (varNum < varCount) {
            fieldIsObject[varNum] = true;
        }
    }

#ifndef RS_COMPATIBILITY_LIB
    // Do not attempt to read pragmas or isThreadable flag in compat lib path.
    // Neither is applicable for compat lib

    if (strgets(line, MAXLINE, &rsInfo) == nullptr) {
        goto error;
    }

    if (sscanf(line, PRAGMA_STR "%zu", &pragmaCount) != 1) {
        ALOGE("Invalid pragma count!: %s", line);
        goto error;
    }

    pragmaKeys = new const char*[pragmaCount];
    if (pragmaKeys == nullptr) {
        goto error;
    }

    pragmaValues = new const char*[pragmaCount];
    if (pragmaValues == nullptr) {
        goto error;
    }

    bzero(pragmaKeys, sizeof(char*) * pragmaCount);
    bzero(pragmaValues, sizeof(char*) * pragmaCount);

    for (size_t i = 0; i < pragmaCount; ++i) {
        if (strgets(line, MAXLINE, &rsInfo) == nullptr) {
            ALOGE("Unable to read pragma at index %zu!", i);
            goto error;
        }
        char key[MAXLINE];
        char value[MAXLINE] = ""; // initialize in case value is empty

        // pragmas can just have a key and no value.  Only check to make sure
        // that the key is not empty
        if (sscanf(line, "%" MAKE_STR(MAXLINESTR) "s - %" MAKE_STR(MAXLINESTR) "s",
                   key, value) == 0 ||
            strlen(key) == 0)
        {
            ALOGE("Invalid pragma value!: %s", line);

            goto error;
        }

        pragmaKeys[i] = duplicateString(key, sizeof(key));
        pragmaValues[i] = duplicateString(value, sizeof(value));
        //ALOGE("Pragma %zu: Key: '%s' Value: '%s'", i, pKey, pValue);
    }

    if (strgets(line, MAXLINE, &rsInfo) == nullptr) {
        goto error;
    }

    char tmpFlag[4];
    if (sscanf(line, THREADABLE_STR "%3s", tmpFlag) != 1) {
        ALOGE("Invalid threadable flag!: %s", line);
        goto error;
    }
    if (strcmp(tmpFlag, "yes") == 0) {
        isThreadable = true;
    } else if (strcmp(tmpFlag, "no") == 0) {
        isThreadable = false;
    } else {
        ALOGE("Invalid threadable flag!: %s", tmpFlag);
        goto error;
    }

    if (strgets(line, MAXLINE, &rsInfo) != nullptr) {
        if (sscanf(line, CHECKSUM_STR "%08x", &checksum) != 1) {
            ALOGE("Invalid checksum flag!: %s", line);
            goto error;
        }
    } else {
        ALOGE("Missing checksum in shared obj file");
        goto error;
    }

    if (expectedChecksum != 0 && checksum != expectedChecksum) {
        ALOGE("Found invalid checksum.  Expected %08x, got %08x\n",
              expectedChecksum, checksum);
        goto error;
    }

    {
      // Parse the version info string, but ignore its contents as it's only
      // used by the debugger
      size_t nLines = 0;
      if (strgets(line, MAXLINE, &rsInfo) != nullptr) {
        if (sscanf(line, VERSIONINFO_STR "%zu", &nLines) != 1) {
          ALOGE("invalid versionInfo count");
          goto error;
        } else {
          // skip the versionInfo packet as libRs doesn't use it
          while (nLines) {
            --nLines;
            if (strgets(line, MAXLINE, &rsInfo) == nullptr)
              goto error;
          }
        }
      } else {
        ALOGE(".rs.info is missing versionInfo section");
      }
    }

#endif  // RS_COMPATIBILITY_LIB

    // Read in information about mutable global variables provided by bcc's
    // RSGlobalInfoPass
    if (rsGlobalEntries) {
        numEntries = *rsGlobalEntries;
        if (numEntries > 0) {
            rsAssert(rsGlobalNames);
            rsAssert(rsGlobalAddresses);
            rsAssert(rsGlobalSizes);
            rsAssert(rsGlobalProperties);
        }
    }

    return new ScriptExecutable(
        fieldAddress, fieldIsObject, fieldName, varCount,
        invokeFunctions, funcCount,
        forEachFunctions, forEachSignatures, forEachCount,
        reduceDescriptions, reduceCount,
        pragmaKeys, pragmaValues, pragmaCount,
        rsGlobalNames, rsGlobalAddresses, rsGlobalSizes, rsGlobalProperties,
        numEntries, isThreadable, checksum);

error:

#ifndef RS_COMPATIBILITY_LIB

    if (pragmaKeys) {
        for (size_t idx = 0; idx < pragmaCount; ++idx) {
            delete [] pragmaKeys[idx];
        }
    }

    if (pragmaValues) {
        for (size_t idx = 0; idx < pragmaCount; ++idx) {
            delete [] pragmaValues[idx];
        }
    }

    delete[] pragmaValues;
    delete[] pragmaKeys;
#endif  // RS_COMPATIBILITY_LIB

    delete[] reduceDescriptions;

    delete[] forEachSignatures;
    delete[] forEachFunctions;

    delete[] invokeFunctions;

    for (size_t i = 0; i < varCount; i++) {
        delete[] fieldName[i];
    }
    delete[] fieldName;
    delete[] fieldIsObject;
    delete[] fieldAddress;

    return nullptr;
}

void* ScriptExecutable::getFieldAddress(const char* name) const {
    // TODO: improve this by using a hash map.
    for (size_t i = 0; i < mExportedVarCount; i++) {
        if (strcmp(name, mFieldName[i]) == 0) {
            return mFieldAddress[i];
        }
    }
    return nullptr;
}

bool ScriptExecutable::dumpGlobalInfo() const {
    ALOGE("Globals: %p %p %p", mGlobalAddresses, mGlobalSizes, mGlobalNames);
    ALOGE("P   - Pointer");
    ALOGE(" C  - Constant");
    ALOGE("  S - Static");
    for (int i = 0; i < mGlobalEntries; i++) {
        ALOGE("Global[%d]: %p %zu %s", i, mGlobalAddresses[i], mGlobalSizes[i],
              mGlobalNames[i]);
        uint32_t properties = mGlobalProperties[i];
        ALOGE("%c%c%c Type: %u",
              isGlobalPointer(properties)  ? 'P' : ' ',
              isGlobalConstant(properties) ? 'C' : ' ',
              isGlobalStatic(properties)   ? 'S' : ' ',
              getGlobalRsType(properties));
    }
    return true;
}

}  // namespace renderscript
}  // namespace android
