1/* $OpenBSD: ldasm.S,v 1.30 2016/08/28 06:15:32 guenther Exp $ */ 2 3/* 4 * Copyright (c) 1999 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 AUX_entry 9 30 31#include <machine/asm.h> 32#include <sys/syscall.h> 33 34ENTRY(_dl_start) 35 mr 19, 1 36 stwu 1, (-16 -((AUX_entry+3)*4))(1) # Some space. 37 38 mflr 27 /* save off old link register */ 39 stw 27, 4(19) /* save in normal location */ 40 41 # squirrel away the arguments for main 42 mr 20, 3 #argc 43 mr 21, 4 #argv 44 mr 22, 5 #envp 45 mr 23, 6 # ??? 46 47 bcl 20, 31, 1f 481: mflr 30 49 addis 30, 30, _GLOBAL_OFFSET_TABLE_-1b@ha 50 addi 30, 30, _GLOBAL_OFFSET_TABLE_-1b@l 51 52 bcl 20, 31, 1f 531: mflr 18, 54 addis 18, 18, _DYNAMIC-1b@ha 55 addi 18, 18, _DYNAMIC-1b@l 56 lwz 4, 0(30) # load address of _DYNAMIC according to got. 57 sub 4, 18, 4 # determine load offset 58 59 mr 17, 4 # save for _dl_boot 60 61 subi 3, 21, 4 # Get stack pointer (arg0 for _dl_boot). 62 addi 4, 1, 8 # dl_data 63 mr 5, 18 # dynamicp 64 65 bl _dl_boot_bind@local 66 67 mr 3, 21 # argv 68 mr 4, 22 # envp 69 mr 5, 17 # loff 70 addi 6, 1, 8 # dl_data 71 72 bl _dl_boot@local 73 74 mtctr 3 # put return value into ctr to execute 75 76 # get back the squirreled away the arguments for main 77 mr 3, 20 78 mr 4, 21 79 mr 5, 22 80 mr 6, 23 81 82 lwz 7, _dl_dtors@got(30) 83 84 mtlr 27 85 lwz 1, 0(1) # Restore stack pointer. 86 bctr # Go execute the 'real' program. 87 88ENTRY(_dl_bind_start) 89 stwu 1,-72(1) 90 91 stw 0,8(1) # save r0 - cerror ;-) 92 mflr 0 93 stw 0,68(1) # save lr 94 95 stw 3,12(1) # save r3-r10, C calling convention 96 stw 4,20(1) # r13 - r31 are preserved by called code 97 stw 5,24(1) 98 stw 6,28(1) 99 stw 7,32(1) 100 stw 8,36(1) 101 stw 9,40(1) 102 stw 10,44(1) 103 104 mr 3,12 # obj 105 mr 4,11 # reloff 106 bl _dl_bind@plt # _rtld_bind(obj, reloff) 107 mtctr 3 108 109 lwz 3,12(1) 110 lwz 4,20(1) 111 lwz 5,24(1) 112 lwz 6,28(1) 113 lwz 7,32(1) 114 lwz 8,36(1) 115 lwz 9,40(1) 116 lwz 10,44(1) 117 118 lwz 0,68(1) # restore lr 119 mtlr 0 120 lwz 0,8(1) 121 122 addi 1,1,72 123 bctr 124 125#define DL_SYSCALL(n) DL_SYSCALL2(n,n) 126#define DL_SYSCALL_NOERR(n) DL_SYSCALL2_NOERR(n,n) 127#define DL_SYSCALL2(n,c) \ 128ENTRY(_dl_##n) \ 129 li 0, SYS_##c; \ 130 sc; \ 131 cmpwi 0, 0; \ 132 beqlr+; \ 133 b _dl_cerror 134#define DL_SYSCALL2_NOERR(n,c) \ 135ENTRY(_dl_##n) \ 136 li 0, SYS_##c; \ 137 sc; \ 138 blr 139 140_dl_cerror: 141 neg 3, 3 142 blr 143 144DL_SYSCALL(close) 145DL_SYSCALL_NOERR(exit) 146DL_SYSCALL(fstat) 147DL_SYSCALL2(getcwd,__getcwd) 148DL_SYSCALL(getdents) 149DL_SYSCALL(getentropy) 150DL_SYSCALL(sendsyslog) 151DL_SYSCALL(pledge) 152DL_SYSCALL_NOERR(issetugid) 153DL_SYSCALL_NOERR(getthrid) 154DL_SYSCALL(mmap) 155DL_SYSCALL(mprotect) 156DL_SYSCALL(munmap) 157DL_SYSCALL(open) 158DL_SYSCALL(read) 159DL_SYSCALL(readlink) 160DL_SYSCALL2(_syscall,__syscall) 161DL_SYSCALL(sysctl) 162DL_SYSCALL(utrace) 163DL_SYSCALL(write) 164