new way of generating crt[ni].o [patch]
Zack Weinberg
zack@bitmover.com
Thu Sep 2 23:52:00 GMT 1999
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__)";
-}
More information about the Libc-hacker
mailing list