rtld_start.S revision 210629
1/* $NetBSD: rtld_start.S,v 1.10 2009/12/14 00:41:19 matt Exp $ */ 2 3/* 4 * Copyright 1997 Michael L. Hitch <mhitch@montana.edu> 5 * Portions copyright 2002 Charles M. Hannum <root@ihack.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. The name of the author may not be used to endorse or promote products 17 * derived from this software without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 21 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 24 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 * 30 * $FreeBSD: head/libexec/rtld-elf/mips/rtld_start.S 210629 2010-07-29 20:18:52Z jchandra $ 31 */ 32 33#include <machine/asm.h> 34 35.globl _C_LABEL(_rtld_relocate_nonplt_self) 36.globl _C_LABEL(_rtld) 37 38#define PTR_SIZE (1<<PTR_SCALESHIFT) 39 40/* 41 * a0 stack pointer 42 * a1 rtld cleanup (filled in by dynamic loader) 43 * a2 rtld object (filled in by dynamic loader) 44 * a3 ps_strings 45 */ 46LEAF(rtld_start) 47 .frame sp, 4*PTR_SIZE, ra 48 .mask 0x10090000,-PTR_SIZE 49 .set noreorder 50 SETUP_GP 51 PTR_SUBU sp, 4*PTR_SIZE /* adjust stack pointer */ 52 SETUP_GP64(s4, rtld_start) 53 SAVE_GP(0) 54 /* -> 1*PTR_SIZE(sp) for atexit */ 55 /* -> 2*PTR_SIZE(sp) for obj_main */ 56 move s0, a0 /* save stack pointer from a0 */ 57 move s3, a3 /* save ps_strings pointer */ 58 59 PTR_LA a1, 1f 60 bal 1f 61 PTR_LA t0, _C_LABEL(_rtld_relocate_nonplt_self) 621: PTR_SUBU a1, ra, a1 /* relocbase */ 63 PTR_LA a0, _DYNAMIC 64 PTR_ADDU t9, a1, t0 65 jalr t9 /* _rtld_relocate_nonplt_self(dynp, relocabase) */ 66 PTR_ADDU a0, a1, a0 /* &_DYNAMIC */ 67 68 move a0, s0 /* sp */ 69 PTR_ADDU a1, sp, 2*PTR_SIZE /* &our atexit function */ 70 PTR_ADDU a2, sp, 3*PTR_SIZE /* obj_main entry */ 71 PTR_LA t9, _C_LABEL(_rtld) 72 jalr t9 /* v0 = _rtld(sp, cleanup, objp) */ 73 nop 74 75 PTR_L a1, 2*PTR_SIZE(sp) /* our atexit function */ 76 PTR_L a2, 3*PTR_SIZE(sp) /* obj_main entry */ 77 PTR_ADDU sp, 4*PTR_SIZE /* readjust stack */ 78 move a0, s0 /* stack pointer */ 79 move t9, v0 80 jr t9 /* _start(sp, cleanup, obj); */ 81 move a3, s3 /* restore ps_strings */ 82 83END(rtld_start) 84 85#define XCALLFRAME_SIZ (12*SZREG) 86#define XCALLFRAME_RA (10*SZREG) 87#define XCALLFRAME_GP (9*SZREG) 88#define XCALLFRAME_S0 (8*SZREG) 89#define XCALLFRAME_A3 (7*SZREG) 90#define XCALLFRAME_A2 (6*SZREG) 91#define XCALLFRAME_A1 (5*SZREG) 92#define XCALLFRAME_A0 (4*SZREG) 93#if defined(__mips_n32) || defined(__mips_n64) 94#define XCALLFRAME_A7 (3*SZREG) 95#define XCALLFRAME_A6 (2*SZREG) 96#define XCALLFRAME_A5 (1*SZREG) 97#define XCALLFRAME_A4 (0*SZREG) 98#endif 99 100 .globl _rtld_bind_start 101 .ent _rtld_bind_start 102_rtld_bind_start: 103 .frame sp, XCALLFRAME_SIZ, $15 104 move v1, gp /* save old GP */ 105#if defined(__mips_o32) || defined(__mips_o64) 106 PTR_ADDU t9, 8 /* modify T9 to point at .cpload */ 107#endif 108 SETUP_GP 109 PTR_SUBU sp, XCALLFRAME_SIZ /* save arguments and sp value in stack */ 110 SETUP_GP64(XCALLFRAME_GP, _rtld_bind_start) 111 SAVE_GP(XCALLFRAME_GP) 112#if defined(__mips_n32) || defined(__mips_n64) 113 REG_S a4, XCALLFRAME_A4(sp) 114 REG_S a5, XCALLFRAME_A5(sp) 115 REG_S a6, XCALLFRAME_A6(sp) 116 REG_S a7, XCALLFRAME_A7(sp) 117#endif 118 REG_S a0, XCALLFRAME_A0(sp) 119 REG_S a1, XCALLFRAME_A1(sp) 120 REG_S a2, XCALLFRAME_A2(sp) 121 REG_S a3, XCALLFRAME_A3(sp) 122 REG_S $15, XCALLFRAME_RA(sp) /* ra is in t7/t3 */ 123 REG_S s0, XCALLFRAME_S0(sp) 124 move s0, sp 125 126 move a0, v1 /* old GP */ 127 PTR_SUBU a0, a0, 0x7ff0 /* The offset of $gp from the */ 128 /* beginning of the .got section: */ 129 /* $gp = .got + 0x7ff0, so */ 130 /* .got = $gp - 0x7ff0 */ 131 /* Simple math as you can see. */ 132#if defined(__mips_n64) 133 ld a0, 8(a0) /* object = pltgot[1] */ 134 and a0, a0, 0x7fffffffffffffff 135#else 136 lw a0, 4(a0) /* object = pltgot[1] & 0x7fffffff */ 137 and a0, a0, 0x7fffffff 138#endif 139 move a1, t8 /* symbol index */ 140 141 PTR_LA t9, _C_LABEL(_mips_rtld_bind) 142 jalr t9 143 nop 144 145 move sp, s0 146 REG_L ra, XCALLFRAME_RA(sp) 147 REG_L s0, XCALLFRAME_S0(sp) 148 REG_L a0, XCALLFRAME_A0(sp) 149 REG_L a1, XCALLFRAME_A1(sp) 150 REG_L a2, XCALLFRAME_A2(sp) 151 REG_L a3, XCALLFRAME_A3(sp) 152#if defined(__mips_n32) || defined(__mips_n64) 153 REG_L a4, XCALLFRAME_A4(sp) 154 REG_L a5, XCALLFRAME_A5(sp) 155 REG_L a6, XCALLFRAME_A6(sp) 156 REG_L a7, XCALLFRAME_A7(sp) 157#endif 158 RESTORE_GP64 159 PTR_ADDU sp, XCALLFRAME_SIZ 160 move t9, v0 161 jr t9 162 nop 163END(_rtld_bind_start) 164