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