Browse Source

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.

Joakim Tjernlund 19 years ago
parent
commit
e3006e038e
4 changed files with 136 additions and 35 deletions
  1. 1 1
      libc/Makefile
  2. 3 20
      libc/misc/internals/__uClibc_main.c
  3. 7 14
      libc/sysdeps/linux/i386/Makefile
  4. 125 0
      libc/sysdeps/linux/i386/crt1.S

+ 1 - 1
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)

+ 3 - 20
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);
-}
-

+ 7 - 14
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

+ 125 - 0
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
+