85 lines
		
	
	
		
			2.3 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			85 lines
		
	
	
		
			2.3 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /* 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);
 | |
| 
 | |
| extern void (*const __preinit_array_start[])(int, char **, char**) __attribute__((weak));
 | |
| extern void (*const __preinit_array_end[])(int, char **, char**) __attribute__((weak));
 | |
| 
 | |
| extern void (*const __init_array_start[])(int, char **, char**) __attribute__((weak));
 | |
| extern void (*const __init_array_end[])(int, char **, char**) __attribute__((weak));
 | |
| 
 | |
| extern void (*const __fini_array_start[])(void) __attribute__((weak));
 | |
| extern void (*const __fini_array_end[])(void) __attribute__((weak));
 | |
| 
 | |
| __attribute__((weak,used))
 | |
| void _start_c(long *sp)
 | |
| {
 | |
| 	long argc;
 | |
| 	char **argv;
 | |
| 	char **envp;
 | |
| 	int exitcode;
 | |
| 	void (* const *ctor_func)(int, char **, char **);
 | |
| 	void (* const *dtor_func)(void);
 | |
| 	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;
 | |
| 
 | |
| 	for (ctor_func = __preinit_array_start; ctor_func < __preinit_array_end; ctor_func++)
 | |
| 		(*ctor_func)(argc, argv, envp);
 | |
| 	for (ctor_func = __init_array_start; ctor_func < __init_array_end; ctor_func++)
 | |
| 		(*ctor_func)(argc, argv, envp);
 | |
| 
 | |
| 	/* go to application */
 | |
| 	exitcode = _nolibc_main(argc, argv, envp);
 | |
| 
 | |
| 	for (dtor_func = __fini_array_end; dtor_func > __fini_array_start;)
 | |
| 		(*--dtor_func)();
 | |
| 
 | |
| 	exit(exitcode);
 | |
| }
 | |
| 
 | |
| #endif /* _NOLIBC_CRT_H */
 |