Chromium Code Reviews| 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_localtime_r) { |
|
Jorge Lucangeli Obes
2012/05/16 02:59:45
Shouldn't you add checks for the *64 versions of t
hshi1
2012/05/16 17:36:16
Done.
| |
| 191 // http://code.google.com/p/chromium/issues/detail?id=16800 | 197 // http://code.google.com/p/chromium/issues/detail?id=16800 |
| 192 // | 198 // |
| 193 // Nvidia's libGL.so overrides dlsym for an unknown reason and replaces | 199 // 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 | 200 // 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! | 201 // 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 " | 202 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" | 203 "reported to be caused by Nvidia's libGL. You should expect" |
| 198 " time related functions to misbehave. " | 204 " time related functions to misbehave. " |
| 199 "http://code.google.com/p/chromium/issues/detail?id=16800"; | 205 "http://code.google.com/p/chromium/issues/detail?id=16800"; |
| 200 } | 206 } |
| 201 | 207 |
| 202 if (!g_libc_localtime) | 208 if (!g_libc_localtime) |
| 203 g_libc_localtime = gmtime; | 209 g_libc_localtime = gmtime; |
| 204 if (!g_libc_localtime_r) | 210 if (!g_libc_localtime_r) |
| 205 g_libc_localtime_r = gmtime_r; | 211 g_libc_localtime_r = gmtime_r; |
| 206 } | 212 } |
| 207 | 213 |
| 208 struct tm* localtime(const time_t* timep) { | 214 __attribute__ ((__visibility__("default"))) |
|
Jorge Lucangeli Obes
2012/05/16 02:59:45
Why do we need the visibility annotations?
hshi1
2012/05/16 03:04:09
This is a copy&paste based on the fopen/fopen64 co
hshi1
2012/05/16 17:36:16
It appears to be useless. I would assume that visi
hshi1
2012/05/16 17:44:57
Sorry, I take this back. It appears that the visib
| |
| 215 struct tm* localtime_override(const time_t* timep) __asm__ ("localtime"); | |
| 216 | |
| 217 __attribute__ ((__visibility__("default"))) | |
| 218 struct tm* localtime_override(const time_t* timep) { | |
| 209 if (g_am_zygote_or_renderer) { | 219 if (g_am_zygote_or_renderer) { |
| 210 static struct tm time_struct; | 220 static struct tm time_struct; |
| 211 static char timezone_string[64]; | 221 static char timezone_string[64]; |
| 212 ProxyLocaltimeCallToBrowser(*timep, &time_struct, timezone_string, | 222 ProxyLocaltimeCallToBrowser(*timep, &time_struct, timezone_string, |
| 213 sizeof(timezone_string)); | 223 sizeof(timezone_string)); |
| 214 return &time_struct; | 224 return &time_struct; |
| 215 } else { | 225 } else { |
| 216 CHECK_EQ(0, pthread_once(&g_libc_localtime_funcs_guard, | 226 CHECK_EQ(0, pthread_once(&g_libc_localtime_funcs_guard, |
| 217 InitLibcLocaltimeFunctions)); | 227 InitLibcLocaltimeFunctions)); |
| 218 return g_libc_localtime(timep); | 228 return g_libc_localtime(timep); |
| 219 } | 229 } |
| 220 } | 230 } |
| 221 | 231 |
| 222 struct tm* localtime_r(const time_t* timep, struct tm* result) { | 232 __attribute__ ((__visibility__("default"))) |
| 233 struct tm* localtime64_override(const time_t* timep) __asm__ ("localtime64"); | |
| 234 | |
| 235 __attribute__ ((__visibility__("default"))) | |
| 236 struct tm* localtime64_override(const time_t* timep) { | |
| 237 if (g_am_zygote_or_renderer) { | |
| 238 static struct tm time_struct; | |
| 239 static char timezone_string[64]; | |
| 240 ProxyLocaltimeCallToBrowser(*timep, &time_struct, timezone_string, | |
| 241 sizeof(timezone_string)); | |
| 242 return &time_struct; | |
| 243 } else { | |
| 244 CHECK_EQ(0, pthread_once(&g_libc_localtime_funcs_guard, | |
| 245 InitLibcLocaltimeFunctions)); | |
| 246 return g_libc_localtime64(timep); | |
| 247 } | |
| 248 } | |
| 249 | |
| 250 __attribute__ ((__visibility__("default"))) | |
| 251 struct tm* localtime_r_override(const time_t* timep, | |
| 252 struct tm* result) __asm__ ("localtime_r"); | |
| 253 | |
| 254 __attribute__ ((__visibility__("default"))) | |
| 255 struct tm* localtime_r_override(const time_t* timep, struct tm* result) { | |
| 223 if (g_am_zygote_or_renderer) { | 256 if (g_am_zygote_or_renderer) { |
| 224 ProxyLocaltimeCallToBrowser(*timep, result, NULL, 0); | 257 ProxyLocaltimeCallToBrowser(*timep, result, NULL, 0); |
| 225 return result; | 258 return result; |
| 226 } else { | 259 } else { |
| 227 CHECK_EQ(0, pthread_once(&g_libc_localtime_funcs_guard, | 260 CHECK_EQ(0, pthread_once(&g_libc_localtime_funcs_guard, |
| 228 InitLibcLocaltimeFunctions)); | 261 InitLibcLocaltimeFunctions)); |
| 229 return g_libc_localtime_r(timep, result); | 262 return g_libc_localtime_r(timep, result); |
| 230 } | 263 } |
| 231 } | 264 } |
| 232 | 265 |
| 266 __attribute__ ((__visibility__("default"))) | |
| 267 struct tm* localtime64_r_override(const time_t* timep, | |
| 268 struct tm* result) __asm__ ("localtime64_r"); | |
| 269 | |
| 270 __attribute__ ((__visibility__("default"))) | |
| 271 struct tm* localtime64_r_override(const time_t* timep, struct tm* result) { | |
| 272 if (g_am_zygote_or_renderer) { | |
| 273 ProxyLocaltimeCallToBrowser(*timep, result, NULL, 0); | |
| 274 return result; | |
| 275 } else { | |
| 276 CHECK_EQ(0, pthread_once(&g_libc_localtime_funcs_guard, | |
| 277 InitLibcLocaltimeFunctions)); | |
| 278 return g_libc_localtime64_r(timep, result); | |
| 279 } | |
| 280 } | |
| 281 | |
| 233 // TODO(sergeyu): Currently this code doesn't work properly under ASAN | 282 // TODO(sergeyu): Currently this code doesn't work properly under ASAN |
| 234 // - it crashes content_unittests. Make sure it works properly and | 283 // - it crashes content_unittests. Make sure it works properly and |
| 235 // enable it here. http://crbug.com/123263 | 284 // enable it here. http://crbug.com/123263 |
| 236 #if !defined(ADDRESS_SANITIZER) | 285 #if !defined(ADDRESS_SANITIZER) |
| 237 | 286 |
| 238 static void InitLibcFileIOFunctions() { | 287 static void InitLibcFileIOFunctions() { |
| 239 g_libc_fopen = reinterpret_cast<FopenFunction>( | 288 g_libc_fopen = reinterpret_cast<FopenFunction>( |
| 240 dlsym(RTLD_NEXT, "fopen")); | 289 dlsym(RTLD_NEXT, "fopen")); |
| 241 g_libc_fopen64 = reinterpret_cast<FopenFunction>( | 290 g_libc_fopen64 = reinterpret_cast<FopenFunction>( |
| 242 dlsym(RTLD_NEXT, "fopen64")); | 291 dlsym(RTLD_NEXT, "fopen64")); |
| (...skipping 291 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 534 } | 583 } |
| 535 } | 584 } |
| 536 #endif // SECCOMP_SANDBOX | 585 #endif // SECCOMP_SANDBOX |
| 537 | 586 |
| 538 Zygote zygote(sandbox_flags, forkdelegate, proc_fd_for_seccomp); | 587 Zygote zygote(sandbox_flags, forkdelegate, proc_fd_for_seccomp); |
| 539 // This function call can return multiple times, once per fork(). | 588 // This function call can return multiple times, once per fork(). |
| 540 return zygote.ProcessRequests(); | 589 return zygote.ProcessRequests(); |
| 541 } | 590 } |
| 542 | 591 |
| 543 } // namespace content | 592 } // namespace content |
| OLD | NEW |