Home | History | Annotate | Line # | Download | only in hppa
      1  1.14     skrll /*	$NetBSD: rtld_start.S,v 1.14 2022/05/30 17:06:34 skrll Exp $	*/
      2   1.1  fredette 
      3   1.1  fredette /*-
      4   1.1  fredette  * Copyright (c) 2002 The NetBSD Foundation, Inc.
      5   1.1  fredette  * All rights reserved.
      6   1.1  fredette  *
      7   1.1  fredette  * This code is derived from software contributed to The NetBSD Foundation
      8   1.1  fredette  * by Matt Fredette.
      9   1.1  fredette  *
     10   1.1  fredette  * Redistribution and use in source and binary forms, with or without
     11   1.1  fredette  * modification, are permitted provided that the following conditions
     12   1.1  fredette  * are met:
     13   1.1  fredette  * 1. Redistributions of source code must retain the above copyright
     14   1.1  fredette  *    notice, this list of conditions and the following disclaimer.
     15   1.1  fredette  * 2. Redistributions in binary form must reproduce the above copyright
     16   1.1  fredette  *    notice, this list of conditions and the following disclaimer in the
     17   1.1  fredette  *    documentation and/or other materials provided with the distribution.
     18   1.1  fredette  *
     19   1.1  fredette  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     20   1.1  fredette  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     21   1.1  fredette  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     22   1.1  fredette  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     23   1.1  fredette  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     24   1.1  fredette  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     25   1.1  fredette  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     26   1.1  fredette  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     27   1.1  fredette  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     28   1.1  fredette  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     29   1.1  fredette  * POSSIBILITY OF SUCH DAMAGE.
     30   1.1  fredette  */
     31   1.1  fredette 
     32   1.1  fredette #include <machine/asm.h>
     33   1.1  fredette #include <machine/frame.h>
     34   1.1  fredette 
     35   1.1  fredette 	.import _GLOBAL_OFFSET_TABLE_
     36   1.1  fredette 
     37   1.4     skrll ENTRY($rtld_start,HPPA_FRAME_SIZE)
     38   1.1  fredette 
     39   1.1  fredette 	/* Start stack calling convention. */
     40  1.13     skrll 	copy	%r3, %r1
     41   1.1  fredette 	copy	%sp, %r3
     42   1.1  fredette 	stw,ma	%r1, HPPA_FRAME_SIZE(%sp)
     43  1.13     skrll 
     44   1.1  fredette 	/*
     45   1.8     skrll 	 * Save our single argument, the ps_strings pointer. We'll need this
     46   1.8     skrll 	 * twice later: once to call _rtld, and again to transfer to the
     47   1.8     skrll 	 * program's entry point.
     48   1.1  fredette 	 */
     49  1.10     skrll 	stw     %arg0, HPPA_FRAME_ARG(0)(%r3)
     50   1.1  fredette 
     51   1.1  fredette 	/*
     52  1.13     skrll 	 * We can't move to C until we relocate at least the
     53   1.1  fredette 	 * Global Offset Table.  Even finding the GOT is tricky
     54   1.1  fredette 	 * without inadvertently causing the linker to make
     55   1.1  fredette 	 * relocations for this part of the text segment.
     56   1.1  fredette 	 */
     57   1.1  fredette 
     58   1.3     skrll 	bl	L$lpc1, %r19
     59   1.3     skrll 	depi	0, 31, 2, %r19
     60   1.3     skrll L$lpc1:	addil	L'_DYNAMIC - ($PIC_pcrel$0 - 8), %r19
     61   1.3     skrll 	ldo	R'_DYNAMIC - ($PIC_pcrel$0 - 12)(%r1),%arg0
     62   1.1  fredette 
     63   1.1  fredette 	/*
     64   1.8     skrll 	 * Load the absolute address of the beginning of the GOT into %r19, the
     65   1.8     skrll 	 * shared library linkage table register, leaving it ready-to-use by
     66   1.8     skrll 	 * the dynamic linker C code.
     67   1.1  fredette 	 */
     68   1.3     skrll 	addil	L'_GLOBAL_OFFSET_TABLE_ - ($PIC_pcrel$0 - 16), %r19
     69   1.3     skrll 	ldo	R'_GLOBAL_OFFSET_TABLE_ - ($PIC_pcrel$0 - 20)(%r1),%r19
     70   1.1  fredette 
     71   1.1  fredette 	/*
     72   1.8     skrll 	 * The linker sets the first entry in the GOT to the unrelocated
     73   1.8     skrll 	 *  address of _DYNAMIC.  Subtract this from the absolute address of
     74   1.8     skrll 	 * _DYNAMIC to get our relocbase.
     75   1.1  fredette 	 */
     76   1.1  fredette 	ldw	0(%r19), %arg1
     77   1.1  fredette 	sub	%arg0, %arg1, %arg1	; %arg1 = relocbase
     78   1.3     skrll 	bl	_rtld_relocate_nonplt_self, %rp
     79   1.3     skrll 	copy	%arg1, %r4		; save for later
     80   1.1  fredette 
     81   1.1  fredette 	/*
     82   1.1  fredette 	 * Recover the ps_strings pointer, and take out the
     83   1.1  fredette 	 * ps_argvstr member.
     84   1.1  fredette 	 */
     85   1.1  fredette 	ldw	HPPA_FRAME_ARG(0)(%r3), %arg0	; ps_strings
     86   1.1  fredette 	ldw	0(%arg0), %arg0		; ps_argvstr member first in struct
     87   1.1  fredette 
     88   1.8     skrll 	/*
     89   1.8     skrll 	 * ps_argvstr - 4 would get us a pointer to argc, comparable to the
     90   1.8     skrll 	 * initial stack pointer on architectures where the stack grows down.
     91   1.8     skrll 	 * Subtracting an additional eight creates the storage for obj and
     92   1.8     skrll 	 * cleanup that _rtld needs.
     93   1.1  fredette 	 */
     94   1.1  fredette 	ldo	-12(%arg0), %arg0
     95   1.3     skrll 	stw	%arg0, HPPA_FRAME_ARG(1)(%r3)
     96   1.1  fredette 
     97   1.3     skrll 	/* Call _rtld, copying relocbase into arg1. */
     98   1.1  fredette 	bl	_rtld, %rp
     99   1.3     skrll 	copy	%r4, %arg1		; %arg1 = relocbase
    100   1.1  fredette 
    101   1.1  fredette 	/* Prepare the arguments for the entry point. */
    102   1.1  fredette 	ldw	HPPA_FRAME_ARG(1)(%r3), %r1
    103   1.1  fredette 	ldw	HPPA_FRAME_ARG(0)(%r3), %arg0	; ps_strings
    104   1.1  fredette 	ldw	0(%r1), %arg1			; cleanup
    105   1.1  fredette 	ldw	4(%r1), %arg2			; obj
    106   1.1  fredette 
    107   1.1  fredette 	/* End stack calling convention. */
    108   1.1  fredette 	ldo	HPPA_FRAME_SIZE(%r3), %sp
    109   1.1  fredette 	ldw,mb	-HPPA_FRAME_SIZE(%sp), %r3
    110   1.1  fredette 
    111   1.1  fredette 	/* Go for it. */
    112   1.1  fredette 	bv	%r0(%ret0)
    113   1.1  fredette 	copy	%r0, %rp
    114   1.1  fredette EXIT($rtld_start)
    115   1.1  fredette 
    116   1.1  fredette /*
    117   1.8     skrll  * This does our setup for an object's GOT.  %arg0 is the Obj_Entry * for the
    118   1.8     skrll  * object, and %arg1 is its GOT pointer.
    119   1.1  fredette  */
    120   1.1  fredette LEAF_ENTRY(__rtld_setup_hppa_pltgot)
    121   1.1  fredette 
    122   1.1  fredette 	/*
    123   1.8     skrll 	 * The second entry of the GOT is reserved for the dynamic linker.  We
    124   1.8     skrll 	 * put the Obj_Entry * for the object in there.
    125   1.1  fredette 	 */
    126   1.1  fredette 	stw	%arg0, 4(%arg1)
    127   1.1  fredette 
    128   1.1  fredette 	/*
    129   1.8     skrll 	 * Fill the fixup_func and fixup_ltp members of the PLT stub.  This
    130   1.8     skrll 	 * stub is inserted by the linker immediately before the GOT.  We use
    131   1.1  fredette 	 * this stub to enter our binder.
    132   1.1  fredette 	 */
    133   1.3     skrll 
    134   1.3     skrll 	bl	L$lpc2, %arg0
    135   1.3     skrll 	depi	0, 31, 2, %arg0
    136   1.3     skrll L$lpc2:	addil	L'_rtld_bind_start - ($PIC_pcrel$0 - 8), %arg0
    137   1.3     skrll 	ldo	R'_rtld_bind_start - ($PIC_pcrel$0 - 12)(%r1),%arg0
    138   1.3     skrll 
    139   1.1  fredette 	stw	%arg0, -8(%arg1)
    140   1.1  fredette 	bv	%r0(%rp)
    141   1.1  fredette 	stw	%r19, -4(%arg1)
    142  1.11       mrg EXIT(__rtld_setup_hppa_pltgot)
    143   1.1  fredette 
    144   1.1  fredette /*
    145   1.8     skrll  * In order to support lazy binding, this implementation of _rtld_bind_start is
    146   1.8     skrll  * very closely tied to the shared-library call stub and the PLT stub, both
    147   1.8     skrll  * inserted by the linker.
    148   1.1  fredette  */
    149   1.9     skrll 
    150   1.9     skrll /*
    151   1.9     skrll  * This is a magic branch instruction that is used by GCC's
    152   1.9     skrll  * __canonicalize_funcptr_for_compare() function to fixup relocations
    153   1.9     skrll  * in order to do function pointer comparisons.
    154   1.9     skrll  */
    155   1.9     skrll 
    156   1.9     skrll 	bl	_rtld_bind, %rp
    157   1.9     skrll 
    158   1.4     skrll ENTRY(_rtld_bind_start,HPPA_FRAME_SIZE)
    159   1.1  fredette 
    160   1.1  fredette 	/* Start stack calling convention.  */
    161  1.13     skrll 	copy	%r3, %r1
    162   1.1  fredette 	copy	%sp, %r3
    163   1.3     skrll 
    164   1.3     skrll 	stw,ma	%r1, HPPA_FRAME_SIZE(%sp)
    165   1.1  fredette 
    166   1.1  fredette 	/*
    167   1.8     skrll 	 * We have to save all calling convention registers that are set by the
    168   1.8     skrll 	 * caller, because we have to restore them before transferring to the
    169   1.8     skrll 	 * bound function.  Note that this includes %ret0, %ret1, and %t1.
    170   1.8     skrll 	 *
    171   1.8     skrll 	 * %ret0 and %ret1 because they can have meaning on entry to a
    172   1.8     skrll 	 * function.
    173   1.8     skrll 	 *
    174   1.8     skrll 	 * %t1 because it's used by libc to pass on errno values to cerror.
    175   1.1  fredette 	 */
    176   1.1  fredette 	stw	%rp, HPPA_FRAME_CRP(%r3)
    177   1.1  fredette 	stw	%arg0, HPPA_FRAME_ARG(0)(%r3)
    178   1.1  fredette 	stw	%arg1, HPPA_FRAME_ARG(1)(%r3)
    179   1.1  fredette 	stw	%arg2, HPPA_FRAME_ARG(2)(%r3)
    180   1.1  fredette 	stw	%arg3, HPPA_FRAME_ARG(3)(%r3)
    181   1.1  fredette 	/* 0(%r3) is filled with the saved %r3 above */
    182   1.1  fredette 	stw	%ret0, 4(%r3)
    183   1.1  fredette 	stw	%ret1, 8(%r3)
    184  1.12     skrll 	stw	%t1, 12(%r3)		/* %r22 */
    185   1.1  fredette 
    186   1.1  fredette 	/*
    187   1.8     skrll 	 * The linker PLT stub loads %r20 with (GOT - 8) for the object that
    188   1.8     skrll 	 * needs binding done.  The second entry of the GOT is reserved for the
    189   1.8     skrll 	 * dynamic linker's use, and we previously stashed the object's
    190   1.8     skrll 	 * Obj_Entry * there.
    191   1.1  fredette 	 */
    192   1.1  fredette 	ldw	12(%r20), %arg0
    193   1.1  fredette 
    194   1.1  fredette 	/*
    195   1.8     skrll 	 * The linker shared-library call stub loads %r19 from the shared
    196   1.8     skrll 	 * linkage member of the PLT entry.  We previously stashed the reloff
    197   1.8     skrll 	 * of the relocation there.
    198   1.1  fredette 	 */
    199   1.1  fredette 	copy	%r19, %arg1
    200   1.1  fredette 
    201   1.1  fredette 	/*
    202   1.8     skrll 	 * The linker PLT stub loads %r21 with the fixup_ltp word in itself.
    203   1.8     skrll 	 * We previously stashed our %r19 value there.
    204   1.1  fredette 	 */
    205   1.1  fredette 	bl	_rtld_bind, %rp
    206   1.1  fredette 	copy	%r21, %r19
    207   1.1  fredette 
    208   1.1  fredette 	/*
    209   1.8     skrll 	 * Our hppa version of _rtld_bind returns to us the address of the PLT
    210   1.8     skrll 	 * entry that it fixed up.  Load the function address and shared
    211   1.8     skrll 	 * linkage for the newly bound function.
    212   1.1  fredette 	 */
    213   1.1  fredette 	ldw	0(%ret0), %r21
    214   1.1  fredette 	ldw	4(%ret0), %r19
    215   1.1  fredette 
    216   1.1  fredette 	/* Restore registers saved above. */
    217   1.1  fredette 	ldw	HPPA_FRAME_CRP(%r3), %rp
    218   1.1  fredette 	ldw	HPPA_FRAME_ARG(0)(%r3), %arg0
    219   1.1  fredette 	ldw	HPPA_FRAME_ARG(1)(%r3), %arg1
    220   1.1  fredette 	ldw	HPPA_FRAME_ARG(2)(%r3), %arg2
    221   1.1  fredette 	ldw	HPPA_FRAME_ARG(3)(%r3), %arg3
    222   1.1  fredette 	ldw	4(%r3), %ret0
    223   1.1  fredette 	ldw	8(%r3), %ret1
    224  1.12     skrll 	ldw	12(%r3), %t1		/* %r22 */
    225   1.1  fredette 
    226   1.1  fredette 	/* End stack calling convention. */
    227   1.1  fredette 	ldo	HPPA_FRAME_SIZE(%r3), %sp
    228   1.1  fredette 	ldw,mb	-HPPA_FRAME_SIZE(%sp), %r3
    229   1.1  fredette 
    230   1.1  fredette 	/* Transfer to the function. */
    231   1.1  fredette 	bv	%r0(%r21)
    232   1.1  fredette 	nop
    233   1.1  fredette EXIT(_rtld_bind_start)
    234  1.14     skrll 
    235  1.14     skrll 
    236  1.14     skrll LEAF_ENTRY_NOPROFILE(_rtld_set_dp)
    237  1.14     skrll 	bv	%r0(%rp)
    238  1.14     skrll 	 copy	%arg0, %dp
    239  1.14     skrll EXIT(_rtld_set_dp)
    240