1 /*
2  * Copyright (c) 2022, Netflix, Inc.
3  *
4  * SPDX-License-Identifier: BSD-2-Clause
5  */
6 
7 /*
8  * Provides a _start routine that calls a _start_c routine that takes a pointer
9  * to the stack as documented in crt1.c. We skip the pointer to _DYNAMIC since
10  * we don't support dynamic libraries, at all. And while _start_c is our own
11  * thing, we comport to the calling conventions that glibc and musl have and
12  * make sure the second argument (%esi) is 0 for _DYNAMIC placeholder.  We
13  * likely could call main directly with only a few more lines of code, but this
14  * is simple enough and concentrates all the expressable in C stuff there.  We
15  * also generate eh_frames should we need to debug things (it doesn't change the
16  * genreated code, but leaves enough breadcrumbs to keep gdb happy).
17  */
18 
19 __asm__(
20 ".text\n"			/* ENTRY(_start) */
21 ".p2align 4,0x90\n"
22 ".global _start\n"
23 ".type _start, @function\n"
24 "_start:\n"
25 ".cfi_startproc\n"
26 "	xor	%rbp, %rbp\n"		/* Clear out the stack frame pointer */
27 "	mov	%rsp, %rdi\n"		/* Pass pointer to current stack with argc, argv and envp on it */
28 "	xor	%rsi, %rsi\n"		/* No dynamic pointer for us, to keep it simple */
29 "	andq	$-16, %rsp\n"		/* Align stack to 16-byte boundary */
30 "	call	_start_c\n"		/* Our MI code takes it from here and won't return */
31 /* NORETURN */
32 ".size _start, . - _start\n"	/* END(_start) */
33 ".cfi_endproc"
34 );
35