Merge "Revert "Move __system_property* to LIBC_PRIVATE for lp64 libc""
diff --git a/Android.bp b/Android.bp
deleted file mode 100644
index b44c296..0000000
--- a/Android.bp
+++ /dev/null
@@ -1 +0,0 @@
-subdirs = ["*"]
diff --git a/Android.mk b/Android.mk
index 7c39751..9f0f0c3 100644
--- a/Android.mk
+++ b/Android.mk
@@ -16,4 +16,5 @@
LOCAL_PATH := $(call my-dir)
-include $(call all-subdir-makefiles)
+include $(call all-makefiles-under,$(LOCAL_PATH)) \
+ $(call all-makefiles-under,$(LOCAL_PATH)/libc)
diff --git a/libc/Android.bp b/libc/Android.bp
index 74fd22b..8df77ce 100644
--- a/libc/Android.bp
+++ b/libc/Android.bp
@@ -112,11 +112,6 @@
device_uses_dlmalloc: {
cflags: ["-DUSE_DLMALLOC"],
},
- // To customize dlmalloc's alignment, set BOARD_MALLOC_ALIGNMENT in
- // the appropriate BoardConfig.mk file.
- dlmalloc_alignment: {
- cflags: ["-DMALLOC_ALIGNMENT=%d"],
- },
},
// Clang/llvm has incompatible long double (fp128) for x86_64.
// https://llvm.org/bugs/show_bug.cgi?id=23897
@@ -142,18 +137,47 @@
// libc_stack_protector.a - stack protector code
// ========================================================
//
-// The stack protector code needs to be compiled
-// with -fno-stack-protector, since it modifies the
-// stack canary.
+// 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.
cc_library_static {
- srcs: ["bionic/__stack_chk_fail.cpp"],
+ srcs: [
+ "bionic/__libc_init_main_thread.cpp",
+ "bionic/__stack_chk_fail.cpp",
+ ],
+ arch: {
+ arm64: {
+ srcs: ["arch-arm64/bionic/__set_tls.c"],
+ },
+ x86: {
+ srcs: ["arch-arm64/bionic/__set_tls.c"],
+ },
+ x86_64: {
+ srcs: ["arch-x86_64/bionic/__set_tls.c"],
+ },
+ },
+
defaults: ["libc_defaults"],
cflags: ["-fno-stack-protector"],
name: "libc_stack_protector",
}
+// 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.
+
+cc_library_static {
+ name: "libc_init_static",
+ defaults: ["libc_defaults"],
+ srcs: ["bionic/libc_init_static.cpp"],
+ cflags: ["-fno-stack-protector"],
+}
+
+
// ========================================================
// libc_tzcode.a - upstream 'tzcode' code
// ========================================================
@@ -1089,7 +1113,6 @@
"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",
@@ -1173,7 +1196,6 @@
"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",
@@ -1214,7 +1236,9 @@
"arch-x86/atom/string/sse2-strlen-atom.S",
"arch-x86/atom/string/ssse3-bcopy-atom.S",
"arch-x86/atom/string/ssse3-memcmp-atom.S",
+ "arch-x86/atom/string/ssse3-memcpy-atom.S",
"arch-x86/atom/string/ssse3-memmove-atom.S",
+ "arch-x86/atom/string/ssse3-strcpy-atom.S",
"arch-x86/atom/string/ssse3-strncpy-atom.S",
"arch-x86/atom/string/ssse3-wmemcmp-atom.S",
],
@@ -1263,7 +1287,6 @@
"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",
@@ -1348,6 +1371,7 @@
"bionic/getpid.cpp",
"bionic/gettid.cpp",
"bionic/__gnu_basename.cpp",
+ "bionic/ifaddrs.cpp",
"bionic/inotify_init.cpp",
"bionic/ioctl.cpp",
"bionic/lchown.cpp",
@@ -1674,7 +1698,6 @@
defaults: ["libc_defaults"],
srcs: [
"bionic/dl_iterate_phdr_static.cpp",
- "bionic/libc_init_static.cpp",
],
arch: {
@@ -1687,7 +1710,10 @@
name: "libc_nomalloc",
- whole_static_libs: ["libc_common"],
+ whole_static_libs: [
+ "libc_common",
+ "libc_init_static",
+ ],
}
// ========================================================
@@ -1724,9 +1750,9 @@
static: {
srcs: [
"bionic/dl_iterate_phdr_static.cpp",
- "bionic/libc_init_static.cpp",
],
cflags: ["-DLIBC_STATIC"],
+ whole_static_libs: ["libc_init_static"],
},
shared: {
srcs: [
@@ -1766,7 +1792,6 @@
nocrt: true,
- // special for arm
arch: {
arm: {
//TODO: This is to work around b/24465209. Remove after root cause is fixed
@@ -1774,6 +1799,11 @@
// Don't re-export new/delete and friends, even if the compiler really wants to.
version_script: "libc.arm.map",
+ product_variables: {
+ brillo: {
+ version_script: "libc.arm.brillo.map",
+ },
+ },
shared: {
srcs: ["arch-arm/bionic/exidx_dynamic.c"],
@@ -1781,6 +1811,8 @@
static: {
srcs: ["arch-arm/bionic/exidx_static.c"],
},
+
+ // special for arm
cflags: ["-DCRT_LEGACY_WORKAROUND"],
srcs: [
"arch-arm/bionic/atexit_legacy.c",
@@ -1793,6 +1825,11 @@
mips: {
// Don't re-export new/delete and friends, even if the compiler really wants to.
version_script: "libc.mips.map",
+ product_variables: {
+ brillo: {
+ version_script: "libc.mips.brillo.map",
+ },
+ },
},
mips64: {
// Don't re-export new/delete and friends, even if the compiler really wants to.
@@ -1804,6 +1841,11 @@
// Don't re-export new/delete and friends, even if the compiler really wants to.
version_script: "libc.x86.map",
+ product_variables: {
+ brillo: {
+ version_script: "libc.x86.brillo.map",
+ },
+ },
},
x86_64: {
// Don't re-export new/delete and friends, even if the compiler really wants to.
diff --git a/libc/Android.mk b/libc/Android.mk
index a399b89..39c8c9e 100644
--- a/libc/Android.mk
+++ b/libc/Android.mk
@@ -149,6 +149,7 @@
bionic/getpid.cpp \
bionic/gettid.cpp \
bionic/__gnu_basename.cpp \
+ bionic/ifaddrs.cpp \
bionic/inotify_init.cpp \
bionic/ioctl.cpp \
bionic/lchown.cpp \
@@ -644,7 +645,7 @@
libc_common_cflags += -DDEBUG
endif
-ifeq ($(MALLOC_IMPL),dlmalloc)
+ifeq ($(MALLOC_SVELTE),true)
libc_common_cflags += -DUSE_DLMALLOC
libc_malloc_src := bionic/dlmalloc.c
else
@@ -653,13 +654,6 @@
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
@@ -690,16 +684,21 @@
# libc_stack_protector.a - stack protector code
# ========================================================
#
-# The stack protector code needs to be compiled
-# with -fno-stack-protector, since it modifies the
-# stack canary.
+# 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.
include $(CLEAR_VARS)
-LOCAL_SRC_FILES := bionic/__stack_chk_fail.cpp
-# On x86, the __set_tls implementation is complex enough that
-# -fstack-protector-strong inserts a check.
+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_CFLAGS := $(libc_common_cflags) -fno-stack-protector
LOCAL_CONLYFLAGS := $(libc_common_conlyflags)
LOCAL_CPPFLAGS := $(libc_common_cppflags)
@@ -716,6 +715,30 @@
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
# ========================================================
@@ -1205,7 +1228,7 @@
LOCAL_WHOLE_STATIC_LIBRARIES_arm := libc_aeabi
LOCAL_CXX_STL := none
-ifneq ($(MALLOC_IMPL),dlmalloc)
+ifneq ($(MALLOC_SVELTE),true)
LOCAL_WHOLE_STATIC_LIBRARIES += libjemalloc
endif
@@ -1277,7 +1300,6 @@
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) \
@@ -1289,7 +1311,7 @@
LOCAL_MODULE := libc_nomalloc
LOCAL_CLANG := $(use_clang)
LOCAL_ADDITIONAL_DEPENDENCIES := $(libc_common_additional_dependencies)
-LOCAL_WHOLE_STATIC_LIBRARIES := libc_common
+LOCAL_WHOLE_STATIC_LIBRARIES := libc_common libc_init_static
LOCAL_CXX_STL := none
LOCAL_SYSTEM_SHARED_LIBRARIES :=
LOCAL_SANITIZE := never
@@ -1329,7 +1351,6 @@
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 \
@@ -1340,9 +1361,9 @@
LOCAL_MODULE := libc
LOCAL_CLANG := $(use_clang)
LOCAL_ADDITIONAL_DEPENDENCIES := $(libc_common_additional_dependencies)
-LOCAL_WHOLE_STATIC_LIBRARIES := libc_common
+LOCAL_WHOLE_STATIC_LIBRARIES := libc_common libc_init_static
-ifneq ($(MALLOC_IMPL),dlmalloc)
+ifneq ($(MALLOC_SVELTE),true)
LOCAL_WHOLE_STATIC_LIBRARIES += libjemalloc
endif
@@ -1408,7 +1429,7 @@
LOCAL_SHARED_LIBRARIES := libdl
LOCAL_WHOLE_STATIC_LIBRARIES := libc_common
-ifneq ($(MALLOC_IMPL),dlmalloc)
+ifneq ($(MALLOC_SVELTE),true)
LOCAL_WHOLE_STATIC_LIBRARIES += libjemalloc
endif
@@ -1608,6 +1629,3 @@
LOCAL_NATIVE_COVERAGE := $(bionic_coverage)
include $(BUILD_STATIC_LIBRARY)
-
-# ========================================================
-include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/libc/arch-arm/bionic/__aeabi.c b/libc/arch-arm/bionic/__aeabi.c
index 254c7a6..1620d45 100644
--- a/libc/arch-arm/bionic/__aeabi.c
+++ b/libc/arch-arm/bionic/__aeabi.c
@@ -51,34 +51,62 @@
*/
int __attribute__((weak))
-__aeabi_atexit(void *object, void (*destructor) (void *), void *dso_handle) {
+__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) {
return __cxa_atexit(destructor, object, dso_handle);
}
-void __attribute__((weak))
-__aeabi_memcpy8(void *dest, const void *src, size_t n) {
+void __attribute__((weak)) __aeabi_memcpy8_impl(void *dest, const void *src, size_t n) {
memcpy(dest, src, n);
}
-void __attribute__((weak)) __aeabi_memcpy4(void *dest, const void *src, size_t n) {
+void __attribute__((weak)) __aeabi_memcpy4_impl(void *dest, const void *src, size_t n) {
memcpy(dest, src, n);
}
-void __attribute__((weak)) __aeabi_memcpy(void *dest, const void *src, size_t 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) {
memcpy(dest, src, n);
}
-void __attribute__((weak)) __aeabi_memmove8(void *dest, const void *src, size_t n) {
+void __attribute__((weak)) __aeabi_memmove8_impl(void *dest, const void *src, size_t n) {
memmove(dest, src, n);
}
-void __attribute__((weak)) __aeabi_memmove4(void *dest, const void *src, size_t n) {
+void __attribute__((weak)) __aeabi_memmove4_impl(void *dest, const void *src, size_t n) {
memmove(dest, src, n);
}
-void __attribute__((weak)) __aeabi_memmove(void *dest, const void *src, size_t 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) {
memmove(dest, src, n);
}
@@ -87,27 +115,71 @@
* This allows __aeabi_memclr to tail-call __aeabi_memset
*/
-void __attribute__((weak)) __aeabi_memset8(void *dest, size_t n, int c) {
+void __attribute__((weak)) __aeabi_memset8_impl(void *dest, size_t n, int c) {
memset(dest, c, n);
}
-void __attribute__((weak)) __aeabi_memset4(void *dest, size_t n, int c) {
+void __attribute__((weak)) __aeabi_memset4_impl(void *dest, size_t n, int c) {
memset(dest, c, n);
}
-void __attribute__((weak)) __aeabi_memset(void *dest, size_t n, int c) {
+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) {
memset(dest, c, n);
}
-void __attribute__((weak)) __aeabi_memclr8(void *dest, size_t n) {
- __aeabi_memset8(dest, n, 0);
+void __attribute__((weak)) __aeabi_memclr8_impl(void *dest, size_t n) {
+ __aeabi_memset8_impl(dest, n, 0);
}
-void __attribute__((weak)) __aeabi_memclr4(void *dest, size_t n) {
- __aeabi_memset4(dest, n, 0);
+void __attribute__((weak)) __aeabi_memclr4_impl(void *dest, size_t n) {
+ __aeabi_memset4_impl(dest, n, 0);
}
-void __attribute__((weak)) __aeabi_memclr(void *dest, size_t n) {
- __aeabi_memset(dest, n, 0);
+void __attribute__((weak)) __aeabi_memclr_impl(void *dest, size_t n) {
+ __aeabi_memset_impl(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
diff --git a/libc/arch-arm/bionic/exidx_dynamic.c b/libc/arch-arm/bionic/exidx_dynamic.c
index c7b7156..60ac8af 100644
--- a/libc/arch-arm/bionic/exidx_dynamic.c
+++ b/libc/arch-arm/bionic/exidx_dynamic.c
@@ -37,7 +37,13 @@
* 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(_Unwind_Ptr pc, int *pcount)
-{
+_Unwind_Ptr __gnu_Unwind_Find_exidx_impl(_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");
diff --git a/libc/arch-arm64/arm64.mk b/libc/arch-arm64/arm64.mk
index 0811c96..9a76072 100644
--- a/libc/arch-arm64/arm64.mk
+++ b/libc/arch-arm64/arm64.mk
@@ -42,7 +42,6 @@
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 \
diff --git a/libc/arch-x86/atom/string/sse2-strrchr-atom.S b/libc/arch-x86/atom/string/sse2-strrchr-atom.S
index da3dc3b..e916bc1 100644
--- a/libc/arch-x86/atom/string/sse2-strrchr-atom.S
+++ b/libc/arch-x86/atom/string/sse2-strrchr-atom.S
@@ -278,7 +278,7 @@
jnz L(FindZeroExit2)
test $0x04, %cl
jnz L(FindZeroExit3)
- and $1 << 4 - 1, %eax
+ and $(1 << 4) - 1, %eax
jz L(return_value)
POP (%ebx)
@@ -296,7 +296,7 @@
jnz L(FindZeroExit6)
test $0x40, %cl
jnz L(FindZeroExit7)
- and $1 << 8 - 1, %eax
+ and $(1 << 8) - 1, %eax
jz L(return_value)
POP (%ebx)
@@ -317,7 +317,7 @@
jnz L(FindZeroExit10)
test $0x04, %ch
jnz L(FindZeroExit11)
- and $1 << 12 - 1, %eax
+ and $(1 << 12) - 1, %eax
jz L(return_value)
POP (%ebx)
@@ -335,7 +335,7 @@
jnz L(FindZeroExit14)
test $0x40, %ch
jnz L(FindZeroExit15)
- and $1 << 16 - 1, %eax
+ and $(1 << 16) - 1, %eax
jz L(return_value)
POP (%ebx)
@@ -359,7 +359,7 @@
.p2align 4
L(FindZeroExit2):
- and $1 << 2 - 1, %eax
+ and $(1 << 2) - 1, %eax
jz L(return_value)
POP (%ebx)
@@ -371,7 +371,7 @@
.p2align 4
L(FindZeroExit3):
- and $1 << 3 - 1, %eax
+ and $(1 << 3) - 1, %eax
jz L(return_value)
POP (%ebx)
@@ -383,7 +383,7 @@
.p2align 4
L(FindZeroExit5):
- and $1 << 5 - 1, %eax
+ and $(1 << 5) - 1, %eax
jz L(return_value)
POP (%ebx)
@@ -395,7 +395,7 @@
.p2align 4
L(FindZeroExit6):
- and $1 << 6 - 1, %eax
+ and $(1 << 6) - 1, %eax
jz L(return_value)
POP (%ebx)
@@ -407,7 +407,7 @@
.p2align 4
L(FindZeroExit7):
- and $1 << 7 - 1, %eax
+ and $(1 << 7) - 1, %eax
jz L(return_value)
POP (%ebx)
@@ -419,7 +419,7 @@
.p2align 4
L(FindZeroExit9):
- and $1 << 9 - 1, %eax
+ and $(1 << 9) - 1, %eax
jz L(return_value)
POP (%ebx)
@@ -431,7 +431,7 @@
.p2align 4
L(FindZeroExit10):
- and $1 << 10 - 1, %eax
+ and $(1 << 10) - 1, %eax
jz L(return_value)
POP (%ebx)
@@ -443,7 +443,7 @@
.p2align 4
L(FindZeroExit11):
- and $1 << 11 - 1, %eax
+ and $(1 << 11) - 1, %eax
jz L(return_value)
POP (%ebx)
@@ -455,7 +455,7 @@
.p2align 4
L(FindZeroExit13):
- and $1 << 13 - 1, %eax
+ and $(1 << 13) - 1, %eax
jz L(return_value)
POP (%ebx)
@@ -467,7 +467,7 @@
.p2align 4
L(FindZeroExit14):
- and $1 << 14 - 1, %eax
+ and $(1 << 14) - 1, %eax
jz L(return_value)
POP (%ebx)
@@ -479,7 +479,7 @@
.p2align 4
L(FindZeroExit15):
- and $1 << 15 - 1, %eax
+ and $(1 << 15) - 1, %eax
jz L(return_value)
POP (%ebx)
@@ -619,7 +619,7 @@
jnz L(PrologFindZeroExit2)
test $0x04, %cl
jnz L(PrologFindZeroExit3)
- and $1 << 4 - 1, %eax
+ and $(1 << 4) - 1, %eax
jnz L(match_case1)
xor %eax, %eax
RETURN
@@ -632,7 +632,7 @@
jnz L(PrologFindZeroExit6)
test $0x40, %cl
jnz L(PrologFindZeroExit7)
- and $1 << 8 - 1, %eax
+ and $(1 << 8) - 1, %eax
jnz L(match_case1)
xor %eax, %eax
RETURN
@@ -648,7 +648,7 @@
jnz L(PrologFindZeroExit10)
test $0x04, %ch
jnz L(PrologFindZeroExit11)
- and $1 << 12 - 1, %eax
+ and $(1 << 12) - 1, %eax
jnz L(match_case1)
xor %eax, %eax
RETURN
@@ -661,7 +661,7 @@
jnz L(PrologFindZeroExit14)
test $0x40, %ch
jnz L(PrologFindZeroExit15)
- and $1 << 16 - 1, %eax
+ and $(1 << 16) - 1, %eax
jnz L(match_case1)
xor %eax, %eax
RETURN
@@ -675,77 +675,77 @@
.p2align 4
L(PrologFindZeroExit2):
- and $1 << 2 - 1, %eax
+ and $(1 << 2) - 1, %eax
jnz L(match_case1)
xor %eax, %eax
RETURN
.p2align 4
L(PrologFindZeroExit3):
- and $1 << 3 - 1, %eax
+ and $(1 << 3) - 1, %eax
jnz L(match_case1)
xor %eax, %eax
RETURN
.p2align 4
L(PrologFindZeroExit5):
- and $1 << 5 - 1, %eax
+ and $(1 << 5) - 1, %eax
jnz L(match_case1)
xor %eax, %eax
RETURN
.p2align 4
L(PrologFindZeroExit6):
- and $1 << 6 - 1, %eax
+ and $(1 << 6) - 1, %eax
jnz L(match_case1)
xor %eax, %eax
RETURN
.p2align 4
L(PrologFindZeroExit7):
- and $1 << 7 - 1, %eax
+ and $(1 << 7) - 1, %eax
jnz L(match_case1)
xor %eax, %eax
RETURN
.p2align 4
L(PrologFindZeroExit9):
- and $1 << 9 - 1, %eax
+ and $(1 << 9) - 1, %eax
jnz L(match_case1)
xor %eax, %eax
RETURN
.p2align 4
L(PrologFindZeroExit10):
- and $1 << 10 - 1, %eax
+ and $(1 << 10) - 1, %eax
jnz L(match_case1)
xor %eax, %eax
RETURN
.p2align 4
L(PrologFindZeroExit11):
- and $1 << 11 - 1, %eax
+ and $(1 << 11) - 1, %eax
jnz L(match_case1)
xor %eax, %eax
RETURN
.p2align 4
L(PrologFindZeroExit13):
- and $1 << 13 - 1, %eax
+ and $(1 << 13) - 1, %eax
jnz L(match_case1)
xor %eax, %eax
RETURN
.p2align 4
L(PrologFindZeroExit14):
- and $1 << 14 - 1, %eax
+ and $(1 << 14) - 1, %eax
jnz L(match_case1)
xor %eax, %eax
RETURN
.p2align 4
L(PrologFindZeroExit15):
- and $1 << 15 - 1, %eax
+ and $(1 << 15) - 1, %eax
jnz L(match_case1)
xor %eax, %eax
RETURN
diff --git a/libc/arch-x86/atom/string/sse2-wcsrchr-atom.S b/libc/arch-x86/atom/string/sse2-wcsrchr-atom.S
index e30779d..1a55df2 100644
--- a/libc/arch-x86/atom/string/sse2-wcsrchr-atom.S
+++ b/libc/arch-x86/atom/string/sse2-wcsrchr-atom.S
@@ -280,7 +280,7 @@
.p2align 4
L(find_zero_in_second_wchar):
- and $1 << 5 - 1, %eax
+ and $(1 << 5) - 1, %eax
jz L(return_value)
POP (%esi)
@@ -296,7 +296,7 @@
L(find_zero_in_third_or_fourth_wchar):
test $15, %ch
jz L(find_zero_in_fourth_wchar)
- and $1 << 9 - 1, %eax
+ and $(1 << 9) - 1, %eax
jz L(return_value)
POP (%esi)
@@ -368,7 +368,7 @@
.p2align 4
L(prolog_find_zero_in_second_wchar):
- and $1 << 5 - 1, %eax
+ and $(1 << 5) - 1, %eax
jz L(return_null)
test $15 << 4, %al
@@ -380,7 +380,7 @@
L(prolog_find_zero_in_third_or_fourth_wchar):
test $15, %ch
jz L(prolog_find_zero_in_fourth_wchar)
- and $1 << 9 - 1, %eax
+ and $(1 << 9) - 1, %eax
jz L(return_null)
test %ah, %ah
diff --git a/libc/arch-x86_64/x86_64.mk b/libc/arch-x86_64/x86_64.mk
index bbf5c8c..ce06217 100644
--- a/libc/arch-x86_64/x86_64.mk
+++ b/libc/arch-x86_64/x86_64.mk
@@ -25,7 +25,6 @@
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 \
diff --git a/libc/bionic/__cxa_thread_atexit_impl.cpp b/libc/bionic/__cxa_thread_atexit_impl.cpp
index 0e903b9..6284b12 100644
--- a/libc/bionic/__cxa_thread_atexit_impl.cpp
+++ b/libc/bionic/__cxa_thread_atexit_impl.cpp
@@ -17,7 +17,8 @@
#include "pthread_internal.h"
-struct thread_local_dtor {
+class thread_local_dtor {
+ public:
void (*func) (void *);
void *arg;
void *dso_handle; // unused...
diff --git a/libc/bionic/__libc_init_main_thread.cpp b/libc/bionic/__libc_init_main_thread.cpp
new file mode 100644
index 0000000..e1445cb
--- /dev/null
+++ b/libc/bionic/__libc_init_main_thread.cpp
@@ -0,0 +1,85 @@
+/*
+ * 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);
+}
diff --git a/libc/bionic/ifaddrs.cpp b/libc/bionic/ifaddrs.cpp
new file mode 100644
index 0000000..b66883e
--- /dev/null
+++ b/libc/bionic/ifaddrs.cpp
@@ -0,0 +1,262 @@
+/*
+ * 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/if_packet.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);
+ }
+
+ void SetPacketAttributes(int ifindex, unsigned short hatype, unsigned char halen) {
+ sockaddr_ll* sll = reinterpret_cast<sockaddr_ll*>(&addr);
+ sll->sll_ifindex = ifindex;
+ sll->sll_hatype = hatype;
+ sll->sll_halen = halen;
+ }
+
+ 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);
+ } else if (family == AF_PACKET) {
+ sockaddr_ll* sll = reinterpret_cast<sockaddr_ll*>(ss);
+ return reinterpret_cast<uint8_t*>(&sll->sll_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_ADDRESS) {
+ if (RTA_PAYLOAD(rta) < sizeof(new_addr->addr)) {
+ new_addr->SetAddress(AF_PACKET, RTA_DATA(rta), RTA_PAYLOAD(rta));
+ new_addr->SetPacketAttributes(ifi->ifi_index, ifi->ifi_type, RTA_PAYLOAD(rta));
+ }
+ } else if (rta->rta_type == IFLA_BROADCAST) {
+ if (RTA_PAYLOAD(rta) < sizeof(new_addr->ifa_ifu)) {
+ new_addr->SetBroadcastAddress(AF_PACKET, RTA_DATA(rta), RTA_PAYLOAD(rta));
+ new_addr->SetPacketAttributes(ifi->ifi_index, ifi->ifi_type, RTA_PAYLOAD(rta));
+ }
+ } else 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.
+ const ifaddrs_storage* addr = reinterpret_cast<const ifaddrs_storage*>(*out);
+ while (addr != nullptr && addr->interface_index != static_cast<int>(msg->ifa_index)) {
+ addr = reinterpret_cast<const 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) {
+ new_addr->SetAddress(msg->ifa_family, RTA_DATA(rta), RTA_PAYLOAD(rta));
+ new_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) {
+ new_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);
+ }
+}
diff --git a/libc/bionic/libc_init_common.cpp b/libc/bionic/libc_init_common.cpp
index b0c62d6..532dab9 100644
--- a/libc/bionic/libc_init_common.cpp
+++ b/libc/bionic/libc_init_common.cpp
@@ -52,8 +52,6 @@
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;
@@ -66,49 +64,6 @@
// 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;
-
- // The x86 -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);
-}
-
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
@@ -336,7 +291,7 @@
if (getauxval(AT_SECURE)) {
// If this is a setuid/setgid program, close the security hole described in
- // ftp://ftp.freebsd.org/pub/FreeBSD/CERT/advisories/FreeBSD-SA-02:23.stdio.asc
+ // https://www.freebsd.org/security/advisories/FreeBSD-SA-02:23.stdio.asc
__nullify_closed_stdio();
__sanitize_environment_variables(args.envp);
diff --git a/libc/bionic/libc_init_dynamic.cpp b/libc/bionic/libc_init_dynamic.cpp
index edf6a44..97d9e39 100644
--- a/libc/bionic/libc_init_dynamic.cpp
+++ b/libc/bionic/libc_init_dynamic.cpp
@@ -25,6 +25,7 @@
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
+
/*
* libc_init_dynamic.c
*
diff --git a/libc/bionic/libc_init_static.cpp b/libc/bionic/libc_init_static.cpp
index 2fe86d0..3cda1a2 100644
--- a/libc/bionic/libc_init_static.cpp
+++ b/libc/bionic/libc_init_static.cpp
@@ -25,17 +25,6 @@
* 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>
@@ -79,12 +68,19 @@
}
}
+// 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.
diff --git a/libc/bionic/ndk_cruft.cpp b/libc/bionic/ndk_cruft.cpp
index 4bbb2c1..dfd0e68 100644
--- a/libc/bionic/ndk_cruft.cpp
+++ b/libc/bionic/ndk_cruft.cpp
@@ -340,10 +340,17 @@
}
// In L we added a public pthread_gettid_np, but some apps were using the private API.
-pid_t __pthread_gettid(pthread_t t) {
+pid_t __pthread_gettid_libc(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) {
diff --git a/libc/bionic/pthread_internal.h b/libc/bionic/pthread_internal.h
index f96e9d2..e8be4ae 100644
--- a/libc/bionic/pthread_internal.h
+++ b/libc/bionic/pthread_internal.h
@@ -40,7 +40,8 @@
/* Has the thread been joined by another thread? */
#define PTHREAD_ATTR_FLAG_JOINED 0x00000002
-struct pthread_key_data_t {
+class pthread_key_data_t {
+ public:
uintptr_t seq; // Use uintptr_t just for alignment, as we use pointer below.
void* data;
};
@@ -52,11 +53,12 @@
THREAD_DETACHED
};
-struct thread_local_dtor;
+class thread_local_dtor;
-struct pthread_internal_t {
- struct pthread_internal_t* next;
- struct pthread_internal_t* prev;
+class pthread_internal_t {
+ public:
+ class pthread_internal_t* next;
+ class pthread_internal_t* prev;
pid_t tid;
diff --git a/libc/private/bionic_time.h b/libc/include/ifaddrs.h
similarity index 70%
rename from libc/private/bionic_time.h
rename to libc/include/ifaddrs.h
index 030dcfd..54a5a2c 100644
--- a/libc/private/bionic_time.h
+++ b/libc/include/ifaddrs.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 The Android Open Source Project
+ * Copyright (C) 2015 The Android Open Source Project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -25,17 +25,35 @@
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
-#ifndef _BIONIC_TIME_H
-#define _BIONIC_TIME_H
-#include <time.h>
+#ifndef _IFADDRS_H_
+#define _IFADDRS_H_
+
#include <sys/cdefs.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
__BEGIN_DECLS
-// We can't remove this (and this file) until we fix MtpUtils.cpp.
-time_t mktime_tz(struct tm* const, char const*);
+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**);
__END_DECLS
-#endif /* _BIONIC_TIME_H */
+#endif
diff --git a/libc/include/sys/sysmacros.h b/libc/include/sys/sysmacros.h
index 6f053a8..54e43dd 100644
--- a/libc/include/sys/sysmacros.h
+++ b/libc/include/sys/sysmacros.h
@@ -25,28 +25,20 @@
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
+
#ifndef _SYS_SYSMACROS_H_
#define _SYS_SYSMACROS_H_
-/* some rogue code includes this file directly :-( */
-#ifndef _SYS_TYPES_H_
-# include <sys/types.h>
-#endif
+#define makedev(__major, __minor) \
+ ( \
+ (((__major) & 0xfffff000ULL) << 32) | (((__major) & 0xfffULL) << 8) | \
+ (((__minor) & 0xffffff00ULL) << 12) | (((__minor) & 0xffULL)) \
+ )
-static __inline__ int major(dev_t _dev)
-{
- return (_dev >> 8) & 0xfff;
-}
+#define major(__dev) \
+ ((unsigned) ((((unsigned long long) (__dev) >> 32) & 0xfffff000) | (((__dev) >> 8) & 0xfff)))
-static __inline__ int minor(dev_t _dev)
-{
- return (_dev & 0xff) | ((_dev >> 12) & 0xfff00);
-}
-
-static __inline__ dev_t makedev(int __ma, int __mi)
-{
- return ((__ma & 0xfff) << 8) | (__mi & 0xff) | ((__mi & 0xfff00) << 12);
-}
+#define minor(__dev) \
+ ((unsigned) ((((__dev) >> 12) & 0xffffff00) | ((__dev) & 0xff)))
#endif /* _SYS_SYSMACROS_H_ */
-
diff --git a/libc/include/sys/types.h b/libc/include/sys/types.h
index a6b0fd8..217fd60 100644
--- a/libc/include/sys/types.h
+++ b/libc/include/sys/types.h
@@ -139,19 +139,18 @@
typedef unsigned int uint_t;
typedef unsigned int uint;
-/* for some applications */
+#ifdef __BSD_VISIBLE
#include <sys/sysmacros.h>
-#ifdef __BSD_VISIBLE
-typedef unsigned char u_char;
-typedef unsigned short u_short;
-typedef unsigned int u_int;
-typedef unsigned long u_long;
+typedef unsigned char u_char;
+typedef unsigned short u_short;
+typedef unsigned int u_int;
+typedef unsigned long u_long;
-typedef uint32_t u_int32_t;
-typedef uint16_t u_int16_t;
-typedef uint8_t u_int8_t;
-typedef uint64_t u_int64_t;
+typedef uint32_t u_int32_t;
+typedef uint16_t u_int16_t;
+typedef uint8_t u_int8_t;
+typedef uint64_t u_int64_t;
#endif
#endif
diff --git a/libc/libc.arm.brillo.map b/libc/libc.arm.brillo.map
index 8cbff2b..c51b7e1 100644
--- a/libc/libc.arm.brillo.map
+++ b/libc/libc.arm.brillo.map
@@ -260,7 +260,6 @@
brk;
bsearch;
btowc;
- bzero; # arm x86 mips
c16rtomb;
c32rtomb;
cacheflush; # arm mips
@@ -675,7 +674,6 @@
mktemp;
mktime;
mktime64; # arm x86 mips
- mktime_tz;
mlock;
mlockall;
mmap;
@@ -1213,15 +1211,31 @@
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
@@ -1388,7 +1402,7 @@
__swrite; # arm x86 mips
__swsetup; # arm x86 mips
__truncdfsf2; # arm
- __udivdi3; # arm x86 mips
+ __udivdi3; # arm mips
__udivsi3; # arm
__unorddf2; # arm
__unordsf2; # arm
diff --git a/libc/libc.arm.map b/libc/libc.arm.map
index bb42c0f..6297fd1 100644
--- a/libc/libc.arm.map
+++ b/libc/libc.arm.map
@@ -122,6 +122,7 @@
__pselect6; # arm x86 mips
__pthread_cleanup_pop;
__pthread_cleanup_push;
+ __pthread_gettid; # arm x86 mips nobrillo
__ptrace; # arm x86 mips
__putlong;
__putshort;
@@ -260,7 +261,6 @@
brk;
bsearch;
btowc;
- bzero; # arm x86 mips
c16rtomb;
c32rtomb;
cacheflush; # arm mips
@@ -675,7 +675,6 @@
mktemp;
mktime;
mktime64; # arm x86 mips
- mktime_tz;
mlock;
mlockall;
mmap;
@@ -1213,15 +1212,31 @@
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
@@ -1399,7 +1414,7 @@
__swrite; # arm x86 mips
__swsetup; # arm x86 mips
__truncdfsf2; # arm
- __udivdi3; # arm x86 mips
+ __udivdi3; # arm mips
__udivsi3; # arm
__unorddf2; # arm
__unordsf2; # arm
@@ -1424,6 +1439,7 @@
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
diff --git a/libc/libc.arm64.map b/libc/libc.arm64.map
index e54bef6..fea1759 100644
--- a/libc/libc.arm64.map
+++ b/libc/libc.arm64.map
@@ -596,7 +596,6 @@
mkstemps64;
mktemp;
mktime;
- mktime_tz;
mlock;
mlockall;
mmap;
@@ -1154,8 +1153,10 @@
__pwrite64_chk;
__write_chk;
fileno_unlocked;
+ freeifaddrs;
getgrgid_r;
getgrnam_r;
+ getifaddrs;
preadv;
preadv64;
pthread_barrierattr_destroy;
diff --git a/libc/libc.map.txt b/libc/libc.map.txt
index c80c19f..258ff48 100644
--- a/libc/libc.map.txt
+++ b/libc/libc.map.txt
@@ -123,6 +123,7 @@
__pselect6; # arm x86 mips
__pthread_cleanup_pop;
__pthread_cleanup_push;
+ __pthread_gettid; # arm x86 mips nobrillo
__ptrace; # arm x86 mips
__putlong;
__putshort;
@@ -209,6 +210,7 @@
__timer_getoverrun; # arm x86 mips
__timer_gettime; # arm x86 mips
__timer_settime; # arm x86 mips
+ __udivdi3; # x86
__umask_chk;
__vsnprintf_chk;
__vsprintf_chk;
@@ -263,7 +265,6 @@
brk;
bsearch;
btowc;
- bzero; # arm x86 mips
c16rtomb;
c32rtomb;
cacheflush; # arm mips
@@ -678,7 +679,6 @@
mktemp;
mktime;
mktime64; # arm x86 mips
- mktime_tz;
mlock;
mlockall;
mmap;
@@ -1239,15 +1239,31 @@
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
@@ -1425,7 +1441,7 @@
__swrite; # arm x86 mips
__swsetup; # arm x86 mips
__truncdfsf2; # arm
- __udivdi3; # arm x86 mips
+ __udivdi3; # arm mips
__udivsi3; # arm
__umoddi3; # x86 mips
__unorddf2; # arm
@@ -1451,6 +1467,7 @@
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
diff --git a/libc/libc.mips.brillo.map b/libc/libc.mips.brillo.map
index 709ffd9..67e1c05 100644
--- a/libc/libc.mips.brillo.map
+++ b/libc/libc.mips.brillo.map
@@ -259,7 +259,6 @@
brk;
bsearch;
btowc;
- bzero; # arm x86 mips
c16rtomb;
c32rtomb;
cacheflush; # arm mips
@@ -674,7 +673,6 @@
mktemp;
mktime;
mktime64; # arm x86 mips
- mktime_tz;
mlock;
mlockall;
mmap;
@@ -1219,8 +1217,10 @@
__pwrite64_chk;
__write_chk;
fileno_unlocked;
+ freeifaddrs;
getgrgid_r;
getgrnam_r;
+ getifaddrs;
preadv;
preadv64;
prlimit; # arm mips x86
@@ -1263,7 +1263,7 @@
__swbuf; # arm x86 mips
__swrite; # arm x86 mips
__swsetup; # arm x86 mips
- __udivdi3; # arm x86 mips
+ __udivdi3; # arm mips
__umoddi3; # x86 mips
_fwalk; # arm x86 mips
free_malloc_leak_info;
diff --git a/libc/libc.mips.map b/libc/libc.mips.map
index cb068ef..b82ef0f 100644
--- a/libc/libc.mips.map
+++ b/libc/libc.mips.map
@@ -120,6 +120,7 @@
__pselect6; # arm x86 mips
__pthread_cleanup_pop;
__pthread_cleanup_push;
+ __pthread_gettid; # arm x86 mips nobrillo
__ptrace; # arm x86 mips
__putlong;
__putshort;
@@ -259,7 +260,6 @@
brk;
bsearch;
btowc;
- bzero; # arm x86 mips
c16rtomb;
c32rtomb;
cacheflush; # arm mips
@@ -674,7 +674,6 @@
mktemp;
mktime;
mktime64; # arm x86 mips
- mktime_tz;
mlock;
mlockall;
mmap;
@@ -1219,8 +1218,10 @@
__pwrite64_chk;
__write_chk;
fileno_unlocked;
+ freeifaddrs;
getgrgid_r;
getgrnam_r;
+ getifaddrs;
preadv;
preadv64;
prlimit; # arm mips x86
@@ -1274,13 +1275,14 @@
__swbuf; # arm x86 mips
__swrite; # arm x86 mips
__swsetup; # arm x86 mips
- __udivdi3; # 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
diff --git a/libc/libc.mips64.map b/libc/libc.mips64.map
index e54bef6..fea1759 100644
--- a/libc/libc.mips64.map
+++ b/libc/libc.mips64.map
@@ -596,7 +596,6 @@
mkstemps64;
mktemp;
mktime;
- mktime_tz;
mlock;
mlockall;
mmap;
@@ -1154,8 +1153,10 @@
__pwrite64_chk;
__write_chk;
fileno_unlocked;
+ freeifaddrs;
getgrgid_r;
getgrnam_r;
+ getifaddrs;
preadv;
preadv64;
pthread_barrierattr_destroy;
diff --git a/libc/libc.x86.brillo.map b/libc/libc.x86.brillo.map
index 82df4a4..71390b7 100644
--- a/libc/libc.x86.brillo.map
+++ b/libc/libc.x86.brillo.map
@@ -205,6 +205,7 @@
__timer_getoverrun; # arm x86 mips
__timer_gettime; # arm x86 mips
__timer_settime; # arm x86 mips
+ __udivdi3; # x86
__umask_chk;
__vsnprintf_chk;
__vsprintf_chk;
@@ -258,7 +259,6 @@
brk;
bsearch;
btowc;
- bzero; # arm x86 mips
c16rtomb;
c32rtomb;
calloc;
@@ -672,7 +672,6 @@
mktemp;
mktime;
mktime64; # arm x86 mips
- mktime_tz;
mlock;
mlockall;
mmap;
@@ -1217,8 +1216,10 @@
__pwrite64_chk;
__write_chk;
fileno_unlocked;
+ freeifaddrs;
getgrgid_r;
getgrnam_r;
+ getifaddrs;
preadv;
preadv64;
prlimit; # arm mips x86
@@ -1262,7 +1263,6 @@
__swbuf; # arm x86 mips
__swrite; # arm x86 mips
__swsetup; # arm x86 mips
- __udivdi3; # arm x86 mips
__umoddi3; # x86 mips
_fwalk; # arm x86 mips
free_malloc_leak_info;
diff --git a/libc/libc.x86.map b/libc/libc.x86.map
index 94e4b80..6905ff8 100644
--- a/libc/libc.x86.map
+++ b/libc/libc.x86.map
@@ -120,6 +120,7 @@
__pselect6; # arm x86 mips
__pthread_cleanup_pop;
__pthread_cleanup_push;
+ __pthread_gettid; # arm x86 mips nobrillo
__ptrace; # arm x86 mips
__putlong;
__putshort;
@@ -205,6 +206,7 @@
__timer_getoverrun; # arm x86 mips
__timer_gettime; # arm x86 mips
__timer_settime; # arm x86 mips
+ __udivdi3; # x86
__umask_chk;
__vsnprintf_chk;
__vsprintf_chk;
@@ -258,7 +260,6 @@
brk;
bsearch;
btowc;
- bzero; # arm x86 mips
c16rtomb;
c32rtomb;
calloc;
@@ -672,7 +673,6 @@
mktemp;
mktime;
mktime64; # arm x86 mips
- mktime_tz;
mlock;
mlockall;
mmap;
@@ -1217,8 +1217,10 @@
__pwrite64_chk;
__write_chk;
fileno_unlocked;
+ freeifaddrs;
getgrgid_r;
getgrnam_r;
+ getifaddrs;
preadv;
preadv64;
prlimit; # arm mips x86
@@ -1273,13 +1275,13 @@
__swbuf; # arm x86 mips
__swrite; # arm x86 mips
__swsetup; # arm x86 mips
- __udivdi3; # 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
diff --git a/libc/libc.x86_64.map b/libc/libc.x86_64.map
index e54bef6..fea1759 100644
--- a/libc/libc.x86_64.map
+++ b/libc/libc.x86_64.map
@@ -596,7 +596,6 @@
mkstemps64;
mktemp;
mktime;
- mktime_tz;
mlock;
mlockall;
mmap;
@@ -1154,8 +1153,10 @@
__pwrite64_chk;
__write_chk;
fileno_unlocked;
+ freeifaddrs;
getgrgid_r;
getgrnam_r;
+ getifaddrs;
preadv;
preadv64;
pthread_barrierattr_destroy;
diff --git a/libc/private/KernelArgumentBlock.h b/libc/private/KernelArgumentBlock.h
index c8ea497..68d4999 100644
--- a/libc/private/KernelArgumentBlock.h
+++ b/libc/private/KernelArgumentBlock.h
@@ -38,32 +38,25 @@
argv = reinterpret_cast<char**>(args + 1);
envp = argv + argc + 1;
- // Skip over all environment variable definitions to find aux vector.
- // The end of the environment block is marked by two NULL pointers.
+ // Skip over all environment variable definitions to find the aux vector.
+ // The end of the environment block is marked by a NULL pointer.
char** p = envp;
while (*p != NULL) {
++p;
}
- ++p; // Skip second NULL;
+ ++p; // Skip the NULL itself.
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. 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) {
+ // so it's safe to call this really early on.
+ unsigned long getauxval(unsigned long type) {
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;
}
diff --git a/libc/private/bionic_tls.h b/libc/private/bionic_tls.h
index 2ca7728..9d3f4c5 100644
--- a/libc/private/bionic_tls.h
+++ b/libc/private/bionic_tls.h
@@ -121,7 +121,7 @@
#if defined(__cplusplus)
class KernelArgumentBlock;
-extern __LIBC_HIDDEN__ void __libc_init_main_thread(KernelArgumentBlock& args);
+extern __LIBC_HIDDEN__ void __libc_init_main_thread(KernelArgumentBlock&);
#endif
#endif /* __BIONIC_PRIVATE_BIONIC_TLS_H_ */
diff --git a/libc/tzcode/localtime.c b/libc/tzcode/localtime.c
index b1ebb24..f370e87 100644
--- a/libc/tzcode/localtime.c
+++ b/libc/tzcode/localtime.c
@@ -2462,50 +2462,4 @@
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
diff --git a/linker/linker.cpp b/linker/linker.cpp
index eb938c7..70c2ca5 100644
--- a/linker/linker.cpp
+++ b/linker/linker.cpp
@@ -3267,7 +3267,7 @@
/* We can't log anything until the linker is relocated */
bool relocating_linker = (flags_ & FLAG_LINKER) != 0;
if (!relocating_linker) {
- INFO("[ linking %s ]", get_realpath());
+ INFO("[ Linking '%s' ]", get_realpath());
DEBUG("si->base = %p si->flags = 0x%08x", reinterpret_cast<void*>(base), flags_);
}
@@ -3954,17 +3954,27 @@
g_ld_debug_verbosity = atoi(LD_DEBUG);
}
+#if defined(__LP64__)
+ INFO("[ Android dynamic linker (64-bit) ]");
+#else
+ INFO("[ Android dynamic linker (32-bit) ]");
+#endif
+
// These should have been sanitized by __libc_init_AT_SECURE, but the test
// doesn't cost us anything.
const char* ldpath_env = nullptr;
const char* ldpreload_env = nullptr;
if (!getauxval(AT_SECURE)) {
ldpath_env = getenv("LD_LIBRARY_PATH");
+ if (ldpath_env != nullptr) {
+ INFO("[ LD_LIBRARY_PATH set to '%s' ]", ldpath_env);
+ }
ldpreload_env = getenv("LD_PRELOAD");
+ if (ldpreload_env != nullptr) {
+ INFO("[ LD_PRELOAD set to '%s' ]", ldpreload_env);
+ }
}
- INFO("[ android linker & debugger ]");
-
soinfo* si = soinfo_alloc(&g_default_namespace, args.argv[0], nullptr, 0, RTLD_GLOBAL);
if (si == nullptr) {
exit(EXIT_FAILURE);
@@ -4144,6 +4154,7 @@
return 0;
}
+extern "C" int __set_tls(void*);
extern "C" void _start();
/*
@@ -4158,6 +4169,9 @@
extern "C" ElfW(Addr) __linker_init(void* raw_args) {
KernelArgumentBlock args(raw_args);
+ void* tls[BIONIC_TLS_SLOTS];
+ __set_tls(tls);
+
ElfW(Addr) linker_addr = args.getauxval(AT_BASE);
ElfW(Addr) entry_point = args.getauxval(AT_ENTRY);
ElfW(Ehdr)* elf_hdr = reinterpret_cast<ElfW(Ehdr)*>(linker_addr);
@@ -4213,7 +4227,7 @@
args.abort_message_ptr = &g_abort_message;
ElfW(Addr) start_address = __linker_init_post_relocation(args, linker_addr);
- INFO("[ jumping to _start ]");
+ INFO("[ Jumping to _start (%p)... ]", reinterpret_cast<void*>(start_address));
// Return the address that the calling assembly stub should jump to.
return start_address;
diff --git a/tests/Android.mk b/tests/Android.mk
index 520892b..3a0d6ee 100644
--- a/tests/Android.mk
+++ b/tests/Android.mk
@@ -40,7 +40,7 @@
test_cflags += -D__STDC_LIMIT_MACROS # For glibc.
-ifeq ($(MALLOC_IMPL),dlmalloc)
+ifeq ($(MALLOC_SVELTE),true)
test_cflags += -DUSE_DLMALLOC
else
test_cflags += -DUSE_JEMALLOC
@@ -62,6 +62,7 @@
ftw_test.cpp \
getauxval_test.cpp \
getcwd_test.cpp \
+ ifaddrs_test.cpp \
inttypes_test.cpp \
libc_logging_test.cpp \
libgen_basename_test.cpp \
@@ -70,6 +71,7 @@
malloc_test.cpp \
math_test.cpp \
mntent_test.cpp \
+ net_if_test.cpp \
netdb_test.cpp \
netinet_udp_test.cpp \
pthread_test.cpp \
@@ -105,6 +107,7 @@
sys_statvfs_test.cpp \
sys_syscall_test.cpp \
sys_sysinfo_test.cpp \
+ sys_sysmacros_test.cpp \
sys_time_test.cpp \
sys_types_test.cpp \
sys_uio_test.cpp \
@@ -121,7 +124,7 @@
libBionicStandardTests_cflags := \
$(test_cflags) \
-ifeq ($(MALLOC_IMPL),dlmalloc)
+ifeq ($(MALLOC_SVELTE),true)
libBionicStandardTests_cflags += -DUSE_DLMALLOC
else
libBionicStandardTests_cflags += -DUSE_JEMALLOC
diff --git a/tests/ifaddrs_test.cpp b/tests/ifaddrs_test.cpp
new file mode 100644
index 0000000..8159710
--- /dev/null
+++ b/tests/ifaddrs_test.cpp
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <gtest/gtest.h>
+
+#include <ifaddrs.h>
+
+#include <linux/if_packet.h>
+#include <net/ethernet.h>
+#include <net/if.h>
+#include <netdb.h>
+#include <netinet/in.h>
+
+TEST(ifaddrs, freeifaddrs_null) {
+ freeifaddrs(nullptr);
+}
+
+TEST(ifaddrs, getifaddrs_smoke) {
+ ifaddrs* addrs = nullptr;
+
+ ASSERT_EQ(0, getifaddrs(&addrs));
+ ASSERT_TRUE(addrs != nullptr);
+
+ // We can't say much about what network interfaces are available, but we can be pretty
+ // sure there's a loopback interface, and that it has IPv4, IPv6, and AF_PACKET entries.
+ ifaddrs* lo_inet4 = nullptr;
+ ifaddrs* lo_inet6 = nullptr;
+ ifaddrs* lo_packet = nullptr;
+ for (ifaddrs* addr = addrs; addr != nullptr; addr = addr->ifa_next) {
+ if (addr->ifa_name && strcmp(addr->ifa_name, "lo") == 0) {
+ if (addr->ifa_addr && addr->ifa_addr->sa_family == AF_INET) lo_inet4 = addr;
+ else if (addr->ifa_addr && addr->ifa_addr->sa_family == AF_INET6) lo_inet6 = addr;
+ else if (addr->ifa_addr && addr->ifa_addr->sa_family == AF_PACKET) lo_packet = addr;
+ }
+ }
+
+ // Does the IPv4 entry look right?
+ ASSERT_TRUE(lo_inet4 != nullptr);
+ const sockaddr_in* sa_inet4 = reinterpret_cast<const sockaddr_in*>(lo_inet4->ifa_addr);
+ ASSERT_TRUE(ntohl(sa_inet4->sin_addr.s_addr) == INADDR_LOOPBACK);
+
+ // Does the IPv6 entry look right?
+ ASSERT_TRUE(lo_inet6 != nullptr);
+ const sockaddr_in6* sa_inet6 = reinterpret_cast<const sockaddr_in6*>(lo_inet6->ifa_addr);
+ ASSERT_TRUE(IN6_IS_ADDR_LOOPBACK(&sa_inet6->sin6_addr));
+
+ // Does the AF_PACKET entry look right?
+ ASSERT_TRUE(lo_packet != nullptr);
+ const sockaddr_ll* sa_ll = reinterpret_cast<const sockaddr_ll*>(lo_packet->ifa_addr);
+ ASSERT_EQ(6, sa_ll->sll_halen);
+
+ freeifaddrs(addrs);
+}
+
+static void print_sockaddr_ll(const char* what, const sockaddr* p) {
+ const sockaddr_ll* s = reinterpret_cast<const sockaddr_ll*>(p);
+ printf("\t%s\t", what);
+ for (int i = 0; i < s->sll_halen; ++i) {
+ if (i > 0) printf(":");
+ printf("%02X", s->sll_addr[i]);
+ }
+ printf(" (%d bytes)\n", s->sll_halen);
+}
+
+static void print_sockaddr_inet(const char* what, const sockaddr* addr) {
+ char host[NI_MAXHOST];
+ int family = addr->sa_family;
+ int error = getnameinfo(addr,
+ (family == AF_INET) ? sizeof(sockaddr_in) : sizeof(sockaddr_in6),
+ host, NI_MAXHOST, nullptr, 0, NI_NUMERICHOST);
+ if (error != 0) {
+ printf("%d getnameinfo() failed: %s\n", family, gai_strerror(error));
+ strcpy(host, "???");
+ }
+ printf("\t%s: <%s>\n", what, host);
+}
+
+static const char* family_to_name(int family) {
+ if (family == AF_INET) return "AF_INET";
+ if (family == AF_INET6) return "AF_INET6";
+ if (family == AF_PACKET) return "AF_PACKET";
+ if (family == AF_UNSPEC) return "AF_UNSPEC";
+ return "?";
+}
+
+// Not really a test, but a useful debugging tool.
+TEST(ifaddrs, dump) {
+ ifaddrs* addrs;
+ ASSERT_EQ(0, getifaddrs(&addrs));
+
+ for (ifaddrs* ifa = addrs; ifa != nullptr; ifa = ifa->ifa_next) {
+ int family = ifa->ifa_addr ? ifa->ifa_addr->sa_family :
+ ifa->ifa_broadaddr ? ifa->ifa_broadaddr->sa_family : AF_UNSPEC;
+
+ printf("%s\n\t%s (%d) flags=%#x\n",
+ ifa->ifa_name, family_to_name(family), family, ifa->ifa_flags);
+
+ if (family == AF_PACKET) {
+ if (ifa->ifa_addr) print_sockaddr_ll("hwaddr", ifa->ifa_addr);
+ if (ifa->ifa_broadaddr) print_sockaddr_ll("hwbroad", ifa->ifa_addr);
+ } else if (family == AF_INET || family == AF_INET6) {
+ if (ifa->ifa_addr) print_sockaddr_inet("address", ifa->ifa_addr);
+ if (ifa->ifa_broadaddr && (ifa->ifa_flags & (IFF_BROADCAST | IFF_POINTOPOINT)) != 0) {
+ print_sockaddr_inet((ifa->ifa_flags & IFF_BROADCAST) ? "broadcast" : "destination",
+ ifa->ifa_broadaddr);
+ }
+ }
+
+ fflush(stdout);
+ }
+
+ freeifaddrs(addrs);
+}
diff --git a/tests/net_if_test.cpp b/tests/net_if_test.cpp
new file mode 100644
index 0000000..9f38411
--- /dev/null
+++ b/tests/net_if_test.cpp
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <net/if.h>
+
+#include <errno.h>
+
+#include <gtest/gtest.h>
+
+TEST(net_if, if_nametoindex_if_indextoname) {
+ unsigned index;
+ index = if_nametoindex("lo");
+ ASSERT_NE(index, 0U);
+
+ char buf[IF_NAMESIZE] = {};
+ char* name = if_indextoname(index, buf);
+ ASSERT_STREQ("lo", name);
+}
+
+TEST(net_if, if_nametoindex_fail) {
+ unsigned index = if_nametoindex("this-interface-does-not-exist");
+ ASSERT_EQ(0U, index);
+}
diff --git a/tests/sys_sysmacros_test.cpp b/tests/sys_sysmacros_test.cpp
new file mode 100644
index 0000000..f17fac5
--- /dev/null
+++ b/tests/sys_sysmacros_test.cpp
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <sys/sysmacros.h>
+
+#include <gtest/gtest.h>
+
+TEST(sys_sysmacros, makedev) {
+ ASSERT_EQ(0x12345aabbcc678ddULL, makedev(0x12345678, 0xaabbccdd));
+}
+
+TEST(sys_sysmacros, major) {
+ ASSERT_EQ(0x12345678UL, major(0x12345aabbcc678dd));
+}
+
+TEST(sys_sysmacros, minor) {
+ ASSERT_EQ(0xaabbccddUL, minor(0x12345aabbcc678dd));
+}