New dlopen, dlclose, etc al. For the new ld changes.
This commit is contained in:
parent
a70c96594a
commit
14a24404ef
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=1157
@ -14,7 +14,7 @@
|
|||||||
* must display the following acknowledgement:
|
* must display the following acknowledgement:
|
||||||
* This product includes software developed by Paul Kranenburg.
|
* This product includes software developed by Paul Kranenburg.
|
||||||
* 4. The name of the author may not be used to endorse or promote products
|
* 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
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
* 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
|
* (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, 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
|
#endif
|
||||||
#include <link.h>
|
#include <link.h>
|
||||||
|
|
||||||
extern struct link_dynamic _DYNAMIC;
|
extern struct _dynamic _DYNAMIC;
|
||||||
|
static struct ld_entry *ld_entry;
|
||||||
static void __do_dynamic_link ();
|
static void __do_dynamic_link ();
|
||||||
static char *_getenv();
|
static char *_getenv();
|
||||||
static int _strncmp();
|
static int _strncmp();
|
||||||
|
|
||||||
#ifdef sparc
|
|
||||||
static __call();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef sun
|
#ifdef sun
|
||||||
#define LDSO "/usr/lib/ld.so"
|
#define LDSO "/usr/lib/ld.so"
|
||||||
#endif
|
#endif
|
||||||
@ -114,68 +111,6 @@ char *__progname = empty;
|
|||||||
_exit(1);
|
_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()
|
start()
|
||||||
{
|
{
|
||||||
struct kframe {
|
struct kframe {
|
||||||
@ -208,6 +143,12 @@ start()
|
|||||||
--targv;
|
--targv;
|
||||||
environ = targv;
|
environ = targv;
|
||||||
|
|
||||||
|
if (argv[0])
|
||||||
|
if ((__progname = _strrchr(argv[0], '/')) == NULL)
|
||||||
|
__progname = argv[0];
|
||||||
|
else
|
||||||
|
++__progname;
|
||||||
|
|
||||||
#ifdef DYNAMIC
|
#ifdef DYNAMIC
|
||||||
/* ld(1) convention: if DYNAMIC = 0 then statically linked */
|
/* ld(1) convention: if DYNAMIC = 0 then statically linked */
|
||||||
#ifdef stupid_gcc
|
#ifdef stupid_gcc
|
||||||
@ -226,18 +167,10 @@ asm("eprol:");
|
|||||||
atexit(_mcleanup);
|
atexit(_mcleanup);
|
||||||
monstartup(&eprol, &etext);
|
monstartup(&eprol, &etext);
|
||||||
#endif MCRT0
|
#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 */
|
asm ("__callmain:"); /* Defined for the benefit of debuggers */
|
||||||
exit(main(kfp->kargc, argv, environ));
|
exit(main(kfp->kargc, argv, environ));
|
||||||
}
|
}
|
||||||
#endif /* i386 */
|
|
||||||
|
|
||||||
#ifdef DYNAMIC
|
#ifdef DYNAMIC
|
||||||
static void
|
static void
|
||||||
@ -247,7 +180,7 @@ __do_dynamic_link ()
|
|||||||
struct exec hdr;
|
struct exec hdr;
|
||||||
char *ldso;
|
char *ldso;
|
||||||
int dupzfd;
|
int dupzfd;
|
||||||
void (*entry)();
|
int (*entry)();
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
/* Provision for alternate ld.so - security risk! */
|
/* Provision for alternate ld.so - security risk! */
|
||||||
@ -264,27 +197,12 @@ __do_dynamic_link ()
|
|||||||
if (read(crt.crt_ldfd, &hdr, sizeof hdr) < sizeof hdr) {
|
if (read(crt.crt_ldfd, &hdr, sizeof hdr) < sizeof hdr) {
|
||||||
_FATAL("Failure reading ld.so\n");
|
_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");
|
_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 */
|
/* We use MAP_ANON */
|
||||||
crt.crt_dzfd = -1;
|
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 */
|
/* Map in ld.so */
|
||||||
crt.crt_ba = mmap(0, hdr.a_text,
|
crt.crt_ba = mmap(0, hdr.a_text,
|
||||||
@ -325,49 +243,63 @@ __do_dynamic_link ()
|
|||||||
crt.crt_dp = &_DYNAMIC;
|
crt.crt_dp = &_DYNAMIC;
|
||||||
crt.crt_ep = environ;
|
crt.crt_ep = environ;
|
||||||
crt.crt_bp = (caddr_t)_callmain;
|
crt.crt_bp = (caddr_t)_callmain;
|
||||||
|
crt.crt_prog = __progname;
|
||||||
|
|
||||||
#if defined(sparc) && defined(SUN_COMPAT)
|
entry = (int (*)())(crt.crt_ba + sizeof hdr);
|
||||||
/* Call Sun's ld.so entry point: version 1, offset crt */
|
if ((*entry)(CRT_VERSION_BSD_3, &crt) == -1) {
|
||||||
__call(CRT_VERSION_SUN, &crt, crt.crt_ba + sizeof hdr);
|
_FATAL("ld.so failed\n");
|
||||||
#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
|
ld_entry = _DYNAMIC.d_entry;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef sparc
|
/*
|
||||||
static
|
* DL stubs
|
||||||
__call()
|
*/
|
||||||
|
|
||||||
|
void *
|
||||||
|
dlopen(name, mode)
|
||||||
|
char *name;
|
||||||
|
int mode;
|
||||||
{
|
{
|
||||||
/*
|
if (ld_entry == NULL)
|
||||||
* adjust the C generated pointer to the crt struct to the
|
return NULL;
|
||||||
* likings of ld.so, which is an offset relative to its %fp
|
|
||||||
*/
|
return (ld_entry->dlopen)(name, mode);
|
||||||
#if 0
|
}
|
||||||
asm("___call:");
|
|
||||||
asm("call %o2");
|
int
|
||||||
asm("sub %o1, %sp, %o1"); /* adjust parameter */
|
dlclose(fd)
|
||||||
#else Hmmm...
|
void *fd;
|
||||||
asm("mov %i0, %o0");
|
{
|
||||||
asm("mov %i1, %o1");
|
if (ld_entry == NULL)
|
||||||
asm("call %i2");
|
return -1;
|
||||||
asm("sub %o1, %sp, %o1");
|
|
||||||
/*NOTREACHED, control is transferred directly to our caller */
|
return (ld_entry->dlclose)(fd);
|
||||||
#endif
|
}
|
||||||
|
|
||||||
|
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
|
* Support routines
|
||||||
@ -407,19 +339,6 @@ _getenv(name)
|
|||||||
return (char *)0;
|
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(" ___syscall:");
|
||||||
asm(" popl %ecx");
|
asm(" popl %ecx");
|
||||||
asm(" popl %eax");
|
asm(" popl %eax");
|
||||||
@ -433,7 +352,6 @@ _getenv(name)
|
|||||||
asm(" 1:");
|
asm(" 1:");
|
||||||
asm(" movl $-1,%eax");
|
asm(" movl $-1,%eax");
|
||||||
asm(" ret");
|
asm(" ret");
|
||||||
#endif /* i386 */
|
|
||||||
|
|
||||||
#endif /* DYNAMIC */
|
#endif /* DYNAMIC */
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user