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/. */
8 #include "mozmemory_wrap.h"
9 #include "mozilla/Types.h"
11 // Declare malloc implementation functions with the right return and
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"
20 // strndup and strdup may be defined as macros in string.h, which would
21 // clash with the definitions below.
25 MOZ_MEMORY_API
char* strndup_impl(const char* src
, size_t len
) {
26 char* dst
= (char*)malloc_impl(len
+ 1);
28 strncpy(dst
, src
, len
);
34 MOZ_MEMORY_API
char* strdup_impl(const char* src
) {
35 size_t len
= strlen(src
);
36 return strndup_impl(src
, len
);
43 MOZ_MEMORY_API
int vasprintf_impl(char** str
, const char* fmt
, va_list ap
) {
47 if (str
== NULL
|| fmt
== NULL
) {
51 ptr
= (char*)malloc_impl(128);
57 ret
= vsnprintf(ptr
, 128, fmt
, ap
);
64 _ptr
= reinterpret_cast<char*>(realloc_impl(ptr
, ret
+ 1));
76 MOZ_MEMORY_API
int asprintf_impl(char** str
, const char* fmt
, ...) {
81 ret
= vasprintf_impl(str
, fmt
, ap
);
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);
101 MOZ_MEMORY_API
void* _aligned_malloc_impl(size_t size
, size_t alignment
) {
102 return memalign_impl(alignment
, size
);
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
))));
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
))));
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.
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
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
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
;