OSDN Git Service

Allow static C++ destructors to be properly called on dlclose().
authorDavid 'Digit' Turner <digit@google.com>
Fri, 18 Jun 2010 21:47:22 +0000 (14:47 -0700)
committerDavid 'Digit' Turner <digit@google.com>
Fri, 18 Jun 2010 23:07:10 +0000 (16:07 -0700)
With this patch, _and_ an upcoming build/ patch, the destruction
of static C++ objects contained in shared libraries will happen
properly when dlclose() is called.

Note that this change introduces crtbegin_so.S and crtend_so.S which
are currently ignored by the build system.

+ move definition of __dso_handle to the right place
  (before that, all shared libraries used the __dso_handle
   global variable from the C library).

  Note that we keep a 'weak' __dso_handle in aeabi.c to avoid
  breaking the build until the next patch to build/core/combo/
  appears. We will be able to remove that later.

+ move bionic/aeabi.c to arch-arm/bionic/ (its proper location)

Change-Id: Ie771aa204e3acbdf02fd30ebd4150373a1398f39
NOTE: The NDK will need to be modified to enable this feature in
      the shared libraries that are generated through it.

12 files changed:
libc/Android.mk
libc/arch-arm/bionic/crtbegin_dynamic.S
libc/arch-arm/bionic/crtbegin_so.S [new file with mode: 0644]
libc/arch-arm/bionic/crtbegin_static.S
libc/arch-arm/bionic/crtend_so.S [new file with mode: 0644]
libc/arch-arm/bionic/eabi.c [moved from libc/bionic/eabi.c with 83% similarity]
libc/arch-sh/bionic/crtbegin_dynamic.S
libc/arch-sh/bionic/crtbegin_static.S
libc/arch-x86/bionic/crtbegin_dynamic.S
libc/arch-x86/bionic/crtbegin_so.S
libc/arch-x86/bionic/crtbegin_static.S
libc/private/__dso_handle.S [new file with mode: 0644]

index 79c89ed..6b2334e 100644 (file)
@@ -317,7 +317,6 @@ libc_common_src_files := \
 # =========================================================
 ifeq ($(TARGET_ARCH),arm)
 libc_common_src_files += \
-       bionic/eabi.c \
        bionic/bionic_clone.c \
        arch-arm/bionic/__get_pc.S \
        arch-arm/bionic/__get_sp.S \
@@ -325,6 +324,7 @@ libc_common_src_files += \
        arch-arm/bionic/_setjmp.S \
        arch-arm/bionic/atomics_arm.S \
        arch-arm/bionic/clone.S \
+       arch-arm/bionic/eabi.c \
        arch-arm/bionic/ffs.S \
        arch-arm/bionic/kill.S \
        arch-arm/bionic/libgcc_compat.c \
@@ -421,7 +421,6 @@ libc_common_src_files += \
        string/strncmp.c \
        string/memcmp.c \
        string/strlen.c \
-       bionic/eabi.c \
        bionic/pthread.c \
        bionic/pthread-rwlocks.c \
        bionic/pthread-timers.c \
@@ -490,6 +489,10 @@ else
     libc_common_cflags += -DANDROID_SMP=0
 endif
 
+# Needed to access private/__dso_handle.S from
+# crtbegin_xxx.S and crtend_xxx.S
+#
+libc_crt_target_cflags += -I$(LOCAL_PATH)/private
 
 # Define some common includes
 # ========================================================
@@ -504,10 +507,17 @@ libc_common_c_includes := \
 # executables)
 # ==========================================================================
 
-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.
+ifneq ($(filter arm x86,$(TARGET_ARCH)),)
+# ARM and x86 need crtbegin_so/crtend_so.
+#
+# For x86, the .init section must point to a function that calls all
+# entries in the .ctors section. (on ARM this is done through the
+# .init_array section instead).
+#
+# For both platforms, the .fini_array section must point to a function
+# that will call __cxa_finalize(&__dso_handle) in order to ensure that
+# static C++ destructors are properly called on dlclose().
+#
 GEN := $(TARGET_OUT_STATIC_LIBRARIES)/crtbegin_so.o
 $(GEN): $(LOCAL_PATH)/arch-$(TARGET_ARCH)/bionic/crtbegin_so.S
        @mkdir -p $(dir $@)
index e265923..d18e715 100644 (file)
@@ -31,7 +31,7 @@
        .globl _start
 
 # this is the small startup code that is first run when
-# any executable that is statically-linked with Bionic
+# any executable that is dynamically-linked with Bionic
 # runs.
 #
 # it's purpose is to call __libc_init with appropriate
@@ -63,13 +63,7 @@ _start:
     .long   __INIT_ARRAY__
     .long   __FINI_ARRAY__
     .long   __CTOR_LIST__
-      
-# the .ctors section contains a list of pointers to "constructor"
-# functions that need to be called in order during C library initialization,
-# just before the program is being run. This is a C++ requirement
-#
-# the last entry shall be 0, and is defined in crtend.S
-#
+
        .section .preinit_array, "aw"
        .globl __PREINIT_ARRAY__
 __PREINIT_ARRAY__:
@@ -90,3 +84,4 @@ __FINI_ARRAY__:
 __CTOR_LIST__:
        .long -1
 
+#include "__dso_handle.S"
diff --git a/libc/arch-arm/bionic/crtbegin_so.S b/libc/arch-arm/bionic/crtbegin_so.S
new file mode 100644 (file)
index 0000000..bb6b3e2
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * 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.
+ */
+
+# Implement static C++ destructors when the shared
+# library is unloaded through dlclose().
+#
+# A call to this function must be the first entry
+# in the .fini_array. See 3.3.5.3.C of C++ ABI
+# standard.
+#
+__on_dlclose:
+        adr     r0, 0f
+        ldr     r0, [r0]
+        b       __cxa_finalize
+
+0:
+        .long   __dso_handle
+
+       .section .init_array, "aw"
+       .globl __INIT_ARRAY__
+__INIT_ARRAY__:
+       .long -1
+
+        .section .fini_array, "aw"
+        .globl __FINI_ARRAY__
+__FINI_ARRAY__:
+        .long -1
+        .long __on_dlclose
+
+#include "__dso_handle.S"
index e265923..6f9cf25 100644 (file)
@@ -63,13 +63,7 @@ _start:
     .long   __INIT_ARRAY__
     .long   __FINI_ARRAY__
     .long   __CTOR_LIST__
-      
-# the .ctors section contains a list of pointers to "constructor"
-# functions that need to be called in order during C library initialization,
-# just before the program is being run. This is a C++ requirement
-#
-# the last entry shall be 0, and is defined in crtend.S
-#
+
        .section .preinit_array, "aw"
        .globl __PREINIT_ARRAY__
 __PREINIT_ARRAY__:
@@ -90,3 +84,5 @@ __FINI_ARRAY__:
 __CTOR_LIST__:
        .long -1
 
+
+#include "__dso_handle.S"
diff --git a/libc/arch-arm/bionic/crtend_so.S b/libc/arch-arm/bionic/crtend_so.S
new file mode 100644 (file)
index 0000000..a1281c4
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2010 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.
+ */
+
+/* This is the same than crtend.S except that a shared library
+ * cannot have a .preinit_array
+ */
+       
+       .section .init_array, "aw"
+       .long 0
+
+       .section .fini_array, "aw"
+       .long 0
+
similarity index 83%
rename from libc/bionic/eabi.c
rename to libc/arch-arm/bionic/eabi.c
index a5f6627..3f26f2b 100644 (file)
 
 extern int  __cxa_atexit(void (*)(void*), void*, void* );
 
-void* __dso_handle = 0;
+/* Temporary hack: this variable should not be part of the C library
+ * itself, but placed in the .bss section of each executable or
+ * shared library instead.
+ *
+ * We keep it here temporarily until the build system has been
+ * modified properly to use crtbegin_so.S and crtend_so.S when
+ * generating shared libraries.
+ *
+ * It must be a 'weak' symbol to avoid conflicts with the definitions
+ * that have been moved to crtbegin_static.S and crtbegin_dynamic.S
+ *
+ * For the record, it is used for static C++ object construction
+ * and destruction. See http://www.codesourcery.com/public/cxx-abi/abi.html#dso-dtor
+ */
+void* __attribute__((weak)) __dso_handle;
 
 /* The "C++ ABI for ARM" document states that static C++ constructors,
  * which are called from the .init_array, should manually call
index dc485dd..daf6c8b 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2009 The Android Open Source Project
+ * Copyright (C) 2009-2010 The Android Open Source Project
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,7 +31,7 @@
 .globl  _start
 
 # this is the small startup code that is first run when
-# any executable that is statically-linked with Bionic
+# any executable that is dynamically-linked with Bionic
 # runs.
 #
 # it's purpose is to call __libc_init with appropriate
@@ -93,3 +93,5 @@ __FINI_ARRAY__:
     .globl __CTOR_LIST__
 __CTOR_LIST__:
     .long -1
+
+#include "__dso_handle.S"
index 97db1e4..1d3fdf8 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2009 The Android Open Source Project
+ * Copyright (C) 2009-2010 The Android Open Source Project
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -68,12 +68,6 @@ _start:
     .long   __FINI_ARRAY__
     .long   __CTOR_LIST__
 
-# the .ctors section contains a list of pointers to "constructor"
-# functions that need to be called in order during C library initialization,
-# just before the program is being run. This is a C++ requirement
-#
-# the last entry shall be 0, and is defined in crtend.S
-#
     .section .preinit_array, "aw"
     .globl __PREINIT_ARRAY__
 __PREINIT_ARRAY__:
@@ -94,3 +88,4 @@ __FINI_ARRAY__:
 __CTOR_LIST__:
     .long -1
 
+#include "__dso_handle.S"
index 3b47b18..88e7e6a 100644 (file)
@@ -30,7 +30,7 @@
        .globl _start
 
 # this is the small startup code that is first run when
-# any executable that is statically-linked with Bionic
+# any executable that is dynamically-linked with Bionic
 # runs.
 #
 # it's purpose is to call __libc_init with appropriate
@@ -94,3 +94,4 @@ __FINI_ARRAY__:
 __CTOR_LIST__:
        .long -1
 
+#include "__dso_handle.S"
index d49e9df..d879fef 100644 (file)
@@ -1,3 +1,10 @@
+# This function is to be called when the shared library
+# is unloaded through dlclose()
+_on_dlclose:
+    lea __dso_handle, %eax
+    call __cxa_finalize
+    ret
+
 /* we put the _init() function here in case the user files for the shared
  * libs want to drop things into .init section.
  * We then will call our ctors from crtend_so.o */
@@ -20,6 +27,7 @@ __INIT_ARRAY__:
 .globl __FINI_ARRAY__
 __FINI_ARRAY__:
     .long -1
+    .long _on_dlclose
 
 .section .ctors, "aw"
 .align 4
@@ -27,3 +35,5 @@ __FINI_ARRAY__:
 .globl __CTOR_LIST__
 __CTOR_LIST__:
         .long -1
+
+#include "__dso_handle.S"
index eb4acee..3f8446e 100644 (file)
@@ -67,12 +67,6 @@ _start:
     .long   __FINI_ARRAY__
     .long   __CTOR_LIST__
 
-# the .ctors section contains a list of pointers to "constructor"
-# functions that need to be called in order during C library initialization,
-# just before the program is being run. This is a C++ requirement
-#
-# the last entry shall be 0, and is defined in crtend.S
-#
        .section .preinit_array, "aw"
        .globl __PREINIT_ARRAY__
 __PREINIT_ARRAY__:
@@ -93,3 +87,4 @@ __FINI_ARRAY__:
 __CTOR_LIST__:
        .long -1
 
+#include "__dso_handle.S"
diff --git a/libc/private/__dso_handle.S b/libc/private/__dso_handle.S
new file mode 100644 (file)
index 0000000..fcebab6
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2010 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.
+ */
+
+# The __dso_handle global variable is used by static
+# C++ constructors and destructors in the binary.
+# See http://www.codesourcery.com/public/cxx-abi/abi.html#dso-dtor
+#
+        .section .bss
+        .align 4
+        .globl __dso_handle
+__dso_handle:
+        .long 0