diff options
author | Dale Rahn <drahn@cvs.openbsd.org> | 2000-10-13 05:14:04 +0000 |
---|---|---|
committer | Dale Rahn <drahn@cvs.openbsd.org> | 2000-10-13 05:14:04 +0000 |
commit | 9c38c1942a644f6c07685cd3baa240884a39bf8c (patch) | |
tree | 662d75e749fc251e1c925f185d82bb6690a66782 | |
parent | 166278aa215c155f4eec814b86d340a3cb4b52ad (diff) |
Changes to the powerpc startup files to work in a more typical ELF
manner. the linker knows about the magic function _init and _fini
and will create a .dynamic tag to point to those symbols in the
executable/shared libraries. Take advantage of that fact to allow
ld.so to easily find the appropriate ctors/dtors calls for shared libraries
Since the crtbeginS.c now contains executable code, it must be compiled
with -fPIC. Rename the __init and __fini functions to _init/_fini so
the linker will locate them.
-rw-r--r-- | lib/csu/powerpc/Makefile | 8 | ||||
-rw-r--r-- | lib/csu/powerpc/crtbeginS.c | 61 |
2 files changed, 63 insertions, 6 deletions
diff --git a/lib/csu/powerpc/Makefile b/lib/csu/powerpc/Makefile index fde62a6b022..94560788ba0 100644 --- a/lib/csu/powerpc/Makefile +++ b/lib/csu/powerpc/Makefile @@ -1,8 +1,10 @@ -# $OpenBSD: Makefile,v 1.6 2000/06/28 04:56:44 rahnds Exp $ +# $OpenBSDe Makefile,v 1.6 2000/06/28 04:56:44 rahnds Exp $ # from: @(#)Makefile 8.1 (Berkeley) 6/1/93 CFLAGS= -DLIBC_SCCS OBJS= crt0.o gcrt0.o scrt0.o crtbegin.o crtend.o crtbeginS.o crtendS.o +PICFLAG?=-fpic + CLEANFILES+= core a.out all: ${OBJS} @@ -35,8 +37,8 @@ crtend.o: crtend.c @rm -f ${.TARGET}.o crtbeginS.o: crtbeginS.c - @echo ${CC} ${CFLAGS} -c ${.ALLSRC} -o ${.TARGET} - @${CC} ${CFLAGS} -c ${.ALLSRC} -o ${.TARGET}.o + @echo ${CC} ${PICFLAG} ${CFLAGS} -c ${.ALLSRC} -o ${.TARGET} + @${CC} ${PICFLAG} ${CFLAGS} -c ${.ALLSRC} -o ${.TARGET}.o @${LD} -x -r -o ${.TARGET} ${.TARGET}.o @rm -f ${.TARGET}.o diff --git a/lib/csu/powerpc/crtbeginS.c b/lib/csu/powerpc/crtbeginS.c index 2b7e08d53a4..bf2ce4498fd 100644 --- a/lib/csu/powerpc/crtbeginS.c +++ b/lib/csu/powerpc/crtbeginS.c @@ -1,4 +1,4 @@ -/* $OpenBSD: crtbeginS.c,v 1.1 2000/06/13 04:07:03 rahnds Exp $ */ +/* $OpenBSD: crtbeginS.c,v 1.2 2000/10/13 05:14:03 drahn Exp $ */ /* $NetBSD: crtbegin.c,v 1.1 1996/09/12 16:59:03 cgd Exp $ */ /* @@ -46,7 +46,62 @@ */ #include <stdlib.h> -void (*__CTOR_LIST__[0]) __P((void)) +static void (*__CTOR_LIST__[0]) __P((void)) __attribute__((section(".ctors"))) = { (void *)-1 }; /* XXX */ -void (*__DTOR_LIST__[0]) __P((void)) +static void (*__DTOR_LIST__[0]) __P((void)) __attribute__((section(".dtors"))) = { (void *)-1 }; /* XXX */ + +static void __dtors __P((void)); +static void __ctors __P((void)); + +void +__dtors() +{ + unsigned long i = (unsigned long) __DTOR_LIST__[0]; + void (**p)(void); + + if (i == -1) { + for (i = 1; __DTOR_LIST__[i] != NULL; i++) + ; + i--; + } + p = __DTOR_LIST__ + i; + while (i--) { + (**p--)(); + } +} + +static void +__ctors() +{ + void (**p)(void) = __CTOR_LIST__ + 1; + + while (*p) { + (**p++)(); + } +} + +void +_init() +{ + static int initialized = 0; + + /* + * Call global constructors. + * Arrange to call global destructors at exit. + */ + if (!initialized) { + initialized = 1; + __ctors(); + + atexit(__dtors); + } +} +void +_fini() +{ + /* + * since the _init() function sets up the destructors to be called + * by atexit, do not call the destructors here. + */ +} |