crt.h 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. /* SPDX-License-Identifier: LGPL-2.1 OR MIT */
  2. /*
  3. * C Run Time support for NOLIBC
  4. * Copyright (C) 2023 Zhangjin Wu <falcon@tinylab.org>
  5. */
  6. #ifndef _NOLIBC_CRT_H
  7. #define _NOLIBC_CRT_H
  8. char **environ __attribute__((weak));
  9. const unsigned long *_auxv __attribute__((weak));
  10. static void __stack_chk_init(void);
  11. static void exit(int);
  12. extern void (*const __preinit_array_start[])(int, char **, char**) __attribute__((weak));
  13. extern void (*const __preinit_array_end[])(int, char **, char**) __attribute__((weak));
  14. extern void (*const __init_array_start[])(int, char **, char**) __attribute__((weak));
  15. extern void (*const __init_array_end[])(int, char **, char**) __attribute__((weak));
  16. extern void (*const __fini_array_start[])(void) __attribute__((weak));
  17. extern void (*const __fini_array_end[])(void) __attribute__((weak));
  18. __attribute__((weak,used))
  19. void _start_c(long *sp)
  20. {
  21. long argc;
  22. char **argv;
  23. char **envp;
  24. int exitcode;
  25. void (* const *ctor_func)(int, char **, char **);
  26. void (* const *dtor_func)(void);
  27. const unsigned long *auxv;
  28. /* silence potential warning: conflicting types for 'main' */
  29. int _nolibc_main(int, char **, char **) __asm__ ("main");
  30. /* initialize stack protector */
  31. __stack_chk_init();
  32. /*
  33. * sp : argc <-- argument count, required by main()
  34. * argv: argv[0] <-- argument vector, required by main()
  35. * argv[1]
  36. * ...
  37. * argv[argc-1]
  38. * null
  39. * environ: environ[0] <-- environment variables, required by main() and getenv()
  40. * environ[1]
  41. * ...
  42. * null
  43. * _auxv: _auxv[0] <-- auxiliary vector, required by getauxval()
  44. * _auxv[1]
  45. * ...
  46. * null
  47. */
  48. /* assign argc and argv */
  49. argc = *sp;
  50. argv = (void *)(sp + 1);
  51. /* find environ */
  52. environ = envp = argv + argc + 1;
  53. /* find _auxv */
  54. for (auxv = (void *)envp; *auxv++;)
  55. ;
  56. _auxv = auxv;
  57. for (ctor_func = __preinit_array_start; ctor_func < __preinit_array_end; ctor_func++)
  58. (*ctor_func)(argc, argv, envp);
  59. for (ctor_func = __init_array_start; ctor_func < __init_array_end; ctor_func++)
  60. (*ctor_func)(argc, argv, envp);
  61. /* go to application */
  62. exitcode = _nolibc_main(argc, argv, envp);
  63. for (dtor_func = __fini_array_end; dtor_func > __fini_array_start;)
  64. (*--dtor_func)();
  65. exit(exitcode);
  66. }
  67. #endif /* _NOLIBC_CRT_H */