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.
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.
9 # One mov pc is left in resolve.S, this is fixed in a different patch -
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.
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
20 * Copyright (C) 2000-2004 by Erik Andersen <andersen@codepoet.org>
28 " ldr r0, .L_FINI_PROC\n"
30 " @ jump to the user_s entry point\n"
31 +#if defined(__THUMB_INTERWORK__)
37 " .word _GLOBAL_OFFSET_TABLE_ - .L_GOT_GOT - 4\n"
40 " .size _start,.-_start\n"
48 + " .type _start,%function\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"
53 + " adr r0, __dl_thumb_start+1\n"
57 + " .globl __dl_thumb_start\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"
64 + " @ returns user entry point in r0\n"
66 + " @ we are PIC code, so get global offset table\n"
67 + " ldr r7, .L_GET_GOT\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"
76 + " @ subtract _dl_skip_args from it\n"
78 + " @ adjust the stack pointer to skip them\n"
81 + " @ get the argv address\n"
83 + " @ store the new argc in the new stack location\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"
97 + " .word _GLOBAL_OFFSET_TABLE_ - .L_GOT_GOT - 4\n"
99 + " .word _dl_skip_args(GOTOFF)\n"
101 + " .word _dl_fini(GOT)\n"
103 + " .size _start,.-_start\n"
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
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.
120 asm ("adr %0, _dl_start" : "=r" (pcrel_addr));
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
127 + asm ("adr\t%0, 1f\n1:\tsub\t%0, #1b-_dl_start\n" : "=r" (pcrel_addr));
129 return pcrel_addr - got_addr;
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
139 +#if defined(__THUMB_INTERWORK__)
145 @ pick the function arg and call address off the stack and execute
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
153 +#if defined(__THUMB_INTERWORK__)
159 /* Check if vfork even exists. */
164 /* Syscal worked. Return to child/parent */
166 +#if defined(__THUMB_INTERWORK__)