summaryrefslogtreecommitdiff
path: root/packages/uclibc/uclibc-0.9.28/thumb-mov-pc-bx.patch
blob: 86713a76782cf2b490d3020bd2fec661d5950936 (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
# This patch changes all cases where the ARM assembler mov pc,rx
# instructions are used to ensure that the thumb/arm interwork change of
# process more works - in essence mov pc,rx needs to become bx rc.
#
# The ldr pc or ldm rx, {pc} instructions are not changed - this is
# fine on ARM >=v5 but will fail to restore thumb mode on ARM v4T,
# i.e. this code will not provide support for thumb on ARM v4T.
#
# One mov pc is left in resolve.S, this is fixed in a different patch -
# thumb-resolve.patch
#
# The changes are protected by __THUMB_INTERWORK__ - the original
# mov instruction will work on newer architectures and is required on
# arch v4 (not v4t) and earlier - those which did not support thumb -
# so this is safe.  See gcc lib1asmfuncs for a more exact test.
#
--- uClibc-0.9.28/.pc/thumb-mov-pc-bx.patch/ldso/ldso/arm/dl-startup.h	2005-08-17 15:49:41.000000000 -0700
+++ uClibc-0.9.28/ldso/ldso/arm/dl-startup.h	2005-09-08 09:34:22.918316874 -0700
@@ -8,6 +8,7 @@
     "	.text\n"
     "	.globl	_start\n"
     "	.type	_start,%function\n"
+    "	.arm\n"
 	"_start:\n"
 	"	@ at start time, all the args are on the stack\n"
 	"	mov	r0, sp\n"
@@ -40,7 +41,11 @@
 	"	ldr	r0, .L_FINI_PROC\n"
 	"	ldr	r0, [sl, r0]\n"
 	"	@ jump to the user_s entry point\n"
+#if defined(__THUMB_INTERWORK__)
+	"	bx	r6\n"
+#else
 	"	mov	pc, r6\n"
+#endif
 	".L_GET_GOT:\n"
 	"	.word	_GLOBAL_OFFSET_TABLE_ - .L_GOT_GOT - 4\n"
 	".L_SKIP_ARGS:\n"
--- uClibc-0.9.28/.pc/thumb-mov-pc-bx.patch/ldso/ldso/arm/dl-sysdep.h	2005-08-17 15:49:41.000000000 -0700
+++ uClibc-0.9.28/ldso/ldso/arm/dl-sysdep.h	2005-09-07 20:10:35.923583424 -0700
@@ -85,7 +85,19 @@
 	extern void __dl_start asm ("_dl_start");
 	Elf32_Addr got_addr = (Elf32_Addr) &__dl_start;
 	Elf32_Addr pcrel_addr;
+#if !defined(__thumb__)
+	/* On thumb this has to be two instructions because
+	 * the offset is negative.
+	 */
 	asm ("adr %0, _dl_start" : "=r" (pcrel_addr));
+#else
+	/* This is dumb, gcc should support a thumb adrl
+	 * but it doesn't, so this is the same thing the
+	 * hard way.  If this code moves too far from _dl_start
+	 * it will fail.
+	 */
+	asm ("adr\t%0, 1f\n1:\tsub\t%0, #1b-_dl_start\n" : "=r" (pcrel_addr));
+#endif
 	return pcrel_addr - got_addr;
 }
 
--- uClibc-0.9.28/.pc/thumb-mov-pc-bx.patch/libc/sysdeps/linux/arm/clone.S	2005-08-17 15:49:41.000000000 -0700
+++ uClibc-0.9.28/libc/sysdeps/linux/arm/clone.S	2005-09-08 09:36:24.801986529 -0700
@@ -51,7 +51,11 @@
 	swi	__NR_clone
 	movs	a1, a1
 	blt	__error
-	movne    pc, lr
+#if defined(__THUMB_INTERWORK__)
+	bxne	lr
+#else
+	movne	pc, lr
+#endif
 
 	@ pick the function arg and call address off the stack and execute
 	ldr	r0, [sp, #4]
--- uClibc-0.9.28/.pc/thumb-mov-pc-bx.patch/libc/sysdeps/linux/arm/vfork.S	2005-08-17 15:49:41.000000000 -0700
+++ uClibc-0.9.28/libc/sysdeps/linux/arm/vfork.S	2005-09-08 09:51:13.377901086 -0700
@@ -34,7 +34,11 @@
 #ifdef __NR_vfork
 	swi	__NR_vfork
 	cmn	r0, #4096
+#if defined(__THUMB_INTERWORK__)
+	bxcc	lr
+#else
 	movcc	pc, lr
+#endif
 
 	/* Check if vfork even exists.  */
 	ldr     r1, =-ENOSYS
@@ -47,7 +51,11 @@
 	cmn     r0, #4096
 
 	/* Syscal worked.  Return to child/parent */
-	movcc   pc, lr
+#if defined(__THUMB_INTERWORK__)
+	bxcc	lr
+#else
+	movcc	pc, lr
+#endif
 
 __error:
 	b	__syscall_error