summaryrefslogtreecommitdiff
path: root/current/sources/android
diff options
context:
space:
mode:
authorAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2022-06-15 21:50:29 +0000
committerAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2022-06-15 21:50:29 +0000
commit44540c07b1dd3addb6d418234838c17f9d2361d6 (patch)
tree538f2862490075cda112e6e17786a116eed28768 /current/sources/android
parent1a8515183b085bcf7ae915fbecf6ba00cafb741d (diff)
parent0473d50cdeb87d17fdc3e77f4a413282b9e22357 (diff)
downloadndk-d5ca225ea10eacf5cceff00b8183f83659af52e4.tar.gz
Change-Id: Ie69082a7204994f90f9ec525f1ff24b52b176a5c
Diffstat (limited to 'current/sources/android')
-rw-r--r--current/sources/android/cpufeatures/Android.mk12
-rw-r--r--current/sources/android/cpufeatures/cpu-features.c80
-rw-r--r--current/sources/android/native_app_glue/Android.mk16
-rw-r--r--current/sources/android/support/Android.mk138
-rw-r--r--current/sources/android/support/include/inttypes.h5
-rw-r--r--current/sources/android/support/include/math.h81
-rw-r--r--current/sources/android/support/include/stdlib.h4
-rw-r--r--current/sources/android/support/src/posix_memalign.cpp20
-rw-r--r--current/sources/android/support/src/support_preinclude.h41
9 files changed, 393 insertions, 4 deletions
diff --git a/current/sources/android/cpufeatures/Android.mk b/current/sources/android/cpufeatures/Android.mk
new file mode 100644
index 000000000..7b53d2318
--- /dev/null
+++ b/current/sources/android/cpufeatures/Android.mk
@@ -0,0 +1,12 @@
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := cpufeatures
+LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0 SPDX-license-identifier-BSD
+LOCAL_LICENSE_CONDITIONS := notice
+LOCAL_NOTICE_FILE := $(LOCAL_PATH)/NOTICE
+LOCAL_SRC_FILES := cpu-features.c
+LOCAL_CFLAGS := -Wall -Wextra -Werror
+LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)
+LOCAL_EXPORT_LDLIBS := -ldl
+include $(BUILD_STATIC_LIBRARY)
diff --git a/current/sources/android/cpufeatures/cpu-features.c b/current/sources/android/cpufeatures/cpu-features.c
index 7569d3e5d..6dae30c21 100644
--- a/current/sources/android/cpufeatures/cpu-features.c
+++ b/current/sources/android/cpufeatures/cpu-features.c
@@ -70,7 +70,6 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <sys/auxv.h>
#include <sys/system_properties.h>
#include <unistd.h>
@@ -492,6 +491,56 @@ cpulist_read_from(CpuList* list, const char* filename)
HWCAP_IDIVT )
#endif
+#if defined(__mips__)
+// see <uapi/asm/hwcap.h> kernel header
+#define HWCAP_MIPS_R6 (1 << 0)
+#define HWCAP_MIPS_MSA (1 << 1)
+#endif
+
+#if defined(__arm__) || defined(__aarch64__) || defined(__mips__)
+
+#define AT_HWCAP 16
+#define AT_HWCAP2 26
+
+// Probe the system's C library for a 'getauxval' function and call it if
+// it exits, or return 0 for failure. This function is available since API
+// level 20.
+//
+// This code does *NOT* check for '__ANDROID_API__ >= 20' to support the
+// edge case where some NDK developers use headers for a platform that is
+// newer than the one really targetted by their application.
+// This is typically done to use newer native APIs only when running on more
+// recent Android versions, and requires careful symbol management.
+//
+// Note that getauxval() can't really be re-implemented here, because
+// its implementation does not parse /proc/self/auxv. Instead it depends
+// on values that are passed by the kernel at process-init time to the
+// C runtime initialization layer.
+static uint32_t
+get_elf_hwcap_from_getauxval(int hwcap_type) {
+ typedef unsigned long getauxval_func_t(unsigned long);
+
+ dlerror();
+ void* libc_handle = dlopen("libc.so", RTLD_NOW);
+ if (!libc_handle) {
+ D("Could not dlopen() C library: %s\n", dlerror());
+ return 0;
+ }
+
+ uint32_t ret = 0;
+ getauxval_func_t* func = (getauxval_func_t*)
+ dlsym(libc_handle, "getauxval");
+ if (!func) {
+ D("Could not find getauxval() in C library\n");
+ } else {
+ // Note: getauxval() returns 0 on failure. Doesn't touch errno.
+ ret = (uint32_t)(*func)(hwcap_type);
+ }
+ dlclose(libc_handle);
+ return ret;
+}
+#endif
+
#if defined(__arm__)
// Parse /proc/self/auxv to extract the ELF HW capabilities bitmap for the
// current CPU. Note that this file is not accessible from regular
@@ -610,6 +659,11 @@ android_cpuInitFamily(void)
g_cpuFamily = ANDROID_CPU_FAMILY_ARM;
#elif defined(__i386__)
g_cpuFamily = ANDROID_CPU_FAMILY_X86;
+#elif defined(__mips64)
+/* Needs to be before __mips__ since the compiler defines both */
+ g_cpuFamily = ANDROID_CPU_FAMILY_MIPS64;
+#elif defined(__mips__)
+ g_cpuFamily = ANDROID_CPU_FAMILY_MIPS;
#elif defined(__aarch64__)
g_cpuFamily = ANDROID_CPU_FAMILY_ARM64;
#elif defined(__x86_64__)
@@ -721,7 +775,8 @@ android_cpuInit(void)
}
/* Extract the list of CPU features from ELF hwcaps */
- uint32_t hwcaps = getauxval(AT_HWCAP);
+ uint32_t hwcaps = 0;
+ hwcaps = get_elf_hwcap_from_getauxval(AT_HWCAP);
if (!hwcaps) {
D("Parsing /proc/self/auxv to extract ELF hwcaps!\n");
hwcaps = get_elf_hwcap_from_proc_self_auxv();
@@ -794,7 +849,8 @@ android_cpuInit(void)
}
/* Extract the list of CPU features from ELF hwcaps2 */
- uint32_t hwcaps2 = getauxval(AT_HWCAP2);
+ uint32_t hwcaps2 = 0;
+ hwcaps2 = get_elf_hwcap_from_getauxval(AT_HWCAP2);
if (hwcaps2 != 0) {
int has_aes = (hwcaps2 & HWCAP2_AES);
int has_pmull = (hwcaps2 & HWCAP2_PMULL);
@@ -903,7 +959,8 @@ android_cpuInit(void)
#ifdef __aarch64__
{
/* Extract the list of CPU features from ELF hwcaps */
- uint32_t hwcaps = getauxval(AT_HWCAP);
+ uint32_t hwcaps = 0;
+ hwcaps = get_elf_hwcap_from_getauxval(AT_HWCAP);
if (hwcaps != 0) {
int has_fp = (hwcaps & HWCAP_FP);
int has_asimd = (hwcaps & HWCAP_ASIMD);
@@ -987,6 +1044,21 @@ android_cpuInit(void)
#endif
+#if defined( __mips__)
+ { /* MIPS and MIPS64 */
+ /* Extract the list of CPU features from ELF hwcaps */
+ uint32_t hwcaps = 0;
+ hwcaps = get_elf_hwcap_from_getauxval(AT_HWCAP);
+ if (hwcaps != 0) {
+ int has_r6 = (hwcaps & HWCAP_MIPS_R6);
+ int has_msa = (hwcaps & HWCAP_MIPS_MSA);
+ if (has_r6)
+ g_cpuFeatures |= ANDROID_CPU_MIPS_FEATURE_R6;
+ if (has_msa)
+ g_cpuFeatures |= ANDROID_CPU_MIPS_FEATURE_MSA;
+ }
+ }
+#endif /* __mips__ */
free(cpuinfo);
}
diff --git a/current/sources/android/native_app_glue/Android.mk b/current/sources/android/native_app_glue/Android.mk
new file mode 100644
index 000000000..a41b80f38
--- /dev/null
+++ b/current/sources/android/native_app_glue/Android.mk
@@ -0,0 +1,16 @@
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE:= android_native_app_glue
+LOCAL_LICENSE_KINDS:= SPDX-license-identifier-Apache-2.0
+LOCAL_LICENSE_CONDITIONS:= notice
+LOCAL_NOTICE_FILE:= $(LOCAL_PATH)/NOTICE
+LOCAL_SRC_FILES:= android_native_app_glue.c
+LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)
+LOCAL_EXPORT_LDLIBS := -llog -landroid
+# The linker will strip this as "unused" since this is a static library, but we
+# need to keep it around since it's the interface for JNI.
+LOCAL_EXPORT_LDFLAGS := -u ANativeActivity_onCreate
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/current/sources/android/support/Android.mk b/current/sources/android/support/Android.mk
new file mode 100644
index 000000000..7cefed18e
--- /dev/null
+++ b/current/sources/android/support/Android.mk
@@ -0,0 +1,138 @@
+LOCAL_PATH := $(call my-dir)
+
+# libandroid_support is only needed on LP32.
+ifeq ($(filter $(NDK_KNOWN_DEVICE_ABI64S),$(TARGET_ARCH_ABI)),)
+
+ifneq ($(LIBCXX_FORCE_REBUILD),true) # Using prebuilt
+
+LIBCXX_LIBS := ../../cxx-stl/llvm-libc++/libs/$(TARGET_ARCH_ABI)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := android_support
+LOCAL_LICENSE_KINDS := SPDX-license-identifier-BSD
+LOCAL_LICENSE_CONDITIONS := notice
+LOCAL_NOTICE_FILE := $(LOCAL_PATH)/NOTICE
+LOCAL_SRC_FILES := $(LIBCXX_LIBS)/lib$(LOCAL_MODULE)$(TARGET_LIB_EXTENSION)
+include $(PREBUILT_STATIC_LIBRARY)
+
+else # Building
+
+android_support_cflags := \
+ -D_GNU_SOURCE \
+ -Drestrict=__restrict__ \
+ -ffunction-sections \
+ -fdata-sections \
+ -fvisibility=hidden \
+
+android_support_c_includes := \
+ $(BIONIC_PATH)/libc \
+ $(BIONIC_PATH)/libc/upstream-openbsd/android/include \
+ $(BIONIC_PATH)/libm \
+ $(BIONIC_PATH)/libm/upstream-freebsd/android/include \
+ $(BIONIC_PATH)/libm/upstream-freebsd/lib/msun/src \
+
+android_support_cflags += \
+ -include freebsd-compat.h \
+ -include openbsd-compat.h \
+ -include $(LOCAL_PATH)/src/support_preinclude.h \
+ -D__BIONIC_BUILD_FOR_ANDROID_SUPPORT \
+ -Werror \
+
+android_support_sources := \
+ $(BIONIC_PATH)/libc/bionic/c32rtomb.cpp \
+ $(BIONIC_PATH)/libc/bionic/locale.cpp \
+ $(BIONIC_PATH)/libc/bionic/mbrtoc32.cpp \
+ $(BIONIC_PATH)/libc/bionic/wchar.cpp \
+ $(BIONIC_PATH)/libc/upstream-freebsd/lib/libc/string/wcscat.c \
+ $(BIONIC_PATH)/libc/upstream-freebsd/lib/libc/string/wcschr.c \
+ $(BIONIC_PATH)/libc/upstream-freebsd/lib/libc/string/wcslen.c \
+ $(BIONIC_PATH)/libc/upstream-freebsd/lib/libc/string/wcsncmp.c \
+ $(BIONIC_PATH)/libc/upstream-freebsd/lib/libc/string/wcsncpy.c \
+ $(BIONIC_PATH)/libc/upstream-freebsd/lib/libc/string/wcspbrk.c \
+ $(BIONIC_PATH)/libc/upstream-freebsd/lib/libc/string/wcsrchr.c \
+ $(BIONIC_PATH)/libc/upstream-freebsd/lib/libc/string/wcsspn.c \
+ $(BIONIC_PATH)/libc/upstream-freebsd/lib/libc/string/wcsstr.c \
+ $(BIONIC_PATH)/libc/upstream-freebsd/lib/libc/string/wcstok.c \
+ $(BIONIC_PATH)/libc/upstream-freebsd/lib/libc/string/wmemchr.c \
+ $(BIONIC_PATH)/libc/upstream-freebsd/lib/libc/string/wmemcmp.c \
+ $(BIONIC_PATH)/libc/upstream-freebsd/lib/libc/string/wmemcpy.c \
+ $(BIONIC_PATH)/libc/upstream-freebsd/lib/libc/string/wmemmove.c \
+ $(BIONIC_PATH)/libc/upstream-freebsd/lib/libc/string/wmemset.c \
+ $(BIONIC_PATH)/libc/upstream-openbsd/lib/libc/locale/mbtowc.c \
+ $(BIONIC_PATH)/libc/upstream-openbsd/lib/libc/stdlib/imaxabs.c \
+ $(BIONIC_PATH)/libc/upstream-openbsd/lib/libc/stdlib/imaxdiv.c \
+ $(BIONIC_PATH)/libm/digittoint.c \
+ $(BIONIC_PATH)/libm/upstream-freebsd/lib/msun/src/e_acos.c \
+ $(BIONIC_PATH)/libm/upstream-freebsd/lib/msun/src/e_acosh.c \
+ $(BIONIC_PATH)/libm/upstream-freebsd/lib/msun/src/e_asin.c \
+ $(BIONIC_PATH)/libm/upstream-freebsd/lib/msun/src/e_atan2.c \
+ $(BIONIC_PATH)/libm/upstream-freebsd/lib/msun/src/e_atanh.c \
+ $(BIONIC_PATH)/libm/upstream-freebsd/lib/msun/src/e_cosh.c \
+ $(BIONIC_PATH)/libm/upstream-freebsd/lib/msun/src/e_exp.c \
+ $(BIONIC_PATH)/libm/upstream-freebsd/lib/msun/src/e_hypot.c \
+ $(BIONIC_PATH)/libm/upstream-freebsd/lib/msun/src/e_log.c \
+ $(BIONIC_PATH)/libm/upstream-freebsd/lib/msun/src/e_log10.c \
+ $(BIONIC_PATH)/libm/upstream-freebsd/lib/msun/src/e_log2.c \
+ $(BIONIC_PATH)/libm/upstream-freebsd/lib/msun/src/e_log2f.c \
+ $(BIONIC_PATH)/libm/upstream-freebsd/lib/msun/src/e_logf.c \
+ $(BIONIC_PATH)/libm/upstream-freebsd/lib/msun/src/e_remainder.c \
+ $(BIONIC_PATH)/libm/upstream-freebsd/lib/msun/src/e_sinh.c \
+ $(BIONIC_PATH)/libm/upstream-freebsd/lib/msun/src/e_sqrt.c \
+ $(BIONIC_PATH)/libm/upstream-freebsd/lib/msun/src/k_cos.c \
+ $(BIONIC_PATH)/libm/upstream-freebsd/lib/msun/src/k_exp.c \
+ $(BIONIC_PATH)/libm/upstream-freebsd/lib/msun/src/k_rem_pio2.c \
+ $(BIONIC_PATH)/libm/upstream-freebsd/lib/msun/src/k_sin.c \
+ $(BIONIC_PATH)/libm/upstream-freebsd/lib/msun/src/k_tan.c \
+ $(BIONIC_PATH)/libm/upstream-freebsd/lib/msun/src/s_asinh.c \
+ $(BIONIC_PATH)/libm/upstream-freebsd/lib/msun/src/s_atan.c \
+ $(BIONIC_PATH)/libm/upstream-freebsd/lib/msun/src/s_cbrt.c \
+ $(BIONIC_PATH)/libm/upstream-freebsd/lib/msun/src/s_cos.c \
+ $(BIONIC_PATH)/libm/upstream-freebsd/lib/msun/src/s_erf.c \
+ $(BIONIC_PATH)/libm/upstream-freebsd/lib/msun/src/s_exp2.c \
+ $(BIONIC_PATH)/libm/upstream-freebsd/lib/msun/src/s_expm1.c \
+ $(BIONIC_PATH)/libm/upstream-freebsd/lib/msun/src/s_frexp.c \
+ $(BIONIC_PATH)/libm/upstream-freebsd/lib/msun/src/s_frexpf.c \
+ $(BIONIC_PATH)/libm/upstream-freebsd/lib/msun/src/s_log1p.c \
+ $(BIONIC_PATH)/libm/upstream-freebsd/lib/msun/src/s_logb.c \
+ $(BIONIC_PATH)/libm/upstream-freebsd/lib/msun/src/s_nextafter.c \
+ $(BIONIC_PATH)/libm/upstream-freebsd/lib/msun/src/s_remquo.c \
+ $(BIONIC_PATH)/libm/upstream-freebsd/lib/msun/src/s_rint.c \
+ $(BIONIC_PATH)/libm/upstream-freebsd/lib/msun/src/s_sin.c \
+ $(BIONIC_PATH)/libm/upstream-freebsd/lib/msun/src/s_tan.c \
+ $(BIONIC_PATH)/libm/upstream-freebsd/lib/msun/src/s_tanh.c \
+ src/locale_support.cpp \
+ src/posix_memalign.cpp \
+ src/swprintf.cpp \
+ src/wcstox.cpp \
+
+ifeq (x86,$(TARGET_ARCH_ABI))
+# Replaces broken implementations in x86 libm.so
+android_support_sources += \
+ $(BIONIC_PATH)/libm/upstream-freebsd/lib/msun/src/s_scalbln.c \
+ $(BIONIC_PATH)/libm/upstream-freebsd/lib/msun/src/s_scalbn.c \
+
+# fake_long_double.c doesn't define this for x86.
+# TODO: seems like we don't pass .S files to the assembler?
+#android_support_c_includes += $(BIONIC_PATH)/libc/arch-x86/include
+#android_support_sources += $(BIONIC_PATH)/libm/x86/lrint.S
+endif
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := android_support
+LOCAL_LICENSE_KINDS := SPDX-license-identifier-BSD
+LOCAL_LICENSE_CONDITIONS := notice
+LOCAL_NOTICE_FILE := $(LOCAL_PATH)/NOTICE
+LOCAL_SRC_FILES := $(android_support_sources)
+LOCAL_C_INCLUDES := $(android_support_c_includes)
+LOCAL_CFLAGS := $(android_support_cflags)
+LOCAL_ARM_NEON := false
+
+LOCAL_CPPFLAGS := \
+ -fvisibility-inlines-hidden \
+ -std=gnu++11 \
+
+include $(BUILD_STATIC_LIBRARY)
+
+endif # Prebuilt/building
+
+endif # LP32
diff --git a/current/sources/android/support/include/inttypes.h b/current/sources/android/support/include/inttypes.h
index 518243418..834ab9170 100644
--- a/current/sources/android/support/include/inttypes.h
+++ b/current/sources/android/support/include/inttypes.h
@@ -32,6 +32,11 @@
__BEGIN_DECLS
+#if __ANDROID_API__ < __ANDROID_API_K__
+intmax_t imaxabs(intmax_t) __attribute_const__;
+imaxdiv_t imaxdiv(intmax_t, intmax_t) __attribute_const__;
+#endif
+
#if __ANDROID_API__ < __ANDROID_API_L__
intmax_t wcstoimax(const wchar_t* __restrict, wchar_t** __restrict, int);
uintmax_t wcstoumax(const wchar_t* __restrict, wchar_t** __restrict, int);
diff --git a/current/sources/android/support/include/math.h b/current/sources/android/support/include/math.h
new file mode 100644
index 000000000..8c29c6b47
--- /dev/null
+++ b/current/sources/android/support/include/math.h
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include_next <math.h>
+
+__BEGIN_DECLS
+
+#if __ANDROID_API__ < __ANDROID_API_J_MR2__
+double log2(double);
+float log2f(float);
+long double log2l(long double);
+long double logbl(long double);
+float tgammaf(float);
+#endif
+
+#if __ANDROID_API__ < __ANDROID_API_L__
+long double acoshl(long double);
+long double acosl(long double);
+long double asinhl(long double);
+long double asinl(long double);
+long double atan2l(long double, long double);
+long double atanhl(long double);
+long double atanl(long double);
+long double cbrtl(long double);
+long double coshl(long double);
+long double cosl(long double);
+long double erfcl(long double);
+long double erfl(long double);
+long double exp2l(long double);
+long double expl(long double);
+long double expm1l(long double);
+long double fmodl(long double, long double);
+long double hypotl(long double, long double);
+long double lgammal(long double);
+long double log10l(long double);
+long double log1pl(long double);
+long double logl(long double);
+long double modfl(long double, long double*);
+long double nearbyintl(long double);
+long double powl(long double, long double);
+long double remainderl(long double, long double);
+long double remquol(long double, long double, int*);
+long double rintl(long double);
+long double sinhl(long double);
+long double sinl(long double);
+long double sqrtl(long double);
+long double tanhl(long double);
+long double tanl(long double);
+long double tgammal(long double);
+long int lrintl(long double);
+long long int llrintl(long double);
+#endif
+
+__END_DECLS
diff --git a/current/sources/android/support/include/stdlib.h b/current/sources/android/support/include/stdlib.h
index 43c47f303..e52e8ce58 100644
--- a/current/sources/android/support/include/stdlib.h
+++ b/current/sources/android/support/include/stdlib.h
@@ -32,6 +32,10 @@
__BEGIN_DECLS
+#if __ANDROID_API__ < __ANDROID_API_J_MR1__
+int posix_memalign(void** memptr, size_t alignment, size_t size);
+#endif
+
#if __ANDROID_API__ < __ANDROID_API_L__
long double strtold_l(const char*, char**, locale_t);
long long strtoll_l(const char*, char**, int, locale_t);
diff --git a/current/sources/android/support/src/posix_memalign.cpp b/current/sources/android/support/src/posix_memalign.cpp
new file mode 100644
index 000000000..cf7abbbf5
--- /dev/null
+++ b/current/sources/android/support/src/posix_memalign.cpp
@@ -0,0 +1,20 @@
+#include <errno.h>
+#include <malloc.h>
+#include <stdlib.h>
+
+int posix_memalign(void** memptr, size_t alignment, size_t size) {
+ if ((alignment & (alignment - 1)) != 0 || alignment == 0) {
+ return EINVAL;
+ }
+
+ if (alignment % sizeof(void*) != 0) {
+ return EINVAL;
+ }
+
+ *memptr = memalign(alignment, size);
+ if (*memptr == NULL) {
+ return errno;
+ }
+
+ return 0;
+}
diff --git a/current/sources/android/support/src/support_preinclude.h b/current/sources/android/support/src/support_preinclude.h
new file mode 100644
index 000000000..bf090b0d2
--- /dev/null
+++ b/current/sources/android/support/src/support_preinclude.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#pragma once
+
+// Declare cimag and creal for use by __ldexp_cexp. libandroid_runtime doesn't
+// really need __ldexp_cexp, but it does need __ldexp_exp, and both functions
+// are defined in the same C file. complex.h doesn't declare cimag/creal when
+// building libandroid_support, because the functions are only available
+// starting with M, and libandroid_support is compiled for the oldest supported
+// NDK API.
+//
+// The two functions are trivial (and have __builtin_{cimag,creal}
+// equivalents). Clang inlines calls to these functions even with -O0.
+double cimag(double _Complex z);
+double creal(double _Complex z);