aboutsummaryrefslogtreecommitdiff
path: root/lib/csu
diff options
context:
space:
mode:
Diffstat (limited to 'lib/csu')
-rw-r--r--lib/csu/i386/crt0.c208
1 files 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 <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 */