New dlopen, dlclose, etc al. For the new ld changes.
This commit is contained in:
parent
a70c96594a
commit
14a24404ef
@ -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 */
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user