New dlopen, dlclose, etc al. For the new ld changes.

This commit is contained in:
Jordan K. Hubbard 1994-02-13 20:53:11 +00:00
parent a70c96594a
commit 14a24404ef
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=1157

View File

@ -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 <link.h>
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 */