From d1b0dffff4be58782a15ebec6595de2447f63dc2 Mon Sep 17 00:00:00 2001 From: Joakim Tjernlund Date: Sat, 28 May 2005 23:44:06 +0000 Subject: Add Peter Mazinger fini/crt compat patch. Select DL_FINI_CRT_COMPAT to be able to run apps built with 0.9.27. This also renames __uClibc_start_main to __uClibc_main. This compat option should be removed some time after 0.9.28 is released. Let me know if you don't like this change. --- Rules.mak | 4 ++++ extra/Configs/Config.in | 7 +++++++ ldso/ldso/Makefile | 4 ++++ ldso/ldso/ldso.c | 10 ++++++++++ libc/misc/internals/__uClibc_main.c | 12 +++++++++++- libc/stdlib/atexit.c | 2 ++ libc/sysdeps/linux/arm/Makefile | 7 +------ libc/sysdeps/linux/arm/crt0.S | 10 +--------- libc/sysdeps/linux/i386/crt1.S | 6 +++--- libc/sysdeps/linux/mips/crt1.S | 9 ++++----- libc/sysdeps/linux/powerpc/crt1.S | 9 ++++----- 11 files changed, 51 insertions(+), 29 deletions(-) diff --git a/Rules.mak b/Rules.mak index 03ed52ec0..746420e1e 100644 --- a/Rules.mak +++ b/Rules.mak @@ -307,6 +307,10 @@ ifeq ($(DOPIC),y) CFLAGS += $(PICFLAG) endif +ifeq ($(DL_FINI_CRT_COMPAT),y) +CFLAGS += -D_DL_FINI_CRT_COMPAT +endif + ASFLAGS = $(CFLAGS) ifeq ($(UCLIBC_BUILD_NOEXECSTACK),y) ASFLAGS += $(call check_as,--noexecstack) diff --git a/extra/Configs/Config.in b/extra/Configs/Config.in index 137d22797..b77ae04fc 100644 --- a/extra/Configs/Config.in +++ b/extra/Configs/Config.in @@ -264,6 +264,13 @@ config LDSO_BASE_FILENAME WARNING: Changing the default prefix could cause problems with binutils' ld ! +config DL_FINI_CRT_COMPAT + bool "uClibc 0.9.27 compatibility" + default n + help + Allows to update a 0.9.27 based system to new crt/fini handling. + After rebuilding all apps, this option can be disabled. + config UCLIBC_CTOR_DTOR bool "Support global constructors and destructors" default y diff --git a/ldso/ldso/Makefile b/ldso/ldso/Makefile index e18b292f6..f2707d820 100644 --- a/ldso/ldso/Makefile +++ b/ldso/ldso/Makefile @@ -28,6 +28,10 @@ ASFLAGS+=$(call check_as,--noexecstack) endif XXFLAGS=$(XWARNINGS) $(SSP_DISABLE_FLAGS) +ifeq ($(DL_FINI_CRT_COMPAT),y) +XXFLAGS+=-D_DL_FINI_CRT_COMPAT +endif + ifeq ($(DODEBUG),y) # Not really much point in including debugging info, since gdb # can't really debug ldso, since gdb requires help from ldso to diff --git a/ldso/ldso/ldso.c b/ldso/ldso/ldso.c index c60815aff..c0f685802 100644 --- a/ldso/ldso/ldso.c +++ b/ldso/ldso/ldso.c @@ -806,6 +806,16 @@ void _dl_get_ready_to_run(struct elf_resolve *tpnt, unsigned long load_addr, (*dl_elf_func) (); } } +#ifdef _DL_FINI_CRT_COMPAT + /* arches that have moved their ldso FINI handling should skip this part */ + { + int (*_dl_atexit) (void *) = (int (*)(void *)) (intptr_t) _dl_find_hash("atexit", + _dl_symbol_tables, NULL, ELF_RTYPE_CLASS_PLT); + + if (_dl_atexit) + (*_dl_atexit) (_dl_fini); + } +#endif /* Find the real malloc function and make ldso functions use that from now on */ _dl_malloc_function = (void* (*)(size_t)) (intptr_t) _dl_find_hash("malloc", diff --git a/libc/misc/internals/__uClibc_main.c b/libc/misc/internals/__uClibc_main.c index 69a03d345..071d6d613 100644 --- a/libc/misc/internals/__uClibc_main.c +++ b/libc/misc/internals/__uClibc_main.c @@ -164,7 +164,7 @@ void attribute_hidden (*__rtld_fini)(void) = NULL; * are initialized, just before we call the application's main function. */ void __attribute__ ((__noreturn__)) -__uClibc_start_main(int (*main)(int, char **, char **), int argc, +__uClibc_main(int (*main)(int, char **, char **), int argc, char **argv, void (*app_init)(void), void (*app_fini)(void), void (*rtld_fini)(void), void *stack_end) { @@ -253,3 +253,13 @@ __uClibc_start_main(int (*main)(int, char **, char **), int argc, */ exit(main(argc, argv, __environ)); } + +#ifdef _DL_FINI_CRT_COMPAT +extern int weak_function main(int argc, char **argv, char **envp); +void __attribute__ ((__noreturn__)) +__uClibc_start_main(int argc, char **argv, char **envp, + void (*app_fini)(void), void (*app_init)(void)) +{ + __uClibc_main(main, argc, argv, app_init, app_fini, NULL, NULL); +} +#endif diff --git a/libc/stdlib/atexit.c b/libc/stdlib/atexit.c index 87a49a015..280f42cb7 100644 --- a/libc/stdlib/atexit.c +++ b/libc/stdlib/atexit.c @@ -239,8 +239,10 @@ void exit(int rv) if (__app_fini != NULL) (__app_fini)(); #endif +#ifndef _DL_FINI_CRT_COMPAT if (__rtld_fini != NULL) (__rtld_fini)(); +#endif /* If we are using stdio, try to shut it down. At the very least, * this will attempt to commit all buffered writes. It may also diff --git a/libc/sysdeps/linux/arm/Makefile b/libc/sysdeps/linux/arm/Makefile index 1a11e43ef..ca41ff6e7 100644 --- a/libc/sysdeps/linux/arm/Makefile +++ b/libc/sysdeps/linux/arm/Makefile @@ -20,7 +20,7 @@ TOPDIR=../../../../ include $(TOPDIR)Rules.mak CRT0_SRC = crt0.S -CRT0_OBJ = crt0.o crt1.o +CRT0_OBJ = crt1.o SCRT0_OBJ = $(patsubst %,S%, $(CRT0_OBJ)) CTOR_TARGETS=$(TOPDIR)lib/crti.o $(TOPDIR)lib/crtn.o @@ -41,11 +41,6 @@ $(OBJ_LIST): $(OBJS) $(CRT0_OBJ) $(SCRT0_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 $(CRT0_OBJ): $(CRT0_SRC) $(CC) $(ASFLAGS) -DL_$* $< -c -o $*.o diff --git a/libc/sysdeps/linux/arm/crt0.S b/libc/sysdeps/linux/arm/crt0.S index f58885d17..4f4a8cefd 100644 --- a/libc/sysdeps/linux/arm/crt0.S +++ b/libc/sysdeps/linux/arm/crt0.S @@ -51,13 +51,9 @@ ARM register quick reference: .text .global _start .type _start,%function -#if defined L_crt0 || ! defined __UCLIBC_CTOR_DTOR__ - .type __uClibc_main,%function -#else .weak _init .weak _fini .type __uClibc_start_main,%function -#endif /* Stick in a dummy reference to main(), so that if an application * is linking when the main() function is in a static library (.a) * we can be sure that main() actually gets linked in */ @@ -92,7 +88,6 @@ _start: ldr r2,[sp, #8] #endif -#if (defined L_crt1 ) && defined __UCLIBC_CTOR_DTOR__ #ifdef __PIC__ /* Store the address of _init in r3 as an argument to main() */ adr r5, .L_init @@ -113,14 +108,11 @@ _start: /* Ok, now run uClibc's main() -- shouldn't return */ bl __uClibc_start_main -#else - bl __uClibc_main -#endif /* Crash if somehow `exit' returns anyways. */ bl abort -#if (defined L_crt1 ) && defined __UCLIBC_CTOR_DTOR__ && defined __PIC__ +#ifdef __PIC__ .L_init: .word _init - .L_init .word _fini - .L_init diff --git a/libc/sysdeps/linux/i386/crt1.S b/libc/sysdeps/linux/i386/crt1.S index 47de89d9a..fe927d9eb 100644 --- a/libc/sysdeps/linux/i386/crt1.S +++ b/libc/sysdeps/linux/i386/crt1.S @@ -60,7 +60,7 @@ .type _init,%function .type _fini,%function .type main,%function - .type __uClibc_start_main,%function + .type __uClibc_main,%function _start: /* Clear the frame pointer. The ABI suggests this be done, to mark the outermost frame obviously. */ @@ -105,7 +105,7 @@ _start: /* Call the user's main function, and exit with its value. But let the libc call main. */ - call __uClibc_start_main@PLT + call __uClibc_main@PLT #else /* Push address of our own entry points to .fini and .init. */ pushl $_fini @@ -118,7 +118,7 @@ _start: /* Call the user's main function, and exit with its value. But let the libc call main. */ - call __uClibc_start_main + call __uClibc_main #endif hlt /* Crash if somehow `exit' does return. */ diff --git a/libc/sysdeps/linux/mips/crt1.S b/libc/sysdeps/linux/mips/crt1.S index 93f3b5e42..82090ae15 100644 --- a/libc/sysdeps/linux/mips/crt1.S +++ b/libc/sysdeps/linux/mips/crt1.S @@ -36,7 +36,6 @@ 02111-1307 USA. */ -#include #include @@ -65,7 +64,7 @@ /* We need to call: - __uClibc_start_main (int (*main) (int, char **, char **), int argc, + __uClibc_main (int (*main) (int, char **, char **), int argc, char **argv, void (*init) (void), void (*fini) (void), void (*rtld_fini) (void), void *stack_end) */ @@ -76,7 +75,7 @@ .type _init,%function .type _fini,%function .type main,%function - .type __uClibc_start_main,%function + .type __uClibc_main,%function __start: #ifdef __PIC__ @@ -108,9 +107,9 @@ __start: sw $8, 16($29) /* fini */ sw $2, 20($29) /* rtld_fini */ sw $29, 24($29) /* stack_end */ - jal __uClibc_start_main + jal __uClibc_main hlt: - /* Crash if somehow `__uClibc_start_main' returns anyway. */ + /* Crash if somehow `__uClibc_main' returns anyway. */ b hlt .size __start,.-__start diff --git a/libc/sysdeps/linux/powerpc/crt1.S b/libc/sysdeps/linux/powerpc/crt1.S index 6a3e0000b..a912481ef 100644 --- a/libc/sysdeps/linux/powerpc/crt1.S +++ b/libc/sysdeps/linux/powerpc/crt1.S @@ -31,15 +31,13 @@ #define r13 13 #define r31 31 -#include - .text .globl _start .type _start,%function .type _init,%function .type _fini,%function .type main,%function - .type __uClibc_start_main,%function + .type __uClibc_main,%function _start: mr r10,r1 /* Save the stack pointer */ @@ -64,7 +62,7 @@ _start: lwz r6,_init@got(r31) lwz r7,_fini@got(r31) lwz r3,main@got(r31) - b __uClibc_start_main@plt + b __uClibc_main@plt # else lis r6,_init@ha # load top 16 bits addi r6,r6,_init@l # load bottom 16 bits @@ -72,8 +70,9 @@ _start: addi r7,r7,_fini@l # load bottom 16 bits lis r3,main@ha # load top 16 bits addi r3,r3,main@l # load bottom 16 bits - b __uClibc_start_main + b __uClibc_main # endif + .size _start,.-_start /* Define a symbol for the first piece of initialized data. */ -- cgit v1.2.3