master
  1/* Startup code compliant to the ELF x86-64 ABI.
  2   Copyright (C) 2001-2020 Free Software Foundation, Inc.
  3   This file is part of the GNU C Library.
  4   Contributed by Andreas Jaeger <aj@suse.de>, 2001.
  5
  6   The GNU C Library is free software; you can redistribute it and/or
  7   modify it under the terms of the GNU Lesser General Public
  8   License as published by the Free Software Foundation; either
  9   version 2.1 of the License, or (at your option) any later version.
 10
 11   In addition to the permissions in the GNU Lesser General Public
 12   License, the Free Software Foundation gives you unlimited
 13   permission to link the compiled version of this file with other
 14   programs, and to distribute those programs without any restriction
 15   coming from the use of this file. (The GNU Lesser General Public
 16   License restrictions do apply in other respects; for example, they
 17   cover modification of the file, and distribution when not linked
 18   into another program.)
 19
 20   Note that people who make modified versions of this file are not
 21   obligated to grant this special exception for their modified
 22   versions; it is their choice whether to do so. The GNU Lesser
 23   General Public License gives permission to release a modified
 24   version without this exception; this exception also makes it
 25   possible to release a modified version which carries forward this
 26   exception.
 27
 28   The GNU C Library is distributed in the hope that it will be useful,
 29   but WITHOUT ANY WARRANTY; without even the implied warranty of
 30   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 31   Lesser General Public License for more details.
 32
 33   You should have received a copy of the GNU Lesser General Public
 34   License along with the GNU C Library; if not, see
 35   <https://www.gnu.org/licenses/>.  */
 36
 37/* This is the canonical entry point, usually the first thing in the text
 38   segment.  The SVR4/i386 ABI (pages 3-31, 3-32) says that when the entry
 39   point runs, most registers' values are unspecified, except for:
 40
 41   %rdx		Contains a function pointer to be registered with `atexit'.
 42		This is how the dynamic linker arranges to have DT_FINI
 43		functions called for shared libraries that have been loaded
 44		before this code runs.
 45
 46   %rsp		The stack contains the arguments and environment:
 47		0(%rsp)				argc
 48		LP_SIZE(%rsp)			argv[0]
 49		...
 50		(LP_SIZE*argc)(%rsp)		NULL
 51		(LP_SIZE*(argc+1))(%rsp)	envp[0]
 52		...
 53						NULL
 54*/
 55
 56#include <sysdep.h>
 57
 58ENTRY (_start)
 59	/* Clearing frame pointer is insufficient, use CFI.  */
 60	cfi_undefined (rip)
 61	/* Clear the frame pointer.  The ABI suggests this be done, to mark
 62	   the outermost frame obviously.  */
 63	xorl %ebp, %ebp
 64
 65	/* Extract the arguments as encoded on the stack and set up
 66	   the arguments for __libc_start_main (int (*main) (int, char **, char **),
 67		   int argc, char *argv,
 68		   void (*init) (void), void (*fini) (void),
 69		   void (*rtld_fini) (void), void *stack_end).
 70	   The arguments are passed via registers and on the stack:
 71	main:		%rdi
 72	argc:		%rsi
 73	argv:		%rdx
 74	init:		%rcx
 75	fini:		%r8
 76	rtld_fini:	%r9
 77	stack_end:	stack.	*/
 78
 79	mov %RDX_LP, %R9_LP	/* Address of the shared library termination
 80				   function.  */
 81#ifdef __ILP32__
 82	mov (%rsp), %esi	/* Simulate popping 4-byte argument count.  */
 83	add $4, %esp
 84#else
 85	popq %rsi		/* Pop the argument count.  */
 86#endif
 87	/* argv starts just at the current stack top.  */
 88	mov %RSP_LP, %RDX_LP
 89	/* Align the stack to a 16 byte boundary to follow the ABI.  */
 90	and  $~15, %RSP_LP
 91
 92	/* Push garbage because we push 8 more bytes.  */
 93	pushq %rax
 94
 95	/* Provide the highest stack address to the user code (for stacks
 96	   which grow downwards).  */
 97	pushq %rsp
 98
 99#ifdef PIC
100	/* Pass address of our own entry points to .fini and .init.  */
101	mov __libc_csu_fini@GOTPCREL(%rip), %R8_LP
102	mov __libc_csu_init@GOTPCREL(%rip), %RCX_LP
103
104	mov main@GOTPCREL(%rip), %RDI_LP
105#else
106	/* Pass address of our own entry points to .fini and .init.  */
107	mov $__libc_csu_fini, %R8_LP
108	mov $__libc_csu_init, %RCX_LP
109
110	mov $main, %RDI_LP
111#endif
112
113	/* Call the user's main function, and exit with its value.
114	   But let the libc call main.  Since __libc_start_main in
115	   libc.so is called very early, lazy binding isn't relevant
116	   here.  Use indirect branch via GOT to avoid extra branch
117	   to PLT slot.  In case of static executable, ld in binutils
118	   2.26 or above can convert indirect branch into direct
119	   branch.  */
120	call *__libc_start_main@GOTPCREL(%rip)
121
122	hlt			/* Crash if somehow `exit' does return.	 */
123END (_start)
124
125/* Define a symbol for the first piece of initialized data.  */
126	.data
127	.globl __data_start
128__data_start:
129	.long 0
130	.weak data_start
131	data_start = __data_start