Replace .S version of x86 crtfiles with .c version

This patch replaces .S versions of x86 crtfiles with .c which are much
easier to support. Some of the files are matching .c version of Arm
crtfiles. x86 files required some cleanup anyway and this cleanup actually
led to matching Arm files.

I didn't change anything to share the same crt*.c between x86 and Arm. I
prefer to keep them separate for a while in case any change is required
for one of the arch, but it's good thing to do in the following patches.

Change-Id: Ibcf033f8d15aa5b10c05c879fd4b79a64dfc70f3
Signed-off-by: Pavel Chupin <pavel.v.chupin@intel.com>
diff --git a/libc/Android.mk b/libc/Android.mk
index a64287a..92bca4c 100644
--- a/libc/Android.mk
+++ b/libc/Android.mk
@@ -623,7 +623,7 @@
     libc_crt_target_so_cflags := -fPIC
 endif
 ifeq ($(TARGET_ARCH),x86)
-    libc_crtbegin_extension := S
+    libc_crtbegin_extension := c
     libc_crt_target_so_cflags := -fPIC
 endif
 ifeq ($(libc_crtbegin_extension),)
diff --git a/libc/arch-x86/bionic/__dso_handle.S b/libc/arch-x86/bionic/__dso_handle.S
deleted file mode 100644
index 3e80128..0000000
--- a/libc/arch-x86/bionic/__dso_handle.S
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * 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
-
-#ifndef CRT_LEGACY_WORKAROUND
-	.hidden __dso_handle
-#endif
-
-        .globl __dso_handle
-__dso_handle:
-        .long 0
diff --git a/libc/arch-x86/bionic/__stack_chk_fail_local.S b/libc/arch-x86/bionic/__stack_chk_fail_local.S
deleted file mode 100644
index 59fe86e..0000000
--- a/libc/arch-x86/bionic/__stack_chk_fail_local.S
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2011 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.
- */
-/*
- * Contributed by: Intel Corporation
- */
-
-	.text
-	.p2align 4,,15
-	.globl	__stack_chk_fail_local
-	.hidden	__stack_chk_fail_local
-	.type	__stack_chk_fail_local, @function
-
-__stack_chk_fail_local:
-#ifdef __PIC__
-	pushl	%ebx
-	call	__x86.get_pc_thunk.bx
-	addl	$_GLOBAL_OFFSET_TABLE_, %ebx
-	call	__stack_chk_fail@PLT
-#else /* PIC */
-	jmp   __stack_chk_fail
-#endif /* not PIC */
-
-	.size	__stack_chk_fail_local, .-__stack_chk_fail_local
diff --git a/libc/arch-x86/bionic/__stack_chk_fail_local.h b/libc/arch-x86/bionic/__stack_chk_fail_local.h
new file mode 100755
index 0000000..4f3699a
--- /dev/null
+++ b/libc/arch-x86/bionic/__stack_chk_fail_local.h
@@ -0,0 +1,60 @@
+/*
+ * 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.
+ */
+
+
+/*
+   __stack_chk_fail routine is runtime part of stack protector compiler
+   feature. It's implemented in libc and represents die routine when stack
+   corruption is detected.
+
+   Calls are generated by compiler and injected into user functions when
+   -fstack-protector* options are used.
+
+   __stack_chk_fail_local is wrapper for __stack_chk_fail. Compiler generates
+   wrapper calls instead for PIC code only and only on IA32 for optimization
+   purpose (see gcc/config/i386/i386.c). Wrapper body is always included into
+   executable or library. This is the idea of optimization.
+
+   Glibc is doing this via libc_nonshared.a which is linked automatically
+   everytime with libc.so. In bionic we have to bring it within crtfiles
+   because libc.so is real library and not a link script like libc.so at glibc.
+
+   For x86_64 or non-PIC code compiler always generates __stack_chk_fail calls.
+*/
+
+#ifdef __i386__
+#ifdef __PIC__
+extern void __stack_chk_fail();
+
+__attribute__ ((visibility ("hidden")))
+void __stack_chk_fail_local()
+{
+  __stack_chk_fail();
+}
+#endif
+#endif
diff --git a/libc/arch-x86/bionic/atexit.S b/libc/arch-x86/bionic/atexit.S
deleted file mode 100644
index b28f40b..0000000
--- a/libc/arch-x86/bionic/atexit.S
+++ /dev/null
@@ -1,66 +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
-	.p2align 4,,15
-	.globl	atexit
-	.hidden	atexit
-	.type	atexit, @function
-atexit:
-	pushl	%ebp
-	movl	%esp, %ebp
-	pushl	%ebx
-	call	__x86.get_pc_thunk.bx
-	addl	$_GLOBAL_OFFSET_TABLE_, %ebx
-	subl	$20, %esp
-	movl	$0, 4(%esp)
-	movl	__dso_handle@GOTOFF(%ebx), %eax
-	movl	%eax, 8(%esp)
-	movl	8(%ebp), %eax
-	movl	%eax, (%esp)
-	call	__cxa_atexit@PLT
-	addl	$20, %esp
-	popl	%ebx
-	popl	%ebp
-	ret
-	.size	atexit, .-atexit
-
-	.section	.text.__x86.get_pc_thunk.bx,"axG",@progbits,__x86.get_pc_thunk.bx,comdat
-	.globl	__x86.get_pc_thunk.bx
-	.hidden	__x86.get_pc_thunk.bx
-	.type	__x86.get_pc_thunk.bx, @function
-__x86.get_pc_thunk.bx:
-	nop
-	nop
-	nop
-	nop
-	nop
-	nop
-	nop
-	nop
-	movl	(%esp), %ebx
-	ret
diff --git a/libc/arch-x86/bionic/__dso_handle_so.S b/libc/arch-x86/bionic/atexit.h
similarity index 79%
rename from libc/arch-x86/bionic/__dso_handle_so.S
rename to libc/arch-x86/bionic/atexit.h
index 77a5d7f..bc776a8 100644
--- a/libc/arch-x86/bionic/__dso_handle_so.S
+++ b/libc/arch-x86/bionic/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/libc/arch-x86/bionic/crtbegin.S b/libc/arch-x86/bionic/crtbegin.S
deleted file mode 100644
index 39b6af0..0000000
--- a/libc/arch-x86/bionic/crtbegin.S
+++ /dev/null
@@ -1,138 +0,0 @@
-# bionic/arch-x86/bionic/crtbegin_dynamic.S
-#
-# Copyright 2006, The Android Open Source Project
-#
-# 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.
-#     * Neither the name of Google Inc. nor the names of its contributors may
-#       be used to endorse or promote products derived from this software
-#       without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY Google Inc. ``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 Google Inc. 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 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. We
-#      can't hard-code it in the adr pseudo instruction
-#      so we use a tiny trampoline that will get relocated
-#      by the dynamic linker before this code runs
-#
-#    - address of the constructor list
-#
-_start:	
-        mov     %esp, %eax
-        # before push arguments, align the stack to a 16 byte boundary
-        andl    $~15, %esp
-        mov     $1f, %edx
-        pushl   %edx
-        mov     $0f, %edx
-        pushl   %edx
-        mov     $0, %edx
-        pushl   %edx
-        pushl   %eax
-        call     __libc_init
-
-0:
-        jmp   main
-
-1:  .long   __PREINIT_ARRAY__
-    .long   __INIT_ARRAY__
-    .long   __FINI_ARRAY__
-
-	.section .preinit_array, "aw"
-	.globl __PREINIT_ARRAY__
-__PREINIT_ARRAY__:
-	.long -1
-
-	.section .init_array, "aw"
-	.globl __INIT_ARRAY__
-__INIT_ARRAY__:
-	.long -1
-	.long	frame_dummy
-
-	.section .fini_array, "aw"
-	.globl __FINI_ARRAY__
-__FINI_ARRAY__:
-	.long -1
-	.long	__do_global_dtors_aux
-
-	.section	.eh_frame,"a",@progbits
-	.align 4
-	.type	__EH_FRAME_BEGIN__, @object
-__EH_FRAME_BEGIN__:
-	.text
-	.p2align 4,,15
-	.type	__do_global_dtors_aux, @function
-__do_global_dtors_aux:
-	pushl	%ebp
-	movl	%esp, %ebp
-	subl	$24, %esp
-	cmpb	$0, completed.4454
-	jne	.L4
-	movl	$__deregister_frame_info_bases, %eax
-	testl	%eax, %eax
-	je	.L3
-	movl	$__EH_FRAME_BEGIN__, (%esp)
-	call	__deregister_frame_info_bases
-.L3:
-	movb	$1, completed.4454
-.L4:
-	leave
-	ret
-	.text
-	.p2align 4,,15
-	.type	frame_dummy, @function
-frame_dummy:
-	pushl	%ebp
-	movl	$__register_frame_info_bases, %eax
-	movl	%esp, %ebp
-	subl	$24, %esp
-	testl	%eax, %eax
-	je	.L7
-	movl	%ebx, 12(%esp)
-	movl	$0, 8(%esp)
-	movl	$object.4466, 4(%esp)
-	movl	$__EH_FRAME_BEGIN__, (%esp)
-	call	__register_frame_info_bases
-.L7:
-	leave
-	ret
-	.local	completed.4454
-	.comm	completed.4454,1,1
-	.local	object.4466
-	.comm	object.4466,24,4
-	.weak	__register_frame_info_bases
-	.weak	__deregister_frame_info_bases
-
-#include "__dso_handle.S"
-#include "atexit.S"
-#include "__stack_chk_fail_local.S"
diff --git a/libc/arch-x86/bionic/crtbegin.c b/libc/arch-x86/bionic/crtbegin.c
new file mode 100755
index 0000000..5106d9e
--- /dev/null
+++ b/libc/arch-x86/bionic/crtbegin.c
@@ -0,0 +1,70 @@
+/*
+ * 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);
+} 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__((visibility("hidden")))
+__attribute__((force_align_arg_pointer))
+void _start() {
+  structors_array_t array;
+  void *elfdata;
+
+  array.preinit_array = &__PREINIT_ARRAY__;
+  array.init_array =    &__INIT_ARRAY__;
+  array.fini_array =    &__FINI_ARRAY__;
+
+  elfdata = __builtin_frame_address(0) + sizeof(void *);
+  __libc_init(elfdata, (void *) 0, &main, &array);
+}
+
+#include "__dso_handle.h"
+#include "atexit.h"
+#include "__stack_chk_fail_local.h"
diff --git a/libc/arch-x86/bionic/crtbegin_so.S b/libc/arch-x86/bionic/crtbegin_so.S
deleted file mode 100644
index 99662fe..0000000
--- a/libc/arch-x86/bionic/crtbegin_so.S
+++ /dev/null
@@ -1,111 +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.
- */
-
-.section .init_array, "aw"
-.align 4
-.type __INIT_ARRAY__, @object
-.globl __INIT_ARRAY__
-__INIT_ARRAY__:
-    .long -1
-    .long frame_dummy
-
-.section .fini_array, "aw"
-.align 4
-.type __FINI_ARRAY__, @object
-.globl __FINI_ARRAY__
-__FINI_ARRAY__:
-    .long -1
-    .long __do_global_dtors_aux
-
-	.section	.eh_frame,"a",@progbits
-	.align 4
-	.type	__EH_FRAME_BEGIN__, @object
-__EH_FRAME_BEGIN__:
-	.text
-	.p2align 4,,15
-	.type	__do_global_dtors_aux, @function
-__do_global_dtors_aux:
-	pushl	%ebp
-	movl	%esp, %ebp
-	pushl	%ebx
-	call	__x86.get_pc_thunk.bx
-	addl	$_GLOBAL_OFFSET_TABLE_, %ebx
-	subl	$20, %esp
-	cmpb	$0, completed.4454@GOTOFF(%ebx)
-	jne	.L5
-	movl	__dso_handle@GOTOFF(%ebx), %eax
-	movl	%eax, (%esp)
-	call	__cxa_finalize@PLT
-	movl	__deregister_frame_info_bases@GOT(%ebx), %eax
-	testl	%eax, %eax
-	je	.L4
-	leal	__EH_FRAME_BEGIN__@GOTOFF(%ebx), %eax
-	movl	%eax, (%esp)
-	call	__deregister_frame_info_bases@PLT
-.L4:
-	movb	$1, completed.4454@GOTOFF(%ebx)
-.L5:
-	addl	$20, %esp
-	popl	%ebx
-	popl	%ebp
-	ret
-	.text
-	.p2align 4,,15
-	.type	frame_dummy, @function
-frame_dummy:
-	pushl	%ebp
-	movl	%esp, %ebp
-	pushl	%ebx
-	call	__x86.get_pc_thunk.bx
-	addl	$_GLOBAL_OFFSET_TABLE_, %ebx
-	subl	$20, %esp
-	movl	__register_frame_info_bases@GOT(%ebx), %eax
-	testl	%eax, %eax
-	je	.L8
-	leal	object.4469@GOTOFF(%ebx), %eax
-	movl	%eax, 4(%esp)
-	leal	__EH_FRAME_BEGIN__@GOTOFF(%ebx), %eax
-	movl	%ebx, 12(%esp)
-	movl	$0, 8(%esp)
-	movl	%eax, (%esp)
-	call	__register_frame_info_bases@PLT
-.L8:
-	addl	$20, %esp
-	popl	%ebx
-	popl	%ebp
-	ret
-	.local	completed.4454
-	.comm	completed.4454,1,1
-	.local	object.4469
-	.comm	object.4469,24,4
-	.weak	__register_frame_info_bases
-	.weak	__deregister_frame_info_bases
-
-#include "__dso_handle_so.S"
-#include "atexit.S"
-#include "__stack_chk_fail_local.S"
diff --git a/libc/arch-x86/bionic/crtbegin_so.c b/libc/arch-x86/bionic/crtbegin_so.c
new file mode 100755
index 0000000..30de6af
--- /dev/null
+++ b/libc/arch-x86/bionic/crtbegin_so.c
@@ -0,0 +1,59 @@
+/*
+ * 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.
+ */
+
+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.
+ *
+ * The C library already defines a function named 'atexit()'
+ * for backwards compatibility with older NDK-generated binaries.
+ *
+ * For newer ones, 'atexit' is actually embedded in the C
+ * runtime objects that are linked into the final ELF
+ * binary (shared library or executable), and will call
+ * __cxa_atexit() in order to un-register any atexit()
+ * handler when a library is unloaded.
+ *
+ * This function must be global *and* hidden. Only the
+ * code inside the same ELF binary should be able to access it.
+ */
+
+#ifdef CRT_LEGACY_WORKAROUND
+#include "__dso_handle.h"
+#else
+#include "__dso_handle_so.h"
+#include "atexit.h"
+#include "__stack_chk_fail_local.h"
+#endif
diff --git a/linker/Android.mk b/linker/Android.mk
index e3bbffa..b757030 100644
--- a/linker/Android.mk
+++ b/linker/Android.mk
@@ -1,8 +1,14 @@
 LOCAL_PATH:= $(call my-dir)
 include $(CLEAR_VARS)
 
+ifeq ($(TARGET_ARCH),x86)
+    linker_begin_extension := c
+else
+    linker_begin_extension := S
+endif
+
 LOCAL_SRC_FILES:= \
-	arch/$(TARGET_ARCH)/begin.S \
+	arch/$(TARGET_ARCH)/begin.$(linker_begin_extension) \
 	debugger.cpp \
 	dlfcn.cpp \
 	linker.cpp \
diff --git a/linker/arch/x86/begin.S b/linker/arch/x86/begin.c
old mode 100644
new mode 100755
similarity index 62%
rename from linker/arch/x86/begin.S
rename to linker/arch/x86/begin.c
index baa386f..2ca15c4
--- a/linker/arch/x86/begin.S
+++ b/linker/arch/x86/begin.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008 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,22 +26,30 @@
  * SUCH DAMAGE.
  */
 
-.text
-.align 4
-.type _start, @function
-.globl _start
+extern unsigned __linker_init(unsigned int *elfdata);
 
-_start:
-        /* save the elfdata ptr to %eax, AND push it onto the stack */
-        mov    %esp, %eax
-        pushl  %esp
+__attribute__((visibility("hidden")))
+void _start() {
+  void *elfdata;
+  void (*start)(void);
 
-        pushl  %eax
-        call   __linker_init
+  elfdata = __builtin_frame_address(0) + sizeof(void *);
+  start = (void(*)(void))__linker_init(elfdata);
 
-        /* linker init returns (%eax) the _entry address in the main image */
-        /* entry point expects sp to point to elfdata */
-        popl   %esp
-        jmp    *%eax
+  /* linker init returns (%eax) the _entry address in the main image */
+  /* entry point expects sp to point to elfdata */
 
-#include "arch-x86/bionic/__stack_chk_fail_local.S"
+  __asm__ (
+     "mov %0, %%esp\n\t"
+     "jmp *%1\n\t"
+     : : "r"(elfdata), "r"(start) :
+  );
+
+  /* Unreachable */
+}
+
+/* Since linker has its own version of crtbegin (this file) it should have */
+/* own version of __stack_chk_fail_local for the case when it's built with */
+/* stack protector feature */
+
+#include "arch-x86/bionic/__stack_chk_fail_local.h"