• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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  */
initGlobals(void)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  */
createTargetDirectory(const char * path,mode_t mode)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  */
initGeneral(void)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  */
initOnce(void)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))
initialize(void)186 static void initialize(void)
187 {
188     pthread_once(&gWrapSimInitialized, initOnce);
189 }
190 
191 
192