OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <dlfcn.h> | 5 #include <dlfcn.h> |
6 #include <fcntl.h> | 6 #include <fcntl.h> |
7 #include <pthread.h> | 7 #include <pthread.h> |
8 #include <stdio.h> | 8 #include <stdio.h> |
9 #include <sys/socket.h> | 9 #include <sys/socket.h> |
10 #include <sys/stat.h> | 10 #include <sys/stat.h> |
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
166 typedef struct tm* (*LocaltimeFunction)(const time_t* timep); | 166 typedef struct tm* (*LocaltimeFunction)(const time_t* timep); |
167 typedef struct tm* (*LocaltimeRFunction)(const time_t* timep, | 167 typedef struct tm* (*LocaltimeRFunction)(const time_t* timep, |
168 struct tm* result); | 168 struct tm* result); |
169 typedef FILE* (*FopenFunction)(const char* path, const char* mode); | 169 typedef FILE* (*FopenFunction)(const char* path, const char* mode); |
170 typedef int (*XstatFunction)(int version, const char *path, struct stat *buf); | 170 typedef int (*XstatFunction)(int version, const char *path, struct stat *buf); |
171 typedef int (*Xstat64Function)(int version, const char *path, | 171 typedef int (*Xstat64Function)(int version, const char *path, |
172 struct stat64 *buf); | 172 struct stat64 *buf); |
173 | 173 |
174 static pthread_once_t g_libc_localtime_funcs_guard = PTHREAD_ONCE_INIT; | 174 static pthread_once_t g_libc_localtime_funcs_guard = PTHREAD_ONCE_INIT; |
175 static LocaltimeFunction g_libc_localtime; | 175 static LocaltimeFunction g_libc_localtime; |
176 static LocaltimeFunction g_libc_localtime64; | |
176 static LocaltimeRFunction g_libc_localtime_r; | 177 static LocaltimeRFunction g_libc_localtime_r; |
178 static LocaltimeRFunction g_libc_localtime64_r; | |
177 | 179 |
178 static pthread_once_t g_libc_file_io_funcs_guard = PTHREAD_ONCE_INIT; | 180 static pthread_once_t g_libc_file_io_funcs_guard = PTHREAD_ONCE_INIT; |
179 static FopenFunction g_libc_fopen; | 181 static FopenFunction g_libc_fopen; |
180 static FopenFunction g_libc_fopen64; | 182 static FopenFunction g_libc_fopen64; |
181 static XstatFunction g_libc_xstat; | 183 static XstatFunction g_libc_xstat; |
182 static Xstat64Function g_libc_xstat64; | 184 static Xstat64Function g_libc_xstat64; |
183 | 185 |
184 static void InitLibcLocaltimeFunctions() { | 186 static void InitLibcLocaltimeFunctions() { |
185 g_libc_localtime = reinterpret_cast<LocaltimeFunction>( | 187 g_libc_localtime = reinterpret_cast<LocaltimeFunction>( |
186 dlsym(RTLD_NEXT, "localtime")); | 188 dlsym(RTLD_NEXT, "localtime")); |
189 g_libc_localtime64 = reinterpret_cast<LocaltimeFunction>( | |
190 dlsym(RTLD_NEXT, "localtime64")); | |
187 g_libc_localtime_r = reinterpret_cast<LocaltimeRFunction>( | 191 g_libc_localtime_r = reinterpret_cast<LocaltimeRFunction>( |
188 dlsym(RTLD_NEXT, "localtime_r")); | 192 dlsym(RTLD_NEXT, "localtime_r")); |
193 g_libc_localtime64_r = reinterpret_cast<LocaltimeRFunction>( | |
194 dlsym(RTLD_NEXT, "localtime64_r")); | |
189 | 195 |
190 if (!g_libc_localtime || !g_libc_localtime_r) { | 196 if (!g_libc_localtime || !g_libc_localtime64 || |
197 !g_libc_localtime_r || !g_libc_localtime64_r) { | |
191 // http://code.google.com/p/chromium/issues/detail?id=16800 | 198 // http://code.google.com/p/chromium/issues/detail?id=16800 |
192 // | 199 // |
193 // Nvidia's libGL.so overrides dlsym for an unknown reason and replaces | 200 // Nvidia's libGL.so overrides dlsym for an unknown reason and replaces |
194 // it with a version which doesn't work. In this case we'll get a NULL | 201 // it with a version which doesn't work. In this case we'll get a NULL |
195 // result. There's not a lot we can do at this point, so we just bodge it! | 202 // result. There's not a lot we can do at this point, so we just bodge it! |
196 LOG(ERROR) << "Your system is broken: dlsym doesn't work! This has been " | 203 LOG(ERROR) << "Your system is broken: dlsym doesn't work! This has been " |
197 "reported to be caused by Nvidia's libGL. You should expect" | 204 "reported to be caused by Nvidia's libGL. You should expect" |
198 " time related functions to misbehave. " | 205 " time related functions to misbehave. " |
199 "http://code.google.com/p/chromium/issues/detail?id=16800"; | 206 "http://code.google.com/p/chromium/issues/detail?id=16800"; |
200 } | 207 } |
201 | 208 |
202 if (!g_libc_localtime) | 209 if (!g_libc_localtime) |
203 g_libc_localtime = gmtime; | 210 g_libc_localtime = gmtime; |
211 if (!g_libc_localtime64) | |
212 g_libc_localtime64 = g_libc_localtime; | |
204 if (!g_libc_localtime_r) | 213 if (!g_libc_localtime_r) |
205 g_libc_localtime_r = gmtime_r; | 214 g_libc_localtime_r = gmtime_r; |
215 if (!g_libc_localtime64_r) | |
216 g_libc_localtime64_r = g_libc_localtime_r; | |
206 } | 217 } |
207 | 218 |
208 struct tm* localtime(const time_t* timep) { | 219 // Define localtime_override() function with asm name "localtime", so that all |
220 // references to localtime() will resolve to this function. The same trick is | |
221 // also applied to override localtime64(), localtime_r() and localtime64_r(). | |
222 __attribute__ ((__visibility__("default"))) | |
223 struct tm* localtime_override(const time_t* timep) __asm__ ("localtime"); | |
224 | |
225 __attribute__ ((__visibility__("default"))) | |
226 struct tm* localtime_override(const time_t* timep) { | |
209 if (g_am_zygote_or_renderer) { | 227 if (g_am_zygote_or_renderer) { |
210 static struct tm time_struct; | 228 static struct tm time_struct; |
211 static char timezone_string[64]; | 229 static char timezone_string[64]; |
212 ProxyLocaltimeCallToBrowser(*timep, &time_struct, timezone_string, | 230 ProxyLocaltimeCallToBrowser(*timep, &time_struct, timezone_string, |
213 sizeof(timezone_string)); | 231 sizeof(timezone_string)); |
214 return &time_struct; | 232 return &time_struct; |
215 } else { | 233 } else { |
216 CHECK_EQ(0, pthread_once(&g_libc_localtime_funcs_guard, | 234 CHECK_EQ(0, pthread_once(&g_libc_localtime_funcs_guard, |
217 InitLibcLocaltimeFunctions)); | 235 InitLibcLocaltimeFunctions)); |
218 return g_libc_localtime(timep); | 236 return g_libc_localtime(timep); |
219 } | 237 } |
220 } | 238 } |
221 | 239 |
222 struct tm* localtime_r(const time_t* timep, struct tm* result) { | 240 __attribute__ ((__visibility__("default"))) |
Jorge Lucangeli Obes
2012/05/16 17:54:55
I wonder how it was working before if we weren't s
| |
241 struct tm* localtime64_override(const time_t* timep) __asm__ ("localtime64"); | |
242 | |
243 __attribute__ ((__visibility__("default"))) | |
244 struct tm* localtime64_override(const time_t* timep) { | |
245 if (g_am_zygote_or_renderer) { | |
246 static struct tm time_struct; | |
247 static char timezone_string[64]; | |
248 ProxyLocaltimeCallToBrowser(*timep, &time_struct, timezone_string, | |
249 sizeof(timezone_string)); | |
250 return &time_struct; | |
251 } else { | |
252 CHECK_EQ(0, pthread_once(&g_libc_localtime_funcs_guard, | |
253 InitLibcLocaltimeFunctions)); | |
254 return g_libc_localtime64(timep); | |
255 } | |
256 } | |
257 | |
258 __attribute__ ((__visibility__("default"))) | |
259 struct tm* localtime_r_override(const time_t* timep, | |
260 struct tm* result) __asm__ ("localtime_r"); | |
261 | |
262 __attribute__ ((__visibility__("default"))) | |
263 struct tm* localtime_r_override(const time_t* timep, struct tm* result) { | |
223 if (g_am_zygote_or_renderer) { | 264 if (g_am_zygote_or_renderer) { |
224 ProxyLocaltimeCallToBrowser(*timep, result, NULL, 0); | 265 ProxyLocaltimeCallToBrowser(*timep, result, NULL, 0); |
225 return result; | 266 return result; |
226 } else { | 267 } else { |
227 CHECK_EQ(0, pthread_once(&g_libc_localtime_funcs_guard, | 268 CHECK_EQ(0, pthread_once(&g_libc_localtime_funcs_guard, |
228 InitLibcLocaltimeFunctions)); | 269 InitLibcLocaltimeFunctions)); |
229 return g_libc_localtime_r(timep, result); | 270 return g_libc_localtime_r(timep, result); |
230 } | 271 } |
231 } | 272 } |
232 | 273 |
274 __attribute__ ((__visibility__("default"))) | |
275 struct tm* localtime64_r_override(const time_t* timep, | |
276 struct tm* result) __asm__ ("localtime64_r"); | |
277 | |
278 __attribute__ ((__visibility__("default"))) | |
279 struct tm* localtime64_r_override(const time_t* timep, struct tm* result) { | |
280 if (g_am_zygote_or_renderer) { | |
281 ProxyLocaltimeCallToBrowser(*timep, result, NULL, 0); | |
282 return result; | |
283 } else { | |
284 CHECK_EQ(0, pthread_once(&g_libc_localtime_funcs_guard, | |
285 InitLibcLocaltimeFunctions)); | |
286 return g_libc_localtime64_r(timep, result); | |
287 } | |
288 } | |
289 | |
233 // TODO(sergeyu): Currently this code doesn't work properly under ASAN | 290 // TODO(sergeyu): Currently this code doesn't work properly under ASAN |
234 // - it crashes content_unittests. Make sure it works properly and | 291 // - it crashes content_unittests. Make sure it works properly and |
235 // enable it here. http://crbug.com/123263 | 292 // enable it here. http://crbug.com/123263 |
236 #if !defined(ADDRESS_SANITIZER) | 293 #if !defined(ADDRESS_SANITIZER) |
237 | 294 |
238 static void InitLibcFileIOFunctions() { | 295 static void InitLibcFileIOFunctions() { |
239 g_libc_fopen = reinterpret_cast<FopenFunction>( | 296 g_libc_fopen = reinterpret_cast<FopenFunction>( |
240 dlsym(RTLD_NEXT, "fopen")); | 297 dlsym(RTLD_NEXT, "fopen")); |
241 g_libc_fopen64 = reinterpret_cast<FopenFunction>( | 298 g_libc_fopen64 = reinterpret_cast<FopenFunction>( |
242 dlsym(RTLD_NEXT, "fopen64")); | 299 dlsym(RTLD_NEXT, "fopen64")); |
(...skipping 291 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
534 } | 591 } |
535 } | 592 } |
536 #endif // SECCOMP_SANDBOX | 593 #endif // SECCOMP_SANDBOX |
537 | 594 |
538 Zygote zygote(sandbox_flags, forkdelegate, proc_fd_for_seccomp); | 595 Zygote zygote(sandbox_flags, forkdelegate, proc_fd_for_seccomp); |
539 // This function call can return multiple times, once per fork(). | 596 // This function call can return multiple times, once per fork(). |
540 return zygote.ProcessRequests(); | 597 return zygote.ProcessRequests(); |
541 } | 598 } |
542 | 599 |
543 } // namespace content | 600 } // namespace content |
OLD | NEW |