summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoakim Tjernlund <joakim.tjernlund@transmode.se>2005-05-21 21:19:43 +0000
committerJoakim Tjernlund <joakim.tjernlund@transmode.se>2005-05-21 21:19:43 +0000
commite3006e038e293a5d52627c9200316acee37ec5fb (patch)
treeec0d2a6217ab4d90504bf764e5f1074fc87089f8
parentbd22e54f65f260f5ea9591a1a60d1686e7dfd052 (diff)
Pass main function ptr from crt1 to __uClibc_start_main.
Kill old crt0/__uClibc_main. This breaks ABI. All apps and toolchain needs to be recompiled. All archs except x86 are now broken and need to be fixed as x86. PPC will be fixed shortly by me, the rest is left to the arch maintainers.
-rw-r--r--libc/Makefile2
-rw-r--r--libc/misc/internals/__uClibc_main.c23
-rw-r--r--libc/sysdeps/linux/i386/Makefile21
-rw-r--r--libc/sysdeps/linux/i386/crt1.S125
4 files changed, 136 insertions, 35 deletions
diff --git a/libc/Makefile b/libc/Makefile
index fc31a2cbb..1df8c801e 100644
--- a/libc/Makefile
+++ b/libc/Makefile
@@ -74,7 +74,7 @@ $(LIBNAME_TARGET): $(LIBNAME)
$(INSTALL) -m 644 $(LIBNAME) $(TOPDIR)lib
shared: $(LIBNAME)
- $(LD) $(LDFLAGS) $(VERSION_SCRIPT) -soname=$(SHARED_MAJORNAME) -o $(SHARED_FULLNAME) \
+ $(LD) $(LDFLAGS) -z defs $(VERSION_SCRIPT) -soname=$(SHARED_MAJORNAME) -o $(SHARED_FULLNAME) \
--whole-archive $(LIBNAME) \
$(TOPDIR)libc/misc/internals/interp.o --no-whole-archive \
-init __uClibc_init $(LIBGCC) $(LDADD_LIBFLOAT)
diff --git a/libc/misc/internals/__uClibc_main.c b/libc/misc/internals/__uClibc_main.c
index a33e6fe4a..70dc07328 100644
--- a/libc/misc/internals/__uClibc_main.c
+++ b/libc/misc/internals/__uClibc_main.c
@@ -32,7 +32,6 @@ extern void __guard_setup(void);
/*
* Prototypes.
*/
-extern int main(int argc, char **argv, char **envp);
extern void weak_function _stdio_init(void);
extern int *weak_const_function __errno_location(void);
extern int *weak_const_function __h_errno_location(void);
@@ -166,7 +165,9 @@ void attribute_hidden (*__rtld_fini)(void) = NULL;
*/
void __attribute__ ((__noreturn__))
__uClibc_start_main(int argc, char **argv, char **envp,
- void (*app_init)(void), void (*app_fini)(void), void (*rtld_fini)(void))
+ void (*app_init)(void), void (*app_fini)(void),
+ int (*main)(int argc, char **argv, char **envp),
+ void (*rtld_fini)(void))
{
#ifdef __ARCH_HAS_MMU__
unsigned long *aux_dat;
@@ -249,21 +250,3 @@ __uClibc_start_main(int argc, char **argv, char **envp,
*/
exit(main(argc, argv, envp));
}
-
-
-/* __uClibc_main is the old main stub of the uClibc. This
- * function is called from crt0 (uClibc 0.9.15 and older) after
- * ALL shared libraries are initialized, and just before we call
- * the application's main() function.
- *
- * Attention: This stub does not call the .init/.fini sections of
- * the application. If you need this, please fix your uClibc port
- * so that __uClibc_start_main is called by your crt0.S with
- * _init and _fini properly set.
-*/
-void __attribute__ ((__noreturn__))
-__uClibc_main(int argc, char **argv, char ** envp)
-{
- __uClibc_start_main(argc, argv, envp, NULL, NULL, NULL);
-}
-
diff --git a/libc/sysdeps/linux/i386/Makefile b/libc/sysdeps/linux/i386/Makefile
index d9bf0239a..e29707f0e 100644
--- a/libc/sysdeps/linux/i386/Makefile
+++ b/libc/sysdeps/linux/i386/Makefile
@@ -19,10 +19,9 @@
TOPDIR=../../../../
include $(TOPDIR)Rules.mak
-CRT0_SRC = crt0.S
-CRT0_OBJ = crt0.o crt1.o
-SCRT0_OBJ = $(patsubst %,S%, $(CRT0_OBJ))
-CRT0_DEPS=gmon-start.S
+CRT_SRC = crt1.S
+CRT_OBJ = crt1.o
+SCRT_OBJ = $(patsubst %,S%, $(CRT_OBJ))
CTOR_TARGETS=$(TOPDIR)lib/crti.o $(TOPDIR)lib/crtn.o
SSRC=__longjmp.S vfork.S clone.S setjmp.S bsd-setjmp.S \
@@ -38,21 +37,16 @@ OBJ_LIST=../../../obj.sysdeps.$(TARGET_ARCH)
all: $(OBJ_LIST)
-$(OBJ_LIST): $(OBJS) $(CRT0_OBJ) $(SCRT0_OBJ) $(CTOR_TARGETS)
+$(OBJ_LIST): $(OBJS) $(CRT_OBJ) $(SCRT_OBJ) $(CTOR_TARGETS)
echo $(patsubst %, sysdeps/linux/$(TARGET_ARCH)/%, $(OBJS)) > $(OBJ_LIST)
$(INSTALL) -d $(TOPDIR)lib/
- cp $(CRT0_OBJ) $(SCRT0_OBJ) $(TOPDIR)lib/
-ifeq ($(strip $(UCLIBC_CTOR_DTOR)),y)
- $(RM) $(TOPDIR)lib/Scrt0.o
-else
- mv $(TOPDIR)lib/Scrt0.o $(TOPDIR)lib/Scrt1.o
-endif
+ cp $(CRT_OBJ) $(SCRT_OBJ) $(TOPDIR)lib/
-$(CRT0_OBJ): $(CRT0_SRC)
+$(CRT_OBJ): $(CRT_SRC)
$(CC) $(ASFLAGS) -DL_$* $< -c -o $*.o
$(STRIPTOOL) -x -R .note -R .comment $*.o
-$(SCRT0_OBJ): $(CRT0_SRC)
+$(SCRT_OBJ): $(CRT_SRC)
$(CC) $(ASFLAGS) $(PIEFLAG) -DL_$* $< -c -o $*.o
$(STRIPTOOL) -x -R .note -R .comment $*.o
@@ -94,4 +88,3 @@ clean:
$(RM) *.[oa] *~ core
$(RM) bits/sysnum.h
$(RM) $(TOPDIR)/include/fpu_control.h
- $(RM) gmon-start.S
diff --git a/libc/sysdeps/linux/i386/crt1.S b/libc/sysdeps/linux/i386/crt1.S
new file mode 100644
index 000000000..76e71be56
--- /dev/null
+++ b/libc/sysdeps/linux/i386/crt1.S
@@ -0,0 +1,125 @@
+/* Copyright (C) 1991, 1992 Free Software Foundation, Inc.
+This file is part of the GNU C Library.
+
+The GNU C Library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public License as
+published by the Free Software Foundation; either version 2 of the
+License, or (at your option) any later version.
+
+The GNU C Library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB. If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA. */
+
+
+/* Based on the code from GNU libc, but hacked up by John Beppu and Erik Andersen */
+/* adapted by PaX Team for ET_DYN/PIE binaries */
+
+/*
+ When we enter this piece of code, the program stack looks like this:
+ argc argument counter (integer)
+ argv[0] program name (pointer)
+ argv[1...N] program args (pointers)
+ argv[argc-1] end of args (integer)
+ NULL
+ env[0...N] environment variables (pointers)
+ NULL
+*/
+
+#include <features.h>
+
+.text
+ .align 4
+
+ .global _start
+ .type _start,%function
+ .weak _init
+ .weak _fini
+ .type __uClibc_start_main,%function
+
+_start:
+ /* locate the start of the environment variables */
+ popl %ecx /* Store argc into %ecx */
+ movl %esp,%ebx /* Store argv into ebx */
+ movl %esp,%eax /* Store argv into eax as well*/
+ movl %edx,%esi /* Store edx(FINI ptr) in %esi */
+ movl %ecx,%edx /* Stick argc into %edx so we can do some math in a sec */
+ leal 4(%eax,%edx,4),%eax
+
+ /* [ register layout ]
+
+ sizeof(char*) == 4
+ %ecx = argc ; 0(esp)
+ %ebx = argv ; 4(esp)
+ %eax = env ; argv + (argc * 4) + 4
+ */
+ xorl %ebp,%ebp /* NULL */
+ /*
+ Before pushing the arguments align the stack to a 16-byte
+ (SSE needs 16-byte alignment) boundary to avoid penalties from
+ misaligned accesses. Thanks to Edward Seidl <seidl@janed.com>
+ for pointing this out.
+ */
+ andl $0xfffffff0, %esp
+ /* Push NULL to make sure stack ptr
+ is 16 byte aligned when calling __uClibc_start_main */
+ pushl %ebp
+ pushl %ebp
+
+ /* Set up an invalid (NULL return address, NULL frame pointer)
+ callers stack frame so anybody unrolling the stack knows where
+ to stop */
+ pushl %ebp /* callers %cs */
+ pushl %ebp /* callers %eip (return address) */
+ pushl %ebp /* callers %ebp (frame pointer) */
+ movl %esp,%ebp /* mark callers stack frame as invalid */
+
+#if defined L_Scrt1
+ call .L0
+.L0:
+ pop %edx
+ addl $_GLOBAL_OFFSET_TABLE_+[.-.L0],%edx
+#endif
+ pushl %esi /* Push FINI pointer */
+
+ /* Push apps .init, .fini and main arguments to __uClibc_start_main() on the stack */
+#ifdef L_Scrt1
+ pushl main@GOT(%edx)
+ pushl _fini@GOT(%edx)
+ pushl _init@GOT(%edx)
+#else
+ pushl $main
+ pushl $_fini
+ pushl $_init
+#endif
+
+ /* Push envp, argc, and argc arguments to __uClibc_start_main() on the stack */
+ pushl %eax /* Environment pointer */
+ pushl %ebx /* Argument pointer */
+ pushl %ecx /* And the argument count */
+
+ /* Ok, now run uClibc's main() -- shouldn't return */
+#ifdef L_Scrt1
+ call *__uClibc_start_main@GOT(%edx)
+#else
+ call __uClibc_start_main
+#endif
+
+ /* Crash if somehow `exit' returns anyways. */
+ hlt
+.size _start,.-_start
+
+
+/* Define a symbol for the first piece of initialized data. */
+ .data
+ .globl __data_start
+__data_start:
+ .long 0
+ .weak data_start
+ data_start = __data_start
+