__uClibc_main.c 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. /*
  2. * Manuel Novoa III Feb 2001
  3. * Erik Anderseni Mar 2002
  4. *
  5. * __uClibc_main is the routine to be called by all the arch-specific
  6. * versions of crt0.S in uClibc.
  7. *
  8. * It is meant to handle any special initialization needed by the library
  9. * such as setting the global variable(s) __environ (environ) and
  10. * initializing the stdio package. Using weak symbols, the latter is
  11. * avoided in the static library case.
  12. */
  13. #define _ERRNO_H
  14. #include <unistd.h>
  15. #if !defined HAVE_ELF
  16. /* This is a theoretical attempt to support old a.out compilers.
  17. * Dunno if this will work properly and I really don't much
  18. * care... Elf is the One True Path(tm). You will be assimilated */
  19. # define __USE_WEAK_ALIASES
  20. #endif
  21. /*
  22. * Prototypes.
  23. */
  24. extern int main(int argc, char **argv, char **envp);
  25. #ifndef __USE_WEAK_ALIASES
  26. #include <stdlib.h>
  27. extern int weak_function atexit(void (*function)(void));
  28. extern void weak_function _init(void);
  29. extern void weak_function _fini(void);
  30. extern void weak_function _stdio_init(void);
  31. extern void weak_function _stdio_term(void);
  32. extern int *weak_const_function __errno_location(void);
  33. extern int *weak_const_function __h_errno_location(void);
  34. #ifdef __UCLIBC_HAS_LOCALE__
  35. extern void weak_function _locale_init(void);
  36. #endif
  37. #else
  38. /*
  39. * Define an empty function and use it as a weak alias for the stdio
  40. * initialization routine. That way we don't pull in all the stdio
  41. * code unless we need to. Similarly, do the same for _stdio_term
  42. * so as not to include atexit unnecessarily.
  43. *
  44. * NOTE!!! This is only true for the _static_ case!!!
  45. */
  46. weak_alias(__environ, environ);
  47. void __uClibc_empty_func(void)
  48. {
  49. }
  50. extern void exit (int status) __attribute__ ((__noreturn__));
  51. extern void _init(void);
  52. extern void _fini(void);
  53. extern void _stdio_init(void);
  54. weak_alias(__uClibc_empty_func, _init);
  55. weak_alias(__uClibc_empty_func, _fini);
  56. //weak_alias(__uClibc_empty_func, _stdio_init);
  57. //weak_alias(__uClibc_empty_func, _stdio_term);
  58. //weak_alias(__uClibc_empty_func, atexit);
  59. extern int atexit(void (*function)(void));
  60. //weak_alias(__uClibc_empty_func, __errno_location);
  61. extern int *__errno_location(void);
  62. //weak_alias(__uClibc_empty_func, __h_errno_location);
  63. extern int *__h_errno_location(void);
  64. #ifdef __UCLIBC_HAS_LOCALE__
  65. extern void _locale_init(void);
  66. #endif
  67. #endif
  68. /*
  69. * Declare the __environ global variable and create a weak alias environ.
  70. * Note: Apparently we must initialize __environ for the weak environ
  71. * symbol to be included.
  72. */
  73. char **__environ = 0;
  74. weak_alias(__environ, environ);
  75. /*
  76. * Now for our main routine.
  77. */
  78. void __attribute__ ((__noreturn__))
  79. __uClibc_main(int argc, char **argv, char **envp)
  80. {
  81. /*
  82. * Initialize the global variable __environ.
  83. */
  84. __environ = envp;
  85. #if 0
  86. /* Some security at this point. Prevent starting a SUID binary
  87. * where the standard file descriptors are not opened. We have
  88. * to do this only for statically linked applications since
  89. * otherwise the dynamic loader did the work already. */
  90. if (unlikely (__libc_enable_secure))
  91. __libc_check_standard_fds ();
  92. #endif
  93. #ifdef __UCLIBC_HAS_LOCALE__
  94. /* Initialize the global locale structure. */
  95. if (likely(_locale_init)) _locale_init();
  96. #endif
  97. /*
  98. * Initialize stdio here. In the static library case, this will
  99. * be bypassed if not needed because of the weak alias above.
  100. */
  101. if (likely(_stdio_init))
  102. _stdio_init();
  103. /* Arrange for dtors to run at exit. */
  104. if (_fini && atexit) {
  105. atexit (&_fini);
  106. }
  107. /* Run all ctors now. */
  108. if (_init)
  109. _init();
  110. /*
  111. * Note: It is possible that any initialization done above could
  112. * have resulted in errno being set nonzero, so set it to 0 before
  113. * we call main.
  114. */
  115. if (likely(__errno_location))
  116. *(__errno_location()) = 0;
  117. /* Set h_errno to 0 as well */
  118. if (likely(__h_errno_location))
  119. *(__h_errno_location()) = 0;
  120. /*
  121. * Finally, invoke application's main and then exit.
  122. */
  123. exit(main(argc, argv, envp));
  124. }