xref: /openbsd/lib/csu/powerpc/md_init.h (revision 91f110e0)
1 /* $OpenBSD: md_init.h,v 1.2 2013/12/03 06:21:41 guenther Exp $ */
2 
3 /*-
4  * Copyright (c) 2001 Ross Harvey
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  * 3. All advertising materials mentioning features or use of this software
16  *    must display the following acknowledgement:
17  *      This product includes software developed by the NetBSD
18  *      Foundation, Inc. and its contributors.
19  * 4. Neither the name of The NetBSD Foundation nor the names of its
20  *    contributors may be used to endorse or promote products derived
21  *    from this software without specific prior written permission.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
24  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
25  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
26  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
27  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
29  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
30  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
31  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33  * POSSIBILITY OF SUCH DAMAGE.
34  */
35 
36 #define MD_SECT_CALL_FUNC(section, func) \
37 	__asm (".section "#section", \"ax\"\n"	\
38 	"	bl " #func "\n"		\
39 	"	.previous")
40 
41 #define MD_SECTION_PROLOGUE(sect, entry_pt)	\
42 	__asm (					\
43 	".section "#sect",\"ax\",@progbits	\n" \
44 	"	.globl " #entry_pt "		\n" \
45 	"	.type " #entry_pt ",@function	\n" \
46 	"	.align 4			\n" \
47 	#entry_pt":				\n" \
48 	"	stwu	%r1,-16(%r1)		\n" \
49 	"	mflr	%r0			\n" \
50 	"	stw	%r0,12(%r1)		\n" \
51 	"	/* fall thru */			\n" \
52 	"	.previous")
53 
54 
55 #define MD_SECTION_EPILOGUE(sect)		\
56 	__asm (					\
57 	".section "#sect",\"ax\",@progbits	\n" \
58 	"	lwz	%r0,12(%r1)		\n" \
59 	"	mtlr	%r0			\n" \
60 	"	addi	%r1,%r1,16		\n" \
61 	"	blr				\n" \
62 	"	.previous")
63 
64 #include <sys/syscall.h>	/* for SYS_mprotect */
65 
66 #define STR(x) __STRING(x)
67 #define	MD_CRT0_START							\
68 __asm(									\
69 "	.text								\n" \
70 "	.section	\".text\"					\n" \
71 "	.align 2							\n" \
72 "	.size	__got_start, 0						\n" \
73 " 	.type	__got_start, @object					\n" \
74 "	.size	__got_end, 0						\n" \
75 " 	.type	__got_end, @object					\n" \
76 "	.weak	__got_start						\n" \
77 "	.weak	__got_end						\n" \
78 "	.globl	_start							\n" \
79 "	.type	_start, @function					\n" \
80 "	.globl	__start							\n" \
81 "	.type	__start, @function					\n" \
82 "_start:								\n" \
83 "__start:								\n" \
84 "	# move argument registers to saved registers for startup flush	\n" \
85 "	# ...except r6 (auxv) as ___start() doesn't need it		\n" \
86 "	mr %r25, %r3							\n" \
87 "	mr %r24, %r4							\n" \
88 "	mr %r23, %r5							\n" \
89 "	mr %r22, %r7							\n" \
90 "	mflr	%r27	/* save off old link register */		\n" \
91 "	bl	1f							\n" \
92 "	# this instruction never gets executed but can be used		\n" \
93 "	# to find the virtual address where the page is loaded.		\n" \
94 "	bl _GLOBAL_OFFSET_TABLE_@local-4				\n" \
95 "1:									\n" \
96 "	mflr	%r6		# this stores where we are (+4)		\n" \
97 "	lwz	%r18, 0(%r6)	# load the instruction at offset_sym	\n" \
98 "				# it contains an offset to the location	\n" \
99 "				# of the GOT.				\n" \
100 "									\n" \
101 "	rlwinm %r18,%r18,0,8,30 # mask off the offset portion of the instr. \n" \
102 "									\n" \
103 "	/*								\n" \
104 "	 * these adds effectively calculate the value the		\n" \
105 "	 * bl _GLOBAL_OFFSET_TABLE_@local-4				\n" \
106 "	 * operation that would be below would calculate.		\n" \
107 "	 */								\n" \
108 "	add	%r28, %r18, %r6						\n" \
109 "									\n" \
110 "	addi	%r3,%r28,4		# calculate the actual got addr \n" \
111 "	lwz	%r0,__got_start@got(%r3)				\n" \
112 "	cmpwi	%r0,0							\n" \
113 "	beq	4f							\n" \
114 "	cmpw	%r0,%r28						\n" \
115 "	bne	4f							\n" \
116 "	lwz	%r4,__got_end@got(%r3)					\n" \
117 "	cmpwi	%r4,0							\n" \
118 "	beq	2f							\n" \
119 "									\n" \
120 "	sub	%r4, %r4, %r0						\n" \
121 "	b 3f								\n" \
122 "2:									\n" \
123 "	li	%r4, 4							\n" \
124 "3:									\n" \
125 "									\n" \
126 "	/* mprotect GOT to eliminate W+X regions in static binaries */	\n" \
127 "	li	%r0, " STR(SYS_mprotect) "				\n" \
128 "	mr	%r3, %r28						\n" \
129 "	li	%r5, 5	/* (PROT_READ|PROT_EXEC) */			\n" \
130 "	sc								\n" \
131 "									\n" \
132 "4:									\n" \
133 "	li	%r0, 0							\n" \
134 "	# flush the blrl instruction out of the data cache		\n" \
135 "	dcbf	%r6, %r18						\n" \
136 "	sync								\n" \
137 "	isync								\n" \
138 "	# make certain that the got table addr is not in the icache	\n" \
139 "	icbi	%r6, %r18						\n" \
140 "	sync								\n" \
141 "	isync								\n" \
142 "	mtlr %r27							\n" \
143 "	# move argument registers back from saved registers		\n" \
144 "	# putting cleanup in r6 instead of r7				\n" \
145 "	mr %r3, %r25							\n" \
146 "	mr %r4, %r24							\n" \
147 "	mr %r5, %r23							\n" \
148 "	mr %r6, %r22							\n" \
149 "	b ___start							\n" \
150 )
151