execsp.S revision 1.1 1 /* $NetBSD: execsp.S,v 1.1 2025/04/20 22:32:49 riastradh Exp $ */
2
3 /*-
4 * Copyright (c) 2025 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
17 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
18 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE.
27 */
28
29 #define _LOCORE
30
31 #include <machine/asm.h>
32
33 RCSID("$NetBSD: execsp.S,v 1.1 2025/04/20 22:32:49 riastradh Exp $")
34
35 .import _GLOBAL_OFFSET_TABLE_
36
37 /*
38 * void execsp_start(struct ps_strings *ps_strings@arg0,
39 * void (*cleanup@arg1)(void), void *obj_main@arg2)
40 *
41 * ELF entry point. Saves the stack pointer in startsp and defers
42 * to the usual csu __start routine.
43 */
44 LEAF_ENTRY(execsp_start)
45 /*
46 * Set up the data pointer (r19) and linkage table register
47 * (r27) like the real startup routine so we can get at the
48 * global symbols startsp and __start.
49 *
50 * XXX Not really sure why we need to set up r27, since we only
51 * use r19 here and the real startup routine, __start, will set
52 * up both r19 and r27 anyway. But this crashes with SIGSEGV
53 * shortly after startup if we don't set up r27, and gdb
54 * crashes on my attempts to single-step, so I'll just leave
55 * the initialization of r27 here for now until someone is
56 * motivated by the potential for a single-instruction
57 * micro-optimization in this test program to find out why r27
58 * is needed too.
59 */
60 bl L$lpc, %r27
61 depi 0, 31, 2, %r27
62 L$lpc: addil L'_GLOBAL_OFFSET_TABLE_ - ($PIC_pcrel$0 - 8), %r27
63 ldo R'_GLOBAL_OFFSET_TABLE_ - ($PIC_pcrel$0 - 12)(%r1), %r27
64 copy %r27, %r19
65
66 addil LT%_C_LABEL(startsp), %r19 /* r20 := &startsp */
67 ldw RT%_C_LABEL(startsp)(%r1), %r20
68
69 /* PIC_TAILCALL(__start), if we had it */
70 addil LT%_C_LABEL(__start), %r19 /* r1 := __start */
71 ldw RT%_C_LABEL(__start)(%r1), %r1
72 bv %r0(%r1) /* jump to __start */
73 stw %sp, 0(%r20) /* startsp := sp */
74 EXIT(execsp_start)
75
76 /*
77 * void execsp_ctor(void)
78 *
79 * ELF constructor. Saves the stack pointer in ctorsp and
80 * returns.
81 */
82 LEAF_ENTRY(execsp_ctor)
83 addil LT%_C_LABEL(ctorsp), %r19 /* r1 := &ctorsp */
84 ldw RT%_C_LABEL(ctorsp)(%r1), %r1
85 bv %r0(%rp) /* return */
86 stw %sp, 0(%r1) /* ctorsp := sp */
87 EXIT(execsp_ctor)
88
89 /* Make execsp_ctor a constructor. */
90 .section .ctors,"aw",@progbits
91 .p2align 2
92 .word _C_LABEL(execsp_ctor)
93
94 /*
95 * int main(int argc@arg0, char **argv@arg1, ...)
96 *
97 * Main function. Saves the stack pointer in mainsp and returns
98 * zero. We will call execsp_main in execsp_dtor once dtorsp has
99 * been initialized.
100 */
101 LEAF_ENTRY(main)
102 addil LT%_C_LABEL(mainsp), %r19 /* r1 := &mainsp */
103 ldw RT%_C_LABEL(mainsp)(%r1), %r1
104 stw %sp, 0(%r1) /* ctorsp := sp */
105 bv %r0(%rp) /* return... */
106 copy %r0, %ret0 /* ...zero */
107 EXIT(main)
108
109 /*
110 * void execsp_dtor(void)
111 *
112 * ELF destructor. Saves the stack pointer in dtorsp and defers
113 * to the C execsp_main in h_execsp.c to report the stack pointers
114 * back to the t_signal_and_sp parent.
115 */
116 LEAF_ENTRY(execsp_dtor)
117 addil LT%_C_LABEL(dtorsp), %r19 /* r20 := &dtorsp */
118 ldw RT%_C_LABEL(dtorsp)(%r1), %r20
119
120 /* PIC_TAILCALL(__start), if we had it */
121 addil LT%_C_LABEL(execsp_main), %r19 /* r1 := execsp_main */
122 ldw RT%_C_LABEL(execsp_main)(%r1), %r1
123 bv %r0(%r1) /* jump to execsp_main */
124 stw %sp, 0(%r20) /* startsp := sp */
125 EXIT(execsp_dtor)
126
127 /* Make execsp_ctor a destructor. */
128 .section .dtors,"aw",@progbits
129 .p2align 2
130 .word _C_LABEL(execsp_dtor)
131