Compare commits
No commits in common. "main" and "brillo-m7-dev" have entirely different histories.
main
...
brillo-m7-
@ -2,7 +2,6 @@ BasedOnStyle: Google
|
||||
AllowShortBlocksOnASingleLine: false
|
||||
AllowShortFunctionsOnASingleLine: false
|
||||
|
||||
ColumnLimit: 100
|
||||
CommentPragmas: NOLINT:.*
|
||||
DerivePointerAlignment: false
|
||||
IndentWidth: 2
|
||||
|
27
README.md
27
README.md
@ -169,10 +169,9 @@ As mentioned above, this is currently a two-step process:
|
||||
Updating tzdata
|
||||
---------------
|
||||
|
||||
This is fully automated (and these days handled by the libcore team, because
|
||||
they own icu, and that needs to be updated in sync with bionic):
|
||||
This is fully automated:
|
||||
|
||||
1. Run update-tzdata.py in external/icu/tools/.
|
||||
1. Run update-tzdata.py.
|
||||
|
||||
|
||||
Verifying changes
|
||||
@ -269,22 +268,18 @@ However, this also makes it difficult to run the tests under GDB. To prevent
|
||||
each test from being forked, run the tests with the flag `--no-isolate`.
|
||||
|
||||
|
||||
32-bit ABI bugs
|
||||
---------------
|
||||
LP32 ABI bugs
|
||||
-------------
|
||||
|
||||
This probably belongs in the NDK documentation rather than here, but these
|
||||
are the known ABI bugs in the 32-bit ABI:
|
||||
are the known ABI bugs in LP32:
|
||||
|
||||
* `time_t` is 32-bit. <http://b/5819737>. In the 64-bit ABI, time_t is
|
||||
64-bit.
|
||||
* `time_t` is 32-bit. <http://b/5819737>
|
||||
|
||||
* `off_t` is 32-bit. There is `off64_t`, and in newer releases there is
|
||||
almost-complete support for `_FILE_OFFSET_BITS`. Unfortunately our stdio
|
||||
implementation uses 32-bit offsets and -- worse -- function pointers to
|
||||
functions that use 32-bit offsets, so there's no good way to implement
|
||||
the last few pieces <http://b/24807045>. In the 64-bit ABI, off_t is
|
||||
off64_t.
|
||||
* `off_t` is 32-bit. There is `off64_t`, but no `_FILE_OFFSET_BITS` support.
|
||||
Many of the `off64_t` functions are missing in older releases, and
|
||||
stdio uses 32-bit offsets, so there's no way to fully implement
|
||||
`_FILE_OFFSET_BITS`.
|
||||
|
||||
* `sigset_t` is too small on ARM and x86 (but correct on MIPS), so support
|
||||
for real-time signals is broken. <http://b/5828899> In the 64-bit ABI,
|
||||
`sigset_t` is the correct size for every architecture.
|
||||
for real-time signals is broken. <http://b/5828899>
|
||||
|
@ -24,7 +24,7 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <android-base/stringprintf.h>
|
||||
#include <base/stringprintf.h>
|
||||
|
||||
#include <benchmark/Benchmark.h>
|
||||
|
||||
|
@ -23,7 +23,7 @@
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <android-base/stringprintf.h>
|
||||
#include <base/stringprintf.h>
|
||||
|
||||
int Round(int n) {
|
||||
int base = 1;
|
||||
|
544
libc/Android.bp
544
libc/Android.bp
File diff suppressed because it is too large
Load Diff
120
libc/Android.mk
120
libc/Android.mk
@ -47,6 +47,7 @@ libc_common_src_files := \
|
||||
bionic/if_indextoname.c \
|
||||
bionic/if_nametoindex.c \
|
||||
bionic/initgroups.c \
|
||||
bionic/ioctl.c \
|
||||
bionic/isatty.c \
|
||||
bionic/memmem.c \
|
||||
bionic/pututline.c \
|
||||
@ -149,9 +150,7 @@ libc_bionic_ndk_src_files := \
|
||||
bionic/getpid.cpp \
|
||||
bionic/gettid.cpp \
|
||||
bionic/__gnu_basename.cpp \
|
||||
bionic/ifaddrs.cpp \
|
||||
bionic/inotify_init.cpp \
|
||||
bionic/ioctl.cpp \
|
||||
bionic/lchown.cpp \
|
||||
bionic/lfs64_support.cpp \
|
||||
bionic/__libc_current_sigrtmax.cpp \
|
||||
@ -171,7 +170,6 @@ libc_bionic_ndk_src_files := \
|
||||
bionic/mkfifo.cpp \
|
||||
bionic/mknod.cpp \
|
||||
bionic/mntent.cpp \
|
||||
bionic/mremap.cpp \
|
||||
bionic/NetdClientDispatch.cpp \
|
||||
bionic/open.cpp \
|
||||
bionic/pathconf.cpp \
|
||||
@ -244,11 +242,9 @@ libc_bionic_ndk_src_files := \
|
||||
|
||||
libc_bionic_src_files :=
|
||||
|
||||
# The following implementations depend on pthread data, so we can't include
|
||||
# them in libc_ndk.a.
|
||||
libc_bionic_src_files += \
|
||||
bionic/__cxa_thread_atexit_impl.cpp \
|
||||
bionic/fork.cpp \
|
||||
# The fork implementation depends on pthread data, so we can't include it in
|
||||
# libc_ndk.a.
|
||||
libc_bionic_src_files += bionic/fork.cpp
|
||||
|
||||
# The data that backs getauxval is initialized in the libc init functions which
|
||||
# are invoked by the linker. If this file is included in libc_ndk.a, only one of
|
||||
@ -567,7 +563,6 @@ libc_upstream_openbsd_ndk_src_files := \
|
||||
libc_pthread_src_files := \
|
||||
bionic/pthread_atfork.cpp \
|
||||
bionic/pthread_attr.cpp \
|
||||
bionic/pthread_barrier.cpp \
|
||||
bionic/pthread_cond.cpp \
|
||||
bionic/pthread_create.cpp \
|
||||
bionic/pthread_detach.cpp \
|
||||
@ -587,7 +582,9 @@ libc_pthread_src_files := \
|
||||
bionic/pthread_setname_np.cpp \
|
||||
bionic/pthread_setschedparam.cpp \
|
||||
bionic/pthread_sigmask.cpp \
|
||||
bionic/pthread_spinlock.cpp \
|
||||
|
||||
libc_thread_atexit_impl_src_files := \
|
||||
bionic/__cxa_thread_atexit_impl.cpp \
|
||||
|
||||
libc_arch_static_src_files := \
|
||||
bionic/dl_iterate_phdr_static.cpp \
|
||||
@ -625,11 +622,6 @@ ifeq ($(TARGET_ARCH),x86_64)
|
||||
use_clang := false
|
||||
endif
|
||||
|
||||
# b/25291096, Clang/llvm compiled libc.so for mips/mips64 failed to boot.
|
||||
ifeq ($(TARGET_ARCH),$(filter $(TARGET_ARCH),mips mips64))
|
||||
use_clang := false
|
||||
endif
|
||||
|
||||
ifeq ($(use_clang),)
|
||||
use_clang := false
|
||||
endif
|
||||
@ -645,7 +637,7 @@ ifeq ($(strip $(DEBUG_BIONIC_LIBC)),true)
|
||||
libc_common_cflags += -DDEBUG
|
||||
endif
|
||||
|
||||
ifeq ($(MALLOC_SVELTE),true)
|
||||
ifeq ($(MALLOC_IMPL),dlmalloc)
|
||||
libc_common_cflags += -DUSE_DLMALLOC
|
||||
libc_malloc_src := bionic/dlmalloc.c
|
||||
else
|
||||
@ -654,6 +646,13 @@ else
|
||||
libc_common_c_includes += external/jemalloc/include
|
||||
endif
|
||||
|
||||
# To customize dlmalloc's alignment, set BOARD_MALLOC_ALIGNMENT in
|
||||
# the appropriate BoardConfig.mk file.
|
||||
#
|
||||
ifneq ($(BOARD_MALLOC_ALIGNMENT),)
|
||||
libc_common_cflags += -DMALLOC_ALIGNMENT=$(BOARD_MALLOC_ALIGNMENT)
|
||||
endif
|
||||
|
||||
# Define some common conlyflags
|
||||
libc_common_conlyflags := \
|
||||
-std=gnu99
|
||||
@ -684,21 +683,13 @@ endef
|
||||
# libc_stack_protector.a - stack protector code
|
||||
# ========================================================
|
||||
#
|
||||
# Code that implements the stack protector (or that runs
|
||||
# before TLS has been set up) needs to be compiled with
|
||||
# -fno-stack-protector, since it accesses the stack canary
|
||||
# TLS slot.
|
||||
# The stack protector code needs to be compiled
|
||||
# with -fno-stack-protector, since it modifies the
|
||||
# stack canary.
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
LOCAL_SRC_FILES := \
|
||||
bionic/__libc_init_main_thread.cpp \
|
||||
bionic/__stack_chk_fail.cpp \
|
||||
|
||||
LOCAL_SRC_FILES_arm64 := arch-arm64/bionic/__set_tls.c
|
||||
LOCAL_SRC_FILES_x86 := arch-x86/bionic/__set_tls.c
|
||||
LOCAL_SRC_FILES_x86_64 := arch-x86_64/bionic/__set_tls.c
|
||||
|
||||
LOCAL_SRC_FILES := bionic/__stack_chk_fail.cpp
|
||||
LOCAL_CFLAGS := $(libc_common_cflags) -fno-stack-protector
|
||||
LOCAL_CONLYFLAGS := $(libc_common_conlyflags)
|
||||
LOCAL_CPPFLAGS := $(libc_common_cppflags)
|
||||
@ -715,30 +706,6 @@ $(eval $(call patch-up-arch-specific-flags,LOCAL_CFLAGS,libc_common_cflags))
|
||||
include $(BUILD_STATIC_LIBRARY)
|
||||
|
||||
|
||||
# libc_init_static.cpp also needs to be built without stack protector,
|
||||
# because it's responsible for setting up TLS for static executables.
|
||||
# This isn't the case for dynamic executables because the dynamic linker
|
||||
# has already set up the main thread's TLS.
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
LOCAL_SRC_FILES := bionic/libc_init_static.cpp
|
||||
LOCAL_CFLAGS := $(libc_common_cflags) -fno-stack-protector
|
||||
LOCAL_CONLYFLAGS := $(libc_common_conlyflags)
|
||||
LOCAL_CPPFLAGS := $(libc_common_cppflags)
|
||||
LOCAL_C_INCLUDES := $(libc_common_c_includes)
|
||||
LOCAL_MODULE := libc_init_static
|
||||
LOCAL_CLANG := $(use_clang)
|
||||
LOCAL_ADDITIONAL_DEPENDENCIES := $(libc_common_additional_dependencies)
|
||||
LOCAL_CXX_STL := none
|
||||
LOCAL_SYSTEM_SHARED_LIBRARIES :=
|
||||
LOCAL_SANITIZE := never
|
||||
LOCAL_NATIVE_COVERAGE := $(bionic_coverage)
|
||||
|
||||
$(eval $(call patch-up-arch-specific-flags,LOCAL_CFLAGS,libc_common_cflags))
|
||||
include $(BUILD_STATIC_LIBRARY)
|
||||
|
||||
|
||||
# ========================================================
|
||||
# libc_tzcode.a - upstream 'tzcode' code
|
||||
# ========================================================
|
||||
@ -757,7 +724,6 @@ LOCAL_CFLAGS := $(libc_common_cflags) \
|
||||
LOCAL_CFLAGS += -DALL_STATE
|
||||
# Include tzsetwall, timelocal, timegm, time2posix, and posix2time.
|
||||
LOCAL_CFLAGS += -DSTD_INSPIRED
|
||||
# Obviously, we want to be thread-safe.
|
||||
LOCAL_CFLAGS += -DTHREAD_SAFE
|
||||
# The name of the tm_gmtoff field in our struct tm.
|
||||
LOCAL_CFLAGS += -DTM_GMTOFF=tm_gmtoff
|
||||
@ -765,8 +731,6 @@ LOCAL_CFLAGS += -DTM_GMTOFF=tm_gmtoff
|
||||
LOCAL_CFLAGS += -DTZDIR=\"/system/usr/share/zoneinfo\"
|
||||
# Include timezone and daylight globals.
|
||||
LOCAL_CFLAGS += -DUSG_COMPAT=1
|
||||
# Use the empty string (instead of " ") as the timezone abbreviation fallback.
|
||||
LOCAL_CFLAGS += -DWILDABBR=\"\"
|
||||
LOCAL_CFLAGS += -DNO_RUN_TIME_WARNINGS_ABOUT_YEAR_2000_PROBLEMS_THANK_YOU
|
||||
LOCAL_CFLAGS += -Dlint
|
||||
|
||||
@ -975,7 +939,6 @@ LOCAL_SANITIZE := never
|
||||
LOCAL_NATIVE_COVERAGE := $(bionic_coverage)
|
||||
|
||||
$(eval $(call patch-up-arch-specific-flags,LOCAL_CFLAGS,libc_common_cflags))
|
||||
$(eval $(call patch-up-arch-specific-flags,LOCAL_SRC_FILES,libc_openbsd_src_files))
|
||||
$(eval $(call patch-up-arch-specific-flags,LOCAL_SRC_FILES_EXCLUDE,libc_openbsd_src_files_exclude))
|
||||
include $(BUILD_STATIC_LIBRARY)
|
||||
|
||||
@ -1071,6 +1034,24 @@ $(eval $(call patch-up-arch-specific-flags,LOCAL_CFLAGS,libc_common_cflags))
|
||||
$(eval $(call patch-up-arch-specific-flags,LOCAL_SRC_FILES,libc_bionic_ndk_src_files))
|
||||
include $(BUILD_STATIC_LIBRARY)
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
LOCAL_SRC_FILES := $(libc_thread_atexit_impl_src_files)
|
||||
LOCAL_CFLAGS := $(libc_common_cflags) -Wframe-larger-than=2048
|
||||
|
||||
LOCAL_CONLYFLAGS := $(libc_common_conlyflags)
|
||||
LOCAL_CPPFLAGS := $(libc_common_cppflags) -Wold-style-cast
|
||||
LOCAL_C_INCLUDES := $(libc_common_c_includes)
|
||||
LOCAL_MODULE := libc_thread_atexit_impl
|
||||
# TODO: Clang tries to use __tls_get_addr which is not supported yet
|
||||
# remove after it is implemented.
|
||||
LOCAL_CLANG := false
|
||||
LOCAL_ADDITIONAL_DEPENDENCIES := $(libc_common_additional_dependencies)
|
||||
LOCAL_CXX_STL := none
|
||||
LOCAL_SYSTEM_SHARED_LIBRARIES :=
|
||||
LOCAL_SANITIZE := never
|
||||
LOCAL_NATIVE_COVERAGE := $(bionic_coverage)
|
||||
|
||||
include $(BUILD_STATIC_LIBRARY)
|
||||
|
||||
# ========================================================
|
||||
# libc_pthread.a - pthreads parts that previously lived in
|
||||
@ -1228,7 +1209,7 @@ LOCAL_WHOLE_STATIC_LIBRARIES := \
|
||||
LOCAL_WHOLE_STATIC_LIBRARIES_arm := libc_aeabi
|
||||
LOCAL_CXX_STL := none
|
||||
|
||||
ifneq ($(MALLOC_SVELTE),true)
|
||||
ifneq ($(MALLOC_IMPL),dlmalloc)
|
||||
LOCAL_WHOLE_STATIC_LIBRARIES += libjemalloc
|
||||
endif
|
||||
|
||||
@ -1268,6 +1249,7 @@ LOCAL_WHOLE_STATIC_LIBRARIES := \
|
||||
libc_pthread \
|
||||
libc_stack_protector \
|
||||
libc_syscalls \
|
||||
libc_thread_atexit_impl \
|
||||
libc_tzcode \
|
||||
|
||||
LOCAL_WHOLE_STATIC_LIBRARIES_arm := libc_aeabi
|
||||
@ -1300,6 +1282,7 @@ include $(CLEAR_VARS)
|
||||
|
||||
LOCAL_SRC_FILES := \
|
||||
$(libc_arch_static_src_files) \
|
||||
bionic/libc_init_static.cpp
|
||||
|
||||
LOCAL_C_INCLUDES := $(libc_common_c_includes)
|
||||
LOCAL_CFLAGS := $(libc_common_cflags) \
|
||||
@ -1311,7 +1294,7 @@ LOCAL_CPPFLAGS := $(libc_common_cppflags)
|
||||
LOCAL_MODULE := libc_nomalloc
|
||||
LOCAL_CLANG := $(use_clang)
|
||||
LOCAL_ADDITIONAL_DEPENDENCIES := $(libc_common_additional_dependencies)
|
||||
LOCAL_WHOLE_STATIC_LIBRARIES := libc_common libc_init_static
|
||||
LOCAL_WHOLE_STATIC_LIBRARIES := libc_common
|
||||
LOCAL_CXX_STL := none
|
||||
LOCAL_SYSTEM_SHARED_LIBRARIES :=
|
||||
LOCAL_SANITIZE := never
|
||||
@ -1351,6 +1334,7 @@ include $(CLEAR_VARS)
|
||||
LOCAL_SRC_FILES := \
|
||||
$(libc_arch_static_src_files) \
|
||||
bionic/malloc_debug_common.cpp \
|
||||
bionic/libc_init_static.cpp \
|
||||
|
||||
LOCAL_CFLAGS := $(libc_common_cflags) \
|
||||
-DLIBC_STATIC \
|
||||
@ -1361,9 +1345,9 @@ LOCAL_C_INCLUDES := $(libc_common_c_includes)
|
||||
LOCAL_MODULE := libc
|
||||
LOCAL_CLANG := $(use_clang)
|
||||
LOCAL_ADDITIONAL_DEPENDENCIES := $(libc_common_additional_dependencies)
|
||||
LOCAL_WHOLE_STATIC_LIBRARIES := libc_common libc_init_static
|
||||
LOCAL_WHOLE_STATIC_LIBRARIES := libc_common
|
||||
|
||||
ifneq ($(MALLOC_SVELTE),true)
|
||||
ifneq ($(MALLOC_IMPL),dlmalloc)
|
||||
LOCAL_WHOLE_STATIC_LIBRARIES += libjemalloc
|
||||
endif
|
||||
|
||||
@ -1407,9 +1391,6 @@ LOCAL_ADDITIONAL_DEPENDENCIES := \
|
||||
$(LOCAL_PATH)/libc.mips64.map \
|
||||
$(LOCAL_PATH)/libc.x86.map \
|
||||
$(LOCAL_PATH)/libc.x86_64.map \
|
||||
$(LOCAL_PATH)/libc.arm.brillo.map \
|
||||
$(LOCAL_PATH)/libc.mips.brillo.map \
|
||||
$(LOCAL_PATH)/libc.x86.brillo.map \
|
||||
|
||||
# Leave the symbols in the shared library so that stack unwinders can produce
|
||||
# meaningful name resolution.
|
||||
@ -1429,7 +1410,7 @@ LOCAL_PACK_MODULE_RELOCATIONS := false
|
||||
LOCAL_SHARED_LIBRARIES := libdl
|
||||
LOCAL_WHOLE_STATIC_LIBRARIES := libc_common
|
||||
|
||||
ifneq ($(MALLOC_SVELTE),true)
|
||||
ifneq ($(MALLOC_IMPL),dlmalloc)
|
||||
LOCAL_WHOLE_STATIC_LIBRARIES += libjemalloc
|
||||
endif
|
||||
|
||||
@ -1441,18 +1422,11 @@ LOCAL_LDFLAGS_arm := -Wl,--hash-style=both
|
||||
LOCAL_LDFLAGS_x86 := -Wl,--hash-style=both
|
||||
|
||||
# Don't re-export new/delete and friends, even if the compiler really wants to.
|
||||
ifdef BRILLO
|
||||
LOCAL_LDFLAGS_arm += -Wl,--version-script,$(LOCAL_PATH)/libc.arm.brillo.map
|
||||
LOCAL_LDFLAGS_mips += -Wl,--version-script,$(LOCAL_PATH)/libc.mips.brillo.map
|
||||
LOCAL_LDFLAGS_x86 += -Wl,--version-script,$(LOCAL_PATH)/libc.x86.brillo.map
|
||||
else
|
||||
LOCAL_LDFLAGS_arm += -Wl,--version-script,$(LOCAL_PATH)/libc.arm.map
|
||||
LOCAL_LDFLAGS_mips += -Wl,--version-script,$(LOCAL_PATH)/libc.mips.map
|
||||
LOCAL_LDFLAGS_x86 += -Wl,--version-script,$(LOCAL_PATH)/libc.x86.map
|
||||
endif
|
||||
|
||||
LOCAL_LDFLAGS_arm64 += -Wl,--version-script,$(LOCAL_PATH)/libc.arm64.map
|
||||
LOCAL_LDFLAGS_mips += -Wl,--version-script,$(LOCAL_PATH)/libc.mips.map
|
||||
LOCAL_LDFLAGS_mips64 += -Wl,--version-script,$(LOCAL_PATH)/libc.mips64.map
|
||||
LOCAL_LDFLAGS_x86 += -Wl,--version-script,$(LOCAL_PATH)/libc.x86.map
|
||||
LOCAL_LDFLAGS_x86_64 += -Wl,--version-script,$(LOCAL_PATH)/libc.x86_64.map
|
||||
|
||||
# We'd really like to do this for all architectures, but since this wasn't done
|
||||
|
@ -107,7 +107,7 @@ ssize_t pwritev|pwritev64(int, const struct iovec*, int, off_t) arm64,mips64
|
||||
int ___close:close(int) all
|
||||
pid_t __getpid:getpid() all
|
||||
int munmap(void*, size_t) all
|
||||
void* ___mremap:mremap(void*, size_t, size_t, int, void*) all
|
||||
void* mremap(void*, size_t, size_t, unsigned long) all
|
||||
int msync(const void*, size_t, int) all
|
||||
int mprotect(const void*, size_t, int) all
|
||||
int madvise(void*, size_t, int) all
|
||||
|
@ -51,62 +51,34 @@ extern int __cxa_atexit(void (*)(void*), void*, void*);
|
||||
*/
|
||||
|
||||
int __attribute__((weak))
|
||||
__aeabi_atexit_impl(void *object, void (*destructor) (void *), void *dso_handle) {
|
||||
return __cxa_atexit(destructor, object, dso_handle);
|
||||
}
|
||||
|
||||
int __attribute__((weak))
|
||||
__aeabi_atexit_impl2(void *object, void (*destructor) (void *), void *dso_handle) {
|
||||
__aeabi_atexit(void *object, void (*destructor) (void *), void *dso_handle) {
|
||||
return __cxa_atexit(destructor, object, dso_handle);
|
||||
}
|
||||
|
||||
|
||||
void __attribute__((weak)) __aeabi_memcpy8_impl(void *dest, const void *src, size_t n) {
|
||||
void __attribute__((weak))
|
||||
__aeabi_memcpy8(void *dest, const void *src, size_t n) {
|
||||
memcpy(dest, src, n);
|
||||
}
|
||||
|
||||
void __attribute__((weak)) __aeabi_memcpy4_impl(void *dest, const void *src, size_t n) {
|
||||
void __attribute__((weak)) __aeabi_memcpy4(void *dest, const void *src, size_t n) {
|
||||
memcpy(dest, src, n);
|
||||
}
|
||||
|
||||
void __attribute__((weak)) __aeabi_memcpy_impl(void *dest, const void *src, size_t n) {
|
||||
memcpy(dest, src, n);
|
||||
}
|
||||
|
||||
void __attribute__((weak)) __aeabi_memcpy8_impl2(void *dest, const void *src, size_t n) {
|
||||
memcpy(dest, src, n);
|
||||
}
|
||||
|
||||
void __attribute__((weak)) __aeabi_memcpy4_impl2(void *dest, const void *src, size_t n) {
|
||||
memcpy(dest, src, n);
|
||||
}
|
||||
|
||||
void __attribute__((weak)) __aeabi_memcpy_impl2(void *dest, const void *src, size_t n) {
|
||||
void __attribute__((weak)) __aeabi_memcpy(void *dest, const void *src, size_t n) {
|
||||
memcpy(dest, src, n);
|
||||
}
|
||||
|
||||
|
||||
void __attribute__((weak)) __aeabi_memmove8_impl(void *dest, const void *src, size_t n) {
|
||||
void __attribute__((weak)) __aeabi_memmove8(void *dest, const void *src, size_t n) {
|
||||
memmove(dest, src, n);
|
||||
}
|
||||
|
||||
void __attribute__((weak)) __aeabi_memmove4_impl(void *dest, const void *src, size_t n) {
|
||||
void __attribute__((weak)) __aeabi_memmove4(void *dest, const void *src, size_t n) {
|
||||
memmove(dest, src, n);
|
||||
}
|
||||
|
||||
void __attribute__((weak)) __aeabi_memmove_impl(void *dest, const void *src, size_t n) {
|
||||
memmove(dest, src, n);
|
||||
}
|
||||
|
||||
void __attribute__((weak)) __aeabi_memmove8_impl2(void *dest, const void *src, size_t n) {
|
||||
memmove(dest, src, n);
|
||||
}
|
||||
|
||||
void __attribute__((weak)) __aeabi_memmove4_impl2(void *dest, const void *src, size_t n) {
|
||||
memmove(dest, src, n);
|
||||
}
|
||||
|
||||
void __attribute__((weak)) __aeabi_memmove_impl2(void *dest, const void *src, size_t n) {
|
||||
void __attribute__((weak)) __aeabi_memmove(void *dest, const void *src, size_t n) {
|
||||
memmove(dest, src, n);
|
||||
}
|
||||
|
||||
@ -115,71 +87,27 @@ void __attribute__((weak)) __aeabi_memmove_impl2(void *dest, const void *src, si
|
||||
* This allows __aeabi_memclr to tail-call __aeabi_memset
|
||||
*/
|
||||
|
||||
void __attribute__((weak)) __aeabi_memset8_impl(void *dest, size_t n, int c) {
|
||||
void __attribute__((weak)) __aeabi_memset8(void *dest, size_t n, int c) {
|
||||
memset(dest, c, n);
|
||||
}
|
||||
|
||||
void __attribute__((weak)) __aeabi_memset4_impl(void *dest, size_t n, int c) {
|
||||
void __attribute__((weak)) __aeabi_memset4(void *dest, size_t n, int c) {
|
||||
memset(dest, c, n);
|
||||
}
|
||||
|
||||
void __attribute__((weak)) __aeabi_memset_impl(void *dest, size_t n, int c) {
|
||||
memset(dest, c, n);
|
||||
}
|
||||
|
||||
void __attribute__((weak)) __aeabi_memset8_impl2(void *dest, size_t n, int c) {
|
||||
memset(dest, c, n);
|
||||
}
|
||||
|
||||
void __attribute__((weak)) __aeabi_memset4_impl2(void *dest, size_t n, int c) {
|
||||
memset(dest, c, n);
|
||||
}
|
||||
|
||||
void __attribute__((weak)) __aeabi_memset_impl2(void *dest, size_t n, int c) {
|
||||
void __attribute__((weak)) __aeabi_memset(void *dest, size_t n, int c) {
|
||||
memset(dest, c, n);
|
||||
}
|
||||
|
||||
|
||||
void __attribute__((weak)) __aeabi_memclr8_impl(void *dest, size_t n) {
|
||||
__aeabi_memset8_impl(dest, n, 0);
|
||||
void __attribute__((weak)) __aeabi_memclr8(void *dest, size_t n) {
|
||||
__aeabi_memset8(dest, n, 0);
|
||||
}
|
||||
|
||||
void __attribute__((weak)) __aeabi_memclr4_impl(void *dest, size_t n) {
|
||||
__aeabi_memset4_impl(dest, n, 0);
|
||||
void __attribute__((weak)) __aeabi_memclr4(void *dest, size_t n) {
|
||||
__aeabi_memset4(dest, n, 0);
|
||||
}
|
||||
|
||||
void __attribute__((weak)) __aeabi_memclr_impl(void *dest, size_t n) {
|
||||
__aeabi_memset_impl(dest, n, 0);
|
||||
void __attribute__((weak)) __aeabi_memclr(void *dest, size_t n) {
|
||||
__aeabi_memset(dest, n, 0);
|
||||
}
|
||||
|
||||
void __attribute__((weak)) __aeabi_memclr8_impl2(void *dest, size_t n) {
|
||||
__aeabi_memset8_impl(dest, n, 0);
|
||||
}
|
||||
|
||||
void __attribute__((weak)) __aeabi_memclr4_impl2(void *dest, size_t n) {
|
||||
__aeabi_memset4_impl(dest, n, 0);
|
||||
}
|
||||
|
||||
void __attribute__((weak)) __aeabi_memclr_impl2(void *dest, size_t n) {
|
||||
__aeabi_memset_impl(dest, n, 0);
|
||||
}
|
||||
|
||||
#define __AEABI_SYMVERS(fn_name) \
|
||||
__asm__(".symver " #fn_name "_impl, " #fn_name "@@LIBC_N"); \
|
||||
__asm__(".symver " #fn_name "_impl2, " #fn_name "@LIBC_PRIVATE")
|
||||
|
||||
__AEABI_SYMVERS(__aeabi_atexit);
|
||||
__AEABI_SYMVERS(__aeabi_memcpy8);
|
||||
__AEABI_SYMVERS(__aeabi_memcpy4);
|
||||
__AEABI_SYMVERS(__aeabi_memcpy);
|
||||
__AEABI_SYMVERS(__aeabi_memmove8);
|
||||
__AEABI_SYMVERS(__aeabi_memmove4);
|
||||
__AEABI_SYMVERS(__aeabi_memmove);
|
||||
__AEABI_SYMVERS(__aeabi_memset8);
|
||||
__AEABI_SYMVERS(__aeabi_memset4);
|
||||
__AEABI_SYMVERS(__aeabi_memset);
|
||||
__AEABI_SYMVERS(__aeabi_memclr8);
|
||||
__AEABI_SYMVERS(__aeabi_memclr4);
|
||||
__AEABI_SYMVERS(__aeabi_memclr);
|
||||
|
||||
#undef __AEABI_SYMVERS
|
||||
|
@ -37,13 +37,7 @@
|
||||
* the expectation that libc will define it and call through to
|
||||
* a differently-named function in the dynamic linker.
|
||||
*/
|
||||
_Unwind_Ptr __gnu_Unwind_Find_exidx_impl(_Unwind_Ptr pc, int *pcount) {
|
||||
_Unwind_Ptr __gnu_Unwind_Find_exidx(_Unwind_Ptr pc, int *pcount)
|
||||
{
|
||||
return dl_unwind_find_exidx(pc, pcount);
|
||||
}
|
||||
|
||||
_Unwind_Ptr __gnu_Unwind_Find_exidx_impl2(_Unwind_Ptr pc, int *pcount) {
|
||||
return dl_unwind_find_exidx(pc, pcount);
|
||||
}
|
||||
|
||||
__asm__(".symver __gnu_Unwind_Find_exidx_impl,__gnu_Unwind_Find_exidx@LIBC_PRIVATE");
|
||||
__asm__(".symver __gnu_Unwind_Find_exidx_impl2,__gnu_Unwind_Find_exidx@@LIBC_N");
|
||||
|
@ -1,23 +0,0 @@
|
||||
/* Generated by gensyscalls.py. Do not edit. */
|
||||
|
||||
#include <private/bionic_asm.h>
|
||||
|
||||
ENTRY(___mremap)
|
||||
mov ip, sp
|
||||
stmfd sp!, {r4, r5, r6, r7}
|
||||
.cfi_def_cfa_offset 16
|
||||
.cfi_rel_offset r4, 0
|
||||
.cfi_rel_offset r5, 4
|
||||
.cfi_rel_offset r6, 8
|
||||
.cfi_rel_offset r7, 12
|
||||
ldmfd ip, {r4, r5, r6}
|
||||
ldr r7, =__NR_mremap
|
||||
swi #0
|
||||
ldmfd sp!, {r4, r5, r6, r7}
|
||||
.cfi_def_cfa_offset 0
|
||||
cmn r0, #(MAX_ERRNO + 1)
|
||||
bxls lr
|
||||
neg r0, r0
|
||||
b __set_errno_internal
|
||||
END(___mremap)
|
||||
.hidden ___mremap
|
14
libc/arch-arm/syscalls/mremap.S
Normal file
14
libc/arch-arm/syscalls/mremap.S
Normal file
@ -0,0 +1,14 @@
|
||||
/* Generated by gensyscalls.py. Do not edit. */
|
||||
|
||||
#include <private/bionic_asm.h>
|
||||
|
||||
ENTRY(mremap)
|
||||
mov ip, r7
|
||||
ldr r7, =__NR_mremap
|
||||
swi #0
|
||||
mov r7, ip
|
||||
cmn r0, #(MAX_ERRNO + 1)
|
||||
bxls lr
|
||||
neg r0, r0
|
||||
b __set_errno_internal
|
||||
END(mremap)
|
@ -42,6 +42,7 @@ libc_bionic_src_files_arm64 += \
|
||||
arch-arm64/bionic/__bionic_clone.S \
|
||||
arch-arm64/bionic/_exit_with_stack_teardown.S \
|
||||
arch-arm64/bionic/setjmp.S \
|
||||
arch-arm64/bionic/__set_tls.c \
|
||||
arch-arm64/bionic/syscall.S \
|
||||
arch-arm64/bionic/vfork.S \
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
#include <private/bionic_asm.h>
|
||||
|
||||
ENTRY(___mremap)
|
||||
ENTRY(mremap)
|
||||
mov x8, __NR_mremap
|
||||
svc #0
|
||||
|
||||
@ -11,5 +11,4 @@ ENTRY(___mremap)
|
||||
b.hi __set_errno_internal
|
||||
|
||||
ret
|
||||
END(___mremap)
|
||||
.hidden ___mremap
|
||||
END(mremap)
|
@ -2,7 +2,7 @@
|
||||
|
||||
#include <private/bionic_asm.h>
|
||||
|
||||
ENTRY(___mremap)
|
||||
ENTRY(mremap)
|
||||
.set noreorder
|
||||
.cpload t9
|
||||
li v0, __NR_mremap
|
||||
@ -16,5 +16,4 @@ ENTRY(___mremap)
|
||||
j t9
|
||||
nop
|
||||
.set reorder
|
||||
END(___mremap)
|
||||
.hidden ___mremap
|
||||
END(mremap)
|
@ -2,7 +2,7 @@
|
||||
|
||||
#include <private/bionic_asm.h>
|
||||
|
||||
ENTRY(___mremap)
|
||||
ENTRY(mremap)
|
||||
.set push
|
||||
.set noreorder
|
||||
li v0, __NR_mremap
|
||||
@ -22,5 +22,4 @@ ENTRY(___mremap)
|
||||
j t9
|
||||
move ra, t0
|
||||
.set pop
|
||||
END(___mremap)
|
||||
.hidden ___mremap
|
||||
END(mremap)
|
@ -2,7 +2,7 @@
|
||||
|
||||
#include <private/bionic_asm.h>
|
||||
|
||||
ENTRY(___mremap)
|
||||
ENTRY(mremap)
|
||||
pushl %ebx
|
||||
.cfi_def_cfa_offset 8
|
||||
.cfi_rel_offset ebx, 0
|
||||
@ -15,14 +15,10 @@ ENTRY(___mremap)
|
||||
pushl %esi
|
||||
.cfi_adjust_cfa_offset 4
|
||||
.cfi_rel_offset esi, 0
|
||||
pushl %edi
|
||||
.cfi_adjust_cfa_offset 4
|
||||
.cfi_rel_offset edi, 0
|
||||
mov 24(%esp), %ebx
|
||||
mov 28(%esp), %ecx
|
||||
mov 32(%esp), %edx
|
||||
mov 36(%esp), %esi
|
||||
mov 40(%esp), %edi
|
||||
mov 20(%esp), %ebx
|
||||
mov 24(%esp), %ecx
|
||||
mov 28(%esp), %edx
|
||||
mov 32(%esp), %esi
|
||||
movl $__NR_mremap, %eax
|
||||
int $0x80
|
||||
cmpl $-MAX_ERRNO, %eax
|
||||
@ -32,11 +28,9 @@ ENTRY(___mremap)
|
||||
call __set_errno_internal
|
||||
addl $4, %esp
|
||||
1:
|
||||
popl %edi
|
||||
popl %esi
|
||||
popl %edx
|
||||
popl %ecx
|
||||
popl %ebx
|
||||
ret
|
||||
END(___mremap)
|
||||
.hidden ___mremap
|
||||
END(mremap)
|
@ -109,6 +109,7 @@ libc_bionic_src_files_x86 += \
|
||||
arch-x86/bionic/libgcc_compat.c \
|
||||
arch-x86/bionic/__restore.S \
|
||||
arch-x86/bionic/setjmp.S \
|
||||
arch-x86/bionic/__set_tls.c \
|
||||
arch-x86/bionic/syscall.S \
|
||||
arch-x86/bionic/vfork.S \
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
#include <private/bionic_asm.h>
|
||||
|
||||
ENTRY(___mremap)
|
||||
ENTRY(mremap)
|
||||
movq %rcx, %r10
|
||||
movl $__NR_mremap, %eax
|
||||
syscall
|
||||
@ -13,5 +13,4 @@ ENTRY(___mremap)
|
||||
call __set_errno_internal
|
||||
1:
|
||||
ret
|
||||
END(___mremap)
|
||||
.hidden ___mremap
|
||||
END(mremap)
|
@ -25,6 +25,7 @@ libc_bionic_src_files_x86_64 += \
|
||||
arch-x86_64/bionic/_exit_with_stack_teardown.S \
|
||||
arch-x86_64/bionic/__restore_rt.S \
|
||||
arch-x86_64/bionic/setjmp.S \
|
||||
arch-x86_64/bionic/__set_tls.c \
|
||||
arch-x86_64/bionic/syscall.S \
|
||||
arch-x86_64/bionic/vfork.S \
|
||||
|
||||
|
@ -109,7 +109,7 @@ extern "C" int __cxa_guard_acquire(_guard_t* gv) {
|
||||
}
|
||||
}
|
||||
|
||||
__futex_wait_ex(&gv->state, false, CONSTRUCTION_UNDERWAY_WITH_WAITER, false, nullptr);
|
||||
__futex_wait_ex(&gv->state, false, CONSTRUCTION_UNDERWAY_WITH_WAITER, NULL);
|
||||
old_value = atomic_load_explicit(&gv->state, memory_order_relaxed);
|
||||
}
|
||||
}
|
||||
|
@ -15,34 +15,32 @@
|
||||
*/
|
||||
#include <sys/cdefs.h>
|
||||
|
||||
#include "pthread_internal.h"
|
||||
|
||||
class thread_local_dtor {
|
||||
public:
|
||||
struct thread_local_dtor {
|
||||
void (*func) (void *);
|
||||
void *arg;
|
||||
void *dso_handle; // unused...
|
||||
thread_local_dtor* next;
|
||||
};
|
||||
|
||||
static __thread thread_local_dtor* thread_local_dtors = nullptr;
|
||||
|
||||
extern "C" int __cxa_thread_atexit_impl(void (*func) (void *), void *arg, void *dso_handle) {
|
||||
thread_local_dtor* dtor = new thread_local_dtor();
|
||||
|
||||
dtor->func = func;
|
||||
dtor->arg = arg;
|
||||
dtor->dso_handle = dso_handle;
|
||||
dtor->next = thread_local_dtors;
|
||||
|
||||
thread_local_dtors = dtor;
|
||||
|
||||
pthread_internal_t* thread = __get_thread();
|
||||
dtor->next = thread->thread_local_dtors;
|
||||
thread->thread_local_dtors = dtor;
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern "C" __LIBC_HIDDEN__ void __cxa_thread_finalize() {
|
||||
pthread_internal_t* thread = __get_thread();
|
||||
while (thread->thread_local_dtors != nullptr) {
|
||||
thread_local_dtor* current = thread->thread_local_dtors;
|
||||
thread->thread_local_dtors = current->next;
|
||||
while (thread_local_dtors != nullptr) {
|
||||
thread_local_dtor* current = thread_local_dtors;
|
||||
thread_local_dtors = current->next;
|
||||
|
||||
current->func(current->arg);
|
||||
delete current;
|
||||
|
@ -1,85 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2008 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.
|
||||
*/
|
||||
|
||||
#include "libc_init_common.h"
|
||||
|
||||
#include "private/bionic_auxv.h"
|
||||
#include "private/bionic_globals.h"
|
||||
#include "private/KernelArgumentBlock.h"
|
||||
#include "pthread_internal.h"
|
||||
|
||||
extern "C" int __set_tls(void* ptr);
|
||||
extern "C" int __set_tid_address(int* tid_address);
|
||||
|
||||
// Setup for the main thread. For dynamic executables, this is called by the
|
||||
// linker _before_ libc is mapped in memory. This means that all writes to
|
||||
// globals from this function will apply to linker-private copies and will not
|
||||
// be visible from libc later on.
|
||||
//
|
||||
// Note: this function creates a pthread_internal_t for the initial thread and
|
||||
// stores the pointer in TLS, but does not add it to pthread's thread list. This
|
||||
// has to be done later from libc itself (see __libc_init_common).
|
||||
//
|
||||
// This is in a file by itself because it needs to be built with
|
||||
// -fno-stack-protector because it's responsible for setting up the main
|
||||
// thread's TLS (which stack protector relies on).
|
||||
|
||||
void __libc_init_main_thread(KernelArgumentBlock& args) {
|
||||
__libc_auxv = args.auxv;
|
||||
|
||||
static pthread_internal_t main_thread;
|
||||
|
||||
// The -fstack-protector implementation uses TLS, so make sure that's
|
||||
// set up before we call any function that might get a stack check inserted.
|
||||
__set_tls(main_thread.tls);
|
||||
|
||||
// Tell the kernel to clear our tid field when we exit, so we're like any other pthread.
|
||||
// As a side-effect, this tells us our pid (which is the same as the main thread's tid).
|
||||
main_thread.tid = __set_tid_address(&main_thread.tid);
|
||||
main_thread.set_cached_pid(main_thread.tid);
|
||||
|
||||
// We don't want to free the main thread's stack even when the main thread exits
|
||||
// because things like environment variables with global scope live on it.
|
||||
// We also can't free the pthread_internal_t itself, since that lives on the main
|
||||
// thread's stack rather than on the heap.
|
||||
// The main thread has no mmap allocated space for stack or pthread_internal_t.
|
||||
main_thread.mmap_size = 0;
|
||||
pthread_attr_init(&main_thread.attr);
|
||||
main_thread.attr.guard_size = 0; // The main thread has no guard page.
|
||||
main_thread.attr.stack_size = 0; // User code should never see this; we'll compute it when asked.
|
||||
// TODO: the main thread's sched_policy and sched_priority need to be queried.
|
||||
|
||||
__init_thread(&main_thread);
|
||||
__init_tls(&main_thread);
|
||||
|
||||
// Store a pointer to the kernel argument block in a TLS slot to be
|
||||
// picked up by the libc constructor.
|
||||
main_thread.tls[TLS_SLOT_BIONIC_PREINIT] = &args;
|
||||
|
||||
__init_alternate_signal_stack(&main_thread);
|
||||
}
|
@ -34,25 +34,27 @@ constexpr char SYSTRACE_PROPERTY_NAME[] = "debug.atrace.tags.enableflags";
|
||||
|
||||
static Lock g_lock;
|
||||
static const prop_info* g_pinfo;
|
||||
static uint32_t g_property_serial = -1;
|
||||
static uint32_t g_property_area_serial = -1;
|
||||
static uint32_t g_serial = -1;
|
||||
static uint64_t g_tags;
|
||||
static int g_trace_marker_fd = -1;
|
||||
|
||||
static bool should_trace() {
|
||||
bool result = false;
|
||||
g_lock.lock();
|
||||
// debug.atrace.tags.enableflags is set to a safe non-tracing value during property
|
||||
// space initialization, so it should only be null in two cases, if there are
|
||||
// insufficient permissions for this process to access the property, in which
|
||||
// case an audit will be logged, and during boot before the property server has
|
||||
// been started, in which case we store the global property_area serial to prevent
|
||||
// the costly find operation until we see a changed property_area.
|
||||
if (!g_pinfo && g_property_area_serial != __system_property_area_serial()) {
|
||||
g_property_area_serial = __system_property_area_serial();
|
||||
// If g_pinfo is null, this means that systrace hasn't been run and it's safe to
|
||||
// assume that no trace writing will need to take place. However, to avoid running
|
||||
// this costly find check each time, we set it to a non-tracing value so that next
|
||||
// time, it will just check the serial to see if the value has been changed.
|
||||
// this function also deals with the bootup case, during which the call to property
|
||||
// set will fail if the property server hasn't yet started.
|
||||
if (g_pinfo == NULL) {
|
||||
g_pinfo = __system_property_find(SYSTRACE_PROPERTY_NAME);
|
||||
if (g_pinfo == NULL) {
|
||||
__system_property_set(SYSTRACE_PROPERTY_NAME, "0");
|
||||
g_pinfo = __system_property_find(SYSTRACE_PROPERTY_NAME);
|
||||
}
|
||||
if (g_pinfo) {
|
||||
}
|
||||
if (g_pinfo != NULL) {
|
||||
// Find out which tags have been enabled on the command line and set
|
||||
// the value of tags accordingly. If the value of the property changes,
|
||||
// the serial will also change, so the costly system_property_read function
|
||||
@ -60,11 +62,11 @@ static bool should_trace() {
|
||||
// first. The values within pinfo may change, but its location is guaranteed
|
||||
// not to move.
|
||||
uint32_t cur_serial = __system_property_serial(g_pinfo);
|
||||
if (cur_serial != g_property_serial) {
|
||||
g_property_serial = cur_serial;
|
||||
if (cur_serial != g_serial) {
|
||||
g_serial = cur_serial;
|
||||
char value[PROP_VALUE_MAX];
|
||||
__system_property_read(g_pinfo, 0, value);
|
||||
g_tags = strtoull(value, nullptr, 0);
|
||||
g_tags = strtoull(value, NULL, 0);
|
||||
}
|
||||
result = ((g_tags & ATRACE_TAG_BIONIC) != 0);
|
||||
}
|
||||
|
@ -52,12 +52,18 @@ void timeval_from_timespec(timeval& tv, const timespec& ts) {
|
||||
tv.tv_usec = ts.tv_nsec / 1000;
|
||||
}
|
||||
|
||||
void absolute_timespec_from_timespec(timespec& abs_ts, const timespec& ts, clockid_t clock) {
|
||||
clock_gettime(clock, &abs_ts);
|
||||
abs_ts.tv_sec += ts.tv_sec;
|
||||
abs_ts.tv_nsec += ts.tv_nsec;
|
||||
if (abs_ts.tv_nsec >= NS_PER_S) {
|
||||
abs_ts.tv_nsec -= NS_PER_S;
|
||||
abs_ts.tv_sec++;
|
||||
// Initializes 'ts' with the difference between 'abs_ts' and the current time
|
||||
// according to 'clock'. Returns false if abstime already expired, true otherwise.
|
||||
bool timespec_from_absolute_timespec(timespec& ts, const timespec& abs_ts, clockid_t clock) {
|
||||
clock_gettime(clock, &ts);
|
||||
ts.tv_sec = abs_ts.tv_sec - ts.tv_sec;
|
||||
ts.tv_nsec = abs_ts.tv_nsec - ts.tv_nsec;
|
||||
if (ts.tv_nsec < 0) {
|
||||
ts.tv_sec--;
|
||||
ts.tv_nsec += NS_PER_S;
|
||||
}
|
||||
if (ts.tv_nsec < 0 || ts.tv_sec < 0) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -36,15 +36,23 @@
|
||||
// struct __sfileext (see fileext.h).
|
||||
|
||||
void flockfile(FILE* fp) {
|
||||
if (fp != nullptr) {
|
||||
if (!__sdidinit) {
|
||||
__sinit();
|
||||
}
|
||||
|
||||
if (fp != NULL) {
|
||||
pthread_mutex_lock(&_FLOCK(fp));
|
||||
}
|
||||
}
|
||||
|
||||
int ftrylockfile(FILE* fp) {
|
||||
if (!__sdidinit) {
|
||||
__sinit();
|
||||
}
|
||||
|
||||
// The specification for ftrylockfile() says it returns 0 on success,
|
||||
// or non-zero on error. So return an errno code directly on error.
|
||||
if (fp == nullptr) {
|
||||
if (fp == NULL) {
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
@ -52,7 +60,11 @@ int ftrylockfile(FILE* fp) {
|
||||
}
|
||||
|
||||
void funlockfile(FILE* fp) {
|
||||
if (fp != nullptr) {
|
||||
if (!__sdidinit) {
|
||||
__sinit();
|
||||
}
|
||||
|
||||
if (fp != NULL) {
|
||||
pthread_mutex_unlock(&_FLOCK(fp));
|
||||
}
|
||||
}
|
||||
|
@ -1,241 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2015 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.
|
||||
*/
|
||||
|
||||
#include <ifaddrs.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <linux/netlink.h>
|
||||
#include <linux/rtnetlink.h>
|
||||
#include <net/if.h>
|
||||
#include <netinet/in.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
// The public ifaddrs struct is full of pointers. Rather than track several
|
||||
// different allocations, we use a maximally-sized structure with the public
|
||||
// part at offset 0, and pointers into its hidden tail.
|
||||
struct ifaddrs_storage {
|
||||
// Must come first, so that `ifaddrs_storage` is-a `ifaddrs`.
|
||||
ifaddrs ifa;
|
||||
|
||||
// The interface index, so we can match RTM_NEWADDR messages with
|
||||
// earlier RTM_NEWLINK messages (to copy the interface flags).
|
||||
int interface_index;
|
||||
|
||||
// Storage for the pointers in `ifa`.
|
||||
sockaddr_storage addr;
|
||||
sockaddr_storage netmask;
|
||||
sockaddr_storage ifa_ifu;
|
||||
char name[IFNAMSIZ + 1];
|
||||
|
||||
ifaddrs_storage(ifaddrs** list) {
|
||||
memset(this, 0, sizeof(*this));
|
||||
|
||||
// push_front onto `list`.
|
||||
ifa.ifa_next = *list;
|
||||
*list = reinterpret_cast<ifaddrs*>(this);
|
||||
}
|
||||
|
||||
// Netlink gives us the address family in the header, and the
|
||||
// sockaddr_in or sockaddr_in6 bytes as the payload. We need to
|
||||
// stitch the two bits together into the sockaddr that's part of
|
||||
// our portable interface.
|
||||
void SetAddress(int family, const void* data, size_t byteCount) {
|
||||
addr.ss_family = family;
|
||||
memcpy(SockaddrBytes(family, &addr), data, byteCount);
|
||||
ifa.ifa_addr = reinterpret_cast<sockaddr*>(&addr);
|
||||
}
|
||||
|
||||
void SetBroadcastAddress(int family, const void* data, size_t byteCount) {
|
||||
ifa_ifu.ss_family = family;
|
||||
memcpy(SockaddrBytes(family, &ifa_ifu), data, byteCount);
|
||||
ifa.ifa_dstaddr = reinterpret_cast<sockaddr*>(&ifa_ifu);
|
||||
}
|
||||
|
||||
// Netlink gives us the prefix length as a bit count. We need to turn
|
||||
// that into a BSD-compatible netmask represented by a sockaddr*.
|
||||
void SetNetmask(int family, size_t prefix_length) {
|
||||
// ...and work out the netmask from the prefix length.
|
||||
netmask.ss_family = family;
|
||||
uint8_t* dst = SockaddrBytes(family, &netmask);
|
||||
memset(dst, 0xff, prefix_length / 8);
|
||||
if ((prefix_length % 8) != 0) {
|
||||
dst[prefix_length/8] = (0xff << (8 - (prefix_length % 8)));
|
||||
}
|
||||
ifa.ifa_netmask = reinterpret_cast<sockaddr*>(&netmask);
|
||||
}
|
||||
|
||||
private:
|
||||
// Returns a pointer to the first byte in the address data (which is
|
||||
// stored in network byte order).
|
||||
uint8_t* SockaddrBytes(int family, sockaddr_storage* ss) {
|
||||
if (family == AF_INET) {
|
||||
sockaddr_in* ss4 = reinterpret_cast<sockaddr_in*>(ss);
|
||||
return reinterpret_cast<uint8_t*>(&ss4->sin_addr);
|
||||
} else if (family == AF_INET6) {
|
||||
sockaddr_in6* ss6 = reinterpret_cast<sockaddr_in6*>(ss);
|
||||
return reinterpret_cast<uint8_t*>(&ss6->sin6_addr);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
#if !defined(__clang__)
|
||||
// GCC gets confused by NLMSG_DATA and doesn't realize that the old-style
|
||||
// cast is from a system header and should be ignored.
|
||||
#pragma GCC diagnostic ignored "-Wold-style-cast"
|
||||
#endif
|
||||
|
||||
static void __handle_netlink_response(ifaddrs** out, nlmsghdr* hdr) {
|
||||
if (hdr->nlmsg_type == RTM_NEWLINK) {
|
||||
ifinfomsg* ifi = reinterpret_cast<ifinfomsg*>(NLMSG_DATA(hdr));
|
||||
|
||||
// Create a new ifaddr entry, and set the interface index and flags.
|
||||
ifaddrs_storage* new_addr = new ifaddrs_storage(out);
|
||||
new_addr->interface_index = ifi->ifi_index;
|
||||
new_addr->ifa.ifa_flags = ifi->ifi_flags;
|
||||
|
||||
// Go through the various bits of information and find the name.
|
||||
rtattr* rta = IFLA_RTA(ifi);
|
||||
size_t rta_len = IFLA_PAYLOAD(hdr);
|
||||
while (RTA_OK(rta, rta_len)) {
|
||||
if (rta->rta_type == IFLA_IFNAME) {
|
||||
if (RTA_PAYLOAD(rta) < sizeof(new_addr->name)) {
|
||||
memcpy(new_addr->name, RTA_DATA(rta), RTA_PAYLOAD(rta));
|
||||
new_addr->ifa.ifa_name = new_addr->name;
|
||||
}
|
||||
}
|
||||
rta = RTA_NEXT(rta, rta_len);
|
||||
}
|
||||
} else if (hdr->nlmsg_type == RTM_NEWADDR) {
|
||||
ifaddrmsg* msg = reinterpret_cast<ifaddrmsg*>(NLMSG_DATA(hdr));
|
||||
|
||||
// We should already know about this from an RTM_NEWLINK message.
|
||||
ifaddrs_storage* addr = reinterpret_cast<ifaddrs_storage*>(*out);
|
||||
while (addr != nullptr && addr->interface_index != static_cast<int>(msg->ifa_index)) {
|
||||
addr = reinterpret_cast<ifaddrs_storage*>(addr->ifa.ifa_next);
|
||||
}
|
||||
// If this is an unknown interface, ignore whatever we're being told about it.
|
||||
if (addr == nullptr) return;
|
||||
|
||||
// Create a new ifaddr entry and copy what we already know.
|
||||
ifaddrs_storage* new_addr = new ifaddrs_storage(out);
|
||||
// We can just copy the name rather than look for IFA_LABEL.
|
||||
strcpy(new_addr->name, addr->name);
|
||||
new_addr->ifa.ifa_name = new_addr->name;
|
||||
new_addr->ifa.ifa_flags = addr->ifa.ifa_flags;
|
||||
new_addr->interface_index = addr->interface_index;
|
||||
|
||||
// Go through the various bits of information and find the address
|
||||
// and any broadcast/destination address.
|
||||
rtattr* rta = IFA_RTA(msg);
|
||||
size_t rta_len = IFA_PAYLOAD(hdr);
|
||||
while (RTA_OK(rta, rta_len)) {
|
||||
if (rta->rta_type == IFA_ADDRESS) {
|
||||
if (msg->ifa_family == AF_INET || msg->ifa_family == AF_INET6) {
|
||||
addr->SetAddress(msg->ifa_family, RTA_DATA(rta), RTA_PAYLOAD(rta));
|
||||
addr->SetNetmask(msg->ifa_family, msg->ifa_prefixlen);
|
||||
}
|
||||
} else if (rta->rta_type == IFA_BROADCAST) {
|
||||
if (msg->ifa_family == AF_INET || msg->ifa_family == AF_INET6) {
|
||||
addr->SetBroadcastAddress(msg->ifa_family, RTA_DATA(rta), RTA_PAYLOAD(rta));
|
||||
}
|
||||
}
|
||||
rta = RTA_NEXT(rta, rta_len);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static bool __send_netlink_request(int fd, int type) {
|
||||
struct NetlinkMessage {
|
||||
nlmsghdr hdr;
|
||||
rtgenmsg msg;
|
||||
} request;
|
||||
memset(&request, 0, sizeof(request));
|
||||
request.hdr.nlmsg_flags = NLM_F_DUMP | NLM_F_REQUEST;
|
||||
request.hdr.nlmsg_type = type;
|
||||
request.hdr.nlmsg_len = sizeof(request);
|
||||
request.msg.rtgen_family = AF_UNSPEC; // All families.
|
||||
return (TEMP_FAILURE_RETRY(send(fd, &request, sizeof(request), 0)) == sizeof(request));
|
||||
}
|
||||
|
||||
static bool __read_netlink_responses(int fd, ifaddrs** out, char* buf, size_t buf_len) {
|
||||
ssize_t bytes_read;
|
||||
// Read through all the responses, handing interesting ones to __handle_netlink_response.
|
||||
while ((bytes_read = TEMP_FAILURE_RETRY(recv(fd, buf, buf_len, 0))) > 0) {
|
||||
nlmsghdr* hdr = reinterpret_cast<nlmsghdr*>(buf);
|
||||
for (; NLMSG_OK(hdr, static_cast<size_t>(bytes_read)); hdr = NLMSG_NEXT(hdr, bytes_read)) {
|
||||
if (hdr->nlmsg_type == NLMSG_DONE) return true;
|
||||
if (hdr->nlmsg_type == NLMSG_ERROR) return false;
|
||||
__handle_netlink_response(out, hdr);
|
||||
}
|
||||
}
|
||||
// We only get here if recv fails before we see a NLMSG_DONE.
|
||||
return false;
|
||||
}
|
||||
|
||||
int getifaddrs(ifaddrs** out) {
|
||||
// Make cleanup easy.
|
||||
*out = nullptr;
|
||||
|
||||
// The kernel keeps packets under 8KiB (NLMSG_GOODSIZE),
|
||||
// but that's a bit too large to go on the stack.
|
||||
size_t buf_len = 8192;
|
||||
char* buf = new char[buf_len];
|
||||
if (buf == nullptr) return -1;
|
||||
|
||||
// Open the netlink socket and ask for all the links and addresses.
|
||||
int fd = socket(PF_NETLINK, SOCK_RAW | SOCK_CLOEXEC, NETLINK_ROUTE);
|
||||
bool okay = fd != -1 &&
|
||||
__send_netlink_request(fd, RTM_GETLINK) && __read_netlink_responses(fd, out, buf, buf_len) &&
|
||||
__send_netlink_request(fd, RTM_GETADDR) && __read_netlink_responses(fd, out, buf, buf_len);
|
||||
|
||||
if (!okay) {
|
||||
freeifaddrs(*out);
|
||||
// Ensure that callers crash if they forget to check for success.
|
||||
*out = nullptr;
|
||||
}
|
||||
{
|
||||
int saved_errno = errno;
|
||||
close(fd);
|
||||
delete[] buf;
|
||||
errno = saved_errno;
|
||||
}
|
||||
return okay ? 0 : -1;
|
||||
}
|
||||
|
||||
void freeifaddrs(ifaddrs* list) {
|
||||
while (list != nullptr) {
|
||||
ifaddrs* current = list;
|
||||
list = list->ifa_next;
|
||||
free(current);
|
||||
}
|
||||
}
|
@ -25,16 +25,19 @@
|
||||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/ioctl.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
extern "C" int __ioctl(int, int, void *);
|
||||
extern int __ioctl(int, int, void *);
|
||||
|
||||
int ioctl(int fd, int request, ...) {
|
||||
int ioctl(int fd, int request, ...)
|
||||
{
|
||||
va_list ap;
|
||||
void * arg;
|
||||
|
||||
va_start(ap, request);
|
||||
void* arg = va_arg(ap, void*);
|
||||
arg = va_arg(ap, void *);
|
||||
va_end(ap);
|
||||
|
||||
return __ioctl(fd, request, arg);
|
||||
}
|
||||
|
@ -52,6 +52,8 @@
|
||||
|
||||
extern "C" abort_msg_t** __abort_message_ptr;
|
||||
extern "C" int __system_properties_init(void);
|
||||
extern "C" int __set_tls(void* ptr);
|
||||
extern "C" int __set_tid_address(int* tid_address);
|
||||
|
||||
__LIBC_HIDDEN__ WriteProtected<libc_globals> __libc_globals;
|
||||
|
||||
@ -64,11 +66,50 @@ char** environ;
|
||||
// Declared in "private/bionic_ssp.h".
|
||||
uintptr_t __stack_chk_guard = 0;
|
||||
|
||||
// Setup for the main thread. For dynamic executables, this is called by the
|
||||
// linker _before_ libc is mapped in memory. This means that all writes to
|
||||
// globals from this function will apply to linker-private copies and will not
|
||||
// be visible from libc later on.
|
||||
//
|
||||
// Note: this function creates a pthread_internal_t for the initial thread and
|
||||
// stores the pointer in TLS, but does not add it to pthread's thread list. This
|
||||
// has to be done later from libc itself (see __libc_init_common).
|
||||
void __libc_init_main_thread(KernelArgumentBlock& args) {
|
||||
__libc_auxv = args.auxv;
|
||||
|
||||
static pthread_internal_t main_thread;
|
||||
|
||||
// Tell the kernel to clear our tid field when we exit, so we're like any other pthread.
|
||||
// As a side-effect, this tells us our pid (which is the same as the main thread's tid).
|
||||
main_thread.tid = __set_tid_address(&main_thread.tid);
|
||||
main_thread.set_cached_pid(main_thread.tid);
|
||||
|
||||
// We don't want to free the main thread's stack even when the main thread exits
|
||||
// because things like environment variables with global scope live on it.
|
||||
// We also can't free the pthread_internal_t itself, since that lives on the main
|
||||
// thread's stack rather than on the heap.
|
||||
// The main thread has no mmap allocated space for stack or pthread_internal_t.
|
||||
main_thread.mmap_size = 0;
|
||||
pthread_attr_init(&main_thread.attr);
|
||||
main_thread.attr.guard_size = 0; // The main thread has no guard page.
|
||||
main_thread.attr.stack_size = 0; // User code should never see this; we'll compute it when asked.
|
||||
// TODO: the main thread's sched_policy and sched_priority need to be queried.
|
||||
|
||||
__init_thread(&main_thread);
|
||||
__init_tls(&main_thread);
|
||||
__set_tls(main_thread.tls);
|
||||
|
||||
// Store a pointer to the kernel argument block in a TLS slot to be
|
||||
// picked up by the libc constructor.
|
||||
main_thread.tls[TLS_SLOT_BIONIC_PREINIT] = &args;
|
||||
|
||||
__init_alternate_signal_stack(&main_thread);
|
||||
}
|
||||
|
||||
void __libc_init_globals(KernelArgumentBlock& args) {
|
||||
// Initialize libc globals that are needed in both the linker and in libc.
|
||||
// In dynamic binaries, this is run at least twice for different copies of the
|
||||
// globals, once for the linker's copy and once for the one in libc.so.
|
||||
__libc_auxv = args.auxv;
|
||||
__libc_globals.initialize();
|
||||
__libc_globals.mutate([&args](libc_globals* globals) {
|
||||
__libc_init_vdso(globals, args);
|
||||
@ -80,6 +121,7 @@ void __libc_init_common(KernelArgumentBlock& args) {
|
||||
// Initialize various globals.
|
||||
environ = args.envp;
|
||||
errno = 0;
|
||||
__libc_auxv = args.auxv;
|
||||
__progname = args.argv[0] ? args.argv[0] : "<unknown>";
|
||||
__abort_message_ptr = args.abort_message_ptr;
|
||||
|
||||
@ -203,11 +245,7 @@ static bool __is_valid_environment_variable(const char* name) {
|
||||
}
|
||||
|
||||
static bool __is_unsafe_environment_variable(const char* name) {
|
||||
// None of these should be allowed when the AT_SECURE auxv
|
||||
// flag is set. This flag is set to inform userspace that a
|
||||
// security transition has occurred, for example, as a result
|
||||
// of executing a setuid program or the result of an SELinux
|
||||
// security transition.
|
||||
// None of these should be allowed in setuid programs.
|
||||
static constexpr const char* UNSAFE_VARIABLE_NAMES[] = {
|
||||
"GCONV_PATH",
|
||||
"GETCONF_DIR",
|
||||
@ -291,7 +329,7 @@ void __libc_init_AT_SECURE(KernelArgumentBlock& args) {
|
||||
|
||||
if (getauxval(AT_SECURE)) {
|
||||
// If this is a setuid/setgid program, close the security hole described in
|
||||
// https://www.freebsd.org/security/advisories/FreeBSD-SA-02:23.stdio.asc
|
||||
// ftp://ftp.freebsd.org/pub/FreeBSD/CERT/advisories/FreeBSD-SA-02:23.stdio.asc
|
||||
__nullify_closed_stdio();
|
||||
|
||||
__sanitize_environment_variables(args.envp);
|
||||
|
@ -25,7 +25,6 @@
|
||||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* libc_init_dynamic.c
|
||||
*
|
||||
|
@ -25,6 +25,17 @@
|
||||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
/*
|
||||
* libc_init_static.c
|
||||
*
|
||||
* The program startup function __libc_init() defined here is
|
||||
* used for static executables only (i.e. those that don't depend
|
||||
* on shared libraries). It is called from arch-$ARCH/bionic/crtbegin_static.S
|
||||
* which is directly invoked by the kernel when the program is launched.
|
||||
*
|
||||
* The 'structors' parameter contains pointers to various initializer
|
||||
* arrays that must be run before the program's 'main' routine is launched.
|
||||
*/
|
||||
|
||||
#include <elf.h>
|
||||
#include <errno.h>
|
||||
@ -68,19 +79,12 @@ static void apply_gnu_relro() {
|
||||
}
|
||||
}
|
||||
|
||||
// The program startup function __libc_init() defined here is
|
||||
// used for static executables only (i.e. those that don't depend
|
||||
// on shared libraries). It is called from arch-$ARCH/bionic/crtbegin_static.S
|
||||
// which is directly invoked by the kernel when the program is launched.
|
||||
//
|
||||
// The 'structors' parameter contains pointers to various initializer
|
||||
// arrays that must be run before the program's 'main' routine is launched.
|
||||
|
||||
__noreturn void __libc_init(void* raw_args,
|
||||
void (*onexit)(void) __unused,
|
||||
int (*slingshot)(int, char**, char**),
|
||||
structors_array_t const * const structors) {
|
||||
KernelArgumentBlock args(raw_args);
|
||||
|
||||
__libc_init_main_thread(args);
|
||||
|
||||
// Initializing the globals requires TLS to be available for errno.
|
||||
|
@ -31,7 +31,6 @@
|
||||
|
||||
#include <android/set_abort_message.h>
|
||||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <pthread.h>
|
||||
@ -47,9 +46,6 @@
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define _REALLY_INCLUDE_SYS__SYSTEM_PROPERTIES_H_
|
||||
#include <sys/_system_properties.h>
|
||||
|
||||
static pthread_mutex_t g_abort_msg_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
__LIBC_HIDDEN__ abort_msg_t** __abort_message_ptr; // Accessible to __libc_init_common.
|
||||
@ -485,64 +481,6 @@ static int __libc_open_log_socket() {
|
||||
return log_fd;
|
||||
}
|
||||
|
||||
struct cache {
|
||||
const prop_info* pinfo;
|
||||
uint32_t serial;
|
||||
char c;
|
||||
};
|
||||
|
||||
static void refresh_cache(struct cache *cache, const char *key)
|
||||
{
|
||||
if (!cache->pinfo) {
|
||||
cache->pinfo = __system_property_find(key);
|
||||
if (!cache->pinfo) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
uint32_t serial = __system_property_serial(cache->pinfo);
|
||||
if (serial == cache->serial) {
|
||||
return;
|
||||
}
|
||||
cache->serial = serial;
|
||||
|
||||
char buf[PROP_VALUE_MAX];
|
||||
__system_property_read(cache->pinfo, 0, buf);
|
||||
cache->c = buf[0];
|
||||
}
|
||||
|
||||
// Timestamp state generally remains constant, since a change is
|
||||
// rare, we can accept a trylock failure gracefully.
|
||||
static pthread_mutex_t lock_clockid = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
static clockid_t __android_log_clockid()
|
||||
{
|
||||
static struct cache r_time_cache = { NULL, static_cast<uint32_t>(-1), 0 };
|
||||
static struct cache p_time_cache = { NULL, static_cast<uint32_t>(-1), 0 };
|
||||
char c;
|
||||
|
||||
if (pthread_mutex_trylock(&lock_clockid)) {
|
||||
// We are willing to accept some race in this context
|
||||
if (!(c = p_time_cache.c)) {
|
||||
c = r_time_cache.c;
|
||||
}
|
||||
} else {
|
||||
static uint32_t serial;
|
||||
uint32_t current_serial = __system_property_area_serial();
|
||||
if (current_serial != serial) {
|
||||
refresh_cache(&r_time_cache, "ro.logd.timestamp");
|
||||
refresh_cache(&p_time_cache, "persist.logd.timestamp");
|
||||
serial = current_serial;
|
||||
}
|
||||
if (!(c = p_time_cache.c)) {
|
||||
c = r_time_cache.c;
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&lock_clockid);
|
||||
}
|
||||
|
||||
return (tolower(c) == 'm') ? CLOCK_MONOTONIC : CLOCK_REALTIME;
|
||||
}
|
||||
|
||||
struct log_time { // Wire format
|
||||
uint32_t tv_sec;
|
||||
uint32_t tv_nsec;
|
||||
@ -563,7 +501,7 @@ static int __libc_write_log(int priority, const char* tag, const char* msg) {
|
||||
vec[1].iov_base = &tid;
|
||||
vec[1].iov_len = sizeof(tid);
|
||||
timespec ts;
|
||||
clock_gettime(__android_log_clockid(), &ts);
|
||||
clock_gettime(CLOCK_REALTIME, &ts);
|
||||
log_time realtime_ts;
|
||||
realtime_ts.tv_sec = ts.tv_sec;
|
||||
realtime_ts.tv_nsec = ts.tv_nsec;
|
||||
@ -606,7 +544,7 @@ static int __libc_android_log_event(int32_t tag, char type, const void* payload,
|
||||
vec[1].iov_base = &tid;
|
||||
vec[1].iov_len = sizeof(tid);
|
||||
timespec ts;
|
||||
clock_gettime(__android_log_clockid(), &ts);
|
||||
clock_gettime(CLOCK_REALTIME, &ts);
|
||||
log_time realtime_ts;
|
||||
realtime_ts.tv_sec = ts.tv_sec;
|
||||
realtime_ts.tv_nsec = ts.tv_nsec;
|
||||
|
@ -27,7 +27,6 @@
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdint.h>
|
||||
#include <sys/mman.h>
|
||||
#include <unistd.h>
|
||||
|
||||
@ -49,19 +48,15 @@ void* mmap64(void* addr, size_t size, int prot, int flags, int fd, off64_t offse
|
||||
|
||||
// prevent allocations large enough for `end - start` to overflow
|
||||
size_t rounded = BIONIC_ALIGN(size, PAGE_SIZE);
|
||||
if (rounded < size || rounded > PTRDIFF_MAX) {
|
||||
if (rounded < size || size > PTRDIFF_MAX) {
|
||||
errno = ENOMEM;
|
||||
return MAP_FAILED;
|
||||
}
|
||||
|
||||
bool is_private_anonymous =
|
||||
(flags & (MAP_PRIVATE | MAP_ANONYMOUS)) == (MAP_PRIVATE | MAP_ANONYMOUS);
|
||||
bool is_stack_or_grows_down = (flags & (MAP_STACK | MAP_GROWSDOWN)) != 0;
|
||||
|
||||
bool is_private_anonymous = (flags & (MAP_PRIVATE | MAP_ANONYMOUS)) != 0;
|
||||
void* result = __mmap2(addr, size, prot, flags, fd, offset >> MMAP2_SHIFT);
|
||||
|
||||
if (result != MAP_FAILED && kernel_has_MADV_MERGEABLE &&
|
||||
is_private_anonymous && !is_stack_or_grows_down) {
|
||||
if (result != MAP_FAILED && kernel_has_MADV_MERGEABLE && is_private_anonymous) {
|
||||
ErrnoRestorer errno_restorer;
|
||||
int rc = madvise(result, size, MADV_MERGEABLE);
|
||||
if (rc == -1 && errno == EINVAL) {
|
||||
|
@ -1,57 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2015 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.
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <sys/mman.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "private/bionic_macros.h"
|
||||
|
||||
extern "C" void* ___mremap(void*, size_t, size_t, int, void*);
|
||||
|
||||
void* mremap(void* old_address, size_t old_size, size_t new_size, int flags, ...) {
|
||||
// prevent allocations large enough for `end - start` to overflow
|
||||
size_t rounded = BIONIC_ALIGN(new_size, PAGE_SIZE);
|
||||
if (rounded < new_size || rounded > PTRDIFF_MAX) {
|
||||
errno = ENOMEM;
|
||||
return MAP_FAILED;
|
||||
}
|
||||
|
||||
void* new_address = nullptr;
|
||||
// The optional argument is only valid if the MREMAP_FIXED flag is set,
|
||||
// so we assume it's not present otherwise.
|
||||
if ((flags & MREMAP_FIXED) != 0) {
|
||||
va_list ap;
|
||||
va_start(ap, flags);
|
||||
new_address = va_arg(ap, void*);
|
||||
va_end(ap);
|
||||
}
|
||||
return ___mremap(old_address, old_size, new_size, flags, new_address);
|
||||
}
|
@ -47,34 +47,37 @@
|
||||
|
||||
#include "private/libc_logging.h"
|
||||
|
||||
extern "C" {
|
||||
// Brillo doesn't need to support any legacy cruft.
|
||||
#if !defined(__BRILLO__)
|
||||
|
||||
// Brillo and LP64 don't need to support any legacy cruft.
|
||||
#if !defined(__BRILLO__) && !defined(__LP64__)
|
||||
// Most of the cruft is only for 32-bit Android targets.
|
||||
#if !defined(__LP64__)
|
||||
|
||||
// These were accidentally declared in <unistd.h> because we stupidly used to inline
|
||||
// getpagesize() and __getpageshift(). Needed for backwards compatibility with old NDK apps.
|
||||
extern "C" {
|
||||
unsigned int __page_size = PAGE_SIZE;
|
||||
unsigned int __page_shift = 12;
|
||||
}
|
||||
|
||||
// TODO: remove this backward compatibility hack (for jb-mr1 strace binaries).
|
||||
pid_t __wait4(pid_t pid, int* status, int options, struct rusage* rusage) {
|
||||
extern "C" pid_t __wait4(pid_t pid, int* status, int options, struct rusage* rusage) {
|
||||
return wait4(pid, status, options, rusage);
|
||||
}
|
||||
|
||||
// TODO: does anything still need this?
|
||||
int __open() {
|
||||
extern "C" int __open() {
|
||||
abort();
|
||||
}
|
||||
|
||||
// TODO: does anything still need this?
|
||||
void** __get_tls() {
|
||||
extern "C" void** __get_tls() {
|
||||
#include "private/__get_tls.h"
|
||||
return __get_tls();
|
||||
}
|
||||
|
||||
// This non-standard function was in our <string.h> for some reason.
|
||||
void memswap(void* m1, void* m2, size_t n) {
|
||||
extern "C" void memswap(void* m1, void* m2, size_t n) {
|
||||
char* p = reinterpret_cast<char*>(m1);
|
||||
char* p_end = p + n;
|
||||
char* q = reinterpret_cast<char*>(m2);
|
||||
@ -87,13 +90,13 @@ void memswap(void* m1, void* m2, size_t n) {
|
||||
}
|
||||
}
|
||||
|
||||
int pthread_attr_setstackaddr(pthread_attr_t*, void*) {
|
||||
extern "C" int pthread_attr_setstackaddr(pthread_attr_t*, void*) {
|
||||
// This was removed from POSIX.1-2008, and is not implemented on bionic.
|
||||
// Needed for ABI compatibility with the NDK.
|
||||
return ENOSYS;
|
||||
}
|
||||
|
||||
int pthread_attr_getstackaddr(const pthread_attr_t* attr, void** stack_addr) {
|
||||
extern "C" int pthread_attr_getstackaddr(const pthread_attr_t* attr, void** stack_addr) {
|
||||
// This was removed from POSIX.1-2008.
|
||||
// Needed for ABI compatibility with the NDK.
|
||||
*stack_addr = (char*)attr->stack_base + attr->stack_size;
|
||||
@ -101,7 +104,7 @@ int pthread_attr_getstackaddr(const pthread_attr_t* attr, void** stack_addr) {
|
||||
}
|
||||
|
||||
// Non-standard cruft that should only ever have been in system/core/toolbox.
|
||||
char* strtotimeval(const char* str, struct timeval* ts) {
|
||||
extern "C" char* strtotimeval(const char* str, struct timeval* ts) {
|
||||
char* s;
|
||||
ts->tv_sec = strtoumax(str, &s, 10);
|
||||
|
||||
@ -143,7 +146,7 @@ static inline int digitval(int ch) {
|
||||
}
|
||||
|
||||
// This non-standard function was in our <inttypes.h> for some reason.
|
||||
uintmax_t strntoumax(const char *nptr, char **endptr, int base, size_t n) {
|
||||
extern "C" uintmax_t strntoumax(const char *nptr, char **endptr, int base, size_t n) {
|
||||
const unsigned char* p = (const unsigned char *)nptr;
|
||||
const unsigned char* end = p + n;
|
||||
int minus = 0;
|
||||
@ -191,12 +194,12 @@ uintmax_t strntoumax(const char *nptr, char **endptr, int base, size_t n) {
|
||||
}
|
||||
|
||||
// This non-standard function was in our <inttypes.h> for some reason.
|
||||
intmax_t strntoimax(const char* nptr, char** endptr, int base, size_t n) {
|
||||
extern "C" intmax_t strntoimax(const char* nptr, char** endptr, int base, size_t n) {
|
||||
return (intmax_t) strntoumax(nptr, endptr, base, n);
|
||||
}
|
||||
|
||||
// POSIX calls this dprintf, but LP32 Android had fdprintf instead.
|
||||
int fdprintf(int fd, const char* fmt, ...) {
|
||||
extern "C" int fdprintf(int fd, const char* fmt, ...) {
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
int rc = vdprintf(fd, fmt, ap);
|
||||
@ -205,7 +208,7 @@ int fdprintf(int fd, const char* fmt, ...) {
|
||||
}
|
||||
|
||||
// POSIX calls this vdprintf, but LP32 Android had fdprintf instead.
|
||||
int vfdprintf(int fd, const char* fmt, va_list ap) {
|
||||
extern "C" int vfdprintf(int fd, const char* fmt, va_list ap) {
|
||||
return vdprintf(fd, fmt, ap);
|
||||
}
|
||||
|
||||
@ -216,64 +219,64 @@ int vfdprintf(int fd, const char* fmt, va_list ap) {
|
||||
#undef __futex_wait
|
||||
|
||||
// This used to be in <sys/atomics.h>.
|
||||
int __futex_wake(volatile void* ftx, int count) {
|
||||
extern "C" int __futex_wake(volatile void* ftx, int count) {
|
||||
return __real_futex_wake(ftx, count);
|
||||
}
|
||||
|
||||
// This used to be in <sys/atomics.h>.
|
||||
int __futex_wait(volatile void* ftx, int value, const struct timespec* timeout) {
|
||||
extern "C" int __futex_wait(volatile void* ftx, int value, const struct timespec* timeout) {
|
||||
return __real_futex_wait(ftx, value, timeout);
|
||||
}
|
||||
|
||||
// Unity's libmono uses this.
|
||||
int tkill(pid_t tid, int sig) {
|
||||
extern "C" int tkill(pid_t tid, int sig) {
|
||||
return syscall(__NR_tkill, tid, sig);
|
||||
}
|
||||
|
||||
// This was removed from POSIX 2008.
|
||||
wchar_t* wcswcs(wchar_t* haystack, wchar_t* needle) {
|
||||
extern "C" wchar_t* wcswcs(wchar_t* haystack, wchar_t* needle) {
|
||||
return wcsstr(haystack, needle);
|
||||
}
|
||||
|
||||
// This was removed from POSIX 2008.
|
||||
sighandler_t bsd_signal(int signum, sighandler_t handler) {
|
||||
extern "C" sighandler_t bsd_signal(int signum, sighandler_t handler) {
|
||||
return signal(signum, handler);
|
||||
}
|
||||
|
||||
#if !defined(__i386__)
|
||||
// This was removed from POSIX 2008.
|
||||
#undef bcopy
|
||||
void bcopy(const void* src, void* dst, size_t n) {
|
||||
memmove(dst, src, n);
|
||||
extern "C" void bcopy(const void* src, void* dst, size_t n) {
|
||||
memcpy(dst, src, n);
|
||||
}
|
||||
#else
|
||||
// x86 has an assembler implementation.
|
||||
#endif
|
||||
|
||||
// sysv_signal() was never in POSIX.
|
||||
extern "C++" sighandler_t _signal(int signum, sighandler_t handler, int flags);
|
||||
sighandler_t sysv_signal(int signum, sighandler_t handler) {
|
||||
extern sighandler_t _signal(int signum, sighandler_t handler, int flags);
|
||||
extern "C" sighandler_t sysv_signal(int signum, sighandler_t handler) {
|
||||
return _signal(signum, handler, SA_RESETHAND);
|
||||
}
|
||||
|
||||
// This is a system call that was never in POSIX. Use readdir(3) instead.
|
||||
int __getdents64(unsigned int, dirent*, unsigned int);
|
||||
int getdents(unsigned int fd, dirent* dirp, unsigned int count) {
|
||||
extern "C" int __getdents64(unsigned int, dirent*, unsigned int);
|
||||
extern "C" int getdents(unsigned int fd, dirent* dirp, unsigned int count) {
|
||||
return __getdents64(fd, dirp, count);
|
||||
}
|
||||
|
||||
// This is a BSDism that we never implemented correctly. Used by Firefox.
|
||||
int issetugid() {
|
||||
extern "C" int issetugid() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// This was removed from POSIX 2004.
|
||||
pid_t wait3(int* status, int options, struct rusage* rusage) {
|
||||
extern "C" pid_t wait3(int* status, int options, struct rusage* rusage) {
|
||||
return wait4(-1, status, options, rusage);
|
||||
}
|
||||
|
||||
// This was removed from POSIX 2004.
|
||||
int getdtablesize() {
|
||||
extern "C" int getdtablesize() {
|
||||
struct rlimit r;
|
||||
|
||||
if (getrlimit(RLIMIT_NOFILE, &r) < 0) {
|
||||
@ -283,10 +286,6 @@ int getdtablesize() {
|
||||
return r.rlim_cur;
|
||||
}
|
||||
|
||||
// A leaked BSD stdio implementation detail that's now a no-op.
|
||||
void __sinit() {}
|
||||
int __sdidinit = 1;
|
||||
|
||||
// Only used by ftime, which was removed from POSIX 2008.
|
||||
struct timeb {
|
||||
time_t time;
|
||||
@ -296,7 +295,7 @@ struct timeb {
|
||||
};
|
||||
|
||||
// This was removed from POSIX 2008.
|
||||
int ftime(struct timeb* tb) {
|
||||
extern "C" int ftime(struct timeb* tb) {
|
||||
struct timeval tv;
|
||||
struct timezone tz;
|
||||
|
||||
@ -318,42 +317,35 @@ int ftime(struct timeb* tb) {
|
||||
}
|
||||
|
||||
// This was removed from POSIX 2008.
|
||||
char* index(const char* str, int ch) {
|
||||
extern "C" char* index(const char* str, int ch) {
|
||||
return strchr(str, ch);
|
||||
}
|
||||
|
||||
// This was removed from BSD.
|
||||
void arc4random_stir(void) {
|
||||
extern "C" void arc4random_stir(void) {
|
||||
// The current implementation stirs itself as needed.
|
||||
}
|
||||
|
||||
// This was removed from BSD.
|
||||
void arc4random_addrandom(unsigned char*, int) {
|
||||
extern "C" void arc4random_addrandom(unsigned char*, int) {
|
||||
// The current implementation adds randomness as needed.
|
||||
}
|
||||
|
||||
// Old versions of the NDK did not export malloc_usable_size, but did
|
||||
// export dlmalloc_usable_size. We are moving away from dlmalloc in L
|
||||
// so make this call malloc_usable_size.
|
||||
size_t dlmalloc_usable_size(void* ptr) {
|
||||
extern "C" size_t dlmalloc_usable_size(void* ptr) {
|
||||
return malloc_usable_size(ptr);
|
||||
}
|
||||
|
||||
// In L we added a public pthread_gettid_np, but some apps were using the private API.
|
||||
pid_t __pthread_gettid_libc(pthread_t t) {
|
||||
extern "C" pid_t __pthread_gettid(pthread_t t) {
|
||||
return pthread_gettid_np(t);
|
||||
}
|
||||
|
||||
pid_t __pthread_gettid_libc_private(pthread_t t) {
|
||||
return pthread_gettid_np(t);
|
||||
}
|
||||
|
||||
__asm__(".symver __pthread_gettid_libc,__pthread_gettid@LIBC");
|
||||
__asm__(".symver __pthread_gettid_libc_private,__pthread_gettid@@LIBC_PRIVATE");
|
||||
|
||||
// Older versions of apportable used dlmalloc directly instead of malloc,
|
||||
// so export this compatibility shim that simply calls malloc.
|
||||
void* dlmalloc(size_t size) {
|
||||
extern "C" void* dlmalloc(size_t size) {
|
||||
return malloc(size);
|
||||
}
|
||||
|
||||
@ -361,39 +353,39 @@ void* dlmalloc(size_t size) {
|
||||
#include "pthread_internal.h"
|
||||
#undef __get_thread
|
||||
// Various third-party apps contain a backport of our pthread_rwlock implementation that uses this.
|
||||
pthread_internal_t* __get_thread() {
|
||||
extern "C" pthread_internal_t* __get_thread() {
|
||||
return __real_get_thread();
|
||||
}
|
||||
|
||||
// This one exists only for the LP32 NDK and is not present anywhere else.
|
||||
extern long __set_errno_internal(int);
|
||||
long __set_errno(int n) {
|
||||
extern "C" long __set_errno_internal(int);
|
||||
extern "C" long __set_errno(int n) {
|
||||
return __set_errno_internal(n);
|
||||
}
|
||||
|
||||
#endif // !defined(__LP64__)
|
||||
|
||||
// This was never implemented in bionic, only needed for ABI compatibility with the NDK.
|
||||
// In the M time frame, over 1000 apps have a reference to this!
|
||||
void endpwent() { }
|
||||
extern "C" void endpwent() { }
|
||||
|
||||
// Since dlmalloc_inspect_all and dlmalloc_trim are exported for systems
|
||||
// that use dlmalloc, be consistent and export them everywhere.
|
||||
#if defined(USE_JEMALLOC)
|
||||
void dlmalloc_inspect_all(void (*)(void*, void*, size_t, void*), void*) {
|
||||
extern "C" void dlmalloc_inspect_all(void (*)(void*, void*, size_t, void*), void*) {
|
||||
}
|
||||
int dlmalloc_trim(size_t) {
|
||||
extern "C" int dlmalloc_trim(size_t) {
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
void dlmalloc_inspect_all_real(void (*)(void*, void*, size_t, void*), void*);
|
||||
void dlmalloc_inspect_all(void (*handler)(void*, void*, size_t, void*), void* arg) {
|
||||
extern "C" void dlmalloc_inspect_all_real(void (*)(void*, void*, size_t, void*), void*);
|
||||
extern "C" void dlmalloc_inspect_all(void (*handler)(void*, void*, size_t, void*), void* arg) {
|
||||
dlmalloc_inspect_all_real(handler, arg);
|
||||
}
|
||||
int dlmalloc_trim_real(size_t);
|
||||
int dlmalloc_trim(size_t pad) {
|
||||
extern "C" int dlmalloc_trim_real(size_t);
|
||||
extern "C" int dlmalloc_trim(size_t pad) {
|
||||
return dlmalloc_trim_real(pad);
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // !defined(__BRILLO__) && !defined (__LP64__)
|
||||
|
||||
} // extern "C"
|
||||
#endif // !defined(__BRILLO__)
|
||||
|
@ -45,7 +45,7 @@ struct atfork_t {
|
||||
|
||||
class atfork_list_t {
|
||||
public:
|
||||
constexpr atfork_list_t() : first_(nullptr), last_(nullptr) {}
|
||||
atfork_list_t() : first_(nullptr), last_(nullptr) {}
|
||||
|
||||
template<typename F>
|
||||
void walk_forward(F f) {
|
||||
|
@ -1,183 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2015 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.
|
||||
*/
|
||||
|
||||
#include <pthread.h>
|
||||
#include <stdatomic.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "private/bionic_futex.h"
|
||||
|
||||
int pthread_barrierattr_init(pthread_barrierattr_t* attr) {
|
||||
*attr = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pthread_barrierattr_destroy(pthread_barrierattr_t* attr) {
|
||||
*attr = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pthread_barrierattr_getpshared(pthread_barrierattr_t* attr, int* pshared) {
|
||||
*pshared = (*attr & 1) ? PTHREAD_PROCESS_SHARED : PTHREAD_PROCESS_PRIVATE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pthread_barrierattr_setpshared(pthread_barrierattr_t* attr, int pshared) {
|
||||
if (pshared == PTHREAD_PROCESS_SHARED) {
|
||||
*attr |= 1;
|
||||
} else {
|
||||
*attr &= ~1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
enum BarrierState {
|
||||
WAIT,
|
||||
RELEASE,
|
||||
};
|
||||
|
||||
struct pthread_barrier_internal_t {
|
||||
// One barrier can be used for unlimited number of cycles. In each cycle, [init_count]
|
||||
// threads must call pthread_barrier_wait() before any of them successfully return from
|
||||
// the call. It is undefined behavior if there are more than [init_count] threads call
|
||||
// pthread_barrier_wait() in one cycle.
|
||||
uint32_t init_count;
|
||||
// Barrier state. It is WAIT if waiting for more threads to enter the barrier in this cycle,
|
||||
// otherwise threads are leaving the barrier.
|
||||
_Atomic(BarrierState) state;
|
||||
// Number of threads having entered but not left the barrier in this cycle.
|
||||
atomic_uint wait_count;
|
||||
// Whether the barrier is shared across processes.
|
||||
bool pshared;
|
||||
uint32_t __reserved[4];
|
||||
};
|
||||
|
||||
static_assert(sizeof(pthread_barrier_t) == sizeof(pthread_barrier_internal_t),
|
||||
"pthread_barrier_t should actually be pthread_barrier_internal_t in implementation."
|
||||
);
|
||||
|
||||
static_assert(alignof(pthread_barrier_t) >= 4,
|
||||
"pthread_barrier_t should fulfill the alignment of pthread_barrier_internal_t.");
|
||||
|
||||
static inline pthread_barrier_internal_t* __get_internal_barrier(pthread_barrier_t* barrier) {
|
||||
return reinterpret_cast<pthread_barrier_internal_t*>(barrier);
|
||||
}
|
||||
|
||||
int pthread_barrier_init(pthread_barrier_t* barrier_interface, const pthread_barrierattr_t* attr,
|
||||
unsigned count) {
|
||||
pthread_barrier_internal_t* barrier = __get_internal_barrier(barrier_interface);
|
||||
if (count == 0) {
|
||||
return EINVAL;
|
||||
}
|
||||
barrier->init_count = count;
|
||||
atomic_init(&barrier->state, WAIT);
|
||||
atomic_init(&barrier->wait_count, 0);
|
||||
barrier->pshared = false;
|
||||
if (attr != nullptr && (*attr & 1)) {
|
||||
barrier->pshared = true;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// According to POSIX standard, pthread_barrier_wait() synchronizes memory between participating
|
||||
// threads. It means all memory operations made by participating threads before calling
|
||||
// pthread_barrier_wait() can be seen by all participating threads after the function call.
|
||||
// We establish this by making a happens-before relation between all threads entering the barrier
|
||||
// with the last thread entering the barrier, and a happens-before relation between the last
|
||||
// thread entering the barrier with all threads leaving the barrier.
|
||||
int pthread_barrier_wait(pthread_barrier_t* barrier_interface) {
|
||||
pthread_barrier_internal_t* barrier = __get_internal_barrier(barrier_interface);
|
||||
|
||||
// Wait until all threads for the previous cycle have left the barrier. This is needed
|
||||
// as a participating thread can call pthread_barrier_wait() again before other
|
||||
// threads have left the barrier. Use acquire operation here to synchronize with
|
||||
// the last thread leaving the previous cycle, so we can read correct wait_count below.
|
||||
while(atomic_load_explicit(&barrier->state, memory_order_acquire) == RELEASE) {
|
||||
__futex_wait_ex(&barrier->state, barrier->pshared, RELEASE, false, nullptr);
|
||||
}
|
||||
|
||||
uint32_t prev_wait_count = atomic_load_explicit(&barrier->wait_count, memory_order_relaxed);
|
||||
while (true) {
|
||||
// It happens when there are more than [init_count] threads trying to enter the barrier
|
||||
// at one cycle. We read the POSIX standard as disallowing this, since additional arriving
|
||||
// threads are not synchronized with respect to the barrier reset. We also don't know of
|
||||
// any reasonable cases in which this would be intentional.
|
||||
if (prev_wait_count >= barrier->init_count) {
|
||||
return EINVAL;
|
||||
}
|
||||
// Use memory_order_acq_rel operation here to synchronize between all threads entering
|
||||
// the barrier with the last thread entering the barrier.
|
||||
if (atomic_compare_exchange_weak_explicit(&barrier->wait_count, &prev_wait_count,
|
||||
prev_wait_count + 1u, memory_order_acq_rel,
|
||||
memory_order_relaxed)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int result = 0;
|
||||
if (prev_wait_count + 1 == barrier->init_count) {
|
||||
result = PTHREAD_BARRIER_SERIAL_THREAD;
|
||||
if (prev_wait_count != 0) {
|
||||
// Use release operation here to synchronize between the last thread entering the
|
||||
// barrier with all threads leaving the barrier.
|
||||
atomic_store_explicit(&barrier->state, RELEASE, memory_order_release);
|
||||
__futex_wake_ex(&barrier->state, barrier->pshared, prev_wait_count);
|
||||
}
|
||||
} else {
|
||||
// Use acquire operation here to synchronize between the last thread entering the
|
||||
// barrier with all threads leaving the barrier.
|
||||
while (atomic_load_explicit(&barrier->state, memory_order_acquire) == WAIT) {
|
||||
__futex_wait_ex(&barrier->state, barrier->pshared, WAIT, false, nullptr);
|
||||
}
|
||||
}
|
||||
// Use release operation here to make it not reordered with previous operations.
|
||||
if (atomic_fetch_sub_explicit(&barrier->wait_count, 1, memory_order_release) == 1) {
|
||||
// Use release operation here to synchronize with threads entering the barrier for
|
||||
// the next cycle, or the thread calling pthread_barrier_destroy().
|
||||
atomic_store_explicit(&barrier->state, WAIT, memory_order_release);
|
||||
__futex_wake_ex(&barrier->state, barrier->pshared, barrier->init_count);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
int pthread_barrier_destroy(pthread_barrier_t* barrier_interface) {
|
||||
pthread_barrier_internal_t* barrier = __get_internal_barrier(barrier_interface);
|
||||
if (barrier->init_count == 0) {
|
||||
return EINVAL;
|
||||
}
|
||||
// Use acquire operation here to synchronize with the last thread leaving the barrier.
|
||||
// So we can read correct wait_count below.
|
||||
while (atomic_load_explicit(&barrier->state, memory_order_acquire) == RELEASE) {
|
||||
__futex_wait_ex(&barrier->state, barrier->pshared, RELEASE, false, nullptr);
|
||||
}
|
||||
if (atomic_load_explicit(&barrier->wait_count, memory_order_relaxed) != 0) {
|
||||
return EBUSY;
|
||||
}
|
||||
barrier->init_count = 0;
|
||||
return 0;
|
||||
}
|
@ -111,8 +111,8 @@ struct pthread_cond_internal_t {
|
||||
return COND_IS_SHARED(atomic_load_explicit(&state, memory_order_relaxed));
|
||||
}
|
||||
|
||||
bool use_realtime_clock() {
|
||||
return COND_GET_CLOCK(atomic_load_explicit(&state, memory_order_relaxed)) == CLOCK_REALTIME;
|
||||
int get_clock() {
|
||||
return COND_GET_CLOCK(atomic_load_explicit(&state, memory_order_relaxed));
|
||||
}
|
||||
|
||||
#if defined(__LP64__)
|
||||
@ -170,17 +170,12 @@ static int __pthread_cond_pulse(pthread_cond_internal_t* cond, int thread_count)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __pthread_cond_timedwait(pthread_cond_internal_t* cond, pthread_mutex_t* mutex,
|
||||
bool use_realtime_clock, const timespec* abs_timeout_or_null) {
|
||||
int result = check_timespec(abs_timeout_or_null, true);
|
||||
if (result != 0) {
|
||||
return result;
|
||||
}
|
||||
|
||||
static int __pthread_cond_timedwait_relative(pthread_cond_internal_t* cond, pthread_mutex_t* mutex,
|
||||
const timespec* rel_timeout_or_null) {
|
||||
unsigned int old_state = atomic_load_explicit(&cond->state, memory_order_relaxed);
|
||||
|
||||
pthread_mutex_unlock(mutex);
|
||||
int status = __futex_wait_ex(&cond->state, cond->process_shared(), old_state,
|
||||
use_realtime_clock, abs_timeout_or_null);
|
||||
int status = __futex_wait_ex(&cond->state, cond->process_shared(), old_state, rel_timeout_or_null);
|
||||
pthread_mutex_lock(mutex);
|
||||
|
||||
if (status == -ETIMEDOUT) {
|
||||
@ -189,6 +184,21 @@ static int __pthread_cond_timedwait(pthread_cond_internal_t* cond, pthread_mutex
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __pthread_cond_timedwait(pthread_cond_internal_t* cond, pthread_mutex_t* mutex,
|
||||
const timespec* abs_timeout_or_null, clockid_t clock) {
|
||||
timespec ts;
|
||||
timespec* rel_timeout = NULL;
|
||||
|
||||
if (abs_timeout_or_null != NULL) {
|
||||
rel_timeout = &ts;
|
||||
if (!timespec_from_absolute_timespec(*rel_timeout, *abs_timeout_or_null, clock)) {
|
||||
return ETIMEDOUT;
|
||||
}
|
||||
}
|
||||
|
||||
return __pthread_cond_timedwait_relative(cond, mutex, rel_timeout);
|
||||
}
|
||||
|
||||
int pthread_cond_broadcast(pthread_cond_t* cond_interface) {
|
||||
return __pthread_cond_pulse(__get_internal_cond(cond_interface), INT_MAX);
|
||||
}
|
||||
@ -199,14 +209,14 @@ int pthread_cond_signal(pthread_cond_t* cond_interface) {
|
||||
|
||||
int pthread_cond_wait(pthread_cond_t* cond_interface, pthread_mutex_t* mutex) {
|
||||
pthread_cond_internal_t* cond = __get_internal_cond(cond_interface);
|
||||
return __pthread_cond_timedwait(cond, mutex, false, nullptr);
|
||||
return __pthread_cond_timedwait(cond, mutex, NULL, cond->get_clock());
|
||||
}
|
||||
|
||||
int pthread_cond_timedwait(pthread_cond_t *cond_interface, pthread_mutex_t * mutex,
|
||||
const timespec *abstime) {
|
||||
|
||||
pthread_cond_internal_t* cond = __get_internal_cond(cond_interface);
|
||||
return __pthread_cond_timedwait(cond, mutex, cond->use_realtime_clock(), abstime);
|
||||
return __pthread_cond_timedwait(cond, mutex, abstime, cond->get_clock());
|
||||
}
|
||||
|
||||
#if !defined(__LP64__)
|
||||
@ -215,7 +225,8 @@ extern "C" int pthread_cond_timedwait_monotonic(pthread_cond_t* cond_interface,
|
||||
pthread_mutex_t* mutex,
|
||||
const timespec* abs_timeout) {
|
||||
|
||||
return __pthread_cond_timedwait(__get_internal_cond(cond_interface), mutex, false, abs_timeout);
|
||||
return __pthread_cond_timedwait(__get_internal_cond(cond_interface), mutex, abs_timeout,
|
||||
CLOCK_MONOTONIC);
|
||||
}
|
||||
|
||||
extern "C" int pthread_cond_timedwait_monotonic_np(pthread_cond_t* cond_interface,
|
||||
@ -227,13 +238,8 @@ extern "C" int pthread_cond_timedwait_monotonic_np(pthread_cond_t* cond_interfac
|
||||
extern "C" int pthread_cond_timedwait_relative_np(pthread_cond_t* cond_interface,
|
||||
pthread_mutex_t* mutex,
|
||||
const timespec* rel_timeout) {
|
||||
timespec ts;
|
||||
timespec* abs_timeout = nullptr;
|
||||
if (rel_timeout != nullptr) {
|
||||
absolute_timespec_from_timespec(ts, *rel_timeout, CLOCK_REALTIME);
|
||||
abs_timeout = &ts;
|
||||
}
|
||||
return __pthread_cond_timedwait(__get_internal_cond(cond_interface), mutex, true, abs_timeout);
|
||||
|
||||
return __pthread_cond_timedwait_relative(__get_internal_cond(cond_interface), mutex, rel_timeout);
|
||||
}
|
||||
|
||||
extern "C" int pthread_cond_timeout_np(pthread_cond_t* cond_interface,
|
||||
|
@ -53,6 +53,13 @@ extern "C" int __isthreaded;
|
||||
|
||||
// This code is used both by each new pthread and the code that initializes the main thread.
|
||||
void __init_tls(pthread_internal_t* thread) {
|
||||
if (thread->mmap_size == 0) {
|
||||
// If the TLS area was not allocated by mmap(), it may not have been cleared to zero.
|
||||
// So assume the worst and zero the TLS area.
|
||||
memset(thread->tls, 0, sizeof(thread->tls));
|
||||
memset(thread->key_data, 0, sizeof(thread->key_data));
|
||||
}
|
||||
|
||||
// Slot 0 must point to itself. The x86 Linux kernel reads the TLS from %fs:0.
|
||||
thread->tls[TLS_SLOT_SELF] = thread->tls;
|
||||
thread->tls[TLS_SLOT_THREAD_ID] = thread;
|
||||
@ -168,11 +175,6 @@ static int __allocate_thread(pthread_attr_t* attr, pthread_internal_t** threadp,
|
||||
(reinterpret_cast<uintptr_t>(stack_top) - sizeof(pthread_internal_t)) & ~0xf);
|
||||
|
||||
pthread_internal_t* thread = reinterpret_cast<pthread_internal_t*>(stack_top);
|
||||
if (mmap_size == 0) {
|
||||
// If thread was not allocated by mmap(), it may not have been cleared to zero.
|
||||
// So assume the worst and zero it.
|
||||
memset(thread, 0, sizeof(pthread_internal_t));
|
||||
}
|
||||
attr->stack_size = stack_top - reinterpret_cast<uint8_t*>(attr->stack_base);
|
||||
|
||||
thread->mmap_size = mmap_size;
|
||||
|
@ -40,8 +40,7 @@
|
||||
/* Has the thread been joined by another thread? */
|
||||
#define PTHREAD_ATTR_FLAG_JOINED 0x00000002
|
||||
|
||||
class pthread_key_data_t {
|
||||
public:
|
||||
struct pthread_key_data_t {
|
||||
uintptr_t seq; // Use uintptr_t just for alignment, as we use pointer below.
|
||||
void* data;
|
||||
};
|
||||
@ -53,12 +52,9 @@ enum ThreadJoinState {
|
||||
THREAD_DETACHED
|
||||
};
|
||||
|
||||
class thread_local_dtor;
|
||||
|
||||
class pthread_internal_t {
|
||||
public:
|
||||
class pthread_internal_t* next;
|
||||
class pthread_internal_t* prev;
|
||||
struct pthread_internal_t {
|
||||
struct pthread_internal_t* next;
|
||||
struct pthread_internal_t* prev;
|
||||
|
||||
pid_t tid;
|
||||
|
||||
@ -98,8 +94,6 @@ class pthread_internal_t {
|
||||
|
||||
size_t mmap_size;
|
||||
|
||||
thread_local_dtor* thread_local_dtors;
|
||||
|
||||
void* tls[BIONIC_TLS_SLOTS];
|
||||
|
||||
pthread_key_data_t key_data[BIONIC_PTHREAD_KEY_COUNT];
|
||||
|
@ -166,13 +166,10 @@ int pthread_mutexattr_getpshared(const pthread_mutexattr_t* attr, int* pshared)
|
||||
#define MUTEX_STATE_BITS_LOCKED_UNCONTENDED MUTEX_STATE_TO_BITS(MUTEX_STATE_LOCKED_UNCONTENDED)
|
||||
#define MUTEX_STATE_BITS_LOCKED_CONTENDED MUTEX_STATE_TO_BITS(MUTEX_STATE_LOCKED_CONTENDED)
|
||||
|
||||
// Return true iff the mutex is unlocked.
|
||||
#define MUTEX_STATE_BITS_IS_UNLOCKED(v) (((v) & MUTEX_STATE_MASK) == MUTEX_STATE_BITS_UNLOCKED)
|
||||
|
||||
// Return true iff the mutex is locked with no waiters.
|
||||
/* return true iff the mutex if locked with no waiters */
|
||||
#define MUTEX_STATE_BITS_IS_LOCKED_UNCONTENDED(v) (((v) & MUTEX_STATE_MASK) == MUTEX_STATE_BITS_LOCKED_UNCONTENDED)
|
||||
|
||||
// return true iff the mutex is locked with maybe waiters.
|
||||
/* return true iff the mutex if locked with maybe waiters */
|
||||
#define MUTEX_STATE_BITS_IS_LOCKED_CONTENDED(v) (((v) & MUTEX_STATE_MASK) == MUTEX_STATE_BITS_LOCKED_CONTENDED)
|
||||
|
||||
/* used to flip from LOCKED_UNCONTENDED to LOCKED_CONTENDED */
|
||||
@ -299,15 +296,11 @@ static inline __always_inline int __pthread_normal_mutex_trylock(pthread_mutex_i
|
||||
*/
|
||||
static inline __always_inline int __pthread_normal_mutex_lock(pthread_mutex_internal_t* mutex,
|
||||
uint16_t shared,
|
||||
bool use_realtime_clock,
|
||||
const timespec* abs_timeout_or_null) {
|
||||
const timespec* abs_timeout_or_null,
|
||||
clockid_t clock) {
|
||||
if (__predict_true(__pthread_normal_mutex_trylock(mutex, shared) == 0)) {
|
||||
return 0;
|
||||
}
|
||||
int result = check_timespec(abs_timeout_or_null, true);
|
||||
if (result != 0) {
|
||||
return result;
|
||||
}
|
||||
|
||||
ScopedTrace trace("Contending for pthread mutex");
|
||||
|
||||
@ -324,8 +317,15 @@ static inline __always_inline int __pthread_normal_mutex_lock(pthread_mutex_inte
|
||||
// made by other threads visible to the current CPU.
|
||||
while (atomic_exchange_explicit(&mutex->state, locked_contended,
|
||||
memory_order_acquire) != unlocked) {
|
||||
if (__futex_wait_ex(&mutex->state, shared, locked_contended, use_realtime_clock,
|
||||
abs_timeout_or_null) == -ETIMEDOUT) {
|
||||
timespec ts;
|
||||
timespec* rel_timeout = NULL;
|
||||
if (abs_timeout_or_null != NULL) {
|
||||
rel_timeout = &ts;
|
||||
if (!timespec_from_absolute_timespec(*rel_timeout, *abs_timeout_or_null, clock)) {
|
||||
return ETIMEDOUT;
|
||||
}
|
||||
}
|
||||
if (__futex_wait_ex(&mutex->state, shared, locked_contended, rel_timeout) == -ETIMEDOUT) {
|
||||
return ETIMEDOUT;
|
||||
}
|
||||
}
|
||||
@ -396,15 +396,14 @@ static inline __always_inline int __recursive_or_errorcheck_mutex_wait(
|
||||
pthread_mutex_internal_t* mutex,
|
||||
uint16_t shared,
|
||||
uint16_t old_state,
|
||||
bool use_realtime_clock,
|
||||
const timespec* abs_timeout) {
|
||||
const timespec* rel_timeout) {
|
||||
// __futex_wait always waits on a 32-bit value. But state is 16-bit. For a normal mutex, the owner_tid
|
||||
// field in mutex is not used. On 64-bit devices, the __pad field in mutex is not used.
|
||||
// But when a recursive or errorcheck mutex is used on 32-bit devices, we need to add the
|
||||
// owner_tid value in the value argument for __futex_wait, otherwise we may always get EAGAIN error.
|
||||
|
||||
#if defined(__LP64__)
|
||||
return __futex_wait_ex(&mutex->state, shared, old_state, use_realtime_clock, abs_timeout);
|
||||
return __futex_wait_ex(&mutex->state, shared, old_state, rel_timeout);
|
||||
|
||||
#else
|
||||
// This implementation works only when the layout of pthread_mutex_internal_t matches below expectation.
|
||||
@ -413,21 +412,19 @@ static inline __always_inline int __recursive_or_errorcheck_mutex_wait(
|
||||
static_assert(offsetof(pthread_mutex_internal_t, owner_tid) == 2, "");
|
||||
|
||||
uint32_t owner_tid = atomic_load_explicit(&mutex->owner_tid, memory_order_relaxed);
|
||||
return __futex_wait_ex(&mutex->state, shared, (owner_tid << 16) | old_state,
|
||||
use_realtime_clock, abs_timeout);
|
||||
return __futex_wait_ex(&mutex->state, shared, (owner_tid << 16) | old_state, rel_timeout);
|
||||
#endif
|
||||
}
|
||||
|
||||
static int __pthread_mutex_lock_with_timeout(pthread_mutex_internal_t* mutex,
|
||||
bool use_realtime_clock,
|
||||
const timespec* abs_timeout_or_null) {
|
||||
const timespec* abs_timeout_or_null, clockid_t clock) {
|
||||
uint16_t old_state = atomic_load_explicit(&mutex->state, memory_order_relaxed);
|
||||
uint16_t mtype = (old_state & MUTEX_TYPE_MASK);
|
||||
uint16_t shared = (old_state & MUTEX_SHARED_MASK);
|
||||
|
||||
// Handle common case first.
|
||||
if ( __predict_true(mtype == MUTEX_TYPE_BITS_NORMAL) ) {
|
||||
return __pthread_normal_mutex_lock(mutex, shared, use_realtime_clock, abs_timeout_or_null);
|
||||
return __pthread_normal_mutex_lock(mutex, shared, abs_timeout_or_null, clock);
|
||||
}
|
||||
|
||||
// Do we already own this recursive or error-check mutex?
|
||||
@ -487,13 +484,16 @@ static int __pthread_mutex_lock_with_timeout(pthread_mutex_internal_t* mutex,
|
||||
old_state = new_state;
|
||||
}
|
||||
|
||||
int result = check_timespec(abs_timeout_or_null, true);
|
||||
if (result != 0) {
|
||||
return result;
|
||||
}
|
||||
// We are in locked_contended state, sleep until someone wakes us up.
|
||||
if (__recursive_or_errorcheck_mutex_wait(mutex, shared, old_state, use_realtime_clock,
|
||||
abs_timeout_or_null) == -ETIMEDOUT) {
|
||||
timespec ts;
|
||||
timespec* rel_timeout = NULL;
|
||||
if (abs_timeout_or_null != NULL) {
|
||||
rel_timeout = &ts;
|
||||
if (!timespec_from_absolute_timespec(*rel_timeout, *abs_timeout_or_null, clock)) {
|
||||
return ETIMEDOUT;
|
||||
}
|
||||
}
|
||||
if (__recursive_or_errorcheck_mutex_wait(mutex, shared, old_state, rel_timeout) == -ETIMEDOUT) {
|
||||
return ETIMEDOUT;
|
||||
}
|
||||
old_state = atomic_load_explicit(&mutex->state, memory_order_relaxed);
|
||||
@ -518,7 +518,7 @@ int pthread_mutex_lock(pthread_mutex_t* mutex_interface) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return __pthread_mutex_lock_with_timeout(mutex, false, nullptr);
|
||||
return __pthread_mutex_lock_with_timeout(mutex, NULL, 0);
|
||||
}
|
||||
|
||||
int pthread_mutex_unlock(pthread_mutex_t* mutex_interface) {
|
||||
@ -613,12 +613,17 @@ int pthread_mutex_trylock(pthread_mutex_t* mutex_interface) {
|
||||
|
||||
#if !defined(__LP64__)
|
||||
extern "C" int pthread_mutex_lock_timeout_np(pthread_mutex_t* mutex_interface, unsigned ms) {
|
||||
timespec ts;
|
||||
timespec_from_ms(ts, ms);
|
||||
timespec abs_timeout;
|
||||
absolute_timespec_from_timespec(abs_timeout, ts, CLOCK_MONOTONIC);
|
||||
clock_gettime(CLOCK_MONOTONIC, &abs_timeout);
|
||||
abs_timeout.tv_sec += ms / 1000;
|
||||
abs_timeout.tv_nsec += (ms % 1000) * 1000000;
|
||||
if (abs_timeout.tv_nsec >= NS_PER_S) {
|
||||
abs_timeout.tv_sec++;
|
||||
abs_timeout.tv_nsec -= NS_PER_S;
|
||||
}
|
||||
|
||||
int error = __pthread_mutex_lock_with_timeout(__get_internal_mutex(mutex_interface),
|
||||
false, &abs_timeout);
|
||||
&abs_timeout, CLOCK_MONOTONIC);
|
||||
if (error == ETIMEDOUT) {
|
||||
error = EBUSY;
|
||||
}
|
||||
@ -628,18 +633,14 @@ extern "C" int pthread_mutex_lock_timeout_np(pthread_mutex_t* mutex_interface, u
|
||||
|
||||
int pthread_mutex_timedlock(pthread_mutex_t* mutex_interface, const timespec* abs_timeout) {
|
||||
return __pthread_mutex_lock_with_timeout(__get_internal_mutex(mutex_interface),
|
||||
true, abs_timeout);
|
||||
abs_timeout, CLOCK_REALTIME);
|
||||
}
|
||||
|
||||
int pthread_mutex_destroy(pthread_mutex_t* mutex_interface) {
|
||||
pthread_mutex_internal_t* mutex = __get_internal_mutex(mutex_interface);
|
||||
uint16_t old_state = atomic_load_explicit(&mutex->state, memory_order_relaxed);
|
||||
// Store 0xffff to make the mutex unusable. Although POSIX standard says it is undefined
|
||||
// behavior to destroy a locked mutex, we prefer not to change mutex->state in that situation.
|
||||
if (MUTEX_STATE_BITS_IS_UNLOCKED(old_state) &&
|
||||
atomic_compare_exchange_strong_explicit(&mutex->state, &old_state, 0xffff,
|
||||
memory_order_relaxed, memory_order_relaxed)) {
|
||||
// Use trylock to ensure that the mutex is valid and not already locked.
|
||||
int error = pthread_mutex_trylock(mutex_interface);
|
||||
if (error != 0) {
|
||||
return error;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
return EBUSY;
|
||||
}
|
||||
|
@ -79,7 +79,7 @@ int pthread_once(pthread_once_t* once_control, void (*init_routine)(void)) {
|
||||
}
|
||||
|
||||
// The initialization is underway, wait for its finish.
|
||||
__futex_wait_ex(once_control_ptr, 0, old_value, false, nullptr);
|
||||
__futex_wait_ex(once_control_ptr, 0, old_value, NULL);
|
||||
old_value = atomic_load_explicit(once_control_ptr, memory_order_acquire);
|
||||
}
|
||||
}
|
||||
|
@ -294,13 +294,9 @@ static int __pthread_rwlock_timedrdlock(pthread_rwlock_internal_t* rwlock,
|
||||
}
|
||||
|
||||
while (true) {
|
||||
int result = __pthread_rwlock_tryrdlock(rwlock);
|
||||
if (result == 0 || result == EAGAIN) {
|
||||
return result;
|
||||
}
|
||||
result = check_timespec(abs_timeout_or_null, true);
|
||||
if (result != 0) {
|
||||
return result;
|
||||
int ret = __pthread_rwlock_tryrdlock(rwlock);
|
||||
if (ret == 0 || ret == EAGAIN) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
int old_state = atomic_load_explicit(&rwlock->state, memory_order_relaxed);
|
||||
@ -308,6 +304,16 @@ static int __pthread_rwlock_timedrdlock(pthread_rwlock_internal_t* rwlock,
|
||||
continue;
|
||||
}
|
||||
|
||||
timespec ts;
|
||||
timespec* rel_timeout = NULL;
|
||||
|
||||
if (abs_timeout_or_null != NULL) {
|
||||
rel_timeout = &ts;
|
||||
if (!timespec_from_absolute_timespec(*rel_timeout, *abs_timeout_or_null, CLOCK_REALTIME)) {
|
||||
return ETIMEDOUT;
|
||||
}
|
||||
}
|
||||
|
||||
rwlock->pending_lock.lock();
|
||||
rwlock->pending_reader_count++;
|
||||
|
||||
@ -321,10 +327,10 @@ static int __pthread_rwlock_timedrdlock(pthread_rwlock_internal_t* rwlock,
|
||||
int old_serial = rwlock->pending_reader_wakeup_serial;
|
||||
rwlock->pending_lock.unlock();
|
||||
|
||||
int futex_result = 0;
|
||||
int futex_ret = 0;
|
||||
if (!__can_acquire_read_lock(old_state, rwlock->writer_nonrecursive_preferred)) {
|
||||
futex_result = __futex_wait_ex(&rwlock->pending_reader_wakeup_serial, rwlock->pshared,
|
||||
old_serial, true, abs_timeout_or_null);
|
||||
futex_ret = __futex_wait_ex(&rwlock->pending_reader_wakeup_serial, rwlock->pshared,
|
||||
old_serial, rel_timeout);
|
||||
}
|
||||
|
||||
rwlock->pending_lock.lock();
|
||||
@ -335,7 +341,7 @@ static int __pthread_rwlock_timedrdlock(pthread_rwlock_internal_t* rwlock,
|
||||
}
|
||||
rwlock->pending_lock.unlock();
|
||||
|
||||
if (futex_result == -ETIMEDOUT) {
|
||||
if (futex_ret == -ETIMEDOUT) {
|
||||
return ETIMEDOUT;
|
||||
}
|
||||
}
|
||||
@ -366,13 +372,9 @@ static int __pthread_rwlock_timedwrlock(pthread_rwlock_internal_t* rwlock,
|
||||
return EDEADLK;
|
||||
}
|
||||
while (true) {
|
||||
int result = __pthread_rwlock_trywrlock(rwlock);
|
||||
if (result == 0) {
|
||||
return result;
|
||||
}
|
||||
result = check_timespec(abs_timeout_or_null, true);
|
||||
if (result != 0) {
|
||||
return result;
|
||||
int ret = __pthread_rwlock_trywrlock(rwlock);
|
||||
if (ret == 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
int old_state = atomic_load_explicit(&rwlock->state, memory_order_relaxed);
|
||||
@ -380,6 +382,16 @@ static int __pthread_rwlock_timedwrlock(pthread_rwlock_internal_t* rwlock,
|
||||
continue;
|
||||
}
|
||||
|
||||
timespec ts;
|
||||
timespec* rel_timeout = NULL;
|
||||
|
||||
if (abs_timeout_or_null != NULL) {
|
||||
rel_timeout = &ts;
|
||||
if (!timespec_from_absolute_timespec(*rel_timeout, *abs_timeout_or_null, CLOCK_REALTIME)) {
|
||||
return ETIMEDOUT;
|
||||
}
|
||||
}
|
||||
|
||||
rwlock->pending_lock.lock();
|
||||
rwlock->pending_writer_count++;
|
||||
|
||||
@ -389,10 +401,10 @@ static int __pthread_rwlock_timedwrlock(pthread_rwlock_internal_t* rwlock,
|
||||
int old_serial = rwlock->pending_writer_wakeup_serial;
|
||||
rwlock->pending_lock.unlock();
|
||||
|
||||
int futex_result = 0;
|
||||
int futex_ret = 0;
|
||||
if (!__can_acquire_write_lock(old_state)) {
|
||||
futex_result = __futex_wait_ex(&rwlock->pending_writer_wakeup_serial, rwlock->pshared,
|
||||
old_serial, true, abs_timeout_or_null);
|
||||
futex_ret = __futex_wait_ex(&rwlock->pending_writer_wakeup_serial, rwlock->pshared,
|
||||
old_serial, rel_timeout);
|
||||
}
|
||||
|
||||
rwlock->pending_lock.lock();
|
||||
@ -403,7 +415,7 @@ static int __pthread_rwlock_timedwrlock(pthread_rwlock_internal_t* rwlock,
|
||||
}
|
||||
rwlock->pending_lock.unlock();
|
||||
|
||||
if (futex_result == -ETIMEDOUT) {
|
||||
if (futex_ret == -ETIMEDOUT) {
|
||||
return ETIMEDOUT;
|
||||
}
|
||||
}
|
||||
@ -415,7 +427,7 @@ int pthread_rwlock_rdlock(pthread_rwlock_t* rwlock_interface) {
|
||||
if (__predict_true(__pthread_rwlock_tryrdlock(rwlock) == 0)) {
|
||||
return 0;
|
||||
}
|
||||
return __pthread_rwlock_timedrdlock(rwlock, nullptr);
|
||||
return __pthread_rwlock_timedrdlock(rwlock, NULL);
|
||||
}
|
||||
|
||||
int pthread_rwlock_timedrdlock(pthread_rwlock_t* rwlock_interface, const timespec* abs_timeout) {
|
||||
@ -434,7 +446,7 @@ int pthread_rwlock_wrlock(pthread_rwlock_t* rwlock_interface) {
|
||||
if (__predict_true(__pthread_rwlock_trywrlock(rwlock) == 0)) {
|
||||
return 0;
|
||||
}
|
||||
return __pthread_rwlock_timedwrlock(rwlock, nullptr);
|
||||
return __pthread_rwlock_timedwrlock(rwlock, NULL);
|
||||
}
|
||||
|
||||
int pthread_rwlock_timedwrlock(pthread_rwlock_t* rwlock_interface, const timespec* abs_timeout) {
|
||||
|
@ -1,81 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2015 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.
|
||||
*/
|
||||
#include <pthread.h>
|
||||
|
||||
#include "private/bionic_lock.h"
|
||||
|
||||
// User-level spinlocks can be hazardous to battery life on Android.
|
||||
// We implement a simple compromise that behaves mostly like a spinlock,
|
||||
// but prevents excessively long spinning.
|
||||
|
||||
struct pthread_spinlock_internal_t {
|
||||
Lock lock;
|
||||
};
|
||||
|
||||
static_assert(sizeof(pthread_spinlock_t) == sizeof(pthread_spinlock_internal_t),
|
||||
"pthread_spinlock_t should actually be pthread_spinlock_internal_t.");
|
||||
|
||||
static_assert(alignof(pthread_spinlock_t) >= 4,
|
||||
"pthread_spinlock_t should fulfill the alignment of pthread_spinlock_internal_t.");
|
||||
|
||||
static inline pthread_spinlock_internal_t* __get_internal_spinlock(pthread_spinlock_t* lock) {
|
||||
return reinterpret_cast<pthread_spinlock_internal_t*>(lock);
|
||||
}
|
||||
|
||||
int pthread_spin_init(pthread_spinlock_t* lock_interface, int pshared) {
|
||||
pthread_spinlock_internal_t* lock = __get_internal_spinlock(lock_interface);
|
||||
lock->lock.init(pshared);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pthread_spin_destroy(pthread_spinlock_t* lock_interface) {
|
||||
pthread_spinlock_internal_t* lock = __get_internal_spinlock(lock_interface);
|
||||
return lock->lock.trylock() ? 0 : EBUSY;
|
||||
}
|
||||
|
||||
int pthread_spin_trylock(pthread_spinlock_t* lock_interface) {
|
||||
pthread_spinlock_internal_t* lock = __get_internal_spinlock(lock_interface);
|
||||
return lock->lock.trylock() ? 0 : EBUSY;
|
||||
}
|
||||
|
||||
int pthread_spin_lock(pthread_spinlock_t* lock_interface) {
|
||||
pthread_spinlock_internal_t* lock = __get_internal_spinlock(lock_interface);
|
||||
for (int i = 0; i < 10000; ++i) {
|
||||
if (lock->lock.trylock()) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
lock->lock.lock();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pthread_spin_unlock(pthread_spinlock_t* lock_interface) {
|
||||
pthread_spinlock_internal_t* lock = __get_internal_spinlock(lock_interface);
|
||||
lock->lock.unlock();
|
||||
return 0;
|
||||
}
|
@ -220,7 +220,7 @@ int sem_wait(sem_t* sem) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
__futex_wait_ex(sem_count_ptr, shared, shared | SEMCOUNT_MINUS_ONE, false, nullptr);
|
||||
__futex_wait_ex(sem_count_ptr, shared, shared | SEMCOUNT_MINUS_ONE, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
@ -235,29 +235,36 @@ int sem_timedwait(sem_t* sem, const timespec* abs_timeout) {
|
||||
}
|
||||
|
||||
// Check it as per POSIX.
|
||||
int result = check_timespec(abs_timeout, false);
|
||||
if (result != 0) {
|
||||
errno = result;
|
||||
if (abs_timeout == NULL || abs_timeout->tv_sec < 0 || abs_timeout->tv_nsec < 0 || abs_timeout->tv_nsec >= NS_PER_S) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
unsigned int shared = SEM_GET_SHARED(sem_count_ptr);
|
||||
|
||||
while (true) {
|
||||
// POSIX mandates CLOCK_REALTIME here.
|
||||
timespec ts;
|
||||
if (!timespec_from_absolute_timespec(ts, *abs_timeout, CLOCK_REALTIME)) {
|
||||
errno = ETIMEDOUT;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Try to grab the semaphore. If the value was 0, this will also change it to -1.
|
||||
if (__sem_dec(sem_count_ptr) > 0) {
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
|
||||
// Contention detected. Wait for a wakeup event.
|
||||
int result = __futex_wait_ex(sem_count_ptr, shared, shared | SEMCOUNT_MINUS_ONE, true, abs_timeout);
|
||||
int ret = __futex_wait_ex(sem_count_ptr, shared, shared | SEMCOUNT_MINUS_ONE, &ts);
|
||||
|
||||
// Return in case of timeout or interrupt.
|
||||
if (result == -ETIMEDOUT || result == -EINTR) {
|
||||
errno = -result;
|
||||
if (ret == -ETIMEDOUT || ret == -EINTR) {
|
||||
errno = -ret;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sem_post(sem_t* sem) {
|
||||
|
@ -25,38 +25,34 @@
|
||||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <poll.h>
|
||||
#include <stdatomic.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <new>
|
||||
#include <stdatomic.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <stddef.h>
|
||||
#include <errno.h>
|
||||
#include <poll.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <linux/xattr.h>
|
||||
#include <netinet/in.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/select.h>
|
||||
|
||||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
#include <sys/select.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/un.h>
|
||||
#include <sys/xattr.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
#define _REALLY_INCLUDE_SYS__SYSTEM_PROPERTIES_H_
|
||||
#include <sys/_system_properties.h>
|
||||
#include <sys/system_properties.h>
|
||||
|
||||
#include "private/bionic_futex.h"
|
||||
#include "private/bionic_lock.h"
|
||||
#include "private/bionic_macros.h"
|
||||
#include "private/libc_logging.h"
|
||||
|
||||
static const char property_service_socket[] = "/dev/socket/" PROP_SERVICE_NAME;
|
||||
|
||||
@ -116,57 +112,23 @@ private:
|
||||
DISALLOW_COPY_AND_ASSIGN(prop_bt);
|
||||
};
|
||||
|
||||
class prop_area {
|
||||
public:
|
||||
struct prop_area {
|
||||
uint32_t bytes_used;
|
||||
atomic_uint_least32_t serial;
|
||||
uint32_t magic;
|
||||
uint32_t version;
|
||||
uint32_t reserved[28];
|
||||
char data[0];
|
||||
|
||||
prop_area(const uint32_t magic, const uint32_t version) :
|
||||
magic_(magic), version_(version) {
|
||||
atomic_init(&serial_, 0);
|
||||
memset(reserved_, 0, sizeof(reserved_));
|
||||
magic(magic), version(version) {
|
||||
atomic_init(&serial, 0);
|
||||
memset(reserved, 0, sizeof(reserved));
|
||||
// Allocate enough space for the root node.
|
||||
bytes_used_ = sizeof(prop_bt);
|
||||
bytes_used = sizeof(prop_bt);
|
||||
}
|
||||
|
||||
const prop_info *find(const char *name);
|
||||
bool add(const char *name, unsigned int namelen,
|
||||
const char *value, unsigned int valuelen);
|
||||
|
||||
bool foreach(void (*propfn)(const prop_info *pi, void *cookie), void *cookie);
|
||||
|
||||
atomic_uint_least32_t *serial() { return &serial_; }
|
||||
uint32_t magic() const { return magic_; }
|
||||
uint32_t version() const { return version_; }
|
||||
|
||||
private:
|
||||
void *allocate_obj(const size_t size, uint_least32_t *const off);
|
||||
prop_bt *new_prop_bt(const char *name, uint8_t namelen, uint_least32_t *const off);
|
||||
prop_info *new_prop_info(const char *name, uint8_t namelen,
|
||||
const char *value, uint8_t valuelen,
|
||||
uint_least32_t *const off);
|
||||
void *to_prop_obj(uint_least32_t off);
|
||||
prop_bt *to_prop_bt(atomic_uint_least32_t *off_p);
|
||||
prop_info *to_prop_info(atomic_uint_least32_t *off_p);
|
||||
|
||||
prop_bt *root_node();
|
||||
|
||||
prop_bt *find_prop_bt(prop_bt *const bt, const char *name,
|
||||
uint8_t namelen, bool alloc_if_needed);
|
||||
|
||||
const prop_info *find_property(prop_bt *const trie, const char *name,
|
||||
uint8_t namelen, const char *value,
|
||||
uint8_t valuelen, bool alloc_if_needed);
|
||||
|
||||
bool foreach_property(prop_bt *const trie,
|
||||
void (*propfn)(const prop_info *pi, void *cookie),
|
||||
void *cookie);
|
||||
|
||||
uint32_t bytes_used_;
|
||||
atomic_uint_least32_t serial_;
|
||||
uint32_t magic_;
|
||||
uint32_t version_;
|
||||
uint32_t reserved_[28];
|
||||
char data_[0];
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(prop_area);
|
||||
};
|
||||
|
||||
@ -196,11 +158,10 @@ struct find_nth_cookie {
|
||||
}
|
||||
};
|
||||
|
||||
static char property_filename[PROP_FILENAME_MAX] = PROP_FILENAME;
|
||||
static char property_filename[PATH_MAX] = PROP_FILENAME;
|
||||
static bool compat_mode = false;
|
||||
static size_t pa_data_size;
|
||||
static size_t pa_size;
|
||||
static bool initialized = false;
|
||||
|
||||
// NOTE: This isn't static because system_properties_compat.c
|
||||
// requires it.
|
||||
@ -221,12 +182,13 @@ static int get_fd_from_env(void)
|
||||
return atoi(env);
|
||||
}
|
||||
|
||||
static prop_area* map_prop_area_rw(const char* filename, const char* context,
|
||||
bool* fsetxattr_failed) {
|
||||
static int map_prop_area_rw()
|
||||
{
|
||||
/* dev is a tmpfs that we can use to carve a shared workspace
|
||||
* out of, so let's do that...
|
||||
*/
|
||||
const int fd = open(filename, O_RDWR | O_CREAT | O_NOFOLLOW | O_CLOEXEC | O_EXCL, 0444);
|
||||
const int fd = open(property_filename,
|
||||
O_RDWR | O_CREAT | O_NOFOLLOW | O_CLOEXEC | O_EXCL, 0444);
|
||||
|
||||
if (fd < 0) {
|
||||
if (errno == EACCES) {
|
||||
@ -235,31 +197,12 @@ static prop_area* map_prop_area_rw(const char* filename, const char* context,
|
||||
*/
|
||||
abort();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (context) {
|
||||
if (fsetxattr(fd, XATTR_NAME_SELINUX, context, strlen(context) + 1, 0) != 0) {
|
||||
__libc_format_log(ANDROID_LOG_ERROR, "libc",
|
||||
"fsetxattr failed to set context (%s) for \"%s\"", context, filename);
|
||||
/*
|
||||
* fsetxattr() will fail during system properties tests due to selinux policy.
|
||||
* We do not want to create a custom policy for the tester, so we will continue in
|
||||
* this function but set a flag that an error has occurred.
|
||||
* Init, which is the only daemon that should ever call this function will abort
|
||||
* when this error occurs.
|
||||
* Otherwise, the tester will ignore it and continue, albeit without any selinux
|
||||
* property separation.
|
||||
*/
|
||||
if (fsetxattr_failed) {
|
||||
*fsetxattr_failed = true;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ftruncate(fd, PA_SIZE) < 0) {
|
||||
close(fd);
|
||||
return nullptr;
|
||||
return -1;
|
||||
}
|
||||
|
||||
pa_size = PA_SIZE;
|
||||
@ -269,26 +212,29 @@ static prop_area* map_prop_area_rw(const char* filename, const char* context,
|
||||
void *const memory_area = mmap(NULL, pa_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
|
||||
if (memory_area == MAP_FAILED) {
|
||||
close(fd);
|
||||
return nullptr;
|
||||
return -1;
|
||||
}
|
||||
|
||||
prop_area *pa = new(memory_area) prop_area(PROP_AREA_MAGIC, PROP_AREA_VERSION);
|
||||
|
||||
/* plug into the lib property services */
|
||||
__system_property_area__ = pa;
|
||||
|
||||
close(fd);
|
||||
return pa;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static prop_area* map_fd_ro(const int fd) {
|
||||
static int map_fd_ro(const int fd) {
|
||||
struct stat fd_stat;
|
||||
if (fstat(fd, &fd_stat) < 0) {
|
||||
return nullptr;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((fd_stat.st_uid != 0)
|
||||
|| (fd_stat.st_gid != 0)
|
||||
|| ((fd_stat.st_mode & (S_IWGRP | S_IWOTH)) != 0)
|
||||
|| (fd_stat.st_size < static_cast<off_t>(sizeof(prop_area))) ) {
|
||||
return nullptr;
|
||||
return -1;
|
||||
}
|
||||
|
||||
pa_size = fd_stat.st_size;
|
||||
@ -296,28 +242,29 @@ static prop_area* map_fd_ro(const int fd) {
|
||||
|
||||
void* const map_result = mmap(NULL, pa_size, PROT_READ, MAP_SHARED, fd, 0);
|
||||
if (map_result == MAP_FAILED) {
|
||||
return nullptr;
|
||||
return -1;
|
||||
}
|
||||
|
||||
prop_area* pa = reinterpret_cast<prop_area*>(map_result);
|
||||
if ((pa->magic() != PROP_AREA_MAGIC) ||
|
||||
(pa->version() != PROP_AREA_VERSION &&
|
||||
pa->version() != PROP_AREA_VERSION_COMPAT)) {
|
||||
if ((pa->magic != PROP_AREA_MAGIC) || (pa->version != PROP_AREA_VERSION &&
|
||||
pa->version != PROP_AREA_VERSION_COMPAT)) {
|
||||
munmap(pa, pa_size);
|
||||
return nullptr;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (pa->version() == PROP_AREA_VERSION_COMPAT) {
|
||||
if (pa->version == PROP_AREA_VERSION_COMPAT) {
|
||||
compat_mode = true;
|
||||
}
|
||||
|
||||
return pa;
|
||||
__system_property_area__ = pa;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static prop_area* map_prop_area(const char* filename, bool is_legacy) {
|
||||
int fd = open(filename, O_CLOEXEC | O_NOFOLLOW | O_RDONLY);
|
||||
static int map_prop_area()
|
||||
{
|
||||
int fd = open(property_filename, O_CLOEXEC | O_NOFOLLOW | O_RDONLY);
|
||||
bool close_fd = true;
|
||||
if (fd == -1 && errno == ENOENT && is_legacy) {
|
||||
if (fd == -1 && errno == ENOENT) {
|
||||
/*
|
||||
* For backwards compatibility, if the file doesn't
|
||||
* exist, we use the environment to get the file descriptor.
|
||||
@ -326,18 +273,16 @@ static prop_area* map_prop_area(const char* filename, bool is_legacy) {
|
||||
* returns other errors such as ENOMEM or ENFILE, since it
|
||||
* might be possible for an external program to trigger this
|
||||
* condition.
|
||||
* Only do this for the legacy prop file, secured prop files
|
||||
* do not have a backup
|
||||
*/
|
||||
fd = get_fd_from_env();
|
||||
close_fd = false;
|
||||
}
|
||||
|
||||
if (fd < 0) {
|
||||
return nullptr;
|
||||
return -1;
|
||||
}
|
||||
|
||||
prop_area* map_result = map_fd_ro(fd);
|
||||
const int map_result = map_fd_ro(fd);
|
||||
if (close_fd) {
|
||||
close(fd);
|
||||
}
|
||||
@ -345,19 +290,20 @@ static prop_area* map_prop_area(const char* filename, bool is_legacy) {
|
||||
return map_result;
|
||||
}
|
||||
|
||||
void *prop_area::allocate_obj(const size_t size, uint_least32_t *const off)
|
||||
static void *allocate_obj(const size_t size, uint_least32_t *const off)
|
||||
{
|
||||
prop_area *pa = __system_property_area__;
|
||||
const size_t aligned = BIONIC_ALIGN(size, sizeof(uint_least32_t));
|
||||
if (bytes_used_ + aligned > pa_data_size) {
|
||||
if (pa->bytes_used + aligned > pa_data_size) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
*off = bytes_used_;
|
||||
bytes_used_ += aligned;
|
||||
return data_ + *off;
|
||||
*off = pa->bytes_used;
|
||||
pa->bytes_used += aligned;
|
||||
return pa->data + *off;
|
||||
}
|
||||
|
||||
prop_bt *prop_area::new_prop_bt(const char *name, uint8_t namelen, uint_least32_t *const off)
|
||||
static prop_bt *new_prop_bt(const char *name, uint8_t namelen, uint_least32_t *const off)
|
||||
{
|
||||
uint_least32_t new_offset;
|
||||
void *const p = allocate_obj(sizeof(prop_bt) + namelen + 1, &new_offset);
|
||||
@ -370,7 +316,7 @@ prop_bt *prop_area::new_prop_bt(const char *name, uint8_t namelen, uint_least32_
|
||||
return NULL;
|
||||
}
|
||||
|
||||
prop_info *prop_area::new_prop_info(const char *name, uint8_t namelen,
|
||||
static prop_info *new_prop_info(const char *name, uint8_t namelen,
|
||||
const char *value, uint8_t valuelen, uint_least32_t *const off)
|
||||
{
|
||||
uint_least32_t new_offset;
|
||||
@ -384,25 +330,27 @@ prop_info *prop_area::new_prop_info(const char *name, uint8_t namelen,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void *prop_area::to_prop_obj(uint_least32_t off)
|
||||
static void *to_prop_obj(uint_least32_t off)
|
||||
{
|
||||
if (off > pa_data_size)
|
||||
return NULL;
|
||||
if (!__system_property_area__)
|
||||
return NULL;
|
||||
|
||||
return (data_ + off);
|
||||
return (__system_property_area__->data + off);
|
||||
}
|
||||
|
||||
inline prop_bt *prop_area::to_prop_bt(atomic_uint_least32_t* off_p) {
|
||||
static inline prop_bt *to_prop_bt(atomic_uint_least32_t* off_p) {
|
||||
uint_least32_t off = atomic_load_explicit(off_p, memory_order_consume);
|
||||
return reinterpret_cast<prop_bt*>(to_prop_obj(off));
|
||||
}
|
||||
|
||||
inline prop_info *prop_area::to_prop_info(atomic_uint_least32_t* off_p) {
|
||||
static inline prop_info *to_prop_info(atomic_uint_least32_t* off_p) {
|
||||
uint_least32_t off = atomic_load_explicit(off_p, memory_order_consume);
|
||||
return reinterpret_cast<prop_info*>(to_prop_obj(off));
|
||||
}
|
||||
|
||||
inline prop_bt *prop_area::root_node()
|
||||
static inline prop_bt *root_node()
|
||||
{
|
||||
return reinterpret_cast<prop_bt*>(to_prop_obj(0));
|
||||
}
|
||||
@ -418,7 +366,7 @@ static int cmp_prop_name(const char *one, uint8_t one_len, const char *two,
|
||||
return strncmp(one, two, one_len);
|
||||
}
|
||||
|
||||
prop_bt *prop_area::find_prop_bt(prop_bt *const bt, const char *name,
|
||||
static prop_bt *find_prop_bt(prop_bt *const bt, const char *name,
|
||||
uint8_t namelen, bool alloc_if_needed)
|
||||
{
|
||||
|
||||
@ -469,7 +417,7 @@ prop_bt *prop_area::find_prop_bt(prop_bt *const bt, const char *name,
|
||||
}
|
||||
}
|
||||
|
||||
const prop_info *prop_area::find_property(prop_bt *const trie, const char *name,
|
||||
static const prop_info *find_property(prop_bt *const trie, const char *name,
|
||||
uint8_t namelen, const char *value, uint8_t valuelen,
|
||||
bool alloc_if_needed)
|
||||
{
|
||||
@ -595,439 +543,44 @@ static void find_nth_fn(const prop_info *pi, void *ptr)
|
||||
cookie->count++;
|
||||
}
|
||||
|
||||
bool prop_area::foreach_property(prop_bt *const trie,
|
||||
static int foreach_property(prop_bt *const trie,
|
||||
void (*propfn)(const prop_info *pi, void *cookie), void *cookie)
|
||||
{
|
||||
if (!trie)
|
||||
return false;
|
||||
return -1;
|
||||
|
||||
uint_least32_t left_offset = atomic_load_explicit(&trie->left, memory_order_relaxed);
|
||||
if (left_offset != 0) {
|
||||
const int err = foreach_property(to_prop_bt(&trie->left), propfn, cookie);
|
||||
if (err < 0)
|
||||
return false;
|
||||
return -1;
|
||||
}
|
||||
uint_least32_t prop_offset = atomic_load_explicit(&trie->prop, memory_order_relaxed);
|
||||
if (prop_offset != 0) {
|
||||
prop_info *info = to_prop_info(&trie->prop);
|
||||
if (!info)
|
||||
return false;
|
||||
return -1;
|
||||
propfn(info, cookie);
|
||||
}
|
||||
uint_least32_t children_offset = atomic_load_explicit(&trie->children, memory_order_relaxed);
|
||||
if (children_offset != 0) {
|
||||
const int err = foreach_property(to_prop_bt(&trie->children), propfn, cookie);
|
||||
if (err < 0)
|
||||
return false;
|
||||
return -1;
|
||||
}
|
||||
uint_least32_t right_offset = atomic_load_explicit(&trie->right, memory_order_relaxed);
|
||||
if (right_offset != 0) {
|
||||
const int err = foreach_property(to_prop_bt(&trie->right), propfn, cookie);
|
||||
if (err < 0)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
const prop_info *prop_area::find(const char *name) {
|
||||
return find_property(root_node(), name, strlen(name), nullptr, 0, false);
|
||||
}
|
||||
|
||||
bool prop_area::add(const char *name, unsigned int namelen,
|
||||
const char *value, unsigned int valuelen) {
|
||||
return find_property(root_node(), name, namelen, value, valuelen, true);
|
||||
}
|
||||
|
||||
bool prop_area::foreach(void (*propfn)(const prop_info* pi, void* cookie), void* cookie) {
|
||||
return foreach_property(root_node(), propfn, cookie);
|
||||
}
|
||||
|
||||
class context_node {
|
||||
public:
|
||||
context_node(context_node* next, const char* context, prop_area* pa)
|
||||
: next(next), context_(strdup(context)), pa_(pa), no_access_(false) {
|
||||
lock_.init(false);
|
||||
}
|
||||
~context_node() {
|
||||
unmap();
|
||||
free(context_);
|
||||
}
|
||||
bool open(bool access_rw, bool* fsetxattr_failed);
|
||||
bool check_access_and_open();
|
||||
void reset_access();
|
||||
|
||||
const char* context() const { return context_; }
|
||||
prop_area* pa() { return pa_; }
|
||||
|
||||
context_node* next;
|
||||
|
||||
private:
|
||||
bool check_access();
|
||||
void unmap();
|
||||
|
||||
Lock lock_;
|
||||
char* context_;
|
||||
prop_area* pa_;
|
||||
bool no_access_;
|
||||
};
|
||||
|
||||
struct prefix_node {
|
||||
prefix_node(struct prefix_node* next, const char* prefix, context_node* context)
|
||||
: prefix(strdup(prefix)), prefix_len(strlen(prefix)), context(context), next(next) {
|
||||
}
|
||||
~prefix_node() {
|
||||
free(prefix);
|
||||
}
|
||||
char* prefix;
|
||||
const size_t prefix_len;
|
||||
context_node* context;
|
||||
struct prefix_node* next;
|
||||
};
|
||||
|
||||
template <typename List, typename... Args>
|
||||
static inline void list_add(List** list, Args... args) {
|
||||
*list = new List(*list, args...);
|
||||
}
|
||||
|
||||
static void list_add_after_len(prefix_node** list, const char* prefix, context_node* context) {
|
||||
size_t prefix_len = strlen(prefix);
|
||||
|
||||
auto next_list = list;
|
||||
|
||||
while (*next_list) {
|
||||
if ((*next_list)->prefix_len < prefix_len || (*next_list)->prefix[0] == '*') {
|
||||
list_add(next_list, prefix, context);
|
||||
return;
|
||||
}
|
||||
next_list = &(*next_list)->next;
|
||||
}
|
||||
list_add(next_list, prefix, context);
|
||||
}
|
||||
|
||||
template <typename List, typename Func>
|
||||
static void list_foreach(List* list, Func func) {
|
||||
while (list) {
|
||||
func(list);
|
||||
list = list->next;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename List, typename Func>
|
||||
static List* list_find(List* list, Func func) {
|
||||
while (list) {
|
||||
if (func(list)) {
|
||||
return list;
|
||||
}
|
||||
list = list->next;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
template <typename List>
|
||||
static void list_free(List** list) {
|
||||
while (*list) {
|
||||
auto old_list = *list;
|
||||
*list = old_list->next;
|
||||
delete old_list;
|
||||
}
|
||||
}
|
||||
|
||||
static prefix_node* prefixes = nullptr;
|
||||
static context_node* contexts = nullptr;
|
||||
|
||||
/*
|
||||
* pthread_mutex_lock() calls into system_properties in the case of contention.
|
||||
* This creates a risk of dead lock if any system_properties functions
|
||||
* use pthread locks after system_property initialization.
|
||||
*
|
||||
* For this reason, the below three functions use a bionic Lock and static
|
||||
* allocation of memory for each filename.
|
||||
*/
|
||||
|
||||
bool context_node::open(bool access_rw, bool* fsetxattr_failed) {
|
||||
lock_.lock();
|
||||
if (pa_) {
|
||||
lock_.unlock();
|
||||
return true;
|
||||
}
|
||||
|
||||
char filename[PROP_FILENAME_MAX];
|
||||
int len = snprintf(filename, sizeof(filename), "%s/%s", property_filename, context_);
|
||||
if (len < 0 || len > PROP_FILENAME_MAX) {
|
||||
lock_.unlock();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (access_rw) {
|
||||
pa_ = map_prop_area_rw(filename, context_, fsetxattr_failed);
|
||||
} else {
|
||||
pa_ = map_prop_area(filename, false);
|
||||
}
|
||||
lock_.unlock();
|
||||
return pa_;
|
||||
}
|
||||
|
||||
bool context_node::check_access_and_open() {
|
||||
if (!pa_ && !no_access_) {
|
||||
if (!check_access() || !open(false, nullptr)) {
|
||||
no_access_ = true;
|
||||
}
|
||||
}
|
||||
return pa_;
|
||||
}
|
||||
|
||||
void context_node::reset_access() {
|
||||
if (!check_access()) {
|
||||
unmap();
|
||||
no_access_ = true;
|
||||
} else {
|
||||
no_access_ = false;
|
||||
}
|
||||
}
|
||||
|
||||
bool context_node::check_access() {
|
||||
char filename[PROP_FILENAME_MAX];
|
||||
int len = snprintf(filename, sizeof(filename), "%s/%s", property_filename, context_);
|
||||
if (len < 0 || len > PROP_FILENAME_MAX) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return access(filename, R_OK) == 0;
|
||||
}
|
||||
|
||||
void context_node::unmap() {
|
||||
if (!pa_) {
|
||||
return;
|
||||
}
|
||||
|
||||
munmap(pa_, pa_size);
|
||||
if (pa_ == __system_property_area__) {
|
||||
__system_property_area__ = nullptr;
|
||||
}
|
||||
pa_ = nullptr;
|
||||
}
|
||||
|
||||
static bool map_system_property_area(bool access_rw, bool* fsetxattr_failed) {
|
||||
char filename[PROP_FILENAME_MAX];
|
||||
int len = snprintf(filename, sizeof(filename), "%s/properties_serial", property_filename);
|
||||
if (len < 0 || len > PROP_FILENAME_MAX) {
|
||||
__system_property_area__ = nullptr;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (access_rw) {
|
||||
__system_property_area__ =
|
||||
map_prop_area_rw(filename, "u:object_r:properties_serial:s0", fsetxattr_failed);
|
||||
} else {
|
||||
__system_property_area__ = map_prop_area(filename, false);
|
||||
}
|
||||
return __system_property_area__;
|
||||
}
|
||||
|
||||
static prop_area* get_prop_area_for_name(const char* name) {
|
||||
auto entry = list_find(prefixes, [name](prefix_node* l) {
|
||||
return l->prefix[0] == '*' || !strncmp(l->prefix, name, l->prefix_len);
|
||||
});
|
||||
if (!entry) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto cnode = entry->context;
|
||||
if (!cnode->pa()) {
|
||||
/*
|
||||
* We explicitly do not check no_access_ in this case because unlike the
|
||||
* case of foreach(), we want to generate an selinux audit for each
|
||||
* non-permitted property access in this function.
|
||||
*/
|
||||
cnode->open(false, nullptr);
|
||||
}
|
||||
return cnode->pa();
|
||||
}
|
||||
|
||||
/*
|
||||
* The below two functions are duplicated from label_support.c in libselinux.
|
||||
* TODO: Find a location suitable for these functions such that both libc and
|
||||
* libselinux can share a common source file.
|
||||
*/
|
||||
|
||||
/*
|
||||
* The read_spec_entries and read_spec_entry functions may be used to
|
||||
* replace sscanf to read entries from spec files. The file and
|
||||
* property services now use these.
|
||||
*/
|
||||
|
||||
/* Read an entry from a spec file (e.g. file_contexts) */
|
||||
static inline int read_spec_entry(char **entry, char **ptr, int *len)
|
||||
{
|
||||
*entry = NULL;
|
||||
char *tmp_buf = NULL;
|
||||
|
||||
while (isspace(**ptr) && **ptr != '\0')
|
||||
(*ptr)++;
|
||||
|
||||
tmp_buf = *ptr;
|
||||
*len = 0;
|
||||
|
||||
while (!isspace(**ptr) && **ptr != '\0') {
|
||||
(*ptr)++;
|
||||
(*len)++;
|
||||
}
|
||||
|
||||
if (*len) {
|
||||
*entry = strndup(tmp_buf, *len);
|
||||
if (!*entry)
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* line_buf - Buffer containing the spec entries .
|
||||
* num_args - The number of spec parameter entries to process.
|
||||
* ... - A 'char **spec_entry' for each parameter.
|
||||
* returns - The number of items processed.
|
||||
*
|
||||
* This function calls read_spec_entry() to do the actual string processing.
|
||||
*/
|
||||
static int read_spec_entries(char *line_buf, int num_args, ...)
|
||||
{
|
||||
char **spec_entry, *buf_p;
|
||||
int len, rc, items, entry_len = 0;
|
||||
va_list ap;
|
||||
|
||||
len = strlen(line_buf);
|
||||
if (line_buf[len - 1] == '\n')
|
||||
line_buf[len - 1] = '\0';
|
||||
else
|
||||
/* Handle case if line not \n terminated by bumping
|
||||
* the len for the check below (as the line is NUL
|
||||
* terminated by getline(3)) */
|
||||
len++;
|
||||
|
||||
buf_p = line_buf;
|
||||
while (isspace(*buf_p))
|
||||
buf_p++;
|
||||
|
||||
/* Skip comment lines and empty lines. */
|
||||
if (*buf_p == '#' || *buf_p == '\0')
|
||||
return 0;
|
||||
|
||||
/* Process the spec file entries */
|
||||
va_start(ap, num_args);
|
||||
|
||||
items = 0;
|
||||
while (items < num_args) {
|
||||
spec_entry = va_arg(ap, char **);
|
||||
|
||||
if (len - 1 == buf_p - line_buf) {
|
||||
va_end(ap);
|
||||
return items;
|
||||
}
|
||||
|
||||
rc = read_spec_entry(spec_entry, &buf_p, &entry_len);
|
||||
if (rc < 0) {
|
||||
va_end(ap);
|
||||
return rc;
|
||||
}
|
||||
if (entry_len)
|
||||
items++;
|
||||
}
|
||||
va_end(ap);
|
||||
return items;
|
||||
}
|
||||
|
||||
static bool initialize_properties() {
|
||||
FILE* file = fopen("/property_contexts", "re");
|
||||
|
||||
if (!file) {
|
||||
return false;
|
||||
}
|
||||
|
||||
char* buffer = nullptr;
|
||||
size_t line_len;
|
||||
char* prop_prefix = nullptr;
|
||||
char* context = nullptr;
|
||||
|
||||
while (getline(&buffer, &line_len, file) > 0) {
|
||||
int items = read_spec_entries(buffer, 2, &prop_prefix, &context);
|
||||
if (items <= 0) {
|
||||
continue;
|
||||
}
|
||||
if (items == 1) {
|
||||
free(prop_prefix);
|
||||
continue;
|
||||
}
|
||||
/*
|
||||
* init uses ctl.* properties as an IPC mechanism and does not write them
|
||||
* to a property file, therefore we do not need to create property files
|
||||
* to store them.
|
||||
*/
|
||||
if (!strncmp(prop_prefix, "ctl.", 4)) {
|
||||
free(prop_prefix);
|
||||
free(context);
|
||||
continue;
|
||||
}
|
||||
|
||||
auto old_context = list_find(
|
||||
contexts, [context](context_node* l) { return !strcmp(l->context(), context); });
|
||||
if (old_context) {
|
||||
list_add_after_len(&prefixes, prop_prefix, old_context);
|
||||
} else {
|
||||
list_add(&contexts, context, nullptr);
|
||||
list_add_after_len(&prefixes, prop_prefix, contexts);
|
||||
}
|
||||
free(prop_prefix);
|
||||
free(context);
|
||||
}
|
||||
|
||||
free(buffer);
|
||||
fclose(file);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool is_dir(const char* pathname) {
|
||||
struct stat info;
|
||||
if (stat(pathname, &info) == -1) {
|
||||
return false;
|
||||
}
|
||||
return S_ISDIR(info.st_mode);
|
||||
}
|
||||
|
||||
static void free_and_unmap_contexts() {
|
||||
list_free(&prefixes);
|
||||
list_free(&contexts);
|
||||
if (__system_property_area__) {
|
||||
munmap(__system_property_area__, pa_size);
|
||||
__system_property_area__ = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
int __system_properties_init()
|
||||
{
|
||||
if (initialized) {
|
||||
list_foreach(contexts, [](context_node* l) { l->reset_access(); });
|
||||
return 0;
|
||||
}
|
||||
if (is_dir(property_filename)) {
|
||||
if (!initialize_properties()) {
|
||||
return -1;
|
||||
}
|
||||
if (!map_system_property_area(false, nullptr)) {
|
||||
free_and_unmap_contexts();
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
__system_property_area__ = map_prop_area(property_filename, true);
|
||||
if (!__system_property_area__) {
|
||||
return -1;
|
||||
}
|
||||
list_add(&contexts, "legacy_system_prop_area", __system_property_area__);
|
||||
list_add_after_len(&prefixes, "*", contexts);
|
||||
}
|
||||
initialized = true;
|
||||
return 0;
|
||||
return map_prop_area();
|
||||
}
|
||||
|
||||
int __system_property_set_filename(const char *filename)
|
||||
@ -1042,24 +595,7 @@ int __system_property_set_filename(const char *filename)
|
||||
|
||||
int __system_property_area_init()
|
||||
{
|
||||
free_and_unmap_contexts();
|
||||
mkdir(property_filename, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
|
||||
if (!initialize_properties()) {
|
||||
return -1;
|
||||
}
|
||||
bool open_failed = false;
|
||||
bool fsetxattr_failed = false;
|
||||
list_foreach(contexts, [&fsetxattr_failed, &open_failed](context_node* l) {
|
||||
if (!l->open(true, &fsetxattr_failed)) {
|
||||
open_failed = true;
|
||||
}
|
||||
});
|
||||
if (open_failed || !map_system_property_area(true, &fsetxattr_failed)) {
|
||||
free_and_unmap_contexts();
|
||||
return -1;
|
||||
}
|
||||
initialized = true;
|
||||
return fsetxattr_failed ? -2 : 0;
|
||||
return map_prop_area_rw();
|
||||
}
|
||||
|
||||
unsigned int __system_property_area_serial()
|
||||
@ -1069,26 +605,15 @@ unsigned int __system_property_area_serial()
|
||||
return -1;
|
||||
}
|
||||
// Make sure this read fulfilled before __system_property_serial
|
||||
return atomic_load_explicit(pa->serial(), memory_order_acquire);
|
||||
return atomic_load_explicit(&(pa->serial), memory_order_acquire);
|
||||
}
|
||||
|
||||
const prop_info *__system_property_find(const char *name)
|
||||
{
|
||||
if (!__system_property_area__) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (__predict_false(compat_mode)) {
|
||||
return __system_property_find_compat(name);
|
||||
}
|
||||
|
||||
prop_area* pa = get_prop_area_for_name(name);
|
||||
if (!pa) {
|
||||
__libc_format_log(ANDROID_LOG_ERROR, "libc", "Access denied finding property \"%s\"", name);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return pa->find(name);
|
||||
return find_property(root_node(), name, strlen(name), NULL, 0, false);
|
||||
}
|
||||
|
||||
// The C11 standard doesn't allow atomic loads from const fields,
|
||||
@ -1163,14 +688,10 @@ int __system_property_set(const char *key, const char *value)
|
||||
|
||||
int __system_property_update(prop_info *pi, const char *value, unsigned int len)
|
||||
{
|
||||
if (len >= PROP_VALUE_MAX)
|
||||
return -1;
|
||||
|
||||
prop_area *pa = __system_property_area__;
|
||||
|
||||
if (!pa) {
|
||||
if (len >= PROP_VALUE_MAX)
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint32_t serial = atomic_load_explicit(&pi->serial, memory_order_relaxed);
|
||||
serial |= 1;
|
||||
@ -1187,10 +708,10 @@ int __system_property_update(prop_info *pi, const char *value, unsigned int len)
|
||||
__futex_wake(&pi->serial, INT32_MAX);
|
||||
|
||||
atomic_store_explicit(
|
||||
pa->serial(),
|
||||
atomic_load_explicit(pa->serial(), memory_order_relaxed) + 1,
|
||||
&pa->serial,
|
||||
atomic_load_explicit(&pa->serial, memory_order_relaxed) + 1,
|
||||
memory_order_release);
|
||||
__futex_wake(pa->serial(), INT32_MAX);
|
||||
__futex_wake(&pa->serial, INT32_MAX);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -1198,6 +719,9 @@ int __system_property_update(prop_info *pi, const char *value, unsigned int len)
|
||||
int __system_property_add(const char *name, unsigned int namelen,
|
||||
const char *value, unsigned int valuelen)
|
||||
{
|
||||
prop_area *pa = __system_property_area__;
|
||||
const prop_info *pi;
|
||||
|
||||
if (namelen >= PROP_NAME_MAX)
|
||||
return -1;
|
||||
if (valuelen >= PROP_VALUE_MAX)
|
||||
@ -1205,28 +729,17 @@ int __system_property_add(const char *name, unsigned int namelen,
|
||||
if (namelen < 1)
|
||||
return -1;
|
||||
|
||||
if (!__system_property_area__) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
prop_area* pa = get_prop_area_for_name(name);
|
||||
|
||||
if (!pa) {
|
||||
__libc_format_log(ANDROID_LOG_ERROR, "libc", "Access denied adding property \"%s\"", name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
bool ret = pa->add(name, namelen, value, valuelen);
|
||||
if (!ret)
|
||||
pi = find_property(root_node(), name, namelen, value, valuelen, true);
|
||||
if (!pi)
|
||||
return -1;
|
||||
|
||||
// There is only a single mutator, but we want to make sure that
|
||||
// updates are visible to a reader waiting for the update.
|
||||
atomic_store_explicit(
|
||||
__system_property_area__->serial(),
|
||||
atomic_load_explicit(__system_property_area__->serial(), memory_order_relaxed) + 1,
|
||||
&pa->serial,
|
||||
atomic_load_explicit(&pa->serial, memory_order_relaxed) + 1,
|
||||
memory_order_release);
|
||||
__futex_wake(__system_property_area__->serial(), INT32_MAX);
|
||||
__futex_wake(&pa->serial, INT32_MAX);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1248,13 +761,9 @@ unsigned int __system_property_wait_any(unsigned int serial)
|
||||
prop_area *pa = __system_property_area__;
|
||||
uint32_t my_serial;
|
||||
|
||||
if (!pa) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
do {
|
||||
__futex_wait(pa->serial(), serial, NULL);
|
||||
my_serial = atomic_load_explicit(pa->serial(), memory_order_acquire);
|
||||
__futex_wait(&pa->serial, serial, NULL);
|
||||
my_serial = atomic_load_explicit(&pa->serial, memory_order_acquire);
|
||||
} while (my_serial == serial);
|
||||
|
||||
return my_serial;
|
||||
@ -1275,18 +784,9 @@ const prop_info *__system_property_find_nth(unsigned n)
|
||||
int __system_property_foreach(void (*propfn)(const prop_info *pi, void *cookie),
|
||||
void *cookie)
|
||||
{
|
||||
if (!__system_property_area__) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (__predict_false(compat_mode)) {
|
||||
return __system_property_foreach_compat(propfn, cookie);
|
||||
}
|
||||
|
||||
list_foreach(contexts, [propfn, cookie](context_node* l) {
|
||||
if (l->check_access_and_open()) {
|
||||
l->pa()->foreach(propfn, cookie);
|
||||
}
|
||||
});
|
||||
return 0;
|
||||
return foreach_property(root_node(), propfn, cookie);
|
||||
}
|
||||
|
@ -98,11 +98,6 @@ enum {
|
||||
*/
|
||||
ANDROID_DLEXT_LOAD_AT_FIXED_ADDRESS = 0x100,
|
||||
|
||||
/* This flag used to load library in a different namespace. The namespace is
|
||||
* specified in library_namespace.
|
||||
*/
|
||||
ANDROID_DLEXT_USE_NAMESPACE = 0x200,
|
||||
|
||||
/* Mask of valid bits */
|
||||
ANDROID_DLEXT_VALID_FLAG_BITS = ANDROID_DLEXT_RESERVED_ADDRESS |
|
||||
ANDROID_DLEXT_RESERVED_ADDRESS_HINT |
|
||||
@ -112,12 +107,9 @@ enum {
|
||||
ANDROID_DLEXT_USE_LIBRARY_FD_OFFSET |
|
||||
ANDROID_DLEXT_FORCE_LOAD |
|
||||
ANDROID_DLEXT_FORCE_FIXED_VADDR |
|
||||
ANDROID_DLEXT_LOAD_AT_FIXED_ADDRESS |
|
||||
ANDROID_DLEXT_USE_NAMESPACE,
|
||||
ANDROID_DLEXT_LOAD_AT_FIXED_ADDRESS,
|
||||
};
|
||||
|
||||
struct android_namespace_t;
|
||||
|
||||
typedef struct {
|
||||
uint64_t flags;
|
||||
void* reserved_addr;
|
||||
@ -125,75 +117,10 @@ typedef struct {
|
||||
int relro_fd;
|
||||
int library_fd;
|
||||
off64_t library_fd_offset;
|
||||
struct android_namespace_t* library_namespace;
|
||||
} android_dlextinfo;
|
||||
|
||||
extern void* android_dlopen_ext(const char* filename, int flag, const android_dlextinfo* extinfo);
|
||||
|
||||
/*
|
||||
* Initializes public and anonymous namespaces. The public_ns_sonames is the list of sonames
|
||||
* to be included into public namespace separated by colon. Example: "libc.so:libm.so:libdl.so".
|
||||
* The libraries in this list should be loaded prior to this call.
|
||||
*
|
||||
* The anon_ns_library_path is the search path for anonymous namespace. The anonymous namespace
|
||||
* is used in the case when linker cannot identify the caller of dlopen/dlsym. This happens
|
||||
* for the code not loaded by dynamic linker; for example calls from the mono-compiled code.
|
||||
*/
|
||||
extern bool android_init_namespaces(const char* public_ns_sonames,
|
||||
const char* anon_ns_library_path);
|
||||
|
||||
|
||||
enum {
|
||||
/* A regular namespace is the namespace with a custom search path that does
|
||||
* not impose any restrictions on the location of native libraries.
|
||||
*/
|
||||
ANDROID_NAMESPACE_TYPE_REGULAR = 0,
|
||||
|
||||
/* An isolated namespace requires all the libraries to be on the search path
|
||||
* or under permitted_when_isolated_path. The search path is the union of
|
||||
* ld_library_path and default_library_path.
|
||||
*/
|
||||
ANDROID_NAMESPACE_TYPE_ISOLATED = 1,
|
||||
|
||||
/* The shared namespace clones the list of libraries of the caller namespace upon creation
|
||||
* which means that they are shared between namespaces - the caller namespace and the new one
|
||||
* will use the same copy of a library if it was loaded prior to android_create_namespace call.
|
||||
*
|
||||
* Note that libraries loaded after the namespace is created will not be shared.
|
||||
*
|
||||
* Shared namespaces can be isolated or regular. Note that they do not inherit the search path nor
|
||||
* permitted_path from the caller's namespace.
|
||||
*/
|
||||
ANDROID_NAMESPACE_TYPE_SHARED = 2,
|
||||
ANDROID_NAMESPACE_TYPE_SHARED_ISOLATED = ANDROID_NAMESPACE_TYPE_SHARED |
|
||||
ANDROID_NAMESPACE_TYPE_ISOLATED,
|
||||
};
|
||||
|
||||
/*
|
||||
* Creates new linker namespace.
|
||||
* ld_library_path and default_library_path represent the search path
|
||||
* for the libraries in the namespace.
|
||||
*
|
||||
* The libraries in the namespace are searched by folowing order:
|
||||
* 1. ld_library_path (Think of this as namespace-local LD_LIBRARY_PATH)
|
||||
* 2. In directories specified by DT_RUNPATH of the "needed by" binary.
|
||||
* 3. deault_library_path (This of this as namespace-local default library path)
|
||||
*
|
||||
* When type is ANDROID_NAMESPACE_TYPE_ISOLATED the resulting namespace requires all of
|
||||
* the libraries to be on the search path or under the permitted_when_isolated_path;
|
||||
* the search_path is ld_library_path:default_library_path. Note that the
|
||||
* permitted_when_isolated_path path is not part of the search_path and
|
||||
* does not affect the search order. It is a way to allow loading libraries from specific
|
||||
* locations when using absolute path.
|
||||
* If a library or any of its dependencies are outside of the permitted_when_isolated_path
|
||||
* and search_path, and it is not part of the public namespace dlopen will fail.
|
||||
*/
|
||||
extern struct android_namespace_t* android_create_namespace(const char* name,
|
||||
const char* ld_library_path,
|
||||
const char* default_library_path,
|
||||
uint64_t type,
|
||||
const char* permitted_when_isolated_path);
|
||||
|
||||
__END_DECLS
|
||||
|
||||
#endif /* __ANDROID_DLEXT_H__ */
|
||||
|
@ -46,8 +46,7 @@ typedef struct {
|
||||
extern void* dlopen(const char* filename, int flag);
|
||||
extern int dlclose(void* handle);
|
||||
extern const char* dlerror(void);
|
||||
extern void* dlsym(void* handle, const char* symbol) __nonnull((2));
|
||||
extern void* dlvsym(void* handle, const char* symbol, const char* version) __nonnull((2, 3));
|
||||
extern void* dlsym(void* handle, const char* symbol);
|
||||
extern int dladdr(const void* addr, Dl_info *info);
|
||||
|
||||
enum {
|
||||
|
@ -32,19 +32,18 @@
|
||||
#include <sys/cdefs.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
#if !defined(__bionic_using_gnu_basename)
|
||||
/*
|
||||
* Including <string.h> will get you the GNU basename, unless <libgen.h> is
|
||||
* included, either before or after including <string.h>.
|
||||
*
|
||||
* Note that this has the wrong argument cv-qualifiers, but doesn't modify its
|
||||
* input and uses thread-local storage for the result if necessary.
|
||||
* <string.h> gets you the GNU basename.
|
||||
* <libgen.h> the POSIX one.
|
||||
* Note that our "POSIX" one has the wrong argument cv-qualifiers, but doesn't
|
||||
* modify its input and uses thread-local storage for the result if necessary.
|
||||
*/
|
||||
extern char* __posix_basename(const char*) __RENAME(basename);
|
||||
|
||||
#define basename __posix_basename
|
||||
extern char* basename(const char*);
|
||||
#define __bionic_using_posix_basename
|
||||
#endif
|
||||
|
||||
/* This has the wrong argument cv-qualifiers, but doesn't modify its input and uses thread-local storage for the result if necessary. */
|
||||
extern char* dirname(const char*);
|
||||
|
@ -96,26 +96,6 @@ typedef int pthread_once_t;
|
||||
|
||||
#define PTHREAD_ONCE_INIT 0
|
||||
|
||||
typedef struct {
|
||||
#if defined(__LP64__)
|
||||
int64_t __private[4];
|
||||
#else
|
||||
int32_t __private[8];
|
||||
#endif
|
||||
} pthread_barrier_t;
|
||||
|
||||
typedef int pthread_barrierattr_t;
|
||||
|
||||
#define PTHREAD_BARRIER_SERIAL_THREAD -1
|
||||
|
||||
typedef struct {
|
||||
#if defined(__LP64__)
|
||||
int64_t __private;
|
||||
#else
|
||||
int32_t __private[2];
|
||||
#endif
|
||||
} pthread_spinlock_t;
|
||||
|
||||
#if defined(__LP64__)
|
||||
#define PTHREAD_STACK_MIN (4 * PAGE_SIZE)
|
||||
#else
|
||||
@ -150,7 +130,7 @@ int pthread_attr_setschedparam(pthread_attr_t*, const struct sched_param*) __non
|
||||
int pthread_attr_setschedpolicy(pthread_attr_t*, int) __nonnull((1));
|
||||
int pthread_attr_setscope(pthread_attr_t*, int) __nonnull((1));
|
||||
int pthread_attr_setstack(pthread_attr_t*, void*, size_t) __nonnull((1));
|
||||
int pthread_attr_setstacksize(pthread_attr_t*, size_t) __nonnull((1));
|
||||
int pthread_attr_setstacksize(pthread_attr_t*, size_t stack_size) __nonnull((1));
|
||||
|
||||
int pthread_condattr_destroy(pthread_condattr_t*) __nonnull((1));
|
||||
int pthread_condattr_getclock(const pthread_condattr_t*, clockid_t*) __nonnull((1, 2));
|
||||
@ -225,24 +205,9 @@ int pthread_rwlock_timedrdlock(pthread_rwlock_t*, const struct timespec*) __nonn
|
||||
int pthread_rwlock_timedwrlock(pthread_rwlock_t*, const struct timespec*) __nonnull((1, 2));
|
||||
int pthread_rwlock_tryrdlock(pthread_rwlock_t*) __nonnull((1));
|
||||
int pthread_rwlock_trywrlock(pthread_rwlock_t*) __nonnull((1));
|
||||
int pthread_rwlock_unlock(pthread_rwlock_t *) __nonnull((1));
|
||||
int pthread_rwlock_unlock(pthread_rwlock_t *rwlock) __nonnull((1));
|
||||
int pthread_rwlock_wrlock(pthread_rwlock_t*) __nonnull((1));
|
||||
|
||||
int pthread_barrierattr_init(pthread_barrierattr_t* attr) __nonnull((1));
|
||||
int pthread_barrierattr_destroy(pthread_barrierattr_t* attr) __nonnull((1));
|
||||
int pthread_barrierattr_getpshared(pthread_barrierattr_t* attr, int* pshared) __nonnull((1, 2));
|
||||
int pthread_barrierattr_setpshared(pthread_barrierattr_t* attr, int pshared) __nonnull((1));
|
||||
|
||||
int pthread_barrier_init(pthread_barrier_t*, const pthread_barrierattr_t*, unsigned) __nonnull((1));
|
||||
int pthread_barrier_destroy(pthread_barrier_t*) __nonnull((1));
|
||||
int pthread_barrier_wait(pthread_barrier_t*) __nonnull((1));
|
||||
|
||||
int pthread_spin_destroy(pthread_spinlock_t*) __nonnull((1));
|
||||
int pthread_spin_init(pthread_spinlock_t*, int) __nonnull((1));
|
||||
int pthread_spin_lock(pthread_spinlock_t*) __nonnull((1));
|
||||
int pthread_spin_trylock(pthread_spinlock_t*) __nonnull((1));
|
||||
int pthread_spin_unlock(pthread_spinlock_t*) __nonnull((1));
|
||||
|
||||
pthread_t pthread_self(void) __pure2;
|
||||
|
||||
int pthread_setname_np(pthread_t, const char*) __nonnull((2));
|
||||
|
@ -270,7 +270,6 @@ int vasprintf(char ** __restrict, const char * __restrict,
|
||||
void clearerr_unlocked(FILE*);
|
||||
int feof_unlocked(FILE*);
|
||||
int ferror_unlocked(FILE*);
|
||||
int fileno_unlocked(FILE*);
|
||||
|
||||
/*
|
||||
* Stdio function-access interface.
|
||||
|
@ -115,18 +115,18 @@ extern size_t strxfrm(char* __restrict, const char* __restrict, size_t);
|
||||
extern int strcoll_l(const char *, const char *, locale_t) __purefunc;
|
||||
extern size_t strxfrm_l(char* __restrict, const char* __restrict, size_t, locale_t);
|
||||
|
||||
#if defined(__USE_GNU) && !defined(basename)
|
||||
#if defined(__USE_GNU) && !defined(__bionic_using_posix_basename)
|
||||
/*
|
||||
* glibc has a basename in <string.h> that's different to the POSIX one in <libgen.h>.
|
||||
* It doesn't modify its argument, and in C++ it's const-correct.
|
||||
*/
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C++" char* basename(char*) __RENAME(__gnu_basename) __nonnull((1));
|
||||
extern "C++" const char* basename(const char*) __RENAME(__gnu_basename) __nonnull((1));
|
||||
#else
|
||||
extern char* basename(const char*) __RENAME(__gnu_basename) __nonnull((1));
|
||||
#endif
|
||||
#define __bionic_using_gnu_basename
|
||||
#endif
|
||||
|
||||
extern void* __memchr_chk(const void*, int, size_t, size_t);
|
||||
|
@ -41,7 +41,6 @@ typedef struct prop_msg prop_msg;
|
||||
#define PROP_AREA_VERSION_COMPAT 0x45434f76
|
||||
|
||||
#define PROP_SERVICE_NAME "property_service"
|
||||
#define PROP_FILENAME_MAX 1024
|
||||
#define PROP_FILENAME "/dev/__properties__"
|
||||
|
||||
#define PA_SIZE (128 * 1024)
|
||||
|
@ -59,7 +59,7 @@ extern void* mmap64(void*, size_t, int, int, int, off64_t);
|
||||
extern int munmap(void*, size_t);
|
||||
extern int msync(const void*, size_t, int);
|
||||
extern int mprotect(const void*, size_t, int);
|
||||
extern void* mremap(void*, size_t, size_t, int, ...);
|
||||
extern void* mremap(void*, size_t, size_t, unsigned long);
|
||||
|
||||
extern int mlockall(int);
|
||||
extern int munlockall(void);
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -10,25 +10,43 @@ LIBC {
|
||||
__b64_ntop;
|
||||
__b64_pton;
|
||||
__brk; # arm x86 mips
|
||||
__cmpdf2; # arm
|
||||
__cmsg_nxthdr;
|
||||
__connect; # arm x86 mips
|
||||
__ctype_get_mb_cur_max;
|
||||
__cxa_atexit;
|
||||
__cxa_finalize;
|
||||
__cxa_thread_atexit_impl;
|
||||
__divdf3; # arm
|
||||
__divdi3; # arm x86 mips
|
||||
__divsf3; # arm
|
||||
__divsi3; # arm
|
||||
__dn_comp;
|
||||
__dn_count_labels;
|
||||
__dn_skipname;
|
||||
__epoll_pwait; # arm x86 mips
|
||||
__eqdf2; # arm
|
||||
__errno;
|
||||
__exit; # arm x86 mips
|
||||
__extendsfdf2; # arm
|
||||
__fbufsize;
|
||||
__fcntl64; # arm x86 mips
|
||||
__FD_CLR_chk;
|
||||
__FD_ISSET_chk;
|
||||
__FD_SET_chk;
|
||||
__fgets_chk;
|
||||
__fixdfsi; # arm
|
||||
__fixsfsi; # arm
|
||||
__fixunssfsi; # arm
|
||||
__flbf;
|
||||
__floatdidf; # arm
|
||||
__floatdisf; # arm
|
||||
__floatsidf; # arm
|
||||
__floatsisf; # arm
|
||||
__floatundidf; # arm
|
||||
__floatundisf; # arm
|
||||
__floatunsidf; # arm
|
||||
__floatunsisf; # arm
|
||||
__fp_nquery;
|
||||
__fp_query;
|
||||
__fpclassify;
|
||||
@ -40,14 +58,23 @@ LIBC {
|
||||
__freadable;
|
||||
__fsetlocking;
|
||||
__fstatfs64; # arm x86 mips
|
||||
__futex_wait; # arm x86 mips
|
||||
__futex_wake; # arm x86 mips
|
||||
__fwritable;
|
||||
__gedf2; # arm
|
||||
__get_h_errno;
|
||||
__get_thread; # arm x86 mips
|
||||
__get_tls; # arm x86 mips
|
||||
__getcpu; # arm x86 mips
|
||||
__getcwd; # arm x86 mips
|
||||
__getdents64; # arm x86 mips
|
||||
__getpid; # arm x86 mips
|
||||
__getpriority; # arm x86 mips
|
||||
__gnu_basename;
|
||||
__gnu_ldivmod_helper; # arm
|
||||
__gnu_strerror_r;
|
||||
__gnu_uldivmod_helper; # arm
|
||||
__gtdf2; # arm
|
||||
__hostalias;
|
||||
__ioctl; # arm x86 mips
|
||||
__isfinite;
|
||||
@ -63,18 +90,25 @@ LIBC {
|
||||
__isnormalf;
|
||||
__isnormall;
|
||||
__isthreaded;
|
||||
__ledf2; # arm
|
||||
__libc_current_sigrtmax;
|
||||
__libc_current_sigrtmin;
|
||||
__libc_init;
|
||||
__llseek; # arm x86 mips
|
||||
__loc_aton;
|
||||
__loc_ntoa;
|
||||
__lshrdi3; # arm
|
||||
__ltdf2; # arm
|
||||
__memchr_chk;
|
||||
__memcpy_chk;
|
||||
__memmove_chk;
|
||||
__memrchr_chk;
|
||||
__memset_chk;
|
||||
__mmap2; # arm x86 mips
|
||||
__muldf3; # arm
|
||||
__muldi3; # arm
|
||||
__mulsf3; # arm
|
||||
__nedf2; # arm
|
||||
__ns_format_ttl; # arm x86 mips
|
||||
__ns_get16; # arm x86 mips
|
||||
__ns_get32; # arm x86 mips
|
||||
@ -97,6 +131,7 @@ LIBC {
|
||||
__ns_skiprr; # arm x86 mips
|
||||
__ns_sprintrr; # arm x86 mips
|
||||
__ns_sprintrrf; # arm x86 mips
|
||||
__open; # arm x86 mips
|
||||
__open_2;
|
||||
__openat; # arm x86 mips
|
||||
__openat_2;
|
||||
@ -113,7 +148,11 @@ LIBC {
|
||||
__p_time;
|
||||
__p_type;
|
||||
__p_type_syms;
|
||||
__page_shift; # arm x86 mips
|
||||
__page_size; # arm x86 mips
|
||||
__poll_chk;
|
||||
__popcount_tab; # arm
|
||||
__popcountsi2; # arm x86 mips
|
||||
__ppoll; # arm x86 mips
|
||||
__ppoll_chk;
|
||||
__pread64_chk;
|
||||
@ -122,7 +161,7 @@ LIBC {
|
||||
__pselect6; # arm x86 mips
|
||||
__pthread_cleanup_pop;
|
||||
__pthread_cleanup_push;
|
||||
__pthread_gettid; # arm x86 mips nobrillo
|
||||
__pthread_gettid; # arm x86 mips
|
||||
__ptrace; # arm x86 mips
|
||||
__putlong;
|
||||
__putshort;
|
||||
@ -152,6 +191,7 @@ LIBC {
|
||||
__res_send;
|
||||
__res_send_setqhook;
|
||||
__res_send_setrhook;
|
||||
__restore_core_regs; # arm
|
||||
__rt_sigaction; # arm x86 mips
|
||||
__rt_sigpending; # arm x86 mips
|
||||
__rt_sigprocmask; # arm x86 mips
|
||||
@ -161,14 +201,27 @@ LIBC {
|
||||
__sched_cpucount;
|
||||
__sched_cpufree;
|
||||
__sched_getaffinity; # arm x86 mips
|
||||
__sclose; # arm x86 mips
|
||||
__sdidinit; # arm x86 mips
|
||||
__set_errno; # arm x86 mips
|
||||
__set_tid_address; # arm x86 mips
|
||||
__set_tls; # arm mips
|
||||
__sF;
|
||||
__sflags; # arm x86 mips
|
||||
__sflush; # arm x86 mips
|
||||
__sfp; # arm x86 mips
|
||||
__sglue; # arm x86 mips
|
||||
__sigaction; # arm x86 mips
|
||||
__signalfd4; # arm x86 mips
|
||||
__sinit; # arm x86 mips
|
||||
__smakebuf; # arm x86 mips
|
||||
__snprintf_chk;
|
||||
__socket; # arm x86 mips
|
||||
__sprintf_chk;
|
||||
__sread; # arm x86 mips
|
||||
__srefill; # arm x86 mips
|
||||
__srget; # arm x86 mips
|
||||
__sseek; # arm x86 mips
|
||||
__stack_chk_fail;
|
||||
__stack_chk_guard;
|
||||
__statfs64; # arm x86 mips
|
||||
@ -185,37 +238,49 @@ LIBC {
|
||||
__strncpy_chk;
|
||||
__strncpy_chk2;
|
||||
__strrchr_chk;
|
||||
__subdf3; # arm
|
||||
__subsf3; # arm
|
||||
__swbuf; # arm x86 mips
|
||||
__swrite; # arm x86 mips
|
||||
__swsetup; # arm x86 mips
|
||||
__sym_ntop;
|
||||
__sym_ntos;
|
||||
__sym_ston;
|
||||
__system_properties_init; # arm x86 mips
|
||||
__system_property_add; # arm x86 mips
|
||||
__system_property_area__; # arm x86 mips
|
||||
__system_property_area_init; # arm x86 mips
|
||||
__system_property_area_serial; # arm x86 mips
|
||||
__system_property_find; # arm x86 mips
|
||||
__system_property_find_nth; # arm x86 mips
|
||||
__system_property_foreach; # arm x86 mips
|
||||
__system_property_get; # arm x86 mips
|
||||
__system_property_read; # arm x86 mips
|
||||
__system_property_serial; # arm x86 mips
|
||||
__system_property_set; # arm x86 mips
|
||||
__system_property_set_filename; # arm x86 mips
|
||||
__system_property_update; # arm x86 mips
|
||||
__system_property_wait_any; # arm x86 mips
|
||||
__system_properties_init;
|
||||
__system_property_add;
|
||||
__system_property_area__;
|
||||
__system_property_area_init;
|
||||
__system_property_area_serial;
|
||||
__system_property_find;
|
||||
__system_property_find_nth;
|
||||
__system_property_foreach;
|
||||
__system_property_get;
|
||||
__system_property_read;
|
||||
__system_property_serial;
|
||||
__system_property_set;
|
||||
__system_property_set_filename;
|
||||
__system_property_update;
|
||||
__system_property_wait_any;
|
||||
__timer_create; # arm x86 mips
|
||||
__timer_delete; # arm x86 mips
|
||||
__timer_getoverrun; # arm x86 mips
|
||||
__timer_gettime; # arm x86 mips
|
||||
__timer_settime; # arm x86 mips
|
||||
__truncdfsf2; # arm
|
||||
__udivdi3; # arm x86 mips
|
||||
__udivsi3; # arm
|
||||
__umask_chk;
|
||||
__unorddf2; # arm
|
||||
__unordsf2; # arm
|
||||
__vsnprintf_chk;
|
||||
__vsprintf_chk;
|
||||
__wait4; # arm x86 mips
|
||||
__waitid; # arm x86 mips
|
||||
_ctype_;
|
||||
_Exit;
|
||||
_exit;
|
||||
_flushlbf;
|
||||
_fwalk; # arm x86 mips
|
||||
_getlong;
|
||||
_getshort;
|
||||
_longjmp;
|
||||
@ -242,7 +307,9 @@ LIBC {
|
||||
android_gethostbynamefornet;
|
||||
android_set_abort_message;
|
||||
arc4random;
|
||||
arc4random_addrandom; # arm x86 mips
|
||||
arc4random_buf;
|
||||
arc4random_stir; # arm x86 mips
|
||||
arc4random_uniform;
|
||||
asctime;
|
||||
asctime64; # arm x86 mips
|
||||
@ -256,11 +323,14 @@ LIBC {
|
||||
atoll;
|
||||
basename;
|
||||
basename_r; # arm x86 mips
|
||||
bcopy; # arm x86 mips
|
||||
bind;
|
||||
bindresvport;
|
||||
brk;
|
||||
bsd_signal; # arm x86 mips
|
||||
bsearch;
|
||||
btowc;
|
||||
bzero; # arm x86 mips
|
||||
c16rtomb;
|
||||
c32rtomb;
|
||||
cacheflush; # arm mips
|
||||
@ -313,6 +383,7 @@ LIBC {
|
||||
dup3;
|
||||
duplocale;
|
||||
endmntent;
|
||||
endpwent;
|
||||
endservent;
|
||||
endutent;
|
||||
environ;
|
||||
@ -359,6 +430,7 @@ LIBC {
|
||||
fdatasync;
|
||||
fdopen;
|
||||
fdopendir;
|
||||
fdprintf; # arm x86 mips
|
||||
feof;
|
||||
feof_unlocked;
|
||||
ferror;
|
||||
@ -390,6 +462,7 @@ LIBC {
|
||||
fputws;
|
||||
fread;
|
||||
free;
|
||||
free_malloc_leak_info;
|
||||
freeaddrinfo;
|
||||
freelocale;
|
||||
fremovexattr;
|
||||
@ -410,6 +483,7 @@ LIBC {
|
||||
fsync;
|
||||
ftell;
|
||||
ftello;
|
||||
ftime; # arm x86 mips
|
||||
ftok;
|
||||
ftruncate;
|
||||
ftruncate64;
|
||||
@ -430,6 +504,7 @@ LIBC {
|
||||
fwscanf;
|
||||
gai_strerror;
|
||||
get_avphys_pages;
|
||||
get_malloc_leak_info;
|
||||
get_nprocs;
|
||||
get_nprocs_conf;
|
||||
get_phys_pages;
|
||||
@ -441,6 +516,8 @@ LIBC {
|
||||
getchar_unlocked;
|
||||
getcwd;
|
||||
getdelim;
|
||||
getdents; # arm x86 mips
|
||||
getdtablesize; # arm x86 mips
|
||||
getegid;
|
||||
getenv;
|
||||
geteuid;
|
||||
@ -515,6 +592,7 @@ LIBC {
|
||||
if_nametoindex;
|
||||
imaxabs;
|
||||
imaxdiv;
|
||||
index; # arm x86 mips
|
||||
inet_addr;
|
||||
inet_aton;
|
||||
inet_lnaof;
|
||||
@ -567,6 +645,7 @@ LIBC {
|
||||
isprint_l;
|
||||
ispunct;
|
||||
ispunct_l;
|
||||
issetugid; # arm x86 mips
|
||||
isspace;
|
||||
isspace_l;
|
||||
isupper;
|
||||
@ -656,6 +735,7 @@ LIBC {
|
||||
mempcpy;
|
||||
memrchr;
|
||||
memset;
|
||||
memswap; # arm x86 mips
|
||||
mincore;
|
||||
mkdir;
|
||||
mkdirat;
|
||||
@ -675,6 +755,7 @@ LIBC {
|
||||
mktemp;
|
||||
mktime;
|
||||
mktime64; # arm x86 mips
|
||||
mktime_tz;
|
||||
mlock;
|
||||
mlockall;
|
||||
mmap;
|
||||
@ -745,6 +826,7 @@ LIBC {
|
||||
pthread_attr_getschedpolicy;
|
||||
pthread_attr_getscope;
|
||||
pthread_attr_getstack;
|
||||
pthread_attr_getstackaddr; # arm x86 mips
|
||||
pthread_attr_getstacksize;
|
||||
pthread_attr_init;
|
||||
pthread_attr_setdetachstate;
|
||||
@ -753,6 +835,7 @@ LIBC {
|
||||
pthread_attr_setschedpolicy;
|
||||
pthread_attr_setscope;
|
||||
pthread_attr_setstack;
|
||||
pthread_attr_setstackaddr; # arm x86 mips
|
||||
pthread_attr_setstacksize;
|
||||
pthread_cond_broadcast;
|
||||
pthread_cond_destroy;
|
||||
@ -868,6 +951,7 @@ LIBC {
|
||||
res_mkquery;
|
||||
res_query;
|
||||
res_search;
|
||||
restore_core_regs; # arm
|
||||
rewind;
|
||||
rewinddir;
|
||||
rmdir;
|
||||
@ -1010,6 +1094,8 @@ LIBC {
|
||||
strncpy;
|
||||
strndup;
|
||||
strnlen;
|
||||
strntoimax; # arm x86 mips
|
||||
strntoumax; # arm x86 mips
|
||||
strpbrk;
|
||||
strptime;
|
||||
strrchr;
|
||||
@ -1028,6 +1114,7 @@ LIBC {
|
||||
strtoll;
|
||||
strtoll_l;
|
||||
strtoq;
|
||||
strtotimeval; # arm x86 mips
|
||||
strtoul;
|
||||
strtoull;
|
||||
strtoull_l;
|
||||
@ -1049,6 +1136,7 @@ LIBC {
|
||||
sysinfo;
|
||||
syslog;
|
||||
system;
|
||||
sysv_signal; # arm x86 mips
|
||||
tcdrain;
|
||||
tcflow;
|
||||
tcflush;
|
||||
@ -1080,6 +1168,7 @@ LIBC {
|
||||
timerfd_settime;
|
||||
times;
|
||||
timezone;
|
||||
tkill; # arm x86 mips
|
||||
tmpfile;
|
||||
tmpnam;
|
||||
toascii;
|
||||
@ -1121,6 +1210,7 @@ LIBC {
|
||||
vdprintf;
|
||||
verr;
|
||||
verrx;
|
||||
vfdprintf; # arm x86 mips
|
||||
vfork;
|
||||
vfprintf;
|
||||
vfscanf;
|
||||
@ -1140,6 +1230,7 @@ LIBC {
|
||||
vwprintf;
|
||||
vwscanf;
|
||||
wait;
|
||||
wait3; # arm x86 mips
|
||||
wait4;
|
||||
waitid;
|
||||
waitpid;
|
||||
@ -1188,6 +1279,7 @@ LIBC {
|
||||
wcstoull;
|
||||
wcstoull_l;
|
||||
wcstoumax;
|
||||
wcswcs; # arm x86 mips
|
||||
wcswidth;
|
||||
wcsxfrm;
|
||||
wcsxfrm_l;
|
||||
@ -1212,46 +1304,17 @@ LIBC {
|
||||
|
||||
LIBC_N {
|
||||
global:
|
||||
__aeabi_atexit; # arm
|
||||
__aeabi_memclr; # arm
|
||||
__aeabi_memclr4; # arm
|
||||
__aeabi_memclr8; # arm
|
||||
__aeabi_memcpy; # arm
|
||||
__aeabi_memcpy4; # arm
|
||||
__aeabi_memcpy8; # arm
|
||||
__aeabi_memmove; # arm
|
||||
__aeabi_memmove4; # arm
|
||||
__aeabi_memmove8; # arm
|
||||
__aeabi_memset; # arm
|
||||
__aeabi_memset4; # arm
|
||||
__aeabi_memset8; # arm
|
||||
__fread_chk;
|
||||
__fwrite_chk;
|
||||
__getcwd_chk;
|
||||
__gnu_Unwind_Find_exidx; # arm
|
||||
__pwrite_chk;
|
||||
__pwrite64_chk;
|
||||
__write_chk;
|
||||
fileno_unlocked;
|
||||
freeifaddrs;
|
||||
getgrgid_r;
|
||||
getgrnam_r;
|
||||
getifaddrs;
|
||||
preadv;
|
||||
preadv64;
|
||||
prlimit; # arm mips x86
|
||||
pthread_barrierattr_destroy;
|
||||
pthread_barrierattr_getpshared;
|
||||
pthread_barrierattr_init;
|
||||
pthread_barrierattr_setpshared;
|
||||
pthread_barrier_destroy;
|
||||
pthread_barrier_init;
|
||||
pthread_barrier_wait;
|
||||
pthread_spin_destroy;
|
||||
pthread_spin_init;
|
||||
pthread_spin_lock;
|
||||
pthread_spin_trylock;
|
||||
pthread_spin_unlock;
|
||||
pwritev;
|
||||
pwritev64;
|
||||
scandirat;
|
||||
@ -1335,33 +1398,8 @@ LIBC_PRIVATE {
|
||||
__ashrdi3; # arm
|
||||
__bionic_brk; # arm x86 mips
|
||||
__bionic_libgcc_compat_symbols; # arm x86
|
||||
__cmpdf2; # arm
|
||||
__divdf3; # arm
|
||||
__divdi3; # arm x86 mips
|
||||
__divsf3; # arm
|
||||
__divsi3; # arm
|
||||
__bionic_libgcc_unwind_symbols; # arm
|
||||
__dso_handle; # arm
|
||||
__eqdf2; # arm
|
||||
__extendsfdf2; # arm
|
||||
__fixdfsi; # arm
|
||||
__fixsfsi; # arm
|
||||
__fixunssfsi; # arm
|
||||
__floatdidf; # arm
|
||||
__floatdisf; # arm
|
||||
__floatsidf; # arm
|
||||
__floatsisf; # arm
|
||||
__floatundidf; # arm
|
||||
__floatundisf; # arm
|
||||
__floatunsidf; # arm
|
||||
__floatunsisf; # arm
|
||||
__futex_wait; # arm x86 mips nobrillo
|
||||
__futex_wake; # arm x86 mips nobrillo
|
||||
__gedf2; # arm
|
||||
__get_thread; # arm x86 mips nobrillo
|
||||
__get_tls; # arm x86 mips nobrillo
|
||||
__getdents64; # arm x86 mips
|
||||
__gnu_ldivmod_helper; # arm
|
||||
__gnu_uldivmod_helper; # arm
|
||||
__gnu_Unwind_Backtrace; # arm
|
||||
__gnu_unwind_execute; # arm
|
||||
__gnu_Unwind_Find_exidx; # arm
|
||||
@ -1380,46 +1418,6 @@ LIBC_PRIVATE {
|
||||
__gnu_Unwind_Save_VFP_D_16_to_31; # arm
|
||||
__gnu_Unwind_Save_WMMXC; # arm
|
||||
__gnu_Unwind_Save_WMMXD; # arm
|
||||
__gtdf2; # arm
|
||||
__ledf2; # arm
|
||||
__lshrdi3; # arm
|
||||
__ltdf2; # arm
|
||||
__muldf3; # arm
|
||||
__muldi3; # arm
|
||||
__mulsf3; # arm
|
||||
__nedf2; # arm
|
||||
__open; # arm x86 mips nobrillo
|
||||
__page_shift; # arm x86 mips nobrillo
|
||||
__page_size; # arm x86 mips nobrillo
|
||||
__popcount_tab; # arm
|
||||
__popcountsi2; # arm x86 mips
|
||||
__pthread_gettid; # arm x86 mips nobrillo
|
||||
__restore_core_regs; # arm
|
||||
__sclose; # arm x86 mips
|
||||
__sdidinit; # arm x86 mips nobrillo
|
||||
__set_errno; # arm x86 mips nobrillo
|
||||
__sflags; # arm x86 mips
|
||||
__sflush; # arm x86 mips
|
||||
__sfp; # arm x86 mips
|
||||
__sglue; # arm x86 mips
|
||||
__sinit; # arm x86 mips nobrillo
|
||||
__smakebuf; # arm x86 mips
|
||||
__sread; # arm x86 mips
|
||||
__srefill; # arm x86 mips
|
||||
__srget; # arm x86 mips
|
||||
__sseek; # arm x86 mips
|
||||
__subdf3; # arm
|
||||
__subsf3; # arm
|
||||
__swbuf; # arm x86 mips
|
||||
__swrite; # arm x86 mips
|
||||
__swsetup; # arm x86 mips
|
||||
__truncdfsf2; # arm
|
||||
__udivdi3; # arm mips
|
||||
__udivsi3; # arm
|
||||
__unorddf2; # arm
|
||||
__unordsf2; # arm
|
||||
__wait4; # arm x86 mips nobrillo
|
||||
_fwalk; # arm x86 mips
|
||||
_Unwind_Backtrace; # arm
|
||||
_Unwind_Complete; # arm
|
||||
_Unwind_DeleteException; # arm
|
||||
@ -1435,40 +1433,14 @@ LIBC_PRIVATE {
|
||||
_Unwind_VRS_Get; # arm
|
||||
_Unwind_VRS_Pop; # arm
|
||||
_Unwind_VRS_Set; # arm
|
||||
arc4random_addrandom; # arm x86 mips nobrillo
|
||||
arc4random_stir; # arm x86 mips nobrillo
|
||||
atexit; # arm
|
||||
bcopy; # arm x86 mips nobrillo
|
||||
bzero; # arm x86 mips nobrillo
|
||||
bsd_signal; # arm x86 mips nobrillo
|
||||
dlmalloc; # arm x86 mips nobrillo
|
||||
dlmalloc_inspect_all; # arm x86 mips nobrillo
|
||||
dlmalloc_trim; # arm x86 mips nobrillo
|
||||
dlmalloc_usable_size; # arm x86 mips nobrillo
|
||||
endpwent; # arm x86 mips nobrillo
|
||||
fdprintf; # arm x86 mips nobrillo
|
||||
free_malloc_leak_info;
|
||||
ftime; # arm x86 mips nobrillo
|
||||
get_malloc_leak_info;
|
||||
getdents; # arm x86 mips nobrillo
|
||||
getdtablesize; # arm x86 mips nobrillo
|
||||
dlmalloc; # arm x86 mips
|
||||
dlmalloc_inspect_all;
|
||||
dlmalloc_trim;
|
||||
dlmalloc_usable_size; # arm x86 mips
|
||||
gMallocLeakZygoteChild;
|
||||
index; # arm x86 mips nobrillo
|
||||
issetugid; # arm x86 mips nobrillo
|
||||
memswap; # arm x86 mips nobrillo
|
||||
pthread_attr_getstackaddr; # arm x86 mips nobrillo
|
||||
pthread_attr_setstackaddr; # arm x86 mips nobrillo
|
||||
restore_core_regs; # arm
|
||||
SHA1Final; # arm x86 mips
|
||||
SHA1Init; # arm x86 mips
|
||||
SHA1Transform; # arm x86 mips
|
||||
SHA1Update; # arm x86 mips
|
||||
strntoimax; # arm x86 mips nobrillo
|
||||
strntoumax; # arm x86 mips nobrillo
|
||||
strtotimeval; # arm x86 mips nobrillo
|
||||
sysv_signal; # arm x86 mips nobrillo
|
||||
tkill; # arm x86 mips nobrillo
|
||||
vfdprintf; # arm x86 mips nobrillo
|
||||
wait3; # arm x86 mips nobrillo
|
||||
wcswcs; # arm x86 mips nobrillo
|
||||
} LIBC_N;
|
||||
|
@ -131,6 +131,21 @@ LIBC {
|
||||
__sym_ntop;
|
||||
__sym_ntos;
|
||||
__sym_ston;
|
||||
__system_properties_init;
|
||||
__system_property_add;
|
||||
__system_property_area__;
|
||||
__system_property_area_init;
|
||||
__system_property_area_serial;
|
||||
__system_property_find;
|
||||
__system_property_find_nth;
|
||||
__system_property_foreach;
|
||||
__system_property_get;
|
||||
__system_property_read;
|
||||
__system_property_serial;
|
||||
__system_property_set;
|
||||
__system_property_set_filename;
|
||||
__system_property_update;
|
||||
__system_property_wait_any;
|
||||
__umask_chk;
|
||||
__vsnprintf_chk;
|
||||
__vsprintf_chk;
|
||||
@ -226,6 +241,7 @@ LIBC {
|
||||
dup3;
|
||||
duplocale;
|
||||
endmntent;
|
||||
endpwent;
|
||||
endservent;
|
||||
endutent;
|
||||
environ;
|
||||
@ -301,6 +317,7 @@ LIBC {
|
||||
fputws;
|
||||
fread;
|
||||
free;
|
||||
free_malloc_leak_info;
|
||||
freeaddrinfo;
|
||||
freelocale;
|
||||
fremovexattr;
|
||||
@ -341,6 +358,7 @@ LIBC {
|
||||
fwscanf;
|
||||
gai_strerror;
|
||||
get_avphys_pages;
|
||||
get_malloc_leak_info;
|
||||
get_nprocs;
|
||||
get_nprocs_conf;
|
||||
get_phys_pages;
|
||||
@ -581,6 +599,7 @@ LIBC {
|
||||
mkstemps64;
|
||||
mktemp;
|
||||
mktime;
|
||||
mktime_tz;
|
||||
mlock;
|
||||
mlockall;
|
||||
mmap;
|
||||
@ -1137,25 +1156,10 @@ LIBC_N {
|
||||
__pwrite_chk;
|
||||
__pwrite64_chk;
|
||||
__write_chk;
|
||||
fileno_unlocked;
|
||||
freeifaddrs;
|
||||
getgrgid_r;
|
||||
getgrnam_r;
|
||||
getifaddrs;
|
||||
preadv;
|
||||
preadv64;
|
||||
pthread_barrierattr_destroy;
|
||||
pthread_barrierattr_getpshared;
|
||||
pthread_barrierattr_init;
|
||||
pthread_barrierattr_setpshared;
|
||||
pthread_barrier_destroy;
|
||||
pthread_barrier_init;
|
||||
pthread_barrier_wait;
|
||||
pthread_spin_destroy;
|
||||
pthread_spin_init;
|
||||
pthread_spin_lock;
|
||||
pthread_spin_trylock;
|
||||
pthread_spin_unlock;
|
||||
pwritev;
|
||||
pwritev64;
|
||||
scandirat;
|
||||
@ -1165,22 +1169,7 @@ LIBC_N {
|
||||
|
||||
LIBC_PRIVATE {
|
||||
global:
|
||||
__system_properties_init; # arm64 x86_64 mips64
|
||||
__system_property_add; # arm64 x86_64 mips64
|
||||
__system_property_area__; # arm64 x86_64 mips64
|
||||
__system_property_area_init; # arm64 x86_64 mips64
|
||||
__system_property_area_serial; # arm64 x86_64 mips64
|
||||
__system_property_find; # arm64 x86_64 mips64
|
||||
__system_property_find_nth; # arm64 x86_64 mips64
|
||||
__system_property_foreach; # arm64 x86_64 mips64
|
||||
__system_property_get; # arm64 x86_64 mips64
|
||||
__system_property_read; # arm64 x86_64 mips64
|
||||
__system_property_serial; # arm64 x86_64 mips64
|
||||
__system_property_set; # arm64 x86_64 mips64
|
||||
__system_property_set_filename; # arm64 x86_64 mips64
|
||||
__system_property_update; # arm64 x86_64 mips64
|
||||
__system_property_wait_any; # arm64 x86_64 mips64
|
||||
free_malloc_leak_info;
|
||||
get_malloc_leak_info;
|
||||
dlmalloc_inspect_all;
|
||||
dlmalloc_trim;
|
||||
gMallocLeakZygoteChild;
|
||||
} LIBC_N;
|
||||
|
@ -9,18 +9,25 @@ LIBC {
|
||||
__b64_ntop;
|
||||
__b64_pton;
|
||||
__brk; # arm x86 mips
|
||||
__cmpdf2; # arm
|
||||
__cmsg_nxthdr;
|
||||
__connect; # arm x86 mips
|
||||
__ctype_get_mb_cur_max;
|
||||
__cxa_atexit;
|
||||
__cxa_finalize;
|
||||
__cxa_thread_atexit_impl;
|
||||
__divdf3; # arm
|
||||
__divdi3; # arm x86 mips
|
||||
__divsf3; # arm
|
||||
__divsi3; # arm
|
||||
__dn_comp;
|
||||
__dn_count_labels;
|
||||
__dn_skipname;
|
||||
__epoll_pwait; # arm x86 mips
|
||||
__eqdf2; # arm
|
||||
__errno;
|
||||
__exit; # arm x86 mips
|
||||
__extendsfdf2; # arm
|
||||
__fadvise64; # x86 mips
|
||||
__fbufsize;
|
||||
__fcntl64; # arm x86 mips
|
||||
@ -28,7 +35,18 @@ LIBC {
|
||||
__FD_ISSET_chk;
|
||||
__FD_SET_chk;
|
||||
__fgets_chk;
|
||||
__fixdfsi; # arm
|
||||
__fixsfsi; # arm
|
||||
__fixunssfsi; # arm
|
||||
__flbf;
|
||||
__floatdidf; # arm
|
||||
__floatdisf; # arm
|
||||
__floatsidf; # arm
|
||||
__floatsisf; # arm
|
||||
__floatundidf; # arm
|
||||
__floatundisf; # arm
|
||||
__floatunsidf; # arm
|
||||
__floatunsisf; # arm
|
||||
__fp_nquery;
|
||||
__fp_query;
|
||||
__fpclassify;
|
||||
@ -40,14 +58,23 @@ LIBC {
|
||||
__freadable;
|
||||
__fsetlocking;
|
||||
__fstatfs64; # arm x86 mips
|
||||
__futex_wait; # arm x86 mips
|
||||
__futex_wake; # arm x86 mips
|
||||
__fwritable;
|
||||
__gedf2; # arm
|
||||
__get_h_errno;
|
||||
__get_thread; # arm x86 mips
|
||||
__get_tls; # arm x86 mips
|
||||
__getcpu; # arm x86 mips
|
||||
__getcwd; # arm x86 mips
|
||||
__getdents64; # arm x86 mips
|
||||
__getpid; # arm x86 mips
|
||||
__getpriority; # arm x86 mips
|
||||
__gnu_basename;
|
||||
__gnu_ldivmod_helper; # arm
|
||||
__gnu_strerror_r;
|
||||
__gnu_uldivmod_helper; # arm
|
||||
__gtdf2; # arm
|
||||
__hostalias;
|
||||
__ioctl; # arm x86 mips
|
||||
__isfinite;
|
||||
@ -63,12 +90,15 @@ LIBC {
|
||||
__isnormalf;
|
||||
__isnormall;
|
||||
__isthreaded;
|
||||
__ledf2; # arm
|
||||
__libc_current_sigrtmax;
|
||||
__libc_current_sigrtmin;
|
||||
__libc_init;
|
||||
__llseek; # arm x86 mips
|
||||
__loc_aton;
|
||||
__loc_ntoa;
|
||||
__lshrdi3; # arm
|
||||
__ltdf2; # arm
|
||||
__memchr_chk;
|
||||
__memcpy_chk;
|
||||
__memmove_chk;
|
||||
@ -76,6 +106,10 @@ LIBC {
|
||||
__memset_chk;
|
||||
__mmap2; # arm x86 mips
|
||||
__moddi3; # x86 mips
|
||||
__muldf3; # arm
|
||||
__muldi3; # arm
|
||||
__mulsf3; # arm
|
||||
__nedf2; # arm
|
||||
__ns_format_ttl; # arm x86 mips
|
||||
__ns_get16; # arm x86 mips
|
||||
__ns_get32; # arm x86 mips
|
||||
@ -98,6 +132,7 @@ LIBC {
|
||||
__ns_skiprr; # arm x86 mips
|
||||
__ns_sprintrr; # arm x86 mips
|
||||
__ns_sprintrrf; # arm x86 mips
|
||||
__open; # arm x86 mips
|
||||
__open_2;
|
||||
__openat; # arm x86 mips
|
||||
__openat_2;
|
||||
@ -114,7 +149,11 @@ LIBC {
|
||||
__p_time;
|
||||
__p_type;
|
||||
__p_type_syms;
|
||||
__page_shift; # arm x86 mips
|
||||
__page_size; # arm x86 mips
|
||||
__poll_chk;
|
||||
__popcount_tab; # arm
|
||||
__popcountsi2; # arm x86 mips
|
||||
__ppoll; # arm x86 mips
|
||||
__ppoll_chk;
|
||||
__pread64_chk;
|
||||
@ -123,7 +162,7 @@ LIBC {
|
||||
__pselect6; # arm x86 mips
|
||||
__pthread_cleanup_pop;
|
||||
__pthread_cleanup_push;
|
||||
__pthread_gettid; # arm x86 mips nobrillo
|
||||
__pthread_gettid; # arm x86 mips
|
||||
__ptrace; # arm x86 mips
|
||||
__putlong;
|
||||
__putshort;
|
||||
@ -153,6 +192,7 @@ LIBC {
|
||||
__res_send;
|
||||
__res_send_setqhook;
|
||||
__res_send_setrhook;
|
||||
__restore_core_regs; # arm
|
||||
__rt_sigaction; # arm x86 mips
|
||||
__rt_sigpending; # arm x86 mips
|
||||
__rt_sigprocmask; # arm x86 mips
|
||||
@ -162,15 +202,28 @@ LIBC {
|
||||
__sched_cpucount;
|
||||
__sched_cpufree;
|
||||
__sched_getaffinity; # arm x86 mips
|
||||
__sclose; # arm x86 mips
|
||||
__sdidinit; # arm x86 mips
|
||||
__set_errno; # arm x86 mips
|
||||
__set_thread_area; # x86
|
||||
__set_tid_address; # arm x86 mips
|
||||
__set_tls; # arm mips
|
||||
__sF;
|
||||
__sflags; # arm x86 mips
|
||||
__sflush; # arm x86 mips
|
||||
__sfp; # arm x86 mips
|
||||
__sglue; # arm x86 mips
|
||||
__sigaction; # arm x86 mips
|
||||
__signalfd4; # arm x86 mips
|
||||
__sinit; # arm x86 mips
|
||||
__smakebuf; # arm x86 mips
|
||||
__snprintf_chk;
|
||||
__socket; # arm x86 mips
|
||||
__sprintf_chk;
|
||||
__sread; # arm x86 mips
|
||||
__srefill; # arm x86 mips
|
||||
__srget; # arm x86 mips
|
||||
__sseek; # arm x86 mips
|
||||
__stack_chk_fail;
|
||||
__stack_chk_guard;
|
||||
__statfs64; # arm x86 mips
|
||||
@ -187,39 +240,51 @@ LIBC {
|
||||
__strncpy_chk;
|
||||
__strncpy_chk2;
|
||||
__strrchr_chk;
|
||||
__subdf3; # arm
|
||||
__subsf3; # arm
|
||||
__swbuf; # arm x86 mips
|
||||
__swrite; # arm x86 mips
|
||||
__swsetup; # arm x86 mips
|
||||
__sym_ntop;
|
||||
__sym_ntos;
|
||||
__sym_ston;
|
||||
__system_properties_init; # arm x86 mips
|
||||
__system_property_add; # arm x86 mips
|
||||
__system_property_area__; # arm x86 mips
|
||||
__system_property_area_init; # arm x86 mips
|
||||
__system_property_area_serial; # arm x86 mips
|
||||
__system_property_find; # arm x86 mips
|
||||
__system_property_find_nth; # arm x86 mips
|
||||
__system_property_foreach; # arm x86 mips
|
||||
__system_property_get; # arm x86 mips
|
||||
__system_property_read; # arm x86 mips
|
||||
__system_property_serial; # arm x86 mips
|
||||
__system_property_set; # arm x86 mips
|
||||
__system_property_set_filename; # arm x86 mips
|
||||
__system_property_update; # arm x86 mips
|
||||
__system_property_wait_any; # arm x86 mips
|
||||
__system_properties_init;
|
||||
__system_property_add;
|
||||
__system_property_area__;
|
||||
__system_property_area_init;
|
||||
__system_property_area_serial;
|
||||
__system_property_find;
|
||||
__system_property_find_nth;
|
||||
__system_property_foreach;
|
||||
__system_property_get;
|
||||
__system_property_read;
|
||||
__system_property_serial;
|
||||
__system_property_set;
|
||||
__system_property_set_filename;
|
||||
__system_property_update;
|
||||
__system_property_wait_any;
|
||||
__timer_create; # arm x86 mips
|
||||
__timer_delete; # arm x86 mips
|
||||
__timer_getoverrun; # arm x86 mips
|
||||
__timer_gettime; # arm x86 mips
|
||||
__timer_settime; # arm x86 mips
|
||||
__udivdi3; # x86
|
||||
__truncdfsf2; # arm
|
||||
__udivdi3; # arm x86 mips
|
||||
__udivsi3; # arm
|
||||
__umask_chk;
|
||||
__umoddi3; # x86 mips
|
||||
__unorddf2; # arm
|
||||
__unordsf2; # arm
|
||||
__vsnprintf_chk;
|
||||
__vsprintf_chk;
|
||||
__wait4; # arm x86 mips
|
||||
__waitid; # arm x86 mips
|
||||
_ctype_;
|
||||
_Exit;
|
||||
_exit;
|
||||
_flush_cache; # mips
|
||||
_flushlbf;
|
||||
_fwalk; # arm x86 mips
|
||||
_getlong;
|
||||
_getshort;
|
||||
_longjmp;
|
||||
@ -246,7 +311,9 @@ LIBC {
|
||||
android_gethostbynamefornet;
|
||||
android_set_abort_message;
|
||||
arc4random;
|
||||
arc4random_addrandom; # arm x86 mips
|
||||
arc4random_buf;
|
||||
arc4random_stir; # arm x86 mips
|
||||
arc4random_uniform;
|
||||
asctime;
|
||||
asctime64; # arm x86 mips
|
||||
@ -260,11 +327,14 @@ LIBC {
|
||||
atoll;
|
||||
basename;
|
||||
basename_r; # arm x86 mips
|
||||
bcopy; # arm x86 mips
|
||||
bind;
|
||||
bindresvport;
|
||||
brk;
|
||||
bsd_signal; # arm x86 mips
|
||||
bsearch;
|
||||
btowc;
|
||||
bzero; # arm x86 mips
|
||||
c16rtomb;
|
||||
c32rtomb;
|
||||
cacheflush; # arm mips
|
||||
@ -317,6 +387,7 @@ LIBC {
|
||||
dup3;
|
||||
duplocale;
|
||||
endmntent;
|
||||
endpwent;
|
||||
endservent;
|
||||
endutent;
|
||||
environ;
|
||||
@ -363,6 +434,7 @@ LIBC {
|
||||
fdatasync;
|
||||
fdopen;
|
||||
fdopendir;
|
||||
fdprintf; # arm x86 mips
|
||||
feof;
|
||||
feof_unlocked;
|
||||
ferror;
|
||||
@ -394,6 +466,7 @@ LIBC {
|
||||
fputws;
|
||||
fread;
|
||||
free;
|
||||
free_malloc_leak_info;
|
||||
freeaddrinfo;
|
||||
freelocale;
|
||||
fremovexattr;
|
||||
@ -414,6 +487,7 @@ LIBC {
|
||||
fsync;
|
||||
ftell;
|
||||
ftello;
|
||||
ftime; # arm x86 mips
|
||||
ftok;
|
||||
ftruncate;
|
||||
ftruncate64;
|
||||
@ -434,6 +508,7 @@ LIBC {
|
||||
fwscanf;
|
||||
gai_strerror;
|
||||
get_avphys_pages;
|
||||
get_malloc_leak_info;
|
||||
get_nprocs;
|
||||
get_nprocs_conf;
|
||||
get_phys_pages;
|
||||
@ -445,6 +520,8 @@ LIBC {
|
||||
getchar_unlocked;
|
||||
getcwd;
|
||||
getdelim;
|
||||
getdents; # arm x86 mips
|
||||
getdtablesize; # arm x86 mips
|
||||
getegid;
|
||||
getenv;
|
||||
geteuid;
|
||||
@ -519,6 +596,7 @@ LIBC {
|
||||
if_nametoindex;
|
||||
imaxabs;
|
||||
imaxdiv;
|
||||
index; # arm x86 mips
|
||||
inet_addr;
|
||||
inet_aton;
|
||||
inet_lnaof;
|
||||
@ -571,6 +649,7 @@ LIBC {
|
||||
isprint_l;
|
||||
ispunct;
|
||||
ispunct_l;
|
||||
issetugid; # arm x86 mips
|
||||
isspace;
|
||||
isspace_l;
|
||||
isupper;
|
||||
@ -660,6 +739,7 @@ LIBC {
|
||||
mempcpy;
|
||||
memrchr;
|
||||
memset;
|
||||
memswap; # arm x86 mips
|
||||
mincore;
|
||||
mkdir;
|
||||
mkdirat;
|
||||
@ -679,6 +759,7 @@ LIBC {
|
||||
mktemp;
|
||||
mktime;
|
||||
mktime64; # arm x86 mips
|
||||
mktime_tz;
|
||||
mlock;
|
||||
mlockall;
|
||||
mmap;
|
||||
@ -772,6 +853,7 @@ LIBC {
|
||||
pthread_attr_getschedpolicy;
|
||||
pthread_attr_getscope;
|
||||
pthread_attr_getstack;
|
||||
pthread_attr_getstackaddr; # arm x86 mips
|
||||
pthread_attr_getstacksize;
|
||||
pthread_attr_init;
|
||||
pthread_attr_setdetachstate;
|
||||
@ -780,6 +862,7 @@ LIBC {
|
||||
pthread_attr_setschedpolicy;
|
||||
pthread_attr_setscope;
|
||||
pthread_attr_setstack;
|
||||
pthread_attr_setstackaddr; # arm x86 mips
|
||||
pthread_attr_setstacksize;
|
||||
pthread_cond_broadcast;
|
||||
pthread_cond_destroy;
|
||||
@ -895,6 +978,7 @@ LIBC {
|
||||
res_mkquery;
|
||||
res_query;
|
||||
res_search;
|
||||
restore_core_regs; # arm
|
||||
rewind;
|
||||
rewinddir;
|
||||
rmdir;
|
||||
@ -1037,6 +1121,8 @@ LIBC {
|
||||
strncpy;
|
||||
strndup;
|
||||
strnlen;
|
||||
strntoimax; # arm x86 mips
|
||||
strntoumax; # arm x86 mips
|
||||
strpbrk;
|
||||
strptime;
|
||||
strrchr;
|
||||
@ -1055,6 +1141,7 @@ LIBC {
|
||||
strtoll;
|
||||
strtoll_l;
|
||||
strtoq;
|
||||
strtotimeval; # arm x86 mips
|
||||
strtoul;
|
||||
strtoull;
|
||||
strtoull_l;
|
||||
@ -1076,6 +1163,7 @@ LIBC {
|
||||
sysinfo;
|
||||
syslog;
|
||||
system;
|
||||
sysv_signal; # arm x86 mips
|
||||
tcdrain;
|
||||
tcflow;
|
||||
tcflush;
|
||||
@ -1107,6 +1195,7 @@ LIBC {
|
||||
timerfd_settime;
|
||||
times;
|
||||
timezone;
|
||||
tkill; # arm x86 mips
|
||||
tmpfile;
|
||||
tmpnam;
|
||||
toascii;
|
||||
@ -1148,6 +1237,7 @@ LIBC {
|
||||
vdprintf;
|
||||
verr;
|
||||
verrx;
|
||||
vfdprintf; # arm x86 mips
|
||||
vfork;
|
||||
vfprintf;
|
||||
vfscanf;
|
||||
@ -1167,6 +1257,7 @@ LIBC {
|
||||
vwprintf;
|
||||
vwscanf;
|
||||
wait;
|
||||
wait3; # arm x86 mips
|
||||
wait4;
|
||||
waitid;
|
||||
waitpid;
|
||||
@ -1215,6 +1306,7 @@ LIBC {
|
||||
wcstoull;
|
||||
wcstoull_l;
|
||||
wcstoumax;
|
||||
wcswcs; # arm x86 mips
|
||||
wcswidth;
|
||||
wcsxfrm;
|
||||
wcsxfrm_l;
|
||||
@ -1239,46 +1331,17 @@ LIBC {
|
||||
|
||||
LIBC_N {
|
||||
global:
|
||||
__aeabi_atexit; # arm
|
||||
__aeabi_memclr; # arm
|
||||
__aeabi_memclr4; # arm
|
||||
__aeabi_memclr8; # arm
|
||||
__aeabi_memcpy; # arm
|
||||
__aeabi_memcpy4; # arm
|
||||
__aeabi_memcpy8; # arm
|
||||
__aeabi_memmove; # arm
|
||||
__aeabi_memmove4; # arm
|
||||
__aeabi_memmove8; # arm
|
||||
__aeabi_memset; # arm
|
||||
__aeabi_memset4; # arm
|
||||
__aeabi_memset8; # arm
|
||||
__fread_chk;
|
||||
__fwrite_chk;
|
||||
__getcwd_chk;
|
||||
__gnu_Unwind_Find_exidx; # arm
|
||||
__pwrite_chk;
|
||||
__pwrite64_chk;
|
||||
__write_chk;
|
||||
fileno_unlocked;
|
||||
freeifaddrs;
|
||||
getgrgid_r;
|
||||
getgrnam_r;
|
||||
getifaddrs;
|
||||
preadv;
|
||||
preadv64;
|
||||
prlimit; # arm mips x86
|
||||
pthread_barrierattr_destroy;
|
||||
pthread_barrierattr_getpshared;
|
||||
pthread_barrierattr_init;
|
||||
pthread_barrierattr_setpshared;
|
||||
pthread_barrier_destroy;
|
||||
pthread_barrier_init;
|
||||
pthread_barrier_wait;
|
||||
pthread_spin_destroy;
|
||||
pthread_spin_init;
|
||||
pthread_spin_lock;
|
||||
pthread_spin_trylock;
|
||||
pthread_spin_unlock;
|
||||
pwritev;
|
||||
pwritev64;
|
||||
scandirat;
|
||||
@ -1362,33 +1425,8 @@ LIBC_PRIVATE {
|
||||
__ashrdi3; # arm
|
||||
__bionic_brk; # arm x86 mips
|
||||
__bionic_libgcc_compat_symbols; # arm x86
|
||||
__cmpdf2; # arm
|
||||
__divdf3; # arm
|
||||
__divdi3; # arm x86 mips
|
||||
__divsf3; # arm
|
||||
__divsi3; # arm
|
||||
__bionic_libgcc_unwind_symbols; # arm
|
||||
__dso_handle; # arm
|
||||
__eqdf2; # arm
|
||||
__extendsfdf2; # arm
|
||||
__fixdfsi; # arm
|
||||
__fixsfsi; # arm
|
||||
__fixunssfsi; # arm
|
||||
__floatdidf; # arm
|
||||
__floatdisf; # arm
|
||||
__floatsidf; # arm
|
||||
__floatsisf; # arm
|
||||
__floatundidf; # arm
|
||||
__floatundisf; # arm
|
||||
__floatunsidf; # arm
|
||||
__floatunsisf; # arm
|
||||
__futex_wait; # arm x86 mips nobrillo
|
||||
__futex_wake; # arm x86 mips nobrillo
|
||||
__gedf2; # arm
|
||||
__get_thread; # arm x86 mips nobrillo
|
||||
__get_tls; # arm x86 mips nobrillo
|
||||
__getdents64; # arm x86 mips
|
||||
__gnu_ldivmod_helper; # arm
|
||||
__gnu_uldivmod_helper; # arm
|
||||
__gnu_Unwind_Backtrace; # arm
|
||||
__gnu_unwind_execute; # arm
|
||||
__gnu_Unwind_Find_exidx; # arm
|
||||
@ -1407,62 +1445,6 @@ LIBC_PRIVATE {
|
||||
__gnu_Unwind_Save_VFP_D_16_to_31; # arm
|
||||
__gnu_Unwind_Save_WMMXC; # arm
|
||||
__gnu_Unwind_Save_WMMXD; # arm
|
||||
__gtdf2; # arm
|
||||
__ledf2; # arm
|
||||
__lshrdi3; # arm
|
||||
__ltdf2; # arm
|
||||
__muldf3; # arm
|
||||
__muldi3; # arm
|
||||
__mulsf3; # arm
|
||||
__nedf2; # arm
|
||||
__open; # arm x86 mips nobrillo
|
||||
__page_shift; # arm x86 mips nobrillo
|
||||
__page_size; # arm x86 mips nobrillo
|
||||
__popcount_tab; # arm
|
||||
__popcountsi2; # arm x86 mips
|
||||
__pthread_gettid; # arm x86 mips nobrillo
|
||||
__restore_core_regs; # arm
|
||||
__sclose; # arm x86 mips
|
||||
__sdidinit; # arm x86 mips nobrillo
|
||||
__set_errno; # arm x86 mips nobrillo
|
||||
__sflags; # arm x86 mips
|
||||
__sflush; # arm x86 mips
|
||||
__sfp; # arm x86 mips
|
||||
__sglue; # arm x86 mips
|
||||
__sinit; # arm x86 mips nobrillo
|
||||
__smakebuf; # arm x86 mips
|
||||
__sread; # arm x86 mips
|
||||
__srefill; # arm x86 mips
|
||||
__srget; # arm x86 mips
|
||||
__sseek; # arm x86 mips
|
||||
__subdf3; # arm
|
||||
__subsf3; # arm
|
||||
__swbuf; # arm x86 mips
|
||||
__swrite; # arm x86 mips
|
||||
__swsetup; # arm x86 mips
|
||||
__system_properties_init; # arm64 x86_64 mips64
|
||||
__system_property_add; # arm64 x86_64 mips64
|
||||
__system_property_area__; # arm64 x86_64 mips64
|
||||
__system_property_area_init; # arm64 x86_64 mips64
|
||||
__system_property_area_serial; # arm64 x86_64 mips64
|
||||
__system_property_find; # arm64 x86_64 mips64
|
||||
__system_property_find_nth; # arm64 x86_64 mips64
|
||||
__system_property_foreach; # arm64 x86_64 mips64
|
||||
__system_property_get; # arm64 x86_64 mips64
|
||||
__system_property_read; # arm64 x86_64 mips64
|
||||
__system_property_serial; # arm64 x86_64 mips64
|
||||
__system_property_set; # arm64 x86_64 mips64
|
||||
__system_property_set_filename; # arm64 x86_64 mips64
|
||||
__system_property_update; # arm64 x86_64 mips64
|
||||
__system_property_wait_any; # arm64 x86_64 mips64
|
||||
__truncdfsf2; # arm
|
||||
__udivdi3; # arm mips
|
||||
__udivsi3; # arm
|
||||
__umoddi3; # x86 mips
|
||||
__unorddf2; # arm
|
||||
__unordsf2; # arm
|
||||
__wait4; # arm x86 mips nobrillo
|
||||
_fwalk; # arm x86 mips
|
||||
_Unwind_Backtrace; # arm
|
||||
_Unwind_Complete; # arm
|
||||
_Unwind_DeleteException; # arm
|
||||
@ -1478,40 +1460,14 @@ LIBC_PRIVATE {
|
||||
_Unwind_VRS_Get; # arm
|
||||
_Unwind_VRS_Pop; # arm
|
||||
_Unwind_VRS_Set; # arm
|
||||
arc4random_addrandom; # arm x86 mips nobrillo
|
||||
arc4random_stir; # arm x86 mips nobrillo
|
||||
atexit; # arm
|
||||
bcopy; # arm x86 mips nobrillo
|
||||
bzero; # arm x86 mips nobrillo
|
||||
bsd_signal; # arm x86 mips nobrillo
|
||||
dlmalloc; # arm x86 mips nobrillo
|
||||
dlmalloc_inspect_all; # arm x86 mips nobrillo
|
||||
dlmalloc_trim; # arm x86 mips nobrillo
|
||||
dlmalloc_usable_size; # arm x86 mips nobrillo
|
||||
endpwent; # arm x86 mips nobrillo
|
||||
fdprintf; # arm x86 mips nobrillo
|
||||
free_malloc_leak_info;
|
||||
ftime; # arm x86 mips nobrillo
|
||||
get_malloc_leak_info;
|
||||
getdents; # arm x86 mips nobrillo
|
||||
getdtablesize; # arm x86 mips nobrillo
|
||||
dlmalloc; # arm x86 mips
|
||||
dlmalloc_inspect_all;
|
||||
dlmalloc_trim;
|
||||
dlmalloc_usable_size; # arm x86 mips
|
||||
gMallocLeakZygoteChild;
|
||||
index; # arm x86 mips nobrillo
|
||||
issetugid; # arm x86 mips nobrillo
|
||||
memswap; # arm x86 mips nobrillo
|
||||
pthread_attr_getstackaddr; # arm x86 mips nobrillo
|
||||
pthread_attr_setstackaddr; # arm x86 mips nobrillo
|
||||
restore_core_regs; # arm
|
||||
SHA1Final; # arm x86 mips
|
||||
SHA1Init; # arm x86 mips
|
||||
SHA1Transform; # arm x86 mips
|
||||
SHA1Update; # arm x86 mips
|
||||
strntoimax; # arm x86 mips nobrillo
|
||||
strntoumax; # arm x86 mips nobrillo
|
||||
strtotimeval; # arm x86 mips nobrillo
|
||||
sysv_signal; # arm x86 mips nobrillo
|
||||
tkill; # arm x86 mips nobrillo
|
||||
vfdprintf; # arm x86 mips nobrillo
|
||||
wait3; # arm x86 mips nobrillo
|
||||
wcswcs; # arm x86 mips nobrillo
|
||||
} LIBC_N;
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -12,6 +12,7 @@ LIBC {
|
||||
__cxa_atexit;
|
||||
__cxa_finalize;
|
||||
__cxa_thread_atexit_impl;
|
||||
__divdi3; # arm x86 mips
|
||||
__dn_comp;
|
||||
__dn_count_labels;
|
||||
__dn_skipname;
|
||||
@ -37,10 +38,15 @@ LIBC {
|
||||
__freadable;
|
||||
__fsetlocking;
|
||||
__fstatfs64; # arm x86 mips
|
||||
__futex_wait; # arm x86 mips
|
||||
__futex_wake; # arm x86 mips
|
||||
__fwritable;
|
||||
__get_h_errno;
|
||||
__get_thread; # arm x86 mips
|
||||
__get_tls; # arm x86 mips
|
||||
__getcpu; # arm x86 mips
|
||||
__getcwd; # arm x86 mips
|
||||
__getdents64; # arm x86 mips
|
||||
__getpid; # arm x86 mips
|
||||
__getpriority; # arm x86 mips
|
||||
__gnu_basename;
|
||||
@ -95,6 +101,7 @@ LIBC {
|
||||
__ns_skiprr; # arm x86 mips
|
||||
__ns_sprintrr; # arm x86 mips
|
||||
__ns_sprintrrf; # arm x86 mips
|
||||
__open; # arm x86 mips
|
||||
__open_2;
|
||||
__openat; # arm x86 mips
|
||||
__openat_2;
|
||||
@ -111,7 +118,10 @@ LIBC {
|
||||
__p_time;
|
||||
__p_type;
|
||||
__p_type_syms;
|
||||
__page_shift; # arm x86 mips
|
||||
__page_size; # arm x86 mips
|
||||
__poll_chk;
|
||||
__popcountsi2; # arm x86 mips
|
||||
__ppoll; # arm x86 mips
|
||||
__ppoll_chk;
|
||||
__pread64_chk;
|
||||
@ -120,7 +130,7 @@ LIBC {
|
||||
__pselect6; # arm x86 mips
|
||||
__pthread_cleanup_pop;
|
||||
__pthread_cleanup_push;
|
||||
__pthread_gettid; # arm x86 mips nobrillo
|
||||
__pthread_gettid; # arm x86 mips
|
||||
__ptrace; # arm x86 mips
|
||||
__putlong;
|
||||
__putshort;
|
||||
@ -159,14 +169,27 @@ LIBC {
|
||||
__sched_cpucount;
|
||||
__sched_cpufree;
|
||||
__sched_getaffinity; # arm x86 mips
|
||||
__sclose; # arm x86 mips
|
||||
__sdidinit; # arm x86 mips
|
||||
__set_errno; # arm x86 mips
|
||||
__set_tid_address; # arm x86 mips
|
||||
__set_tls; # arm mips
|
||||
__sF;
|
||||
__sflags; # arm x86 mips
|
||||
__sflush; # arm x86 mips
|
||||
__sfp; # arm x86 mips
|
||||
__sglue; # arm x86 mips
|
||||
__sigaction; # arm x86 mips
|
||||
__signalfd4; # arm x86 mips
|
||||
__sinit; # arm x86 mips
|
||||
__smakebuf; # arm x86 mips
|
||||
__snprintf_chk;
|
||||
__socket; # arm x86 mips
|
||||
__sprintf_chk;
|
||||
__sread; # arm x86 mips
|
||||
__srefill; # arm x86 mips
|
||||
__srget; # arm x86 mips
|
||||
__sseek; # arm x86 mips
|
||||
__stack_chk_fail;
|
||||
__stack_chk_guard;
|
||||
__statfs64; # arm x86 mips
|
||||
@ -183,38 +206,45 @@ LIBC {
|
||||
__strncpy_chk;
|
||||
__strncpy_chk2;
|
||||
__strrchr_chk;
|
||||
__swbuf; # arm x86 mips
|
||||
__swrite; # arm x86 mips
|
||||
__swsetup; # arm x86 mips
|
||||
__sym_ntop;
|
||||
__sym_ntos;
|
||||
__sym_ston;
|
||||
__system_properties_init; # arm x86 mips
|
||||
__system_property_add; # arm x86 mips
|
||||
__system_property_area__; # arm x86 mips
|
||||
__system_property_area_init; # arm x86 mips
|
||||
__system_property_area_serial; # arm x86 mips
|
||||
__system_property_find; # arm x86 mips
|
||||
__system_property_find_nth; # arm x86 mips
|
||||
__system_property_foreach; # arm x86 mips
|
||||
__system_property_get; # arm x86 mips
|
||||
__system_property_read; # arm x86 mips
|
||||
__system_property_serial; # arm x86 mips
|
||||
__system_property_set; # arm x86 mips
|
||||
__system_property_set_filename; # arm x86 mips
|
||||
__system_property_update; # arm x86 mips
|
||||
__system_property_wait_any; # arm x86 mips
|
||||
__system_properties_init;
|
||||
__system_property_add;
|
||||
__system_property_area__;
|
||||
__system_property_area_init;
|
||||
__system_property_area_serial;
|
||||
__system_property_find;
|
||||
__system_property_find_nth;
|
||||
__system_property_foreach;
|
||||
__system_property_get;
|
||||
__system_property_read;
|
||||
__system_property_serial;
|
||||
__system_property_set;
|
||||
__system_property_set_filename;
|
||||
__system_property_update;
|
||||
__system_property_wait_any;
|
||||
__timer_create; # arm x86 mips
|
||||
__timer_delete; # arm x86 mips
|
||||
__timer_getoverrun; # arm x86 mips
|
||||
__timer_gettime; # arm x86 mips
|
||||
__timer_settime; # arm x86 mips
|
||||
__udivdi3; # arm x86 mips
|
||||
__umask_chk;
|
||||
__umoddi3; # x86 mips
|
||||
__vsnprintf_chk;
|
||||
__vsprintf_chk;
|
||||
__wait4; # arm x86 mips
|
||||
__waitid; # arm x86 mips
|
||||
_ctype_;
|
||||
_Exit;
|
||||
_exit;
|
||||
_flush_cache; # mips
|
||||
_flushlbf;
|
||||
_fwalk; # arm x86 mips
|
||||
_getlong;
|
||||
_getshort;
|
||||
_longjmp;
|
||||
@ -241,7 +271,9 @@ LIBC {
|
||||
android_gethostbynamefornet;
|
||||
android_set_abort_message;
|
||||
arc4random;
|
||||
arc4random_addrandom; # arm x86 mips
|
||||
arc4random_buf;
|
||||
arc4random_stir; # arm x86 mips
|
||||
arc4random_uniform;
|
||||
asctime;
|
||||
asctime64; # arm x86 mips
|
||||
@ -255,11 +287,14 @@ LIBC {
|
||||
atoll;
|
||||
basename;
|
||||
basename_r; # arm x86 mips
|
||||
bcopy; # arm x86 mips
|
||||
bind;
|
||||
bindresvport;
|
||||
brk;
|
||||
bsd_signal; # arm x86 mips
|
||||
bsearch;
|
||||
btowc;
|
||||
bzero; # arm x86 mips
|
||||
c16rtomb;
|
||||
c32rtomb;
|
||||
cacheflush; # arm mips
|
||||
@ -312,6 +347,7 @@ LIBC {
|
||||
dup3;
|
||||
duplocale;
|
||||
endmntent;
|
||||
endpwent;
|
||||
endservent;
|
||||
endutent;
|
||||
environ;
|
||||
@ -358,6 +394,7 @@ LIBC {
|
||||
fdatasync;
|
||||
fdopen;
|
||||
fdopendir;
|
||||
fdprintf; # arm x86 mips
|
||||
feof;
|
||||
feof_unlocked;
|
||||
ferror;
|
||||
@ -389,6 +426,7 @@ LIBC {
|
||||
fputws;
|
||||
fread;
|
||||
free;
|
||||
free_malloc_leak_info;
|
||||
freeaddrinfo;
|
||||
freelocale;
|
||||
fremovexattr;
|
||||
@ -409,6 +447,7 @@ LIBC {
|
||||
fsync;
|
||||
ftell;
|
||||
ftello;
|
||||
ftime; # arm x86 mips
|
||||
ftok;
|
||||
ftruncate;
|
||||
ftruncate64;
|
||||
@ -429,6 +468,7 @@ LIBC {
|
||||
fwscanf;
|
||||
gai_strerror;
|
||||
get_avphys_pages;
|
||||
get_malloc_leak_info;
|
||||
get_nprocs;
|
||||
get_nprocs_conf;
|
||||
get_phys_pages;
|
||||
@ -440,6 +480,8 @@ LIBC {
|
||||
getchar_unlocked;
|
||||
getcwd;
|
||||
getdelim;
|
||||
getdents; # arm x86 mips
|
||||
getdtablesize; # arm x86 mips
|
||||
getegid;
|
||||
getenv;
|
||||
geteuid;
|
||||
@ -514,6 +556,7 @@ LIBC {
|
||||
if_nametoindex;
|
||||
imaxabs;
|
||||
imaxdiv;
|
||||
index; # arm x86 mips
|
||||
inet_addr;
|
||||
inet_aton;
|
||||
inet_lnaof;
|
||||
@ -566,6 +609,7 @@ LIBC {
|
||||
isprint_l;
|
||||
ispunct;
|
||||
ispunct_l;
|
||||
issetugid; # arm x86 mips
|
||||
isspace;
|
||||
isspace_l;
|
||||
isupper;
|
||||
@ -655,6 +699,7 @@ LIBC {
|
||||
mempcpy;
|
||||
memrchr;
|
||||
memset;
|
||||
memswap; # arm x86 mips
|
||||
mincore;
|
||||
mkdir;
|
||||
mkdirat;
|
||||
@ -674,6 +719,7 @@ LIBC {
|
||||
mktemp;
|
||||
mktime;
|
||||
mktime64; # arm x86 mips
|
||||
mktime_tz;
|
||||
mlock;
|
||||
mlockall;
|
||||
mmap;
|
||||
@ -744,6 +790,7 @@ LIBC {
|
||||
pthread_attr_getschedpolicy;
|
||||
pthread_attr_getscope;
|
||||
pthread_attr_getstack;
|
||||
pthread_attr_getstackaddr; # arm x86 mips
|
||||
pthread_attr_getstacksize;
|
||||
pthread_attr_init;
|
||||
pthread_attr_setdetachstate;
|
||||
@ -752,6 +799,7 @@ LIBC {
|
||||
pthread_attr_setschedpolicy;
|
||||
pthread_attr_setscope;
|
||||
pthread_attr_setstack;
|
||||
pthread_attr_setstackaddr; # arm x86 mips
|
||||
pthread_attr_setstacksize;
|
||||
pthread_cond_broadcast;
|
||||
pthread_cond_destroy;
|
||||
@ -1009,6 +1057,8 @@ LIBC {
|
||||
strncpy;
|
||||
strndup;
|
||||
strnlen;
|
||||
strntoimax; # arm x86 mips
|
||||
strntoumax; # arm x86 mips
|
||||
strpbrk;
|
||||
strptime;
|
||||
strrchr;
|
||||
@ -1027,6 +1077,7 @@ LIBC {
|
||||
strtoll;
|
||||
strtoll_l;
|
||||
strtoq;
|
||||
strtotimeval; # arm x86 mips
|
||||
strtoul;
|
||||
strtoull;
|
||||
strtoull_l;
|
||||
@ -1048,6 +1099,7 @@ LIBC {
|
||||
sysinfo;
|
||||
syslog;
|
||||
system;
|
||||
sysv_signal; # arm x86 mips
|
||||
tcdrain;
|
||||
tcflow;
|
||||
tcflush;
|
||||
@ -1079,6 +1131,7 @@ LIBC {
|
||||
timerfd_settime;
|
||||
times;
|
||||
timezone;
|
||||
tkill; # arm x86 mips
|
||||
tmpfile;
|
||||
tmpnam;
|
||||
toascii;
|
||||
@ -1120,6 +1173,7 @@ LIBC {
|
||||
vdprintf;
|
||||
verr;
|
||||
verrx;
|
||||
vfdprintf; # arm x86 mips
|
||||
vfork;
|
||||
vfprintf;
|
||||
vfscanf;
|
||||
@ -1139,6 +1193,7 @@ LIBC {
|
||||
vwprintf;
|
||||
vwscanf;
|
||||
wait;
|
||||
wait3; # arm x86 mips
|
||||
wait4;
|
||||
waitid;
|
||||
waitpid;
|
||||
@ -1187,6 +1242,7 @@ LIBC {
|
||||
wcstoull;
|
||||
wcstoull_l;
|
||||
wcstoumax;
|
||||
wcswcs; # arm x86 mips
|
||||
wcswidth;
|
||||
wcsxfrm;
|
||||
wcsxfrm_l;
|
||||
@ -1217,26 +1273,11 @@ LIBC_N {
|
||||
__pwrite_chk;
|
||||
__pwrite64_chk;
|
||||
__write_chk;
|
||||
fileno_unlocked;
|
||||
freeifaddrs;
|
||||
getgrgid_r;
|
||||
getgrnam_r;
|
||||
getifaddrs;
|
||||
preadv;
|
||||
preadv64;
|
||||
prlimit; # arm mips x86
|
||||
pthread_barrierattr_destroy;
|
||||
pthread_barrierattr_getpshared;
|
||||
pthread_barrierattr_init;
|
||||
pthread_barrierattr_setpshared;
|
||||
pthread_barrier_destroy;
|
||||
pthread_barrier_init;
|
||||
pthread_barrier_wait;
|
||||
pthread_spin_destroy;
|
||||
pthread_spin_init;
|
||||
pthread_spin_lock;
|
||||
pthread_spin_trylock;
|
||||
pthread_spin_unlock;
|
||||
pwritev;
|
||||
pwritev64;
|
||||
scandirat;
|
||||
@ -1248,69 +1289,13 @@ LIBC_PRIVATE {
|
||||
global:
|
||||
__accept4; # arm x86 mips
|
||||
__bionic_brk; # arm x86 mips
|
||||
__divdi3; # arm x86 mips
|
||||
__futex_wait; # arm x86 mips nobrillo
|
||||
__futex_wake; # arm x86 mips nobrillo
|
||||
__get_thread; # arm x86 mips nobrillo
|
||||
__get_tls; # arm x86 mips nobrillo
|
||||
__getdents64; # arm x86 mips
|
||||
__open; # arm x86 mips nobrillo
|
||||
__page_shift; # arm x86 mips nobrillo
|
||||
__page_size; # arm x86 mips nobrillo
|
||||
__popcountsi2; # arm x86 mips
|
||||
__pthread_gettid; # arm x86 mips nobrillo
|
||||
__sclose; # arm x86 mips
|
||||
__sdidinit; # arm x86 mips nobrillo
|
||||
__set_errno; # arm x86 mips nobrillo
|
||||
__sflags; # arm x86 mips
|
||||
__sflush; # arm x86 mips
|
||||
__sfp; # arm x86 mips
|
||||
__sglue; # arm x86 mips
|
||||
__sinit; # arm x86 mips nobrillo
|
||||
__smakebuf; # arm x86 mips
|
||||
__sread; # arm x86 mips
|
||||
__srefill; # arm x86 mips
|
||||
__srget; # arm x86 mips
|
||||
__sseek; # arm x86 mips
|
||||
__swbuf; # arm x86 mips
|
||||
__swrite; # arm x86 mips
|
||||
__swsetup; # arm x86 mips
|
||||
__udivdi3; # arm mips
|
||||
__umoddi3; # x86 mips
|
||||
__wait4; # arm x86 mips nobrillo
|
||||
_fwalk; # arm x86 mips
|
||||
arc4random_addrandom; # arm x86 mips nobrillo
|
||||
arc4random_stir; # arm x86 mips nobrillo
|
||||
bcopy; # arm x86 mips nobrillo
|
||||
bzero; # arm x86 mips nobrillo
|
||||
bsd_signal; # arm x86 mips nobrillo
|
||||
dlmalloc; # arm x86 mips nobrillo
|
||||
dlmalloc_inspect_all; # arm x86 mips nobrillo
|
||||
dlmalloc_trim; # arm x86 mips nobrillo
|
||||
dlmalloc_usable_size; # arm x86 mips nobrillo
|
||||
endpwent; # arm x86 mips nobrillo
|
||||
fdprintf; # arm x86 mips nobrillo
|
||||
free_malloc_leak_info;
|
||||
ftime; # arm x86 mips nobrillo
|
||||
get_malloc_leak_info;
|
||||
getdents; # arm x86 mips nobrillo
|
||||
getdtablesize; # arm x86 mips nobrillo
|
||||
dlmalloc; # arm x86 mips
|
||||
dlmalloc_inspect_all;
|
||||
dlmalloc_trim;
|
||||
dlmalloc_usable_size; # arm x86 mips
|
||||
gMallocLeakZygoteChild;
|
||||
index; # arm x86 mips nobrillo
|
||||
issetugid; # arm x86 mips nobrillo
|
||||
memswap; # arm x86 mips nobrillo
|
||||
pthread_attr_getstackaddr; # arm x86 mips nobrillo
|
||||
pthread_attr_setstackaddr; # arm x86 mips nobrillo
|
||||
SHA1Final; # arm x86 mips
|
||||
SHA1Init; # arm x86 mips
|
||||
SHA1Transform; # arm x86 mips
|
||||
SHA1Update; # arm x86 mips
|
||||
strntoimax; # arm x86 mips nobrillo
|
||||
strntoumax; # arm x86 mips nobrillo
|
||||
strtotimeval; # arm x86 mips nobrillo
|
||||
sysv_signal; # arm x86 mips nobrillo
|
||||
tkill; # arm x86 mips nobrillo
|
||||
vfdprintf; # arm x86 mips nobrillo
|
||||
wait3; # arm x86 mips nobrillo
|
||||
wcswcs; # arm x86 mips nobrillo
|
||||
} LIBC_N;
|
||||
|
@ -131,6 +131,21 @@ LIBC {
|
||||
__sym_ntop;
|
||||
__sym_ntos;
|
||||
__sym_ston;
|
||||
__system_properties_init;
|
||||
__system_property_add;
|
||||
__system_property_area__;
|
||||
__system_property_area_init;
|
||||
__system_property_area_serial;
|
||||
__system_property_find;
|
||||
__system_property_find_nth;
|
||||
__system_property_foreach;
|
||||
__system_property_get;
|
||||
__system_property_read;
|
||||
__system_property_serial;
|
||||
__system_property_set;
|
||||
__system_property_set_filename;
|
||||
__system_property_update;
|
||||
__system_property_wait_any;
|
||||
__umask_chk;
|
||||
__vsnprintf_chk;
|
||||
__vsprintf_chk;
|
||||
@ -226,6 +241,7 @@ LIBC {
|
||||
dup3;
|
||||
duplocale;
|
||||
endmntent;
|
||||
endpwent;
|
||||
endservent;
|
||||
endutent;
|
||||
environ;
|
||||
@ -301,6 +317,7 @@ LIBC {
|
||||
fputws;
|
||||
fread;
|
||||
free;
|
||||
free_malloc_leak_info;
|
||||
freeaddrinfo;
|
||||
freelocale;
|
||||
fremovexattr;
|
||||
@ -341,6 +358,7 @@ LIBC {
|
||||
fwscanf;
|
||||
gai_strerror;
|
||||
get_avphys_pages;
|
||||
get_malloc_leak_info;
|
||||
get_nprocs;
|
||||
get_nprocs_conf;
|
||||
get_phys_pages;
|
||||
@ -581,6 +599,7 @@ LIBC {
|
||||
mkstemps64;
|
||||
mktemp;
|
||||
mktime;
|
||||
mktime_tz;
|
||||
mlock;
|
||||
mlockall;
|
||||
mmap;
|
||||
@ -1137,25 +1156,10 @@ LIBC_N {
|
||||
__pwrite_chk;
|
||||
__pwrite64_chk;
|
||||
__write_chk;
|
||||
fileno_unlocked;
|
||||
freeifaddrs;
|
||||
getgrgid_r;
|
||||
getgrnam_r;
|
||||
getifaddrs;
|
||||
preadv;
|
||||
preadv64;
|
||||
pthread_barrierattr_destroy;
|
||||
pthread_barrierattr_getpshared;
|
||||
pthread_barrierattr_init;
|
||||
pthread_barrierattr_setpshared;
|
||||
pthread_barrier_destroy;
|
||||
pthread_barrier_init;
|
||||
pthread_barrier_wait;
|
||||
pthread_spin_destroy;
|
||||
pthread_spin_init;
|
||||
pthread_spin_lock;
|
||||
pthread_spin_trylock;
|
||||
pthread_spin_unlock;
|
||||
pwritev;
|
||||
pwritev64;
|
||||
scandirat;
|
||||
@ -1165,22 +1169,7 @@ LIBC_N {
|
||||
|
||||
LIBC_PRIVATE {
|
||||
global:
|
||||
__system_properties_init; # arm64 x86_64 mips64
|
||||
__system_property_add; # arm64 x86_64 mips64
|
||||
__system_property_area__; # arm64 x86_64 mips64
|
||||
__system_property_area_init; # arm64 x86_64 mips64
|
||||
__system_property_area_serial; # arm64 x86_64 mips64
|
||||
__system_property_find; # arm64 x86_64 mips64
|
||||
__system_property_find_nth; # arm64 x86_64 mips64
|
||||
__system_property_foreach; # arm64 x86_64 mips64
|
||||
__system_property_get; # arm64 x86_64 mips64
|
||||
__system_property_read; # arm64 x86_64 mips64
|
||||
__system_property_serial; # arm64 x86_64 mips64
|
||||
__system_property_set; # arm64 x86_64 mips64
|
||||
__system_property_set_filename; # arm64 x86_64 mips64
|
||||
__system_property_update; # arm64 x86_64 mips64
|
||||
__system_property_wait_any; # arm64 x86_64 mips64
|
||||
free_malloc_leak_info;
|
||||
get_malloc_leak_info;
|
||||
dlmalloc_inspect_all;
|
||||
dlmalloc_trim;
|
||||
gMallocLeakZygoteChild;
|
||||
} LIBC_N;
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -12,6 +12,7 @@ LIBC {
|
||||
__cxa_atexit;
|
||||
__cxa_finalize;
|
||||
__cxa_thread_atexit_impl;
|
||||
__divdi3; # arm x86 mips
|
||||
__dn_comp;
|
||||
__dn_count_labels;
|
||||
__dn_skipname;
|
||||
@ -37,10 +38,15 @@ LIBC {
|
||||
__freadable;
|
||||
__fsetlocking;
|
||||
__fstatfs64; # arm x86 mips
|
||||
__futex_wait; # arm x86 mips
|
||||
__futex_wake; # arm x86 mips
|
||||
__fwritable;
|
||||
__get_h_errno;
|
||||
__get_thread; # arm x86 mips
|
||||
__get_tls; # arm x86 mips
|
||||
__getcpu; # arm x86 mips
|
||||
__getcwd; # arm x86 mips
|
||||
__getdents64; # arm x86 mips
|
||||
__getpid; # arm x86 mips
|
||||
__getpriority; # arm x86 mips
|
||||
__gnu_basename;
|
||||
@ -95,6 +101,7 @@ LIBC {
|
||||
__ns_skiprr; # arm x86 mips
|
||||
__ns_sprintrr; # arm x86 mips
|
||||
__ns_sprintrrf; # arm x86 mips
|
||||
__open; # arm x86 mips
|
||||
__open_2;
|
||||
__openat; # arm x86 mips
|
||||
__openat_2;
|
||||
@ -111,7 +118,10 @@ LIBC {
|
||||
__p_time;
|
||||
__p_type;
|
||||
__p_type_syms;
|
||||
__page_shift; # arm x86 mips
|
||||
__page_size; # arm x86 mips
|
||||
__poll_chk;
|
||||
__popcountsi2; # arm x86 mips
|
||||
__ppoll; # arm x86 mips
|
||||
__ppoll_chk;
|
||||
__pread64_chk;
|
||||
@ -120,7 +130,7 @@ LIBC {
|
||||
__pselect6; # arm x86 mips
|
||||
__pthread_cleanup_pop;
|
||||
__pthread_cleanup_push;
|
||||
__pthread_gettid; # arm x86 mips nobrillo
|
||||
__pthread_gettid; # arm x86 mips
|
||||
__ptrace; # arm x86 mips
|
||||
__putlong;
|
||||
__putshort;
|
||||
@ -159,14 +169,27 @@ LIBC {
|
||||
__sched_cpucount;
|
||||
__sched_cpufree;
|
||||
__sched_getaffinity; # arm x86 mips
|
||||
__sclose; # arm x86 mips
|
||||
__sdidinit; # arm x86 mips
|
||||
__set_errno; # arm x86 mips
|
||||
__set_thread_area; # x86
|
||||
__set_tid_address; # arm x86 mips
|
||||
__sF;
|
||||
__sflags; # arm x86 mips
|
||||
__sflush; # arm x86 mips
|
||||
__sfp; # arm x86 mips
|
||||
__sglue; # arm x86 mips
|
||||
__sigaction; # arm x86 mips
|
||||
__signalfd4; # arm x86 mips
|
||||
__sinit; # arm x86 mips
|
||||
__smakebuf; # arm x86 mips
|
||||
__snprintf_chk;
|
||||
__socket; # arm x86 mips
|
||||
__sprintf_chk;
|
||||
__sread; # arm x86 mips
|
||||
__srefill; # arm x86 mips
|
||||
__srget; # arm x86 mips
|
||||
__sseek; # arm x86 mips
|
||||
__stack_chk_fail;
|
||||
__stack_chk_guard;
|
||||
__statfs64; # arm x86 mips
|
||||
@ -183,38 +206,44 @@ LIBC {
|
||||
__strncpy_chk;
|
||||
__strncpy_chk2;
|
||||
__strrchr_chk;
|
||||
__swbuf; # arm x86 mips
|
||||
__swrite; # arm x86 mips
|
||||
__swsetup; # arm x86 mips
|
||||
__sym_ntop;
|
||||
__sym_ntos;
|
||||
__sym_ston;
|
||||
__system_properties_init; # arm x86 mips
|
||||
__system_property_add; # arm x86 mips
|
||||
__system_property_area__; # arm x86 mips
|
||||
__system_property_area_init; # arm x86 mips
|
||||
__system_property_area_serial; # arm x86 mips
|
||||
__system_property_find; # arm x86 mips
|
||||
__system_property_find_nth; # arm x86 mips
|
||||
__system_property_foreach; # arm x86 mips
|
||||
__system_property_get; # arm x86 mips
|
||||
__system_property_read; # arm x86 mips
|
||||
__system_property_serial; # arm x86 mips
|
||||
__system_property_set; # arm x86 mips
|
||||
__system_property_set_filename; # arm x86 mips
|
||||
__system_property_update; # arm x86 mips
|
||||
__system_property_wait_any; # arm x86 mips
|
||||
__system_properties_init;
|
||||
__system_property_add;
|
||||
__system_property_area__;
|
||||
__system_property_area_init;
|
||||
__system_property_area_serial;
|
||||
__system_property_find;
|
||||
__system_property_find_nth;
|
||||
__system_property_foreach;
|
||||
__system_property_get;
|
||||
__system_property_read;
|
||||
__system_property_serial;
|
||||
__system_property_set;
|
||||
__system_property_set_filename;
|
||||
__system_property_update;
|
||||
__system_property_wait_any;
|
||||
__timer_create; # arm x86 mips
|
||||
__timer_delete; # arm x86 mips
|
||||
__timer_getoverrun; # arm x86 mips
|
||||
__timer_gettime; # arm x86 mips
|
||||
__timer_settime; # arm x86 mips
|
||||
__udivdi3; # x86
|
||||
__udivdi3; # arm x86 mips
|
||||
__umask_chk;
|
||||
__umoddi3; # x86 mips
|
||||
__vsnprintf_chk;
|
||||
__vsprintf_chk;
|
||||
__wait4; # arm x86 mips
|
||||
__waitid; # arm x86 mips
|
||||
_ctype_;
|
||||
_Exit;
|
||||
_exit;
|
||||
_flushlbf;
|
||||
_fwalk; # arm x86 mips
|
||||
_getlong;
|
||||
_getshort;
|
||||
_longjmp;
|
||||
@ -241,7 +270,9 @@ LIBC {
|
||||
android_gethostbynamefornet;
|
||||
android_set_abort_message;
|
||||
arc4random;
|
||||
arc4random_addrandom; # arm x86 mips
|
||||
arc4random_buf;
|
||||
arc4random_stir; # arm x86 mips
|
||||
arc4random_uniform;
|
||||
asctime;
|
||||
asctime64; # arm x86 mips
|
||||
@ -255,11 +286,14 @@ LIBC {
|
||||
atoll;
|
||||
basename;
|
||||
basename_r; # arm x86 mips
|
||||
bcopy; # arm x86 mips
|
||||
bind;
|
||||
bindresvport;
|
||||
brk;
|
||||
bsd_signal; # arm x86 mips
|
||||
bsearch;
|
||||
btowc;
|
||||
bzero; # arm x86 mips
|
||||
c16rtomb;
|
||||
c32rtomb;
|
||||
calloc;
|
||||
@ -311,6 +345,7 @@ LIBC {
|
||||
dup3;
|
||||
duplocale;
|
||||
endmntent;
|
||||
endpwent;
|
||||
endservent;
|
||||
endutent;
|
||||
environ;
|
||||
@ -357,6 +392,7 @@ LIBC {
|
||||
fdatasync;
|
||||
fdopen;
|
||||
fdopendir;
|
||||
fdprintf; # arm x86 mips
|
||||
feof;
|
||||
feof_unlocked;
|
||||
ferror;
|
||||
@ -388,6 +424,7 @@ LIBC {
|
||||
fputws;
|
||||
fread;
|
||||
free;
|
||||
free_malloc_leak_info;
|
||||
freeaddrinfo;
|
||||
freelocale;
|
||||
fremovexattr;
|
||||
@ -408,6 +445,7 @@ LIBC {
|
||||
fsync;
|
||||
ftell;
|
||||
ftello;
|
||||
ftime; # arm x86 mips
|
||||
ftok;
|
||||
ftruncate;
|
||||
ftruncate64;
|
||||
@ -428,6 +466,7 @@ LIBC {
|
||||
fwscanf;
|
||||
gai_strerror;
|
||||
get_avphys_pages;
|
||||
get_malloc_leak_info;
|
||||
get_nprocs;
|
||||
get_nprocs_conf;
|
||||
get_phys_pages;
|
||||
@ -439,6 +478,8 @@ LIBC {
|
||||
getchar_unlocked;
|
||||
getcwd;
|
||||
getdelim;
|
||||
getdents; # arm x86 mips
|
||||
getdtablesize; # arm x86 mips
|
||||
getegid;
|
||||
getenv;
|
||||
geteuid;
|
||||
@ -513,6 +554,7 @@ LIBC {
|
||||
if_nametoindex;
|
||||
imaxabs;
|
||||
imaxdiv;
|
||||
index; # arm x86 mips
|
||||
inet_addr;
|
||||
inet_aton;
|
||||
inet_lnaof;
|
||||
@ -565,6 +607,7 @@ LIBC {
|
||||
isprint_l;
|
||||
ispunct;
|
||||
ispunct_l;
|
||||
issetugid; # arm x86 mips
|
||||
isspace;
|
||||
isspace_l;
|
||||
isupper;
|
||||
@ -654,6 +697,7 @@ LIBC {
|
||||
mempcpy;
|
||||
memrchr;
|
||||
memset;
|
||||
memswap; # arm x86 mips
|
||||
mincore;
|
||||
mkdir;
|
||||
mkdirat;
|
||||
@ -673,6 +717,7 @@ LIBC {
|
||||
mktemp;
|
||||
mktime;
|
||||
mktime64; # arm x86 mips
|
||||
mktime_tz;
|
||||
mlock;
|
||||
mlockall;
|
||||
mmap;
|
||||
@ -743,6 +788,7 @@ LIBC {
|
||||
pthread_attr_getschedpolicy;
|
||||
pthread_attr_getscope;
|
||||
pthread_attr_getstack;
|
||||
pthread_attr_getstackaddr; # arm x86 mips
|
||||
pthread_attr_getstacksize;
|
||||
pthread_attr_init;
|
||||
pthread_attr_setdetachstate;
|
||||
@ -751,6 +797,7 @@ LIBC {
|
||||
pthread_attr_setschedpolicy;
|
||||
pthread_attr_setscope;
|
||||
pthread_attr_setstack;
|
||||
pthread_attr_setstackaddr; # arm x86 mips
|
||||
pthread_attr_setstacksize;
|
||||
pthread_cond_broadcast;
|
||||
pthread_cond_destroy;
|
||||
@ -1008,6 +1055,8 @@ LIBC {
|
||||
strncpy;
|
||||
strndup;
|
||||
strnlen;
|
||||
strntoimax; # arm x86 mips
|
||||
strntoumax; # arm x86 mips
|
||||
strpbrk;
|
||||
strptime;
|
||||
strrchr;
|
||||
@ -1026,6 +1075,7 @@ LIBC {
|
||||
strtoll;
|
||||
strtoll_l;
|
||||
strtoq;
|
||||
strtotimeval; # arm x86 mips
|
||||
strtoul;
|
||||
strtoull;
|
||||
strtoull_l;
|
||||
@ -1047,6 +1097,7 @@ LIBC {
|
||||
sysinfo;
|
||||
syslog;
|
||||
system;
|
||||
sysv_signal; # arm x86 mips
|
||||
tcdrain;
|
||||
tcflow;
|
||||
tcflush;
|
||||
@ -1078,6 +1129,7 @@ LIBC {
|
||||
timerfd_settime;
|
||||
times;
|
||||
timezone;
|
||||
tkill; # arm x86 mips
|
||||
tmpfile;
|
||||
tmpnam;
|
||||
toascii;
|
||||
@ -1119,6 +1171,7 @@ LIBC {
|
||||
vdprintf;
|
||||
verr;
|
||||
verrx;
|
||||
vfdprintf; # arm x86 mips
|
||||
vfork;
|
||||
vfprintf;
|
||||
vfscanf;
|
||||
@ -1138,6 +1191,7 @@ LIBC {
|
||||
vwprintf;
|
||||
vwscanf;
|
||||
wait;
|
||||
wait3; # arm x86 mips
|
||||
wait4;
|
||||
waitid;
|
||||
waitpid;
|
||||
@ -1186,6 +1240,7 @@ LIBC {
|
||||
wcstoull;
|
||||
wcstoull_l;
|
||||
wcstoumax;
|
||||
wcswcs; # arm x86 mips
|
||||
wcswidth;
|
||||
wcsxfrm;
|
||||
wcsxfrm_l;
|
||||
@ -1216,26 +1271,11 @@ LIBC_N {
|
||||
__pwrite_chk;
|
||||
__pwrite64_chk;
|
||||
__write_chk;
|
||||
fileno_unlocked;
|
||||
freeifaddrs;
|
||||
getgrgid_r;
|
||||
getgrnam_r;
|
||||
getifaddrs;
|
||||
preadv;
|
||||
preadv64;
|
||||
prlimit; # arm mips x86
|
||||
pthread_barrierattr_destroy;
|
||||
pthread_barrierattr_getpshared;
|
||||
pthread_barrierattr_init;
|
||||
pthread_barrierattr_setpshared;
|
||||
pthread_barrier_destroy;
|
||||
pthread_barrier_init;
|
||||
pthread_barrier_wait;
|
||||
pthread_spin_destroy;
|
||||
pthread_spin_init;
|
||||
pthread_spin_lock;
|
||||
pthread_spin_trylock;
|
||||
pthread_spin_unlock;
|
||||
pwritev;
|
||||
pwritev64;
|
||||
scandirat;
|
||||
@ -1248,68 +1288,13 @@ LIBC_PRIVATE {
|
||||
__accept4; # arm x86 mips
|
||||
__bionic_brk; # arm x86 mips
|
||||
__bionic_libgcc_compat_symbols; # arm x86
|
||||
__divdi3; # arm x86 mips
|
||||
__futex_wait; # arm x86 mips nobrillo
|
||||
__futex_wake; # arm x86 mips nobrillo
|
||||
__get_thread; # arm x86 mips nobrillo
|
||||
__get_tls; # arm x86 mips nobrillo
|
||||
__getdents64; # arm x86 mips
|
||||
__open; # arm x86 mips nobrillo
|
||||
__page_shift; # arm x86 mips nobrillo
|
||||
__page_size; # arm x86 mips nobrillo
|
||||
__popcountsi2; # arm x86 mips
|
||||
__pthread_gettid; # arm x86 mips nobrillo
|
||||
__sclose; # arm x86 mips
|
||||
__sdidinit; # arm x86 mips nobrillo
|
||||
__set_errno; # arm x86 mips nobrillo
|
||||
__sflags; # arm x86 mips
|
||||
__sflush; # arm x86 mips
|
||||
__sfp; # arm x86 mips
|
||||
__sglue; # arm x86 mips
|
||||
__sinit; # arm x86 mips nobrillo
|
||||
__smakebuf; # arm x86 mips
|
||||
__sread; # arm x86 mips
|
||||
__srefill; # arm x86 mips
|
||||
__srget; # arm x86 mips
|
||||
__sseek; # arm x86 mips
|
||||
__swbuf; # arm x86 mips
|
||||
__swrite; # arm x86 mips
|
||||
__swsetup; # arm x86 mips
|
||||
__umoddi3; # x86 mips
|
||||
__wait4; # arm x86 mips nobrillo
|
||||
_fwalk; # arm x86 mips
|
||||
arc4random_addrandom; # arm x86 mips nobrillo
|
||||
arc4random_stir; # arm x86 mips nobrillo
|
||||
bcopy; # arm x86 mips nobrillo
|
||||
bzero; # arm x86 mips nobrillo
|
||||
bsd_signal; # arm x86 mips nobrillo
|
||||
dlmalloc; # arm x86 mips nobrillo
|
||||
dlmalloc_inspect_all; # arm x86 mips nobrillo
|
||||
dlmalloc_trim; # arm x86 mips nobrillo
|
||||
dlmalloc_usable_size; # arm x86 mips nobrillo
|
||||
endpwent; # arm x86 mips nobrillo
|
||||
fdprintf; # arm x86 mips nobrillo
|
||||
free_malloc_leak_info;
|
||||
ftime; # arm x86 mips nobrillo
|
||||
get_malloc_leak_info;
|
||||
getdents; # arm x86 mips nobrillo
|
||||
getdtablesize; # arm x86 mips nobrillo
|
||||
dlmalloc; # arm x86 mips
|
||||
dlmalloc_inspect_all;
|
||||
dlmalloc_trim;
|
||||
dlmalloc_usable_size; # arm x86 mips
|
||||
gMallocLeakZygoteChild;
|
||||
index; # arm x86 mips nobrillo
|
||||
issetugid; # arm x86 mips nobrillo
|
||||
memswap; # arm x86 mips nobrillo
|
||||
pthread_attr_getstackaddr; # arm x86 mips nobrillo
|
||||
pthread_attr_setstackaddr; # arm x86 mips nobrillo
|
||||
SHA1Final; # arm x86 mips
|
||||
SHA1Init; # arm x86 mips
|
||||
SHA1Transform; # arm x86 mips
|
||||
SHA1Update; # arm x86 mips
|
||||
strntoimax; # arm x86 mips nobrillo
|
||||
strntoumax; # arm x86 mips nobrillo
|
||||
strtotimeval; # arm x86 mips nobrillo
|
||||
sysv_signal; # arm x86 mips nobrillo
|
||||
tkill; # arm x86 mips nobrillo
|
||||
vfdprintf; # arm x86 mips nobrillo
|
||||
wait3; # arm x86 mips nobrillo
|
||||
wcswcs; # arm x86 mips nobrillo
|
||||
} LIBC_N;
|
||||
|
@ -131,6 +131,21 @@ LIBC {
|
||||
__sym_ntop;
|
||||
__sym_ntos;
|
||||
__sym_ston;
|
||||
__system_properties_init;
|
||||
__system_property_add;
|
||||
__system_property_area__;
|
||||
__system_property_area_init;
|
||||
__system_property_area_serial;
|
||||
__system_property_find;
|
||||
__system_property_find_nth;
|
||||
__system_property_foreach;
|
||||
__system_property_get;
|
||||
__system_property_read;
|
||||
__system_property_serial;
|
||||
__system_property_set;
|
||||
__system_property_set_filename;
|
||||
__system_property_update;
|
||||
__system_property_wait_any;
|
||||
__umask_chk;
|
||||
__vsnprintf_chk;
|
||||
__vsprintf_chk;
|
||||
@ -226,6 +241,7 @@ LIBC {
|
||||
dup3;
|
||||
duplocale;
|
||||
endmntent;
|
||||
endpwent;
|
||||
endservent;
|
||||
endutent;
|
||||
environ;
|
||||
@ -301,6 +317,7 @@ LIBC {
|
||||
fputws;
|
||||
fread;
|
||||
free;
|
||||
free_malloc_leak_info;
|
||||
freeaddrinfo;
|
||||
freelocale;
|
||||
fremovexattr;
|
||||
@ -341,6 +358,7 @@ LIBC {
|
||||
fwscanf;
|
||||
gai_strerror;
|
||||
get_avphys_pages;
|
||||
get_malloc_leak_info;
|
||||
get_nprocs;
|
||||
get_nprocs_conf;
|
||||
get_phys_pages;
|
||||
@ -581,6 +599,7 @@ LIBC {
|
||||
mkstemps64;
|
||||
mktemp;
|
||||
mktime;
|
||||
mktime_tz;
|
||||
mlock;
|
||||
mlockall;
|
||||
mmap;
|
||||
@ -1137,25 +1156,10 @@ LIBC_N {
|
||||
__pwrite_chk;
|
||||
__pwrite64_chk;
|
||||
__write_chk;
|
||||
fileno_unlocked;
|
||||
freeifaddrs;
|
||||
getgrgid_r;
|
||||
getgrnam_r;
|
||||
getifaddrs;
|
||||
preadv;
|
||||
preadv64;
|
||||
pthread_barrierattr_destroy;
|
||||
pthread_barrierattr_getpshared;
|
||||
pthread_barrierattr_init;
|
||||
pthread_barrierattr_setpshared;
|
||||
pthread_barrier_destroy;
|
||||
pthread_barrier_init;
|
||||
pthread_barrier_wait;
|
||||
pthread_spin_destroy;
|
||||
pthread_spin_init;
|
||||
pthread_spin_lock;
|
||||
pthread_spin_trylock;
|
||||
pthread_spin_unlock;
|
||||
pwritev;
|
||||
pwritev64;
|
||||
scandirat;
|
||||
@ -1165,22 +1169,7 @@ LIBC_N {
|
||||
|
||||
LIBC_PRIVATE {
|
||||
global:
|
||||
__system_properties_init; # arm64 x86_64 mips64
|
||||
__system_property_add; # arm64 x86_64 mips64
|
||||
__system_property_area__; # arm64 x86_64 mips64
|
||||
__system_property_area_init; # arm64 x86_64 mips64
|
||||
__system_property_area_serial; # arm64 x86_64 mips64
|
||||
__system_property_find; # arm64 x86_64 mips64
|
||||
__system_property_find_nth; # arm64 x86_64 mips64
|
||||
__system_property_foreach; # arm64 x86_64 mips64
|
||||
__system_property_get; # arm64 x86_64 mips64
|
||||
__system_property_read; # arm64 x86_64 mips64
|
||||
__system_property_serial; # arm64 x86_64 mips64
|
||||
__system_property_set; # arm64 x86_64 mips64
|
||||
__system_property_set_filename; # arm64 x86_64 mips64
|
||||
__system_property_update; # arm64 x86_64 mips64
|
||||
__system_property_wait_any; # arm64 x86_64 mips64
|
||||
free_malloc_leak_info;
|
||||
get_malloc_leak_info;
|
||||
dlmalloc_inspect_all;
|
||||
dlmalloc_trim;
|
||||
gMallocLeakZygoteChild;
|
||||
} LIBC_N;
|
||||
|
@ -38,25 +38,32 @@ class KernelArgumentBlock {
|
||||
argv = reinterpret_cast<char**>(args + 1);
|
||||
envp = argv + argc + 1;
|
||||
|
||||
// Skip over all environment variable definitions to find the aux vector.
|
||||
// The end of the environment block is marked by a NULL pointer.
|
||||
// Skip over all environment variable definitions to find aux vector.
|
||||
// The end of the environment block is marked by two NULL pointers.
|
||||
char** p = envp;
|
||||
while (*p != NULL) {
|
||||
++p;
|
||||
}
|
||||
++p; // Skip the NULL itself.
|
||||
++p; // Skip second NULL;
|
||||
|
||||
auxv = reinterpret_cast<ElfW(auxv_t)*>(p);
|
||||
}
|
||||
|
||||
// Similar to ::getauxval but doesn't require the libc global variables to be set up,
|
||||
// so it's safe to call this really early on.
|
||||
unsigned long getauxval(unsigned long type) {
|
||||
// so it's safe to call this really early on. This function also lets you distinguish
|
||||
// between the inability to find the given type and its value just happening to be 0.
|
||||
unsigned long getauxval(unsigned long type, bool* found_match = NULL) {
|
||||
for (ElfW(auxv_t)* v = auxv; v->a_type != AT_NULL; ++v) {
|
||||
if (v->a_type == type) {
|
||||
if (found_match != NULL) {
|
||||
*found_match = true;
|
||||
}
|
||||
return v->a_un.a_val;
|
||||
}
|
||||
}
|
||||
if (found_match != NULL) {
|
||||
*found_match = false;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -34,7 +34,7 @@ class ScopedPthreadMutexLocker {
|
||||
private:
|
||||
pthread_mutex_t* mu_;
|
||||
|
||||
DISALLOW_IMPLICIT_CONSTRUCTORS(ScopedPthreadMutexLocker);
|
||||
DISALLOW_COPY_AND_ASSIGN(ScopedPthreadMutexLocker);
|
||||
};
|
||||
|
||||
#endif // SCOPED_PTHREAD_MUTEX_LOCKER_H
|
||||
|
@ -40,12 +40,10 @@ __BEGIN_DECLS
|
||||
|
||||
struct timespec;
|
||||
|
||||
static inline __always_inline int __futex(volatile void* ftx, int op, int value,
|
||||
const struct timespec* timeout,
|
||||
int bitset) {
|
||||
static inline __always_inline int __futex(volatile void* ftx, int op, int value, const struct timespec* timeout) {
|
||||
// Our generated syscall assembler sets errno, but our callers (pthread functions) don't want to.
|
||||
int saved_errno = errno;
|
||||
int result = syscall(__NR_futex, ftx, op, value, timeout, NULL, bitset);
|
||||
int result = syscall(__NR_futex, ftx, op, value, timeout);
|
||||
if (__predict_false(result == -1)) {
|
||||
result = -errno;
|
||||
errno = saved_errno;
|
||||
@ -54,22 +52,19 @@ static inline __always_inline int __futex(volatile void* ftx, int op, int value,
|
||||
}
|
||||
|
||||
static inline int __futex_wake(volatile void* ftx, int count) {
|
||||
return __futex(ftx, FUTEX_WAKE, count, NULL, 0);
|
||||
return __futex(ftx, FUTEX_WAKE, count, NULL);
|
||||
}
|
||||
|
||||
static inline int __futex_wake_ex(volatile void* ftx, bool shared, int count) {
|
||||
return __futex(ftx, shared ? FUTEX_WAKE : FUTEX_WAKE_PRIVATE, count, NULL, 0);
|
||||
return __futex(ftx, shared ? FUTEX_WAKE : FUTEX_WAKE_PRIVATE, count, NULL);
|
||||
}
|
||||
|
||||
static inline int __futex_wait(volatile void* ftx, int value, const struct timespec* timeout) {
|
||||
return __futex(ftx, FUTEX_WAIT, value, timeout, 0);
|
||||
return __futex(ftx, FUTEX_WAIT, value, timeout);
|
||||
}
|
||||
|
||||
static inline int __futex_wait_ex(volatile void* ftx, bool shared, int value,
|
||||
bool use_realtime_clock, const struct timespec* abs_timeout) {
|
||||
return __futex(ftx, (shared ? FUTEX_WAIT_BITSET : FUTEX_WAIT_BITSET_PRIVATE) |
|
||||
(use_realtime_clock ? FUTEX_CLOCK_REALTIME : 0), value, abs_timeout,
|
||||
FUTEX_BITSET_MATCH_ANY);
|
||||
static inline int __futex_wait_ex(volatile void* ftx, bool shared, int value, const struct timespec* timeout) {
|
||||
return __futex(ftx, shared ? FUTEX_WAIT : FUTEX_WAIT_PRIVATE, value, timeout);
|
||||
}
|
||||
|
||||
__END_DECLS
|
||||
|
@ -30,7 +30,6 @@
|
||||
|
||||
#include <stdatomic.h>
|
||||
#include "private/bionic_futex.h"
|
||||
#include "private/bionic_macros.h"
|
||||
|
||||
// Lock is used in places like pthread_rwlock_t, which can be initialized without calling
|
||||
// an initialization function. So make sure Lock can be initialized by setting its memory to 0.
|
||||
@ -50,12 +49,6 @@ class Lock {
|
||||
this->process_shared = process_shared;
|
||||
}
|
||||
|
||||
bool trylock() {
|
||||
LockState old_state = Unlocked;
|
||||
return __predict_true(atomic_compare_exchange_strong_explicit(&state, &old_state,
|
||||
LockedWithoutWaiter, memory_order_acquire, memory_order_relaxed));
|
||||
}
|
||||
|
||||
void lock() {
|
||||
LockState old_state = Unlocked;
|
||||
if (__predict_true(atomic_compare_exchange_strong_explicit(&state, &old_state,
|
||||
@ -64,7 +57,7 @@ class Lock {
|
||||
}
|
||||
while (atomic_exchange_explicit(&state, LockedWithWaiter, memory_order_acquire) != Unlocked) {
|
||||
// TODO: As the critical section is brief, it is a better choice to spin a few times befor sleeping.
|
||||
__futex_wait_ex(&state, process_shared, LockedWithWaiter, false, nullptr);
|
||||
__futex_wait_ex(&state, process_shared, LockedWithWaiter, NULL);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -42,8 +42,8 @@
|
||||
(((value) + (alignment) - 1) & ~((alignment) - 1))
|
||||
|
||||
#define BIONIC_ROUND_UP_POWER_OF_2(value) \
|
||||
((sizeof(value) == 8) \
|
||||
(sizeof(value) == 8) \
|
||||
? (1UL << (64 - __builtin_clzl(static_cast<unsigned long>(value)))) \
|
||||
: (1UL << (32 - __builtin_clz(static_cast<unsigned int>(value)))))
|
||||
: (1UL << (32 - __builtin_clz(static_cast<unsigned int>(value))))
|
||||
|
||||
#endif // _BIONIC_MACROS_H_
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2015 The Android Open Source Project
|
||||
* Copyright (C) 2011 The Android Open Source Project
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -25,35 +25,17 @@
|
||||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
#ifndef _BIONIC_TIME_H
|
||||
#define _BIONIC_TIME_H
|
||||
|
||||
#ifndef _IFADDRS_H_
|
||||
#define _IFADDRS_H_
|
||||
|
||||
#include <time.h>
|
||||
#include <sys/cdefs.h>
|
||||
#include <netinet/in.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
struct ifaddrs {
|
||||
struct ifaddrs* ifa_next;
|
||||
char* ifa_name;
|
||||
unsigned int ifa_flags;
|
||||
struct sockaddr* ifa_addr;
|
||||
struct sockaddr* ifa_netmask;
|
||||
union {
|
||||
struct sockaddr* ifu_broadaddr;
|
||||
struct sockaddr* ifu_dstaddr;
|
||||
} ifa_ifu;
|
||||
void* ifa_data;
|
||||
};
|
||||
|
||||
#define ifa_broadaddr ifa_ifu.ifu_broadaddr
|
||||
#define ifa_dstaddr ifa_ifu.ifu_dstaddr
|
||||
|
||||
void freeifaddrs(struct ifaddrs*);
|
||||
int getifaddrs(struct ifaddrs**);
|
||||
// We can't remove this (and this file) until we fix MtpUtils.cpp.
|
||||
time_t mktime_tz(struct tm* const, char const*);
|
||||
|
||||
__END_DECLS
|
||||
|
||||
#endif
|
||||
#endif /* _BIONIC_TIME_H */
|
@ -29,12 +29,9 @@
|
||||
#ifndef _BIONIC_TIME_CONVERSIONS_H
|
||||
#define _BIONIC_TIME_CONVERSIONS_H
|
||||
|
||||
#include <errno.h>
|
||||
#include <time.h>
|
||||
#include <sys/cdefs.h>
|
||||
|
||||
#include "private/bionic_constants.h"
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
__LIBC_HIDDEN__ bool timespec_from_timeval(timespec& ts, const timeval& tv);
|
||||
@ -42,24 +39,8 @@ __LIBC_HIDDEN__ void timespec_from_ms(timespec& ts, const int ms);
|
||||
|
||||
__LIBC_HIDDEN__ void timeval_from_timespec(timeval& tv, const timespec& ts);
|
||||
|
||||
__LIBC_HIDDEN__ void absolute_timespec_from_timespec(timespec& abs_ts, const timespec& ts,
|
||||
clockid_t clock);
|
||||
__LIBC_HIDDEN__ bool timespec_from_absolute_timespec(timespec& ts, const timespec& abs_ts, clockid_t clock);
|
||||
|
||||
__END_DECLS
|
||||
|
||||
static inline int check_timespec(const timespec* ts, bool null_allowed) {
|
||||
if (null_allowed && ts == nullptr) {
|
||||
return 0;
|
||||
}
|
||||
// glibc just segfaults if you pass a null timespec.
|
||||
// That seems a lot more likely to catch bad code than returning EINVAL.
|
||||
if (ts->tv_nsec < 0 || ts->tv_nsec >= NS_PER_S) {
|
||||
return EINVAL;
|
||||
}
|
||||
if (ts->tv_sec < 0) {
|
||||
return ETIMEDOUT;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -121,7 +121,7 @@ __END_DECLS
|
||||
|
||||
#if defined(__cplusplus)
|
||||
class KernelArgumentBlock;
|
||||
extern __LIBC_HIDDEN__ void __libc_init_main_thread(KernelArgumentBlock&);
|
||||
extern __LIBC_HIDDEN__ void __libc_init_main_thread(KernelArgumentBlock& args);
|
||||
#endif
|
||||
|
||||
#endif /* __BIONIC_PRIVATE_BIONIC_TLS_H_ */
|
||||
|
@ -44,44 +44,37 @@
|
||||
#define ALIGNBYTES (sizeof(uintptr_t) - 1)
|
||||
#define ALIGN(p) (((uintptr_t)(p) + ALIGNBYTES) &~ ALIGNBYTES)
|
||||
|
||||
int __sdidinit;
|
||||
|
||||
#define NDYNAMIC 10 /* add ten more whenever necessary */
|
||||
|
||||
#define std(flags, file) \
|
||||
{0,0,0,flags,file,{0,0},0,__sF+file,__sclose,__sread,__sseek,__swrite, \
|
||||
{(unsigned char *)(__sFext+file), 0},NULL,0,{0},{0},{0,0},0,0}
|
||||
|
||||
/* the usual - (stdin + stdout + stderr) */
|
||||
static FILE usual[FOPEN_MAX - 3];
|
||||
static struct __sfileext usualext[FOPEN_MAX - 3];
|
||||
static struct glue uglue = { 0, FOPEN_MAX - 3, usual };
|
||||
static struct glue *lastglue = &uglue;
|
||||
_THREAD_PRIVATE_MUTEX(__sfp_mutex);
|
||||
|
||||
// TODO: when we no longer have to support both clang and GCC, we can simplify all this.
|
||||
#define SBUF_INIT {0,0}
|
||||
#if defined(__LP64__)
|
||||
#define MBSTATE_T_INIT {{0},{0}}
|
||||
#else
|
||||
#define MBSTATE_T_INIT {{0}}
|
||||
#endif
|
||||
#define WCHAR_IO_DATA_INIT {MBSTATE_T_INIT,MBSTATE_T_INIT,{0},0,0}
|
||||
|
||||
static struct __sfileext __sFext[3] = {
|
||||
{ SBUF_INIT, WCHAR_IO_DATA_INIT, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP, false },
|
||||
{ SBUF_INIT, WCHAR_IO_DATA_INIT, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP, false },
|
||||
{ SBUF_INIT, WCHAR_IO_DATA_INIT, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP, false },
|
||||
};
|
||||
static struct __sfileext __sFext[3];
|
||||
|
||||
// __sF is exported for backwards compatibility. Until M, we didn't have symbols
|
||||
// for stdin/stdout/stderr; they were macros accessing __sF.
|
||||
FILE __sF[3] = {
|
||||
std(__SRD, STDIN_FILENO),
|
||||
std(__SWR, STDOUT_FILENO),
|
||||
std(__SWR|__SNBF, STDERR_FILENO),
|
||||
std(__SRD, STDIN_FILENO), /* stdin */
|
||||
std(__SWR, STDOUT_FILENO), /* stdout */
|
||||
std(__SWR|__SNBF, STDERR_FILENO) /* stderr */
|
||||
};
|
||||
|
||||
struct glue __sglue = { &uglue, 3, __sF };
|
||||
|
||||
FILE* stdin = &__sF[0];
|
||||
FILE* stdout = &__sF[1];
|
||||
FILE* stderr = &__sF[2];
|
||||
|
||||
struct glue __sglue = { NULL, 3, __sF };
|
||||
static struct glue* lastglue = &__sglue;
|
||||
|
||||
static struct glue *
|
||||
moreglue(int n)
|
||||
{
|
||||
@ -121,6 +114,9 @@ __sfp(void)
|
||||
int n;
|
||||
struct glue *g;
|
||||
|
||||
if (!__sdidinit)
|
||||
__sinit();
|
||||
|
||||
_THREAD_PRIVATE_MUTEX_LOCK(__sfp_mutex);
|
||||
for (g = &__sglue; g != NULL; g = g->next) {
|
||||
for (fp = g->iobs, n = g->niobs; --n >= 0; fp++)
|
||||
@ -153,7 +149,48 @@ found:
|
||||
return (fp);
|
||||
}
|
||||
|
||||
__LIBC_HIDDEN__ void __libc_stdio_cleanup(void) {
|
||||
/*
|
||||
* exit() and abort() call _cleanup() through the callback registered
|
||||
* with __atexit_register_cleanup(), set whenever we open or buffer a
|
||||
* file. This chicanery is done so that programs that do not use stdio
|
||||
* need not link it all in.
|
||||
*
|
||||
* The name `_cleanup' is, alas, fairly well known outside stdio.
|
||||
*/
|
||||
void
|
||||
_cleanup(void)
|
||||
{
|
||||
/* (void) _fwalk(fclose); */
|
||||
(void) _fwalk(__sflush); /* `cheating' */
|
||||
}
|
||||
|
||||
/*
|
||||
* __sinit() is called whenever stdio's internal variables must be set up.
|
||||
*/
|
||||
void
|
||||
__sinit(void)
|
||||
{
|
||||
_THREAD_PRIVATE_MUTEX(__sinit_mutex);
|
||||
|
||||
_THREAD_PRIVATE_MUTEX_LOCK(__sinit_mutex);
|
||||
if (__sdidinit) {
|
||||
/* bail out if caller lost the race */
|
||||
_THREAD_PRIVATE_MUTEX_UNLOCK(__sinit_mutex);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Initialize stdin/stdout/stderr (for the recursive mutex). http://b/18208568. */
|
||||
for (size_t i = 0; i < 3; ++i) {
|
||||
_FILEEXT_SETUP(__sF+i, __sFext+i);
|
||||
}
|
||||
/* Initialize the pre-allocated (but initially unused) streams. */
|
||||
for (size_t i = 0; i < FOPEN_MAX - 3; ++i) {
|
||||
_FILEEXT_SETUP(usual+i, usualext+i);
|
||||
}
|
||||
|
||||
/* make sure we clean up on exit */
|
||||
__atexit_register_cleanup(_cleanup); /* conservative */
|
||||
__sdidinit = 1;
|
||||
|
||||
_THREAD_PRIVATE_MUTEX_UNLOCK(__sinit_mutex);
|
||||
}
|
||||
|
@ -109,7 +109,7 @@ struct __sfileext {
|
||||
pthread_mutex_t _lock;
|
||||
|
||||
/* __fsetlocking support */
|
||||
bool _caller_handles_locking;
|
||||
bool _stdio_handles_locking;
|
||||
};
|
||||
|
||||
#if defined(__cplusplus)
|
||||
@ -131,7 +131,7 @@ do { \
|
||||
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); \
|
||||
pthread_mutex_init(&_FLOCK(fp), &attr); \
|
||||
pthread_mutexattr_destroy(&attr); \
|
||||
_EXT(fp)->_caller_handles_locking = false; \
|
||||
_EXT(fp)->_stdio_handles_locking = true; \
|
||||
} while (0)
|
||||
|
||||
#define _FILEEXT_SETUP(f, fext) \
|
||||
@ -153,8 +153,10 @@ __LIBC32_LEGACY_PUBLIC__ int __srefill(FILE*);
|
||||
__LIBC32_LEGACY_PUBLIC__ int __swsetup(FILE*);
|
||||
|
||||
/* These were referenced by a couple of different pieces of middleware and the Crystax NDK. */
|
||||
__LIBC32_LEGACY_PUBLIC__ extern int __sdidinit;
|
||||
__LIBC32_LEGACY_PUBLIC__ int __sflags(const char*, int*);
|
||||
__LIBC32_LEGACY_PUBLIC__ FILE* __sfp(void);
|
||||
__LIBC32_LEGACY_PUBLIC__ void __sinit(void);
|
||||
__LIBC32_LEGACY_PUBLIC__ void __smakebuf(FILE*);
|
||||
|
||||
/* These are referenced by the Greed for Glory franchise. */
|
||||
@ -168,6 +170,7 @@ __LIBC32_LEGACY_PUBLIC__ int _fwalk(int (*)(FILE *));
|
||||
#pragma GCC visibility push(hidden)
|
||||
|
||||
int __sflush_locked(FILE *);
|
||||
void _cleanup(void);
|
||||
int __swhatbuf(FILE *, size_t *, int *);
|
||||
wint_t __fgetwc_unlock(FILE *);
|
||||
wint_t __ungetwc(wint_t, FILE *);
|
||||
@ -176,6 +179,8 @@ int __svfscanf(FILE * __restrict, const char * __restrict, __va_list);
|
||||
int __vfwprintf(FILE * __restrict, const wchar_t * __restrict, __va_list);
|
||||
int __vfwscanf(FILE * __restrict, const wchar_t * __restrict, __va_list);
|
||||
|
||||
extern void __atexit_register_cleanup(void (*)(void));
|
||||
|
||||
/*
|
||||
* Return true if the given FILE cannot be written now.
|
||||
*/
|
||||
@ -203,8 +208,8 @@ int __vfwscanf(FILE * __restrict, const wchar_t * __restrict, __va_list);
|
||||
(fp)->_lb._base = NULL; \
|
||||
}
|
||||
|
||||
#define FLOCKFILE(fp) if (!_EXT(fp)->_caller_handles_locking) flockfile(fp)
|
||||
#define FUNLOCKFILE(fp) if (!_EXT(fp)->_caller_handles_locking) funlockfile(fp)
|
||||
#define FLOCKFILE(fp) if (_EXT(fp)->_stdio_handles_locking) flockfile(fp)
|
||||
#define FUNLOCKFILE(fp) if (_EXT(fp)->_stdio_handles_locking) funlockfile(fp)
|
||||
|
||||
#define FLOATING_POINT
|
||||
#define PRINTF_WIDE_CHAR
|
||||
@ -232,10 +237,6 @@ struct __suio;
|
||||
extern int __sfvwrite(FILE *, struct __suio *);
|
||||
wint_t __fputwc_unlock(wchar_t wc, FILE *fp);
|
||||
|
||||
/* Remove the if (!__sdidinit) __sinit() idiom from untouched upstream stdio code. */
|
||||
extern void __sinit(void); // Not actually implemented.
|
||||
#define __sdidinit 1
|
||||
|
||||
#pragma GCC visibility pop
|
||||
|
||||
__END_DECLS
|
||||
|
@ -51,6 +51,11 @@ lflush(FILE *fp)
|
||||
int
|
||||
__srefill(FILE *fp)
|
||||
{
|
||||
|
||||
/* make sure stdio is set up */
|
||||
if (!__sdidinit)
|
||||
__sinit();
|
||||
|
||||
fp->_r = 0; /* largely a convenience for callers */
|
||||
|
||||
#if !defined(__ANDROID__)
|
||||
|
@ -74,7 +74,7 @@ void _flushlbf() {
|
||||
}
|
||||
|
||||
int __fsetlocking(FILE* fp, int type) {
|
||||
int old_state = _EXT(fp)->_caller_handles_locking ? FSETLOCKING_BYCALLER : FSETLOCKING_INTERNAL;
|
||||
int old_state = _EXT(fp)->_stdio_handles_locking ? FSETLOCKING_INTERNAL : FSETLOCKING_BYCALLER;
|
||||
if (type == FSETLOCKING_QUERY) {
|
||||
return old_state;
|
||||
}
|
||||
@ -84,7 +84,7 @@ int __fsetlocking(FILE* fp, int type) {
|
||||
__libc_fatal("Bad type (%d) passed to __fsetlocking", type);
|
||||
}
|
||||
|
||||
_EXT(fp)->_caller_handles_locking = (type == FSETLOCKING_BYCALLER);
|
||||
_EXT(fp)->_stdio_handles_locking = (type == FSETLOCKING_INTERNAL);
|
||||
return old_state;
|
||||
}
|
||||
|
||||
@ -99,7 +99,3 @@ int feof_unlocked(FILE* fp) {
|
||||
int ferror_unlocked(FILE* fp) {
|
||||
return __sferror(fp);
|
||||
}
|
||||
|
||||
int fileno_unlocked(FILE* fp) {
|
||||
return __sfileno(fp);
|
||||
}
|
||||
|
@ -185,12 +185,51 @@ restart:
|
||||
}
|
||||
_ATEXIT_UNLOCK();
|
||||
|
||||
extern void __libc_stdio_cleanup(void);
|
||||
__libc_stdio_cleanup();
|
||||
|
||||
/* BEGIN android-changed: call __unregister_atfork if dso is not null */
|
||||
if (dso != NULL) {
|
||||
__unregister_atfork(dso);
|
||||
}
|
||||
/* END android-changed */
|
||||
}
|
||||
|
||||
/*
|
||||
* Register the cleanup function
|
||||
*/
|
||||
void
|
||||
__atexit_register_cleanup(void (*func)(void))
|
||||
{
|
||||
struct atexit *p;
|
||||
size_t pgsize = getpagesize();
|
||||
|
||||
if (pgsize < sizeof(*p))
|
||||
return;
|
||||
_ATEXIT_LOCK();
|
||||
p = __atexit;
|
||||
while (p != NULL && p->next != NULL)
|
||||
p = p->next;
|
||||
if (p == NULL) {
|
||||
p = mmap(NULL, pgsize, PROT_READ | PROT_WRITE,
|
||||
MAP_ANON | MAP_PRIVATE, -1, 0);
|
||||
if (p == MAP_FAILED)
|
||||
goto unlock;
|
||||
/* BEGIN android-changed */
|
||||
prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, p, pgsize,
|
||||
"atexit handlers");
|
||||
/* END android-changed */
|
||||
p->ind = 1;
|
||||
p->max = (pgsize - ((char *)&p->fns[0] - (char *)p)) /
|
||||
sizeof(p->fns[0]);
|
||||
p->next = NULL;
|
||||
__atexit = p;
|
||||
} else {
|
||||
if (mprotect(p, pgsize, PROT_READ | PROT_WRITE))
|
||||
goto unlock;
|
||||
}
|
||||
p->fns[0].fn_ptr = (void (*)(void *))func;
|
||||
p->fns[0].fn_arg = NULL;
|
||||
p->fns[0].fn_dso = NULL;
|
||||
mprotect(p, pgsize, PROT_READ);
|
||||
restartloop = 1;
|
||||
unlock:
|
||||
_ATEXIT_UNLOCK();
|
||||
}
|
||||
|
@ -36,9 +36,7 @@ class VersionScriptGenerator(object):
|
||||
basename = os.path.basename(script)
|
||||
dirname = os.path.dirname(script)
|
||||
for arch in all_arches:
|
||||
for brillo in [False, True]:
|
||||
has_nobrillo = False
|
||||
name = basename.split(".")[0] + "." + arch + (".brillo" if brillo else "") + ".map"
|
||||
name = basename.split(".")[0] + "." + arch + ".map"
|
||||
tmp_path = os.path.join(bionic_temp, name)
|
||||
dest_path = os.path.join(dirname, name)
|
||||
with open(tmp_path, "w") as fout:
|
||||
@ -47,14 +45,10 @@ class VersionScriptGenerator(object):
|
||||
for line in fin:
|
||||
index = line.find("#")
|
||||
if index != -1:
|
||||
tags = line[index+1:].split()
|
||||
if arch not in tags:
|
||||
continue
|
||||
if brillo and "nobrillo" in tags:
|
||||
has_nobrillo = True
|
||||
arches = line[index+1:].split()
|
||||
if arch not in arches:
|
||||
continue
|
||||
fout.write(line)
|
||||
if not brillo or has_nobrillo:
|
||||
shutil.copyfile(tmp_path, dest_path)
|
||||
|
||||
|
||||
|
@ -1316,10 +1316,9 @@ static void
|
||||
tzset_unlocked(void)
|
||||
{
|
||||
#if defined(__ANDROID__)
|
||||
// The TZ environment variable is meant to override the system-wide setting.
|
||||
const char * name = getenv("TZ");
|
||||
|
||||
// If that's not set, look at the "persist.sys.timezone" system property.
|
||||
// Try the "persist.sys.timezone" system property.
|
||||
if (name == NULL) {
|
||||
static const prop_info *pi;
|
||||
|
||||
@ -1341,10 +1340,6 @@ tzset_unlocked(void)
|
||||
}
|
||||
}
|
||||
|
||||
// If that's not available (because you're running AOSP on a WiFi-only
|
||||
// device, say), fall back to GMT.
|
||||
if (name == NULL) name = gmt;
|
||||
|
||||
tzsetlcl(name);
|
||||
#else
|
||||
tzsetlcl(getenv("TZ"));
|
||||
@ -2462,4 +2457,50 @@ static int __bionic_open_tzdata(const char* olson_id) {
|
||||
return fd;
|
||||
}
|
||||
|
||||
// Caches the most recent timezone (http://b/8270865).
|
||||
static int __bionic_tzload_cached(const char* name, struct state* const sp, const int doextend) {
|
||||
lock();
|
||||
|
||||
// Our single-item cache.
|
||||
static char* g_cached_time_zone_name;
|
||||
static struct state g_cached_time_zone;
|
||||
|
||||
// Do we already have this timezone cached?
|
||||
if (g_cached_time_zone_name != NULL && strcmp(name, g_cached_time_zone_name) == 0) {
|
||||
*sp = g_cached_time_zone;
|
||||
unlock();
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Can we load it?
|
||||
int rc = tzload(name, sp, doextend);
|
||||
if (rc == 0) {
|
||||
// Update the cache.
|
||||
free(g_cached_time_zone_name);
|
||||
g_cached_time_zone_name = strdup(name);
|
||||
g_cached_time_zone = *sp;
|
||||
}
|
||||
|
||||
unlock();
|
||||
return rc;
|
||||
}
|
||||
|
||||
// Non-standard API: mktime(3) but with an explicit timezone parameter.
|
||||
// This can't actually be hidden/removed until we fix MtpUtils.cpp
|
||||
__attribute__((visibility("default"))) time_t mktime_tz(struct tm* const tmp, const char* tz) {
|
||||
struct state* st = malloc(sizeof(*st));
|
||||
time_t return_value;
|
||||
|
||||
if (st == NULL)
|
||||
return 0;
|
||||
if (__bionic_tzload_cached(tz, st, true) != 0) {
|
||||
// TODO: not sure what's best here, but for now, we fall back to gmt.
|
||||
gmtload(st);
|
||||
}
|
||||
|
||||
return_value = time1(tmp, localsub, st, 0L);
|
||||
free(st);
|
||||
return return_value;
|
||||
}
|
||||
|
||||
// END android-added
|
||||
|
@ -502,23 +502,7 @@ label:
|
||||
continue;
|
||||
case 'Z':
|
||||
#ifdef TM_ZONE
|
||||
// BEGIN: Android-changed.
|
||||
{
|
||||
const char* zone = t->TM_ZONE;
|
||||
if (!zone || !*zone) {
|
||||
// "The value of tm_isdst shall be positive if Daylight Savings Time is
|
||||
// in effect, 0 if Daylight Savings Time is not in effect, and negative
|
||||
// if the information is not available."
|
||||
if (t->tm_isdst == 0) zone = tzname[0];
|
||||
else if (t->tm_isdst > 0) zone = tzname[1];
|
||||
|
||||
// "Replaced by the timezone name or abbreviation, or by no bytes if no
|
||||
// timezone information exists."
|
||||
if (!zone || !*zone) zone = "";
|
||||
}
|
||||
pt = _add(zone, pt, ptlim, modifier);
|
||||
}
|
||||
// END: Android-changed.
|
||||
pt = _add(t->TM_ZONE, pt, ptlim, modifier);
|
||||
#else
|
||||
if (t->tm_isdst >= 0)
|
||||
pt = _add(tzname[t->tm_isdst != 0],
|
||||
|
@ -4822,13 +4822,8 @@ void* dlcalloc(size_t n_elements, size_t elem_size) {
|
||||
req = MAX_SIZE_T; /* force downstream failure on overflow */
|
||||
}
|
||||
mem = dlmalloc(req);
|
||||
if (mem != 0) {
|
||||
mchunkptr p = mem2chunk(mem);
|
||||
if (calloc_must_clear(p)) {
|
||||
/* Make sure to clear all of the buffer, not just the requested size. */
|
||||
memset(mem, 0, chunksize(p) - overhead_for(p));
|
||||
}
|
||||
}
|
||||
if (mem != 0 && calloc_must_clear(mem2chunk(mem)))
|
||||
memset(mem, 0, req);
|
||||
return mem;
|
||||
}
|
||||
|
||||
|
@ -32,6 +32,6 @@
|
||||
#define __unlockenv() 0
|
||||
|
||||
#include <stddef.h>
|
||||
__LIBC_HIDDEN__ int reallocarr(void*, size_t, size_t);
|
||||
int reallocarr(void*, size_t, size_t);
|
||||
|
||||
#endif
|
||||
|
@ -13,28 +13,15 @@ cc_library {
|
||||
// DO NOT REMOVE --exclude-libs!
|
||||
|
||||
ldflags: ["-Wl,--exclude-libs=libgcc.a"],
|
||||
version_script: "libdl.map",
|
||||
|
||||
// for x86, exclude libgcc_eh.a for the same reasons as above
|
||||
arch: {
|
||||
arm: {
|
||||
version_script: "libdl.arm.map",
|
||||
},
|
||||
arm64: {
|
||||
version_script: "libdl.arm64.map",
|
||||
},
|
||||
mips: {
|
||||
version_script: "libdl.mips.map",
|
||||
},
|
||||
mips64: {
|
||||
version_script: "libdl.mips64.map",
|
||||
},
|
||||
x86: {
|
||||
ldflags: ["-Wl,--exclude-libs=libgcc_eh.a"],
|
||||
version_script: "libdl.x86.map",
|
||||
},
|
||||
x86_64: {
|
||||
ldflags: ["-Wl,--exclude-libs=libgcc_eh.a"],
|
||||
version_script: "libdl.x86_64.map",
|
||||
},
|
||||
},
|
||||
srcs: ["libdl.c"],
|
||||
|
@ -33,13 +33,7 @@ LOCAL_CFLAGS := -Wall -Wextra -Wunused -Werror
|
||||
LOCAL_CXX_STL := none
|
||||
|
||||
LOCAL_MODULE := libdl
|
||||
LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk \
|
||||
$(LOCAL_PATH)/libdl.arm.map \
|
||||
$(LOCAL_PATH)/libdl.arm64.map \
|
||||
$(LOCAL_PATH)/libdl.mips.map \
|
||||
$(LOCAL_PATH)/libdl.mips64.map \
|
||||
$(LOCAL_PATH)/libdl.x86.map \
|
||||
$(LOCAL_PATH)/libdl.x86_64.map \
|
||||
LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
|
||||
|
||||
# NOTE: libdl needs __aeabi_unwind_cpp_pr0 from libgcc.a but libgcc.a needs a
|
||||
# few symbols from libc. Using --no-undefined here results in having to link
|
||||
|
@ -14,17 +14,10 @@ LIBC {
|
||||
*;
|
||||
};
|
||||
|
||||
LIBC_N {
|
||||
global:
|
||||
android_init_namespaces;
|
||||
android_create_namespace;
|
||||
dlvsym;
|
||||
} LIBC;
|
||||
|
||||
LIBC_PRIVATE {
|
||||
global:
|
||||
android_get_application_target_sdk_version;
|
||||
android_set_application_target_sdk_version;
|
||||
android_get_LD_LIBRARY_PATH;
|
||||
android_update_LD_LIBRARY_PATH;
|
||||
} LIBC_N;
|
||||
} LIBC;
|
||||
|
@ -13,17 +13,10 @@ LIBC {
|
||||
*;
|
||||
};
|
||||
|
||||
LIBC_N {
|
||||
global:
|
||||
android_init_namespaces;
|
||||
android_create_namespace;
|
||||
dlvsym;
|
||||
} LIBC;
|
||||
|
||||
LIBC_PRIVATE {
|
||||
global:
|
||||
android_get_application_target_sdk_version;
|
||||
android_set_application_target_sdk_version;
|
||||
android_get_LD_LIBRARY_PATH;
|
||||
android_update_LD_LIBRARY_PATH;
|
||||
} LIBC_N;
|
||||
} LIBC;
|
||||
|
@ -24,48 +24,21 @@
|
||||
// in the dynamic linker and hijacked at runtime.
|
||||
|
||||
void* dlopen(const char* filename __unused, int flag __unused) { return 0; }
|
||||
|
||||
const char* dlerror(void) { return 0; }
|
||||
|
||||
void* dlsym(void* handle __unused, const char* symbol __unused) { return 0; }
|
||||
|
||||
void* dlvsym(void* handle __unused, const char* symbol __unused, const char* version __unused) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dladdr(const void* addr __unused, Dl_info* info __unused) { return 0; }
|
||||
|
||||
int dlclose(void* handle __unused) { return 0; }
|
||||
|
||||
#if defined(__arm__)
|
||||
_Unwind_Ptr dl_unwind_find_exidx(_Unwind_Ptr pc __unused, int* pcount __unused) { return 0; }
|
||||
#endif
|
||||
|
||||
int dl_iterate_phdr(int (*cb)(struct dl_phdr_info* info, size_t size, void* data) __unused,
|
||||
void* data __unused) {
|
||||
return 0;
|
||||
}
|
||||
int dl_iterate_phdr(int (*cb)(struct dl_phdr_info* info, size_t size, void* data) __unused, void* data __unused) { return 0; }
|
||||
|
||||
void android_get_LD_LIBRARY_PATH(char* buffer __unused, size_t buffer_size __unused) { }
|
||||
void android_update_LD_LIBRARY_PATH(const char* ld_library_path __unused) { }
|
||||
|
||||
void* android_dlopen_ext(const char* filename __unused, int flag __unused,
|
||||
const android_dlextinfo* extinfo __unused) {
|
||||
return 0;
|
||||
}
|
||||
void* android_dlopen_ext(const char* filename __unused, int flag __unused, const android_dlextinfo* extinfo __unused) { return 0; }
|
||||
|
||||
void android_set_application_target_sdk_version(uint32_t target __unused) { }
|
||||
uint32_t android_get_application_target_sdk_version() { return 0; }
|
||||
|
||||
bool android_init_namespaces(const char* public_ns_sonames __unused,
|
||||
const char* anon_ns_library_path __unused) {
|
||||
return false;
|
||||
}
|
||||
|
||||
struct android_namespace_t* android_create_namespace(const char* name __unused,
|
||||
const char* ld_library_path __unused,
|
||||
const char* default_library_path __unused,
|
||||
uint64_t type __unused,
|
||||
const char* permitted_when_isolated_path __unused) {
|
||||
return 0;
|
||||
}
|
||||
|
@ -28,17 +28,10 @@ LIBC {
|
||||
*;
|
||||
};
|
||||
|
||||
LIBC_N {
|
||||
global:
|
||||
android_init_namespaces;
|
||||
android_create_namespace;
|
||||
dlvsym;
|
||||
} LIBC;
|
||||
|
||||
LIBC_PRIVATE {
|
||||
global:
|
||||
android_get_application_target_sdk_version;
|
||||
android_set_application_target_sdk_version;
|
||||
android_get_LD_LIBRARY_PATH;
|
||||
android_update_LD_LIBRARY_PATH;
|
||||
} LIBC_N;
|
||||
} LIBC;
|
||||
|
@ -13,17 +13,10 @@ LIBC {
|
||||
*;
|
||||
};
|
||||
|
||||
LIBC_N {
|
||||
global:
|
||||
android_init_namespaces;
|
||||
android_create_namespace;
|
||||
dlvsym;
|
||||
} LIBC;
|
||||
|
||||
LIBC_PRIVATE {
|
||||
global:
|
||||
android_get_application_target_sdk_version;
|
||||
android_set_application_target_sdk_version;
|
||||
android_get_LD_LIBRARY_PATH;
|
||||
android_update_LD_LIBRARY_PATH;
|
||||
} LIBC_N;
|
||||
} LIBC;
|
||||
|
@ -13,17 +13,10 @@ LIBC {
|
||||
*;
|
||||
};
|
||||
|
||||
LIBC_N {
|
||||
global:
|
||||
android_init_namespaces;
|
||||
android_create_namespace;
|
||||
dlvsym;
|
||||
} LIBC;
|
||||
|
||||
LIBC_PRIVATE {
|
||||
global:
|
||||
android_get_application_target_sdk_version;
|
||||
android_set_application_target_sdk_version;
|
||||
android_get_LD_LIBRARY_PATH;
|
||||
android_update_LD_LIBRARY_PATH;
|
||||
} LIBC_N;
|
||||
} LIBC;
|
||||
|
@ -13,17 +13,10 @@ LIBC {
|
||||
*;
|
||||
};
|
||||
|
||||
LIBC_N {
|
||||
global:
|
||||
android_init_namespaces;
|
||||
android_create_namespace;
|
||||
dlvsym;
|
||||
} LIBC;
|
||||
|
||||
LIBC_PRIVATE {
|
||||
global:
|
||||
android_get_application_target_sdk_version;
|
||||
android_set_application_target_sdk_version;
|
||||
android_get_LD_LIBRARY_PATH;
|
||||
android_update_LD_LIBRARY_PATH;
|
||||
} LIBC_N;
|
||||
} LIBC;
|
||||
|
@ -13,17 +13,10 @@ LIBC {
|
||||
*;
|
||||
};
|
||||
|
||||
LIBC_N {
|
||||
global:
|
||||
android_init_namespaces;
|
||||
android_create_namespace;
|
||||
dlvsym;
|
||||
} LIBC;
|
||||
|
||||
LIBC_PRIVATE {
|
||||
global:
|
||||
android_get_application_target_sdk_version;
|
||||
android_set_application_target_sdk_version;
|
||||
android_get_LD_LIBRARY_PATH;
|
||||
android_update_LD_LIBRARY_PATH;
|
||||
} LIBC_N;
|
||||
} LIBC;
|
||||
|
180
libm/Android.bp
180
libm/Android.bp
@ -3,7 +3,18 @@
|
||||
|
||||
bionic_coverage = false
|
||||
|
||||
libm_common_src_files = [
|
||||
// TODO: this comes from from upstream's libc, not libm, but it's an
|
||||
// implementation detail that should have hidden visibility, so it needs
|
||||
// to be in whatever library the math code is in.
|
||||
libm_common_src_files = ["digittoint.c"]
|
||||
|
||||
// TODO: this is not in the BSDs.
|
||||
libm_common_src_files += [
|
||||
"significandl.c",
|
||||
"sincos.c",
|
||||
]
|
||||
|
||||
libm_common_src_files += [
|
||||
"upstream-freebsd/lib/msun/bsdsrc/b_exp.c",
|
||||
"upstream-freebsd/lib/msun/bsdsrc/b_log.c",
|
||||
"upstream-freebsd/lib/msun/bsdsrc/b_tgamma.c",
|
||||
@ -175,19 +186,8 @@ libm_common_src_files = [
|
||||
]
|
||||
|
||||
libm_common_src_files += [
|
||||
// TODO: this comes from from upstream's libc, not libm, but it's an
|
||||
// implementation detail that should have hidden visibility, so it needs
|
||||
// to be in whatever library the math code is in.
|
||||
"digittoint.c",
|
||||
|
||||
// Functionality not in the BSDs.
|
||||
"significandl.c",
|
||||
"sincos.c",
|
||||
|
||||
// Modified versions of BSD code.
|
||||
"fake_long_double.c",
|
||||
"signbit.c",
|
||||
|
||||
// Home-grown stuff.
|
||||
"fabs.cpp",
|
||||
]
|
||||
|
||||
@ -254,7 +254,6 @@ libm_common_cflags = [
|
||||
"-D__BIONIC_NO_MATH_INLINES",
|
||||
"-DFLT_EVAL_METHOD=0",
|
||||
"-include freebsd-compat.h",
|
||||
"-Werror",
|
||||
"-Wno-missing-braces",
|
||||
"-Wno-parentheses",
|
||||
"-Wno-sign-compare",
|
||||
@ -291,10 +290,9 @@ cc_library {
|
||||
native_coverage: bionic_coverage,
|
||||
sanitize: ["never"],
|
||||
|
||||
version_script: "libm.map",
|
||||
|
||||
multilib: {
|
||||
lib32: {
|
||||
srcs: ["fake_long_double.c"],
|
||||
},
|
||||
lib64: {
|
||||
srcs: libm_ld128_src_files,
|
||||
local_include_dirs: libm_ld_local_includes,
|
||||
@ -310,27 +308,23 @@ cc_library {
|
||||
arm: {
|
||||
srcs: [
|
||||
"arm/fenv.c",
|
||||
],
|
||||
armv7_a_neon: {
|
||||
srcs: [
|
||||
"arm/sqrt.S",
|
||||
"arm/floor.S",
|
||||
],
|
||||
exclude_srcs: [
|
||||
// TODO: these require neon not available in arm
|
||||
"upstream-freebsd/lib/msun/src/e_sqrt.c",
|
||||
"upstream-freebsd/lib/msun/src/e_sqrtf.c",
|
||||
"upstream-freebsd/lib/msun/src/s_floor.c",
|
||||
],
|
||||
},
|
||||
instruction_set: "arm",
|
||||
ldflags: ["-Wl,--hash-style=both"],
|
||||
version_script: "libm.arm.map",
|
||||
},
|
||||
|
||||
arm64: {
|
||||
srcs: [
|
||||
"arm64/ceil.S",
|
||||
"arm64/fenv.c",
|
||||
"arm64/ceil.S",
|
||||
"arm64/fma.S",
|
||||
"arm64/floor.S",
|
||||
"arm64/lrint.S",
|
||||
@ -339,8 +333,6 @@ cc_library {
|
||||
"arm64/trunc.S",
|
||||
],
|
||||
exclude_srcs: [
|
||||
"upstream-freebsd/lib/msun/src/e_sqrt.c",
|
||||
"upstream-freebsd/lib/msun/src/e_sqrtf.c",
|
||||
"upstream-freebsd/lib/msun/src/s_ceil.c",
|
||||
"upstream-freebsd/lib/msun/src/s_ceilf.c",
|
||||
"upstream-freebsd/lib/msun/src/s_fma.c",
|
||||
@ -353,163 +345,33 @@ cc_library {
|
||||
"upstream-freebsd/lib/msun/src/s_lrintf.c",
|
||||
"upstream-freebsd/lib/msun/src/s_rint.c",
|
||||
"upstream-freebsd/lib/msun/src/s_rintf.c",
|
||||
"upstream-freebsd/lib/msun/src/e_sqrt.c",
|
||||
"upstream-freebsd/lib/msun/src/e_sqrtf.c",
|
||||
"upstream-freebsd/lib/msun/src/s_trunc.c",
|
||||
"upstream-freebsd/lib/msun/src/s_truncf.c",
|
||||
],
|
||||
version_script: "libm.arm64.map",
|
||||
},
|
||||
|
||||
mips: {
|
||||
srcs: ["mips/fenv.c"],
|
||||
version_script: "libm.mips.map",
|
||||
},
|
||||
|
||||
mips64: {
|
||||
srcs: ["mips/fenv.c"],
|
||||
version_script: "libm.mips64.map",
|
||||
},
|
||||
|
||||
x86: {
|
||||
srcs: [
|
||||
"i387/fenv.c",
|
||||
"x86/sqrt.S",
|
||||
"x86/sqrtf.S",
|
||||
"x86/e_acos.S",
|
||||
"x86/e_asin.S",
|
||||
"x86/e_atan2.S",
|
||||
"x86/e_cosh.S",
|
||||
"x86/e_exp.S",
|
||||
"x86/e_hypot.S",
|
||||
"x86/e_log10.S",
|
||||
"x86/e_log.S",
|
||||
"x86/e_pow.S",
|
||||
"x86/e_sinh.S",
|
||||
"x86/libm_reduce_pi04l.S",
|
||||
"x86/libm_sincos_huge.S",
|
||||
"x86/libm_tancot_huge.S",
|
||||
"x86/s_atan.S",
|
||||
"x86/s_cbrt.S",
|
||||
"x86/s_cos.S",
|
||||
"x86/s_expm1.S",
|
||||
"x86/s_log1p.S",
|
||||
"x86/s_sin.S",
|
||||
"x86/s_tanh.S",
|
||||
"x86/s_tan.S",
|
||||
],
|
||||
exclude_srcs: [
|
||||
"upstream-freebsd/lib/msun/src/e_acos.c",
|
||||
"upstream-freebsd/lib/msun/src/e_asin.c",
|
||||
"upstream-freebsd/lib/msun/src/e_atan2.c",
|
||||
"upstream-freebsd/lib/msun/src/e_cosh.c",
|
||||
"upstream-freebsd/lib/msun/src/e_exp.c",
|
||||
"upstream-freebsd/lib/msun/src/e_hypot.c",
|
||||
"upstream-freebsd/lib/msun/src/e_log.c",
|
||||
"upstream-freebsd/lib/msun/src/e_log10.c",
|
||||
"upstream-freebsd/lib/msun/src/e_pow.c",
|
||||
"upstream-freebsd/lib/msun/src/e_sinh.c",
|
||||
"upstream-freebsd/lib/msun/src/e_sqrt.c",
|
||||
"upstream-freebsd/lib/msun/src/e_sqrtf.c",
|
||||
"upstream-freebsd/lib/msun/src/s_atan.c",
|
||||
"upstream-freebsd/lib/msun/src/s_cbrt.c",
|
||||
"upstream-freebsd/lib/msun/src/s_cos.c",
|
||||
"upstream-freebsd/lib/msun/src/s_expm1.c",
|
||||
"upstream-freebsd/lib/msun/src/s_log1p.c",
|
||||
"upstream-freebsd/lib/msun/src/s_sin.c",
|
||||
"upstream-freebsd/lib/msun/src/s_tan.c",
|
||||
"upstream-freebsd/lib/msun/src/s_tanh.c",
|
||||
],
|
||||
sse4_1: {
|
||||
srcs: [
|
||||
"x86/ceil.S",
|
||||
"x86/ceilf.S",
|
||||
"x86/floor.S",
|
||||
"x86/floorf.S",
|
||||
"x86/trunc.S",
|
||||
"x86/truncf.S",
|
||||
],
|
||||
exclude_srcs: [
|
||||
"upstream-freebsd/lib/msun/src/s_ceil.c",
|
||||
"upstream-freebsd/lib/msun/src/s_ceilf.c",
|
||||
"upstream-freebsd/lib/msun/src/s_floor.c",
|
||||
"upstream-freebsd/lib/msun/src/s_floorf.c",
|
||||
"upstream-freebsd/lib/msun/src/s_trunc.c",
|
||||
"upstream-freebsd/lib/msun/src/s_truncf.c",
|
||||
],
|
||||
},
|
||||
local_include_dirs: ["i387"],
|
||||
srcs: ["i387/fenv.c"],
|
||||
// Clang has wrong long double sizes for x86.
|
||||
clang: false,
|
||||
ldflags: ["-Wl,--hash-style=both"],
|
||||
version_script: "libm.x86.map",
|
||||
},
|
||||
|
||||
x86_64: {
|
||||
srcs: [
|
||||
"amd64/fenv.c",
|
||||
"x86_64/sqrt.S",
|
||||
"x86_64/sqrtf.S",
|
||||
"x86_64/e_acos.S",
|
||||
"x86_64/e_asin.S",
|
||||
"x86_64/e_atan2.S",
|
||||
"x86_64/e_cosh.S",
|
||||
"x86_64/e_exp.S",
|
||||
"x86_64/e_hypot.S",
|
||||
"x86_64/e_log10.S",
|
||||
"x86_64/e_log.S",
|
||||
"x86_64/e_pow.S",
|
||||
"x86_64/e_sinh.S",
|
||||
"x86_64/s_atan.S",
|
||||
"x86_64/s_cbrt.S",
|
||||
"x86_64/s_cos.S",
|
||||
"x86_64/s_expm1.S",
|
||||
"x86_64/s_log1p.S",
|
||||
"x86_64/s_sin.S",
|
||||
"x86_64/s_tanh.S",
|
||||
"x86_64/s_tan.S",
|
||||
],
|
||||
exclude_srcs: [
|
||||
"upstream-freebsd/lib/msun/src/e_acos.c",
|
||||
"upstream-freebsd/lib/msun/src/e_asin.c",
|
||||
"upstream-freebsd/lib/msun/src/e_atan2.c",
|
||||
"upstream-freebsd/lib/msun/src/e_cosh.c",
|
||||
"upstream-freebsd/lib/msun/src/e_exp.c",
|
||||
"upstream-freebsd/lib/msun/src/e_hypot.c",
|
||||
"upstream-freebsd/lib/msun/src/e_log.c",
|
||||
"upstream-freebsd/lib/msun/src/e_log10.c",
|
||||
"upstream-freebsd/lib/msun/src/e_pow.c",
|
||||
"upstream-freebsd/lib/msun/src/e_sinh.c",
|
||||
"upstream-freebsd/lib/msun/src/e_sqrt.c",
|
||||
"upstream-freebsd/lib/msun/src/e_sqrtf.c",
|
||||
"upstream-freebsd/lib/msun/src/s_atan.c",
|
||||
"upstream-freebsd/lib/msun/src/s_cbrt.c",
|
||||
"upstream-freebsd/lib/msun/src/s_cos.c",
|
||||
"upstream-freebsd/lib/msun/src/s_expm1.c",
|
||||
"upstream-freebsd/lib/msun/src/s_log1p.c",
|
||||
"upstream-freebsd/lib/msun/src/s_sin.c",
|
||||
"upstream-freebsd/lib/msun/src/s_tan.c",
|
||||
"upstream-freebsd/lib/msun/src/s_tanh.c",
|
||||
],
|
||||
sse4_1: {
|
||||
srcs: [
|
||||
"x86_64/ceil.S",
|
||||
"x86_64/ceilf.S",
|
||||
"x86_64/floor.S",
|
||||
"x86_64/floorf.S",
|
||||
"x86_64/trunc.S",
|
||||
"x86_64/truncf.S",
|
||||
],
|
||||
exclude_srcs: [
|
||||
"upstream-freebsd/lib/msun/src/s_ceil.c",
|
||||
"upstream-freebsd/lib/msun/src/s_ceilf.c",
|
||||
"upstream-freebsd/lib/msun/src/s_floor.c",
|
||||
"upstream-freebsd/lib/msun/src/s_floorf.c",
|
||||
"upstream-freebsd/lib/msun/src/s_trunc.c",
|
||||
"upstream-freebsd/lib/msun/src/s_truncf.c",
|
||||
],
|
||||
},
|
||||
srcs: ["amd64/fenv.c"],
|
||||
// Clang has wrong long double sizes for x86.
|
||||
clang: false,
|
||||
version_script: "libm.x86_64.map",
|
||||
},
|
||||
},
|
||||
|
||||
|
212
libm/Android.mk
212
libm/Android.mk
@ -22,19 +22,14 @@ LOCAL_SRC_FILES := \
|
||||
upstream-freebsd/lib/msun/bsdsrc/b_tgamma.c \
|
||||
upstream-freebsd/lib/msun/src/catrig.c \
|
||||
upstream-freebsd/lib/msun/src/catrigf.c \
|
||||
upstream-freebsd/lib/msun/src/e_acos.c \
|
||||
upstream-freebsd/lib/msun/src/e_acosf.c \
|
||||
upstream-freebsd/lib/msun/src/e_acosh.c \
|
||||
upstream-freebsd/lib/msun/src/e_acoshf.c \
|
||||
upstream-freebsd/lib/msun/src/e_asin.c \
|
||||
upstream-freebsd/lib/msun/src/e_asinf.c \
|
||||
upstream-freebsd/lib/msun/src/e_atan2.c \
|
||||
upstream-freebsd/lib/msun/src/e_atan2f.c \
|
||||
upstream-freebsd/lib/msun/src/e_atanh.c \
|
||||
upstream-freebsd/lib/msun/src/e_atanhf.c \
|
||||
upstream-freebsd/lib/msun/src/e_cosh.c \
|
||||
upstream-freebsd/lib/msun/src/e_coshf.c \
|
||||
upstream-freebsd/lib/msun/src/e_exp.c \
|
||||
upstream-freebsd/lib/msun/src/e_expf.c \
|
||||
upstream-freebsd/lib/msun/src/e_fmod.c \
|
||||
upstream-freebsd/lib/msun/src/e_fmodf.c \
|
||||
@ -42,7 +37,6 @@ LOCAL_SRC_FILES := \
|
||||
upstream-freebsd/lib/msun/src/e_gammaf.c \
|
||||
upstream-freebsd/lib/msun/src/e_gammaf_r.c \
|
||||
upstream-freebsd/lib/msun/src/e_gamma_r.c \
|
||||
upstream-freebsd/lib/msun/src/e_hypot.c \
|
||||
upstream-freebsd/lib/msun/src/e_hypotf.c \
|
||||
upstream-freebsd/lib/msun/src/e_j0.c \
|
||||
upstream-freebsd/lib/msun/src/e_j0f.c \
|
||||
@ -54,13 +48,10 @@ LOCAL_SRC_FILES := \
|
||||
upstream-freebsd/lib/msun/src/e_lgammaf.c \
|
||||
upstream-freebsd/lib/msun/src/e_lgammaf_r.c \
|
||||
upstream-freebsd/lib/msun/src/e_lgamma_r.c \
|
||||
upstream-freebsd/lib/msun/src/e_log10.c \
|
||||
upstream-freebsd/lib/msun/src/e_log10f.c \
|
||||
upstream-freebsd/lib/msun/src/e_log2.c \
|
||||
upstream-freebsd/lib/msun/src/e_log2f.c \
|
||||
upstream-freebsd/lib/msun/src/e_log.c \
|
||||
upstream-freebsd/lib/msun/src/e_logf.c \
|
||||
upstream-freebsd/lib/msun/src/e_pow.c \
|
||||
upstream-freebsd/lib/msun/src/e_powf.c \
|
||||
upstream-freebsd/lib/msun/src/e_remainder.c \
|
||||
upstream-freebsd/lib/msun/src/e_remainderf.c \
|
||||
@ -68,10 +59,7 @@ LOCAL_SRC_FILES := \
|
||||
upstream-freebsd/lib/msun/src/e_rem_pio2f.c \
|
||||
upstream-freebsd/lib/msun/src/e_scalb.c \
|
||||
upstream-freebsd/lib/msun/src/e_scalbf.c \
|
||||
upstream-freebsd/lib/msun/src/e_sinh.c \
|
||||
upstream-freebsd/lib/msun/src/e_sinhf.c \
|
||||
upstream-freebsd/lib/msun/src/e_sqrt.c \
|
||||
upstream-freebsd/lib/msun/src/e_sqrtf.c \
|
||||
upstream-freebsd/lib/msun/src/imprecise.c \
|
||||
upstream-freebsd/lib/msun/src/k_cos.c \
|
||||
upstream-freebsd/lib/msun/src/k_cosf.c \
|
||||
@ -84,17 +72,13 @@ LOCAL_SRC_FILES := \
|
||||
upstream-freebsd/lib/msun/src/k_tanf.c \
|
||||
upstream-freebsd/lib/msun/src/s_asinh.c \
|
||||
upstream-freebsd/lib/msun/src/s_asinhf.c \
|
||||
upstream-freebsd/lib/msun/src/s_atan.c \
|
||||
upstream-freebsd/lib/msun/src/s_atanf.c \
|
||||
upstream-freebsd/lib/msun/src/s_carg.c \
|
||||
upstream-freebsd/lib/msun/src/s_cargf.c \
|
||||
upstream-freebsd/lib/msun/src/s_cargl.c \
|
||||
upstream-freebsd/lib/msun/src/s_cbrt.c \
|
||||
upstream-freebsd/lib/msun/src/s_cbrtf.c \
|
||||
upstream-freebsd/lib/msun/src/s_ccosh.c \
|
||||
upstream-freebsd/lib/msun/src/s_ccoshf.c \
|
||||
upstream-freebsd/lib/msun/src/s_ceil.c \
|
||||
upstream-freebsd/lib/msun/src/s_ceilf.c \
|
||||
upstream-freebsd/lib/msun/src/s_cexp.c \
|
||||
upstream-freebsd/lib/msun/src/s_cexpf.c \
|
||||
upstream-freebsd/lib/msun/src/s_cimag.c \
|
||||
@ -105,7 +89,6 @@ LOCAL_SRC_FILES := \
|
||||
upstream-freebsd/lib/msun/src/s_conjl.c \
|
||||
upstream-freebsd/lib/msun/src/s_copysign.c \
|
||||
upstream-freebsd/lib/msun/src/s_copysignf.c \
|
||||
upstream-freebsd/lib/msun/src/s_cos.c \
|
||||
upstream-freebsd/lib/msun/src/s_cosf.c \
|
||||
upstream-freebsd/lib/msun/src/s_cproj.c \
|
||||
upstream-freebsd/lib/msun/src/s_cprojf.c \
|
||||
@ -124,15 +107,10 @@ LOCAL_SRC_FILES := \
|
||||
upstream-freebsd/lib/msun/src/s_erff.c \
|
||||
upstream-freebsd/lib/msun/src/s_exp2.c \
|
||||
upstream-freebsd/lib/msun/src/s_exp2f.c \
|
||||
upstream-freebsd/lib/msun/src/s_expm1.c \
|
||||
upstream-freebsd/lib/msun/src/s_expm1f.c \
|
||||
upstream-freebsd/lib/msun/src/s_fdim.c \
|
||||
upstream-freebsd/lib/msun/src/s_finite.c \
|
||||
upstream-freebsd/lib/msun/src/s_finitef.c \
|
||||
upstream-freebsd/lib/msun/src/s_floor.c \
|
||||
upstream-freebsd/lib/msun/src/s_floorf.c \
|
||||
upstream-freebsd/lib/msun/src/s_fma.c \
|
||||
upstream-freebsd/lib/msun/src/s_fmaf.c \
|
||||
upstream-freebsd/lib/msun/src/s_fmax.c \
|
||||
upstream-freebsd/lib/msun/src/s_fmaxf.c \
|
||||
upstream-freebsd/lib/msun/src/s_fmin.c \
|
||||
@ -141,16 +119,11 @@ LOCAL_SRC_FILES := \
|
||||
upstream-freebsd/lib/msun/src/s_frexpf.c \
|
||||
upstream-freebsd/lib/msun/src/s_ilogb.c \
|
||||
upstream-freebsd/lib/msun/src/s_ilogbf.c \
|
||||
upstream-freebsd/lib/msun/src/s_llrint.c \
|
||||
upstream-freebsd/lib/msun/src/s_llrintf.c \
|
||||
upstream-freebsd/lib/msun/src/s_llround.c \
|
||||
upstream-freebsd/lib/msun/src/s_llroundf.c \
|
||||
upstream-freebsd/lib/msun/src/s_log1p.c \
|
||||
upstream-freebsd/lib/msun/src/s_log1pf.c \
|
||||
upstream-freebsd/lib/msun/src/s_logb.c \
|
||||
upstream-freebsd/lib/msun/src/s_logbf.c \
|
||||
upstream-freebsd/lib/msun/src/s_lrint.c \
|
||||
upstream-freebsd/lib/msun/src/s_lrintf.c \
|
||||
upstream-freebsd/lib/msun/src/s_lround.c \
|
||||
upstream-freebsd/lib/msun/src/s_lroundf.c \
|
||||
upstream-freebsd/lib/msun/src/s_modf.c \
|
||||
@ -161,8 +134,6 @@ LOCAL_SRC_FILES := \
|
||||
upstream-freebsd/lib/msun/src/s_nextafterf.c \
|
||||
upstream-freebsd/lib/msun/src/s_remquo.c \
|
||||
upstream-freebsd/lib/msun/src/s_remquof.c \
|
||||
upstream-freebsd/lib/msun/src/s_rint.c \
|
||||
upstream-freebsd/lib/msun/src/s_rintf.c \
|
||||
upstream-freebsd/lib/msun/src/s_round.c \
|
||||
upstream-freebsd/lib/msun/src/s_roundf.c \
|
||||
upstream-freebsd/lib/msun/src/s_scalbln.c \
|
||||
@ -171,15 +142,10 @@ LOCAL_SRC_FILES := \
|
||||
upstream-freebsd/lib/msun/src/s_signgam.c \
|
||||
upstream-freebsd/lib/msun/src/s_significand.c \
|
||||
upstream-freebsd/lib/msun/src/s_significandf.c \
|
||||
upstream-freebsd/lib/msun/src/s_sin.c \
|
||||
upstream-freebsd/lib/msun/src/s_sinf.c \
|
||||
upstream-freebsd/lib/msun/src/s_tan.c \
|
||||
upstream-freebsd/lib/msun/src/s_tanf.c \
|
||||
upstream-freebsd/lib/msun/src/s_tanh.c \
|
||||
upstream-freebsd/lib/msun/src/s_tanhf.c \
|
||||
upstream-freebsd/lib/msun/src/s_tgammaf.c \
|
||||
upstream-freebsd/lib/msun/src/s_trunc.c \
|
||||
upstream-freebsd/lib/msun/src/s_truncf.c \
|
||||
upstream-freebsd/lib/msun/src/w_cabs.c \
|
||||
upstream-freebsd/lib/msun/src/w_cabsf.c \
|
||||
upstream-freebsd/lib/msun/src/w_cabsl.c \
|
||||
@ -270,6 +236,37 @@ LOCAL_SRC_FILES += \
|
||||
# -----------------------------------------------------------------------------
|
||||
LOCAL_SRC_FILES_arm += \
|
||||
arm/fenv.c \
|
||||
upstream-freebsd/lib/msun/src/e_acos.c \
|
||||
upstream-freebsd/lib/msun/src/e_asin.c \
|
||||
upstream-freebsd/lib/msun/src/e_atan2.c \
|
||||
upstream-freebsd/lib/msun/src/e_cosh.c \
|
||||
upstream-freebsd/lib/msun/src/e_exp.c \
|
||||
upstream-freebsd/lib/msun/src/e_hypot.c \
|
||||
upstream-freebsd/lib/msun/src/e_log.c \
|
||||
upstream-freebsd/lib/msun/src/e_log10.c \
|
||||
upstream-freebsd/lib/msun/src/e_pow.c \
|
||||
upstream-freebsd/lib/msun/src/e_sinh.c \
|
||||
upstream-freebsd/lib/msun/src/s_atan.c \
|
||||
upstream-freebsd/lib/msun/src/s_cbrt.c \
|
||||
upstream-freebsd/lib/msun/src/s_ceil.c \
|
||||
upstream-freebsd/lib/msun/src/s_ceilf.c \
|
||||
upstream-freebsd/lib/msun/src/s_cos.c \
|
||||
upstream-freebsd/lib/msun/src/s_fma.c \
|
||||
upstream-freebsd/lib/msun/src/s_fmaf.c \
|
||||
upstream-freebsd/lib/msun/src/s_floorf.c \
|
||||
upstream-freebsd/lib/msun/src/s_expm1.c \
|
||||
upstream-freebsd/lib/msun/src/s_llrint.c \
|
||||
upstream-freebsd/lib/msun/src/s_llrintf.c \
|
||||
upstream-freebsd/lib/msun/src/s_log1p.c \
|
||||
upstream-freebsd/lib/msun/src/s_lrint.c \
|
||||
upstream-freebsd/lib/msun/src/s_lrintf.c \
|
||||
upstream-freebsd/lib/msun/src/s_rint.c \
|
||||
upstream-freebsd/lib/msun/src/s_rintf.c \
|
||||
upstream-freebsd/lib/msun/src/s_sin.c \
|
||||
upstream-freebsd/lib/msun/src/s_tan.c \
|
||||
upstream-freebsd/lib/msun/src/s_tanh.c \
|
||||
upstream-freebsd/lib/msun/src/s_trunc.c \
|
||||
upstream-freebsd/lib/msun/src/s_truncf.c \
|
||||
|
||||
# s_floor.S requires neon instructions.
|
||||
ifdef TARGET_2ND_ARCH
|
||||
@ -279,16 +276,17 @@ arch_variant := $(TARGET_ARCH_VARIANT)
|
||||
endif
|
||||
|
||||
# Use the C version on armv7-a since it doesn't support neon instructions.
|
||||
ifneq ($(arch_variant),armv7-a)
|
||||
ifeq ($(arch_variant),armv7-a)
|
||||
LOCAL_SRC_FILES_arm += \
|
||||
arm/sqrt.S \
|
||||
arm/floor.S \
|
||||
|
||||
LOCAL_SRC_FILES_EXCLUDE_arm += \
|
||||
upstream-freebsd/lib/msun/src/e_sqrt.c \
|
||||
upstream-freebsd/lib/msun/src/e_sqrtf.c \
|
||||
upstream-freebsd/lib/msun/src/s_floor.c \
|
||||
|
||||
else
|
||||
LOCAL_SRC_FILES_arm += \
|
||||
arm/sqrt.S \
|
||||
arm/floor.S \
|
||||
|
||||
endif
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
@ -303,30 +301,64 @@ LOCAL_SRC_FILES_arm64 += \
|
||||
arm64/rint.S \
|
||||
arm64/sqrt.S \
|
||||
arm64/trunc.S \
|
||||
|
||||
LOCAL_SRC_FILES_EXCLUDE_arm64 += \
|
||||
upstream-freebsd/lib/msun/src/e_sqrt.c \
|
||||
upstream-freebsd/lib/msun/src/e_sqrtf.c \
|
||||
upstream-freebsd/lib/msun/src/s_ceil.c \
|
||||
upstream-freebsd/lib/msun/src/s_ceilf.c \
|
||||
upstream-freebsd/lib/msun/src/s_fma.c \
|
||||
upstream-freebsd/lib/msun/src/s_fmaf.c \
|
||||
upstream-freebsd/lib/msun/src/s_floor.c \
|
||||
upstream-freebsd/lib/msun/src/s_floorf.c \
|
||||
upstream-freebsd/lib/msun/src/s_llrint.c \
|
||||
upstream-freebsd/lib/msun/src/s_llrintf.c \
|
||||
upstream-freebsd/lib/msun/src/s_lrint.c \
|
||||
upstream-freebsd/lib/msun/src/s_lrintf.c \
|
||||
upstream-freebsd/lib/msun/src/s_rint.c \
|
||||
upstream-freebsd/lib/msun/src/s_rintf.c \
|
||||
upstream-freebsd/lib/msun/src/s_trunc.c \
|
||||
upstream-freebsd/lib/msun/src/s_truncf.c \
|
||||
upstream-freebsd/lib/msun/src/e_acos.c \
|
||||
upstream-freebsd/lib/msun/src/e_asin.c \
|
||||
upstream-freebsd/lib/msun/src/e_atan2.c \
|
||||
upstream-freebsd/lib/msun/src/e_cosh.c \
|
||||
upstream-freebsd/lib/msun/src/e_exp.c \
|
||||
upstream-freebsd/lib/msun/src/e_hypot.c \
|
||||
upstream-freebsd/lib/msun/src/e_log.c \
|
||||
upstream-freebsd/lib/msun/src/e_log10.c \
|
||||
upstream-freebsd/lib/msun/src/e_pow.c \
|
||||
upstream-freebsd/lib/msun/src/e_sinh.c \
|
||||
upstream-freebsd/lib/msun/src/s_atan.c \
|
||||
upstream-freebsd/lib/msun/src/s_cbrt.c \
|
||||
upstream-freebsd/lib/msun/src/s_cos.c \
|
||||
upstream-freebsd/lib/msun/src/s_expm1.c \
|
||||
upstream-freebsd/lib/msun/src/s_log1p.c \
|
||||
upstream-freebsd/lib/msun/src/s_sin.c \
|
||||
upstream-freebsd/lib/msun/src/s_tan.c \
|
||||
upstream-freebsd/lib/msun/src/s_tanh.c \
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# mips
|
||||
# -----------------------------------------------------------------------------
|
||||
libm_mips_arch_files := \
|
||||
mips/fenv.c \
|
||||
upstream-freebsd/lib/msun/src/e_acos.c \
|
||||
upstream-freebsd/lib/msun/src/e_asin.c \
|
||||
upstream-freebsd/lib/msun/src/e_atan2.c \
|
||||
upstream-freebsd/lib/msun/src/e_cosh.c \
|
||||
upstream-freebsd/lib/msun/src/e_exp.c \
|
||||
upstream-freebsd/lib/msun/src/e_hypot.c \
|
||||
upstream-freebsd/lib/msun/src/e_log.c \
|
||||
upstream-freebsd/lib/msun/src/e_log10.c \
|
||||
upstream-freebsd/lib/msun/src/e_pow.c \
|
||||
upstream-freebsd/lib/msun/src/e_sinh.c \
|
||||
upstream-freebsd/lib/msun/src/e_sqrt.c \
|
||||
upstream-freebsd/lib/msun/src/e_sqrtf.c \
|
||||
upstream-freebsd/lib/msun/src/s_atan.c \
|
||||
upstream-freebsd/lib/msun/src/s_cbrt.c \
|
||||
upstream-freebsd/lib/msun/src/s_ceil.c \
|
||||
upstream-freebsd/lib/msun/src/s_ceilf.c \
|
||||
upstream-freebsd/lib/msun/src/s_cos.c \
|
||||
upstream-freebsd/lib/msun/src/s_fma.c \
|
||||
upstream-freebsd/lib/msun/src/s_fmaf.c \
|
||||
upstream-freebsd/lib/msun/src/s_floor.c \
|
||||
upstream-freebsd/lib/msun/src/s_floorf.c \
|
||||
upstream-freebsd/lib/msun/src/s_expm1.c \
|
||||
upstream-freebsd/lib/msun/src/s_llrint.c \
|
||||
upstream-freebsd/lib/msun/src/s_llrintf.c \
|
||||
upstream-freebsd/lib/msun/src/s_log1p.c \
|
||||
upstream-freebsd/lib/msun/src/s_lrint.c \
|
||||
upstream-freebsd/lib/msun/src/s_lrintf.c \
|
||||
upstream-freebsd/lib/msun/src/s_rint.c \
|
||||
upstream-freebsd/lib/msun/src/s_rintf.c \
|
||||
upstream-freebsd/lib/msun/src/s_sin.c \
|
||||
upstream-freebsd/lib/msun/src/s_tan.c \
|
||||
upstream-freebsd/lib/msun/src/s_tanh.c \
|
||||
upstream-freebsd/lib/msun/src/s_trunc.c \
|
||||
upstream-freebsd/lib/msun/src/s_truncf.c \
|
||||
|
||||
LOCAL_SRC_FILES_mips += $(libm_mips_arch_files)
|
||||
LOCAL_SRC_FILES_mips64 += $(libm_mips_arch_files)
|
||||
@ -336,6 +368,14 @@ LOCAL_SRC_FILES_mips64 += $(libm_mips_arch_files)
|
||||
# -----------------------------------------------------------------------------
|
||||
LOCAL_SRC_FILES_x86 += \
|
||||
i387/fenv.c \
|
||||
upstream-freebsd/lib/msun/src/s_fma.c \
|
||||
upstream-freebsd/lib/msun/src/s_fmaf.c \
|
||||
upstream-freebsd/lib/msun/src/s_llrint.c \
|
||||
upstream-freebsd/lib/msun/src/s_llrintf.c \
|
||||
upstream-freebsd/lib/msun/src/s_lrint.c \
|
||||
upstream-freebsd/lib/msun/src/s_lrintf.c \
|
||||
upstream-freebsd/lib/msun/src/s_rint.c \
|
||||
upstream-freebsd/lib/msun/src/s_rintf.c \
|
||||
x86/sqrt.S \
|
||||
x86/sqrtf.S \
|
||||
x86/e_acos.S \
|
||||
@ -360,28 +400,6 @@ LOCAL_SRC_FILES_x86 += \
|
||||
x86/s_tanh.S \
|
||||
x86/s_tan.S \
|
||||
|
||||
LOCAL_SRC_FILES_EXCLUDE_x86 += \
|
||||
upstream-freebsd/lib/msun/src/e_acos.c \
|
||||
upstream-freebsd/lib/msun/src/e_asin.c \
|
||||
upstream-freebsd/lib/msun/src/e_atan2.c \
|
||||
upstream-freebsd/lib/msun/src/e_cosh.c \
|
||||
upstream-freebsd/lib/msun/src/e_exp.c \
|
||||
upstream-freebsd/lib/msun/src/e_hypot.c \
|
||||
upstream-freebsd/lib/msun/src/e_log.c \
|
||||
upstream-freebsd/lib/msun/src/e_log10.c \
|
||||
upstream-freebsd/lib/msun/src/e_pow.c \
|
||||
upstream-freebsd/lib/msun/src/e_sinh.c \
|
||||
upstream-freebsd/lib/msun/src/e_sqrt.c \
|
||||
upstream-freebsd/lib/msun/src/e_sqrtf.c \
|
||||
upstream-freebsd/lib/msun/src/s_atan.c \
|
||||
upstream-freebsd/lib/msun/src/s_cbrt.c \
|
||||
upstream-freebsd/lib/msun/src/s_cos.c \
|
||||
upstream-freebsd/lib/msun/src/s_expm1.c \
|
||||
upstream-freebsd/lib/msun/src/s_log1p.c \
|
||||
upstream-freebsd/lib/msun/src/s_sin.c \
|
||||
upstream-freebsd/lib/msun/src/s_tan.c \
|
||||
upstream-freebsd/lib/msun/src/s_tanh.c \
|
||||
|
||||
ifeq ($(ARCH_X86_HAVE_SSE4_1),true)
|
||||
LOCAL_SRC_FILES_x86 += \
|
||||
x86/ceil.S \
|
||||
@ -391,7 +409,8 @@ LOCAL_SRC_FILES_x86 += \
|
||||
x86/trunc.S \
|
||||
x86/truncf.S \
|
||||
|
||||
LOCAL_SRC_FILES_EXCLUDE_x86 += \
|
||||
else
|
||||
LOCAL_SRC_FILES_x86 += \
|
||||
upstream-freebsd/lib/msun/src/s_ceil.c \
|
||||
upstream-freebsd/lib/msun/src/s_ceilf.c \
|
||||
upstream-freebsd/lib/msun/src/s_floor.c \
|
||||
@ -406,6 +425,14 @@ endif
|
||||
# -----------------------------------------------------------------------------
|
||||
LOCAL_SRC_FILES_x86_64 += \
|
||||
amd64/fenv.c \
|
||||
upstream-freebsd/lib/msun/src/s_fma.c \
|
||||
upstream-freebsd/lib/msun/src/s_fmaf.c \
|
||||
upstream-freebsd/lib/msun/src/s_llrint.c \
|
||||
upstream-freebsd/lib/msun/src/s_llrintf.c \
|
||||
upstream-freebsd/lib/msun/src/s_lrint.c \
|
||||
upstream-freebsd/lib/msun/src/s_lrintf.c \
|
||||
upstream-freebsd/lib/msun/src/s_rint.c \
|
||||
upstream-freebsd/lib/msun/src/s_rintf.c \
|
||||
x86_64/sqrt.S \
|
||||
x86_64/sqrtf.S \
|
||||
x86_64/e_acos.S \
|
||||
@ -427,28 +454,6 @@ LOCAL_SRC_FILES_x86_64 += \
|
||||
x86_64/s_tanh.S \
|
||||
x86_64/s_tan.S \
|
||||
|
||||
LOCAL_SRC_FILES_EXCLUDE_x86_64 += \
|
||||
upstream-freebsd/lib/msun/src/e_acos.c \
|
||||
upstream-freebsd/lib/msun/src/e_asin.c \
|
||||
upstream-freebsd/lib/msun/src/e_atan2.c \
|
||||
upstream-freebsd/lib/msun/src/e_cosh.c \
|
||||
upstream-freebsd/lib/msun/src/e_exp.c \
|
||||
upstream-freebsd/lib/msun/src/e_hypot.c \
|
||||
upstream-freebsd/lib/msun/src/e_log.c \
|
||||
upstream-freebsd/lib/msun/src/e_log10.c \
|
||||
upstream-freebsd/lib/msun/src/e_pow.c \
|
||||
upstream-freebsd/lib/msun/src/e_sinh.c \
|
||||
upstream-freebsd/lib/msun/src/e_sqrt.c \
|
||||
upstream-freebsd/lib/msun/src/e_sqrtf.c \
|
||||
upstream-freebsd/lib/msun/src/s_atan.c \
|
||||
upstream-freebsd/lib/msun/src/s_cbrt.c \
|
||||
upstream-freebsd/lib/msun/src/s_cos.c \
|
||||
upstream-freebsd/lib/msun/src/s_expm1.c \
|
||||
upstream-freebsd/lib/msun/src/s_log1p.c \
|
||||
upstream-freebsd/lib/msun/src/s_sin.c \
|
||||
upstream-freebsd/lib/msun/src/s_tan.c \
|
||||
upstream-freebsd/lib/msun/src/s_tanh.c \
|
||||
|
||||
ifeq ($(ARCH_X86_HAVE_SSE4_1),true)
|
||||
LOCAL_SRC_FILES_x86_64 += \
|
||||
x86_64/ceil.S \
|
||||
@ -458,7 +463,8 @@ LOCAL_SRC_FILES_x86_64 += \
|
||||
x86_64/trunc.S \
|
||||
x86_64/truncf.S \
|
||||
|
||||
LOCAL_SRC_FILES_EXCLUDE_x86_64 += \
|
||||
else
|
||||
LOCAL_SRC_FILES_x86_64 += \
|
||||
upstream-freebsd/lib/msun/src/s_ceil.c \
|
||||
upstream-freebsd/lib/msun/src/s_ceilf.c \
|
||||
upstream-freebsd/lib/msun/src/s_floor.c \
|
||||
|
@ -272,8 +272,8 @@ LIBC {
|
||||
*;
|
||||
};
|
||||
|
||||
LIBC_PRIVATE { # arm mips
|
||||
global: # arm mips
|
||||
LIBC_PRIVATE { # arm x86 mips
|
||||
global: # arm x86 mips
|
||||
___Unwind_Backtrace; # arm
|
||||
___Unwind_ForcedUnwind; # arm
|
||||
___Unwind_RaiseException; # arm
|
||||
@ -354,6 +354,7 @@ LIBC_PRIVATE { # arm mips
|
||||
__lesf2; # arm
|
||||
__ltdf2; # arm
|
||||
__ltsf2; # arm
|
||||
__muldc3; # arm x86 mips
|
||||
__muldf3; # arm
|
||||
__nedf2; # arm
|
||||
__nesf2; # arm
|
||||
@ -375,4 +376,4 @@ LIBC_PRIVATE { # arm mips
|
||||
_Unwind_VRS_Pop; # arm
|
||||
_Unwind_VRS_Set; # arm
|
||||
restore_core_regs; # arm
|
||||
} LIBC; # arm mips
|
||||
} LIBC; # arm x86 mips
|
||||
|
@ -271,8 +271,8 @@ LIBC {
|
||||
*;
|
||||
};
|
||||
|
||||
LIBC_PRIVATE { # arm mips
|
||||
global: # arm mips
|
||||
LIBC_PRIVATE { # arm x86 mips
|
||||
global: # arm x86 mips
|
||||
___Unwind_Backtrace; # arm
|
||||
___Unwind_ForcedUnwind; # arm
|
||||
___Unwind_RaiseException; # arm
|
||||
@ -353,6 +353,7 @@ LIBC_PRIVATE { # arm mips
|
||||
__lesf2; # arm
|
||||
__ltdf2; # arm
|
||||
__ltsf2; # arm
|
||||
__muldc3; # arm x86 mips
|
||||
__muldf3; # arm
|
||||
__nedf2; # arm
|
||||
__nesf2; # arm
|
||||
@ -374,4 +375,4 @@ LIBC_PRIVATE { # arm mips
|
||||
_Unwind_VRS_Pop; # arm
|
||||
_Unwind_VRS_Set; # arm
|
||||
restore_core_regs; # arm
|
||||
} LIBC; # arm mips
|
||||
} LIBC; # arm x86 mips
|
||||
|
@ -272,10 +272,11 @@ LIBC {
|
||||
*;
|
||||
};
|
||||
|
||||
LIBC_PRIVATE { # arm mips
|
||||
global: # arm mips
|
||||
LIBC_PRIVATE { # arm x86 mips
|
||||
global: # arm x86 mips
|
||||
__fixdfdi; # arm mips
|
||||
__fixsfdi; # arm mips
|
||||
__fixunsdfdi; # arm mips
|
||||
__fixunssfdi; # arm mips
|
||||
} LIBC; # arm mips
|
||||
__muldc3; # arm x86 mips
|
||||
} LIBC; # arm x86 mips
|
||||
|
@ -272,3 +272,7 @@ LIBC {
|
||||
*;
|
||||
};
|
||||
|
||||
LIBC_PRIVATE { # arm x86 mips
|
||||
global: # arm x86 mips
|
||||
__muldc3; # arm x86 mips
|
||||
} LIBC; # arm x86 mips
|
||||
|
@ -9,12 +9,12 @@ LOCAL_SRC_FILES := \
|
||||
dlfcn.cpp \
|
||||
linker.cpp \
|
||||
linker_allocator.cpp \
|
||||
linker_sdk_versions.cpp \
|
||||
linker_block_allocator.cpp \
|
||||
linker_libc_support.c \
|
||||
linker_mapped_file_fragment.cpp \
|
||||
linker_memory.cpp \
|
||||
linker_phdr.cpp \
|
||||
linker_sdk_versions.cpp \
|
||||
linker_utils.cpp \
|
||||
rt.cpp \
|
||||
|
||||
|
120
linker/dlfcn.cpp
120
linker/dlfcn.cpp
@ -16,10 +16,12 @@
|
||||
|
||||
#include "linker.h"
|
||||
|
||||
#include <dlfcn.h>
|
||||
#include <pthread.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <android/dlext.h>
|
||||
#include <android/api-level.h>
|
||||
|
||||
#include <bionic/pthread_internal.h>
|
||||
@ -68,7 +70,8 @@ void android_update_LD_LIBRARY_PATH(const char* ld_library_path) {
|
||||
static void* dlopen_ext(const char* filename, int flags,
|
||||
const android_dlextinfo* extinfo, void* caller_addr) {
|
||||
ScopedPthreadMutexLocker locker(&g_dl_mutex);
|
||||
soinfo* result = do_dlopen(filename, flags, extinfo, caller_addr);
|
||||
soinfo* caller = find_containing_library(caller_addr);
|
||||
soinfo* result = do_dlopen(filename, flags, extinfo, caller);
|
||||
if (result == nullptr) {
|
||||
__bionic_format_dlerror("dlopen failed", linker_get_error_buffer());
|
||||
return nullptr;
|
||||
@ -86,32 +89,70 @@ void* dlopen(const char* filename, int flags) {
|
||||
return dlopen_ext(filename, flags, nullptr, caller_addr);
|
||||
}
|
||||
|
||||
extern android_namespace_t* g_anonymous_namespace;
|
||||
|
||||
void* dlsym_impl(void* handle, const char* symbol, const char* version, void* caller_addr) {
|
||||
void* dlsym(void* handle, const char* symbol) {
|
||||
ScopedPthreadMutexLocker locker(&g_dl_mutex);
|
||||
void* result;
|
||||
if (!do_dlsym(handle, symbol, version, caller_addr, &result)) {
|
||||
__bionic_format_dlerror(linker_get_error_buffer(), nullptr);
|
||||
|
||||
#if !defined(__LP64__)
|
||||
if (handle == nullptr) {
|
||||
__bionic_format_dlerror("dlsym library handle is null", nullptr);
|
||||
return nullptr;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (symbol == nullptr) {
|
||||
__bionic_format_dlerror("dlsym symbol name is null", nullptr);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return result;
|
||||
soinfo* found = nullptr;
|
||||
const ElfW(Sym)* sym = nullptr;
|
||||
void* caller_addr = __builtin_return_address(0);
|
||||
soinfo* caller = find_containing_library(caller_addr);
|
||||
|
||||
if (handle == RTLD_DEFAULT || handle == RTLD_NEXT) {
|
||||
sym = dlsym_linear_lookup(symbol, &found, caller, handle);
|
||||
} else {
|
||||
sym = dlsym_handle_lookup(reinterpret_cast<soinfo*>(handle), &found, symbol);
|
||||
}
|
||||
|
||||
void* dlsym(void* handle, const char* symbol) {
|
||||
void* caller_addr = __builtin_return_address(0);
|
||||
return dlsym_impl(handle, symbol, nullptr, caller_addr);
|
||||
if (sym != nullptr) {
|
||||
unsigned bind = ELF_ST_BIND(sym->st_info);
|
||||
|
||||
if ((bind == STB_GLOBAL || bind == STB_WEAK) && sym->st_shndx != 0) {
|
||||
return reinterpret_cast<void*>(found->resolve_symbol_address(sym));
|
||||
}
|
||||
|
||||
void* dlvsym(void* handle, const char* symbol, const char* version) {
|
||||
void* caller_addr = __builtin_return_address(0);
|
||||
return dlsym_impl(handle, symbol, version, caller_addr);
|
||||
__bionic_format_dlerror("symbol found but not global", symbol);
|
||||
return nullptr;
|
||||
} else {
|
||||
__bionic_format_dlerror("undefined symbol", symbol);
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
int dladdr(const void* addr, Dl_info* info) {
|
||||
ScopedPthreadMutexLocker locker(&g_dl_mutex);
|
||||
return do_dladdr(addr, info);
|
||||
|
||||
// Determine if this address can be found in any library currently mapped.
|
||||
soinfo* si = find_containing_library(addr);
|
||||
if (si == nullptr) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
memset(info, 0, sizeof(Dl_info));
|
||||
|
||||
info->dli_fname = si->get_realpath();
|
||||
// Address at which the shared object is loaded.
|
||||
info->dli_fbase = reinterpret_cast<void*>(si->base);
|
||||
|
||||
// Determine if any symbol in the library contains the specified address.
|
||||
ElfW(Sym)* sym = si->find_symbol_by_address(addr);
|
||||
if (sym != nullptr) {
|
||||
info->dli_sname = si->get_string(sym->st_name);
|
||||
info->dli_saddr = reinterpret_cast<void*>(si->resolve_symbol_address(sym));
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int dlclose(void* handle) {
|
||||
@ -136,34 +177,6 @@ uint32_t android_get_application_target_sdk_version() {
|
||||
return get_application_target_sdk_version();
|
||||
}
|
||||
|
||||
bool android_init_namespaces(const char* public_ns_sonames,
|
||||
const char* anon_ns_library_path) {
|
||||
ScopedPthreadMutexLocker locker(&g_dl_mutex);
|
||||
bool success = init_namespaces(public_ns_sonames, anon_ns_library_path);
|
||||
if (!success) {
|
||||
__bionic_format_dlerror("android_init_namespaces failed", linker_get_error_buffer());
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
android_namespace_t* android_create_namespace(const char* name, const char* ld_library_path,
|
||||
const char* default_library_path, uint64_t type,
|
||||
const char* permitted_when_isolated_path) {
|
||||
void* caller_addr = __builtin_return_address(0);
|
||||
ScopedPthreadMutexLocker locker(&g_dl_mutex);
|
||||
|
||||
android_namespace_t* result = create_namespace(caller_addr, name, ld_library_path,
|
||||
default_library_path, type,
|
||||
permitted_when_isolated_path);
|
||||
|
||||
if (result == nullptr) {
|
||||
__bionic_format_dlerror("android_create_namespace failed", linker_get_error_buffer());
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// name_offset: starting index of the name in libdl_info.strtab
|
||||
#define ELF32_SYM_INITIALIZER(name_offset, value, shndx) \
|
||||
{ name_offset, \
|
||||
@ -190,11 +203,11 @@ static const char ANDROID_LIBDL_STRTAB[] =
|
||||
// 00000000001 1111111112222222222 3333333333444444444455555555556666666666777 777777788888888889999999999
|
||||
// 01234567890 1234567890123456789 0123456789012345678901234567890123456789012 345678901234567890123456789
|
||||
"erate_phdr\0android_dlopen_ext\0android_set_application_target_sdk_version\0android_get_application_tar"
|
||||
// 0000000000111111 111122222222223333333333 4444444444555555555566666 6666677
|
||||
// 0123456789012345 678901234567890123456789 0123456789012345678901234 5678901
|
||||
"get_sdk_version\0android_init_namespaces\0android_create_namespace\0dlvsym\0"
|
||||
// 0000000000111111
|
||||
// 0123456789012345
|
||||
"get_sdk_version\0"
|
||||
#if defined(__arm__)
|
||||
// 272
|
||||
// 216
|
||||
"dl_unwind_find_exidx\0"
|
||||
#endif
|
||||
;
|
||||
@ -216,11 +229,8 @@ static ElfW(Sym) g_libdl_symtab[] = {
|
||||
ELFW(SYM_INITIALIZER)(111, &android_dlopen_ext, 1),
|
||||
ELFW(SYM_INITIALIZER)(130, &android_set_application_target_sdk_version, 1),
|
||||
ELFW(SYM_INITIALIZER)(173, &android_get_application_target_sdk_version, 1),
|
||||
ELFW(SYM_INITIALIZER)(216, &android_init_namespaces, 1),
|
||||
ELFW(SYM_INITIALIZER)(240, &android_create_namespace, 1),
|
||||
ELFW(SYM_INITIALIZER)(265, &dlvsym, 1),
|
||||
#if defined(__arm__)
|
||||
ELFW(SYM_INITIALIZER)(272, &dl_unwind_find_exidx, 1),
|
||||
ELFW(SYM_INITIALIZER)(216, &dl_unwind_find_exidx, 1),
|
||||
#endif
|
||||
};
|
||||
|
||||
@ -237,20 +247,18 @@ static ElfW(Sym) g_libdl_symtab[] = {
|
||||
// Note that adding any new symbols here requires stubbing them out in libdl.
|
||||
static unsigned g_libdl_buckets[1] = { 1 };
|
||||
#if defined(__arm__)
|
||||
static unsigned g_libdl_chains[] = { 0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0 };
|
||||
static unsigned g_libdl_chains[] = { 0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 0 };
|
||||
#else
|
||||
static unsigned g_libdl_chains[] = { 0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 0 };
|
||||
static unsigned g_libdl_chains[] = { 0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0 };
|
||||
#endif
|
||||
|
||||
static uint8_t __libdl_info_buf[sizeof(soinfo)] __attribute__((aligned(8)));
|
||||
static soinfo* __libdl_info = nullptr;
|
||||
|
||||
extern android_namespace_t g_default_namespace;
|
||||
|
||||
// This is used by the dynamic linker. Every process gets these symbols for free.
|
||||
soinfo* get_libdl_info() {
|
||||
if (__libdl_info == nullptr) {
|
||||
__libdl_info = new (__libdl_info_buf) soinfo(&g_default_namespace, "libdl.so", nullptr, 0, RTLD_GLOBAL);
|
||||
__libdl_info = new (__libdl_info_buf) soinfo("libdl.so", nullptr, 0, RTLD_GLOBAL);
|
||||
__libdl_info->flags_ |= FLAG_LINKED;
|
||||
__libdl_info->strtab_ = ANDROID_LIBDL_STRTAB;
|
||||
__libdl_info->symtab_ = g_libdl_symtab;
|
||||
|
@ -25,49 +25,12 @@ struct LinkedListEntry {
|
||||
T* element;
|
||||
};
|
||||
|
||||
// ForwardInputIterator
|
||||
template<typename T>
|
||||
class LinkedListIterator {
|
||||
public:
|
||||
LinkedListIterator() : entry_(nullptr) {}
|
||||
LinkedListIterator(const LinkedListIterator<T>& that) : entry_(that.entry_) {}
|
||||
explicit LinkedListIterator(LinkedListEntry<T>* entry) : entry_(entry) {}
|
||||
|
||||
LinkedListIterator<T>& operator=(const LinkedListIterator<T>& that) {
|
||||
entry_ = that.entry_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
LinkedListIterator<T>& operator++() {
|
||||
entry_ = entry_->next;
|
||||
return *this;
|
||||
}
|
||||
|
||||
T* operator*() {
|
||||
return entry_->element;
|
||||
}
|
||||
|
||||
bool operator==(const LinkedListIterator<T>& that) const {
|
||||
return entry_ == that.entry_;
|
||||
}
|
||||
|
||||
bool operator!=(const LinkedListIterator<T>& that) const {
|
||||
return entry_ != that.entry_;
|
||||
}
|
||||
|
||||
private:
|
||||
LinkedListEntry<T> *entry_;
|
||||
};
|
||||
|
||||
/*
|
||||
* Represents linked list of objects of type T
|
||||
*/
|
||||
template<typename T, typename Allocator>
|
||||
class LinkedList {
|
||||
public:
|
||||
typedef LinkedListIterator<T> iterator;
|
||||
typedef T* value_type;
|
||||
|
||||
LinkedList() : head_(nullptr), tail_(nullptr) {}
|
||||
~LinkedList() {
|
||||
clear();
|
||||
@ -164,13 +127,7 @@ class LinkedList {
|
||||
} else {
|
||||
p->next = next;
|
||||
}
|
||||
|
||||
if (tail_ == e) {
|
||||
tail_ = p;
|
||||
}
|
||||
|
||||
Allocator::free(e);
|
||||
|
||||
e = next;
|
||||
} else {
|
||||
p = e;
|
||||
@ -190,24 +147,6 @@ class LinkedList {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
iterator begin() {
|
||||
return iterator(head_);
|
||||
}
|
||||
|
||||
iterator end() {
|
||||
return iterator(nullptr);
|
||||
}
|
||||
|
||||
iterator find(T* value) {
|
||||
for (LinkedListEntry<T>* e = head_; e != nullptr; e = e->next) {
|
||||
if (e->element == value) {
|
||||
return iterator(e);
|
||||
}
|
||||
}
|
||||
|
||||
return end();
|
||||
}
|
||||
|
||||
size_t copy_to_array(T* array[], size_t array_length) const {
|
||||
size_t sz = 0;
|
||||
for (LinkedListEntry<T>* e = head_; sz < array_length && e != nullptr; e = e->next) {
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user