1/* $OpenBSD: ldasm.S,v 1.9 2012/11/01 10:25:33 kettenis Exp $ */ 2 3/* 4 * Copyright (c) 2006 Dale Rahn 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS 16 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 19 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 * 27 */ 28 29#define DL_DATA_SIZE (16 * 4) /* XXX */ 30#include <machine/asm.h> 31#include <sys/syscall.h> 32#include <SYS.h> 33 34ENTRY(_dl_start) 35 mov r15, r12 // save for later 36 sts pr, r11 37 mov r15, r4 // boot_bind(sp, dl_data) (sp) 38 mov.l .L_datasize, r0 39 sub r0, r15 40 mov r15, r5 41 mov r5, r13 42 // not trusting register to store the data, push it on the stack. 43 // callee/caller save questions 44 45 mov r15, r14 46 47 bsr 1f 48 nop 491: 50.L_offbase: 51 sts pr, r0 52 mov.l .L_dynamic, r6 53 add r0, r6 54 mov r14, r15 55 mov r15, r14 56 mov.l .L_boot_bind, r0 57 bsrf r0 58 nop 59.L_call_boot_bind: 60 mov r12, r4 61 add #4, r4 62 mov.l @r12, r5 //loads argc 63 add #2, r5 64 shll2 r5 65 add r12, r5 // calc argv 66 67 mov r13, r7 68 mov r7, r6 69 mov.l .L_loff, r0 70 add r0, r6 71 mov.l @r6, r6 72 73 mov.l .L_boot, r0 74 bsrf r0 75 nop 76.L_call_boot: 77 78 mov r12, r15 79 lds r11, pr 80 mov.l @r15, r4 81 mov r15, r5 82 add #4, r5 83 84 mov r4, r6 85 add #1, r6 86 shll2 r6 87 add r5, r6 // calc envp 88 jmp @r0 89 mov #0, r7 90 91 .align 2 92.L_boot_bind: 93 .long _dl_boot_bind-.L_call_boot_bind 94.L_boot: 95 .long _dl_boot-.L_call_boot 96.L_datasize: 97 .long 4+4+DL_DATA_SIZE 98.L_dynamic: 99 .long _DYNAMIC-.L_offbase 100.L_loff: 101 .long 7*4 102 .size _dl_start, .-dl_start 103 104 105/* 106 * r0 - obj 107 * r1 - reloff 108 */ 109 110ENTRY(_dl_bind_start) 111 mov.l r2, @-r15 112 mov.l r3, @-r15 113 mov.l r4, @-r15 114 mov.l r5, @-r15 115 mov.l r6, @-r15 116 mov.l r7, @-r15 117 sts.l pr, @-r15 118 sts.l macl, @-r15 119 sts.l mach, @-r15 120 121 mov r0, r4 /* move obj to 'C' arg */ 122 mov.l .L_dl_bind, r0 123 bsrf r0 124 mov r1, r5 /* move reloff to 'C' arg */ 125.L_call_dl_bind: 126 127 lds.l @r15+, mach 128 lds.l @r15+, macl 129 lds.l @r15+, pr 130 mov.l @r15+, r7 131 mov.l @r15+, r6 132 mov.l @r15+, r5 133 mov.l @r15+, r4 134 mov.l @r15+, r3 135 jmp @r0 /* jump to specified address */ 136 mov.l @r15+, r2 137 138 .align 2 139.L_dl_bind: 140 .long _dl_bind-.L_call_dl_bind 141 .size _dl_bind_start, .-dl_bind_start 142 143 144 /* STUB */ 145 146 147/* ld.so SYSCALLS */ 148 149#define DL_SYSCALL(n) DL_SYSCALL2(n,n) 150#define DL_SYSCALL2(n,c) \ 151 .global __CONCAT(_dl_,n) ;\ 152 .type __CONCAT(_dl_,n)%function ;\ 153__CONCAT(_dl_,n): ;\ 154 SYSTRAP(c) ;\ 155 bf .L_cerr ;\ 156 nop ;\ 157 rts ;\ 158 nop 159 160#define DL_SYSCALL2_NOERR(n,c) \ 161 .global __CONCAT(_dl_,n) ;\ 162 .type __CONCAT(_dl_,n)%function ;\ 163__CONCAT(_dl_,n): ;\ 164 SYSTRAP(c) ;\ 165 rts ;\ 166 nop 167 168 169 .section ".text" 170 .align 4 171DL_SYSCALL(close) 172 173 174 .global _dl_exit 175 .type _dl_exit%function 176_dl_exit: 177 SYSTRAP(exit) 1781: 179 bra 1b 180 nop 181 182DL_SYSCALL(issetugid) 183DL_SYSCALL2(_syscall,__syscall) 184DL_SYSCALL(munmap) 185DL_SYSCALL(mprotect) 186DL_SYSCALL(open) 187DL_SYSCALL(read) 188 189.L_cerr: 190 mov #-1, r0 191 rts 192 nop 193 194DL_SYSCALL(write) 195DL_SYSCALL(fstat) 196DL_SYSCALL(fcntl) 197DL_SYSCALL(gettimeofday) 198DL_SYSCALL2(sysctl,__sysctl) 199 200DL_SYSCALL(getdirentries) 201 202 .global _dl_sigprocmask 203 .type _dl_sigprocmask%function 204_dl_sigprocmask: 205 mov r5, r2 /* fetch new sigset pointer */ 206 tst r2, r2 /* check new sigset pointer */ 207 bf 1f /* if not null, indirect */ 208 mov #1, r4 /* SIG_BLOCK */ 209 bra 2f 210 nop 2111: mov.l @r2, r2 /* fetch indirect ... */ 212 mov r2, r5 /* to new mask arg */ 2132: mov.l LSYS_sigprocmask, r0 214 trapa #0x80 215 bf .L_cerr 216 mov r6, r2 /* fetch old mask requested */ 217 tst r2, r2 /* test if old mask requested */ 218 bt out 219 mov.l r0, @r2 /* store old mask */ 220out: 221 xor r0, r0 222 rts 223 nop 224 225 .align 2 226LSYS_sigprocmask: 227 .long SYS_sigprocmask 228 229 230