summaryrefslogtreecommitdiffstats
path: root/mozglue/build
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 14:29:10 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 14:29:10 +0000
commit2aa4a82499d4becd2284cdb482213d541b8804dd (patch)
treeb80bf8bf13c3766139fbacc530efd0dd9d54394c /mozglue/build
parentInitial commit. (diff)
downloadfirefox-2aa4a82499d4becd2284cdb482213d541b8804dd.tar.xz
firefox-2aa4a82499d4becd2284cdb482213d541b8804dd.zip
Adding upstream version 86.0.1.upstream/86.0.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'mozglue/build')
-rw-r--r--mozglue/build/AsanOptions.cpp186
-rw-r--r--mozglue/build/BionicGlue.cpp37
-rw-r--r--mozglue/build/Makefile.in15
-rw-r--r--mozglue/build/SSE.cpp196
-rw-r--r--mozglue/build/SSE.h350
-rw-r--r--mozglue/build/TsanOptions.cpp305
-rw-r--r--mozglue/build/UbsanOptions.cpp16
-rw-r--r--mozglue/build/arm-eabi-filter4
-rw-r--r--mozglue/build/arm.cpp131
-rw-r--r--mozglue/build/arm.h145
-rw-r--r--mozglue/build/dummy.cpp5
-rw-r--r--mozglue/build/mips.cpp42
-rw-r--r--mozglue/build/mips.h29
-rw-r--r--mozglue/build/moz.build120
-rw-r--r--mozglue/build/mozglue.def22
-rw-r--r--mozglue/build/mozglue.dll.manifest9
-rw-r--r--mozglue/build/mozglue.ver4
-rw-r--r--mozglue/build/ppc.cpp64
-rw-r--r--mozglue/build/ppc.h47
-rw-r--r--mozglue/build/replace_malloc.mozbuild6
20 files changed, 1733 insertions, 0 deletions
diff --git a/mozglue/build/AsanOptions.cpp b/mozglue/build/AsanOptions.cpp
new file mode 100644
index 0000000000..79ff503a68
--- /dev/null
+++ b/mozglue/build/AsanOptions.cpp
@@ -0,0 +1,186 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "mozilla/Attributes.h"
+
+#ifndef _MSC_VER // Not supported by clang-cl yet
+
+// When running with AddressSanitizer, we need to explicitly set some
+// options specific to our codebase to prevent errors during runtime.
+// To override these, set the ASAN_OPTIONS environment variable.
+//
+// Currently, these are:
+//
+// allow_user_segv_handler=1 - Tell ASan to allow our code to use its
+// own SIGSEGV handlers. This is required by ASM.js internally.
+//
+// alloc_dealloc_mismatch=0 - Disable alloc-dealloc mismatch checking
+// in ASan. This is required because we define our own new/delete
+// operators that are backed by malloc/free. If one of them gets inlined
+// while the other doesn't, ASan will report false positives.
+//
+// detect_leaks=0 - Disable LeakSanitizer. This is required because
+// otherwise leak checking will be enabled for various building and
+// testing executables where we don't care much about leaks.
+//
+// allocator_may_return_null=1 - Tell ASan to return NULL when an allocation
+// fails instead of aborting the program. This allows us to handle failing
+// allocations the same way we would handle them with a regular allocator and
+// also uncovers potential bugs that might occur in these situations.
+//
+// max_malloc_fill_size - Tell ASan to initialize memory to a certain value
+// when it is allocated. This option specifies the maximum allocation size
+// for which ASan should still initialize the memory. The value we specify
+// here is exactly 256MiB.
+//
+// max_free_fill_size - Similar to max_malloc_fill_size, tell ASan to
+// overwrite memory with a certain value when it is freed. Again, the value
+// here specifies the maximum allocation size, larger allocations will
+// skipped.
+//
+// malloc_fill_byte / free_fill_byte - These values specify the byte values
+// used to initialize/overwrite memory in conjunction with the previous
+// options max_malloc_fill_size and max_free_fill_size. The values used here
+// are 0xe4 and 0xe5 to match the kAllocPoison and kAllocJunk constants used
+// by mozjemalloc.
+//
+// malloc_context_size - This value specifies how many stack frames are
+// stored for each malloc and free call. Since Firefox can have lots of deep
+// stacks with allocations, we limit the default size here further to save
+// some memory.
+//
+// fast_unwind_on_check - Use the fast (frame-pointer-based) stack unwinder
+// for internal CHECK failures. The slow unwinder doesn't work on Android.
+//
+// fast_unwind_on_fatal - Use the fast (frame-pointer-based) stack unwinder
+// to print fatal error reports. The slow unwinder doesn't work on Android.
+//
+// !! Note: __asan_default_options is not used on Android! (bug 1576213)
+// These should be updated in:
+// mobile/android/geckoview/src/asan/resources/lib/*/wrap.sh
+//
+extern "C" MOZ_ASAN_BLACKLIST const char* __asan_default_options() {
+ return "allow_user_segv_handler=1:alloc_dealloc_mismatch=0:detect_leaks=0"
+# ifdef MOZ_ASAN_REPORTER
+ ":malloc_context_size=20"
+# endif
+# ifdef __ANDROID__
+ ":fast_unwind_on_check=1:fast_unwind_on_fatal=1"
+# endif
+ ":max_free_fill_size=268435456:max_malloc_fill_size=268435456"
+ ":malloc_fill_byte=228:free_fill_byte=229"
+ ":handle_sigill=1"
+ ":allocator_may_return_null=1";
+}
+
+// !!! Please do not add suppressions for new leaks in Gecko code, unless they
+// are intentional !!!
+extern "C" const char* __lsan_default_suppressions() {
+ return "# Add your suppressions below\n"
+
+ // LSan runs with a shallow stack depth and no debug symbols, so some
+ // small intentional leaks in system libraries show up with this. You
+ // do not want this enabled when running locally with a deep stack, as
+ // it can catch too much.
+ "leak:libc.so\n"
+
+ // nsComponentManagerImpl intentionally leaks factory entries, and
+ // probably some other stuff.
+ "leak:nsComponentManagerImpl\n"
+ // These two variants are needed when fast unwind is disabled and stack
+ // depth is limited.
+ "leak:mozJSComponentLoader::LoadModule\n"
+ "leak:nsNativeModuleLoader::LoadModule\n"
+
+ // Bug 981220 - Pixman fails to free TLS memory.
+ "leak:pixman_implementation_lookup_composite\n"
+
+ // Bug 987918 - Font shutdown leaks when CLEANUP_MEMORY is not enabled.
+ "leak:libfontconfig.so\n"
+ "leak:libfreetype.so\n"
+ "leak:GI___strdup\n"
+ // The symbol is really __GI___strdup, but if you have the leading _,
+ // it doesn't suppress it.
+
+ // Bug 1078015 - If the process terminates during a PR_Sleep, LSAN
+ // detects a leak
+ "leak:PR_Sleep\n"
+
+ // Bug 1363976 - Stylo holds some global data alive forever.
+ "leak:style::global_style_data\n"
+
+ //
+ // Many leaks only affect some test suites. The suite annotations are
+ // not checked.
+ //
+
+ // Bug 979928 - WebRTC leaks in different mochitest suites.
+ "leak:NR_reg_init\n"
+ // nr_reg_local_init should be redundant with NR_reg_init, but on
+ // Aurora we get fewer stack frames for some reason.
+ "leak:nr_reg_local_init\n"
+ "leak:r_log_register\n"
+ "leak:nr_reg_set\n"
+
+ // This is a one-time leak in mochitest-bc, so it is probably okay to
+ // ignore.
+ "leak:GlobalPrinters::InitializeGlobalPrinters\n"
+ "leak:nsPSPrinterList::GetPrinterList\n"
+
+ // Bug 1028456 - Various NSPR fd-related leaks in different mochitest
+ // suites.
+ "leak:_PR_Getfd\n"
+
+ // Bug 1028483 - The XML parser sometimes leaks an object. Mostly
+ // happens in toolkit/components/thumbnails.
+ "leak:processInternalEntity\n"
+
+ // Bug 1187421 - NSS does not always free the error stack in different
+ // mochitest suites.
+ "leak:nss_ClearErrorStack\n"
+
+ // Bug 1602689 - leak at mozilla::NotNull, RacyRegisteredThread,
+ // RegisteredThread::RegisteredThread, mozilla::detail::UniqueSelector
+ "leak:RegisteredThread::RegisteredThread\n"
+
+ //
+ // Leaks with system libraries in their stacks. These show up across a
+ // number of tests. Better symbols and disabling fast stackwalking may
+ // help diagnose these.
+ //
+ "leak:libcairo.so\n"
+ "leak:libdl.so\n"
+ "leak:libdricore.so\n"
+ "leak:libdricore9.2.1.so\n"
+ "leak:libGL.so\n"
+ "leak:libglib-2.0.so\n"
+ "leak:libglsl.so\n"
+ "leak:libp11-kit.so\n"
+ "leak:libpixman-1.so\n"
+ "leak:libpulse.so\n"
+ // lubpulsecommon 1.1 is Ubuntu 12.04
+ "leak:libpulsecommon-1.1.so\n"
+ // lubpulsecommon 1.1 is Ubuntu 16.04
+ "leak:libpulsecommon-8.0.so\n"
+ "leak:libresolv.so\n"
+ "leak:libstdc++.so\n"
+ "leak:libXrandr.so\n"
+ "leak:libX11.so\n"
+ "leak:pthread_setspecific_internal\n"
+ "leak:swrast_dri.so\n"
+
+ "leak:js::frontend::BytecodeEmitter:\n"
+ "leak:js::frontend::GeneralParser\n"
+ "leak:js::frontend::Parse\n"
+ "leak:xpc::CIGSHelper\n"
+ "leak:mozJSComponentLoader\n"
+ "leak:mozilla::xpcom::ConstructJSMComponent\n"
+ "leak:XPCWrappedNativeJSOps\n"
+
+ // End of suppressions.
+ ; // Please keep this semicolon.
+}
+
+#endif // _MSC_VER
diff --git a/mozglue/build/BionicGlue.cpp b/mozglue/build/BionicGlue.cpp
new file mode 100644
index 0000000000..8cc21b54e5
--- /dev/null
+++ b/mozglue/build/BionicGlue.cpp
@@ -0,0 +1,37 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include <sys/types.h>
+#include <unistd.h>
+#include <sys/syscall.h>
+
+#define NS_EXPORT __attribute__((visibility("default")))
+
+extern "C" NS_EXPORT int raise(int sig) {
+ // Bug 741272: Bionic incorrectly uses kill(), which signals the
+ // process, and thus could signal another thread (and let this one
+ // return "successfully" from raising a fatal signal).
+ //
+ // Bug 943170: POSIX specifies pthread_kill(pthread_self(), sig) as
+ // equivalent to raise(sig), but Bionic also has a bug with these
+ // functions, where a forked child will kill its parent instead.
+
+ extern pid_t gettid(void);
+ return syscall(__NR_tgkill, getpid(), gettid(), sig);
+}
+
+/* Flash plugin uses symbols that are not present in Android >= 4.4 */
+namespace android {
+namespace VectorImpl {
+NS_EXPORT void reservedVectorImpl1(void) {}
+NS_EXPORT void reservedVectorImpl2(void) {}
+NS_EXPORT void reservedVectorImpl3(void) {}
+NS_EXPORT void reservedVectorImpl4(void) {}
+NS_EXPORT void reservedVectorImpl5(void) {}
+NS_EXPORT void reservedVectorImpl6(void) {}
+NS_EXPORT void reservedVectorImpl7(void) {}
+NS_EXPORT void reservedVectorImpl8(void) {}
+} // namespace VectorImpl
+} // namespace android
diff --git a/mozglue/build/Makefile.in b/mozglue/build/Makefile.in
new file mode 100644
index 0000000000..558ceba066
--- /dev/null
+++ b/mozglue/build/Makefile.in
@@ -0,0 +1,15 @@
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+# For FORCE_SHARED_LIB
+include $(topsrcdir)/config/config.mk
+
+ifeq (WINNT,$(OS_TARGET))
+# Rebuild mozglue.dll if the manifest changes - it's included by mozglue.rc.
+# (this dependency should really be just for mozglue.dll, not other targets)
+# Note the manifest file exists in the tree, so we use the explicit filename
+# here.
+EXTRA_DEPS += $(srcdir)/mozglue.dll.manifest
+endif
diff --git a/mozglue/build/SSE.cpp b/mozglue/build/SSE.cpp
new file mode 100644
index 0000000000..b3c9a57224
--- /dev/null
+++ b/mozglue/build/SSE.cpp
@@ -0,0 +1,196 @@
+/* vim: set shiftwidth=4 tabstop=8 autoindent cindent expandtab: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/* compile-time and runtime tests for whether to use SSE instructions */
+
+#include "SSE.h"
+
+#ifdef HAVE_CPUID_H
+// cpuid.h is available on gcc 4.3 and higher on i386 and x86_64
+# include <cpuid.h>
+#elif defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_AMD64))
+// MSVC 2005 or newer on x86-32 or x86-64
+# include <intrin.h>
+#endif
+
+namespace {
+
+// SSE.h has parallel #ifs which declare MOZILLA_SSE_HAVE_CPUID_DETECTION.
+// We can't declare these functions in the header file, however, because
+// <intrin.h> conflicts with <windows.h> on MSVC 2005, and some files want to
+// include both SSE.h and <windows.h>.
+
+#ifdef HAVE_CPUID_H
+
+enum CPUIDRegister { eax = 0, ebx = 1, ecx = 2, edx = 3 };
+
+static bool has_cpuid_bits(unsigned int level, CPUIDRegister reg,
+ unsigned int bits) {
+ unsigned int regs[4];
+ unsigned int eax, ebx, ecx, edx;
+ unsigned max = __get_cpuid_max(0, NULL);
+ if (level > max) return false;
+ __cpuid_count(level, 0, eax, ebx, ecx, edx);
+ regs[0] = eax;
+ regs[1] = ebx;
+ regs[2] = ecx;
+ regs[3] = edx;
+ return (regs[reg] & bits) == bits;
+}
+
+#elif defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_AMD64))
+
+enum CPUIDRegister { eax = 0, ebx = 1, ecx = 2, edx = 3 };
+
+static bool has_cpuid_bits(unsigned int level, CPUIDRegister reg,
+ unsigned int bits) {
+ // Check that the level in question is supported.
+ int regs[4];
+ __cpuid(regs, level & 0x80000000u);
+ if (unsigned(regs[0]) < level) return false;
+
+ // "The __cpuid intrinsic clears the ECX register before calling the cpuid
+ // instruction."
+ __cpuid(regs, level);
+ return (unsigned(regs[reg]) & bits) == bits;
+}
+
+#elif (defined(__GNUC__) || defined(__SUNPRO_CC)) && \
+ (defined(__i386) || defined(__x86_64__))
+
+enum CPUIDRegister { eax = 0, ebx = 1, ecx = 2, edx = 3 };
+
+# ifdef __i386
+static void moz_cpuid(int CPUInfo[4], int InfoType) {
+ asm("xchg %esi, %ebx\n"
+ "xor %ecx, %ecx\n" // ecx is the sub-leaf (we only ever need 0)
+ "cpuid\n"
+ "movl %eax, (%edi)\n"
+ "movl %ebx, 4(%edi)\n"
+ "movl %ecx, 8(%edi)\n"
+ "movl %edx, 12(%edi)\n"
+ "xchg %esi, %ebx\n"
+ :
+ : "a"(InfoType), // %eax
+ "D"(CPUInfo) // %edi
+ : "%ecx", "%edx", "%esi");
+}
+# else
+static void moz_cpuid(int CPUInfo[4], int InfoType) {
+ asm("xchg %rsi, %rbx\n"
+ "xor %ecx, %ecx\n" // ecx is the sub-leaf (we only ever need 0)
+ "cpuid\n"
+ "movl %eax, (%rdi)\n"
+ "movl %ebx, 4(%rdi)\n"
+ "movl %ecx, 8(%rdi)\n"
+ "movl %edx, 12(%rdi)\n"
+ "xchg %rsi, %rbx\n"
+ :
+ : "a"(InfoType), // %eax
+ "D"(CPUInfo) // %rdi
+ : "%ecx", "%edx", "%rsi");
+}
+# endif
+
+static bool has_cpuid_bits(unsigned int level, CPUIDRegister reg,
+ unsigned int bits) {
+ // Check that the level in question is supported.
+ volatile int regs[4];
+ moz_cpuid((int*)regs, level & 0x80000000u);
+ if (unsigned(regs[0]) < level) return false;
+
+ moz_cpuid((int*)regs, level);
+ return (unsigned(regs[reg]) & bits) == bits;
+}
+
+#endif // end CPUID declarations
+
+} // namespace
+
+namespace mozilla {
+
+namespace sse_private {
+
+#if defined(MOZILLA_SSE_HAVE_CPUID_DETECTION)
+
+# if !defined(MOZILLA_PRESUME_MMX)
+bool mmx_enabled = has_cpuid_bits(1u, edx, (1u << 23));
+# endif
+
+# if !defined(MOZILLA_PRESUME_SSE)
+bool sse_enabled = has_cpuid_bits(1u, edx, (1u << 25));
+# endif
+
+# if !defined(MOZILLA_PRESUME_SSE2)
+bool sse2_enabled = has_cpuid_bits(1u, edx, (1u << 26));
+# endif
+
+# if !defined(MOZILLA_PRESUME_SSE3)
+bool sse3_enabled = has_cpuid_bits(1u, ecx, (1u << 0));
+# endif
+
+# if !defined(MOZILLA_PRESUME_SSSE3)
+bool ssse3_enabled = has_cpuid_bits(1u, ecx, (1u << 9));
+# endif
+
+# if !defined(MOZILLA_PRESUME_SSE4A)
+bool sse4a_enabled = has_cpuid_bits(0x80000001u, ecx, (1u << 6));
+# endif
+
+# if !defined(MOZILLA_PRESUME_SSE4_1)
+bool sse4_1_enabled = has_cpuid_bits(1u, ecx, (1u << 19));
+# endif
+
+# if !defined(MOZILLA_PRESUME_SSE4_2)
+bool sse4_2_enabled = has_cpuid_bits(1u, ecx, (1u << 20));
+# endif
+
+# if !defined(MOZILLA_PRESUME_AVX) || !defined(MOZILLA_PRESUME_AVX2)
+static bool has_avx() {
+# if defined(MOZILLA_PRESUME_AVX)
+ return true;
+# else
+ const unsigned AVX = 1u << 28;
+ const unsigned OSXSAVE = 1u << 27;
+ const unsigned XSAVE = 1u << 26;
+
+ const unsigned XMM_STATE = 1u << 1;
+ const unsigned YMM_STATE = 1u << 2;
+ const unsigned AVX_STATE = XMM_STATE | YMM_STATE;
+
+ return has_cpuid_bits(1u, ecx, AVX | OSXSAVE | XSAVE) &&
+ // ensure the OS supports XSAVE of YMM registers
+ (xgetbv(0) & AVX_STATE) == AVX_STATE;
+# endif // MOZILLA_PRESUME_AVX
+}
+# endif // !MOZILLA_PRESUME_AVX || !MOZILLA_PRESUME_AVX2
+
+# if !defined(MOZILLA_PRESUME_AVX)
+bool avx_enabled = has_avx();
+# endif
+
+# if !defined(MOZILLA_PRESUME_AVX2)
+bool avx2_enabled = has_avx() && has_cpuid_bits(7u, ebx, (1u << 5));
+# endif
+
+# if !defined(MOZILLA_PRESUME_AES)
+bool aes_enabled = has_cpuid_bits(1u, ecx, (1u << 25));
+# endif
+
+#endif
+
+} // namespace sse_private
+
+#ifdef HAVE_CPUID_H
+
+uint64_t xgetbv(uint32_t xcr) {
+ uint32_t eax, edx;
+ __asm__(".byte 0x0f, 0x01, 0xd0" : "=a"(eax), "=d"(edx) : "c"(xcr));
+ return (uint64_t)(edx) << 32 | eax;
+}
+
+#endif
+
+} // namespace mozilla
diff --git a/mozglue/build/SSE.h b/mozglue/build/SSE.h
new file mode 100644
index 0000000000..8a2e668247
--- /dev/null
+++ b/mozglue/build/SSE.h
@@ -0,0 +1,350 @@
+/* vim: set shiftwidth=2 tabstop=8 autoindent cindent expandtab: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/* compile-time and runtime tests for whether to use SSE instructions */
+
+#ifndef mozilla_SSE_h_
+#define mozilla_SSE_h_
+
+// for definition of MFBT_DATA
+#include "mozilla/Types.h"
+
+/**
+ * The public interface of this header consists of a set of macros and
+ * functions for Intel CPU features.
+ *
+ * DETECTING ISA EXTENSIONS
+ * ========================
+ *
+ * This header provides the following functions for determining whether the
+ * current CPU supports a particular instruction set extension:
+ *
+ * mozilla::supports_mmx
+ * mozilla::supports_sse
+ * mozilla::supports_sse2
+ * mozilla::supports_sse3
+ * mozilla::supports_ssse3
+ * mozilla::supports_sse4a
+ * mozilla::supports_sse4_1
+ * mozilla::supports_sse4_2
+ * mozilla::supports_avx
+ * mozilla::supports_avx2
+ * mozilla::supports_aes
+ *
+ * If you're writing code using inline assembly, you should guard it with a
+ * call to one of these functions. For instance:
+ *
+ * if (mozilla::supports_sse2()) {
+ * asm(" ... ");
+ * }
+ * else {
+ * ...
+ * }
+ *
+ * Note that these functions depend on cpuid intrinsics only available in gcc
+ * 4.3 or later and MSVC 8.0 (Visual C++ 2005) or later, so they return false
+ * in older compilers. (This could be fixed by replacing the code with inline
+ * assembly.)
+ *
+ *
+ * USING INTRINSICS
+ * ================
+ *
+ * This header also provides support for coding using CPU intrinsics.
+ *
+ * For each mozilla::supports_abc function, we define a MOZILLA_MAY_SUPPORT_ABC
+ * macro which indicates that the target/compiler combination we're using is
+ * compatible with the ABC extension. For instance, x86_64 with MSVC 2003 is
+ * compatible with SSE2 but not SSE3, since although there exist x86_64 CPUs
+ * with SSE3 support, MSVC 2003 only supports through SSE2.
+ *
+ * Until gcc fixes #pragma target [1] [2] or our x86 builds require SSE2,
+ * you'll need to separate code using intrinsics into a file separate from your
+ * regular code. Here's the recommended pattern:
+ *
+ * #ifdef MOZILLA_MAY_SUPPORT_ABC
+ * namespace mozilla {
+ * namespace ABC {
+ * void foo();
+ * }
+ * }
+ * #endif
+ *
+ * void foo() {
+ * #ifdef MOZILLA_MAY_SUPPORT_ABC
+ * if (mozilla::supports_abc()) {
+ * mozilla::ABC::foo(); // in a separate file
+ * return;
+ * }
+ * #endif
+ *
+ * foo_unvectorized();
+ * }
+ *
+ * You'll need to define mozilla::ABC::foo() in a separate file and add the
+ * -mabc flag when using gcc.
+ *
+ * [1] http://gcc.gnu.org/bugzilla/show_bug.cgi?id=39787 and
+ * [2] http://gcc.gnu.org/bugzilla/show_bug.cgi?id=41201 being fixed.
+ *
+ */
+
+#if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
+
+# ifdef __MMX__
+// It's ok to use MMX instructions based on the -march option (or
+// the default for x86_64 or for Intel Mac).
+# define MOZILLA_PRESUME_MMX 1
+# endif
+# ifdef __SSE__
+// It's ok to use SSE instructions based on the -march option (or
+// the default for x86_64 or for Intel Mac).
+# define MOZILLA_PRESUME_SSE 1
+# endif
+# ifdef __SSE2__
+// It's ok to use SSE2 instructions based on the -march option (or
+// the default for x86_64 or for Intel Mac).
+# define MOZILLA_PRESUME_SSE2 1
+# endif
+# ifdef __SSE3__
+// It's ok to use SSE3 instructions based on the -march option (or the
+// default for Intel Mac).
+# define MOZILLA_PRESUME_SSE3 1
+# endif
+# ifdef __SSSE3__
+// It's ok to use SSSE3 instructions based on the -march option.
+# define MOZILLA_PRESUME_SSSE3 1
+# endif
+# ifdef __SSE4A__
+// It's ok to use SSE4A instructions based on the -march option.
+# define MOZILLA_PRESUME_SSE4A 1
+# endif
+# ifdef __SSE4_1__
+// It's ok to use SSE4.1 instructions based on the -march option.
+# define MOZILLA_PRESUME_SSE4_1 1
+# endif
+# ifdef __SSE4_2__
+// It's ok to use SSE4.2 instructions based on the -march option.
+# define MOZILLA_PRESUME_SSE4_2 1
+# endif
+# ifdef __AVX__
+// It's ok to use AVX instructions based on the -march option.
+# define MOZILLA_PRESUME_AVX 1
+# endif
+# ifdef __AVX2__
+// It's ok to use AVX instructions based on the -march option.
+# define MOZILLA_PRESUME_AVX2 1
+# endif
+# ifdef __AES__
+// It's ok to use AES instructions based on the -march option.
+# define MOZILLA_PRESUME_AES 1
+# endif
+
+# ifdef HAVE_CPUID_H
+# define MOZILLA_SSE_HAVE_CPUID_DETECTION
+# endif
+
+#elif defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_AMD64))
+
+# define MOZILLA_SSE_HAVE_CPUID_DETECTION
+
+# if defined(_M_IX86_FP)
+
+# if _M_IX86_FP >= 1
+// It's ok to use SSE instructions based on the /arch option
+# define MOZILLA_PRESUME_SSE
+# endif
+# if _M_IX86_FP >= 2
+// It's ok to use SSE2 instructions based on the /arch option
+# define MOZILLA_PRESUME_SSE2
+# endif
+
+# elif defined(_M_AMD64)
+// MSVC for AMD64 doesn't support MMX, so don't presume it here.
+
+// SSE is always available on AMD64.
+# define MOZILLA_PRESUME_SSE
+// SSE2 is always available on AMD64.
+# define MOZILLA_PRESUME_SSE2
+# endif
+
+#elif defined(__SUNPRO_CC) && (defined(__i386) || defined(__x86_64__))
+// Sun Studio on x86 or amd64
+
+# define MOZILLA_SSE_HAVE_CPUID_DETECTION
+
+# if defined(__x86_64__)
+// MMX is always available on AMD64.
+# define MOZILLA_PRESUME_MMX
+// SSE is always available on AMD64.
+# define MOZILLA_PRESUME_SSE
+// SSE2 is always available on AMD64.
+# define MOZILLA_PRESUME_SSE2
+# endif
+
+#endif
+
+namespace mozilla {
+
+namespace sse_private {
+#if defined(MOZILLA_SSE_HAVE_CPUID_DETECTION)
+# if !defined(MOZILLA_PRESUME_MMX)
+extern bool MFBT_DATA mmx_enabled;
+# endif
+# if !defined(MOZILLA_PRESUME_SSE)
+extern bool MFBT_DATA sse_enabled;
+# endif
+# if !defined(MOZILLA_PRESUME_SSE2)
+extern bool MFBT_DATA sse2_enabled;
+# endif
+# if !defined(MOZILLA_PRESUME_SSE3)
+extern bool MFBT_DATA sse3_enabled;
+# endif
+# if !defined(MOZILLA_PRESUME_SSSE3)
+extern bool MFBT_DATA ssse3_enabled;
+# endif
+# if !defined(MOZILLA_PRESUME_SSE4A)
+extern bool MFBT_DATA sse4a_enabled;
+# endif
+# if !defined(MOZILLA_PRESUME_SSE4_1)
+extern bool MFBT_DATA sse4_1_enabled;
+# endif
+# if !defined(MOZILLA_PRESUME_SSE4_2)
+extern bool MFBT_DATA sse4_2_enabled;
+# endif
+# if !defined(MOZILLA_PRESUME_AVX)
+extern bool MFBT_DATA avx_enabled;
+# endif
+# if !defined(MOZILLA_PRESUME_AVX2)
+extern bool MFBT_DATA avx2_enabled;
+# endif
+# if !defined(MOZILLA_PRESUME_AES)
+extern bool MFBT_DATA aes_enabled;
+# endif
+
+#endif
+} // namespace sse_private
+
+#ifdef HAVE_CPUID_H
+MOZ_EXPORT uint64_t xgetbv(uint32_t xcr);
+#endif
+
+#if defined(MOZILLA_PRESUME_MMX)
+# define MOZILLA_MAY_SUPPORT_MMX 1
+inline bool supports_mmx() { return true; }
+#elif defined(MOZILLA_SSE_HAVE_CPUID_DETECTION)
+# if !(defined(_MSC_VER) && defined(_M_AMD64))
+// Define MOZILLA_MAY_SUPPORT_MMX only if we're not on MSVC for
+// AMD64, since that compiler doesn't support MMX.
+# define MOZILLA_MAY_SUPPORT_MMX 1
+# endif
+inline bool supports_mmx() { return sse_private::mmx_enabled; }
+#else
+inline bool supports_mmx() { return false; }
+#endif
+
+#if defined(MOZILLA_PRESUME_SSE)
+# define MOZILLA_MAY_SUPPORT_SSE 1
+inline bool supports_sse() { return true; }
+#elif defined(MOZILLA_SSE_HAVE_CPUID_DETECTION)
+# define MOZILLA_MAY_SUPPORT_SSE 1
+inline bool supports_sse() { return sse_private::sse_enabled; }
+#else
+inline bool supports_sse() { return false; }
+#endif
+
+#if defined(MOZILLA_PRESUME_SSE2)
+# define MOZILLA_MAY_SUPPORT_SSE2 1
+inline bool supports_sse2() { return true; }
+#elif defined(MOZILLA_SSE_HAVE_CPUID_DETECTION)
+# define MOZILLA_MAY_SUPPORT_SSE2 1
+inline bool supports_sse2() { return sse_private::sse2_enabled; }
+#else
+inline bool supports_sse2() { return false; }
+#endif
+
+#if defined(MOZILLA_PRESUME_SSE3)
+# define MOZILLA_MAY_SUPPORT_SSE3 1
+inline bool supports_sse3() { return true; }
+#elif defined(MOZILLA_SSE_HAVE_CPUID_DETECTION)
+# define MOZILLA_MAY_SUPPORT_SSE3 1
+inline bool supports_sse3() { return sse_private::sse3_enabled; }
+#else
+inline bool supports_sse3() { return false; }
+#endif
+
+#if defined(MOZILLA_PRESUME_SSSE3)
+# define MOZILLA_MAY_SUPPORT_SSSE3 1
+inline bool supports_ssse3() { return true; }
+#elif defined(MOZILLA_SSE_HAVE_CPUID_DETECTION)
+# define MOZILLA_MAY_SUPPORT_SSSE3 1
+inline bool supports_ssse3() { return sse_private::ssse3_enabled; }
+#else
+inline bool supports_ssse3() { return false; }
+#endif
+
+#if defined(MOZILLA_PRESUME_SSE4A)
+# define MOZILLA_MAY_SUPPORT_SSE4A 1
+inline bool supports_sse4a() { return true; }
+#elif defined(MOZILLA_SSE_HAVE_CPUID_DETECTION)
+# define MOZILLA_MAY_SUPPORT_SSE4A 1
+inline bool supports_sse4a() { return sse_private::sse4a_enabled; }
+#else
+inline bool supports_sse4a() { return false; }
+#endif
+
+#if defined(MOZILLA_PRESUME_SSE4_1)
+# define MOZILLA_MAY_SUPPORT_SSE4_1 1
+inline bool supports_sse4_1() { return true; }
+#elif defined(MOZILLA_SSE_HAVE_CPUID_DETECTION)
+# define MOZILLA_MAY_SUPPORT_SSE4_1 1
+inline bool supports_sse4_1() { return sse_private::sse4_1_enabled; }
+#else
+inline bool supports_sse4_1() { return false; }
+#endif
+
+#if defined(MOZILLA_PRESUME_SSE4_2)
+# define MOZILLA_MAY_SUPPORT_SSE4_2 1
+inline bool supports_sse4_2() { return true; }
+#elif defined(MOZILLA_SSE_HAVE_CPUID_DETECTION)
+# define MOZILLA_MAY_SUPPORT_SSE4_2 1
+inline bool supports_sse4_2() { return sse_private::sse4_2_enabled; }
+#else
+inline bool supports_sse4_2() { return false; }
+#endif
+
+#if defined(MOZILLA_PRESUME_AVX)
+# define MOZILLA_MAY_SUPPORT_AVX 1
+inline bool supports_avx() { return true; }
+#elif defined(MOZILLA_SSE_HAVE_CPUID_DETECTION)
+# define MOZILLA_MAY_SUPPORT_AVX 1
+inline bool supports_avx() { return sse_private::avx_enabled; }
+#else
+inline bool supports_avx() { return false; }
+#endif
+
+#if defined(MOZILLA_PRESUME_AVX2)
+# define MOZILLA_MAY_SUPPORT_AVX2 1
+inline bool supports_avx2() { return true; }
+#elif defined(MOZILLA_SSE_HAVE_CPUID_DETECTION)
+# define MOZILLA_MAY_SUPPORT_AVX2 1
+inline bool supports_avx2() { return sse_private::avx2_enabled; }
+#else
+inline bool supports_avx2() { return false; }
+#endif
+
+#if defined(MOZILLA_PRESUME_AES)
+# define MOZILLA_MAY_SUPPORT_AES 1
+inline bool supports_aes() { return true; }
+#elif defined(MOZILLA_SSE_HAVE_CPUID_DETECTION)
+# define MOZILLA_MAY_SUPPORT_AES 1
+inline bool supports_aes() { return sse_private::aes_enabled; }
+#else
+inline bool supports_aes() { return false; }
+#endif
+
+} // namespace mozilla
+
+#endif /* !defined(mozilla_SSE_h_) */
diff --git a/mozglue/build/TsanOptions.cpp b/mozglue/build/TsanOptions.cpp
new file mode 100644
index 0000000000..160cfc12d1
--- /dev/null
+++ b/mozglue/build/TsanOptions.cpp
@@ -0,0 +1,305 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "mozilla/Attributes.h"
+#include "mozilla/TsanOptions.h"
+
+#ifndef _MSC_VER // Not supported by clang-cl yet
+
+//
+// When running with ThreadSanitizer, we sometimes need to suppress existing
+// races. However, in any case, it should be either because
+//
+// 1) a bug is on file. In this case, the bug number should always be
+// included with the suppression.
+//
+// or 2) this is an intentional race. Please be very careful with judging
+// races as intentional and benign. Races in C++ are undefined behavior
+// and compilers increasingly rely on exploiting this for optimizations.
+// Hence, many seemingly benign races cause harmful or unexpected
+// side-effects.
+//
+// See also:
+// https://software.intel.com/en-us/blogs/2013/01/06/benign-data-races-what-could-possibly-go-wrong
+//
+//
+// Also, when adding any race suppressions here, make sure to always add
+// a signature for each of the two race stacks. Sometimes, TSan fails to
+// symbolize one of the two traces and this can cause suppressed races to
+// show up intermittently.
+//
+// clang-format off
+extern "C" const char* __tsan_default_suppressions() {
+ return "# Add your suppressions below\n"
+
+ // External uninstrumented libraries
+ MOZ_TSAN_DEFAULT_EXTLIB_SUPPRESSIONS
+
+ // TSan internals
+ "race:__tsan::ProcessPendingSignals\n"
+ "race:__tsan::CallUserSignalHandler\n"
+
+
+
+
+
+ // Uninstrumented code causing false positives
+
+ // These libraries are uninstrumented and cause mutex false positives.
+ // However, they can be unloaded by GTK early which we cannot avoid.
+ "mutex:libGL.so\n"
+ "mutex:libGLdispatch\n"
+ "mutex:libGLX\n"
+ // Bug 1637707 - permanent
+ "mutex:libEGL_mesa.so\n"
+ // ~GLContextGLX unlocks a libGL mutex.
+ "mutex:GLContextGLX::~GLContextGLX\n"
+ // Bug 1651446 - permanent (ffmpeg)
+ "race:libavcodec.so*\n"
+ "race:libavutil.so*\n"
+ // For some reason, the suppressions on libpulse.so
+ // through `called_from_lib` only work partially.
+ "race:libpulse.so\n"
+ "race:pa_context_suspend_source_by_index\n"
+ "race:pa_context_unref\n"
+ "race:pa_format_info_set_prop_string_array\n"
+ "race:pa_stream_get_index\n"
+ "race:pa_stream_update_timing_info\n"
+ // This is a callback from libglib-2 that is apparently
+ // not fully suppressed through `called_from_lib`.
+ "race:g_main_context_dispatch\n"
+ // This is likely a false positive involving a mutex from GTK.
+ // See also bug 1642653 - permanent.
+ "mutex:GetMaiAtkType\n"
+
+
+
+
+
+ // Deadlock reports on single-threaded runtime.
+ //
+ // This is a known false positive from TSan where it reports
+ // a potential deadlock even though all mutexes are only
+ // taken by a single thread. For applications/tasks where we
+ // are absolutely sure that no second thread will be involved
+ // we should suppress these issues.
+ //
+ // See also https://github.com/google/sanitizers/issues/488
+
+ // Bug 1614605 - permanent
+ "deadlock:SanctionsTestServer\n"
+ "deadlock:OCSPStaplingServer\n"
+ // Bug 1643087 - permanent
+ "deadlock:BadCertAndPinningServer\n"
+ // Bug 1606804 - permanent
+ "deadlock:cert_storage::SecurityState::open_db\n"
+ "deadlock:cert_storage::SecurityState::add_certs\n"
+ // Bug 1651770 - permanent
+ "deadlock:mozilla::camera::LockAndDispatch\n"
+ // Bug 1606804 - permanent
+ "deadlock:third_party/rust/rkv/src/env.rs\n"
+ // Bug 1680655 - permanent
+ "deadlock:EncryptedClientHelloServer\n"
+ // Bug 1682861 - permanent
+ "deadlock:nsDOMWindowUtils::CompareCanvases\n"
+
+
+
+
+
+ // Benign races in third-party code (should be fixed upstream)
+
+ // No Bug - permanent
+ // No Upstream Bug Filed!
+ //
+ // SIMD Initialization in libjpeg, potentially runs
+ // initialization twice, but otherwise benign. Init
+ // routine itself is in native assembler.
+ "race:init_simd\n"
+ "race:simd_support\n"
+ "race:jsimd_can_ycc_rgb\n"
+ // Bug 1615228 - permanent
+ // No Upstream Bug Filed!
+ //
+ // Likely benign race in ipc/chromium/ where we set
+ // `message_loop_` to `NULL` on two threads when stopping
+ // a thread at the same time it is already finishing.
+ "race:base::Thread::Stop\n"
+ // Bug 1615569 - permanent
+ // No Upstream Bug Filed!
+ //
+ // NSS is using freebl from two different threads but freebl isn't
+ // that threadsafe.
+ "race:mp_exptmod.max_window_bits\n"
+ // Bug 1652499 - permanent
+ // No Upstream Bug Filed!
+ //
+ // Likely benign race in webrtc.org code - race while updating the
+ // minimum log severity.
+ "race:Loggable\n"
+ "race:UpdateMinLogSeverity\n"
+ // Bug 1652174 - permanent
+ // Upstream Bug: https://github.com/libevent/libevent/issues/777
+ //
+ // Likely benign write-write race in libevent to set a sticky boolean
+ // flag to true.
+ "race:event_debug_mode_too_late\n"
+ // Bug 1648606 - permanent
+ // No Upstream Bug Filed!
+ //
+ // Race on some flag being checking in libusrsctp.
+ "race:sctp_close\n"
+ "race:sctp_iterator_work\n"
+ // Bug 1653618 - permanent
+ // Upstream Bug: https://github.com/sctplab/usrsctp/issues/507
+ //
+ // Might lead to scheduled timers in libusrsctp getting dropped?
+ "race:sctp_handle_tick\n"
+ "race:sctp_handle_sack\n"
+ // Bug 1648604 - permanent
+ // Upstream Bug: https://github.com/sctplab/usrsctp/issues/482
+ //
+ // Likely benign race in libusrsctp allocator during a free.
+ "race:system_base_info\n"
+ // Bug 1153409 - permanent
+ // No Upstream Bug Filed!
+ //
+ // Probably benign - sqlite has a few optimizations where it does
+ // racy reads and then does properly synchornized integrity checks
+ // afterwards. Some concern of compiler optimizations messing this
+ // up due to "volatile" being too weak for this.
+ "race:third_party/sqlite3/*\n"
+ "deadlock:third_party/sqlite3/*\n"
+ // Bug 1674770 - permanent
+ // Upstream Bug: https://github.com/Amanieu/parking_lot/issues/257
+ //
+ // parking_lot using incorrect atomic orderings in RwLock, upstream
+ // fix already up for review.
+ "race:StrongRuleNode::ensure_child\n"
+ // No Bug - permanent
+ // Upstream Bug: https://github.com/rayon-rs/rayon/issues/812
+ //
+ // Probably a false-positive from crossbeam's deque not being
+ // understood by tsan.
+ "race:crossbeam_deque::Worker*::resize\n"
+ "race:crossbeam_deque::Worker*::push\n"
+ "race:crossbeam_deque::Buffer*::write\n"
+ "race:crossbeam_deque::Buffer*::read\n"
+
+
+
+
+
+ // The rest of these suppressions are miscellaneous issues in gecko
+ // that should be investigated and ideally fixed.
+
+ // Bug 1601600
+ "race:SkARGB32_Blitter\n"
+ "race:SkARGB32_Shader_Blitter\n"
+ "race:SkARGB32_Opaque_Blitter\n"
+ "race:SkRasterPipelineBlitter\n"
+ "race:Clamp_S32_D32_nofilter_trans_shaderproc\n"
+ "race:SkSpriteBlitter_Memcpy\n"
+
+ // Bug 1606651
+ "race:nsPluginTag::nsPluginTag\n"
+ "race:nsFakePluginTag\n"
+
+ // Bug 1606800
+ "race:CallInitFunc\n"
+
+ // Bug 1606803
+ "race:ipv6_is_present\n"
+
+ // Bug 1606864
+ "race:nsSocketTransport::Close\n"
+ "race:nsSocketTransport::OnSocketDetached\n"
+ "race:nsSocketTransport::OnMsgInputClosed\n"
+ "race:nsSocketTransport::OpenOutputStream\n"
+
+ // Bug 1615017
+ "race:CacheFileMetadata::SetHash\n"
+ "race:CacheFileMetadata::OnDataWritten\n"
+
+ // Bug 1615123
+ "race:_dl_deallocate_tls\n"
+ "race:__libc_memalign\n"
+
+ // Bug 1664535
+ "race:setNeedsIncrementalBarrier\n"
+ "race:needsIncrementalBarrier\n"
+
+ // Bug 1664803
+ "race:Sampler::sSigHandlerCoordinator\n"
+
+ // Bug 1656068
+ "race:WebRtcAec_Create\n"
+
+ // No Bug - Logging bug in Mochitests
+ "race:mochitest/ssltunnel/ssltunnel.cpp\n"
+
+ // This thread does not seem to be stopped/joined.
+ // ImageBridgeChild should be turned back into a background
+ // task queue in bug 1647628, in which case these suppressions
+ // can be removed.
+ "race:mozilla::layers::ImageBridgeChild::ShutDown\n"
+
+ // Bug 1652530
+ "mutex:XErrorTrap\n"
+
+ // Bug 1671572
+ "race:IdentifyTextureHost\n"
+ "race:GetCompositorBackendType\n"
+ "race:SupportsTextureDirectMapping\n"
+
+ // Bug 1671601
+ "race:CamerasParent::ActorDestroy\n"
+ "race:CamerasParent::DispatchToVideoCaptureThread\n"
+
+ // Bug 1623541
+ "race:VRShMem::PullSystemState\n"
+ "race:VRShMem::PushSystemState\n"
+ "race:VRShMem::PullBrowserState\n"
+ "race:VRShMem::PushBrowserState\n"
+
+ // Bug 1674776
+ "race:DocumentTimeline::GetCurrentTimeAsDuration\n"
+
+ // Bug 1674835
+ "race:nsHttpTransaction::ReadSegments\n"
+ "race:nsHttpTransaction::SecurityInfo\n"
+
+ // Bug 1680285
+ "race:style::traversal::note_children\n"
+ "race:style::matching::MatchMethods::apply_selector_flags\n"
+
+ // Bug 1607588
+ "race:nssToken_Destroy\n"
+ "race:nssSlot_GetToken\n"
+
+ // Bug 1683439
+ "race:AudioCallbackDriver::MixerCallback\n"
+ "race:AudioCallbackDriver::Init\n"
+
+ // Bug 1683417
+ "race:DataChannelConnection::SetSignals\n"
+ "race:DataChannelConnection::SetReady\n"
+
+ // Bug 1683404
+ "race:nsTimerImpl::Shutdown\n"
+ "race:nsTimerImpl::CancelImpl\n"
+
+ // Bug 1682951
+ "race:storage::Connection::Release\n"
+
+ // Bug 1683357
+ "race:image::ImageSurfaceCache::SuggestedSizeInternal\n"
+ "race:image::RasterImage::SetMetadata\n"
+
+ // End of suppressions.
+ ; // Please keep this semicolon.
+}
+// clang-format on
+#endif // _MSC_VER
diff --git a/mozglue/build/UbsanOptions.cpp b/mozglue/build/UbsanOptions.cpp
new file mode 100644
index 0000000000..547baa790c
--- /dev/null
+++ b/mozglue/build/UbsanOptions.cpp
@@ -0,0 +1,16 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "mozilla/Attributes.h"
+
+#ifndef _MSC_VER // Not supported by clang-cl yet
+
+extern "C" const char* __ubsan_default_options() {
+ return "print_stacktrace=1";
+}
+
+extern "C" const char* __ubsan_default_suppressions() { return ""; }
+
+#endif
diff --git a/mozglue/build/arm-eabi-filter b/mozglue/build/arm-eabi-filter
new file mode 100644
index 0000000000..401454ee88
--- /dev/null
+++ b/mozglue/build/arm-eabi-filter
@@ -0,0 +1,4 @@
+{
+ local:
+ __aeabi*;
+};
diff --git a/mozglue/build/arm.cpp b/mozglue/build/arm.cpp
new file mode 100644
index 0000000000..a74a41f6c0
--- /dev/null
+++ b/mozglue/build/arm.cpp
@@ -0,0 +1,131 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/* compile-time and runtime tests for whether to use various ARM extensions */
+
+#include "arm.h"
+
+#if defined(MOZILLA_ARM_HAVE_CPUID_DETECTION)
+
+// arm.h has parallel #ifs which declare MOZILLA_ARM_HAVE_CPUID_DETECTION.
+// We don't check it here so that we get compile errors if it's defined, but
+// we don't compile one of these detection methods. The detection code here is
+// based on the CPU detection in libtheora.
+
+# if defined(__linux__) || defined(ANDROID)
+# include <stdio.h>
+# include <stdlib.h>
+# include <string.h>
+
+enum {
+ MOZILLA_HAS_EDSP_FLAG = 1,
+ MOZILLA_HAS_ARMV6_FLAG = 2,
+ MOZILLA_HAS_ARMV7_FLAG = 4,
+ MOZILLA_HAS_NEON_FLAG = 8
+};
+
+static unsigned get_arm_cpu_flags(void) {
+ unsigned flags;
+ FILE* fin;
+ bool armv6_processor = false;
+ flags = 0;
+ /*Reading /proc/self/auxv would be easier, but that doesn't work reliably on
+ Android. This also means that detection will fail in Scratchbox, which is
+ desirable, as NEON does not work in the qemu shipped with the Maemo 5 SDK.
+ I don't know if /proc/self/auxv would do any better in that case, anyway,
+ or if it would return random flags from the host CPU.*/
+ fin = fopen("/proc/cpuinfo", "r");
+ if (fin != nullptr) {
+ /*512 should be enough for anybody (it's even enough for all the flags that
+ x86 has accumulated... so far).*/
+ char buf[512];
+ while (fgets(buf, 511, fin) != nullptr) {
+ if (memcmp(buf, "Features", 8) == 0) {
+ char* p;
+ p = strstr(buf, " edsp");
+ if (p != nullptr && (p[5] == ' ' || p[5] == '\n'))
+ flags |= MOZILLA_HAS_EDSP_FLAG;
+ p = strstr(buf, " neon");
+ if (p != nullptr && (p[5] == ' ' || p[5] == '\n'))
+ flags |= MOZILLA_HAS_NEON_FLAG;
+ }
+ if (memcmp(buf, "CPU architecture:", 17) == 0) {
+ int version;
+ version = atoi(buf + 17);
+ if (version >= 6) flags |= MOZILLA_HAS_ARMV6_FLAG;
+ if (version >= 7) flags |= MOZILLA_HAS_ARMV7_FLAG;
+ }
+ /* media/webrtc/trunk/src/system_wrappers/source/cpu_features_arm.c
+ * Unfortunately, it seems that certain ARMv6-based CPUs
+ * report an incorrect architecture number of 7!
+ *
+ * We try to correct this by looking at the 'elf_format'
+ * field reported by the 'Processor' field, which is of the
+ * form of "(v7l)" for an ARMv7-based CPU, and "(v6l)" for
+ * an ARMv6-one.
+ */
+ if (memcmp(buf, "Processor\t:", 11) == 0) {
+ if (strstr(buf, "(v6l)") != 0) {
+ armv6_processor = true;
+ }
+ }
+ }
+ fclose(fin);
+ }
+ if (armv6_processor) {
+ // ARMv6 pretending to be ARMv7? clear flag
+ if (flags & MOZILLA_HAS_ARMV7_FLAG) {
+ flags &= ~MOZILLA_HAS_ARMV7_FLAG;
+ }
+ }
+ return flags;
+}
+
+// Cache a local copy so we only have to read /proc/cpuinfo once.
+static unsigned arm_cpu_flags = get_arm_cpu_flags();
+
+# if !defined(MOZILLA_PRESUME_EDSP)
+static bool check_edsp(void) {
+ return (arm_cpu_flags & MOZILLA_HAS_EDSP_FLAG) != 0;
+}
+# endif
+
+# if !defined(MOZILLA_PRESUME_ARMV6)
+static bool check_armv6(void) {
+ return (arm_cpu_flags & MOZILLA_HAS_ARMV6_FLAG) != 0;
+}
+# endif
+
+# if !defined(MOZILLA_PRESUME_ARMV7)
+static bool check_armv7(void) {
+ return (arm_cpu_flags & MOZILLA_HAS_ARMV7_FLAG) != 0;
+}
+# endif
+
+# if !defined(MOZILLA_PRESUME_NEON)
+static bool check_neon(void) {
+ return (arm_cpu_flags & MOZILLA_HAS_NEON_FLAG) != 0;
+}
+# endif
+
+# endif // defined(__linux__) || defined(ANDROID)
+
+namespace mozilla {
+namespace arm_private {
+# if !defined(MOZILLA_PRESUME_EDSP)
+bool edsp_enabled = check_edsp();
+# endif
+# if !defined(MOZILLA_PRESUME_ARMV6)
+bool armv6_enabled = check_armv6();
+# endif
+# if !defined(MOZILLA_PRESUME_ARMV7)
+bool armv7_enabled = check_armv7();
+# endif
+# if !defined(MOZILLA_PRESUME_NEON)
+bool neon_enabled = check_neon();
+# endif
+} // namespace arm_private
+} // namespace mozilla
+
+#endif // MOZILLA_ARM_HAVE_CPUID_DETECTION
diff --git a/mozglue/build/arm.h b/mozglue/build/arm.h
new file mode 100644
index 0000000000..8600329931
--- /dev/null
+++ b/mozglue/build/arm.h
@@ -0,0 +1,145 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/* compile-time and runtime tests for whether to use SSE instructions */
+
+#ifndef mozilla_arm_h_
+#define mozilla_arm_h_
+
+// for definition of MFBT_DATA
+#include "mozilla/Types.h"
+
+/* This is patterned after SSE.h, but provides ARMv5E, ARMv6, and NEON
+ detection. For reasons similar to the SSE code, code using NEON (even just
+ in inline asm) needs to be in a separate compilation unit from the regular
+ code, because it requires an ".fpu neon" directive which can't be undone.
+ ARMv5E and ARMv6 code may also require an .arch directive, since by default
+ the assembler refuses to generate code for opcodes outside of its current
+ .arch setting.
+
+ TODO: Add Thumb, Thumb2, VFP, iwMMX, etc. detection, if we need it. */
+
+#if defined(__GNUC__) && defined(__arm__)
+
+# define MOZILLA_ARM_ARCH 3
+
+# if defined(__ARM_ARCH_4__) || defined(__ARM_ARCH_4T__) || \
+ defined(_ARM_ARCH_4)
+# undef MOZILLA_ARM_ARCH
+# define MOZILLA_ARM_ARCH 4
+# endif
+
+# if defined(__ARM_ARCH_5__) || defined(__ARM_ARCH_5T__) || \
+ defined(__ARM_ARCH_5E__) || defined(__ARM_ARCH_5TE__) || \
+ defined(__ARM_ARCH_5TEJ__) || defined(_ARM_ARCH_5)
+# undef MOZILLA_ARM_ARCH
+# define MOZILLA_ARM_ARCH 5
+# endif
+
+# if defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || \
+ defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) || \
+ defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__) || \
+ defined(__ARM_ARCH_6M__) || defined(_ARM_ARCH_6)
+# undef MOZILLA_ARM_ARCH
+# define MOZILLA_ARM_ARCH 6
+# endif
+
+# if defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || \
+ defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) || \
+ defined(__ARM_ARCH_7EM__) || defined(_ARM_ARCH_7)
+# undef MOZILLA_ARM_ARCH
+# define MOZILLA_ARM_ARCH 7
+# endif
+
+# ifdef __GNUC__
+# define MOZILLA_MAY_SUPPORT_EDSP 1
+
+# if defined(HAVE_ARM_SIMD)
+# define MOZILLA_MAY_SUPPORT_ARMV6 1
+# endif
+
+# if defined(HAVE_ARM_NEON)
+# define MOZILLA_MAY_SUPPORT_NEON 1
+# endif
+
+# if defined(HAVE_ARM_SIMD)
+# define MOZILLA_MAY_SUPPORT_ARMV7 1
+# endif
+# endif
+
+// Currently we only have CPU detection for Linux via /proc/cpuinfo
+# if defined(__linux__) || defined(ANDROID)
+# define MOZILLA_ARM_HAVE_CPUID_DETECTION 1
+# endif
+
+#endif
+
+// When using -mfpu=neon on arm gcc, or using default on aarch64,
+// the compiler generates neon instructions.
+#if defined(__ARM_NEON)
+# define MOZILLA_PRESUME_NEON 1
+#endif
+
+namespace mozilla {
+
+namespace arm_private {
+#if defined(MOZILLA_ARM_HAVE_CPUID_DETECTION)
+# if !defined(MOZILLA_PRESUME_EDSP)
+extern bool MFBT_DATA edsp_enabled;
+# endif
+# if !defined(MOZILLA_PRESUME_ARMV6)
+extern bool MFBT_DATA armv6_enabled;
+# endif
+# if !defined(MOZILLA_PRESUME_ARMV7)
+extern bool MFBT_DATA armv7_enabled;
+# endif
+# if !defined(MOZILLA_PRESUME_NEON)
+extern bool MFBT_DATA neon_enabled;
+# endif
+#endif
+} // namespace arm_private
+
+#if defined(MOZILLA_PRESUME_EDSP)
+# define MOZILLA_MAY_SUPPORT_EDSP 1
+inline bool supports_edsp() { return true; }
+#elif defined(MOZILLA_MAY_SUPPORT_EDSP) && \
+ defined(MOZILLA_ARM_HAVE_CPUID_DETECTION)
+inline bool supports_edsp() { return arm_private::edsp_enabled; }
+#else
+inline bool supports_edsp() { return false; }
+#endif
+
+#if defined(MOZILLA_PRESUME_ARMV6)
+# define MOZILLA_MAY_SUPPORT_ARMV6 1
+inline bool supports_armv6() { return true; }
+#elif defined(MOZILLA_MAY_SUPPORT_ARMV6) && \
+ defined(MOZILLA_ARM_HAVE_CPUID_DETECTION)
+inline bool supports_armv6() { return arm_private::armv6_enabled; }
+#else
+inline bool supports_armv6() { return false; }
+#endif
+
+#if defined(MOZILLA_PRESUME_ARMV7)
+# define MOZILLA_MAY_SUPPORT_ARMV7 1
+inline bool supports_armv7() { return true; }
+#elif defined(MOZILLA_MAY_SUPPORT_ARMV7) && \
+ defined(MOZILLA_ARM_HAVE_CPUID_DETECTION)
+inline bool supports_armv7() { return arm_private::armv7_enabled; }
+#else
+inline bool supports_armv7() { return false; }
+#endif
+
+#if defined(MOZILLA_PRESUME_NEON)
+# define MOZILLA_MAY_SUPPORT_NEON 1
+inline bool supports_neon() { return true; }
+#elif defined(MOZILLA_MAY_SUPPORT_NEON) && \
+ defined(MOZILLA_ARM_HAVE_CPUID_DETECTION)
+inline bool supports_neon() { return arm_private::neon_enabled; }
+#else
+inline bool supports_neon() { return false; }
+#endif
+
+} // namespace mozilla
+
+#endif /* !defined(mozilla_arm_h_) */
diff --git a/mozglue/build/dummy.cpp b/mozglue/build/dummy.cpp
new file mode 100644
index 0000000000..c6b1ccd808
--- /dev/null
+++ b/mozglue/build/dummy.cpp
@@ -0,0 +1,5 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+void _dummy(void) {}
diff --git a/mozglue/build/mips.cpp b/mozglue/build/mips.cpp
new file mode 100644
index 0000000000..7166080f5e
--- /dev/null
+++ b/mozglue/build/mips.cpp
@@ -0,0 +1,42 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/* compile-time and runtime tests for whether to use MIPS-specific extensions */
+
+#include "mips.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+enum {
+ MIPS_FLAG_LOONGSON3 = 1,
+};
+
+static unsigned get_mips_cpu_flags(void) {
+ unsigned flags = 0;
+ FILE* fin;
+
+ fin = fopen("/proc/cpuinfo", "r");
+ if (fin != nullptr) {
+ char buf[1024];
+ memset(buf, 0, sizeof(buf));
+ fread(buf, sizeof(char), sizeof(buf) - 1, fin);
+ fclose(fin);
+ if (strstr(buf, "Loongson-3")) flags |= MIPS_FLAG_LOONGSON3;
+ }
+ return flags;
+}
+
+static bool check_loongson3(void) {
+ // Cache a local copy so we only have to read /proc/cpuinfo once.
+ static unsigned mips_cpu_flags = get_mips_cpu_flags();
+ return (mips_cpu_flags & MIPS_FLAG_LOONGSON3) != 0;
+}
+
+namespace mozilla {
+namespace mips_private {
+bool isLoongson3 = check_loongson3();
+} // namespace mips_private
+} // namespace mozilla
diff --git a/mozglue/build/mips.h b/mozglue/build/mips.h
new file mode 100644
index 0000000000..a7c3ed5416
--- /dev/null
+++ b/mozglue/build/mips.h
@@ -0,0 +1,29 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/* compile-time and runtime tests for whether to use MIPS-specific extensions */
+
+#ifndef mozilla_mips_h_
+#define mozilla_mips_h_
+
+// for definition of MFBT_DATA
+#include "mozilla/Types.h"
+
+namespace mozilla {
+
+namespace mips_private {
+extern bool MFBT_DATA isLoongson3;
+} // namespace mips_private
+
+inline bool supports_mmi() {
+#ifdef __mips__
+ return mips_private::isLoongson3;
+#else
+ return false;
+#endif
+}
+
+} // namespace mozilla
+
+#endif /* !defined(mozilla_mips_h_) */
diff --git a/mozglue/build/moz.build b/mozglue/build/moz.build
new file mode 100644
index 0000000000..11c2e41e16
--- /dev/null
+++ b/mozglue/build/moz.build
@@ -0,0 +1,120 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+# Build mozglue as a shared lib on Windows, OSX and Android. But not for
+# embedders!
+# If this is ever changed, update MOZ_SHARED_MOZGLUE in browser/installer/Makefile.in
+if CONFIG["JS_STANDALONE"] and not CONFIG["MOZ_MEMORY"]:
+ Library("mozglue")
+elif CONFIG["OS_TARGET"] in ("WINNT", "Darwin", "Android"):
+ SharedLibrary("mozglue")
+else:
+ Library("mozglue")
+
+if CONFIG["OS_TARGET"] == "Android":
+ LDFLAGS += ["-Wl,--version-script,%s/mozglue.ver" % SRCDIR]
+ SOURCES += [
+ "BionicGlue.cpp",
+ ]
+
+if CONFIG["MOZ_ASAN"]:
+ SOURCES += [
+ "AsanOptions.cpp",
+ ]
+
+if CONFIG["MOZ_UBSAN"]:
+ SOURCES += [
+ "UbsanOptions.cpp",
+ ]
+
+if CONFIG["MOZ_TSAN"]:
+ SOURCES += [
+ "TsanOptions.cpp",
+ ]
+
+if CONFIG["OS_TARGET"] == "WINNT":
+ if CONFIG["MOZ_MEMORY"]:
+ DEFFILE = "mozglue.def"
+ # We'll break the DLL blocklist if we immediately load user32.dll.
+ # For the same reason, we delayload winmm.dll which statically links
+ # user32.dll.
+ DELAYLOAD_DLLS += [
+ "user32.dll",
+ "winmm.dll",
+ ]
+
+if CONFIG["MOZ_WIDGET_TOOLKIT"]:
+
+ if CONFIG["MOZ_MEMORY"] and FORCE_SHARED_LIB:
+ pass
+ # TODO: SHARED_LIBRARY_LIBS go here
+ else:
+ # Temporary, until bug 662814 lands
+ NoVisibilityFlags()
+ SOURCES += [
+ "dummy.cpp",
+ ]
+
+ if CONFIG["OS_TARGET"] == "WINNT":
+ LOCAL_INCLUDES += [
+ "/memory/build",
+ ]
+
+ EXPORTS.mozilla += [
+ "arm.h",
+ "mips.h",
+ "ppc.h",
+ "SSE.h",
+ ]
+
+ if CONFIG["CPU_ARCH"].startswith("x86"):
+ SOURCES += [
+ "SSE.cpp",
+ ]
+
+ if CONFIG["CPU_ARCH"] == "arm":
+ SOURCES += [
+ "arm.cpp",
+ ]
+
+ if CONFIG["CPU_ARCH"].startswith("mips"):
+ SOURCES += [
+ "mips.cpp",
+ ]
+
+ if CONFIG["CPU_ARCH"].startswith("ppc"):
+ SOURCES += [
+ "ppc.cpp",
+ ]
+
+ if CONFIG["MOZ_LINKER"]:
+ USE_LIBS += [
+ "zlib",
+ ]
+
+USE_LIBS += [
+ "mfbt",
+]
+
+LIBRARY_DEFINES["IMPL_MFBT"] = True
+LIBRARY_DEFINES["MOZ_HAS_MOZGLUE"] = True
+
+if CONFIG["OS_TARGET"] == "Darwin":
+ # On OSX 10.10.3, a dead lock happens in some cases involving dynamic
+ # symbol resolution for symbols that jemalloc itself uses. While it
+ # might be possible to find a way to avoid all such symbol resolutions,
+ # it's currently not possible because at the very least there's a call
+ # to pthread_self from tsd_init_check_recursion, which is necessary
+ # because somehow clang doesn't want to accept the __thread keyword
+ # for TLS.
+ LDFLAGS += ["-Wl,-bind_at_load"]
+
+if CONFIG["MOZ_LINKER"] and CONFIG["CPU_ARCH"] == "arm":
+ LDFLAGS += ["-Wl,-version-script,%s/arm-eabi-filter" % SRCDIR]
+
+DIST_INSTALL = True
+
+include("replace_malloc.mozbuild")
diff --git a/mozglue/build/mozglue.def b/mozglue/build/mozglue.def
new file mode 100644
index 0000000000..188037b9f1
--- /dev/null
+++ b/mozglue/build/mozglue.def
@@ -0,0 +1,22 @@
+; This Source Code Form is subject to the terms of the Mozilla Public
+; License, v. 2.0. If a copy of the MPL was not distributed with this
+; file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+LIBRARY mozglue.dll
+
+EXPORTS
+ ; symbols that are actually useful
+ malloc=je_malloc
+ calloc=je_calloc
+ realloc=je_realloc
+ free=je_free
+ posix_memalign=je_posix_memalign
+ malloc_usable_size=je_malloc_usable_size
+ malloc_good_size=je_malloc_good_size
+ _aligned_free=je_free
+ _aligned_malloc=wrap__aligned_malloc
+ strndup=wrap_strndup
+ strdup=wrap_strdup
+ _strdup=wrap_strdup
+ wcsdup=wrap_wcsdup
+ _wcsdup=wrap_wcsdup
diff --git a/mozglue/build/mozglue.dll.manifest b/mozglue/build/mozglue.dll.manifest
new file mode 100644
index 0000000000..037eae4f77
--- /dev/null
+++ b/mozglue/build/mozglue.dll.manifest
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
+<assemblyIdentity
+ version="1.0.0.0"
+ name="mozglue"
+ type="win32"
+/>
+<file name="mozglue.dll"/>
+</assembly>
diff --git a/mozglue/build/mozglue.ver b/mozglue/build/mozglue.ver
new file mode 100644
index 0000000000..433d820b36
--- /dev/null
+++ b/mozglue/build/mozglue.ver
@@ -0,0 +1,4 @@
+libmozglue.so {
+global:
+ *;
+};
diff --git a/mozglue/build/ppc.cpp b/mozglue/build/ppc.cpp
new file mode 100644
index 0000000000..20ef121386
--- /dev/null
+++ b/mozglue/build/ppc.cpp
@@ -0,0 +1,64 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/* compile-time and runtime tests for whether to use Power ISA-specific
+ * extensions */
+
+#include "ppc.h"
+#include "mozilla/Unused.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#if defined(XP_LINUX)
+// Use the getauxval() function if available.
+// ARCH_3_00 wasn't defined until glibc 2.23, so include just in case.
+# include <sys/auxv.h>
+# ifndef PPC_FEATURE2_ARCH_3_00
+# define PPC_FEATURE2_ARCH_3_00 0x00800000
+# endif
+#endif
+
+const unsigned PPC_FLAG_VMX = 1;
+const unsigned PPC_FLAG_VSX = 2;
+const unsigned PPC_FLAG_VSX3 = 4;
+
+static signed get_ppc_cpu_flags(void) {
+ // This could be expensive, so cache the result.
+ static signed cpu_flags = -1;
+
+ if (cpu_flags > -1) { // already checked
+ return cpu_flags;
+ }
+ cpu_flags = 0;
+
+#if defined(XP_LINUX)
+ // Try getauxval().
+ unsigned long int cap = getauxval(AT_HWCAP);
+ unsigned long int cap2 = getauxval(AT_HWCAP2);
+
+ if (cap & PPC_FEATURE_HAS_ALTIVEC) {
+ cpu_flags |= PPC_FLAG_VMX;
+ }
+ if (cap & PPC_FEATURE_HAS_VSX) {
+ cpu_flags |= PPC_FLAG_VSX;
+ }
+ if (cap2 & PPC_FEATURE2_ARCH_3_00) {
+ cpu_flags |= PPC_FLAG_VSX3;
+ }
+#else
+ // Non-Linux detection here. Currently, on systems other than Linux,
+ // no CPU SIMD features will be detected.
+#endif
+
+ return cpu_flags;
+}
+
+namespace mozilla {
+namespace ppc_private {
+bool vmx_enabled = !!(get_ppc_cpu_flags() & PPC_FLAG_VMX);
+bool vsx_enabled = !!(get_ppc_cpu_flags() & PPC_FLAG_VSX);
+bool vsx3_enabled = !!(get_ppc_cpu_flags() & PPC_FLAG_VSX3);
+} // namespace ppc_private
+} // namespace mozilla
diff --git a/mozglue/build/ppc.h b/mozglue/build/ppc.h
new file mode 100644
index 0000000000..9527d8dadd
--- /dev/null
+++ b/mozglue/build/ppc.h
@@ -0,0 +1,47 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/* compile-time and runtime tests for whether to use Power ISA-specific
+ extensions */
+
+#ifndef mozilla_ppc_h_
+#define mozilla_ppc_h_
+
+// for definition of MFBT_DATA
+#include "mozilla/Types.h"
+
+namespace mozilla {
+namespace ppc_private {
+extern bool MFBT_DATA vmx_enabled;
+extern bool MFBT_DATA vsx_enabled;
+extern bool MFBT_DATA vsx3_enabled;
+} // namespace ppc_private
+
+inline bool supports_vmx() {
+#ifdef __powerpc__
+ return ppc_private::vmx_enabled;
+#else
+ return false;
+#endif
+}
+
+inline bool supports_vsx() {
+#ifdef __powerpc__
+ return ppc_private::vsx_enabled;
+#else
+ return false;
+#endif
+}
+
+inline bool supports_vsx3() {
+#ifdef __powerpc__
+ return ppc_private::vsx3_enabled;
+#else
+ return false;
+#endif
+}
+
+} // namespace mozilla
+
+#endif /* !defined(mozilla_ppc_h_) */
diff --git a/mozglue/build/replace_malloc.mozbuild b/mozglue/build/replace_malloc.mozbuild
new file mode 100644
index 0000000000..16c8b7271f
--- /dev/null
+++ b/mozglue/build/replace_malloc.mozbuild
@@ -0,0 +1,6 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+if CONFIG['OS_TARGET'] == 'Darwin' and CONFIG['MOZ_REPLACE_MALLOC']:
+ LDFLAGS += ['-Wl,-U,_replace_init']