1/*
2 * Copyright (c) 2022, Netflix, Inc.
3 *
4 * SPDX-License-Identifier: BSD-2-Clause
5 */
6
7/*
8 * MI part of the C startup code. We take a long * pointer (we assume long is
9 * the same size as a pointer, as the Linux world is wont to do). We get a
10 * pointer to the stack with the main args on it. We don't bother decoding the
11 * aux vector, but may need to do so in the future.
12 *
13 * The long *p points to:
14 *
15 * +--------------------+
16 * | argc               | Small address
17 * +--------------------+
18 * | argv[0]            | argv
19 * +--------------------+
20 * | argv[1]            |
21 * +--------------------+
22 *  ...
23 * +--------------------+
24 * | NULL               | &argv[argc]
25 * +--------------------+
26 * | envp[0]            | envp
27 * +--------------------+
28 * | envp[1]            |
29 * +--------------------+
30 *  ...
31 * +--------------------+
32 * | NULL               |
33 * +--------------------+
34 * | aux type           | AT_xxxx
35 * +--------------------+
36 * | aux value          |
37 * +--------------------+
38 * | aux type           | AT_xxxx
39 * +--------------------+
40 * | aux value          |
41 * +--------------------+
42 * | aux type           | AT_xxxx
43 * +--------------------+
44 * | aux value          |
45 * +--------------------+
46 *...
47 * +--------------------+
48 * | NULL               |
49 * +--------------------+
50 *
51 * The AUX vector contains additional information for the process to know from
52 * the kernel (not parsed currently). AT_xxxx constants are small (< 50).
53 */
54
55extern void _start_c(long *);
56extern int main(int, const char **, char **);
57
58#include "start_arch.h"
59
60void
61_start_c(long *p)
62{
63	int argc;
64	const char **argv;
65	char **envp;
66
67	argc = p[0];
68	argv = (const char **)(p + 1);
69	envp = (char **)argv + argc + 1;
70
71	/* Note: we don't ensure that fd 0, 1, and 2 are sane at this level */
72	/* Also note: we expect main to exit, not return off the end */
73	main(argc, argv, envp);
74}
75