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