ldasm.S revision 1.15
1/* $OpenBSD: ldasm.S,v 1.15 2002/11/23 06:19:26 drahn Exp $ */ 2/* $NetBSD: rtld_start.S,v 1.5 2001/08/14 22:17:48 eeh Exp $ */ 3 4/* 5 * Copyright (c) 2001 Jason L. Wright (jason@thought.net) 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. All advertising materials mentioning features or use of this software 17 * must display the following acknowledgement: 18 * This product includes software developed by Jason L. Wright 19 * 4. The name of the author may not be used to endorse or promote products 20 * derived from this software without specific prior written permission. 21 * 22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 24 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 25 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, 26 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 27 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 28 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 30 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 31 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 32 * POSSIBILITY OF SUCH DAMAGE. 33 */ 34 35/*- 36 * Copyright (c) 2000 Eduardo Horvath. 37 * Copyright (c) 1999 The NetBSD Foundation, Inc. 38 * All rights reserved. 39 * 40 * This code is derived from software contributed to The NetBSD Foundation 41 * by Christos Zoulas and Paul Kranenburg. 42 * 43 * Redistribution and use in source and binary forms, with or without 44 * modification, are permitted provided that the following conditions 45 * are met: 46 * 1. Redistributions of source code must retain the above copyright 47 * notice, this list of conditions and the following disclaimer. 48 * 2. Redistributions in binary form must reproduce the above copyright 49 * notice, this list of conditions and the following disclaimer in the 50 * documentation and/or other materials provided with the distribution. 51 * 3. All advertising materials mentioning features or use of this software 52 * must display the following acknowledgement: 53 * This product includes software developed by the NetBSD 54 * Foundation, Inc. and its contributors. 55 * 4. Neither the name of The NetBSD Foundation nor the names of its 56 * contributors may be used to endorse or promote products derived 57 * from this software without specific prior written permission. 58 * 59 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 60 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 61 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 62 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 63 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 64 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 65 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 66 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 67 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 68 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 69 * POSSIBILITY OF SUCH DAMAGE. 70 */ 71 72#include <sys/syscall.h> 73#include <machine/trap.h> 74#include <machine/asm.h> 75#define _LOCORE 76#include <machine/frame.h> 77 78/* 79 * ELF: 80 * On startup the stack should contain 16 extended word register save area, 81 * followed by the arg count, etc. 82 * 83 * _rtld() expects the stack pointer to point to two longwords for argument 84 * return followed by argc, etc. We need to create a pointer to 85 * &argc + 16 and pass that in. The return args will be in those locations. 86 * 87 * NB: We are violating the ELF spec by passing a pointer to the ps strings in 88 * %g1 instead of a termination routine. 89 */ 90 91/* Offset of ARGC from bottom of stack */ 92#define ARGC (16*8) 93/* XXX - DL_DATA_SIZE should be (9*8), but I can't think right now. */ 94#define DL_DATA_SIZE (16*8) 95 96 .section ".text" 97 .align 16 98 .global _dl_start 99 .type _dl_start,@function 100_dl_start: 101 sub %g0, %g0, %fp ! clear frame 102 mov %g1, %l1 ! save ps_strings 103 sub %sp, DL_DATA_SIZE, %sp ! make room for dl_data 104 add %sp, BIAS + ARGC, %l3 105 106 add %l3, DL_DATA_SIZE, %o0 107 mov %o0, %l0 108 call _dl_boot_bind ! _dl_boot_bind(sp,dl_data) 109 mov %l3, %o1 110 111 mov %l3, %o3 112 ldx [%l0], %l3 ! argc = *sp 113 sllx %l3, 3, %l3 ! argc *= sizeof(long) 114 addx %l0, 8, %o0 ! argv = [sp + argc] 115 addx %l0, 16, %o1 ! envp = sp + 16 + 116 addx %o1, %l3, %o1 ! + argc 117 118 addx %o3, (7*8), %l2 119 ldx [%l2], %o2 ! loff = dl_data[AUX_base]; 120 121 call _dl_boot ! _dl_boot(argv,envp,loff,dynp,dl_data) 122 nop 123 124 add %sp, DL_DATA_SIZE, %sp ! restore stack 125 mov %l1, %g1 ! restore ps_strings 126 127 jmp %o0 128 nop 129 130 /* 131 * We have two separate entry points to the runtime linker. 132 * I'm implementing this following the SPARC v9 ABI spec. 133 * 134 * _dl_bind_start_0(x, y) is called from .PLT0, and is used for 135 * PLT entries above 32768. 136 * 137 * _dl_bind_start_1(x, y) is called from .PLT1, and is used for 138 * PLT entries below 32768. 139 * 140 * The first two entries of PLT2 contain the xword object pointer. 141 * 142 * These routines are called with two longword arguments, 143 * x and y. To calculate the address of the entry, 144 * _dl_bind_start_1(x, y) does: 145 * 146 * n = x >> 15; 147 * 148 * and _dl_bind_start_0(x, y) does: 149 * 150 * i = x - y + 1048596; 151 * n = 32768 + (i/5120)*160 + (i%5120)/24; 152 * 153 * Neither routine needs to issue a save since it's already been 154 * done in the PLT entry. 155 */ 156 157 /* NOTE: _dl_bind_start_0 is untested. Hence the debug stuff */ 158 159 .section ".text" 160 .align 4 161 .global _dl_bind_start_0 162 .type _dl_bind_start_0,@function 163_dl_bind_start_0: # (x, y) 164#if 0 165 call _dl_bind_start_0_stub 166 ldx [%o1 + (10*4)], %l7 167 mov %o0, %o1 168 169 call _dl_bind 170 mov %l7, %o0 171#else 172 sethi %hi(1048596), %l1 173 sub %o0, %o1, %l0 /* x - y */ 174 or %l1, %lo(1048596), %l1 175 add %l0, %l1, %l0 /* x - y + 1048596 */ 176 177 sdivx %l0, 5120, %l1 /* Calculate i/5120 */ 178 ldx [%o1 + (10*4)], %o0 /* Load object pointer from PLT2 */ 179 sub %l0, %l1, %l2 /* And i%5120 */ 180 181 /* Let the division churn for a bit. */ 182 sdivx %l2, 14, %l4 /* (i%5120)/24 */ 183 184 /* 160 is (32 * 5) or (32 * (4 + 1)) */ 185 sllx %l1, 2, %l3 /* 4 * (i/5120) */ 186 add %l1, %l3, %l3 /* 5 * (i/5120) */ 187 sllx %l3, 5, %l3 /* 32 * 5 * (i/5120) */ 188 189 sethi %hi(32768), %l6 190 add %l3, %l4, %l5 /* %l5 = (i/5120)*160 + (i%5120)/24; */ 191 add %l5, %l6, %l5 192 193 call _dl_bind /* Call _dl_bind(obj, offset) */ 194 mov %l5, %o1 195 196 jmp %o0 /* return value == function address */ 197 restore /* Dump our stack frame */ 198#endif 199 200 .section ".text" 201 .align 4 202 .global _dl_bind_start_1 203 .type _dl_bind_start_1,@function 204_dl_bind_start_1: # (x, y) 205 srax %o0, 15, %o2 /* %o0 is the index to our PLT slot */ 206 207 ldx [%o1 + 8], %o0 /* The object pointer is at [%o1 + 8] */ 208 209 call _dl_bind /* Call _dl_bind(obj, offset) */ 210 mov %o2, %o1 211 212 jmp %o0 /* return value == function address */ 213 restore /* Dump our stack frame */ 214 215 .section ".text" 216 .align 4 217 .global _dl_close 218 .type _dl_close,@function 219_dl_close: 220 mov SYS_close | SYSCALL_G2RFLAG, %g1 ! call sys_close 221 add %o7, 8, %g2 ! just return on success 222 t ST_SYSCALL ! off to wonderland 223 retl 224 sub %g0, %o0, %o0 ! error: result = -errno 225 226 227 .section ".text" 228 .align 4 229 .global _dl_exit 230 .type _dl_exit,@function 231_dl_exit: 232 mov SYS_exit | SYSCALL_G2RFLAG, %g1 ! call sys_exit 233 add %o7, 8, %g2 ! just return on success 234 t ST_SYSCALL ! off to wonderland 235 retl 236 sub %g0, %o0, %o0 ! error: result = -errno 237 238 239 .section ".text" 240 .align 4 241 .global _dl_issetugid 242 .type _dl_issetugid,@function 243_dl_issetugid: 244 mov SYS_issetugid | SYSCALL_G2RFLAG, %g1 ! call sys_issetugid 245 add %o7, 8, %g2 ! just return on success 246 t ST_SYSCALL ! off to wonderland 247 retl 248 sub %g0, %o0, %o0 ! error: result = -errno 249 250 251 .section ".text" 252 .align 4 253 .global _dl__syscall 254 .type _dl__syscall,@function 255_dl__syscall: 256 mov SYS___syscall | SYSCALL_G2RFLAG, %g1 ! call sys___syscall 257 add %o7, 8, %g2 ! just return on success 258 t ST_SYSCALL ! off to wonderland 259 retl 260 sub %g0, %o0, %o0 ! error: result = -errno 261 262 263 .section ".text" 264 .align 4 265 .global _dl_munmap 266 .type _dl_munmap,@function 267_dl_munmap: 268 mov SYS_munmap | SYSCALL_G2RFLAG, %g1 ! calling sys_munmap 269 add %o7, 8, %g2 ! just return on success 270 t ST_SYSCALL ! off to wonderland 271 retl 272 sub %g0, %o0, %o0 ! error: result = -errno 273 274 275 .section ".text" 276 .align 4 277 .global _dl_mprotect 278 .type _dl_mprotect,@function 279_dl_mprotect: 280 mov SYS_mprotect | SYSCALL_G2RFLAG, %g1 ! calling sys_mprotect 281 add %o7, 8, %g2 ! just return on success 282 t ST_SYSCALL ! off to wonderland 283 retl 284 sub %g0, %o0, %o0 ! error: result = -errno 285 286 287 .section ".text" 288 .align 4 289 .global _dl_open 290 .type _dl_open,@function 291_dl_open: 292 mov SYS_open | SYSCALL_G2RFLAG, %g1 ! calling sys_open 293 add %o7, 8, %g2 ! just return on success 294 t ST_SYSCALL ! off to wonderland 295 retl 296 sub %g0, %o0, %o0 ! error: result = -errno 297 298 299 .section ".text" 300 .align 4 301 .global _dl_read 302 .type _dl_read,@function 303_dl_read: 304 mov SYS_read | SYSCALL_G2RFLAG, %g1 ! calling sys_read 305 add %o7, 8, %g2 ! just return on success 306 t ST_SYSCALL ! off to wonderland 307 retl 308 sub %g0, %o0, %o0 ! error: result = -errno 309 310 311 .section ".text" 312 .align 4 313 .global _dl_write 314 .type _dl_write,@function 315_dl_write: 316 mov SYS_write | SYSCALL_G2RFLAG, %g1 ! calling sys_write 317 add %o7, 8, %g2 ! just return on success 318 t ST_SYSCALL ! off to wonderland 319 retl 320 sub %g0, %o0, %o0 ! error: result = -errno 321 322 323 .section ".text" 324 .align 4 325 .global _dl_stat 326 .type _dl_stat,@function 327_dl_stat: 328 mov SYS_stat | SYSCALL_G2RFLAG, %g1 ! call sys_stat 329 add %o7, 8, %g2 ! just return on success 330 t ST_SYSCALL ! off to wonderland 331 retl 332 sub %g0, %o0, %o0 ! error: result = -errno 333 334 335 .section ".text" 336 .align 4 337 .globl _dl_fstat 338 .type _dl_fstat,@function 339_dl_fstat: 340 mov SYS_fstat | SYSCALL_G2RFLAG, %g1 ! call sys_fstat 341 add %o7, 8, %g2 ! just return on success 342 t ST_SYSCALL ! off to wonderland 343 retl 344 sub %g0, %o0, %o0 ! error: result = -errno 345 346 347 .section ".text" 348 .align 4 349 .globl _dl_fcntl 350 .type _dl_fcntl,@function 351_dl_fcntl: 352 mov SYS_fcntl | SYSCALL_G2RFLAG, %g1 ! call sys_fcntl 353 add %o7, 8, %g2 ! just return on success 354 t ST_SYSCALL ! off to wonderland 355 retl 356 sub %g0, %o0, %o0 ! error: result = -errno 357 358 359 .section ".text" 360 .align 4 361 .globl _dl_getdirentries 362 .type _dl_getdirentries,@function 363_dl_getdirentries: 364 mov SYS_getdirentries | SYSCALL_G2RFLAG, %g1 ! call sys_getdirentries 365 add %o7, 8, %g2 ! just return on success 366 t ST_SYSCALL ! off to wonderland 367 retl 368 sub %g0, %o0, %o0 ! error: result = -errno 369