This is the mail archive of the libc-hacker@sourceware.cygnus.com mailing list for the glibc project.

Note that libc-hacker is a closed list. You may look at the archives of this list, but subscription and posting are not open.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

new way of generating crt[ni].o [patch]



The new x86 back end wants to generate trampolines to load the PIC
base register all the time (yes, even with -march=i386).  The current
crt[in] generation can't handle this.  So I rewrote it again.  This
version does the split in the object file; it turns out to be much,
much cleaner that way.  On the other hand, it is dependent on more
gnu-binutils-specific features than before.  I'm using binutils
2.9.5.0.10, but it ought to work with 2.9.1 and later, at least.

zw

1999-09-02 23:41 -0700  Zack Weinberg  <zack@bitmover.com>

	* csu/Makefile (distribute): Drop defs.awk; add crti.ld and
	crtn.ld.
	(generated [have-initfini]): Just add initfini.o.
	(crt%.o): Extract them from initfini.o using ld and objcopy.
	(CFLAGS-initfini.c): New variable.
	(initfini.s, crti.S, crtn.S, defs.h, CFLAGS-initfini.s): Drop.
	* csu/initfini.c: Use __attribute__ ((section)) tags to say
	where the functions' beginnings go.  Rip out all the asm
	insertions except the section switches inside the functions.
	Function epilogs now go in .init.end/.fini.end respectively.
	Drop dummy().
	* sysdeps/i386/Makefile (CFLAGS-initfini.s): Delete.
	* sysdeps/mach/hurd/Makefile (CFLAGS-initfini.s): Rename to
	CFLAGS-initfini.c.
	* sysdeps/powerpc/Makefile: Likewise.
	* sysdeps/unix/sysv/linux/Makefile: Likewise.
	* csu/crti.ld: New file.
	* csu/crtn.ld: New file.
	* csu/defs.awk: Delete.

===================================================================
Index: csu/Makefile
--- csu/Makefile	1999/08/19 16:28:49	1.37
+++ csu/Makefile	1999/09/03 06:38:08
@@ -36,8 +36,8 @@ omit-deps = $(patsubst %.o,%,$(start-ins
 		             $(csu-dummies))
 install-lib = $(start-installed-name) g$(start-installed-name) \
 	      $(csu-dummies)
-distribute = initfini.c gmon-start.c start.c defs.awk munch.awk \
-	     abi-note.S init.c munch-tmpl.c
+distribute = initfini.c gmon-start.c start.c munch.awk \
+	     abi-note.S init.c munch-tmpl.c crti.ld crtn.ld
 generated = version-info.h
 before-compile = $(objpfx)version-info.h
 
@@ -68,6 +68,8 @@ endif
 ifeq ($(have-initfini),yes)
 
 CPPFLAGS += -DHAVE_INITFINI
+LD = ld
+OBJCOPY = objcopy
 
 # These are the special initializer/finalizer files.  They are always the
 # first and last file in the link.  crti.o ... crtn.o define the global
@@ -76,34 +78,17 @@ crtstuff = crti crtn
 
 install-lib += $(crtstuff:=.o)
 extra-objs += $(crtstuff:=.o)
-generated += $(crtstuff:=.S) initfini.s defs.h
+generated += initfini.o
 omit-deps += $(crtstuff)
 
 # Special rules for the building of crti.o and crtn.o
-$(objpfx)crt%.o: $(objpfx)crt%.S $(objpfx)defs.h
-	$(compile.S) -g0 $(ASFLAGS-.os) -o $@
+$(objpfx)crt%.o: $(objpfx)initfini.o crt%.ld
+	$(LD) -r -o $@T $^
+	$(OBJCOPY) -R .discard $@T $@
+	-rm -f $@T
 
-CFLAGS-initfini.s = -g0 -fPIC -fno-inline-functions
-
-$(objpfx)initfini.s: initfini.c
-	$(compile.c) -S $(CFLAGS-initfini.s) -finhibit-size-directive \
-		$(patsubst -f%,-fno-%,$(exceptions)) -o $@
-
-# We only have one kind of startup code files.  Static binaries and
-# shared libraries are build using the PIC version.
-$(objpfx)crti.S: $(objpfx)initfini.s
-	sed -n -e '1,/@HEADER_ENDS/p' \
-	       -e '/@_.*_PROLOG_BEGINS/,/@_.*_PROLOG_ENDS/p' \
-	       -e '/@TRAILER_BEGINS/,$$p' $< > $@
-
-$(objpfx)crtn.S: $(objpfx)initfini.s
-	sed -n -e '1,/@HEADER_ENDS/p' \
-	       -e '/@_.*_EPILOG_BEGINS/,/@_.*_EPILOG_ENDS/p' \
-	       -e '/@TRAILER_BEGINS/,$$p' $< > $@
-
-$(objpfx)defs.h: $(objpfx)initfini.s
-	sed -n -e '/@TESTS_BEGIN/,/@TESTS_END/p' $< | \
-		$(AWK) -f defs.awk > $@
+CFLAGS-initfini.c = -g0 -fPIC -fno-inline-functions -finhibit-size-directive \
+	$(patsubst -f%,-fno-%,$(exceptions))
 
 endif
 
Index: csu/initfini.c
===================================================================
RCS file: /glibc/cvsfiles/libc/csu/initfini.c,v
retrieving revision 1.26
diff -u -p -r1.26 initfini.c
--- csu/initfini.c	1998/09/08 23:25:30	1.26
+++ csu/initfini.c	1999/09/03 06:38:08
@@ -26,43 +26,29 @@
    write to the Free Software Foundation, 59 Temple Place - Suite 330,
    Boston, MA 02111-1307, USA.  */
 
-/* This file is compiled into assembly code which is then munged by a sed
-   script into two files: crti.s and crtn.s.
+/* This file is compiled and then split apart by linker magic into
+   crti.o and crtn.o.  The split falls in the middle of the functions
+   _init and _fini.  Static constructor or destructor calls will be
+   inserted into the middle of the functions by .init or .fini
+   sections in other object files.  (Sort of.)  */
 
-   * crti.s puts a function prologue at the beginning of the
-   .init and .fini sections and defines global symbols for
-   those addresses, so they can be called as functions.
-
-   * crtn.s puts the corresponding function epilogues
-   in the .init and .fini sections. */
-
-#include <stdlib.h>
-
-/* We use embedded asm for .section unconditionally, as this makes it
-   easier to insert the necessary directives into crtn.S. */
-#define SECTION(x) asm (".section " x );
-
-/* Embed an #include to pull in the alignment and .end directives. */
-asm ("\n#include \"defs.h\"");
-
-/* The initial common code ends here. */
-asm ("\n/*@HEADER_ENDS*/");
+#ifndef WEAK_GMON_START
+/* This version of __gmon_start__ is used if no other is found.  By providing
+   a default function we avoid the need to test whether the pointer is NULL,
+   which can be painful on some machines.  */
 
-/* To determine whether we need .end and .align: */
-asm ("\n/*@TESTS_BEGIN*/");
-void
-dummy (void (*foo) (void))
+void __attribute__ ((weak))
+__gmon_start__ (void)
 {
-  if (foo)
-    (*foo) ();
+  /* do nothing */
 }
-asm ("\n/*@TESTS_END*/");
+#endif
 
-/* The beginning of _init:  */
-asm ("\n/*@_init_PROLOG_BEGINS*/");
+/* This is correct syntax for GAS.  If we ever need to support another
+   assembler, we can ifdef this up.  */
+#define SECTION(x) asm (".section\t" #x ",\"ax\",@progbits")
 
-SECTION (".init")
-void
+void __attribute__ ((section (".init")))
 _init (void)
 {
   /* We cannot use the normal constructor mechanism in gcrt1.o because it
@@ -71,7 +57,7 @@ _init (void)
      gcrt1.o to reference a symbol which would be defined by some library
      module which has a constructor; but then user code's constructors
      would come first, and not be profiled.  */
-  extern void __gmon_start__ (void) __attribute__ ((weak)); /*weak_extern (__gmon_start__);*/
+  extern void __gmon_start__ (void) __attribute__ ((weak));
 
 #ifndef WEAK_GMON_START
   __gmon_start__ ();
@@ -80,42 +66,13 @@ _init (void)
     __gmon_start__ ();
 #endif
 
-  asm ("ALIGN");
-  asm("END_INIT");
-  /* Now the epilog. */
-  asm ("\n/*@_init_PROLOG_ENDS*/");
-  asm ("\n/*@_init_EPILOG_BEGINS*/");
-  SECTION(".init");
+  SECTION(.init.end);
 }
-asm ("END_INIT");
-#ifndef WEAK_GMON_START
-SECTION(".text");
 
-/* This version of __gmon_start__ is used if no other is found.  By providing
-   a default function we avoid the need to test whether the pointer is NULL,
-   which can be painful on some machines.  */
-
-void __attribute__ ((weak))
-__gmon_start__ (void)
-{
-  /* do nothing */
-}
-#endif
-
-/* End of the _init epilog, beginning of the _fini prolog. */
-asm ("\n/*@_init_EPILOG_ENDS*/");
-asm ("\n/*@_fini_PROLOG_BEGINS*/");
-
-SECTION (".fini")
-void
+void __attribute__ ((section (".fini")))
 _fini (void)
 {
-
-  /* End of the _fini prolog. */
-  asm ("ALIGN");
-  asm ("END_FINI");
-  asm ("\n/*@_fini_PROLOG_ENDS*/");
-
+  SECTION(.discard);
   {
     /* Let GCC know that _fini is not a leaf function by having a dummy
        function call here.  We arrange for this call to be omitted from
@@ -123,16 +80,5 @@ _fini (void)
     extern void i_am_not_a_leaf (void);
     i_am_not_a_leaf ();
   }
-
-  /* Beginning of the _fini epilog. */
-  asm ("\n/*@_fini_EPILOG_BEGINS*/");
-  SECTION (".fini");
+  SECTION(.fini.end);
 }
-asm ("END_FINI");
-
-/* End of the _fini epilog.  Any further generated assembly (e.g. .ident)
-   is shared between both crt files. */
-asm ("\n/*@_fini_EPILOG_ENDS*/");
-asm ("\n/*@TRAILER_BEGINS*/");
-
-/* End of file. */
===================================================================
Index: sysdeps/i386/Makefile
--- sysdeps/i386/Makefile	1999/08/31 01:01:21	1.10
+++ sysdeps/i386/Makefile	1999/09/03 06:38:09
@@ -5,12 +5,6 @@ asm-CPPFLAGS += -DGAS_SYNTAX
 # The i386 `long double' is a distinct type we support.
 long-double-fcts = yes
 
-ifeq ($(subdir),csu)
-# On i686 we must avoid generating the trampoline functions generated
-# to get the GOT pointer.
-CFLAGS-initfini.s += -march=i386
-endif
-
 ifeq ($(subdir),db2)
 CPPFLAGS += -DHAVE_SPINLOCKS=1 -DHAVE_ASSEM_X86_GCC=1
 endif
===================================================================
Index: sysdeps/mach/hurd/i386/Makefile
--- sysdeps/mach/hurd/i386/Makefile	1999/06/13 10:02:39	1.4
+++ Makefile	1999/09/03 06:38:09
@@ -13,6 +13,6 @@ $(objpfx)crt0.o: $(objpfx)static-start.o
 # This is needed to be backward-compatible with glibc-2.0.x startup code
 # that was miscompiled so that it jumps to 0 if there is a nonzero
 # __gmon_start__ symbol, but works if there is none.
-CFLAGS-initfini.s += -DWEAK_GMON_START
+CFLAGS-initfini.c += -DWEAK_GMON_START
 
 endif
===================================================================
Index: sysdeps/powerpc/Makefile
--- sysdeps/powerpc/Makefile	1998/09/01 14:30:52	1.7
+++ sysdeps/powerpc/Makefile	1999/09/03 06:38:09
@@ -17,7 +17,7 @@ endif
 ifeq ($(subdir),csu)
 # The initfini generation code doesn't work in the presence of -fPIC, so
 # we use -fpic instead which is much better.
-CFLAGS-initfini.s = -g0 -fpic
+CFLAGS-initfini.c = -g0 -fpic
 
 # There is no benefit to using sdata for these objects, and the user
 # of the library should be able to control what goes into sdata.
===================================================================
Index: sysdeps/unix/sysv/linux/i386/Makefile
--- sysdeps/unix/sysv/linux/i386/Makefile	1998/10/21 15:16:04	1.14
+++ sysdeps/unix/sysv/linux/i386/Makefile	1999/09/03 06:38:09
@@ -9,5 +9,5 @@ install-bin += lddlibc4
 endif
 
 ifeq ($(subdir),csu)
-CFLAGS-initfini.s += -DWEAK_GMON_START
+CFLAGS-initfini.c += -DWEAK_GMON_START
 endif

 sysdep-routines += errno-loc
===================================================================
Index: csu/crti.ld
--- csu/crti.ld	Mon Feb 22 19:41:16 1999
+++ csu/crti.ld	Thu Sep  2 23:15:00 1999
@@ -0,0 +1,7 @@
+/* Linker script to extract the head of _init and _fini from initfini.o.  */
+SECTIONS
+{
+    /* The /DISCARD/ feature causes the 2.9.5.0.10 linker (at least) to
+       dump core.  */
+    .discard : { *(.discard) *(.init.end) *(.fini.end) }
+}
===================================================================
Index: csu/crtn.ld
--- csu/crtn.ld	Mon Feb 22 19:41:16 1999
+++ csu/crtn.ld	Thu Sep  2 23:14:51 1999
@@ -0,0 +1,9 @@
+/* Linker script to extract the tail of _init and _fini from initfini.o.  */
+SECTIONS
+{
+    /* The /DISCARD/ feature causes the 2.9.5.0.10 linker (at least) to
+       dump core.  */
+    .discard : { *(.discard) *(.init) *(.fini) *(.text) }
+    .init : { *(.init.end) }
+    .fini : { *(.fini.end) }
+}
===================================================================
Index: csu/defs.awk
--- csu/defs.awk	Sat Aug  2 12:28:29 1997
+++ csu/defs.awk	Mon Feb 22 19:41:16 1999
@@ -1,22 +0,0 @@
-/\.end/	 { need_end = 1 }
-/\.align/ { if($2 > max) max = $2; }
-
-END {
-    if(need_end)
-    {
-	print "#define END_INIT .end _init";
-	print "#define END_FINI .end _fini";
-    }
-    else
-    {
-	print "#define END_INIT";
-	print "#define END_FINI";
-    }
-    if(max)
-	print "#define ALIGN .align", max;
-    else
-	print "#define ALIGN";
-
-    print "#include <libc-symbols.h>";
-    print "weak_extern (__gmon_start__)";
-}

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]