crt1.c revision 67811
134198Sjdp/*-
234198Sjdp * Copyright 1996-1998 John D. Polstra.
334198Sjdp * All rights reserved.
434198Sjdp *
534198Sjdp * Redistribution and use in source and binary forms, with or without
634198Sjdp * modification, are permitted provided that the following conditions
734198Sjdp * are met:
834198Sjdp * 1. Redistributions of source code must retain the above copyright
934198Sjdp *    notice, this list of conditions and the following disclaimer.
1034198Sjdp * 2. Redistributions in binary form must reproduce the above copyright
1134198Sjdp *    notice, this list of conditions and the following disclaimer in the
1234198Sjdp *    documentation and/or other materials provided with the distribution.
1334198Sjdp *
1434198Sjdp * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
1534198Sjdp * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
1634198Sjdp * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
1734198Sjdp * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
1834198Sjdp * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
1934198Sjdp * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2034198Sjdp * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2134198Sjdp * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2234198Sjdp * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
2334198Sjdp * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2434198Sjdp *
2550476Speter * $FreeBSD: head/lib/csu/amd64/crt1.c 67811 2000-10-28 21:26:48Z obrien $
2634198Sjdp */
2734198Sjdp
2834198Sjdp#ifndef __GNUC__
2934198Sjdp#error "GCC is needed to compile this file"
3034198Sjdp#endif
3134198Sjdp
3242049Ssteve#include <stddef.h>
3334198Sjdp#include <stdlib.h>
3467811Sobrien#include "crtbrand.c"
3534198Sjdp
3634198Sjdptypedef void (*fptr)(void);
3734198Sjdp
3834198Sjdpextern void _fini(void);
3934198Sjdpextern void _init(void);
4034198Sjdpextern int main(int, char **, char **);
4134198Sjdp
4238928Sjdp#ifdef GCRT
4338928Sjdpextern void _mcleanup(void);
4438928Sjdpextern void monstartup(void *, void *);
4538928Sjdpextern int eprol;
4638928Sjdpextern int etext;
4738928Sjdp#endif
4838928Sjdp
4934198Sjdpextern int _DYNAMIC;
5034198Sjdp#pragma weak _DYNAMIC
5134198Sjdp
5234198Sjdp#ifdef __i386__
5334198Sjdp#define get_rtld_cleanup()				\
5434198Sjdp    ({ fptr __value;					\
5534198Sjdp       __asm__("movl %%edx,%0" : "=rm"(__value));	\
5634198Sjdp       __value; })
5734198Sjdp#else
5834198Sjdp#error "This file only supports the i386 architecture"
5934198Sjdp#endif
6034198Sjdp
6134198Sjdpchar **environ;
6234198Sjdpchar *__progname = "";
6334198Sjdp
6434198Sjdpvoid
6534198Sjdp_start(char *arguments, ...)
6634198Sjdp{
6734198Sjdp    fptr rtld_cleanup;
6834198Sjdp    int argc;
6934198Sjdp    char **argv;
7034198Sjdp    char **env;
7134198Sjdp
7234198Sjdp    rtld_cleanup = get_rtld_cleanup();
7334198Sjdp    argv = &arguments;
7434198Sjdp    argc = * (int *) (argv - 1);
7534198Sjdp    env = argv + argc + 1;
7634198Sjdp    environ = env;
7742049Ssteve    if(argc > 0 && argv[0] != NULL) {
7842049Ssteve	char *s;
7934198Sjdp	__progname = argv[0];
8042049Ssteve	for (s = __progname; *s != '\0'; s++)
8142049Ssteve	    if (*s == '/')
8242049Ssteve		__progname = s + 1;
8342049Ssteve    }
8434198Sjdp
8542049Ssteve    if(&_DYNAMIC != NULL)
8634198Sjdp	atexit(rtld_cleanup);
8734198Sjdp
8838928Sjdp#ifdef GCRT
8938928Sjdp    atexit(_mcleanup);
9038928Sjdp#endif
9134198Sjdp    atexit(_fini);
9238928Sjdp#ifdef GCRT
9338928Sjdp    monstartup(&eprol, &etext);
9438928Sjdp#endif
9534198Sjdp    _init();
9634198Sjdp    exit( main(argc, argv, env) );
9734198Sjdp}
9838928Sjdp
9938928Sjdp#ifdef GCRT
10038928Sjdp__asm__(".text");
10138928Sjdp__asm__("eprol:");
10238928Sjdp__asm__(".previous");
10338928Sjdp#endif
104