1/*	$NetBSD: crtbegin.S,v 1.9 2023/07/28 07:17:30 rin Exp $	*/
2/*-
3 * Copyright (c) 2013 The NetBSD Foundation, Inc.
4 * All rights reserved.
5 *
6 * This code is derived from software contributed to The NetBSD Foundation
7 * by Matt Thomas of 3am Software Foundry.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 *    notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 *    notice, this list of conditions and the following disclaimer in the
16 *    documentation and/or other materials provided with the distribution.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
19 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
20 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
22 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28 * POSSIBILITY OF SUCH DAMAGE.
29 */
30
31#include <vax/asm.h>
32
33RCSID("$NetBSD: crtbegin.S,v 1.9 2023/07/28 07:17:30 rin Exp $")
34
35	.section	.ctors, "aw", @progbits
36	.p2align 2
37__CTOR_LIST__:		/* symbol is not used */
38	.long -1
39
40	.section	.dtors, "aw", @progbits
41	.p2align 2
42__DTOR_LIST__:
43	.long -1
44
45	.section	.eh_frame, "a", @progbits
46	.p2align 2
47__EH_FRAME_LIST__:
48
49	.section	.jcr, "aw", @progbits
50	.p2align 2
51__JCR_LIST__:
52
53	.section	.data.rel, "aw", @progbits
54	.p2align 2
55	.type	__dso_handle, @object
56	.size	__dso_handle, 4
57	.globl	__dso_handle
58	.hidden	__dso_handle
59__dso_handle:
60#ifdef SHARED
61	.long	__dso_handle
62#else
63	.long	0
64#endif
65
66	.local	__dwarf_eh_object
67	.comm	__dwarf_eh_object,32
68	.local	__initialized
69	.comm	__initialized,1
70	.local	__finished
71	.comm	__finished,1
72
73	.text
74/*
75 * All variables are local to this DSO so we can skip using GOT references
76 * and instead use PCREL references to access them.  We do this regardless
77 * of being PIC since it isn't any additional overhead to do so.
78 *
79 * We don't setup a TOC since all of ours calls are indirect so it isn't
80 * needed.
81 */
82
83	.hidden __do_global_dtors_aux
84
85_ENTRY(__do_global_dtors_aux, R8)
86	tstb	__finished			/* done this already? */
87	bneq	4f
88	movb	$1, __finished			/* mark it as done */
89
90#ifdef SHARED
91	/*
92	 * if (__cxa_finalize)
93	 *	__cxa_finalize(&__dso_handle);
94	 */
95	movab	__cxa_finalize, %r0
96	beql	1f
97	pushal	__dso_handle
98	calls	$0, (%r0)
991:
100#endif /* SHARED */
101
102	/*
103	 * We use load with postincrement to advance the pointer along.
104	 * We know the list ends with 0.  If we load one, we must be done.
105	 */
106	moval	__DTOR_LIST__+4, %r8	/* skip first entry */
1072:	movl	(%r8)+, %r0		/* r0 = *r8++; */
108	beql	3f
109	calls	$0, (%r0)
110	brb	2b
1113:
112
113#ifdef SHARED
114	/*
115	 * if (__deregister_frame_info)
116	 *     __deregister_frame_info(&__EH_FRAME_LIST__[0]);
117	 */
118	moval	__deregister_frame_info, %r0
119	beql	4f
120	pushal	__EH_FRAME_LIST__
121	calls	$0, (%r0)
122#endif /* SHARED */
123
1244:	ret
125END(__do_global_dtors_aux)
126
127	.weak	__deregister_frame_info
128	.weak	__cxa_finalize
129
130	.weak	__register_frame_info
131	.weak	_Jv_RegisterClasses
132
133	.hidden __do_global_ctors_aux
134
135_ENTRY(__do_global_ctors_aux, R8)
136	tstb	__initialized
137	bneq	4f
138	movb	$1, __initialized
139
140	/*
141	 * if (__register_frame_info)
142	 *     __register_frame_info(&__EH_FRAME_LIST__[0], &__dwarf_eh_object)
143	 */
144	movab	__register_frame_info, %r0
145	beql	1f
146
147	pushal	__dwarf_eh_object
148	pushal	__EH_FRAME_LIST__
149	calls	$0, (%r0)
1501:
151
152	/*
153	 * if (_Jv_RegisterClasses && __JCR_LIST__[0])
154	 *     _Jv_RegisterClasses(&__JCR_LIST__[0]);
155	 */
156	movab	_Jv_RegisterClasses, %r0
157	beql	2f
158
159	pushal	__JCR_LIST__
160	calls	$0, (%r0)
1612:
162
163	/*
164	 * Get the end of the CTOR list.  The first entry is -1 so if we
165	 * load a negative address, we know we are done.
166	 */
167
168	moval	__CTOR_LIST_END__, %r8	/* get end of list */
1693:	movl	-(%r8), %r0		/* get function pointer with predec */
170	blss	4f			/*  negative?  done. */
171	calls	$0, (%r0)		/* call it */
172	brb	3b			/* get next one */
173
1744:	ret
175END(__do_global_ctors_aux)
176
177	.hidden	_C_LABEL(__CTOR_LIST_END__)
178
179	.section	.init, "ax", @progbits
180	calls	$0, __do_global_ctors_aux
181	.section	.fini, "ax", @progbits
182	calls	$0, __do_global_dtors_aux
183