Compare commits

..

No commits in common. "main" and "brillo-m7-dev" have entirely different histories.

139 changed files with 2580 additions and 10100 deletions

View File

@ -2,7 +2,6 @@ BasedOnStyle: Google
AllowShortBlocksOnASingleLine: false
AllowShortFunctionsOnASingleLine: false
ColumnLimit: 100
CommentPragmas: NOLINT:.*
DerivePointerAlignment: false
IndentWidth: 2

View File

@ -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>

View File

@ -24,7 +24,7 @@
#include <string>
#include <vector>
#include <android-base/stringprintf.h>
#include <base/stringprintf.h>
#include <benchmark/Benchmark.h>

View File

@ -23,7 +23,7 @@
#include <string>
#include <android-base/stringprintf.h>
#include <base/stringprintf.h>
int Round(int n) {
int base = 1;

File diff suppressed because it is too large Load Diff

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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");

View File

@ -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

View 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)

View File

@ -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 \

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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 \

View File

@ -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)

View File

@ -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 \

View File

@ -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);
}
}

View File

@ -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;

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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));
}
}

View File

@ -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);
}
}

View File

@ -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);
}

View File

@ -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);

View File

@ -25,7 +25,6 @@
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/*
* libc_init_dynamic.c
*

View File

@ -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.

View File

@ -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;

View File

@ -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) {

View File

@ -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);
}

View File

@ -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__)

View File

@ -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) {

View File

@ -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;
}

View File

@ -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,

View File

@ -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;

View File

@ -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];

View File

@ -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;
}

View File

@ -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);
}
}

View File

@ -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) {

View File

@ -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;
}

View File

@ -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) {

View File

@ -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);
}

View File

@ -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__ */

View File

@ -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 {

View File

@ -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*);

View File

@ -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));

View File

@ -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.

View File

@ -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);

View File

@ -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)

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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;
}

View File

@ -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

View File

@ -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

View File

@ -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;
}

View File

@ -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_

View File

@ -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 */

View File

@ -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

View File

@ -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_ */

View File

@ -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);
}

View File

@ -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

View File

@ -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__)

View File

@ -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);
}

View File

@ -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();
}

View File

@ -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)

View File

@ -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

View File

@ -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],

View File

@ -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;
}

View File

@ -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

View File

@ -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"],

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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;
}

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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",
},
},

View File

@ -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 \

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -272,3 +272,7 @@ LIBC {
*;
};
LIBC_PRIVATE { # arm x86 mips
global: # arm x86 mips
__muldc3; # arm x86 mips
} LIBC; # arm x86 mips

View File

@ -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 \

View File

@ -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;

View File

@ -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