]> pilppa.org Git - familiar-h63xx-build.git/blob - org.handhelds.familiar/packages/uclibc/uclibc-0.9.28/thumb-mov-pc-bx.patch
OE tree imported from monotone branch org.openembedded.oz354fam083 at revision 8b12e3...
[familiar-h63xx-build.git] / org.handhelds.familiar / packages / uclibc / uclibc-0.9.28 / thumb-mov-pc-bx.patch
1 # This patch changes all cases where the ARM assembler mov pc,rx
2 # instructions are used to ensure that the thumb/arm interwork change of
3 # process more works - in essence mov pc,rx needs to become bx rc.
4 #
5 # The ldr pc or ldm rx, {pc} instructions are not changed - this is
6 # fine on ARM >=v5 but will fail to restore thumb mode on ARM v4T,
7 # i.e. this code will not provide support for thumb on ARM v4T.
8 #
9 # One mov pc is left in resolve.S, this is fixed in a different patch -
10 # thumb-resolve.patch
11 #
12 # The changes are protected by __THUMB_INTERWORK__ - the original
13 # mov instruction will work on newer architectures and is required on
14 # arch v4 (not v4t) and earlier - those which did not support thumb -
15 # so this is safe.  See gcc lib1asmfuncs for a more exact test.
16 #
17 --- uClibc-0.9.28/.pc/thumb-mov-pc-bx.patch/ldso/ldso/arm/dl-startup.h  2005-08-17 15:49:41.000000000 -0700
18 +++ uClibc-0.9.28/ldso/ldso/arm/dl-startup.h    2005-09-16 23:38:34.266546180 -0700
19 @@ -4,6 +4,7 @@
20   * Copyright (C) 2000-2004 by Erik Andersen <andersen@codepoet.org>
21   */
22  
23 +#if defined(__arm__)
24  asm(
25      "  .text\n"
26      "  .globl  _start\n"
27 @@ -40,7 +41,11 @@
28         "       ldr     r0, .L_FINI_PROC\n"
29         "       ldr     r0, [sl, r0]\n"
30         "       @ jump to the user_s entry point\n"
31 +#if defined(__THUMB_INTERWORK__)
32 +       "       bx      r6\n"
33 +#else
34         "       mov     pc, r6\n"
35 +#endif
36         ".L_GET_GOT:\n"
37         "       .word   _GLOBAL_OFFSET_TABLE_ - .L_GOT_GOT - 4\n"
38         ".L_SKIP_ARGS:\n"
39 @@ -51,6 +56,70 @@
40      "  .size   _start,.-_start\n"
41         ".previous\n"
42  );
43 +#else
44 +asm(
45 +    "  .text\n"
46 +    "  .arm\n"
47 +    "  .globl  _start\n"
48 +    "  .type   _start,%function\n"
49 +       "_start:\n"
50 +       "       @ dumb: can't persuade the linker to make the start address\n"
51 +       "       @ odd, so use an arm function and change to thumb (_dl_start\n"
52 +       "       @ is thumb)\n"
53 +       "       adr     r0, __dl_thumb_start+1\n"
54 +       "       bx      r0\n"
55 +       "\n\n"
56 +    "  .thumb\n"
57 +    "  .globl  __dl_thumb_start\n"
58 +    "  .thumb_func\n"
59 +    "  .type   __dl_thumb_start,%function\n"
60 +       "__dl_thumb_start:\n"
61 +       "       @ at start time, all the args are on the stack\n"
62 +       "       mov     r0, sp\n"
63 +       "       bl      _dl_start\n"
64 +       "       @ returns user entry point in r0\n"
65 +       "       mov     r6, r0\n"
66 +       "       @ we are PIC code, so get global offset table\n"
67 +       "       ldr     r7, .L_GET_GOT\n"
68 +       ".L_GOT_GOT:\n"
69 +       "       add     r7, pc\n"
70 +       "       @ See if we were run as a command with the executable file\n"
71 +       "       @ name as an extra leading argument.\n"
72 +       "       ldr     r4, .L_SKIP_ARGS\n"
73 +       "       ldr     r4, [r7, r4]\n"
74 +       "       @ get the original arg count\n"
75 +       "       ldr     r1, [sp]\n"
76 +       "       @ subtract _dl_skip_args from it\n"
77 +       "       sub     r1, r1, r4\n"
78 +       "       @ adjust the stack pointer to skip them\n"
79 +       "       lsl     r4, r4, #2\n"
80 +       "       add     sp, r4\n"
81 +       "       @ get the argv address\n"
82 +       "       add     r2, sp, #4\n"
83 +       "       @ store the new argc in the new stack location\n"
84 +       "       str     r1, [sp]\n"
85 +       "       @ compute envp\n"
86 +       "       lsl     r3, r1, #2\n"
87 +       "       add     r3, r3, r2\n"
88 +       "       add     r3, #4\n"
89 +       "\n\n"
90 +       "       @ load the finalizer function\n"
91 +       "       ldr     r0, .L_FINI_PROC\n"
92 +       "       ldr     r0, [r7, r0]\n"
93 +       "       @ jump to the user_s entry point\n"
94 +       "       bx      r6\n"
95 +       "\n\n"
96 +       ".L_GET_GOT:\n"
97 +       "       .word   _GLOBAL_OFFSET_TABLE_ - .L_GOT_GOT - 4\n"
98 +       ".L_SKIP_ARGS:\n"
99 +       "       .word   _dl_skip_args(GOTOFF)\n"
100 +       ".L_FINI_PROC:\n"
101 +       "       .word   _dl_fini(GOT)\n"
102 +       "\n\n"
103 +    "  .size   _start,.-_start\n"
104 +       ".previous\n"
105 +);
106 +#endif
107  
108  
109  /* Get a pointer to the argv array.  On many platforms this can be just
110 --- uClibc-0.9.28/.pc/thumb-mov-pc-bx.patch/ldso/ldso/arm/dl-sysdep.h   2005-08-17 15:49:41.000000000 -0700
111 +++ uClibc-0.9.28/ldso/ldso/arm/dl-sysdep.h     2005-09-07 20:10:35.923583424 -0700
112 @@ -85,7 +85,19 @@
113         extern void __dl_start asm ("_dl_start");
114         Elf32_Addr got_addr = (Elf32_Addr) &__dl_start;
115         Elf32_Addr pcrel_addr;
116 +#if !defined(__thumb__)
117 +       /* On thumb this has to be two instructions because
118 +        * the offset is negative.
119 +        */
120         asm ("adr %0, _dl_start" : "=r" (pcrel_addr));
121 +#else
122 +       /* This is dumb, gcc should support a thumb adrl
123 +        * but it doesn't, so this is the same thing the
124 +        * hard way.  If this code moves too far from _dl_start
125 +        * it will fail.
126 +        */
127 +       asm ("adr\t%0, 1f\n1:\tsub\t%0, #1b-_dl_start\n" : "=r" (pcrel_addr));
128 +#endif
129         return pcrel_addr - got_addr;
130  }
131  
132 --- uClibc-0.9.28/.pc/thumb-mov-pc-bx.patch/libc/sysdeps/linux/arm/clone.S      2005-08-17 15:49:41.000000000 -0700
133 +++ uClibc-0.9.28/libc/sysdeps/linux/arm/clone.S        2005-09-08 09:36:24.801986529 -0700
134 @@ -51,7 +51,11 @@
135         swi     __NR_clone
136         movs    a1, a1
137         blt     __error
138 -       movne    pc, lr
139 +#if defined(__THUMB_INTERWORK__)
140 +       bxne    lr
141 +#else
142 +       movne   pc, lr
143 +#endif
144  
145         @ pick the function arg and call address off the stack and execute
146         ldr     r0, [sp, #4]
147 --- uClibc-0.9.28/.pc/thumb-mov-pc-bx.patch/libc/sysdeps/linux/arm/vfork.S      2005-08-17 15:49:41.000000000 -0700
148 +++ uClibc-0.9.28/libc/sysdeps/linux/arm/vfork.S        2005-09-08 09:51:13.377901086 -0700
149 @@ -34,7 +34,11 @@
150  #ifdef __NR_vfork
151         swi     __NR_vfork
152         cmn     r0, #4096
153 +#if defined(__THUMB_INTERWORK__)
154 +       bxcc    lr
155 +#else
156         movcc   pc, lr
157 +#endif
158  
159         /* Check if vfork even exists.  */
160         ldr     r1, =-ENOSYS
161 @@ -47,7 +51,11 @@
162         cmn     r0, #4096
163  
164         /* Syscal worked.  Return to child/parent */
165 -       movcc   pc, lr
166 +#if defined(__THUMB_INTERWORK__)
167 +       bxcc    lr
168 +#else
169 +       movcc   pc, lr
170 +#endif
171  
172  __error:
173         b       __syscall_error