1/* $OpenBSD: ldasm.S,v 1.13 2003/07/09 21:01:10 drahn 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 bl 1f 48 # this instruction never gets executed but can be used 49 # to find the virtual address where the page is loaded. 50 bl _GLOBAL_OFFSET_TABLE_@local-4 51 bl _DYNAMIC@local 521: 53 mflr 5 # this stores where we are (+4) 54 lwz 18, 0(5) # load the instruction at offset_sym 55 # it contains an offset to the location 56 # of the GOT. 57 58 rlwinm 18,18,0,8,30 # mask off the offset portion of the instr. 59 60 /* 61 * these adds effectively calculate the value the 62 * bl _GLOBAL_OFFSET_TABLE_@local-4 63 * operation that would be below would calulate. 64 */ 65 add 28, 18, 5 66 mr 6, 5 # save offset for later use 67 68 /* mprotect GOT-4 for correct execution of blrl instruction */ 69 li 0, SYS_mprotect 70 mr 3, 28 71 li 4, 4 72 li 5, 7 /* (PROT_READ|PROT_WRITE|PROT_EXEC) */ 73 sc 74 75 mr 5, 6 76 77 li 0, 0 78 dcbf 5, 18 79 sync 80 isync 81 icbi 5, 18 # make certain that the got table addr is 82 # not in the icache 83 sync 84 isync 85 86 /* This calculates the address of _DYNAMIC the same way 87 * that the GLOBAL_OFFSET_TABLE was calculated. 88 */ 89 lwz 18, 4(5) 90 rlwinm 18,18,0,8,30 # mask off the offset portion of the instr. 91 add 8, 18, 5 # address of _DYNAMIC (arg6 for _dl_boot) 92 addi 18, 8, 4 # correction. 93 lwz 4, 4(28) # load address of _DYNAMIC according to got. 94 sub 4, 18, 4 # determine load offset 95 96 mr 17, 4 # save for _dl_boot 97 98 99 subi 3, 21, 4 # Get stack pointer (arg0 for _dl_boot). 100 addi 4, 1, 8 # dl_data 101 mr 5, 18 # dynamicp 102 103 bl _dl_boot_bind@local 104 105 mr 3, 21 # argv 106 mr 4, 22 # envp 107 mr 5, 17 # loff 108 addi 6, 1, 8 # dl_data 109 110 bl _dl_boot@local 111 112 mtctr 3 # put return value into ctr to execute 113 114 # get back the squirreled away the arguments for main 115 mr 3, 20 116 mr 4, 21 117 mr 5, 22 118 mr 6, 23 119 li 7, 0 120 121 122 mtlr 27 123 lwz 1, 0(1) # Restore stack pointer. 124 bctr # Go execute the 'real' program. 125 126ENTRY(_dl_bind_start) 127 stwu 1,-64(1) 128 129 stw 0,8(1) # save r0 - cerror ;-) 130 mflr 0 131 stw 0,68(1) # save lr 132 133 stw 3,12(1) # save r3-r10, C calling convention 134 stw 4,20(1) # r13 - r31 are preserved by called code 135 stw 5,24(1) 136 stw 6,28(1) 137 stw 7,32(1) 138 stw 8,36(1) 139 stw 9,40(1) 140 stw 10,44(1) 141 142 mr 3,12 # obj 143 mr 4,11 # reloff 144 bl _dl_bind@plt # _rtld_bind(obj, reloff) 145 mtctr 3 146 147 lwz 3,12(1) 148 lwz 4,20(1) 149 lwz 5,24(1) 150 lwz 6,28(1) 151 lwz 7,32(1) 152 lwz 8,36(1) 153 lwz 9,40(1) 154 lwz 10,44(1) 155 156 lwz 0,68(1) # restore lr 157 mtlr 0 158 lwz 0,8(1) 159 160 addi 1,1,64 161 bctr 162