8322 nl: misleading-indentation
[unleashed/tickless.git] / usr / src / cmd / sgs / rtld / sparcv9 / boot.s
blobd67dc3ef5a95f2a0445ca824dd405846111cdb99
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
19 * CDDL HEADER END
23 * Copyright (c) 1988 AT&T
24 * All Rights Reserved
26 * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
27 * Use is subject to license terms.
29 #pragma ident "%Z%%M% %I% %E% SMI"
32 * Bootstrap routine for ld.so. Control arrives here directly from
33 * exec() upon invocation of a dynamically linked program specifying ld.so
34 * as its interpreter.
36 * On entry, the stack appears as:
38 * !_______________________! high addresses
39 * ! 0 word !
40 * !_______________________!
41 * ! !
42 * ! Information !
43 * ! Block !
44 * ! (size varies) !
45 * !_______________________!
46 * ! Auxiliary !
47 * ! vector !
48 * ! 2 word entries !
49 * ! !
50 * !_______________________!
51 * ! 0 word !
52 * !_______________________!
53 * ! Environment !
54 * ! pointers !
55 * ! ... !
56 * ! (one word each) !
57 * !_______________________!
58 * ! 0 word !
59 * !_______________________!
60 * ! Argument ! low addresses
61 * ! pointers !
62 * ! Argc words !
63 * !_______________________!
64 * ! !
65 * ! Argc !
66 * !_______________________! <- %sp + STACK_BIAS + WINDOWSIZE
67 * ! !
68 * ! Window save area !
69 * !_______________________! <- %sp + STACK_BIAS
72 #if defined(lint)
74 extern unsigned long _setup();
75 extern void atexit_fini();
77 void
78 main()
80 (void) _setup();
81 atexit_fini();
84 #else
86 #include <sys/asm_linkage.h>
87 #include <sys/param.h>
88 #include <link.h>
90 .file "boot.s"
91 .seg ".text"
92 .global _rt_boot, _setup, atexit_fini
93 .type _rt_boot, #function
94 .align 4
96 ! Entry vector
97 ! +0: normal start
98 ! +4: normal start
99 ! +8: alias start (frame exists) XX64 what's this for?
101 _rt_boot:
103 ba,a _elf_start
104 ba,a _alias_start
106 ! Start up routines
108 _elf_start:
110 ! Create a stack frame, perform PIC set up. We have
111 ! to determine a bunch of things from our "environment" and
112 ! construct an Elf64_Boot attribute value vector.
114 save %sp, -SA(MINFRAME + (EB_MAX * 16)), %sp
116 _alias_start:
118 1: ! PIC prologue
119 call 2f
120 sethi %hh(_GLOBAL_OFFSET_TABLE_ + (. - 1b)), %g1
121 2: or %g1, %hm(_GLOBAL_OFFSET_TABLE_ + (. - 1b)), %g1
122 sllx %g1, 32, %g5
123 sethi %lm(_GLOBAL_OFFSET_TABLE_ + (. - 1b)), %l7
124 or %l7, %lo(_GLOBAL_OFFSET_TABLE_ + (. - 1b)), %l7
125 or %g5, %l7, %l7
126 add %l7, %o7, %l7 ! finish PIC prologue
128 ! %fp points to the root of our ELF bootstrap vector, use it to construct
129 ! the vector and send it to _setup.
131 ! The resulting Elf64_Boot vector looks like this:
133 ! Offset Contents
134 ! +0x0 EB_ARGV
135 ! +0x8 argv[]
136 ! +0x10 EB_ENVP
137 ! +0x18 envp[]
138 ! +0x20 EB_AUXV
139 ! +0x28 auxv[]
140 ! +0x30 EB_NULL
142 add %sp, STACK_BIAS + SA(MINFRAME), %o0
143 ! &eb[0] == %sp + frame size
144 mov EB_ARGV, %l0 ! code for this entry
145 stx %l0, [%o0] ! store it
146 add %fp, WINDOWSIZE + 8 + STACK_BIAS, %l0
147 ! argument vector
148 stx %l0, [%o0 + 0x8] ! store that
149 ldx [%fp + WINDOWSIZE + STACK_BIAS], %l1
150 ! get argument count (argc)
151 inc %l1 ! account for last element of 0
152 sllx %l1, 3, %l1 ! multiply by 8
153 add %l0, %l1, %l0 ! and get address of first env ptr
154 stx %l0, [%o0 + 0x18] ! store it in the vector
155 mov EB_ENVP, %l1 ! code for environment base
156 stx %l1, [%o0 + 0x10] ! store it
157 mov EB_AUXV, %l1 ! get code for auxiliary vector
158 stx %l1, [%o0 + 0x20] ! store it
160 3: ldx [%l0], %l1 ! get an entry
161 brnz,pt %l1, 3b ! if not at end, go back and look again
162 add %l0, 8, %l0 ! incrementing pointer in delay
163 stx %l0, [%o0 + 0x28] ! store aux vector pointer
165 mov EB_NULL, %l0 ! set up for the last pointer
166 stx %l0, [%o0 + 0x30] ! and store it
167 mov %g0, %g2 ! clear globals
168 mov %g0, %g3
170 ! Call _setup. Two arguments, the ELF bootstrap vector and our (unrelocated)
171 ! _DYNAMIC address. The _DYNAMIC address is located in entry 0 of the GOT
174 call _setup ! call it
175 ldx [%l7], %o1
177 ! On return, give callee the exit function in %g1, and jump to the
178 ! target program, clearing out the reserved globals as we go.
180 ldx [%l7 + atexit_fini], %g1! get function address
181 restore %o0, %g0, %l1 ! release frame
182 jmpl %l1, %g0 ! call main program
183 mov %g0, %g4 ! clear one last global in delay
185 .size _rt_boot, . - _rt_boot
186 #endif