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