Ejemplo n.º 1
0
/*
 * Create a new FakeDev entry, and open a file descriptor that actually
 * works.
 */
FakeDev* wsCreateRealFakeDev(const char* debugName)
{
    FakeDev* newDev = wsCreateFakeDev(debugName);
    if (newDev == NULL)
        return newDev;
    
    int fds[2];

    if (socketpair(AF_UNIX, SOCK_STREAM, 0, fds) < 0) {
        wsLog("socketpair() failed: %s\n", strerror(errno));
        wsFreeFakeDev(newDev);
        return NULL;
    }

    if (dup2(fds[0], newDev->fd) < 0) {
        wsLog("dup2(%d,%d) failed: %s\n",
            fds[0], newDev->fd, strerror(errno));
        wsFreeFakeDev(newDev);
        return NULL;
    }
    close(fds[0]);

    /* okay to leave this one in the "normal" range; not visible to app */
    newDev->otherFd = fds[1];

    return newDev;
}
Ejemplo n.º 2
0
/*
 * Check to see if we're opening a device that we want to fake out.
 *
 * We return a file descriptor >= 0 on success, -1 if we're not interested,
 * or -2 if we explicitly want to pretend that the device doesn't exist.
 */
int wsInterceptDeviceOpen(const char* pathName, int flags)
{
    FakedPath* p = fakedpaths;

    while (p->pathexpr) {
        if (fnmatch(p->pathexpr, pathName, 0) == 0) {
            if (p->hook != NULL) {
                FakeDev* dev = p->hook(pathName, flags);
                if (dev != NULL) {
                    /*
                     * Now that the device entry is ready, add it to the list.
                     */
                    wsLog("## created fake dev %d: '%s' %p\n",
                        dev->fd, dev->debugName, dev->state);
                    gWrapSim.fakeFdList[dev->fd - kFakeFdBase] = dev;
                    return dev->fd;
                }
            } else {
                wsLog("## rejecting attempt to open %s\n", pathName);
                errno = ENOENT;
                return -2;
            }
            break;
        }
        p++;
    }
    return -1;
}
Ejemplo n.º 3
0
/*
 * Generic drop-in for an unimplemented call.
 *
 * Returns -1, which conveniently is the same as MAP_FAILED for mmap.
 */
static int notImplemented(FakeDev* dev, const char* callName)
{
    wsLog("WARNING: unimplemented %s() on '%s' %p\n",
        callName, dev->debugName, dev->state);
    errno = kNoHandlerError;
    return -1;
}
Ejemplo n.º 4
0
/*
 * Free fake device entry.
 */
void wsFreeFakeDev(FakeDev* dev)
{
    if (dev == NULL)
        return;

    wsLog("## closing/freeing '%s' (%d/%d)\n",
        dev->debugName, dev->fd, dev->otherFd);

    /*
     * If we assigned a file descriptor slot, free it up.
     */
    if (dev->fd >= 0) {
        int cc;

        gWrapSim.fakeFdList[dev->fd - kFakeFdBase] = NULL;

        cc = pthread_mutex_lock(&gWrapSim.fakeFdLock); assert(cc == 0);
        wsFreeBit(gWrapSim.fakeFdMap, dev->fd - kFakeFdBase);
        cc = pthread_mutex_unlock(&gWrapSim.fakeFdLock); assert(cc == 0);
    }
    if (dev->otherFd >= 0)
        close(dev->otherFd);

    if (dev->debugName) free(dev->debugName);
    free(dev);
}
/*
 * If appropriate, rewrite the path to point to a different location.
 *
 * Returns either "pathBuf" or "origPath" depending on whether or not we
 * chose to rewrite the path.  "origPath" must be a buffer capable of
 * holding an extended pathname; for best results use PATH_MAX.
 */
static const char* rewritePath(const char* func, char* pathBuf,
    const char* origPath)
{
    /*
     * Rewrite paths that start with "/system/" or "/data/"
     */
    if (origPath[0] != '/')
        goto skip_rewrite;
    if (memcmp(origPath+1, "system", 6) == 0 &&
        (origPath[7] == '/' || origPath[7] == '\0'))
            goto do_rewrite;
    if (memcmp(origPath+1, "data", 4) == 0 &&
        (origPath[5] == '/' || origPath[5] == '\0'))
            goto do_rewrite;

skip_rewrite:
    /* check to see if something is side-stepping the rewrite */
    if (memcmp(origPath, gWrapSim.remapBaseDir, gWrapSim.remapBaseDirLen) == 0)
    {
        wsLog("NOTE: full path used: %s(%s)\n", func, origPath);
    }

    CALLTRACE("rewrite %s('%s') --> (not rewritten)\n", func, origPath);
    return origPath;

do_rewrite:
    memcpy(pathBuf, gWrapSim.remapBaseDir, gWrapSim.remapBaseDirLen);
    strcpy(pathBuf + gWrapSim.remapBaseDirLen, origPath);
    CALLTRACE("rewrite %s('%s') --> '%s'\n", func, origPath, pathBuf);
    return pathBuf;
}
Ejemplo n.º 6
0
/*
 * Set some stuff up.
 */
static int configureInitialState(const char* pathName, AudioState* audioState)
{
#if BUILD_SIM_WITHOUT_AUDIO
    return 0;
#else
    audioState->handle = NULL;

    snd_pcm_open(&audioState->handle, "default", SND_PCM_STREAM_PLAYBACK, 0);

    if (audioState->handle) {
        snd_pcm_hw_params_t *params;
        snd_pcm_hw_params_malloc(&params);
        snd_pcm_hw_params_any(audioState->handle, params);
        snd_pcm_hw_params_set_access(audioState->handle, params, SND_PCM_ACCESS_RW_INTERLEAVED);
        snd_pcm_hw_params_set_format(audioState->handle, params, SND_PCM_FORMAT_S16_LE);
        unsigned int rate = 44100;
        snd_pcm_hw_params_set_rate_near(audioState->handle, params, &rate, NULL);
        snd_pcm_hw_params_set_channels(audioState->handle, params, 2);
        snd_pcm_hw_params(audioState->handle, params);
        snd_pcm_hw_params_free(params);
    } else {
        wsLog("Couldn't open audio hardware, faking it\n");
    }

    return 0;
#endif
}
Ejemplo n.º 7
0
/*
 * Any setup that would normally be done by init(8).
 * Note that since the syscall redirects have been installed
 * at this point, we are effectively operating within the
 * simulation context.
 */
static void initGeneral(void)
{
    wsLog("--- preparing system\n");

    /* Try to make sure that certain directories exist.
     * If we fail to create them, the errors will show up in the log,
     * but we keep going.
     */
    createTargetDirectory("/data", 0777);
    createTargetDirectory("/data/dalvik-cache", 0777);
}
Ejemplo n.º 8
0
/*
 * Creates a directory, or prints a log message if it fails.
 */
static int createTargetDirectory(const char *path, mode_t mode)
{
    int ret;

    ret = mkdir(path, mode);
    if (ret == 0 || errno == EEXIST) {
        return 0;
    }
    wsLog("--- could not create target directory %s: %s\n",
            path, strerror(errno));
    return ret;
}
Ejemplo n.º 9
0
/*
 * Check to see if we're accessing a device that we want to fake out.
 * Returns 0 if the device can be (fake) opened with the given mode,
 * -1 if it can't, -2 if it can't and we don't want to allow fallback
 * to the host-device either.
 * TODO: actually check the mode.
 */
int wsInterceptDeviceAccess(const char *pathName, int mode)
{
    FakedPath *p = fakedpaths;

    while (p->pathexpr) {
        if (fnmatch(p->pathexpr, pathName, 0) == 0) {
            if (p->hook) {
                return 0;
            } else {
                wsLog("## rejecting attempt to open %s\n", pathName);
                errno = ENOENT;
                return -2;
            }
            break;
        }
        p++;
    }
    errno = ENOENT;
    return -1;
}
Ejemplo n.º 10
0
/*
 * Create a new FakeDev entry.
 *
 * We mark the fd slot as "used" in the bitmap, but don't add it to the
 * table yet since the entry is not fully prepared.
 */
FakeDev* wsCreateFakeDev(const char* debugName)
{
    FakeDev* newDev;
    int cc;

    assert(debugName != NULL);

    newDev = (FakeDev*) calloc(1, sizeof(FakeDev));
    if (newDev == NULL)
        return NULL;

    newDev->debugName = strdup(debugName);
    newDev->state = NULL;

    newDev->close = (Fake_close) noClose;
    newDev->read = (Fake_read) noRead;
    newDev->readv = (Fake_readv) noReadv;
    newDev->write = (Fake_write) noWrite;
    newDev->writev = (Fake_writev) noWritev;
    newDev->mmap = (Fake_mmap) noMmap;
    newDev->ioctl = (Fake_ioctl) noIoctl;

    /*
     * Allocate a new entry.  The bit vector map is really only used as a
     * performance boost in the current implementation.
     */
    cc = pthread_mutex_lock(&gWrapSim.fakeFdLock); assert(cc == 0);
    int newfd = wsAllocBit(gWrapSim.fakeFdMap);
    cc = pthread_mutex_unlock(&gWrapSim.fakeFdLock); assert(cc == 0);

    if (newfd < 0) {
        wsLog("WARNING: ran out of 'fake' file descriptors\n");
        free(newDev);
        return NULL;
    }
    newDev->fd = newfd + kFakeFdBase;
    newDev->otherFd = -1;
    assert(gWrapSim.fakeFdList[newDev->fd - kFakeFdBase] == NULL);

    return newDev;
}
Ejemplo n.º 11
0
/*
 * Initialize our global state.
 */
static void initGlobals(void)
{
    memset(&gWrapSim, 0xdd, sizeof(gWrapSim));
    gWrapSim.logFd = -1;
    gWrapSim.keyMap = NULL;

    /*
     * Find the original version of functions we override.
     */
    _ws_access = dlsym(RTLD_NEXT, "access");
    _ws_open = dlsym(RTLD_NEXT, "open");
    _ws_open64 = dlsym(RTLD_NEXT, "open64");

    _ws_close = dlsym(RTLD_NEXT, "close");
    _ws_dup = dlsym(RTLD_NEXT, "dup");
    _ws_read = dlsym(RTLD_NEXT, "read");
    _ws_readv = dlsym(RTLD_NEXT, "readv");
    _ws_write = dlsym(RTLD_NEXT, "write");
    _ws_writev = dlsym(RTLD_NEXT, "writev");
    _ws_mmap = dlsym(RTLD_NEXT, "mmap");
    _ws_mmap64 = dlsym(RTLD_NEXT, "mmap64");
    _ws_ioctl = dlsym(RTLD_NEXT, "ioctl");

    _ws_chdir = dlsym(RTLD_NEXT, "chdir");
    _ws_chmod = dlsym(RTLD_NEXT, "chmod");
    _ws_chown = dlsym(RTLD_NEXT, "chown");
    _ws_creat = dlsym(RTLD_NEXT, "creat");
    _ws_execve = dlsym(RTLD_NEXT, "execve");
    _ws_getcwd = dlsym(RTLD_NEXT, "getcwd");
    _ws_lchown = dlsym(RTLD_NEXT, "lchown");
    _ws_link = dlsym(RTLD_NEXT, "link");
    _ws_lstat = dlsym(RTLD_NEXT, "lstat");
    _ws_lstat64 = dlsym(RTLD_NEXT, "lstat64");
    _ws___lxstat = dlsym(RTLD_NEXT, "__lxstat");
    _ws___lxstat64 = dlsym(RTLD_NEXT, "__lxstat64");
    _ws_mkdir = dlsym(RTLD_NEXT, "mkdir");
    _ws_readlink = dlsym(RTLD_NEXT, "readlink");
    _ws_rename = dlsym(RTLD_NEXT, "rename");
    _ws_rmdir = dlsym(RTLD_NEXT, "rmdir");
    _ws_stat = dlsym(RTLD_NEXT, "stat");
    _ws_stat64 = dlsym(RTLD_NEXT, "stat64");
    _ws___xstat = dlsym(RTLD_NEXT, "__xstat");
    _ws___xstat64 = dlsym(RTLD_NEXT, "__xstat64");
    _ws_statfs = dlsym(RTLD_NEXT, "statfs");
    _ws_statfs64 = dlsym(RTLD_NEXT, "statfs64");
    _ws_symlink = dlsym(RTLD_NEXT, "symlink");
    _ws_unlink = dlsym(RTLD_NEXT, "unlink");
    _ws_utime = dlsym(RTLD_NEXT, "utime");
    _ws_utimes = dlsym(RTLD_NEXT, "utimes");

    _ws_execl = dlsym(RTLD_NEXT, "execl");
    _ws_execle = dlsym(RTLD_NEXT, "execle");
    _ws_execlp = dlsym(RTLD_NEXT, "execlp");
    _ws_execv = dlsym(RTLD_NEXT, "execv");
    _ws_execvp = dlsym(RTLD_NEXT, "execvp");
    _ws_fopen = dlsym(RTLD_NEXT, "fopen");
    _ws_fopen64 = dlsym(RTLD_NEXT, "fopen64");
    _ws_freopen = dlsym(RTLD_NEXT, "freopen");
    _ws_ftw = dlsym(RTLD_NEXT, "ftw");
    _ws_opendir = dlsym(RTLD_NEXT, "opendir");
    _ws_dlopen = dlsym(RTLD_NEXT, "dlopen");

    _ws_setpriority = dlsym(RTLD_NEXT, "setpriority");
    //_ws_pipe = dlsym(RTLD_NEXT, "pipe");

    const char* logFileName = getenv("WRAPSIM_LOG");
    if (logFileName != NULL ){
        gWrapSim.logFd = _ws_open(logFileName, O_WRONLY|O_APPEND|O_CREAT, 0664);
    }

    /* log messages now work; say hello */
    wsLog("--- initializing sim wrapper ---\n");

    gWrapSim.simulatorFd = -1;

    pthread_mutex_init(&gWrapSim.startLock, NULL);
    pthread_cond_init(&gWrapSim.startCond, NULL);
    gWrapSim.startReady = 0;

    pthread_mutex_init(&gWrapSim.fakeFdLock, NULL);
    gWrapSim.fakeFdMap = wsAllocBitVector(kMaxFakeFdCount, 0);
    memset(gWrapSim.fakeFdList, 0, sizeof(gWrapSim.fakeFdList));

    pthread_mutex_init(&gWrapSim.atomicLock, NULL);

    gWrapSim.numDisplays = 0;

    gWrapSim.keyInputDevice = NULL;

    /*
     * Get target for remapped "/system" and "/data".
     *
     * The ANDROID_PRODUCT_OUT env var *must* be set for rewriting to work.
     */
    const char* outEnv = getenv("ANDROID_PRODUCT_OUT");
    if (outEnv == NULL) {
        gWrapSim.remapBaseDir = NULL;
        wsLog("--- $ANDROID_PRODUCT_OUT not set, "
                "filename remapping disabled\n");
    } else {
        /* grab string and append '/' -- note this never gets freed */
        gWrapSim.remapBaseDirLen = strlen(outEnv);
        gWrapSim.remapBaseDir = strdup(outEnv);
        wsLog("--- name remap to %s\n", gWrapSim.remapBaseDir);
    }

    gWrapSim.initialized = 1;
}