Thu Jul 18 04:33:21 1996 Roland McGrath <roland@baalperazim.frob.com>
[glibc.git] / sysdeps / alpha / elf / start.S
blobc534d6987b41338dcbbb46daba59b9f502a072dd
1 /* Startup code for Alpha/ELF.
2 Copyright (C) 1993, 1995, 1996 Free Software Foundation, Inc.
3 Contributed by Richard Henderson <rth@tamu.edu>
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public License as
7 published by the Free Software Foundation; either version 2 of the
8 License, or (at your option) any later version.
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 Library General Public License for more details.
15 You should have received a copy of the GNU Library General Public
16 License along with the GNU C Library; see the file COPYING.LIB.  If
17 not, write to the Free Software Foundation, Inc., 675 Mass Ave,
18 Cambridge, MA 02139, USA.  */
20 #include <sysdep.h>
22         .text
23         .globl __start
24         .align 3
25         .ent __start, 0
26 __start:
27         .frame fp, 0, zero
28         mov     zero, fp
29         br      gp, 1f
30 1:      ldgp    gp, 0(gp)
31         .prologue 1
33   /* Save v0.  When starting a binary via the dynamic linker, s0
34      contains the address of the shared library termination function,
35      which we will register below with atexit() to be called by exit().
36      If we are statically linked, this will be NULL.  */
37         mov     v0, s0
39   /* Do essential libc initialization (sp points to argc, argv, and envp)  */
40         jsr     ra, __libc_init_first
41         ldgp    gp, 0(ra)
43   /* Now that we have the proper stack frame, register library termination
44      function, if there is any:  */
46         beq     s0, 1f
47         mov     s0, a0
48         jsr     ra, atexit
49         ldgp    gp, 0(ra)
52   /* Extract the arguments and environment as encoded on the stack.  */
53         ldl     a0, 0(sp)       /* get argc */
54         lda     a1, 8(sp)       /* get argv */
55         s8addq  a0, a1, a2      /* get envp */
56         addq    a2, 8, a2
57         stq     a2, _environ
59         mov     a0, s0          /* tuck them away */
60         mov     a1, s1
61         mov     a2, s2
63 #ifdef HAVE_INITFINI
64   /* Call _init, the entry point to our own .init section.  */
65         jsr     ra, _init
66         ldgp    gp, 0(ra)
68   /* Register our .fini section with atexit.  */
69         lda     a0, _fini
70         jsr     ra, atexit
71         ldgp    gp, 0(ra)
72 #else
73   /* initialize constructors: */
74         jsr     ra, __main
75         ldgp    gp, 0(ra)
76 #endif
77         mov     s0, a0
78         mov     s1, a1
79         mov     s2, a2
81   /* Call the user's main and exit with its return value.  */
82         jsr     ra, main
83         ldgp    gp, 0(ra)
85         mov     v0, a0
86         jsr     ra, exit
88   /* Die very horribly if exit returns.  Call_pal hlt is callable from
89      kernel mode only; this will result in an illegal instruction trap.  */
90         call_pal 0
91 END(__start)
93 /* Define a symbol for the first piece of initialized data.  */
94         .data
95         .globl __data_start
96 __data_start:
97         .long 0
99 #ifdef __ELF__
100         .size __data_start, 4
101         .type __data_start, @object
102 #endif
104 weak_alias(__data_start, data_start)