1109905Smarkm/* LINTLIBRARY */
2100167Smarkm/*-
3100167Smarkm * Copyright 2001 David E. O'Brien.
487991Sobrien * All rights reserved.
587991Sobrien * Copyright (c) 1995, 1998 Berkeley Software Design, Inc.
687991Sobrien * All rights reserved.
787991Sobrien * Copyright 1996-1998 John D. Polstra.
887991Sobrien * All rights reserved.
987991Sobrien *
1087991Sobrien * Redistribution and use in source and binary forms, with or without
1187991Sobrien * modification, are permitted provided that the following conditions
1287991Sobrien * are met:
1387991Sobrien * 1. Redistributions of source code must retain the above copyright
1487991Sobrien *    notice, this list of conditions and the following disclaimer.
1587991Sobrien * 2. Redistributions in binary form must reproduce the above copyright
1687991Sobrien *    notice, this list of conditions and the following disclaimer in the
1787991Sobrien *    documentation and/or other materials provided with the distribution.
1887991Sobrien * 3. The name of the authors may not be used to endorse or promote products
1987991Sobrien *    derived from this software without specific prior written permission
2087991Sobrien *
2187991Sobrien * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
2287991Sobrien * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
2387991Sobrien * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
2487991Sobrien * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
2587991Sobrien * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
2687991Sobrien * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2787991Sobrien * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2887991Sobrien * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2987991Sobrien * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
3087991Sobrien * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3187991Sobrien */
3287991Sobrien
33216338Sdim#include <sys/cdefs.h>
34216338Sdim__FBSDID("$FreeBSD$");
35216338Sdim
36100167Smarkm#ifndef lint
3787991Sobrien#ifndef __GNUC__
3887991Sobrien#error "GCC is needed to compile this file"
3987991Sobrien#endif
40100167Smarkm#endif /* lint */
4187991Sobrien
4287991Sobrien#include <stdlib.h>
43100167Smarkm
4493399Smarkm#include "libc_private.h"
4587991Sobrien#include "crtbrand.c"
4687991Sobrien
4787991Sobrienstruct Struct_Obj_Entry;
4887991Sobrienstruct ps_strings;
4987991Sobrien
50100167Smarkmextern int _DYNAMIC;
5187991Sobrien#pragma weak _DYNAMIC
5287991Sobrien
53100167Smarkmextern void _fini(void);
5487991Sobrienextern void _init(void);
5587991Sobrienextern int main(int, char **, char **);
56100167Smarkmextern void __sparc_utrap_setup(void);
5787991Sobrien
5887991Sobrien#ifdef GCRT
5987991Sobrienextern void _mcleanup(void);
6087991Sobrienextern void monstartup(void *, void *);
6187991Sobrienextern int eprol;
6287991Sobrienextern int etext;
6387991Sobrien#endif
6487991Sobrien
6587991Sobrienchar **environ;
6693399Smarkmconst char *__progname = "";
6787991Sobrien
68204756Suqsvoid _start(char **, void (*)(void), struct Struct_Obj_Entry *,
69204756Suqs    struct ps_strings *);
70204756Suqs
7187991Sobrien/* The entry function. */
7288581Sjake/*
73109903Smarkm * %o0 holds ps_strings pointer.
7487991Sobrien *
7587991Sobrien * Note: kernel may (is not set in stone yet) pass ELF aux vector in %o1,
7687991Sobrien * but for now we do not use it here.
77109903Smarkm *
78109903Smarkm * The SPARC compliance definitions specifies that the kernel pass the
79109903Smarkm * address of a function to be executed on exit in %g1. We do not make
80109903Smarkm * use of it as it is quite broken, because gcc can use this register
81109903Smarkm * as a temporary, so it is not safe from C code. Its even more broken
82109903Smarkm * for dynamic executables since rtld runs first.
8387991Sobrien */
84100167Smarkm/* ARGSUSED */
8587991Sobrienvoid
86100167Smarkm_start(char **ap, void (*cleanup)(void), struct Struct_Obj_Entry *obj __unused,
87100167Smarkm    struct ps_strings *ps_strings __unused)
8887991Sobrien{
8987991Sobrien	int argc;
9087991Sobrien	char **argv;
9187991Sobrien	char **env;
9293399Smarkm	const char *s;
9387991Sobrien
94100167Smarkm	argc = *(long *)(void *)ap;
9587991Sobrien	argv = ap + 1;
9687991Sobrien	env  = ap + 2 + argc;
97245777Skib	if (environ == NULL)
98245777Skib		environ = env;
9991500Sobrien	if (argc > 0 && argv[0] != NULL) {
10087991Sobrien		__progname = argv[0];
10187991Sobrien		for (s = __progname; *s != '\0'; s++)
10287991Sobrien			if (*s == '/')
10387991Sobrien				__progname = s + 1;
10487991Sobrien	}
10587991Sobrien
10687991Sobrien	if (&_DYNAMIC != NULL)
10787991Sobrien		atexit(cleanup);
108163118Skmacy	else {
109163118Skmacy		__sparc_utrap_setup();
110133754Sdfr		_init_tls();
111163118Skmacy	}
11287991Sobrien#ifdef GCRT
11387991Sobrien	atexit(_mcleanup);
11487991Sobrien#endif
11587991Sobrien	atexit(_fini);
11687991Sobrien#ifdef GCRT
11787991Sobrien	monstartup(&eprol, &etext);
11887991Sobrien#endif
11987991Sobrien	_init();
12087991Sobrien	exit( main(argc, argv, env) );
12187991Sobrien}
12287991Sobrien
12387991Sobrien#ifdef GCRT
12487991Sobrien__asm__(".text");
12587991Sobrien__asm__("eprol:");
12687991Sobrien__asm__(".previous");
12787991Sobrien#endif
128