1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/mozglue/build/BionicGlue.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,264 @@ 1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this file, 1.7 + * You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +#include <pthread.h> 1.10 +#include <string.h> 1.11 +#include <stdlib.h> 1.12 +#include <time.h> 1.13 +#include <unistd.h> 1.14 +#include <android/log.h> 1.15 +#include <sys/syscall.h> 1.16 + 1.17 +#include "mozilla/Alignment.h" 1.18 + 1.19 +#include <vector> 1.20 + 1.21 +#define NS_EXPORT __attribute__ ((visibility("default"))) 1.22 + 1.23 +#if ANDROID_VERSION < 17 || defined(MOZ_WIDGET_ANDROID) 1.24 +/* Android doesn't have pthread_atfork(), so we need to use our own. */ 1.25 +struct AtForkFuncs { 1.26 + void (*prepare)(void); 1.27 + void (*parent)(void); 1.28 + void (*child)(void); 1.29 +}; 1.30 + 1.31 +/* jemalloc's initialization calls pthread_atfork. When pthread_atfork (see 1.32 + * further below) stores the corresponding data, it's going to allocate memory, 1.33 + * which will loop back to jemalloc's initialization, leading to a dead-lock. 1.34 + * So, for that specific vector, we use a special allocator that returns a 1.35 + * static buffer for small sizes, and force the initial vector capacity to 1.36 + * a size enough to store one atfork function table. */ 1.37 +template <typename T> 1.38 +struct SpecialAllocator: public std::allocator<T> 1.39 +{ 1.40 + SpecialAllocator(): bufUsed(false) {} 1.41 + 1.42 + inline typename std::allocator<T>::pointer allocate(typename std::allocator<T>::size_type n, const void * = 0) { 1.43 + if (!bufUsed && n == 1) { 1.44 + bufUsed = true; 1.45 + return buf.addr(); 1.46 + } 1.47 + return reinterpret_cast<T *>(::operator new(sizeof(T) * n)); 1.48 + } 1.49 + 1.50 + inline void deallocate(typename std::allocator<T>::pointer p, typename std::allocator<T>::size_type n) { 1.51 + if (p == buf.addr()) 1.52 + bufUsed = false; 1.53 + else 1.54 + ::operator delete(p); 1.55 + } 1.56 + 1.57 + template<typename U> 1.58 + struct rebind { 1.59 + typedef SpecialAllocator<U> other; 1.60 + }; 1.61 + 1.62 +private: 1.63 + mozilla::AlignedStorage2<T> buf; 1.64 + bool bufUsed; 1.65 +}; 1.66 + 1.67 +static std::vector<AtForkFuncs, SpecialAllocator<AtForkFuncs> > atfork; 1.68 +#endif 1.69 + 1.70 +#ifdef MOZ_WIDGET_GONK 1.71 +#include "cpuacct.h" 1.72 +#define WRAP(x) x 1.73 + 1.74 +#if ANDROID_VERSION < 17 || defined(MOZ_WIDGET_ANDROID) 1.75 +extern "C" NS_EXPORT int 1.76 +timer_create(clockid_t, struct sigevent*, timer_t*) 1.77 +{ 1.78 + __android_log_print(ANDROID_LOG_ERROR, "BionicGlue", "timer_create not supported!"); 1.79 + abort(); 1.80 + return -1; 1.81 +} 1.82 +#endif 1.83 + 1.84 +#else 1.85 +#define cpuacct_add(x) 1.86 +#define WRAP(x) __wrap_##x 1.87 +#endif 1.88 + 1.89 +#if ANDROID_VERSION < 17 || defined(MOZ_WIDGET_ANDROID) 1.90 +extern "C" NS_EXPORT int 1.91 +WRAP(pthread_atfork)(void (*prepare)(void), void (*parent)(void), void (*child)(void)) 1.92 +{ 1.93 + AtForkFuncs funcs; 1.94 + funcs.prepare = prepare; 1.95 + funcs.parent = parent; 1.96 + funcs.child = child; 1.97 + if (!atfork.capacity()) 1.98 + atfork.reserve(1); 1.99 + atfork.push_back(funcs); 1.100 + return 0; 1.101 +} 1.102 + 1.103 +extern "C" NS_EXPORT pid_t 1.104 +WRAP(fork)(void) 1.105 +{ 1.106 + pid_t pid; 1.107 + for (auto it = atfork.rbegin(); 1.108 + it < atfork.rend(); ++it) 1.109 + if (it->prepare) 1.110 + it->prepare(); 1.111 + 1.112 + switch ((pid = syscall(__NR_clone, SIGCHLD, NULL, NULL, NULL, NULL))) { 1.113 + case 0: 1.114 + cpuacct_add(getuid()); 1.115 + for (auto it = atfork.begin(); 1.116 + it < atfork.end(); ++it) 1.117 + if (it->child) 1.118 + it->child(); 1.119 + break; 1.120 + default: 1.121 + for (auto it = atfork.begin(); 1.122 + it < atfork.end(); ++it) 1.123 + if (it->parent) 1.124 + it->parent(); 1.125 + } 1.126 + return pid; 1.127 +} 1.128 +#endif 1.129 + 1.130 +extern "C" NS_EXPORT int 1.131 +WRAP(raise)(int sig) 1.132 +{ 1.133 + // Bug 741272: Bionic incorrectly uses kill(), which signals the 1.134 + // process, and thus could signal another thread (and let this one 1.135 + // return "successfully" from raising a fatal signal). 1.136 + // 1.137 + // Bug 943170: POSIX specifies pthread_kill(pthread_self(), sig) as 1.138 + // equivalent to raise(sig), but Bionic also has a bug with these 1.139 + // functions, where a forked child will kill its parent instead. 1.140 + 1.141 + extern pid_t gettid(void); 1.142 + return syscall(__NR_tgkill, getpid(), gettid(), sig); 1.143 +} 1.144 + 1.145 +/* 1.146 + * The following wrappers for PR_Xxx are needed until we can get 1.147 + * PR_DuplicateEnvironment landed in NSPR. 1.148 + * See see bug 772734 and bug 773414. 1.149 + * 1.150 + * We can't #include the pr headers here, and we can't call any of the 1.151 + * PR/PL functions either, so we just reimplemnt using native code. 1.152 + */ 1.153 + 1.154 +static pthread_mutex_t _pr_envLock = PTHREAD_MUTEX_INITIALIZER; 1.155 + 1.156 +extern "C" NS_EXPORT char* 1.157 +__wrap_PR_GetEnv(const char *var) 1.158 +{ 1.159 + char *ev; 1.160 + 1.161 + pthread_mutex_lock(&_pr_envLock); 1.162 + ev = getenv(var); 1.163 + pthread_mutex_unlock(&_pr_envLock); 1.164 + return ev; 1.165 +} 1.166 + 1.167 +extern "C" NS_EXPORT int 1.168 +__wrap_PR_SetEnv(const char *string) 1.169 +{ 1.170 + int result; 1.171 + 1.172 + if ( !strchr(string, '=')) return(-1); 1.173 + 1.174 + pthread_mutex_lock(&_pr_envLock); 1.175 + result = putenv(string); 1.176 + pthread_mutex_unlock(&_pr_envLock); 1.177 + return (result)? -1 : 0; 1.178 +} 1.179 + 1.180 +extern "C" NS_EXPORT pthread_mutex_t * 1.181 +PR_GetEnvLock(void) 1.182 +{ 1.183 + return &_pr_envLock; 1.184 +} 1.185 + 1.186 +/* Amazon Kindle Fire HD's libc provides most of the 1.187 + * functions in string.h as weak symbols, which dlsym 1.188 + * cannot resolve. Thus, we must wrap these functions. 1.189 + * See bug 791419. 1.190 + */ 1.191 + 1.192 +#ifndef MOZ_WIDGET_GONK 1.193 +#include <string.h> 1.194 +extern "C" NS_EXPORT void* __real_memccpy(void * a0, const void * a1, int a2, size_t a3); 1.195 +extern "C" NS_EXPORT void* __real_memchr(const void * a0, int a1, size_t a2); 1.196 +extern "C" NS_EXPORT void* __real_memrchr(const void * a0, int a1, size_t a2); 1.197 +extern "C" NS_EXPORT int __real_memcmp(const void * a0, const void * a1, size_t a2); 1.198 +extern "C" NS_EXPORT void* __real_memcpy(void * a0, const void * a1, size_t a2); 1.199 +extern "C" NS_EXPORT void* __real_memmove(void * a0, const void * a1, size_t a2); 1.200 +extern "C" NS_EXPORT void* __real_memset(void * a0, int a1, size_t a2); 1.201 +extern "C" NS_EXPORT void* __real_memmem(const void * a0, size_t a1, const void * a2, size_t a3); 1.202 +extern "C" NS_EXPORT void __real_memswap(void * a0, void * a1, size_t a2); 1.203 +extern "C" NS_EXPORT char* __real_index(const char * a0, int a1); 1.204 +extern "C" NS_EXPORT char* __real_strchr(const char * a0, int a1); 1.205 +extern "C" NS_EXPORT char* __real_strrchr(const char * a0, int a1); 1.206 +extern "C" NS_EXPORT size_t __real_strlen(const char * a0); 1.207 +extern "C" NS_EXPORT int __real_strcmp(const char * a0, const char * a1); 1.208 +extern "C" NS_EXPORT char* __real_strcpy(char * a0, const char * a1); 1.209 +extern "C" NS_EXPORT char* __real_strcat(char * a0, const char * a1); 1.210 +extern "C" NS_EXPORT int __real_strcasecmp(const char * a0, const char * a1); 1.211 +extern "C" NS_EXPORT int __real_strncasecmp(const char * a0, const char * a1, size_t a2); 1.212 +extern "C" NS_EXPORT char* __real_strstr(const char * a0, const char * a1); 1.213 +extern "C" NS_EXPORT char* __real_strcasestr(const char * a0, const char * a1); 1.214 +extern "C" NS_EXPORT char* __real_strtok(char * a0, const char * a1); 1.215 +extern "C" NS_EXPORT char* __real_strtok_r(char * a0, const char * a1, char** a2); 1.216 +extern "C" NS_EXPORT char* __real_strerror(int a0); 1.217 +extern "C" NS_EXPORT int __real_strerror_r(int a0, char * a1, size_t a2); 1.218 +extern "C" NS_EXPORT size_t __real_strnlen(const char * a0, size_t a1); 1.219 +extern "C" NS_EXPORT char* __real_strncat(char * a0, const char * a1, size_t a2); 1.220 +extern "C" NS_EXPORT int __real_strncmp(const char * a0, const char * a1, size_t a2); 1.221 +extern "C" NS_EXPORT char* __real_strncpy(char * a0, const char * a1, size_t a2); 1.222 +extern "C" NS_EXPORT size_t __real_strlcat(char * a0, const char * a1, size_t a2); 1.223 +extern "C" NS_EXPORT size_t __real_strlcpy(char * a0, const char * a1, size_t a2); 1.224 +extern "C" NS_EXPORT size_t __real_strcspn(const char * a0, const char * a1); 1.225 +extern "C" NS_EXPORT char* __real_strpbrk(const char * a0, const char * a1); 1.226 +extern "C" NS_EXPORT char* __real_strsep(char ** a0, const char * a1); 1.227 +extern "C" NS_EXPORT size_t __real_strspn(const char * a0, const char * a1); 1.228 +extern "C" NS_EXPORT int __real_strcoll(const char * a0, const char * a1); 1.229 +extern "C" NS_EXPORT size_t __real_strxfrm(char * a0, const char * a1, size_t a2); 1.230 + 1.231 +extern "C" NS_EXPORT void* __wrap_memccpy(void * a0, const void * a1, int a2, size_t a3) { return __real_memccpy(a0, a1, a2, a3); } 1.232 +extern "C" NS_EXPORT void* __wrap_memchr(const void * a0, int a1, size_t a2) { return __real_memchr(a0, a1, a2); } 1.233 +extern "C" NS_EXPORT void* __wrap_memrchr(const void * a0, int a1, size_t a2) { return __real_memrchr(a0, a1, a2); } 1.234 +extern "C" NS_EXPORT int __wrap_memcmp(const void * a0, const void * a1, size_t a2) { return __real_memcmp(a0, a1, a2); } 1.235 +extern "C" NS_EXPORT void* __wrap_memcpy(void * a0, const void * a1, size_t a2) { return __real_memcpy(a0, a1, a2); } 1.236 +extern "C" NS_EXPORT void* __wrap_memmove(void * a0, const void * a1, size_t a2) { return __real_memmove(a0, a1, a2); } 1.237 +extern "C" NS_EXPORT void* __wrap_memset(void * a0, int a1, size_t a2) { return __real_memset(a0, a1, a2); } 1.238 +extern "C" NS_EXPORT void* __wrap_memmem(const void * a0, size_t a1, const void * a2, size_t a3) { return __real_memmem(a0, a1, a2, a3); } 1.239 +extern "C" NS_EXPORT void __wrap_memswap(void * a0, void * a1, size_t a2) { __real_memswap(a0, a1, a2); } 1.240 +extern "C" NS_EXPORT char* __wrap_index(const char * a0, int a1) { return __real_index(a0, a1); } 1.241 +extern "C" NS_EXPORT char* __wrap_strchr(const char * a0, int a1) { return __real_strchr(a0, a1); } 1.242 +extern "C" NS_EXPORT char* __wrap_strrchr(const char * a0, int a1) { return __real_strrchr(a0, a1); } 1.243 +extern "C" NS_EXPORT size_t __wrap_strlen(const char * a0) { return __real_strlen(a0); } 1.244 +extern "C" NS_EXPORT int __wrap_strcmp(const char * a0, const char * a1) { return __real_strcmp(a0, a1); } 1.245 +extern "C" NS_EXPORT char* __wrap_strcpy(char * a0, const char * a1) { return __real_strcpy(a0, a1); } 1.246 +extern "C" NS_EXPORT char* __wrap_strcat(char * a0, const char * a1) { return __real_strcat(a0, a1); } 1.247 +extern "C" NS_EXPORT int __wrap_strcasecmp(const char * a0, const char * a1) { return __real_strcasecmp(a0, a1); } 1.248 +extern "C" NS_EXPORT int __wrap_strncasecmp(const char * a0, const char * a1, size_t a2) { return __real_strncasecmp(a0, a1, a2); } 1.249 +extern "C" NS_EXPORT char* __wrap_strstr(const char * a0, const char * a1) { return __real_strstr(a0, a1); } 1.250 +extern "C" NS_EXPORT char* __wrap_strcasestr(const char * a0, const char * a1) { return __real_strcasestr(a0, a1); } 1.251 +extern "C" NS_EXPORT char* __wrap_strtok(char * a0, const char * a1) { return __real_strtok(a0, a1); } 1.252 +extern "C" NS_EXPORT char* __wrap_strtok_r(char * a0, const char * a1, char** a2) { return __real_strtok_r(a0, a1, a2); } 1.253 +extern "C" NS_EXPORT char* __wrap_strerror(int a0) { return __real_strerror(a0); } 1.254 +extern "C" NS_EXPORT int __wrap_strerror_r(int a0, char * a1, size_t a2) { return __real_strerror_r(a0, a1, a2); } 1.255 +extern "C" NS_EXPORT size_t __wrap_strnlen(const char * a0, size_t a1) { return __real_strnlen(a0, a1); } 1.256 +extern "C" NS_EXPORT char* __wrap_strncat(char * a0, const char * a1, size_t a2) { return __real_strncat(a0, a1, a2); } 1.257 +extern "C" NS_EXPORT int __wrap_strncmp(const char * a0, const char * a1, size_t a2) { return __real_strncmp(a0, a1, a2); } 1.258 +extern "C" NS_EXPORT char* __wrap_strncpy(char * a0, const char * a1, size_t a2) { return __real_strncpy(a0, a1, a2); } 1.259 +extern "C" NS_EXPORT size_t __wrap_strlcat(char * a0, const char * a1, size_t a2) { return __real_strlcat(a0, a1, a2); } 1.260 +extern "C" NS_EXPORT size_t __wrap_strlcpy(char * a0, const char * a1, size_t a2) { return __real_strlcpy(a0, a1, a2); } 1.261 +extern "C" NS_EXPORT size_t __wrap_strcspn(const char * a0, const char * a1) { return __real_strcspn(a0, a1); } 1.262 +extern "C" NS_EXPORT char* __wrap_strpbrk(const char * a0, const char * a1) { return __real_strpbrk(a0, a1); } 1.263 +extern "C" NS_EXPORT char* __wrap_strsep(char ** a0, const char * a1) { return __real_strsep(a0, a1); } 1.264 +extern "C" NS_EXPORT size_t __wrap_strspn(const char * a0, const char * a1) { return __real_strspn(a0, a1); } 1.265 +extern "C" NS_EXPORT int __wrap_strcoll(const char * a0, const char * a1) { return __real_strcoll(a0, a1); } 1.266 +extern "C" NS_EXPORT size_t __wrap_strxfrm(char * a0, const char * a1, size_t a2) { return __real_strxfrm(a0, a1, a2); } 1.267 +#endif