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
55 extern void _start_c(long *);
56 extern int main(int, const char **, char **);
57
58 #include "start_arch.h"
59
60 void
_start_c(long * p)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