summaryrefslogtreecommitdiff
path: root/libc/misc/internals/__uClibc_main.c
blob: 4a0f840cb264da9c5e4e12230ab7a2ab3fe03051 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
/*
 * Manuel Novoa III           Feb 2001
 * Erik Anderseni             Mar 2002
 *
 * __uClibc_main is the routine to be called by all the arch-specific
 * versions of crt0.S in uClibc.
 *
 * It is meant to handle any special initialization needed by the library
 * such as setting the global variable(s) __environ (environ) and
 * initializing the stdio package.  Using weak symbols, the latter is
 * avoided in the static library case.
 */

#define	_ERRNO_H
#include <stdlib.h>
#include <unistd.h>

#if !defined HAVE_ELF || !defined __UCLIBC_HAS_MMU__
# undef weak_function
# undef weak_const_function
# define weak_function
# define weak_const_function
# define __USE_WEAK_ALIASES
#endif

/*
 * Prototypes.
 */
extern int main(int argc, char **argv, char **envp);
extern int weak_function atexit(void (*function)(void));
extern void weak_function _init(void);
extern void weak_function _fini(void);
extern void weak_function _stdio_init(void);
extern void weak_function _stdio_term(void);
extern int *weak_const_function __errno_location(void);
extern int *weak_const_function __h_errno_location(void);

/*
 * Declare the __environ global variable and create a weak alias environ.
 * Note: Apparently we must initialize __environ for the weak environ
 * symbol to be included.
 */

char **__environ = 0;
weak_alias(__environ, environ);


/*
 * Now for our main routine.
 */
void __attribute__ ((__noreturn__)) 
__uClibc_main(int argc, char **argv, char **envp) 
{
	/* 
	 * Initialize the global variable __environ.
	 */
	__environ = envp;

#if 0
	/* Some security at this point.  Prevent starting a SUID binary
	 * where the standard file descriptors are not opened.  We have
	 * to do this only for statically linked applications since
	 * otherwise the dynamic loader did the work already.  */
	if (unlikely (__libc_enable_secure))
	    __libc_check_standard_fds ();
#endif
	/*
	 * Initialize stdio here.  In the static library case, this will
	 * be bypassed if not needed because of the weak alias above.
	 */
	if (likely(_stdio_init))
	  _stdio_init();

	/* Arrange for dtors to run at exit.  */
	atexit (&_fini);
	/* Run all ctors now.  */
	_init();

	/*
	 * Note: It is possible that any initialization done above could
	 * have resulted in errno being set nonzero, so set it to 0 before
	 * we call main.
	 */
	if (likely(__errno_location))
	    *(__errno_location()) = 0;

	/* Set h_errno to 0 as well */
	if (likely(__h_errno_location))
	    *(__h_errno_location()) = 0;

	/*
	 * Finally, invoke application's main and then exit.
	 */
	exit(main(argc, argv, envp));
}

#ifdef __USE_WEAK_ALIASES
/*
 * Define an empty function and use it as a weak alias for the stdio
 * initialization routine.  That way we don't pull in all the stdio
 * code unless we need to.  Similarly, do the same for _stdio_term
 * so as not to include atexit unnecessarily.
 *
 * NOTE!!! This is only true for the _static_ case!!!
 */

weak_alias(__environ, environ);
void __uClibc_empty_func(void)
{
}
weak_alias(__uClibc_empty_func, atexit);
weak_alias(__uClibc_empty_func, _init);
weak_alias(__uClibc_empty_func, _fini);
weak_alias(__uClibc_empty_func, __errno_location);
weak_alias(__uClibc_empty_func, __h_errno_location);
weak_alias(__uClibc_empty_func, _stdio_init);
weak_alias(__uClibc_empty_func, _stdio_term);
#endif