2 /* From: NetBSD: rtld_start.S,v 1.1 1996/12/16 20:38:09 cgd Exp */
5 * Copyright 1996 Matt Thomas <matt@3am-software.com>
6 * Copyright 2000 John D. Polstra
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. The name of the author may not be used to endorse or promote products
18 * derived from this software without specific prior written permission.
20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
21 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
22 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
23 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
24 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
29 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 #include <machine/asm.h>
33 #include <sys/syscall.h>
36 alloc r2=ar.pfs,3,0,3,0
38 1: mov r14=ip // calculate gp
44 2: data4 @ltv(1b) // unrelocated address of 1b
51 sub out0=r14,r15 // out0 is image base address
52 br.call.sptk.many rp=_rtld_reloc // fixup image
54 add sp=-16,sp // 16 bytes for us, 16 for _rtld
57 add out1=16,sp // address for exit proc
58 add out2=24,sp // address for obj_main
60 br.call.sptk.many rp=_rtld // r8=_rtld(sp, &exit_proc, &obj_main)
62 add r16=16,sp // address for exit proc
64 ld8 r15=[r16] // read exit proc
65 add sp=16,sp // readjust stack
66 mov b7=r8 // address of real _start
68 alloc r2=ar.pfs,0,0,3,0 // dump register frame
71 br.call.sptk.many rp=b7 // transfer to main program
72 br.call.sptk.many rp=exit // die
76 * _rtld_bind_start: lookup a lazy binding and transfer to real target
79 * r1 gp value for rtld
81 * r16 Obj_Entry of caller
82 * in0-in7 Arguments for target procedure
83 * rp Return address back to caller
85 ENTRY(_rtld_bind_start, 0)
87 alloc loc0=ar.pfs,8,6,3,0 // space to save r8-r11
88 add r17=16-8*16,sp // leave 16 bytes for _rtld_bind
92 mov loc2=r8 // structure return address
93 add sp=-8*16,sp // space to save f8-f15
97 stf.spill [r17]=f8,32 // save float arguments
98 mov loc3=r9 // language specific
99 mov loc4=r10 // language specific
101 stf.spill [r18]=f9,32
102 mov loc5=r11 // language specific
103 shl out1=r15,4 // 16 * index
106 stf.spill [r17]=f10,32
107 stf.spill [r18]=f11,32
108 mov out0=r16 // Obj_Entry for caller
111 stf.spill [r17]=f12,32
112 stf.spill [r18]=f13,32
113 shladd out1=r15,3,out1 // rela offset = 24 * index
116 stf.spill [r17]=f14,32
117 stf.spill [r18]=f15,32
118 br.call.sptk.many rp=_rtld_bind
120 ld8 r14=[r8],8 // target address
125 ld8 r1=[r8] // target gp
126 mov ar.pfs=loc0 // clean up
129 ldf.fill f8=[r17],32 // restore float arguments
131 mov r8=loc2 // restore structure pointer
134 ldf.fill f10=[r17],32
135 ldf.fill f11=[r18],32
139 ldf.fill f12=[r17],32
140 ldf.fill f13=[r18],32
144 ldf.fill f14=[r17],32
145 ldf.fill f15=[r18],32
154 alloc r14=ar.pfs,0,0,8,0 // drop our register frame
156 br.sptk.many b7 // jump to target
158 END(_rtld_bind_start)
160 #define DT_NULL 0 /* Terminating entry. */
161 #define DT_RELA 7 /* Address of ElfNN_Rela relocations. */
162 #define DT_RELASZ 8 /* Total size of ElfNN_Rela relocations. */
163 #define DT_RELAENT 9 /* Size of each ElfNN_Rela relocation entry. */
165 #define R_IA_64_NONE 0 /* None */
166 #define R_IA_64_DIR64LSB 0x27 /* word64 LSB S + A */
167 #define R_IA_64_REL64LSB 0x6f /* word64 LSB BD + A */
170 * _rtld_reloc: relocate the rtld image, apart from @fptrs.
172 * Assumes that rtld was linked at zero and that we only need to
173 * handle REL64LSB and DIR64LSB relocations.
176 * r1 gp value for rtld
177 * in0 rtld base address
179 STATIC_ENTRY(_rtld_reloc, 1)
180 alloc loc0=ar.pfs,1,2,0,0
183 movl r15=@gprel(_DYNAMIC) // find _DYNAMIC etc.
185 add r15=r15,gp // relocate _DYNAMIC etc.
187 1: ld8 r16=[r15],8 // read r15->d_tag
189 ld8 r17=[r15],8 // and r15->d_val
191 cmp.eq p6,p0=DT_NULL,r16 // done?
192 (p6) br.cond.dpnt.few 2f
194 cmp.eq p6,p0=DT_RELA,r16
196 (p6) add r18=r17,in0 // found rela section
198 cmp.eq p6,p0=DT_RELASZ,r16
200 (p6) mov r19=r17 // found rela size
202 cmp.eq p6,p0=DT_RELAENT,r16
204 (p6) mov r22=r17 // found rela entry size
209 ld8 r15=[r18],8 // read r_offset
211 ld8 r16=[r18],8 // read r_info
212 add r15=r15,in0 // relocate r_offset
214 ld8 r17=[r18],8 // read r_addend
215 sub r19=r19,r22 // update relasz
217 extr.u r23=r16,0,32 // ELF64_R_TYPE(r16)
219 cmp.eq p6,p0=R_IA_64_NONE,r23
220 (p6) br.cond.dpnt.few 3f
222 cmp.eq p6,p0=R_IA_64_DIR64LSB,r23
224 (p6) br.cond.dptk.few 4f
226 cmp.eq p6,p0=R_IA_64_REL64LSB,r23
228 (p6) br.cond.dptk.few 4f
231 3: cmp.ltu p6,p0=0,r19 // more?
232 (p6) br.cond.dptk.few 2b // loop
234 mov r8=0 // success return value
236 br.cond.sptk.few 9f // done
239 ld8 r16=[r15] // read value
241 add r16=r16,in0 // relocate it
243 st8 [r15]=r16 // and store it back