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