127bd4146SNathan Whitehorn/* $NetBSD: rtld_start.S,v 1.4 2001/09/26 04:06:43 mycroft Exp $ */ 227bd4146SNathan Whitehorn 327bd4146SNathan Whitehorn/*- 427bd4146SNathan Whitehorn * Copyright (C) 1998 Tsubai Masanari 527bd4146SNathan Whitehorn * All rights reserved. 627bd4146SNathan Whitehorn * 727bd4146SNathan Whitehorn * Redistribution and use in source and binary forms, with or without 827bd4146SNathan Whitehorn * modification, are permitted provided that the following conditions 927bd4146SNathan Whitehorn * are met: 1027bd4146SNathan Whitehorn * 1. Redistributions of source code must retain the above copyright 1127bd4146SNathan Whitehorn * notice, this list of conditions and the following disclaimer. 1227bd4146SNathan Whitehorn * 2. Redistributions in binary form must reproduce the above copyright 1327bd4146SNathan Whitehorn * notice, this list of conditions and the following disclaimer in the 1427bd4146SNathan Whitehorn * documentation and/or other materials provided with the distribution. 1527bd4146SNathan Whitehorn * 3. The name of the author may not be used to endorse or promote products 1627bd4146SNathan Whitehorn * derived from this software without specific prior written permission. 1727bd4146SNathan Whitehorn * 1827bd4146SNathan Whitehorn * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 1927bd4146SNathan Whitehorn * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 2027bd4146SNathan Whitehorn * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 2127bd4146SNathan Whitehorn * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 2227bd4146SNathan Whitehorn * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 2327bd4146SNathan Whitehorn * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2427bd4146SNathan Whitehorn * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2527bd4146SNathan Whitehorn * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2627bd4146SNathan Whitehorn * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2727bd4146SNathan Whitehorn * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2827bd4146SNathan Whitehorn */ 2927bd4146SNathan Whitehorn 3027bd4146SNathan Whitehorn#include <machine/asm.h> 3127bd4146SNathan Whitehorn 3227bd4146SNathan Whitehorn.extern _GLOBAL_OFFSET_TABLE_ 3327bd4146SNathan Whitehorn.extern _DYNAMIC 3427bd4146SNathan Whitehorn 3527bd4146SNathan Whitehorn_ENTRY(_rtld_start) 36071a51cfSNathan Whitehorn stdu %r1,-144(%r1) /* 16-byte aligned stack for reg saves + 3727bd4146SNathan Whitehorn exit_proc & obj _rtld args + 3827bd4146SNathan Whitehorn backchain & lrsave stack frame */ 391180fa86SLeandro Lupori 401180fa86SLeandro Lupori /* Save and restore only initial argv, because _rtld will modify 411180fa86SLeandro Lupori * argv and envp if invoked explicitly, making it necessary to 421180fa86SLeandro Lupori * load the (possibly) adjusted values from the stack. 431180fa86SLeandro Lupori */ 44071a51cfSNathan Whitehorn std %r4,104(%r1) /* argv */ 45071a51cfSNathan Whitehorn/* std %r6,120(%r1) *//* obj (always 0) */ 46071a51cfSNathan Whitehorn/* std %r7,128(%r1) *//* cleanup (always 0) */ 47071a51cfSNathan Whitehorn std %r8,136(%r1) /* ps_strings */ 4827bd4146SNathan Whitehorn 4927bd4146SNathan Whitehorn /* 5027bd4146SNathan Whitehorn * Perform initial relocation of ld-elf.so. Not as easy as it 5127bd4146SNathan Whitehorn * sounds. 5227bd4146SNathan Whitehorn * - perform small forward branch to put PC into link reg 5327bd4146SNathan Whitehorn * - use link-time constants to determine offset to the 5427bd4146SNathan Whitehorn * _DYNAMIC section and the GOT. Add these to the PC to 5527bd4146SNathan Whitehorn * convert to absolute addresses. 5627bd4146SNathan Whitehorn * - call reloc_non_plt_self() to fix up ld-elf.so's relocations 5727bd4146SNathan Whitehorn */ 5827bd4146SNathan Whitehorn 5927bd4146SNathan Whitehorn bl 1f 6027bd4146SNathan Whitehorn .llong _DYNAMIC-. 6127bd4146SNathan Whitehorn1: 6227bd4146SNathan Whitehorn mflr %r3 /* PC value at .llong */ 6327bd4146SNathan Whitehorn ld %r4,0(%r3) /* offset to _DYNAMIC */ 6427bd4146SNathan Whitehorn add %r3,%r4,%r3 /* r3 = &_DYNAMIC, absolute value */ 6527bd4146SNathan Whitehorn 6627bd4146SNathan Whitehorn ld %r4,-0x8000(%r2) /* First TOC entry is TOC base */ 6727bd4146SNathan Whitehorn subf %r4,%r4,%r2 /* Subtract from real TOC base to get base */ 6827bd4146SNathan Whitehorn 6979c77d72SNathan Whitehorn bl reloc_non_plt_self /* reloc_non_plt_self(&_DYNAMIC,base) */ 7027bd4146SNathan Whitehorn nop 7127bd4146SNathan Whitehorn 7227bd4146SNathan Whitehorn /* 7327bd4146SNathan Whitehorn * The _rtld() function likes to see a stack layout containing 7427bd4146SNathan Whitehorn * { argc, argv[0], argv[1] ... argv[N], 0, env[0], ... , env[N] } 7527bd4146SNathan Whitehorn * Since the PowerPC stack was 16-byte aligned at exec time, the 7627bd4146SNathan Whitehorn * original stack layout has to be found by moving back a word 7727bd4146SNathan Whitehorn * from the argv pointer. 7827bd4146SNathan Whitehorn */ 79071a51cfSNathan Whitehorn ld %r4,104(%r1) 8027bd4146SNathan Whitehorn addi %r3,%r4,-8 /* locate argc ptr, &argv[-1] */ 81071a51cfSNathan Whitehorn addi %r4,%r1,128 /* &exit_proc on stack */ 82071a51cfSNathan Whitehorn addi %r5,%r1,120 /* &obj_main on stack */ 8327bd4146SNathan Whitehorn 8479c77d72SNathan Whitehorn bl _rtld /* &_start = _rtld(sp, &exit_proc, &obj_main)*/ 8527bd4146SNathan Whitehorn nop 8629ba9b61SNathan Whitehorn#if !defined(_CALL_ELF) || _CALL_ELF == 1 8727bd4146SNathan Whitehorn ld %r2,8(%r3) 8827bd4146SNathan Whitehorn ld %r11,16(%r3) 8927bd4146SNathan Whitehorn ld %r3,0(%r3) 9029ba9b61SNathan Whitehorn#else 9129ba9b61SNathan Whitehorn mr %r12,%r3 9229ba9b61SNathan Whitehorn#endif 9327bd4146SNathan Whitehorn mtlr %r3 9427bd4146SNathan Whitehorn 9527bd4146SNathan Whitehorn /* 9627bd4146SNathan Whitehorn * Restore args, with new obj/exit proc 9727bd4146SNathan Whitehorn */ 98071a51cfSNathan Whitehorn ld %r4,104(%r1) /* argv */ 991180fa86SLeandro Lupori ld %r3,-8(%r4) /* argc */ 1001180fa86SLeandro Lupori 1011180fa86SLeandro Lupori /* envp = argv + argc + 1 */ 1021180fa86SLeandro Lupori addi %r5,%r3,1 1031180fa86SLeandro Lupori sldi %r5,%r5,3 /* x8 */ 1041180fa86SLeandro Lupori add %r5,%r4,%r5 1051180fa86SLeandro Lupori 106071a51cfSNathan Whitehorn ld %r6,120(%r1) /* obj */ 107071a51cfSNathan Whitehorn ld %r7,128(%r1) /* exit proc */ 108071a51cfSNathan Whitehorn ld %r8,136(%r1) /* ps_strings */ 10927bd4146SNathan Whitehorn 11027bd4146SNathan Whitehorn blrl /* _start(argc, argv, envp, obj, cleanup, ps_strings) */ 11127bd4146SNathan Whitehorn 11227bd4146SNathan Whitehorn li %r0,1 /* _exit() */ 11327bd4146SNathan Whitehorn sc 114*78599c32SConrad Meyer_END(_rtld_start) 11527bd4146SNathan Whitehorn 11627bd4146SNathan Whitehorn/* 11727bd4146SNathan Whitehorn * _rtld_bind_start() 11827bd4146SNathan Whitehorn * 11927bd4146SNathan Whitehorn * Call into the MI binder. This routine is reached via the PLT call cell 12029ba9b61SNathan Whitehorn * 121a4c5dfc0SNathan Whitehorn * On entry, %r11 contains an object pointer and %r0 contains the PLT index. 12227bd4146SNathan Whitehorn * 12327bd4146SNathan Whitehorn * Save all registers, call into the binder to resolve and fixup the external 12427bd4146SNathan Whitehorn * routine, and then transfer to the external routine on return. 12527bd4146SNathan Whitehorn */ 12627bd4146SNathan Whitehorn .globl _rtld_bind 12727bd4146SNathan Whitehorn 12827bd4146SNathan Whitehorn_ENTRY(_rtld_bind_start) 129a4c5dfc0SNathan Whitehorn mr %r12,%r0 # save r0 (index) immediately to r12 13027bd4146SNathan Whitehorn mflr %r0 13127bd4146SNathan Whitehorn std %r0,16(%r1) # save lr 13227bd4146SNathan Whitehorn mfcr %r0 13327bd4146SNathan Whitehorn std %r0,8(%r1) # save cr 13427bd4146SNathan Whitehorn 135071a51cfSNathan Whitehorn stdu %r1,-48-12*8(%r1) # stack space for 8 regs + header 136071a51cfSNathan Whitehorn # + 2 save regs 13729ba9b61SNathan Whitehorn std %r3,64+0*8(%r1) # save r3-r10 (arguments) 138071a51cfSNathan Whitehorn std %r4,64+1*8(%r1) 139071a51cfSNathan Whitehorn std %r5,64+2*8(%r1) 140071a51cfSNathan Whitehorn std %r6,64+3*8(%r1) 141071a51cfSNathan Whitehorn std %r7,64+4*8(%r1) 142071a51cfSNathan Whitehorn std %r8,64+5*8(%r1) 143071a51cfSNathan Whitehorn std %r9,64+6*8(%r1) 144071a51cfSNathan Whitehorn std %r10,64+7*8(%r1) 14527bd4146SNathan Whitehorn 14629ba9b61SNathan Whitehorn mr %r3,%r11 147a4c5dfc0SNathan Whitehorn mulli %r4,%r12,24 # Multiply index by sizeof(Elf_Rela) 148a4c5dfc0SNathan Whitehorn 14979c77d72SNathan Whitehorn bl _rtld_bind # target addr = _rtld_bind(obj, reloff) 15027bd4146SNathan Whitehorn nop 15127bd4146SNathan Whitehorn 15229ba9b61SNathan Whitehorn#if !defined(_CALL_ELF) || _CALL_ELF == 1 15327bd4146SNathan Whitehorn ld %r2,8(%r3) 15427bd4146SNathan Whitehorn ld %r11,16(%r3) 15527bd4146SNathan Whitehorn ld %r3,0(%r3) 15629ba9b61SNathan Whitehorn#else 15729ba9b61SNathan Whitehorn mr %r12,%r3 15829ba9b61SNathan Whitehorn#endif 15927bd4146SNathan Whitehorn mtctr %r3 # move absolute target addr into ctr 16027bd4146SNathan Whitehorn 16129ba9b61SNathan Whitehorn ld %r3,64+0*8(%r1) # restore r3-r10 162071a51cfSNathan Whitehorn ld %r4,64+1*8(%r1) 163071a51cfSNathan Whitehorn ld %r5,64+2*8(%r1) 164071a51cfSNathan Whitehorn ld %r6,64+3*8(%r1) 165071a51cfSNathan Whitehorn ld %r7,64+4*8(%r1) 166071a51cfSNathan Whitehorn ld %r8,64+5*8(%r1) 167071a51cfSNathan Whitehorn ld %r9,64+6*8(%r1) 168071a51cfSNathan Whitehorn ld %r10,64+7*8(%r1) 16927bd4146SNathan Whitehorn 170071a51cfSNathan Whitehorn ld %r1,0(%r1) # restore stack 17127bd4146SNathan Whitehorn ld %r0,8(%r1) # restore cr 17227bd4146SNathan Whitehorn mtcr %r0 17327bd4146SNathan Whitehorn ld %r0,16(%r1) # restore lr 17427bd4146SNathan Whitehorn mtlr %r0 17527bd4146SNathan Whitehorn 17627bd4146SNathan Whitehorn bctr # jump to target 177*78599c32SConrad Meyer_END(_rtld_bind_start) 17827bd4146SNathan Whitehorn 1798ae32158SKonstantin Belousov .section .note.GNU-stack,"",%progbits 180