| /* 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 */ |