From 44d76bb77781a30b6cfa3bfb69efb6a3136b0e4d Mon Sep 17 00:00:00 2001 From: Paul Richards Date: Thu, 4 Nov 1993 01:09:18 +0000 Subject: Added shared libs support from NetBSD. --- lib/csu/i386/Makefile | 14 +- lib/csu/i386/crt0.c | 440 ++++++++++++++++++++++++++++++++++++++++++++------ lib/csu/i386/gmon.c | 3 +- lib/csu/i386/gmon.h | 3 +- 4 files changed, 403 insertions(+), 57 deletions(-) (limited to 'lib/csu') diff --git a/lib/csu/i386/Makefile b/lib/csu/i386/Makefile index aeb328edc755..b4a50b7dac1f 100644 --- a/lib/csu/i386/Makefile +++ b/lib/csu/i386/Makefile @@ -1,15 +1,16 @@ -# @(#)Makefile 5.6 (Berkeley) 5/22/91 +# from: @(#)Makefile 5.6 (Berkeley) 5/22/91 +# $Id: Makefile,v 1.9 1993/10/24 01:34:24 pk Exp $ -CFLAGS= -O -DLIBC_SCCS -OBJS= crt0.o gcrt0.o +CFLAGS+= -DLIBC_SCCS #-DDYNAMIC +OBJS= crt0.o gcrt0.o CLEANFILES+= gmon.o moncrt0.o core a.out all: ${OBJS} crt0.o: crt0.c ${CC} ${CFLAGS} -c -DCRT0 ${.ALLSRC} - ${LD} -x -r ${.TARGET} - mv a.out ${.TARGET} +# ${LD} -x -r ${.TARGET} +# mv a.out ${.TARGET} moncrt0.o: crt0.c ${CC} ${CFLAGS} -c -DMCRT0 ${.ALLSRC} -o ${.TARGET} @@ -20,11 +21,12 @@ gcrt0.o: moncrt0.o gmon.o ${LD} -x -r -o ${.TARGET} moncrt0.o gmon.o gmon.o: gmon.c gmon.h - ${CC} -c ${DEFS} ${.IMPSRC} + ${CC} ${CFLAGS} -c ${.IMPSRC} ${LD} -x -r ${.TARGET} mv a.out ${.TARGET} install: + install -d -o ${BINOWN} -g ${BINGRP} -m 0755 ${DESTDIR}/usr/lib install ${COPY} -o ${BINOWN} -g ${BINGRP} -m 444 ${OBJS} \ ${DESTDIR}/usr/lib diff --git a/lib/csu/i386/crt0.c b/lib/csu/i386/crt0.c index 623cf6438b46..9f43b6610832 100644 --- a/lib/csu/i386/crt0.c +++ b/lib/csu/i386/crt0.c @@ -1,5 +1,5 @@ -/*- - * Copyright (c) 1990 The Regents of the University of California. +/* + * Copyright (c) 1993 Paul Kranenburg * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -12,53 +12,170 @@ * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. + * This product includes software developed by Paul Kranenburg. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software withough specific prior written permission + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. + * $Id: crt0.c,v 1.7 1993/10/23 00:47:18 pk Exp $ */ + #if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)crt0.c 5.7 (Berkeley) 7/3/91"; +static char sccsid[] = "%W% (Erasmus) %G%"; #endif /* LIBC_SCCS and not lint */ +extern void exit(); +int _callmain(); -/* - * C start up routine. - * Robert Henry, UCB, 20 Oct 81 - * - * We make the following (true) assumption: - * 1) The only register variable that we can trust is the frame pointer, - * ebp, which points to the base of the kernel calling frame. - */ +#include + +#ifdef DYNAMIC +#include +#include +#include +#ifndef N_GETMAGIC +#define N_GETMAGIC(x) ((x).a_magic) +#endif +#ifndef N_BSSADDR +#define N_BSSADDR(x) (N_DATADDR(x)+(x).a_data) +#endif +#include +#ifdef sun +#define MAP_COPY MAP_PRIVATE +#define MAP_FILE 0 +#define MAP_ANON 0 +#endif +#include + +extern struct link_dynamic _DYNAMIC; +static void __do_dynamic_link (); +static char *_getenv(); +static int _strncmp(); + +#ifdef sparc +static __call(); +#endif -#include -#include -#include +#ifdef sun +#define LDSO "/usr/lib/ld.so" +#endif +#ifdef BSD +#define LDSO "/usr/libexec/ld.so" +#endif -char **environ = (char **)0; -static char empty[1]; -char *__progname = empty; -int errno = 0; +#endif /* DYNAMIC */ +static char *_strrchr(); + +char **environ; + +#ifdef BSD extern unsigned char etext; extern unsigned char eprol asm ("eprol"); extern start() asm("start"); extern mcount() asm ("mcount"); +int errno; +static char empty[1]; +char *__progname = empty; +#endif + +/* + * We need these system calls, but can't use library stubs + */ +#define _exit(v) __syscall(SYS_exit, (v)) +#define open(name, f, m) __syscall(SYS_open, (name), (f), (m)) +#define close(fd) __syscall(SYS_close, (fd)) +#define read(fd, s, n) __syscall(SYS_read, (fd), (s), (n)) +#define write(fd, s, n) __syscall(SYS_write, (fd), (s), (n)) +#define dup(fd) __syscall(SYS_dup, (fd)) +#define dup2(fd, fdnew) __syscall(SYS_dup2, (fd), (fdnew)) +#ifdef sun +#define mmap(addr, len, prot, flags, fd, off) \ + __syscall(SYS_mmap, (addr), (len), (prot), _MAP_NEW|(flags), (fd), (off)) +#else +#define mmap(addr, len, prot, flags, fd, off) \ + __syscall(SYS_mmap, (addr), (len), (prot), (flags), (fd), (off)) +#endif + +#define _FATAL(str) \ + write(2, str, sizeof(str)), \ + _exit(1); + + +#ifdef sparc +asm (" .global start"); +asm (" .text"); +asm (" start:"); + +/* Set up `argc', `argv', and `envp' into local registers (from GNU Emacs). */ +asm (" mov 0, %fp"); +asm (" ld [%sp + 64], %l0"); /* argc */ +asm (" add %sp, 68, %l1"); /* argv */ +asm (" sll %l0, 2, %l2"); /**/ +asm (" add %l2, 4, %l2"); /* envp = argv + (argc << 2) + 4 */ +asm (" add %l1, %l2, %l2"); /**/ +asm (" sethi %hi(_environ), %l3"); +asm (" st %l2, [%l3+%lo(_environ)]"); /* *environ = l2 */ + +/* Finish diddling with stack. */ +asm (" andn %sp, 7, %sp"); +asm (" sub %sp, 24, %sp"); + +#ifdef DYNAMIC +/* Resolve symbols in dynamic libraries */ +asm (" call ___do_dynamic_link"); +asm (" nop"); +#endif + +/* From here, all symbols should have been resolved, so we can use libc */ +#ifdef MCRT0 +asm (" call ___do_mcrt"); +asm (" nop"); +#endif + +/* Stay Sun compatible (currently (SunOS 4.1.2) does nothing on sun4) */ +asm (" call start_float"); +asm (" nop"); + +/* Move `argc', `argv', and `envp' from locals to parameters for `main'. */ +asm (" mov %l0,%o0"); +asm (" mov %l1,%o1"); +asm ("__callmain:"); /* Defined for the benefit of debuggers */ +asm (" call _main"); +asm (" mov %l2,%o2"); + +asm (" call _exit"); +asm (" nop"); + +#ifdef MCRT0 +static void +__do_mcrt () +{ + extern unsigned char eprol, etext; + extern void _mcleanup(); + + on_exit(_mcleanup, 0); + monstartup(&eprol, &etext); + return; +} +#endif + +#endif /* sparc */ + + +#ifdef i386 start() { struct kframe { @@ -74,44 +191,269 @@ start() register char **targv; register char **argv; extern void _mcleanup(); +#ifdef DYNAMIC + volatile caddr_t x; +#endif #ifdef lint kfp = 0; initcode = initcode = 0; -#else not lint +#else /* not lint */ /* just above the saved frame pointer */ asm ("lea 4(%%ebp), %0" : "=r" (kfp) ); -#endif not lint +#endif /* not lint */ for (argv = targv = &kfp->kargv[0]; *targv++; /* void */) /* void */ ; if (targv >= (char **)(*argv)) --targv; environ = targv; + +#ifdef DYNAMIC +#ifdef stupid_gcc + if (&_DYNAMIC) + __do_dynamic_link(); +#else + x = (caddr_t)&_DYNAMIC; + if (x) + __do_dynamic_link(); +#endif +#endif /* DYNAMIC */ + asm("eprol:"); #ifdef MCRT0 atexit(_mcleanup); monstartup(&eprol, &etext); #endif MCRT0 - errno = 0; - if (argv[0]) - if ((__progname = strrchr(argv[0], '/')) == NULL) - __progname = argv[0]; - else - ++__progname; +#if 0 + errno = 0; +#endif + if (argv[0]) + if ((__progname = _strrchr(argv[0], '/')) == NULL) + __progname = argv[0]; + else + ++__progname; +asm ("__callmain:"); /* Defined for the benefit of debuggers */ exit(main(kfp->kargc, argv, environ)); } +#endif /* i386 */ + +#ifdef DYNAMIC +static void +__do_dynamic_link () +{ + struct crt_ldso crt; + struct exec hdr; + char *ldso; + int dupzfd; + void (*entry)(); + + /* ld(1) convention: if DYNAMIC = 0 then statically linked */ + if (&_DYNAMIC == (struct link_dynamic *)0) + return; + + /* Provision for alternate ld.so - security risk! */ + if (!(ldso = _getenv("LDSO"))) + ldso = LDSO; + + crt.crt_ldfd = open(ldso, 0, 0); + if (crt.crt_ldfd == -1) { + _FATAL("No ld.so\n"); + } + + /* Read LDSO exec header */ + if (read(crt.crt_ldfd, &hdr, sizeof hdr) < sizeof hdr) { + _FATAL("Failure reading ld.so\n"); + } + if (N_GETMAGIC(hdr) != ZMAGIC) { + _FATAL("Bad magic: ld.so\n"); + } + +#ifdef sun + /* Get bucket of zeroes */ + crt.crt_dzfd = open("/dev/zero", 0, 0); + if (crt.crt_dzfd == -1) { + _FATAL("No /dev/zero\n"); + } +#endif +#ifdef BSD + /* We use MAP_ANON */ + crt.crt_dzfd = -1; +#endif + +#if defined(sun) && defined(DUPZFD) + if ((dupzfd = dup(crt.crt_dzfd)) < 0) { + _FATAL("Cannot dup /dev/zero\n"); + } +#endif + + /* Map in ld.so */ + crt.crt_ba = mmap(0, hdr.a_text+hdr.a_data+hdr.a_bss, + PROT_READ|PROT_EXEC, + MAP_FILE|MAP_COPY, + crt.crt_ldfd, N_TXTOFF(hdr)); + if (crt.crt_ba == -1) { + _FATAL("Cannot map ld.so\n"); + } + +#ifdef BSD +/* !!! + * This is gross, ld.so is a ZMAGIC a.out, but has `sizeof(hdr)' for + * an entry point and not at PAGSIZ as the N_*ADDR macros assume. + */ +#undef N_DATADDR +#undef N_BSSADDR +#define N_DATADDR(x) ((x).a_text) +#define N_BSSADDR(x) ((x).a_text + (x).a_data) +#endif + + /* Map in data segment of ld.so writable */ + if (mmap(crt.crt_ba+N_DATADDR(hdr), hdr.a_data, + PROT_READ|PROT_EXEC|PROT_WRITE, + MAP_FIXED|MAP_FILE|MAP_COPY, + crt.crt_ldfd, N_DATOFF(hdr)) == -1) { + _FATAL("Cannot map ld.so\n"); + } + + /* Map bss segment of ld.so zero */ + if (hdr.a_bss && mmap(crt.crt_ba+N_BSSADDR(hdr), hdr.a_bss, + PROT_READ|PROT_EXEC|PROT_WRITE, + MAP_FIXED|MAP_ANON|MAP_COPY, + crt.crt_dzfd, 0) == -1) { + _FATAL("Cannot map ld.so\n"); + } + + crt.crt_dp = &_DYNAMIC; + crt.crt_ep = environ; + crt.crt_bp = (caddr_t)_callmain; + +#if defined(sparc) && defined(SUN_COMPAT) + /* Call Sun's ld.so entry point: version 1, offset crt */ + __call(CRT_VERSION_SUN, &crt, crt.crt_ba + sizeof hdr); +#else + entry = (void (*)())(crt.crt_ba + sizeof hdr); +#ifdef SUN_COMPAT + (*entry)(CRT_VERSION_SUN, &crt); +#else + (*entry)(CRT_VERSION_BSD, &crt); +#endif +#endif + +#if defined(sun) && defined(DUPZFD) + if (dup2(dupzfd, crt.crt_dzfd) < 0) { + _FATAL("Cannot dup2 /dev/zero\n"); + } + (void)close(dupzfd); +#endif + return; +} + +#ifdef sparc +static +__call() +{ + /* + * adjust the C generated pointer to the crt struct to the + * likings of ld.so, which is an offset relative to its %fp + */ +#if 0 + asm("___call:"); + asm("call %o2"); + asm("sub %o1, %sp, %o1"); /* adjust parameter */ +#else Hmmm... + asm("mov %i0, %o0"); + asm("mov %i1, %o1"); + asm("call %i2"); + asm("sub %o1, %sp, %o1"); + /*NOTREACHED, control is transferred directly to our caller */ +#endif +} +#endif -#ifdef CRT0 /* - * null mcount and moncontrol, - * just in case some routine is compiled for profiling + * Support routines */ -moncontrol(val) - int val; + +static int +_strncmp(s1, s2, n) + register char *s1, *s2; + register n; { + if (n == 0) + return (0); + do { + if (*s1 != *s2++) + return (*(unsigned char *)s1 - *(unsigned char *)--s2); + if (*s1++ == 0) + break; + } while (--n != 0); + return (0); } -mcount() { } -#endif CRT0 +static char * +_getenv(name) + register char *name; +{ + extern char **environ; + register int len; + register char **P, *C; + + for (C = name, len = 0; *C && *C != '='; ++C, ++len); + for (P = environ; *P; ++P) + if (!_strncmp(*P, name, len)) + if (*(C = *P + len) == '=') { + return(++C); + } + return (char *)0; +} + +#ifdef sparc + /* System call entry */ + asm("___syscall:"); + asm("clr %g1"); + asm("ta %g0"); + asm("bgeu Lsyscallx"); /* good result ? */ + asm("nop"); + asm("mov -0x1, %o0"); /* Note: no `errno' */ + asm("Lsyscallx:"); + asm("jmp %o7 + 0x8"); + asm("nop"); +#endif /* sparc */ +#ifdef i386 + asm(" ___syscall:"); + asm(" popl %ecx"); + asm(" popl %eax"); + asm(" pushl %ecx"); + asm(" .byte 0x9a"); + asm(" .long 0"); + asm(" .word 7"); + asm(" pushl %ecx"); + asm(" jc 1f"); + asm(" ret"); + asm(" 1:"); + asm(" movl $-1,%eax"); + asm(" ret"); +#endif /* i386 */ + +#endif /* DYNAMIC */ + +static char * +_strrchr(p, ch) +register char *p, ch; +{ + register char *save; + + for (save = NULL;; ++p) { + if (*p == ch) + save = (char *)p; + if (!*p) + return(save); + } +/* NOTREACHED */ +} + +#ifdef MCRT0 +asm (" .text"); +asm ("_eprol:"); +#endif diff --git a/lib/csu/i386/gmon.c b/lib/csu/i386/gmon.c index 55486881e133..4ca8333ecdb0 100644 --- a/lib/csu/i386/gmon.c +++ b/lib/csu/i386/gmon.c @@ -32,7 +32,8 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)gmon.c 5.3 (Berkeley) 5/22/91"; +/*static char sccsid[] = "from: @(#)gmon.c 5.3 (Berkeley) 5/22/91";*/ +static char rcsid[] = "$Id: gmon.c,v 1.2 1993/08/01 18:44:18 mycroft Exp $"; #endif /* LIBC_SCCS and not lint */ diff --git a/lib/csu/i386/gmon.h b/lib/csu/i386/gmon.h index c89a721972bd..e40060216a41 100644 --- a/lib/csu/i386/gmon.h +++ b/lib/csu/i386/gmon.h @@ -30,7 +30,8 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * @(#)gmon.h 5.2 (Berkeley) 5/6/91 + * from: @(#)gmon.h 5.2 (Berkeley) 5/6/91 + * $Id: gmon.h,v 1.2 1993/08/01 18:44:21 mycroft Exp $ */ struct phdr { -- cgit v1.2.3