2002-09-29 Roland McGrath <roland@redhat.com>
[kopensolaris-gnu/glibc.git] / sysdeps / x86_64 / elf / start.S
1 /* Startup code compliant to the ELF x86-64 ABI.
2    Copyright (C) 2001 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    The GNU C Library is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14    Lesser General Public License for more details.
15
16    You should have received a copy of the GNU Lesser General Public
17    License along with the GNU C Library; if not, write to the Free
18    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19    02111-1307 USA.  */
20
21 /* This is the canonical entry point, usually the first thing in the text
22    segment.  The SVR4/i386 ABI (pages 3-31, 3-32) says that when the entry
23    point runs, most registers' values are unspecified, except for:
24
25    %rdx         Contains a function pointer to be registered with `atexit'.
26                 This is how the dynamic linker arranges to have DT_FINI
27                 functions called for shared libraries that have been loaded
28                 before this code runs.
29
30    %rsp         The stack contains the arguments and environment:
31                 0(%rsp)                 argc
32                 8(%rsp)                 argv[0]
33                 ...
34                 (8*argc)(%rsp)          NULL
35                 (8*(argc+1))(%rsp)      envp[0]
36                 ...
37                                         NULL
38 */
39
40 #include "bp-sym.h"
41
42         .text
43         .globl _start
44         .type _start,@function
45 _start:
46         /* Clear the frame pointer.  The ABI suggests this be done, to mark
47            the outermost frame obviously.  */
48         xorq %rbp, %rbp
49
50         /* Extract the arguments as encoded on the stack and set up
51            the arguments for __libc_start_main (int (*main) (int, char **, char **),
52                    int argc, char *argv,
53                    void (*init) (void), void (*fini) (void),
54                    void (*rtld_fini) (void), void *stack_end).
55            The arguments are passed via registers and on the stack:
56         main:           %rdi
57         argc:           %rsi
58         argv:           %rdx
59         init:           %rcx
60         fini:           %r8
61         rtld_fini:      %r9
62         stack_end:      stack.  */
63
64         movq %rdx, %r9          /* Address of the shared library termination
65                                    function.  */
66         popq %rsi               /* Pop the argument count.  */
67         movq %rsp, %rdx         /* argv starts just at the current stack top.  */
68         /* Align the stack to a 16 byte boundary to follow the ABI.  */
69         andq  $~15, %rsp
70
71         pushq %rax              /* Push garbage because we push 8 more bytes.  */
72
73         /* Provide the highest stack address to the user code (for stacks
74            which grow downwards).  */
75         pushq %rsp
76
77         /* Pass address of our own entry points to .fini and .init.  */
78         movq $_fini, %r8
79         movq $_init, %rcx
80
81         movq $BP_SYM (main), %rdi
82
83         /* Call the user's main function, and exit with its value.
84            But let the libc call main.    */
85         call BP_SYM (__libc_start_main)
86
87         hlt                     /* Crash if somehow `exit' does return.  */
88
89 /* Define a symbol for the first piece of initialized data.  */
90         .data
91         .globl __data_start
92 __data_start:
93         .long 0
94         .weak data_start
95         data_start = __data_start