/* SPDX-License-Identifier: LGPL-2.1 OR MIT */ /* * C Run Time support for NOLIBC * Copyright (C) 2023 Zhangjin Wu <falcon@tinylab.org> */ #ifndef _NOLIBC_CRT_H #define _NOLIBC_CRT_H char **environ __attribute__((weak)); const unsigned long *_auxv __attribute__((weak)); static void __stack_chk_init(void); static void exit(int); __attribute__((weak)) void _start_c(long *sp) { long argc; char **argv; char **envp; const unsigned long *auxv; /* silence potential warning: conflicting types for 'main' */ int _nolibc_main(int, char **, char **) __asm__ ("main"); /* initialize stack protector */ __stack_chk_init(); /* * sp : argc <-- argument count, required by main() * argv: argv[0] <-- argument vector, required by main() * argv[1] * ... * argv[argc-1] * null * environ: environ[0] <-- environment variables, required by main() and getenv() * environ[1] * ... * null * _auxv: _auxv[0] <-- auxiliary vector, required by getauxval() * _auxv[1] * ... * null */ /* assign argc and argv */ argc = *sp; argv = (void *)(sp + 1); /* find environ */ environ = envp = argv + argc + 1; /* find _auxv */ for (auxv = (void *)envp; *auxv++;) ; _auxv = auxv; /* go to application */ exit(_nolibc_main(argc, argv, envp)); } #endif /* _NOLIBC_CRT_H */