| Index: content/zygote/zygote_main_linux.cc
|
| diff --git a/content/zygote/zygote_main_linux.cc b/content/zygote/zygote_main_linux.cc
|
| index 21f54d8dfa9318328c7874b398c5da6dfa021cf9..f9073646d864a478ff1e76342f141734992ea80e 100644
|
| --- a/content/zygote/zygote_main_linux.cc
|
| +++ b/content/zygote/zygote_main_linux.cc
|
| @@ -173,7 +173,9 @@ typedef int (*Xstat64Function)(int version, const char *path,
|
|
|
| static pthread_once_t g_libc_localtime_funcs_guard = PTHREAD_ONCE_INIT;
|
| static LocaltimeFunction g_libc_localtime;
|
| +static LocaltimeFunction g_libc_localtime64;
|
| static LocaltimeRFunction g_libc_localtime_r;
|
| +static LocaltimeRFunction g_libc_localtime64_r;
|
|
|
| static pthread_once_t g_libc_file_io_funcs_guard = PTHREAD_ONCE_INIT;
|
| static FopenFunction g_libc_fopen;
|
| @@ -184,8 +186,12 @@ static Xstat64Function g_libc_xstat64;
|
| static void InitLibcLocaltimeFunctions() {
|
| g_libc_localtime = reinterpret_cast<LocaltimeFunction>(
|
| dlsym(RTLD_NEXT, "localtime"));
|
| + g_libc_localtime64 = reinterpret_cast<LocaltimeFunction>(
|
| + dlsym(RTLD_NEXT, "localtime64"));
|
| g_libc_localtime_r = reinterpret_cast<LocaltimeRFunction>(
|
| dlsym(RTLD_NEXT, "localtime_r"));
|
| + g_libc_localtime64_r = reinterpret_cast<LocaltimeRFunction>(
|
| + dlsym(RTLD_NEXT, "localtime64_r"));
|
|
|
| if (!g_libc_localtime || !g_libc_localtime_r) {
|
| // http://code.google.com/p/chromium/issues/detail?id=16800
|
| @@ -201,11 +207,23 @@ static void InitLibcLocaltimeFunctions() {
|
|
|
| if (!g_libc_localtime)
|
| g_libc_localtime = gmtime;
|
| + if (!g_libc_localtime64)
|
| + g_libc_localtime64 = g_libc_localtime;
|
| if (!g_libc_localtime_r)
|
| g_libc_localtime_r = gmtime_r;
|
| + if (!g_libc_localtime64_r)
|
| + g_libc_localtime64_r = g_libc_localtime_r;
|
| }
|
|
|
| -struct tm* localtime(const time_t* timep) {
|
| +// Define localtime_override() function with asm name "localtime", so that all
|
| +// references to localtime() will resolve to this function. Notice that we need
|
| +// to set visibility attribute to "default" to export the symbol, as it is set
|
| +// to "hidden" by default in chrome per build/common.gypi.
|
| +__attribute__ ((__visibility__("default")))
|
| +struct tm* localtime_override(const time_t* timep) __asm__ ("localtime");
|
| +
|
| +__attribute__ ((__visibility__("default")))
|
| +struct tm* localtime_override(const time_t* timep) {
|
| if (g_am_zygote_or_renderer) {
|
| static struct tm time_struct;
|
| static char timezone_string[64];
|
| @@ -219,7 +237,31 @@ struct tm* localtime(const time_t* timep) {
|
| }
|
| }
|
|
|
| -struct tm* localtime_r(const time_t* timep, struct tm* result) {
|
| +// Use same trick to override localtime64(), localtime_r() and localtime64_r().
|
| +__attribute__ ((__visibility__("default")))
|
| +struct tm* localtime64_override(const time_t* timep) __asm__ ("localtime64");
|
| +
|
| +__attribute__ ((__visibility__("default")))
|
| +struct tm* localtime64_override(const time_t* timep) {
|
| + if (g_am_zygote_or_renderer) {
|
| + static struct tm time_struct;
|
| + static char timezone_string[64];
|
| + ProxyLocaltimeCallToBrowser(*timep, &time_struct, timezone_string,
|
| + sizeof(timezone_string));
|
| + return &time_struct;
|
| + } else {
|
| + CHECK_EQ(0, pthread_once(&g_libc_localtime_funcs_guard,
|
| + InitLibcLocaltimeFunctions));
|
| + return g_libc_localtime64(timep);
|
| + }
|
| +}
|
| +
|
| +__attribute__ ((__visibility__("default")))
|
| +struct tm* localtime_r_override(const time_t* timep,
|
| + struct tm* result) __asm__ ("localtime_r");
|
| +
|
| +__attribute__ ((__visibility__("default")))
|
| +struct tm* localtime_r_override(const time_t* timep, struct tm* result) {
|
| if (g_am_zygote_or_renderer) {
|
| ProxyLocaltimeCallToBrowser(*timep, result, NULL, 0);
|
| return result;
|
| @@ -230,6 +272,22 @@ struct tm* localtime_r(const time_t* timep, struct tm* result) {
|
| }
|
| }
|
|
|
| +__attribute__ ((__visibility__("default")))
|
| +struct tm* localtime64_r_override(const time_t* timep,
|
| + struct tm* result) __asm__ ("localtime64_r");
|
| +
|
| +__attribute__ ((__visibility__("default")))
|
| +struct tm* localtime64_r_override(const time_t* timep, struct tm* result) {
|
| + if (g_am_zygote_or_renderer) {
|
| + ProxyLocaltimeCallToBrowser(*timep, result, NULL, 0);
|
| + return result;
|
| + } else {
|
| + CHECK_EQ(0, pthread_once(&g_libc_localtime_funcs_guard,
|
| + InitLibcLocaltimeFunctions));
|
| + return g_libc_localtime64_r(timep, result);
|
| + }
|
| +}
|
| +
|
| // TODO(sergeyu): Currently this code doesn't work properly under ASAN
|
| // - it crashes content_unittests. Make sure it works properly and
|
| // enable it here. http://crbug.com/123263
|
|
|