summaryrefslogtreecommitdiffstats
path: root/libc
diff options
context:
space:
mode:
Diffstat (limited to 'libc')
-rw-r--r--libc/Android.mk218
-rw-r--r--libc/bionic/eabi.c8
-rw-r--r--libc/docs/ISSUES.TXT20
-rw-r--r--libc/include/sys/stat.h7
-rw-r--r--libc/kernel/common/linux/if_pppolac.h29
-rw-r--r--libc/kernel/common/linux/if_pppopns.h28
-rw-r--r--libc/kernel/common/linux/ipsec.h56
-rwxr-xr-xlibc/kernel/tools/update_all.py4
-rw-r--r--libc/netbsd/net/getservent.c9
-rw-r--r--libc/stdlib/atexit.c9
10 files changed, 273 insertions, 115 deletions
diff --git a/libc/Android.mk b/libc/Android.mk
index c0773cc..457e7dd 100644
--- a/libc/Android.mk
+++ b/libc/Android.mk
@@ -1,6 +1,9 @@
LOCAL_PATH:= $(call my-dir)
include $(LOCAL_PATH)/arch-$(TARGET_ARCH)/syscalls.mk
+
+# Define the common source files for all the libc instances
+# =========================================================
libc_common_src_files := \
$(syscall_src) \
unistd/abort.c \
@@ -272,6 +275,8 @@ libc_common_src_files := \
netbsd/nameser/ns_print.c \
netbsd/nameser/ns_samedomain.c
+# Architecture specific source files go here
+# =========================================================
ifeq ($(TARGET_ARCH),arm)
libc_common_src_files += \
bionic/eabi.c \
@@ -302,6 +307,14 @@ libc_common_src_files += \
bionic/pthread.c.arm \
bionic/pthread-timers.c.arm \
bionic/ptrace.c.arm
+
+# these are used by the static and dynamic versions of the libc
+# respectively
+libc_arch_static_src_files := \
+ arch-arm/bionic/exidx_static.c
+
+libc_arch_dynamic_src_files := \
+ arch-arm/bionic/exidx_dynamic.c
else # !arm
ifeq ($(TARGET_ARCH),x86)
@@ -323,10 +336,17 @@ libc_common_src_files += \
bionic/pthread.c \
bionic/pthread-timers.c \
bionic/ptrace.c
-endif # x86
+# this is needed for static versions of libc
+libc_arch_static_src_files := \
+ arch-x86/bionic/dl_iterate_phdr_static.c
+
+libc_arch_dynamic_src_files :=
+endif # x86
endif # !arm
+# Define some common cflags
+# ========================================================
libc_common_cflags := \
-DWITH_ERRLIST \
-DANDROID_CHANGES \
@@ -338,6 +358,7 @@ libc_common_cflags := \
-DNEED_PSELECT=1 \
-DINET6 \
-I$(LOCAL_PATH)/private \
+ -DUSE_DL_PREFIX
ifeq ($(strip $(DEBUG_BIONIC_LIBC)),true)
libc_common_cflags += -DDEBUG
@@ -345,159 +366,154 @@ endif
ifeq ($(TARGET_ARCH),arm)
libc_common_cflags += -fstrict-aliasing
-endif
+ libc_crt_target_cflags := -mthumb-interwork
+else # !arm
+ ifeq ($(TARGET_ARCH),x86)
+ libc_crt_target_cflags := -m32
+ endif # x86
+endif # !arm
ifneq (, $(filter msm7630_surf msm7630_ffa qsd8250_surf qsd8250_ffa, $(TARGET_PRODUCT)))
libc_common_cflags += -DCOPROC_TLS=1
endif
+# Define some common includes
+# ========================================================
libc_common_c_includes := \
$(LOCAL_PATH)/stdlib \
$(LOCAL_PATH)/string \
$(LOCAL_PATH)/stdio
-# libc_common.a
-# ========================================================
-
-include $(CLEAR_VARS)
-LOCAL_SRC_FILES := $(libc_common_src_files)
-LOCAL_CFLAGS := $(libc_common_cflags) -DUSE_DL_PREFIX
-LOCAL_C_INCLUDES := $(libc_common_c_includes)
+# Define the libc run-time (crt) support object files that must be built,
+# which are needed to build all other objects (shared/static libs and
+# executables)
+# ==========================================================================
-ifneq ($(TARGET_SIMULATOR),true)
- ifeq ($(TARGET_ARCH),arm)
- crtend_target_cflags := -mthumb-interwork
- else
- ifeq ($(TARGET_ARCH),x86)
- crtend_target_cflags := -m32
- endif
- endif
-# We rename crtend.o to crtend_android.o to avoid a
-# name clash between gcc and bionic.
-GEN := $(TARGET_OUT_STATIC_LIBRARIES)/crtend_android.o
-$(GEN): $(LOCAL_PATH)/arch-$(TARGET_ARCH)/bionic/crtend.S
+ifeq ($(TARGET_ARCH),x86)
+# we only need begin_so/end_so for x86, since it needs an appropriate .init
+# section in the shared library with a function to call all the entries in
+# .ctors section. ARM uses init_array, and does not need the function.
+GEN := $(TARGET_OUT_STATIC_LIBRARIES)/crtbegin_so.o
+$(GEN): $(LOCAL_PATH)/arch-$(TARGET_ARCH)/bionic/crtbegin_so.S
@mkdir -p $(dir $@)
- $(TARGET_CC) $(crtend_target_cflags) -o $@ -c $<
+ $(TARGET_CC) $(libc_crt_target_cflags) -o $@ -c $<
ALL_GENERATED_SOURCES += $(GEN)
-endif
+GEN := $(TARGET_OUT_STATIC_LIBRARIES)/crtend_so.o
+$(GEN): $(LOCAL_PATH)/arch-$(TARGET_ARCH)/bionic/crtend_so.S
+ @mkdir -p $(dir $@)
+ $(TARGET_CC) $(libc_crt_target_cflags) -o $@ -c $<
+ALL_GENERATED_SOURCES += $(GEN)
+endif # TARGET_ARCH == x86
-# crtbegin_so.o/crtend_so.o
-# These are needed for building the shared libs.
-ifneq ($(TARGET_SIMULATOR),true)
-
-ifeq ($(TARGET_ARCH),x86)
-crt_begin_end_so_target_cflags := -m32
+GEN := $(TARGET_OUT_STATIC_LIBRARIES)/crtbegin_static.o
+$(GEN): $(LOCAL_PATH)/arch-$(TARGET_ARCH)/bionic/crtbegin_static.S
+ @mkdir -p $(dir $@)
+ $(TARGET_CC) $(libc_crt_target_cflags) -o $@ -c $<
+ALL_GENERATED_SOURCES += $(GEN)
-GEN := $(TARGET_OUT_STATIC_LIBRARIES)/crtbegin_so.o
-$(GEN): $(LOCAL_PATH)/arch-$(TARGET_ARCH)/bionic/crtbegin_so.S
+GEN := $(TARGET_OUT_STATIC_LIBRARIES)/crtbegin_dynamic.o
+$(GEN): $(LOCAL_PATH)/arch-$(TARGET_ARCH)/bionic/crtbegin_dynamic.S
@mkdir -p $(dir $@)
- $(TARGET_CC) $(crt_begin_end_so_target_cflags) -o $@ -c $<
+ $(TARGET_CC) $(libc_crt_target_cflags) -o $@ -c $<
ALL_GENERATED_SOURCES += $(GEN)
-GEN := $(TARGET_OUT_STATIC_LIBRARIES)/crtend_so.o
-$(GEN): $(LOCAL_PATH)/arch-$(TARGET_ARCH)/bionic/crtend_so.S
+
+# We rename crtend.o to crtend_android.o to avoid a
+# name clash between gcc and bionic.
+GEN := $(TARGET_OUT_STATIC_LIBRARIES)/crtend_android.o
+$(GEN): $(LOCAL_PATH)/arch-$(TARGET_ARCH)/bionic/crtend.S
@mkdir -p $(dir $@)
- $(TARGET_CC) $(crt_begin_end_so_target_cflags) -o $@ -c $<
+ $(TARGET_CC) $(libc_crt_target_cflags) -o $@ -c $<
ALL_GENERATED_SOURCES += $(GEN)
-endif # TARGET_ARCH == x86
-endif # !TARGET_SIMULATOR
+# To enable malloc leak check for statically linked programs, add
+# "WITH_MALLOC_CHECK_LIBC_A := true" to buildspec.mk
+WITH_MALLOC_CHECK_LIBC_A := $(strip $(WITH_MALLOC_CHECK_LIBC_A))
+# ========================================================
+# libc_common.a
+# ========================================================
+include $(CLEAR_VARS)
+LOCAL_SRC_FILES := $(libc_common_src_files)
+LOCAL_CFLAGS := $(libc_common_cflags)
+LOCAL_C_INCLUDES := $(libc_common_c_includes)
LOCAL_MODULE := libc_common
LOCAL_SYSTEM_SHARED_LIBRARIES :=
include $(BUILD_STATIC_LIBRARY)
-# libc.a
# ========================================================
+# libc_nomalloc.a
+# ========================================================
+#
+# This is a version of the static C library that does not
+# include malloc. It's useful in situations when calling
+# the user wants to provide their own malloc implementation,
+# or wants to explicitly disallow the use of the use of malloc,
+# like the dynamic loader.
include $(CLEAR_VARS)
-include $(LOCAL_PATH)/arch-$(TARGET_ARCH)/syscalls.mk
-
-# To enable malloc leak check for statically linked programs, add
-# "WITH_MALLOC_CHECK_LIBC_A := true" to device/buildspec.mk
-WITH_MALLOC_CHECK_LIBC_A := $(strip $(WITH_MALLOC_CHECK_LIBC_A))
-
LOCAL_SRC_FILES := \
- $(libc_common_src_files) \
- bionic/dlmalloc.c \
+ $(libc_arch_static_src_files) \
bionic/libc_init_static.c
-ifeq ($(WITH_MALLOC_CHECK_LIBC_A),true)
- LOCAL_SRC_FILES += bionic/malloc_leak.c.arm
-endif
+LOCAL_C_INCLUDES := $(libc_common_c_includes)
+LOCAL_CFLAGS := $(libc_common_cflags)
-ifeq ($(TARGET_ARCH),arm)
-LOCAL_SRC_FILES += \
- arch-arm/bionic/exidx_static.c
+LOCAL_MODULE := libc_nomalloc
+LOCAL_WHOLE_STATIC_LIBRARIES := libc_common
+LOCAL_SYSTEM_SHARED_LIBRARIES :=
-else # TARGET_ARCH != arm
+include $(BUILD_STATIC_LIBRARY)
-ifeq ($(TARGET_ARCH),x86)
-LOCAL_SRC_FILES += \
- arch-x86/bionic/dl_iterate_phdr_static.c
-endif
-endif
+# ========================================================
+# libc.a
+# ========================================================
+include $(CLEAR_VARS)
-ifneq ($(TARGET_SIMULATOR),true)
- ifeq ($(TARGET_ARCH),arm)
- crtbegin_static_target_cflags := -mthumb-interwork
- else
- ifeq ($(TARGET_ARCH),x86)
- crtbegin_static_target_cflags := -m32
- endif
- endif
-GEN := $(TARGET_OUT_STATIC_LIBRARIES)/crtbegin_static.o
-$(GEN): $(LOCAL_PATH)/arch-$(TARGET_ARCH)/bionic/crtbegin_static.S
- @mkdir -p $(dir $@)
- $(TARGET_CC) $(crtbegin_static_target_cflags) -o $@ -c $<
-ALL_GENERATED_SOURCES += $(GEN)
-endif
+LOCAL_SRC_FILES := \
+ $(libc_arch_static_src_files) \
+ bionic/dlmalloc.c \
+ bionic/libc_init_static.c
LOCAL_CFLAGS := $(libc_common_cflags)
-LOCAL_C_INCLUDES := $(libc_common_c_includes)
-
ifeq ($(WITH_MALLOC_CHECK_LIBC_A),true)
- LOCAL_CFLAGS += -DUSE_DL_PREFIX -DMALLOC_LEAK_CHECK
+ LOCAL_CFLAGS += -DMALLOC_LEAK_CHECK
+ LOCAL_SRC_FILES += bionic/malloc_leak.c.arm
endif
+LOCAL_C_INCLUDES := $(libc_common_c_includes)
+
+LOCAL_MODULE := libc
LOCAL_WHOLE_STATIC_LIBRARIES := libc_common
-LOCAL_MODULE:= libc
LOCAL_SYSTEM_SHARED_LIBRARIES :=
include $(BUILD_STATIC_LIBRARY)
+# ========================================================
# libc.so
# ========================================================
-
include $(CLEAR_VARS)
LOCAL_CFLAGS := $(libc_common_cflags)
-
-LOCAL_CFLAGS += -DUSE_DL_PREFIX
-
LOCAL_C_INCLUDES := $(libc_common_c_includes)
LOCAL_SRC_FILES := \
+ $(libc_arch_dynamic_src_files) \
bionic/dlmalloc.c \
bionic/malloc_leak.c.arm \
bionic/libc_init_dynamic.c
-ifeq ($(TARGET_ARCH),arm)
-LOCAL_SRC_FILES += \
- arch-arm/bionic/exidx_dynamic.c
-endif
-
LOCAL_MODULE:= libc
# WARNING: The only library libc.so should depend on is libdl.so! If you add other libraries,
@@ -512,45 +528,26 @@ LOCAL_SHARED_LIBRARIES := libdl
LOCAL_WHOLE_STATIC_LIBRARIES := libc_common
LOCAL_SYSTEM_SHARED_LIBRARIES :=
-ifneq ($(TARGET_SIMULATOR),true)
- ifeq ($(TARGET_ARCH),arm)
- crtbegin_dynamic_target_cflags := -mthumb-interwork
- else
- ifeq ($(TARGET_ARCH),x86)
- crtbegin_dynamic_target_cflags := -m32
- endif
- endif
-GEN := $(TARGET_OUT_STATIC_LIBRARIES)/crtbegin_dynamic.o
-$(GEN): $(LOCAL_PATH)/arch-$(TARGET_ARCH)/bionic/crtbegin_dynamic.S
- @mkdir -p $(dir $@)
- $(TARGET_CC) $(crtbegin_dynamic_target_cflags) -o $@ -c $<
-ALL_GENERATED_SOURCES += $(GEN)
-endif
-
include $(BUILD_SHARED_LIBRARY)
+# ========================================================
# libc_debug.so
# ========================================================
-
include $(CLEAR_VARS)
-LOCAL_CFLAGS := $(libc_common_cflags)
-
-LOCAL_CFLAGS += -DUSE_DL_PREFIX -DMALLOC_LEAK_CHECK
+LOCAL_CFLAGS := \
+ $(libc_common_cflags) \
+ -DMALLOC_LEAK_CHECK
LOCAL_C_INCLUDES := $(libc_common_c_includes)
LOCAL_SRC_FILES := \
+ $(libc_arch_dynamic_src_files) \
bionic/dlmalloc.c \
bionic/malloc_leak.c.arm \
bionic/libc_init_dynamic.c
-ifeq ($(TARGET_ARCH),arm)
-LOCAL_SRC_FILES += \
- arch-arm/bionic/exidx_dynamic.c
-endif
-
LOCAL_MODULE:= libc_debug
# WARNING: The only library libc.so should depend on is libdl.so! If you add other libraries,
@@ -569,9 +566,6 @@ LOCAL_PRELINK_MODULE := false
# Don't install on release build
LOCAL_MODULE_TAGS := eng
-GEN := $(TARGET_OUT_STATIC_LIBRARIES)/crtbegin_dynamic.o
-ALL_GENERATED_SOURCES += $(GEN)
-
include $(BUILD_SHARED_LIBRARY)
# ========================================================
diff --git a/libc/bionic/eabi.c b/libc/bionic/eabi.c
index 21d8537..a5f6627 100644
--- a/libc/bionic/eabi.c
+++ b/libc/bionic/eabi.c
@@ -32,6 +32,14 @@ extern int __cxa_atexit(void (*)(void*), void*, void* );
void* __dso_handle = 0;
+/* The "C++ ABI for ARM" document states that static C++ constructors,
+ * which are called from the .init_array, should manually call
+ * __aeabi_atexit() to register static destructors explicitely.
+ *
+ * Note that 'dso_handle' is the address of a magic linker-generate
+ * variable from the shared object that contains the constructor/destructor
+ */
+
/* Make this a weak symbol to avoid a multiple definition error when linking
* with libstdc++-v3. */
int __attribute__((weak))
diff --git a/libc/docs/ISSUES.TXT b/libc/docs/ISSUES.TXT
new file mode 100644
index 0000000..b53eb16
--- /dev/null
+++ b/libc/docs/ISSUES.TXT
@@ -0,0 +1,20 @@
+Bionic C Library Issues:
+========================
+
+This document lists important known issues of various releases
+of the Bionic C library. Note that these differ from specific
+implementation choices that are documented in the OVERVIEW.TXT
+document.
+
+Currently known issues:
+-----------------------
+
+- The C library initialization will improperly run static C++
+ constructors located in shared libraries twice.
+
+Android-1.5 issues:
+-------------------
+
+- getservbyname() returned the port number in the s_port field of
+ the 'struct servent' structure in host-byte-order, instead of
+ network-byte-order.
diff --git a/libc/include/sys/stat.h b/libc/include/sys/stat.h
index 23ab5ae..091ee6d 100644
--- a/libc/include/sys/stat.h
+++ b/libc/include/sys/stat.h
@@ -71,6 +71,13 @@ struct stat {
unsigned long long st_ino;
};
+/* For compatibility with GLibc, we provide macro aliases
+ * for the non-Posix nano-seconds accessors.
+ */
+#define st_atimensec st_atime_nsec
+#define st_mtimensec st_mtime_nsec
+#define st_ctimensec st_ctime_nsec
+
extern int chmod(const char *, mode_t);
extern int fchmod(int, mode_t);
extern int mkdir(const char *, mode_t);
diff --git a/libc/kernel/common/linux/if_pppolac.h b/libc/kernel/common/linux/if_pppolac.h
new file mode 100644
index 0000000..bf6eba0
--- /dev/null
+++ b/libc/kernel/common/linux/if_pppolac.h
@@ -0,0 +1,29 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ *** This header was automatically generated from a Linux kernel header
+ *** of the same name, to make information necessary for userspace to
+ *** call into the kernel available to libc. It contains only constants,
+ *** structures, and macros generated from the original header, and thus,
+ *** contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __LINUX_IF_PPPOLAC_H
+#define __LINUX_IF_PPPOLAC_H
+
+#include <linux/socket.h>
+#include <linux/types.h>
+
+#define PX_PROTO_OLAC 2
+
+struct sockaddr_pppolac {
+ sa_family_t sa_family;
+ unsigned int sa_protocol;
+ int udp_socket;
+ struct __attribute__((packed)) {
+ __u16 tunnel, session;
+ } local, remote;
+} __attribute__((packed));
+
+#endif
diff --git a/libc/kernel/common/linux/if_pppopns.h b/libc/kernel/common/linux/if_pppopns.h
new file mode 100644
index 0000000..ac75210
--- /dev/null
+++ b/libc/kernel/common/linux/if_pppopns.h
@@ -0,0 +1,28 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ *** This header was automatically generated from a Linux kernel header
+ *** of the same name, to make information necessary for userspace to
+ *** call into the kernel available to libc. It contains only constants,
+ *** structures, and macros generated from the original header, and thus,
+ *** contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __LINUX_IF_PPPOPNS_H
+#define __LINUX_IF_PPPOPNS_H
+
+#include <linux/socket.h>
+#include <linux/types.h>
+
+#define PX_PROTO_OPNS 3
+
+struct sockaddr_pppopns {
+ sa_family_t sa_family;
+ unsigned int sa_protocol;
+ int tcp_socket;
+ __u16 local;
+ __u16 remote;
+} __attribute__((packed));
+
+#endif
diff --git a/libc/kernel/common/linux/ipsec.h b/libc/kernel/common/linux/ipsec.h
new file mode 100644
index 0000000..56acafa
--- /dev/null
+++ b/libc/kernel/common/linux/ipsec.h
@@ -0,0 +1,56 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ *** This header was automatically generated from a Linux kernel header
+ *** of the same name, to make information necessary for userspace to
+ *** call into the kernel available to libc. It contains only constants,
+ *** structures, and macros generated from the original header, and thus,
+ *** contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_IPSEC_H
+#define _LINUX_IPSEC_H
+
+#include <linux/pfkeyv2.h>
+
+#define IPSEC_PORT_ANY 0
+#define IPSEC_ULPROTO_ANY 255
+#define IPSEC_PROTO_ANY 255
+
+enum {
+ IPSEC_MODE_ANY = 0,
+ IPSEC_MODE_TRANSPORT = 1,
+ IPSEC_MODE_TUNNEL = 2,
+ IPSEC_MODE_BEET = 3
+};
+
+enum {
+ IPSEC_DIR_ANY = 0,
+ IPSEC_DIR_INBOUND = 1,
+ IPSEC_DIR_OUTBOUND = 2,
+ IPSEC_DIR_FWD = 3,
+ IPSEC_DIR_MAX = 4,
+ IPSEC_DIR_INVALID = 5
+};
+
+enum {
+ IPSEC_POLICY_DISCARD = 0,
+ IPSEC_POLICY_NONE = 1,
+ IPSEC_POLICY_IPSEC = 2,
+ IPSEC_POLICY_ENTRUST = 3,
+ IPSEC_POLICY_BYPASS = 4
+};
+
+enum {
+ IPSEC_LEVEL_DEFAULT = 0,
+ IPSEC_LEVEL_USE = 1,
+ IPSEC_LEVEL_REQUIRE = 2,
+ IPSEC_LEVEL_UNIQUE = 3
+};
+
+#define IPSEC_MANUAL_REQID_MAX 0x3fff
+
+#define IPSEC_REPLAYWSIZE 32
+
+#endif
diff --git a/libc/kernel/tools/update_all.py b/libc/kernel/tools/update_all.py
index 6272fcf..d25dc0e 100755
--- a/libc/kernel/tools/update_all.py
+++ b/libc/kernel/tools/update_all.py
@@ -73,7 +73,9 @@ for path in sources:
print "cleaning: %-*s -> %-*s (%s)" % ( 35, path, 35, dst_path, r )
-usePerforce = os.environ.has_key("ANDROID_PRODUCT_OUT")
+# We don't use Perforce anymore, but just in case, define ANDROID_USE_P4
+# in your environment if you think you need it.
+usePerforce = os.environ.has_key("ANDROID_USE_P4")
if usePerforce:
b.updateP4Files()
diff --git a/libc/netbsd/net/getservent.c b/libc/netbsd/net/getservent.c
index 45207df..65fbd7e 100644
--- a/libc/netbsd/net/getservent.c
+++ b/libc/netbsd/net/getservent.c
@@ -27,6 +27,7 @@
*/
#include <sys/cdefs.h>
#include <sys/types.h>
+#include <sys/endian.h>
#include <netdb.h>
#include "servent.h"
#include "services.h"
@@ -54,6 +55,7 @@ getservent_r( res_static rs )
int namelen;
int nn,count;
int total = 0;
+ int port;
char* p2;
p = rs->servent_ptr;
@@ -92,9 +94,12 @@ getservent_r( res_static rs )
memcpy( rs->servent.s_name, p+1, namelen );
rs->servent.s_name[namelen] = 0;
p += 1 + namelen;
- rs->servent.s_port = ((((unsigned char*)p)[0] << 8) |
- ((unsigned char*)p)[1]);
+ /* s_port must be in network byte order */
+ port = ((((unsigned char*)p)[0] << 8) |
+ ((unsigned char*)p)[1]);
+
+ rs->servent.s_port = htons(port);
rs->servent.s_proto = p[2] == 't' ? "tcp" : "udp";
p += 4; /* skip port(2) + proto(1) + aliascount(1) */
diff --git a/libc/stdlib/atexit.c b/libc/stdlib/atexit.c
index 5bf82ba..4ba2177 100644
--- a/libc/stdlib/atexit.c
+++ b/libc/stdlib/atexit.c
@@ -147,10 +147,19 @@ __cxa_finalize(void *dso)
p->fns[n].fn_ptr.cxa_func = NULL;
mprotect(p, pgsize, PROT_READ);
}
+#if ANDROID
+ /* it looks like we should always call the function
+ * with an argument, even if dso is not NULL. Otherwise
+ * static destructors will not be called properly on
+ * the ARM.
+ */
+ (*fn.fn_ptr.cxa_func)(fn.fn_arg);
+#else /* !ANDROID */
if (dso != NULL)
(*fn.fn_ptr.cxa_func)(fn.fn_arg);
else
(*fn.fn_ptr.std_func)();
+#endif /* !ANDROID */
}
}