mozglue/build/BionicGlue.cpp

changeset 0
6474c204b198
     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

mercurial