1/*-
2 * SPDX-License-Identifier: BSD-2-Clause
3 *
4 * Copyright (C) 2023 Dmitry Chagin <dchagin@FreeBSD.org>
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 *    notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 *    notice, this list of conditions and the following disclaimer in the
13 *    documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 */
27
28#include <machine/asm.h>
29
30
31	.text
32	.align 8
33
34	/*
35	 * The program entry point
36	 *		  %rdi		%rsi
37	 * void _start(char **ap, void (*cleanup)(void)) __dead2
38	 */
39	.globl	_start
40	.type	_start, @function
41_start:
42	.cfi_startproc
43	.cfi_undefined %rip		/* Terminate call chain. */
44	pushq	%rbp			/* Align stack, terminate call chain. */
45	.cfi_def_cfa_offset 8
46	movq	%rsp, %rbp
47	.cfi_offset %rbp, -16
48	.cfi_def_cfa_register %rbp
49#ifdef GCRT
50	subq	$16, %rsp
51#endif
52	movq	%rsi, %rcx
53	movq	%rdi, %rsi		/* argv = ap */
54	addq	$8, %rsi		/* argv += 1 */
55	movq	%rdi, %rdx		/* env = ap */
56	addq	$16, %rdx		/* env += 2 */
57	movslq	(%rdi), %rax
58	movl	%eax, %edi		/* argc = *(long *)(void *)ap */
59	shlq	$3, %rax
60	addq	%rax, %rdx		/* env += argc */
61#ifdef PIC
62	/*
63	 * XXX. %rip relative addressing is not intended for use in the
64	 * large memory model due to the offset from %rip being limited
65	 * to 32 bits.
66	 */
67	leaq	main@plt(%rip), %r8
68#else
69	movabsq	$main, %r8
70#endif
71#ifdef GCRT
72	movabsq	$eprol, %r9
73	movabsq	$etext, %rax
74	movq    %rax, (%rsp)
75	/*
76	 *		      %edi  %rsi  %rdx  %rcx    %r8    %r9    (%rsp)
77	 * __libc_start1_gcrt(argc, argv, env, cleanup, main, &eprol, &etext)
78	 */
79	callq	__libc_start1_gcrt
80eprol:
81#else
82	/* __libc_start1(argc, argv, env, cleanup, main) */
83	callq	__libc_start1
84#endif
85	int3
86	.cfi_endproc
87	.size   _start, . - _start
88
89	.section .note.GNU-stack,"",%progbits
90