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