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