1/* $NetBSD: rtld_start.S,v 1.17 2011/09/26 01:52:22 mrg Exp $ */ 2 3/*- 4 * Copyright (c) 2014 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Matt Thomas of 3am Software Foundry. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32#include <machine/asm.h> 33 34 .globl _rtld_start 35 .globl _rtld 36 37#define CF_LEN (3*__SIZEOF_POINTER__) 38#define CF_OBJ (2*__SIZEOF_POINTER__) 39#define CF_CLEANUP (1*__SIZEOF_POINTER__) 40 41 /* 42 * void ___start(void (*cleanup)(void), const Obj_Entry *obj, 43 * struct ps_strings *ps_strings); 44 */ 45ENTRY_NP(_rtld_start) 46 l.sw CF_LEN(r1), r1 # reserve some stack space 47#if 0 48 l.ori r26, r3, 0 # obj (should be 0) 49 l.ori r28, r4, 0 # cleanup (should be 0) 50#endif 51 l.ori r30, r5, 0 # ps_strings 52 l.addi r1, r1, -CF_LEN 53 54 PIC_GOTSETUP(r16) 55 56 l.movhi r3, gotoffhi(_DYNAMIC) # get _DYNAMIC gotoff address 57 l.ori r3, r3, gotofflo(_DYNAMIC) 58 59 l.lwz r7, 0(r16) # get base-relative &_DYNAMIC 60 l.add r3, r3, r16 # r3 = _DYNAMIC actual address 61 l.sub r24, r3, r7 # r24 = relocbase 62 l.ori r4, r24, 0 # r4 = relocbase 63 l.jal _C_LABEL(_rtld_relocate_nonplt_self) 64 l.nop 65 66 l.addi r3, r1, CF_CLEANUP 67 l.ori r4, r24, 0 # r4 = relocbase 68 l.jal _C_LABEL(_rtld) # _start = _rtld(sp, relocbase) 69 l.nop 70 71 l.lwz r3, CF_OBJ(r1) # obj 72 l.lwz r4, CF_CLEANUP(r1) # cleanup 73 l.ori r5, r30, 0 # ps_strings 74 75 l.addi r1, r1, CF_LEN # pop stack 76 l.jalr r11 # _start(obj, cleanup, ps_strings) 77 78 l.ori r13, r0, 1 # _exit() 79 l.sys 0 80 81END(_rtld_start) 82 83 .globl _rtld_bind 84 85/* 86 * r11 = rela offset 87 * r12 = GOT[1] (&obj) 88 * r15 = GOT[2] (&_rtld_bind_start) 89 */ 90ENTRY_NP(_rtld_bind_start) 91 92 l.sw -4(r1), r9 # save lr 93 l.sw -8(r1), r8 # save arg5 94 l.sw -12(r1), r7 # save arg4 95 l.sw -16(r1), r6 # save arg3 96 l.sw -20(r1), r5 # save arg2 97 l.sw -24(r1), r4 # save arg1 98 l.sw -28(r1), r3 # save arg0 99 l.sw -32(r1), r1 # establish stack frame 100 l.addi r1, r1, -32 101 102 l.ori r3, r12, 0 # obj 103 l.ori r4, r11, 0 # reloff 104 l.jal _C_LABEL(_rtld_bind) # _rtld_bind(obj, reloff) 105 l.nop 106 107 l.addi r1, r1, 32 # pop stack frame 108 l.lwz r3, -28(r1) # restore arg0 109 l.lwz r4, -24(r1) # restore arg1 110 l.lwz r5, -20(r1) # restore arg2 111 l.lwz r6, -16(r1) # restore arg3 112 l.lwz r7, -12(r1) # restore arg4 113 l.lwz r8, -8(r1) # restore arg5 114 l.lwz r9, -4(r1) # restore lr 115 116 l.jr r11 # jump to routine 117 l.nop 118END(_rtld_bind_start) 119