From 14a24404ef973dace757ebdb648992989e00ba28 Mon Sep 17 00:00:00 2001 From: "Jordan K. Hubbard" Date: Sun, 13 Feb 1994 20:53:11 +0000 Subject: [PATCH] New dlopen, dlclose, etc al. For the new ld changes. --- lib/csu/i386/crt0.c | 208 ++++++++++++++------------------------------ 1 file changed, 63 insertions(+), 145 deletions(-) diff --git a/lib/csu/i386/crt0.c b/lib/csu/i386/crt0.c index 02700106463c..2b8c123bc48b 100644 --- a/lib/csu/i386/crt0.c +++ b/lib/csu/i386/crt0.c @@ -14,7 +14,7 @@ * must display the following acknowledgement: * 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 + * derived from this software without 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 @@ -27,7 +27,7 @@ * (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.6 1993/11/09 04:26:11 paul Exp $ + * $Id: crt0.c,v 1.12 1994/01/29 01:58:44 jtc Exp $ */ @@ -58,15 +58,12 @@ int _callmain(); #endif #include -extern struct link_dynamic _DYNAMIC; +extern struct _dynamic _DYNAMIC; +static struct ld_entry *ld_entry; static void __do_dynamic_link (); static char *_getenv(); static int _strncmp(); -#ifdef sparc -static __call(); -#endif - #ifdef sun #define LDSO "/usr/lib/ld.so" #endif @@ -114,68 +111,6 @@ char *__progname = empty; _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 { @@ -208,6 +143,12 @@ start() --targv; environ = targv; + if (argv[0]) + if ((__progname = _strrchr(argv[0], '/')) == NULL) + __progname = argv[0]; + else + ++__progname; + #ifdef DYNAMIC /* ld(1) convention: if DYNAMIC = 0 then statically linked */ #ifdef stupid_gcc @@ -226,18 +167,10 @@ asm("eprol:"); atexit(_mcleanup); monstartup(&eprol, &etext); #endif MCRT0 -#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 @@ -247,7 +180,7 @@ __do_dynamic_link () struct exec hdr; char *ldso; int dupzfd; - void (*entry)(); + int (*entry)(); #ifdef DEBUG /* Provision for alternate ld.so - security risk! */ @@ -264,27 +197,12 @@ __do_dynamic_link () if (read(crt.crt_ldfd, &hdr, sizeof hdr) < sizeof hdr) { _FATAL("Failure reading ld.so\n"); } - if ((N_GETMAGIC_NET(hdr) != ZMAGIC) && (N_GETMAGIC(hdr) != QMAGIC)) { + if (N_GETMAGIC(hdr) != ZMAGIC && N_GETMAGIC(hdr) != QMAGIC) { _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, @@ -325,49 +243,63 @@ __do_dynamic_link () crt.crt_dp = &_DYNAMIC; crt.crt_ep = environ; crt.crt_bp = (caddr_t)_callmain; + crt.crt_prog = __progname; -#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"); + entry = (int (*)())(crt.crt_ba + sizeof hdr); + if ((*entry)(CRT_VERSION_BSD_3, &crt) == -1) { + _FATAL("ld.so failed\n"); } - (void)close(dupzfd); -#endif + + ld_entry = _DYNAMIC.d_entry; return; } -#ifdef sparc -static -__call() +/* + * DL stubs + */ + +void * +dlopen(name, mode) +char *name; +int mode; { - /* - * 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 + if (ld_entry == NULL) + return NULL; + + return (ld_entry->dlopen)(name, mode); +} + +int +dlclose(fd) +void *fd; +{ + if (ld_entry == NULL) + return -1; + + return (ld_entry->dlclose)(fd); +} + +void * +dlsym(fd, name) +void *fd; +char *name; +{ + if (ld_entry == NULL) + return NULL; + + return (ld_entry->dlsym)(fd, name); +} + +int +dlctl(fd, cmd, arg) +void *fd, *arg; +int cmd; +{ + if (ld_entry == NULL) + return -1; + + return (ld_entry->dlctl)(fd, cmd, arg); } -#endif /* * Support routines @@ -407,19 +339,6 @@ _getenv(name) 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"); @@ -433,7 +352,6 @@ _getenv(name) asm(" 1:"); asm(" movl $-1,%eax"); asm(" ret"); -#endif /* i386 */ #endif /* DYNAMIC */