summaryrefslogtreecommitdiff
path: root/recipes/uclibc/uclibc-0.9.28/thumb-call-via-rx.patch
blob: eae54f37e539a4f10487ff03c0dd63bef0bf4020 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
# Put the call_via_rx code into each executable - call_via_ip cannot
# possibly work if called through the PLT!  ldso requires this code
# too as it is not linked with the crt stuff and thumb ldso does
# make calls via a register.
#
# The patch puts the code into crti.S so that it is linked into
# every normally built application (if thumb or interworking is
# selected).  This is only 30 extra bytes and it works - the previous
# code did not because nothing both implemented and exported the
# APIs (they were in libgcc, but not in the version script).
#
# crti.S and crtn.S is also brought up to date with GCC 3.4.4 - this
# is essential for thumb support because the .init and .fini sections
# must use arm or thumb code to match the compilation of the libraries.
#
# Note that code which pushes stuff into .init or .fini must be
# compiled with or without -mthumb to match the uclibc compilation -
# and gcc itself (which does do this) must therefore be compiled to
# match.
#
--- uClibc-0.9.28/.pc/thumb-call-via-rx.patch/libc/sysdeps/linux/arm/crti.S	2005-08-17 15:49:41.000000000 -0700
+++ uClibc-0.9.28/libc/sysdeps/linux/arm/crti.S	2005-09-21 19:15:19.996721584 -0700
@@ -1,26 +1,86 @@
 	.file	"initfini.c"
 	
 	.section .init
-	.align	2
 	.global	_init
 	.type	_init, %function
+#if defined __thumb__
+	.align	1
+	.thumb
+	.thumb_func
 _init:
-	@ args = 0, pretend = 0, frame = 0
-	@ frame_needed = 0, uses_anonymous_args = 0
-	str	lr, [sp, #-4]!
-	
-	.align 2
-	
-	
-	.section .fini
+	push	{r4-r7, lr}
+#else
 	.align	2
+	.arm
+_init:
+	@ gcc 3.3.2 didn't create a stack frame, gcc 3.4.4 does -
+	@ presumably 3.4.4 can put stuff into .init which requires
+	@ the arguments to be saved.  This code is copied from 3.4.4
+	mov	ip, sp
+	stmdb	sp!, {r4, r5, r6, r7, r8, r9, sl, fp, ip, lr, pc}
+	sub	fp, ip, #4
+#endif
+
+
+	.section .fini
 	.global	_fini
 	.type	_fini, %function
+#if defined __thumb__
+	.align	1
+	.thumb
+	.thumb_func
 _fini:
-	@ args = 0, pretend = 0, frame = 0
-	@ frame_needed = 0, uses_anonymous_args = 0
-	str	lr, [sp, #-4]!
-	.align 2
-	
-	
+	push	{r4-r7, lr}
+#else
+	.align	2
+	.arm
+_fini:
+	mov	ip, sp
+	stmdb	sp!, {r4, r5, r6, r7, r8, r9, sl, fp, ip, lr, pc}
+	sub	fp, ip, #4
+#endif
+
+
+#if (defined __thumb__ || defined __THUMB_INTERWORK__) && (defined __ARM_ARCH_4T__ || defined __ARM_ARCH_5T__ || defined __ARM_ARCH_5TE__)
+	@ To support thumb code it is currently necessary to have the _call_via_rX
+	@ functions exposed to the linker for any program or shared library.  PLT
+	@ references are inadequate - the PLT zaps ip and therefore breaks _call_via_ip
+	@ (and the compiler does generate this).  It is simpler to put all the
+	@ required code in here - it only amounts to 60 bytes overhead.
+	@NOTE: it would be better to have the compiler generate this stuff as
+	@ required...
+	.section	".text"
+	.align 0
+	.force_thumb
+
+.macro call_via register
+	.global _call_via_\register
+	.type	_call_via_\register, %function
+	.weak	_call_via_\register
+	.hidden	_call_via_\register
+	.thumb_func
+_call_via_\register:
+	bx	\register
+	nop
+	.size	_call_via_\register, . - _call_via_\register
+.endm
+
+	@ and calls for the 15 general purpose registers (2 bytes each).
+	call_via r0
+	call_via r1
+	call_via r2
+	call_via r3
+	call_via r4
+	call_via r5
+	call_via r6
+	call_via r7
+	call_via r8
+	call_via r9
+	call_via sl
+	call_via fp
+	call_via ip
+	call_via sp
+	call_via lr
+#endif
+
 	.ident	"GCC: (GNU) 3.3.2 20031005 (Debian prerelease)"
--- uClibc-0.9.28/libc/sysdeps/linux/arm/crtn.S.orig	2005-09-20 16:39:20.010925582 -0700
+++ uClibc-0.9.28/libc/sysdeps/linux/arm/crtn.S	2005-09-20 17:00:51.700206464 -0700
@@ -1,17 +1,34 @@
 	.file	"initfini.c"
 	
 	.section .init
-	.align	2
 	.global	_init
 	.type	_init, %function
-	ldr	pc, [sp], #4
+#if defined __thumb__
+	.align	1
+	.thumb
+	@ this will not work on ARMv4T, but lots of stuff
+	@ in here won't work there anyway...
+	pop	{r4-r7, pc}
+#else
+	.align	2
+	.arm
+	ldmdb	fp, {r4, r5, r6, r7, r8, r9, sl, fp, sp, pc}
+#endif
 	.size	_init, .-_init
 	
 	.section .fini
-	.align	2
 	.global	_fini
 	.type	_fini, %function
-	ldr	pc, [sp], #4
+#if defined __thumb__
+	.align	1
+	.thumb
+	pop	{r4-r7, pc}
+#else
+	.align	2
+	.arm
+	ldmdb	fp, {r4, r5, r6, r7, r8, r9, sl, fp, sp, pc}
+#endif
 	.size	_fini, .-_fini
 	
+	@ In fact this is modified to 3.4.4
 	.ident	"GCC: (GNU) 3.3.2 20031005 (Debian prerelease)"
--- uClibc-0.9.28/.pc/thumb-call-via-rx.patch/ldso/ldso/arm/dl-syscalls.h	2005-08-17 15:49:41.000000000 -0700
+++ uClibc-0.9.28/ldso/ldso/arm/dl-syscalls.h	2005-09-21 19:17:01.143086323 -0700
@@ -4,3 +4,39 @@
 #define __set_errno(X) {(_dl_errno) = (X);}
 #include "sys/syscall.h"
 
+/* _call_via_rX calls are used in thumb ldso because of calls via
+ * function pointers, but ldso is not linked with anything which
+ * provides them, so define them here (only required for thumb).
+ */
+#if defined(__thumb__)
+asm(
+	".macro call_via register\n"
+	"	.global	_call_via_\\register\n"
+	"	.hidden	_call_via_\\register\n"
+	"	.type	_call_via_\\register, %function\n"
+	"	.thumb_func\n"
+	"_call_via_\\register:\n"
+	"	bx	\\register\n"
+	"	.size	_call_via_\\register, . - _call_via_\\register\n"
+	".endm\n"
+
+	".text\n"
+	".thumb\n"
+	".align 1\n"
+	"	call_via r0\n"
+	"	call_via r1\n"
+	"	call_via r2\n"
+	"	call_via r3\n"
+	"	call_via r4\n"
+	"	call_via r5\n"
+	"	call_via r6\n"
+	"	call_via r7\n"
+	"	call_via r8\n"
+	"	call_via r9\n"
+	"	call_via r10\n"
+	"	call_via r11\n"
+	"	call_via r12\n"
+	"	call_via r13\n"
+	"	call_via r14\n"
+);
+#endif