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

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

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

#include <dlfcn.h>

namespace android {
namespace renderscript {

namespace {

// Check if a path exists and attempt to create it if it doesn't.
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.
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) {
    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);
    scriptSOName.append(".so");

    return scriptSOName;
}

}  // 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) {
    std::string sharedLibName = findSharedObjectName(cacheDir, resName);
    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");

    const char *compiler_rt = SYSLIBPATH"/libcompiler_rt.so";
    const char *mTriple = "-mtriple=" DEFAULT_TARGET_TRIPLE_STRING;
    const char *libPath = "--library-path=" SYSLIBPATH;
    const char *vendorLibPath = "--library-path=" SYSLIBPATH_VENDOR;

    std::vector<const char *> args = {
        LD_EXE_PATH,
        "-shared",
        "-nostdlib",
        compiler_rt, mTriple, vendorLibPath, 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::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) {
        ALOGE("Unable to open shared library (%s): %s",
              scriptSOName.c_str(), dlerror());

#ifdef RS_COMPATIBILITY_LIB
        // 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;
}

String8 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 String8(buf);
}

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;

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

    // 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).string());  // 62^6 potential filename variants.
    newName.append(".so");

    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());
    }
    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: "

// 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;
}

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] = new char[strlen(line)+1];
        strcpy(fieldName[i], 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;
        }

        char *pKey = new char[strlen(key)+1];
        strcpy(pKey, key);
        pragmaKeys[i] = pKey;

        char *pValue = new char[strlen(value)+1];
        strcpy(pValue, value);
        pragmaValues[i] = pValue;
        //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;
    }

#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
