OSDN Git Service

Make support for global constructors and global destructors be
authorEric Andersen <andersen@codepoet.org>
Wed, 27 Nov 2002 23:34:07 +0000 (23:34 -0000)
committerEric Andersen <andersen@codepoet.org>
Wed, 27 Nov 2002 23:34:07 +0000 (23:34 -0000)
configurable, so people who do not need or want ctor/dtor support
can disable it and make their binaries a little bit smaller.
 -Erik

extra/Configs/Config.in
extra/gcc-uClibc/Makefile
extra/gcc-uClibc/gcc-uClibc.c
extra/scripts/get-needed-libgcc-objects.sh
libc/Makefile
libc/sysdeps/linux/arm/crt0.S
libc/sysdeps/linux/common/Makefile
libc/sysdeps/linux/i386/crt0.S
libc/sysdeps/linux/mips/crt0.S
libc/sysdeps/linux/sh/crt0.S
libpthread/Makefile

index 089c1b4..95c5ba7 100644 (file)
@@ -60,6 +60,23 @@ config LDSO_LDD_SUPPORT
          application to function.  Disabling this option will makes uClibc's
          shared library loader a little bit smaller.  Most people will answer Y.
 
+config UCLIBC_CTOR_DTOR
+       bool "Support global constructors and destructos"
+       default y
+       help
+         If you wish to build uClibc with support for global constructor
+         (ctor) and global destructor (dtor) support, then answer Y here.
+         When ctor/dtor support is enabled, binaries linked with uClibc must
+         also be linked with crtbegin.o and crtend.o which are provided by gcc
+         (the "*startfile:" and "*endfile:" settings in your gcc specs file
+         may need to be adjusted to include these files).  This support will
+         also add a small amount of additional size to each binary compiled vs
+         uClibc.  If you will be using uClibc with C++, or if you need the gcc
+         __attribute__((constructor)) and __attribute__((destructor)) to work,
+         then you definately want to answer Y here.  If you don't need ctors
+         or dtors and want your binaries to be as small as possible, then
+         answer N.
+
 config UCLIBC_HAS_THREADS
        bool "POSIX Threading Support"
        default y
index 677b10f..1c64f85 100644 (file)
@@ -1,7 +1,7 @@
 # Makefile for building a fake gcc/binutils toolchain
 # that simply spoofs the location of the C library
 #
-# Copyright (C) 2000,2001 Erik Andersen <andersen@uclibc.org>
+# Copyright (C) 2000-2002 Erik Andersen <andersen@uclibc.org>
 #
 
 TOPDIR = ../../
@@ -34,6 +34,11 @@ ifeq ($(strip $(HAS_ELF)),y)
 else
        @echo "#undef __HAS_ELF__" >> gcc-uClibc.h
 endif
+ifeq ($(strip $(UCLIBC_CTOR_DTOR)),y)
+       @echo "#define __UCLIBC_CTOR_DTOR__ 1" >> gcc-uClibc.h
+else
+       @echo "#undef __UCLIBC_CTOR_DTOR__" >> gcc-uClibc.h
+endif
 
 gcc-uClibc: gcc-uClibc.h gcc-uClibc.c
        $(NATIVE_CC) $(NATIVE_CFLAGS) -Wl,-s gcc-uClibc.c -o $(TARGET_ARCH)-uclibc-gcc
@@ -50,14 +55,16 @@ install: all
        install -d $(PREFIX)$(SYSTEM_DEVEL_PREFIX)/bin;
        install -m 755 $(TARGET_ARCH)-uclibc-gcc $(PREFIX)$(SYSTEM_DEVEL_PREFIX)/bin/
        install -m 755 $(TARGET_ARCH)-uclibc-ld $(PREFIX)$(SYSTEM_DEVEL_PREFIX)/bin/
-       ln -fs $(TARGET_ARCH)-uclibc-gcc $(PREFIX)$(SYSTEM_DEVEL_PREFIX)/bin/$(TARGET_ARCH)-uclibc-g++
-       ln -fs $(TARGET_ARCH)-uclibc-gcc $(PREFIX)$(SYSTEM_DEVEL_PREFIX)/bin/$(TARGET_ARCH)-uclibc-c++
        ln -fs $(TARGET_ARCH)-uclibc-gcc $(PREFIX)$(SYSTEM_DEVEL_PREFIX)/bin/$(TARGET_ARCH)-uclibc-cc
-       ln -fs $(SYSTEM_DEVEL_PREFIX)/bin/$(TARGET_ARCH)-uclibc-gcc $(PREFIX)$(DEVEL_TOOL_PREFIX)/bin/c++
-       ln -fs $(SYSTEM_DEVEL_PREFIX)/bin/$(TARGET_ARCH)-uclibc-gcc $(PREFIX)$(DEVEL_TOOL_PREFIX)/bin/g++
        ln -fs $(SYSTEM_DEVEL_PREFIX)/bin/$(TARGET_ARCH)-uclibc-gcc $(PREFIX)$(DEVEL_TOOL_PREFIX)/bin/gcc
        ln -fs $(SYSTEM_DEVEL_PREFIX)/bin/$(TARGET_ARCH)-uclibc-gcc $(PREFIX)$(DEVEL_TOOL_PREFIX)/bin/cc
        ln -fs $(SYSTEM_DEVEL_PREFIX)/bin/$(TARGET_ARCH)-uclibc-ld  $(PREFIX)$(DEVEL_TOOL_PREFIX)/bin/ld
+ifeq ($(strip $(UCLIBC_CTOR_DTOR)),y)
+       ln -fs $(TARGET_ARCH)-uclibc-gcc $(PREFIX)$(SYSTEM_DEVEL_PREFIX)/bin/$(TARGET_ARCH)-uclibc-g++
+       ln -fs $(TARGET_ARCH)-uclibc-gcc $(PREFIX)$(SYSTEM_DEVEL_PREFIX)/bin/$(TARGET_ARCH)-uclibc-c++
+       ln -fs $(SYSTEM_DEVEL_PREFIX)/bin/$(TARGET_ARCH)-uclibc-gcc $(PREFIX)$(DEVEL_TOOL_PREFIX)/bin/c++
+       ln -fs $(SYSTEM_DEVEL_PREFIX)/bin/$(TARGET_ARCH)-uclibc-gcc $(PREFIX)$(DEVEL_TOOL_PREFIX)/bin/g++
+endif
        for app in addr2line ar as cpp gasp nm objcopy \
            objdump ranlib size strings strip; do \
          APPNAME=`which $(CROSS)$${app}`; \
index 8b7f53e..765521e 100644 (file)
@@ -83,10 +83,12 @@ static char *our_usr_lib_path = "-L"UCLIBC_DEVEL_PREFIX"/lib";
 
 static char static_linking[] = "-static";
 static char nostdinc[] = "-nostdinc";
-static char nostdinc_plus[] = "-nostdinc++";
 static char nostartfiles[] = "-nostartfiles";
 static char nodefaultlibs[] = "-nodefaultlibs";
 static char nostdlib[] = "-nostdlib";
+#ifdef __UCLIBC_CTOR_DTOR__
+static char nostdinc_plus[] = "-nostdinc++";
+#endif
 
 
 extern void *xmalloc(size_t size)
@@ -120,9 +122,8 @@ void xstrcat(char **string, ...)
 int main(int argc, char **argv)
 {
        int use_build_dir = 0, linking = 1, use_static_linking = 0;
-       int use_stdinc = 1, use_nostdinc_plus = 0, use_start = 1, use_stdlib = 1, use_pic = 0;
+       int use_stdinc = 1, use_start = 1, use_stdlib = 1, use_pic = 0;
        int source_count = 0, use_rpath = 0, verbose = 0;
-       int ctor_dtor = 1, cplusplus = 0;
        int i, j, k, l, m, n;
        char ** gcc_argv;
        char ** gcc_argument;
@@ -141,15 +142,19 @@ int main(int argc, char **argv)
        char *our_lib_path[2];
        char *crt0_path[2];
        const char *application_name;
+#ifdef __UCLIBC_CTOR_DTOR__
        char *crti_path[2];
        char *crtn_path[2];
-       char *GPLUSPLUS_BIN = NULL;
        int len;
+       int ctor_dtor = 1, cplusplus = 0, use_nostdinc_plus = 0;
+       char *GPLUSPLUS_BIN = NULL;
+#endif
 
        application_name = basename(argv[0]);
        if (application_name[0] == '-')
                application_name++;
 
+#ifdef __UCLIBC_CTOR_DTOR__
        /* We must use strstr since g++ might be named like a
         * cross compiler (i.e. arm-linux-g++).   We must also
         * search carefully, in case we are searching something 
@@ -168,6 +173,7 @@ int main(int argc, char **argv)
            cplusplus = 1;
            use_nostdinc_plus = 1;
        }
+#endif
 
        devprefix = getenv("UCLIBC_DEVEL_PREFIX");
        if (!devprefix) {
@@ -193,10 +199,12 @@ int main(int argc, char **argv)
 
        xstrcat(&(crt0_path[0]), devprefix, "/lib/crt0.o", NULL);
        xstrcat(&(crt0_path[1]), builddir, "/lib/crt0.o", NULL);
+#ifdef __UCLIBC_CTOR_DTOR__
        xstrcat(&(crti_path[0]), devprefix, "/lib/crti.o", NULL);
        xstrcat(&(crti_path[1]), builddir, "/lib/crti.o", NULL);
        xstrcat(&(crtn_path[0]), devprefix, "/lib/crtn.o", NULL);
        xstrcat(&(crtn_path[1]), builddir, "/lib/crtn.o", NULL);
+#endif
 
        xstrcat(&(our_lib_path[0]), "-L", devprefix, "/lib", NULL);
        xstrcat(&(our_lib_path[1]), "-L", builddir, "/lib", NULL);
@@ -267,11 +275,14 @@ int main(int argc, char **argv)
                                        } else if (strcmp(nostdlib,argv[i]) == 0) {
                                                use_start = 0;
                                                use_stdlib = 0;
-                                       } else if (strcmp(nostdinc_plus,argv[i]) == 0) {
+                                       } 
+#ifdef __UCLIBC_CTOR_DTOR__
+                                       else if (strcmp(nostdinc_plus,argv[i]) == 0) {
                                                if (cplusplus==1) {
                                                        use_nostdinc_plus = 0;
                                                }
                                        }
+#endif
                                        break;
                                case 's':
                                        if (strstr(argv[i],static_linking) != NULL) {
@@ -310,10 +321,13 @@ int main(int argc, char **argv)
                                        } else if (strcmp("--uclibc-use-rpath",argv[i]) == 0) {
                                            use_rpath = 1;
                                            argv[i]='\0';
-                                       } else if (strcmp("--uclibc-no-ctors",argv[i]) == 0) {
+                                       }
+#ifdef __UCLIBC_CTOR_DTOR__
+                                       else if (strcmp("--uclibc-no-ctors",argv[i]) == 0) {
                                            ctor_dtor = 0;
                                            argv[i]='\0';
                                        }
+#endif
                                        break;
                        }
                } else {                                /* assume it is an existing source file */
@@ -325,9 +339,11 @@ int main(int argc, char **argv)
        gcc_argument = __builtin_alloca(sizeof(char*) * (argc + 20));
 
        i = 0; k = 0;
+#ifdef __UCLIBC_CTOR_DTOR__
        if (cplusplus && GPLUSPLUS_BIN)
            gcc_argv[i++] = GPLUSPLUS_BIN;
        else
+#endif
            gcc_argv[i++] = GCC_BIN;
        
        for ( j = 1 ; j < argc ; j++ ) {
@@ -370,6 +386,7 @@ int main(int argc, char **argv)
        }
        if (use_stdinc && source_count) {
            gcc_argv[i++] = nostdinc;
+#ifdef __UCLIBC_CTOR_DTOR__
            if (cplusplus) {
                char *cppinc;
                if (use_nostdinc_plus) {
@@ -382,6 +399,7 @@ int main(int argc, char **argv)
                gcc_argv[i++] = "-isystem";
                gcc_argv[i++] = cppinc;
            }
+#endif
            gcc_argv[i++] = "-isystem";
            gcc_argv[i++] = uClibc_inc[use_build_dir];
            gcc_argv[i++] = "-iwithprefix";
@@ -392,6 +410,7 @@ int main(int argc, char **argv)
 
        if (linking && source_count) {
            if (use_start) {
+#ifdef __UCLIBC_CTOR_DTOR__
                if (ctor_dtor) {
                    gcc_argv[i++] = crti_path[use_build_dir];
                    if (use_pic) {
@@ -400,6 +419,7 @@ int main(int argc, char **argv)
                        gcc_argv[i++] = LIBGCC_DIR "crtbegin.o" ;
                    }
                }
+#endif
                gcc_argv[i++] = crt0_path[use_build_dir];
            }
            for ( l = 0 ; l < k ; l++ ) {
@@ -413,14 +433,17 @@ int main(int argc, char **argv)
                if (libraries[l]) gcc_argv[i++] = libraries[l];
            }
            if (use_stdlib) {
+#ifdef __UCLIBC_CTOR_DTOR__
                if (cplusplus) {
                    gcc_argv[ i++ ] = "-lstdc++";
                    gcc_argv[ i++ ] = "-lm";
                }
+#endif
                gcc_argv[i++] = "-lc";
                gcc_argv[i++] = "-lgcc";
                //gcc_argv[i++] = "-Wl,--end-group";
            }
+#ifdef __UCLIBC_CTOR_DTOR__
            if (ctor_dtor) {
                if (use_pic) {
                    gcc_argv[i++] = LIBGCC_DIR "crtendS.o" ;
@@ -429,6 +452,7 @@ int main(int argc, char **argv)
                }
                gcc_argv[i++] = crtn_path[use_build_dir];
            }
+#endif
        } else {
            for ( l = 0 ; l < k ; l++ ) {
                if (gcc_argument[l]) gcc_argv[i++] = gcc_argument[l];
@@ -443,8 +467,10 @@ int main(int argc, char **argv)
                fflush(stdout);
        }
        //no need to free memory from xstrcat because we never return... 
+#ifdef __UCLIBC_CTOR_DTOR__
        if (cplusplus && GPLUSPLUS_BIN)
            return execvp(GPLUSPLUS_BIN, gcc_argv);
        else
+#endif
            return execvp(GCC_BIN, gcc_argv);
 }
index 588634c..04e6737 100755 (executable)
@@ -18,7 +18,7 @@
 echo Finding missing symbols in libc.a ...
 echo "    partial linking..."
 rm -f libc.ldr
-$LD $LDFLAGS -r -o libc.ldr ../../lib/crt0.o ../../lib/crti.o ../../lib/crtn.o --whole-archive ../libc.a
+$LD $LDFLAGS -r -o libc.ldr $CRTOBJS --whole-archive ../libc.a
 
 if $NM --undefined-only libc.ldr 2>&1 | grep -v "^main$" | grep -v "^_GLOBAL_OFFSET_TABLE_$" | grep -v "_gp_disp" > sym.need ; then
     EXIT_WITH_ERROR=0
index 595f69e..4a5110f 100644 (file)
 TOPDIR=../
 include $(TOPDIR)Rules.mak
 
+ifeq ($(strip $(UCLIBC_CTOR_DTOR)),y)
+CRTOBJS="../../lib/crti.o ../../lib/crt0.o ../../lib/crtn.o"
+else
+CRTOBJS="../../lib/crt0.o"
+endif
+
 DIRS = misc pwd_grp stdio string termios inet signal stdlib sysdeps unistd
 
 # Check if the target architecture has a version script for
@@ -49,7 +55,8 @@ shared: $(TOPDIR)lib/$(LIBNAME)
        @rm -rf tmp
        @mkdir tmp
        $(AR) rv ./tmp/libgcc-need.a
-       @(cd tmp && CC=$(CC) LD=$(LD) LDFLAGS=$(CPU_LDFLAGS-y) NM=$(NM) AR=$(AR) LIBGCC=$(LIBGCC) \
+       @(cd tmp && CC=$(CC) LD=$(LD) LDFLAGS=$(CPU_LDFLAGS-y) NM=$(NM) AR=$(AR) \
+               LIBGCC=$(LIBGCC) CRTOBJS=$(CRTOBJS) \
                /bin/sh $(TOPDIR)../extra/scripts/get-needed-libgcc-objects.sh)
        $(LD) $(LDFLAGS) $(VERSION_SCRIPT) -soname=$(SHARED_MAJORNAME) -o $(SHARED_FULLNAME) \
                --whole-archive ./tmp/libgcc-need.a $(LIBNAME) --no-whole-archive \
index ad4865c..a930ff3 100644 (file)
@@ -80,6 +80,7 @@ _start:
        ldr r2,[sp, #8]
 #endif
 
+#ifdef __UCLIBC_CTOR_DTOR__
        /* Store the address of _init in r3 as an argument to main() */
        ldr r3, =_init
 
@@ -89,6 +90,9 @@ _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
index f66c09f..8e0ed94 100644 (file)
 TOPDIR=../../../../
 include $(TOPDIR)Rules.mak
 
-SAFECFLAGS=$(WARNINGS) $(CPU_CFLAGS-y) $(OPTIMIZATION) -fno-builtin
-ifeq ($(strip $(DOPIC)),y)
-SAFECFLAGS+=-fPIC
-endif
-
 CSRC=  waitpid.c getdnnm.c gethstnm.c getcwd.c \
        mkfifo.c setegid.c wait.c getpagesize.c seteuid.c \
        wait3.c setpgrp.c getdtablesize.c create_module.c ptrace.c \
@@ -44,13 +39,21 @@ COBJS=$(patsubst %.c,%.o, $(CSRC))
 MSRC=syscalls.c
 MOBJ=$(shell ./list_syscalls.sh)
 
+ifeq ($(strip $(UCLIBC_CTOR_DTOR)),y)
+CTOR_TARGETS=$(TOPDIR)lib/crti.o $(TOPDIR)lib/crtn.o
+SAFECFLAGS=$(WARNINGS) $(CPU_CFLAGS-y) $(OPTIMIZATION) -fno-builtin
+ifeq ($(strip $(DOPIC)),y)
+SAFECFLAGS+=-fPIC
+endif
+endif
+
 OBJ=$(COBJS) $(MOBJ)
 
 all: $(STR_SYSCALLS) $(OBJ) $(LIBC)
 
 $(LIBC): ar-target
 
-ar-target: $(OBJ) $(TOPDIR)lib/crti.o $(TOPDIR)lib/crtn.o
+ar-target: $(OBJ) $(CTOR_TARGETS)
        $(AR) $(ARFLAGS) $(LIBC) $(OBJ)
        (cd $(TOPDIR)lib/; ln -fs crt0.o crt1.o)
 
index 97f1fde..be66b9a 100644 (file)
@@ -61,6 +61,7 @@ _start:
        pushl %ebp      /* callers %ebp (frame pointer) */
        movl %esp,%ebp  /* mark callers stack frame as invalid */
 
+#ifdef __UCLIBC_CTOR_DTOR__
        /* Push .init and .fini arguments to __uClibc_start_main() on the stack */
        pushl $_fini
        pushl $_init
@@ -72,6 +73,14 @@ _start:
 
        /* Ok, now run uClibc's main() -- shouldn't return */
        call __uClibc_start_main
+#else
+       /* 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 */
+
+       call __uClibc_main
+#endif
 
        /* Crash if somehow `exit' returns anyways.  */
        hlt
index fd1f4b9..0522298 100644 (file)
@@ -30,6 +30,7 @@ __start:
        addu a2, a0, 1      /* argv[0] program name (ordinal->cardinal) */
         sll  a2, a2, 2     /* multiple by 4 */
        add  a2, a2, a1     /* a2 now points to start of envp */
+#ifdef __UCLIBC_CTOR_DTOR__
        la   a3, _init      /* a3 is address of _init */
        addiu sp, sp, -24   /* 16 + 4 rounded up to multiple of 8 */
                            /* multiple of 8 for longlong/double support */
@@ -38,6 +39,9 @@ __start:
        
        /* Ok, now run uClibc's main() -- shouldn't return */
        jal  __uClibc_start_main
+#else
+       jal  __uClibc_main
+#endif
 
        addiu sp, sp, 24    /* undo stack argument */
 
index e74ae86..a27775e 100644 (file)
@@ -48,6 +48,34 @@ _start:
        mov.l @r15+,r4
        mov r15, r5
 
+#if ! defined __UCLIBC_CTOR_DTOR__
+       /*
+        * Setup the value for the environment pointer:
+        * r6 = (argc + 1) * 4
+        * r6 += argv (in delay slot)
+        */
+       mov r4,r6
+       add #1,r6
+       shll2 r6
+       add r5, r6
+
+       /* jump to __uClibc_main (argc, argv, envp) */
+       mov.l L_main, r0
+       jsr @r0
+       nop /* delay slot */
+
+       /* We should not get here. */
+       mov.l L_abort, r0
+       jmp @r0
+       nop
+
+_start_end:    
+       .align  2
+
+L_main:
+       .long   __uClibc_main /* in libuClibc.*.so */
+
+#else /* __UCLIBC_CTOR_DTOR__ */
        /* Push the finip argument to __uClibc_start_main() onto the stack */
        mov.l L_fini,r6
        mov.l r6,@-r15
@@ -72,10 +100,12 @@ _start:
        mov.l L_abort, r0
        jmp @r0
        nop
-
 _start_end:    
        .align  2
 
+L_main:
+       .long   __uClibc_start_main /* in libuClibc.*.so */
+
        .weak   _init
        .type   _init,@function
 _init:
@@ -87,13 +117,13 @@ _init:
        .weak   _fini
        .set    _fini,_init
 
-L_main:
-       .long   __uClibc_start_main /* in libuClibc.*.so */
-
 L_init:
       .long   _init
 L_fini:
       .long   _fini
+
+#endif
+
 L_abort: 
       .long   abort   
 
index c98ef8b..87e2074 100644 (file)
@@ -36,6 +36,7 @@ ifeq ($(strip $(DODEBUG)),y)
 endif
 endif
 
+ifeq ($(strip $(UCLIBC_CTOR_DTOR)),y)
 ifeq ($(strip $(DOPIC)),y)
     START_FILES  = $(TOPDIR)lib/crti.o    $(LIBGCC_DIR)crtbeginS.o
     END_FILES    = $(LIBGCC_DIR)crtendS.o $(TOPDIR)lib/crtn.o
@@ -43,6 +44,7 @@ else
     START_FILES  = $(TOPDIR)lib/crti.o    $(LIBGCC_DIR)crtbegin.o
     END_FILES    = $(LIBGCC_DIR)crtend.o  $(TOPDIR)lib/crtn.o
 endif
+endif
 
 ALL_SUBDIRS = linuxthreads linuxthreads_db