Home | History | Annotate | Download | only in wrapsim
      1 /*
      2  * Copyright 2007 The Android Open Source Project
      3  *
      4  * Initialize the intercepts.
      5  */
      6 #include "Common.h"
      7 
      8 #define __USE_GNU       /* need RTLD_NEXT */
      9 #include <dlfcn.h>
     10 
     11 #include <stdlib.h>
     12 #include <pthread.h>
     13 #include <string.h>
     14 #include <errno.h>
     15 #include <assert.h>
     16 #include <sys/stat.h>
     17 #include <sys/types.h>
     18 
     19 
     20 /*
     21  * Global state.
     22  */
     23 struct WrapSimGlobals gWrapSim;
     24 pthread_once_t gWrapSimInitialized = PTHREAD_ONCE_INIT;
     25 
     26 /*
     27  * Initialize our global state.
     28  */
     29 static void initGlobals(void)
     30 {
     31     memset(&gWrapSim, 0xdd, sizeof(gWrapSim));
     32     gWrapSim.logFd = -1;
     33     gWrapSim.keyMap = NULL;
     34 
     35     /*
     36      * Find the original version of functions we override.
     37      */
     38     _ws_access = dlsym(RTLD_NEXT, "access");
     39     _ws_open = dlsym(RTLD_NEXT, "open");
     40     _ws_open64 = dlsym(RTLD_NEXT, "open64");
     41 
     42     _ws_close = dlsym(RTLD_NEXT, "close");
     43     _ws_dup = dlsym(RTLD_NEXT, "dup");
     44     _ws_read = dlsym(RTLD_NEXT, "read");
     45     _ws_readv = dlsym(RTLD_NEXT, "readv");
     46     _ws_write = dlsym(RTLD_NEXT, "write");
     47     _ws_writev = dlsym(RTLD_NEXT, "writev");
     48     _ws_mmap = dlsym(RTLD_NEXT, "mmap");
     49     _ws_mmap64 = dlsym(RTLD_NEXT, "mmap64");
     50     _ws_ioctl = dlsym(RTLD_NEXT, "ioctl");
     51 
     52     _ws_chdir = dlsym(RTLD_NEXT, "chdir");
     53     _ws_chmod = dlsym(RTLD_NEXT, "chmod");
     54     _ws_chown = dlsym(RTLD_NEXT, "chown");
     55     _ws_creat = dlsym(RTLD_NEXT, "creat");
     56     _ws_execve = dlsym(RTLD_NEXT, "execve");
     57     _ws_getcwd = dlsym(RTLD_NEXT, "getcwd");
     58     _ws_lchown = dlsym(RTLD_NEXT, "lchown");
     59     _ws_link = dlsym(RTLD_NEXT, "link");
     60     _ws_lstat = dlsym(RTLD_NEXT, "lstat");
     61     _ws_lstat64 = dlsym(RTLD_NEXT, "lstat64");
     62     _ws___lxstat = dlsym(RTLD_NEXT, "__lxstat");
     63     _ws___lxstat64 = dlsym(RTLD_NEXT, "__lxstat64");
     64     _ws_mkdir = dlsym(RTLD_NEXT, "mkdir");
     65     _ws_readlink = dlsym(RTLD_NEXT, "readlink");
     66     _ws_rename = dlsym(RTLD_NEXT, "rename");
     67     _ws_rmdir = dlsym(RTLD_NEXT, "rmdir");
     68     _ws_stat = dlsym(RTLD_NEXT, "stat");
     69     _ws_stat64 = dlsym(RTLD_NEXT, "stat64");
     70     _ws___xstat = dlsym(RTLD_NEXT, "__xstat");
     71     _ws___xstat64 = dlsym(RTLD_NEXT, "__xstat64");
     72     _ws_statfs = dlsym(RTLD_NEXT, "statfs");
     73     _ws_statfs64 = dlsym(RTLD_NEXT, "statfs64");
     74     _ws_symlink = dlsym(RTLD_NEXT, "symlink");
     75     _ws_unlink = dlsym(RTLD_NEXT, "unlink");
     76     _ws_utime = dlsym(RTLD_NEXT, "utime");
     77     _ws_utimes = dlsym(RTLD_NEXT, "utimes");
     78 
     79     _ws_execl = dlsym(RTLD_NEXT, "execl");
     80     _ws_execle = dlsym(RTLD_NEXT, "execle");
     81     _ws_execlp = dlsym(RTLD_NEXT, "execlp");
     82     _ws_execv = dlsym(RTLD_NEXT, "execv");
     83     _ws_execvp = dlsym(RTLD_NEXT, "execvp");
     84     _ws_fopen = dlsym(RTLD_NEXT, "fopen");
     85     _ws_fopen64 = dlsym(RTLD_NEXT, "fopen64");
     86     _ws_freopen = dlsym(RTLD_NEXT, "freopen");
     87     _ws_ftw = dlsym(RTLD_NEXT, "ftw");
     88     _ws_opendir = dlsym(RTLD_NEXT, "opendir");
     89     _ws_dlopen = dlsym(RTLD_NEXT, "dlopen");
     90 
     91     _ws_setpriority = dlsym(RTLD_NEXT, "setpriority");
     92     //_ws_pipe = dlsym(RTLD_NEXT, "pipe");
     93 
     94     const char* logFileName = getenv("WRAPSIM_LOG");
     95     if (logFileName != NULL ){
     96         gWrapSim.logFd = _ws_open(logFileName, O_WRONLY|O_APPEND|O_CREAT, 0664);
     97     }
     98 
     99     /* log messages now work; say hello */
    100     wsLog("--- initializing sim wrapper ---\n");
    101 
    102     gWrapSim.simulatorFd = -1;
    103 
    104     pthread_mutex_init(&gWrapSim.startLock, NULL);
    105     pthread_cond_init(&gWrapSim.startCond, NULL);
    106     gWrapSim.startReady = 0;
    107 
    108     pthread_mutex_init(&gWrapSim.fakeFdLock, NULL);
    109     gWrapSim.fakeFdMap = wsAllocBitVector(kMaxFakeFdCount, 0);
    110     memset(gWrapSim.fakeFdList, 0, sizeof(gWrapSim.fakeFdList));
    111 
    112     pthread_mutex_init(&gWrapSim.atomicLock, NULL);
    113 
    114     gWrapSim.numDisplays = 0;
    115 
    116     gWrapSim.keyInputDevice = NULL;
    117 
    118     /*
    119      * Get target for remapped "/system" and "/data".
    120      *
    121      * The ANDROID_PRODUCT_OUT env var *must* be set for rewriting to work.
    122      */
    123     const char* outEnv = getenv("ANDROID_PRODUCT_OUT");
    124     if (outEnv == NULL) {
    125         gWrapSim.remapBaseDir = NULL;
    126         wsLog("--- $ANDROID_PRODUCT_OUT not set, "
    127                 "filename remapping disabled\n");
    128     } else {
    129         /* grab string and append '/' -- note this never gets freed */
    130         gWrapSim.remapBaseDirLen = strlen(outEnv);
    131         gWrapSim.remapBaseDir = strdup(outEnv);
    132         wsLog("--- name remap to %s\n", gWrapSim.remapBaseDir);
    133     }
    134 
    135     gWrapSim.initialized = 1;
    136 }
    137 
    138 /*
    139  * Creates a directory, or prints a log message if it fails.
    140  */
    141 static int createTargetDirectory(const char *path, mode_t mode)
    142 {
    143     int ret;
    144 
    145     ret = mkdir(path, mode);
    146     if (ret == 0 || errno == EEXIST) {
    147         return 0;
    148     }
    149     wsLog("--- could not create target directory %s: %s\n",
    150             path, strerror(errno));
    151     return ret;
    152 }
    153 
    154 /*
    155  * Any setup that would normally be done by init(8).
    156  * Note that since the syscall redirects have been installed
    157  * at this point, we are effectively operating within the
    158  * simulation context.
    159  */
    160 static void initGeneral(void)
    161 {
    162     wsLog("--- preparing system\n");
    163 
    164     /* Try to make sure that certain directories exist.
    165      * If we fail to create them, the errors will show up in the log,
    166      * but we keep going.
    167      */
    168     createTargetDirectory("/data", 0777);
    169     createTargetDirectory("/data/dalvik-cache", 0777);
    170 }
    171 
    172 /*
    173  * Initialize all necessary state, and indicate that we're ready to go.
    174  */
    175 static void initOnce(void)
    176 {
    177     initGlobals();
    178     initGeneral();
    179 }
    180 
    181 /*
    182  * Shared object initializer.  glibc guarantees that this function is
    183  * called before dlopen() returns.  It may be called multiple times.
    184  */
    185 __attribute__((constructor))
    186 static void initialize(void)
    187 {
    188     pthread_once(&gWrapSimInitialized, initOnce);
    189 }
    190 
    191 
    192