Rewrite ARM crtbegin* as C files

This is port of related CLs:
  9d40326830c2bd407427889c554adeb915ee6b4a
  f3cfcd869ded41d25c1f4f4e48e7c374a64f9583

Summary: By placing  __PREINIT_ARRAY__, __INIT_ARRAY__, __FINI_ARRAY__
and __CTOR_LIST__ on stack, this change allows PIC w/o relying on text
relocations.

Change-Id: I02a1b496b16aba692f4f9fa998a71efd943689fd
diff --git a/ndk/platforms/android-3/arch-arm/src/__dso_handle.S b/ndk/platforms/android-3/arch-arm/src/__dso_handle.h
similarity index 61%
rename from ndk/platforms/android-3/arch-arm/src/__dso_handle.S
rename to ndk/platforms/android-3/arch-arm/src/__dso_handle.h
index 2d78389..3b56eba 100644
--- a/ndk/platforms/android-3/arch-arm/src/__dso_handle.S
+++ b/ndk/platforms/android-3/arch-arm/src/__dso_handle.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2010 The Android Open Source Project
+ * Copyright (C) 2012 The Android Open Source Project
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -26,30 +26,25 @@
  * 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
-#
-        .data
-        .align 4
+/* 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
 
-/* CRT_LEGACY_WORKAROUND is only defined when building this file
- * for the C library. This forces __dso_handle to be exported by
- * it. This is only required to ensure binary compatibility with
- * old NDK application machine code that contains reference to
- * the symbol, but do not have a proper definition for it.
- *
- * These binaries cannot call their destructorson dlclose(), but
- * at least they will not fail to load.
- *
- * When this file is built for the NDK, CRT_LEGACY_WORKAROUND
- * should never be defined.
+   CRT_LEGACY_WORKAROUND is only defined when building this file
+   for the C library. This forces __dso_handle to be exported by
+   it. This is only required to ensure binary compatibility with
+   old NDK application machine code that contains reference to
+   the symbol, but do not have a proper definition for it.
+
+   These binaries cannot call their destructorson dlclose(), but
+   at least they will not fail to load.
+
+   When this file is built for the NDK, CRT_LEGACY_WORKAROUND
+   should never be defined.
  */
 
 #ifndef CRT_LEGACY_WORKAROUND
-	.hidden __dso_handle
+__attribute__ ((visibility ("hidden")))
 #endif
-
-        .globl __dso_handle
-__dso_handle:
-        .long __dso_handle
+__attribute__ ((section (".bss")))
+void *__dso_handle = (void *) 0;
diff --git a/ndk/platforms/android-3/arch-arm/src/__dso_handle_so.S b/ndk/platforms/android-3/arch-arm/src/__dso_handle_so.h
similarity index 79%
rename from ndk/platforms/android-3/arch-arm/src/__dso_handle_so.S
rename to ndk/platforms/android-3/arch-arm/src/__dso_handle_so.h
index 77a5d7f..bd8b378 100644
--- a/ndk/platforms/android-3/arch-arm/src/__dso_handle_so.S
+++ b/ndk/platforms/android-3/arch-arm/src/__dso_handle_so.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2010 The Android Open Source Project
+ * Copyright (C) 2012 The Android Open Source Project
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -26,13 +26,11 @@
  * 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
-#
-	.data
-        .align 4
-	.hidden __dso_handle
-        .globl __dso_handle
-__dso_handle:
-        .long __dso_handle
+/* 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
+*/
+
+__attribute__ ((visibility ("hidden")))
+__attribute__ ((section (".data")))
+void *__dso_handle;
diff --git a/ndk/platforms/android-3/arch-arm/src/__dso_handle_so.S b/ndk/platforms/android-3/arch-arm/src/atexit.h
similarity index 79%
copy from ndk/platforms/android-3/arch-arm/src/__dso_handle_so.S
copy to ndk/platforms/android-3/arch-arm/src/atexit.h
index 77a5d7f..bc776a8 100644
--- a/ndk/platforms/android-3/arch-arm/src/__dso_handle_so.S
+++ b/ndk/platforms/android-3/arch-arm/src/atexit.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2010 The Android Open Source Project
+ * Copyright (C) 2012 The Android Open Source Project
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -26,13 +26,10 @@
  * 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
-#
-	.data
-        .align 4
-	.hidden __dso_handle
-        .globl __dso_handle
-__dso_handle:
-        .long __dso_handle
+extern void *__dso_handle;
+
+__attribute__ ((visibility ("hidden")))
+int atexit(void (*func)(void))
+{
+  return (__cxa_atexit((void (*)(void *))func, (void *)0, &__dso_handle));
+}
diff --git a/ndk/platforms/android-3/arch-arm/src/crtbegin_dynamic.S b/ndk/platforms/android-3/arch-arm/src/crtbegin_dynamic.S
deleted file mode 100644
index c7c9f6d..0000000
--- a/ndk/platforms/android-3/arch-arm/src/crtbegin_dynamic.S
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *  * Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *  * Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-	.text
-	.align 4
-	.type _start,#function
-	.globl _start
-
-# this is the small startup code that is first run when
-# any executable that is dynamically-linked with Bionic
-# runs.
-#
-# it's purpose is to call __libc_init with appropriate
-# arguments, which are:
-#
-#    - the address of the raw data block setup by the Linux
-#      kernel ELF loader
-#
-#    - address of an "onexit" function, not used on any
-#      platform supported by Bionic
-#
-#    - address of the "main" function of the program.
-#
-#    - address of the constructor list
-#
-_start:	
-	mov	r0, sp
-	mov	r1, #0
-	ldr	r2, =main
-	adr	r3, 1f
-	ldr	r4, =__libc_init
-# Use blx intead of bx so stack unwinding past __libc_init can terminate at _start
-	blx	r4
-	mov	r0, #0
-	bx	r0
-
-1:  .long   __PREINIT_ARRAY__
-    .long   __INIT_ARRAY__
-    .long   __FINI_ARRAY__
-    .long   __CTOR_LIST__
-
-	.section .preinit_array, "aw"
-	.globl __PREINIT_ARRAY__
-__PREINIT_ARRAY__:
-	.long -1
-
-	.section .init_array, "aw"
-	.globl __INIT_ARRAY__
-__INIT_ARRAY__:
-	.long -1
-
-	.section .fini_array, "aw"
-	.globl __FINI_ARRAY__
-__FINI_ARRAY__:
-	.long -1
-
-	.section .ctors, "aw"
-	.globl __CTOR_LIST__
-__CTOR_LIST__:
-	.long -1
-
-#include "__dso_handle.S"
-#include "atexit.S"
diff --git a/ndk/platforms/android-3/arch-arm/src/crtbegin_dynamic.c b/ndk/platforms/android-3/arch-arm/src/crtbegin_dynamic.c
new file mode 100644
index 0000000..edb417d
--- /dev/null
+++ b/ndk/platforms/android-3/arch-arm/src/crtbegin_dynamic.c
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2012 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.
+ */
+
+typedef struct
+{
+    void (**preinit_array)(void);
+    void (**init_array)(void);
+    void (**fini_array)(void);
+    void (**ctor_list)(void);
+} structors_array_t;
+
+extern int main(int argc, char **argv, char **env);
+
+extern void __libc_init(
+  unsigned int *elfdata,
+  void (*onexit)(void),
+  int (*slingshot)(int, char**, char**),
+  structors_array_t const * const structors
+);
+
+__attribute__ ((section (".preinit_array")))
+void (*__PREINIT_ARRAY__)(void) = (void (*)(void)) -1;
+
+__attribute__ ((section (".init_array")))
+void (*__INIT_ARRAY__)(void) = (void (*)(void)) -1;
+
+__attribute__ ((section (".fini_array")))
+void (*__FINI_ARRAY__)(void) = (void (*)(void)) -1;
+
+__attribute__ ((section (".ctors")))
+void (*__CTOR_LIST__)(void) = (void (*)(void)) -1;
+
+/* this is the small startup code that is first run when
+   any executable that is dynamically-linked with Bionic
+   runs.
+
+   it's purpose is to call __libc_init with appropriate
+   arguments, which are:
+
+    - the address of the raw data block setup by the Linux
+      kernel ELF loader
+
+    - address of an "onexit" function, not used on any
+      platform supported by Bionic
+
+    - address of the "main" function of the program.
+
+    - address of the constructor list
+*/
+
+__attribute__((visibility("hidden")))
+void _start() {
+  structors_array_t array;
+  void *elfdata;
+
+  array.preinit_array = &__PREINIT_ARRAY__;
+  array.init_array =    &__INIT_ARRAY__;
+  array.fini_array =    &__FINI_ARRAY__;
+  array.ctor_list =    &__CTOR_LIST__;
+
+  elfdata = __builtin_frame_address(0) + sizeof(void *);
+  __libc_init(elfdata, (void *) 0, &main, &array);
+}
+
+#include "__dso_handle.h"
+#include "atexit.h"
diff --git a/ndk/platforms/android-3/arch-arm/src/crtbegin_so.S b/ndk/platforms/android-3/arch-arm/src/crtbegin_so.S
deleted file mode 100644
index 9275b1e..0000000
--- a/ndk/platforms/android-3/arch-arm/src/crtbegin_so.S
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *  * Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *  * Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-# 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
-
-#ifdef CRT_LEGACY_WORKAROUND
-#include "__dso_handle.S"
-#else
-#include "__dso_handle_so.S"
-#endif
-
-#include "atexit.S"
diff --git a/ndk/platforms/android-3/arch-arm/src/atexit.S b/ndk/platforms/android-3/arch-arm/src/crtbegin_so.c
similarity index 72%
rename from ndk/platforms/android-3/arch-arm/src/atexit.S
rename to ndk/platforms/android-3/arch-arm/src/crtbegin_so.c
index b6401ed..cd0257a 100644
--- a/ndk/platforms/android-3/arch-arm/src/atexit.S
+++ b/ndk/platforms/android-3/arch-arm/src/crtbegin_so.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011 The Android Open Source Project
+ * Copyright (C) 2012 The Android Open Source Project
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -26,6 +26,14 @@
  * SUCH DAMAGE.
  */
 
+extern void __cxa_finalize(void *);
+extern void *__dso_handle;
+
+__attribute__((visibility("hidden"),destructor))
+void __on_dlclose() {
+  __cxa_finalize(&__dso_handle);
+}
+
 /* CRT_LEGACY_WORKAROUND should only be defined when building
  * this file as part of the platform's C library.
  *
@@ -41,43 +49,10 @@
  * This function must be global *and* hidden. Only the
  * code inside the same ELF binary should be able to access it.
  */
-#ifndef CRT_LEGACY_WORKAROUND
-	.arch armv5te
-	.fpu softvfp
-	.eabi_attribute 20, 1
-	.eabi_attribute 21, 1
-	.eabi_attribute 23, 3
-	.eabi_attribute 24, 1
-	.eabi_attribute 25, 1
-	.eabi_attribute 26, 2
-	.eabi_attribute 30, 4
-	.eabi_attribute 18, 4
-	.hidden	atexit
-	.code	16
-	.thumb_func
-        .text
-        .align 0
-        .global atexit
-        .type atexit, #function
-atexit: .fnstart
-.LFB0:
-	.save	{r4, lr}
-	push	{r4, lr}
-.LCFI0:
-	ldr	r3, .L3
-	mov	r1, #0
-	@ sp needed for prologue
-.LPIC0:
-	add	r3, pc
-	ldr	r2, [r3]
-        ldr     r3, =__cxa_atexit
-	blx     r3
-	pop	{r4, pc}
-.L4:
-	.align	2
-.L3:
-	.word	__dso_handle-(.LPIC0+4)
-.LFE0:
-        .fnend
-        .size atexit, . - atexit
+
+#ifdef CRT_LEGACY_WORKAROUND
+#include "__dso_handle.h"
+#else
+#include "__dso_handle_so.h"
+#include "atexit.h"
 #endif
diff --git a/ndk/platforms/android-3/arch-arm/src/crtbegin_static.S b/ndk/platforms/android-3/arch-arm/src/crtbegin_static.S
deleted file mode 100644
index 62ed4bb..0000000
--- a/ndk/platforms/android-3/arch-arm/src/crtbegin_static.S
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *  * Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *  * Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-	.text
-	.align 4
-	.type _start,#function
-	.globl _start
-
-# this is the small startup code that is first run when
-# any executable that is statically-linked with Bionic
-# runs.
-#
-# it's purpose is to call __libc_init with appropriate
-# arguments, which are:
-#
-#    - the address of the raw data block setup by the Linux
-#      kernel ELF loader
-#
-#    - address of an "onexit" function, not used on any
-#      platform supported by Bionic
-#
-#    - address of the "main" function of the program.
-#
-#    - address of the constructor list
-#
-_start:	
-	mov	r0, sp
-	mov	r1, #0
-	ldr	r2, =main
-	adr	r3, 1f
-	ldr	r4, =__libc_init
-# Use blx intead of bx so stack unwinding past __libc_init can terminate at _start
-	blx	r4
-	mov	r0, #0
-	bx	r0
-
-1:  .long   __PREINIT_ARRAY__
-    .long   __INIT_ARRAY__
-    .long   __FINI_ARRAY__
-    .long   __CTOR_LIST__
-
-	.section .preinit_array, "aw"
-	.globl __PREINIT_ARRAY__
-__PREINIT_ARRAY__:
-	.long -1
-
-	.section .init_array, "aw"
-	.globl __INIT_ARRAY__
-__INIT_ARRAY__:
-	.long -1
-
-	.section .fini_array, "aw"
-	.globl __FINI_ARRAY__
-__FINI_ARRAY__:
-	.long -1
-
-	.section .ctors, "aw"
-	.globl __CTOR_LIST__
-__CTOR_LIST__:
-	.long -1
-
-
-#include "__dso_handle.S"
-/* NOTE: atexit() is  not be provided by crtbegin_static.S, but by libc.a */
-
diff --git a/ndk/platforms/android-3/arch-arm/src/crtbegin_static.c b/ndk/platforms/android-3/arch-arm/src/crtbegin_static.c
new file mode 100644
index 0000000..0a72335
--- /dev/null
+++ b/ndk/platforms/android-3/arch-arm/src/crtbegin_static.c
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2012 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.
+ */
+
+typedef struct
+{
+    void (**preinit_array)(void);
+    void (**init_array)(void);
+    void (**fini_array)(void);
+    void (**ctor_list)(void);
+} structors_array_t;
+
+extern int main(int argc, char **argv, char **env);
+
+extern void __libc_init(
+  unsigned int *elfdata,
+  void (*onexit)(void),
+  int (*slingshot)(int, char**, char**),
+  structors_array_t const * const structors
+);
+
+__attribute__ ((section (".preinit_array")))
+void (*__PREINIT_ARRAY__)(void) = (void (*)(void)) -1;
+
+__attribute__ ((section (".init_array")))
+void (*__INIT_ARRAY__)(void) = (void (*)(void)) -1;
+
+__attribute__ ((section (".fini_array")))
+void (*__FINI_ARRAY__)(void) = (void (*)(void)) -1;
+
+__attribute__ ((section (".ctors")))
+void (*__CTOR_LIST__)(void) = (void (*)(void)) -1;
+
+/* this is the small startup code that is first run when
+   any executable that is statically-linked with Bionic
+   runs.
+
+   it's purpose is to call __libc_init with appropriate
+   arguments, which are:
+
+    - the address of the raw data block setup by the Linux
+      kernel ELF loader
+
+    - address of an "onexit" function, not used on any
+      platform supported by Bionic
+
+    - address of the "main" function of the program.
+
+    - address of the constructor list
+*/
+
+__attribute__((visibility("hidden")))
+void _start() {
+  structors_array_t array;
+  void *elfdata;
+
+  array.preinit_array = &__PREINIT_ARRAY__;
+  array.init_array =    &__INIT_ARRAY__;
+  array.fini_array =    &__FINI_ARRAY__;
+  array.ctor_list =    &__CTOR_LIST__;
+
+  elfdata = __builtin_frame_address(0) + sizeof(void *);
+  __libc_init(elfdata, (void *) 0, &main, &array);
+}
+
+#include "__dso_handle.h"
+/* NOTE: atexit() is  not be provided by crtbegin_static.c, but by libc.a */