1/*        $NetBSD: rtld_start.S,v 1.17 2011/09/26 01:52:22 mrg Exp $  */
2
3/*-
4 * Copyright (C) 1998         Tsubai Masanari
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
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31#include <machine/asm.h>
32
33          .globl    _rtld_start
34          .globl    _rtld
35
36          .text
37
38_rtld_start:
39          stwu      %r1,-48(%r1)
40          stw       %r3,12(%r1)                   # argc
41          stw       %r4,16(%r1)                   # argv
42          stw       %r5,20(%r1)                   # envp
43/*        stw       %r6,24(%r1)                   # obj               (always 0) */
44/*        stw       %r7,28(%r1)                   # cleanup (always 0) */
45          stw       %r8,32(%r1)                   # ps_strings
46
47          bcl       20,31,1f
481:        mflr      %r30
49          mr        %r3,%r30            # save for _DYNAMIC
50          addis     %r30,%r30,_GLOBAL_OFFSET_TABLE_-1b@ha
51          addi      %r30,%r30,_GLOBAL_OFFSET_TABLE_-1b@l
52          addis     %r3,%r3,_DYNAMIC-1b@ha        # get _DYNAMIC actual address
53          addi      %r3,%r3,_DYNAMIC-1b@l
54          lwz       %r28,0(%r30)                  # get base-relative &_DYNAMIC
55          sub       %r28,%r3,%r28                 # r28 = relocbase
56          mr        %r4,%r28            # r4 = relocbase
57          bl        _rtld_relocate_nonplt_self
58
59          lwz       %r3,16(%r1)
60          addi      %r3,%r3,-12                   # sp = &argv[-3]    /* XXX */
61          mr        %r4,%r28            # r4 = relocbase
62          bl        _rtld                         # _start = _rtld(sp, relocbase)
63          mtlr      %r3
64
65          lwz       %r3,12(%r1)                   # argc
66          lwz       %r4,16(%r1)                   # argv
67          lwz       %r5,20(%r1)                   # envp
68          lwz       %r6,-8(%r4)                   # obj = sp[1] (== argv[-2])
69          lwz       %r7,-12(%r4)                  # cleanup = sp[0] (== argv[-3])
70          lwz       %r8,32(%r1)                   # ps_strings
71
72          addi      %r1,%r1,48
73          blrl                # _start(argc, argv, envp, obj, cleanup, ps_strings)
74
75          li        %r0,1                         # _exit()
76          sc
77
78END(_rtld_start)
79
80          .globl    _rtld_bind
81
82/*
83 * secure-plt expects %r11 to be the offset to the rela entry.
84 * bss-plt expects %r11 to be index of the rela entry.
85 * So for bss-plt, we multiply the index by 12 to get the offset.
86 */
87ENTRY_NOPROFILE(_rtld_bind_secureplt_start)
88          stwu      %r1,-160(%r1)
89          stw       %r0,20(%r1)
90
91          /*
92           * Instead of division which is costly we will use multiplicative
93           * inverse.  a / n = ((a * inv(n)) >> 32)
94           * where inv(n) = (0x100000000 + n - 1) / n
95           */
96          mr        %r0,%r11
97          lis       %r11,0x15555556@h   # load multiplicative inverse of 12
98          ori       %r11,%r11,0x15555556@l
99          mulhwu    %r11,%r11,%r0                 # get high half of multiplication
100
101          b         1f
102ENTRY_NOPROFILE(_rtld_bind_bssplt_start)
103          stwu      %r1,-160(%r1)
104
105          stw       %r0,20(%r1)
1061:
107          mflr      %r0
108          stw       %r0,16(%r1)                   # save lr
109          mfcr      %r0
110          stw       %r0,12(%r1)                   # save cr
111          stmw      %r3,24(%r1)                   # save r3-r31
112
113          mr        %r3,%r12            # obj
114          mr        %r4,%r11            # reloff
115          bl        _rtld_bind                    # _rtld_bind(obj, reloff)
116          mtctr     %r3
117
118          lmw       %r3,24(%r1)                   # load r3-r31
119          lwz       %r0,12(%r1)                   # restore cr
120          mtcr      %r0
121          lwz       %r0,16(%r1)                   # restore lr
122          mtlr      %r0
123          lwz       %r0,20(%r1)
124
125          addi      %r1,%r1,160
126          bctr
127END(_rtld_bind_secureplt_start)
128
129          .globl    _rtld_powerpc_pltcall
130          .globl    _rtld_powerpc_pltresolve
131
132_rtld_powerpc_pltcall:
133          slwi      %r11,%r11,2
134          addis     %r11,%r11,0                   # addis   11,11,jmptab@ha
135          lwz       %r11,0(%r11)                  # lwz     11,jmptab@l(11)
136          mtctr     %r11
137          bctr
138
139_rtld_powerpc_pltresolve:
140          lis       %r12,0                        # lis     12,_rtld_bind_bssplt_start@ha
141          addi      %r12,%r12,0                   # addi    12,12,_rtld_bind_bssplt_start@l
142          mtctr     %r12
143          lis       %r12,0                        # lis     12,obj@ha
144          addi      %r12,%r12,0                   # addi    12,12,obj@l
145          bctr
146