etc/services - sync with NetBSD-8
[minix.git] / libexec / ld.elf_so / arch / aarch64 / rtld_start.S
blob622e0d04ee35be80e45cbd2703ded63779201d46
1 /* $NetBSD: rtld_start.S,v 1.1 2014/08/10 05:47:37 matt Exp $ */
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  */
32 #include <machine/asm.h>
34 RCSID("$NetBSD: rtld_start.S,v 1.1 2014/08/10 05:47:37 matt Exp $")
37  * void _rtld_start(void (*cleanup)(void), const Obj_Entry *obj,
38  *    struct ps_strings *ps_strings);
39  *
40  * X0           = NULL
41  * X1           = NULL
42  * X2           = ps_strings
43  * X30 (LR)     = 0
44  * X29 (FP)     = 0
45  */
47 ENTRY_NP(_rtld_start)
48         mov     x24, x2                 /* save ps_strings */
50 #if 1
51         adrp    x1, _PROCEDURE_LINKAGE_TABLE_   /* load _DYNAMIC offset from GOT */
52         ldr     x1, [x1, #:got_lo12:_PROCEDURE_LINKAGE_TABLE_]
53 #else
54         adrp    x1, :got:_DYNAMIC       /* load _DYNAMIC offset from GOT */
55         ldr     x1, [x1, #:got_lo12:_DYNAMIC]
56 #endif
58         adrp    x0, _DYNAMIC            /* get &_DYNAMIC */
59         add     x0, x0, #:lo12:_DYNAMIC
60         sub     x25, x0, x1             /* relocbase = &_DYNAMIC - GOT:_DYNAMIC */
61         mov     x1, x25                 /* pass as 2nd argument */
62         bl      _rtld_relocate_nonplt_self
64         sub     sp, sp, #16             /* reserve space for returns */
65         mov     x0, sp                  /* pointer to reserved space */
66         mov     x1, x25                 /* pass relocbase */
67         bl      _rtld
68         mov     x17, x0                 /* save entry point */
70         ldp     x0, x1, [sp], #16       /* pop cleanup & obj_main */
71         mov     x2, x24                 /* restore ps_strings */
73         br      x17                     /* call saved entry point */
74 END(_rtld_start)
77  * Upon entry from plt0 entry:
78  * X17 = &PLTGOT[n]
79  * X16 = &PLTGOT[2]
80  */
81 ENTRY_NP(_rtld_bind_start)
82         sub     sp, sp, #96             /* reserve stack space */
83         stp     x29, x30, [sp, #80]     /* save FP & LR */
84         add     x29, sp, #80            /* get new FP */
85         str     x24, [sp, #64]          /* save caller-saved register */
86         stp     x6, x7, [sp, #48]       /* save arguments */
87         stp     x4, x5, [sp, #32]       /* save arguments */
88         stp     x2, x3, [sp, #16]       /* save arguments */
89         stp     x0, x1, [sp, #0]        /* save arguments */
91         sub     x16, x16, #16           /* adjust to &PLTGOT[0] */
92         mov     x24, x17                /* preserve across _rtld_bind */
93         sub     x1, x17, x16            /* x1 = &PLTGOT[N] - &PLTGOT[2] */
94         lsr     x1, x1, #3              /* x1 = N - 2 */
95         ldr     x0, [x16, #8]           /* get obj ptr from &PLTGOT[1] */
96         bl      _rtld_bind
97         str     x0, [x24]               /* save address in PLTGOT[N] */
98         mov     x17, x0                 /* save address */
100         ldp     x0, x1, [sp, #0]        /* restore arguments */
101         ldp     x2, x3, [sp, #16]       /* restore arguments */
102         ldp     x4, x5, [sp, #32]       /* restore arguments */
103         ldp     x6, x7, [sp, #48]       /* restore arguments */
104         ldr     x24, [sp, #64]          /* save caller-saved register */
105         ldp     x29, x30, [sp, #80]     /* restore FP & LR */
106         add     sp, sp, #96             /* reclaim stack */
107         br      x17                     /* call bound function */
108 END(_rtld_bind_start)