tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

mozmemory_wrap.cpp (4399B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
      3 /* This Source Code Form is subject to the terms of the Mozilla Public
      4 * License, v. 2.0. If a copy of the MPL was not distributed with this
      5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 
      7 #include <string.h>
      8 #include "mozmemory_wrap.h"
      9 #include "mozilla/Types.h"
     10 
     11 // Declare malloc implementation functions with the right return and
     12 // argument types.
     13 #define NOTHROW_MALLOC_DECL(name, return_type, ...) \
     14  MOZ_MEMORY_API return_type name##_impl(__VA_ARGS__) noexcept(true);
     15 #define MALLOC_DECL(name, return_type, ...) \
     16  MOZ_MEMORY_API return_type name##_impl(__VA_ARGS__);
     17 #define MALLOC_FUNCS MALLOC_FUNCS_MALLOC
     18 #include "malloc_decls.h"
     19 
     20 // strndup and strdup may be defined as macros in string.h, which would
     21 // clash with the definitions below.
     22 #undef strndup
     23 #undef strdup
     24 
     25 MOZ_MEMORY_API char* strndup_impl(const char* src, size_t len) {
     26  char* dst = (char*)malloc_impl(len + 1);
     27  if (dst) {
     28    strncpy(dst, src, len);
     29    dst[len] = '\0';
     30  }
     31  return dst;
     32 }
     33 
     34 MOZ_MEMORY_API char* strdup_impl(const char* src) {
     35  size_t len = strlen(src);
     36  return strndup_impl(src, len);
     37 }
     38 
     39 #ifdef ANDROID
     40 #  include <stdarg.h>
     41 #  include <stdio.h>
     42 
     43 MOZ_MEMORY_API int vasprintf_impl(char** str, const char* fmt, va_list ap) {
     44  char *ptr, *_ptr;
     45  int ret;
     46 
     47  if (str == NULL || fmt == NULL) {
     48    return -1;
     49  }
     50 
     51  ptr = (char*)malloc_impl(128);
     52  if (ptr == NULL) {
     53    *str = NULL;
     54    return -1;
     55  }
     56 
     57  ret = vsnprintf(ptr, 128, fmt, ap);
     58  if (ret < 0) {
     59    free_impl(ptr);
     60    *str = NULL;
     61    return -1;
     62  }
     63 
     64  _ptr = reinterpret_cast<char*>(realloc_impl(ptr, ret + 1));
     65  if (_ptr == NULL) {
     66    free_impl(ptr);
     67    *str = NULL;
     68    return -1;
     69  }
     70 
     71  *str = _ptr;
     72 
     73  return ret;
     74 }
     75 
     76 MOZ_MEMORY_API int asprintf_impl(char** str, const char* fmt, ...) {
     77  int ret;
     78  va_list ap;
     79  va_start(ap, fmt);
     80 
     81  ret = vasprintf_impl(str, fmt, ap);
     82 
     83  va_end(ap);
     84 
     85  return ret;
     86 }
     87 #endif
     88 
     89 #ifdef XP_WIN
     90 #  include <wchar.h>
     91 
     92 // We also need to provide our own impl of wcsdup so that we don't ask
     93 // the CRT for memory from its heap (which will then be unfreeable).
     94 MOZ_MEMORY_API wchar_t* wcsdup_impl(const wchar_t* src) {
     95  size_t len = wcslen(src);
     96  wchar_t* dst = (wchar_t*)malloc_impl((len + 1) * sizeof(wchar_t));
     97  if (dst) wcsncpy(dst, src, len + 1);
     98  return dst;
     99 }
    100 
    101 MOZ_MEMORY_API void* _aligned_malloc_impl(size_t size, size_t alignment) {
    102  return memalign_impl(alignment, size);
    103 }
    104 
    105 #  ifdef __MINGW32__
    106 MOZ_BEGIN_EXTERN_C
    107 // As in mozjemalloc.cpp, we generate aliases for functions
    108 // redirected in mozglue.def
    109 void* _aligned_malloc(size_t size, size_t alignment)
    110    __attribute__((alias(MOZ_STRINGIFY(_aligned_malloc_impl))));
    111 void _aligned_free(void* aPtr) __attribute__((alias(MOZ_STRINGIFY(free_impl))));
    112 
    113 char* strndup(const char* src, size_t len)
    114    __attribute__((alias(MOZ_STRINGIFY(strdup_impl))));
    115 char* strdup(const char* src)
    116    __attribute__((alias(MOZ_STRINGIFY(strdup_impl))));
    117 char* _strdup(const char* src)
    118    __attribute__((alias(MOZ_STRINGIFY(strdup_impl))));
    119 wchar_t* wcsdup(const wchar_t* src)
    120    __attribute__((alias(MOZ_STRINGIFY(wcsdup_impl))));
    121 wchar_t* _wcsdup(const wchar_t* src)
    122    __attribute__((alias(MOZ_STRINGIFY(wcsdup_impl))));
    123 
    124 // jemalloc has _aligned_malloc, and friends. libc++.a contains
    125 // references to __imp__aligned_malloc (and friends) because it
    126 // is declared dllimport in the headers.
    127 //
    128 // The linker sees jemalloc's _aligned_malloc symbol in our objects,
    129 // but then libc++.a comes along and needs __imp__aligned_malloc, which
    130 // pulls in those parts of libucrt.a (or libmsvcrt.a in practice),
    131 // which define both __imp__aligned_malloc and _aligned_malloc, and
    132 // this causes a conflict.  (And repeat for each of the symbols defined
    133 // here.)
    134 //
    135 // The fix is to define not only an _aligned_malloc symbol (via an
    136 // alias), but also define the __imp__aligned_malloc pointer to it.
    137 // This prevents those parts of libucrt from being pulled in and causing
    138 // conflicts.
    139 // This is done with __MINGW_IMP_SYMBOL to handle x86/x64 differences.
    140 void (*__MINGW_IMP_SYMBOL(_aligned_free))(void*) = _aligned_free;
    141 void* (*__MINGW_IMP_SYMBOL(_aligned_malloc))(size_t, size_t) = _aligned_malloc;
    142 char* (*__MINGW_IMP_SYMBOL(_strdup))(const char* src) = _strdup;
    143 MOZ_END_EXTERN_C
    144 #  endif
    145 #endif  // XP_WIN